Preserve Colors in STEP Exports
When you export a shape to a regular STEP file, it loses all color information. The geometry is preserved, but open that file in FreeCAD or Fusion 360 and everything will be gray. That's just how STEP files work.
To keep colors, you need to wrap your shapes in an assembly document. This uses OCCT's XCAF format, which stores both geometry and appearance data. It's an extra step, but it means your colors will show up correctly in other CAD software.
What This Example Does
The scripts below create a "pod shell" shape and export it as a colored STEP file. The geometry part uses several OCCT operations (points, wires, faces, mirrors, fillets) to build an interesting 3D solid. But the important part for this tutorial is at the end.
Once we have the shape, we create an assembly structure around it. We define a part, put it inside an assembly, and assign it a white color. Then we export the whole thing to a .stpZ file (compressed STEP format). When you open that file in FreeCAD, the shape appears in white, just as we specified.
Try It Yourself
Run the script and a pods.stpZ file will download automatically. Open it in FreeCAD (File → Import) and you'll see the pod shape with its white color intact.
- Rete
- Blockly
- TypeScript
{
"id": "rete-v2-json",
"nodes": {
"64871127d97b4fc2": {
"id": "64871127d97b4fc2",
"name": "bitbybit.point.pointXYZ",
"customName": "point xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 15,
"y": 0,
"z": 0
},
"inputs": {},
"position": [
275.34375,
377.90234375
]
},
"d536b05cd46ef37f": {
"id": "d536b05cd46ef37f",
"name": "bitbybit.point.pointXYZ",
"customName": "point xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": -3,
"y": 1,
"z": 6
},
"inputs": {},
"position": [
279.16319071375034,
1062.9949700942132
]
},
"9732d4c476b4f0e5": {
"id": "9732d4c476b4f0e5",
"name": "bitbybit.point.pointXYZ",
"customName": "point xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 6,
"z": 0
},
"inputs": {},
"position": [
277.4677265084968,
718.7797508371792
]
},
"76af1dae173d3a1f": {
"id": "76af1dae173d3a1f",
"name": "bitbybit.occt.shapes.wire.createPolygonWire",
"customName": "polygon wire",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"points": {
"connections": [
{
"node": "463e72411efc06d8",
"output": "list",
"data": {}
}
]
}
},
"position": [
1280.9143171960466,
678.1590154333052
]
},
"463e72411efc06d8": {
"id": "463e72411efc06d8",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "64871127d97b4fc2",
"output": "result",
"data": {}
},
{
"node": "9732d4c476b4f0e5",
"output": "result",
"data": {}
},
{
"node": "d536b05cd46ef37f",
"output": "result",
"data": {}
}
]
}
},
"position": [
847.1473476816714,
722.1961723527584
]
},
"ceecfa006f11f1ce": {
"id": "ceecfa006f11f1ce",
"name": "bitbybit.point.pointXYZ",
"customName": "point xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": -12,
"y": 2.45,
"z": 0
},
"inputs": {},
"position": [
283.4617707586295,
1421.87752645253
]
},
"5c88f8068fe94761": {
"id": "5c88f8068fe94761",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "ceecfa006f11f1ce",
"output": "result",
"data": {}
},
{
"node": "d536b05cd46ef37f",
"output": "result",
"data": {}
},
{
"node": "9732d4c476b4f0e5",
"output": "result",
"data": {}
}
]
}
},
"position": [
848.1401755186496,
1098.1938036051324
]
},
"3bb91e2a3ded9107": {
"id": "3bb91e2a3ded9107",
"name": "bitbybit.occt.shapes.wire.createPolygonWire",
"customName": "polygon wire",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"points": {
"connections": [
{
"node": "5c88f8068fe94761",
"output": "list",
"data": {}
}
]
}
},
"position": [
1262.2728654268767,
1054.5670568739129
]
},
"c97305d51c624ff2": {
"id": "c97305d51c624ff2",
"name": "bitbybit.occt.shapes.face.createFaceFromWire",
"customName": "face from wire",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"planar": true
},
"inputs": {
"shape": {
"connections": [
{
"node": "3bb91e2a3ded9107",
"output": "result",
"data": {}
}
]
}
},
"position": [
1681.734142047135,
1053.4578572429577
]
},
"7c2010ea592be4fb": {
"id": "7c2010ea592be4fb",
"name": "bitbybit.occt.operations.offset",
"customName": "offset",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"distance": -0.6,
"tolerance": 0.0001
},
"inputs": {
"shape": {
"connections": [
{
"node": "76af1dae173d3a1f",
"output": "result",
"data": {}
}
]
}
},
"position": [
1770.5671446406664,
377.78925385745447
]
},
"51f6abc839e671aa": {
"id": "51f6abc839e671aa",
"name": "bitbybit.occt.fillets.fillet2d",
"customName": "fillet 2d",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 0.2
},
"inputs": {
"shape": {
"connections": [
{
"node": "7c2010ea592be4fb",
"output": "result",
"data": {}
}
]
}
},
"position": [
2133.778533923677,
377.68454139412086
]
},
"133ae40807793cda": {
"id": "133ae40807793cda",
"name": "bitbybit.occt.shapes.wire.reversedWire",
"customName": "reversed wire",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"shape": {
"connections": [
{
"node": "51f6abc839e671aa",
"output": "result",
"data": {}
}
]
}
},
"position": [
2497.3580961563584,
374.1564609901723
]
},
"18fb6e60d692df41": {
"id": "18fb6e60d692df41",
"name": "bitbybit.occt.shapes.face.createFaceFromWires",
"customName": "face from wires",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"planar": true
},
"inputs": {
"shapes": {
"connections": [
{
"node": "59379de4bb955f54",
"output": "list",
"data": {}
}
]
}
},
"position": [
3389.3839006031126,
713.2123538106906
]
},
"59379de4bb955f54": {
"id": "59379de4bb955f54",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "76af1dae173d3a1f",
"output": "result",
"data": {}
},
{
"node": "133ae40807793cda",
"output": "result",
"data": {}
}
]
}
},
"position": [
3030.6330166778657,
751.1782561971714
]
},
"4762a53692a55f64": {
"id": "4762a53692a55f64",
"name": "bitbybit.point.pointXYZ",
"customName": "point xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 3,
"y": -2,
"z": 0
},
"inputs": {},
"position": [
281.09968390890657,
1775.5941702304067
]
},
"90ac5e8674b1131c": {
"id": "90ac5e8674b1131c",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "d536b05cd46ef37f",
"output": "result",
"data": {}
},
{
"node": "ceecfa006f11f1ce",
"output": "result",
"data": {}
},
{
"node": "4762a53692a55f64",
"output": "result",
"data": {}
}
]
}
},
"position": [
845.3401615330362,
1537.0728785676797
]
},
"fcb31875148285f1": {
"id": "fcb31875148285f1",
"name": "bitbybit.occt.shapes.wire.createPolygonWire",
"customName": "polygon wire",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"points": {
"connections": [
{
"node": "90ac5e8674b1131c",
"output": "list",
"data": {}
}
]
}
},
"position": [
1255.7937742674867,
1495.6466553401565
]
},
"6035c25e747f32ff": {
"id": "6035c25e747f32ff",
"name": "bitbybit.occt.shapes.face.createFaceFromWire",
"customName": "face from wire",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"planar": true
},
"inputs": {
"shape": {
"connections": [
{
"node": "fcb31875148285f1",
"output": "result",
"data": {}
}
]
}
},
"position": [
1677.6387260816632,
1495.0770215253126
]
},
"6280360fb0bc2aa0": {
"id": "6280360fb0bc2aa0",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "64871127d97b4fc2",
"output": "result",
"data": {}
},
{
"node": "d536b05cd46ef37f",
"output": "result",
"data": {}
},
{
"node": "4762a53692a55f64",
"output": "result",
"data": {}
}
]
}
},
"position": [
831.3320952143066,
1910.8909383009402
]
},
"9cac379ae9572bbf": {
"id": "9cac379ae9572bbf",
"name": "bitbybit.occt.shapes.wire.createPolygonWire",
"customName": "polygon wire",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"points": {
"connections": [
{
"node": "6280360fb0bc2aa0",
"output": "list",
"data": {}
}
]
}
},
"position": [
1239.7456243362474,
1869.0563335599054
]
},
"a478262985898be0": {
"id": "a478262985898be0",
"name": "bitbybit.occt.shapes.face.createFaceFromWire",
"customName": "face from wire",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"planar": true
},
"inputs": {
"shape": {
"connections": [
{
"node": "9cac379ae9572bbf",
"output": "result",
"data": {}
}
]
}
},
"position": [
1676.2743940573935,
1869.5241274721375
]
},
"c6be494998d6700b": {
"id": "c6be494998d6700b",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "18fb6e60d692df41",
"output": "result",
"data": {}
},
{
"node": "c97305d51c624ff2",
"output": "result",
"data": {}
},
{
"node": "6035c25e747f32ff",
"output": "result",
"data": {}
},
{
"node": "a478262985898be0",
"output": "result",
"data": {}
}
]
}
},
"position": [
3838.491985293574,
1421.5244971481136
]
},
"96918722cd093bc9": {
"id": "96918722cd093bc9",
"name": "bitbybit.occt.shapes.shell.sewFaces",
"customName": "sew faces",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"tolerance": 1e-7
},
"inputs": {
"shapes": {
"connections": [
{
"node": "c6be494998d6700b",
"output": "list",
"data": {}
}
]
}
},
"position": [
4195.666169339617,
1378.2511515645638
]
},
"c2f6eb82fe529da0": {
"id": "c2f6eb82fe529da0",
"name": "bitbybit.occt.transforms.mirrorAlongNormal",
"customName": "mirror along normal",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"origin": [
0,
0,
0
],
"normal": [
0,
0,
1
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "96918722cd093bc9",
"output": "result",
"data": {}
}
]
}
},
"position": [
4595.456911047103,
1050.6417234070864
]
},
"38845f520dc0ee91": {
"id": "38845f520dc0ee91",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "96918722cd093bc9",
"output": "result",
"data": {}
},
{
"node": "c2f6eb82fe529da0",
"output": "result",
"data": {}
}
]
}
},
"position": [
5000.281336560723,
1717.9815842806065
]
},
"c2a552f546a6b60a": {
"id": "c2a552f546a6b60a",
"name": "bitbybit.occt.shapes.shell.sewFaces",
"customName": "sew faces",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"tolerance": 1e-7
},
"inputs": {
"shapes": {
"connections": [
{
"node": "38845f520dc0ee91",
"output": "list",
"data": {}
}
]
}
},
"position": [
5365.271779405733,
1677.0188599601715
]
},
"7d2941d3be8e2a3a": {
"id": "7d2941d3be8e2a3a",
"name": "bitbybit.occt.fillets.filletEdges",
"customName": "fillet edges",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 0.1
},
"inputs": {
"shape": {
"connections": [
{
"node": "c2a552f546a6b60a",
"output": "result",
"data": {}
}
]
}
},
"position": [
5734.028133633279,
1675.5827076007108
]
},
"22383304991f8529": {
"id": "22383304991f8529",
"name": "bitbybit.occt.operations.makeThickSolidSimple",
"customName": "make thick solid simple",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"offset": 0.2
},
"inputs": {
"shape": {
"connections": [
{
"node": "7d2941d3be8e2a3a",
"output": "result",
"data": {}
}
]
}
},
"position": [
6101.855984210116,
1675.4531073625872
]
},
"f9cada164abd3c07": {
"id": "f9cada164abd3c07",
"name": "bitbybit.babylon.scene.drawDirectionalLight",
"customName": "draw directional light",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"direction": [
-100,
-100,
-100
],
"intensity": 3,
"diffuse": "#ffffff",
"specular": "#ffffff",
"shadowGeneratorMapSize": 2056,
"enableShadows": true,
"shadowDarkness": 0,
"shadowUsePercentageCloserFiltering": true,
"transparencyShadow": false,
"shadowContactHardeningLightSizeUVRatio": 0.2,
"shadowBias": 0.001,
"shadowNormalBias": 0.02,
"shadowMaxZ": 1000,
"shadowMinZ": 0,
"shadowRefreshRate": 1
},
"inputs": {
"direction": {
"connections": [
{
"node": "6e0e86cfceecaf92",
"output": "result",
"data": {}
}
]
}
},
"position": [
519.2679663090069,
2411.9560049670945
]
},
"4a74c07e049d4f66": {
"id": "4a74c07e049d4f66",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "draw any async",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"options": {
"connections": [
{
"node": "e85b6d79b38bebac",
"output": "result",
"data": {}
}
]
},
"entity": {
"connections": [
{
"node": "22383304991f8529",
"output": "result",
"data": {}
}
]
}
},
"position": [
6724.342370479487,
1861.445136803221
]
},
"1e3882c852cf7fa2": {
"id": "1e3882c852cf7fa2",
"name": "bitbybit.babylon.scene.twoColorRadialGradientBackground",
"customName": "two color radial gradient background",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"colorFrom": "#8194b1",
"colorTo": "#1c1e21",
"position": "center",
"stopFrom": 0,
"stopTo": 100,
"shape": "circle"
},
"inputs": {},
"position": [
1008.3162151796415,
2413.590215837871
]
},
"e85b6d79b38bebac": {
"id": "e85b6d79b38bebac",
"name": "bitbybit.draw.optionsOcctShapeMaterial",
"customName": "options occt shape material",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"precision": 0.01,
"drawEdges": true,
"edgeColour": "#000000",
"edgeWidth": 1
},
"inputs": {
"faceMaterial": {
"connections": [
{
"node": "6dd0ac2312d8a445",
"output": "result",
"data": {}
}
]
}
},
"position": [
6151.066736588239,
2137.6524649277453
]
},
"6dd0ac2312d8a445": {
"id": "6dd0ac2312d8a445",
"name": "bitbybit.babylon.material.pbrMetallicRoughness.create",
"customName": "pbr metallic roughness",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"name": "Custom Material",
"baseColor": "#ff0000",
"emissiveColor": "#000000",
"metallic": 0.8,
"roughness": 0.8,
"alpha": 1,
"backFaceCulling": false,
"zOffset": 2
},
"inputs": {},
"position": [
5770.4914206873555,
2175.503071200361
]
},
"548d3d6be71ea269": {
"id": "548d3d6be71ea269",
"name": "bitbybit.babylon.scene.enableSkybox",
"customName": "enable skybox",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"skybox": "city",
"size": 1000,
"blur": 0.1,
"environmentIntensity": 0.7,
"hideSkybox": true
},
"inputs": {},
"position": [
1009.5002269620913,
2866.7419875317214
]
},
"6e0e86cfceecaf92": {
"id": "6e0e86cfceecaf92",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": -20,
"y": -20,
"z": -20
},
"inputs": {},
"position": [
150.7664490428099,
2415.6906891308363
]
},
"38d8893e092a9843": {
"id": "38d8893e092a9843",
"name": "bitbybit.babylon.camera.setPosition",
"customName": "set position",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"position": [
20,
20,
20
]
},
"inputs": {
"position": {
"connections": [
{
"node": "df3618f8981e2a00",
"output": "result",
"data": {}
}
]
},
"camera": {
"connections": [
{
"node": "f1acf02de8e17cb7",
"output": "result",
"data": {}
}
]
}
},
"position": [
2353.8662038966104,
2728.0314948472023
]
},
"df3618f8981e2a00": {
"id": "df3618f8981e2a00",
"name": "bitbybit.point.pointXYZ",
"customName": "point xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": -2.5,
"z": 0
},
"inputs": {},
"position": [
1879.5932131480004,
2834.4954624274087
]
},
"f1acf02de8e17cb7": {
"id": "f1acf02de8e17cb7",
"name": "bitbybit.draw.drawGridMesh",
"customName": "draw grid mesh",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"width": 400,
"height": 400,
"subdivisions": 10,
"majorUnitFrequency": 10,
"minorUnitVisibility": 0.45,
"gridRatio": 0.5,
"opacity": 0.5,
"backFaceCulling": false,
"mainColor": "#ffffff",
"secondaryColor": "#ffffff"
},
"inputs": {},
"position": [
1436.7515998096599,
2418.6945334492084
]
},
"69e844a2d1b39004": {
"id": "69e844a2d1b39004",
"name": "bitbybit.occt.assembly.manager.createPart",
"customName": "create part",
"async": true,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"id": "pod-shell",
"name": "Pod Shell",
"colorRgba": {
"r": 1,
"g": 0,
"b": 0,
"a": 1
}
},
"inputs": {
"shape": {
"connections": [
{
"node": "22383304991f8529",
"output": "result",
"data": {}
}
]
}
},
"position": [
6772.878858590931,
156.9390376290428
]
},
"d36337342b4fd25b": {
"id": "d36337342b4fd25b",
"name": "bitbybit.occt.assembly.manager.createInstanceNode",
"customName": "create instance node",
"async": true,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"id": "pod-instance",
"partId": "pod-shell",
"name": "pod",
"parentId": "pod-assembly",
"translation": [
0,
0,
0
],
"rotation": [
0,
0,
0
],
"scale": 1,
"colorRgba": {
"r": 1,
"g": 0,
"b": 0,
"a": 1
}
},
"inputs": {
"translation": {
"connections": [
{
"node": "e15d4a82f46c10f5",
"output": "result",
"data": {}
}
]
}
},
"position": [
6769.973951836359,
954.6580041097689
]
},
"112f1ae3d18fcd78": {
"id": "112f1ae3d18fcd78",
"name": "bitbybit.occt.assembly.manager.createAssemblyNode",
"customName": "create assembly node",
"async": true,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"id": "pod-assembly",
"name": "Pod Assembly",
"parentId": "",
"colorRgba": {
"r": 1,
"g": 0,
"b": 0,
"a": 1
}
},
"inputs": {},
"position": [
6770.672871081287,
559.0474055476269
]
},
"f937d491e06994c9": {
"id": "f937d491e06994c9",
"name": "bitbybit.occt.assembly.manager.combineStructure",
"customName": "combine structure",
"async": true,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"parts": [],
"nodes": [],
"clearDocument": true
},
"inputs": {
"parts": {
"connections": [
{
"node": "3cf1ed52d51b23e7",
"output": "list",
"data": {}
}
]
},
"nodes": {
"connections": [
{
"node": "f9b417b0c21a7f82",
"output": "list",
"data": {}
}
]
},
"removals": {
"connections": [
{
"node": "fe1b8865ce1cac55",
"output": "list",
"data": {}
}
]
},
"partUpdates": {
"connections": [
{
"node": "fe1b8865ce1cac55",
"output": "list",
"data": {}
}
]
}
},
"position": [
7905.079840644276,
506.0087238223271
]
},
"01e663d060268770": {
"id": "01e663d060268770",
"name": "bitbybit.occt.assembly.manager.buildAssemblyDocument",
"customName": "build assembly document",
"async": true,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"structure": {
"connections": [
{
"node": "f937d491e06994c9",
"output": "result",
"data": {}
}
]
}
},
"position": [
8311.598059831911,
507.03243798196337
]
},
"3cf1ed52d51b23e7": {
"id": "3cf1ed52d51b23e7",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "69e844a2d1b39004",
"output": "result",
"data": {}
}
]
}
},
"position": [
7255.976186927161,
324.93009279382125
]
},
"f9b417b0c21a7f82": {
"id": "f9b417b0c21a7f82",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "112f1ae3d18fcd78",
"output": "result",
"data": {}
},
{
"node": "d36337342b4fd25b",
"output": "result",
"data": {}
}
]
}
},
"position": [
7254.38690650243,
798.942743654834
]
},
"fe1b8865ce1cac55": {
"id": "fe1b8865ce1cac55",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {},
"position": [
7257.5877730420625,
996.9447788860685
]
},
"034366d3e6231fb0": {
"id": "034366d3e6231fb0",
"name": "bitbybit.occt.assembly.manager.exportDocumentToStep",
"customName": "export document to step",
"async": true,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"fileName": "pods2.stpZ",
"author": "Bitbybit user",
"organization": "Bitbybit",
"compress": true,
"tryDownload": true
},
"inputs": {
"document": {
"connections": [
{
"node": "01e663d060268770",
"output": "result",
"data": {}
}
]
}
},
"position": [
8732.992298291007,
503.933261394487
]
},
"dd029c2ae2a42179": {
"id": "dd029c2ae2a42179",
"name": "bitbybit.previewData",
"customName": "preview data",
"data": {},
"inputs": {
"data": {
"connections": [
{
"node": "f937d491e06994c9",
"output": "result",
"data": {}
}
]
}
},
"position": [
8260.606405709495,
56.04990133835869
]
},
"e15d4a82f46c10f5": {
"id": "e15d4a82f46c10f5",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 0,
"z": 0
},
"inputs": {},
"position": [
6374.774712204608,
1106.0259971284574
]
}
}
}
<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="bg">bg</variable><variable id="pt1">pt1</variable><variable id="pt2">pt2</variable><variable id="pt3">pt3</variable><variable id="pt4">pt4</variable><variable id="polygonWire1">polygonWire1</variable><variable id="polygonWire2">polygonWire2</variable><variable id="face1">face1</variable><variable id="polygonWire3">polygonWire3</variable><variable id="face2">face2</variable><variable id="polygonWire4">polygonWire4</variable><variable id="face3">face3</variable><variable id="offsetWire">offsetWire</variable><variable id="filletWire">filletWire</variable><variable id="reversedWire">reversedWire</variable><variable id="faceWithHole">faceWithHole</variable><variable id="shell1">shell1</variable><variable id="mirroredShell">mirroredShell</variable><variable id="combinedShell">combinedShell</variable><variable id="filletedShell">filletedShell</variable><variable id="thickSolid">thickSolid</variable><variable id="pbrMaterial">pbrMaterial</variable><variable id="podPart">podPart</variable><variable id="assemblyNode">assemblyNode</variable><variable id="instanceNode">instanceNode</variable><variable id="partsList">partsList</variable><variable id="nodesList">nodesList</variable><variable id="structure">structure</variable><variable id="document">document</variable><variable id="exportedDoc">exportedDoc</variable></variables><block type="bitbybit.babylon.scene.drawDirectionalLightNoReturn" id="drawLight" x="-350" y="-100"><value name="Direction"><block type="bitbybit.vector.vectorXYZ" id="lightDir"><value name="X"><block type="math_number" id="ldx"><field name="NUM">-20</field></block></value><value name="Y"><block type="math_number" id="ldy"><field name="NUM">-20</field></block></value><value name="Z"><block type="math_number" id="ldz"><field name="NUM">-20</field></block></value></block></value><value name="Intensity"><block type="math_number" id="lightInt"><field name="NUM">3</field></block></value><value name="Diffuse"><block type="colour_picker" id="diffuse"><field name="COLOUR">#ffffff</field></block></value><value name="Specular"><block type="colour_picker" id="specular"><field name="COLOUR">#ffffff</field></block></value><value name="ShadowGeneratorMapSize"><block type="math_number" id="shadowMap"><field name="NUM">2056</field></block></value><value name="EnableShadows"><block type="logic_boolean" id="enableShadows"><field name="BOOL">TRUE</field></block></value><value name="ShadowDarkness"><block type="math_number" id="shadowDark"><field name="NUM">0</field></block></value><value name="ShadowUsePercentageCloserFiltering"><block type="logic_boolean" id="shadowPCF"><field name="BOOL">TRUE</field></block></value><value name="TransparencyShadow"><block type="logic_boolean" id="transShadow"><field name="BOOL">FALSE</field></block></value><value name="ShadowContactHardeningLightSizeUVRatio"><block type="math_number" id="shadowContact"><field name="NUM">0.2</field></block></value><value name="ShadowBias"><block type="math_number" id="shadowBias"><field name="NUM">0.001</field></block></value><value name="ShadowNormalBias"><block type="math_number" id="shadowNormalBias"><field name="NUM">0.02</field></block></value><value name="ShadowMaxZ"><block type="math_number" id="shadowMaxZ"><field name="NUM">1000</field></block></value><value name="ShadowMinZ"><block type="math_number" id="shadowMinZ"><field name="NUM">0</field></block></value><value name="ShadowRefreshRate"><block type="math_number" id="shadowRefresh"><field name="NUM">1</field></block></value><next><block type="variables_set" id="setBg"><field name="VAR" id="bg">bg</field><value name="VALUE"><block type="bitbybit.babylon.scene.twoColorRadialGradientBackground" id="radialBg"><value name="ColorFrom"><block type="colour_picker" id="colorFrom"><field name="COLOUR">#8194b1</field></block></value><value name="ColorTo"><block type="colour_picker" id="colorTo"><field name="COLOUR">#1c1e21</field></block></value><value name="Position"><block type="text" id="radialPos"><field name="TEXT">center</field></block></value><value name="StopFrom"><block type="math_number" id="stopFrom"><field name="NUM">0</field></block></value><value name="StopTo"><block type="math_number" id="stopTo"><field name="NUM">100</field></block></value><value name="Shape"><block type="text" id="radialShape"><field name="TEXT">circle</field></block></value></block></value><next><block type="bitbybit.babylon.scene.enableSkybox" id="enableSkybox"><value name="Skybox"><block type="bitbybit.babylon.enums.skyboxEnum" id="skyboxEnum"><field name="bitbybit.babylon.enums.skyboxEnum">'city'</field></block></value><value name="Size"><block type="math_number" id="skyboxSize"><field name="NUM">1000</field></block></value><value name="Blur"><block type="math_number" id="skyboxBlur"><field name="NUM">0.1</field></block></value><value name="EnvironmentIntensity"><block type="math_number" id="envIntensity"><field name="NUM">0.7</field></block></value><value name="HideSkybox"><block type="logic_boolean" id="hideSkybox"><field name="BOOL">TRUE</field></block></value><next><block type="variables_set" id="setPt1"><field name="VAR" id="pt1">pt1</field><value name="VALUE"><block type="bitbybit.point.pointXYZ" id="createPt1"><value name="X"><block type="math_number" id="pt1x"><field name="NUM">15</field></block></value><value name="Y"><block type="math_number" id="pt1y"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="pt1z"><field name="NUM">0</field></block></value></block></value><next><block type="variables_set" id="setPt2"><field name="VAR" id="pt2">pt2</field><value name="VALUE"><block type="bitbybit.point.pointXYZ" id="createPt2"><value name="X"><block type="math_number" id="pt2x"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="pt2y"><field name="NUM">6</field></block></value><value name="Z"><block type="math_number" id="pt2z"><field name="NUM">0</field></block></value></block></value><next><block type="variables_set" id="setPt3"><field name="VAR" id="pt3">pt3</field><value name="VALUE"><block type="bitbybit.point.pointXYZ" id="createPt3"><value name="X"><block type="math_number" id="pt3x"><field name="NUM">-3</field></block></value><value name="Y"><block type="math_number" id="pt3y"><field name="NUM">1</field></block></value><value name="Z"><block type="math_number" id="pt3z"><field name="NUM">6</field></block></value></block></value><next><block type="variables_set" id="setPt4"><field name="VAR" id="pt4">pt4</field><value name="VALUE"><block type="bitbybit.point.pointXYZ" id="createPt4"><value name="X"><block type="math_number" id="pt4x"><field name="NUM">-12</field></block></value><value name="Y"><block type="math_number" id="pt4y"><field name="NUM">2.45</field></block></value><value name="Z"><block type="math_number" id="pt4z"><field name="NUM">0</field></block></value></block></value><next><block type="variables_set" id="setPolygonWire1"><field name="VAR" id="polygonWire1">polygonWire1</field><value name="VALUE"><block type="base_time_await_return" id="awaitPoly1"><value name="Promise"><block type="bitbybit.occt.shapes.wire.createPolygonWire" id="createPoly1"><value name="Points"><block type="lists_create_with" id="poly1Points"><mutation items="3"></mutation><value name="ADD0"><block type="variables_get" id="getPt1a"><field name="VAR" id="pt1">pt1</field></block></value><value name="ADD1"><block type="variables_get" id="getPt2a"><field name="VAR" id="pt2">pt2</field></block></value><value name="ADD2"><block type="variables_get" id="getPt3a"><field name="VAR" id="pt3">pt3</field></block></value></block></value></block></value></block></value><next><block type="variables_set" id="setPolygonWire2"><field name="VAR" id="polygonWire2">polygonWire2</field><value name="VALUE"><block type="base_time_await_return" id="awaitPoly2"><value name="Promise"><block type="bitbybit.occt.shapes.wire.createPolygonWire" id="createPoly2"><value name="Points"><block type="lists_create_with" id="poly2Points"><mutation items="3"></mutation><value name="ADD0"><block type="variables_get" id="getPt4a"><field name="VAR" id="pt4">pt4</field></block></value><value name="ADD1"><block type="variables_get" id="getPt3b"><field name="VAR" id="pt3">pt3</field></block></value><value name="ADD2"><block type="variables_get" id="getPt2b"><field name="VAR" id="pt2">pt2</field></block></value></block></value></block></value></block></value><next><block type="variables_set" id="setFace1"><field name="VAR" id="face1">face1</field><value name="VALUE"><block type="base_time_await_return" id="awaitFace1"><value name="Promise"><block type="bitbybit.occt.shapes.face.createFaceFromWire" id="createFace1"><value name="Shape"><block type="variables_get" id="getPolygonWire2"><field name="VAR" id="polygonWire2">polygonWire2</field></block></value><value name="Planar"><block type="logic_boolean" id="planar1"><field name="BOOL">TRUE</field></block></value></block></value></block></value><next><block type="variables_set" id="setPolygonWire3"><field name="VAR" id="polygonWire3">polygonWire3</field><value name="VALUE"><block type="base_time_await_return" id="awaitPoly3"><value name="Promise"><block type="bitbybit.occt.shapes.wire.createPolygonWire" id="createPoly3"><value name="Points"><block type="lists_create_with" id="poly3Points"><mutation items="3"></mutation><value name="ADD0"><block type="variables_get" id="getPt3c"><field name="VAR" id="pt3">pt3</field></block></value><value name="ADD1"><block type="variables_get" id="getPt4b"><field name="VAR" id="pt4">pt4</field></block></value><value name="ADD2"><block type="bitbybit.point.pointXYZ" id="pt5"><value name="X"><block type="math_number" id="pt5x"><field name="NUM">3</field></block></value><value name="Y"><block type="math_number" id="pt5y"><field name="NUM">-2</field></block></value><value name="Z"><block type="math_number" id="pt5z"><field name="NUM">0</field></block></value></block></value></block></value></block></value></block></value><next><block type="variables_set" id="setFace2"><field name="VAR" id="face2">face2</field><value name="VALUE"><block type="base_time_await_return" id="awaitFace2"><value name="Promise"><block type="bitbybit.occt.shapes.face.createFaceFromWire" id="createFace2"><value name="Shape"><block type="variables_get" id="getPolygonWire3"><field name="VAR" id="polygonWire3">polygonWire3</field></block></value><value name="Planar"><block type="logic_boolean" id="planar2"><field name="BOOL">TRUE</field></block></value></block></value></block></value><next><block type="variables_set" id="setPolygonWire4"><field name="VAR" id="polygonWire4">polygonWire4</field><value name="VALUE"><block type="base_time_await_return" id="awaitPoly4"><value name="Promise"><block type="bitbybit.occt.shapes.wire.createPolygonWire" id="createPoly4"><value name="Points"><block type="lists_create_with" id="poly4Points"><mutation items="3"></mutation><value name="ADD0"><block type="variables_get" id="getPt1c"><field name="VAR" id="pt1">pt1</field></block></value><value name="ADD1"><block type="variables_get" id="getPt3d"><field name="VAR" id="pt3">pt3</field></block></value><value name="ADD2"><block type="bitbybit.point.pointXYZ" id="pt5b"><value name="X"><block type="math_number" id="pt5bx"><field name="NUM">3</field></block></value><value name="Y"><block type="math_number" id="pt5by"><field name="NUM">-2</field></block></value><value name="Z"><block type="math_number" id="pt5bz"><field name="NUM">0</field></block></value></block></value></block></value></block></value></block></value><next><block type="variables_set" id="setFace3"><field name="VAR" id="face3">face3</field><value name="VALUE"><block type="base_time_await_return" id="awaitFace3"><value name="Promise"><block type="bitbybit.occt.shapes.face.createFaceFromWire" id="createFace3"><value name="Shape"><block type="variables_get" id="getPolygonWire4"><field name="VAR" id="polygonWire4">polygonWire4</field></block></value><value name="Planar"><block type="logic_boolean" id="planar3"><field name="BOOL">TRUE</field></block></value></block></value></block></value><next><block type="variables_set" id="setOffsetWire"><field name="VAR" id="offsetWire">offsetWire</field><value name="VALUE"><block type="base_time_await_return" id="awaitOffset"><value name="Promise"><block type="bitbybit.occt.operations.offset" id="offsetOp"><value name="Shape"><block type="variables_get" id="getPolyWire1"><field name="VAR" id="polygonWire1">polygonWire1</field></block></value><value name="Distance"><block type="math_number" id="offsetDist"><field name="NUM">-0.6</field></block></value><value name="Tolerance"><block type="math_number" id="offsetTol"><field name="NUM">0.0001</field></block></value></block></value></block></value><next><block type="variables_set" id="setFilletWire"><field name="VAR" id="filletWire">filletWire</field><value name="VALUE"><block type="base_time_await_return" id="awaitFillet2d"><value name="Promise"><block type="bitbybit.occt.fillets.fillet2d" id="fillet2dOp"><value name="Shape"><block type="variables_get" id="getOffsetWire"><field name="VAR" id="offsetWire">offsetWire</field></block></value><value name="Radius"><block type="math_number" id="fillet2dRad"><field name="NUM">0.2</field></block></value></block></value></block></value><next><block type="variables_set" id="setReversedWire"><field name="VAR" id="reversedWire">reversedWire</field><value name="VALUE"><block type="base_time_await_return" id="awaitReverse"><value name="Promise"><block type="bitbybit.occt.shapes.wire.reversedWire" id="reverseWireOp"><value name="Shape"><block type="variables_get" id="getFilletWire"><field name="VAR" id="filletWire">filletWire</field></block></value></block></value></block></value><next><block type="variables_set" id="setFaceWithHole"><field name="VAR" id="faceWithHole">faceWithHole</field><value name="VALUE"><block type="base_time_await_return" id="awaitFaceWires"><value name="Promise"><block type="bitbybit.occt.shapes.face.createFaceFromWires" id="createFaceFromWires"><value name="Shapes"><block type="lists_create_with" id="wiresList"><mutation items="2"></mutation><value name="ADD0"><block type="variables_get" id="getPolyWire1b"><field name="VAR" id="polygonWire1">polygonWire1</field></block></value><value name="ADD1"><block type="variables_get" id="getRevWire"><field name="VAR" id="reversedWire">reversedWire</field></block></value></block></value><value name="Planar"><block type="logic_boolean" id="planarWires"><field name="BOOL">TRUE</field></block></value></block></value></block></value><next><block type="variables_set" id="setShell1"><field name="VAR" id="shell1">shell1</field><value name="VALUE"><block type="base_time_await_return" id="awaitSew1"><value name="Promise"><block type="bitbybit.occt.shapes.shell.sewFaces" id="sewFaces1"><value name="Shapes"><block type="lists_create_with" id="facesList1"><mutation items="4"></mutation><value name="ADD0"><block type="variables_get" id="getFaceHole"><field name="VAR" id="faceWithHole">faceWithHole</field></block></value><value name="ADD1"><block type="variables_get" id="getFace1"><field name="VAR" id="face1">face1</field></block></value><value name="ADD2"><block type="variables_get" id="getFace2"><field name="VAR" id="face2">face2</field></block></value><value name="ADD3"><block type="variables_get" id="getFace3"><field name="VAR" id="face3">face3</field></block></value></block></value><value name="Tolerance"><block type="math_number" id="sewTol1"><field name="NUM">1e-7</field></block></value></block></value></block></value><next><block type="variables_set" id="setMirrored"><field name="VAR" id="mirroredShell">mirroredShell</field><value name="VALUE"><block type="base_time_await_return" id="awaitMirror"><value name="Promise"><block type="bitbybit.occt.transforms.mirrorAlongNormal" id="mirrorOp"><value name="Shape"><block type="variables_get" id="getShell1"><field name="VAR" id="shell1">shell1</field></block></value><value name="Origin"><block type="bitbybit.vector.vectorXYZ" id="mirrorOrigin"><value name="X"><block type="math_number" id="mox"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="moy"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="moz"><field name="NUM">0</field></block></value></block></value><value name="Normal"><block type="bitbybit.vector.vectorXYZ" id="mirrorNormal"><value name="X"><block type="math_number" id="mnx"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="mny"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="mnz"><field name="NUM">1</field></block></value></block></value></block></value></block></value><next><block type="variables_set" id="setCombined"><field name="VAR" id="combinedShell">combinedShell</field><value name="VALUE"><block type="base_time_await_return" id="awaitSew2"><value name="Promise"><block type="bitbybit.occt.shapes.shell.sewFaces" id="sewFaces2"><value name="Shapes"><block type="lists_create_with" id="shellsList"><mutation items="2"></mutation><value name="ADD0"><block type="variables_get" id="getShell1b"><field name="VAR" id="shell1">shell1</field></block></value><value name="ADD1"><block type="variables_get" id="getMirrored"><field name="VAR" id="mirroredShell">mirroredShell</field></block></value></block></value><value name="Tolerance"><block type="math_number" id="sewTol2"><field name="NUM">1e-7</field></block></value></block></value></block></value><next><block type="variables_set" id="setFilleted"><field name="VAR" id="filletedShell">filletedShell</field><value name="VALUE"><block type="base_time_await_return" id="awaitFilletEdges"><value name="Promise"><block type="bitbybit.occt.fillets.filletEdges" id="filletEdgesOp"><value name="Shape"><block type="variables_get" id="getCombined"><field name="VAR" id="combinedShell">combinedShell</field></block></value><value name="Radius"><block type="math_number" id="filletRad"><field name="NUM">0.1</field></block></value></block></value></block></value><next><block type="variables_set" id="setThickSolid"><field name="VAR" id="thickSolid">thickSolid</field><value name="VALUE"><block type="base_time_await_return" id="awaitThick"><value name="Promise"><block type="bitbybit.occt.operations.makeThickSolidSimple" id="thickSolidOp"><value name="Shape"><block type="variables_get" id="getFilleted"><field name="VAR" id="filletedShell">filletedShell</field></block></value><value name="Offset"><block type="math_number" id="thickOffset"><field name="NUM">0.2</field></block></value></block></value></block></value><next><block type="variables_set" id="setPbrMat"><field name="VAR" id="pbrMaterial">pbrMaterial</field><value name="VALUE"><block type="bitbybit.babylon.material.pbrMetallicRoughness.create" id="createPbr"><value name="Name"><block type="text" id="pbrName"><field name="TEXT">Custom Material</field></block></value><value name="BaseColor"><block type="colour_picker" id="baseColor"><field name="COLOUR">#ff0000</field></block></value><value name="EmissiveColor"><block type="colour_picker" id="emissiveColor"><field name="COLOUR">#000000</field></block></value><value name="Metallic"><block type="math_number" id="metallic"><field name="NUM">0.8</field></block></value><value name="Roughness"><block type="math_number" id="roughness"><field name="NUM">0.8</field></block></value><value name="Alpha"><block type="math_number" id="alpha"><field name="NUM">1</field></block></value><value name="BackFaceCulling"><block type="logic_boolean" id="backFaceCull"><field name="BOOL">FALSE</field></block></value><value name="ZOffset"><block type="math_number" id="zOffset"><field name="NUM">2</field></block></value></block></value><next><block type="bitbybit.draw.drawAnyAsyncNoReturn" id="drawShape"><value name="Entity"><block type="variables_get" id="getThickSolid"><field name="VAR" id="thickSolid">thickSolid</field></block></value><value name="Options"><block type="bitbybit.draw.optionsOcctShapeMaterial" id="drawOptMat"><value name="Precision"><block type="math_number" id="drawPrec"><field name="NUM">0.01</field></block></value><value name="FaceMaterial"><block type="variables_get" id="getPbrMat"><field name="VAR" id="pbrMaterial">pbrMaterial</field></block></value><value name="DrawEdges"><block type="logic_boolean" id="drawEdges"><field name="BOOL">TRUE</field></block></value><value name="EdgeColour"><block type="colour_picker" id="edgeColor"><field name="COLOUR">#000000</field></block></value><value name="EdgeWidth"><block type="math_number" id="edgeWidth"><field name="NUM">1</field></block></value></block></value><next><block type="variables_set" id="setPodPart"><field name="VAR" id="podPart">podPart</field><value name="VALUE"><block type="base_time_await_return" id="awaitPart"><value name="Promise"><block type="bitbybit.occt.assembly.manager.createPart" id="createPart"><value name="Id"><block type="text" id="partId"><field name="TEXT">pod-shell</field></block></value><value name="Shape"><block type="variables_get" id="getThickSolidPart"><field name="VAR" id="thickSolid">thickSolid</field></block></value><value name="Name"><block type="text" id="partName"><field name="TEXT">Pod Shell</field></block></value><value name="ColorRgba"><block type="bitbybit.color.hexToRgbMapped" id="ulMnm)ExJslire8Rm}lS"><value name="Color"><block type="colour_picker" id="vzUw4cd;PeG@lK|4o-Kh"><field name="COLOUR">#ff0000</field></block></value><value name="From"><block type="math_number" id="JZ=(Vk=3;K]l!v_:%5Ft"><field name="NUM">0</field></block></value><value name="To"><block type="math_number" id="gG[1U%bR6h%Uw^7B@9]o"><field name="NUM">1</field></block></value></block></value></block></value></block></value><next><block type="variables_set" id="setAssemblyNode"><field name="VAR" id="assemblyNode">assemblyNode</field><value name="VALUE"><block type="base_time_await_return" id="awaitAssembly"><value name="Promise"><block type="bitbybit.occt.assembly.manager.createAssemblyNode" id="createAssemblyNode"><value name="Id"><block type="text" id="assemblyId"><field name="TEXT">pod-assembly</field></block></value><value name="Name"><block type="text" id="assemblyName"><field name="TEXT">Pod Assembly</field></block></value><value name="ParentId"><block type="text" id="assemblyParent"><field name="TEXT"></field></block></value><value name="ColorRgba"><block type="bitbybit.color.hexToRgbMapped" id="y}9tJF]Rqd^gD`}5UsYV"><value name="Color"><block type="colour_picker" id="{2^?44B:,0sO#oZ]hRk4"><field name="COLOUR">#ff0000</field></block></value><value name="From"><block type="math_number" id="$1j=!M.Vf$EVSqC/%TxI"><field name="NUM">0</field></block></value><value name="To"><block type="math_number" id="+{9rr6Tn*3//=@Y}_rQy"><field name="NUM">1</field></block></value></block></value></block></value></block></value><next><block type="variables_set" id="setInstanceNode"><field name="VAR" id="instanceNode">instanceNode</field><value name="VALUE"><block type="base_time_await_return" id="awaitInstance"><value name="Promise"><block type="bitbybit.occt.assembly.manager.createInstanceNode" id="createInstance"><value name="Id"><block type="text" id="instanceId"><field name="TEXT">pod-instance</field></block></value><value name="PartId"><block type="text" id="instancePartId"><field name="TEXT">pod-shell</field></block></value><value name="Name"><block type="text" id="instanceName"><field name="TEXT">pod</field></block></value><value name="ParentId"><block type="text" id="instanceParent"><field name="TEXT">pod-assembly</field></block></value><value name="Translation"><block type="bitbybit.vector.vectorXYZ" id="instanceTrans"><value name="X"><block type="math_number" id="itx"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="ity"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="itz"><field name="NUM">0</field></block></value></block></value><value name="Rotation"><block type="bitbybit.vector.vectorXYZ" id="instanceRot"><value name="X"><block type="math_number" id="irx"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="iry"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="irz"><field name="NUM">0</field></block></value></block></value><value name="Scale"><block type="math_number" id="instanceScale"><field name="NUM">1</field></block></value><value name="ColorRgba"><block type="bitbybit.color.hexToRgbMapped" id="instanceColor"><value name="Color"><block type="colour_picker" id="instColorPicker"><field name="COLOUR">#ff0000</field></block></value><value name="From"><block type="math_number" id="AUFXnH7M]a3;nbH5YL-L"><field name="NUM">0</field></block></value><value name="To"><block type="math_number" id="colorToNum"><field name="NUM">1</field></block></value></block></value></block></value></block></value><next><block type="variables_set" id="setPartsList"><field name="VAR" id="partsList">partsList</field><value name="VALUE"><block type="lists_create_with" id="createPartsList"><mutation items="1"></mutation><value name="ADD0"><block type="variables_get" id="getPodPart"><field name="VAR" id="podPart">podPart</field></block></value></block></value><next><block type="variables_set" id="setNodesList"><field name="VAR" id="nodesList">nodesList</field><value name="VALUE"><block type="lists_create_with" id="createNodesList"><mutation items="2"></mutation><value name="ADD0"><block type="variables_get" id="getAssNode"><field name="VAR" id="assemblyNode">assemblyNode</field></block></value><value name="ADD1"><block type="variables_get" id="getInstNode"><field name="VAR" id="instanceNode">instanceNode</field></block></value></block></value><next><block type="variables_set" id="setStructure"><field name="VAR" id="structure">structure</field><value name="VALUE"><block type="base_time_await_return" id="awaitStructure"><value name="Promise"><block type="bitbybit.occt.assembly.manager.combineStructure" id="combineStructure"><value name="Parts"><block type="variables_get" id="getPartsList"><field name="VAR" id="partsList">partsList</field></block></value><value name="Nodes"><block type="variables_get" id="getNodesList"><field name="VAR" id="nodesList">nodesList</field></block></value><value name="Removals"><block type="lists_create_with" id="emptyRemovals"><mutation items="0"></mutation></block></value><value name="PartUpdates"><block type="lists_create_with" id="emptyUpdates"><mutation items="0"></mutation></block></value><value name="ClearDocument"><block type="logic_boolean" id="clearDoc"><field name="BOOL">FALSE</field></block></value></block></value></block></value><next><block type="variables_set" id="setDocument"><field name="VAR" id="document">document</field><value name="VALUE"><block type="base_time_await_return" id="awaitBuild"><value name="Promise"><block type="bitbybit.occt.assembly.manager.buildAssemblyDocument" id="buildDoc"><value name="Structure"><block type="variables_get" id="getStructure"><field name="VAR" id="structure">structure</field></block></value></block></value></block></value><next><block type="variables_set" id="setExportedDoc"><field name="VAR" id="exportedDoc">exportedDoc</field><value name="VALUE"><block type="bitbybit.occt.assembly.manager.exportDocumentToStep" id="exportStep"><value name="Document"><block type="variables_get" id="getDocument"><field name="VAR" id="document">document</field></block></value><value name="FileName"><block type="text" id="fileName"><field name="TEXT">pods.stpZ</field></block></value><value name="Author"><block type="text" id="author"><field name="TEXT">Bitbybit user</field></block></value><value name="Organization"><block type="text" id="organization"><field name="TEXT">Bitbybit</field></block></value><value name="Compress"><block type="logic_boolean" id="compress"><field name="BOOL">TRUE</field></block></value><value name="TryDownload"><block type="logic_boolean" id="tryDownload"><field name="BOOL">TRUE</field></block></value></block></value></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></xml>
// Import required DTOs for scene setup and OCCT operations
const { SceneTwoColorRadialGradientDto, DirectionalLightDto, SkyboxDto } = Bit.Inputs.BabylonScene;
const { PolygonDto, ShapeDto, FaceFromWireDto, FaceFromWiresDto, OffsetDto, FilletDto, SewDto, MirrorAlongNormalDto,
ThisckSolidSimpleDto, CreateAssemblyPartDto, CreateAssemblyNodeDto, CreateInstanceNodeDto,
CombineAssemblyStructureDto, BuildAssemblyDocumentDto, ExportDocumentToStepDto } = Bit.Inputs.OCCT;
const { DrawOcctShapeMaterialOptions } = Bit.Inputs.Draw;
const { PBRMetallicRoughnessDto } = Bit.Inputs.BabylonMaterial;
const { gradientPositionEnum, gradientShapeEnum, skyboxEnum } = Bit.Inputs.Base;
// Type definitions
type Point3 = Bit.Inputs.Base.Point3;
type Vector3 = Bit.Inputs.Base.Vector3;
type TopoDSShapePointer = Bit.Inputs.OCCT.TopoDSShapePointer;
type TopoDSWirePointer = Bit.Inputs.OCCT.TopoDSWirePointer;
type TopoDSFacePointer = Bit.Inputs.OCCT.TopoDSFacePointer;
type TDocStdDocumentPointer = Bit.Inputs.OCCT.TDocStdDocumentPointer;
// Get access to OCCT modules
const { wire, face, shell } = bitbybit.occt.shapes;
const { operations, transforms, fillets, assembly } = bitbybit.occt;
const { manager } = assembly;
const { scene, material } = bitbybit.babylon;
const start = async () => {
// Setup directional light
const dirLightOpt = new DirectionalLightDto();
dirLightOpt.direction = [-20, -20, -20] as Vector3;
dirLightOpt.intensity = 3;
dirLightOpt.shadowGeneratorMapSize = 2056;
dirLightOpt.enableShadows = true;
dirLightOpt.shadowBias = 0.001;
dirLightOpt.shadowNormalBias = 0.02;
scene.drawDirectionalLight(dirLightOpt);
// Setup radial gradient background
const bgOpt = new SceneTwoColorRadialGradientDto();
bgOpt.colorFrom = "#8194b1";
bgOpt.colorTo = "#1c1e21";
bgOpt.position = gradientPositionEnum.center;
bgOpt.shape = gradientShapeEnum.circle;
scene.twoColorRadialGradientBackground(bgOpt);
// Enable skybox (hidden but provides environment lighting)
const skyboxOpt = new SkyboxDto();
skyboxOpt.skybox = skyboxEnum.city;
skyboxOpt.size = 1000;
skyboxOpt.blur = 0.1;
skyboxOpt.environmentIntensity = 0.7;
skyboxOpt.hideSkybox = true;
scene.enableSkybox(skyboxOpt);
// Define the 4 key points for the pod shell geometry
const pt1: Point3 = [15, 0, 0];
const pt2: Point3 = [0, 6, 0];
const pt3: Point3 = [-3, 1, 6];
const pt4: Point3 = [-12, 2.45, 0];
const pt5: Point3 = [3, -2, 0];
// Create polygon wire 1 (pt1, pt2, pt3)
const poly1Opt = new PolygonDto();
poly1Opt.points = [pt1, pt2, pt3];
const polygonWire1 = await wire.createPolygonWire(poly1Opt);
// Create polygon wire 2 (pt4, pt3, pt2)
const poly2Opt = new PolygonDto();
poly2Opt.points = [pt4, pt3, pt2];
const polygonWire2 = await wire.createPolygonWire(poly2Opt);
// Create face 1 from polygonWire2
const face1Opt = new FaceFromWireDto<TopoDSWirePointer>();
face1Opt.shape = polygonWire2;
face1Opt.planar = true;
const face1 = await face.createFaceFromWire(face1Opt);
// Create polygon wire 3 (pt3, pt4, pt5)
const poly3Opt = new PolygonDto();
poly3Opt.points = [pt3, pt4, pt5];
const polygonWire3 = await wire.createPolygonWire(poly3Opt);
// Create face 2 from polygonWire3
const face2Opt = new FaceFromWireDto<TopoDSWirePointer>();
face2Opt.shape = polygonWire3;
face2Opt.planar = true;
const face2 = await face.createFaceFromWire(face2Opt);
// Create polygon wire 4 (pt1, pt3, pt5)
const poly4Opt = new PolygonDto();
poly4Opt.points = [pt1, pt3, pt5];
const polygonWire4 = await wire.createPolygonWire(poly4Opt);
// Create face 3 from polygonWire4
const face3Opt = new FaceFromWireDto<TopoDSWirePointer>();
face3Opt.shape = polygonWire4;
face3Opt.planar = true;
const face3 = await face.createFaceFromWire(face3Opt);
// Offset polygonWire1 to create inner wire for the hole
const offsetOpt = new OffsetDto<TopoDSWirePointer, TopoDSFacePointer>();
offsetOpt.shape = polygonWire1;
offsetOpt.distance = -0.6;
offsetOpt.tolerance = 0.0001;
const offsetWire = await operations.offset(offsetOpt);
// Fillet the offset wire corners
const fillet2dOpt = new FilletDto<TopoDSWirePointer>();
fillet2dOpt.shape = offsetWire as TopoDSWirePointer;
fillet2dOpt.radius = 0.2;
const filletWire = await fillets.fillet2d(fillet2dOpt);
// Reverse the filleted wire for hole creation
const reverseOpt = new ShapeDto<TopoDSWirePointer>();
reverseOpt.shape = filletWire as TopoDSWirePointer;
const reversedWire = await wire.reversedWire(reverseOpt);
// Create face with hole from polygonWire1 (outer) and reversedWire (hole)
const faceWithHoleOpt = new FaceFromWiresDto<TopoDSWirePointer>();
faceWithHoleOpt.shapes = [polygonWire1, reversedWire];
faceWithHoleOpt.planar = true;
const faceWithHole = await face.createFaceFromWires(faceWithHoleOpt);
// Sew all faces into a shell
const sew1Opt = new SewDto<TopoDSFacePointer>();
sew1Opt.shapes = [faceWithHole, face1, face2, face3] as TopoDSFacePointer[];
sew1Opt.tolerance = 0.0000001;
const shell1 = await shell.sewFaces(sew1Opt);
// Mirror the shell along Z normal to create the other half
const mirrorOpt = new MirrorAlongNormalDto<TopoDSShapePointer>();
mirrorOpt.shape = shell1;
mirrorOpt.origin = [0, 0, 0];
mirrorOpt.normal = [0, 0, 1];
const mirroredShell = await transforms.mirrorAlongNormal(mirrorOpt);
// Sew both shells together
const sew2Opt = new SewDto<TopoDSShapePointer>();
sew2Opt.shapes = [shell1, mirroredShell];
sew2Opt.tolerance = 0.0000001;
const combinedShell = await shell.sewFaces(sew2Opt);
// Fillet edges of the combined shell
const filletEdgesOpt = new FilletDto<TopoDSShapePointer>();
filletEdgesOpt.shape = combinedShell;
filletEdgesOpt.radius = 0.1;
const filletedShell = await fillets.filletEdges(filletEdgesOpt);
// Make thick solid from the shell
const thickSolidOpt = new ThisckSolidSimpleDto<TopoDSShapePointer>();
thickSolidOpt.shape = filletedShell;
thickSolidOpt.offset = 0.2;
const thickSolid = await operations.makeThickSolidSimple(thickSolidOpt);
// Create PBR material for rendering
const pbrOpt = new PBRMetallicRoughnessDto();
pbrOpt.name = "Custom Material";
pbrOpt.baseColor = "#ff0000";
pbrOpt.emissiveColor = "#000000";
pbrOpt.metallic = 0.8;
pbrOpt.roughness = 0.8;
pbrOpt.alpha = 1;
pbrOpt.backFaceCulling = false;
pbrOpt.zOffset = 2;
const pbrMaterial = material.pbrMetallicRoughness.create(pbrOpt);
// Draw the shape with material
const drawOpt = new DrawOcctShapeMaterialOptions();
drawOpt.precision = 0.01;
drawOpt.drawEdges = true;
drawOpt.edgeColour = "#000000";
drawOpt.edgeWidth = 1;
drawOpt.faceMaterial = pbrMaterial;
await bitbybit.draw.drawAnyAsync({ entity: thickSolid, options: drawOpt });
// Create the pod part for the assembly
const podPartOpt = new CreateAssemblyPartDto<TopoDSShapePointer>();
podPartOpt.id = "pod-shell";
podPartOpt.shape = thickSolid;
podPartOpt.name = "Pod Shell";
podPartOpt.colorRgba = { r: 1, g: 0, b: 0, a: 1 };
const podPart = await manager.createPart(podPartOpt);
// Create assembly node
const assemblyNodeOpt = new CreateAssemblyNodeDto();
assemblyNodeOpt.id = "pod-assembly";
assemblyNodeOpt.name = "Pod Assembly";
assemblyNodeOpt.parentId = "";
assemblyNodeOpt.colorRgba = { r: 1, g: 0, b: 0, a: 1 };
const assemblyNode = await manager.createAssemblyNode(assemblyNodeOpt);
// Create instance node with white color
const instanceNodeOpt = new CreateInstanceNodeDto();
instanceNodeOpt.id = "pod-instance";
instanceNodeOpt.partId = "pod-shell";
instanceNodeOpt.name = "pod";
instanceNodeOpt.parentId = "pod-assembly";
instanceNodeOpt.translation = [0, 0, 0];
instanceNodeOpt.rotation = [0, 0, 0];
instanceNodeOpt.scale = 1;
instanceNodeOpt.colorRgba = { r: 1, g: 0, b: 0, a: 1 };
const instanceNode = await manager.createInstanceNode(instanceNodeOpt);
// Combine parts and nodes into structure
const partsList = [podPart];
const nodesList = [assemblyNode, instanceNode];
const combineOpt = new CombineAssemblyStructureDto();
combineOpt.parts = partsList;
combineOpt.nodes = nodesList;
combineOpt.removals = [];
combineOpt.partUpdates = [];
combineOpt.clearDocument = false;
const structure = await manager.combineStructure(combineOpt);
// Build assembly document
const buildDocOpt = new BuildAssemblyDocumentDto<TopoDSShapePointer, TDocStdDocumentPointer>();
buildDocOpt.structure = structure;
const document = await manager.buildAssemblyDocument(buildDocOpt);
// Export to STEP file with color preserved
const exportOpt = new ExportDocumentToStepDto<TDocStdDocumentPointer>();
exportOpt.document = document;
exportOpt.fileName = "pods.stpZ";
exportOpt.author = "Bitbybit user";
exportOpt.organization = "Bitbybit";
exportOpt.compress = true;
exportOpt.tryDownload = true;
await manager.exportDocumentToStep(exportOpt);
}
start();



