Twisted Polygon Ornament
Create an elegant twisted ornament by systematically rotating and scaling hexagonal wire profiles, then connecting them with a lofting operation. This produces a sophisticated spiraling form from simple geometric transformations.
- Rete
- Blockly
- TypeScript
{
"id": "rete-v2-json",
"nodes": {
"c940f73fedde5be2": {
"id": "c940f73fedde5be2",
"name": "bitbybit.occt.shapes.wire.createNGonWire",
"customName": "ngon wire",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"center": [
0,
0,
0
],
"direction": [
0,
1,
0
],
"nrCorners": 6,
"radius": 1
},
"inputs": {
"nrCorners": {
"connections": [
{
"node": "2779cb88a00fc8f0",
"output": "result",
"data": {}
}
]
}
},
"position": [
-87.16935946327095,
385.84712462819857
]
},
"0198547716a2313c": {
"id": "0198547716a2313c",
"name": "bitbybit.vector.span",
"customName": "span",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"step": 1,
"min": 0,
"max": 10
},
"inputs": {},
"position": [
-653.172394259992,
868.9277466168596
]
},
"ec5067979e4247cf": {
"id": "ec5067979e4247cf",
"name": "bitbybit.occt.transforms.rotate",
"customName": "rotate",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"axis": [
0,
0,
1
],
"angle": 0
},
"inputs": {
"shape": {
"connections": [
{
"node": "c940f73fedde5be2",
"output": "result",
"data": {}
}
]
},
"angle": {
"connections": [
{
"node": "3c9f0071f95bee4d",
"output": "result",
"data": {}
}
]
}
},
"position": [
1494.5553911714715,
397.3367197861394
]
},
"714701dc00622a7f": {
"id": "714701dc00622a7f",
"name": "bitbybit.lists.flatten",
"customName": "flatten",
"data": {
"nrLevels": 1
},
"inputs": {
"list": {
"connections": [
{
"node": "0198547716a2313c",
"output": "result",
"data": {}
}
]
}
},
"position": [
-83.86211683676447,
909.6067279607852
]
},
"3b161acbd21e120e": {
"id": "3b161acbd21e120e",
"name": "bitbybit.occt.transforms.scale",
"customName": "scale",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": true,
"flatten": 0,
"forceExecution": false
},
"factor": 1
},
"inputs": {
"shape": {
"connections": [
{
"node": "ec5067979e4247cf",
"output": "result",
"data": {}
}
]
},
"factor": {
"connections": [
{
"node": "fb3df9487e3944bf",
"output": "result",
"data": {}
}
]
}
},
"position": [
2165.2014549782243,
650.3406866388525
]
},
"3c9f0071f95bee4d": {
"id": "3c9f0071f95bee4d",
"name": "bitbybit.math.multiply",
"customName": "multiply",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"first": 1,
"second": 9
},
"inputs": {
"first": {
"connections": [
{
"node": "714701dc00622a7f",
"output": "result",
"data": {}
}
]
}
},
"position": [
1012.5593269579366,
-90.10569891713044
]
},
"fb3df9487e3944bf": {
"id": "fb3df9487e3944bf",
"name": "bitbybit.math.add",
"customName": "add",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"first": 1,
"second": 1
},
"inputs": {
"first": {
"connections": [
{
"node": "714701dc00622a7f",
"output": "result",
"data": {}
}
]
}
},
"position": [
1501.7217074766622,
887.2475931536995
]
},
"0c60bbacc9c096f5": {
"id": "0c60bbacc9c096f5",
"name": "bitbybit.occt.shapes.wire.createNGonWire",
"customName": "ngon wire",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"center": [
0,
0,
0
],
"direction": [
0,
1,
0
],
"nrCorners": 6,
"radius": 1
},
"inputs": {
"center": {
"connections": [
{
"node": "c737b0ca10acd566",
"output": "result",
"data": {}
}
]
},
"nrCorners": {
"connections": [
{
"node": "2779cb88a00fc8f0",
"output": "result",
"data": {}
}
]
}
},
"position": [
-88.78951325568744,
-18.839483037047426
]
},
"c737b0ca10acd566": {
"id": "c737b0ca10acd566",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 0.1,
"z": 0
},
"inputs": {},
"position": [
-1801.0635278579464,
-469.1893598863592
]
},
"e6436e6e2641d71d": {
"id": "e6436e6e2641d71d",
"name": "bitbybit.occt.transforms.rotate",
"customName": "rotate",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"axis": [
0,
0,
1
],
"angle": 0
},
"inputs": {
"shape": {
"connections": [
{
"node": "0c60bbacc9c096f5",
"output": "result",
"data": {}
}
]
},
"angle": {
"connections": [
{
"node": "3c9f0071f95bee4d",
"output": "result",
"data": {}
}
]
}
},
"position": [
1494.0385249150322,
31.935564634602997
]
},
"040363eedce66d1f": {
"id": "040363eedce66d1f",
"name": "bitbybit.occt.transforms.scale",
"customName": "scale",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": true,
"flatten": 0,
"forceExecution": false
},
"factor": 1
},
"inputs": {
"shape": {
"connections": [
{
"node": "e6436e6e2641d71d",
"output": "result",
"data": {}
}
]
},
"factor": {
"connections": [
{
"node": "fb3df9487e3944bf",
"output": "result",
"data": {}
}
]
}
},
"position": [
2169.0391619967213,
317.719741248141
]
},
"8a78204118e8596d": {
"id": "8a78204118e8596d",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "040363eedce66d1f",
"output": "result",
"data": {}
}
]
}
},
"position": [
2660.5135826108144,
292.7677721491148
]
},
"f1d2dfdba5169989": {
"id": "f1d2dfdba5169989",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "3b161acbd21e120e",
"output": "result",
"data": {}
}
]
}
},
"position": [
2659.9204742065085,
469.9660469532882
]
},
"fd6e78fa2e6ebc3d": {
"id": "fd6e78fa2e6ebc3d",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "f1d2dfdba5169989",
"output": "list",
"data": {}
},
{
"node": "8a78204118e8596d",
"output": "list",
"data": {}
}
]
}
},
"position": [
3060.0930647846803,
313.9824469455675
]
},
"e7d38cbb4e9f33d4": {
"id": "e7d38cbb4e9f33d4",
"name": "bitbybit.lists.flipLists",
"customName": "flip lists",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"clone": true
},
"inputs": {
"list": {
"connections": [
{
"node": "fd6e78fa2e6ebc3d",
"output": "list",
"data": {}
}
]
}
},
"position": [
3880.6439413727367,
273.36344350257474
]
},
"a22008dbfa0f5e85": {
"id": "a22008dbfa0f5e85",
"name": "bitbybit.lists.flatten",
"customName": "flatten",
"data": {
"nrLevels": 2
},
"inputs": {
"list": {
"connections": [
{
"node": "e7d38cbb4e9f33d4",
"output": "result",
"data": {}
}
]
}
},
"position": [
4272.789138552096,
310.39484125558005
]
},
"56bada98da8952ba": {
"id": "56bada98da8952ba",
"name": "bitbybit.occt.operations.loftAdvanced",
"customName": "loft advanced",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"makeSolid": false,
"closed": true,
"periodic": false,
"straight": true,
"nrPeriodicSections": 10,
"useSmoothing": false,
"maxUDegree": 3,
"tolerance": 1e-7,
"parType": "approxCentripetal"
},
"inputs": {
"shapes": {
"connections": [
{
"node": "81e2e67326e5ed6e",
"output": "result",
"data": {}
}
]
}
},
"position": [
7374.800524510511,
1.3864378914565236
]
},
"24ef7b7392f56669": {
"id": "24ef7b7392f56669",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "a22008dbfa0f5e85",
"output": "result",
"data": {}
}
]
}
},
"position": [
4657.578225380678,
309.24755272180926
]
},
"03697e061e74921b": {
"id": "03697e061e74921b",
"name": "bitbybit.occt.shapes.wire.createNGonWire",
"customName": "ngon wire",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"center": [
0,
0,
0
],
"direction": [
0,
1,
0
],
"nrCorners": 6,
"radius": 1
},
"inputs": {
"center": {
"connections": [
{
"node": "774e9423dd36e71e",
"output": "result",
"data": {}
}
]
},
"nrCorners": {
"connections": [
{
"node": "2779cb88a00fc8f0",
"output": "result",
"data": {}
}
]
}
},
"position": [
-101.62434774797674,
-417.2427481304569
]
},
"774e9423dd36e71e": {
"id": "774e9423dd36e71e",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 0.2,
"z": 0
},
"inputs": {},
"position": [
-1806.86486618717,
-824.234792918588
]
},
"e9ca3e32bf63589f": {
"id": "e9ca3e32bf63589f",
"name": "bitbybit.occt.transforms.rotate",
"customName": "rotate",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"axis": [
0,
0,
1
],
"angle": 0
},
"inputs": {
"angle": {
"connections": [
{
"node": "3c9f0071f95bee4d",
"output": "result",
"data": {}
}
]
},
"shape": {
"connections": [
{
"node": "03697e061e74921b",
"output": "result",
"data": {}
}
]
}
},
"position": [
1495.7499741235242,
-339.7493322608073
]
},
"107d436a90f06935": {
"id": "107d436a90f06935",
"name": "bitbybit.occt.transforms.scale",
"customName": "scale",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": true,
"flatten": 0,
"forceExecution": false
},
"factor": 1
},
"inputs": {
"factor": {
"connections": [
{
"node": "fb3df9487e3944bf",
"output": "result",
"data": {}
}
]
},
"shape": {
"connections": [
{
"node": "e9ca3e32bf63589f",
"output": "result",
"data": {}
}
]
}
},
"position": [
2172.107922047001,
-17.142228048668002
]
},
"605c138b5f0cbf75": {
"id": "605c138b5f0cbf75",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "107d436a90f06935",
"output": "result",
"data": {}
}
]
}
},
"position": [
2658.97111853101,
107.53338054515552
]
},
"1d563348ef9bd7db": {
"id": "1d563348ef9bd7db",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "c61d98eea835f811",
"output": "list",
"data": {}
},
{
"node": "605c138b5f0cbf75",
"output": "list",
"data": {}
}
]
}
},
"position": [
3066.986712318514,
-3.505170813094793
]
},
"1c7847065f643162": {
"id": "1c7847065f643162",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 0.3,
"z": 0
},
"inputs": {},
"position": [
-1809.1115358871393,
-1178.4475560164922
]
},
"972d1c0f36ff6baf": {
"id": "972d1c0f36ff6baf",
"name": "bitbybit.occt.shapes.wire.createNGonWire",
"customName": "ngon wire",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"center": [
0,
0,
0
],
"direction": [
0,
1,
0
],
"nrCorners": 6,
"radius": 1
},
"inputs": {
"center": {
"connections": [
{
"node": "1c7847065f643162",
"output": "result",
"data": {}
}
]
},
"nrCorners": {
"connections": [
{
"node": "2779cb88a00fc8f0",
"output": "result",
"data": {}
}
]
}
},
"position": [
-102.9470664913074,
-821.8450852049377
]
},
"90ddb85834879414": {
"id": "90ddb85834879414",
"name": "bitbybit.occt.transforms.rotate",
"customName": "rotate",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"axis": [
0,
0,
1
],
"angle": 0
},
"inputs": {
"shape": {
"connections": [
{
"node": "972d1c0f36ff6baf",
"output": "result",
"data": {}
}
]
},
"angle": {
"connections": [
{
"node": "3c9f0071f95bee4d",
"output": "result",
"data": {}
}
]
}
},
"position": [
1495.5574110552545,
-703.1003748033835
]
},
"2a8586568646b04f": {
"id": "2a8586568646b04f",
"name": "bitbybit.occt.transforms.scale",
"customName": "scale",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": true,
"flatten": 0,
"forceExecution": false
},
"factor": 1
},
"inputs": {
"factor": {
"connections": [
{
"node": "fb3df9487e3944bf",
"output": "result",
"data": {}
}
]
},
"shape": {
"connections": [
{
"node": "90ddb85834879414",
"output": "result",
"data": {}
}
]
}
},
"position": [
2170.044982617886,
-342.69805855121587
]
},
"c61d98eea835f811": {
"id": "c61d98eea835f811",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "2a8586568646b04f",
"output": "result",
"data": {}
}
]
}
},
"position": [
2657.4727639232765,
-68.35808329918291
]
},
"65197945a7cd704f": {
"id": "65197945a7cd704f",
"name": "bitbybit.lists.flipLists",
"customName": "flip lists",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"clone": true
},
"inputs": {
"list": {
"connections": [
{
"node": "1d563348ef9bd7db",
"output": "list",
"data": {}
}
]
}
},
"position": [
3481.056470376855,
-41.87163625694573
]
},
"faaef7a05f31e6ff": {
"id": "faaef7a05f31e6ff",
"name": "bitbybit.lists.flatten",
"customName": "flatten",
"data": {
"nrLevels": 2
},
"inputs": {
"list": {
"connections": [
{
"node": "65197945a7cd704f",
"output": "result",
"data": {}
}
]
}
},
"position": [
3867.5386094499654,
-2.5367948981930155
]
},
"ef0b526a33c0a0c2": {
"id": "ef0b526a33c0a0c2",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "faaef7a05f31e6ff",
"output": "result",
"data": {}
}
]
}
},
"position": [
4269.895185508352,
-0.40579425228959565
]
},
"58c84e9563b18e34": {
"id": "58c84e9563b18e34",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "5b39fbca9da96365",
"output": "result",
"data": {}
},
{
"node": "1a09b103719ce747",
"output": "result",
"data": {}
}
]
}
},
"position": [
5803.759298214255,
49.2151469243704
]
},
"733f5834e3bf05ed": {
"id": "733f5834e3bf05ed",
"name": "bitbybit.lists.flatten",
"customName": "flatten",
"data": {
"nrLevels": 2
},
"inputs": {
"list": {
"connections": [
{
"node": "58c84e9563b18e34",
"output": "list",
"data": {}
}
]
}
},
"position": [
6194.859378928453,
46.18448252792308
]
},
"9b3d411b5e91db23": {
"id": "9b3d411b5e91db23",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "733f5834e3bf05ed",
"output": "result",
"data": {}
}
]
}
},
"position": [
6579.826735266703,
48.01328770052231
]
},
"9e51fc1e5e621544": {
"id": "9e51fc1e5e621544",
"name": "bitbybit.lists.reverse",
"customName": "reverse",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"clone": true
},
"inputs": {
"list": {
"connections": [
{
"node": "ef0b526a33c0a0c2",
"output": "list",
"data": {}
}
]
}
},
"position": [
4653.1410209858905,
-38.91295836325259
]
},
"81e2e67326e5ed6e": {
"id": "81e2e67326e5ed6e",
"name": "bitbybit.lists.reverse",
"customName": "reverse",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"clone": true
},
"inputs": {
"list": {
"connections": [
{
"node": "9b3d411b5e91db23",
"output": "list",
"data": {}
}
]
}
},
"position": [
6995.404533601065,
6.110107908921407
]
},
"b58b5737b0636b4c": {
"id": "b58b5737b0636b4c",
"name": "bitbybit.occt.shapes.shape.unifySameDomain",
"customName": "unify same domain",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"unifyEdges": true,
"unifyFaces": true,
"concatBSplines": true
},
"inputs": {
"shape": {
"connections": [
{
"node": "56bada98da8952ba",
"output": "result",
"data": {}
}
]
}
},
"position": [
7877.537523975781,
258.9942183762652
]
},
"2779cb88a00fc8f0": {
"id": "2779cb88a00fc8f0",
"name": "bitbybit.math.numberSlider",
"customName": "number slider",
"data": {
"options": {
"min": 6,
"max": 12,
"step": 1,
"width": 350,
"updateOnDrag": false
},
"number": 6
},
"inputs": {},
"position": [
-1925.2393139234562,
51.84532205098242
]
},
"274aa88520a40ef9": {
"id": "274aa88520a40ef9",
"name": "bitbybit.babylon.scene.enableSkybox",
"customName": "enable skybox",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"skybox": "city",
"size": 1000,
"blur": 0.3,
"environmentIntensity": 0.7,
"hideSkybox": true
},
"inputs": {},
"position": [
-654.3959515533811,
1285.928408905116
]
},
"ecc3ad58da1fa136": {
"id": "ecc3ad58da1fa136",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "draw any async",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"entity": {
"connections": [
{
"node": "b58b5737b0636b4c",
"output": "result",
"data": {}
}
]
},
"options": {
"connections": [
{
"node": "1780b9e4e289352d",
"output": "result",
"data": {}
}
]
}
},
"position": [
8377.0919800693,
404.01336264627315
]
},
"1780b9e4e289352d": {
"id": "1780b9e4e289352d",
"name": "bitbybit.draw.optionsOcctShapeMaterial",
"customName": "options occt shape material",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"precision": 0.01,
"drawEdges": true,
"edgeColour": "#ffffff",
"edgeWidth": 2
},
"inputs": {
"faceMaterial": {
"connections": [
{
"node": "cc03d2ce513efde3",
"output": "result",
"data": {}
}
]
}
},
"position": [
7876.583305071206,
673.095271080181
]
},
"cc03d2ce513efde3": {
"id": "cc03d2ce513efde3",
"name": "bitbybit.babylon.material.pbrMetallicRoughness.create",
"customName": "pbr metallic roughness",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"name": "Custom Material",
"baseColor": "#94ffd1",
"emissiveColor": "#000000",
"metallic": 0.9,
"roughness": 0.3,
"alpha": 1,
"backFaceCulling": false,
"zOffset": 2
},
"inputs": {},
"position": [
7384.2112593530765,
773.1097567048442
]
},
"5b39fbca9da96365": {
"id": "5b39fbca9da96365",
"name": "bitbybit.lists.removeFirstItem",
"customName": "remove first item",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"clone": true
},
"inputs": {
"list": {
"connections": [
{
"node": "24ef7b7392f56669",
"output": "list",
"data": {}
}
]
}
},
"position": [
5045.948536351465,
270.0039632572086
]
},
"1a09b103719ce747": {
"id": "1a09b103719ce747",
"name": "bitbybit.lists.removeLastItem",
"customName": "remove last item",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"clone": true
},
"inputs": {
"list": {
"connections": [
{
"node": "9e51fc1e5e621544",
"output": "result",
"data": {}
}
]
}
},
"position": [
5046.031470068248,
-39.89860548013917
]
}
}
}
<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="nrCorners">nrCorners</variable><variable id="wire1">wire1</variable><variable id="wire2">wire2</variable><variable id="wire3">wire3</variable><variable id="wire4">wire4</variable><variable id="list1">list1</variable><variable id="list2">list2</variable><variable id="i">i</variable><variable id="angle">angle</variable><variable id="factor">factor</variable><variable id="tempShape">tempShape</variable><variable id="finalList">finalList</variable><variable id="item">item</variable><variable id="loftShape">loftShape</variable><variable id="unifiedShape">unifiedShape</variable></variables><block type="bitbybit.babylon.scene.enableSkybox" id="o8FWi-@{6wx*O:[6HauY" x="0" y="-316"><value name="Skybox"><block type="bitbybit.babylon.enums.skyboxEnum" id="}#iP5mnR??_)Rgd#Exw("><field name="bitbybit.babylon.enums.skyboxEnum">'city'</field></block></value><value name="Size"><block type="math_number" id="e0[]j@=KJdEw,{:?^;op"><field name="NUM">1000</field></block></value><value name="Blur"><block type="math_number" id="kOaN7x[5tD6lUiV0,t+["><field name="NUM">0.23</field></block></value><value name="EnvironmentIntensity"><block type="math_number" id="O@d,m9^dlJkU5L/*3Vg7"><field name="NUM">0.7</field></block></value><value name="HideSkybox"><block type="logic_boolean" id="qbCO#(e#AWBF8v-!Nf@X"><field name="BOOL">TRUE</field></block></value><next><block type="variables_set" id="setCorners"><field name="VAR" id="nrCorners">nrCorners</field><value name="VALUE"><block type="math_number" id="cornersVal"><field name="NUM">6</field></block></value><next><block type="variables_set" id="sW1"><field name="VAR" id="wire1">wire1</field><value name="VALUE"><block type="base_time_await_return" id="aw1"><value name="Promise"><block type="bitbybit.occt.shapes.wire.createNGonWire" id="ng1"><value name="Center"><block type="bitbybit.vector.vectorXYZ" id="vc1"><value name="X"><block type="math_number" id="x1"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="y1"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="z1"><field name="NUM">0</field></block></value></block></value><value name="Direction"><block type="bitbybit.vector.vectorXYZ" id="vd1"><value name="X"><block type="math_number" id="dx1"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="dy1"><field name="NUM">1</field></block></value><value name="Z"><block type="math_number" id="dz1"><field name="NUM">0</field></block></value></block></value><value name="NrCorners"><block type="variables_get" id="gc1"><field name="VAR" id="nrCorners">nrCorners</field></block></value><value name="Radius"><block type="math_number" id="rad1"><field name="NUM">1</field></block></value></block></value></block></value><next><block type="variables_set" id="sW2"><field name="VAR" id="wire2">wire2</field><value name="VALUE"><block type="base_time_await_return" id="aw2"><value name="Promise"><block type="bitbybit.occt.shapes.wire.createNGonWire" id="ng2"><value name="Center"><block type="bitbybit.vector.vectorXYZ" id="vc2"><value name="X"><block type="math_number" id="x2"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="y2"><field name="NUM">0.1</field></block></value><value name="Z"><block type="math_number" id="z2"><field name="NUM">0</field></block></value></block></value><value name="Direction"><block type="bitbybit.vector.vectorXYZ" id="vd2"><value name="X"><block type="math_number" id="dx2"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="dy2"><field name="NUM">1</field></block></value><value name="Z"><block type="math_number" id="dz2"><field name="NUM">0</field></block></value></block></value><value name="NrCorners"><block type="variables_get" id="gc2"><field name="VAR" id="nrCorners">nrCorners</field></block></value><value name="Radius"><block type="math_number" id="rad2"><field name="NUM">1</field></block></value></block></value></block></value><next><block type="variables_set" id="sW3"><field name="VAR" id="wire3">wire3</field><value name="VALUE"><block type="base_time_await_return" id="aw3"><value name="Promise"><block type="bitbybit.occt.shapes.wire.createNGonWire" id="ng3"><value name="Center"><block type="bitbybit.vector.vectorXYZ" id="vc3"><value name="X"><block type="math_number" id="x3"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="y3"><field name="NUM">0.2</field></block></value><value name="Z"><block type="math_number" id="z3"><field name="NUM">0</field></block></value></block></value><value name="Direction"><block type="bitbybit.vector.vectorXYZ" id="vd3"><value name="X"><block type="math_number" id="dx3"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="dy3"><field name="NUM">1</field></block></value><value name="Z"><block type="math_number" id="dz3"><field name="NUM">0</field></block></value></block></value><value name="NrCorners"><block type="variables_get" id="gc3"><field name="VAR" id="nrCorners">nrCorners</field></block></value><value name="Radius"><block type="math_number" id="rad3"><field name="NUM">1</field></block></value></block></value></block></value><next><block type="variables_set" id="sW4"><field name="VAR" id="wire4">wire4</field><value name="VALUE"><block type="base_time_await_return" id="aw4"><value name="Promise"><block type="bitbybit.occt.shapes.wire.createNGonWire" id="ng4"><value name="Center"><block type="bitbybit.vector.vectorXYZ" id="vc4"><value name="X"><block type="math_number" id="x4"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="y4"><field name="NUM">0.3</field></block></value><value name="Z"><block type="math_number" id="z4"><field name="NUM">0</field></block></value></block></value><value name="Direction"><block type="bitbybit.vector.vectorXYZ" id="vd4"><value name="X"><block type="math_number" id="dx4"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="dy4"><field name="NUM">1</field></block></value><value name="Z"><block type="math_number" id="dz4"><field name="NUM">0</field></block></value></block></value><value name="NrCorners"><block type="variables_get" id="gc4"><field name="VAR" id="nrCorners">nrCorners</field></block></value><value name="Radius"><block type="math_number" id="rad4"><field name="NUM">1</field></block></value></block></value></block></value><next><block type="variables_set" id="iL1"><field name="VAR" id="list1">list1</field><value name="VALUE"><block type="lists_create_with" id="lc1"><mutation items="0"></mutation></block></value><next><block type="variables_set" id="iL2"><field name="VAR" id="list2">list2</field><value name="VALUE"><block type="lists_create_with" id="lc2"><mutation items="0"></mutation></block></value><next><block type="controls_for" id="loop"><field name="VAR" id="i">i</field><value name="FROM"><block type="math_number" id="lFr"><field name="NUM">0</field></block></value><value name="TO"><block type="math_number" id="lTo"><field name="NUM">10</field></block></value><value name="BY"><block type="math_number" id="lBy"><field name="NUM">1</field></block></value><statement name="DO"><block type="variables_set" id="sAng"><field name="VAR" id="angle">angle</field><value name="VALUE"><block type="math_arithmetic" id="cAng"><field name="OP">MULTIPLY</field><value name="A"><block type="variables_get" id="gi1"><field name="VAR" id="i">i</field></block></value><value name="B"><block type="math_number" id="n9"><field name="NUM">9</field></block></value></block></value><next><block type="variables_set" id="sFac"><field name="VAR" id="factor">factor</field><value name="VALUE"><block type="math_arithmetic" id="cFac"><field name="OP">ADD</field><value name="A"><block type="variables_get" id="gi2"><field name="VAR" id="i">i</field></block></value><value name="B"><block type="math_number" id="n1"><field name="NUM">1</field></block></value></block></value><next><block type="variables_set" id="tr1"><field name="VAR" id="tempShape">tempShape</field><value name="VALUE"><block type="base_time_await_return" id="awr1"><value name="Promise"><block type="bitbybit.occt.transforms.rotate" id="rot1"><value name="Shape"><block type="variables_get" id="gw1"><field name="VAR" id="wire1">wire1</field></block></value><value name="Axis"><block type="bitbybit.vector.vectorXYZ" id="ax1"><value name="X"><block type="math_number" id="ax1x"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="ax1y"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="ax1z"><field name="NUM">1</field></block></value></block></value><value name="Angle"><block type="variables_get" id="ga1"><field name="VAR" id="angle">angle</field></block></value></block></value></block></value><next><block type="variables_set" id="ts1"><field name="VAR" id="tempShape">tempShape</field><value name="VALUE"><block type="base_time_await_return" id="aws1"><value name="Promise"><block type="bitbybit.occt.transforms.scale" id="sca1"><value name="Shape"><block type="variables_get" id="gt1"><field name="VAR" id="tempShape">tempShape</field></block></value><value name="Factor"><block type="variables_get" id="gf1"><field name="VAR" id="factor">factor</field></block></value></block></value></block></value><next><block type="lists_setIndex" id="li1"><mutation at="false"></mutation><field name="MODE">INSERT</field><field name="WHERE">LAST</field><value name="LIST"><block type="variables_get" id="gl1"><field name="VAR" id="list1">list1</field></block></value><value name="TO"><block type="variables_get" id="gt2"><field name="VAR" id="tempShape">tempShape</field></block></value><next><block type="variables_set" id="tr2"><field name="VAR" id="tempShape">tempShape</field><value name="VALUE"><block type="base_time_await_return" id="awr2"><value name="Promise"><block type="bitbybit.occt.transforms.rotate" id="rot2"><value name="Shape"><block type="variables_get" id="gw2"><field name="VAR" id="wire2">wire2</field></block></value><value name="Axis"><block type="bitbybit.vector.vectorXYZ" id="ax2"><value name="X"><block type="math_number" id="ax2x"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="ax2y"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="ax2z"><field name="NUM">1</field></block></value></block></value><value name="Angle"><block type="variables_get" id="ga2"><field name="VAR" id="angle">angle</field></block></value></block></value></block></value><next><block type="variables_set" id="ts2"><field name="VAR" id="tempShape">tempShape</field><value name="VALUE"><block type="base_time_await_return" id="aws2"><value name="Promise"><block type="bitbybit.occt.transforms.scale" id="sca2"><value name="Shape"><block type="variables_get" id="gt3"><field name="VAR" id="tempShape">tempShape</field></block></value><value name="Factor"><block type="variables_get" id="gf2"><field name="VAR" id="factor">factor</field></block></value></block></value></block></value><next><block type="lists_setIndex" id="li2"><mutation at="false"></mutation><field name="MODE">INSERT</field><field name="WHERE">LAST</field><value name="LIST"><block type="variables_get" id="gl2"><field name="VAR" id="list1">list1</field></block></value><value name="TO"><block type="variables_get" id="gt4"><field name="VAR" id="tempShape">tempShape</field></block></value><next><block type="variables_set" id="tr4"><field name="VAR" id="tempShape">tempShape</field><value name="VALUE"><block type="base_time_await_return" id="awr4"><value name="Promise"><block type="bitbybit.occt.transforms.rotate" id="rot4"><value name="Shape"><block type="variables_get" id="gw4"><field name="VAR" id="wire4">wire4</field></block></value><value name="Axis"><block type="bitbybit.vector.vectorXYZ" id="ax4"><value name="X"><block type="math_number" id="ax4x"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="ax4y"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="ax4z"><field name="NUM">1</field></block></value></block></value><value name="Angle"><block type="variables_get" id="ga4"><field name="VAR" id="angle">angle</field></block></value></block></value></block></value><next><block type="variables_set" id="ts4"><field name="VAR" id="tempShape">tempShape</field><value name="VALUE"><block type="base_time_await_return" id="aws4"><value name="Promise"><block type="bitbybit.occt.transforms.scale" id="sca4"><value name="Shape"><block type="variables_get" id="gt7"><field name="VAR" id="tempShape">tempShape</field></block></value><value name="Factor"><block type="variables_get" id="gf4"><field name="VAR" id="factor">factor</field></block></value></block></value></block></value><next><block type="lists_setIndex" id="li4"><mutation at="false"></mutation><field name="MODE">INSERT</field><field name="WHERE">LAST</field><value name="LIST"><block type="variables_get" id="gl4"><field name="VAR" id="list2">list2</field></block></value><value name="TO"><block type="variables_get" id="gt8"><field name="VAR" id="tempShape">tempShape</field></block></value><next><block type="variables_set" id="tr3"><field name="VAR" id="tempShape">tempShape</field><value name="VALUE"><block type="base_time_await_return" id="awr3"><value name="Promise"><block type="bitbybit.occt.transforms.rotate" id="rot3"><value name="Shape"><block type="variables_get" id="gw3"><field name="VAR" id="wire3">wire3</field></block></value><value name="Axis"><block type="bitbybit.vector.vectorXYZ" id="ax3"><value name="X"><block type="math_number" id="ax3x"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="ax3y"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="ax3z"><field name="NUM">1</field></block></value></block></value><value name="Angle"><block type="variables_get" id="ga3"><field name="VAR" id="angle">angle</field></block></value></block></value></block></value><next><block type="variables_set" id="ts3"><field name="VAR" id="tempShape">tempShape</field><value name="VALUE"><block type="base_time_await_return" id="aws3"><value name="Promise"><block type="bitbybit.occt.transforms.scale" id="sca3"><value name="Shape"><block type="variables_get" id="gt5"><field name="VAR" id="tempShape">tempShape</field></block></value><value name="Factor"><block type="variables_get" id="gf3"><field name="VAR" id="factor">factor</field></block></value></block></value></block></value><next><block type="lists_setIndex" id="li3"><mutation at="false"></mutation><field name="MODE">INSERT</field><field name="WHERE">LAST</field><value name="LIST"><block type="variables_get" id="gl3"><field name="VAR" id="list2">list2</field></block></value><value name="TO"><block type="variables_get" id="gt6"><field name="VAR" id="tempShape">tempShape</field></block></value></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></statement><next><block type="variables_set" id="rm1"><field name="VAR" id="list1">list1</field><value name="VALUE"><block type="bitbybit.lists.removeFirstItem" id="rf1"><value name="List"><block type="variables_get" id="gl1rm"><field name="VAR" id="list1">list1</field></block></value><value name="Clone"><block type="logic_boolean" id="cl1"><field name="BOOL">TRUE</field></block></value></block></value><next><block type="variables_set" id="rm2"><field name="VAR" id="list2">list2</field><value name="VALUE"><block type="bitbybit.lists.removeLastItem" id="rl2"><value name="List"><block type="bitbybit.lists.reverse" id="rv2"><value name="List"><block type="variables_get" id="gl2rv"><field name="VAR" id="list2">list2</field></block></value><value name="Clone"><block type="logic_boolean" id="cl2"><field name="BOOL">TRUE</field></block></value></block></value><value name="Clone"><block type="logic_boolean" id="cl3"><field name="BOOL">TRUE</field></block></value></block></value><next><block type="variables_set" id="finL"><field name="VAR" id="finalList">finalList</field><value name="VALUE"><block type="lists_create_with" id="clF"><mutation items="0"></mutation></block></value><next><block type="controls_forEach" id="fe2"><field name="VAR" id="item">item</field><value name="LIST"><block type="variables_get" id="gFE2"><field name="VAR" id="list2">list2</field></block></value><statement name="DO"><block type="lists_setIndex" id="addF2"><mutation at="false"></mutation><field name="MODE">INSERT</field><field name="WHERE">LAST</field><value name="LIST"><block type="variables_get" id="gF2"><field name="VAR" id="finalList">finalList</field></block></value><value name="TO"><block type="variables_get" id="gIT2"><field name="VAR" id="item">item</field></block></value></block></statement><next><block type="controls_forEach" id="fe1"><field name="VAR" id="item">item</field><value name="LIST"><block type="variables_get" id="gFE1"><field name="VAR" id="list1">list1</field></block></value><statement name="DO"><block type="lists_setIndex" id="addF1"><mutation at="false"></mutation><field name="MODE">INSERT</field><field name="WHERE">LAST</field><value name="LIST"><block type="variables_get" id="gF1"><field name="VAR" id="finalList">finalList</field></block></value><value name="TO"><block type="variables_get" id="gIT1"><field name="VAR" id="item">item</field></block></value></block></statement><next><block type="variables_set" id="revF"><field name="VAR" id="finalList">finalList</field><value name="VALUE"><block type="bitbybit.lists.reverse" id="rvF"><value name="List"><block type="variables_get" id="gFin"><field name="VAR" id="finalList">finalList</field></block></value><value name="Clone"><block type="logic_boolean" id=")-ps,@(;na@t3RQA!+}Q"><field name="BOOL">TRUE</field></block></value></block></value><next><block type="variables_set" id="mkLoft"><field name="VAR" id="loftShape">loftShape</field><value name="VALUE"><block type="base_time_await_return" id="awL"><value name="Promise"><block type="bitbybit.occt.operations.loftAdvanced" id="loft"><value name="Shapes"><block type="variables_get" id="gShp"><field name="VAR" id="finalList">finalList</field></block></value><value name="MakeSolid"><block type="logic_boolean" id="mSol"><field name="BOOL">FALSE</field></block></value><value name="Closed"><block type="logic_boolean" id="mClo"><field name="BOOL">TRUE</field></block></value><value name="Periodic"><block type="logic_boolean" id="mPer"><field name="BOOL">FALSE</field></block></value><value name="Straight"><block type="logic_boolean" id="mStr"><field name="BOOL">TRUE</field></block></value><value name="NrPeriodicSections"><block type="math_number" id="mSec"><field name="NUM">10</field></block></value><value name="UseSmoothing"><block type="logic_boolean" id="mSmo"><field name="BOOL">FALSE</field></block></value><value name="MaxUDegree"><block type="math_number" id="mMax"><field name="NUM">3</field></block></value><value name="Tolerance"><block type="math_number" id="mTol"><field name="NUM">1e-7</field></block></value><value name="ParType"><block type="text" id="mPar"><field name="TEXT">approxCentripetal</field></block></value></block></value></block></value><next><block type="variables_set" id="mkUni"><field name="VAR" id="unifiedShape">unifiedShape</field><value name="VALUE"><block type="base_time_await_return" id="awU"><value name="Promise"><block type="bitbybit.occt.shapes.shape.unifySameDomain" id="unify"><value name="Shape"><block type="variables_get" id="gLoft"><field name="VAR" id="loftShape">loftShape</field></block></value><value name="UnifyEdges"><block type="logic_boolean" id="uEdg"><field name="BOOL">TRUE</field></block></value><value name="UnifyFaces"><block type="logic_boolean" id="uFac"><field name="BOOL">TRUE</field></block></value><value name="ConcatBSplines"><block type="logic_boolean" id="uSpl"><field name="BOOL">TRUE</field></block></value></block></value></block></value><next><block type="bitbybit.draw.drawAnyAsyncNoReturn" id="draw"><value name="Entity"><block type="variables_get" id="gU"><field name="VAR" id="unifiedShape">unifiedShape</field></block></value><value name="Options"><block type="bitbybit.draw.optionsOcctShapeMaterial" id="dOpt"><value name="Precision"><block type="math_number" id="dPr"><field name="NUM">0.01</field></block></value><value name="FaceMaterial"><block type="bitbybit.babylon.material.pbrMetallicRoughness.create" id="dMat"><value name="Name"><block type="text" id="dNam"><field name="TEXT">Custom Material</field></block></value><value name="BaseColor"><block type="colour_picker" id="dCol"><field name="COLOUR">#94ffd1</field></block></value><value name="EmissiveColor"><block type="colour_picker" id="dEmi"><field name="COLOUR">#000000</field></block></value><value name="Metallic"><block type="math_number" id="dMet"><field name="NUM">0.9</field></block></value><value name="Roughness"><block type="math_number" id="dRgh"><field name="NUM">0.3</field></block></value><value name="Alpha"><block type="math_number" id="dAlp"><field name="NUM">1</field></block></value><value name="BackFaceCulling"><block type="logic_boolean" id="dCul"><field name="BOOL">FALSE</field></block></value><value name="ZOffset"><block type="math_number" id="dZof"><field name="NUM">2</field></block></value></block></value><value name="DrawEdges"><block type="logic_boolean" id="dDrE"><field name="BOOL">TRUE</field></block></value><value name="EdgeColour"><block type="colour_picker" id="dECo"><field name="COLOUR">#ffffff</field></block></value><value name="EdgeWidth"><block type="math_number" id="dEWi"><field name="NUM">2</field></block></value></block></value></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></xml>
const { NGonWireDto, RotateDto, ScaleDto, LoftAdvancedDto, UnifySameDomainDto } = Bit.Inputs.OCCT;
const { PBRMetallicRoughnessDto } = Bit.Inputs.BabylonMaterial;
const { SkyboxDto } = Bit.Inputs.BabylonScene;
const { DrawOcctShapeOptions } = Bit.Inputs.Draw;
const { skyboxEnum } = Bit.Inputs.Base;
const { ZoomOnDto } = Bit.Advanced.Navigation;
const { approxParametrizationTypeEnum } = Bit.Inputs.OCCT;
type TopoDSShapePointer = Bit.Inputs.OCCT.TopoDSShapePointer;
const { wire, shape } = bitbybit.occt.shapes;
const { operations, transforms } = bitbybit.occt;
const start = async () => {
const skyboxOpt = new SkyboxDto();
skyboxOpt.skybox = skyboxEnum.city;
skyboxOpt.hideSkybox = true;
bitbybit.babylon.scene.enableSkybox(skyboxOpt);
const nrCorners = 6;
// 1. Create Base Wires
const ngonDto = new NGonWireDto();
ngonDto.nrCorners = nrCorners;
ngonDto.direction = [0, 1, 0];
ngonDto.radius = 1;
ngonDto.center = [0, 0, 0];
const wire1 = await wire.createNGonWire(ngonDto);
ngonDto.center = [0, 0.1, 0];
const wire2 = await wire.createNGonWire(ngonDto);
ngonDto.center = [0, 0.2, 0];
const wire3 = await wire.createNGonWire(ngonDto);
ngonDto.center = [0, 0.3, 0];
const wire4 = await wire.createNGonWire(ngonDto);
// 2. Generate Lists of Transformed Wires
const list1: TopoDSShapePointer[] = [];
const list2: TopoDSShapePointer[] = [];
for (let i = 0; i <= 10; i++) {
const angle = i * 9;
const factor = i + 1;
// Helper to rotate and scale
const transform = async (w: TopoDSShapePointer) => {
const rotDto = new RotateDto<TopoDSShapePointer>();
rotDto.shape = w;
rotDto.axis = [0, 0, 1];
rotDto.angle = angle;
const rotated = await transforms.rotate(rotDto);
const scaleDto = new ScaleDto<TopoDSShapePointer>();
scaleDto.shape = rotated;
scaleDto.factor = factor;
return await transforms.scale(scaleDto);
};
list1.push(await transform(wire1));
list1.push(await transform(wire2));
list2.push(await transform(wire3));
list2.push(await transform(wire4));
}
// 3. Process Lists
// Remove first item from list1
list1.shift();
// Reverse list2 and remove last item
list2.reverse();
list2.shift();
list2.pop();
// 4. Merge and Reverse Final List
// Merge: list2 items then list1 items
let finalList = [...list2, ...list1];
// Reverse the final list for the loft direction
finalList.reverse();
// 5. Loft
const loftDto = new LoftAdvancedDto<TopoDSShapePointer>();
loftDto.shapes = finalList;
loftDto.makeSolid = false;
loftDto.closed = true;
loftDto.periodic = false;
loftDto.straight = true;
loftDto.nrPeriodicSections = 10;
loftDto.useSmoothing = false;
loftDto.maxUDegree = 3;
loftDto.tolerance = 1e-7;
loftDto.parType = approxParametrizationTypeEnum.approxCentripetal;
const loftShape = await operations.loftAdvanced(loftDto);
// 6. Unify Domain
const unifyDto = new UnifySameDomainDto<TopoDSShapePointer>();
unifyDto.shape = loftShape;
unifyDto.unifyEdges = true;
unifyDto.unifyFaces = true;
unifyDto.concatBSplines = true;
const unifiedShape = await shape.unifySameDomain(unifyDto);
// 7. Draw
const materialOptions = new PBRMetallicRoughnessDto();
materialOptions.name = 'Custom Material';
materialOptions.baseColor = '#94ffd1';
materialOptions.emissiveColor = '#000000';
materialOptions.metallic = 0.9;
materialOptions.roughness = 0.3;
materialOptions.alpha = 1;
materialOptions.backFaceCulling = false;
materialOptions.zOffset = 2;
const material = bitbybit.babylon.material.pbrMetallicRoughness.create(materialOptions);
const drawOptions = new DrawOcctShapeOptions();
drawOptions.precision = 0.01;
drawOptions.drawEdges = true;
drawOptions.edgeColour = '#ffffff';
drawOptions.edgeWidth = 2;
drawOptions.faceMaterial = material;
const drawnMesh = await bitbybit.draw.drawAnyAsync({
entity: unifiedShape,
options: drawOptions,
});
const zoomDto = new ZoomOnDto();
zoomDto.meshes = [drawnMesh];
bitbybit.advanced.navigation.zoomOn(zoomDto);
};
start();
How It Works
The algorithm creates a twisted ornament by stacking transformed hexagonal profiles. We start with four base hexagons at different heights, then generate eleven iterations where each step rotates by 9 degrees and scales progressively larger. This creates a smooth spiraling form that expands outward as it rises.
The technique uses two separate lists to control the twist direction. After transforming all profiles, we carefully arrange and reverse these lists before connecting them with a lofting operation. The loft creates smooth surfaces between profiles using straight transitions, maintaining crisp edges while achieving an organic twisted appearance. Finally, a unification step cleans up the geometry by merging adjacent faces and edges.
Algorithm Steps
1. Create four base hexagon wires at heights: 0, 0.1, 0.2, 0.3
2. For each iteration i from 0 to 10:
- Calculate angle = i × 9 degrees
- Calculate scale factor = i + 1
- Transform wires 1 and 2 → add to list1
- Transform wires 3 and 4 → add to list2
3. Process lists:
- Remove first item from list1
- Reverse list2, then remove first and last items
4. Combine lists:
- Merge list2 + list1 → finalList
- Reverse finalList
5. Loft profiles:
- Connect all profiles with straight transitions
- Create closed, non-periodic surface
6. Unify geometry:
- Merge coplanar faces
- Combine adjacent edges
7. Render with metallic material and visible edges
Experiment with the number of polygon corners or rotation angle to create unique variations of this twisted form.



