Merge branch 'main' into wip-multi-profile
This commit is contained in:
		@ -62,8 +62,80 @@ string],
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -127,6 +199,7 @@ string],
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	// The extrude surfaces.
 | 
						// The extrude surfaces.
 | 
				
			||||||
@ -152,24 +225,6 @@ string],
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -184,8 +239,80 @@ string],
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -249,6 +376,7 @@ string],
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	// The extrude surfaces.
 | 
						// The extrude surfaces.
 | 
				
			||||||
@ -274,24 +402,6 @@ string],
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -220,8 +220,80 @@ const example = extrude(10, exampleSketch)
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -285,6 +357,7 @@ const example = extrude(10, exampleSketch)
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	type: "extrudeGroup",
 | 
						type: "extrudeGroup",
 | 
				
			||||||
@ -311,24 +384,6 @@ const example = extrude(10, exampleSketch)
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
} |
 | 
					} |
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	type: "extrudeGroups",
 | 
						type: "extrudeGroups",
 | 
				
			||||||
 | 
				
			|||||||
@ -62,8 +62,80 @@ string],
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -127,6 +199,7 @@ string],
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	// The extrude surfaces.
 | 
						// The extrude surfaces.
 | 
				
			||||||
@ -152,24 +225,6 @@ string],
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -184,8 +239,80 @@ string],
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -249,6 +376,7 @@ string],
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	// The extrude surfaces.
 | 
						// The extrude surfaces.
 | 
				
			||||||
@ -274,24 +402,6 @@ string],
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -49,8 +49,80 @@ const revolution = startSketchOn(box, "revolveAxis")
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -114,6 +186,7 @@ const revolution = startSketchOn(box, "revolveAxis")
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	// The extrude surfaces.
 | 
						// The extrude surfaces.
 | 
				
			||||||
@ -139,24 +212,6 @@ const revolution = startSketchOn(box, "revolveAxis")
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -47,8 +47,80 @@ const example = extrude(5, exampleSketch)
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -112,6 +184,7 @@ const example = extrude(5, exampleSketch)
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	// The extrude surfaces.
 | 
						// The extrude surfaces.
 | 
				
			||||||
@ -137,24 +210,6 @@ const example = extrude(5, exampleSketch)
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -45,8 +45,80 @@ const example = extrude(5, exampleSketch)
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -110,6 +182,7 @@ const example = extrude(5, exampleSketch)
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	// The extrude surfaces.
 | 
						// The extrude surfaces.
 | 
				
			||||||
@ -135,24 +208,6 @@ const example = extrude(5, exampleSketch)
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -47,8 +47,80 @@ const example = extrude(5, exampleSketch)
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -112,6 +184,7 @@ const example = extrude(5, exampleSketch)
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	// The extrude surfaces.
 | 
						// The extrude surfaces.
 | 
				
			||||||
@ -137,24 +210,6 @@ const example = extrude(5, exampleSketch)
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -52,8 +52,80 @@ const part001 = startSketchOn('XY')
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -117,6 +189,7 @@ const part001 = startSketchOn('XY')
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	// The extrude surfaces.
 | 
						// The extrude surfaces.
 | 
				
			||||||
@ -142,24 +215,6 @@ const part001 = startSketchOn('XY')
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -174,8 +229,80 @@ const part001 = startSketchOn('XY')
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -239,6 +366,7 @@ const part001 = startSketchOn('XY')
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	// The extrude surfaces.
 | 
						// The extrude surfaces.
 | 
				
			||||||
@ -264,24 +392,6 @@ const part001 = startSketchOn('XY')
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -56,8 +56,80 @@ const example = extrude(-5, exampleSketch)
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -121,6 +193,7 @@ const example = extrude(-5, exampleSketch)
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	type: "extrudeGroup",
 | 
						type: "extrudeGroup",
 | 
				
			||||||
@ -147,24 +220,6 @@ const example = extrude(-5, exampleSketch)
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
} |
 | 
					} |
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	type: "extrudeGroups",
 | 
						type: "extrudeGroups",
 | 
				
			||||||
 | 
				
			|||||||
@ -54,8 +54,80 @@ const example = extrude(1, exampleSketch)
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -119,6 +191,7 @@ const example = extrude(1, exampleSketch)
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	type: "extrudeGroup",
 | 
						type: "extrudeGroup",
 | 
				
			||||||
@ -145,24 +218,6 @@ const example = extrude(1, exampleSketch)
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
} |
 | 
					} |
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	type: "extrudeGroups",
 | 
						type: "extrudeGroups",
 | 
				
			||||||
 | 
				
			|||||||
@ -311,8 +311,80 @@ string,
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -376,6 +448,7 @@ string,
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	// The extrude surfaces.
 | 
						// The extrude surfaces.
 | 
				
			||||||
@ -401,24 +474,6 @@ string,
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -50,8 +50,80 @@ string],
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -115,6 +187,7 @@ string],
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	// The extrude surfaces.
 | 
						// The extrude surfaces.
 | 
				
			||||||
@ -140,24 +213,6 @@ string],
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -172,8 +227,80 @@ string],
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -237,6 +364,7 @@ string],
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	// The extrude surfaces.
 | 
						// The extrude surfaces.
 | 
				
			||||||
