introduction to CAD

Previous topic - Next topic

sf-in-sf

I realized it was easier to program 3D shapes (thank you so much Gernot) than using an unknown super-whizz-bang-3D-modeller software. The aftermath of a failed project shows the basic concepts for a CAD modeller. This approach is not the most graphical one, but anything is allowed if you want to program any kind of anything, like a very special procedural deformer, or probabilistic shapes like the natural trees !....
Use, re-use, ab-use, improve, or artistically decimate at will!

main:
Code (glbasic) Select

// --------------------------------- //
// Project: CADpipes_A
// Start: Saturday, November 08, 2014
// IDE Version: 10.283



//notes: Maybe it would make sense to create arrays of 3Dobjects
// in order to group them, (group or "layer")
// so we can quickly choose whether to draw or ommit a whole array/group.
// It depends what you do...
// Draw a group/layer with "FOREACH ob in group_array[]".

//colors are 0xBBGGRR in hex.
//arrows -> move the camera.
// +/- -> zoom
// 1/3,4/6,7/9 -> move model +/- on x,y,z axes.

// to do: every obj in a different color for clarity, then
// all of them in main color for final view. (probably all vertices in white, then use X_SETTEXTURE.)
// 3 guide planes / rasters in xy yz xz would be useful, switchable with "g".


LIMITFPS 25
CONSTANT rseg%=60//20
CONSTANT r_3=1.2
GLOBAL mcol%=0xaaffaa, scrx,scry
GLOBAL mousefree%, mx,my,b1,b2,t$
GLOBAL cam_d=75, cam_phi=6, cam_theta=20, cam_px=0,cam_py=0,cam_pz=0
GLOBAL model_px, model_py, model_pz
GOSUB make_bg


//make all pieces:
make_pipe_A(1,r_3,-1,1,mcol)//small, inside the S's
make_pipe_A(2,r_3,-5,5,0xbbbbbb)
make_pipe_A(3,r_3,0,100,0xe07777)//0x99ff33)

make_shoulder_A(20,r_3,30,90,10,mcol)
make_shoulder_A(24,r_3,30,180,10,mcol)
//make_disc(201,5,360,8,0xff5500)
//make_closed_cylinder(101,5,300,30,1,-1,0x00ffff)
//---------------------------------


//  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
main:
X_MAKE2D ; DRAWSPRITE 1,0,0
X_MAKE3D 1,1024,35

X_CAMERA cam_d*COS(cam_phi)*COS(cam_theta),cam_d*SIN(cam_theta),cam_d*SIN(cam_phi)*COS(cam_theta), cam_px,cam_py,cam_pz
X_AMBIENT_LT 0,0x66bb66
X_SPOT_LT 1,0xccffff,4,2,1,  0,0,0,360

X_DRAWAXES cam_px, cam_py,cam_pz //0,0,0
GOSUB draw_all
SHOWSCREEN
HIBERNATE

//arrows -> move the camera, theta and phi.
//keypad -> 5 = recenter all, else move model's x,y,z.
// 1,4,7 <=> x,y,z and East<=> increase, West <=> decrease.
//Axes: RGB <=> xyz. Easy!
IF KEY(74) THEN INC cam_d,2
IF KEY(78) THEN DEC cam_d,2
setminmax(cam_d, 2, 300)
IF KEY(203) THEN INC cam_phi,2
IF KEY(205) THEN DEC cam_phi,2

IF KEY(200) THEN INC cam_theta,2
IF KEY(208) THEN DEC cam_theta,2
setminmax(cam_theta, -84,84)

IF KEY(79) THEN INC model_px,5 //kp1
IF KEY(81) THEN DEC model_px,5 //3
IF KEY(75) THEN INC model_py,5 //4
IF KEY(77) THEN DEC model_py,5 //6
IF KEY(71) THEN INC model_pz,5 //7
IF KEY(73) THEN DEC model_pz,5 //9
IF KEY(76) // kp "5" = "help, I'm lost"
cam_px=0 ; cam_py=0 ; cam_pz=0 //unused, always 0, weird movements otherwise.
model_px=0 ; model_py=0 ; model_pz=0
ENDIF
IF KEY(48) THEN GOSUB make_bg
//note: the inc/dec should follow the zoom values,as an option.

