Build a drone: payload and sliders
The last parts hang under the frame: a camera on its gimbal and the battery in its straps, placed where they belong without any module. Then the sliders show what the graph was built for.
-
The payload hangs under the frame: a camera on its gimbal at the front, and the battery in two straps. Shapes made of a few primitives are nodes: the camera is a box with its edges rounded joined with a cylinder for the barrel, the battery a rounded box, the lens a glass cylinder. The gimbal's bracket is a profile of six points and the straps a pair placed by a loop, so those two are code components.
-
Add typescript editor as gimbal: hidden, with the code below.
-
Add box as camera box: width 24, length 20, height 18, center [0, -26, 55], hidden.
-
Add fillet edges as camera body: radius 3, hidden.
-
Wire camera box › result into camera body › shape.
-
Add cylinder as lens barrel: radius 6.5, height 9, center [0, -26, 63], direction [0, 0, 1], hidden.
-
Add create list as camera parts.
-
Wire camera body › result into camera parts › listElements.
-
Wire lens barrel › result into camera parts › listElements.
-
Add union as camera: hidden.
-
Wire camera parts › list into camera › shapes.
-
Add cylinder as lens: radius 5.2, height 1.5, center [0, -26, 71.5], direction [0, 0, 1], hidden.
-
Add box as battery box: width 36, length 72, height 26, center [0, -16, -20], hidden.
-
Add fillet edges as battery: radius 3, hidden.
-
Wire battery box › result into battery › shape.
-
Add typescript editor as straps: hidden, with the code below.
-
Wire gimbal › result into aluminium › entity.
-
Wire camera › result into polymer › entity.
-
Wire battery › result into polymer › entity.
-
Wire straps › result into accent › entity.
-
Add pbr metallic roughness as glass material: name glass, base color #0c1522, metallic 0.1, roughness 0.05, z offset 2, in the Materials group.
-
Add options occt shape as glass look: precision 0.05, draw two sided off, edge colour #f2f2f2, edge width 4, in the Materials group.
-
Wire glass material › result into glass look › faceMaterial.
-
Add draw any async as glass in the Materials group.
-
Wire glass look › result into glass › options.
-
Wire lens › result into glass › entity.
-
Press Add a comment, double-click the comment and write:
Payload
A camera on a gimbal at the front and the battery in two straps underneath, placed directly without modules.
-
Select the comment, gimbal, camera box, camera body, lens barrel, camera parts, camera, lens, battery box, battery and straps, press Group selected components and title the group Payload.
const start = async (inputs: any, index: number) => {const outline = await bitbybit.occt.shapes.wire.createPolygonWire({ points: [[-4, 19, -4], [19.5, 19, -4], [19.5, -7, -4], [14.5, -7, -4], [14.5, 15, -4], [-4, 15, -4]] });const rounded = await bitbybit.occt.fillets.fillet2d({ shape: outline, radius: 1.5 });const face = await bitbybit.occt.shapes.face.createFaceFromWire({ shape: rounded, planar: true });const bracket = await bitbybit.occt.operations.extrude({ shape: face, direction: [0, 0, 8] });const yaw = await bitbybit.occt.shapes.solid.createCylinder({ radius: 9, height: 8, center: [0, 18, 0], direction: [0, 1, 0] });const roll = await bitbybit.occt.shapes.solid.createCylinder({ radius: 6, height: 5, center: [14.5, 0, 0], direction: [-1, 0, 0] });const gimbal = await bitbybit.occt.booleans.union({ shapes: [yaw, bracket, roll], keepEdges: false });return bitbybit.occt.transforms.translate({ shape: gimbal, translation: [0, -26, 55] });}const start = async (inputs: any, index: number) => {const outer = await bitbybit.occt.shapes.solid.createBox({ width: 40, length: 10, height: 30, center: [0, 0, 0] });const inner = await bitbybit.occt.shapes.solid.createBox({ width: 36.5, length: 12, height: 26.5, center: [0, 0, 0] });const strap = await bitbybit.occt.booleans.difference({ shape: outer, shapes: [inner], keepEdges: false });const pair = [];for (const z of [-42, 2]) {pair.push(await bitbybit.occt.transforms.translate({ shape: strap, translation: [0, -16, z] }));}return bitbybit.occt.shapes.compound.makeCompound({ shapes: pair });}
-
-
Move the sliders: six arms rebuild the drone, every Around follows the arms slider, and the propeller shrinks to fit between its neighbours.
- On arms, number 6.

