cancel
Showing results for 
Search instead for 
Did you mean: 
EN
cancel
Showing results for 
Search instead for 
Did you mean: 
rudl
Booster

Easy gdl mesh

Easy mesh:

! No more VERT EDGE PGON ! (because its a bit of a pain)

just a vertex array

and a face array with vert indices

Face direction should be automatic with the order of vertices, Edges are automatic

Needs more testing, may add some more features.

 

! ------------------------------------------------------------
! Geometry stored in vert and pgon arrays only Example: Pyramid
! ------------------------------------------------------------
! Important order of vertices in Pgon determine Normal / Face direction

! --- SETUP VARIABLES ---

dim points_s[][3]	!points start
dim edges_pi[][2]	!edges point index
dim faces_pi[][]	!faces point index
dim ppf[]			!points per face

! --- POPULATE ---

points_s[1][1] = -1 : points_s[1][2] = -1 : points_s[1][3] = 0	! base
points_s[2][1] =  1 : points_s[2][2] = -1 : points_s[2][3] = 0
points_s[3][1] =  1 : points_s[3][2] =  1 : points_s[3][3] = 0
points_s[4][1] = -1 : points_s[4][2] =  1 : points_s[4][3] = 0
points_s[5][1] =  0 : points_s[5][2] =  0 : points_s[5][3] = 2  	! apex

ppf[1] = 4 : faces_pi[1][1] = 1 : faces_pi[1][2] = 4 : faces_pi[1][3] = 3 : faces_pi[1][4] = 2 	! base (quad)
ppf[2] = 3 : faces_pi[2][1] = 1 : faces_pi[2][2] = 2 : faces_pi[2][3] = 5
ppf[3] = 3 : faces_pi[3][1] = 2 : faces_pi[3][2] = 3 : faces_pi[3][3] = 5
ppf[4] = 3 : faces_pi[4][1] = 3 : faces_pi[4][2] = 4 : faces_pi[4][3] = 5
ppf[5] = 3 : faces_pi[5][1] = 4 : faces_pi[5][2] = 1 : faces_pi[5][3] = 5

nPoints = 5 		! this should be known does not make sense to calc! optional with VARDIM1
nFaces = 5 		! this should be known does not make sense to calc! optional with VARDIM1

! ------------------------------------------------------------
! DO THE MAGIC THING:
! ------------------------------------------------------------

! --- Point index for edges --- edges_pi[][2] for use in EDGE

x=0	! the counter is important!
FOR i=1 TO nFaces
	FOR j=1 TO ppf[i]
		x = x+1
		IF j < ppf[i] THEN 
			edges_pi[x][1]=faces_pi[i][j]
			edges_pi[x][2]=faces_pi[i][j+1]
		ELSE 
			edges_pi[x][1]=faces_pi[i][j] !connect last point of face with first
			edges_pi[x][2]=faces_pi[i][1]		
		ENDIF
	NEXT j
NEXT i

lengthedge = VARDIM1 (edges_pi) ! total edges with duplicates should be nEDGE

! --- Create edge index --- edges[] for use in PGON
! There is some kind of "sorting" through to make the double edge indices negative
! could be optimised for larger meshes though

DIM edges[]
negcount = 0
FOR i = 1 TO lengthedge
	u = edges_pi[i][1]
	v = edges_pi[i][2] 
	edges[i]=i-negcount
		FOR j = 1 To i
			IF edges_pi[j][1]=v AND edges_pi[j][2] = u THEN
				edges[i]= edges[j]*(-1)
				negcount = negcount+1
			ENDIF
		NEXT J
NEXT i

! ------------------------------------------------------------
! BUILDING THE MESH:
! ------------------------------------------------------------

!PUT EVERYTHING TOGETHER

BASE
FOR i = 1 TO nPoints
	VERT points_s[i][1],points_s[i][2],points_s[i][3]
NEXT i

FOR i = 1 TO lengthedge
	IF edges[i]>=1 THEN
		EDGE edges_pi[i][1], edges_pi[i][2],-1,-1,0
	ENDIF
NEXT i

PUT edges
FOR i = 1 TO nFaces
	PGON ppf[i],0,0,GET(ppf[i])
NEXT i

BODY -1

! ------------------------------------------------------------
! DEBUG:
! ------------------------------------------------------------

!PRINT edges_pi
!PRINT edges

 

15 Replies 15
rudl
Booster

That is definitely on my todo list.
Main focus is still making it easier to script meshes within gdl.

rudl
Booster

Parametric torus and bended beams.

Torus example:

theta = 360/u
FOR i = 2 TO u
	vec_temp[1]=po_s[i-1]
	GOSUB "V_ArotX":
	po_s[i] = vec_temp[3] 
NEXT i
FOR i =1 TO u
	po_s[i][2]=	po_s[i][2]+rv
NEXT i
theta = 360/v
FOR i = 1 TO v-1
	FOR j = 1 TO u
		vec_temp[1]=po_s[(i-1)*u+j]
		GOSUB "V_ArotZ":
		po_s[i*u+j] = vec_temp[3]
	NEXT j
