Constructive Solid Geometry

Charles Pooh, Wolfram Research

(RowDefault[, (Spacer1), , (Spacer1), ])  #WolframTechConf

What’s Constructive Solid Geometry?

Constructive solid geometry (CSG) is a scheme for representing solids as Boolean constructions or combinations of primitives via the regularized set operations.

({{, , , , }})

What’s Constructive Solid Geometry?

CSG representations take the form of ordered binary trees where non-terminal nodes represent either transformations or regularized set operations. Terminal nodes are primitive leaves that represent closed regular sets.

({{, , , , }})

What’s Constructive Solid Geometry?

CSG representations are particularly useful for capturing design intent in the form of features corresponding to material addition or removal.

∘ Conciseness
∘ Guaranteed validity of solids
∘ Computationally convenient Boolean algebraic properties
∘ Natural control of a solid's shape in terms of high level parameters defining the solid's primitives and their positions and orientations

CSG in the Wolfram Language

CSGRegion["op",{(Subscript[reg, 1]),(Subscript[reg, 2]),…}]
represents the solid region corresponding to the Boolean combination "op" of regions (Subscript[reg, 1]),(Subscript[reg, 2]),….

cylinder=Cylinder[{{0., 0., -0.6}, {0., 0., 0.6}}, 0.3];

CSGRegion["Union", {cylinder, 
       Rotate[cylinder,{{0,0,1},{1,0,0}}], Rotate[cylinder,{{0,0,1},{0,1,0}}]}]

CSG Operations

The following Boolean operators can be used:

({{      , , "Intersection"}, {      , , "Difference"}, {      , , "Union"}})

CSGRegion[#, {Rotate[cylinder,{{0,0,1},{1,0,0}}],Rotate[cylinder,{{0,0,1},{0,1,0}}]}] & /@ {"Intersection","Difference","Union"}

2D CSG  Primitives

The following 2D primitives are supported:

({{      , , Disk}, {      , , Ellipsoid}, {      , , Parallelogram}, {      , , Rectangle}, {      , , Triangle}, {      , , RegularPolygon}, {      , , Simplex}, {      , , StadiumShape}})

3D CSG Primitives

The following 3D primitives are supported:

({{      , , Ball}, {      , , CapsuleShape}, {      , , Cone}, {      , , Cube}, {      , , Cuboid}, {      , , Cylinder}, {      , , Dodecahedron}, {      , , Ellipsoid}, {      , , Icosahedron}, {      , , Octahedron}, {      , , Parallelepiped}, {      , , Prism}, {      , , Pyramid}, {      , , Simplex}, {      , , Tetrahedron}, {      , , Torus}})

CSG Transformations

The following geometric transformations (Subscript[w, i]) can be used:

({{      , GeometricTransformation[(Subscript[reg, i]),…], affine transformation }, {      , Rotate[(Subscript[reg, i]),…], rotation}, {      , Scale[(Subscript[reg, i]),…], scaling}, {      , Translate[(Subscript[reg, i]),…], translation}})

Solid Modeling & Representation Schemes

Implicit representation – ImplicitRegion

Surface mesh modeling – BoundaryMeshRegion

Constructive solid geometry – CSGRegion

Primitive Instancing – Ball, Tetrahedron, Polyhedron, …

Geometric Modeling – BooleanRegion, TransformedRegion, …

CAD Modeling: Shaft Bracket

CAD Modeling: Shaft Bracket

CSGRegion["Union",{Cylinder[{{0,0,0},{0,0,3}},2],Cuboid[{-2,-5,0},{2,0,1}],Cuboid[{-2,-5,0},{2,-4,3}]}]

CSGRegion["Union",{Cylinder[{{0,0,-1},{0,0,4}},1],Cylinder[{{0,0,2.5},{0,0,4}},1.5],Cylinder[{{0,-6,3},{0,-4,3}},1.2]}]

CSGRegion["Difference",{%%,%}]

CAD Modeling: Linear Rail Support

CAD Modeling: Linear Rail Support

CSGRegion["Union",{Cuboid[{-10,-10,0},{10,10,40}],Cuboid[{-26,-10,0},{26,10,5}]}]

CSGRegion["Union",{Cuboid[{-1,-12,30},{1,12,50}],Cylinder[{{-20,0,35},{20,0,35}},2],Cylinder[{{0,-20,25},{0,20,25}},7],Cylinder[{{-18,0,-1},{-18,0,12}},4],Cylinder[{{18,0,-1},{18,0,12}},4]}]

CSGRegion["Difference",{%%,%}]

CAD Modeling: Pipe Guide Bracket

CAD Modeling: Pipe Guide Bracket

pos=CSGRegion["Union",{Cuboid[{-30,-30,-1},{30,30,1}],Cylinder[{{-30,0,0},{30,0,0}},10],Cylinder[{{0,-30,0},{0,30,0}},10]}];

corners={{-1,-1,0},{-1,1,0},{1,-1,0},{1,1,0}};

corners=Table[CSGRegion["Difference",{Cube[c*25+c*5*Sqrt[2],15],Cylinder[{c*25-{0,0,10},c*25+{0,0,10}},5]}],{c,corners}];

neg=CSGRegion["Union",{Cylinder[{{-31,0,0},{31,0,0}},9],Cylinder[{{0,-31,0},{0,31,0}},9],Cylinder[{{-20,-20,-2},{-20,-20,2}},3],Cylinder[{{20,-20,-2},{20,-20,2}},3],Cylinder[{{-20,20,-2},{-20,20,2}},3],Cylinder[{{20,20,-2},{20,20,2}},3],Cuboid[{-40,-40,0},{40,40,-15}],Cylinder[{{0,0,-15},{0,0,15}},10],Sequence@@corners}];

CSGRegion["Difference",{pos,neg}]

CAD Modeling: Universal Joint

CAD Modeling: Universal Joint

pos=Cylinder[{{0,0,-15},{0,0,15}},10];

part=CSGRegion["Difference",{Cuboid[{-11,-12,8},{11,12,18}],Cylinder[{{0,-14,8},{0,14,8}},4]}];

neg=CSGRegion["Union",{Cylinder[{{-9,-10,0},{-9,10,0}},5],Cylinder[{{9,-10,0},{9,10,0}},5],Cuboid[{-12,-10,0},{-4,10,10}],Cuboid[{12,-10,0},{4,10,10}],Cylinder[{{0,0,-8},{0,0,16}},8],Cylinder[{{0,0,-16},{0,0,16}},4],Cylinder[{{0,-14,8},{0,14,8}},2],part}];

yoke=CSGRegion["Difference",{pos,neg}]

cross=CSGRegion["Union",{Cylinder[{{0,-12,8},{0,12,8}},1.5],Cylinder[{{-12,0,8},{12,0,8}},1.5],Ball[{0,0,8},4]}];

CSGRegion["Union",{yoke,Translate[Rotate[Rotate[yoke,180Degree,{1,0,0}],90Degree,{0,0,1}],{0,0,16}],cross},BaseStyle->{1->Gray,2->Gray,3->GrayLevel[0.2]}]

CSG Tree Expression

CSGRegion representation as a Tree expression.

cylinder=Cylinder[{{0., 0., -0.6},{0., 0., 0.6}}, 0.3];

csg=CSGRegion["Difference", {CSGRegion["Intersection", {Ball[{0, 0, 0}, 0.65], Cube[]}], 
   CSGRegion["Union", {cylinder, 
       Rotate[cylinder,{{0,0,1},{1,0,0}}], Rotate[cylinder,{{0,0,1},{0,1,0}}]}]}]

tree = CSGRegionTree[csg]

Unprotect[CSGRegionTree];
Clear[CSGRegionTree];
$rules={
CSGRegion-> Tree,
 Rotate[g_,parm___] :> Tree[RotationTransform[parm],{g /. $rules},Trees`TreeElementShapeFunction->(Inset[MatrixForm[TransformationMatrix[RotationTransform[parm]][[1;;3,1;;3]]],#1]&),TreeElementLabel->None],
a_?Region`GraphicsRegionQ:>Tree[a,{},Trees`TreeElementShapeFunction->(Inset[ Graphics3D[a,ImageSize->20,Boxed-> False],#1]&),TreeElementLabel->None]};
CSGRegionTree[csg_]:=csg/. $rules

CSG Tree Expression

Edit and modify CSGRegion.

tree

TreeExtract[tree,2]

TreeExpression[%,"CSGRegion"]

TreeLeaves[tree]

Unprotect[TreeExpression];
Clear[tocsg];
tocsg[op_String,parm_]:=CSGRegion[op,parm];
tocsg[tf_,{parm_}]:=GeometricTransformation[parm,tf];
tocsg[reg_?Region`GraphicsRegionQ,parm_]:=reg;
TreeExpression[tree_,"CSGRegion"]:=
TreeFold[tocsg,tree]

CSG Subsystem

CSGTree – gives the binary CSG tree data structure

CSGRegionExtract – extracts the CSGRegion at a given position

CSGRegionDelete – delete the CSGRegion at a given position

CSGRegionInsert – insert the CSGRegion at a given position

CSGRegionPrimitives – gives the primitives of the CSGRegion

RegionApproximate – gives a CSGRegion that approximates a given MeshRegion

Office Hour: Geometry
Friday 1:00 PM CDT

Office Hour: Graphs & Networks
Friday 2:00 PM CDT

(RowDefault[, (Spacer1), , (Spacer1), ])  #WolframTechConf