OCCT Boolean Operations: Combining and Modifying Shapes
Introduction to Boolean Operations
Boolean operations are fundamental tools in 3D modeling that allow you to combine or modify two or more shapes based on set theory principles. OpenCascade Technology (OCCT) provides robust support for these operations. The three most common types are:
- Union: Combines two or more shapes into a single, unified shape.
- Difference (or Subtraction): Subtracts one or more shapes from a base shape.
- Intersection: Creates a new shape consisting only of the volume or area common to all input shapes.
Union
The Union operation is used to merge two or more shapes into one.
- Requirement: The shapes involved in a union operation must typically intersect or touch each other. If there's no intersection, a valid union might not be constructible, or the result might be a compound of separate objects.
- Result: A successful union results in a single new shape. Intersecting faces are resolved, and new edges are created to delimit the combined geometry. The resulting solid will not have self-intersecting faces, making it suitable for further operations like filleting or chamfering.
Visual Example:
-
Before Union:
Non-unioned result of 3 solids -
After Union:
Unioned result of 3 solids
Union Examples
The following scripts demonstrate creating three solids (a box, a cylinder, and a sphere) and then applying a union operation to combine them.
TypeScript Example: Union of Solids
const start = async () => {
const boxOpt = new Bit.Inputs.OCCT.BoxDto();
boxOpt.width = 5;
boxOpt.length = 8;
boxOpt.height = 5;
const box = await bitbybit.occt.shapes.solid.createBox(boxOpt);
const cylinderOpt = new Bit.Inputs.OCCT.CylinderDto();
cylinderOpt.radius = 3;
cylinderOpt.height = 7;
cylinderOpt.center = [3, 0, 3];
const cylinder = await bitbybit.occt.shapes.solid.createCylinder(cylinderOpt);
const sphereOpt = new Bit.Inputs.OCCT.SphereDto();
sphereOpt.radius = 3;
sphereOpt.center = [-1.5, 1.5, -5];
const sphere = await bitbybit.occt.shapes.solid.createSphere(sphereOpt);
const union = await bitbybit.occt.booleans.union({
shapes: [box, cylinder, sphere],
keepEdges: false
})
bitbybit.draw.drawAnyAsync({
entity: union
});
}
start();
Blockly Example: Union of Solids
<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="l5/.Vj:-%/7j#Mp-KG-{">box</variable><variable id="$,ptpAm%U=h@sH/96hTi">sphere</variable><variable id="OE@k$FUN36JWm^coa`u~">cylinder</variable></variables><block type="variables_set" id="I`U?.]|X:A}`{)9SZ{x)" x="-418" y="-1317"><field name="VAR" id="l5/.Vj:-%/7j#Mp-KG-{">box</field><value name="VALUE"><block type="bitbybit.occt.shapes.solid.createBox" id="5`S[E1UCYhl/VS=Q_P3V"><value name="Width"><block type="math_number" id="7(tS5YiaFY)fP]z2Gy=?"><field name="NUM">5</field></block></value><value name="Length"><block type="math_number" id="~=,]X^toALK]n=W5H/n6"><field name="NUM">8</field></block></value><value name="Height"><block type="math_number" id="XLQ:AgP*MiE5595Jr+$p"><field name="NUM">5</field></block></value><value name="Center"><block type="bitbybit.point.pointXYZ" id="Y/U#if|`(h@*w+aoJIMD"><value name="X"><block type="math_number" id="o/K86r3y:)#H|7j6N;iA"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="d-.7A/[qU(RsaV,;/m-{"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="nL5w|xi%EwUrI{_U(52!"><field name="NUM">0</field></block></value></block></value></block></value><next><block type="variables_set" id="!,ejK/hPJ+UxE]^uKecE"><field name="VAR" id="$,ptpAm%U=h@sH/96hTi">sphere</field><value name="VALUE"><block type="bitbybit.occt.shapes.solid.createSphere" id="28j-evJlfTTT_ZJmBVLr"><value name="Radius"><block type="math_number" id="N@e4Q8YX*1k$o$Z()Q2*"><field name="NUM">3</field></block></value><value name="Center"><block type="bitbybit.point.pointXYZ" id="Fbgp45mPsf0OTLC3-7Fn"><value name="X"><block type="math_number" id="*g!LWGj[~,1vLsf5~/mM"><field name="NUM">-1.5</field></block></value><value name="Y"><block type="math_number" id="S*l,er@XNSxuiM;Y;pxe"><field name="NUM">1.5</field></block></value><value name="Z"><block type="math_number" id="?)e:0Uw;CEMpaw*=blg0"><field name="NUM">-5</field></block></value></block></value></block></value><next><block type="variables_set" id="KCGdMO`WfJZHOr*}E,CQ"><field name="VAR" id="OE@k$FUN36JWm^coa`u~">cylinder</field><value name="VALUE"><block type="bitbybit.occt.shapes.solid.createCylinder" id="(I3!-TyrzZ,@rr%0^e%^"><value name="Radius"><block type="math_number" id="HN.G4scLmzR;eUlv;$b]"><field name="NUM">3</field></block></value><value name="Height"><block type="math_number" id="?)K2.6HH4Z~9h%Y.7;/-"><field name="NUM">7</field></block></value><value name="Center"><block type="bitbybit.point.pointXYZ" id="-YxXPEHvRmNp+rF~=rem"><value name="X"><block type="math_number" id="^D@@@d5uZk%)PW#:RXd:"><field name="NUM">3</field></block></value><value name="Y"><block type="math_number" id="}/a}|-Q#ORM7W~Y|zY1P"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="I5xl{Y+)!j~^`(I4RQLB"><field name="NUM">3</field></block></value></block></value><value name="Direction"><block type="bitbybit.vector.vectorXYZ" id="p=#w%c@Hiz;%o|N%oR[A"><value name="X"><block type="math_number" id="60#8mXW%AOPaR%QE6$T^"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="h15Rui?{Id@b6bKC.=_B"><field name="NUM">1</field></block></value><value name="Z"><block type="math_number" id=".-c62k/j-E2;2KdmAgJq"><field name="NUM">0</field></block></value></block></value></block></value><next><block type="bitbybit.draw.drawAnyAsyncNoReturn" id="UO^K1-FNciNjT{DsaF2S"><value name="Entity"><block type="bitbybit.occt.booleans.union" id="k{PW=1BrUC/dNFCvXivJ"><value name="Shapes"><block type="lists_create_with" id="z*}swV`%[FwIlXV-kXlO"><mutation items="3"></mutation><value name="ADD0"><block type="variables_get" id="b?gv83]7nG5Tmdy;-{U6"><field name="VAR" id="l5/.Vj:-%/7j#Mp-KG-{">box</field></block></value><value name="ADD1"><block type="variables_get" id=")7Z7.=wG=Af3dh[5#9O["><field name="VAR" id="OE@k$FUN36JWm^coa`u~">cylinder</field></block></value><value name="ADD2"><block type="variables_get" id="ZsBN:h[2m.;_qIl2joB;"><field name="VAR" id="$,ptpAm%U=h@sH/96hTi">sphere</field></block></value></block></value><value name="KeepEdges"><block type="logic_boolean" id="xk|{YSq}t{%5*C6/xgGO"><field name="BOOL">FALSE</field></block></value></block></value></block></next></block></next></block></next></block></xml>
Rete Example: Union of Solids
{
"id": "rete-v2-json",
"nodes": {
"e3a91874d35fed36": {
"id": "e3a91874d35fed36",
"name": "bitbybit.occt.shapes.solid.createBox",
"customName": "box",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"width": 5,
"length": 8,
"height": 5,
"center": [
0,
0,
0
],
"originOnCenter": true
},
"inputs": {},
"position": [
-962.7244843514161,
953.4668432455264
]
},
"f0047033d1cf708e": {
"id": "f0047033d1cf708e",
"name": "bitbybit.occt.shapes.solid.createCylinder",
"customName": "cylinder",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 3,
"height": 7,
"center": [
0,
0,
0
],
"direction": [
0,
1,
0
],
"angle": 360,
"originOnCenter": false
},
"inputs": {
"center": {
"connections": [
{
"node": "17ed45a416872a64",
"output": "result",
"data": {}
}
]
}
},
"position": [
-996.4690833108496,
1304.5010230126259
]
},
"17ed45a416872a64": {
"id": "17ed45a416872a64",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 3,
"y": 0,
"z": 3
},
"inputs": {},
"position": [
-1361.617583593442,
1325.4150656353868
]
},
"02a86d62fa90ceff": {
"id": "02a86d62fa90ceff",
"name": "bitbybit.occt.shapes.solid.createSphere",
"customName": "sphere",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 3,
"center": [
0,
0,
0
]
},
"inputs": {
"center": {
"connections": [
{
"node": "ffc84ac75f3ae847",
"output": "result",
"data": {}
}
]
}
},
"position": [
-970.6006661329077,
1672.181268989269
]
},
"ffc84ac75f3ae847": {
"id": "ffc84ac75f3ae847",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": -1.5,
"y": 1.5,
"z": -5
},
"inputs": {},
"position": [
-1315.516361464423,
1641.7722755088807
]
},
"4558746aadb6d65a": {
"id": "4558746aadb6d65a",
"name": "bitbybit.occt.booleans.union",
"customName": "union",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"keepEdges": false
},
"inputs": {
"shapes": {
"connections": [
{
"node": "3e302a94d8e46e57",
"output": "list",
"data": {}
}
]
}
},
"position": [
-164.14411429731987,
1308.9160270232292
]
},
"3e302a94d8e46e57": {
"id": "3e302a94d8e46e57",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "e3a91874d35fed36",
"output": "result",
"data": {}
},
{
"node": "f0047033d1cf708e",
"output": "result",
"data": {}
},
{
"node": "02a86d62fa90ceff",
"output": "result",
"data": {}
}
]
}
},
"position": [
-568.9054803751495,
1365.5769853133597
]
}
}
}
Difference (Subtraction)
The Difference operation is used to subtract one or more shapes (tools) from a base shape.
- Requirement: The shapes must typically intersect for a meaningful subtraction to occur.
- Result: The operation "cuts away" the volume of the tool shapes from the base shape.
Visual Example:
-
Before Difference:
Before difference is computed -
After Difference (Box - (Cylinder + Sphere)):
After difference is computed
The Difference operation takes a main shape (from which to subtract) and one or more "tool" shapes to be subtracted. While you can subtract many shapes, be mindful of potential performance impacts with increasing complexity.
Difference Examples
These scripts demonstrate creating a box, cylinder, and sphere, then subtracting the cylinder and sphere from the box.
TypeScript Example: Difference of Solids
const start = async () => {
const boxOpt = new Bit.Inputs.OCCT.BoxDto();
boxOpt.width = 5;
boxOpt.length = 8;
boxOpt.height = 5;
const box = await bitbybit.occt.shapes.solid.createBox(boxOpt);
const cylinderOpt = new Bit.Inputs.OCCT.CylinderDto();
cylinderOpt.radius = 3;
cylinderOpt.height = 7;
cylinderOpt.center = [3, 0, 3];
const cylinder = await bitbybit.occt.shapes.solid.createCylinder(cylinderOpt);
const sphereOpt = new Bit.Inputs.OCCT.SphereDto();
sphereOpt.radius = 3;
sphereOpt.center = [-1.5, 1.5, -5];
const sphere = await bitbybit.occt.shapes.solid.createSphere(sphereOpt);
const diff = await bitbybit.occt.booleans.difference({
shape: box,
shapes: [cylinder, sphere],
keepEdges: false
})
bitbybit.draw.drawAnyAsync({
entity: diff
});
}
start();
Blockly Example: Difference of Solids
<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="l5/.Vj:-%/7j#Mp-KG-{">box</variable><variable id="$,ptpAm%U=h@sH/96hTi">sphere</variable><variable id="OE@k$FUN36JWm^coa`u~">cylinder</variable></variables><block type="variables_set" id="I`U?.]|X:A}`{)9SZ{x)" x="-418" y="-1317"><field name="VAR" id="l5/.Vj:-%/7j#Mp-KG-{">box</field><value name="VALUE"><block type="bitbybit.occt.shapes.solid.createBox" id="5`S[E1UCYhl/VS=Q_P3V"><value name="Width"><block type="math_number" id="7(tS5YiaFY)fP]z2Gy=?"><field name="NUM">5</field></block></value><value name="Length"><block type="math_number" id="~=,]X^toALK]n=W5H/n6"><field name="NUM">8</field></block></value><value name="Height"><block type="math_number" id="XLQ:AgP*MiE5595Jr+$p"><field name="NUM">5</field></block></value><value name="Center"><block type="bitbybit.point.pointXYZ" id="Y/U#if|`(h@*w+aoJIMD"><value name="X"><block type="math_number" id="o/K86r3y:)#H|7j6N;iA"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="d-.7A/[qU(RsaV,;/m-{"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="nL5w|xi%EwUrI{_U(52!"><field name="NUM">0</field></block></value></block></value></block></value><next><block type="variables_set" id="!,ejK/hPJ+UxE]^uKecE"><field name="VAR" id="$,ptpAm%U=h@sH/96hTi">sphere</field><value name="VALUE"><block type="bitbybit.occt.shapes.solid.createSphere" id="28j-evJlfTTT_ZJmBVLr"><value name="Radius"><block type="math_number" id="N@e4Q8YX*1k$o$Z()Q2*"><field name="NUM">3</field></block></value><value name="Center"><block type="bitbybit.point.pointXYZ" id="Fbgp45mPsf0OTLC3-7Fn"><value name="X"><block type="math_number" id="*g!LWGj[~,1vLsf5~/mM"><field name="NUM">-1.5</field></block></value><value name="Y"><block type="math_number" id="S*l,er@XNSxuiM;Y;pxe"><field name="NUM">1.5</field></block></value><value name="Z"><block type="math_number" id="?)e:0Uw;CEMpaw*=blg0"><field name="NUM">-5</field></block></value></block></value></block></value><next><block type="variables_set" id="KCGdMO`WfJZHOr*}E,CQ"><field name="VAR" id="OE@k$FUN36JWm^coa`u~">cylinder</field><value name="VALUE"><block type="bitbybit.occt.shapes.solid.createCylinder" id="(I3!-TyrzZ,@rr%0^e%^"><value name="Radius"><block type="math_number" id="HN.G4scLmzR;eUlv;$b]"><field name="NUM">3</field></block></value><value name="Height"><block type="math_number" id="?)K2.6HH4Z~9h%Y.7;/-"><field name="NUM">7</field></block></value><value name="Center"><block type="bitbybit.point.pointXYZ" id="-YxXPEHvRmNp+rF~=rem"><value name="X"><block type="math_number" id="^D@@@d5uZk%)PW#:RXd:"><field name="NUM">3</field></block></value><value name="Y"><block type="math_number" id="}/a}|-Q#ORM7W~Y|zY1P"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="I5xl{Y+)!j~^`(I4RQLB"><field name="NUM">3</field></block></value></block></value><value name="Direction"><block type="bitbybit.vector.vectorXYZ" id="p=#w%c@Hiz;%o|N%oR[A"><value name="X"><block type="math_number" id="60#8mXW%AOPaR%QE6$T^"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="h15Rui?{Id@b6bKC.=_B"><field name="NUM">1</field></block></value><value name="Z"><block type="math_number" id=".-c62k/j-E2;2KdmAgJq"><field name="NUM">0</field></block></value></block></value></block></value><next><block type="bitbybit.draw.drawAnyAsyncNoReturn" id="UO^K1-FNciNjT{DsaF2S"><value name="Entity"><block type="bitbybit.occt.booleans.difference" id="4D0=3FaNd$f/J^Db+vU)"><value name="Shape"><block type="variables_get" id="b?gv83]7nG5Tmdy;-{U6"><field name="VAR" id="l5/.Vj:-%/7j#Mp-KG-{">box</field></block></value><value name="Shapes"><block type="lists_create_with" id="z*}swV`%[FwIlXV-kXlO"><mutation items="2"></mutation><value name="ADD0"><block type="variables_get" id=")7Z7.=wG=Af3dh[5#9O["><field name="VAR" id="OE@k$FUN36JWm^coa`u~">cylinder</field></block></value><value name="ADD1"><block type="variables_get" id="ZsBN:h[2m.;_qIl2joB;"><field name="VAR" id="$,ptpAm%U=h@sH/96hTi">sphere</field></block></value></block></value><value name="KeepEdges"><block type="logic_boolean" id="dQd]Z,sZV2Pr*BP+NgJ$"><field name="BOOL">FALSE</field></block></value></block></value></block></next></block></next></block></next></block></xml>
Rete Example: Difference of Solids
{
"id": "rete-v2-json",
"nodes": {
"8d20d5373e2042b9": {
"id": "8d20d5373e2042b9",
"name": "bitbybit.occt.shapes.solid.createBox",
"customName": "box",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"width": 5,
"length": 8,
"height": 5,
"center": [
0,
0,
0
],
"originOnCenter": true
},
"inputs": {},
"position": [
-962.7244843514161,
953.4668432455264
]
},
"b3da0ff1dce92565": {
"id": "b3da0ff1dce92565",
"name": "bitbybit.occt.shapes.solid.createCylinder",
"customName": "cylinder",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 3,
"height": 7,
"center": [
0,
0,
0
],
"direction": [
0,
1,
0
],
"angle": 360,
"originOnCenter": false
},
"inputs": {
"center": {
"connections": [
{
"node": "0e04186c2298548e",
"output": "result",
"data": {}
}
]
}
},
"position": [
-996.4690833108496,
1304.5010230126259
]
},
"0e04186c2298548e": {
"id": "0e04186c2298548e",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 3,
"y": 0,
"z": 3
},
"inputs": {},
"position": [
-1361.617583593442,
1325.4150656353868
]
},
"117049b289c1d142": {
"id": "117049b289c1d142",
"name": "bitbybit.occt.shapes.solid.createSphere",
"customName": "sphere",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 3,
"center": [
0,
0,
0
]
},
"inputs": {
"center": {
"connections": [
{
"node": "ceecc90b9500b0e0",
"output": "result",
"data": {}
}
]
}
},
"position": [
-970.6006661329077,
1672.181268989269
]
},
"ceecc90b9500b0e0": {
"id": "ceecc90b9500b0e0",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": -1.5,
"y": 1.5,
"z": -5
},
"inputs": {},
"position": [
-1315.516361464423,
1641.7722755088807
]
},
"79467eae946af29f": {
"id": "79467eae946af29f",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "b3da0ff1dce92565",
"output": "result",
"data": {}
},
{
"node": "117049b289c1d142",
"output": "result",
"data": {}
}
]
}
},
"position": [
-568.9054803751495,
1365.5769853133597
]
},
"a36ae5e09a7219b5": {
"id": "a36ae5e09a7219b5",
"name": "bitbybit.occt.booleans.difference",
"customName": "difference",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"keepEdges": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "8d20d5373e2042b9",
"output": "result",
"data": {}
}
]
},
"shapes": {
"connections": [
{
"node": "79467eae946af29f",
"output": "list",
"data": {}
}
]
}
},
"position": [
-223.80764346729455,
1210.2675671422721
]
}
}
}
Intersection
The Intersection operation creates a new shape that consists only of the volume or area that is common to all input shapes. It discards any parts of the shapes that do not overlap.
- Requirement: The shapes must intersect for a non-empty result. If there is no common overlapping region, the intersection operation might fail or result in an empty shape.
- Result: The output is a new shape representing the shared portion. In the example below, the intersection of a box, cylinder, and sphere results in a compound shape made of two distinct solid pieces where all three original shapes overlapped.
Visual Example:
-
Before Intersection:
Before intersection is computed -
After Intersection:
After intersection is computed
Intersection Examples
These scripts create a box, cylinder, and sphere, and then compute their common intersection.
TypeScript Example: Intersection of Solids
const start = async () => {
const boxOpt = new Bit.Inputs.OCCT.BoxDto();
boxOpt.width = 5;
boxOpt.length = 8;
boxOpt.height = 5;
const box = await bitbybit.occt.shapes.solid.createBox(boxOpt);
const cylinderOpt = new Bit.Inputs.OCCT.CylinderDto();
cylinderOpt.radius = 3;
cylinderOpt.height = 7;
cylinderOpt.center = [3, 0, 3];
const cylinder = await bitbybit.occt.shapes.solid.createCylinder(cylinderOpt);
const sphereOpt = new Bit.Inputs.OCCT.SphereDto();
sphereOpt.radius = 3;
sphereOpt.center = [-1.5, 1.5, -5];
const sphere = await bitbybit.occt.shapes.solid.createSphere(sphereOpt);
const diff = await bitbybit.occt.booleans.intersection({
shapes: [box, cylinder, sphere],
keepEdges: false
})
bitbybit.draw.drawAnyAsync({
entity: diff
});
}
start();
Blockly Example: Intersection of Solids
<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="l5/.Vj:-%/7j#Mp-KG-{">box</variable><variable id="$,ptpAm%U=h@sH/96hTi">sphere</variable><variable id="OE@k$FUN36JWm^coa`u~">cylinder</variable></variables><block type="variables_set" id="I`U?.]|X:A}`{)9SZ{x)" x="-418" y="-1317"><field name="VAR" id="l5/.Vj:-%/7j#Mp-KG-{">box</field><value name="VALUE"><block type="bitbybit.occt.shapes.solid.createBox" id="5`S[E1UCYhl/VS=Q_P3V"><value name="Width"><block type="math_number" id="7(tS5YiaFY)fP]z2Gy=?"><field name="NUM">5</field></block></value><value name="Length"><block type="math_number" id="~=,]X^toALK]n=W5H/n6"><field name="NUM">8</field></block></value><value name="Height"><block type="math_number" id="XLQ:AgP*MiE5595Jr+$p"><field name="NUM">5</field></block></value><value name="Center"><block type="bitbybit.point.pointXYZ" id="Y/U#if|`(h@*w+aoJIMD"><value name="X"><block type="math_number" id="o/K86r3y:)#H|7j6N;iA"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="d-.7A/[qU(RsaV,;/m-{"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="nL5w|xi%EwUrI{_U(52!"><field name="NUM">0</field></block></value></block></value></block></value><next><block type="variables_set" id="!,ejK/hPJ+UxE]^uKecE"><field name="VAR" id="$,ptpAm%U=h@sH/96hTi">sphere</field><value name="VALUE"><block type="bitbybit.occt.shapes.solid.createSphere" id="28j-evJlfTTT_ZJmBVLr"><value name="Radius"><block type="math_number" id="N@e4Q8YX*1k$o$Z()Q2*"><field name="NUM">3</field></block></value><value name="Center"><block type="bitbybit.point.pointXYZ" id="Fbgp45mPsf0OTLC3-7Fn"><value name="X"><block type="math_number" id="*g!LWGj[~,1vLsf5~/mM"><field name="NUM">-1.5</field></block></value><value name="Y"><block type="math_number" id="S*l,er@XNSxuiM;Y;pxe"><field name="NUM">1.5</field></block></value><value name="Z"><block type="math_number" id="?)e:0Uw;CEMpaw*=blg0"><field name="NUM">-5</field></block></value></block></value></block></value><next><block type="variables_set" id="KCGdMO`WfJZHOr*}E,CQ"><field name="VAR" id="OE@k$FUN36JWm^coa`u~">cylinder</field><value name="VALUE"><block type="bitbybit.occt.shapes.solid.createCylinder" id="(I3!-TyrzZ,@rr%0^e%^"><value name="Radius"><block type="math_number" id="HN.G4scLmzR;eUlv;$b]"><field name="NUM">3</field></block></value><value name="Height"><block type="math_number" id="?)K2.6HH4Z~9h%Y.7;/-"><field name="NUM">7</field></block></value><value name="Center"><block type="bitbybit.point.pointXYZ" id="-YxXPEHvRmNp+rF~=rem"><value name="X"><block type="math_number" id="^D@@@d5uZk%)PW#:RXd:"><field name="NUM">3</field></block></value><value name="Y"><block type="math_number" id="}/a}|-Q#ORM7W~Y|zY1P"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="I5xl{Y+)!j~^`(I4RQLB"><field name="NUM">3</field></block></value></block></value><value name="Direction"><block type="bitbybit.vector.vectorXYZ" id="p=#w%c@Hiz;%o|N%oR[A"><value name="X"><block type="math_number" id="60#8mXW%AOPaR%QE6$T^"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="h15Rui?{Id@b6bKC.=_B"><field name="NUM">1</field></block></value><value name="Z"><block type="math_number" id=".-c62k/j-E2;2KdmAgJq"><field name="NUM">0</field></block></value></block></value></block></value><next><block type="bitbybit.draw.drawAnyAsyncNoReturn" id="UO^K1-FNciNjT{DsaF2S"><value name="Entity"><block type="bitbybit.occt.booleans.intersection" id="h1i2^B[EH`z/Lde?r*EZ"><value name="Shapes"><block type="lists_create_with" id="z*}swV`%[FwIlXV-kXlO"><mutation items="3"></mutation><value name="ADD0"><block type="variables_get" id="b?gv83]7nG5Tmdy;-{U6"><field name="VAR" id="l5/.Vj:-%/7j#Mp-KG-{">box</field></block></value><value name="ADD1"><block type="variables_get" id=")7Z7.=wG=Af3dh[5#9O["><field name="VAR" id="OE@k$FUN36JWm^coa`u~">cylinder</field></block></value><value name="ADD2"><block type="variables_get" id="ZsBN:h[2m.;_qIl2joB;"><field name="VAR" id="$,ptpAm%U=h@sH/96hTi">sphere</field></block></value></block></value><value name="KeepEdges"><block type="logic_boolean" id="i{bVs6:%Jzb@vP`uXRFz"><field name="BOOL">FALSE</field></block></value></block></value></block></next></block></next></block></next></block></xml>
Rete Example: Intersection of Solids
{
"id": "rete-v2-json",
"nodes": {
"1185370897752f77": {
"id": "1185370897752f77",
"name": "bitbybit.occt.shapes.solid.createBox",
"customName": "box",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"width": 5,
"length": 8,
"height": 5,
"center": [
0,
0,
0
],
"originOnCenter": true
},
"inputs": {},
"position": [
-962.7244843514161,
953.4668432455264
]
},
"e3d0c30359e3380b": {
"id": "e3d0c30359e3380b",
"name": "bitbybit.occt.shapes.solid.createCylinder",
"customName": "cylinder",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 3,
"height": 7,
"center": [
0,
0,
0
],
"direction": [
0,
1,
0
],
"angle": 360,
"originOnCenter": false
},
"inputs": {
"center": {
"connections": [
{
"node": "99e03e0405018ea2",
"output": "result",
"data": {}
}
]
}
},
"position": [
-996.4690833108496,
1304.5010230126259
]
},
"99e03e0405018ea2": {
"id": "99e03e0405018ea2",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 3,
"y": 0,
"z": 3
},
"inputs": {},
"position": [
-1361.617583593442,
1325.4150656353868
]
},
"6995c438fa66bb5b": {
"id": "6995c438fa66bb5b",
"name": "bitbybit.occt.shapes.solid.createSphere",
"customName": "sphere",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 3,
"center": [
0,
0,
0
]
},
"inputs": {
"center": {
"connections": [
{
"node": "8d075ada9c8acca1",
"output": "result",
"data": {}
}
]
}
},
"position": [
-970.6006661329077,
1672.181268989269
]
},
"8d075ada9c8acca1": {
"id": "8d075ada9c8acca1",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": -1.5,
"y": 1.5,
"z": -5
},
"inputs": {},
"position": [
-1315.516361464423,
1641.7722755088807
]
},
"1e16f94aefb86adf": {
"id": "1e16f94aefb86adf",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "1185370897752f77",
"output": "result",
"data": {}
},
{
"node": "e3d0c30359e3380b",
"output": "result",
"data": {}
},
{
"node": "6995c438fa66bb5b",
"output": "result",
"data": {}
}
]
}
},
"position": [
-568.6598644469133,
1365.5769853133597
]
},
"c4013db42564d119": {
"id": "c4013db42564d119",
"name": "bitbybit.occt.booleans.intersection",
"customName": "intersection",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"keepEdges": false
},
"inputs": {
"shapes": {
"connections": [
{
"node": "1e16f94aefb86adf",
"output": "list",
"data": {}
}
]
}
},
"position": [
-161.93904723030266,
1329.0338059743085
]
}
}
}
Note on Shape Types for Boolean Operations
Boolean operations in OCCT are versatile and can be applied to various types of shapes, not just solids.
- You can perform a union on two overlapping faces to create a new, combined face.
- You can union two wires that share a common point to form a single, longer wire.
- Difference and intersection operations can also be applied to these lower-dimensional shapes.
The type of the resulting shape will depend on the input shape types and the specific operation. For example, unioning two faces typically results in a new face (or a compound of faces if they don't form a single manifold region).
Note on Performance
While boolean operations are powerful and often seem like simple, intuitive tools for modifying geometry (sometimes referred to as Constructive Solid Geometry - CSG), they can be computationally complex and expensive, especially with intricate shapes.
- Simplicity vs. Cost: It's often tempting to rely heavily on booleans due to their conceptual simplicity.
- Performance Impact: For simple geometries, boolean operations will generally be fast and perform well. However, as the complexity of the input shapes grows (e.g., many faces, complex curves), the performance of boolean operations can degrade rapidly.
- Alternatives: When possible, especially in performance-critical applications or with highly complex models, consider alternative modeling strategies that might build up the desired geometry from its constituent parts using operations like extrusions, lofts, sweeps, and transformations, rather than relying solely on booleans for major form creation.
Boolean operations are a fundamental part of the CAD toolkit, but understanding their potential performance implications is key to using them effectively.