NEXT i

c =0
FOR i = 1 TO v
	FOR j = 1 TO u
		IF i = v THEN
		IF j = u THEN
		c = c +1
		f_pi[c][1]=(i-1)*u+j
		f_pi[c][2]= j
		f_pi[c][3]=(i-2)*u+j+1
		c = c +1
		f_pi[c][1]= j
		f_pi[c][2]= 1
		f_pi[c][3]=(i-2)*u+j+1
		ELSE
		c = c +1
		f_pi[c][1]=(i-1)*u+j
		f_pi[c][2]= j
		f_pi[c][3]=(i-1)*u+j+1
		c = c +1
		f_pi[c][1]= j
		f_pi[c][2]= j+1
		f_pi[c][3]= (i-1)*u+j+1
	 	ENDIF
			
		ELSE
		IF j = u THEN
		c = c +1
		f_pi[c][1]=(i-1)*u+j
		f_pi[c][2]=(i)*u+j
		f_pi[c][3]=(i-2)*u+j+1
		c = c +1
		f_pi[c][1]=(i)*u+j
		f_pi[c][2]=(i-1)*u+j+1
		f_pi[c][3]=(i-2)*u+j+1
		ELSE
		c = c +1
		f_pi[c][1]=(i-1)*u+j
		f_pi[c][2]=(i)*u+j
		f_pi[c][3]=(i-1)*u+j+1
		c = c +1
		f_pi[c][1]= (i)*u+j
		f_pi[c][2]= (i)*u+j+1
		f_pi[c][3]= (i-1)*u+j+1
	 	ENDIF
		ENDIF
	NEXT j
NEXT i

Screenshot 2025-11-19 004824.png

rudl
Booster

*) Monkey read from text-file
*) Arbitary rotation around an axis rodriques transformation
*) Display Helper Axes

Screenshot 2025-12-10 002916.png



rudl
Booster

UVs

 

Screenshot 2026-05-29 001058.png

 

Screenshot 2026-05-29 001003.png

  

rudl
Booster

Subdivided Icosahedron  / Geodesic

! ------------------------------------------------------------
! ICOSPHERE
! ------------------------------------------------------------
IF examples = "icosphere" THEN

!BASE ICOSAHEDRON

	phi = (1.0 + SQR(5.0)) / 2 !1.6180339887
	nPoints = 12 : nFaces = 20 : nEdges = 60
	
	!POINTS

	po_s[1][1] = -1 : po_s[1][2] = phi : po_s[1][3] = 0
	po_s[2][1] = 1 : po_s[2][2] = phi : po_s[2][3] = 0
	po_s[3][1] = -1 : po_s[3][2] = -phi : po_s[3][3] = 0
	po_s[4][1] = 1 : po_s[4][2] = -phi : po_s[4][3] = 0	
	
	po_s[5][1] = 0 : po_s[5][2] = -1 : po_s[5][3] = phi
	po_s[6][1] = 0 : po_s[6][2] = 1 : po_s[6][3] = phi
	po_s[7][1] = 0 : po_s[7][2] = -1 : po_s[7][3] = -phi
	po_s[8][1] = 0 : po_s[8][2] = 1 : po_s[8][3] = -phi	
	
	po_s[9][1] = phi : po_s[9][2] = 0 : po_s[9][3] = -1
	po_s[10][1] = phi : po_s[10][2] = 0 : po_s[10][3] = 1
	po_s[11][1] = -phi : po_s[11][2] = 0 : po_s[11][3] = -1
	po_s[12][1] = -phi : po_s[12][2] = 0 : po_s[12][3] = 1

	!FACES

	f_pi[1][1] = 1 : f_pi[1][2] = 12 : f_pi[1][3]= 6
	f_pi[2][1] = 1 : f_pi[2][2] = 6 : f_pi[2][3]= 2
	f_pi[3][1] = 1 : f_pi[3][2] = 2 : f_pi[3][3]= 8
	f_pi[4][1] = 1 : f_pi[4][2] = 8 : f_pi[4][3]= 11
	f_pi[5][1] = 1 : f_pi[5][2] = 11 : f_pi[5][3]= 12

	f_pi[6][1] = 2 : f_pi[6][2] = 6 : f_pi[6][3]= 10
	f_pi[7][1] = 6 : f_pi[7][2] = 12 : f_pi[7][3]= 5
	f_pi[8][1] = 12 : f_pi[8][2] = 11 : f_pi[8][3]= 3
	f_pi[9][1] = 11 : f_pi[9][2] = 8 : f_pi[9][3]= 7
	f_pi[10][1] = 8 : f_pi[10][2] = 2 : f_pi[10][3]= 9

	f_pi[11][1] = 4 : f_pi[11][2] = 10 : f_pi[11][3]= 5
	f_pi[12][1] = 4 : f_pi[12][2] = 5 : f_pi[12][3]= 3
	f_pi[13][1] = 4 : f_pi[13][2] = 3 : f_pi[13][3]= 7
	f_pi[14][1] = 4 : f_pi[14][2] = 7 : f_pi[14][3]= 9
	f_pi[15][1] = 4 : f_pi[15][2] = 9 : f_pi[15][3]= 10

	f_pi[16][1] = 5 : f_pi[16][2] = 10 : f_pi[16][3]= 6
	f_pi[17][1] = 3 : f_pi[17][2] = 5 : f_pi[17][3]= 12
	f_pi[18][1] = 7 : f_pi[18][2] = 3 : f_pi[18][3]= 11
	f_pi[19][1] = 9 : f_pi[19][2] = 7 : f_pi[19][3]= 8
	f_pi[20][1] = 10 : f_pi[20][2] = 9 : f_pi[20][3]= 2