GOTO main
//   //////////////////////////////////////////////////////////



fn.gbas
Code (glbasic) Select
// --------------------------------- //
// Project: CADpipes_A
// Start: Saturday, November 08, 2014
// IDE Version: 10.283




//*****************************
// obj  1+ --> pipes          *
// obj 20+ --> shoulders      *
//*****************************

FUNCTION make_pipe_A: obnum%, r, l1,l2,col//straight pipe
//LOCAL rseg%=120,
//LOCAL r= 0.33, l1=-2.0, l2=2.0
STATIC ka, kb
X_OBJSTART obnum//1
FOR i=0 TO rseg-1
ka=360*i/rseg ; kb=360*(i+1)/rseg
X_OBJADDVERTEX r*COS(ka),r*SIN(ka),l1, 0,0,col
X_OBJADDVERTEX r*COS(ka),r*SIN(ka),l2, 0,0,col

X_OBJADDVERTEX r*COS(kb),r*SIN(kb),l1, 0,0,col
X_OBJADDVERTEX r*COS(kb),r*SIN(kb),l2, 0,0,col
X_OBJNEWGROUP
NEXT

X_OBJEND
ENDFUNCTION

FUNCTION make_shoulder_A: obnum%,r,sh_seg%,sh_an,sh_r,col  //rounded corner
// works like a deformer. Here the pipe segments' Nb are always rseg!
// bow's length <- shoulder's r and angle. easy.
STATIC ka, kb, ka2,kb2, x1,y1, x2,y2, x3,y3,z3, x4,y4,z4, x5,y5,z5, x6,y6,z6
X_OBJSTART obnum
FOR i=0 TO rseg-1
ka=360*i/rseg ; kb=360*(i+1)/rseg
x1=r*COS(ka)+sh_r ; y1=r*SIN(ka)
x2=r*COS(kb)+sh_r ; y2=r*SIN(kb)

FOR j=0 TO sh_seg-1
ka2=sh_an*j/sh_seg ; kb2=sh_an*(j+1)/sh_seg
x3=x1*COS(ka2)
x5=x1*COS(kb2)
x4=x2*COS(ka2)
x6=x2*COS(kb2)
y3=y1 ; y5=y1 ; y4=y2 ; y6=y2

z3=x1*SIN(ka2)
z5=x1*SIN(kb2)
z4=x2*SIN(ka2)
z6=x2*SIN(kb2)

X_OBJADDVERTEX x3,y3,z3, 0,0,col
X_OBJADDVERTEX x5,y5,z5, 0,0,col
X_OBJADDVERTEX x4,y4,z4, 0,0,col
X_OBJADDVERTEX x6,y6,z6, 0,0,col
X_OBJNEWGROUP
NEXT ; NEXT

X_OBJEND
ENDFUNCTION //ENDSUB worked!


?IF 0 //not compiled, now unused:
// 2D is 200+
FUNCTION make_disc: obnum%, r,an,sectors,col%
STATIC ka, kb
X_OBJSTART obnum //200+
FOR i=0 TO sectors-1
ka=an*i/sectors ; kb=an*(i+1)/sectors
X_OBJADDVERTEX r*COS(ka),r*SIN(ka),0,  0,0, col
X_OBJADDVERTEX 0,0,0,  0,0, col
X_OBJADDVERTEX r*COS(kb),r*SIN(kb),0,  0,0, col
X_OBJNEWGROUP
NEXT
X_OBJEND
ENDFUNCTION
FUNCTION make_closed_cylinder: obnum%, r,an,sectors,thickup,thickdown,col%
STATIC ka, kb
X_OBJSTART obnum //200+
FOR i=0 TO sectors-1
ka=an*i/sectors ; kb=an*(i+1)/sectors
X_OBJADDVERTEX r*COS(ka),r*SIN(ka),thickup,  0,0, col
X_OBJADDVERTEX 0,0,thickup,  0,0, col
X_OBJADDVERTEX r*COS(kb),r*SIN(kb),thickup,  0,0, col
X_OBJNEWGROUP//stripe mode only.
X_OBJADDVERTEX r*COS(ka),r*SIN(ka),thickdown,  0,0, col
X_OBJADDVERTEX 0,0,thickdown,  0,0, col
X_OBJADDVERTEX r*COS(kb),r*SIN(kb),thickdown,  0,0, col
X_OBJNEWGROUP//stripe mode only.