@ -262,24 +390,6 @@ string],
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -167,8 +167,80 @@ const a1 = startSketchOn({
 | 
				
			|||||||
	height: number,
 | 
						height: number,
 | 
				
			||||||
	// The id of the extrude group.
 | 
						// The id of the extrude group.
 | 
				
			||||||
	id: uuid,
 | 
						id: uuid,
 | 
				
			||||||
	// The sketch group paths.
 | 
						// The sketch group.
 | 
				
			||||||
	sketchGroupValues: [{
 | 
						sketchGroup: {
 | 
				
			||||||
 | 
						// The id of the sketch group.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// What the sketch is on (can be a plane or a face).
 | 
				
			||||||
 | 
						on: {
 | 
				
			||||||
 | 
						// The id of the plane.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// Origin of the plane.
 | 
				
			||||||
 | 
						origin: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						type: "plane",
 | 
				
			||||||
 | 
						// Type for a plane.
 | 
				
			||||||
 | 
						value: "XY" | "XZ" | "YZ" | "Custom",
 | 
				
			||||||
 | 
						// What should the plane’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the plane’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					} |
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// The id of the face.
 | 
				
			||||||
 | 
						id: uuid,
 | 
				
			||||||
 | 
						// The original sketch group id of the object we are sketching on.
 | 
				
			||||||
 | 
						sketchGroupId: uuid,
 | 
				
			||||||
 | 
						type: "face",
 | 
				
			||||||
 | 
						// The tag of the face.
 | 
				
			||||||
 | 
						value: string,
 | 
				
			||||||
 | 
						// What should the face’s X axis be?
 | 
				
			||||||
 | 
						xAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// What should the face’s Y axis be?
 | 
				
			||||||
 | 
						yAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The z-axis (normal).
 | 
				
			||||||
 | 
						zAxis: {
 | 
				
			||||||
 | 
						x: number,
 | 
				
			||||||
 | 
						y: number,
 | 
				
			||||||
 | 
						z: number,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The starting path.
 | 
				
			||||||
 | 
						start: {
 | 
				
			||||||
 | 
						// The from point.
 | 
				
			||||||
 | 
						from: [number, number],
 | 
				
			||||||
 | 
						// The name of the path.
 | 
				
			||||||
 | 
						name: string,
 | 
				
			||||||
 | 
						// The to point.
 | 
				
			||||||
 | 
						to: [number, number],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
						// The paths in the sketch group.
 | 
				
			||||||
 | 
						value: [{
 | 
				
			||||||
	// The from point.
 | 
						// The from point.
 | 
				
			||||||
	from: [number, number],
 | 
						from: [number, number],
 | 
				
			||||||
	// The name of the path.
 | 
						// The name of the path.
 | 
				
			||||||
@ -232,6 +304,7 @@ const a1 = startSketchOn({
 | 
				
			|||||||
	to: [number, number],
 | 
						to: [number, number],
 | 
				
			||||||
	type: "Base",
 | 
						type: "Base",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
	// The id of the extrusion start cap
 | 
						// The id of the extrusion start cap
 | 
				
			||||||
	startCapId: uuid,
 | 
						startCapId: uuid,
 | 
				
			||||||
	// The extrude surfaces.
 | 
						// The extrude surfaces.
 | 
				
			||||||
@ -257,24 +330,6 @@ const a1 = startSketchOn({
 | 
				
			|||||||
	sourceRange: [number, number],
 | 
						sourceRange: [number, number],
 | 
				
			||||||
	type: "extrudeArc",
 | 
						type: "extrudeArc",
 | 
				
			||||||
}],
 | 
					}],
 | 
				
			||||||
	// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	xAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	yAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
	// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
	zAxis: {
 | 
					 | 
				
			||||||
	x: number,
 | 
					 | 
				
			||||||
	y: number,
 | 
					 | 
				
			||||||
	z: number,
 | 
					 | 
				
			||||||
},
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
* `tag`: `SketchOnFaceTag` - A tag for sketch on face. (OPTIONAL)
 | 
					* `tag`: `SketchOnFaceTag` - A tag for sketch on face. (OPTIONAL)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										29236
									
								
								docs/kcl/std.json
									
									
									
									
									
								
							
							
						
						
									
										29236
									
								
								docs/kcl/std.json
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -6,6 +6,7 @@ import {
 | 
				
			|||||||
  wiggleMove,
 | 
					  wiggleMove,
 | 
				
			||||||
  doExport,
 | 
					  doExport,
 | 
				
			||||||
  metaModifier,
 | 
					  metaModifier,
 | 
				
			||||||
 | 
					  TEST_COLORS,
 | 
				
			||||||
} from './test-utils'
 | 
					} from './test-utils'
 | 
				
			||||||
import waitOn from 'wait-on'
 | 
					import waitOn from 'wait-on'
 | 
				
			||||||
import { XOR, roundOff, uuidv4 } from 'lib/utils'
 | 
					import { XOR, roundOff, uuidv4 } from 'lib/utils'
 | 
				
			||||||
@ -77,7 +78,7 @@ test.beforeEach(async ({ context, page }) => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
test.setTimeout(60000)
 | 
					test.setTimeout(60000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test('Basic sketch', async ({ page }) => {
 | 
					async function doBasicSketch(page: Page, openPanes: string[]) {
 | 
				
			||||||
  const u = await getUtils(page)
 | 
					  const u = await getUtils(page)
 | 
				
			||||||
  await page.setViewportSize({ width: 1200, height: 500 })
 | 
					  await page.setViewportSize({ width: 1200, height: 500 })
 | 
				
			||||||
  const PUR = 400 / 37.5 //pixeltoUnitRatio
 | 
					  const PUR = 400 / 37.5 //pixeltoUnitRatio
 | 
				
			||||||
@ -85,6 +86,14 @@ test('Basic sketch', async ({ page }) => {
 | 
				
			|||||||
  await u.waitForAuthSkipAppStart()
 | 
					  await u.waitForAuthSkipAppStart()
 | 
				
			||||||
  await u.openDebugPanel()
 | 
					  await u.openDebugPanel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // If we have the code pane open, we should see the code.
 | 
				
			||||||
 | 
					  if (openPanes.includes('code')) {
 | 
				
			||||||
 | 
					    await expect(u.codeLocator).toHaveText(``)
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    // Ensure we don't see the code.
 | 
				
			||||||
 | 
					    await expect(u.codeLocator).not.toBeVisible()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  await expect(
 | 
					  await expect(
 | 
				
			||||||
    page.getByRole('button', { name: 'Start Sketch' })
 | 
					    page.getByRole('button', { name: 'Start Sketch' })
 | 
				
			||||||
  ).not.toBeDisabled()
 | 
					  ).not.toBeDisabled()
 | 
				
			||||||
@ -98,51 +107,72 @@ test('Basic sketch', async ({ page }) => {
 | 
				
			|||||||
  // select a plane
 | 
					  // select a plane
 | 
				
			||||||
  await page.mouse.click(700, 200)
 | 
					  await page.mouse.click(700, 200)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  await expect(u.codeLocator).toHaveText(
 | 
					  if (openPanes.includes('code')) {
 | 
				
			||||||
    `const sketch001 = startSketchOn('XZ')`
 | 
					    await expect(u.codeLocator).toHaveText(
 | 
				
			||||||
  )
 | 
					      `const sketch001 = startSketchOn('XZ')`
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  await u.closeDebugPanel()
 | 
					  await u.closeDebugPanel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
 | 
					  await page.waitForTimeout(1000) // TODO detect animation ending, or disable animation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const startXPx = 600
 | 
					  const startXPx = 600
 | 
				
			||||||
  await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
 | 
					  await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
 | 
				
			||||||
  await expect(u.codeLocator).toHaveText(`const sketch001 = startSketchOn('XZ')
 | 
					  if (openPanes.includes('code')) {
 | 
				
			||||||
 | 
					    await expect(u.codeLocator)
 | 
				
			||||||
 | 
					      .toHaveText(`const sketch001 = startSketchOn('XZ')
 | 
				
			||||||
  |> startProfileAt(${commonPoints.startAt}, %)`)
 | 
					  |> startProfileAt(${commonPoints.startAt}, %)`)
 | 
				
			||||||
  await page.waitForTimeout(100)
 | 
					  }
 | 
				
			||||||
 | 
					  await page.waitForTimeout(500)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
 | 
					  await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
 | 
				
			||||||
  await page.waitForTimeout(100)
 | 
					  await page.waitForTimeout(500)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  await expect(u.codeLocator).toHaveText(`const sketch001 = startSketchOn('XZ')
 | 
					  if (openPanes.includes('code')) {
 | 
				
			||||||
 | 
					    await expect(u.codeLocator)
 | 
				
			||||||
 | 
					      .toHaveText(`const sketch001 = startSketchOn('XZ')
 | 
				
			||||||
  |> startProfileAt(${commonPoints.startAt}, %)
 | 
					  |> startProfileAt(${commonPoints.startAt}, %)
 | 
				
			||||||
  |> line([${commonPoints.num1}, 0], %)`)
 | 
					  |> line([${commonPoints.num1}, 0], %)`)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  await page.waitForTimeout(500)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
 | 
					  await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
 | 
				
			||||||
  await expect(u.codeLocator).toHaveText(`const sketch001 = startSketchOn('XZ')
 | 
					  if (openPanes.includes('code')) {
 | 
				
			||||||
 | 
					    await expect(u.codeLocator)
 | 
				
			||||||
 | 
					      .toHaveText(`const sketch001 = startSketchOn('XZ')
 | 
				
			||||||
  |> startProfileAt(${commonPoints.startAt}, %)
 | 
					  |> startProfileAt(${commonPoints.startAt}, %)
 | 
				
			||||||
  |> line([${commonPoints.num1}, 0], %)
 | 
					  |> line([${commonPoints.num1}, 0], %)
 | 
				
			||||||
  |> line([0, ${commonPoints.num1 + 0.01}], %)`)
 | 
					  |> line([0, ${commonPoints.num1 + 0.01}], %)`)
 | 
				
			||||||
  await page.waitForTimeout(100)
 | 
					  }
 | 
				
			||||||
 | 
					  await page.waitForTimeout(500)
 | 
				
			||||||
  await page.mouse.click(startXPx, 500 - PUR * 20)
 | 
					  await page.mouse.click(startXPx, 500 - PUR * 20)
 | 
				
			||||||
  await expect(u.codeLocator).toHaveText(`const sketch001 = startSketchOn('XZ')
 | 
					  if (openPanes.includes('code')) {
 | 
				
			||||||
 | 
					    await expect(u.codeLocator)
 | 
				
			||||||
 | 
					      .toHaveText(`const sketch001 = startSketchOn('XZ')
 | 
				
			||||||
  |> startProfileAt(${commonPoints.startAt}, %)
 | 
					  |> startProfileAt(${commonPoints.startAt}, %)
 | 
				
			||||||
  |> line([${commonPoints.num1}, 0], %)
 | 
					  |> line([${commonPoints.num1}, 0], %)
 | 
				
			||||||
  |> line([0, ${commonPoints.num1 + 0.01}], %)
 | 
					  |> line([0, ${commonPoints.num1 + 0.01}], %)
 | 
				
			||||||
  |> line([-${commonPoints.num2}, 0], %)`)
 | 
					  |> line([-${commonPoints.num2}, 0], %)`)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // deselect line tool
 | 
					  // deselect line tool
 | 
				
			||||||
  await page.getByRole('button', { name: 'Line' }).click()
 | 
					  await page.getByRole('button', { name: 'Line' }).click()
 | 
				
			||||||
  await page.waitForTimeout(100)
 | 
					  await page.waitForTimeout(500)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const line1 = await u.getSegmentBodyCoords(`[data-overlay-index="${0}"]`, 0)
 | 
					  const line1 = await u.getSegmentBodyCoords(`[data-overlay-index="${0}"]`, 0)
 | 
				
			||||||
  await expect(await u.getGreatestPixDiff(line1, [249, 249, 249])).toBeLessThan(
 | 
					  if (openPanes.includes('code')) {
 | 
				
			||||||
    3
 | 
					    expect(await u.getGreatestPixDiff(line1, TEST_COLORS.WHITE)).toBeLessThan(3)
 | 
				
			||||||
  )
 | 
					    await expect(
 | 
				
			||||||
 | 
					      await u.getGreatestPixDiff(line1, [249, 249, 249])
 | 
				
			||||||
 | 
					    ).toBeLessThan(3)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  // click between first two clicks to get center of the line
 | 
					  // click between first two clicks to get center of the line
 | 
				
			||||||
  await page.mouse.click(startXPx + PUR * 15, 500 - PUR * 10)
 | 
					  await page.mouse.click(startXPx + PUR * 15, 500 - PUR * 10)
 | 
				
			||||||
  await page.waitForTimeout(100)
 | 
					  await page.waitForTimeout(100)
 | 
				
			||||||
  await expect(await u.getGreatestPixDiff(line1, [0, 0, 255])).toBeLessThan(3)
 | 
					  if (openPanes.includes('code')) {
 | 
				
			||||||
 | 
					    expect(await u.getGreatestPixDiff(line1, TEST_COLORS.BLUE)).toBeLessThan(3)
 | 
				
			||||||
 | 
					    await expect(await u.getGreatestPixDiff(line1, [0, 0, 255])).toBeLessThan(3)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // hold down shift
 | 
					  // hold down shift
 | 
				
			||||||
  await page.keyboard.down('Shift')
 | 
					  await page.keyboard.down('Shift')
 | 
				
			||||||
@ -150,16 +180,55 @@ test('Basic sketch', async ({ page }) => {
 | 
				
			|||||||
  await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 20)
 | 
					  await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 20)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // selected two lines therefore there should be two cursors
 | 
					  // selected two lines therefore there should be two cursors
 | 
				
			||||||
  await expect(page.locator('.cm-cursor')).toHaveCount(2)
 | 
					  if (openPanes.includes('code')) {
 | 
				
			||||||
 | 
					    await expect(page.locator('.cm-cursor')).toHaveCount(2)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  await page.getByRole('button', { name: 'Constrain' }).click()
 | 
					  await page.getByRole('button', { name: 'Constrain' }).click()
 | 
				
			||||||
  await page.getByRole('button', { name: 'Equal Length' }).click()
 | 
					  await page.getByRole('button', { name: 'Equal Length' }).click()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Open the code pane.
 | 
				
			||||||
 | 
					  await u.openKclCodePanel()
 | 
				
			||||||
  await expect(u.codeLocator).toHaveText(`const sketch001 = startSketchOn('XZ')
 | 
					  await expect(u.codeLocator).toHaveText(`const sketch001 = startSketchOn('XZ')
 | 
				
			||||||
  |> startProfileAt(${commonPoints.startAt}, %)
 | 
					  |> startProfileAt(${commonPoints.startAt}, %)
 | 
				
			||||||
  |> line([${commonPoints.num1}, 0], %, 'seg01')
 | 
					  |> line([${commonPoints.num1}, 0], %, 'seg01')
 | 
				
			||||||
  |> line([0, ${commonPoints.num1 + 0.01}], %)
 | 
					  |> line([0, ${commonPoints.num1 + 0.01}], %)
 | 
				
			||||||
  |> angledLine([180, segLen('seg01', %)], %)`)
 | 
					  |> angledLine([180, segLen('seg01', %)], %)`)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test.describe('Basic sketch', () => {
 | 
				
			||||||
 | 
					  test('code pane open at start', async ({ page }) => {
 | 
				
			||||||
 | 
					    // Load the app with the code panes
 | 
				
			||||||
 | 
					    await page.addInitScript(async () => {
 | 
				
			||||||
 | 
					      localStorage.setItem(
 | 
				
			||||||
 | 
					        'store',
 | 
				
			||||||
 | 
					        JSON.stringify({
 | 
				
			||||||
 | 
					          state: {
 | 
				
			||||||
 | 
					            openPanes: ['code'],
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          version: 0,
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await doBasicSketch(page, ['code'])
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  test('code pane closed at start', async ({ page }) => {
 | 
				
			||||||
 | 
					    // Load the app with the code panes
 | 
				
			||||||
 | 
					    await page.addInitScript(async () => {
 | 
				
			||||||
 | 
					      localStorage.setItem(
 | 
				
			||||||
 | 
					        'store',
 | 
				
			||||||
 | 
					        JSON.stringify({
 | 
				
			||||||
 | 
					          state: {
 | 
				
			||||||
 | 
					            openPanes: [],
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          version: 0,
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    await doBasicSketch(page, [])
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test.describe('Testing Camera Movement', () => {
 | 
					test.describe('Testing Camera Movement', () => {
 | 
				
			||||||
@ -2559,7 +2628,173 @@ const part002 = startSketchOn('-XZ')
 | 
				
			|||||||
  await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeVisible()
 | 
					  await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeVisible()
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test('Can edit segments by dragging their handles', async ({ page }) => {
 | 
					async function doEditSegmentsByDraggingHandle(page: Page, openPanes: string[]) {
 | 
				
			||||||
 | 
					  // Load the app with the code panes
 | 
				
			||||||
 | 
					  await page.addInitScript(async () => {
 | 
				
			||||||
 | 
					    localStorage.setItem(
 | 
				
			||||||
 | 
					      'persistCode',
 | 
				
			||||||
 | 
					      `const sketch001 = startSketchOn('XZ')
 | 
				
			||||||
 | 
					  |> startProfileAt([4.61, -14.01], %)
 | 
				
			||||||
 | 
					  |> line([12.73, -0.09], %)
 | 
				
			||||||
 | 
					  |> tangentialArcTo([24.95, -5.38], %)
 | 
				
			||||||
 | 
					  |> close(%)`
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const u = await getUtils(page)
 | 
				
			||||||
 | 
					  await page.setViewportSize({ width: 1200, height: 500 })
 | 
				
			||||||
 | 
					  await page.goto('/')
 | 
				
			||||||
 | 
					  await u.waitForAuthSkipAppStart()
 | 
				
			||||||
 | 
					  await expect(
 | 
				
			||||||
 | 
					    page.getByRole('button', { name: 'Start Sketch' })
 | 
				
			||||||
 | 
					  ).not.toBeDisabled()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  await page.waitForTimeout(100)
 | 
				
			||||||
 | 
					  await u.openAndClearDebugPanel()
 | 
				
			||||||
 | 
					  await u.sendCustomCmd({
 | 
				
			||||||
 | 
					    type: 'modeling_cmd_req',
 | 
				
			||||||
 | 
					    cmd_id: uuidv4(),
 | 
				
			||||||
 | 
					    cmd: {
 | 
				
			||||||
 | 
					      type: 'default_camera_look_at',
 | 
				
			||||||
 | 
					      vantage: { x: 0, y: -1250, z: 580 },
 | 
				
			||||||
 | 
					      center: { x: 0, y: 0, z: 0 },
 | 
				
			||||||
 | 
					      up: { x: 0, y: 0, z: 1 },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  await page.waitForTimeout(100)
 | 
				
			||||||
 | 
					  await u.sendCustomCmd({
 | 
				
			||||||
 | 
					    type: 'modeling_cmd_req',
 | 
				
			||||||
 | 
					    cmd_id: uuidv4(),
 | 
				
			||||||
 | 
					    cmd: {
 | 
				
			||||||
 | 
					      type: 'default_camera_get_settings',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  await page.waitForTimeout(100)
 | 
				
			||||||
 | 
					  await u.closeDebugPanel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // If we have the code pane open, we should see the code.
 | 
				
			||||||
 | 
					  if (openPanes.includes('code')) {
 | 
				
			||||||
 | 
					    await expect(u.codeLocator)
 | 
				
			||||||
 | 
					      .toHaveText(`const sketch001 = startSketchOn('XZ')
 | 
				
			||||||
 | 
					  |> startProfileAt([4.61, -14.01], %)
 | 
				
			||||||
 | 
					  |> line([12.73, -0.09], %)
 | 
				
			||||||
 | 
					  |> tangentialArcTo([24.95, -5.38], %)
 | 
				
			||||||
 | 
					  |> close(%)`)
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    // Ensure we don't see the code.
 | 
				
			||||||
 | 
					    await expect(u.codeLocator).not.toBeVisible()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const startPX = [665, 458]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const dragPX = 30
 | 
				
			||||||
 | 
					  let prevContent = ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (openPanes.includes('code')) {
 | 
				
			||||||
 | 
					    await page.getByText('startProfileAt([4.61, -14.01], %)').click()
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    // Wait for the render.
 | 
				
			||||||
 | 
					    await page.waitForTimeout(1000)
 | 
				
			||||||
 | 
					    // Select the sketch
 | 
				
			||||||
 | 
					    await page.mouse.click(700, 370)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeVisible()
 | 
				
			||||||
 | 
					  await page.getByRole('button', { name: 'Edit Sketch' }).click()
 | 
				
			||||||
 | 
					  await page.waitForTimeout(400)
 | 
				
			||||||
 | 
					  if (openPanes.includes('code')) {
 | 
				
			||||||
 | 
					    prevContent = await page.locator('.cm-content').innerText()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const step5 = { steps: 5 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // drag startProfieAt handle
 | 
				
			||||||
 | 
					  await page.mouse.move(startPX[0], startPX[1])
 | 
				
			||||||
 | 
					  await page.mouse.down()
 | 
				
			||||||
 | 
					  await page.mouse.move(startPX[0] + dragPX, startPX[1] - dragPX, step5)
 | 
				
			||||||
 | 
					  await page.mouse.up()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (openPanes.includes('code')) {
 | 
				
			||||||
 | 
					    await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
 | 
				
			||||||
 | 
					    prevContent = await page.locator('.cm-content').innerText()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // drag line handle
 | 
				
			||||||
 | 
					  await page.waitForTimeout(100)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const lineEnd = await u.getBoundingBox('[data-overlay-index="0"]')
 | 
				
			||||||
 | 
					  await page.mouse.move(lineEnd.x - 5, lineEnd.y)
 | 
				
			||||||
 | 
					  await page.mouse.down()
 | 
				
			||||||
 | 
					  await page.mouse.move(lineEnd.x + dragPX, lineEnd.y - dragPX, step5)
 | 
				
			||||||
 | 
					  await page.mouse.up()
 | 
				
			||||||
 | 
					  await page.waitForTimeout(100)
 | 
				
			||||||
 | 
					  if (openPanes.includes('code')) {
 | 
				
			||||||
 | 
					    await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
 | 
				
			||||||
 | 
					    prevContent = await page.locator('.cm-content').innerText()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // drag tangentialArcTo handle
 | 
				
			||||||
 | 
					  const tangentEnd = await u.getBoundingBox('[data-overlay-index="1"]')
 | 
				
			||||||
 | 
					  await page.mouse.move(tangentEnd.x, tangentEnd.y - 5)
 | 
				
			||||||
 | 
					  await page.mouse.down()
 | 
				
			||||||
 | 
					  await page.mouse.move(tangentEnd.x + dragPX, tangentEnd.y - dragPX, step5)
 | 
				
			||||||
 | 
					  await page.mouse.up()
 | 
				
			||||||
 | 
					  await page.waitForTimeout(100)
 | 
				
			||||||
 | 
					  if (openPanes.includes('code')) {
 | 
				
			||||||
 | 
					    await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Open the code pane
 | 
				
			||||||
 | 
					  await u.openKclCodePanel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // expect the code to have changed
 | 
				
			||||||
 | 
					  await expect(page.locator('.cm-content'))
 | 
				
			||||||
 | 
					    .toHaveText(`const sketch001 = startSketchOn('XZ')
 | 
				
			||||||
 | 
					  |> startProfileAt([6.44, -12.07], %)
 | 
				
			||||||
 | 
					  |> line([14.72, 1.97], %)
 | 
				
			||||||
 | 
					  |> tangentialArcTo([24.95, -5.38], %)
 | 
				
			||||||
 | 
					  |> line([1.97, 2.06], %)
 | 
				
			||||||
 | 
					  |> close(%)`)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test.describe('Can edit segments by dragging their handles', () => {
 | 
				
			||||||
 | 
					  test('code pane open at start', async ({ page }) => {
 | 
				
			||||||
 | 
					    // Load the app with the code panes
 | 
				
			||||||
 | 
					    await page.addInitScript(async () => {
 | 
				
			||||||
 | 
					      localStorage.setItem(
 | 
				
			||||||
 | 
					        'store',
 | 
				
			||||||
 | 
					        JSON.stringify({
 | 
				
			||||||
 | 
					          state: {
 | 
				
			||||||
 | 
					            openPanes: ['code'],
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          version: 0,
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    await doEditSegmentsByDraggingHandle(page, ['code'])
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  test('code pane closed at start', async ({ page }) => {
 | 
				
			||||||
 | 
					    // Load the app with the code panes
 | 
				
			||||||
 | 
					    await page.addInitScript(async () => {
 | 
				
			||||||
 | 
					      localStorage.setItem(
 | 
				
			||||||
 | 
					        'store',
 | 
				
			||||||
 | 
					        JSON.stringify({
 | 
				
			||||||
 | 
					          state: {
 | 
				
			||||||
 | 
					            openPanes: [],
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          version: 0,
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    await doEditSegmentsByDraggingHandle(page, [])
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('Can edit a sketch that has been extruded in the same pipe', async ({
 | 
				
			||||||
 | 
					  page,
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
  const u = await getUtils(page)
 | 
					  const u = await getUtils(page)
 | 
				
			||||||
  await page.addInitScript(async () => {
 | 
					  await page.addInitScript(async () => {
 | 
				
			||||||
    localStorage.setItem(
 | 
					    localStorage.setItem(
 | 
				
			||||||
@ -2567,7 +2802,9 @@ test('Can edit segments by dragging their handles', async ({ page }) => {
 | 
				
			|||||||
      `const sketch001 = startSketchOn('XZ')
 | 
					      `const sketch001 = startSketchOn('XZ')
 | 
				
			||||||
  |> startProfileAt([4.61, -14.01], %)
 | 
					  |> startProfileAt([4.61, -14.01], %)
 | 
				
			||||||
  |> line([12.73, -0.09], %)
 | 
					  |> line([12.73, -0.09], %)
 | 
				
			||||||
  |> tangentialArcTo([24.95, -5.38], %)`
 | 
					  |> tangentialArcTo([24.95, -5.38], %)
 | 
				
			||||||
 | 
					  |> close(%)
 | 
				
			||||||
 | 
					  |> extrude(5, %)`
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2648,8 +2885,111 @@ test('Can edit segments by dragging their handles', async ({ page }) => {
 | 
				
			|||||||
  await expect(page.locator('.cm-content'))
 | 
					  await expect(page.locator('.cm-content'))
 | 
				
			||||||
    .toHaveText(`const sketch001 = startSketchOn('XZ')
 | 
					    .toHaveText(`const sketch001 = startSketchOn('XZ')
 | 
				
			||||||
  |> startProfileAt([6.44, -12.07], %)
 | 
					  |> startProfileAt([6.44, -12.07], %)
 | 
				
			||||||
  |> line([14.72, 1.97], %)
 | 
					  |> line([14.72, 2.01], %)
 | 
				
			||||||
  |> tangentialArcTo([26.92, -3.32], %)`)
 | 
					  |> tangentialArcTo([24.95, -5.38], %)
 | 
				
			||||||
 | 
					  |> line([1.97, 2.06], %)
 | 
				
			||||||
 | 
					  |> close(%)
 | 
				
			||||||
 | 
					  |> extrude(5, %)`)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('Can edit a sketch that has been revolved in the same pipe', async ({
 | 
				
			||||||
 | 
					  page,
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
 | 
					  const u = await getUtils(page)
 | 
				
			||||||
 | 
					  await page.addInitScript(async () => {
 | 
				
			||||||
 | 
					    localStorage.setItem(
 | 
				
			||||||
 | 
					      'persistCode',
 | 
				
			||||||
 | 
					      `const sketch001 = startSketchOn('XZ')
 | 
				
			||||||
 | 
					  |> startProfileAt([4.61, -14.01], %)
 | 
				
			||||||
 | 
					  |> line([12.73, -0.09], %)
 | 
				
			||||||
 | 
					  |> tangentialArcTo([24.95, -5.38], %)
 | 
				
			||||||
 | 
					  |> close(%)
 | 
				
			||||||
 | 
					  |> revolve({ axis: "X",}, %)`
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  await page.setViewportSize({ width: 1200, height: 500 })
 | 
				
			||||||
 | 
					  await page.goto('/')
 | 
				
			||||||
 | 
					  await u.waitForAuthSkipAppStart()
 | 
				
			||||||
 | 
					  await expect(
 | 
				
			||||||
 | 
					    page.getByRole('button', { name: 'Start Sketch' })
 | 
				
			||||||
 | 
					  ).not.toBeDisabled()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  await page.waitForTimeout(100)
 | 
				
			||||||
 | 
					  await u.openAndClearDebugPanel()
 | 
				
			||||||
 | 
					  await u.sendCustomCmd({
 | 
				
			||||||
 | 
					    type: 'modeling_cmd_req',
 | 
				
			||||||
 | 
					    cmd_id: uuidv4(),
 | 
				
			||||||
 | 
					    cmd: {
 | 
				
			||||||
 | 
					      type: 'default_camera_look_at',
 | 
				
			||||||
 | 
					      vantage: { x: 0, y: -1250, z: 580 },
 | 
				
			||||||
 | 
					      center: { x: 0, y: 0, z: 0 },
 | 
				
			||||||
 | 
					      up: { x: 0, y: 0, z: 1 },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  await page.waitForTimeout(100)
 | 
				
			||||||
 | 
					  await u.sendCustomCmd({
 | 
				
			||||||
 | 
					    type: 'modeling_cmd_req',
 | 
				
			||||||
 | 
					    cmd_id: uuidv4(),
 | 
				
			||||||
 | 
					    cmd: {
 | 
				
			||||||
 | 
					      type: 'default_camera_get_settings',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  await page.waitForTimeout(100)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const startPX = [665, 458]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const dragPX = 30
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  await page.getByText('startProfileAt([4.61, -14.01], %)').click()
 | 
				
			||||||
 | 
					  await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeVisible()
 | 
				
			||||||
 | 
					  await page.getByRole('button', { name: 'Edit Sketch' }).click()
 | 
				
			||||||
 | 
					  await page.waitForTimeout(400)
 | 
				
			||||||
 | 
					  let prevContent = await page.locator('.cm-content').innerText()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const step5 = { steps: 5 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // drag startProfieAt handle
 | 
				
			||||||
 | 
					  await page.mouse.move(startPX[0], startPX[1])
 | 
				
			||||||
 | 
					  await page.mouse.down()
 | 
				
			||||||
 | 
					  await page.mouse.move(startPX[0] + dragPX, startPX[1] - dragPX, step5)
 | 
				
			||||||
 | 
					  await page.mouse.up()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
 | 
				
			||||||
 | 
					  prevContent = await page.locator('.cm-content').innerText()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // drag line handle
 | 
				
			||||||
 | 
					  await page.waitForTimeout(100)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const lineEnd = await u.getBoundingBox('[data-overlay-index="0"]')
 | 
				
			||||||
 | 
					  await page.mouse.move(lineEnd.x - 5, lineEnd.y)
 | 
				
			||||||
 | 
					  await page.mouse.down()
 | 
				
			||||||
 | 
					  await page.mouse.move(lineEnd.x + dragPX, lineEnd.y - dragPX, step5)
 | 
				
			||||||
 | 
					  await page.mouse.up()
 | 
				
			||||||
 | 
					  await page.waitForTimeout(100)
 | 
				
			||||||
 | 
					  await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
 | 
				
			||||||
 | 
					  prevContent = await page.locator('.cm-content').innerText()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // drag tangentialArcTo handle
 | 
				
			||||||
 | 
					  const tangentEnd = await u.getBoundingBox('[data-overlay-index="1"]')
 | 
				
			||||||
 | 
					  await page.mouse.move(tangentEnd.x, tangentEnd.y - 5)
 | 
				
			||||||
 | 
					  await page.mouse.down()
 | 
				
			||||||
 | 
					  await page.mouse.move(tangentEnd.x + dragPX, tangentEnd.y - dragPX, step5)
 | 
				
			||||||
 | 
					  await page.mouse.up()
 | 
				
			||||||
 | 
					  await page.waitForTimeout(100)
 | 
				
			||||||
 | 
					  await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // expect the code to have changed
 | 
				
			||||||
 | 
					  await expect(page.locator('.cm-content'))
 | 
				
			||||||
 | 
					    .toHaveText(`const sketch001 = startSketchOn('XZ')
 | 
				
			||||||
 | 
					  |> startProfileAt([6.44, -12.07], %)
 | 
				
			||||||
 | 
					  |> line([14.72, 2.01], %)
 | 
				
			||||||
 | 
					  |> tangentialArcTo([24.95, -5.38], %)
 | 
				
			||||||
 | 
					  |> line([1.97, 2.06], %)
 | 
				
			||||||
 | 
					  |> close(%)
 | 
				
			||||||
 | 
					  |> revolve({ axis: "X" }, %)`)
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const doSnapAtDifferentScales = async (
 | 
					const doSnapAtDifferentScales = async (
 | 
				
			||||||
@ -3769,6 +4109,81 @@ const part002 = startSketchOn('XZ')
 | 
				
			|||||||
      })
 | 
					      })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  test('Horizontally constrained line remains selected after applying constraint', async ({
 | 
				
			||||||
 | 
					    page,
 | 
				
			||||||
 | 
					  }) => {
 | 
				
			||||||
 | 
					    await page.addInitScript(async () => {
 | 
				
			||||||
 | 
					      localStorage.setItem(
 | 
				
			||||||
 | 
					        'persistCode',
 | 
				
			||||||
 | 
					        `const sketch001 = startSketchOn('XY')
 | 
				
			||||||
 | 
					  |> startProfileAt([-1.05, -1.07], %)
 | 
				
			||||||
 | 
					  |> line([3.79, 2.68], %, 'seg01')
 | 
				
			||||||
 | 
					  |> line([3.13, -2.4], %)`
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    const u = await getUtils(page)
 | 
				
			||||||
 | 
					    await page.setViewportSize({ width: 1200, height: 500 })
 | 
				
			||||||
 | 
					    await page.goto('/')
 | 
				
			||||||
 | 
					    await u.waitForAuthSkipAppStart()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await page.getByText("line([3.79, 2.68], %, 'seg01')").click()
 | 
				
			||||||
 | 
					    await page.getByRole('button', { name: 'Edit Sketch' }).click()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await page.waitForTimeout(100)
 | 
				
			||||||
 | 
					    const lineBefore = await u.getSegmentBodyCoords(
 | 
				
			||||||
 | 
					      `[data-overlay-index="1"]`,
 | 
				
			||||||
 | 
					      0
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    expect(
 | 
				
			||||||
 | 
					      await u.getGreatestPixDiff(lineBefore, TEST_COLORS.WHITE)
 | 
				
			||||||
 | 
					    ).toBeLessThan(3)
 | 
				
			||||||
 | 
					    await page.mouse.move(lineBefore.x, lineBefore.y)
 | 
				
			||||||
 | 
					    await page.waitForTimeout(50)
 | 
				
			||||||
 | 
					    await page.mouse.click(lineBefore.x, lineBefore.y)
 | 
				
			||||||
 | 
					    expect(
 | 
				
			||||||
 | 
					      await u.getGreatestPixDiff(lineBefore, TEST_COLORS.BLUE)
 | 
				
			||||||
 | 
					    ).toBeLessThan(3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await page
 | 
				
			||||||
 | 
					      .getByRole('button', {
 | 
				
			||||||
 | 
					        name: 'Constrain',
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .click()
 | 
				
			||||||
 | 
					    await page.getByRole('button', { name: 'horizontal', exact: true }).click()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let activeLinesContent = await page.locator('.cm-activeLine').all()
 | 
				
			||||||
 | 
					    await expect(activeLinesContent[0]).toHaveText(`|> xLine(3.13, %)`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // If the overlay-angle is updated the THREE.js scene is in a good state
 | 
				
			||||||
 | 
					    await expect(
 | 
				
			||||||
 | 
					      await page.locator('[data-overlay-index="1"]')
 | 
				
			||||||
 | 
					    ).toHaveAttribute('data-overlay-angle', '0')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const lineAfter = await u.getSegmentBodyCoords(
 | 
				
			||||||
 | 
					      `[data-overlay-index="1"]`,
 | 
				
			||||||
 | 
					      0
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    expect(
 | 
				
			||||||
 | 
					      await u.getGreatestPixDiff(lineAfter, TEST_COLORS.BLUE)
 | 
				
			||||||
 | 
					    ).toBeLessThan(3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await page
 | 
				
			||||||
 | 
					      .getByRole('button', {
 | 
				
			||||||
 | 
					        name: 'Constrain',
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .click()
 | 
				
			||||||
 | 
					    await page.getByRole('button', { name: 'length', exact: true }).click()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await page.getByLabel('length Value').fill('10')
 | 
				
			||||||
 | 
					    await page.getByRole('button', { name: 'Add constraining value' }).click()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    activeLinesContent = await page.locator('.cm-activeLine').all()
 | 
				
			||||||
 | 
					    await expect(activeLinesContent[0]).toHaveText(`|> xLine(length001, %)`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
 | 
				
			||||||
 | 
					    await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test.describe('Testing segment overlays', () => {
 | 
					test.describe('Testing segment overlays', () => {
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,13 @@ import { Protocol } from 'playwright-core/types/protocol'
 | 
				
			|||||||
import type { Models } from '@kittycad/lib'
 | 
					import type { Models } from '@kittycad/lib'
 | 
				
			||||||
import { APP_NAME } from 'lib/constants'
 | 
					import { APP_NAME } from 'lib/constants'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TestColor = [number, number, number]
 | 
				
			||||||
 | 
					export const TEST_COLORS = {
 | 
				
			||||||
 | 
					  WHITE: [249, 249, 249] as TestColor,
 | 
				
			||||||
 | 
					  YELLOW: [255, 255, 0] as TestColor,
 | 
				
			||||||
 | 
					  BLUE: [0, 0, 255] as TestColor,
 | 
				
			||||||
 | 
					} as const
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function waitForPageLoad(page: Page) {
 | 
					async function waitForPageLoad(page: Page) {
 | 
				
			||||||
  // wait for 'Loading stream...' spinner
 | 
					  // wait for 'Loading stream...' spinner
 | 
				
			||||||
  await page.getByTestId('loading-stream').waitFor()
 | 
					  await page.getByTestId('loading-stream').waitFor()
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "untitled-app",
 | 
					  "name": "untitled-app",
 | 
				
			||||||
  "version": "0.22.3",
 | 
					  "version": "0.22.5",
 | 
				
			||||||
  "private": true,
 | 
					  "private": true,
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "@codemirror/autocomplete": "^6.16.0",
 | 
					    "@codemirror/autocomplete": "^6.16.0",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1480
									
								
								src-tauri/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1480
									
								
								src-tauri/Cargo.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -20,7 +20,7 @@ kittycad = "0.3.5"
 | 
				
			|||||||
log = "0.4.21"
 | 
					log = "0.4.21"
 | 
				
			||||||
oauth2 = "4.4.2"
 | 
					oauth2 = "4.4.2"
 | 
				
			||||||
serde_json = "1.0"
 | 
					serde_json = "1.0"
 | 
				
			||||||
tauri = { version = "2.0.0-beta.22", features = [ "devtools", "unstable"] }
 | 
					tauri = { version = "2.0.0-beta.15", features = [ "devtools", "unstable"] }
 | 
				
			||||||
tauri-plugin-cli = { version = "2.0.0-beta.3" }
 | 
					tauri-plugin-cli = { version = "2.0.0-beta.3" }
 | 
				
			||||||
tauri-plugin-deep-link = { version = "2.0.0-beta.3" }
 | 
					tauri-plugin-deep-link = { version = "2.0.0-beta.3" }
 | 
				
			||||||
tauri-plugin-dialog = { version = "2.0.0-beta.6" }
 | 
					tauri-plugin-dialog = { version = "2.0.0-beta.6" }
 | 
				
			||||||
 | 
				
			|||||||
@ -63,17 +63,16 @@
 | 
				
			|||||||
      "subcommands": {}
 | 
					      "subcommands": {}
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "deep-link": {
 | 
					    "deep-link": {
 | 
				
			||||||
      "mobile": [],
 | 
					      "domains": [
 | 
				
			||||||
      "desktop": {
 | 
					        {
 | 
				
			||||||
        "schemes": [
 | 
					          "host": "app.zoo.dev"
 | 
				
			||||||
          "app.zoo.dev"
 | 
					        }
 | 
				
			||||||
        ]
 | 
					      ]
 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "shell": {
 | 
					    "shell": {
 | 
				
			||||||
      "open": true
 | 
					      "open": true
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "productName": "Zoo Modeling App",
 | 
					  "productName": "Zoo Modeling App",
 | 
				
			||||||
  "version": "0.22.3"
 | 
					  "version": "0.22.5"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -73,7 +73,7 @@ import {
 | 
				
			|||||||
  changeSketchArguments,
 | 
					  changeSketchArguments,
 | 
				
			||||||
  updateStartProfileAtArgs,
 | 
					  updateStartProfileAtArgs,
 | 
				
			||||||
} from 'lang/std/sketch'
 | 
					} from 'lang/std/sketch'
 | 
				
			||||||
import { normaliseAngle, roundOff, throttle } from 'lib/utils'
 | 
					import { isOverlap, normaliseAngle, roundOff, throttle } from 'lib/utils'
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  createArrayExpression,
 | 
					  createArrayExpression,
 | 
				
			||||||
  createCallExpressionStdLib,
 | 
					  createCallExpressionStdLib,
 | 
				
			||||||
@ -83,6 +83,7 @@ import {
 | 
				
			|||||||
  findUniqueName,
 | 
					  findUniqueName,
 | 
				
			||||||
} from 'lang/modifyAst'
 | 
					} from 'lang/modifyAst'
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
 | 
					  Selections,
 | 
				
			||||||
  getEventForSegmentSelection,
 | 
					  getEventForSegmentSelection,
 | 
				
			||||||
  sendSelectEventToEngine,
 | 
					  sendSelectEventToEngine,
 | 
				
			||||||
} from 'lib/selections'
 | 
					} from 'lib/selections'
 | 
				
			||||||
@ -300,6 +301,7 @@ export class SceneEntities {
 | 
				
			|||||||
    position,
 | 
					    position,
 | 
				
			||||||
    maybeModdedAst,
 | 
					    maybeModdedAst,
 | 
				
			||||||
    draftExpressionsIndices,
 | 
					    draftExpressionsIndices,
 | 
				
			||||||
 | 
					    selectionRanges,
 | 
				
			||||||
  }: {
 | 
					  }: {
 | 
				
			||||||
    sketchPathToNode: PathToNode
 | 
					    sketchPathToNode: PathToNode
 | 
				
			||||||
    maybeModdedAst: Program
 | 
					    maybeModdedAst: Program
 | 
				
			||||||
@ -307,6 +309,7 @@ export class SceneEntities {
 | 
				
			|||||||
    forward: [number, number, number]
 | 
					    forward: [number, number, number]
 | 
				
			||||||
    up: [number, number, number]
 | 
					    up: [number, number, number]
 | 
				
			||||||
    position?: [number, number, number]
 | 
					    position?: [number, number, number]
 | 
				
			||||||
 | 
					    selectionRanges?: Selections
 | 
				
			||||||
  }): Promise<{
 | 
					  }): Promise<{
 | 
				
			||||||
    truncatedAst: Program
 | 
					    truncatedAst: Program
 | 
				
			||||||
    programMemoryOverride: ProgramMemory
 | 
					    programMemoryOverride: ProgramMemory
 | 
				
			||||||
@ -396,6 +399,12 @@ export class SceneEntities {
 | 
				
			|||||||
        draftExpressionsIndices &&
 | 
					        draftExpressionsIndices &&
 | 
				
			||||||
        index <= draftExpressionsIndices.end &&
 | 
					        index <= draftExpressionsIndices.end &&
 | 
				
			||||||
        index >= draftExpressionsIndices.start
 | 
					        index >= draftExpressionsIndices.start
 | 
				
			||||||
 | 
					      const isSelected = selectionRanges?.codeBasedSelections.some(
 | 
				
			||||||
 | 
					        (selection) => {
 | 
				
			||||||
 | 
					          return isOverlap(selection.range, segment.__geoMeta.sourceRange)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      let seg
 | 
					      let seg
 | 
				
			||||||
      const callExpName = getNodeFromPath<CallExpression>(
 | 
					      const callExpName = getNodeFromPath<CallExpression>(
 | 
				
			||||||
        maybeModdedAst,
 | 
					        maybeModdedAst,
 | 
				
			||||||
@ -413,6 +422,7 @@ export class SceneEntities {
 | 
				
			|||||||
          scale: factor,
 | 
					          scale: factor,
 | 
				
			||||||
          texture: sceneInfra.extraSegmentTexture,
 | 
					          texture: sceneInfra.extraSegmentTexture,
 | 
				
			||||||
          theme: sceneInfra._theme,
 | 
					          theme: sceneInfra._theme,
 | 
				
			||||||
 | 
					          isSelected,
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        callbacks.push(
 | 
					        callbacks.push(
 | 
				
			||||||
          this.updateTangentialArcToSegment({
 | 
					          this.updateTangentialArcToSegment({
 | 
				
			||||||
@ -434,6 +444,7 @@ export class SceneEntities {
 | 
				
			|||||||
          callExpName,
 | 
					          callExpName,
 | 
				
			||||||
          texture: sceneInfra.extraSegmentTexture,
 | 
					          texture: sceneInfra.extraSegmentTexture,
 | 
				
			||||||
          theme: sceneInfra._theme,
 | 
					          theme: sceneInfra._theme,
 | 
				
			||||||
 | 
					          isSelected,
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        callbacks.push(
 | 
					        callbacks.push(
 | 
				
			||||||
          this.updateStraightSegment({
 | 
					          this.updateStraightSegment({
 | 
				
			||||||
@ -1388,11 +1399,12 @@ export class SceneEntities {
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
      onClick: async (args) => {
 | 
					      onClick: async (args) => {
 | 
				
			||||||
        const { streamDimensions } = useStore.getState()
 | 
					        const { streamDimensions } = useStore.getState()
 | 
				
			||||||
        const { entity_id, ...rest } = await sendSelectEventToEngine(
 | 
					        const { entity_id } = await sendSelectEventToEngine(
 | 
				
			||||||
          args?.mouseEvent,
 | 
					          args?.mouseEvent,
 | 
				
			||||||
          document.getElementById('video-stream') as HTMLVideoElement,
 | 
					          document.getElementById('video-stream') as HTMLVideoElement,
 | 
				
			||||||
          streamDimensions
 | 
					          streamDimensions
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let _entity_id = entity_id
 | 
					        let _entity_id = entity_id
 | 
				
			||||||
        if (!_entity_id) return
 | 
					        if (!_entity_id) return
 | 
				
			||||||
        if (
 | 
					        if (
 | 
				
			||||||
@ -1762,7 +1774,11 @@ export function sketchGroupFromPathToNode({
 | 
				
			|||||||
    pathToNode,
 | 
					    pathToNode,
 | 
				
			||||||
    'VariableDeclarator'
 | 
					    'VariableDeclarator'
 | 
				
			||||||
  ).node
 | 
					  ).node
 | 
				
			||||||
  return programMemory.root[varDec?.id?.name || ''] as SketchGroup
 | 
					  const result = programMemory.root[varDec?.id?.name || '']
 | 
				
			||||||
 | 
					  if (result?.type === 'ExtrudeGroup') {
 | 
				
			||||||
 | 
					    return result.sketchGroup
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return result as SketchGroup
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function colorSegment(object: any, color: number) {
 | 
					function colorSegment(object: any, color: number) {
 | 
				
			||||||
 | 
				
			|||||||
@ -45,18 +45,21 @@ export function profileStart({
 | 
				
			|||||||
  pathToNode,
 | 
					  pathToNode,
 | 
				
			||||||
  scale = 1,
 | 
					  scale = 1,
 | 
				
			||||||
  theme,
 | 
					  theme,
 | 
				
			||||||
 | 
					  isSelected,
 | 
				
			||||||
}: {
 | 
					}: {
 | 
				
			||||||
  from: Coords2d
 | 
					  from: Coords2d
 | 
				
			||||||
  id: string
 | 
					  id: string
 | 
				
			||||||
  pathToNode: PathToNode
 | 
					  pathToNode: PathToNode
 | 
				
			||||||
  scale?: number
 | 
					  scale?: number
 | 
				
			||||||
  theme: Themes
 | 
					  theme: Themes
 | 
				
			||||||
 | 
					  isSelected?: boolean
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
  const group = new Group()
 | 
					  const group = new Group()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const geometry = new BoxGeometry(12, 12, 12) // in pixels scaled later
 | 
					  const geometry = new BoxGeometry(12, 12, 12) // in pixels scaled later
 | 
				
			||||||
  const baseColor = getThemeColorForThreeJs(theme)
 | 
					  const baseColor = getThemeColorForThreeJs(theme)
 | 
				
			||||||
  const body = new MeshBasicMaterial({ color: baseColor })
 | 
					  const color = isSelected ? 0x0000ff : baseColor
 | 
				
			||||||
 | 
					  const body = new MeshBasicMaterial({ color })
 | 
				
			||||||
  const mesh = new Mesh(geometry, body)
 | 
					  const mesh = new Mesh(geometry, body)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  group.add(mesh)
 | 
					  group.add(mesh)
 | 
				
			||||||
@ -66,7 +69,8 @@ export function profileStart({
 | 
				
			|||||||
    id,
 | 
					    id,
 | 
				
			||||||
    from,
 | 
					    from,
 | 
				
			||||||
    pathToNode,
 | 
					    pathToNode,
 | 
				
			||||||
    isSelected: false,
 | 
					    isSelected,
 | 
				
			||||||
 | 
					    baseColor,
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  group.name = PROFILE_START
 | 
					  group.name = PROFILE_START
 | 
				
			||||||
  group.position.set(from[0], from[1], 0)
 | 
					  group.position.set(from[0], from[1], 0)
 | 
				
			||||||
@ -84,6 +88,7 @@ export function straightSegment({
 | 
				
			|||||||
  callExpName,
 | 
					  callExpName,
 | 
				
			||||||
  texture,
 | 
					  texture,
 | 
				
			||||||
  theme,
 | 
					  theme,
 | 
				
			||||||
 | 
					  isSelected = false,
 | 
				
			||||||
}: {
 | 
					}: {
 | 
				
			||||||
  from: Coords2d
 | 
					  from: Coords2d
 | 
				
			||||||
  to: Coords2d
 | 
					  to: Coords2d
 | 
				
			||||||
@ -94,6 +99,7 @@ export function straightSegment({
 | 
				
			|||||||
  callExpName: string
 | 
					  callExpName: string
 | 
				
			||||||
  texture: Texture
 | 
					  texture: Texture
 | 
				
			||||||
  theme: Themes
 | 
					  theme: Themes
 | 
				
			||||||
 | 
					  isSelected?: boolean
 | 
				
			||||||
}): Group {
 | 
					}): Group {
 | 
				
			||||||
  const group = new Group()
 | 
					  const group = new Group()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -119,7 +125,8 @@ export function straightSegment({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  const baseColor =
 | 
					  const baseColor =
 | 
				
			||||||
    callExpName === 'close' ? 0x444444 : getThemeColorForThreeJs(theme)
 | 
					    callExpName === 'close' ? 0x444444 : getThemeColorForThreeJs(theme)
 | 
				
			||||||
  const body = new MeshBasicMaterial({ color: baseColor })
 | 
					  const color = isSelected ? 0x0000ff : baseColor
 | 
				
			||||||
 | 
					  const body = new MeshBasicMaterial({ color })
 | 
				
			||||||
  const mesh = new Mesh(geometry, body)
 | 
					  const mesh = new Mesh(geometry, body)
 | 
				
			||||||
  mesh.userData.type = isDraftSegment
 | 
					  mesh.userData.type = isDraftSegment
 | 
				
			||||||
    ? STRAIGHT_SEGMENT_DASH
 | 
					    ? STRAIGHT_SEGMENT_DASH
 | 
				
			||||||
@ -132,7 +139,7 @@ export function straightSegment({
 | 
				
			|||||||
    from,
 | 
					    from,
 | 
				
			||||||
    to,
 | 
					    to,
 | 
				
			||||||
    pathToNode,
 | 
					    pathToNode,
 | 
				
			||||||
    isSelected: false,
 | 
					    isSelected,
 | 
				
			||||||
    callExpName,
 | 
					    callExpName,
 | 
				
			||||||
    baseColor,
 | 
					    baseColor,
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -141,7 +148,7 @@ export function straightSegment({
 | 
				
			|||||||
  const length = Math.sqrt(
 | 
					  const length = Math.sqrt(
 | 
				
			||||||
    Math.pow(to[0] - from[0], 2) + Math.pow(to[1] - from[1], 2)
 | 
					    Math.pow(to[0] - from[0], 2) + Math.pow(to[1] - from[1], 2)
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
  const arrowGroup = createArrowhead(scale, theme)
 | 
					  const arrowGroup = createArrowhead(scale, theme, color)
 | 
				
			||||||
  arrowGroup.position.set(to[0], to[1], 0)
 | 
					  arrowGroup.position.set(to[0], to[1], 0)
 | 
				
			||||||
  const dir = new Vector3()
 | 
					  const dir = new Vector3()
 | 
				
			||||||
    .subVectors(new Vector3(to[0], to[1], 0), new Vector3(from[0], from[1], 0))
 | 
					    .subVectors(new Vector3(to[0], to[1], 0), new Vector3(from[0], from[1], 0))
 | 
				
			||||||
@ -169,9 +176,10 @@ export function straightSegment({
 | 
				
			|||||||
  return group
 | 
					  return group
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function createArrowhead(scale = 1, theme: Themes): Group {
 | 
					function createArrowhead(scale = 1, theme: Themes, color?: number): Group {
 | 
				
			||||||
 | 
					  const baseColor = getThemeColorForThreeJs(theme)
 | 
				
			||||||
  const arrowMaterial = new MeshBasicMaterial({
 | 
					  const arrowMaterial = new MeshBasicMaterial({
 | 
				
			||||||
    color: getThemeColorForThreeJs(theme),
 | 
					    color: color || baseColor,
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
  // specify the size of the geometry in pixels (i.e. cone height = 20px, cone radius = 4.5px)
 | 
					  // specify the size of the geometry in pixels (i.e. cone height = 20px, cone radius = 4.5px)
 | 
				
			||||||
  // we'll scale the group to the correct size later to match these sizes in screen space
 | 
					  // we'll scale the group to the correct size later to match these sizes in screen space
 | 
				
			||||||
@ -232,6 +240,7 @@ export function tangentialArcToSegment({
 | 
				
			|||||||
  scale = 1,
 | 
					  scale = 1,
 | 
				
			||||||
  texture,
 | 
					  texture,
 | 
				
			||||||
  theme,
 | 
					  theme,
 | 
				
			||||||
 | 
					  isSelected,
 | 
				
			||||||
}: {
 | 
					}: {
 | 
				
			||||||
  prevSegment: SketchGroup['value'][number]
 | 
					  prevSegment: SketchGroup['value'][number]
 | 
				
			||||||
  from: Coords2d
 | 
					  from: Coords2d
 | 
				
			||||||
@ -242,6 +251,7 @@ export function tangentialArcToSegment({
 | 
				
			|||||||
  scale?: number
 | 
					  scale?: number
 | 
				
			||||||
  texture: Texture
 | 
					  texture: Texture
 | 
				
			||||||
  theme: Themes
 | 
					  theme: Themes
 | 
				
			||||||
 | 
					  isSelected?: boolean
 | 
				
			||||||
}): Group {
 | 
					}): Group {
 | 
				
			||||||
  const group = new Group()
 | 
					  const group = new Group()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -273,7 +283,8 @@ export function tangentialArcToSegment({
 | 
				
			|||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const baseColor = getThemeColorForThreeJs(theme)
 | 
					  const baseColor = getThemeColorForThreeJs(theme)
 | 
				
			||||||
  const body = new MeshBasicMaterial({ color: baseColor })
 | 
					  const color = isSelected ? 0x0000ff : baseColor
 | 
				
			||||||
 | 
					  const body = new MeshBasicMaterial({ color })
 | 
				
			||||||
  const mesh = new Mesh(geometry, body)
 | 
					  const mesh = new Mesh(geometry, body)
 | 
				
			||||||
  mesh.userData.type = isDraftSegment
 | 
					  mesh.userData.type = isDraftSegment
 | 
				
			||||||
    ? TANGENTIAL_ARC_TO__SEGMENT_DASH
 | 
					    ? TANGENTIAL_ARC_TO__SEGMENT_DASH
 | 
				
			||||||
@ -286,12 +297,12 @@ export function tangentialArcToSegment({
 | 
				
			|||||||
    to,
 | 
					    to,
 | 
				
			||||||
    prevSegment,
 | 
					    prevSegment,
 | 
				
			||||||
    pathToNode,
 | 
					    pathToNode,
 | 
				
			||||||
    isSelected: false,
 | 
					    isSelected,
 | 
				
			||||||
    baseColor,
 | 
					    baseColor,
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  group.name = TANGENTIAL_ARC_TO_SEGMENT
 | 
					  group.name = TANGENTIAL_ARC_TO_SEGMENT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const arrowGroup = createArrowhead(scale, theme)
 | 
					  const arrowGroup = createArrowhead(scale, theme, color)
 | 
				
			||||||
  arrowGroup.position.set(to[0], to[1], 0)
 | 
					  arrowGroup.position.set(to[0], to[1], 0)
 | 
				
			||||||
  const arrowheadAngle = endAngle + (Math.PI / 2) * (ccw ? 1 : -1)
 | 
					  const arrowheadAngle = endAngle + (Math.PI / 2) * (ccw ? 1 : -1)
 | 
				
			||||||
  arrowGroup.quaternion.setFromUnitVectors(
 | 
					  arrowGroup.quaternion.setFromUnitVectors(
 | 
				
			||||||
 | 
				
			|||||||
@ -275,9 +275,9 @@ export const ModelingMachineProvider = ({
 | 
				
			|||||||
        ),
 | 
					        ),
 | 
				
			||||||
        'Set selection': assign(({ selectionRanges, sketchDetails }, event) => {
 | 
					        'Set selection': assign(({ selectionRanges, sketchDetails }, event) => {
 | 
				
			||||||
          const setSelections = event.data as SetSelections // this was needed for ts after adding 'Set selection' action to on done modal events
 | 
					          const setSelections = event.data as SetSelections // this was needed for ts after adding 'Set selection' action to on done modal events
 | 
				
			||||||
          if (!editorManager.editorView) return {}
 | 
					 | 
				
			||||||
          const dispatchSelection = (selection?: EditorSelection) => {
 | 
					          const dispatchSelection = (selection?: EditorSelection) => {
 | 
				
			||||||
            if (!selection) return // TODO less of hack for the below please
 | 
					            if (!selection) return // TODO less of hack for the below please
 | 
				
			||||||
 | 
					            if (!editorManager.editorView) return
 | 
				
			||||||
            editorManager.lastSelectionEvent = Date.now()
 | 
					            editorManager.lastSelectionEvent = Date.now()
 | 
				
			||||||
            setTimeout(() => {
 | 
					            setTimeout(() => {
 | 
				
			||||||
              if (editorManager.editorView) {
 | 
					              if (editorManager.editorView) {
 | 
				
			||||||
 | 
				
			|||||||
@ -160,9 +160,6 @@ export default class EditorManager {
 | 
				
			|||||||
    if (selections.codeBasedSelections.length === 0) {
 | 
					    if (selections.codeBasedSelections.length === 0) {
 | 
				
			||||||
      return
 | 
					      return
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (!this.editorView) {
 | 
					 | 
				
			||||||
      return
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    let codeBasedSelections = []
 | 
					    let codeBasedSelections = []
 | 
				
			||||||
    for (const selection of selections.codeBasedSelections) {
 | 
					    for (const selection of selections.codeBasedSelections) {
 | 
				
			||||||
      codeBasedSelections.push(
 | 
					      codeBasedSelections.push(
 | 
				
			||||||
@ -177,6 +174,9 @@ export default class EditorManager {
 | 
				
			|||||||
        ].range[1]
 | 
					        ].range[1]
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					    if (!this.editorView) {
 | 
				
			||||||
 | 
					      return
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    this.editorView.dispatch({
 | 
					    this.editorView.dispatch({
 | 
				
			||||||
      selection: EditorSelection.create(codeBasedSelections, 1),
 | 
					      selection: EditorSelection.create(codeBasedSelections, 1),
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
				
			|||||||
@ -86,32 +86,36 @@ const mySketch001 = startSketchOn('XY')
 | 
				
			|||||||
          sourceRange: [108, 132],
 | 
					          sourceRange: [108, 132],
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      ],
 | 
					      ],
 | 
				
			||||||
      sketchGroupValues: [
 | 
					      sketchGroup: {
 | 
				
			||||||
        {
 | 
					        id: expect.any(String),
 | 
				
			||||||
          type: 'ToPoint',
 | 
					        __meta: expect.any(Array),
 | 
				
			||||||
          from: [0, 0],
 | 
					        on: expect.any(Object),
 | 
				
			||||||
          to: [-1.59, -1.54],
 | 
					        start: expect.any(Object),
 | 
				
			||||||
          name: '',
 | 
					        type: 'SketchGroup',
 | 
				
			||||||
          __geoMeta: {
 | 
					        value: [
 | 
				
			||||||
            id: expect.any(String),
 | 
					          {
 | 
				
			||||||
            sourceRange: [77, 102],
 | 
					            type: 'ToPoint',
 | 
				
			||||||
 | 
					            from: [0, 0],
 | 
				
			||||||
 | 
					            to: [-1.59, -1.54],
 | 
				
			||||||
 | 
					            name: '',
 | 
				
			||||||
 | 
					            __geoMeta: {
 | 
				
			||||||
 | 
					              id: expect.any(String),
 | 
				
			||||||
 | 
					              sourceRange: [77, 102],
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        },
 | 
					          {
 | 
				
			||||||
        {
 | 
					            type: 'ToPoint',
 | 
				
			||||||
          type: 'ToPoint',
 | 
					            from: [-1.59, -1.54],
 | 
				
			||||||
          from: [-1.59, -1.54],
 | 
					            to: [0.46, -5.82],
 | 
				
			||||||
          to: [0.46, -5.82],
 | 
					            name: '',
 | 
				
			||||||
          name: '',
 | 
					            __geoMeta: {
 | 
				
			||||||
          __geoMeta: {
 | 
					              id: expect.any(String),
 | 
				
			||||||
            id: expect.any(String),
 | 
					              sourceRange: [108, 132],
 | 
				
			||||||
            sourceRange: [108, 132],
 | 
					            },
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        },
 | 
					        ],
 | 
				
			||||||
      ],
 | 
					      },
 | 
				
			||||||
      height: 2,
 | 
					      height: 2,
 | 
				
			||||||
      xAxis: { x: 1, y: 0, z: 0 },
 | 
					 | 
				
			||||||
      yAxis: { x: 0, y: 1, z: 0 },
 | 
					 | 
				
			||||||
      zAxis: { x: 0, y: 0, z: 1 },
 | 
					 | 
				
			||||||
      startCapId: expect.any(String),
 | 
					      startCapId: expect.any(String),
 | 
				
			||||||
      endCapId: expect.any(String),
 | 
					      endCapId: expect.any(String),
 | 
				
			||||||
      __meta: [{ sourceRange: [46, 71] }],
 | 
					      __meta: [{ sourceRange: [46, 71] }],
 | 
				
			||||||
@ -170,42 +174,46 @@ const sk2 = startSketchOn('XY')
 | 
				
			|||||||
            sourceRange: [124, 143],
 | 
					            sourceRange: [124, 143],
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        sketchGroupValues: [
 | 
					        sketchGroup: {
 | 
				
			||||||
          {
 | 
					          id: expect.any(String),
 | 
				
			||||||
            type: 'ToPoint',
 | 
					          __meta: expect.any(Array),
 | 
				
			||||||
            from: [0, 0],
 | 
					          on: expect.any(Object),
 | 
				
			||||||
            to: [-2.5, 0],
 | 
					          start: expect.any(Object),
 | 
				
			||||||
            name: '',
 | 
					          type: 'SketchGroup',
 | 
				
			||||||
            __geoMeta: {
 | 
					          value: [
 | 
				
			||||||
              id: expect.any(String),
 | 
					            {
 | 
				
			||||||
              sourceRange: [69, 89],
 | 
					              type: 'ToPoint',
 | 
				
			||||||
 | 
					              from: [0, 0],
 | 
				
			||||||
 | 
					              to: [-2.5, 0],
 | 
				
			||||||
 | 
					              name: '',
 | 
				
			||||||
 | 
					              __geoMeta: {
 | 
				
			||||||
 | 
					                id: expect.any(String),
 | 
				
			||||||
 | 
					                sourceRange: [69, 89],
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          },
 | 
					            {
 | 
				
			||||||
          {
 | 
					              type: 'ToPoint',
 | 
				
			||||||
            type: 'ToPoint',
 | 
					              from: [-2.5, 0],
 | 
				
			||||||
            from: [-2.5, 0],
 | 
					              to: [0, 10],
 | 
				
			||||||
            to: [0, 10],
 | 
					              name: 'p',
 | 
				
			||||||
            name: 'p',
 | 
					              __geoMeta: {
 | 
				
			||||||
            __geoMeta: {
 | 
					                id: expect.any(String),
 | 
				
			||||||
              id: expect.any(String),
 | 
					                sourceRange: [95, 118],
 | 
				
			||||||
              sourceRange: [95, 118],
 | 
					              },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          },
 | 
					            {
 | 
				
			||||||
          {
 | 
					              type: 'ToPoint',
 | 
				
			||||||
            type: 'ToPoint',
 | 
					              from: [0, 10],
 | 
				
			||||||
            from: [0, 10],
 | 
					              to: [2.5, 0],
 | 
				
			||||||
            to: [2.5, 0],
 | 
					              name: '',
 | 
				
			||||||
            name: '',
 | 
					              __geoMeta: {
 | 
				
			||||||
            __geoMeta: {
 | 
					                id: expect.any(String),
 | 
				
			||||||
              id: expect.any(String),
 | 
					                sourceRange: [124, 143],
 | 
				
			||||||
              sourceRange: [124, 143],
 | 
					              },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          },
 | 
					          ],
 | 
				
			||||||
        ],
 | 
					        },
 | 
				
			||||||
        height: 2,
 | 
					        height: 2,
 | 
				
			||||||
        xAxis: { x: 1, y: 0, z: 0 },
 | 
					 | 
				
			||||||
        yAxis: { x: 0, y: 1, z: 0 },
 | 
					 | 
				
			||||||
        zAxis: { x: 0, y: 0, z: 1 },
 | 
					 | 
				
			||||||
        startCapId: expect.any(String),
 | 
					        startCapId: expect.any(String),
 | 
				
			||||||
        endCapId: expect.any(String),
 | 
					        endCapId: expect.any(String),
 | 
				
			||||||
        __meta: [{ sourceRange: [38, 63] }],
 | 
					        __meta: [{ sourceRange: [38, 63] }],
 | 
				
			||||||
@ -236,42 +244,46 @@ const sk2 = startSketchOn('XY')
 | 
				
			|||||||
            sourceRange: [428, 447],
 | 
					            sourceRange: [428, 447],
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        sketchGroupValues: [
 | 
					        sketchGroup: {
 | 
				
			||||||
          {
 | 
					          id: expect.any(String),
 | 
				
			||||||
            type: 'ToPoint',
 | 
					          __meta: expect.any(Array),
 | 
				
			||||||
            from: [0, 0],
 | 
					          on: expect.any(Object),
 | 
				
			||||||
            to: [-2.5, 0],
 | 
					          start: expect.any(Object),
 | 
				
			||||||
            name: '',
 | 
					          type: 'SketchGroup',
 | 
				
			||||||
            __geoMeta: {
 | 
					          value: [
 | 
				
			||||||
              id: expect.any(String),
 | 
					            {
 | 
				
			||||||
              sourceRange: [374, 394],
 | 
					              type: 'ToPoint',
 | 
				
			||||||
 | 
					              from: [0, 0],
 | 
				
			||||||
 | 
					              to: [-2.5, 0],
 | 
				
			||||||
 | 
					              name: '',
 | 
				
			||||||
 | 
					              __geoMeta: {
 | 
				
			||||||
 | 
					                id: expect.any(String),
 | 
				
			||||||
 | 
					                sourceRange: [374, 394],
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          },
 | 
					            {
 | 
				
			||||||
          {
 | 
					              type: 'ToPoint',
 | 
				
			||||||
            type: 'ToPoint',
 | 
					              from: [-2.5, 0],
 | 
				
			||||||
            from: [-2.5, 0],
 | 
					              to: [0, 3],
 | 
				
			||||||
            to: [0, 3],
 | 
					              name: 'p',
 | 
				
			||||||
            name: 'p',
 | 
					              __geoMeta: {
 | 
				
			||||||
            __geoMeta: {
 | 
					                id: expect.any(String),
 | 
				
			||||||
              id: expect.any(String),
 | 
					                sourceRange: [400, 422],
 | 
				
			||||||
              sourceRange: [400, 422],
 | 
					              },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          },
 | 
					            {
 | 
				
			||||||
          {
 | 
					              type: 'ToPoint',
 | 
				
			||||||
            type: 'ToPoint',
 | 
					              from: [0, 3],
 | 
				
			||||||
            from: [0, 3],
 | 
					              to: [2.5, 0],
 | 
				
			||||||
            to: [2.5, 0],
 | 
					              name: '',
 | 
				
			||||||
            name: '',
 | 
					              __geoMeta: {
 | 
				
			||||||
            __geoMeta: {
 | 
					                id: expect.any(String),
 | 
				
			||||||
              id: expect.any(String),
 | 
					                sourceRange: [428, 447],
 | 
				
			||||||
              sourceRange: [428, 447],
 | 
					              },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          },
 | 
					          ],
 | 
				
			||||||
        ],
 | 
					        },
 | 
				
			||||||
        height: 2,
 | 
					        height: 2,
 | 
				
			||||||
        xAxis: { x: 1, y: 0, z: 0 },
 | 
					 | 
				
			||||||
        yAxis: { x: 0, y: 1, z: 0 },
 | 
					 | 
				
			||||||
        zAxis: { x: 0, y: 0, z: 1 },
 | 
					 | 
				
			||||||
        startCapId: expect.any(String),
 | 
					        startCapId: expect.any(String),
 | 
				
			||||||
        endCapId: expect.any(String),
 | 
					        endCapId: expect.any(String),
 | 
				
			||||||
        __meta: [{ sourceRange: [343, 368] }],
 | 
					        __meta: [{ sourceRange: [343, 368] }],
 | 
				
			||||||
 | 
				
			|||||||
@ -661,14 +661,6 @@ export function isSingleCursorInPipe(
 | 
				
			|||||||
  ast: Program
 | 
					  ast: Program
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
  if (selectionRanges.codeBasedSelections.length !== 1) return false
 | 
					  if (selectionRanges.codeBasedSelections.length !== 1) return false
 | 
				
			||||||
  if (
 | 
					 | 
				
			||||||
    doesPipeHaveCallExp({
 | 
					 | 
				
			||||||
      ast,
 | 
					 | 
				
			||||||
      selection: selectionRanges.codeBasedSelections[0],
 | 
					 | 
				
			||||||
      calleeName: 'extrude',
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
    return false
 | 
					 | 
				
			||||||
  const selection = selectionRanges.codeBasedSelections[0]
 | 
					  const selection = selectionRanges.codeBasedSelections[0]
 | 
				
			||||||
  const pathToNode = getNodePathFromSourceRange(ast, selection.range)
 | 
					  const pathToNode = getNodePathFromSourceRange(ast, selection.range)
 | 
				
			||||||
  const nodeTypes = pathToNode.map(([, type]) => type)
 | 
					  const nodeTypes = pathToNode.map(([, type]) => type)
 | 
				
			||||||
 | 
				
			|||||||
@ -1583,7 +1583,10 @@ export function transformAstSketchLines({
 | 
				
			|||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const varName = varDec.id.name
 | 
					    const varName = varDec.id.name
 | 
				
			||||||
    const sketchGroup = programMemory.root?.[varName]
 | 
					    let sketchGroup = programMemory.root?.[varName]
 | 
				
			||||||
 | 
					    if (sketchGroup.type === 'ExtrudeGroup') {
 | 
				
			||||||
 | 
					      sketchGroup = sketchGroup.sketchGroup
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (!sketchGroup || sketchGroup.type !== 'SketchGroup')
 | 
					    if (!sketchGroup || sketchGroup.type !== 'SketchGroup')
 | 
				
			||||||
      throw new Error('not a sketch group')
 | 
					      throw new Error('not a sketch group')
 | 
				
			||||||
    const seg = getSketchSegmentFromPathToNode(
 | 
					    const seg = getSketchSegmentFromPathToNode(
 | 
				
			||||||
 | 
				
			|||||||
@ -59,9 +59,11 @@ export function isCursorInSketchCommandRange(
 | 
				
			|||||||
          artifact.commandType === 'close_path')
 | 
					          artifact.commandType === 'close_path')
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
  return overlapingEntries.length && overlapingEntries[0][1].parentId
 | 
					  let result =
 | 
				
			||||||
    ? overlapingEntries[0][1].parentId
 | 
					    overlapingEntries.length && overlapingEntries[0][1].parentId
 | 
				
			||||||
    : overlapingEntries.find(
 | 
					      ? overlapingEntries[0][1].parentId
 | 
				
			||||||
        ([, artifact]) => artifact.commandType === 'start_path'
 | 
					      : overlapingEntries.find(
 | 
				
			||||||
      )?.[0] || false
 | 
					          ([, artifact]) => artifact.commandType === 'start_path'
 | 
				
			||||||
 | 
					        )?.[0] || false
 | 
				
			||||||
 | 
					  return result
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -278,7 +278,7 @@ export function processCodeMirrorRanges({
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function updateSceneObjectColors(codeBasedSelections: Selection[]) {
 | 
					export function updateSceneObjectColors(codeBasedSelections: Selection[]) {
 | 
				
			||||||
  let updated: Program
 | 
					  let updated: Program
 | 
				
			||||||
  try {
 | 
					  try {
 | 
				
			||||||
    updated = parse(recast(kclManager.ast))
 | 
					    updated = parse(recast(kclManager.ast))
 | 
				
			||||||
@ -301,6 +301,7 @@ function updateSceneObjectColors(codeBasedSelections: Selection[]) {
 | 
				
			|||||||
    const groupHasCursor = codeBasedSelections.some((selection) => {
 | 
					    const groupHasCursor = codeBasedSelections.some((selection) => {
 | 
				
			||||||
      return isOverlap(selection.range, [node.start, node.end])
 | 
					      return isOverlap(selection.range, [node.start, node.end])
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const color = groupHasCursor
 | 
					    const color = groupHasCursor
 | 
				
			||||||
      ? 0x0000ff
 | 
					      ? 0x0000ff
 | 
				
			||||||
      : segmentGroup?.userData?.baseColor || 0xffffff
 | 
					      : segmentGroup?.userData?.baseColor || 0xffffff
 | 
				
			||||||
 | 
				
			|||||||
@ -900,7 +900,10 @@ export const modelingMachine = createMachine(
 | 
				
			|||||||
          sceneInfra.modelingSend('Equip Line tool')
 | 
					          sceneInfra.modelingSend('Equip Line tool')
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      'setup client side sketch segments': ({ sketchDetails }) => {
 | 
					      'setup client side sketch segments': ({
 | 
				
			||||||
 | 
					        sketchDetails,
 | 
				
			||||||
 | 
					        selectionRanges,
 | 
				
			||||||
 | 
					      }) => {
 | 
				
			||||||
        if (!sketchDetails) return
 | 
					        if (!sketchDetails) return
 | 
				
			||||||
        ;(async () => {
 | 
					        ;(async () => {
 | 
				
			||||||
          if (Object.keys(sceneEntitiesManager.activeSegments).length > 0) {
 | 
					          if (Object.keys(sceneEntitiesManager.activeSegments).length > 0) {
 | 
				
			||||||
@ -913,6 +916,7 @@ export const modelingMachine = createMachine(
 | 
				
			|||||||
            up: sketchDetails.yAxis,
 | 
					            up: sketchDetails.yAxis,
 | 
				
			||||||
            position: sketchDetails.origin,
 | 
					            position: sketchDetails.origin,
 | 
				
			||||||
            maybeModdedAst: kclManager.ast,
 | 
					            maybeModdedAst: kclManager.ast,
 | 
				
			||||||
 | 
					            selectionRanges,
 | 
				
			||||||
          })
 | 
					          })
 | 
				
			||||||
          sceneInfra.resetMouseListeners()
 | 
					          sceneInfra.resetMouseListeners()
 | 
				
			||||||
          sceneEntitiesManager.setupSketchIdleCallbacks({
 | 
					          sceneEntitiesManager.setupSketchIdleCallbacks({
 | 
				
			||||||
 | 
				
			|||||||
@ -570,16 +570,10 @@ pub struct ExtrudeGroup {
 | 
				
			|||||||
    pub id: uuid::Uuid,
 | 
					    pub id: uuid::Uuid,
 | 
				
			||||||
    /// The extrude surfaces.
 | 
					    /// The extrude surfaces.
 | 
				
			||||||
    pub value: Vec<ExtrudeSurface>,
 | 
					    pub value: Vec<ExtrudeSurface>,
 | 
				
			||||||
    /// The sketch group paths.
 | 
					    /// The sketch group.
 | 
				
			||||||
    pub sketch_group_values: Vec<Path>,
 | 
					    pub sketch_group: SketchGroup,
 | 
				
			||||||
    /// The height of the extrude group.
 | 
					    /// The height of the extrude group.
 | 
				
			||||||
    pub height: f64,
 | 
					    pub height: f64,
 | 
				
			||||||
    /// The x-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
    pub x_axis: Point3d,
 | 
					 | 
				
			||||||
    /// The y-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
    pub y_axis: Point3d,
 | 
					 | 
				
			||||||
    /// The z-axis of the extrude group base plane in the 3D space
 | 
					 | 
				
			||||||
    pub z_axis: Point3d,
 | 
					 | 
				
			||||||
    /// The id of the extrusion start cap
 | 
					    /// The id of the extrusion start cap
 | 
				
			||||||
    pub start_cap_id: Option<uuid::Uuid>,
 | 
					    pub start_cap_id: Option<uuid::Uuid>,
 | 
				
			||||||
    /// The id of the extrusion end cap
 | 
					    /// The id of the extrusion end cap
 | 
				
			||||||
 | 
				
			|||||||
@ -94,7 +94,8 @@ async fn inner_chamfer(
 | 
				
			|||||||
            EdgeReference::Uuid(uuid) => uuid,
 | 
					            EdgeReference::Uuid(uuid) => uuid,
 | 
				
			||||||
            EdgeReference::Tag(tag) => {
 | 
					            EdgeReference::Tag(tag) => {
 | 
				
			||||||
                extrude_group
 | 
					                extrude_group
 | 
				
			||||||
                    .sketch_group_values
 | 
					                    .sketch_group
 | 
				
			||||||
 | 
					                    .value
 | 
				
			||||||
                    .iter()
 | 
					                    .iter()
 | 
				
			||||||
                    .find(|p| p.get_name() == tag)
 | 
					                    .find(|p| p.get_name() == tag)
 | 
				
			||||||
                    .ok_or_else(|| {
 | 
					                    .ok_or_else(|| {
 | 
				
			||||||
 | 
				
			|||||||
@ -239,11 +239,8 @@ pub(crate) async fn do_post_extrude(
 | 
				
			|||||||
        // sketch group.
 | 
					        // sketch group.
 | 
				
			||||||
        id: sketch_group.id,
 | 
					        id: sketch_group.id,
 | 
				
			||||||
        value: new_value,
 | 
					        value: new_value,
 | 
				
			||||||
        sketch_group_values: sketch_group.value.clone(),
 | 
					        sketch_group: sketch_group.clone(),
 | 
				
			||||||
        height: length,
 | 
					        height: length,
 | 
				
			||||||
        x_axis: sketch_group.on.x_axis(),
 | 
					 | 
				
			||||||
        y_axis: sketch_group.on.y_axis(),
 | 
					 | 
				
			||||||
        z_axis: sketch_group.on.z_axis(),
 | 
					 | 
				
			||||||
        start_cap_id,
 | 
					        start_cap_id,
 | 
				
			||||||
        end_cap_id,
 | 
					        end_cap_id,
 | 
				
			||||||
        meta: sketch_group.meta,
 | 
					        meta: sketch_group.meta,
 | 
				
			||||||
 | 
				
			|||||||
@ -95,7 +95,8 @@ async fn inner_fillet(
 | 
				
			|||||||
            EdgeReference::Uuid(uuid) => uuid,
 | 
					            EdgeReference::Uuid(uuid) => uuid,
 | 
				
			||||||
            EdgeReference::Tag(tag) => {
 | 
					            EdgeReference::Tag(tag) => {
 | 
				
			||||||
                extrude_group
 | 
					                extrude_group
 | 
				
			||||||
                    .sketch_group_values
 | 
					                    .sketch_group
 | 
				
			||||||
 | 
					                    .value
 | 
				
			||||||
                    .iter()
 | 
					                    .iter()
 | 
				
			||||||
                    .find(|p| p.get_name() == tag)
 | 
					                    .find(|p| p.get_name() == tag)
 | 
				
			||||||
                    .ok_or_else(|| {
 | 
					                    .ok_or_else(|| {
 | 
				
			||||||
@ -177,7 +178,8 @@ async fn inner_get_opposite_edge(tag: String, extrude_group: Box<ExtrudeGroup>,
 | 
				
			|||||||
        return Ok(Uuid::new_v4());
 | 
					        return Ok(Uuid::new_v4());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let tagged_path = extrude_group
 | 
					    let tagged_path = extrude_group
 | 
				
			||||||
        .sketch_group_values
 | 
					        .sketch_group
 | 
				
			||||||
 | 
					        .value
 | 
				
			||||||
        .iter()
 | 
					        .iter()
 | 
				
			||||||
        .find(|p| p.get_name() == tag)
 | 
					        .find(|p| p.get_name() == tag)
 | 
				
			||||||
        .ok_or_else(|| {
 | 
					        .ok_or_else(|| {
 | 
				
			||||||
@ -268,7 +270,8 @@ async fn inner_get_next_adjacent_edge(
 | 
				
			|||||||
        return Ok(Uuid::new_v4());
 | 
					        return Ok(Uuid::new_v4());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let tagged_path = extrude_group
 | 
					    let tagged_path = extrude_group
 | 
				
			||||||
        .sketch_group_values
 | 
					        .sketch_group
 | 
				
			||||||
 | 
					        .value
 | 
				
			||||||
        .iter()
 | 
					        .iter()
 | 
				
			||||||
        .find(|p| p.get_name() == tag)
 | 
					        .find(|p| p.get_name() == tag)
 | 
				
			||||||
        .ok_or_else(|| {
 | 
					        .ok_or_else(|| {
 | 
				
			||||||
@ -364,7 +367,8 @@ async fn inner_get_previous_adjacent_edge(
 | 
				
			|||||||
        return Ok(Uuid::new_v4());
 | 
					        return Ok(Uuid::new_v4());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let tagged_path = extrude_group
 | 
					    let tagged_path = extrude_group
 | 
				
			||||||
        .sketch_group_values
 | 
					        .sketch_group
 | 
				
			||||||
 | 
					        .value
 | 
				
			||||||
        .iter()
 | 
					        .iter()
 | 
				
			||||||
        .find(|p| p.get_name() == tag)
 | 
					        .find(|p| p.get_name() == tag)
 | 
				
			||||||
        .ok_or_else(|| {
 | 
					        .ok_or_else(|| {
 | 
				
			||||||
 | 
				
			|||||||
@ -336,7 +336,8 @@ async fn inner_get_edge(tag: String, extrude_group: Box<ExtrudeGroup>, args: Arg
 | 
				
			|||||||
        return Ok(Uuid::new_v4());
 | 
					        return Ok(Uuid::new_v4());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let tagged_path = extrude_group
 | 
					    let tagged_path = extrude_group
 | 
				
			||||||
        .sketch_group_values
 | 
					        .sketch_group
 | 
				
			||||||
 | 
					        .value
 | 
				
			||||||
        .iter()
 | 
					        .iter()
 | 
				
			||||||
        .find(|p| p.get_name() == tag)
 | 
					        .find(|p| p.get_name() == tag)
 | 
				
			||||||
        .ok_or_else(|| {
 | 
					        .ok_or_else(|| {
 | 
				
			||||||
 | 
				
			|||||||
@ -1074,9 +1074,9 @@ async fn start_sketch_on_face(
 | 
				
			|||||||
        value: tag.to_string(),
 | 
					        value: tag.to_string(),
 | 
				
			||||||
        sketch_group_id: extrude_group.id,
 | 
					        sketch_group_id: extrude_group.id,
 | 
				
			||||||
        // TODO: get this from the extrude plane data.
 | 
					        // TODO: get this from the extrude plane data.
 | 
				
			||||||
        x_axis: extrude_group.x_axis,
 | 
					        x_axis: extrude_group.sketch_group.on.x_axis(),
 | 
				
			||||||
        y_axis: extrude_group.y_axis,
 | 
					        y_axis: extrude_group.sketch_group.on.y_axis(),
 | 
				
			||||||
        z_axis: extrude_group.z_axis,
 | 
					        z_axis: extrude_group.sketch_group.on.z_axis(),
 | 
				
			||||||
        meta: vec![args.source_range.into()],
 | 
					        meta: vec![args.source_range.into()],
 | 
				
			||||||
    }))
 | 
					    }))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user