// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // % % // % IsoCSG Include File - experimental version 0.2 % // % % // % iso_csg.inc - CSG-like operations with isosurface functions % // % % // % written June 2001 - February 2002 % // % by Christoph Hormann % // % % // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // % % // % Experimental version % // % please do not redistribute % // % % // % I encourage you to contact me if you have ideas for % // % improvements % // % % // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #ifdef(iso_CSG_Inc_Temp) // do nothing #else #declare iso_CSG_Inc_Temp = version; #ifdef(View_POV_Include_Stack) # debug "including iso_csg.inc\n" #end #include "math.inc" #include "transforms.inc" #include "functions.inc" //------------------------------------------------------------- // ---- CSG macros ---------------------------------------- //------------------------------------------------------------- #macro IC_Merge2(fn_A, fn_B) // merge 2 objects function(x, y, z){ min(fn_A(x, y, z), fn_B(x, y, z)) } #end #macro IC_Merge3(fn_A, fn_B, fn_C) // merge 3 objects function(x, y, z){ min(fn_A(x, y, z), fn_B(x, y, z), fn_C(x, y, z)) } #end #macro IC_Merge4(fn_A, fn_B, fn_C, fn_D) // merge 4 objects function(x, y, z){ min(fn_A(x, y, z), fn_B(x, y, z), fn_C(x, y, z), fn_D(x, y, z)) } #end #macro IC_Intersection2(fn_A, fn_B) // intersection between 2 objects function(x, y, z){ max(fn_A(x, y, z), fn_B(x, y, z)) } #end #macro IC_Intersection3(fn_A, fn_B, fn_C) // intersection between 3 objects function(x, y, z){ max(fn_A(x, y, z), fn_B(x, y, z), fn_C(x, y, z)) } #end #macro IC_Intersection3(fn_A, fn_B, fn_C, fn_D) // intersection between 4 objects function(x, y, z){ max(fn_A(x, y, z), fn_B(x, y, z), fn_C(x, y, z), fn_D(x, y, z)) } #end #macro IC_Difference2(fn_A, fn_B) // difference between 2 objects function(x, y, z){ max(fn_A(x, y, z), (-fn_B(x, y, z))) } #end #macro IC_Difference3(fn_A, fn_B, fn_C) // difference between 3 objects function(x, y, z){ max(fn_A(x, y, z), (-fn_B(x, y, z)), (-fn_C(x, y, z))) } #end #macro IC_Difference3(fn_A, fn_B, fn_C, fn_D) // difference between 4 objects function(x, y, z){ max(fn_A(x, y, z), (-fn_B(x, y, z)), (-fn_C(x, y, z)), (-fn_D(x, y, z))) } #end //------------------------------------------------------------- // ---- Shape macros -------------------------------------- //------------------------------------------------------------- #macro IC_Plane (Direction, Distance) #local Cx=Direction.x; #local Cy=Direction.y; #local Cz=Direction.z; function(x, y, z){ ((x*Cx)+(y*Cy)+(z*Cz)-Distance) } #end #macro IC_Sphere (Center, Radius) #local Cx=Center.x; #local Cy=Center.y; #local Cz=Center.z; function(x, y, z){ f_sphere(x-Cx, y-Cy, z-Cz, Radius) //(sqrt((x-Cx)^2 + (y-Cy)^2 + (z-Cz)^2) - Radius) } #end #macro IC_Box (Start, End) #local Cx=max(Start.x, End.x); #local Cy=max(Start.y, End.y); #local Cz=max(Start.z, End.z); #local Dx=min(Start.x, End.x); #local Dy=min(Start.y, End.y); #local Dz=min(Start.z, End.z); function(x, y, z){ max(x-Cx, y-Cy, z-Cz, Dx-x, Dy-y, Dz-z) } #end #macro IC_Torus (MaR, MiR) function(x, y, z){ f_torus(x, y, z, MaR, MiR) } #end #macro IC_Cylinder (Start, End, Radius) #local Cx=Start.x; #local Cy=Start.y; #local Cz=Start.z; #local Len=vlength(End-Start); #if (Len=0) #error "iso_csg.inc: Error: zero height cylinder" #end #local fn_T=function { Reorient_Trans(End-Start, x) } #local fn_X= function(x, y, z){ max(sqrt(y^2 + z^2) - Radius, -x, x-Len) } #local fn_Y= function(x, y, z){ fn_X(fn_T(x, y, z).x, fn_T(x, y, z).y, fn_T(x, y, z).z) } function(x, y, z){ (fn_Y((x-Cx),(y-Cy),(z-Cz))) } #end #macro IC_Cone (Start, Radius1, End, Radius2) #local Cx=Start.x; #local Cy=Start.y; #local Cz=Start.z; #local Len=vlength(End-Start); #if (Len=0) #error "iso_csg.inc: Error: zero height cone" #end #local fn_T=function { Reorient_Trans(End-Start, x) } #local fn_X=function(x, y, z){ max(sqrt(y^2 + z^2) - Radius1+x*((Radius1-Radius2)/Len), -x, x-Len) } #local fn_Y= function(x, y, z){ fn_X(fn_T(x, y, z).x, fn_T(x, y, z).y, fn_T(x, y, z).z) } function(x, y, z){ (fn_Y((x-Cx),(y-Cy),(z-Cz))) } #end //------------------------------------------------------------- // ---- Transform macros ---------------------------------- //------------------------------------------------------------- #macro IC_Transform (Fn, Trans) #local fn_T=function { transform { Trans inverse } } function(x, y, z){ Fn(fn_T(x, y, z).x, fn_T(x, y, z).y, fn_T(x, y, z).z) } #end #macro IC_Translate (Fn, Vect) #local Cx=Vect.x; #local Cy=Vect.y; #local Cz=Vect.z; function(x, y, z){ (Fn(x-Cx, y-Cy, z-Cz)) } #end #macro IC_Scale (Fn, Vect) #local Cx=Vect.x; #local Cy=Vect.y; #local Cz=Vect.z; #if (Cx=0) #warning "iso_csg.inc: Scale 0 changed to Scale 1" Cx=1.0; #end #if (Cy=0) #warning "iso_csg.inc: Scale 0 changed to Scale 1" Cy=1.0; #end #if (Cz=0) #warning "iso_csg.inc: Scale 0 changed to Scale 1" Cz=1.0; #end function(x, y, z){ (Fn(x/Cx, y/Cy, z/Cz)) } #end #macro IC_Matrix (Fn, Mtrx) // not equivalent to the matrix transform! function(x, y, z){ Fn(x*Mtrx[0][0] + y*Mtrx[0][1] + z*Mtrx[0][2], x*Mtrx[1][0] + y*Mtrx[1][1] + z*Mtrx[1][2], x*Mtrx[2][0] + y*Mtrx[2][1] + z*Mtrx[2][2]) } #end #macro IC_RotateR (Fn, Vect) // Rotate Radians #local Cx=-Vect.x; #local Cy=-Vect.y; #local Cz=-Vect.z; #local MtrxA=array[3][3] #local MtrxB=array[3][3] #local MtrxC=array[3][3] #local MtrxA[0][0] = 1.0; #local MtrxA[0][1] = 0; #local MtrxA[0][2] = 0; #local MtrxA[1][0] = 0; #local MtrxA[1][1] = cos(Cx); #local MtrxA[1][2] = sin(Cx); #local MtrxA[2][0] = 0; #local MtrxA[2][1] = -sin(Cx); #local MtrxA[2][2] = cos(Cx); #local MtrxB[0][0] = cos(Cy); #local MtrxB[0][1] = 0; #local MtrxB[0][2] = -sin(Cy); #local MtrxB[1][0] = 0; #local MtrxB[1][1] = 1; #local MtrxB[1][2] = 0; #local MtrxB[2][0] = sin(Cy); #local MtrxB[2][1] = 0; #local MtrxB[2][2] = cos(Cy); #local MtrxC[0][0] = cos(Cz); #local MtrxC[0][1] = sin(Cz); #local MtrxC[0][2] = 0; #local MtrxC[1][0] = -sin(Cz); #local MtrxC[1][1] = cos(Cz); #local MtrxC[1][2] = 0; #local MtrxC[2][0] = 0; #local MtrxC[2][1] = 0; #local MtrxC[2][2] = 1; #local fn_X=IC_Matrix (function(x, y, z){ Fn(x, y, z) }, MtrxA) #local fn_Y=IC_Matrix (function(x, y, z){ fn_X(x, y, z) }, MtrxB) IC_Matrix (function { fn_Y(x, y, z) }, MtrxC) #end #macro IC_Rotate (Fn, Vect) // Rotate Degrees #local Cx=(Vect.x/180)*pi; #local Cy=(Vect.y/180)*pi; #local Cz=(Vect.z/180)*pi; IC_RotateR (function(x, y, z){ Fn(x, y, z) }, ) #end //------------------------------------------------------------- #version iso_CSG_Inc_Temp; #end