!SUBDIVISION

FOR s = 1 TO subdivide

DIM f_pi_temp[][]		!faces point index
DIM edge_su[][2] 		!temp edges for subdivision
DIM po_midkeys[][]		!mid keys of points po_midkeys[][1] = count | po_midkeys[][x+1] midpoint indices 
DIM mid_indices[] 		!mid indices
DIM mid_indices_clear[] !mid indices clear

FOR i = 1 to nFaces

	mid_indices = mid_indices_clear

	edge_su[1][1] = f_pi[i][1] : edge_su[1][2] = f_pi[i][2]
	edge_su[2][1] = f_pi[i][2] : edge_su[2][2] = f_pi[i][3]
	edge_su[3][1] = f_pi[i][3] : edge_su[3][2] = f_pi[i][1]

	FOR j = 1 TO 3 
		
		midpoint = 0
		
		!Check if midpoint exists

		IF po_midkeys[edge_su[j][1]] [1] # 0 AND po_midkeys[edge_su[j][2]] [1] # 0 THEN

			FOR l = 1 TO  po_midkeys[edge_su[j][1]] [1]
				FOR m = 1 TO  po_midkeys[edge_su[j][2]] [1]
					IF 	po_midkeys[edge_su[j][1]][l+1] = po_midkeys[edge_su[j][2]][m+1] THEN
						mid_indices[j] = po_midkeys[edge_su[j][2]][m+1]
						midpoint = 1
					ENDIF
				NEXT m
			NEXT l

		ENDIF
		
		IF midpoint = 0 THEN
			
			nPoints = nPoints + 1
			mid_indices[j] = nPoints

			po_s[nPoints][1] = (po_s[edge_su[j][1]][1]+po_s[edge_su[j][2]][1])/2
			po_s[nPoints][2] = (po_s[edge_su[j][1]][2]+po_s[edge_su[j][2]][2])/2
			po_s[nPoints][3] = (po_s[edge_su[j][1]][3]+po_s[edge_su[j][2]][3])/2
			
			countm = po_midkeys[edge_su[j][1]] [1]
			countm = countm +1
			po_midkeys[edge_su[j][1]] [1] = countm
			po_midkeys[edge_su[j][1]] [countm +1] = nPoints
			
			countm = po_midkeys[edge_su[j][2]] [1]
			countm = countm +1
			po_midkeys[edge_su[j][2]] [1] = countm
			po_midkeys[edge_su[j][2]] [countm +1] = nPoints
			
		ENDIF

	NEXT j

	f_pi_temp[(i-1)*4+1][1] = f_pi[i][1]
	f_pi_temp[(i-1)*4+1][2] = mid_indices[1]
	f_pi_temp[(i-1)*4+1][3] = mid_indices[3]

	f_pi_temp[(i-1)*4+2][1] = f_pi[i][2]
	f_pi_temp[(i-1)*4+2][2] = mid_indices[2]
	f_pi_temp[(i-1)*4+2][3] = mid_indices[1]

	f_pi_temp[(i-1)*4+3][1] = f_pi[i][3]
	f_pi_temp[(i-1)*4+3][2] = mid_indices[3]
	f_pi_temp[(i-1)*4+3][3] = mid_indices[2]

   	f_pi_temp[(i-1)*4+4][1] = mid_indices[1]
	f_pi_temp[(i-1)*4+4][2] = mid_indices[2]
	f_pi_temp[(i-1)*4+4][3] = mid_indices[3]

NEXT i

f_pi = f_pi_temp

GOSUB "metrics_calc"

next s

FOR i = 1 TO nPoints
	vec_temp[1] = po_s[i]
	GOSUB "V_Aunit":
	po_s[i] = vec_out[1]
	po_s[i][1] = po_s[i][1]*p_ru
	po_s[i][2] = po_s[i][2]*p_ru
	po_s[i][3] = po_s[i][3]*p_ru
NEXT i

GOSUB "BB_calc"

ENDIF

 

Screenshot 2026-08-27 023956.png

rudl
Booster

Loop subdivision, having some fun with chatgpt

 

Screenshot 2026-09-13 002051.png

Didn't find the answer?

Check other topics in this Forum

Back to Forum

Read the latest accepted solutions!

Accepted Solutions

Start a new conversation!