X_OBJADDVERTEX r*COS(ka),r*SIN(ka),thickup,  0,0, col
X_OBJADDVERTEX r*COS(kb),r*SIN(kb),thickup,  0,0, col
X_OBJADDVERTEX r*COS(ka),r*SIN(ka),thickdown,  0,0, col
X_OBJADDVERTEX r*COS(kb),r*SIN(kb),thickdown,  0,0, col
X_OBJNEWGROUP//(edge)
NEXT
X_OBJEND
ENDFUNCTION
?ENDIF //unused functions

FUNCTION setminmax: BYREF a, mi, ma
IF a<mi THEN a=mi
IF a>ma THEN a=ma
ENDFUNCTION


gosubb.gbas
Code (glbasic) Select
// --------------------------------- //
// Project: CADpipes_A
// Start: Saturday, November 08, 2014
// IDE Version: 10.283


SUB draw_all:
X_MOVEMENT -model_px, -model_py, -model_pz ; X_PUSHMATRIX
//top wave:----------------
FOR i=0 TO 2
X_MOVEMENT 40*i,0,0 ; X_PUSHMATRIX
GOSUB draw_S1
X_POPMATRIX
NEXT
//  (end segment)
X_MOVEMENT 100,0,0 ; X_ROTATION 180, 0,1,0
X_DRAWOBJ 24,0
X_MOVEMENT 0,0,0

//mid wave
X_MOVEMENT 0,0,30 ; X_PUSHMATRIX
GOSUB draw_S2
X_POPMATRIX

//bottom wave
X_MOVEMENT 0,0,60 ; X_PUSHMATRIX
GOSUB draw_S2
X_POPMATRIX

//montants hauts / Frame bar:

X_MOVEMENT -30,0,0 ; X_DRAWOBJ 3,0

X_POPMATRIX
ENDSUB

SUB draw_S1:
X_MOVEMENT -20,0,0 ; X_ROTATION 180, 0,1,0
X_DRAWOBJ 24,0
X_MOVEMENT 0,0,2 ; X_DRAWOBJ 24,0

X_MOVEMENT 10,0,1 ; X_DRAWOBJ 1,0
X_MOVEMENT -10,0,1 ; X_DRAWOBJ 1,0
ENDSUB

SUB draw_S2:

FOR i%=1 TO 3
X_MOVEMENT i*40-40,0,0
X_DRAWOBJ 24,0
X_MOVEMENT i*40-50,0,-1 ; X_DRAWOBJ 1,0
X_MOVEMENT i*40-30,0,-1 ; X_DRAWOBJ 1,0
NEXT
FOR i%=1 TO 2
X_MOVEMENT i*40-20,0,-2 ; X_ROTATION 180, 0,1,0
X_DRAWOBJ 24,0
NEXT

//2 end 90 elbows:
X_MOVEMENT -20,0,-2 ; X_ROTATION 90,0,1,0 ; X_DRAWOBJ 20,0
X_MOVEMENT 100,0,-2 ; X_ROTATION 180,0,1,0 ; X_DRAWOBJ 20,0
// 2 end straights:
X_MOVEMENT -25,0,-12 ; X_ROTATION 90,0,1,0 ; X_DRAWOBJ 2,0
X_MOVEMENT 105,0,-12 ; X_ROTATION 90,0,1,0 ; X_DRAWOBJ 2,0
ENDSUB


SUB make_bg:
GETSCREENSIZE scrx,scry
CREATESCREEN 1,1,scrx,scry ; USESCREEN 1
LOCAL c%
FOR i=0 TO scrx STEP (scrx/12.0)
IF RND(100)>33
c=0x010101*(55+RND(190))
ELSE
c=bOR(RND(0xffffff),ASL(0xff,8*RND(2))) //not dull, 1 chanel is full on.
ENDIF
DRAWRECT i,0, scrx,scry,c
NEXT

USESCREEN -1
ENDSUB


On the day the atom is a cube I will start believing in the square pixel.

erico

Hey, this looks quite special! :good:

Schranz0r

I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard