Rendering 3D Objects in Bitbybit Editors
This guide demonstrates how to use the core "Draw" functionalities across Bitbybit's different editor environments: Rete, Blockly, and TypeScript. The objective is to render a 3D object—specifically, a cube with rounded edges—and customize its appearance.
Rete Implementation
We begin with the Rete editor. The following script constructs a cube, applies a fillet to its edges to round them, and then renders the resulting shape. Notice the customization: the cube's default face color is changed to blue, its edges are rendered in orange, and its vertices are also drawn as distinct points.
The primary component for custom drawing is typically found under the path:
draw > draw async > draw any async
Rete Example: Filleted Cube with Custom Drawing Options
{
"id": "rete-v2-json",
"nodes": {
"b1bf89dae109c64b": {
"id": "b1bf89dae109c64b",
"name": "bitbybit.occt.shapes.solid.createCube",
"customName": "cube",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"size": 5,
"center": [
0,
0,
0
],
"originOnCenter": true
},
"inputs": {},
"position": [
376.49611866408657,
295.8380861953228
]
},
"511f71201db977e8": {
"id": "511f71201db977e8",
"name": "bitbybit.occt.fillets.filletEdges",
"customName": "fillet edges",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 1
},
"inputs": {
"shape": {
"connections": [
{
"node": "b1bf89dae109c64b",
"output": "result",
"data": {}
}
]
}
},
"position": [
751.1640625,
293.23828125
]
},
"d1567030a8ca9ba2": {
"id": "d1567030a8ca9ba2",
"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": "511f71201db977e8",
"output": "result",
"data": {}
}
]
},
"options": {
"connections": [
{
"node": "8136f5dbe1a1aa7f",
"output": "result",
"data": {}
}
]
}
},
"position": [
1202.458352666743,
483.28792369009324
]
},
"8136f5dbe1a1aa7f": {
"id": "8136f5dbe1a1aa7f",
"name": "bitbybit.draw.optionsOcctShape",
"customName": "options occt shape",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"faceOpacity": 1,
"edgeOpacity": 1,
"edgeColour": "#ffbb00",
"faceColour": "#0008ff",
"vertexColour": "#ff00ff",
"edgeWidth": 2,
"vertexSize": 0.3,
"drawEdges": true,
"drawFaces": true,
"drawVertices": true,
"precision": 0.01,
"drawEdgeIndexes": false,
"edgeIndexHeight": 0.1,
"edgeIndexColour": "#ff00ff",
"drawFaceIndexes": false,
"faceIndexHeight": 0.06,
"faceIndexColour": "#0000ff"
},
"inputs": {},
"position": [
748.3541705405835,
689.9545863118427
]
}
}
}
Blockly
Blockly Implementation
The same geometric operations and drawing customizations can be achieved using the Blockly editor. The example below replicates the filleted cube, applying similar visual styles. Note that in this Blockly example, blocks are nested directly without the use of intermediate variables for simplicity.
The primary block for custom drawing is typically found under:
draw > draw async > draw any async no return
<xml xmlns="https://developers.google.com/blockly/xml"><block type="bitbybit.draw.drawAnyAsyncNoReturn" id=")!Y^k-S7bFI-:mJRQU#F" x="-149" y="-100"><value name="Entity"><block type="bitbybit.occt.fillets.filletEdges" id="n+$8hWF3ff|j^Xve}{O6"><value name="Shape"><block type="bitbybit.occt.shapes.solid.createCube" id="t0|A|Y[vnb%oBPy$C$Z*"><value name="Size"><block type="math_number" id="YCDl|N-|.4?(.GhV+VTX"><field name="NUM">5</field></block></value><value name="Center"><block type="bitbybit.point.pointXYZ" id="aJ?9ro.i{m$4k}j|N@mT"><value name="X"><block type="math_number" id="=/V{o8E^skD1_4lms;N/"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="t.yBPk5{bgN}H0x1#)LG"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="R$=fsU[0y*e3GacQHBox"><field name="NUM">0</field></block></value></block></value><value name="OriginOnCenter"><block type="logic_boolean" id="VQK}aL5ljTERjo7HGgVj"><field name="BOOL">TRUE</field></block></value></block></value><value name="Radius"><block type="math_number" id="I+g6zozkKfG]-1jLf0*-"><field name="NUM">1</field></block></value></block></value><value name="Options"><block type="bitbybit.draw.optionsOcctShape" id="@;`i=v%GFgxk.i=MA?)M"><value name="FaceOpacity"><block type="math_number" id="2kC_vXp1*jC{-aQ]q%py"><field name="NUM">1</field></block></value><value name="EdgeOpacity"><block type="math_number" id="IGqXw_bw_}ZV#@^)?fF6"><field name="NUM">1</field></block></value><value name="EdgeColour"><block type="colour_picker" id="wvy|/BQE9GS1Mtv]hTz;"><field name="COLOUR">#ff6600</field></block></value><value name="FaceColour"><block type="colour_picker" id=":2@]_{@#C1RbA2j_e^]{"><field name="COLOUR">#000099</field></block></value><value name="VertexColour"><block type="colour_picker" id="}B+Nm45X*vwTeyXF[n1b"><field name="COLOUR">#cc33cc</field></block></value><value name="EdgeWidth"><block type="math_number" id="`4{6FfYFX}`|Wcdc!deC"><field name="NUM">2</field></block></value><value name="VertexSize"><block type="math_number" id="m3=w1T_;AK^W5@UJTPbz"><field name="NUM">0.3</field></block></value><value name="DrawEdges"><block type="logic_boolean" id="fP-8~bf/_TLI`G+gx_?c"><field name="BOOL">TRUE</field></block></value><value name="DrawFaces"><block type="logic_boolean" id="UiQFnq?qj50OPp;v%H%*"><field name="BOOL">TRUE</field></block></value><value name="DrawVertices"><block type="logic_boolean" id="[MP`pvB2-B#B.kMi+3bk"><field name="BOOL">TRUE</field></block></value><value name="Precision"><block type="math_number" id="~.JdF}{W$o;$_n/UJ%IV"><field name="NUM">0.01</field></block></value><value name="DrawEdgeIndexes"><block type="logic_boolean" id="_Z6-!qrE@a24R#(hcq*D"><field name="BOOL">FALSE</field></block></value><value name="EdgeIndexHeight"><block type="math_number" id="l(/z|-OXhLfKssJNlj(v"><field name="NUM">0.06</field></block></value><value name="EdgeIndexColour"><block type="colour_picker" id="Yl:=G]eN4w:,:I0=8=z6"><field name="COLOUR">#ff00ff</field></block></value><value name="DrawFaceIndexes"><block type="logic_boolean" id="Un/.QLjQH+)OOS#64#{o"><field name="BOOL">FALSE</field></block></value><value name="FaceIndexHeight"><block type="math_number" id="j0+*3$/5zFYqv8ga1,L1"><field name="NUM">0.06</field></block></value><value name="FaceIndexColour"><block type="colour_picker" id="[L`XO!78kzhKa,Vv:Rx^"><field name="COLOUR">#0000ff</field></block></value></block></value></block></xml>
TypeScript Implementation
Finally, we achieve the same result using TypeScript. The code follows a similar logical flow: create a cube, fillet its edges, define drawing options, and then draw the resulting shape. This approach offers maximum flexibility and control for developers comfortable with text-based coding.
const start = async () => {
const cubeOptions = new Bit.Inputs.OCCT.CubeDto();
cubeOptions.size = 5;
const cube = await bitbybit.occt.shapes.solid.createCube(cubeOptions);
const filletOptions = new Bit.Inputs.OCCT.FilletDto<Bit.Inputs.OCCT.TopoDSShapePointer>()
filletOptions.shape = cube;
filletOptions.radius = 1;
const roundedCube = await bitbybit.occt.fillets.filletEdges(filletOptions);
const drawOcctOptions = new Bit.Inputs.Draw.DrawOcctShapeOptions();
drawOcctOptions.faceColour = "#0000ff";
drawOcctOptions.edgeColour = "#ff5555";
drawOcctOptions.drawVertices = true;
drawOcctOptions.vertexSize = 0.3;
// The rest of options remain default (initialized inside the instance)
const drawnMesh = await bitbybit.draw.drawAnyAsync({ entity: roundedCube, options: drawOcctOptions })
// drawnMesh is BABYLONJS Mesh if BabylonJS engine is used. In Three.JS it turns into Group.
return drawnMesh;
}
start();



