Skip to main content

Creating Advanded Loft

OCCT category icon with a stylized logo representation

The file explains how to create complex 3D shapes using an advanced lofting operation. This operation generates a surface or solid by connecting a series of 2D wire profiles, offering more control than a simple loft.

Here's a breakdown of the process described:

  1. Profile Creation: The script begins by creating three distinct n-sided polygonal wires (using createNGonWire). These wires serve as the cross-sections for the loft. Each wire can be customized with a different number of corners, radius, and spatial position.
  2. Profile Refinement: To achieve smoother transitions, 2D fillets (using fillet2d) are applied to the corners of these polygonal wires.
  3. Advanced Loft Operation: The core of the script is the loftAdvanced function. This function takes the refined wire profiles and a set of parameters to generate the final 3D shape.

Key Parameters for loftAdvanced

  • shapes: This is the list of 2D wire profiles that the loft will pass through.
  • startVertex and endVertex: These optional parameters allow the loft to begin or end at a single point, creating a tapered or pointed shape.
  • makeSolid: A boolean that determines whether the output is a hollow shell (surface) or a solid object.
  • closed: If set to true, the loft connects the last profile back to the first, forming a closed loop.
  • periodic: Useful for creating smooth, continuous surfaces when the input profiles form a repeating pattern.
  • straight: When true, the loft creates ruled surfaces, meaning it uses straight lines to connect corresponding points on adjacent profiles.
  • useSmoothing: Applies a smoothing algorithm to the generated surface for a more organic look.
  • maxUDegree: Controls the maximum degree of the resulting BSpline surface in the U direction.
  • tolerance: Defines the geometric precision for the lofting operation.
  • parType: Specifies the method used for parameterizing the surface along the path of the loft (e.g., approxCentripetal, approxChordLength).

Overlap with Simple Loft

  • Fundamental Principle: Both simple and advanced lofting share the core concept of creating a 3D form by sweeping through a sequence of 2D profiles. The basic input of a list of shapes (wires) is common to both.
Bitbybit Platform

Advanced Loft Operation