The finished drone
The script the chapters build, to run here:
{
"id": "rete-v2-json",
"nodes": {
"f76ccf6f72f1c500": {
"id": "f76ccf6f72f1c500",
"name": "bitbybit.groups.group",
"customName": "Sizes",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 1547,
"groupHeight": 1024,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
0,
0
]
},
"6ba3682774530749": {
"id": "6ba3682774530749",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Sizes\nThree sliders drive the whole drone: **arms**, **arm length** and **propeller** diameter, in millimetres. Arms come in steps of two, so the propellers can alternate their spin. *fit propeller* keeps the propeller clear of its neighbours and the canopy.",
"commentWidth": 440,
"commentHeight": 202,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
24,
64
],
"parent": "f76ccf6f72f1c500"
},
"3cd26cf2e0f4e288": {
"id": "3cd26cf2e0f4e288",
"name": "bitbybit.math.numberSlider",
"customName": "arms",
"async": false,
"drawable": false,
"data": {
"options": {
"min": 4,
"max": 8,
"step": 2
},
"number": 4
},
"inputs": {},
"position": [
24,
290
],
"parent": "f76ccf6f72f1c500"
},
"7bb8bdd6a9a62983": {
"id": "7bb8bdd6a9a62983",
"name": "bitbybit.math.numberSlider",
"customName": "arm length",
"async": false,
"drawable": false,
"data": {
"options": {
"min": 120,
"max": 260,
"step": 5
},
"number": 185
},
"inputs": {},
"position": [
24,
449
],
"parent": "f76ccf6f72f1c500"
},
"c8c1604a5ea31f67": {
"id": "c8c1604a5ea31f67",
"name": "bitbybit.math.numberSlider",
"customName": "propeller",
"async": false,
"drawable": false,
"data": {
"options": {
"min": 100,
"max": 300,
"step": 5
},
"number": 230
},
"inputs": {},
"position": [
24,
608
],
"parent": "f76ccf6f72f1c500"
},
"06abdff8fb0917f0": {
"id": "06abdff8fb0917f0",
"name": "bitbybit.lists.createList",
"customName": "sizes",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "3cd26cf2e0f4e288",
"output": "result",
"data": {}
},
{
"node": "7bb8bdd6a9a62983",
"output": "result",
"data": {}
},
{
"node": "c8c1604a5ea31f67",
"output": "result",
"data": {}
}
]
}
},
"position": [
614,
64
],
"parent": "f76ccf6f72f1c500"
},
"99812753de6947a6": {
"id": "99812753de6947a6",
"name": "bitbybit.code.typeScriptEditor",
"customName": "fit propeller",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const start99812753de6947a6 = async (inputs: any, index: number) => {\n const [arms, length, diameter] = inputs;\n const neighbours = 2 * length * Math.sin(Math.PI / arms) - 10;\n const canopy = 2 * (length - 68);\n const largest = Math.floor(Math.min(neighbours, canopy) / 5) * 5;\n return Math.min(diameter, largest);\n}"
}
},
"inputs": {
"inputs": {
"connections": [
{
"node": "06abdff8fb0917f0",
"output": "list",
"data": {}
}
]
}
},
"position": [
949,
64
],
"parent": "f76ccf6f72f1c500"
},
"86a4136a3e0d72d3": {
"id": "86a4136a3e0d72d3",
"name": "bitbybit.groups.group",
"customName": "Scene",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 1520,
"groupHeight": 1025,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
0,
1144
]
},
"896027381380ee34": {
"id": "896027381380ee34",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Scene\nA dark background, a city environment the metal reflects, a sun that casts shadows, and a camera that starts outside the drone.",
"commentWidth": 440,
"commentHeight": 158,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
24,
1208
],
"parent": "86a4136a3e0d72d3"
},
"8c2a3ea8e5d031bc": {
"id": "8c2a3ea8e5d031bc",
"name": "bitbybit.babylon.scene.backgroundColour",
"customName": "background",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"colour": "#15171a"
},
"inputs": {},
"position": [
24,
1390
],
"parent": "86a4136a3e0d72d3"
},
"5cc8e7031e1f747b": {
"id": "5cc8e7031e1f747b",
"name": "bitbybit.babylon.scene.enableSkybox",
"customName": "environment",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"skybox": "city",
"size": 1000,
"blur": 0.1,
"environmentIntensity": 0.4,
"hideSkybox": true,
"enableGroundProjection": false,
"projectedGroundRadius": 20,
"projectedGroundHeight": 3
},
"inputs": {},
"position": [
24,
1647
],
"parent": "86a4136a3e0d72d3"
},
"57b123938bee2151": {
"id": "57b123938bee2151",
"name": "bitbybit.babylon.scene.drawDirectionalLight",
"customName": "sun",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"direction": [
-0.45,
-1,
-0.3
],
"intensity": 2,
"diffuse": "#ffffff",
"specular": "#ffffff",
"shadowGeneratorMapSize": 4096,
"enableShadows": true,
"shadowDarkness": 0,
"shadowUsePercentageCloserFiltering": true,
"transparencyShadow": false,
"shadowContactHardeningLightSizeUVRatio": 0.2,
"shadowBias": 0.0003,
"shadowNormalBias": 1,
"shadowMaxZ": 1000,
"shadowMinZ": -1000,
"shadowRefreshRate": 1
},
"inputs": {},
"position": [
584,
1208
],
"parent": "86a4136a3e0d72d3"
},
"1be2dac4430fdf4b": {
"id": "1be2dac4430fdf4b",
"name": "bitbybit.babylon.scene.adjustActiveArcRotateCamera",
"customName": "view",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"position": [
620,
380,
760
],
"lookAt": [
0,
-20,
0
],
"lowerBetaLimit": 1,
"upperBetaLimit": 179,
"angularSensibilityX": 1000,
"angularSensibilityY": 1000,
"maxZ": 20000,
"panningSensibility": 2,
"wheelPrecision": 3
},
"inputs": {},
"position": [
1175,
1208
],
"parent": "86a4136a3e0d72d3"
},
"4f296fff2bf2d8ce": {
"id": "4f296fff2bf2d8ce",
"name": "bitbybit.groups.group",
"customName": "Materials",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 4471,
"groupHeight": 4510,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
9054,
0
]
},
"756588cfe9804dd8": {
"id": "756588cfe9804dd8",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Materials\nEach material is physically based: a colour, how metallic and how rough. It sits a little behind its edges, so the edges drawn over it stay sharp: white on dark materials, black on light ones. Parts from anywhere in the graph can share a draw.",
"commentWidth": 440,
"commentHeight": 202,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
9078,
64
],
"parent": "4f296fff2bf2d8ce"
},
"e015aa341890c1fd": {
"id": "e015aa341890c1fd",
"name": "bitbybit.groups.group",
"customName": "Frame plate",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 4209,
"groupHeight": 1358,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
2863,
0
]
},
"3c80bf287a00931c": {
"id": "3c80bf287a00931c",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Frame plate\nOne carbon plate, 3 mm thick with rounded corners. Hexagon vents front and back and four leg openings are cut out of it; the top plate is the same shape, 13 mm higher.",
"commentWidth": 440,
"commentHeight": 180,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
2887,
64
],
"parent": "e015aa341890c1fd"
},
"e0082fb411145b8c": {
"id": "e0082fb411145b8c",
"name": "bitbybit.occt.shapes.wire.createRectangleWire",
"customName": "plate rectangle",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"width": 96,
"length": 150,
"center": [
0,
0,
0
],
"direction": [
0,
1,
0
]
},
"inputs": {},
"position": [
2887,
268
],
"parent": "e015aa341890c1fd"
},
"2204d6db1c6c12b3": {
"id": "2204d6db1c6c12b3",
"name": "bitbybit.occt.fillets.fillet2d",
"customName": "plate outline",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 26
},
"inputs": {
"shape": {
"connections": [
{
"node": "e0082fb411145b8c",
"output": "result",
"data": {}
}
]
}
},
"position": [
3447,
64
],
"parent": "e015aa341890c1fd"
},
"5e4bce83059bd0b0": {
"id": "5e4bce83059bd0b0",
"name": "bitbybit.occt.shapes.face.createFaceFromWire",
"customName": "plate face",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"planar": true
},
"inputs": {
"shape": {
"connections": [
{
"node": "2204d6db1c6c12b3",
"output": "result",
"data": {}
}
]
}
},
"position": [
3899,
64
],
"parent": "e015aa341890c1fd"
},
"28a406c9f210d81e": {
"id": "28a406c9f210d81e",
"name": "bitbybit.occt.operations.extrude",
"customName": "plate slab",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"direction": [
0,
3,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "5e4bce83059bd0b0",
"output": "result",
"data": {}
}
]
}
},
"position": [
4350,
64
],
"parent": "e015aa341890c1fd"
},
"66de8267ba8fbe1a": {
"id": "66de8267ba8fbe1a",
"name": "bitbybit.math.number",
"customName": "hex wall",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"number": 0.8
},
"inputs": {},
"position": [
2887,
638
],
"parent": "e015aa341890c1fd"
},
"9a88a2df56621fb0": {
"id": "9a88a2df56621fb0",
"name": "bitbybit.lists.createList",
"customName": "scale pattern",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "66de8267ba8fbe1a",
"output": "result",
"data": {}
}
]
}
},
"position": [
3447,
443
],
"parent": "e015aa341890c1fd"
},
"c8e108529875bf50": {
"id": "c8e108529875bf50",
"name": "bitbybit.occt.shapes.wire.hexagonsInGrid",
"customName": "vent hexagons",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"width": 56,
"height": 20,
"nrHexagonsInWidth": 5,
"nrHexagonsInHeight": 2,
"flatTop": true,
"extendTop": false,
"extendBottom": false,
"extendLeft": false,
"extendRight": false
},
"inputs": {
"scalePatternWidth": {
"connections": [
{
"node": "9a88a2df56621fb0",
"output": "list",
"data": {}
}
]
},
"scalePatternHeight": {
"connections": [
{
"node": "9a88a2df56621fb0",
"output": "list",
"data": {}
}
]
}
},
"position": [
3899,
366
],
"parent": "e015aa341890c1fd"
},
"a29d3ac1b71bebf4": {
"id": "a29d3ac1b71bebf4",
"name": "bitbybit.occt.shapes.face.createFacesFromWires",
"customName": "vent faces",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"planar": true
},
"inputs": {
"shapes": {
"connections": [
{
"node": "c8e108529875bf50",
"output": "result",
"data": {}
}
]
}
},
"position": [
4350,
363
],
"parent": "e015aa341890c1fd"
},
"3ec3347868a9af67": {
"id": "3ec3347868a9af67",
"name": "bitbybit.occt.operations.extrudeShapes",
"customName": "vent prisms",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"direction": [
0,
3,
0
]
},
"inputs": {
"shapes": {
"connections": [
{
"node": "a29d3ac1b71bebf4",
"output": "result",
"data": {}
}
]
}
},
"position": [
4770,
64
],
"parent": "e015aa341890c1fd"
},
"3b92125c4401411d": {
"id": "3b92125c4401411d",
"name": "bitbybit.occt.shapes.compound.makeCompound",
"customName": "vent set",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"shapes": {
"connections": [
{
"node": "3ec3347868a9af67",
"output": "result",
"data": {}
}
]
}
},
"position": [
5190,
64
],
"parent": "e015aa341890c1fd"
},
"1fea786243392cd2": {
"id": "1fea786243392cd2",
"name": "bitbybit.occt.transforms.translate",
"customName": "front vents",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"translation": [
0,
0,
60
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "3b92125c4401411d",
"output": "result",
"data": {}
}
]
}
},
"position": [
5576,
64
],
"parent": "e015aa341890c1fd"
},
"e58dc236f6df345a": {
"id": "e58dc236f6df345a",
"name": "bitbybit.occt.transforms.translate",
"customName": "back vents",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"translation": [
0,
0,
-60
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "3b92125c4401411d",
"output": "result",
"data": {}
}
]
}
},
"position": [
5576,
363
],
"parent": "e015aa341890c1fd"
},
"03f2f29b432e2dbc": {
"id": "03f2f29b432e2dbc",
"name": "bitbybit.lists.createList",
"customName": "cut-outs",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "1fea786243392cd2",
"output": "result",
"data": {}
},
{
"node": "e58dc236f6df345a",
"output": "result",
"data": {}
},
{
"node": "5f9d636df6418035",
"output": "result",
"data": {}
}
]
}
},
"position": [
6008,
64
],
"parent": "e015aa341890c1fd"
},
"0bcaa7c9e52e0bb6": {
"id": "0bcaa7c9e52e0bb6",
"name": "bitbybit.occt.booleans.difference",
"customName": "plate",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"keepEdges": false,
"strategy": "oneAfterAnother"
},
"inputs": {
"shape": {
"connections": [
{
"node": "28a406c9f210d81e",
"output": "result",
"data": {}
}
]
},
"shapes": {
"connections": [
{
"node": "03f2f29b432e2dbc",
"output": "list",
"data": {}
}
]
}
},
"position": [
6368,
64
],
"parent": "e015aa341890c1fd"
},
"048fee24a1f882ed": {
"id": "048fee24a1f882ed",
"name": "bitbybit.occt.transforms.translate",
"customName": "top plate",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"translation": [
0,
13,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "0bcaa7c9e52e0bb6",
"output": "result",
"data": {}
}
]
}
},
"position": [
6736,
64
],
"parent": "e015aa341890c1fd"
},
"df692f6a4959f755": {
"id": "df692f6a4959f755",
"name": "bitbybit.babylon.material.pbrMetallicRoughness.create",
"customName": "carbon material",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"name": "carbon",
"baseColor": "#23262b",
"emissiveColor": "#000000",
"metallic": 0.35,
"roughness": 0.45,
"alpha": 1,
"backFaceCulling": false,
"zOffset": 2
},
"inputs": {},
"position": [
9078,
290
],
"parent": "4f296fff2bf2d8ce"
},
"ff3ab1cc8cfc5308": {
"id": "ff3ab1cc8cfc5308",
"name": "bitbybit.draw.optionsOcctShape",
"customName": "carbon look",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"faceOpacity": 1,
"edgeOpacity": 1,
"edgeColour": "#f2f2f2",
"faceColour": "#ff0000",
"vertexColour": "#ff00ff",
"edgeWidth": 6,
"vertexSize": 0.03,
"drawEdges": true,
"drawFaces": true,
"drawVertices": false,
"precision": 0.05,
"angularDeflection": 0.5,
"relativeDeflection": false,
"drawEdgeIndexes": false,
"edgeIndexHeight": 0.06,
"edgeIndexColour": "#ff00ff",
"drawFaceIndexes": false,
"faceIndexHeight": 0.06,
"faceIndexColour": "#0000ff",
"drawTwoSided": false,
"backFaceColour": "#0000ff",
"backFaceOpacity": 1,
"edgeArrowSize": 0,
"edgeArrowAngle": 15,
"keepMeshData": false,
"allowQualityDecrease": true,
"forceFaceDeflection": false,
"drawIsoCurves": false,
"isoCurvesU": 5,
"isoCurvesV": 5,
"isoCurvesColour": "#808080",
"surfaceAnalysis": "none",
"draftDirection": [
0,
1,
0
]
},
"inputs": {
"faceMaterial": {
"connections": [
{
"node": "df692f6a4959f755",
"output": "result",
"data": {}
}
]
}
},
"position": [
10065,
64
],
"parent": "4f296fff2bf2d8ce"
},
"70d7d035fc4b7ea2": {
"id": "70d7d035fc4b7ea2",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "carbon",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"options": {
"connections": [
{
"node": "ff3ab1cc8cfc5308",
"output": "result",
"data": {}
}
]
},
"entity": {
"connections": [
{
"node": "0bcaa7c9e52e0bb6",
"output": "result",
"data": {}
},
{
"node": "048fee24a1f882ed",
"output": "result",
"data": {}
},
{
"node": "e878ed854ab76b8f",
"output": "copies",
"data": {}
},
{
"node": "57edd2996cf03498",
"output": "copies",
"data": {}
}
]
}
},
"position": [
13236,
64
],
"parent": "4f296fff2bf2d8ce"
},
"3a2e66a525e10413": {
"id": "3a2e66a525e10413",
"name": "bitbybit.groups.group",
"customName": "Modules",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 488,
"groupHeight": 448,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
0,
2289
]
},
"1f1f1c449648adfb": {
"id": "1f1f1c449648adfb",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Modules\nA module is a graph used many times. Double-click one to go inside; every instance of it changes with it.",
"commentWidth": 440,
"commentHeight": 158,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
24,
2353
],
"parent": "3a2e66a525e10413"
},
"06bf028b1e8d35a4": {
"id": "06bf028b1e8d35a4",
"name": "bitbybit.modules.definition",
"customName": "Around",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_e07d2900372f77c7",
"moduleName": "Around"
},
"inputs": {},
"position": [
24,
2535
],
"parent": "3a2e66a525e10413"
},
"99af658df4b8c37a": {
"id": "99af658df4b8c37a",
"name": "bitbybit.math.number",
"customName": "legs",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"number": 4
},
"inputs": {},
"position": [
24,
767
],
"parent": "f76ccf6f72f1c500"
},
"6616c877a80ade55": {
"id": "6616c877a80ade55",
"name": "bitbybit.occt.shapes.solid.createCylinder",
"customName": "leg opening",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 6,
"height": 3,
"center": [
52,
0,
0
],
"direction": [
0,
1,
0
],
"angle": 360,
"originOnCenter": false
},
"inputs": {},
"position": [
2887,
895
],
"parent": "e015aa341890c1fd"
},
"ead6e5b69d9dca81": {
"id": "ead6e5b69d9dca81",
"name": "bitbybit.modules.module",
"customName": "leg openings around",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_e07d2900372f77c7",
"embedded": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "6616c877a80ade55",
"output": "result",
"data": {}
}
]
},
"count": {
"connections": [
{
"node": "99af658df4b8c37a",
"output": "result",
"data": {}
}
]
}
},
"position": [
3447,
602
],
"parent": "e015aa341890c1fd"
},
"5f9d636df6418035": {
"id": "5f9d636df6418035",
"name": "bitbybit.occt.shapes.compound.makeCompound",
"customName": "leg openings",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"shapes": {
"connections": [
{
"node": "ead6e5b69d9dca81",
"output": "copies",
"data": {}
}
]
}
},
"position": [
3899,
1096
],
"parent": "e015aa341890c1fd"
},
"1388335f1c0427d1": {
"id": "1388335f1c0427d1",
"name": "bitbybit.groups.group",
"customName": "M3 bolt",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 1182,
"groupHeight": 549,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
0,
2857
]
},
"e611f6c7f6446c0f": {
"id": "e611f6c7f6446c0f",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### M3 bolt\nA socket-head bolt from a code component: a profile revolved into its body, with a hexagon socket cut into the head. The standoffs and the legs use it.",
"commentWidth": 440,
"commentHeight": 158,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
24,
2921
],
"parent": "1388335f1c0427d1"
},
"035d49b79981fd13": {
"id": "035d49b79981fd13",
"name": "bitbybit.math.number",
"customName": "bolt length",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"number": 8
},
"inputs": {},
"position": [
24,
3103
],
"parent": "1388335f1c0427d1"
},
"2a9a6821b1fa56c6": {
"id": "2a9a6821b1fa56c6",
"name": "bitbybit.code.typeScriptEditor",
"customName": "M3 bolt",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const start2a9a6821b1fa56c6 = async (inputs: any, index: number) => {\n const length = inputs;\n const profile = [[0, -3, 0], [2.35, -3, 0], [2.75, -2.6, 0], [2.75, 0, 0], [1.5, 0, 0], [1.5, length - 0.4, 0], [1.1, length, 0], [0, length, 0]];\n const outline = await bitbybit.occt.shapes.wire.createPolygonWire({ points: profile });\n const face = await bitbybit.occt.shapes.face.createFaceFromWire({ shape: outline, planar: true });\n const body = await bitbybit.occt.operations.revolve({ shape: face, angle: 360, direction: [0, 1, 0], copy: false });\n const hexagon = await bitbybit.occt.shapes.wire.createNGonWire({ nrCorners: 6, radius: 1.45, center: [0, -3.5, 0], direction: [0, 1, 0] });\n const socketFace = await bitbybit.occt.shapes.face.createFaceFromWire({ shape: hexagon, planar: true });\n const socket = await bitbybit.occt.operations.extrude({ shape: socketFace, direction: [0, 2.5, 0] });\n return bitbybit.occt.booleans.difference({ shape: body, shapes: [socket], keepEdges: false });\n}"
}
},
"inputs": {
"inputs": {
"connections": [
{
"node": "035d49b79981fd13",
"output": "result",
"data": {}
}
]
}
},
"position": [
584,
2921
],
"parent": "1388335f1c0427d1"
},
"cdd3c18049d04f7e": {
"id": "cdd3c18049d04f7e",
"name": "bitbybit.groups.group",
"customName": "Standoffs",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 2817,
"groupHeight": 1835,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
2863,
1478
]
},
"0e65a40ccf39eefc": {
"id": "0e65a40ccf39eefc",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Standoffs\nPosts that hold the plates 10 mm apart, bolted from above and below. They stand between the arms, so they are turned back half a step before Around repeats them.",
"commentWidth": 440,
"commentHeight": 180,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
2887,
1542
],
"parent": "cdd3c18049d04f7e"
},
"1e3d1b707015a4ea": {
"id": "1e3d1b707015a4ea",
"name": "bitbybit.occt.shapes.solid.createCylinder",
"customName": "standoff",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 3.2,
"height": 10,
"center": [
40,
3,
0
],
"direction": [
0,
1,
0
],
"angle": 360,
"originOnCenter": false
},
"inputs": {},
"position": [
2887,
1746
],
"parent": "cdd3c18049d04f7e"
},
"16f243826b5eff97": {
"id": "16f243826b5eff97",
"name": "bitbybit.occt.transforms.translate",
"customName": "lower bolt",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"translation": [
40,
0,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "2a9a6821b1fa56c6",
"output": "result",
"data": {}
}
]
}
},
"position": [
2887,
2193
],
"parent": "cdd3c18049d04f7e"
},
"31e1cb6641690e8e": {
"id": "31e1cb6641690e8e",
"name": "bitbybit.occt.transforms.rotate",
"customName": "flipped bolt",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"axis": [
1,
0,
0
],
"angle": 180
},
"inputs": {
"shape": {
"connections": [
{
"node": "2a9a6821b1fa56c6",
"output": "result",
"data": {}
}
]
}
},
"position": [
2887,
2492
],
"parent": "cdd3c18049d04f7e"
},
"0e7705019e0edacb": {
"id": "0e7705019e0edacb",
"name": "bitbybit.occt.transforms.translate",
"customName": "upper bolt",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"translation": [
40,
16,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "31e1cb6641690e8e",
"output": "result",
"data": {}
}
]
}
},
"position": [
3581,
1542
],
"parent": "cdd3c18049d04f7e"
},
"0fbbf2ce0e9242db": {
"id": "0fbbf2ce0e9242db",
"name": "bitbybit.lists.createList",
"customName": "standoff bolts",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "16f243826b5eff97",
"output": "result",
"data": {}
},
{
"node": "0e7705019e0edacb",
"output": "result",
"data": {}
}
]
}
},
"position": [
4050,
1542
],
"parent": "cdd3c18049d04f7e"
},
"894cb1d3c0d66381": {
"id": "894cb1d3c0d66381",
"name": "bitbybit.occt.shapes.compound.makeCompound",
"customName": "bolt pair",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"shapes": {
"connections": [
{
"node": "0fbbf2ce0e9242db",
"output": "list",
"data": {}
}
]
}
},
"position": [
4477,
1542
],
"parent": "cdd3c18049d04f7e"
},
"83ce840d88109654": {
"id": "83ce840d88109654",
"name": "bitbybit.code.typeScriptEditor",
"customName": "half a step back",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const start83ce840d88109654 = async (inputs: any, index: number) => {\n return -180 / inputs;\n}"
}
},
"inputs": {
"inputs": {
"connections": [
{
"node": "3cd26cf2e0f4e288",
"output": "result",
"data": {}
}
]
}
},
"position": [
2887,
2828
],
"parent": "cdd3c18049d04f7e"
},
"53e7ef459c157e34": {
"id": "53e7ef459c157e34",
"name": "bitbybit.occt.transforms.rotate",
"customName": "standoff between arms",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"axis": [
0,
1,
0
],
"angle": 0
},
"inputs": {
"shape": {
"connections": [
{
"node": "1e3d1b707015a4ea",
"output": "result",
"data": {}
}
]
},
"angle": {
"connections": [
{
"node": "83ce840d88109654",
"output": "result",
"data": {}
}
]
}
},
"position": [
3581,
1841
],
"parent": "cdd3c18049d04f7e"
},
"81576187e7bf3283": {
"id": "81576187e7bf3283",
"name": "bitbybit.occt.transforms.rotate",
"customName": "bolts between arms",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"axis": [
0,
1,
0
],
"angle": 0
},
"inputs": {
"shape": {
"connections": [
{
"node": "894cb1d3c0d66381",
"output": "result",
"data": {}
}
]
},
"angle": {
"connections": [
{
"node": "83ce840d88109654",
"output": "result",
"data": {}
}
]
}
},
"position": [
4863,
1542
],
"parent": "cdd3c18049d04f7e"
},
"1e2ae0e5a87cbe40": {
"id": "1e2ae0e5a87cbe40",
"name": "bitbybit.modules.module",
"customName": "standoffs around",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_e07d2900372f77c7",
"embedded": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "53e7ef459c157e34",
"output": "result",
"data": {}
}
]
},
"count": {
"connections": [
{
"node": "3cd26cf2e0f4e288",
"output": "result",
"data": {}
}
]
}
},
"position": [
4050,
1701
],
"parent": "cdd3c18049d04f7e"
},
"e377ce47888c5b3e": {
"id": "e377ce47888c5b3e",
"name": "bitbybit.modules.module",
"customName": "standoff bolts around",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_e07d2900372f77c7",
"embedded": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "81576187e7bf3283",
"output": "result",
"data": {}
}
]
},
"count": {
"connections": [
{
"node": "3cd26cf2e0f4e288",
"output": "result",
"data": {}
}
]
}
},
"position": [
5307,
1542
],
"parent": "cdd3c18049d04f7e"
},
"871753d3056afe66": {
"id": "871753d3056afe66",
"name": "bitbybit.babylon.material.pbrMetallicRoughness.create",
"customName": "accent material",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"name": "accent",
"baseColor": "#f0cebb",
"emissiveColor": "#000000",
"metallic": 0.85,
"roughness": 0.35,
"alpha": 1,
"backFaceCulling": false,
"zOffset": 2
},
"inputs": {},
"position": [
9078,
809
],
"parent": "4f296fff2bf2d8ce"
},
"52b03e68dc7dc971": {
"id": "52b03e68dc7dc971",
"name": "bitbybit.draw.optionsOcctShape",
"customName": "accent look",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"faceOpacity": 1,
"edgeOpacity": 1,
"edgeColour": "#0d0e10",
"faceColour": "#ff0000",
"vertexColour": "#ff00ff",
"edgeWidth": 4,
"vertexSize": 0.03,
"drawEdges": true,
"drawFaces": true,
"drawVertices": false,
"precision": 0.05,
"angularDeflection": 0.5,
"relativeDeflection": false,
"drawEdgeIndexes": false,
"edgeIndexHeight": 0.06,
"edgeIndexColour": "#ff00ff",
"drawFaceIndexes": false,
"faceIndexHeight": 0.06,
"faceIndexColour": "#0000ff",
"drawTwoSided": false,
"backFaceColour": "#0000ff",
"backFaceOpacity": 1,
"edgeArrowSize": 0,
"edgeArrowAngle": 15,
"keepMeshData": false,
"allowQualityDecrease": true,
"forceFaceDeflection": false,
"drawIsoCurves": false,
"isoCurvesU": 5,
"isoCurvesV": 5,
"isoCurvesColour": "#808080",
"surfaceAnalysis": "none",
"draftDirection": [
0,
1,
0
]
},
"inputs": {
"faceMaterial": {
"connections": [
{
"node": "871753d3056afe66",
"output": "result",
"data": {}
}
]
}
},
"position": [
10065,
1689
],
"parent": "4f296fff2bf2d8ce"
},
"4866e77cf0ac75ea": {
"id": "4866e77cf0ac75ea",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "accent",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"options": {
"connections": [
{
"node": "52b03e68dc7dc971",
"output": "result",
"data": {}
}
]
},
"entity": {
"connections": [
{
"node": "1e2ae0e5a87cbe40",
"output": "copies",
"data": {}
},
{
"node": "5659c77ed2647d09",
"output": "result",
"data": {}
},
{
"node": "b561ea9c301029c7",
"output": "result",
"data": {}
}
]
}
},
"position": [
13236,
406
],
"parent": "4f296fff2bf2d8ce"
},
"9342d7f3c54ffee2": {
"id": "9342d7f3c54ffee2",
"name": "bitbybit.babylon.material.pbrMetallicRoughness.create",
"customName": "steel material",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"name": "steel",
"baseColor": "#1c1c1e",
"emissiveColor": "#000000",
"metallic": 0.9,
"roughness": 0.42,
"alpha": 1,
"backFaceCulling": false,
"zOffset": 2
},
"inputs": {},
"position": [
9078,
1328
],
"parent": "4f296fff2bf2d8ce"
},
"780844dd15319225": {
"id": "780844dd15319225",
"name": "bitbybit.draw.optionsOcctShape",
"customName": "steel look",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"faceOpacity": 1,
"edgeOpacity": 1,
"edgeColour": "#f2f2f2",
"faceColour": "#ff0000",
"vertexColour": "#ff00ff",
"edgeWidth": 4,
"vertexSize": 0.03,
"drawEdges": true,
"drawFaces": true,
"drawVertices": false,
"precision": 0.05,
"angularDeflection": 0.5,
"relativeDeflection": false,
"drawEdgeIndexes": false,
"edgeIndexHeight": 0.06,
"edgeIndexColour": "#ff00ff",
"drawFaceIndexes": false,
"faceIndexHeight": 0.06,
"faceIndexColour": "#0000ff",
"drawTwoSided": false,
"backFaceColour": "#0000ff",
"backFaceOpacity": 1,
"edgeArrowSize": 0,
"edgeArrowAngle": 15,
"keepMeshData": false,
"allowQualityDecrease": true,
"forceFaceDeflection": false,
"drawIsoCurves": false,
"isoCurvesU": 5,
"isoCurvesV": 5,
"isoCurvesColour": "#808080",
"surfaceAnalysis": "none",
"draftDirection": [
0,
1,
0
]
},
"inputs": {
"faceMaterial": {
"connections": [
{
"node": "9342d7f3c54ffee2",
"output": "result",
"data": {}
}
]
}
},
"position": [
10518,
64
],
"parent": "4f296fff2bf2d8ce"
},
"aa4e22479d6e01c0": {
"id": "aa4e22479d6e01c0",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "steel",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"options": {
"connections": [
{
"node": "780844dd15319225",
"output": "result",
"data": {}
}
]
},
"entity": {
"connections": [
{
"node": "e377ce47888c5b3e",
"output": "copies",
"data": {}
},
{
"node": "5007c40eac83b48c",
"output": "copies",
"data": {}
},
{
"node": "321cd1a9f9ccff35",
"output": "copies",
"data": {}
},
{
"node": "8c624beca6ae04f4",
"output": "copies",
"data": {}
}
]
}
},
"position": [
13236,
748
],
"parent": "4f296fff2bf2d8ce"
},
"8c628461fcd2ca1c": {
"id": "8c628461fcd2ca1c",
"name": "bitbybit.modules.definition",
"customName": "Arm",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_1b640754df2b28cd",
"moduleName": "Arm"
},
"inputs": {},
"position": [
24,
2636
],
"parent": "3a2e66a525e10413"
},
"fe5f89ce79a40a4d": {
"id": "fe5f89ce79a40a4d",
"name": "bitbybit.groups.group",
"customName": "Arms",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 898,
"groupHeight": 884,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
2863,
3433
]
},
"0166cd1d2ad2fbed": {
"id": "0166cd1d2ad2fbed",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Arms\nOne Arm instance makes an arm from the sliders. Around instances repeat each of its parts as many times as the arms slider says.",
"commentWidth": 440,
"commentHeight": 158,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
2887,
3497
],
"parent": "fe5f89ce79a40a4d"
},
"e8c03ef3f8c1f4f9": {
"id": "e8c03ef3f8c1f4f9",
"name": "bitbybit.modules.module",
"customName": "one arm",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_1b640754df2b28cd",
"embedded": false
},
"inputs": {
"length": {
"connections": [
{
"node": "7bb8bdd6a9a62983",
"output": "result",
"data": {}
}
]
},
"propeller": {
"connections": [
{
"node": "99812753de6947a6",
"output": "result",
"data": {}
}
]
}
},
"position": [
2887,
3679
],
"parent": "fe5f89ce79a40a4d"
},
"e878ed854ab76b8f": {
"id": "e878ed854ab76b8f",
"name": "bitbybit.modules.module",
"customName": "arms around",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_e07d2900372f77c7",
"embedded": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "e8c03ef3f8c1f4f9",
"output": "arm",
"data": {}
}
]
},
"count": {
"connections": [
{
"node": "3cd26cf2e0f4e288",
"output": "result",
"data": {}
}
]
}
},
"position": [
3447,
3497
],
"parent": "fe5f89ce79a40a4d"
},
"2610f2bcd35f6305": {
"id": "2610f2bcd35f6305",
"name": "bitbybit.modules.module",
"customName": "motors around",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_e07d2900372f77c7",
"embedded": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "e8c03ef3f8c1f4f9",
"output": "motor",
"data": {}
}
]
},
"count": {
"connections": [
{
"node": "3cd26cf2e0f4e288",
"output": "result",
"data": {}
}
]
}
},
"position": [
3447,
3702
],
"parent": "fe5f89ce79a40a4d"
},
"ca8884bdb218d13e": {
"id": "ca8884bdb218d13e",
"name": "bitbybit.modules.module",
"customName": "stators around",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_e07d2900372f77c7",
"embedded": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "e8c03ef3f8c1f4f9",
"output": "stator",
"data": {}
}
]
},
"count": {
"connections": [
{
"node": "3cd26cf2e0f4e288",
"output": "result",
"data": {}
}
]
}
},
"position": [
3447,
3907
],
"parent": "fe5f89ce79a40a4d"
},
"aa80d49bb0cf0e44": {
"id": "aa80d49bb0cf0e44",
"name": "bitbybit.babylon.material.pbrMetallicRoughness.create",
"customName": "aluminium material",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"name": "aluminium",
"baseColor": "#b9bec6",
"emissiveColor": "#000000",
"metallic": 1,
"roughness": 0.32,
"alpha": 1,
"backFaceCulling": false,
"zOffset": 2
},
"inputs": {},
"position": [
9078,
1847
],
"parent": "4f296fff2bf2d8ce"
},
"5551b2bf06fafe82": {
"id": "5551b2bf06fafe82",
"name": "bitbybit.draw.optionsOcctShape",
"customName": "aluminium look",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"faceOpacity": 1,
"edgeOpacity": 1,
"edgeColour": "#0d0e10",
"faceColour": "#ff0000",
"vertexColour": "#ff00ff",
"edgeWidth": 4,
"vertexSize": 0.03,
"drawEdges": true,
"drawFaces": true,
"drawVertices": false,
"precision": 0.05,
"angularDeflection": 0.5,
"relativeDeflection": false,
"drawEdgeIndexes": false,
"edgeIndexHeight": 0.06,
"edgeIndexColour": "#ff00ff",
"drawFaceIndexes": false,
"faceIndexHeight": 0.06,
"faceIndexColour": "#0000ff",
"drawTwoSided": false,
"backFaceColour": "#0000ff",
"backFaceOpacity": 1,
"edgeArrowSize": 0,
"edgeArrowAngle": 15,
"keepMeshData": false,
"allowQualityDecrease": true,
"forceFaceDeflection": false,
"drawIsoCurves": false,
"isoCurvesU": 5,
"isoCurvesV": 5,
"isoCurvesColour": "#808080",
"surfaceAnalysis": "none",
"draftDirection": [
0,
1,
0
]
},
"inputs": {
"faceMaterial": {
"connections": [
{
"node": "aa80d49bb0cf0e44",
"output": "result",
"data": {}
}
]
}
},
"position": [
10518,
1689
],
"parent": "4f296fff2bf2d8ce"
},
"b33f88c76a8018cd": {
"id": "b33f88c76a8018cd",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "aluminium",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"options": {
"connections": [
{
"node": "5551b2bf06fafe82",
"output": "result",
"data": {}
}
]
},
"entity": {
"connections": [
{
"node": "2610f2bcd35f6305",
"output": "copies",
"data": {}
},
{
"node": "58c458a3a5c243de",
"output": "copies",
"data": {}
},
{
"node": "bce1e79ac1754448",
"output": "result",
"data": {}
}
]
}
},
"position": [
13236,
1090
],
"parent": "4f296fff2bf2d8ce"
},
"5ca4c2ced641b2d9": {
"id": "5ca4c2ced641b2d9",
"name": "bitbybit.babylon.material.pbrMetallicRoughness.create",
"customName": "copper material",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"name": "copper",
"baseColor": "#b87333",
"emissiveColor": "#000000",
"metallic": 1,
"roughness": 0.5,
"alpha": 1,
"backFaceCulling": false,
"zOffset": 2
},
"inputs": {},
"position": [
9078,
2366
],
"parent": "4f296fff2bf2d8ce"
},
"eecfd8525a75e0ca": {
"id": "eecfd8525a75e0ca",
"name": "bitbybit.draw.optionsOcctShape",
"customName": "copper look",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"faceOpacity": 1,
"edgeOpacity": 1,
"edgeColour": "#0d0e10",
"faceColour": "#ff0000",
"vertexColour": "#ff00ff",
"edgeWidth": 4,
"vertexSize": 0.03,
"drawEdges": true,
"drawFaces": true,
"drawVertices": false,
"precision": 0.05,
"angularDeflection": 0.5,
"relativeDeflection": false,
"drawEdgeIndexes": false,
"edgeIndexHeight": 0.06,
"edgeIndexColour": "#ff00ff",
"drawFaceIndexes": false,
"faceIndexHeight": 0.06,
"faceIndexColour": "#0000ff",
"drawTwoSided": false,
"backFaceColour": "#0000ff",
"backFaceOpacity": 1,
"edgeArrowSize": 0,
"edgeArrowAngle": 15,
"keepMeshData": false,
"allowQualityDecrease": true,
"forceFaceDeflection": false,
"drawIsoCurves": false,
"isoCurvesU": 5,
"isoCurvesV": 5,
"isoCurvesColour": "#808080",
"surfaceAnalysis": "none",
"draftDirection": [
0,
1,
0
]
},
"inputs": {
"faceMaterial": {
"connections": [
{
"node": "5ca4c2ced641b2d9",
"output": "result",
"data": {}
}
]
}
},
"position": [
10971,
64
],
"parent": "4f296fff2bf2d8ce"
},
"cc9cca5f8a4a17e2": {
"id": "cc9cca5f8a4a17e2",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "copper",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"options": {
"connections": [
{
"node": "eecfd8525a75e0ca",
"output": "result",
"data": {}
}
]
},
"entity": {
"connections": [
{
"node": "ca8884bdb218d13e",
"output": "copies",
"data": {}
}
]
}
},
"position": [
13236,
1432
],
"parent": "4f296fff2bf2d8ce"
},
"29337403c546a27d": {
"id": "29337403c546a27d",
"name": "bitbybit.groups.group",
"customName": "Spin",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 1182,
"groupHeight": 549,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
7472,
0
]
},
"80a5d0bdd318f4f5": {
"id": "80a5d0bdd318f4f5",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Spin\nNeighbouring propellers turn opposite ways, so the drone does not spin. Every second propeller is mirrored across its own arm, and each is turned a little, so the blades do not all line up.",
"commentWidth": 440,
"commentHeight": 180,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
7496,
64
],
"parent": "29337403c546a27d"
},
"58d318c35993476f": {
"id": "58d318c35993476f",
"name": "bitbybit.modules.module",
"customName": "propellers around",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_e07d2900372f77c7",
"embedded": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "e8c03ef3f8c1f4f9",
"output": "propeller",
"data": {}
}
]
},
"count": {
"connections": [
{
"node": "3cd26cf2e0f4e288",
"output": "result",
"data": {}
}
]
}
},
"position": [
7496,
268
],
"parent": "29337403c546a27d"
},
"5659c77ed2647d09": {
"id": "5659c77ed2647d09",
"name": "bitbybit.code.typeScriptEditor",
"customName": "alternate spin",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const start5659c77ed2647d09 = async (inputs: any, index: number) => {\n const propellers = inputs;\n const count = propellers.length;\n const spun = [];\n for (const [i, propeller] of propellers.entries()) {\n const angle = (i + 0.5) * 360 / count * Math.PI / 180;\n const centre = (await bitbybit.occt.analysis.measure.tightBoundingBox({ shape: propeller })).center;\n const turned = await bitbybit.occt.transforms.rotateAroundCenter({ shape: propeller, angle: i * 37, center: [centre[0], 0, centre[2]], axis: [0, 1, 0] });\n spun.push(i % 2 === 0 ? turned : await bitbybit.occt.transforms.mirrorAlongNormal({ shape: turned, origin: [0, 0, 0], normal: [Math.sin(angle), 0, Math.cos(angle)] }));\n }\n return spun;\n}"
}
},
"inputs": {
"inputs": {
"connections": [
{
"node": "58d318c35993476f",
"output": "copies",
"data": {}
}
]
}
},
"position": [
8056,
64
],
"parent": "29337403c546a27d"
},
"273c5f46c3e6ca82": {
"id": "273c5f46c3e6ca82",
"name": "bitbybit.groups.group",
"customName": "Lights",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 1182,
"groupHeight": 1034,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
7472,
669
]
},
"d311009995692ff2": {
"id": "d311009995692ff2",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Lights\nGreen at the front, red at the back, as on an aircraft: two code components sort the lights by the side they are on.",
"commentWidth": 440,
"commentHeight": 158,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
7496,
733
],
"parent": "273c5f46c3e6ca82"
},
"5007c40eac83b48c": {
"id": "5007c40eac83b48c",
"name": "bitbybit.modules.module",
"customName": "bolts around",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_e07d2900372f77c7",
"embedded": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "e8c03ef3f8c1f4f9",
"output": "bolts",
"data": {}
}
]
},
"count": {
"connections": [
{
"node": "3cd26cf2e0f4e288",
"output": "result",
"data": {}
}
]
}
},
"position": [
3447,
4112
],
"parent": "fe5f89ce79a40a4d"
},
"514ed3857482d37a": {
"id": "514ed3857482d37a",
"name": "bitbybit.modules.module",
"customName": "lights around",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_e07d2900372f77c7",
"embedded": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "e8c03ef3f8c1f4f9",
"output": "light",
"data": {}
}
]
},
"count": {
"connections": [
{
"node": "3cd26cf2e0f4e288",
"output": "result",
"data": {}
}
]
}
},
"position": [
7496,
915
],
"parent": "273c5f46c3e6ca82"
},
"d188faf10f534fc8": {
"id": "d188faf10f534fc8",
"name": "bitbybit.code.typeScriptEditor",
"customName": "front lights",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const startd188faf10f534fc8 = async (inputs: any, index: number) => {\n const lights = [];\n for (const light of inputs) {\n const centre = (await bitbybit.occt.analysis.measure.tightBoundingBox({ shape: light })).center;\n if (centre[2] > 0) {\n lights.push(light);\n }\n }\n return lights;\n}"
}
},
"inputs": {
"inputs": {
"connections": [
{
"node": "514ed3857482d37a",
"output": "copies",
"data": {}
}
]
}
},
"position": [
8056,
733
],
"parent": "273c5f46c3e6ca82"
},
"a7fd811b4bd8d49c": {
"id": "a7fd811b4bd8d49c",
"name": "bitbybit.code.typeScriptEditor",
"customName": "back lights",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const starta7fd811b4bd8d49c = async (inputs: any, index: number) => {\n const lights = [];\n for (const light of inputs) {\n const centre = (await bitbybit.occt.analysis.measure.tightBoundingBox({ shape: light })).center;\n if (centre[2] <= 0) {\n lights.push(light);\n }\n }\n return lights;\n}"
}
},
"inputs": {
"inputs": {
"connections": [
{
"node": "514ed3857482d37a",
"output": "copies",
"data": {}
}
]
}
},
"position": [
8056,
1218
],
"parent": "273c5f46c3e6ca82"
},
"27b3d01b400e073f": {
"id": "27b3d01b400e073f",
"name": "bitbybit.babylon.material.pbrMetallicRoughness.create",
"customName": "green light material",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"name": "green light",
"baseColor": "#22ff66",
"emissiveColor": "#22ff66",
"metallic": 0,
"roughness": 0.2,
"alpha": 1,
"backFaceCulling": false,
"zOffset": 2
},
"inputs": {},
"position": [
9078,
2885
],
"parent": "4f296fff2bf2d8ce"
},
"daf3c06c36893e37": {
"id": "daf3c06c36893e37",
"name": "bitbybit.draw.optionsOcctShape",
"customName": "green light look",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"faceOpacity": 1,
"edgeOpacity": 1,
"edgeColour": "#ffffff",
"faceColour": "#ff0000",
"vertexColour": "#ff00ff",
"edgeWidth": 2,
"vertexSize": 0.03,
"drawEdges": false,
"drawFaces": true,
"drawVertices": false,
"precision": 0.05,
"angularDeflection": 0.5,
"relativeDeflection": false,
"drawEdgeIndexes": false,
"edgeIndexHeight": 0.06,
"edgeIndexColour": "#ff00ff",
"drawFaceIndexes": false,
"faceIndexHeight": 0.06,
"faceIndexColour": "#0000ff",
"drawTwoSided": false,
"backFaceColour": "#0000ff",
"backFaceOpacity": 1,
"edgeArrowSize": 0,
"edgeArrowAngle": 15,
"keepMeshData": false,
"allowQualityDecrease": true,
"forceFaceDeflection": false,
"drawIsoCurves": false,
"isoCurvesU": 5,
"isoCurvesV": 5,
"isoCurvesColour": "#808080",
"surfaceAnalysis": "none",
"draftDirection": [
0,
1,
0
]
},
"inputs": {
"faceMaterial": {
"connections": [
{
"node": "27b3d01b400e073f",
"output": "result",
"data": {}
}
]
}
},
"position": [
10971,
1689
],
"parent": "4f296fff2bf2d8ce"
},
"c18bed881e96eebf": {
"id": "c18bed881e96eebf",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "green light",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"options": {
"connections": [
{
"node": "daf3c06c36893e37",
"output": "result",
"data": {}
}
]
},
"entity": {
"connections": [
{
"node": "d188faf10f534fc8",
"output": "result",
"data": {}
}
]
}
},
"position": [
13236,
1774
],
"parent": "4f296fff2bf2d8ce"
},
"b0e0bbcc88559f9d": {
"id": "b0e0bbcc88559f9d",
"name": "bitbybit.babylon.material.pbrMetallicRoughness.create",
"customName": "red light material",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"name": "red light",
"baseColor": "#ff2a2a",
"emissiveColor": "#ff2a2a",
"metallic": 0,
"roughness": 0.2,
"alpha": 1,
"backFaceCulling": false,
"zOffset": 2
},
"inputs": {},
"position": [
9078,
3404
],
"parent": "4f296fff2bf2d8ce"
},
"a523551d99e53757": {
"id": "a523551d99e53757",
"name": "bitbybit.draw.optionsOcctShape",
"customName": "red light look",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"faceOpacity": 1,
"edgeOpacity": 1,
"edgeColour": "#ffffff",
"faceColour": "#ff0000",
"vertexColour": "#ff00ff",
"edgeWidth": 2,
"vertexSize": 0.03,
"drawEdges": false,
"drawFaces": true,
"drawVertices": false,
"precision": 0.05,
"angularDeflection": 0.5,
"relativeDeflection": false,
"drawEdgeIndexes": false,
"edgeIndexHeight": 0.06,
"edgeIndexColour": "#ff00ff",
"drawFaceIndexes": false,
"faceIndexHeight": 0.06,
"faceIndexColour": "#0000ff",
"drawTwoSided": false,
"backFaceColour": "#0000ff",
"backFaceOpacity": 1,
"edgeArrowSize": 0,
"edgeArrowAngle": 15,
"keepMeshData": false,
"allowQualityDecrease": true,
"forceFaceDeflection": false,
"drawIsoCurves": false,
"isoCurvesU": 5,
"isoCurvesV": 5,
"isoCurvesColour": "#808080",
"surfaceAnalysis": "none",
"draftDirection": [
0,
1,
0
]
},
"inputs": {
"faceMaterial": {
"connections": [
{
"node": "b0e0bbcc88559f9d",
"output": "result",
"data": {}
}
]
}
},
"position": [
11424,
64
],
"parent": "4f296fff2bf2d8ce"
},
"49aa50416cfee8fe": {
"id": "49aa50416cfee8fe",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "red light",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"options": {
"connections": [
{
"node": "a523551d99e53757",
"output": "result",
"data": {}
}
]
},
"entity": {
"connections": [
{
"node": "a7fd811b4bd8d49c",
"output": "result",
"data": {}
}
]
}
},
"position": [
13236,
2116
],
"parent": "4f296fff2bf2d8ce"
},
"8de14ad4d536ecb8": {
"id": "8de14ad4d536ecb8",
"name": "bitbybit.groups.group",
"customName": "Canopy",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 2170,
"groupHeight": 1150,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
0,
3526
]
},
"8f7715fa1b3dd1c2": {
"id": "8f7715fa1b3dd1c2",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Canopy\nLofted through five rounded rectangles that narrow as they rise. A honeycomb of hexagons is traced on its sides, and a hatch closes the top.",
"commentWidth": 440,
"commentHeight": 158,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
24,
3590
],
"parent": "8de14ad4d536ecb8"
},
"da2b97476d03cc08": {
"id": "da2b97476d03cc08",
"name": "bitbybit.code.typeScriptEditor",
"customName": "canopy sections",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const startda2b97476d03cc08 = async (inputs: any, index: number) => {\n const sections = [[0, 140, 90, 26, 4], [12, 132, 84, 24, 6], [22, 110, 70, 19, 9], [29, 76, 48, 13, 10], [32, 52, 36, 10, 10]];\n const wires = [];\n for (const [y, length, width, radius, forward] of sections) {\n const rectangle = await bitbybit.occt.shapes.wire.createRectangleWire({ width, length, center: [0, y, forward], direction: [0, 1, 0] });\n wires.push(await bitbybit.occt.fillets.fillet2d({ shape: rectangle, radius }));\n }\n return wires;\n}"
}
},
"inputs": {},
"position": [
24,
3772
],
"parent": "8de14ad4d536ecb8"
},
"99b7febb562698b0": {
"id": "99b7febb562698b0",
"name": "bitbybit.occt.operations.loft",
"customName": "canopy loft",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"makeSolid": true
},
"inputs": {
"shapes": {
"connections": [
{
"node": "da2b97476d03cc08",
"output": "result",
"data": {}
}
]
}
},
"position": [
718,
3590
],
"parent": "8de14ad4d536ecb8"
},
"f146117a7991e090": {
"id": "f146117a7991e090",
"name": "bitbybit.occt.transforms.translate",
"customName": "canopy",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"translation": [
0,
16,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "99b7febb562698b0",
"output": "result",
"data": {}
}
]
}
},
"position": [
1120,
3590
],
"parent": "8de14ad4d536ecb8"
},
"e88dc8002074783f": {
"id": "e88dc8002074783f",
"name": "bitbybit.babylon.material.pbrMetallicRoughness.create",
"customName": "paint material",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"name": "paint",
"baseColor": "#1f2b4d",
"emissiveColor": "#000000",
"metallic": 0.1,
"roughness": 0.25,
"alpha": 1,
"backFaceCulling": false,
"zOffset": 2
},
"inputs": {},
"position": [
9078,
3923
],
"parent": "4f296fff2bf2d8ce"
},
"9735989ab6738c87": {
"id": "9735989ab6738c87",
"name": "bitbybit.draw.optionsOcctShape",
"customName": "paint look",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"faceOpacity": 1,
"edgeOpacity": 1,
"edgeColour": "#f2f2f2",
"faceColour": "#ff0000",
"vertexColour": "#ff00ff",
"edgeWidth": 6,
"vertexSize": 0.03,
"drawEdges": true,
"drawFaces": true,
"drawVertices": false,
"precision": 0.05,
"angularDeflection": 0.5,
"relativeDeflection": false,
"drawEdgeIndexes": false,
"edgeIndexHeight": 0.06,
"edgeIndexColour": "#ff00ff",
"drawFaceIndexes": false,
"faceIndexHeight": 0.06,
"faceIndexColour": "#0000ff",
"drawTwoSided": false,
"backFaceColour": "#0000ff",
"backFaceOpacity": 1,
"edgeArrowSize": 0,
"edgeArrowAngle": 15,
"keepMeshData": false,
"allowQualityDecrease": true,
"forceFaceDeflection": false,
"drawIsoCurves": false,
"isoCurvesU": 5,
"isoCurvesV": 5,
"isoCurvesColour": "#808080",
"surfaceAnalysis": "none",
"draftDirection": [
0,
1,
0
]
},
"inputs": {
"faceMaterial": {
"connections": [
{
"node": "e88dc8002074783f",
"output": "result",
"data": {}
}
]
}
},
"position": [
11424,
1689
],
"parent": "4f296fff2bf2d8ce"
},
"44d7777399305ab0": {
"id": "44d7777399305ab0",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "paint",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"options": {
"connections": [
{
"node": "9735989ab6738c87",
"output": "result",
"data": {}
}
]
},
"entity": {
"connections": [
{
"node": "f146117a7991e090",
"output": "result",
"data": {}
},
{
"node": "79b158dbbe51a78d",
"output": "result",
"data": {}
}
]
}
},
"position": [
13236,
2458
],
"parent": "4f296fff2bf2d8ce"
},
"a7f7437bb73aa81c": {
"id": "a7f7437bb73aa81c",
"name": "bitbybit.code.typeScriptEditor",
"customName": "honeycomb",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const starta7f7437bb73aa81c = async (inputs: any, index: number) => {\n const canopy = inputs;\n const centre = (await bitbybit.occt.analysis.measure.tightBoundingBox({ shape: canopy })).center;\n const grown = await bitbybit.occt.transforms.scale3d({ shape: canopy, scale: [1.02, 1.02, 1.02], center: [centre[0], 0, centre[2]] });\n const faces = await bitbybit.occt.shapes.face.getFaces({ shape: grown });\n const areas = await bitbybit.occt.shapes.face.getFacesAreas({ shapes: faces });\n const largestSide = Math.max(...areas.slice(0, -2));\n const wires = [];\n for (const [i, face] of faces.entries()) {\n const normal = await bitbybit.occt.shapes.face.normalOnUV({ shape: face, paramU: 0.5, paramV: 0.5 });\n if (Math.abs(normal[1]) > 0.9) {\n continue;\n }\n const across = areas[i] > largestSide * 0.7 ? 8 : 5;\n wires.push(...await bitbybit.occt.shapes.face.subdivideToHexagonWires({ shape: face, nrHexagonsU: across, nrHexagonsV: 3, flatU: false, scalePatternU: [0.8], scalePatternV: [0.8], filletPattern: [0.35], offsetFromBorderU: 0.05, offsetFromBorderV: 0.08 }));\n }\n return bitbybit.occt.shapes.compound.makeCompound({ shapes: wires });\n}"
}
},
"inputs": {
"inputs": {
"connections": [
{
"node": "99b7febb562698b0",
"output": "result",
"data": {}
}
]
}
},
"position": [
1120,
3889
],
"parent": "8de14ad4d536ecb8"
},
"0676e1bd7bbff847": {
"id": "0676e1bd7bbff847",
"name": "bitbybit.occt.transforms.translate",
"customName": "honeycomb on canopy",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"translation": [
0,
16,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "a7f7437bb73aa81c",
"output": "result",
"data": {}
}
]
}
},
"position": [
1814,
3590
],
"parent": "8de14ad4d536ecb8"
},
"0435c09397582ee1": {
"id": "0435c09397582ee1",
"name": "bitbybit.draw.optionsOcctShape",
"customName": "honeycomb look",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"faceOpacity": 1,
"edgeOpacity": 1,
"edgeColour": "#f2f2f2",
"faceColour": "#ff0000",
"vertexColour": "#ff00ff",
"edgeWidth": 8,
"vertexSize": 0.03,
"drawEdges": true,
"drawFaces": true,
"drawVertices": false,
"precision": 0.05,
"angularDeflection": 0.5,
"relativeDeflection": false,
"drawEdgeIndexes": false,
"edgeIndexHeight": 0.06,
"edgeIndexColour": "#ff00ff",
"drawFaceIndexes": false,
"faceIndexHeight": 0.06,
"faceIndexColour": "#0000ff",
"drawTwoSided": false,
"backFaceColour": "#0000ff",
"backFaceOpacity": 1,
"edgeArrowSize": 0,
"edgeArrowAngle": 15,
"keepMeshData": false,
"allowQualityDecrease": true,
"forceFaceDeflection": false,
"drawIsoCurves": false,
"isoCurvesU": 5,
"isoCurvesV": 5,
"isoCurvesColour": "#808080",
"surfaceAnalysis": "none",
"draftDirection": [
0,
1,
0
]
},
"inputs": {
"faceMaterial": {
"connections": [
{
"node": "e88dc8002074783f",
"output": "result",
"data": {}
}
]
}
},
"position": [
11877,
64
],
"parent": "4f296fff2bf2d8ce"
},
"5c23a5d4ded6334e": {
"id": "5c23a5d4ded6334e",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "honeycomb",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"options": {
"connections": [
{
"node": "0435c09397582ee1",
"output": "result",
"data": {}
}
]
},
"entity": {
"connections": [
{
"node": "0676e1bd7bbff847",
"output": "result",
"data": {}
}
]
}
},
"position": [
13236,
2800
],
"parent": "4f296fff2bf2d8ce"
},
"d8d221be2bb19e5c": {
"id": "d8d221be2bb19e5c",
"name": "bitbybit.occt.shapes.wire.createRectangleWire",
"customName": "hatch rectangle",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"width": 34,
"length": 50,
"center": [
0,
48,
10
],
"direction": [
0,
1,
0
]
},
"inputs": {},
"position": [
24,
4257
],
"parent": "8de14ad4d536ecb8"
},
"4a74bd01fe96f9f3": {
"id": "4a74bd01fe96f9f3",
"name": "bitbybit.occt.fillets.fillet2d",
"customName": "hatch outline",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 9
},
"inputs": {
"shape": {
"connections": [
{
"node": "d8d221be2bb19e5c",
"output": "result",
"data": {}
}
]
}
},
"position": [
718,
3892
],
"parent": "8de14ad4d536ecb8"
},
"434f07a94c33b1c6": {
"id": "434f07a94c33b1c6",
"name": "bitbybit.occt.shapes.face.createFaceFromWire",
"customName": "hatch face",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"planar": true
},
"inputs": {
"shape": {
"connections": [
{
"node": "4a74bd01fe96f9f3",
"output": "result",
"data": {}
}
]
}
},
"position": [
1120,
4374
],
"parent": "8de14ad4d536ecb8"
},
"f0051446b806b8e1": {
"id": "f0051446b806b8e1",
"name": "bitbybit.occt.operations.extrude",
"customName": "hatch",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"direction": [
0,
1.4,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "434f07a94c33b1c6",
"output": "result",
"data": {}
}
]
}
},
"position": [
1814,
3889
],
"parent": "8de14ad4d536ecb8"
},
"1d98ae31011cdfcf": {
"id": "1d98ae31011cdfcf",
"name": "bitbybit.groups.group",
"customName": "Logo",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 2818,
"groupHeight": 699,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
2863,
4437
]
},
"7cf2693162605105": {
"id": "7cf2693162605105",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Logo\nThe bitbybit logo, read from a STEP file on the CDN, scaled to 26 mm and centred on the hatch: cut through the hatch, and set into the cut a little smaller as a white emblem.",
"commentWidth": 440,
"commentHeight": 180,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
2887,
4501
],
"parent": "1d98ae31011cdfcf"
},
"3003e170090be2b7": {
"id": "3003e170090be2b7",
"name": "bitbybit.asset.fetchText",
"customName": "logo file",
"async": true,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"url": "https://git-cdn.bitbybit.dev/latest/assets/logo/logo-faces.stp"
},
"inputs": {},
"position": [
2887,
4705
],
"parent": "1d98ae31011cdfcf"
},
"9c2a04330e2dfe86": {
"id": "9c2a04330e2dfe86",
"name": "bitbybit.occt.io.loadSTEPorIGESFromText",
"customName": "logo shape",
"async": true,
"drawable": false,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"text": "",
"fileType": "step",
"adjustZtoY": true
},
"inputs": {
"text": {
"connections": [
{
"node": "3003e170090be2b7",
"output": "result",
"data": {}
}
]
}
},
"position": [
3447,
4501
],
"parent": "1d98ae31011cdfcf"
},
"846c1429314c7857": {
"id": "846c1429314c7857",
"name": "bitbybit.code.typeScriptEditor",
"customName": "logo on the hatch",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const start846c1429314c7857 = async (inputs: any, index: number) => {\n const mirrored = await bitbybit.occt.transforms.mirrorAlongNormal({ shape: inputs, origin: [0, 0, 0], normal: [1, 0, 0] });\n const size = (await bitbybit.occt.analysis.measure.tightBoundingBox({ shape: mirrored })).size;\n const scaled = await bitbybit.occt.transforms.scale({ shape: mirrored, factor: 26 / Math.max(size[0], size[2]) });\n const box = await bitbybit.occt.analysis.measure.tightBoundingBox({ shape: scaled });\n return bitbybit.occt.transforms.translate({ shape: scaled, translation: [-box.center[0], 47.9 - box.min[1], 10 - box.center[2]] });\n}"
}
},
"inputs": {
"inputs": {
"connections": [
{
"node": "9c2a04330e2dfe86",
"output": "result",
"data": {}
}
]
}
},
"position": [
3824,
4501
],
"parent": "1d98ae31011cdfcf"
},
"d9aa5c72eb468afb": {
"id": "d9aa5c72eb468afb",
"name": "bitbybit.occt.operations.extrude",
"customName": "logo cut",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"direction": [
0,
1.7,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "846c1429314c7857",
"output": "result",
"data": {}
}
]
}
},
"position": [
4518,
4501
],
"parent": "1d98ae31011cdfcf"
},
"4828bae55fcbcac5": {
"id": "4828bae55fcbcac5",
"name": "bitbybit.lists.createList",
"customName": "logo cut-outs",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "d9aa5c72eb468afb",
"output": "result",
"data": {}
}
]
}
},
"position": [
4938,
4501
],
"parent": "1d98ae31011cdfcf"
},
"79b158dbbe51a78d": {
"id": "79b158dbbe51a78d",
"name": "bitbybit.occt.booleans.difference",
"customName": "hatch with logo",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"keepEdges": false,
"strategy": "oneAfterAnother"
},
"inputs": {
"shape": {
"connections": [
{
"node": "f0051446b806b8e1",
"output": "result",
"data": {}
}
]
},
"shapes": {
"connections": [
{
"node": "4828bae55fcbcac5",
"output": "list",
"data": {}
}
]
}
},
"position": [
5358,
4501
],
"parent": "1d98ae31011cdfcf"
},
"a27ce75c35681976": {
"id": "a27ce75c35681976",
"name": "bitbybit.occt.transforms.scale3d",
"customName": "emblem faces",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"scale": [
0.96,
1,
0.96
],
"center": [
0,
47.9,
10
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "846c1429314c7857",
"output": "result",
"data": {}
}
]
}
},
"position": [
4518,
4800
],
"parent": "1d98ae31011cdfcf"
},
"81f254cd60c52af4": {
"id": "81f254cd60c52af4",
"name": "bitbybit.occt.operations.extrude",
"customName": "emblem",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"direction": [
0,
1.1,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "a27ce75c35681976",
"output": "result",
"data": {}
}
]
}
},
"position": [
4938,
4660
],
"parent": "1d98ae31011cdfcf"
},
"52b57a77b32439dd": {
"id": "52b57a77b32439dd",
"name": "bitbybit.babylon.material.pbrMetallicRoughness.create",
"customName": "emblem material",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"name": "emblem",
"baseColor": "#f4f4f4",
"emissiveColor": "#000000",
"metallic": 0.2,
"roughness": 0.5,
"alpha": 1,
"backFaceCulling": false,
"zOffset": 2
},
"inputs": {},
"position": [
9638,
64
],
"parent": "4f296fff2bf2d8ce"
},
"9e2b2f86721d51d6": {
"id": "9e2b2f86721d51d6",
"name": "bitbybit.draw.optionsOcctShape",
"customName": "emblem look",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"faceOpacity": 1,
"edgeOpacity": 1,
"edgeColour": "#0d0e10",
"faceColour": "#ff0000",
"vertexColour": "#ff00ff",
"edgeWidth": 4,
"vertexSize": 0.03,
"drawEdges": true,
"drawFaces": true,
"drawVertices": false,
"precision": 0.05,
"angularDeflection": 0.5,
"relativeDeflection": false,
"drawEdgeIndexes": false,
"edgeIndexHeight": 0.06,
"edgeIndexColour": "#ff00ff",
"drawFaceIndexes": false,
"faceIndexHeight": 0.06,
"faceIndexColour": "#0000ff",
"drawTwoSided": false,
"backFaceColour": "#0000ff",
"backFaceOpacity": 1,
"edgeArrowSize": 0,
"edgeArrowAngle": 15,
"keepMeshData": false,
"allowQualityDecrease": true,
"forceFaceDeflection": false,
"drawIsoCurves": false,
"isoCurvesU": 5,
"isoCurvesV": 5,
"isoCurvesColour": "#808080",
"surfaceAnalysis": "none",
"draftDirection": [
0,
1,
0
]
},
"inputs": {
"faceMaterial": {
"connections": [
{
"node": "52b57a77b32439dd",
"output": "result",
"data": {}
}
]
}
},
"position": [
11877,
1689
],
"parent": "4f296fff2bf2d8ce"
},
"7414c7837dfe2e9f": {
"id": "7414c7837dfe2e9f",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "emblem",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"options": {
"connections": [
{
"node": "9e2b2f86721d51d6",
"output": "result",
"data": {}
}
]
},
"entity": {
"connections": [
{
"node": "81f254cd60c52af4",
"output": "result",
"data": {}
}
]
}
},
"position": [
13236,
3142
],
"parent": "4f296fff2bf2d8ce"
},
"e48760cbd24beccf": {
"id": "e48760cbd24beccf",
"name": "bitbybit.groups.group",
"customName": "Electronics",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 1753,
"groupHeight": 1625,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
0,
4796
]
},
"41497d1f5df7c7e8": {
"id": "41497d1f5df7c7e8",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Electronics\nThe GPS sits on a mast behind the canopy, clear of the frame, and two antennas angle down and back from the bottom plate.",
"commentWidth": 440,
"commentHeight": 158,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
24,
4860
],
"parent": "e48760cbd24beccf"
},
"5c01484d8c5cba2e": {
"id": "5c01484d8c5cba2e",
"name": "bitbybit.occt.shapes.solid.createCylinder",
"customName": "GPS mast",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 2.5,
"height": 34,
"center": [
0,
16,
-70
],
"direction": [
0,
1,
0
],
"angle": 360,
"originOnCenter": false
},
"inputs": {},
"position": [
24,
5042
],
"parent": "e48760cbd24beccf"
},
"969fcd02ae0d7979": {
"id": "969fcd02ae0d7979",
"name": "bitbybit.occt.shapes.solid.createCylinder",
"customName": "GPS puck",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 11,
"height": 6,
"center": [
0,
50,
-70
],
"direction": [
0,
1,
0
],
"angle": 360,
"originOnCenter": false
},
"inputs": {},
"position": [
24,
5489
],
"parent": "e48760cbd24beccf"
},
"70d7418c5b622fea": {
"id": "70d7418c5b622fea",
"name": "bitbybit.occt.fillets.filletEdges",
"customName": "rounded puck",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 1.5
},
"inputs": {
"shape": {
"connections": [
{
"node": "969fcd02ae0d7979",
"output": "result",
"data": {}
}
]
}
},
"position": [
718,
4860
],
"parent": "e48760cbd24beccf"
},
"24c9713b90c05745": {
"id": "24c9713b90c05745",
"name": "bitbybit.lists.createList",
"customName": "GPS parts",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "5c01484d8c5cba2e",
"output": "result",
"data": {}
},
{
"node": "70d7418c5b622fea",
"output": "result",
"data": {}
}
]
}
},
"position": [
1112,
4860
],
"parent": "e48760cbd24beccf"
},
"565166cd63978994": {
"id": "565166cd63978994",
"name": "bitbybit.occt.booleans.union",
"customName": "GPS",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"keepEdges": false,
"strategy": "oneAfterAnother"
},
"inputs": {
"shapes": {
"connections": [
{
"node": "24c9713b90c05745",
"output": "list",
"data": {}
}
]
}
},
"position": [
1481,
4860
],
"parent": "e48760cbd24beccf"
},
"341843cb573931aa": {
"id": "341843cb573931aa",
"name": "bitbybit.code.typeScriptEditor",
"customName": "antennas",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const start341843cb573931aa = async (inputs: any, index: number) => {\n const rod = await bitbybit.occt.shapes.solid.createCylinder({ radius: 1.5, height: 42, center: [0, 0, 0], direction: [0, 1, 0] });\n const tip = await bitbybit.occt.shapes.solid.createSphere({ radius: 1.5, center: [0, 42, 0] });\n const antenna = await bitbybit.occt.booleans.union({ shapes: [rod, tip], keepEdges: false });\n const tilted = await bitbybit.occt.transforms.rotate({ shape: antenna, axis: [1, 0, 0], angle: 225 });\n const pair = [];\n for (const x of [-14, 14]) {\n pair.push(await bitbybit.occt.transforms.translate({ shape: tilted, translation: [x, 0, -67] }));\n }\n return bitbybit.occt.shapes.compound.makeCompound({ shapes: pair });\n}"
}
},
"inputs": {},
"position": [
24,
5936
],
"parent": "e48760cbd24beccf"
},
"cad128f173b0bd0e": {
"id": "cad128f173b0bd0e",
"name": "bitbybit.babylon.material.pbrMetallicRoughness.create",
"customName": "polymer material",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"name": "polymer",
"baseColor": "#2a2d31",
"emissiveColor": "#000000",
"metallic": 0.05,
"roughness": 0.4,
"alpha": 1,
"backFaceCulling": false,
"zOffset": 2
},
"inputs": {},
"position": [
9638,
583
],
"parent": "4f296fff2bf2d8ce"
},
"897f5e3287e522ac": {
"id": "897f5e3287e522ac",
"name": "bitbybit.draw.optionsOcctShape",
"customName": "polymer look",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"faceOpacity": 1,
"edgeOpacity": 1,
"edgeColour": "#f2f2f2",
"faceColour": "#ff0000",
"vertexColour": "#ff00ff",
"edgeWidth": 6,
"vertexSize": 0.03,
"drawEdges": true,
"drawFaces": true,
"drawVertices": false,
"precision": 0.05,
"angularDeflection": 0.5,
"relativeDeflection": false,
"drawEdgeIndexes": false,
"edgeIndexHeight": 0.06,
"edgeIndexColour": "#ff00ff",
"drawFaceIndexes": false,
"faceIndexHeight": 0.06,
"faceIndexColour": "#0000ff",
"drawTwoSided": false,
"backFaceColour": "#0000ff",
"backFaceOpacity": 1,
"edgeArrowSize": 0,
"edgeArrowAngle": 15,
"keepMeshData": false,
"allowQualityDecrease": true,
"forceFaceDeflection": false,
"drawIsoCurves": false,
"isoCurvesU": 5,
"isoCurvesV": 5,
"isoCurvesColour": "#808080",
"surfaceAnalysis": "none",
"draftDirection": [
0,
1,
0
]
},
"inputs": {
"faceMaterial": {
"connections": [
{
"node": "cad128f173b0bd0e",
"output": "result",
"data": {}
}
]
}
},
"position": [
12330,
64
],
"parent": "4f296fff2bf2d8ce"
},
"76c3fca2625dc4cc": {
"id": "76c3fca2625dc4cc",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "polymer",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"options": {
"connections": [
{
"node": "897f5e3287e522ac",
"output": "result",
"data": {}
}
]
},
"entity": {
"connections": [
{
"node": "565166cd63978994",
"output": "result",
"data": {}
},
{
"node": "6217959750151f59",
"output": "result",
"data": {}
},
{
"node": "921f831fb98fa05b",
"output": "result",
"data": {}
}
]
}
},
"position": [
13236,
3484
],
"parent": "4f296fff2bf2d8ce"
},
"0db0a64dd78b5ed2": {
"id": "0db0a64dd78b5ed2",
"name": "bitbybit.babylon.material.pbrMetallicRoughness.create",
"customName": "rubber material",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"name": "rubber",
"baseColor": "#111214",
"emissiveColor": "#000000",
"metallic": 0,
"roughness": 0.92,
"alpha": 1,
"backFaceCulling": false,
"zOffset": 2
},
"inputs": {},
"position": [
9638,
1102
],
"parent": "4f296fff2bf2d8ce"
},
"907f8db1421bc7af": {
"id": "907f8db1421bc7af",
"name": "bitbybit.draw.optionsOcctShape",
"customName": "rubber look",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"faceOpacity": 1,
"edgeOpacity": 1,
"edgeColour": "#f2f2f2",
"faceColour": "#ff0000",
"vertexColour": "#ff00ff",
"edgeWidth": 4,
"vertexSize": 0.03,
"drawEdges": true,
"drawFaces": true,
"drawVertices": false,
"precision": 0.05,
"angularDeflection": 0.5,
"relativeDeflection": false,
"drawEdgeIndexes": false,
"edgeIndexHeight": 0.06,
"edgeIndexColour": "#ff00ff",
"drawFaceIndexes": false,
"faceIndexHeight": 0.06,
"faceIndexColour": "#0000ff",
"drawTwoSided": false,
"backFaceColour": "#0000ff",
"backFaceOpacity": 1,
"edgeArrowSize": 0,
"edgeArrowAngle": 15,
"keepMeshData": false,
"allowQualityDecrease": true,
"forceFaceDeflection": false,
"drawIsoCurves": false,
"isoCurvesU": 5,
"isoCurvesV": 5,
"isoCurvesColour": "#808080",
"surfaceAnalysis": "none",
"draftDirection": [
0,
1,
0
]
},
"inputs": {
"faceMaterial": {
"connections": [
{
"node": "0db0a64dd78b5ed2",
"output": "result",
"data": {}
}
]
}
},
"position": [
12330,
1689
],
"parent": "4f296fff2bf2d8ce"
},
"6c535d87a0dbb5fb": {
"id": "6c535d87a0dbb5fb",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "rubber",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"options": {
"connections": [
{
"node": "907f8db1421bc7af",
"output": "result",
"data": {}
}
]
},
"entity": {
"connections": [
{
"node": "341843cb573931aa",
"output": "result",
"data": {}
},
{
"node": "05e4efbc347436ba",
"output": "copies",
"data": {}
}
]
}
},
"position": [
13236,
3826
],
"parent": "4f296fff2bf2d8ce"
},
"af0287853e5faf87": {
"id": "af0287853e5faf87",
"name": "bitbybit.groups.group",
"customName": "Landing gear",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 2304,
"groupHeight": 2207,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
2863,
5256
]
},
"d04ec8e1e2e5caeb": {
"id": "d04ec8e1e2e5caeb",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Landing gear\nOne leg is made along the x axis, 52 mm out: a bent carbon tube, a damper with its spring, and a rubber foot. Around repeats each part four times, under the arms.",
"commentWidth": 440,
"commentHeight": 180,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
2887,
5320
],
"parent": "af0287853e5faf87"
},
"b7914e8be5dec9b1": {
"id": "b7914e8be5dec9b1",
"name": "bitbybit.code.typeScriptEditor",
"customName": "leg",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const startb7914e8be5dec9b1 = async (inputs: any, index: number) => {\n const path = await bitbybit.occt.shapes.wire.createPolylineWire({ points: [[52, 0, 0], [58, -18, 0], [78, -34, 0], [78, -48, 0]] });\n const bent = await bitbybit.occt.fillets.fillet3DWire({ shape: path, radiusList: [12, 6], indexes: [0, 1], direction: [0, 0, 1] });\n const tube = await bitbybit.occt.operations.pipeWireCylindrical({ shape: bent, radius: 4, makeSolid: true, trihedronEnum: \"isConstantNormal\", forceApproxC1: false });\n const flange = await bitbybit.occt.shapes.solid.createBox({ width: 20, length: 12, height: 3, center: [52, -1.5, 0] });\n const boss = await bitbybit.occt.shapes.solid.createCylinder({ radius: 5.5, height: 6.4, center: [52, -3, 0], direction: [0, 1, 0] });\n return bitbybit.occt.booleans.union({ shapes: [tube, flange, boss], keepEdges: false });\n}"
}
},
"inputs": {},
"position": [
2887,
5524
],
"parent": "af0287853e5faf87"
},
"57edd2996cf03498": {
"id": "57edd2996cf03498",
"name": "bitbybit.modules.module",
"customName": "legs around",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_e07d2900372f77c7",
"embedded": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "b7914e8be5dec9b1",
"output": "result",
"data": {}
}
]
},
"count": {
"connections": [
{
"node": "99af658df4b8c37a",
"output": "result",
"data": {}
}
]
}
},
"position": [
4013,
5320
],
"parent": "af0287853e5faf87"
},
"c0a05a946ed6d787": {
"id": "c0a05a946ed6d787",
"name": "bitbybit.code.typeScriptEditor",
"customName": "damper",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const startc0a05a946ed6d787 = async (inputs: any, index: number) => {\n const profile = [[0, 0, 0], [6.5, 0, 0], [6.5, -4, 0], [5.5, -4.5, 0], [5.5, -14, 0], [6.2, -14, 0], [6.2, -16.5, 0], [4, -16.5, 0], [4, -18, 0], [2.2, -18, 0], [2.2, -30, 0], [0, -30, 0]];\n const outline = await bitbybit.occt.shapes.wire.createPolygonWire({ points: profile });\n const face = await bitbybit.occt.shapes.face.createFaceFromWire({ shape: outline, planar: true });\n const body = await bitbybit.occt.operations.revolve({ shape: face, angle: 360, direction: [0, 1, 0], copy: false });\n return bitbybit.occt.transforms.translate({ shape: body, translation: [78, -46, 0] });\n}"
}
},
"inputs": {},
"position": [
2887,
6009
],
"parent": "af0287853e5faf87"
},
"023878c0746631c2": {
"id": "023878c0746631c2",
"name": "bitbybit.occt.shapes.wire.createHelixWire",
"customName": "spring helix",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 4.2,
"pitch": 2.8,
"height": 12.5,
"center": [
78,
-75.8,
0
],
"direction": [
0,
1,
0
],
"clockwise": false,
"tolerance": 0.0001
},
"inputs": {},
"position": [
2887,
6494
],
"parent": "af0287853e5faf87"
},
"789ac9cb952dcf15": {
"id": "789ac9cb952dcf15",
"name": "bitbybit.occt.operations.pipeWireCylindrical",
"customName": "spring",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 0.9,
"makeSolid": true,
"trihedronEnum": "isCorrectedFrenet",
"forceApproxC1": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "023878c0746631c2",
"output": "result",
"data": {}
}
]
}
},
"position": [
4013,
5525
],
"parent": "af0287853e5faf87"
},
"58c458a3a5c243de": {
"id": "58c458a3a5c243de",
"name": "bitbybit.modules.module",
"customName": "dampers around",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_e07d2900372f77c7",
"embedded": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "c0a05a946ed6d787",
"output": "result",
"data": {}
}
]
},
"count": {
"connections": [
{
"node": "99af658df4b8c37a",
"output": "result",
"data": {}
}
]
}
},
"position": [
4013,
5941
],
"parent": "af0287853e5faf87"
},
"321cd1a9f9ccff35": {
"id": "321cd1a9f9ccff35",
"name": "bitbybit.modules.module",
"customName": "springs around",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_e07d2900372f77c7",
"embedded": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "789ac9cb952dcf15",
"output": "result",
"data": {}
}
]
},
"count": {
"connections": [
{
"node": "99af658df4b8c37a",
"output": "result",
"data": {}
}
]
}
},
"position": [
4426,
5320
],
"parent": "af0287853e5faf87"
},
"62732ed498c24e0d": {
"id": "62732ed498c24e0d",
"name": "bitbybit.code.typeScriptEditor",
"customName": "foot",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const start62732ed498c24e0d = async (inputs: any, index: number) => {\n const rings = [];\n for (const [y, radius] of [[0, 3.2], [-2, 7], [-5, 9.5], [-8, 9], [-10, 7]]) {\n rings.push(await bitbybit.occt.shapes.wire.createCircleWire({ radius, center: [78, -76 + y, 0], direction: [0, 1, 0] }));\n }\n return bitbybit.occt.operations.loft({ shapes: rings, makeSolid: true });\n}"
}
},
"inputs": {},
"position": [
2887,
6978
],
"parent": "af0287853e5faf87"
},
"05e4efbc347436ba": {
"id": "05e4efbc347436ba",
"name": "bitbybit.modules.module",
"customName": "feet around",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_e07d2900372f77c7",
"embedded": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "62732ed498c24e0d",
"output": "result",
"data": {}
}
]
},
"count": {
"connections": [
{
"node": "99af658df4b8c37a",
"output": "result",
"data": {}
}
]
}
},
"position": [
4013,
6146
],
"parent": "af0287853e5faf87"
},
"7c359a6a20371f6b": {
"id": "7c359a6a20371f6b",
"name": "bitbybit.occt.transforms.translate",
"customName": "inner leg bolt",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"translation": [
44.5,
-3,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "2a9a6821b1fa56c6",
"output": "result",
"data": {}
}
]
}
},
"position": [
3581,
5320
],
"parent": "af0287853e5faf87"
},
"e6ac66fae8da06b2": {
"id": "e6ac66fae8da06b2",
"name": "bitbybit.occt.transforms.translate",
"customName": "outer leg bolt",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"translation": [
59.5,
-3,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "2a9a6821b1fa56c6",
"output": "result",
"data": {}
}
]
}
},
"position": [
3581,
5619
],
"parent": "af0287853e5faf87"
},
"01221caeb438c137": {
"id": "01221caeb438c137",
"name": "bitbybit.lists.createList",
"customName": "leg bolts",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "7c359a6a20371f6b",
"output": "result",
"data": {}
},
{
"node": "e6ac66fae8da06b2",
"output": "result",
"data": {}
}
]
}
},
"position": [
4013,
6351
],
"parent": "af0287853e5faf87"
},
"46675b5f2ed2d6a4": {
"id": "46675b5f2ed2d6a4",
"name": "bitbybit.occt.shapes.compound.makeCompound",
"customName": "leg bolt pair",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"shapes": {
"connections": [
{
"node": "01221caeb438c137",
"output": "list",
"data": {}
}
]
}
},
"position": [
4426,
5525
],
"parent": "af0287853e5faf87"
},
"8c624beca6ae04f4": {
"id": "8c624beca6ae04f4",
"name": "bitbybit.modules.module",
"customName": "leg bolts around",
"async": false,
"drawable": false,
"data": {
"moduleId": "module_e07d2900372f77c7",
"embedded": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "46675b5f2ed2d6a4",
"output": "result",
"data": {}
}
]
},
"count": {
"connections": [
{
"node": "99af658df4b8c37a",
"output": "result",
"data": {}
}
]
}
},
"position": [
4836,
5320
],
"parent": "af0287853e5faf87"
},
"b0bb5665379a15d1": {
"id": "b0bb5665379a15d1",
"name": "bitbybit.groups.group",
"customName": "Payload",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 2463,
"groupHeight": 2445,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
0,
6541
]
},
"ac0bdcaac3e3bfa1": {
"id": "ac0bdcaac3e3bfa1",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Payload\nA camera on a gimbal at the front and the battery in two straps underneath, placed directly without modules.",
"commentWidth": 440,
"commentHeight": 158,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
24,
6605
],
"parent": "b0bb5665379a15d1"
},
"bce1e79ac1754448": {
"id": "bce1e79ac1754448",
"name": "bitbybit.code.typeScriptEditor",
"customName": "gimbal",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const startbce1e79ac1754448 = async (inputs: any, index: number) => {\n const outline = await bitbybit.occt.shapes.wire.createPolygonWire({ points: [[-4, 19, -4], [19.5, 19, -4], [19.5, -7, -4], [14.5, -7, -4], [14.5, 15, -4], [-4, 15, -4]] });\n const rounded = await bitbybit.occt.fillets.fillet2d({ shape: outline, radius: 1.5 });\n const face = await bitbybit.occt.shapes.face.createFaceFromWire({ shape: rounded, planar: true });\n const bracket = await bitbybit.occt.operations.extrude({ shape: face, direction: [0, 0, 8] });\n const yaw = await bitbybit.occt.shapes.solid.createCylinder({ radius: 9, height: 8, center: [0, 18, 0], direction: [0, 1, 0] });\n const roll = await bitbybit.occt.shapes.solid.createCylinder({ radius: 6, height: 5, center: [14.5, 0, 0], direction: [-1, 0, 0] });\n const gimbal = await bitbybit.occt.booleans.union({ shapes: [yaw, bracket, roll], keepEdges: false });\n return bitbybit.occt.transforms.translate({ shape: gimbal, translation: [0, -26, 55] });\n}"
}
},
"inputs": {},
"position": [
24,
6787
],
"parent": "b0bb5665379a15d1"
},
"37eaecc307433539": {
"id": "37eaecc307433539",
"name": "bitbybit.occt.shapes.solid.createBox",
"customName": "camera box",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"width": 24,
"length": 20,
"height": 18,
"center": [
0,
-26,
55
],
"originOnCenter": true
},
"inputs": {},
"position": [
24,
7272
],
"parent": "b0bb5665379a15d1"
},
"875172188fbc6362": {
"id": "875172188fbc6362",
"name": "bitbybit.occt.fillets.filletEdges",
"customName": "camera body",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 3
},
"inputs": {
"shape": {
"connections": [
{
"node": "37eaecc307433539",
"output": "result",
"data": {}
}
]
}
},
"position": [
1412,
6605
],
"parent": "b0bb5665379a15d1"
},
"9969b71fe10d3bd0": {
"id": "9969b71fe10d3bd0",
"name": "bitbybit.occt.shapes.solid.createCylinder",
"customName": "lens barrel",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 6.5,
"height": 9,
"center": [
0,
-26,
63
],
"direction": [
0,
0,
1
],
"angle": 360,
"originOnCenter": false
},
"inputs": {},
"position": [
24,
7682
],
"parent": "b0bb5665379a15d1"
},
"fda2c39c66181772": {
"id": "fda2c39c66181772",
"name": "bitbybit.lists.createList",
"customName": "camera parts",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "875172188fbc6362",
"output": "result",
"data": {}
},
{
"node": "9969b71fe10d3bd0",
"output": "result",
"data": {}
}
]
}
},
"position": [
1797,
6605
],
"parent": "b0bb5665379a15d1"
},
"6217959750151f59": {
"id": "6217959750151f59",
"name": "bitbybit.occt.booleans.union",
"customName": "camera",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"keepEdges": false,
"strategy": "oneAfterAnother"
},
"inputs": {
"shapes": {
"connections": [
{
"node": "fda2c39c66181772",
"output": "list",
"data": {}
}
]
}
},
"position": [
2191,
6605
],
"parent": "b0bb5665379a15d1"
},
"09b9b1b453cf2c7f": {
"id": "09b9b1b453cf2c7f",
"name": "bitbybit.occt.shapes.solid.createCylinder",
"customName": "lens",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 5.2,
"height": 1.5,
"center": [
0,
-26,
71.5
],
"direction": [
0,
0,
1
],
"angle": 360,
"originOnCenter": false
},
"inputs": {},
"position": [
24,
8129
],
"parent": "b0bb5665379a15d1"
},
"df5cc4267247efa9": {
"id": "df5cc4267247efa9",
"name": "bitbybit.occt.shapes.solid.createBox",
"customName": "battery box",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"width": 36,
"length": 72,
"height": 26,
"center": [
0,
-16,
-20
],
"originOnCenter": true
},
"inputs": {},
"position": [
24,
8576
],
"parent": "b0bb5665379a15d1"
},
"921f831fb98fa05b": {
"id": "921f831fb98fa05b",
"name": "bitbybit.occt.fillets.filletEdges",
"customName": "battery",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 3
},
"inputs": {
"shape": {
"connections": [
{
"node": "df5cc4267247efa9",
"output": "result",
"data": {}
}
]
}
},
"position": [
1412,
6984
],
"parent": "b0bb5665379a15d1"
},
"b561ea9c301029c7": {
"id": "b561ea9c301029c7",
"name": "bitbybit.code.typeScriptEditor",
"customName": "straps",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const startb561ea9c301029c7 = async (inputs: any, index: number) => {\n const outer = await bitbybit.occt.shapes.solid.createBox({ width: 40, length: 10, height: 30, center: [0, 0, 0] });\n const inner = await bitbybit.occt.shapes.solid.createBox({ width: 36.5, length: 12, height: 26.5, center: [0, 0, 0] });\n const strap = await bitbybit.occt.booleans.difference({ shape: outer, shapes: [inner], keepEdges: false });\n const pair = [];\n for (const z of [-42, 2]) {\n pair.push(await bitbybit.occt.transforms.translate({ shape: strap, translation: [0, -16, z] }));\n }\n return bitbybit.occt.shapes.compound.makeCompound({ shapes: pair });\n}"
}
},
"inputs": {},
"position": [
718,
6605
],
"parent": "b0bb5665379a15d1"
},
"5dbfbf3e3f165eec": {
"id": "5dbfbf3e3f165eec",
"name": "bitbybit.babylon.material.pbrMetallicRoughness.create",
"customName": "glass material",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"name": "glass",
"baseColor": "#0c1522",
"emissiveColor": "#000000",
"metallic": 0.1,
"roughness": 0.05,
"alpha": 1,
"backFaceCulling": false,
"zOffset": 2
},
"inputs": {},
"position": [
9638,
1621
],
"parent": "4f296fff2bf2d8ce"
},
"24b80822e6903db6": {
"id": "24b80822e6903db6",
"name": "bitbybit.draw.optionsOcctShape",
"customName": "glass look",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"faceOpacity": 1,
"edgeOpacity": 1,
"edgeColour": "#f2f2f2",
"faceColour": "#ff0000",
"vertexColour": "#ff00ff",
"edgeWidth": 4,
"vertexSize": 0.03,
"drawEdges": true,
"drawFaces": true,
"drawVertices": false,
"precision": 0.05,
"angularDeflection": 0.5,
"relativeDeflection": false,
"drawEdgeIndexes": false,
"edgeIndexHeight": 0.06,
"edgeIndexColour": "#ff00ff",
"drawFaceIndexes": false,
"faceIndexHeight": 0.06,
"faceIndexColour": "#0000ff",
"drawTwoSided": false,
"backFaceColour": "#0000ff",
"backFaceOpacity": 1,
"edgeArrowSize": 0,
"edgeArrowAngle": 15,
"keepMeshData": false,
"allowQualityDecrease": true,
"forceFaceDeflection": false,
"drawIsoCurves": false,
"isoCurvesU": 5,
"isoCurvesV": 5,
"isoCurvesColour": "#808080",
"surfaceAnalysis": "none",
"draftDirection": [
0,
1,
0
]
},
"inputs": {
"faceMaterial": {
"connections": [
{
"node": "5dbfbf3e3f165eec",
"output": "result",
"data": {}
}
]
}
},
"position": [
12783,
64
],
"parent": "4f296fff2bf2d8ce"
},
"cb16ef4cbbc0c5aa": {
"id": "cb16ef4cbbc0c5aa",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "glass",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"options": {
"connections": [
{
"node": "24b80822e6903db6",
"output": "result",
"data": {}
}
]
},
"entity": {
"connections": [
{
"node": "09b9b1b453cf2c7f",
"output": "result",
"data": {}
}
]
}
},
"position": [
13236,
4168
],
"parent": "4f296fff2bf2d8ce"
}
},
"modules": {
"module_e07d2900372f77c7": {
"id": "rete-v2-json",
"nodes": {
"module-input": {
"id": "module-input",
"name": "bitbybit.modules.input",
"customName": "shape",
"async": false,
"drawable": false,
"data": {
"sample": ""
},
"inputs": {},
"position": [
24,
268
],
"parent": "f71dd17d630c1e47"
},
"module-output": {
"id": "module-output",
"name": "bitbybit.modules.output",
"customName": "copies",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"value": {
"connections": [
{
"node": "393e9854d5de80bf",
"output": "result",
"data": {}
}
]
}
},
"position": [
1663,
64
],
"parent": "f71dd17d630c1e47"
},
"f71dd17d630c1e47": {
"id": "f71dd17d630c1e47",
"name": "bitbybit.groups.group",
"customName": "Around",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 1911,
"groupHeight": 1149,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
0,
0
]
},
"ea64168493c6a033": {
"id": "ea64168493c6a033",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Around\nRepeats **shape** **count** times around the upright axis, half a step off the axes: for four, at 45, 135, 225 and 315 degrees, so four arms point to the corners of the frame.",
"commentWidth": 440,
"commentHeight": 180,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
24,
64
],
"parent": "f71dd17d630c1e47"
},
"19eb750b3afcb87e": {
"id": "19eb750b3afcb87e",
"name": "bitbybit.modules.input",
"customName": "count",
"async": false,
"drawable": false,
"data": {
"sample": "4"
},
"inputs": {},
"position": [
24,
407
],
"parent": "f71dd17d630c1e47"
},
"fed111f912afdc7b": {
"id": "fed111f912afdc7b",
"name": "bitbybit.lists.repeat",
"customName": "repeat shape",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"times": 10
},
"inputs": {
"item": {
"connections": [
{
"node": "module-input",
"output": "value",
"data": {}
}
]
},
"times": {
"connections": [
{
"node": "19eb750b3afcb87e",
"output": "value",
"data": {}
}
]
}
},
"position": [
584,
64
],
"parent": "f71dd17d630c1e47"
},
"7ec5a16b8e2f6034": {
"id": "7ec5a16b8e2f6034",
"name": "bitbybit.vector.vectorXYZ",
"customName": "up",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 1,
"z": 0
},
"inputs": {},
"position": [
24,
546
],
"parent": "f71dd17d630c1e47"
},
"29bf38e480294430": {
"id": "29bf38e480294430",
"name": "bitbybit.lists.repeat",
"customName": "repeat axis",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"times": 10
},
"inputs": {
"item": {
"connections": [
{
"node": "7ec5a16b8e2f6034",
"output": "result",
"data": {}
}
]
},
"times": {
"connections": [
{
"node": "19eb750b3afcb87e",
"output": "value",
"data": {}
}
]
}
},
"position": [
584,
364
],
"parent": "f71dd17d630c1e47"
},
"36905bf687ff808d": {
"id": "36905bf687ff808d",
"name": "bitbybit.code.typeScriptEditor",
"customName": "angles",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const start36905bf687ff808d = async (inputs: any, index: number) => {\n const count = Math.max(1, Math.round(inputs));\n return Array.from({ length: count }, (_, i) => (i + 0.5) * 360 / count);\n}"
}
},
"inputs": {
"inputs": {
"connections": [
{
"node": "19eb750b3afcb87e",
"output": "value",
"data": {}
}
]
}
},
"position": [
584,
664
],
"parent": "f71dd17d630c1e47"
},
"393e9854d5de80bf": {
"id": "393e9854d5de80bf",
"name": "bitbybit.occt.transforms.rotateShapes",
"customName": "turn copies",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"axes": [
[
0,
0,
1
]
],
"angles": [
0
]
},
"inputs": {
"shapes": {
"connections": [
{
"node": "fed111f912afdc7b",
"output": "result",
"data": {}
}
]
},
"axes": {
"connections": [
{
"node": "29bf38e480294430",
"output": "result",
"data": {}
}
]
},
"angles": {
"connections": [
{
"node": "36905bf687ff808d",
"output": "result",
"data": {}
}
]
}
},
"position": [
1278,
64
],
"parent": "f71dd17d630c1e47"
}
},
"modules": {}
},
"module_1b640754df2b28cd": {
"id": "rete-v2-json",
"nodes": {
"module-input": {
"id": "module-input",
"name": "bitbybit.modules.input",
"customName": "length",
"async": false,
"drawable": false,
"data": {
"sample": "185"
},
"inputs": {},
"position": [
24,
246
],
"parent": "75ac145d86289af2"
},
"module-output": {
"id": "module-output",
"name": "bitbybit.modules.output",
"customName": "arm",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"value": {
"connections": [
{
"node": "8a07407ef7d839e9",
"output": "result",
"data": {}
}
]
}
},
"position": [
5121,
224
],
"parent": "9ce976993b9a9912"
},
"75ac145d86289af2": {
"id": "75ac145d86289af2",
"name": "bitbybit.groups.group",
"customName": "Inputs",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 488,
"groupHeight": 524,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
0,
0
]
},
"26f8971864a7887c": {
"id": "26f8971864a7887c",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Inputs\nThe arm's length and the propeller's diameter. While you edit the module, each input's sample stands in for the value an instance gives it.",
"commentWidth": 440,
"commentHeight": 158,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
24,
64
],
"parent": "75ac145d86289af2"
},
"38425cb505bd4cd3": {
"id": "38425cb505bd4cd3",
"name": "bitbybit.modules.input",
"customName": "propeller",
"async": false,
"drawable": false,
"data": {
"sample": "230"
},
"inputs": {},
"position": [
24,
385
],
"parent": "75ac145d86289af2"
},
"9ce976993b9a9912": {
"id": "9ce976993b9a9912",
"name": "bitbybit.groups.group",
"customName": "Outputs",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 488,
"groupHeight": 1058,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
5097,
0
]
},
"3848e51c9a55626e": {
"id": "3848e51c9a55626e",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Outputs\nOne output per material, so the main graph draws each in its colour.",
"commentWidth": 440,
"commentHeight": 136,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
5121,
64
],
"parent": "9ce976993b9a9912"
},
"2757fd89b3f9dad6": {
"id": "2757fd89b3f9dad6",
"name": "bitbybit.modules.output",
"customName": "motor",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"value": {
"connections": [
{
"node": "1f54a831d92fac57",
"output": "result",
"data": {}
}
]
}
},
"position": [
5121,
363
],
"parent": "9ce976993b9a9912"
},
"adf4b5329d721a17": {
"id": "adf4b5329d721a17",
"name": "bitbybit.modules.output",
"customName": "stator",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"value": {
"connections": [
{
"node": "e45adcf853e664a2",
"output": "result",
"data": {}
}
]
}
},
"position": [
5121,
502
],
"parent": "9ce976993b9a9912"
},
"2f5e7dadd32a2a97": {
"id": "2f5e7dadd32a2a97",
"name": "bitbybit.modules.output",
"customName": "propeller",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"value": {
"connections": [
{
"node": "7ebbc54fcdd43d41",
"output": "result",
"data": {}
}
]
}
},
"position": [
5121,
641
],
"parent": "9ce976993b9a9912"
},
"a014cc69ad13b58d": {
"id": "a014cc69ad13b58d",
"name": "bitbybit.modules.output",
"customName": "bolts",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"value": {
"connections": [
{
"node": "e787d6d72fb6256f",
"output": "result",
"data": {}
}
]
}
},
"position": [
5121,
780
],
"parent": "9ce976993b9a9912"
},
"99b2c2ef4d90fa9a": {
"id": "99b2c2ef4d90fa9a",
"name": "bitbybit.modules.output",
"customName": "light",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"value": {
"connections": [
{
"node": "c1cbdb49743d47cc",
"output": "result",
"data": {}
}
]
}
},
"position": [
5121,
919
],
"parent": "9ce976993b9a9912"
},
"506ad71d18d52b8a": {
"id": "506ad71d18d52b8a",
"name": "bitbybit.groups.group",
"customName": "Arm",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 3809,
"groupHeight": 1550,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
888,
0
]
},
"e42cb3803bcf6d11": {
"id": "e42cb3803bcf6d11",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Arm\nCarbon, 10 mm thick, narrowing from 26 mm at the root to 16 at the tip. A round pad at the tip carries the motor, and hexagon cut-outs lighten it.",
"commentWidth": 440,
"commentHeight": 158,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
912,
64
],
"parent": "506ad71d18d52b8a"
},
"72837ff64e2b0776": {
"id": "72837ff64e2b0776",
"name": "bitbybit.code.typeScriptEditor",
"customName": "outline points",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const start72837ff64e2b0776 = async (inputs: any, index: number) => {\n const tip = inputs - 12;\n return [[28, 0, -13], [tip, 0, -8], [tip, 0, 8], [28, 0, 13]];\n}"
}
},
"inputs": {
"inputs": {
"connections": [
{
"node": "module-input",
"output": "value",
"data": {}
}
]
}
},
"position": [
912,
246
],
"parent": "506ad71d18d52b8a"
},
"1546efbc1801e071": {
"id": "1546efbc1801e071",
"name": "bitbybit.occt.shapes.wire.createPolygonWire",
"customName": "arm outline",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"points": {
"connections": [
{
"node": "72837ff64e2b0776",
"output": "result",
"data": {}
}
]
}
},
"position": [
1606,
64
],
"parent": "506ad71d18d52b8a"
},
"ab61bea2ba2caced": {
"id": "ab61bea2ba2caced",
"name": "bitbybit.occt.fillets.fillet2d",
"customName": "rounded outline",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 4
},
"inputs": {
"shape": {
"connections": [
{
"node": "1546efbc1801e071",
"output": "result",
"data": {}
}
]
}
},
"position": [
2026,
64
],
"parent": "506ad71d18d52b8a"
},
"4aa3949aaa63f123": {
"id": "4aa3949aaa63f123",
"name": "bitbybit.occt.shapes.face.createFaceFromWire",
"customName": "arm face",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"planar": true
},
"inputs": {
"shape": {
"connections": [
{
"node": "ab61bea2ba2caced",
"output": "result",
"data": {}
}
]
}
},
"position": [
2445,
64
],
"parent": "506ad71d18d52b8a"
},
"7be06ef450947e48": {
"id": "7be06ef450947e48",
"name": "bitbybit.occt.operations.extrude",
"customName": "arm slab",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"direction": [
0,
10,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "4aa3949aaa63f123",
"output": "result",
"data": {}
}
]
}
},
"position": [
2819,
64
],
"parent": "506ad71d18d52b8a"
},
"89a1e06116bc0a02": {
"id": "89a1e06116bc0a02",
"name": "bitbybit.occt.transforms.translate",
"customName": "arm on plate",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"translation": [
0,
3,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "7be06ef450947e48",
"output": "result",
"data": {}
}
]
}
},
"position": [
3239,
64
],
"parent": "506ad71d18d52b8a"
},
"513a6045bd98eb7c": {
"id": "513a6045bd98eb7c",
"name": "bitbybit.point.pointXYZ",
"customName": "pad centre",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 3,
"z": 0
},
"inputs": {
"x": {
"connections": [
{
"node": "module-input",
"output": "value",
"data": {}
}
]
}
},
"position": [
912,
731
],
"parent": "506ad71d18d52b8a"
},
"dc27d9996a4bf4ad": {
"id": "dc27d9996a4bf4ad",
"name": "bitbybit.occt.shapes.solid.createCylinder",
"customName": "motor pad",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 15,
"height": 10,
"center": [
0,
0,
0
],
"direction": [
0,
1,
0
],
"angle": 360,
"originOnCenter": false
},
"inputs": {
"center": {
"connections": [
{
"node": "513a6045bd98eb7c",
"output": "result",
"data": {}
}
]
}
},
"position": [
1606,
326
],
"parent": "506ad71d18d52b8a"
},
"4a6553c33f36bbc8": {
"id": "4a6553c33f36bbc8",
"name": "bitbybit.lists.createList",
"customName": "arm parts",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "89a1e06116bc0a02",
"output": "result",
"data": {}
},
{
"node": "dc27d9996a4bf4ad",
"output": "result",
"data": {}
}
]
}
},
"position": [
3671,
64
],
"parent": "506ad71d18d52b8a"
},
"b2e5cfd6017943a5": {
"id": "b2e5cfd6017943a5",
"name": "bitbybit.occt.booleans.union",
"customName": "arm and pad",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"keepEdges": false,
"strategy": "oneAfterAnother"
},
"inputs": {
"shapes": {
"connections": [
{
"node": "4a6553c33f36bbc8",
"output": "list",
"data": {}
}
]
}
},
"position": [
4040,
64
],
"parent": "506ad71d18d52b8a"
},
"1b0215c3356f2e64": {
"id": "1b0215c3356f2e64",
"name": "bitbybit.code.typeScriptEditor",
"customName": "hex cut-outs",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const start1b0215c3356f2e64 = async (inputs: any, index: number) => {\n const length = inputs;\n const tip = length - 12;\n const holes = [];\n for (let x = 62; x < length - 34; x += 24) {\n const half = 13 + (8 - 13) * (x - 28) / (tip - 28);\n const hexagon = await bitbybit.occt.shapes.wire.createNGonWire({ nrCorners: 6, radius: Math.max(half - 3.5, 2.5), center: [x, 3, 0], direction: [0, 1, 0] });\n const rounded = await bitbybit.occt.fillets.fillet2d({ shape: hexagon, radius: 1.2 });\n const face = await bitbybit.occt.shapes.face.createFaceFromWire({ shape: rounded, planar: true });\n holes.push(await bitbybit.occt.operations.extrude({ shape: face, direction: [0, 10, 0] }));\n }\n return holes;\n}"
}
},
"inputs": {
"inputs": {
"connections": [
{
"node": "module-input",
"output": "value",
"data": {}
}
]
}
},
"position": [
912,
1065
],
"parent": "506ad71d18d52b8a"
},
"8a07407ef7d839e9": {
"id": "8a07407ef7d839e9",
"name": "bitbybit.occt.booleans.difference",
"customName": "arm",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"keepEdges": false,
"strategy": "oneAfterAnother"
},
"inputs": {
"shape": {
"connections": [
{
"node": "b2e5cfd6017943a5",
"output": "result",
"data": {}
}
]
},
"shapes": {
"connections": [
{
"node": "1b0215c3356f2e64",
"output": "result",
"data": {}
}
]
}
},
"position": [
4425,
64
],
"parent": "506ad71d18d52b8a"
},
"478e331a4831b516": {
"id": "478e331a4831b516",
"name": "bitbybit.groups.group",
"customName": "Motor",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 1434,
"groupHeight": 1200,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
888,
1670
]
},
"514c0f9754b38b5b": {
"id": "514c0f9754b38b5b",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Motor\nThe body is a profile revolved around the shaft, with a cavity and eight cooling slots cut away and the propeller nut on top. The copper stator shows through the slots.",
"commentWidth": 440,
"commentHeight": 180,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
912,
1734
],
"parent": "478e331a4831b516"
},
"5f9c31c1c34cb3dc": {
"id": "5f9c31c1c34cb3dc",
"name": "bitbybit.code.typeScriptEditor",
"customName": "motor",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const start5f9c31c1c34cb3dc = async (inputs: any, index: number) => {\n const revolved = async (points: number[][]) => {\n const outline = await bitbybit.occt.shapes.wire.createPolygonWire({ points });\n const face = await bitbybit.occt.shapes.face.createFaceFromWire({ shape: outline, planar: true });\n return bitbybit.occt.operations.revolve({ shape: face, angle: 360, direction: [0, 1, 0], copy: false });\n };\n const body = await revolved([[0, 0, 0], [13, 0, 0], [13, 3, 0], [8, 3, 0], [8, 6, 0], [14, 6, 0], [14, 19, 0], [12.8, 20, 0], [6, 20, 0], [6, 22, 0], [2.5, 22, 0], [2.5, 28, 0], [0, 28, 0]]);\n const cavity = await bitbybit.occt.shapes.solid.createCylinder({ radius: 12.4, height: 12, center: [0, 6, 0], direction: [0, 1, 0] });\n const bearing = await bitbybit.occt.shapes.solid.createCylinder({ radius: 4, height: 14, center: [0, 5, 0], direction: [0, 1, 0] });\n const ring = await bitbybit.occt.booleans.difference({ shape: cavity, shapes: [bearing], keepEdges: false });\n const cuts = [ring];\n for (let i = 0; i < 8; i++) {\n const slot = await bitbybit.occt.shapes.solid.createBox({ width: 2.2, length: 8, height: 9, center: [0, 13, 12] });\n cuts.push(await bitbybit.occt.transforms.rotate({ shape: slot, axis: [0, 1, 0], angle: i * 45 }));\n }\n const motor = await bitbybit.occt.booleans.difference({ shape: body, shapes: cuts, keepEdges: false });\n const hexagon = await bitbybit.occt.shapes.wire.createNGonWire({ nrCorners: 6, radius: 3.6, center: [0, 34, 0], direction: [0, 1, 0] });\n const hexFace = await bitbybit.occt.shapes.face.createFaceFromWire({ shape: hexagon, planar: true });\n const hex = await bitbybit.occt.operations.extrude({ shape: hexFace, direction: [0, 3.5, 0] });\n const chamfer = await revolved([[0, 34, 0], [2.9, 34, 0], [3.7, 34.7, 0], [3.7, 36.8, 0], [2.9, 37.5, 0], [0, 37.5, 0]]);\n const nut = await bitbybit.occt.booleans.intersection({ shapes: [hex, chamfer], keepEdges: false });\n return bitbybit.occt.shapes.compound.makeCompound({ shapes: [motor, nut] });\n}"
}
},
"inputs": {},
"position": [
912,
1938
],
"parent": "478e331a4831b516"
},
"922d44922010a2af": {
"id": "922d44922010a2af",
"name": "bitbybit.occt.shapes.solid.createCylinder",
"customName": "stator",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 11.8,
"height": 11,
"center": [
0,
6.5,
0
],
"direction": [
0,
1,
0
],
"angle": 360,
"originOnCenter": false
},
"inputs": {},
"position": [
912,
2423
],
"parent": "478e331a4831b516"
},
"6218b8fdb652fcc3": {
"id": "6218b8fdb652fcc3",
"name": "bitbybit.vector.vectorXYZ",
"customName": "motor position",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 13,
"z": 0
},
"inputs": {
"x": {
"connections": [
{
"node": "module-input",
"output": "value",
"data": {}
}
]
}
},
"position": [
1606,
1734
],
"parent": "478e331a4831b516"
},
"1f54a831d92fac57": {
"id": "1f54a831d92fac57",
"name": "bitbybit.occt.transforms.translate",
"customName": "motor at tip",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"translation": [
0,
0,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "5f9c31c1c34cb3dc",
"output": "result",
"data": {}
}
]
},
"translation": {
"connections": [
{
"node": "6218b8fdb652fcc3",
"output": "result",
"data": {}
}
]
}
},
"position": [
2016,
1734
],
"parent": "478e331a4831b516"
},
"e45adcf853e664a2": {
"id": "e45adcf853e664a2",
"name": "bitbybit.occt.transforms.translate",
"customName": "stator at tip",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"translation": [
0,
0,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "922d44922010a2af",
"output": "result",
"data": {}
}
]
},
"translation": {
"connections": [
{
"node": "6218b8fdb652fcc3",
"output": "result",
"data": {}
}
]
}
},
"position": [
2016,
2036
],
"parent": "478e331a4831b516"
},
"947579b9debcc85b": {
"id": "947579b9debcc85b",
"name": "bitbybit.groups.group",
"customName": "Propeller",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 2231,
"groupHeight": 1550,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
888,
2990
]
},
"140fcf4b90448668": {
"id": "140fcf4b90448668",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Propeller\nEach blade is lofted through five twisted ellipses, from a thick root to a thin, swept tip. A second blade half a turn round and a revolved hub complete it.",
"commentWidth": 440,
"commentHeight": 158,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
912,
3054
],
"parent": "947579b9debcc85b"
},
"41f9a7498bedbcf0": {
"id": "41f9a7498bedbcf0",
"name": "bitbybit.code.typeScriptEditor",
"customName": "blade loft",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const start41f9a7498bedbcf0 = async (inputs: any, index: number) => {\n const stations = [[0, 12, 3.2, 38, 0], [0.25, 17, 2.4, 24, 0.6], [0.5, 15.5, 1.8, 16, 1.8], [0.78, 11, 1.4, 11, 3.6], [1, 4.5, 1, 8, 6]];\n const root = 6;\n const span = inputs / 2 - root;\n const sections = [];\n for (const [t, chord, thickness, twist, sweep] of stations) {\n const r = root + span * t;\n const ellipse = await bitbybit.occt.shapes.wire.createEllipseWire({ center: [r, 0, sweep], direction: [1, 0, 0], radiusMinor: thickness / 2, radiusMajor: chord / 2 });\n sections.push(await bitbybit.occt.transforms.rotateAroundCenter({ shape: ellipse, angle: twist, center: [r, 0, sweep], axis: [1, 0, 0] }));\n }\n return bitbybit.occt.operations.loft({ shapes: sections, makeSolid: true });\n}"
}
},
"inputs": {
"inputs": {
"connections": [
{
"node": "38425cb505bd4cd3",
"output": "value",
"data": {}
}
]
}
},
"position": [
912,
3236
],
"parent": "947579b9debcc85b"
},
"a8f2ae1c6e0cbfed": {
"id": "a8f2ae1c6e0cbfed",
"name": "bitbybit.occt.transforms.rotate",
"customName": "second blade",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"axis": [
0,
1,
0
],
"angle": 180
},
"inputs": {
"shape": {
"connections": [
{
"node": "41f9a7498bedbcf0",
"output": "result",
"data": {}
}
]
}
},
"position": [
1606,
3054
],
"parent": "947579b9debcc85b"
},
"798ba4a04d640c64": {
"id": "798ba4a04d640c64",
"name": "bitbybit.code.typeScriptEditor",
"customName": "hub",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const start798ba4a04d640c64 = async (inputs: any, index: number) => {\n const outline = await bitbybit.occt.shapes.wire.createPolygonWire({ points: [[0, -5, 0], [8, -5, 0], [8, 4.5, 0], [6.5, 6.2, 0], [4.5, 7, 0], [0, 7, 0]] });\n const face = await bitbybit.occt.shapes.face.createFaceFromWire({ shape: outline, planar: true });\n return bitbybit.occt.operations.revolve({ shape: face, angle: 360, direction: [0, 1, 0], copy: false });\n}"
}
},
"inputs": {},
"position": [
912,
3721
],
"parent": "947579b9debcc85b"
},
"ac9b65293d5e3969": {
"id": "ac9b65293d5e3969",
"name": "bitbybit.lists.createList",
"customName": "propeller parts",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "798ba4a04d640c64",
"output": "result",
"data": {}
},
{
"node": "41f9a7498bedbcf0",
"output": "result",
"data": {}
},
{
"node": "a8f2ae1c6e0cbfed",
"output": "result",
"data": {}
}
]
}
},
"position": [
2000,
3054
],
"parent": "947579b9debcc85b"
},
"69f0125008ce2285": {
"id": "69f0125008ce2285",
"name": "bitbybit.occt.booleans.union",
"customName": "propeller",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"keepEdges": false,
"strategy": "oneAfterAnother"
},
"inputs": {
"shapes": {
"connections": [
{
"node": "ac9b65293d5e3969",
"output": "list",
"data": {}
}
]
}
},
"position": [
2419,
3054
],
"parent": "947579b9debcc85b"
},
"de06552cae0ceb34": {
"id": "de06552cae0ceb34",
"name": "bitbybit.vector.vectorXYZ",
"customName": "propeller position",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 40,
"z": 0
},
"inputs": {
"x": {
"connections": [
{
"node": "module-input",
"output": "value",
"data": {}
}
]
}
},
"position": [
912,
4206
],
"parent": "947579b9debcc85b"
},
"7ebbc54fcdd43d41": {
"id": "7ebbc54fcdd43d41",
"name": "bitbybit.occt.transforms.translate",
"customName": "propeller at tip",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"translation": [
0,
0,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "69f0125008ce2285",
"output": "result",
"data": {}
}
]
},
"translation": {
"connections": [
{
"node": "de06552cae0ceb34",
"output": "result",
"data": {}
}
]
}
},
"position": [
2788,
3054
],
"parent": "947579b9debcc85b"
},
"c79b17f598ffad71": {
"id": "c79b17f598ffad71",
"name": "bitbybit.groups.group",
"customName": "Bolts and light",
"async": false,
"drawable": false,
"data": {
"description": "",
"groupWidth": 622,
"groupHeight": 1216,
"groupColor": "#f0cebb",
"groupOpacity": 0.15
},
"inputs": {},
"position": [
888,
4660
]
},
"7673d5a370b1dd5e": {
"id": "7673d5a370b1dd5e",
"name": "bitbybit.comments.comment",
"customName": "Comment",
"async": false,
"drawable": false,
"data": {
"commentText": "### Bolts and light\nTwo bolts clamp the arm between the plates, four hold the motor from below, and an LED under the arm shows which way the drone faces.",
"commentWidth": 440,
"commentHeight": 158,
"commentTextColor": "#f0cebb",
"commentBackgroundColor": "#1a1c1f",
"commentOpacity": 0.85,
"commentTextScale": 1
},
"inputs": {},
"position": [
912,
4724
],
"parent": "c79b17f598ffad71"
},
"e787d6d72fb6256f": {
"id": "e787d6d72fb6256f",
"name": "bitbybit.code.typeScriptEditor",
"customName": "arm bolts",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const starte787d6d72fb6256f = async (inputs: any, index: number) => {\n const length = inputs;\n const bolt = async (size: number) => {\n const profile = [[0, -3, 0], [2.35, -3, 0], [2.75, -2.6, 0], [2.75, 0, 0], [1.5, 0, 0], [1.5, size - 0.4, 0], [1.1, size, 0], [0, size, 0]];\n const outline = await bitbybit.occt.shapes.wire.createPolygonWire({ points: profile });\n const face = await bitbybit.occt.shapes.face.createFaceFromWire({ shape: outline, planar: true });\n return bitbybit.occt.operations.revolve({ shape: face, angle: 360, direction: [0, 1, 0], copy: false });\n };\n const clamp = await bitbybit.occt.transforms.rotate({ shape: await bolt(16), axis: [1, 0, 0], angle: 180 });\n const motorBolt = await bolt(12);\n const placed = [];\n for (const x of [34, 44]) {\n placed.push(await bitbybit.occt.transforms.translate({ shape: clamp, translation: [x, 16, 0] }));\n }\n for (const angle of [45, 135, 225, 315]) {\n const a = angle * Math.PI / 180;\n placed.push(await bitbybit.occt.transforms.translate({ shape: motorBolt, translation: [length + 8 * Math.cos(a), 3, 8 * Math.sin(a)] }));\n }\n return bitbybit.occt.shapes.compound.makeCompound({ shapes: placed });\n}"
}
},
"inputs": {
"inputs": {
"connections": [
{
"node": "module-input",
"output": "value",
"data": {}
}
]
}
},
"position": [
912,
4906
],
"parent": "c79b17f598ffad71"
},
"c1cbdb49743d47cc": {
"id": "c1cbdb49743d47cc",
"name": "bitbybit.code.typeScriptEditor",
"customName": "light",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": true
},
"options": {},
"code": {
"code": "const startc1cbdb49743d47cc = async (inputs: any, index: number) => {\n const dome = await bitbybit.occt.shapes.solid.createSphere({ radius: 3, center: [inputs - 24, 3, 0] });\n const above = await bitbybit.occt.shapes.solid.createBox({ width: 8, length: 8, height: 4, center: [inputs - 24, 5, 0] });\n return bitbybit.occt.booleans.difference({ shape: dome, shapes: [above], keepEdges: false });\n}"
}
},
"inputs": {
"inputs": {
"connections": [
{
"node": "module-input",
"output": "value",
"data": {}
}
]
}
},
"position": [
912,
5391
],
"parent": "c79b17f598ffad71"
}
},
"modules": {}
}
}
}
The finished script is also the Rete showcase, to download and open.
Verified against the product in October 2026

