Multiple Wire Offsets
Multiple wire offsetting creates a series of parallel curves at specified distances from an original open wire. This technique generates multiple paths that maintain the same general shape as the original while being displaced perpendicular to the wire direction. The operation is useful for various applications including toolpath generation, pattern creation, and design iterations where you need parallel geometric elements.
The process involves creating an initial open wire through point interpolation, then systematically generating offset curves at incrementally increasing distances. Each offset curve preserves the original wire's character while providing controlled spacing for your specific application needs.
Interactive Example
The following example demonstrates creating multiple offset curves from a single interpolated wire, showing how a simple reference path can generate a family of parallel curves.
- Rete
- Blockly
- TypeScript
{
"id": "rete-v2-json",
"nodes": {
"38ab4551ee8c1af6": {
"id": "38ab4551ee8c1af6",
"name": "bitbybit.lists.createList",
"customName": "create list",
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "p1",
"output": "result",
"data": {}
},
{
"node": "p2",
"output": "result",
"data": {}
},
{
"node": "p3",
"output": "result",
"data": {}
},
{
"node": "p4",
"output": "result",
"data": {}
},
{
"node": "p5",
"output": "result",
"data": {}
}
]
}
},
"position": [
400,
200
]
},
"p1": {
"id": "p1",
"name": "bitbybit.vector.vectorXYZ",
"customName": "point 1",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": -4,
"y": 0,
"z": -2
},
"inputs": {},
"position": [
-190.80902171677602,
-389.40998864339485
]
},
"p2": {
"id": "p2",
"name": "bitbybit.vector.vectorXYZ",
"customName": "point 2",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": -2,
"y": 0,
"z": 2
},
"inputs": {},
"position": [
-184.48746508777663,
-51.45988709568172
]
},
"p3": {
"id": "p3",
"name": "bitbybit.vector.vectorXYZ",
"customName": "point 3",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 0,
"z": 1
},
"inputs": {},
"position": [
-182.69518017759944,
284.6979295418542
]
},
"p4": {
"id": "p4",
"name": "bitbybit.vector.vectorXYZ",
"customName": "point 4",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 2,
"y": 0,
"z": 3
},
"inputs": {},
"position": [
-178.16590845877727,
621.8445930263844
]
},
"p5": {
"id": "p5",
"name": "bitbybit.vector.vectorXYZ",
"customName": "point 5",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 4,
"y": 0,
"z": 0
},
"inputs": {},
"position": [
-177.78626190144908,
960.9248052563768
]
},
"basewire": {
"id": "basewire",
"name": "bitbybit.occt.shapes.wire.interpolatePoints",
"customName": "base wire",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"periodic": false,
"tolerance": 0.01
},
"inputs": {
"points": {
"connections": [
{
"node": "38ab4551ee8c1af6",
"output": "list",
"data": {}
}
]
}
},
"position": [
798.0752802442432,
7.828210074300614
]
},
"e80cf9124defa4d4": {
"id": "e80cf9124defa4d4",
"name": "bitbybit.math.numberSlider",
"customName": "number slider",
"data": {
"options": {
"min": 0.1,
"max": 2,
"step": 0.1,
"width": 300,
"updateOnDrag": false
},
"number": 2
},
"inputs": {},
"position": [
507.72512479553654,
683.9608294997644
]
},
"offset1": {
"id": "offset1",
"name": "bitbybit.occt.operations.offset",
"customName": "offset 1",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"distance": 0.2,
"tolerance": 0.01
},
"inputs": {
"shape": {
"connections": [
{
"node": "basewire",
"output": "result",
"data": {}
}
]
},
"distance": {
"connections": [
{
"node": "e80cf9124defa4d4",
"output": "result",
"data": {}
}
]
}
},
"position": [
1221.466307302009,
35.9679552097118
]
},
"multiply2": {
"id": "multiply2",
"name": "bitbybit.math.twoNrOperation",
"customName": "distance x2",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"first": 1,
"second": 1,
"operation": "multiply"
},
"inputs": {
"first": {
"connections": [
{
"node": "e80cf9124defa4d4",
"output": "result",
"data": {}
}
]
},
"second": {
"connections": [
{
"node": "two",
"output": "result",
"data": {}
}
]
}
},
"position": [
1224.7781345357528,
420.76788306204287
]
},
"multiply3": {
"id": "multiply3",
"name": "bitbybit.math.twoNrOperation",
"customName": "distance x3",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"first": 1,
"second": 1,
"operation": "multiply"
},
"inputs": {
"first": {
"connections": [
{
"node": "e80cf9124defa4d4",
"output": "result",
"data": {}
}
]
},
"second": {
"connections": [
{
"node": "three",
"output": "result",
"data": {}
}
]
}
},
"position": [
1223.336847020343,
763.5274114633796
]
},
"two": {
"id": "two",
"name": "bitbybit.math.number",
"customName": "2",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"number": 2
},
"inputs": {},
"position": [
794.9971478885859,
358.9193706214926
]
},
"three": {
"id": "three",
"name": "bitbybit.math.number",
"customName": "3",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"number": 3
},
"inputs": {},
"position": [
776.7709280853388,
864.3650074471401
]
},
"offset2": {
"id": "offset2",
"name": "bitbybit.occt.operations.offset",
"customName": "offset 2",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"distance": 0.2,
"tolerance": 0.01
},
"inputs": {
"shape": {
"connections": [
{
"node": "basewire",
"output": "result",
"data": {}
}
]
},
"distance": {
"connections": [
{
"node": "multiply2",
"output": "result",
"data": {}
}
]
}
},
"position": [
1753.5553421737566,
-819.7376021048046
]
},
"offset3": {
"id": "offset3",
"name": "bitbybit.occt.operations.offset",
"customName": "offset 3",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"distance": 0.2,
"tolerance": 0.01
},
"inputs": {
"shape": {
"connections": [
{
"node": "basewire",
"output": "result",
"data": {}
}
]
},
"distance": {
"connections": [
{
"node": "multiply3",
"output": "result",
"data": {}
}
]
}
},
"position": [
1755.7551374986147,
-412.67129767464064
]
},
"basestyle": {
"id": "basestyle",
"name": "bitbybit.draw.optionsOcctShapeSimple",
"customName": "base wire style",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"precision": 0.01,
"drawFaces": false,
"faceColour": "#ff0000",
"drawEdges": true,
"edgeColour": "#00ff00",
"edgeWidth": 10
},
"inputs": {},
"position": [
2185.479415729077,
24.660799545770598
]
},
"offset1style": {
"id": "offset1style",
"name": "bitbybit.draw.optionsOcctShapeSimple",
"customName": "offset 1 style",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"precision": 0.01,
"drawFaces": false,
"faceColour": "#ff0000",
"drawEdges": true,
"edgeColour": "#ff9900",
"edgeWidth": 10
},
"inputs": {},
"position": [
2185.41761280114,
479.95843456556105
]
},
"offset2style": {
"id": "offset2style",
"name": "bitbybit.draw.optionsOcctShapeSimple",
"customName": "offset 2 style",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"precision": 0.01,
"drawFaces": false,
"faceColour": "#ff0000",
"drawEdges": true,
"edgeColour": "#ff6600",
"edgeWidth": 10
},
"inputs": {},
"position": [
2189.911568561141,
949.1264124123878
]
},
"offset3style": {
"id": "offset3style",
"name": "bitbybit.draw.optionsOcctShapeSimple",
"customName": "offset 3 style",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"precision": 0.01,
"drawFaces": false,
"faceColour": "#ff0000",
"drawEdges": true,
"edgeColour": "#ff3300",
"edgeWidth": 10
},
"inputs": {},
"position": [
2198.7405582664474,
1412.2906772596061
]
},
"drawbase": {
"id": "drawbase",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "draw base wire",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"entity": {
"connections": [
{
"node": "basewire",
"output": "result",
"data": {}
}
]
},
"options": {
"connections": [
{
"node": "basestyle",
"output": "result",
"data": {}
}
]
}
},
"position": [
2962.5743950324195,
-338.5447476522748
]
},
"drawoffset1": {
"id": "drawoffset1",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "draw offset 1",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"entity": {
"connections": [
{
"node": "offset1",
"output": "result",
"data": {}
}
]
},
"options": {
"connections": [
{
"node": "offset1style",
"output": "result",
"data": {}
}
]
}
},
"position": [
2966.944744936546,
20.383033435246347
]
},
"drawoffset2": {
"id": "drawoffset2",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "draw offset 2",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"entity": {
"connections": [
{
"node": "offset2",
"output": "result",
"data": {}
}
]
},
"options": {
"connections": [
{
"node": "offset2style",
"output": "result",
"data": {}
}
]
}
},
"position": [
2968.163145515878,
374.15611583371833
]
},
"drawoffset3": {
"id": "drawoffset3",
"name": "bitbybit.draw.drawAnyAsync",
"customName": "draw offset 3",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"entity": {
"connections": [
{
"node": "offset3",
"output": "result",
"data": {}
}
]
},
"options": {
"connections": [
{
"node": "offset3style",
"output": "result",
"data": {}
}
]
}
},
"position": [
2971.5181616038944,
746.5142215618604
]
}
}
}
<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="controlPoints">controlPoints</variable><variable id="baseWire">baseWire</variable><variable id="stepoverDistance">stepoverDistance</variable><variable id="offset1">offset1</variable><variable id="offset2">offset2</variable><variable id="offset3">offset3</variable><variable id="baseStyle">baseStyle</variable><variable id="offset1Style">offset1Style</variable><variable id="offset2Style">offset2Style</variable><variable id="offset3Style">offset3Style</variable></variables><block type="variables_set" id="points_list" x="50" y="50"><field name="VAR" id="controlPoints">controlPoints</field><value name="VALUE"><block type="lists_create_with" id="points_create"><mutation items="5"></mutation><value name="ADD0"><block type="bitbybit.point.pointXYZ" id="p1"><value name="X"><block type="math_number" id="p1_x"><field name="NUM">-4</field></block></value><value name="Y"><block type="math_number" id="p1_y"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="p1_z"><field name="NUM">-2</field></block></value></block></value><value name="ADD1"><block type="bitbybit.point.pointXYZ" id="p2"><value name="X"><block type="math_number" id="p2_x"><field name="NUM">-2</field></block></value><value name="Y"><block type="math_number" id="p2_y"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="p2_z"><field name="NUM">2</field></block></value></block></value><value name="ADD2"><block type="bitbybit.point.pointXYZ" id="p3"><value name="X"><block type="math_number" id="p3_x"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="p3_y"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="p3_z"><field name="NUM">1</field></block></value></block></value><value name="ADD3"><block type="bitbybit.point.pointXYZ" id="p4"><value name="X"><block type="math_number" id="p4_x"><field name="NUM">2</field></block></value><value name="Y"><block type="math_number" id="p4_y"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="p4_z"><field name="NUM">3</field></block></value></block></value><value name="ADD4"><block type="bitbybit.point.pointXYZ" id="p5"><value name="X"><block type="math_number" id="p5_x"><field name="NUM">4</field></block></value><value name="Y"><block type="math_number" id="p5_y"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="p5_z"><field name="NUM">0</field></block></value></block></value></block></value><next><block type="variables_set" id="stepover_set" x="50" y="150"><field name="VAR" id="stepoverDistance">stepoverDistance</field><value name="VALUE"><block type="math_number" id="stepover_value"><field name="NUM">0.5</field></block></value><next><block type="variables_set" id="base_wire_create" x="50" y="250"><field name="VAR" id="baseWire">baseWire</field><value name="VALUE"><block type="bitbybit.occt.shapes.wire.interpolatePoints" id="base_wire"><value name="Points"><block type="variables_get" id="get_points"><field name="VAR" id="controlPoints">controlPoints</field></block></value><value name="Periodic"><block type="logic_boolean" id="base_periodic"><field name="BOOL">FALSE</field></block></value><value name="Tolerance"><block type="math_number" id="base_tolerance"><field name="NUM">0.01</field></block></value></block></value><next><block type="variables_set" id="offset1_create" x="50" y="350"><field name="VAR" id="offset1">offset1</field><value name="VALUE"><block type="bitbybit.occt.operations.offset" id="offset_1"><value name="Shape"><block type="variables_get" id="get_base_wire"><field name="VAR" id="baseWire">baseWire</field></block></value><value name="Distance"><block type="variables_get" id="get_stepover"><field name="VAR" id="stepoverDistance">stepoverDistance</field></block></value><value name="Tolerance"><block type="math_number" id="offset1_tolerance"><field name="NUM">0.01</field></block></value></block></value><next><block type="variables_set" id="offset2_create" x="50" y="450"><field name="VAR" id="offset2">offset2</field><value name="VALUE"><block type="bitbybit.occt.operations.offset" id="offset_2"><value name="Shape"><block type="variables_get" id="get_base_wire2"><field name="VAR" id="baseWire">baseWire</field></block></value><value name="Distance"><block type="math_arithmetic" id="distance2"><field name="OP">MULTIPLY</field><value name="A"><block type="variables_get" id="get_stepover2"><field name="VAR" id="stepoverDistance">stepoverDistance</field></block></value><value name="B"><block type="math_number" id="mult2"><field name="NUM">2</field></block></value></block></value><value name="Tolerance"><block type="math_number" id="offset2_tolerance"><field name="NUM">0.01</field></block></value></block></value><next><block type="variables_set" id="offset3_create" x="50" y="550"><field name="VAR" id="offset3">offset3</field><value name="VALUE"><block type="bitbybit.occt.operations.offset" id="offset_3"><value name="Shape"><block type="variables_get" id="get_base_wire3"><field name="VAR" id="baseWire">baseWire</field></block></value><value name="Distance"><block type="math_arithmetic" id="distance3"><field name="OP">MULTIPLY</field><value name="A"><block type="variables_get" id="get_stepover3"><field name="VAR" id="stepoverDistance">stepoverDistance</field></block></value><value name="B"><block type="math_number" id="mult3"><field name="NUM">3</field></block></value></block></value><value name="Tolerance"><block type="math_number" id="offset3_tolerance"><field name="NUM">0.01</field></block></value></block></value><next><block type="variables_set" id="base_style_create" x="50" y="650"><field name="VAR" id="baseStyle">baseStyle</field><value name="VALUE"><block type="bitbybit.draw.optionsOcctShapeSimple" id="base_style"><value name="Precision"><block type="math_number" id="base_precision"><field name="NUM">0.01</field></block></value><value name="DrawFaces"><block type="logic_boolean" id="base_drawfaces"><field name="BOOL">FALSE</field></block></value><value name="DrawEdges"><block type="logic_boolean" id="base_drawedges"><field name="BOOL">TRUE</field></block></value><value name="EdgeColour"><block type="colour_picker" id="base_edgecolor"><field name="COLOUR">#00ff00</field></block></value><value name="EdgeWidth"><block type="math_number" id="base_edgewidth"><field name="NUM">4</field></block></value></block></value><next><block type="variables_set" id="offset1_style_create" x="50" y="750"><field name="VAR" id="offset1Style">offset1Style</field><value name="VALUE"><block type="bitbybit.draw.optionsOcctShapeSimple" id="offset1_style"><value name="Precision"><block type="math_number" id="offset1_precision"><field name="NUM">0.01</field></block></value><value name="DrawFaces"><block type="logic_boolean" id="offset1_drawfaces"><field name="BOOL">FALSE</field></block></value><value name="DrawEdges"><block type="logic_boolean" id="offset1_drawedges"><field name="BOOL">TRUE</field></block></value><value name="EdgeColour"><block type="colour_picker" id="offset1_edgecolor"><field name="COLOUR">#ff9900</field></block></value><value name="EdgeWidth"><block type="math_number" id="offset1_edgewidth"><field name="NUM">3</field></block></value></block></value><next><block type="variables_set" id="offset2_style_create" x="50" y="850"><field name="VAR" id="offset2Style">offset2Style</field><value name="VALUE"><block type="bitbybit.draw.optionsOcctShapeSimple" id="offset2_style"><value name="Precision"><block type="math_number" id="offset2_precision"><field name="NUM">0.01</field></block></value><value name="DrawFaces"><block type="logic_boolean" id="offset2_drawfaces"><field name="BOOL">FALSE</field></block></value><value name="DrawEdges"><block type="logic_boolean" id="offset2_drawedges"><field name="BOOL">TRUE</field></block></value><value name="EdgeColour"><block type="colour_picker" id="offset2_edgecolor"><field name="COLOUR">#ff6600</field></block></value><value name="EdgeWidth"><block type="math_number" id="offset2_edgewidth"><field name="NUM">3</field></block></value></block></value><next><block type="variables_set" id="offset3_style_create" x="50" y="950"><field name="VAR" id="offset3Style">offset3Style</field><value name="VALUE"><block type="bitbybit.draw.optionsOcctShapeSimple" id="offset3_style"><value name="Precision"><block type="math_number" id="offset3_precision"><field name="NUM">0.01</field></block></value><value name="DrawFaces"><block type="logic_boolean" id="offset3_drawfaces"><field name="BOOL">FALSE</field></block></value><value name="DrawEdges"><block type="logic_boolean" id="offset3_drawedges"><field name="BOOL">TRUE</field></block></value><value name="EdgeColour"><block type="colour_picker" id="offset3_edgecolor"><field name="COLOUR">#ff3300</field></block></value><value name="EdgeWidth"><block type="math_number" id="offset3_edgewidth"><field name="NUM">3</field></block></value></block></value><next><block type="bitbybit.draw.drawAnyAsyncNoReturn" id="draw_base" x="50" y="1050"><value name="Entity"><block type="variables_get" id="get_base_for_draw"><field name="VAR" id="baseWire">baseWire</field></block></value><value name="Options"><block type="variables_get" id="get_base_style"><field name="VAR" id="baseStyle">baseStyle</field></block></value><next><block type="bitbybit.draw.drawAnyAsyncNoReturn" id="draw_offset1" x="50" y="1150"><value name="Entity"><block type="variables_get" id="get_offset1_for_draw"><field name="VAR" id="offset1">offset1</field></block></value><value name="Options"><block type="variables_get" id="get_offset1_style"><field name="VAR" id="offset1Style">offset1Style</field></block></value><next><block type="bitbybit.draw.drawAnyAsyncNoReturn" id="draw_offset2" x="50" y="1250"><value name="Entity"><block type="variables_get" id="get_offset2_for_draw"><field name="VAR" id="offset2">offset2</field></block></value><value name="Options"><block type="variables_get" id="get_offset2_style"><field name="VAR" id="offset2Style">offset2Style</field></block></value><next><block type="bitbybit.draw.drawAnyAsyncNoReturn" id="draw_offset3" x="50" y="1350"><value name="Entity"><block type="variables_get" id="get_offset3_for_draw"><field name="VAR" id="offset3">offset3</field></block></value><value name="Options"><block type="variables_get" id="get_offset3_style"><field name="VAR" id="offset3Style">offset3Style</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></xml>
// Import required modules for wire creation and operations
const { wire } = bitbybit.occt.shapes;
const { operations } = bitbybit.occt;
// Import DTOs for interpolation and offset operations
const { InterpolationDto, OffsetDto } = Bit.Inputs.OCCT;
type TopoDSWirePointer = Bit.Inputs.OCCT.TopoDSWirePointer;
type Point3 = Bit.Inputs.Base.Point3;
const start = async () => {
// Define the stepover distance for CNC toolpaths
const stepoverDistance = 0.5;
// Step 1: Define control points for the base toolpath
const points = [
[-4, 0, -2],
[-2, 0, 2],
[0, 0, 1],
[2, 0, 3],
[4, 0, 0]
] as Point3[];
// Step 2: Create base wire through interpolation
const interpolationOpt = new InterpolationDto();
interpolationOpt.points = points;
interpolationOpt.periodic = false;
interpolationOpt.tolerance = 0.01;
const baseWire = await wire.interpolatePoints(interpolationOpt);
// Step 3: Create multiple offset toolpaths
// First offset
const offset1Opt = new OffsetDto<TopoDSWirePointer, any>();
offset1Opt.shape = baseWire;
offset1Opt.distance = stepoverDistance;
offset1Opt.tolerance = 0.01;
const offset1 = await operations.offset(offset1Opt);
// Second offset
const offset2Opt = new OffsetDto<TopoDSWirePointer, any>();
offset2Opt.shape = baseWire;
offset2Opt.distance = stepoverDistance * 2;
offset2Opt.tolerance = 0.01;
const offset2 = await operations.offset(offset2Opt);
// Third offset
const offset3Opt = new OffsetDto<TopoDSWirePointer, any>();
offset3Opt.shape = baseWire;
offset3Opt.distance = stepoverDistance * 3;
offset3Opt.tolerance = 0.01;
const offset3 = await operations.offset(offset3Opt);
// Step 4: Visualize all toolpaths with different colors
// Base wire (green - reference path)
const baseOptions = new Bit.Inputs.Draw.DrawOcctShapeSimpleOptions();
baseOptions.edgeWidth = 4;
baseOptions.edgeColour = "#00ff00"; // Green
baseOptions.drawFaces = false;
// Offset 1 (orange)
const offset1Options = new Bit.Inputs.Draw.DrawOcctShapeSimpleOptions();
offset1Options.edgeWidth = 3;
offset1Options.edgeColour = "#ff9900"; // Orange
offset1Options.drawFaces = false;
// Offset 2 (red-orange)
const offset2Options = new Bit.Inputs.Draw.DrawOcctShapeSimpleOptions();
offset2Options.edgeWidth = 3;
offset2Options.edgeColour = "#ff6600"; // Red-orange
offset2Options.drawFaces = false;
// Offset 3 (red)
const offset3Options = new Bit.Inputs.Draw.DrawOcctShapeSimpleOptions();
offset3Options.edgeWidth = 3;
offset3Options.edgeColour = "#ff3300"; // Red
offset3Options.drawFaces = false;
// Draw all toolpaths
bitbybit.draw.drawAnyAsync({ entity: baseWire, options: baseOptions });
bitbybit.draw.drawAnyAsync({ entity: offset1, options: offset1Options });
bitbybit.draw.drawAnyAsync({ entity: offset2, options: offset2Options });
bitbybit.draw.drawAnyAsync({ entity: offset3, options: offset3Options });
}
start();
Understanding the Workflow
The multiple wire offset workflow demonstrates a practical approach to generating parallel curves. You start by defining control points that establish the desired path geometry, then create a smooth interpolated wire that serves as your reference curve. Each offset operation takes this base wire and creates a new curve at a specified distance, with the distance typically calculated as multiples of a base offset value.
The stepover distance parameter controls the spacing between parallel curves and can be adjusted based on your specific requirements. In the example, we use multiples of 0.5 units to create three additional curves, each progressively further from the original. The visualization uses different colors to clearly distinguish between the base curve and its offsets, making it easy to understand the relationship between all generated elements.
This technique provides a foundation for various applications where parallel geometric elements are needed, from manufacturing processes to architectural design patterns. The consistent spacing and predictable geometric relationships make it particularly valuable for systematic design approaches where precision and repeatability are important.