rete logoRete
Script Source (rete)
{
"id": "rete-v2-json",
"nodes": {
"5b0a2e7a36e52bc6": {
"id": "5b0a2e7a36e52bc6",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 3,
"z": 0
},
"inputs": {},
"position": [
-294.44305408107294,
625.494016393214
]
},
"31cc8830d0d5b8d6": {
"id": "31cc8830d0d5b8d6",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 7,
"z": 0
},
"inputs": {},
"position": [
-297.9642807136139,
1019.3121779042008
]
},
"8bd8f5d69c0ee3d9": {
"id": "8bd8f5d69c0ee3d9",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "11be4dd28dcd4b33",
"output": "result",
"data": {}
},
{
"node": "3522cf5d866d7d91",
"output": "result",
"data": {}
},
{
"node": "d469db5335ea3400",
"output": "result",
"data": {}
}
]
}
},
"position": [
1276.7110950696322,
648.5670623793434
]
},
"71104a241cda7a83": {
"id": "71104a241cda7a83",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "draw any async",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"options": {
"connections": [
{
"node": "2b01c4bcdaa8b222",
"output": "result",
"data": {}
}
]
},
"entity": {
"connections": [
{
"node": "e589c6b135aa1393",
"output": "result",
"data": {}
}
]
}
},
"position": [
2216.0217964086746,
945.9977380414867
]
},
"2b01c4bcdaa8b222": {
"id": "2b01c4bcdaa8b222",
"name": "bitbybit.draw.optionsOcctShapeSimple",
"customName": "options occt shape simple",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"precision": 0.008,
"drawFaces": true,
"faceColour": "#8000ff",
"drawEdges": true,
"edgeColour": "#ffffff",
"edgeWidth": 2
},
"inputs": {},
"position": [
1690.6871109875997,
1317.9796252756155
]
},
"e589c6b135aa1393": {
"id": "e589c6b135aa1393",
"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": false,
"periodic": false,
"straight": false,
"nrPeriodicSections": 10,
"useSmoothing": false,
"maxUDegree": 3,
"tolerance": 1e-7,
"parType": "approxCentripetal"
},
"inputs": {
"shapes": {
"connections": [
{
"node": "8bd8f5d69c0ee3d9",
"output": "list",
"data": {}
}
]
},
"startVertex": {
"connections": [
{
"node": "e00b530f027cb3cf",
"output": "result",
"data": {}
}
]
},
"endVertex": {
"connections": [
{
"node": "8dd22a99e9b89b2c",
"output": "result",
"data": {}
}
]
}
},
"position": [
1682.426755659047,
607.1297407593821
]
},
"8743a42520c8d1c3": {
"id": "8743a42520c8d1c3",
"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": 3
},
"inputs": {
"nrCorners": {
"connections": [
{
"node": "64f3dc2622aaf590",
"output": "result",
"data": {}
}
]
}
},
"position": [
442.8040971986445,
241.22876028466678
]
},
"ac432e5d7a5200e3": {
"id": "ac432e5d7a5200e3",
"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": "5b0a2e7a36e52bc6",
"output": "result",
"data": {}
}
]
},
"nrCorners": {
"connections": [
{
"node": "64f3dc2622aaf590",
"output": "result",
"data": {}
}
]
}
},
"position": [
442.3146113374279,
621.9002839093048
]
},
"c5e492a02fd8859d": {
"id": "c5e492a02fd8859d",
"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": 6
},
"inputs": {
"center": {
"connections": [
{
"node": "31cc8830d0d5b8d6",
"output": "result",
"data": {}
}
]
},
"nrCorners": {
"connections": [
{
"node": "64f3dc2622aaf590",
"output": "result",
"data": {}
}
]
}
},
"position": [
443.91583594610427,
1006.2290060921524
]
},
"3522cf5d866d7d91": {
"id": "3522cf5d866d7d91",
"name": "bitbybit.occt.fillets.fillet2d",
"customName": "fillet 2d",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 0.3
},
"inputs": {
"shape": {
"connections": [
{
"node": "ac432e5d7a5200e3",
"output": "result",
"data": {}
}
]
}
},
"position": [
853.6233508415709,
620.7419018219557
]
},
"64f3dc2622aaf590": {
"id": "64f3dc2622aaf590",
"name": "bitbybit.math.numberSlider",
"customName": "number slider",
"data": {
"options": {
"min": 3,
"max": 10,
"step": 1,
"width": 350,
"updateOnDrag": false
},
"number": 10
},
"inputs": {},
"position": [
-541.8367158412975,
362.3552015537263
]
},
"d469db5335ea3400": {
"id": "d469db5335ea3400",
"name": "bitbybit.occt.fillets.fillet2d",
"customName": "fillet 2d",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 1
},
"inputs": {
"shape": {
"connections": [
{
"node": "8743a42520c8d1c3",
"output": "result",
"data": {}
}
]
}
},
"position": [
851.3977807392785,
238.02015166684114
]
},
"11be4dd28dcd4b33": {
"id": "11be4dd28dcd4b33",
"name": "bitbybit.occt.fillets.fillet2d",
"customName": "fillet 2d",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 0.5
},
"inputs": {
"shape": {
"connections": [
{
"node": "c5e492a02fd8859d",
"output": "result",
"data": {}
}
]
}
},
"position": [
852.7507275204114,
1002.0571428632672
]
},
"e00b530f027cb3cf": {
"id": "e00b530f027cb3cf",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 10,
"z": 0
},
"inputs": {},
"position": [
1281.5387853734014,
883.3651422481488
]
},
"8dd22a99e9b89b2c": {
"id": "8dd22a99e9b89b2c",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": -3,
"z": 0
},
"inputs": {},
"position": [
1281.0131144912798,
1233.3391294416137
]
},
"9419c83e5db4e3ec": {
"id": "9419c83e5db4e3ec",
"name": "bitbybit.babylon.scene.adjustActiveArcRotateCamera",
"customName": "adjust active arc rotate camera",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"position": [
10,
10,
10
],
"lookAt": [
0,
0,
0
],
"lowerBetaLimit": 1,
"upperBetaLimit": 179,
"angularSensibilityX": 1000,
"angularSensibilityY": 1000,
"maxZ": 1000,
"panningSensibility": 1000,
"wheelPrecision": 3
},
"inputs": {
"lookAt": {
"connections": [
{
"node": "60cc6a6554a486c3",
"output": "result",
"data": {}
}
]
},
"position": {
"connections": [
{
"node": "2610f0aa01da8491",
"output": "result",
"data": {}
}
]
}
},
"position": [
446.1321692664079,
1396.818212894413
]
},
"60cc6a6554a486c3": {
"id": "60cc6a6554a486c3",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 3,
"z": 0
},
"inputs": {},
"position": [
-302.7615363793083,
1739.5547926387696
]
},
"2610f0aa01da8491": {
"id": "2610f0aa01da8491",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 15,
"y": 15,
"z": 15
},
"inputs": {},
"position": [
-302.43034583359827,
1401.0514769387867
]
}
}
}

Conclusions

The advanced loft operation provides a much richer set of tools for controlling the lofting process compared to a basic loft. While a simple loft typically connects profiles in a straightforward manner, loftAdvanced allows for:

  • The creation of either solid bodies or open surfaces (shells).
  • The ability to close the loft into a continuous loop or make it periodic.
  • The option to taper the loft to a specific start or end point.
  • Fine-grained control over the surface's smoothness, straightness (ruled surfaces), and mathematical definition (degree, parameterization).

This makes the advanced loft operation highly versatile for generating complex, precise, and aesthetically refined 3D geometries. The example demonstrates this by creating a shape from three filleted n-gon wires, with the added capability of defining specific start and end vertices for the loft.