Compare commits
	
		
			3 Commits
		
	
	
		
			pierremtb/
			...
			nrc-std-ax
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 87dfda28a9 | |||
| 42f44e11f5 | |||
| 16ad7ff77a | 
| @ -54,7 +54,7 @@ example = extrude(exampleSketch, length = 5) | ||||
| // Add color to a revolved solid. | ||||
| sketch001 = startSketchOn(XY) | ||||
|   |> circle(center = [15, 0], radius = 5) | ||||
|   |> revolve(angle = 360, axis = 'y') | ||||
|   |> revolve(angle = 360, axis = Y) | ||||
|   |> appearance(color = '#ff0000', metalness = 90, roughness = 90) | ||||
| ``` | ||||
|  | ||||
|  | ||||
| @ -9,13 +9,12 @@ layout: manual | ||||
|  | ||||
| ### `std` | ||||
|  | ||||
| - [`HALF_TURN`](/docs/kcl/consts/std-HALF_TURN) | ||||
| - [`QUARTER_TURN`](/docs/kcl/consts/std-QUARTER_TURN) | ||||
| - [`THREE_QUARTER_TURN`](/docs/kcl/consts/std-THREE_QUARTER_TURN) | ||||
| - [`X`](/docs/kcl/consts/std-X) | ||||
| - [`XY`](/docs/kcl/consts/std-XY) | ||||
| - [`XZ`](/docs/kcl/consts/std-XZ) | ||||
| - [`Y`](/docs/kcl/consts/std-Y) | ||||
| - [`YZ`](/docs/kcl/consts/std-YZ) | ||||
| - [`ZERO`](/docs/kcl/consts/std-ZERO) | ||||
| - [`Z`](/docs/kcl/consts/std-Z) | ||||
|  | ||||
| ### `std::math` | ||||
|  | ||||
| @ -23,3 +22,10 @@ layout: manual | ||||
| - [`PI`](/docs/kcl/consts/std-math-PI) | ||||
| - [`TAU`](/docs/kcl/consts/std-math-TAU) | ||||
|  | ||||
| ### `std::turns` | ||||
|  | ||||
| - [`HALF_TURN`](/docs/kcl/consts/std-turns-HALF_TURN) | ||||
| - [`QUARTER_TURN`](/docs/kcl/consts/std-turns-QUARTER_TURN) | ||||
| - [`THREE_QUARTER_TURN`](/docs/kcl/consts/std-turns-THREE_QUARTER_TURN) | ||||
| - [`ZERO`](/docs/kcl/consts/std-turns-ZERO) | ||||
|  | ||||
|  | ||||
| @ -1,15 +0,0 @@ | ||||
| --- | ||||
| title: "std::HALF_TURN" | ||||
| excerpt: "" | ||||
| layout: manual | ||||
| --- | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ```js | ||||
| std::HALF_TURN: number(deg) = 180deg | ||||
| ``` | ||||
|  | ||||
|  | ||||
| @ -1,15 +0,0 @@ | ||||
| --- | ||||
| title: "std::QUARTER_TURN" | ||||
| excerpt: "" | ||||
| layout: manual | ||||
| --- | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ```js | ||||
| std::QUARTER_TURN: number(deg) = 90deg | ||||
| ``` | ||||
|  | ||||
|  | ||||
| @ -1,15 +0,0 @@ | ||||
| --- | ||||
| title: "std::THREE_QUARTER_TURN" | ||||
| excerpt: "" | ||||
| layout: manual | ||||
| --- | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ```js | ||||
| std::THREE_QUARTER_TURN: number(deg) = 270deg | ||||
| ``` | ||||
|  | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| --- | ||||
| title: "std::ZERO" | ||||
| title: "std::X" | ||||
| excerpt: "" | ||||
| layout: manual | ||||
| --- | ||||
| @ -9,7 +9,7 @@ layout: manual | ||||
| 
 | ||||
| 
 | ||||
| ```js | ||||
| std::ZERO: number = 0 | ||||
| std::X | ||||
| ``` | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										15
									
								
								docs/kcl/consts/std-Y.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								docs/kcl/consts/std-Y.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| --- | ||||
| title: "std::Y" | ||||
| excerpt: "" | ||||
| layout: manual | ||||
| --- | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ```js | ||||
| std::Y | ||||
| ``` | ||||
|  | ||||
|  | ||||
							
								
								
									
										15
									
								
								docs/kcl/consts/std-Z.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								docs/kcl/consts/std-Z.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| --- | ||||
| title: "std::Z" | ||||
| excerpt: "" | ||||
| layout: manual | ||||
| --- | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ```js | ||||
| std::Z | ||||
| ``` | ||||
|  | ||||
|  | ||||
							
								
								
									
										15
									
								
								docs/kcl/consts/std-turns-HALF_TURN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								docs/kcl/consts/std-turns-HALF_TURN.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| --- | ||||
| title: "std::turns::HALF_TURN" | ||||
| excerpt: "" | ||||
| layout: manual | ||||
| --- | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ```js | ||||
| std::turns::HALF_TURN: number(deg) = 180deg | ||||
| ``` | ||||
|  | ||||
|  | ||||
							
								
								
									
										15
									
								
								docs/kcl/consts/std-turns-QUARTER_TURN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								docs/kcl/consts/std-turns-QUARTER_TURN.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| --- | ||||
| title: "std::turns::QUARTER_TURN" | ||||
| excerpt: "" | ||||
| layout: manual | ||||
| --- | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ```js | ||||
| std::turns::QUARTER_TURN: number(deg) = 90deg | ||||
| ``` | ||||
|  | ||||
|  | ||||
							
								
								
									
										15
									
								
								docs/kcl/consts/std-turns-THREE_QUARTER_TURN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								docs/kcl/consts/std-turns-THREE_QUARTER_TURN.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| --- | ||||
| title: "std::turns::THREE_QUARTER_TURN" | ||||
| excerpt: "" | ||||
| layout: manual | ||||
| --- | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ```js | ||||
| std::turns::THREE_QUARTER_TURN: number(deg) = 270deg | ||||
| ``` | ||||
|  | ||||
|  | ||||
							
								
								
									
										15
									
								
								docs/kcl/consts/std-turns-ZERO.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								docs/kcl/consts/std-turns-ZERO.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| --- | ||||
| title: "std::turns::ZERO" | ||||
| excerpt: "" | ||||
| layout: manual | ||||
| --- | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ```js | ||||
| std::turns::ZERO: number = 0 | ||||
| ``` | ||||
|  | ||||
|  | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -22,20 +22,22 @@ layout: manual | ||||
|   * [`string`](kcl/types/string) | ||||
|   * [`tag`](kcl/types/tag) | ||||
| * **std** | ||||
|   * [`Axis2d`](kcl/types/Axis2d) | ||||
|   * [`Axis3d`](kcl/types/Axis3d) | ||||
|   * [`Edge`](kcl/types/Edge) | ||||
|   * [`Face`](kcl/types/Face) | ||||
|   * [`HALF_TURN`](kcl/consts/std-HALF_TURN) | ||||
|   * [`Helix`](kcl/types/Helix) | ||||
|   * [`Plane`](kcl/types/Plane) | ||||
|   * [`Point2d`](kcl/types/Point2d) | ||||
|   * [`Point3d`](kcl/types/Point3d) | ||||
|   * [`QUARTER_TURN`](kcl/consts/std-QUARTER_TURN) | ||||
|   * [`Sketch`](kcl/types/Sketch) | ||||
|   * [`Solid`](kcl/types/Solid) | ||||
|   * [`THREE_QUARTER_TURN`](kcl/consts/std-THREE_QUARTER_TURN) | ||||
|   * [`X`](kcl/consts/std-X) | ||||
|   * [`XY`](kcl/consts/std-XY) | ||||
|   * [`XZ`](kcl/consts/std-XZ) | ||||
|   * [`Y`](kcl/consts/std-Y) | ||||
|   * [`YZ`](kcl/consts/std-YZ) | ||||
|   * [`ZERO`](kcl/consts/std-ZERO) | ||||
|   * [`Z`](kcl/consts/std-Z) | ||||
|   * [`abs`](kcl/abs) | ||||
|   * [`acos`](kcl/acos) | ||||
|   * [`angleToMatchLengthX`](kcl/angleToMatchLengthX) | ||||
| @ -72,7 +74,7 @@ layout: manual | ||||
|   * [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge) | ||||
|   * [`getOppositeEdge`](kcl/getOppositeEdge) | ||||
|   * [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge) | ||||
|   * [`helix`](kcl/helix) | ||||
|   * [`helix`](kcl/std-helix) | ||||
|   * [`hole`](kcl/hole) | ||||
|   * [`hollow`](kcl/hollow) | ||||
|   * [`inch`](kcl/inch) | ||||
| @ -91,7 +93,6 @@ layout: manual | ||||
|   * [`map`](kcl/map) | ||||
|   * [`max`](kcl/max) | ||||
|   * [`min`](kcl/min) | ||||
|   * [`mirror2d`](kcl/mirror2d) | ||||
|   * [`mm`](kcl/mm) | ||||
|   * [`offsetPlane`](kcl/offsetPlane) | ||||
|   * [`patternCircular2d`](kcl/patternCircular2d) | ||||
| @ -110,7 +111,7 @@ layout: manual | ||||
|   * [`push`](kcl/push) | ||||
|   * [`reduce`](kcl/reduce) | ||||
|   * [`rem`](kcl/rem) | ||||
|   * [`revolve`](kcl/revolve) | ||||
|   * [`revolve`](kcl/std-revolve) | ||||
|   * [`rotate`](kcl/rotate) | ||||
|   * [`round`](kcl/round) | ||||
|   * [`scale`](kcl/scale) | ||||
| @ -146,3 +147,9 @@ layout: manual | ||||
|   * [`tan`](kcl/std-math-tan) | ||||
| * **std::sketch** | ||||
|   * [`circle`](kcl/std-sketch-circle) | ||||
|   * [`mirror2d`](kcl/std-sketch-mirror2d) | ||||
| * **std::turns** | ||||
|   * [`turns::HALF_TURN`](kcl/consts/std-turns-HALF_TURN) | ||||
|   * [`turns::QUARTER_TURN`](kcl/consts/std-turns-QUARTER_TURN) | ||||
|   * [`turns::THREE_QUARTER_TURN`](kcl/consts/std-turns-THREE_QUARTER_TURN) | ||||
|   * [`turns::ZERO`](kcl/consts/std-turns-ZERO) | ||||
|  | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -146,7 +146,7 @@ exampleSketch = startSketchOn(XY) | ||||
|   |> line(end = [-2, 0]) | ||||
|   |> close() | ||||
|  | ||||
| example = revolve(exampleSketch, axis = 'y', angle = 180) | ||||
| example = revolve(exampleSketch, axis = Y, angle = 180) | ||||
|  | ||||
| exampleSketch002 = startSketchOn(example, 'end') | ||||
|   |> startProfileAt([4.5, -5], %) | ||||
| @ -177,7 +177,7 @@ exampleSketch = startSketchOn(XY) | ||||
|  | ||||
| example = revolve( | ||||
|   exampleSketch, | ||||
|   axis = 'y', | ||||
|   axis = Y, | ||||
|   angle = 180, | ||||
|   tagEnd = $end01, | ||||
| ) | ||||
|  | ||||
							
								
								
									
										116
									
								
								docs/kcl/std-helix.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								docs/kcl/std-helix.md
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										246
									
								
								docs/kcl/std-revolve.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										246
									
								
								docs/kcl/std-revolve.md
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										98
									
								
								docs/kcl/std-sketch-mirror2d.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								docs/kcl/std-sketch-mirror2d.md
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										17412
									
								
								docs/kcl/std.json
									
									
									
									
									
								
							
							
						
						
									
										17412
									
								
								docs/kcl/std.json
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -74,7 +74,7 @@ helixPath = helix( | ||||
|   revolutions = 4, | ||||
|   length = 10, | ||||
|   radius = 5, | ||||
|   axis = 'Z', | ||||
|   axis = Z, | ||||
| ) | ||||
|  | ||||
| // Create a spring by sweeping around the helix path. | ||||
|  | ||||
							
								
								
									
										12
									
								
								docs/kcl/types/Axis2d.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								docs/kcl/types/Axis2d.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| --- | ||||
| title: "std::Axis2d" | ||||
| excerpt: "An infinte line in 2d space." | ||||
| layout: manual | ||||
| --- | ||||
|  | ||||
| An infinte line in 2d space. | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										12
									
								
								docs/kcl/types/Axis3d.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								docs/kcl/types/Axis3d.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| --- | ||||
| title: "std::Axis3d" | ||||
| excerpt: "An infinte line in 3d space." | ||||
| layout: manual | ||||
| --- | ||||
|  | ||||
| An infinte line in 3d space. | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										12
									
								
								docs/kcl/types/Edge.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								docs/kcl/types/Edge.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| --- | ||||
| title: "std::Edge" | ||||
| excerpt: "The edge of a solid." | ||||
| layout: manual | ||||
| --- | ||||
|  | ||||
| The edge of a solid. | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -21,7 +21,7 @@ sketch001 = startSketchOn(XZ) | ||||
|   |> angledLine([-45, length001], %) | ||||
|   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | ||||
|   |> close() | ||||
| revolve001 = revolve(sketch001, axis = "X") | ||||
| revolve001 = revolve(sketch001, axis = X) | ||||
| triangle() | ||||
|   |> extrude(length = 30) | ||||
| plane001 = offsetPlane(XY, offset = 10) | ||||
| @ -126,7 +126,7 @@ test.describe('Feature Tree pane', () => { | ||||
|       await testViewSource({ | ||||
|         operationName: 'Revolve', | ||||
|         operationIndex: 0, | ||||
|         expectedActiveLine: 'revolve001 = revolve(sketch001, axis = "X")', | ||||
|         expectedActiveLine: 'revolve001 = revolve(sketch001, axis = X)', | ||||
|       }) | ||||
|       await testViewSource({ | ||||
|         operationName: 'Triangle', | ||||
|  | ||||
| @ -3469,7 +3469,7 @@ segAng(rectangleSegmentA002), | ||||
|       await cmdBar.progressCmdBar() | ||||
|       await cmdBar.progressCmdBar() | ||||
|  | ||||
|       const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360, axis = 'X')` | ||||
|       const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360, axis = X)` | ||||
|       expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy() | ||||
|     }) | ||||
|     test('revolve surface around edge from an extruded solid2d', async ({ | ||||
|  | ||||
| @ -674,7 +674,7 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002) | ||||
|   |> line(end = [12.73, -0.09]) | ||||
|   |> tangentialArcTo([24.95, -5.38], %) | ||||
|   |> close() | ||||
|   |> revolve(axis = "X")` | ||||
|   |> revolve(axis = X)` | ||||
|       ) | ||||
|     }) | ||||
|  | ||||
| @ -761,7 +761,7 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002) | ||||
|   |> tangentialArcTo([24.95, -5.38], %) | ||||
|   |> line(end = [1.97, 2.06]) | ||||
|   |> close() | ||||
|   |> revolve(axis = "X")`) | ||||
|   |> revolve(axis = X)`) | ||||
|   }) | ||||
|   test('Can add multiple sketches', async ({ page, homePage }) => { | ||||
|     const u = await getUtils(page) | ||||
| @ -1209,7 +1209,7 @@ profile001 = startProfileAt([${roundOff(scale * 69.6)}, ${roundOff( | ||||
|           |> xLine(endAbsolute = 0 + .001) | ||||
|           |> yLine(endAbsolute = 0) | ||||
|           |> close() | ||||
|           |> revolve(axis = "Y") | ||||
|           |> revolve(axis = Y) | ||||
|  | ||||
|         return lugSketch | ||||
|       } | ||||
|  | ||||
| @ -76,11 +76,11 @@ part001 = startSketchOn(-XZ) | ||||
|   |> xLine(endAbsolute = totalLen, tag = $seg03) | ||||
|   |> yLine(length = -armThick, tag = $seg01) | ||||
|   |> angledLineThatIntersects({ | ||||
|         angle = HALF_TURN, | ||||
|         angle = turns::HALF_TURN, | ||||
|         offset = -armThick, | ||||
|         intersectTag = seg04 | ||||
|       }, %) | ||||
|   |> angledLineToY([segAng(seg04, %) + 180, ZERO], %) | ||||
|   |> angledLineToY([segAng(seg04, %) + 180, turns::ZERO], %) | ||||
|   |> angledLineToY({ | ||||
|         angle = -bottomAng, | ||||
|         to = -totalHeightHalf - armThick, | ||||
| @ -88,12 +88,12 @@ part001 = startSketchOn(-XZ) | ||||
|   |> xLine(length = endAbsolute = segEndX(seg03) + 0) | ||||
|   |> yLine(length = -segLen(seg01, %)) | ||||
|   |> angledLineThatIntersects({ | ||||
|         angle = HALF_TURN, | ||||
|         angle = turns::HALF_TURN, | ||||
|         offset = -armThick, | ||||
|         intersectTag = seg02 | ||||
|       }, %) | ||||
|   |> angledLineToY([segAng(seg02, %) + 180, -baseHeight], %) | ||||
|   |> xLine(endAbsolute = ZERO) | ||||
|   |> xLine(endAbsolute = turns::ZERO) | ||||
|   |> close() | ||||
|   |> extrude(length = 4)` | ||||
|       ) | ||||
|  | ||||
| @ -486,13 +486,13 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => { | ||||
|         testName: 'Add variable, selecting axis', | ||||
|         addVariable: true, | ||||
|         axisSelect: true, | ||||
|         value: 'QUARTER_TURN - angle001', | ||||
|         value: 'turns::QUARTER_TURN - angle001', | ||||
|       }, | ||||
|       { | ||||
|         testName: 'No variable, selecting axis', | ||||
|         addVariable: false, | ||||
|         axisSelect: true, | ||||
|         value: 'QUARTER_TURN - 7', | ||||
|         value: 'turns::QUARTER_TURN - 7', | ||||
|       }, | ||||
|     ] as const | ||||
|     for (const { testName, addVariable, value, axisSelect } of cases) { | ||||
| @ -935,12 +935,12 @@ part002 = startSketchOn(XZ) | ||||
|   test.describe('Axis & segment - no modal constraints', () => { | ||||
|     const cases = [ | ||||
|       { | ||||
|         codeAfter: `|> line(endAbsolute = [154.9, ZERO])`, | ||||
|         codeAfter: `|> line(endAbsolute = [154.9, turns::ZERO])`, | ||||
|         axisClick: { x: 950, y: 250 }, | ||||
|         constraintName: 'Snap To X', | ||||
|       }, | ||||
|       { | ||||
|         codeAfter: `|> line(endAbsolute = [ZERO, 61.34])`, | ||||
|         codeAfter: `|> line(endAbsolute = [turns::ZERO, 61.34])`, | ||||
|         axisClick: { x: 600, y: 150 }, | ||||
|         constraintName: 'Snap To Y', | ||||
|       }, | ||||
|  | ||||
| @ -319,7 +319,7 @@ part009 = startSketchOn(XY) | ||||
|   |> line(end = [0, pipeLength]) | ||||
|   |> angledLineToX({ angle = 60, to = pipeLargeDia }, %) | ||||
|   |> close() | ||||
| rev = revolve(part009, axis = 'y') | ||||
| rev = revolve(part009, axis = Y) | ||||
| sketch006 = startSketchOn(XY) | ||||
| profile001 = circle( | ||||
|   sketch006, | ||||
| @ -376,7 +376,7 @@ profile003 = startProfileAt([40.16, -120.48], sketch006) | ||||
|     await page.waitForTimeout(200) | ||||
|  | ||||
|     await expect(u.codeLocator).not.toContainText( | ||||
|       `rev = revolve(part009, axis: 'y')` | ||||
|       `rev = revolve(part009, axis: Y)` | ||||
|     ) | ||||
|  | ||||
|     // FIXME (commented section below), this test would select a wall that had a sketch on it, and delete the underlying extrude | ||||
|  | ||||
| @ -67,11 +67,11 @@ part001 = startSketchOn(-XZ) | ||||
| |> xLine(endAbsolute = totalLen, tag = $seg03) | ||||
| |> yLine(length = -armThick, tag = $seg01) | ||||
| |> angledLineThatIntersects({ | ||||
|       angle = HALF_TURN, | ||||
|       angle = turns::HALF_TURN, | ||||
|       offset = -armThick, | ||||
|       intersectTag = seg04 | ||||
|     }, %) | ||||
| |> angledLineToY([segAng(seg04) + 180, ZERO], %) | ||||
| |> angledLineToY([segAng(seg04) + 180, turns::ZERO], %) | ||||
| |> angledLineToY({ | ||||
|       angle = -bottomAng, | ||||
|       to = -totalHeightHalf - armThick, | ||||
| @ -79,12 +79,12 @@ part001 = startSketchOn(-XZ) | ||||
| |> xLine(endAbsolute = segEndX(seg03) + 0) | ||||
| |> yLine(length = -segLen(seg01)) | ||||
| |> angledLineThatIntersects({ | ||||
|       angle = HALF_TURN, | ||||
|       angle = turns::HALF_TURN, | ||||
|       offset = -armThick, | ||||
|       intersectTag = seg02 | ||||
|     }, %) | ||||
| |> angledLineToY([segAng(seg02) + 180, -baseHeight], %) | ||||
| |> xLine(endAbsolute = ZERO) | ||||
| |> xLine(endAbsolute = turns::ZERO) | ||||
| |> close() | ||||
| |> extrude(length = 4)` | ||||
|       ) | ||||
|  | ||||
| @ -35,7 +35,7 @@ ballsSketch = startSketchOn(XY) | ||||
|   |> close() | ||||
|  | ||||
| // Revolve the ball to make a sphere and pattern around the inside wall | ||||
| balls = revolve(ballsSketch, axis = "X") | ||||
| balls = revolve(ballsSketch, axis = X) | ||||
|   |> patternCircular3d( | ||||
|        arcDegrees = 360, | ||||
|        axis = [0, 0, 1], | ||||
| @ -60,7 +60,7 @@ chainSketch = startSketchOn(XY) | ||||
|   |> close() | ||||
|  | ||||
| // Revolve the chain sketch | ||||
| chainHead = revolve(chainSketch, axis = "X") | ||||
| chainHead = revolve(chainSketch, axis = X) | ||||
|   |> patternCircular3d( | ||||
|        arcDegrees = 360, | ||||
|        axis = [0, 0, 1], | ||||
| @ -80,7 +80,7 @@ linkSketch = startSketchOn(XZ) | ||||
|      ) | ||||
|  | ||||
| // Revolve the link sketch | ||||
| linkRevolve = revolve(linkSketch, axis = 'Y', angle = 360 / nBalls) | ||||
| linkRevolve = revolve(linkSketch, axis = Y, angle = 360 / nBalls) | ||||
|   |> patternCircular3d( | ||||
|        arcDegrees = 360, | ||||
|        axis = [0, 0, 1], | ||||
|  | ||||
| @ -80,5 +80,5 @@ brakeCaliperSketch = startSketchOn(XY) | ||||
|   |> close() | ||||
|  | ||||
| // Revolve the brake caliper sketch | ||||
| revolve(brakeCaliperSketch, axis = "Y", angle = -70) | ||||
| revolve(brakeCaliperSketch, axis = Y, angle = -70) | ||||
|   |> appearance(color = "#c82d2d", metalness = 90, roughness = 90) | ||||
|  | ||||
| @ -41,5 +41,5 @@ tireSketch = startSketchOn(XY) | ||||
|   |> close() | ||||
|  | ||||
| // Revolve the sketch to create the tire | ||||
| revolve(tireSketch, axis = "Y") | ||||
| revolve(tireSketch, axis = Y) | ||||
|   |> appearance(color = "#0f0f0f", roughness = 80) | ||||
|  | ||||
| @ -54,7 +54,7 @@ wheelCenterInner = startSketchOn(XY) | ||||
|   |> yLine(endAbsolute = 0) | ||||
|   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | ||||
|   |> close() | ||||
|   |> revolve(axis = 'y') | ||||
|   |> revolve(axis = Y) | ||||
|   |> appearance(color = "#ffffff", metalness = 0, roughness = 0) | ||||
|  | ||||
| wheelCenterOuter = startSketchOn(XY) | ||||
| @ -68,7 +68,7 @@ wheelCenterOuter = startSketchOn(XY) | ||||
|   |> yLine(endAbsolute = -wheelWidth / 20) | ||||
|   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | ||||
|   |> close() | ||||
|   |> revolve(axis = 'y') | ||||
|   |> revolve(axis = Y) | ||||
|   |> appearance(color = "#ffffff", metalness = 0, roughness = 0) | ||||
|  | ||||
| // Write a function that defines the spoke geometry, patterns and extrudes it | ||||
| @ -173,5 +173,5 @@ startSketchOn(XY) | ||||
|   |> xLine(length = wheelWidth * 0.03) | ||||
|   |> yLine(length = wheelWidth * 0.05) | ||||
|   |> close() | ||||
|   |> revolve(axis = 'y') | ||||
|   |> revolve(axis = Y) | ||||
|   |> appearance(color = "#ffffff", metalness = 0, roughness = 0) | ||||
|  | ||||
| @ -32,7 +32,7 @@ fn lug(plane, length, diameter) { | ||||
|     |> xLine(endAbsolute = lugThreadDiameter) | ||||
|     |> yLine(endAbsolute = 0) | ||||
|     |> close() | ||||
|     |> revolve(axis = "Y") | ||||
|     |> revolve(axis = Y) | ||||
|     |> appearance(color = "#dbcd70", roughness = 90, metalness = 90) | ||||
|   return lugSketch | ||||
| } | ||||
|  | ||||
| @ -23,7 +23,7 @@ sketch001 = startSketchOn(XZ) | ||||
|      ], %, $rectangleSegmentC001) | ||||
|   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | ||||
|   |> close() | ||||
|   |> revolve(angle = 360, axis = 'Y') | ||||
|   |> revolve(angle = 360, axis = Y) | ||||
|  | ||||
| // Create an angled plane to sketch the supports | ||||
| plane001 = { | ||||
| @ -132,7 +132,7 @@ sketch005 = startSketchOn(XZ) | ||||
|   |> xLine(endAbsolute = 0.15) | ||||
|   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | ||||
|   |> close() | ||||
|   |> revolve(axis = 'y') | ||||
|   |> revolve(axis = Y) | ||||
|  | ||||
| // Plunger and stem | ||||
| sketch006 = startSketchOn(XZ) | ||||
| @ -145,7 +145,7 @@ sketch006 = startSketchOn(XZ) | ||||
|   |> tangentialArc({ radius = 0.6, offset = -90 }, %) | ||||
|   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | ||||
|   |> close() | ||||
|   |> revolve(axis = 'y') | ||||
|   |> revolve(axis = Y) | ||||
|  | ||||
| // Spiral plate | ||||
| sketch007 = startSketchOn(offsetPlane(XY, offset = 1.12)) | ||||
| @ -201,7 +201,7 @@ sketch011 = startSketchOn(XZ) | ||||
|      }, %) | ||||
|   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | ||||
|   |> close() | ||||
|   |> revolve(axis = 'y') | ||||
|   |> revolve(axis = Y) | ||||
|  | ||||
| // Draw and extrude handle | ||||
| sketch012 = startSketchOn(offsetPlane(XZ, offset = handleThickness / 2)) | ||||
|  | ||||
| @ -48,10 +48,8 @@ sides = patternCircular3d( | ||||
|  | ||||
| // define an axis axis000 | ||||
| axis000 = { | ||||
|   custom = { | ||||
|     axis = [0.0, 1.0], | ||||
|     origin = [cornerRadius, cornerRadius] | ||||
|   } | ||||
|   direction = [0.0, 1.0], | ||||
|   origin = [cornerRadius, cornerRadius] | ||||
| } | ||||
|  | ||||
| // create a single corner of the bin | ||||
|  | ||||
| @ -45,10 +45,8 @@ sides = patternCircular3d( | ||||
|  | ||||
| // define an axis axis000 | ||||
| axis000 = { | ||||
|   custom = { | ||||
|     axis = [0.0, 1.0], | ||||
|     origin = [cornerRadius, cornerRadius] | ||||
|   } | ||||
|   direction = [0.0, 1.0], | ||||
|   origin = [cornerRadius, cornerRadius] | ||||
| } | ||||
|  | ||||
| // create a single corner of the bin | ||||
|  | ||||
| @ -65,13 +65,11 @@ sides = patternCircular3d( | ||||
|  | ||||
| // define an axis axis000 | ||||
| axis000 = { | ||||
|   custom = { | ||||
|     axis = [0.0, 1.0], | ||||
|     origin = [ | ||||
|       cornerRadius + binTol, | ||||
|       cornerRadius + binTol | ||||
|     ] | ||||
|   } | ||||
|   direction = [0.0, 1.0], | ||||
|   origin = [ | ||||
|     cornerRadius + binTol, | ||||
|     cornerRadius + binTol | ||||
|   ] | ||||
| } | ||||
|  | ||||
| // create a single corner of the bin | ||||
| @ -272,10 +270,8 @@ lipWidths = patternCircular3d( | ||||
|  | ||||
| // define an axis axis000 | ||||
| axis001 = { | ||||
|   custom = { | ||||
|     axis = [0.0, 1.0], | ||||
|     origin = [cornerRadius, cornerRadius] | ||||
|   } | ||||
|   direction = [0.0, 1.0], | ||||
|   origin = [cornerRadius, cornerRadius] | ||||
| } | ||||
|  | ||||
| // create a single corner of the bin | ||||
|  | ||||
| @ -58,13 +58,11 @@ sides = patternCircular3d( | ||||
|  | ||||
| // define an axis axis000 | ||||
| axis000 = { | ||||
|   custom = { | ||||
|     axis = [0.0, 1.0], | ||||
|     origin = [ | ||||
|       cornerRadius + binTol, | ||||
|       cornerRadius + binTol | ||||
|     ] | ||||
|   } | ||||
|   direction = [0.0, 1.0], | ||||
|   origin = [ | ||||
|     cornerRadius + binTol, | ||||
|     cornerRadius + binTol | ||||
|   ] | ||||
| } | ||||
|  | ||||
| // create a single corner of the bin | ||||
|  | ||||
| @ -20,6 +20,6 @@ sketch001 = startSketchOn(-XZ) | ||||
|   |> xLine(endAbsolute = webThickness / 2 + rootRadius) | ||||
|   |> tangentialArc({ radius = rootRadius, offset = 90 }, %) | ||||
|   |> yLine(endAbsolute = 0) | ||||
|   |> mirror2d({ axis = 'X' }, %) | ||||
|   |> mirror2d({ axis = 'Y' }, %) | ||||
|   |> mirror2d(axis = X) | ||||
|   |> mirror2d(axis = Y) | ||||
|   |> extrude(length = beamLength) | ||||
|  | ||||
| @ -24,4 +24,4 @@ pipeProfile = outerProfile | ||||
|   |> hole(innerProfile, %) | ||||
|  | ||||
| // revolve the pipe profile at the desired angle | ||||
| pipe = revolve(pipeProfile, axis = 'Y', angle = bendAngle) | ||||
| pipe = revolve(pipeProfile, axis = Y, angle = bendAngle) | ||||
|  | ||||
| @ -33,4 +33,4 @@ pipeSketch = startSketchOn(XY) | ||||
|   |> close() | ||||
|  | ||||
| // Revolve the sketch to create the pipe | ||||
| pipe = revolve(pipeSketch, axis = 'y') | ||||
| pipe = revolve(pipeSketch, axis = Y) | ||||
|  | ||||
| @ -34,10 +34,8 @@ part001 = revolve( | ||||
|   sketch001, | ||||
|   angle = 90, | ||||
|   axis = { | ||||
|     custom = { | ||||
|       axis = [1.0, 0.0], | ||||
|       origin = [0.0, height + .0001] | ||||
|     } | ||||
|     direction = [1.0, 0.0], | ||||
|     origin = [0.0, height + .0001] | ||||
|   }, | ||||
| ) | ||||
|  | ||||
|  | ||||
| @ -14,7 +14,7 @@ radius = 10 | ||||
| depth = 30 | ||||
| distanceToInsideEdge = slateWidthHalf + templateThickness + templateGap | ||||
| sketch001 = startSketchOn(XZ) | ||||
|   |> startProfileAt([ZERO, depth + templateGap], %) | ||||
|   |> startProfileAt([turns::ZERO, depth + templateGap], %) | ||||
|   |> xLine(length = slateWidthHalf - radius, tag = $seg01) | ||||
|   |> arc({ | ||||
|        angleEnd = 0, | ||||
| @ -28,7 +28,7 @@ sketch001 = startSketchOn(XZ) | ||||
|   |> yLine(length = templateThickness * 2, tag = $seg08) | ||||
|   |> xLine(endAbsolute = segEndX(seg02) + 0, tag = $seg05) | ||||
|   |> yLine(endAbsolute = segEndY(seg01) + templateThickness, tag = $seg10) | ||||
|   |> xLine(endAbsolute = ZERO, tag = $seg04) | ||||
|   |> xLine(endAbsolute = turns::ZERO, tag = $seg04) | ||||
|   |> xLine(length = -segLen(seg04)) | ||||
|   |> yLine(length = -segLen(seg10)) | ||||
|   |> xLine(length = -segLen(seg05)) | ||||
|  | ||||
| @ -28,7 +28,7 @@ sketch001 = startSketchOn(XZ) | ||||
|   |> yLine(endAbsolute = -templateGap * 2 - (templateDiameter / 2), tag = $seg05) | ||||
|   |> xLine(endAbsolute = slateWidthHalf + templateThickness, tag = $seg04) | ||||
|   |> yLine(length = -length002, tag = $seg03) | ||||
|   |> xLine(endAbsolute = ZERO, tag = $seg02) | ||||
|   |> xLine(endAbsolute = turns::ZERO, tag = $seg02) | ||||
|   // |> line(end = [7.78, 11.16]) | ||||
|   |> xLine(length = -segLen(seg02)) | ||||
|   |> yLine(length = segLen(seg03)) | ||||
|  | ||||
| @ -21,7 +21,7 @@ export fn knob() { | ||||
|        }, %) | ||||
|     |> xLine(endAbsolute = 0.0001) | ||||
|     |> close() | ||||
|     |> revolve(axis = "Y") | ||||
|     |> revolve(axis = Y) | ||||
|     |> appearance(color = '#D0FF01', metalness = 90, roughness = 50) | ||||
|  | ||||
|   return knob | ||||
|  | ||||
| @ -876,7 +876,7 @@ async fn kcl_test_simple_revolve() { | ||||
|      |> line(end = [0, -5.5]) | ||||
|      |> line(end = [-2, 0]) | ||||
|      |> close() | ||||
|      |> revolve(axis = 'y') | ||||
|      |> revolve(axis = Y) | ||||
|  | ||||
| "#; | ||||
|  | ||||
| @ -896,7 +896,7 @@ async fn kcl_test_simple_revolve_uppercase() { | ||||
|      |> line(end = [0, -5.5]) | ||||
|      |> line(end = [-2, 0]) | ||||
|      |> close() | ||||
|      |> revolve(axis = 'Y') | ||||
|      |> revolve(axis = Y) | ||||
|  | ||||
| "#; | ||||
|  | ||||
| @ -916,7 +916,7 @@ async fn kcl_test_simple_revolve_negative() { | ||||
|      |> line(end = [0, -5.5]) | ||||
|      |> line(end = [-2, 0]) | ||||
|      |> close() | ||||
|      |> revolve(axis = '-Y', angle = 180) | ||||
|      |> revolve(axis = -Y, angle = 180) | ||||
|  | ||||
| "#; | ||||
|  | ||||
| @ -936,7 +936,7 @@ async fn kcl_test_revolve_bad_angle_low() { | ||||
|      |> line(end = [0, -5.5]) | ||||
|      |> line(end = [-2, 0]) | ||||
|      |> close() | ||||
|      |> revolve(axis = 'y', angle = -455) | ||||
|      |> revolve(axis = Y, angle = -455) | ||||
|  | ||||
| "#; | ||||
|  | ||||
| @ -962,7 +962,7 @@ async fn kcl_test_revolve_bad_angle_high() { | ||||
|      |> line(end = [0, -5.5]) | ||||
|      |> line(end = [-2, 0]) | ||||
|      |> close() | ||||
|      |> revolve(axis = 'y', angle = 455) | ||||
|      |> revolve(axis = Y, angle = 455) | ||||
|  | ||||
| "#; | ||||
|  | ||||
| @ -988,7 +988,7 @@ async fn kcl_test_simple_revolve_custom_angle() { | ||||
|      |> line(end = [0, -5.5]) | ||||
|      |> line(end = [-2, 0]) | ||||
|      |> close() | ||||
|      |> revolve(axis = 'y', angle = 180) | ||||
|      |> revolve(axis = Y, angle = 180) | ||||
|  | ||||
| "#; | ||||
|  | ||||
| @ -1008,7 +1008,7 @@ async fn kcl_test_simple_revolve_custom_axis() { | ||||
|      |> line(end = [0, -5.5]) | ||||
|      |> line(end = [-2, 0]) | ||||
|      |> close() | ||||
|      |> revolve(axis = {custom: {axis: [0, -1], origin: [0,0]}}, angle = 180) | ||||
|      |> revolve(axis = { direction = [0, -1], origin: [0,0] }, angle = 180) | ||||
|  | ||||
| "#; | ||||
|  | ||||
| @ -1106,7 +1106,7 @@ sketch001 = startSketchOn(box, "END") | ||||
|   |> circle(center = [10,10], radius= 4 ) | ||||
|   |> revolve( | ||||
|     angle = -90,  | ||||
|     axis = 'y'  | ||||
|     axis = Y  | ||||
|     ) | ||||
| "#; | ||||
|  | ||||
| @ -1131,7 +1131,7 @@ sketch001 = startSketchOn(box, "end") | ||||
|   |> line(end = [0, 10]) | ||||
|   |> close() | ||||
|   |> revolve( | ||||
|       axis = 'y', | ||||
|       axis = Y, | ||||
|       angle = -90, | ||||
|   ) | ||||
| "#; | ||||
| @ -1146,7 +1146,7 @@ async fn kcl_test_basic_revolve_circle() { | ||||
|   |> circle(center = [15, 0], radius= 5) | ||||
|   |> revolve( | ||||
|     angle = 360,  | ||||
|     axis = 'y'  | ||||
|     axis = Y  | ||||
|     ) | ||||
| "#; | ||||
|  | ||||
| @ -1166,7 +1166,7 @@ async fn kcl_test_simple_revolve_sketch_on_edge() { | ||||
|      |> line(end = [0, -5.5]) | ||||
|      |> line(end = [-2, 0]) | ||||
|      |> close() | ||||
|      |> revolve(axis = 'y', angle = 180) | ||||
|      |> revolve(axis = Y, angle = 180) | ||||
|  | ||||
| part002 = startSketchOn(part001, 'end') | ||||
|     |> startProfileAt([4.5, -5], %) | ||||
|  | ||||
| @ -23,8 +23,9 @@ use crate::{ | ||||
| const TYPES_DIR: &str = "../../docs/kcl/types"; | ||||
| const LANG_TOPICS: [&str; 5] = ["Types", "Modules", "Settings", "Known Issues", "Constants"]; | ||||
| // These types are declared in std. | ||||
| const DECLARED_TYPES: [&str; 11] = [ | ||||
|     "number", "string", "tag", "bool", "Sketch", "Solid", "Plane", "Helix", "Face", "Point2d", "Point3d", | ||||
| const DECLARED_TYPES: [&str; 14] = [ | ||||
|     "number", "string", "tag", "bool", "Sketch", "Solid", "Plane", "Helix", "Face", "Edge", "Point2d", "Point3d", | ||||
|     "Axis2d", "Axis3d", | ||||
| ]; | ||||
|  | ||||
| fn init_handlebars() -> Result<handlebars::Handlebars<'static>> { | ||||
| @ -339,9 +340,9 @@ fn generate_index(combined: &IndexMap<String, Box<dyn StdLibFn>>, kcl_lib: &[Doc | ||||
|         } | ||||
|  | ||||
|         functions.entry(d.mod_name()).or_default().push(match d { | ||||
|             DocData::Fn(f) => (f.name.clone(), d.file_name()), | ||||
|             DocData::Const(c) => (c.name.clone(), d.file_name()), | ||||
|             DocData::Ty(t) => (t.name.clone(), d.file_name()), | ||||
|             DocData::Fn(f) => (f.preferred_name.clone(), d.file_name()), | ||||
|             DocData::Const(c) => (c.preferred_name.clone(), d.file_name()), | ||||
|             DocData::Ty(t) => (t.preferred_name.clone(), d.file_name()), | ||||
|         }); | ||||
|  | ||||
|         if let DocData::Const(c) = d { | ||||
|  | ||||
| @ -9,7 +9,7 @@ use tower_lsp::lsp_types::{ | ||||
| use crate::{ | ||||
|     execution::annotations, | ||||
|     parsing::{ | ||||
|         ast::types::{Annotation, Node, PrimitiveType, Type, VariableKind}, | ||||
|         ast::types::{Annotation, ImportSelector, Node, PrimitiveType, Type, VariableKind}, | ||||
|         token::NumericSuffix, | ||||
|     }, | ||||
|     ModuleId, | ||||
| @ -17,7 +17,7 @@ use crate::{ | ||||
|  | ||||
| pub fn walk_prelude() -> Vec<DocData> { | ||||
|     let mut visitor = CollectionVisitor::default(); | ||||
|     visitor.visit_module("prelude").unwrap(); | ||||
|     visitor.visit_module("prelude", "").unwrap(); | ||||
|     visitor.result | ||||
| } | ||||
|  | ||||
| @ -29,7 +29,7 @@ struct CollectionVisitor { | ||||
| } | ||||
|  | ||||
| impl CollectionVisitor { | ||||
|     fn visit_module(&mut self, name: &str) -> Result<(), String> { | ||||
|     fn visit_module(&mut self, name: &str, preferred_prefix: &str) -> Result<(), String> { | ||||
|         let old_name = std::mem::replace(&mut self.name, name.to_owned()); | ||||
|         let source = crate::modules::read_std(name).unwrap(); | ||||
|         let parsed = crate::parsing::parse_str(source, ModuleId::from_usize(self.id)) | ||||
| @ -40,14 +40,16 @@ impl CollectionVisitor { | ||||
|         for n in &parsed.body { | ||||
|             match n { | ||||
|                 crate::parsing::ast::types::BodyItem::ImportStatement(import) if !import.visibility.is_default() => { | ||||
|                     // Only supports glob imports for now. | ||||
|                     assert!(matches!( | ||||
|                         import.selector, | ||||
|                         crate::parsing::ast::types::ImportSelector::Glob(..) | ||||
|                     )); | ||||
|                     match &import.path { | ||||
|                         crate::parsing::ast::types::ImportPath::Std { path } => { | ||||
|                             self.visit_module(&path[1])?; | ||||
|                             match import.selector { | ||||
|                                 ImportSelector::Glob(..) => self.visit_module(&path[1], "")?, | ||||
|                                 ImportSelector::None { .. } => { | ||||
|                                     self.visit_module(&path[1], &format!("{}::", import.module_name().unwrap()))? | ||||
|                                 } | ||||
|                                 // Only supports glob or whole-module imports for now. | ||||
|                                 _ => unimplemented!(), | ||||
|                             } | ||||
|                         } | ||||
|                         p => return Err(format!("Unexpected import: `{p}`")), | ||||
|                     } | ||||
| @ -59,8 +61,8 @@ impl CollectionVisitor { | ||||
|                         format!("std::{}::", self.name) | ||||
|                     }; | ||||
|                     let mut dd = match var.kind { | ||||
|                         VariableKind::Fn => DocData::Fn(FnData::from_ast(var, qual_name)), | ||||
|                         VariableKind::Const => DocData::Const(ConstData::from_ast(var, qual_name)), | ||||
|                         VariableKind::Fn => DocData::Fn(FnData::from_ast(var, qual_name, preferred_prefix)), | ||||
|                         VariableKind::Const => DocData::Const(ConstData::from_ast(var, qual_name, preferred_prefix)), | ||||
|                     }; | ||||
|  | ||||
|                     dd.with_meta(&var.outer_attrs); | ||||
| @ -77,7 +79,7 @@ impl CollectionVisitor { | ||||
|                     } else { | ||||
|                         format!("std::{}::", self.name) | ||||
|                     }; | ||||
|                     let mut dd = DocData::Ty(TyData::from_ast(ty, qual_name)); | ||||
|                     let mut dd = DocData::Ty(TyData::from_ast(ty, qual_name, preferred_prefix)); | ||||
|  | ||||
|                     dd.with_meta(&ty.outer_attrs); | ||||
|                     for a in &ty.outer_attrs { | ||||
| @ -200,6 +202,8 @@ impl DocData { | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct ConstData { | ||||
|     pub name: String, | ||||
|     /// How the const is indexed, etc. | ||||
|     pub preferred_name: String, | ||||
|     /// The fully qualified name. | ||||
|     pub qual_name: String, | ||||
|     pub value: Option<String>, | ||||
| @ -216,7 +220,11 @@ pub struct ConstData { | ||||
| } | ||||
|  | ||||
| impl ConstData { | ||||
|     fn from_ast(var: &crate::parsing::ast::types::VariableDeclaration, mut qual_name: String) -> Self { | ||||
|     fn from_ast( | ||||
|         var: &crate::parsing::ast::types::VariableDeclaration, | ||||
|         mut qual_name: String, | ||||
|         preferred_prefix: &str, | ||||
|     ) -> Self { | ||||
|         assert_eq!(var.kind, crate::parsing::ast::types::VariableKind::Const); | ||||
|  | ||||
|         let (value, ty) = match &var.declaration.init { | ||||
| @ -240,6 +248,7 @@ impl ConstData { | ||||
|         let name = var.declaration.id.name.clone(); | ||||
|         qual_name.push_str(&name); | ||||
|         ConstData { | ||||
|             preferred_name: format!("{preferred_prefix}{name}"), | ||||
|             name, | ||||
|             qual_name, | ||||
|             value, | ||||
| @ -272,7 +281,7 @@ impl ConstData { | ||||
|             detail.push_str(ty); | ||||
|         } | ||||
|         CompletionItem { | ||||
|             label: self.name.clone(), | ||||
|             label: self.preferred_name.clone(), | ||||
|             label_details: Some(CompletionItemLabelDetails { | ||||
|                 detail: self.value.clone(), | ||||
|                 description: None, | ||||
| @ -306,6 +315,8 @@ impl ConstData { | ||||
| pub struct FnData { | ||||
|     /// The name of the function. | ||||
|     pub name: String, | ||||
|     /// How the function is indexed, etc. | ||||
|     pub preferred_name: String, | ||||
|     /// The fully qualified name. | ||||
|     pub qual_name: String, | ||||
|     /// The args of the function. | ||||
| @ -326,7 +337,11 @@ pub struct FnData { | ||||
| } | ||||
|  | ||||
| impl FnData { | ||||
|     fn from_ast(var: &crate::parsing::ast::types::VariableDeclaration, mut qual_name: String) -> Self { | ||||
|     fn from_ast( | ||||
|         var: &crate::parsing::ast::types::VariableDeclaration, | ||||
|         mut qual_name: String, | ||||
|         preferred_prefix: &str, | ||||
|     ) -> Self { | ||||
|         assert_eq!(var.kind, crate::parsing::ast::types::VariableKind::Fn); | ||||
|         let crate::parsing::ast::types::Expr::FunctionExpression(expr) = &var.declaration.init else { | ||||
|             unreachable!(); | ||||
| @ -345,6 +360,7 @@ impl FnData { | ||||
|         } | ||||
|  | ||||
|         FnData { | ||||
|             preferred_name: format!("{preferred_prefix}{name}"), | ||||
|             name, | ||||
|             qual_name, | ||||
|             args: expr.params.iter().map(ArgData::from_ast).collect(), | ||||
| @ -443,7 +459,7 @@ impl FnData { | ||||
|         } | ||||
|         // We end with ${} so you can jump to the end of the snippet. | ||||
|         // After the last argument. | ||||
|         format!("{}({})${{}}", self.name, args.join(", ")) | ||||
|         format!("{}({})${{}}", self.preferred_name, args.join(", ")) | ||||
|     } | ||||
|  | ||||
|     fn to_signature_help(&self) -> SignatureHelp { | ||||
| @ -452,7 +468,7 @@ impl FnData { | ||||
|  | ||||
|         SignatureHelp { | ||||
|             signatures: vec![SignatureInformation { | ||||
|                 label: self.name.clone(), | ||||
|                 label: self.preferred_name.clone(), | ||||
|                 documentation: self.short_docs().map(|s| { | ||||
|                     Documentation::MarkupContent(MarkupContent { | ||||
|                         kind: MarkupKind::Markdown, | ||||
| @ -492,6 +508,7 @@ pub struct ArgData { | ||||
|     pub ty: Option<String>, | ||||
|     /// If the argument is required. | ||||
|     pub kind: ArgKind, | ||||
|     pub override_in_snippet: Option<bool>, | ||||
|     /// Additional information that could be used instead of the type's description. | ||||
|     /// This is helpful if the type is really basic, like "number" -- that won't tell the user much about | ||||
|     /// how this argument is meant to be used. | ||||
| @ -512,6 +529,7 @@ impl ArgData { | ||||
|             name: arg.identifier.name.clone(), | ||||
|             ty: arg.type_.as_ref().map(|t| t.to_string()), | ||||
|             docs: None, | ||||
|             override_in_snippet: None, | ||||
|             kind: if arg.labeled { | ||||
|                 ArgKind::Labelled(arg.optional()) | ||||
|             } else { | ||||
| @ -519,26 +537,54 @@ impl ArgData { | ||||
|             }, | ||||
|         }; | ||||
|  | ||||
|         for attr in &arg.identifier.outer_attrs { | ||||
|             if let Annotation { | ||||
|                 name: None, | ||||
|                 properties: Some(props), | ||||
|                 .. | ||||
|             } = &attr.inner | ||||
|             { | ||||
|                 for p in props { | ||||
|                     match &*p.key.name { | ||||
|                         "include_in_snippet" => { | ||||
|                             if let Some(b) = p.value.literal_bool() { | ||||
|                                 result.override_in_snippet = Some(b); | ||||
|                             } else { | ||||
|                                 panic!( | ||||
|                                     "Invalid value for `include_in_snippet`, expected bool literal, found {:?}", | ||||
|                                     p.value | ||||
|                                 ); | ||||
|                             } | ||||
|                         } | ||||
|                         _ => {} | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         result.with_comments(&arg.identifier.pre_comments); | ||||
|         result | ||||
|     } | ||||
|  | ||||
|     pub fn get_autocomplete_snippet(&self, index: usize) -> Option<(usize, String)> { | ||||
|         match self.override_in_snippet { | ||||
|             Some(false) => return None, | ||||
|             None if !self.kind.required() => return None, | ||||
|             _ => {} | ||||
|         } | ||||
|  | ||||
|         let label = if self.kind == ArgKind::Special { | ||||
|             String::new() | ||||
|         } else { | ||||
|             format!("{} = ", self.name) | ||||
|         }; | ||||
|         match self.ty.as_deref() { | ||||
|             Some(s) if ["Sketch", "Solid", "Plane | Face", "Sketch | Plane | Face"].contains(&s) => { | ||||
|                 Some((index, format!("{label}${{{}:{}}}", index, "%"))) | ||||
|             } | ||||
|             Some("number") if self.kind.required() => Some((index, format!(r#"{label}${{{}:3.14}}"#, index))), | ||||
|             Some("Point2d") if self.kind.required() => Some(( | ||||
|             Some(s) if s.starts_with("number") => Some((index, format!(r#"{label}${{{}:3.14}}"#, index))), | ||||
|             Some("Point2d") => Some(( | ||||
|                 index + 1, | ||||
|                 format!(r#"{label}[${{{}:3.14}}, ${{{}:3.14}}]"#, index, index + 1), | ||||
|             )), | ||||
|             Some("Point3d") if self.kind.required() => Some(( | ||||
|             Some("Point3d") => Some(( | ||||
|                 index + 2, | ||||
|                 format!( | ||||
|                     r#"{label}[${{{}:3.14}}, ${{{}:3.14}}, ${{{}:3.14}}]"#, | ||||
| @ -547,8 +593,10 @@ impl ArgData { | ||||
|                     index + 2 | ||||
|                 ), | ||||
|             )), | ||||
|             Some("string") if self.kind.required() => Some((index, format!(r#"{label}${{{}:"string"}}"#, index))), | ||||
|             Some("bool") if self.kind.required() => Some((index, format!(r#"{label}${{{}:false}}"#, index))), | ||||
|             Some("Axis2d | Edge") | Some("Axis3d | Edge") => Some((index, format!(r#"{label}${{{}:X}}"#, index))), | ||||
|  | ||||
|             Some("string") => Some((index, format!(r#"{label}${{{}:"string"}}"#, index))), | ||||
|             Some("bool") => Some((index, format!(r#"{label}${{{}:false}}"#, index))), | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| @ -580,6 +628,8 @@ impl ArgKind { | ||||
| pub struct TyData { | ||||
|     /// The name of the function. | ||||
|     pub name: String, | ||||
|     /// How the type is indexed, etc. | ||||
|     pub preferred_name: String, | ||||
|     /// The fully qualified name. | ||||
|     pub qual_name: String, | ||||
|     pub properties: Properties, | ||||
| @ -597,7 +647,11 @@ pub struct TyData { | ||||
| } | ||||
|  | ||||
| impl TyData { | ||||
|     fn from_ast(ty: &crate::parsing::ast::types::TypeDeclaration, mut qual_name: String) -> Self { | ||||
|     fn from_ast( | ||||
|         ty: &crate::parsing::ast::types::TypeDeclaration, | ||||
|         mut qual_name: String, | ||||
|         preferred_prefix: &str, | ||||
|     ) -> Self { | ||||
|         let name = ty.name.name.clone(); | ||||
|         qual_name.push_str(&name); | ||||
|         let mut referenced_types = HashSet::new(); | ||||
| @ -606,6 +660,7 @@ impl TyData { | ||||
|         } | ||||
|  | ||||
|         TyData { | ||||
|             preferred_name: format!("{preferred_prefix}{name}"), | ||||
|             name, | ||||
|             qual_name, | ||||
|             properties: Properties { | ||||
| @ -641,7 +696,7 @@ impl TyData { | ||||
|  | ||||
|     fn to_completion_item(&self) -> CompletionItem { | ||||
|         CompletionItem { | ||||
|             label: self.name.clone(), | ||||
|             label: self.preferred_name.clone(), | ||||
|             label_details: self.alias.as_ref().map(|t| CompletionItemLabelDetails { | ||||
|                 detail: Some(format!("type {} = {t}", self.name)), | ||||
|                 description: None, | ||||
| @ -658,7 +713,7 @@ impl TyData { | ||||
|             preselect: None, | ||||
|             sort_text: None, | ||||
|             filter_text: None, | ||||
|             insert_text: Some(self.name.clone()), | ||||
|             insert_text: Some(self.preferred_name.clone()), | ||||
|             insert_text_format: Some(InsertTextFormat::SNIPPET), | ||||
|             insert_text_mode: None, | ||||
|             text_edit: None, | ||||
|  | ||||
| @ -1000,9 +1000,12 @@ mod tests { | ||||
|  | ||||
|     #[test] | ||||
|     fn get_autocomplete_snippet_revolve() { | ||||
|         let revolve_fn: Box<dyn StdLibFn> = Box::new(crate::std::revolve::Revolve); | ||||
|         let snippet = revolve_fn.to_autocomplete_snippet().unwrap(); | ||||
|         assert_eq!(snippet, r#"revolve(${0:%}, axis = ${1:"X"})${}"#); | ||||
|         let data = kcl_doc::walk_prelude(); | ||||
|         let DocData::Fn(revolve_fn) = data.into_iter().find(|d| d.name() == "revolve").unwrap() else { | ||||
|             panic!(); | ||||
|         }; | ||||
|         let snippet = revolve_fn.to_autocomplete_snippet(); | ||||
|         assert_eq!(snippet, r#"revolve(axis = ${0:X})${}"#); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
| @ -1015,7 +1018,7 @@ mod tests { | ||||
|         let snippet = circle_fn.to_autocomplete_snippet(); | ||||
|         assert_eq!( | ||||
|             snippet, | ||||
|             r#"circle(${0:%}, center = [${1:3.14}, ${2:3.14}], radius = ${3:3.14})${}"# | ||||
|             r#"circle(center = [${0:3.14}, ${1:3.14}], radius = ${2:3.14})${}"# | ||||
|         ); | ||||
|     } | ||||
|  | ||||
| @ -1089,11 +1092,14 @@ mod tests { | ||||
|     #[test] | ||||
|     #[allow(clippy::literal_string_with_formatting_args)] | ||||
|     fn get_autocomplete_snippet_helix() { | ||||
|         let helix_fn: Box<dyn StdLibFn> = Box::new(crate::std::helix::Helix); | ||||
|         let snippet = helix_fn.to_autocomplete_snippet().unwrap(); | ||||
|         let data = kcl_doc::walk_prelude(); | ||||
|         let DocData::Fn(helix_fn) = data.into_iter().find(|d| d.name() == "helix").unwrap() else { | ||||
|             panic!(); | ||||
|         }; | ||||
|         let snippet = helix_fn.to_autocomplete_snippet(); | ||||
|         assert_eq!( | ||||
|             snippet, | ||||
|             r#"helix(revolutions = ${0:3.14}, angleStart = ${1:3.14}, radius = ${2:3.14}, axis = ${3:"X"}, length = ${4:3.14})${}"# | ||||
|             r#"helix(revolutions = ${0:3.14}, angleStart = ${1:3.14}, radius = ${2:3.14}, axis = ${3:X}, length = ${4:3.14})${}"# | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -27,6 +27,19 @@ pub enum Operation { | ||||
|         is_error: bool, | ||||
|     }, | ||||
|     #[serde(rename_all = "camelCase")] | ||||
|     KclStdLibCall { | ||||
|         name: String, | ||||
|         /// The unlabeled argument to the function. | ||||
|         unlabeled_arg: Option<OpArg>, | ||||
|         /// The labeled keyword arguments to the function. | ||||
|         labeled_args: IndexMap<String, OpArg>, | ||||
|         /// The source range of the operation in the source code. | ||||
|         source_range: SourceRange, | ||||
|         /// True if the operation resulted in an error. | ||||
|         #[serde(default, skip_serializing_if = "is_false")] | ||||
|         is_error: bool, | ||||
|     }, | ||||
|     #[serde(rename_all = "camelCase")] | ||||
|     UserDefinedFunctionCall { | ||||
|         /// The name of the user-defined function being called.  Anonymous | ||||
|         /// functions have no name. | ||||
| @ -49,6 +62,7 @@ impl Operation { | ||||
|     pub(crate) fn set_std_lib_call_is_error(&mut self, is_err: bool) { | ||||
|         match self { | ||||
|             Self::StdLibCall { ref mut is_error, .. } => *is_error = is_err, | ||||
|             Self::KclStdLibCall { ref mut is_error, .. } => *is_error = is_err, | ||||
|             Self::UserDefinedFunctionCall { .. } | Self::UserDefinedFunctionReturn => {} | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -3,7 +3,7 @@ use std::collections::HashMap; | ||||
| use async_recursion::async_recursion; | ||||
| use indexmap::IndexMap; | ||||
|  | ||||
| use super::kcl_value::TypeDef; | ||||
| use super::{kcl_value::TypeDef, types::PrimitiveType}; | ||||
| use crate::{ | ||||
|     engine::ExecutionKind, | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
| @ -1031,6 +1031,15 @@ impl Node<UnaryExpression> { | ||||
|         } | ||||
|  | ||||
|         let value = &self.argument.get_result(exec_state, ctx).await?; | ||||
|         let err = || { | ||||
|             KclError::Semantic(KclErrorDetails { | ||||
|                 message: format!( | ||||
|                     "You can only negate numbers, planes, or lines, but this is a {}", | ||||
|                     value.human_friendly_type() | ||||
|                 ), | ||||
|                 source_ranges: vec![self.into()], | ||||
|             }) | ||||
|         }; | ||||
|         match value { | ||||
|             KclValue::Number { value, ty, .. } => { | ||||
|                 let meta = vec![Metadata { | ||||
| @ -1052,13 +1061,63 @@ impl Node<UnaryExpression> { | ||||
|                 plane.id = exec_state.next_uuid(); | ||||
|                 Ok(KclValue::Plane { value: plane }) | ||||
|             } | ||||
|             _ => Err(KclError::Semantic(KclErrorDetails { | ||||
|                 message: format!( | ||||
|                     "You can only negate numbers or planes, but this is a {}", | ||||
|                     value.human_friendly_type() | ||||
|                 ), | ||||
|                 source_ranges: vec![self.into()], | ||||
|             })), | ||||
|             KclValue::Object { value: values, meta } => { | ||||
|                 // Special-case for negating line-like objects. | ||||
|                 let Some(direction) = values.get("direction") else { | ||||
|                     return Err(err()); | ||||
|                 }; | ||||
|  | ||||
|                 let direction = match direction { | ||||
|                     KclValue::MixedArray { value: values, meta } => { | ||||
|                         let values = values | ||||
|                             .iter() | ||||
|                             .map(|v| match v { | ||||
|                                 KclValue::Number { value, ty, meta } => Ok(KclValue::Number { | ||||
|                                     value: *value * -1.0, | ||||
|                                     ty: ty.clone(), | ||||
|                                     meta: meta.clone(), | ||||
|                                 }), | ||||
|                                 _ => Err(err()), | ||||
|                             }) | ||||
|                             .collect::<Result<Vec<_>, _>>()?; | ||||
|  | ||||
|                         KclValue::MixedArray { | ||||
|                             value: values, | ||||
|                             meta: meta.clone(), | ||||
|                         } | ||||
|                     } | ||||
|                     KclValue::HomArray { | ||||
|                         value: values, | ||||
|                         ty: ty @ RuntimeType::Primitive(PrimitiveType::Number(_)), | ||||
|                     } => { | ||||
|                         let values = values | ||||
|                             .iter() | ||||
|                             .map(|v| match v { | ||||
|                                 KclValue::Number { value, ty, meta } => Ok(KclValue::Number { | ||||
|                                     value: *value * -1.0, | ||||
|                                     ty: ty.clone(), | ||||
|                                     meta: meta.clone(), | ||||
|                                 }), | ||||
|                                 _ => Err(err()), | ||||
|                             }) | ||||
|                             .collect::<Result<Vec<_>, _>>()?; | ||||
|  | ||||
|                         KclValue::HomArray { | ||||
|                             value: values, | ||||
|                             ty: ty.clone(), | ||||
|                         } | ||||
|                     } | ||||
|                     _ => return Err(err()), | ||||
|                 }; | ||||
|  | ||||
|                 let mut value = values.clone(); | ||||
|                 value.insert("direction".to_owned(), direction); | ||||
|                 Ok(KclValue::Object { | ||||
|                     value, | ||||
|                     meta: meta.clone(), | ||||
|                 }) | ||||
|             } | ||||
|             _ => Err(err()), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -2145,6 +2204,27 @@ impl FunctionSource { | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 let op = if props.include_in_feature_tree { | ||||
|                     let op_labeled_args = args | ||||
|                         .kw_args | ||||
|                         .labeled | ||||
|                         .iter() | ||||
|                         .map(|(k, arg)| (k.clone(), OpArg::new(OpKclValue::from(&arg.value), arg.source_range))) | ||||
|                         .collect(); | ||||
|                     Some(Operation::KclStdLibCall { | ||||
|                         // TODO | ||||
|                         name: String::new(), | ||||
|                         unlabeled_arg: args | ||||
|                             .unlabeled_kw_arg_unconverted() | ||||
|                             .map(|arg| OpArg::new(OpKclValue::from(&arg.value), arg.source_range)), | ||||
|                         labeled_args: op_labeled_args, | ||||
|                         source_range: callsite, | ||||
|                         is_error: false, | ||||
|                     }) | ||||
|                 } else { | ||||
|                     None | ||||
|                 }; | ||||
|  | ||||
|                 // Attempt to call the function. | ||||
|                 exec_state.mut_stack().push_new_env_for_rust_call(); | ||||
|                 let mut result = { | ||||
| @ -2152,7 +2232,15 @@ impl FunctionSource { | ||||
|                     let result = func(exec_state, args).await; | ||||
|                     exec_state.mut_stack().pop_env(); | ||||
|  | ||||
|                     // TODO support recording op into the feature tree | ||||
|                     if let Some(mut op) = op { | ||||
|                         op.set_std_lib_call_is_error(result.is_err()); | ||||
|                         // Track call operation.  We do this after the call | ||||
|                         // since things like patternTransform may call user code | ||||
|                         // before running, and we will likely want to use the | ||||
|                         // return value. The call takes ownership of the args, | ||||
|                         // so we need to build the op before the call. | ||||
|                         exec_state.global.operations.push(op); | ||||
|                     } | ||||
|                     result | ||||
|                 }?; | ||||
|  | ||||
|  | ||||
| @ -56,6 +56,20 @@ impl RuntimeType { | ||||
|         RuntimeType::Primitive(PrimitiveType::ImportedGeometry) | ||||
|     } | ||||
|  | ||||
|     /// `[number; 2]` | ||||
|     pub fn point2d() -> Self { | ||||
|         RuntimeType::Array(Box::new(RuntimeType::number_any()), ArrayLen::Known(2)) | ||||
|     } | ||||
|  | ||||
|     /// `[number; 3]` | ||||
|     pub fn point3d() -> Self { | ||||
|         RuntimeType::Array(Box::new(RuntimeType::number_any()), ArrayLen::Known(3)) | ||||
|     } | ||||
|  | ||||
|     pub fn number_any() -> Self { | ||||
|         RuntimeType::Primitive(PrimitiveType::Number(NumericType::Any)) | ||||
|     } | ||||
|  | ||||
|     pub fn from_parsed( | ||||
|         value: Type, | ||||
|         exec_state: &mut ExecState, | ||||
| @ -93,24 +107,30 @@ impl RuntimeType { | ||||
|             AstPrimitiveType::Number(suffix) => RuntimeType::Primitive(PrimitiveType::Number( | ||||
|                 NumericType::from_parsed(suffix, &exec_state.mod_local.settings), | ||||
|             )), | ||||
|             AstPrimitiveType::Named(name) => { | ||||
|                 let ty_val = exec_state | ||||
|                     .stack() | ||||
|                     .get(&format!("{}{}", memory::TYPE_PREFIX, name.name), source_range) | ||||
|                     .map_err(|_| CompilationError::err(source_range, format!("Unknown type: {}", name.name)))?; | ||||
|  | ||||
|                 match ty_val { | ||||
|                     KclValue::Type { value, .. } => match value { | ||||
|                         TypeDef::RustRepr(ty, _) => RuntimeType::Primitive(ty.clone()), | ||||
|                         TypeDef::Alias(ty) => ty.clone(), | ||||
|                     }, | ||||
|                     _ => unreachable!(), | ||||
|                 } | ||||
|             } | ||||
|             AstPrimitiveType::Named(name) => Self::from_alias(&name.name, exec_state, source_range)?, | ||||
|             AstPrimitiveType::Tag => RuntimeType::Primitive(PrimitiveType::Tag), | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     pub fn from_alias( | ||||
|         alias: &str, | ||||
|         exec_state: &mut ExecState, | ||||
|         source_range: SourceRange, | ||||
|     ) -> Result<Self, CompilationError> { | ||||
|         let ty_val = exec_state | ||||
|             .stack() | ||||
|             .get(&format!("{}{}", memory::TYPE_PREFIX, alias), source_range) | ||||
|             .map_err(|_| CompilationError::err(source_range, format!("Unknown type: {}", alias)))?; | ||||
|  | ||||
|         Ok(match ty_val { | ||||
|             KclValue::Type { value, .. } => match value { | ||||
|                 TypeDef::RustRepr(ty, _) => RuntimeType::Primitive(ty.clone()), | ||||
|                 TypeDef::Alias(ty) => ty.clone(), | ||||
|             }, | ||||
|             _ => unreachable!(), | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     pub fn human_friendly_type(&self) -> String { | ||||
|         match self { | ||||
|             RuntimeType::Primitive(ty) => ty.to_string(), | ||||
| @ -143,6 +163,35 @@ impl RuntimeType { | ||||
|             (Object(t1), Object(t2)) => t2 | ||||
|                 .iter() | ||||
|                 .all(|(f, t)| t1.iter().any(|(ff, tt)| f == ff && tt.subtype(t))), | ||||
|             // Equality between Axis types and there object representation. | ||||
|             (Object(t1), Primitive(PrimitiveType::Axis2d)) => { | ||||
|                 t1.iter() | ||||
|                     .any(|(n, t)| n == "origin" && t.subtype(&RuntimeType::point2d())) | ||||
|                     && t1 | ||||
|                         .iter() | ||||
|                         .any(|(n, t)| n == "direction" && t.subtype(&RuntimeType::point2d())) | ||||
|             } | ||||
|             (Object(t1), Primitive(PrimitiveType::Axis3d)) => { | ||||
|                 t1.iter() | ||||
|                     .any(|(n, t)| n == "origin" && t.subtype(&RuntimeType::point3d())) | ||||
|                     && t1 | ||||
|                         .iter() | ||||
|                         .any(|(n, t)| n == "direction" && t.subtype(&RuntimeType::point3d())) | ||||
|             } | ||||
|             (Primitive(PrimitiveType::Axis2d), Object(t2)) => { | ||||
|                 t2.iter() | ||||
|                     .any(|(n, t)| n == "origin" && t.subtype(&RuntimeType::point2d())) | ||||
|                     && t2 | ||||
|                         .iter() | ||||
|                         .any(|(n, t)| n == "direction" && t.subtype(&RuntimeType::point2d())) | ||||
|             } | ||||
|             (Primitive(PrimitiveType::Axis3d), Object(t2)) => { | ||||
|                 t2.iter() | ||||
|                     .any(|(n, t)| n == "origin" && t.subtype(&RuntimeType::point3d())) | ||||
|                     && t2 | ||||
|                         .iter() | ||||
|                         .any(|(n, t)| n == "direction" && t.subtype(&RuntimeType::point3d())) | ||||
|             } | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
| @ -213,11 +262,11 @@ impl ArrayLen { | ||||
|     } | ||||
|  | ||||
|     /// True if the length constraint is satisfied by the supplied length. | ||||
|     fn satisfied(self, len: usize) -> bool { | ||||
|     fn satisfied(self, len: usize, allow_shrink: bool) -> Option<usize> { | ||||
|         match self { | ||||
|             ArrayLen::None => true, | ||||
|             ArrayLen::NonEmpty => len > 0, | ||||
|             ArrayLen::Known(s) => len == s, | ||||
|             ArrayLen::None => Some(len), | ||||
|             ArrayLen::NonEmpty => (len > 0).then_some(len), | ||||
|             ArrayLen::Known(s) => (if allow_shrink { len >= s } else { len == s }).then_some(s), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -233,6 +282,9 @@ pub enum PrimitiveType { | ||||
|     Plane, | ||||
|     Helix, | ||||
|     Face, | ||||
|     Edge, | ||||
|     Axis2d, | ||||
|     Axis3d, | ||||
|     ImportedGeometry, | ||||
| } | ||||
|  | ||||
| @ -248,6 +300,9 @@ impl PrimitiveType { | ||||
|             PrimitiveType::Plane => "Planes".to_owned(), | ||||
|             PrimitiveType::Helix => "Helices".to_owned(), | ||||
|             PrimitiveType::Face => "Faces".to_owned(), | ||||
|             PrimitiveType::Edge => "Edges".to_owned(), | ||||
|             PrimitiveType::Axis2d => "2d axes".to_owned(), | ||||
|             PrimitiveType::Axis3d => "3d axes".to_owned(), | ||||
|             PrimitiveType::ImportedGeometry => "imported geometries".to_owned(), | ||||
|             PrimitiveType::Tag => "tags".to_owned(), | ||||
|         } | ||||
| @ -273,6 +328,9 @@ impl fmt::Display for PrimitiveType { | ||||
|             PrimitiveType::Solid => write!(f, "Solid"), | ||||
|             PrimitiveType::Plane => write!(f, "Plane"), | ||||
|             PrimitiveType::Face => write!(f, "Face"), | ||||
|             PrimitiveType::Edge => write!(f, "Edge"), | ||||
|             PrimitiveType::Axis2d => write!(f, "Axis2d"), | ||||
|             PrimitiveType::Axis3d => write!(f, "Axis3d"), | ||||
|             PrimitiveType::Helix => write!(f, "Helix"), | ||||
|             PrimitiveType::ImportedGeometry => write!(f, "imported geometry"), | ||||
|         } | ||||
| @ -298,6 +356,10 @@ impl NumericType { | ||||
|         NumericType::Known(UnitType::Count) | ||||
|     } | ||||
|  | ||||
|     pub fn mm() -> Self { | ||||
|         NumericType::Known(UnitType::Length(UnitLen::Mm)) | ||||
|     } | ||||
|  | ||||
|     /// Combine two types when we expect them to be equal. | ||||
|     pub fn combine_eq(self, other: &NumericType) -> NumericType { | ||||
|         if &self == other { | ||||
| @ -541,7 +603,7 @@ impl KclValue { | ||||
|     pub fn coerce(&self, ty: &RuntimeType, exec_state: &mut ExecState) -> Option<KclValue> { | ||||
|         match ty { | ||||
|             RuntimeType::Primitive(ty) => self.coerce_to_primitive_type(ty, exec_state), | ||||
|             RuntimeType::Array(ty, len) => self.coerce_to_array_type(ty, *len, exec_state), | ||||
|             RuntimeType::Array(ty, len) => self.coerce_to_array_type(ty, *len, exec_state, false), | ||||
|             RuntimeType::Tuple(tys) => self.coerce_to_tuple_type(tys, exec_state), | ||||
|             RuntimeType::Union(tys) => self.coerce_to_union_type(tys, exec_state), | ||||
|             RuntimeType::Object(tys) => self.coerce_to_object_type(tys, exec_state), | ||||
| @ -609,6 +671,55 @@ impl KclValue { | ||||
|                 KclValue::Helix { .. } => Some(value.clone()), | ||||
|                 _ => None, | ||||
|             }, | ||||
|             PrimitiveType::Edge => match value { | ||||
|                 KclValue::Uuid { .. } => Some(value.clone()), | ||||
|                 KclValue::TagIdentifier { .. } => Some(value.clone()), | ||||
|                 _ => None, | ||||
|             }, | ||||
|             PrimitiveType::Axis2d => match value { | ||||
|                 KclValue::Object { value: values, meta } => { | ||||
|                     if values.get("origin")?.has_type(&RuntimeType::point2d()) | ||||
|                         && values.get("direction")?.has_type(&RuntimeType::point2d()) | ||||
|                     { | ||||
|                         return Some(value.clone()); | ||||
|                     } | ||||
|  | ||||
|                     let origin = values.get("origin").and_then(|p| { | ||||
|                         p.coerce_to_array_type(&RuntimeType::number_any(), ArrayLen::Known(2), exec_state, true) | ||||
|                     })?; | ||||
|                     let direction = values.get("direction").and_then(|p| { | ||||
|                         p.coerce_to_array_type(&RuntimeType::number_any(), ArrayLen::Known(2), exec_state, true) | ||||
|                     })?; | ||||
|  | ||||
|                     Some(KclValue::Object { | ||||
|                         value: [("origin".to_owned(), origin), ("direction".to_owned(), direction)].into(), | ||||
|                         meta: meta.clone(), | ||||
|                     }) | ||||
|                 } | ||||
|                 _ => None, | ||||
|             }, | ||||
|             PrimitiveType::Axis3d => match value { | ||||
|                 KclValue::Object { value: values, meta } => { | ||||
|                     if values.get("origin")?.has_type(&RuntimeType::point3d()) | ||||
|                         && values.get("direction")?.has_type(&RuntimeType::point3d()) | ||||
|                     { | ||||
|                         return Some(value.clone()); | ||||
|                     } | ||||
|  | ||||
|                     let origin = values.get("origin").and_then(|p| { | ||||
|                         p.coerce_to_array_type(&RuntimeType::number_any(), ArrayLen::Known(3), exec_state, true) | ||||
|                     })?; | ||||
|                     let direction = values.get("direction").and_then(|p| { | ||||
|                         p.coerce_to_array_type(&RuntimeType::number_any(), ArrayLen::Known(3), exec_state, true) | ||||
|                     })?; | ||||
|  | ||||
|                     Some(KclValue::Object { | ||||
|                         value: [("origin".to_owned(), origin), ("direction".to_owned(), direction)].into(), | ||||
|                         meta: meta.clone(), | ||||
|                     }) | ||||
|                 } | ||||
|                 _ => None, | ||||
|             }, | ||||
|             PrimitiveType::ImportedGeometry => match value { | ||||
|                 KclValue::ImportedGeometry { .. } => Some(value.clone()), | ||||
|                 _ => None, | ||||
| @ -621,60 +732,35 @@ impl KclValue { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn coerce_to_array_type(&self, ty: &RuntimeType, len: ArrayLen, exec_state: &mut ExecState) -> Option<KclValue> { | ||||
|     fn coerce_to_array_type( | ||||
|         &self, | ||||
|         ty: &RuntimeType, | ||||
|         len: ArrayLen, | ||||
|         exec_state: &mut ExecState, | ||||
|         allow_shrink: bool, | ||||
|     ) -> Option<KclValue> { | ||||
|         match self { | ||||
|             KclValue::HomArray { value, ty: aty } if aty == ty => { | ||||
|                 let value = match len { | ||||
|                     ArrayLen::None => value.clone(), | ||||
|                     ArrayLen::NonEmpty => { | ||||
|                         if value.is_empty() { | ||||
|                             return None; | ||||
|                         } | ||||
|  | ||||
|                         value.clone() | ||||
|                     } | ||||
|                     ArrayLen::Known(n) => { | ||||
|                         if n != value.len() { | ||||
|                             return None; | ||||
|                         } | ||||
|  | ||||
|                         value[..n].to_vec() | ||||
|                     } | ||||
|                 }; | ||||
|  | ||||
|                 Some(KclValue::HomArray { value, ty: ty.clone() }) | ||||
|             KclValue::HomArray { value, ty: aty } if aty.subtype(ty) => { | ||||
|                 len.satisfied(value.len(), allow_shrink).map(|len| KclValue::HomArray { | ||||
|                     value: value[..len].to_vec(), | ||||
|                     ty: aty.clone(), | ||||
|                 }) | ||||
|             } | ||||
|             value if len.satisfied(1) && value.has_type(ty) => Some(KclValue::HomArray { | ||||
|             value if len.satisfied(1, false).is_some() && value.has_type(ty) => Some(KclValue::HomArray { | ||||
|                 value: vec![value.clone()], | ||||
|                 ty: ty.clone(), | ||||
|             }), | ||||
|             KclValue::MixedArray { value, .. } => { | ||||
|                 let value = match len { | ||||
|                     ArrayLen::None => value.clone(), | ||||
|                     ArrayLen::NonEmpty => { | ||||
|                         if value.is_empty() { | ||||
|                             return None; | ||||
|                         } | ||||
|                 let len = len.satisfied(value.len(), allow_shrink)?; | ||||
|  | ||||
|                         value.clone() | ||||
|                     } | ||||
|                     ArrayLen::Known(n) => { | ||||
|                         if n != value.len() { | ||||
|                             return None; | ||||
|                         } | ||||
|  | ||||
|                         value[..n].to_vec() | ||||
|                     } | ||||
|                 }; | ||||
|  | ||||
|                 let value = value | ||||
|                 let value = value[..len] | ||||
|                     .iter() | ||||
|                     .map(|v| v.coerce(ty, exec_state)) | ||||
|                     .collect::<Option<Vec<_>>>()?; | ||||
|  | ||||
|                 Some(KclValue::HomArray { value, ty: ty.clone() }) | ||||
|             } | ||||
|             KclValue::KclNone { .. } if len.satisfied(0) => Some(KclValue::HomArray { | ||||
|             KclValue::KclNone { .. } if len.satisfied(0, false).is_some() => Some(KclValue::HomArray { | ||||
|                 value: Vec::new(), | ||||
|                 ty: ty.clone(), | ||||
|             }), | ||||
| @ -1251,4 +1337,119 @@ mod test { | ||||
|         assert!(count.coerce(&tyb, &mut exec_state).is_none()); | ||||
|         assert!(count.coerce(&tyb2, &mut exec_state).is_none()); | ||||
|     } | ||||
|  | ||||
|     #[tokio::test(flavor = "multi_thread")] | ||||
|     async fn coerce_axes() { | ||||
|         let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock().await); | ||||
|  | ||||
|         // Subtyping | ||||
|         assert!(RuntimeType::Primitive(PrimitiveType::Axis2d).subtype(&RuntimeType::Primitive(PrimitiveType::Axis2d))); | ||||
|         assert!(RuntimeType::Primitive(PrimitiveType::Axis3d).subtype(&RuntimeType::Primitive(PrimitiveType::Axis3d))); | ||||
|         assert!(!RuntimeType::Primitive(PrimitiveType::Axis3d).subtype(&RuntimeType::Primitive(PrimitiveType::Axis2d))); | ||||
|         assert!(!RuntimeType::Primitive(PrimitiveType::Axis2d).subtype(&RuntimeType::Primitive(PrimitiveType::Axis3d))); | ||||
|  | ||||
|         // Coercion | ||||
|         let a2d = KclValue::Object { | ||||
|             value: [ | ||||
|                 ( | ||||
|                     "origin".to_owned(), | ||||
|                     KclValue::HomArray { | ||||
|                         value: vec![ | ||||
|                             KclValue::Number { | ||||
|                                 value: 0.0, | ||||
|                                 ty: NumericType::mm(), | ||||
|                                 meta: Vec::new(), | ||||
|                             }, | ||||
|                             KclValue::Number { | ||||
|                                 value: 0.0, | ||||
|                                 ty: NumericType::mm(), | ||||
|                                 meta: Vec::new(), | ||||
|                             }, | ||||
|                         ], | ||||
|                         ty: RuntimeType::Primitive(PrimitiveType::Number(NumericType::mm())), | ||||
|                     }, | ||||
|                 ), | ||||
|                 ( | ||||
|                     "direction".to_owned(), | ||||
|                     KclValue::HomArray { | ||||
|                         value: vec![ | ||||
|                             KclValue::Number { | ||||
|                                 value: 1.0, | ||||
|                                 ty: NumericType::mm(), | ||||
|                                 meta: Vec::new(), | ||||
|                             }, | ||||
|                             KclValue::Number { | ||||
|                                 value: 0.0, | ||||
|                                 ty: NumericType::mm(), | ||||
|                                 meta: Vec::new(), | ||||
|                             }, | ||||
|                         ], | ||||
|                         ty: RuntimeType::Primitive(PrimitiveType::Number(NumericType::mm())), | ||||
|                     }, | ||||
|                 ), | ||||
|             ] | ||||
|             .into(), | ||||
|             meta: Vec::new(), | ||||
|         }; | ||||
|         let a3d = KclValue::Object { | ||||
|             value: [ | ||||
|                 ( | ||||
|                     "origin".to_owned(), | ||||
|                     KclValue::HomArray { | ||||
|                         value: vec![ | ||||
|                             KclValue::Number { | ||||
|                                 value: 0.0, | ||||
|                                 ty: NumericType::mm(), | ||||
|                                 meta: Vec::new(), | ||||
|                             }, | ||||
|                             KclValue::Number { | ||||
|                                 value: 0.0, | ||||
|                                 ty: NumericType::mm(), | ||||
|                                 meta: Vec::new(), | ||||
|                             }, | ||||
|                             KclValue::Number { | ||||
|                                 value: 0.0, | ||||
|                                 ty: NumericType::mm(), | ||||
|                                 meta: Vec::new(), | ||||
|                             }, | ||||
|                         ], | ||||
|                         ty: RuntimeType::Primitive(PrimitiveType::Number(NumericType::mm())), | ||||
|                     }, | ||||
|                 ), | ||||
|                 ( | ||||
|                     "direction".to_owned(), | ||||
|                     KclValue::HomArray { | ||||
|                         value: vec![ | ||||
|                             KclValue::Number { | ||||
|                                 value: 1.0, | ||||
|                                 ty: NumericType::mm(), | ||||
|                                 meta: Vec::new(), | ||||
|                             }, | ||||
|                             KclValue::Number { | ||||
|                                 value: 0.0, | ||||
|                                 ty: NumericType::mm(), | ||||
|                                 meta: Vec::new(), | ||||
|                             }, | ||||
|                             KclValue::Number { | ||||
|                                 value: 1.0, | ||||
|                                 ty: NumericType::mm(), | ||||
|                                 meta: Vec::new(), | ||||
|                             }, | ||||
|                         ], | ||||
|                         ty: RuntimeType::Primitive(PrimitiveType::Number(NumericType::mm())), | ||||
|                     }, | ||||
|                 ), | ||||
|             ] | ||||
|             .into(), | ||||
|             meta: Vec::new(), | ||||
|         }; | ||||
|  | ||||
|         let ty2d = RuntimeType::Primitive(PrimitiveType::Axis2d); | ||||
|         let ty3d = RuntimeType::Primitive(PrimitiveType::Axis3d); | ||||
|  | ||||
|         assert_coerce_results(&a2d, &ty2d, &a2d, &mut exec_state); | ||||
|         assert_coerce_results(&a3d, &ty3d, &a3d, &mut exec_state); | ||||
|         assert_coerce_results(&a3d, &ty2d, &a2d, &mut exec_state); | ||||
|         assert!(a2d.coerce(&ty3d, &mut exec_state).is_none()); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -120,7 +120,7 @@ const Part001 = startSketchOn('XY') | ||||
|   |> line([0, pipeLength], %) | ||||
|   |> angledLineToX({ angle: 60, to: pipeLargeDia }, %) | ||||
|   |> close() | ||||
|   |> revolve({ axis: 'y' }, %) | ||||
|   |> revolve({ axis = Y }, %) | ||||
| " | ||||
|     ); | ||||
|  | ||||
| @ -156,7 +156,7 @@ const part001 = startSketchOn('XY') | ||||
|   |> line([0, pipeLength], %) | ||||
|   |> angledLineToX({ angle: 60, to: pipeLargeDia }, %) | ||||
|   |> close() | ||||
|   |> revolve({ axis: 'y' }, %) | ||||
|   |> revolve({ axis = Y }, %) | ||||
| " | ||||
|     ); | ||||
|  | ||||
|  | ||||
| @ -1632,7 +1632,7 @@ insideRevolve = startSketchOn(XZ) | ||||
|   |> line(end = [0, -thickness]) | ||||
|   |> line(end = [-overHangLength, 0]) | ||||
|   |> close() | ||||
|   |> revolve({ axis: 'y' }, %) | ||||
|   |> revolve({ axis = Y }, %) | ||||
|  | ||||
| // Sketch and revolve one of the balls and duplicate it using a circular pattern. (This is currently a workaround, we have a bug with rotating on a sketch that touches the rotation axis) | ||||
| sphere = startSketchOn(XZ) | ||||
| @ -1647,7 +1647,7 @@ sphere = startSketchOn(XZ) | ||||
|        radius: sphereDia / 2 - 0.05 | ||||
|      }, %) | ||||
|   |> close() | ||||
|   |> revolve({ axis: 'x' }, %) | ||||
|   |> revolve({ axis = X }, %) | ||||
|   |> patternCircular3d( | ||||
|        axis = [0, 0, 1], | ||||
|        center = [0, 0, 0], | ||||
| @ -1671,7 +1671,7 @@ outsideRevolve = startSketchOn(XZ) | ||||
|   |> line(end = [0, thickness]) | ||||
|   |> line(end = [overHangLength - thickness, 0]) | ||||
|   |> close() | ||||
|   |> revolve({ axis: 'y' }, %)"# | ||||
|   |> revolve({ axis = Y }, %)"# | ||||
|                     .to_string(), | ||||
|             }, | ||||
|         }) | ||||
| @ -1705,7 +1705,7 @@ outsideRevolve = startSketchOn(XZ) | ||||
|             start: tower_lsp::lsp_types::Position { line: 0, character: 0 }, | ||||
|             end: tower_lsp::lsp_types::Position { | ||||
|                 line: 60, | ||||
|                 character: 30 | ||||
|                 character: 29 | ||||
|             } | ||||
|         } | ||||
|     ); | ||||
| @ -1732,7 +1732,7 @@ insideRevolve = startSketchOn(XZ) | ||||
|   |> line(end = [0, -thickness]) | ||||
|   |> line(end = [-overHangLength, 0]) | ||||
|   |> close() | ||||
|   |> revolve({ axis = 'y' }, %) | ||||
|   |> revolve({ axis = Y }, %) | ||||
|  | ||||
| // Sketch and revolve one of the balls and duplicate it using a circular pattern. (This is currently a workaround, we have a bug with rotating on a sketch that touches the rotation axis) | ||||
| sphere = startSketchOn(XZ) | ||||
| @ -1747,7 +1747,7 @@ sphere = startSketchOn(XZ) | ||||
|        radius = sphereDia / 2 - 0.05 | ||||
|      }, %) | ||||
|   |> close() | ||||
|   |> revolve({ axis = 'x' }, %) | ||||
|   |> revolve({ axis = X }, %) | ||||
|   |> patternCircular3d( | ||||
|        axis = [0, 0, 1], | ||||
|        center = [0, 0, 0], | ||||
| @ -1771,7 +1771,7 @@ outsideRevolve = startSketchOn(XZ) | ||||
|   |> line(end = [0, thickness]) | ||||
|   |> line(end = [overHangLength - thickness, 0]) | ||||
|   |> close() | ||||
|   |> revolve({ axis = 'y' }, %)"# | ||||
|   |> revolve({ axis = Y }, %)"# | ||||
|     ); | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -88,6 +88,7 @@ pub(crate) fn read_std(mod_name: &str) -> Option<&'static str> { | ||||
|         "prelude" => Some(include_str!("../std/prelude.kcl")), | ||||
|         "math" => Some(include_str!("../std/math.kcl")), | ||||
|         "sketch" => Some(include_str!("../std/sketch.kcl")), | ||||
|         "turns" => Some(include_str!("../std/turns.kcl")), | ||||
|         _ => None, | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1609,19 +1609,21 @@ impl ImportStatement { | ||||
|             return Some(alias.name.clone()); | ||||
|         } | ||||
|  | ||||
|         let mut parts = match &self.path { | ||||
|             ImportPath::Kcl { filename: s } | ImportPath::Foreign { path: s } => s.split('.'), | ||||
|             _ => return None, | ||||
|         }; | ||||
|         let path = parts.next()?; | ||||
|         let _ext = parts.next()?; | ||||
|         let rest = parts.next(); | ||||
|         match &self.path { | ||||
|             ImportPath::Kcl { filename: s } | ImportPath::Foreign { path: s } => { | ||||
|                 let mut parts = s.split('.'); | ||||
|                 let path = parts.next()?; | ||||
|                 let _ext = parts.next()?; | ||||
|                 let rest = parts.next(); | ||||
|  | ||||
|         if rest.is_some() { | ||||
|             return None; | ||||
|                 if rest.is_some() { | ||||
|                     return None; | ||||
|                 } | ||||
|  | ||||
|                 path.rsplit(&['/', '\\']).next().map(str::to_owned) | ||||
|             } | ||||
|             ImportPath::Std { path } => path.last().cloned(), | ||||
|         } | ||||
|  | ||||
|         path.rsplit(&['/', '\\']).next().map(str::to_owned) | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -152,7 +152,12 @@ const STR_DEPRECATIONS: [(&str, &str); 6] = [ | ||||
|     ("-YZ", "-YZ"), | ||||
| ]; | ||||
| const FN_DEPRECATIONS: [(&str, &str); 3] = [("pi", "PI"), ("e", "E"), ("tau", "TAU")]; | ||||
| const CONST_DEPRECATIONS: [(&str, &str); 0] = []; | ||||
| const CONST_DEPRECATIONS: [(&str, &str); 4] = [ | ||||
|     ("ZERO", "turns::ZERO"), | ||||
|     ("QUARTER_TURN", "turns::QUARTER_TURN"), | ||||
|     ("HALF_TURN", "turns::HALF_TURN"), | ||||
|     ("THREE_QUARTER_TURN", "turns::THREE_QUARTER_TURN"), | ||||
| ]; | ||||
|  | ||||
| #[derive(Clone, Copy)] | ||||
| pub enum DeprecationKind { | ||||
|  | ||||
| @ -286,6 +286,11 @@ fn non_code_node(i: &mut TokenSlice) -> PResult<Node<NonCodeNode>> { | ||||
|     alt((non_code_node_leading_whitespace, non_code_node_no_leading_whitespace)).parse_next(i) | ||||
| } | ||||
|  | ||||
| fn outer_annotation(i: &mut TokenSlice) -> PResult<Node<Annotation>> { | ||||
|     peek((at_sign, open_paren)).parse_next(i)?; | ||||
|     annotation(i) | ||||
| } | ||||
|  | ||||
| fn annotation(i: &mut TokenSlice) -> PResult<Node<Annotation>> { | ||||
|     let at = at_sign.parse_next(i)?; | ||||
|     let name = opt(binding_name).parse_next(i)?; | ||||
| @ -1823,14 +1828,6 @@ fn import_stmt(i: &mut TokenSlice) -> PResult<BoxNode<ImportStatement>> { | ||||
|             ) | ||||
|             .into(), | ||||
|         )); | ||||
|     } else if matches!(path, ImportPath::Std { .. }) && matches!(selector, ImportSelector::None { .. }) { | ||||
|         return Err(ErrMode::Cut( | ||||
|             CompilationError::fatal( | ||||
|                 SourceRange::new(start, end, module_id), | ||||
|                 "the standard library cannot be imported as a part", | ||||
|             ) | ||||
|             .into(), | ||||
|         )); | ||||
|     } | ||||
|  | ||||
|     Ok(Node::boxed( | ||||
| @ -2910,13 +2907,17 @@ struct ParamDescription { | ||||
|     arg_name: Token, | ||||
|     type_: std::option::Option<Node<Type>>, | ||||
|     default_value: Option<DefaultParamVal>, | ||||
|     attr: Option<Node<Annotation>>, | ||||
|     comments: Option<Node<Vec<String>>>, | ||||
| } | ||||
|  | ||||
| fn parameter(i: &mut TokenSlice) -> PResult<ParamDescription> { | ||||
|     let (_, comments, found_at_sign, arg_name, question_mark, _, type_, _ws, default_literal) = ( | ||||
|     let (_, comments, _, attr, _, found_at_sign, arg_name, question_mark, _, type_, _ws, default_literal) = ( | ||||
|         opt(whitespace), | ||||
|         opt(comments), | ||||
|         opt(whitespace), | ||||
|         opt(outer_annotation), | ||||
|         opt(whitespace), | ||||
|         opt(at_sign), | ||||
|         any.verify(|token: &Token| !matches!(token.token_type, TokenType::Brace) || token.value != ")"), | ||||
|         opt(question_mark), | ||||
| @ -2941,6 +2942,7 @@ fn parameter(i: &mut TokenSlice) -> PResult<ParamDescription> { | ||||
|                 return Err(ErrMode::Backtrack(ContextError::from(e))); | ||||
|             } | ||||
|         }, | ||||
|         attr, | ||||
|         comments, | ||||
|     }) | ||||
| } | ||||
| @ -2962,6 +2964,7 @@ fn parameters(i: &mut TokenSlice) -> PResult<Vec<Parameter>> { | ||||
|                  arg_name, | ||||
|                  type_, | ||||
|                  default_value, | ||||
|                  attr, | ||||
|                  comments, | ||||
|              }| { | ||||
|                 let mut identifier = Node::<Identifier>::try_from(arg_name)?; | ||||
| @ -2969,6 +2972,9 @@ fn parameters(i: &mut TokenSlice) -> PResult<Vec<Parameter>> { | ||||
|                     identifier.comment_start = comments.start; | ||||
|                     identifier.pre_comments = comments.inner; | ||||
|                 } | ||||
|                 if let Some(attr) = attr { | ||||
|                     identifier.outer_attrs.push(attr); | ||||
|                 } | ||||
|  | ||||
|                 Ok(Parameter { | ||||
|                     identifier, | ||||
|  | ||||
| @ -75,7 +75,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal | ||||
| /// This will work on any solid, including extruded solids, revolved solids, and shelled solids. | ||||
| /// ```no_run | ||||
| /// // Add color to an extruded solid. | ||||
| /// exampleSketch = startSketchOn("XZ") | ||||
| /// exampleSketch = startSketchOn(XZ) | ||||
| ///   |> startProfileAt([0, 0], %) | ||||
| ///   |> line(endAbsolute = [10, 0]) | ||||
| ///   |> line(endAbsolute = [0, 10]) | ||||
| @ -89,9 +89,9 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal | ||||
| /// | ||||
| /// ```no_run | ||||
| /// // Add color to a revolved solid. | ||||
| /// sketch001 = startSketchOn('XY') | ||||
| /// sketch001 = startSketchOn(XY) | ||||
| ///     |> circle( center = [15, 0], radius = 5 ) | ||||
| ///     |> revolve( angle = 360, axis = 'y') | ||||
| ///     |> revolve( angle = 360, axis = Y) | ||||
| ///     |> appearance( | ||||
| ///         color = '#ff0000', | ||||
| ///         metalness = 90, | ||||
| @ -102,7 +102,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal | ||||
| /// ```no_run | ||||
| /// // Add color to different solids. | ||||
| /// fn cube(center) { | ||||
| ///    return startSketchOn('XY') | ||||
| ///    return startSketchOn(XY) | ||||
| ///    |> startProfileAt([center[0] - 10, center[1] - 10], %) | ||||
| ///    |> line(endAbsolute = [center[0] + 10, center[1] - 10]) | ||||
| ///     |> line(endAbsolute = [center[0] + 10, center[1] + 10]) | ||||
| @ -122,7 +122,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal | ||||
| /// ```no_run | ||||
| /// // You can set the appearance before or after you shell it will yield the same result. | ||||
| /// // This example shows setting the appearance _after_ the shell. | ||||
| /// firstSketch = startSketchOn('XY') | ||||
| /// firstSketch = startSketchOn(XY) | ||||
| ///     |> startProfileAt([-12, 12], %) | ||||
| ///     |> line(end = [24, 0]) | ||||
| ///     |> line(end = [0, -24]) | ||||
| @ -145,7 +145,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal | ||||
| /// ```no_run | ||||
| /// // You can set the appearance before or after you shell it will yield the same result. | ||||
| /// // This example shows setting the appearance _before_ the shell. | ||||
| /// firstSketch = startSketchOn('XY') | ||||
| /// firstSketch = startSketchOn(XY) | ||||
| ///     |> startProfileAt([-12, 12], %) | ||||
| ///     |> line(end = [24, 0]) | ||||
| ///     |> line(end = [0, -24]) | ||||
| @ -168,7 +168,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal | ||||
| /// ```no_run | ||||
| /// // Setting the appearance of a 3D pattern can be done _before_ or _after_ the pattern. | ||||
| /// // This example shows _before_ the pattern. | ||||
| /// exampleSketch = startSketchOn('XZ') | ||||
| /// exampleSketch = startSketchOn(XZ) | ||||
| ///   |> startProfileAt([0, 0], %) | ||||
| ///   |> line(end = [0, 2]) | ||||
| ///   |> line(end = [3, 1]) | ||||
| @ -191,7 +191,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal | ||||
| /// ```no_run | ||||
| /// // Setting the appearance of a 3D pattern can be done _before_ or _after_ the pattern. | ||||
| /// // This example shows _after_ the pattern. | ||||
| /// exampleSketch = startSketchOn('XZ') | ||||
| /// exampleSketch = startSketchOn(XZ) | ||||
| ///   |> startProfileAt([0, 0], %) | ||||
| ///   |> line(end = [0, 2]) | ||||
| ///   |> line(end = [3, 1]) | ||||
| @ -213,7 +213,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal | ||||
| /// | ||||
| /// ```no_run | ||||
| /// // Color the result of a 2D pattern that was extruded. | ||||
| /// exampleSketch = startSketchOn('XZ') | ||||
| /// exampleSketch = startSketchOn(XZ) | ||||
| ///   |> startProfileAt([.5, 25], %) | ||||
| ///   |> line(end = [0, 5]) | ||||
| ///   |> line(end = [-1, 0]) | ||||
| @ -238,7 +238,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal | ||||
| /// // Color the result of a sweep. | ||||
| /// | ||||
| /// // Create a path for the sweep. | ||||
| /// sweepPath = startSketchOn('XZ') | ||||
| /// sweepPath = startSketchOn(XZ) | ||||
| ///     |> startProfileAt([0.05, 0.05], %) | ||||
| ///     |> line(end = [0, 7]) | ||||
| ///     |> tangentialArc({ | ||||
| @ -252,13 +252,13 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal | ||||
| ///     }, %) | ||||
| ///     |> line(end = [0, 7]) | ||||
| /// | ||||
| /// pipeHole = startSketchOn('XY') | ||||
| /// pipeHole = startSketchOn(XY) | ||||
| ///     |> circle( | ||||
| ///         center = [0, 0], | ||||
| ///         radius = 1.5, | ||||
| ///     ) | ||||
| /// | ||||
| /// sweepSketch = startSketchOn('XY') | ||||
| /// sweepSketch = startSketchOn(XY) | ||||
| ///     |> circle( | ||||
| ///         center = [0, 0], | ||||
| ///         radius = 2, | ||||
|  | ||||
| @ -154,6 +154,22 @@ impl Args { | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     pub(crate) fn get_kw_arg_opt_typed<T>( | ||||
|         &self, | ||||
|         label: &str, | ||||
|         ty: &RuntimeType, | ||||
|         exec_state: &mut ExecState, | ||||
|     ) -> Result<Option<T>, KclError> | ||||
|     where | ||||
|         T: for<'a> FromKclValue<'a>, | ||||
|     { | ||||
|         if self.kw_args.labeled.get(label).is_none() { | ||||
|             return Ok(None); | ||||
|         }; | ||||
|  | ||||
|         self.get_kw_arg_typed(label, ty, exec_state).map(Some) | ||||
|     } | ||||
|  | ||||
|     /// Get a keyword argument. If not set, returns Err. | ||||
|     pub(crate) fn get_kw_arg<'a, T>(&'a self, label: &str) -> Result<T, KclError> | ||||
|     where | ||||
| @ -675,37 +691,6 @@ impl Args { | ||||
|         FromArgs::from_args(self, 0) | ||||
|     } | ||||
|  | ||||
|     pub(crate) fn get_data_and_sketches<'a, T>( | ||||
|         &'a self, | ||||
|         exec_state: &mut ExecState, | ||||
|     ) -> Result<(T, Vec<Sketch>), KclError> | ||||
|     where | ||||
|         T: serde::de::DeserializeOwned + FromArgs<'a>, | ||||
|     { | ||||
|         let data: T = FromArgs::from_args(self, 0)?; | ||||
|         let Some(arg1) = self.args.get(1) else { | ||||
|             return Err(KclError::Semantic(KclErrorDetails { | ||||
|                 message: "Expected one or more sketches for second argument".to_owned(), | ||||
|                 source_ranges: vec![self.source_range], | ||||
|             })); | ||||
|         }; | ||||
|         let sarg = arg1 | ||||
|             .value | ||||
|             .coerce(&RuntimeType::sketches(), exec_state) | ||||
|             .ok_or(KclError::Type(KclErrorDetails { | ||||
|                 message: format!( | ||||
|                     "Expected one or more sketches for second argument, found {}", | ||||
|                     arg1.value.human_friendly_type() | ||||
|                 ), | ||||
|                 source_ranges: vec![self.source_range], | ||||
|             }))?; | ||||
|         let sketches = match sarg { | ||||
|             KclValue::HomArray { value, .. } => value.iter().map(|v| v.as_sketch().unwrap().clone()).collect(), | ||||
|             _ => unreachable!(), | ||||
|         }; | ||||
|         Ok((data, sketches)) | ||||
|     } | ||||
|  | ||||
|     pub(crate) fn get_data_and_sketch_and_tag<'a, T>( | ||||
|         &'a self, | ||||
|         exec_state: &mut ExecState, | ||||
| @ -1583,50 +1568,6 @@ impl<'a> FromKclValue<'a> for super::sketch::SketchData { | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'a> FromKclValue<'a> for super::axis_or_reference::AxisAndOrigin2d { | ||||
|     fn from_kcl_val(arg: &'a KclValue) -> Option<Self> { | ||||
|         // Case 1: predefined planes. | ||||
|         if let Some(s) = arg.as_str() { | ||||
|             return match s { | ||||
|                 "X" | "x" => Some(Self::X), | ||||
|                 "Y" | "y" => Some(Self::Y), | ||||
|                 "-X" | "-x" => Some(Self::NegX), | ||||
|                 "-Y" | "-y" => Some(Self::NegY), | ||||
|                 _ => None, | ||||
|             }; | ||||
|         } | ||||
|         // Case 2: custom planes. | ||||
|         let obj = arg.as_object()?; | ||||
|         let_field_of!(obj, custom, &KclObjectFields); | ||||
|         let_field_of!(custom, origin); | ||||
|         let_field_of!(custom, axis); | ||||
|         Some(Self::Custom { axis, origin }) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'a> FromKclValue<'a> for super::axis_or_reference::AxisAndOrigin3d { | ||||
|     fn from_kcl_val(arg: &'a KclValue) -> Option<Self> { | ||||
|         // Case 1: predefined planes. | ||||
|         if let Some(s) = arg.as_str() { | ||||
|             return match s { | ||||
|                 "X" | "x" => Some(Self::X), | ||||
|                 "Y" | "y" => Some(Self::Y), | ||||
|                 "Z" | "z" => Some(Self::Z), | ||||
|                 "-X" | "-x" => Some(Self::NegX), | ||||
|                 "-Y" | "-y" => Some(Self::NegY), | ||||
|                 "-Z" | "-z" => Some(Self::NegZ), | ||||
|                 _ => None, | ||||
|             }; | ||||
|         } | ||||
|         // Case 2: custom planes. | ||||
|         let obj = arg.as_object()?; | ||||
|         let_field_of!(obj, custom, &KclObjectFields); | ||||
|         let_field_of!(custom, origin); | ||||
|         let_field_of!(custom, axis); | ||||
|         Some(Self::Custom { axis, origin }) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'a> FromKclValue<'a> for super::fillet::EdgeReference { | ||||
|     fn from_kcl_val(arg: &'a KclValue) -> Option<Self> { | ||||
|         let id = arg.as_uuid().map(Self::Uuid); | ||||
| @ -1637,25 +1578,27 @@ impl<'a> FromKclValue<'a> for super::fillet::EdgeReference { | ||||
|  | ||||
| impl<'a> FromKclValue<'a> for super::axis_or_reference::Axis2dOrEdgeReference { | ||||
|     fn from_kcl_val(arg: &'a KclValue) -> Option<Self> { | ||||
|         let case1 = super::axis_or_reference::AxisAndOrigin2d::from_kcl_val; | ||||
|         let case1 = |arg: &KclValue| { | ||||
|             let obj = arg.as_object()?; | ||||
|             let_field_of!(obj, direction); | ||||
|             let_field_of!(obj, origin); | ||||
|             Some(Self::Axis { direction, origin }) | ||||
|         }; | ||||
|         let case2 = super::fillet::EdgeReference::from_kcl_val; | ||||
|         case1(arg).map(Self::Axis).or_else(|| case2(arg).map(Self::Edge)) | ||||
|         case1(arg).or_else(|| case2(arg).map(Self::Edge)) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'a> FromKclValue<'a> for super::axis_or_reference::Axis3dOrEdgeReference { | ||||
|     fn from_kcl_val(arg: &'a KclValue) -> Option<Self> { | ||||
|         let case1 = super::axis_or_reference::AxisAndOrigin3d::from_kcl_val; | ||||
|         let case1 = |arg: &KclValue| { | ||||
|             let obj = arg.as_object()?; | ||||
|             let_field_of!(obj, direction); | ||||
|             let_field_of!(obj, origin); | ||||
|             Some(Self::Axis { direction, origin }) | ||||
|         }; | ||||
|         let case2 = super::fillet::EdgeReference::from_kcl_val; | ||||
|         case1(arg).map(Self::Axis).or_else(|| case2(arg).map(Self::Edge)) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'a> FromKclValue<'a> for super::mirror::Mirror2dData { | ||||
|     fn from_kcl_val(arg: &'a KclValue) -> Option<Self> { | ||||
|         let obj = arg.as_object()?; | ||||
|         let_field_of!(obj, axis); | ||||
|         Some(Self { axis }) | ||||
|         case1(arg).or_else(|| case2(arg).map(Self::Edge)) | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -1,233 +1,21 @@ | ||||
| //! Types for referencing an axis or edge. | ||||
|  | ||||
| use anyhow::Result; | ||||
| use kcmc::length_unit::LengthUnit; | ||||
| use kittycad_modeling_cmds::{self as kcmc}; | ||||
| use schemars::JsonSchema; | ||||
| use serde::{Deserialize, Serialize}; | ||||
|  | ||||
| use crate::{errors::KclError, std::fillet::EdgeReference}; | ||||
| use crate::std::fillet::EdgeReference; | ||||
|  | ||||
| /// A 2D axis or tagged edge. | ||||
| #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] | ||||
| #[ts(export)] | ||||
| #[serde(untagged)] | ||||
| #[derive(Debug, Clone, PartialEq)] | ||||
| pub enum Axis2dOrEdgeReference { | ||||
|     /// 2D axis and origin. | ||||
|     Axis(AxisAndOrigin2d), | ||||
|     Axis { direction: [f64; 2], origin: [f64; 2] }, | ||||
|     /// Tagged edge. | ||||
|     Edge(EdgeReference), | ||||
| } | ||||
|  | ||||
| /// A 2D axis and origin. | ||||
| #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] | ||||
| #[ts(export)] | ||||
| #[serde(rename_all = "camelCase")] | ||||
| pub enum AxisAndOrigin2d { | ||||
|     /// X-axis. | ||||
|     #[serde(rename = "X", alias = "x")] | ||||
|     X, | ||||
|     /// Y-axis. | ||||
|     #[serde(rename = "Y", alias = "y")] | ||||
|     Y, | ||||
|     /// Flip the X-axis. | ||||
|     #[serde(rename = "-X", alias = "-x")] | ||||
|     NegX, | ||||
|     /// Flip the Y-axis. | ||||
|     #[serde(rename = "-Y", alias = "-y")] | ||||
|     NegY, | ||||
|     Custom { | ||||
|         /// The axis. | ||||
|         axis: [f64; 2], | ||||
|         /// The origin. | ||||
|         origin: [f64; 2], | ||||
|     }, | ||||
| } | ||||
|  | ||||
| impl AxisAndOrigin2d { | ||||
|     /// Get the axis and origin. | ||||
|     pub fn axis_and_origin(&self) -> Result<(kcmc::shared::Point3d<f64>, kcmc::shared::Point3d<LengthUnit>), KclError> { | ||||
|         let (axis, origin) = match self { | ||||
|             AxisAndOrigin2d::X => ([1.0, 0.0, 0.0], [0.0, 0.0, 0.0]), | ||||
|             AxisAndOrigin2d::Y => ([0.0, 1.0, 0.0], [0.0, 0.0, 0.0]), | ||||
|             AxisAndOrigin2d::NegX => ([-1.0, 0.0, 0.0], [0.0, 0.0, 0.0]), | ||||
|             AxisAndOrigin2d::NegY => ([0.0, -1.0, 0.0], [0.0, 0.0, 0.0]), | ||||
|             AxisAndOrigin2d::Custom { axis, origin } => ([axis[0], axis[1], 0.0], [origin[0], origin[1], 0.0]), | ||||
|         }; | ||||
|  | ||||
|         Ok(( | ||||
|             kcmc::shared::Point3d { | ||||
|                 x: axis[0], | ||||
|                 y: axis[1], | ||||
|                 z: axis[2], | ||||
|             }, | ||||
|             kcmc::shared::Point3d { | ||||
|                 x: LengthUnit(origin[0]), | ||||
|                 y: LengthUnit(origin[1]), | ||||
|                 z: LengthUnit(origin[2]), | ||||
|             }, | ||||
|         )) | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// A 3D axis or tagged edge. | ||||
| #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] | ||||
| #[ts(export)] | ||||
| #[serde(untagged)] | ||||
| #[derive(Debug, Clone, PartialEq)] | ||||
| pub enum Axis3dOrEdgeReference { | ||||
|     /// 3D axis and origin. | ||||
|     Axis(AxisAndOrigin3d), | ||||
|     Axis { direction: [f64; 3], origin: [f64; 3] }, | ||||
|     /// Tagged edge. | ||||
|     Edge(EdgeReference), | ||||
| } | ||||
|  | ||||
| /// A 3D axis and origin. | ||||
| #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] | ||||
| #[ts(export)] | ||||
| #[serde(rename_all = "camelCase")] | ||||
| pub enum AxisAndOrigin3d { | ||||
|     /// X-axis. | ||||
|     #[serde(rename = "X", alias = "x")] | ||||
|     X, | ||||
|     /// Y-axis. | ||||
|     #[serde(rename = "Y", alias = "y")] | ||||
|     Y, | ||||
|     /// Z-axis. | ||||
|     #[serde(rename = "Z", alias = "z")] | ||||
|     Z, | ||||
|     /// Flip the X-axis. | ||||
|     #[serde(rename = "-X", alias = "-x")] | ||||
|     NegX, | ||||
|     /// Flip the Y-axis. | ||||
|     #[serde(rename = "-Y", alias = "-y")] | ||||
|     NegY, | ||||
|     /// Flip the Z-axis. | ||||
|     #[serde(rename = "-Z", alias = "-z")] | ||||
|     NegZ, | ||||
|     Custom { | ||||
|         /// The axis. | ||||
|         axis: [f64; 3], | ||||
|         /// The origin. | ||||
|         origin: [f64; 3], | ||||
|     }, | ||||
| } | ||||
|  | ||||
| impl AxisAndOrigin3d { | ||||
|     /// Get the axis and origin. | ||||
|     pub fn axis_and_origin(&self) -> Result<(kcmc::shared::Point3d<f64>, kcmc::shared::Point3d<LengthUnit>), KclError> { | ||||
|         let (axis, origin) = match self { | ||||
|             AxisAndOrigin3d::X => ([1.0, 0.0, 0.0], [0.0, 0.0, 0.0]), | ||||
|             AxisAndOrigin3d::Y => ([0.0, 1.0, 0.0], [0.0, 0.0, 0.0]), | ||||
|             AxisAndOrigin3d::Z => ([0.0, 0.0, 1.0], [0.0, 0.0, 0.0]), | ||||
|             AxisAndOrigin3d::NegX => ([-1.0, 0.0, 0.0], [0.0, 0.0, 0.0]), | ||||
|             AxisAndOrigin3d::NegY => ([0.0, -1.0, 0.0], [0.0, 0.0, 0.0]), | ||||
|             AxisAndOrigin3d::NegZ => ([0.0, 0.0, -1.0], [0.0, 0.0, 0.0]), | ||||
|             AxisAndOrigin3d::Custom { axis, origin } => { | ||||
|                 ([axis[0], axis[1], axis[2]], [origin[0], origin[1], origin[2]]) | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         Ok(( | ||||
|             kcmc::shared::Point3d { | ||||
|                 x: axis[0], | ||||
|                 y: axis[1], | ||||
|                 z: axis[2], | ||||
|             }, | ||||
|             kcmc::shared::Point3d { | ||||
|                 x: LengthUnit(origin[0]), | ||||
|                 y: LengthUnit(origin[1]), | ||||
|                 z: LengthUnit(origin[2]), | ||||
|             }, | ||||
|         )) | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|  | ||||
|     use pretty_assertions::assert_eq; | ||||
|  | ||||
|     use crate::std::axis_or_reference::{ | ||||
|         Axis2dOrEdgeReference, Axis3dOrEdgeReference, AxisAndOrigin2d, AxisAndOrigin3d, | ||||
|     }; | ||||
|  | ||||
|     #[test] | ||||
|     fn test_deserialize_revolve_axis_2d() { | ||||
|         let data = Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::X); | ||||
|         let mut str_json = serde_json::to_string(&data).unwrap(); | ||||
|         assert_eq!(str_json, "\"X\""); | ||||
|  | ||||
|         str_json = "\"Y\"".to_string(); | ||||
|         let data: Axis2dOrEdgeReference = serde_json::from_str(&str_json).unwrap(); | ||||
|         assert_eq!(data, Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::Y)); | ||||
|  | ||||
|         str_json = "\"-Y\"".to_string(); | ||||
|         let data: Axis2dOrEdgeReference = serde_json::from_str(&str_json).unwrap(); | ||||
|         assert_eq!(data, Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::NegY)); | ||||
|  | ||||
|         str_json = "\"-x\"".to_string(); | ||||
|         let data: Axis2dOrEdgeReference = serde_json::from_str(&str_json).unwrap(); | ||||
|         assert_eq!(data, Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::NegX)); | ||||
|  | ||||
|         let data = Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::Custom { | ||||
|             axis: [0.0, -1.0], | ||||
|             origin: [1.0, 0.0], | ||||
|         }); | ||||
|         str_json = serde_json::to_string(&data).unwrap(); | ||||
|         assert_eq!(str_json, r#"{"custom":{"axis":[0.0,-1.0],"origin":[1.0,0.0]}}"#); | ||||
|  | ||||
|         str_json = r#"{"custom": {"axis": [0,-1], "origin": [1,2.0]}}"#.to_string(); | ||||
|         let data: Axis2dOrEdgeReference = serde_json::from_str(&str_json).unwrap(); | ||||
|         assert_eq!( | ||||
|             data, | ||||
|             Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::Custom { | ||||
|                 axis: [0.0, -1.0], | ||||
|                 origin: [1.0, 2.0] | ||||
|             }) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     fn test_deserialize_revolve_axis_3d() { | ||||
|         let data = Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::X); | ||||
|         let mut str_json = serde_json::to_string(&data).unwrap(); | ||||
|         assert_eq!(str_json, "\"X\""); | ||||
|  | ||||
|         str_json = "\"Y\"".to_string(); | ||||
|         let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap(); | ||||
|         assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::Y)); | ||||
|  | ||||
|         str_json = "\"Z\"".to_string(); | ||||
|         let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap(); | ||||
|         assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::Z)); | ||||
|  | ||||
|         str_json = "\"-Y\"".to_string(); | ||||
|         let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap(); | ||||
|         assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::NegY)); | ||||
|  | ||||
|         str_json = "\"-x\"".to_string(); | ||||
|         let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap(); | ||||
|         assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::NegX)); | ||||
|  | ||||
|         str_json = "\"-z\"".to_string(); | ||||
|         let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap(); | ||||
|         assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::NegZ)); | ||||
|  | ||||
|         let data = Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::Custom { | ||||
|             axis: [0.0, -1.0, 0.0], | ||||
|             origin: [1.0, 0.0, 0.0], | ||||
|         }); | ||||
|         str_json = serde_json::to_string(&data).unwrap(); | ||||
|         assert_eq!(str_json, r#"{"custom":{"axis":[0.0,-1.0,0.0],"origin":[1.0,0.0,0.0]}}"#); | ||||
|  | ||||
|         str_json = r#"{"custom": {"axis": [0,-1,0], "origin": [1,2.0,0]}}"#.to_string(); | ||||
|         let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap(); | ||||
|         assert_eq!( | ||||
|             data, | ||||
|             Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::Custom { | ||||
|                 axis: [0.0, -1.0, 0.0], | ||||
|                 origin: [1.0, 2.0, 0.0] | ||||
|             }) | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,13 +1,15 @@ | ||||
| //! Standard library helices. | ||||
|  | ||||
| use anyhow::Result; | ||||
| use kcl_derive_docs::stdlib; | ||||
| use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, ModelingCmd}; | ||||
| use kittycad_modeling_cmds as kcmc; | ||||
| use kittycad_modeling_cmds::{self as kcmc, shared::Point3d}; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::KclError, | ||||
|     execution::{ExecState, Helix as HelixValue, KclValue, Solid}, | ||||
|     execution::{ | ||||
|         types::{PrimitiveType, RuntimeType}, | ||||
|         ExecState, Helix as HelixValue, KclValue, Solid, | ||||
|     }, | ||||
|     std::{axis_or_reference::Axis3dOrEdgeReference, Args}, | ||||
| }; | ||||
|  | ||||
| @ -17,7 +19,14 @@ pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K | ||||
|     let revolutions = args.get_kw_arg("revolutions")?; | ||||
|     let ccw = args.get_kw_arg_opt("ccw")?; | ||||
|     let radius = args.get_kw_arg_opt("radius")?; | ||||
|     let axis = args.get_kw_arg_opt("axis")?; | ||||
|     let axis: Option<Axis3dOrEdgeReference> = args.get_kw_arg_opt_typed( | ||||
|         "axis", | ||||
|         &RuntimeType::Union(vec![ | ||||
|             RuntimeType::Primitive(PrimitiveType::Edge), | ||||
|             RuntimeType::Primitive(PrimitiveType::Axis3d), | ||||
|         ]), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let length = args.get_kw_arg_opt("length")?; | ||||
|     let cylinder = args.get_kw_arg_opt("cylinder")?; | ||||
|  | ||||
| @ -84,100 +93,6 @@ pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K | ||||
|     Ok(KclValue::Helix { value }) | ||||
| } | ||||
|  | ||||
| /// Create a helix. | ||||
| /// | ||||
| /// ```no_run | ||||
| /// // Create a helix around the Z axis. | ||||
| /// helixPath = helix( | ||||
| ///     angleStart = 0, | ||||
| ///     ccw = true, | ||||
| ///     revolutions = 5, | ||||
| ///     length = 10, | ||||
| ///     radius = 5, | ||||
| ///     axis = 'Z', | ||||
| ///  ) | ||||
| /// | ||||
| /// | ||||
| /// // Create a spring by sweeping around the helix path. | ||||
| /// springSketch = startSketchOn('YZ') | ||||
| ///     |> circle( center = [0, 0], radius = 0.5) | ||||
| ///     |> sweep(path = helixPath) | ||||
| /// ``` | ||||
| /// | ||||
| /// ```no_run | ||||
| /// // Create a helix around an edge. | ||||
| /// helper001 = startSketchOn('XZ') | ||||
| ///  |> startProfileAt([0, 0], %) | ||||
| ///  |> line(end = [0, 10], tag = $edge001) | ||||
| /// | ||||
| /// helixPath = helix( | ||||
| ///     angleStart = 0, | ||||
| ///     ccw = true, | ||||
| ///     revolutions = 5, | ||||
| ///     length = 10, | ||||
| ///     radius = 5, | ||||
| ///     axis = edge001, | ||||
| ///  ) | ||||
| /// | ||||
| /// // Create a spring by sweeping around the helix path. | ||||
| /// springSketch = startSketchOn('XY') | ||||
| ///     |> circle( center = [0, 0], radius = 0.5 ) | ||||
| ///     |> sweep(path = helixPath) | ||||
| /// ``` | ||||
| /// | ||||
| /// ```no_run | ||||
| /// // Create a helix around a custom axis. | ||||
| /// helixPath = helix( | ||||
| ///     angleStart = 0, | ||||
| ///     ccw = true, | ||||
| ///     revolutions = 5, | ||||
| ///     length = 10, | ||||
| ///     radius = 5, | ||||
| ///     axis = { | ||||
| ///         custom = { | ||||
| ///             axis = [0, 0, 1.0], | ||||
| ///             origin = [0, 0.25, 0] | ||||
| ///             } | ||||
| ///         } | ||||
| ///  ) | ||||
| /// | ||||
| /// // Create a spring by sweeping around the helix path. | ||||
| /// springSketch = startSketchOn('XY') | ||||
| ///     |> circle( center = [0, 0], radius = 1 ) | ||||
| ///     |> sweep(path = helixPath) | ||||
| /// ``` | ||||
| /// | ||||
| /// | ||||
| /// | ||||
| /// ```no_run | ||||
| /// // Create a helix on a cylinder. | ||||
| /// | ||||
| /// part001 = startSketchOn('XY') | ||||
| ///   |> circle( center= [5, 5], radius= 10 ) | ||||
| ///   |> extrude(length = 10) | ||||
| /// | ||||
| /// helix( | ||||
| ///     angleStart = 0, | ||||
| ///     ccw = true, | ||||
| ///     revolutions = 16, | ||||
| ///     cylinder = part001, | ||||
| ///  ) | ||||
| /// ``` | ||||
| #[stdlib { | ||||
|     name = "helix", | ||||
|     keywords = true, | ||||
|     unlabeled_first = false, | ||||
|     args = { | ||||
|         revolutions = { docs = "Number of revolutions."}, | ||||
|         angle_start = { docs = "Start angle (in degrees)."}, | ||||
|         ccw = { docs = "Is the helix rotation counter clockwise? The default is `false`.", include_in_snippet = false}, | ||||
|         radius = { docs = "Radius of the helix.", include_in_snippet = true}, | ||||
|         axis = { docs = "Axis to use for the helix.", include_in_snippet = true}, | ||||
|         length = { docs = "Length of the helix. This is not necessary if the helix is created around an edge. If not given the length of the edge is used.", include_in_snippet = true}, | ||||
|         cylinder = { docs = "Cylinder to create the helix on.", include_in_snippet = false}, | ||||
|     }, | ||||
|     feature_tree_operation = true, | ||||
| }] | ||||
| #[allow(clippy::too_many_arguments)] | ||||
| async fn inner_helix( | ||||
|     revolutions: f64, | ||||
| @ -221,9 +136,7 @@ async fn inner_helix( | ||||
|         .await?; | ||||
|     } else if let (Some(axis), Some(radius)) = (axis, radius) { | ||||
|         match axis { | ||||
|             Axis3dOrEdgeReference::Axis(axis) => { | ||||
|                 let (axis, origin) = axis.axis_and_origin()?; | ||||
|  | ||||
|             Axis3dOrEdgeReference::Axis { direction, origin } => { | ||||
|                 // Make sure they gave us a length. | ||||
|                 let Some(length) = length else { | ||||
|                     return Err(KclError::Semantic(crate::errors::KclErrorDetails { | ||||
| @ -240,8 +153,16 @@ async fn inner_helix( | ||||
|                         length: LengthUnit(length), | ||||
|                         revolutions, | ||||
|                         start_angle: Angle::from_degrees(angle_start), | ||||
|                         axis, | ||||
|                         center: origin, | ||||
|                         axis: Point3d { | ||||
|                             x: direction[0], | ||||
|                             y: direction[1], | ||||
|                             z: direction[2], | ||||
|                         }, | ||||
|                         center: Point3d { | ||||
|                             x: LengthUnit(origin[0]), | ||||
|                             y: LengthUnit(origin[1]), | ||||
|                             z: LengthUnit(origin[2]), | ||||
|                         }, | ||||
|                     }), | ||||
|                 ) | ||||
|                 .await?; | ||||
|  | ||||
| @ -1,109 +1,39 @@ | ||||
| //! Standard library mirror. | ||||
|  | ||||
| use anyhow::Result; | ||||
| use kcl_derive_docs::stdlib; | ||||
| use kcmc::{each_cmd as mcmd, ModelingCmd}; | ||||
| use kittycad_modeling_cmds::{self as kcmc}; | ||||
| use schemars::JsonSchema; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use kittycad_modeling_cmds::{self as kcmc, length_unit::LengthUnit, shared::Point3d}; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::KclError, | ||||
|     execution::{ExecState, KclValue, Sketch}, | ||||
|     execution::{ | ||||
|         types::{PrimitiveType, RuntimeType}, | ||||
|         ExecState, KclValue, Sketch, | ||||
|     }, | ||||
|     std::{axis_or_reference::Axis2dOrEdgeReference, Args}, | ||||
| }; | ||||
|  | ||||
| /// Data for a mirror. | ||||
| #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] | ||||
| #[ts(export)] | ||||
| #[serde(rename_all = "camelCase")] | ||||
| pub struct Mirror2dData { | ||||
|     /// Axis to use as mirror. | ||||
|     pub axis: Axis2dOrEdgeReference, | ||||
| } | ||||
|  | ||||
| /// Mirror a sketch. | ||||
| /// | ||||
| /// Only works on unclosed sketches for now. | ||||
| pub async fn mirror_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let (data, sketch_set): (Mirror2dData, Vec<Sketch>) = args.get_data_and_sketches(exec_state)?; | ||||
|     let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?; | ||||
|     let axis = args.get_kw_arg_typed( | ||||
|         "axis", | ||||
|         &RuntimeType::Union(vec![ | ||||
|             RuntimeType::Primitive(PrimitiveType::Edge), | ||||
|             RuntimeType::Primitive(PrimitiveType::Axis2d), | ||||
|         ]), | ||||
|         exec_state, | ||||
|     )?; | ||||
|  | ||||
|     let sketches = inner_mirror_2d(data, sketch_set, exec_state, args).await?; | ||||
|     let sketches = inner_mirror_2d(sketches, axis, exec_state, args).await?; | ||||
|     Ok(sketches.into()) | ||||
| } | ||||
|  | ||||
| /// Mirror a sketch. | ||||
| /// | ||||
| /// Only works on unclosed sketches for now. | ||||
| /// | ||||
| /// Mirror occurs around a local sketch axis rather than a global axis. | ||||
| /// | ||||
| /// ```no_run | ||||
| /// // Mirror an un-closed sketch across the Y axis. | ||||
| /// sketch001 = startSketchOn('XZ') | ||||
| ///     |> startProfileAt([0, 10], %) | ||||
| ///     |> line(end = [15, 0]) | ||||
| ///     |> line(end = [-7, -3]) | ||||
| ///     |> line(end = [9, -1]) | ||||
| ///     |> line(end = [-8, -5]) | ||||
| ///     |> line(end = [9, -3]) | ||||
| ///     |> line(end = [-8, -3]) | ||||
| ///     |> line(end = [9, -1]) | ||||
| ///     |> line(end = [-19, -0]) | ||||
| ///     |> mirror2d({axis = 'Y'}, %) | ||||
| /// | ||||
| /// example = extrude(sketch001, length = 10) | ||||
| /// ``` | ||||
| /// | ||||
| /// ```no_run | ||||
| /// // Mirror a un-closed sketch across the Y axis. | ||||
| /// sketch001 = startSketchOn('XZ') | ||||
| ///     |> startProfileAt([0, 8.5], %) | ||||
| ///     |> line(end = [20, -8.5]) | ||||
| ///     |> line(end = [-20, -8.5]) | ||||
| ///     |> mirror2d({axis = 'Y'}, %) | ||||
| /// | ||||
| /// example = extrude(sketch001, length = 10) | ||||
| /// ``` | ||||
| /// | ||||
| /// ```no_run | ||||
| /// // Mirror a un-closed sketch across an edge. | ||||
| /// helper001 = startSketchOn('XZ') | ||||
| ///  |> startProfileAt([0, 0], %) | ||||
| ///  |> line(end = [0, 10], tag = $edge001) | ||||
| /// | ||||
| /// sketch001 = startSketchOn('XZ') | ||||
| ///     |> startProfileAt([0, 8.5], %) | ||||
| ///     |> line(end = [20, -8.5]) | ||||
| ///     |> line(end = [-20, -8.5]) | ||||
| ///     |> mirror2d({axis = edge001}, %) | ||||
| /// | ||||
| /// // example = extrude(sketch001, length = 10) | ||||
| /// ``` | ||||
| /// | ||||
| /// ```no_run | ||||
| /// // Mirror an un-closed sketch across a custom axis. | ||||
| /// sketch001 = startSketchOn('XZ') | ||||
| ///     |> startProfileAt([0, 8.5], %) | ||||
| ///     |> line(end = [20, -8.5]) | ||||
| ///     |> line(end = [-20, -8.5]) | ||||
| ///     |> mirror2d({ | ||||
| ///   axis = { | ||||
| ///     custom = { | ||||
| ///       axis = [0.0, 1.0], | ||||
| ///       origin = [0.0, 0.0] | ||||
| ///     } | ||||
| ///   } | ||||
| /// }, %) | ||||
| /// | ||||
| /// example = extrude(sketch001, length = 10) | ||||
| /// ``` | ||||
| #[stdlib { | ||||
|     name = "mirror2d", | ||||
| }] | ||||
| async fn inner_mirror_2d( | ||||
|     data: Mirror2dData, | ||||
|     sketches: Vec<Sketch>, | ||||
|     axis: Axis2dOrEdgeReference, | ||||
|     exec_state: &mut ExecState, | ||||
|     args: Args, | ||||
| ) -> Result<Vec<Sketch>, KclError> { | ||||
| @ -113,16 +43,22 @@ async fn inner_mirror_2d( | ||||
|         return Ok(starting_sketches); | ||||
|     } | ||||
|  | ||||
|     match data.axis { | ||||
|         Axis2dOrEdgeReference::Axis(axis) => { | ||||
|             let (axis, origin) = axis.axis_and_origin()?; | ||||
|  | ||||
|     match axis { | ||||
|         Axis2dOrEdgeReference::Axis { direction, origin } => { | ||||
|             args.batch_modeling_cmd( | ||||
|                 exec_state.next_uuid(), | ||||
|                 ModelingCmd::from(mcmd::EntityMirror { | ||||
|                     ids: starting_sketches.iter().map(|sketch| sketch.id).collect(), | ||||
|                     axis, | ||||
|                     point: origin, | ||||
|                     axis: Point3d { | ||||
|                         x: direction[0], | ||||
|                         y: direction[1], | ||||
|                         z: 0.0, | ||||
|                     }, | ||||
|                     point: Point3d { | ||||
|                         x: LengthUnit(origin[0]), | ||||
|                         y: LengthUnit(origin[1]), | ||||
|                         z: LengthUnit(0.0), | ||||
|                     }, | ||||
|                 }), | ||||
|             ) | ||||
|             .await?; | ||||
|  | ||||
| @ -26,7 +26,6 @@ pub mod shell; | ||||
| pub mod sketch; | ||||
| pub mod sweep; | ||||
| pub mod transform; | ||||
| pub mod types; | ||||
| pub mod units; | ||||
| pub mod utils; | ||||
|  | ||||
| @ -96,7 +95,6 @@ lazy_static! { | ||||
|         Box::new(crate::std::sketch::TangentialArcToRelative), | ||||
|         Box::new(crate::std::sketch::BezierCurve), | ||||
|         Box::new(crate::std::sketch::Hole), | ||||
|         Box::new(crate::std::mirror::Mirror2D), | ||||
|         Box::new(crate::std::patterns::PatternLinear2D), | ||||
|         Box::new(crate::std::patterns::PatternLinear3D), | ||||
|         Box::new(crate::std::patterns::PatternCircular2D), | ||||
| @ -113,10 +111,8 @@ lazy_static! { | ||||
|         Box::new(crate::std::edge::GetNextAdjacentEdge), | ||||
|         Box::new(crate::std::edge::GetPreviousAdjacentEdge), | ||||
|         Box::new(crate::std::edge::GetCommonEdge), | ||||
|         Box::new(crate::std::helix::Helix), | ||||
|         Box::new(crate::std::shell::Shell), | ||||
|         Box::new(crate::std::shell::Hollow), | ||||
|         Box::new(crate::std::revolve::Revolve), | ||||
|         Box::new(crate::std::sweep::Sweep), | ||||
|         Box::new(crate::std::loft::Loft), | ||||
|         Box::new(crate::std::planes::OffsetPlane), | ||||
| @ -177,6 +173,7 @@ pub fn get_stdlib_fn(name: &str) -> Option<Box<dyn StdLibFn>> { | ||||
| pub struct StdFnProps { | ||||
|     pub name: String, | ||||
|     pub deprecated: bool, | ||||
|     pub include_in_feature_tree: bool, | ||||
| } | ||||
|  | ||||
| impl StdFnProps { | ||||
| @ -184,8 +181,14 @@ impl StdFnProps { | ||||
|         Self { | ||||
|             name: name.to_owned(), | ||||
|             deprecated: false, | ||||
|             include_in_feature_tree: false, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn include_in_feature_tree(mut self) -> Self { | ||||
|         self.include_in_feature_tree = true; | ||||
|         self | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub(crate) fn std_fn(path: &str, fn_name: &str) -> (crate::std::StdFn, StdFnProps) { | ||||
| @ -206,6 +209,18 @@ pub(crate) fn std_fn(path: &str, fn_name: &str) -> (crate::std::StdFn, StdFnProp | ||||
|             |e, a| Box::pin(crate::std::shapes::circle(e, a)), | ||||
|             StdFnProps::default("std::sketch::circle"), | ||||
|         ), | ||||
|         ("prelude", "helix") => ( | ||||
|             |e, a| Box::pin(crate::std::helix::helix(e, a)), | ||||
|             StdFnProps::default("std::helix").include_in_feature_tree(), | ||||
|         ), | ||||
|         ("sketch", "mirror2d") => ( | ||||
|             |e, a| Box::pin(crate::std::mirror::mirror_2d(e, a)), | ||||
|             StdFnProps::default("std::sketch::mirror2d"), | ||||
|         ), | ||||
|         ("prelude", "revolve") => ( | ||||
|             |e, a| Box::pin(crate::std::revolve::revolve(e, a)), | ||||
|             StdFnProps::default("std::revolve").include_in_feature_tree(), | ||||
|         ), | ||||
|         _ => unreachable!(), | ||||
|     } | ||||
| } | ||||
| @ -217,6 +232,9 @@ pub(crate) fn std_ty(path: &str, fn_name: &str) -> (PrimitiveType, StdFnProps) { | ||||
|         ("prelude", "Plane") => (PrimitiveType::Plane, StdFnProps::default("std::Plane")), | ||||
|         ("prelude", "Face") => (PrimitiveType::Face, StdFnProps::default("std::Face")), | ||||
|         ("prelude", "Helix") => (PrimitiveType::Helix, StdFnProps::default("std::Helix")), | ||||
|         ("prelude", "Edge") => (PrimitiveType::Edge, StdFnProps::default("std::Edge")), | ||||
|         ("prelude", "Axis2d") => (PrimitiveType::Axis2d, StdFnProps::default("std::Axis2d")), | ||||
|         ("prelude", "Axis3d") => (PrimitiveType::Axis3d, StdFnProps::default("std::Axis3d")), | ||||
|         _ => unreachable!(), | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,13 +1,15 @@ | ||||
| //! Standard library revolution surfaces. | ||||
|  | ||||
| use anyhow::Result; | ||||
| use kcl_derive_docs::stdlib; | ||||
| use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, ModelingCmd}; | ||||
| use kittycad_modeling_cmds::{self as kcmc}; | ||||
| use kittycad_modeling_cmds::{self as kcmc, shared::Point3d}; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{types::RuntimeType, ExecState, KclValue, Sketch, Solid}, | ||||
|     execution::{ | ||||
|         types::{PrimitiveType, RuntimeType}, | ||||
|         ExecState, KclValue, Sketch, Solid, | ||||
|     }, | ||||
|     parsing::ast::types::TagNode, | ||||
|     std::{axis_or_reference::Axis2dOrEdgeReference, extrude::do_post_extrude, fillet::default_tolerance, Args}, | ||||
| }; | ||||
| @ -15,7 +17,14 @@ use crate::{ | ||||
| /// Revolve a sketch or set of sketches around an axis. | ||||
| pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?; | ||||
|     let axis: Axis2dOrEdgeReference = args.get_kw_arg("axis")?; | ||||
|     let axis = args.get_kw_arg_typed( | ||||
|         "axis", | ||||
|         &RuntimeType::Union(vec![ | ||||
|             RuntimeType::Primitive(PrimitiveType::Edge), | ||||
|             RuntimeType::Primitive(PrimitiveType::Axis2d), | ||||
|         ]), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let angle = args.get_kw_arg_opt("angle")?; | ||||
|     let tolerance = args.get_kw_arg_opt("tolerance")?; | ||||
|     let tag_start = args.get_kw_arg_opt("tagStart")?; | ||||
| @ -25,215 +34,6 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
|     Ok(value.into()) | ||||
| } | ||||
|  | ||||
| /// Rotate a sketch around some provided axis, creating a solid from its extent. | ||||
| /// | ||||
| /// This, like extrude, is able to create a 3-dimensional solid from a | ||||
| /// 2-dimensional sketch. However, unlike extrude, this creates a solid | ||||
| /// by using the extent of the sketch as its revolved around an axis rather | ||||
| /// than using the extent of the sketch linearly translated through a third | ||||
| /// dimension. | ||||
| /// | ||||
| /// Revolve occurs around a local sketch axis rather than a global axis. | ||||
| /// | ||||
| /// You can provide more than one sketch to revolve, and they will all be | ||||
| /// revolved around the same axis. | ||||
| /// | ||||
| /// ```no_run | ||||
| /// part001 = startSketchOn('XY') | ||||
| ///     |> startProfileAt([4, 12], %) | ||||
| ///     |> line(end = [2, 0]) | ||||
| ///     |> line(end = [0, -6]) | ||||
| ///     |> line(end = [4, -6]) | ||||
| ///     |> line(end = [0, -6]) | ||||
| ///     |> line(end = [-3.75, -4.5]) | ||||
| ///     |> line(end = [0, -5.5]) | ||||
| ///     |> line(end = [-2, 0]) | ||||
| ///     |> close() | ||||
| ///     |> revolve(axis = 'y') // default angle is 360 | ||||
| /// ``` | ||||
| /// | ||||
| /// ```no_run | ||||
| /// // A donut shape. | ||||
| /// sketch001 = startSketchOn('XY') | ||||
| ///     |> circle( center = [15, 0], radius = 5 ) | ||||
| ///     |> revolve( | ||||
| ///         angle = 360, | ||||
| ///         axis = 'y' | ||||
| ///     ) | ||||
| /// ``` | ||||
| /// | ||||
| /// ```no_run | ||||
| /// part001 = startSketchOn('XY') | ||||
| ///     |> startProfileAt([4, 12], %) | ||||
| ///     |> line(end = [2, 0]) | ||||
| ///     |> line(end = [0, -6]) | ||||
| ///     |> line(end = [4, -6]) | ||||
| ///     |> line(end = [0, -6]) | ||||
| ///     |> line(end = [-3.75, -4.5]) | ||||
| ///     |> line(end = [0, -5.5]) | ||||
| ///     |> line(end = [-2, 0]) | ||||
| ///     |> close() | ||||
| ///     |> revolve(axis = 'y', angle = 180) | ||||
| /// ``` | ||||
| /// | ||||
| /// ```no_run | ||||
| /// part001 = startSketchOn('XY') | ||||
| ///     |> startProfileAt([4, 12], %) | ||||
| ///     |> line(end = [2, 0]) | ||||
| ///     |> line(end = [0, -6]) | ||||
| ///     |> line(end = [4, -6]) | ||||
| ///     |> line(end = [0, -6]) | ||||
| ///     |> line(end = [-3.75, -4.5]) | ||||
| ///     |> line(end = [0, -5.5]) | ||||
| ///     |> line(end = [-2, 0]) | ||||
| ///     |> close() | ||||
| ///     |> revolve(axis = 'y', angle = 180) | ||||
| /// | ||||
| /// part002 = startSketchOn(part001, 'end') | ||||
| ///     |> startProfileAt([4.5, -5], %) | ||||
| ///     |> line(end = [0, 5]) | ||||
| ///     |> line(end = [5, 0]) | ||||
| ///     |> line(end = [0, -5]) | ||||
| ///     |> close() | ||||
| ///     |> extrude(length = 5) | ||||
| /// ``` | ||||
| /// | ||||
| /// ```no_run | ||||
| /// box = startSketchOn('XY') | ||||
| ///     |> startProfileAt([0, 0], %) | ||||
| ///     |> line(end = [0, 20]) | ||||
| ///     |> line(end = [20, 0]) | ||||
| ///     |> line(end = [0, -20]) | ||||
| ///     |> close() | ||||
| ///     |> extrude(length = 20) | ||||
| /// | ||||
| /// sketch001 = startSketchOn(box, "END") | ||||
| ///     |> circle( center = [10,10], radius = 4 ) | ||||
| ///     |> revolve( | ||||
| ///         angle = -90, | ||||
| ///         axis = 'y' | ||||
| ///     ) | ||||
| /// ``` | ||||
| /// | ||||
| /// ```no_run | ||||
| /// box = startSketchOn('XY') | ||||
| ///     |> startProfileAt([0, 0], %) | ||||
| ///     |> line(end = [0, 20]) | ||||
| ///     |> line(end = [20, 0]) | ||||
| ///     |> line(end = [0, -20], tag = $revolveAxis) | ||||
| ///     |> close() | ||||
| ///     |> extrude(length = 20) | ||||
| /// | ||||
| /// sketch001 = startSketchOn(box, "END") | ||||
| ///     |> circle( center = [10,10], radius = 4 ) | ||||
| ///     |> revolve( | ||||
| ///         angle = 90, | ||||
| ///         axis = getOppositeEdge(revolveAxis) | ||||
| ///     ) | ||||
| /// ``` | ||||
| /// | ||||
| /// ```no_run | ||||
| /// box = startSketchOn('XY') | ||||
| ///     |> startProfileAt([0, 0], %) | ||||
| ///     |> line(end = [0, 20]) | ||||
| ///     |> line(end = [20, 0]) | ||||
| ///     |> line(end = [0, -20], tag = $revolveAxis) | ||||
| ///     |> close() | ||||
| ///     |> extrude(length = 20) | ||||
| /// | ||||
| /// sketch001 = startSketchOn(box, "END") | ||||
| ///     |> circle( center = [10,10], radius = 4 ) | ||||
| ///     |> revolve( | ||||
| ///         angle = 90, | ||||
| ///         axis = getOppositeEdge(revolveAxis), | ||||
| ///         tolerance = 0.0001 | ||||
| ///     ) | ||||
| /// ``` | ||||
| /// | ||||
| /// ```no_run | ||||
| /// sketch001 = startSketchOn('XY') | ||||
| ///   |> startProfileAt([10, 0], %) | ||||
| ///   |> line(end = [5, -5]) | ||||
| ///   |> line(end = [5, 5]) | ||||
| ///   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | ||||
| ///   |> close() | ||||
| /// | ||||
| /// part001 = revolve( | ||||
| ///    sketch001, | ||||
| ///   axis = { | ||||
| ///     custom: { | ||||
| ///       axis = [0.0, 1.0], | ||||
| ///       origin: [0.0, 0.0] | ||||
| ///     } | ||||
| ///   } | ||||
| /// ) | ||||
| /// ``` | ||||
| /// | ||||
| /// ```no_run | ||||
| /// // Revolve two sketches around the same axis. | ||||
| /// | ||||
| /// sketch001 = startSketchOn('XY') | ||||
| /// profile001 = startProfileAt([4, 8], sketch001) | ||||
| ///     |> xLine(length = 3) | ||||
| ///     |> yLine(length = -3) | ||||
| ///     |> xLine(length = -3) | ||||
| ///     |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | ||||
| ///     |> close() | ||||
| /// | ||||
| /// profile002 = startProfileAt([-5, 8], sketch001) | ||||
| ///     |> xLine(length = 3) | ||||
| ///     |> yLine(length = -3) | ||||
| ///     |> xLine(length = -3) | ||||
| ///     |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | ||||
| ///     |> close() | ||||
| /// | ||||
| /// revolve( | ||||
| ///     [profile001, profile002], | ||||
| ///     axis = "X", | ||||
| /// ) | ||||
| /// ``` | ||||
| /// | ||||
| /// ```no_run | ||||
| /// // Revolve around a path that has not been extruded. | ||||
| /// | ||||
| /// profile001 = startSketchOn('XY') | ||||
| ///     |> startProfileAt([0, 0], %) | ||||
| ///     |> line(end = [0, 20], tag = $revolveAxis) | ||||
| ///     |> line(end = [20, 0]) | ||||
| ///     |> line(end = [0, -20]) | ||||
| ///     |> close(%) | ||||
| /// | ||||
| /// sketch001 = startSketchOn('XY') | ||||
| ///     |> circle(center = [-10, 10], radius = 4) | ||||
| ///     |> revolve(angle = 90, axis = revolveAxis) | ||||
| /// ``` | ||||
| /// | ||||
| /// ```no_run | ||||
| /// // Revolve around a path that has not been extruded or closed. | ||||
| /// | ||||
| /// profile001 = startSketchOn('XY') | ||||
| ///     |> startProfileAt([0, 0], %) | ||||
| ///     |> line(end = [0, 20], tag = $revolveAxis) | ||||
| ///     |> line(end = [20, 0]) | ||||
| /// | ||||
| /// sketch001 = startSketchOn('XY') | ||||
| ///     |> circle(center = [-10, 10], radius = 4) | ||||
| ///     |> revolve(angle = 90, axis = revolveAxis) | ||||
| /// ``` | ||||
| #[stdlib { | ||||
|     name = "revolve", | ||||
|     feature_tree_operation = true, | ||||
|     keywords = true, | ||||
|     unlabeled_first = true, | ||||
|     args = { | ||||
|         sketches = { docs = "The sketch or set of sketches that should be revolved" }, | ||||
|         axis = { docs = "Axis of revolution." }, | ||||
|         angle = { docs = "Angle to revolve (in degrees). Default is 360." }, | ||||
|         tolerance = { docs = "Tolerance for the revolve operation." }, | ||||
|         tag_start = { docs = "A named tag for the face at the start of the revolve, i.e. the original sketch" }, | ||||
|         tag_end = { docs = "A named tag for the face at the end of the revolve" }, | ||||
|     } | ||||
| }] | ||||
| #[allow(clippy::too_many_arguments)] | ||||
| async fn inner_revolve( | ||||
|     sketches: Vec<Sketch>, | ||||
| @ -264,15 +64,22 @@ async fn inner_revolve( | ||||
|         let id = exec_state.next_uuid(); | ||||
|  | ||||
|         match &axis { | ||||
|             Axis2dOrEdgeReference::Axis(axis) => { | ||||
|                 let (axis, origin) = axis.axis_and_origin()?; | ||||
|             Axis2dOrEdgeReference::Axis { direction, origin } => { | ||||
|                 args.batch_modeling_cmd( | ||||
|                     id, | ||||
|                     ModelingCmd::from(mcmd::Revolve { | ||||
|                         angle, | ||||
|                         target: sketch.id.into(), | ||||
|                         axis, | ||||
|                         origin, | ||||
|                         axis: Point3d { | ||||
|                             x: direction[0], | ||||
|                             y: direction[1], | ||||
|                             z: 0.0, | ||||
|                         }, | ||||
|                         origin: Point3d { | ||||
|                             x: LengthUnit(origin[0]), | ||||
|                             y: LengthUnit(origin[1]), | ||||
|                             z: LengthUnit(0.0), | ||||
|                         }, | ||||
|                         tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))), | ||||
|                         axis_is_2d: true, | ||||
|                     }), | ||||
|  | ||||
| @ -1021,7 +1021,7 @@ pub async fn start_sketch_on(exec_state: &mut ExecState, args: Args) -> Result<K | ||||
| ///   |> line(end = [-2, 0]) | ||||
| ///   |> close() | ||||
| /// | ||||
| /// example = revolve(exampleSketch, axis = 'y', angle = 180) | ||||
| /// example = revolve(exampleSketch, axis = Y, angle = 180) | ||||
| /// | ||||
| /// exampleSketch002 = startSketchOn(example, 'end') | ||||
| ///   |> startProfileAt([4.5, -5], %) | ||||
| @ -1047,7 +1047,7 @@ pub async fn start_sketch_on(exec_state: &mut ExecState, args: Args) -> Result<K | ||||
| ///   |> line(end = [-2, 0]) | ||||
| ///   |> close() | ||||
| /// | ||||
| /// example = revolve(exampleSketch, axis = 'y', angle = 180, tagEnd = $end01) | ||||
| /// example = revolve(exampleSketch, axis = Y, angle = 180, tagEnd = $end01) | ||||
| /// | ||||
| /// exampleSketch002 = startSketchOn(example, end01) | ||||
| ///   |> startProfileAt([4.5, -5], %) | ||||
|  | ||||
| @ -54,7 +54,7 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K | ||||
| /// // Create a pipe using a sweep. | ||||
| /// | ||||
| /// // Create a path for the sweep. | ||||
| /// sweepPath = startSketchOn('XZ') | ||||
| /// sweepPath = startSketchOn(XZ) | ||||
| ///     |> startProfileAt([0.05, 0.05], %) | ||||
| ///     |> line(end = [0, 7]) | ||||
| ///     |> tangentialArc({ | ||||
| @ -69,13 +69,13 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K | ||||
| ///     |> line(end = [0, 7]) | ||||
| /// | ||||
| /// // Create a hole for the pipe. | ||||
| /// pipeHole = startSketchOn('XY') | ||||
| /// pipeHole = startSketchOn(XY) | ||||
| ///     |> circle( | ||||
| ///         center = [0, 0], | ||||
| ///         radius = 1.5, | ||||
| ///     ) | ||||
| /// | ||||
| /// sweepSketch = startSketchOn('XY') | ||||
| /// sweepSketch = startSketchOn(XY) | ||||
| ///     |> circle( | ||||
| ///         center = [0, 0], | ||||
| ///         radius = 2, | ||||
| @ -94,12 +94,12 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K | ||||
| ///     revolutions = 4, | ||||
| ///     length = 10, | ||||
| ///     radius = 5, | ||||
| ///     axis = 'Z', | ||||
| ///     axis = Z, | ||||
| ///  ) | ||||
| /// | ||||
| /// | ||||
| /// // Create a spring by sweeping around the helix path. | ||||
| /// springSketch = startSketchOn('YZ') | ||||
| /// springSketch = startSketchOn(YZ) | ||||
| ///     |> circle( center = [0, 0], radius = 1) | ||||
| ///     |> sweep(path = helixPath) | ||||
| /// ``` | ||||
| @ -107,7 +107,7 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K | ||||
| /// ``` | ||||
| /// // Sweep two sketches along the same path. | ||||
| /// | ||||
| /// sketch001 = startSketchOn('XY') | ||||
| /// sketch001 = startSketchOn(XY) | ||||
| /// rectangleSketch = startProfileAt([-200, 23.86], sketch001) | ||||
| ///     |> angledLine([0, 73.47], %, $rectangleSegmentA001) | ||||
| ///     |> angledLine([ | ||||
| @ -123,7 +123,7 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K | ||||
| /// | ||||
| /// circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63) | ||||
| /// | ||||
| /// sketch002 = startSketchOn('YZ') | ||||
| /// sketch002 = startSketchOn(YZ) | ||||
| /// sweepPath = startProfileAt([0, 0], sketch002) | ||||
| ///     |> yLine(length = 231.81) | ||||
| ///     |> tangentialArc({ | ||||
| @ -137,7 +137,7 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K | ||||
| /// ``` | ||||
| /// // Sectionally sweep one sketch along the path | ||||
| /// | ||||
| /// sketch001 = startSketchOn('XY') | ||||
| /// sketch001 = startSketchOn(XY) | ||||
| /// circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63) | ||||
| /// | ||||
| /// sketch002 = startSketchOn('YZ') | ||||
|  | ||||
| @ -1 +0,0 @@ | ||||
|  | ||||
| @ -1235,7 +1235,7 @@ insideRevolve = startSketchOn(XZ) | ||||
|   |> line([0, -thickness], %) | ||||
|   |> line([-overHangLength, 0], %) | ||||
|   |> close() | ||||
|   |> revolve({ axis: 'y' }, %) | ||||
|   |> revolve({ axis = Y }, %) | ||||
|  | ||||
| // Sketch and revolve one of the balls and duplicate it using a circular pattern. (This is currently a workaround, we have a bug with rotating on a sketch that touches the rotation axis) | ||||
| sphere = startSketchOn(XZ) | ||||
| @ -1250,7 +1250,7 @@ sphere = startSketchOn(XZ) | ||||
|        radius = sphereDia / 2 - 0.05 | ||||
|      }, %) | ||||
|   |> close() | ||||
|   |> revolve({ axis: 'x' }, %) | ||||
|   |> revolve({ axis = X }, %) | ||||
|   |> patternCircular3d( | ||||
|        axis = [0, 0, 1], | ||||
|        center = [0, 0, 0], | ||||
| @ -1274,7 +1274,7 @@ outsideRevolve = startSketchOn(XZ) | ||||
|   |> line([0, thickness], %) | ||||
|   |> line([overHangLength - thickness, 0], %) | ||||
|   |> close() | ||||
|   |> revolve({ axis: 'y' }, %)"#; | ||||
|   |> revolve({ axis = Y }, %)"#; | ||||
|         let program = crate::parsing::top_level_parse(some_program_string).unwrap(); | ||||
|  | ||||
|         let recasted = program.recast(&Default::default(), 0); | ||||
| @ -1301,7 +1301,7 @@ insideRevolve = startSketchOn(XZ) | ||||
|   |> line([0, -thickness], %) | ||||
|   |> line([-overHangLength, 0], %) | ||||
|   |> close() | ||||
|   |> revolve({ axis = 'y' }, %) | ||||
|   |> revolve({ axis = Y }, %) | ||||
|  | ||||
| // Sketch and revolve one of the balls and duplicate it using a circular pattern. (This is currently a workaround, we have a bug with rotating on a sketch that touches the rotation axis) | ||||
| sphere = startSketchOn(XZ) | ||||
| @ -1316,7 +1316,7 @@ sphere = startSketchOn(XZ) | ||||
|        radius = sphereDia / 2 - 0.05 | ||||
|      }, %) | ||||
|   |> close() | ||||
|   |> revolve({ axis = 'x' }, %) | ||||
|   |> revolve({ axis = X }, %) | ||||
|   |> patternCircular3d( | ||||
|        axis = [0, 0, 1], | ||||
|        center = [0, 0, 0], | ||||
| @ -1340,7 +1340,7 @@ outsideRevolve = startSketchOn(XZ) | ||||
|   |> line([0, thickness], %) | ||||
|   |> line([overHangLength - thickness, 0], %) | ||||
|   |> close() | ||||
|   |> revolve({ axis = 'y' }, %) | ||||
|   |> revolve({ axis = Y }, %) | ||||
| "# | ||||
|         ); | ||||
|     } | ||||
| @ -1613,9 +1613,9 @@ fn bracketSketch = (w, d, t) => { | ||||
|   s = startSketchOn({ | ||||
|          plane: { | ||||
|   origin: { x = 0, y = length / 2 + thk, z = 0 }, | ||||
|   x_axis: { x = 1, y = 0, z = 0 }, | ||||
|   y_axis: { x = 0, y = 0, z = 1 }, | ||||
|   z_axis: { x = 0, y = 1, z = 0 } | ||||
|   x_axis = { x = 1, y = 0, z = 0 }, | ||||
|   y_axis = { x = 0, y = 0, z = 1 }, | ||||
|   z_axis = { x = 0, y = 1, z = 0 } | ||||
| } | ||||
|        }) | ||||
|     |> startProfileAt([-w / 2 - t, d + t], %) | ||||
| @ -1645,9 +1645,9 @@ bracket_body = bracketSketch(width, depth, thk) | ||||
| tabs_r = startSketchOn({ | ||||
|        plane: { | ||||
|   origin: { x = 0, y = 0, z = depth + thk }, | ||||
|   x_axis: { x = 1, y = 0, z = 0 }, | ||||
|   y_axis: { x = 0, y = 1, z = 0 }, | ||||
|   z_axis: { x = 0, y = 0, z = 1 } | ||||
|   x_axis = { x = 1, y = 0, z = 0 }, | ||||
|   y_axis = { x = 0, y = 1, z = 0 }, | ||||
|   z_axis = { x = 0, y = 0, z = 1 } | ||||
| } | ||||
|      }) | ||||
|   |> startProfileAt([width / 2 + thk, length / 2 + thk], %) | ||||
| @ -2528,9 +2528,9 @@ fn f() { | ||||
| sketch002 = startSketchOn({ | ||||
|        plane: { | ||||
|     origin: { x = 1, y = 2, z = 3 }, | ||||
|     x_axis: { x = 4, y = 5, z = 6 }, | ||||
|     y_axis: { x = 7, y = 8, z = 9 }, | ||||
|     z_axis: { x = 10, y = 11, z = 12 } | ||||
|     x_axis = { x = 4, y = 5, z = 6 }, | ||||
|     y_axis = { x = 7, y = 8, z = 9 }, | ||||
|     z_axis = { x = 10, y = 11, z = 12 } | ||||
|        } | ||||
|   }) | ||||
| "#; | ||||
|  | ||||
| @ -5,6 +5,7 @@ | ||||
|  | ||||
| export import * from "std::math" | ||||
| export import * from "std::sketch" | ||||
| export import "std::turns" | ||||
|  | ||||
| /// A number | ||||
| /// | ||||
| @ -233,6 +234,10 @@ export type Face | ||||
| @(impl = std_rust) | ||||
| export type Helix | ||||
|  | ||||
| /// The edge of a solid. | ||||
| @(impl = std_rust) | ||||
| export type Edge | ||||
|  | ||||
| /// A point in two dimensional space. | ||||
| /// | ||||
| /// `Point2d` is an alias for a two-element array of [number](/docs/kcl/types/number)s. To write a value | ||||
| @ -245,11 +250,6 @@ export type Point2d = [number; 2] | ||||
| /// with type `Point3d`, use an array, e.g., `[0, 0, 0]` or `[5.0, 3.14, 6.8]`. | ||||
| export type Point3d = [number; 3] | ||||
|  | ||||
| export ZERO = 0 | ||||
| export QUARTER_TURN = 90deg | ||||
| export HALF_TURN = 180deg | ||||
| export THREE_QUARTER_TURN = 270deg | ||||
|  | ||||
| export XY = { | ||||
|   origin = { x = 0, y = 0, z = 0 }, | ||||
|   xAxis = { x = 1, y = 0, z = 0 }, | ||||
| @ -270,3 +270,330 @@ export YZ = { | ||||
|   yAxis = { x = 0, y = 0, z = 1 }, | ||||
|   zAxis = { x = 1, y = 0, z = 0 }, | ||||
| }: Plane | ||||
|  | ||||
| /// An infinte line in 2d space. | ||||
| @(impl = std_rust) | ||||
| export type Axis2d | ||||
|  | ||||
| /// An infinte line in 3d space. | ||||
| @(impl = std_rust) | ||||
| export type Axis3d | ||||
|  | ||||
| export X = { | ||||
|   origin = [0, 0, 0], | ||||
|   direction = [1, 0, 0], | ||||
| }: Axis3d | ||||
|  | ||||
| export Y = { | ||||
|   origin = [0, 0, 0], | ||||
|   direction = [0, 1, 0], | ||||
| }: Axis3d | ||||
|  | ||||
| export Z = { | ||||
|   origin = [0, 0, 0], | ||||
|   direction = [0, 0, 1], | ||||
| }: Axis3d | ||||
|  | ||||
| /// Create a helix. | ||||
| /// | ||||
| /// ``` | ||||
| /// // Create a helix around the Z axis. | ||||
| /// helixPath = helix( | ||||
| ///     angleStart = 0, | ||||
| ///     ccw = true, | ||||
| ///     revolutions = 5, | ||||
| ///     length = 10, | ||||
| ///     radius = 5, | ||||
| ///     axis = Z, | ||||
| ///  ) | ||||
| /// | ||||
| /// // Create a spring by sweeping around the helix path. | ||||
| /// springSketch = startSketchOn(YZ) | ||||
| ///     |> circle( center = [0, 0], radius = 0.5) | ||||
| ///     |> sweep(path = helixPath) | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// // Create a helix around an edge. | ||||
| /// helper001 = startSketchOn(XZ) | ||||
| ///  |> startProfileAt([0, 0], %) | ||||
| ///  |> line(end = [0, 10], tag = $edge001) | ||||
| /// | ||||
| /// helixPath = helix( | ||||
| ///     angleStart = 0, | ||||
| ///     ccw = true, | ||||
| ///     revolutions = 5, | ||||
| ///     length = 10, | ||||
| ///     radius = 5, | ||||
| ///     axis = edge001, | ||||
| ///  ) | ||||
| /// | ||||
| /// // Create a spring by sweeping around the helix path. | ||||
| /// springSketch = startSketchOn(XY) | ||||
| ///     |> circle( center = [0, 0], radius = 0.5 ) | ||||
| ///     |> sweep(path = helixPath) | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// // Create a helix around a custom axis. | ||||
| /// helixPath = helix( | ||||
| ///     angleStart = 0, | ||||
| ///     ccw = true, | ||||
| ///     revolutions = 5, | ||||
| ///     length = 10, | ||||
| ///     radius = 5, | ||||
| ///     axis = { | ||||
| ///         direction = [0, 0, 1.0], | ||||
| ///         origin = [0, 0.25, 0] | ||||
| ///     } | ||||
| ///  ) | ||||
| /// | ||||
| /// // Create a spring by sweeping around the helix path. | ||||
| /// springSketch = startSketchOn(XY) | ||||
| ///     |> circle( center = [0, 0], radius = 1 ) | ||||
| ///     |> sweep(path = helixPath) | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// // Create a helix on a cylinder. | ||||
| /// | ||||
| /// part001 = startSketchOn(XY) | ||||
| ///   |> circle( center= [5, 5], radius= 10 ) | ||||
| ///   |> extrude(length = 10) | ||||
| /// | ||||
| /// helix( | ||||
| ///     angleStart = 0, | ||||
| ///     ccw = true, | ||||
| ///     revolutions = 16, | ||||
| ///     cylinder = part001, | ||||
| ///  ) | ||||
| /// ``` | ||||
| @(impl = std_rust) | ||||
| export fn helix( | ||||
|   /// Number of revolutions. | ||||
|   revolutions: number(_), | ||||
|   /// Start angle (in degrees). | ||||
|   angleStart: number(deg), | ||||
|   /// Is the helix rotation counter clockwise? The default is `false`. | ||||
|   ccw?: bool, | ||||
|   /// Radius of the helix. | ||||
|   @(include_in_snippet = true) | ||||
|   radius?: number(mm), | ||||
|   /// Axis to use for the helix. | ||||
|   @(include_in_snippet = true) | ||||
|   axis?: Axis3d | Edge, | ||||
|   /// Length of the helix. This is not necessary if the helix is created around an edge. If not given the length of the edge is used. | ||||
|   @(include_in_snippet = true) | ||||
|   length?: number(mm), | ||||
|   /// Cylinder to create the helix on. | ||||
|   cylinder?: Solid, | ||||
| ): Helix {} | ||||
|  | ||||
| /// Rotate a sketch around some provided axis, creating a solid from its extent. | ||||
| /// | ||||
| /// This, like extrude, is able to create a 3-dimensional solid from a | ||||
| /// 2-dimensional sketch. However, unlike extrude, this creates a solid | ||||
| /// by using the extent of the sketch as its revolved around an axis rather | ||||
| /// than using the extent of the sketch linearly translated through a third | ||||
| /// dimension. | ||||
| /// | ||||
| /// Revolve occurs around a local sketch axis rather than a global axis. | ||||
| /// | ||||
| /// You can provide more than one sketch to revolve, and they will all be | ||||
| /// revolved around the same axis. | ||||
| /// | ||||
| /// ``` | ||||
| /// part001 = startSketchOn(XY) | ||||
| ///     |> startProfileAt([4, 12], %) | ||||
| ///     |> line(end = [2, 0]) | ||||
| ///     |> line(end = [0, -6]) | ||||
| ///     |> line(end = [4, -6]) | ||||
| ///     |> line(end = [0, -6]) | ||||
| ///     |> line(end = [-3.75, -4.5]) | ||||
| ///     |> line(end = [0, -5.5]) | ||||
| ///     |> line(end = [-2, 0]) | ||||
| ///     |> close() | ||||
| ///     |> revolve(axis = Y) // default angle is 360 | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// // A donut shape. | ||||
| /// sketch001 = startSketchOn(XY) | ||||
| ///     |> circle( center = [15, 0], radius = 5 ) | ||||
| ///     |> revolve( | ||||
| ///         angle = 360, | ||||
| ///         axis = Y, | ||||
| ///     ) | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// part001 = startSketchOn(XY) | ||||
| ///     |> startProfileAt([4, 12], %) | ||||
| ///     |> line(end = [2, 0]) | ||||
| ///     |> line(end = [0, -6]) | ||||
| ///     |> line(end = [4, -6]) | ||||
| ///     |> line(end = [0, -6]) | ||||
| ///     |> line(end = [-3.75, -4.5]) | ||||
| ///     |> line(end = [0, -5.5]) | ||||
| ///     |> line(end = [-2, 0]) | ||||
| ///     |> close() | ||||
| ///     |> revolve(axis = Y, angle = 180) | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// part001 = startSketchOn(XY) | ||||
| ///     |> startProfileAt([4, 12], %) | ||||
| ///     |> line(end = [2, 0]) | ||||
| ///     |> line(end = [0, -6]) | ||||
| ///     |> line(end = [4, -6]) | ||||
| ///     |> line(end = [0, -6]) | ||||
| ///     |> line(end = [-3.75, -4.5]) | ||||
| ///     |> line(end = [0, -5.5]) | ||||
| ///     |> line(end = [-2, 0]) | ||||
| ///     |> close() | ||||
| ///     |> revolve(axis = Y, angle = 180) | ||||
| /// | ||||
| /// part002 = startSketchOn(part001, 'end') | ||||
| ///     |> startProfileAt([4.5, -5], %) | ||||
| ///     |> line(end = [0, 5]) | ||||
| ///     |> line(end = [5, 0]) | ||||
| ///     |> line(end = [0, -5]) | ||||
| ///     |> close() | ||||
| ///     |> extrude(length = 5) | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// box = startSketchOn(XY) | ||||
| ///     |> startProfileAt([0, 0], %) | ||||
| ///     |> line(end = [0, 20]) | ||||
| ///     |> line(end = [20, 0]) | ||||
| ///     |> line(end = [0, -20]) | ||||
| ///     |> close() | ||||
| ///     |> extrude(length = 20) | ||||
| /// | ||||
| /// sketch001 = startSketchOn(box, "END") | ||||
| ///     |> circle( center = [10,10], radius = 4 ) | ||||
| ///     |> revolve( | ||||
| ///         angle = -90, | ||||
| ///         axis = Y | ||||
| ///     ) | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// box = startSketchOn(XY) | ||||
| ///     |> startProfileAt([0, 0], %) | ||||
| ///     |> line(end = [0, 20]) | ||||
| ///     |> line(end = [20, 0]) | ||||
| ///     |> line(end = [0, -20], tag = $revolveAxis) | ||||
| ///     |> close() | ||||
| ///     |> extrude(length = 20) | ||||
| /// | ||||
| /// sketch001 = startSketchOn(box, "END") | ||||
| ///     |> circle( center = [10,10], radius = 4 ) | ||||
| ///     |> revolve( | ||||
| ///         angle = 90, | ||||
| ///         axis = getOppositeEdge(revolveAxis) | ||||
| ///     ) | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// box = startSketchOn(XY) | ||||
| ///     |> startProfileAt([0, 0], %) | ||||
| ///     |> line(end = [0, 20]) | ||||
| ///     |> line(end = [20, 0]) | ||||
| ///     |> line(end = [0, -20], tag = $revolveAxis) | ||||
| ///     |> close() | ||||
| ///     |> extrude(length = 20) | ||||
| /// | ||||
| /// sketch001 = startSketchOn(box, "END") | ||||
| ///     |> circle( center = [10,10], radius = 4 ) | ||||
| ///     |> revolve( | ||||
| ///         angle = 90, | ||||
| ///         axis = getOppositeEdge(revolveAxis), | ||||
| ///         tolerance = 0.0001 | ||||
| ///     ) | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// sketch001 = startSketchOn(XY) | ||||
| ///   |> startProfileAt([10, 0], %) | ||||
| ///   |> line(end = [5, -5]) | ||||
| ///   |> line(end = [5, 5]) | ||||
| ///   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | ||||
| ///   |> close() | ||||
| /// | ||||
| /// part001 = revolve( | ||||
| ///    sketch001, | ||||
| ///    axis = { | ||||
| ///      direction = [0.0, 1.0], | ||||
| ///      origin: [0.0, 0.0] | ||||
| ///   } | ||||
| /// ) | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// // Revolve two sketches around the same axis. | ||||
| /// | ||||
| /// sketch001 = startSketchOn(XY) | ||||
| /// profile001 = startProfileAt([4, 8], sketch001) | ||||
| ///     |> xLine(length = 3) | ||||
| ///     |> yLine(length = -3) | ||||
| ///     |> xLine(length = -3) | ||||
| ///     |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | ||||
| ///     |> close() | ||||
| /// | ||||
| /// profile002 = startProfileAt([-5, 8], sketch001) | ||||
| ///     |> xLine(length = 3) | ||||
| ///     |> yLine(length = -3) | ||||
| ///     |> xLine(length = -3) | ||||
| ///     |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | ||||
| ///     |> close() | ||||
| /// | ||||
| /// revolve( | ||||
| ///     [profile001, profile002], | ||||
| ///     axis = X, | ||||
| /// ) | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// // Revolve around a path that has not been extruded. | ||||
| /// | ||||
| /// profile001 = startSketchOn(XY) | ||||
| ///     |> startProfileAt([0, 0], %) | ||||
| ///     |> line(end = [0, 20], tag = $revolveAxis) | ||||
| ///     |> line(end = [20, 0]) | ||||
| ///     |> line(end = [0, -20]) | ||||
| ///     |> close(%) | ||||
| /// | ||||
| /// sketch001 = startSketchOn(XY) | ||||
| ///     |> circle(center = [-10, 10], radius = 4) | ||||
| ///     |> revolve(angle = 90, axis = revolveAxis) | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// // Revolve around a path that has not been extruded or closed. | ||||
| /// | ||||
| /// profile001 = startSketchOn(XY) | ||||
| ///     |> startProfileAt([0, 0], %) | ||||
| ///     |> line(end = [0, 20], tag = $revolveAxis) | ||||
| ///     |> line(end = [20, 0]) | ||||
| /// | ||||
| /// sketch001 = startSketchOn(XY) | ||||
| ///     |> circle(center = [-10, 10], radius = 4) | ||||
| ///     |> revolve(angle = 90, axis = revolveAxis) | ||||
| /// ``` | ||||
| @(impl = std_rust) | ||||
| export fn revolve( | ||||
|   /// The sketch or set of sketches that should be revolved | ||||
|   @sketches: [Sketch; 1+], | ||||
|   /// Axis of revolution. | ||||
|   axis: Axis2d | Edge, | ||||
|   /// Angle to revolve (in degrees). Default is 360. | ||||
|   angle?: number(deg), | ||||
|   /// Tolerance for the revolve operation. | ||||
|   tolerance?: number(mm), | ||||
|   /// A named tag for the face at the start of the revolve, i.e. the original sketch. | ||||
|   tagStart?: tag, | ||||
|   /// A named tag for the face at the end of the revolve. | ||||
|   tagEnd?: tag, | ||||
| ): Solid {} | ||||
|  | ||||
| @ -32,3 +32,74 @@ export fn circle( | ||||
|   /// Create a new tag which refers to this circle. | ||||
|   tag?: tag, | ||||
| ): Sketch {} | ||||
|  | ||||
| /// Mirror a sketch. | ||||
| /// | ||||
| /// Only works on unclosed sketches for now. | ||||
| /// | ||||
| /// Mirror occurs around a local sketch axis rather than a global axis. | ||||
| /// | ||||
| /// ``` | ||||
| /// // Mirror an un-closed sketch across the Y axis. | ||||
| /// sketch001 = startSketchOn(XZ) | ||||
| ///     |> startProfileAt([0, 10], %) | ||||
| ///     |> line(end = [15, 0]) | ||||
| ///     |> line(end = [-7, -3]) | ||||
| ///     |> line(end = [9, -1]) | ||||
| ///     |> line(end = [-8, -5]) | ||||
| ///     |> line(end = [9, -3]) | ||||
| ///     |> line(end = [-8, -3]) | ||||
| ///     |> line(end = [9, -1]) | ||||
| ///     |> line(end = [-19, -0]) | ||||
| ///     |> mirror2d(axis = Y) | ||||
| /// | ||||
| /// example = extrude(sketch001, length = 10) | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// // Mirror a un-closed sketch across the Y axis. | ||||
| /// sketch001 = startSketchOn(XZ) | ||||
| ///     |> startProfileAt([0, 8.5], %) | ||||
| ///     |> line(end = [20, -8.5]) | ||||
| ///     |> line(end = [-20, -8.5]) | ||||
| ///     |> mirror2d(axis = Y) | ||||
| /// | ||||
| /// example = extrude(sketch001, length = 10) | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// // Mirror a un-closed sketch across an edge. | ||||
| /// helper001 = startSketchOn(XZ) | ||||
| ///  |> startProfileAt([0, 0], %) | ||||
| ///  |> line(end = [0, 10], tag = $edge001) | ||||
| /// | ||||
| /// sketch001 = startSketchOn(XZ) | ||||
| ///     |> startProfileAt([0, 8.5], %) | ||||
| ///     |> line(end = [20, -8.5]) | ||||
| ///     |> line(end = [-20, -8.5]) | ||||
| ///     |> mirror2d(axis = edge001) | ||||
| /// | ||||
| /// // example = extrude(sketch001, length = 10) | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// // Mirror an un-closed sketch across a custom axis. | ||||
| /// sketch001 = startSketchOn(XZ) | ||||
| ///     |> startProfileAt([0, 8.5], %) | ||||
| ///     |> line(end = [20, -8.5]) | ||||
| ///     |> line(end = [-20, -8.5]) | ||||
| ///     |> mirror2d( | ||||
| ///       axis = { | ||||
| ///         direction = [0.0, 1.0], | ||||
| ///         origin = [0.0, 0.0] | ||||
| ///       }) | ||||
| /// | ||||
| /// example = extrude(sketch001, length = 10) | ||||
| /// ``` | ||||
| @(impl = std_rust) | ||||
| export fn mirror2d( | ||||
|   /// The sketch or sketches to be reflected. | ||||
|   @sketches: [Sketch; 1+], | ||||
|   /// The axis to refect around. | ||||
|   axis: Axis2d | Edge, | ||||
| ): Sketch {} | ||||
|  | ||||
							
								
								
									
										6
									
								
								rust/kcl-lib/std/turns.kcl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								rust/kcl-lib/std/turns.kcl
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| @no_std | ||||
|  | ||||
| export ZERO = 0 | ||||
| export QUARTER_TURN = 90deg | ||||
| export HALF_TURN = 180deg | ||||
| export THREE_QUARTER_TURN = 270deg | ||||
| @ -1,25 +1,25 @@ | ||||
| ```mermaid | ||||
| flowchart LR | ||||
|   subgraph path2 [Path] | ||||
|     2["Path<br>[76, 113, 4]"] | ||||
|     3["Segment<br>[119, 136, 4]"] | ||||
|     4["Segment<br>[142, 160, 4]"] | ||||
|     5["Segment<br>[166, 184, 4]"] | ||||
|     6["Segment<br>[190, 246, 4]"] | ||||
|     7["Segment<br>[252, 259, 4]"] | ||||
|     2["Path<br>[76, 113, 5]"] | ||||
|     3["Segment<br>[119, 136, 5]"] | ||||
|     4["Segment<br>[142, 160, 5]"] | ||||
|     5["Segment<br>[166, 184, 5]"] | ||||
|     6["Segment<br>[190, 246, 5]"] | ||||
|     7["Segment<br>[252, 259, 5]"] | ||||
|     8[Solid2d] | ||||
|   end | ||||
|   subgraph path25 [Path] | ||||
|     25["Path<br>[76, 111, 5]"] | ||||
|     26["Segment<br>[117, 134, 5]"] | ||||
|     27["Segment<br>[140, 158, 5]"] | ||||
|     28["Segment<br>[164, 182, 5]"] | ||||
|     29["Segment<br>[188, 244, 5]"] | ||||
|     30["Segment<br>[250, 257, 5]"] | ||||
|     25["Path<br>[76, 111, 6]"] | ||||
|     26["Segment<br>[117, 134, 6]"] | ||||
|     27["Segment<br>[140, 158, 6]"] | ||||
|     28["Segment<br>[164, 182, 6]"] | ||||
|     29["Segment<br>[188, 244, 6]"] | ||||
|     30["Segment<br>[250, 257, 6]"] | ||||
|     31[Solid2d] | ||||
|   end | ||||
|   1["Plane<br>[47, 66, 4]"] | ||||
|   9["Sweep Extrusion<br>[265, 287, 4]"] | ||||
|   1["Plane<br>[47, 66, 5]"] | ||||
|   9["Sweep Extrusion<br>[265, 287, 5]"] | ||||
|   10[Wall] | ||||
|   11[Wall] | ||||
|   12[Wall] | ||||
| @ -34,8 +34,8 @@ flowchart LR | ||||
|   21["SweepEdge Adjacent"] | ||||
|   22["SweepEdge Opposite"] | ||||
|   23["SweepEdge Adjacent"] | ||||
|   24["Plane<br>[47, 66, 5]"] | ||||
|   32["Sweep Extrusion<br>[263, 285, 5]"] | ||||
|   24["Plane<br>[47, 66, 6]"] | ||||
|   32["Sweep Extrusion<br>[263, 285, 6]"] | ||||
|   33[Wall] | ||||
|   34[Wall] | ||||
|   35[Wall] | ||||
|  | ||||
| @ -5,10 +5,10 @@ description: Variables in memory after executing assembly_mixed_units_cubes.kcl | ||||
| { | ||||
|   "cubeIn": { | ||||
|     "type": "Module", | ||||
|     "value": 4 | ||||
|     "value": 5 | ||||
|   }, | ||||
|   "cubeMm": { | ||||
|     "type": "Module", | ||||
|     "value": 5 | ||||
|     "value": 6 | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,17 +1,17 @@ | ||||
| ```mermaid | ||||
| flowchart LR | ||||
|   subgraph path2 [Path] | ||||
|     2["Path<br>[197, 232, 4]"] | ||||
|     3["Segment<br>[197, 232, 4]"] | ||||
|     2["Path<br>[197, 232, 5]"] | ||||
|     3["Segment<br>[197, 232, 5]"] | ||||
|     4[Solid2d] | ||||
|   end | ||||
|   subgraph path6 [Path] | ||||
|     6["Path<br>[113, 148, 5]"] | ||||
|     7["Segment<br>[113, 148, 5]"] | ||||
|     6["Path<br>[113, 148, 6]"] | ||||
|     7["Segment<br>[113, 148, 6]"] | ||||
|     8[Solid2d] | ||||
|   end | ||||
|   1["Plane<br>[172, 191, 4]"] | ||||
|   5["Plane<br>[88, 107, 5]"] | ||||
|   1["Plane<br>[172, 191, 5]"] | ||||
|   5["Plane<br>[88, 107, 6]"] | ||||
|   1 --- 2 | ||||
|   2 --- 3 | ||||
|   2 --- 4 | ||||
|  | ||||
| @ -5,10 +5,10 @@ description: Variables in memory after executing assembly_non_default_units.kcl | ||||
| { | ||||
|   "other1": { | ||||
|     "type": "Module", | ||||
|     "value": 4 | ||||
|     "value": 5 | ||||
|   }, | ||||
|   "other2": { | ||||
|     "type": "Module", | ||||
|     "value": 5 | ||||
|     "value": 6 | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -148,6 +148,22 @@ description: Operations executed crazy_multi_profile.kcl | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "revolve", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Sketch", | ||||
|         "value": { | ||||
|           "artifactId": "[uuid]" | ||||
|         } | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "angle": { | ||||
|         "value": { | ||||
| @ -173,18 +189,54 @@ description: Operations executed crazy_multi_profile.kcl | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "name": "revolve", | ||||
|     "sourceRange": [], | ||||
|     "type": "StdLibCall", | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "KclStdLibCall", | ||||
|     "name": "", | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Sketch", | ||||
|         "value": { | ||||
|           "artifactId": "[uuid]" | ||||
|         } | ||||
|         "type": "Array", | ||||
|         "value": [ | ||||
|           { | ||||
|             "type": "Sketch", | ||||
|             "value": { | ||||
|               "artifactId": "[uuid]" | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     } | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "angle": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 45.0, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "axis": { | ||||
|         "value": { | ||||
|           "type": "Uuid", | ||||
|           "value": "[uuid]" | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
| @ -338,6 +390,22 @@ description: Operations executed crazy_multi_profile.kcl | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "revolve", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Sketch", | ||||
|         "value": { | ||||
|           "artifactId": "[uuid]" | ||||
|         } | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "angle": { | ||||
|         "value": { | ||||
| @ -364,17 +432,54 @@ description: Operations executed crazy_multi_profile.kcl | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "name": "revolve", | ||||
|     "sourceRange": [], | ||||
|     "type": "StdLibCall", | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "KclStdLibCall", | ||||
|     "name": "", | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Sketch", | ||||
|         "value": { | ||||
|           "artifactId": "[uuid]" | ||||
|         } | ||||
|         "type": "Array", | ||||
|         "value": [ | ||||
|           { | ||||
|             "type": "Sketch", | ||||
|             "value": { | ||||
|               "artifactId": "[uuid]" | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     } | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "angle": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 45.0, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "axis": { | ||||
|         "value": { | ||||
|           "type": "TagIdentifier", | ||||
|           "value": "seg02", | ||||
|           "artifact_id": "[uuid]" | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -117,6 +117,14 @@ description: Operations executed helix_ccw.kcl | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "helix", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "angleStart": { | ||||
|         "value": { | ||||
| @ -167,9 +175,11 @@ description: Operations executed helix_ccw.kcl | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "name": "helix", | ||||
|     "sourceRange": [], | ||||
|     "type": "StdLibCall", | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "KclStdLibCall", | ||||
|     "name": "", | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Solid", | ||||
| @ -178,6 +188,60 @@ description: Operations executed helix_ccw.kcl | ||||
|         } | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     } | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "angleStart": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.0, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "ccw": { | ||||
|         "value": { | ||||
|           "type": "Bool", | ||||
|           "value": true | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "cylinder": { | ||||
|         "value": { | ||||
|           "type": "Solid", | ||||
|           "value": { | ||||
|             "artifactId": "[uuid]" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "revolutions": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 16.0, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -19,6 +19,14 @@ description: Operations executed helix_simple.kcl | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "helix", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "angleStart": { | ||||
|         "value": { | ||||
| @ -100,9 +108,96 @@ description: Operations executed helix_simple.kcl | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "name": "helix", | ||||
|     "sourceRange": [], | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "KclStdLibCall", | ||||
|     "name": "", | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "angleStart": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.0, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "axis": { | ||||
|         "value": { | ||||
|           "type": "TagIdentifier", | ||||
|           "value": "edge001", | ||||
|           "artifact_id": "[uuid]" | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "ccw": { | ||||
|         "value": { | ||||
|           "type": "Bool", | ||||
|           "value": true | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "length": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 10.0, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 5.0, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "revolutions": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 5.0, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -5,7 +5,7 @@ description: Variables in memory after executing import_foreign.kcl | ||||
| { | ||||
|   "cube": { | ||||
|     "type": "Module", | ||||
|     "value": 4 | ||||
|     "value": 5 | ||||
|   }, | ||||
|   "model": { | ||||
|     "type": "ImportedGeometry", | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| @settings(defaultLengthUnit = mm) | ||||
|  | ||||
| export part001 = startSketchOn('XY') | ||||
| export part001 = startSketchOn(XY) | ||||
|   |> startProfileAt([4, 12], %) | ||||
|   |> line(end = [2, 0]) | ||||
|   |> line(end = [0, -6]) | ||||
| @ -10,7 +10,7 @@ export part001 = startSketchOn('XY') | ||||
|   |> line(end = [0, -5.5]) | ||||
|   |> line(end = [-2, 0]) | ||||
|   |> close() | ||||
|   |> revolve(axis = 'y') // default angle is 360 | ||||
|   |> revolve(axis = Y) // default angle is 360 | ||||
|  | ||||
| export fn two() { | ||||
|   return 5 | ||||
|  | ||||
| @ -7,8 +7,8 @@ description: Operations executed import_function_not_sketch.kcl | ||||
|     "labeledArgs": { | ||||
|       "data": { | ||||
|         "value": { | ||||
|           "type": "String", | ||||
|           "value": "XY" | ||||
|           "type": "Plane", | ||||
|           "artifact_id": "[uuid]" | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
| @ -19,18 +19,117 @@ description: Operations executed import_function_not_sketch.kcl | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "revolve", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "axis": { | ||||
|         "value": { | ||||
|           "type": "String", | ||||
|           "value": "y" | ||||
|           "type": "Object", | ||||
|           "value": { | ||||
|             "direction": { | ||||
|               "type": "Array", | ||||
|               "value": [ | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 1.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             }, | ||||
|             "origin": { | ||||
|               "type": "Array", | ||||
|               "value": [ | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "name": "revolve", | ||||
|     "sourceRange": [], | ||||
|     "type": "StdLibCall", | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "KclStdLibCall", | ||||
|     "name": "", | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Sketch", | ||||
| @ -39,6 +138,82 @@ description: Operations executed import_function_not_sketch.kcl | ||||
|         } | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     } | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "axis": { | ||||
|         "value": { | ||||
|           "type": "Object", | ||||
|           "value": { | ||||
|             "direction": { | ||||
|               "type": "Array", | ||||
|               "value": [ | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 1.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             }, | ||||
|             "origin": { | ||||
|               "type": "Array", | ||||
|               "value": [ | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -14,7 +14,7 @@ export part001 = startSketchOn(XY) | ||||
|   |> line(end = [0, -5.5]) | ||||
|   |> line(end = [-2, 0]) | ||||
|   |> close() | ||||
|   |> revolve(axis = 'y') // default angle is 360 | ||||
|   |> revolve(axis = Y) // default angle is 360 | ||||
|  | ||||
| export fn two() { | ||||
|   return 5 | ||||
|  | ||||
| @ -5,6 +5,6 @@ description: Variables in memory after executing import_transform.kcl | ||||
| { | ||||
|   "screw": { | ||||
|     "type": "Module", | ||||
|     "value": 4 | ||||
|     "value": 5 | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,12 +1,12 @@ | ||||
| ```mermaid | ||||
| flowchart LR | ||||
|   subgraph path2 [Path] | ||||
|     2["Path<br>[83, 119, 4]"] | ||||
|     3["Segment<br>[83, 119, 4]"] | ||||
|     2["Path<br>[83, 119, 5]"] | ||||
|     3["Segment<br>[83, 119, 5]"] | ||||
|     4[Solid2d] | ||||
|   end | ||||
|   1["Plane<br>[60, 77, 4]"] | ||||
|   5["Sweep Extrusion<br>[125, 145, 4]"] | ||||
|   1["Plane<br>[60, 77, 5]"] | ||||
|   5["Sweep Extrusion<br>[125, 145, 5]"] | ||||
|   6[Wall] | ||||
|   7["Cap Start"] | ||||
|   8["Cap End"] | ||||
|  | ||||
| @ -111,6 +111,6 @@ description: Variables in memory after executing import_whole.kcl | ||||
|   }, | ||||
|   "foo": { | ||||
|     "type": "Module", | ||||
|     "value": 4 | ||||
|     "value": 5 | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -17,26 +17,26 @@ flowchart LR | ||||
|     18[Solid2d] | ||||
|   end | ||||
|   subgraph path24 [Path] | ||||
|     24["Path<br>[1576, 1709, 0]"] | ||||
|     25["Segment<br>[1715, 1808, 0]"] | ||||
|     26["Segment<br>[1814, 1845, 0]"] | ||||
|     27["Segment<br>[1851, 1879, 0]"] | ||||
|     28["Segment<br>[1885, 1892, 0]"] | ||||
|     24["Path<br>[1574, 1707, 0]"] | ||||
|     25["Segment<br>[1713, 1806, 0]"] | ||||
|     26["Segment<br>[1812, 1843, 0]"] | ||||
|     27["Segment<br>[1849, 1877, 0]"] | ||||
|     28["Segment<br>[1883, 1890, 0]"] | ||||
|     29[Solid2d] | ||||
|   end | ||||
|   subgraph path40 [Path] | ||||
|     40["Path<br>[2228, 2370, 0]"] | ||||
|     41["Segment<br>[2228, 2370, 0]"] | ||||
|     40["Path<br>[2224, 2366, 0]"] | ||||
|     41["Segment<br>[2224, 2366, 0]"] | ||||
|     42[Solid2d] | ||||
|   end | ||||
|   subgraph path50 [Path] | ||||
|     50["Path<br>[2766, 2819, 0]"] | ||||
|     51["Segment<br>[2766, 2819, 0]"] | ||||
|     50["Path<br>[2760, 2813, 0]"] | ||||
|     51["Segment<br>[2760, 2813, 0]"] | ||||
|     52[Solid2d] | ||||
|   end | ||||
|   subgraph path53 [Path] | ||||
|     53["Path<br>[2830, 2904, 0]"] | ||||
|     54["Segment<br>[2830, 2904, 0]"] | ||||
|     53["Path<br>[2824, 2898, 0]"] | ||||
|     54["Segment<br>[2824, 2898, 0]"] | ||||
|     55[Solid2d] | ||||
|   end | ||||
|   1["Plane<br>[677, 724, 0]"] | ||||
| @ -47,12 +47,12 @@ flowchart LR | ||||
|   12["SweepEdge Opposite"] | ||||
|   13["SweepEdge Adjacent"] | ||||
|   14["Plane<br>[1014, 1031, 0]"] | ||||
|   19["Sweep Revolve<br>[1286, 1318, 0]"] | ||||
|   19["Sweep Revolve<br>[1286, 1316, 0]"] | ||||
|   20[Wall] | ||||
|   21[Wall] | ||||
|   22["SweepEdge Adjacent"] | ||||
|   23["Plane<br>[1553, 1570, 0]"] | ||||
|   30["Sweep Revolve<br>[1934, 1966, 0]"] | ||||
|   23["Plane<br>[1551, 1568, 0]"] | ||||
|   30["Sweep Revolve<br>[1932, 1962, 0]"] | ||||
|   31[Wall] | ||||
|   32[Wall] | ||||
|   33[Wall] | ||||
| @ -61,22 +61,22 @@ flowchart LR | ||||
|   36["SweepEdge Adjacent"] | ||||
|   37["SweepEdge Adjacent"] | ||||
|   38["SweepEdge Adjacent"] | ||||
|   39["Plane<br>[2205, 2222, 0]"] | ||||
|   43["Sweep Revolve<br>[2413, 2466, 0]"] | ||||
|   39["Plane<br>[2201, 2218, 0]"] | ||||
|   43["Sweep Revolve<br>[2409, 2460, 0]"] | ||||
|   44[Wall] | ||||
|   45["Cap Start"] | ||||
|   46["Cap End"] | ||||
|   47["SweepEdge Opposite"] | ||||
|   48["SweepEdge Adjacent"] | ||||
|   49["Plane<br>[2712, 2759, 0]"] | ||||
|   56["Sweep Extrusion<br>[2924, 2977, 0]"] | ||||
|   49["Plane<br>[2706, 2753, 0]"] | ||||
|   56["Sweep Extrusion<br>[2918, 2971, 0]"] | ||||
|   57[Wall] | ||||
|   58["Cap Start"] | ||||
|   59["Cap End"] | ||||
|   60["SweepEdge Opposite"] | ||||
|   61["SweepEdge Adjacent"] | ||||
|   62["StartSketchOnPlane<br>[663, 725, 0]"] | ||||
|   63["StartSketchOnPlane<br>[2698, 2760, 0]"] | ||||
|   63["StartSketchOnPlane<br>[2692, 2754, 0]"] | ||||
|   1 --- 2 | ||||
|   1 --- 5 | ||||
|   2 --- 3 | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -236,18 +236,13 @@ description: Operations executed ball-bearing.kcl | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "axis": { | ||||
|         "value": { | ||||
|           "type": "String", | ||||
|           "value": "X" | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "revolve", | ||||
|     "sourceRange": [], | ||||
|     "type": "StdLibCall", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Sketch", | ||||
| @ -256,7 +251,200 @@ description: Operations executed ball-bearing.kcl | ||||
|         } | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     } | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "axis": { | ||||
|         "value": { | ||||
|           "type": "Object", | ||||
|           "value": { | ||||
|             "direction": { | ||||
|               "type": "Array", | ||||
|               "value": [ | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 1.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             }, | ||||
|             "origin": { | ||||
|               "type": "Array", | ||||
|               "value": [ | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "KclStdLibCall", | ||||
|     "name": "", | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Array", | ||||
|         "value": [ | ||||
|           { | ||||
|             "type": "Sketch", | ||||
|             "value": { | ||||
|               "artifactId": "[uuid]" | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "axis": { | ||||
|         "value": { | ||||
|           "type": "Object", | ||||
|           "value": { | ||||
|             "direction": { | ||||
|               "type": "Array", | ||||
|               "value": [ | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 1.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             }, | ||||
|             "origin": { | ||||
|               "type": "Array", | ||||
|               "value": [ | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
| @ -438,18 +626,13 @@ description: Operations executed ball-bearing.kcl | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "axis": { | ||||
|         "value": { | ||||
|           "type": "String", | ||||
|           "value": "X" | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "revolve", | ||||
|     "sourceRange": [], | ||||
|     "type": "StdLibCall", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Sketch", | ||||
| @ -458,7 +641,200 @@ description: Operations executed ball-bearing.kcl | ||||
|         } | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     } | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "axis": { | ||||
|         "value": { | ||||
|           "type": "Object", | ||||
|           "value": { | ||||
|             "direction": { | ||||
|               "type": "Array", | ||||
|               "value": [ | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 1.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             }, | ||||
|             "origin": { | ||||
|               "type": "Array", | ||||
|               "value": [ | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "KclStdLibCall", | ||||
|     "name": "", | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Array", | ||||
|         "value": [ | ||||
|           { | ||||
|             "type": "Sketch", | ||||
|             "value": { | ||||
|               "artifactId": "[uuid]" | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "axis": { | ||||
|         "value": { | ||||
|           "type": "Object", | ||||
|           "value": { | ||||
|             "direction": { | ||||
|               "type": "Array", | ||||
|               "value": [ | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 1.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             }, | ||||
|             "origin": { | ||||
|               "type": "Array", | ||||
|               "value": [ | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
| @ -679,6 +1055,22 @@ description: Operations executed ball-bearing.kcl | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "revolve", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Sketch", | ||||
|         "value": { | ||||
|           "artifactId": "[uuid]" | ||||
|         } | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "angle": { | ||||
|         "value": { | ||||
| @ -692,24 +1084,206 @@ description: Operations executed ball-bearing.kcl | ||||
|       }, | ||||
|       "axis": { | ||||
|         "value": { | ||||
|           "type": "String", | ||||
|           "value": "Y" | ||||
|           "type": "Object", | ||||
|           "value": { | ||||
|             "direction": { | ||||
|               "type": "Array", | ||||
|               "value": [ | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 1.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             }, | ||||
|             "origin": { | ||||
|               "type": "Array", | ||||
|               "value": [ | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "name": "revolve", | ||||
|     "sourceRange": [], | ||||
|     "type": "StdLibCall", | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "KclStdLibCall", | ||||
|     "name": "", | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Sketch", | ||||
|         "value": { | ||||
|           "artifactId": "[uuid]" | ||||
|         } | ||||
|         "type": "Array", | ||||
|         "value": [ | ||||
|           { | ||||
|             "type": "Sketch", | ||||
|             "value": { | ||||
|               "artifactId": "[uuid]" | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     } | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "angle": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 36.0, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "axis": { | ||||
|         "value": { | ||||
|           "type": "Object", | ||||
|           "value": { | ||||
|             "direction": { | ||||
|               "type": "Array", | ||||
|               "value": [ | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 1.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             }, | ||||
|             "origin": { | ||||
|               "type": "Array", | ||||
|               "value": [ | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "Number", | ||||
|                   "value": 0.0, | ||||
|                   "ty": { | ||||
|                     "type": "Default", | ||||
|                     "len": { | ||||
|                       "type": "Mm" | ||||
|                     }, | ||||
|                     "angle": { | ||||
|                       "type": "Degrees" | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|  | ||||
| @ -1,239 +1,239 @@ | ||||
| ```mermaid | ||||
| flowchart LR | ||||
|   subgraph path2 [Path] | ||||
|     2["Path<br>[361, 394, 4]"] | ||||
|     3["Segment<br>[402, 428, 4]"] | ||||
|     4["Segment<br>[436, 489, 4]"] | ||||
|     5["Segment<br>[497, 550, 4]"] | ||||
|     6["Segment<br>[558, 612, 4]"] | ||||
|     7["Segment<br>[620, 645, 4]"] | ||||
|     8["Segment<br>[653, 673, 4]"] | ||||
|     9["Segment<br>[681, 705, 4]"] | ||||
|     10["Segment<br>[713, 766, 4]"] | ||||
|     11["Segment<br>[774, 799, 4]"] | ||||
|     12["Segment<br>[807, 827, 4]"] | ||||
|     13["Segment<br>[835, 859, 4]"] | ||||
|     14["Segment<br>[867, 919, 4]"] | ||||
|     15["Segment<br>[927, 979, 4]"] | ||||
|     16["Segment<br>[987, 1012, 4]"] | ||||
|     17["Segment<br>[1020, 1044, 4]"] | ||||
|     18["Segment<br>[1052, 1105, 4]"] | ||||
|     19["Segment<br>[1113, 1138, 4]"] | ||||
|     20["Segment<br>[1146, 1173, 4]"] | ||||
|     21["Segment<br>[1181, 1233, 4]"] | ||||
|     22["Segment<br>[1241, 1276, 4]"] | ||||
|     23["Segment<br>[1284, 1291, 4]"] | ||||
|     2["Path<br>[361, 394, 5]"] | ||||
|     3["Segment<br>[402, 428, 5]"] | ||||
|     4["Segment<br>[436, 489, 5]"] | ||||
|     5["Segment<br>[497, 550, 5]"] | ||||
|     6["Segment<br>[558, 612, 5]"] | ||||
|     7["Segment<br>[620, 645, 5]"] | ||||
|     8["Segment<br>[653, 673, 5]"] | ||||
|     9["Segment<br>[681, 705, 5]"] | ||||
|     10["Segment<br>[713, 766, 5]"] | ||||
|     11["Segment<br>[774, 799, 5]"] | ||||
|     12["Segment<br>[807, 827, 5]"] | ||||
|     13["Segment<br>[835, 859, 5]"] | ||||
|     14["Segment<br>[867, 919, 5]"] | ||||
|     15["Segment<br>[927, 979, 5]"] | ||||
|     16["Segment<br>[987, 1012, 5]"] | ||||
|     17["Segment<br>[1020, 1044, 5]"] | ||||
|     18["Segment<br>[1052, 1105, 5]"] | ||||
|     19["Segment<br>[1113, 1138, 5]"] | ||||
|     20["Segment<br>[1146, 1173, 5]"] | ||||
|     21["Segment<br>[1181, 1233, 5]"] | ||||
|     22["Segment<br>[1241, 1276, 5]"] | ||||
|     23["Segment<br>[1284, 1291, 5]"] | ||||
|     24[Solid2d] | ||||
|   end | ||||
|   subgraph path89 [Path] | ||||
|     89["Path<br>[361, 394, 4]"] | ||||
|     90["Segment<br>[402, 428, 4]"] | ||||
|     91["Segment<br>[436, 489, 4]"] | ||||
|     92["Segment<br>[497, 550, 4]"] | ||||
|     93["Segment<br>[558, 612, 4]"] | ||||
|     94["Segment<br>[620, 645, 4]"] | ||||
|     95["Segment<br>[653, 673, 4]"] | ||||
|     96["Segment<br>[681, 705, 4]"] | ||||
|     97["Segment<br>[713, 766, 4]"] | ||||
|     98["Segment<br>[774, 799, 4]"] | ||||
|     99["Segment<br>[807, 827, 4]"] | ||||
|     100["Segment<br>[835, 859, 4]"] | ||||
|     101["Segment<br>[867, 919, 4]"] | ||||
|     102["Segment<br>[927, 979, 4]"] | ||||
|     103["Segment<br>[987, 1012, 4]"] | ||||
|     104["Segment<br>[1020, 1044, 4]"] | ||||
|     105["Segment<br>[1052, 1105, 4]"] | ||||
|     106["Segment<br>[1113, 1138, 4]"] | ||||
|     107["Segment<br>[1146, 1173, 4]"] | ||||
|     108["Segment<br>[1181, 1233, 4]"] | ||||
|     109["Segment<br>[1241, 1276, 4]"] | ||||
|     110["Segment<br>[1284, 1291, 4]"] | ||||
|     89["Path<br>[361, 394, 5]"] | ||||
|     90["Segment<br>[402, 428, 5]"] | ||||
|     91["Segment<br>[436, 489, 5]"] | ||||
|     92["Segment<br>[497, 550, 5]"] | ||||
|     93["Segment<br>[558, 612, 5]"] | ||||
|     94["Segment<br>[620, 645, 5]"] | ||||
|     95["Segment<br>[653, 673, 5]"] | ||||
|     96["Segment<br>[681, 705, 5]"] | ||||
|     97["Segment<br>[713, 766, 5]"] | ||||
|     98["Segment<br>[774, 799, 5]"] | ||||
|     99["Segment<br>[807, 827, 5]"] | ||||
|     100["Segment<br>[835, 859, 5]"] | ||||
|     101["Segment<br>[867, 919, 5]"] | ||||
|     102["Segment<br>[927, 979, 5]"] | ||||
|     103["Segment<br>[987, 1012, 5]"] | ||||
|     104["Segment<br>[1020, 1044, 5]"] | ||||
|     105["Segment<br>[1052, 1105, 5]"] | ||||
|     106["Segment<br>[1113, 1138, 5]"] | ||||
|     107["Segment<br>[1146, 1173, 5]"] | ||||
|     108["Segment<br>[1181, 1233, 5]"] | ||||
|     109["Segment<br>[1241, 1276, 5]"] | ||||
|     110["Segment<br>[1284, 1291, 5]"] | ||||
|     111[Solid2d] | ||||
|   end | ||||
|   subgraph path176 [Path] | ||||
|     176["Path<br>[361, 394, 4]"] | ||||
|     177["Segment<br>[402, 428, 4]"] | ||||
|     178["Segment<br>[436, 489, 4]"] | ||||
|     179["Segment<br>[497, 550, 4]"] | ||||
|     180["Segment<br>[558, 612, 4]"] | ||||
|     181["Segment<br>[620, 645, 4]"] | ||||
|     182["Segment<br>[653, 673, 4]"] | ||||
|     183["Segment<br>[681, 705, 4]"] | ||||
|     184["Segment<br>[713, 766, 4]"] | ||||
|     185["Segment<br>[774, 799, 4]"] | ||||
|     186["Segment<br>[807, 827, 4]"] | ||||
|     187["Segment<br>[835, 859, 4]"] | ||||
|     188["Segment<br>[867, 919, 4]"] | ||||
|     189["Segment<br>[927, 979, 4]"] | ||||
|     190["Segment<br>[987, 1012, 4]"] | ||||
|     191["Segment<br>[1020, 1044, 4]"] | ||||
|     192["Segment<br>[1052, 1105, 4]"] | ||||
|     193["Segment<br>[1113, 1138, 4]"] | ||||
|     194["Segment<br>[1146, 1173, 4]"] | ||||
|     195["Segment<br>[1181, 1233, 4]"] | ||||
|     196["Segment<br>[1241, 1276, 4]"] | ||||
|     197["Segment<br>[1284, 1291, 4]"] | ||||
|     176["Path<br>[361, 394, 5]"] | ||||
|     177["Segment<br>[402, 428, 5]"] | ||||
|     178["Segment<br>[436, 489, 5]"] | ||||
|     179["Segment<br>[497, 550, 5]"] | ||||
|     180["Segment<br>[558, 612, 5]"] | ||||
|     181["Segment<br>[620, 645, 5]"] | ||||
|     182["Segment<br>[653, 673, 5]"] | ||||
|     183["Segment<br>[681, 705, 5]"] | ||||
|     184["Segment<br>[713, 766, 5]"] | ||||
|     185["Segment<br>[774, 799, 5]"] | ||||
|     186["Segment<br>[807, 827, 5]"] | ||||
|     187["Segment<br>[835, 859, 5]"] | ||||
|     188["Segment<br>[867, 919, 5]"] | ||||
|     189["Segment<br>[927, 979, 5]"] | ||||
|     190["Segment<br>[987, 1012, 5]"] | ||||
|     191["Segment<br>[1020, 1044, 5]"] | ||||
|     192["Segment<br>[1052, 1105, 5]"] | ||||
|     193["Segment<br>[1113, 1138, 5]"] | ||||
|     194["Segment<br>[1146, 1173, 5]"] | ||||
|     195["Segment<br>[1181, 1233, 5]"] | ||||
|     196["Segment<br>[1241, 1276, 5]"] | ||||
|     197["Segment<br>[1284, 1291, 5]"] | ||||
|     198[Solid2d] | ||||
|   end | ||||
|   subgraph path262 [Path] | ||||
|     262["Path<br>[361, 394, 4]"] | ||||
|     263["Segment<br>[402, 428, 4]"] | ||||
|     264["Segment<br>[436, 489, 4]"] | ||||
|     265["Segment<br>[497, 550, 4]"] | ||||
|     266["Segment<br>[558, 612, 4]"] | ||||
|     267["Segment<br>[620, 645, 4]"] | ||||
|     268["Segment<br>[653, 673, 4]"] | ||||
|     269["Segment<br>[681, 705, 4]"] | ||||
|     270["Segment<br>[713, 766, 4]"] | ||||
|     271["Segment<br>[774, 799, 4]"] | ||||
|     272["Segment<br>[807, 827, 4]"] | ||||
|     273["Segment<br>[835, 859, 4]"] | ||||
|     274["Segment<br>[867, 919, 4]"] | ||||
|     275["Segment<br>[927, 979, 4]"] | ||||
|     276["Segment<br>[987, 1012, 4]"] | ||||
|     277["Segment<br>[1020, 1044, 4]"] | ||||
|     278["Segment<br>[1052, 1105, 4]"] | ||||
|     279["Segment<br>[1113, 1138, 4]"] | ||||
|     280["Segment<br>[1146, 1173, 4]"] | ||||
|     281["Segment<br>[1181, 1233, 4]"] | ||||
|     282["Segment<br>[1241, 1276, 4]"] | ||||
|     283["Segment<br>[1284, 1291, 4]"] | ||||
|     262["Path<br>[361, 394, 5]"] | ||||
|     263["Segment<br>[402, 428, 5]"] | ||||
|     264["Segment<br>[436, 489, 5]"] | ||||
|     265["Segment<br>[497, 550, 5]"] | ||||
|     266["Segment<br>[558, 612, 5]"] | ||||
|     267["Segment<br>[620, 645, 5]"] | ||||
|     268["Segment<br>[653, 673, 5]"] | ||||
|     269["Segment<br>[681, 705, 5]"] | ||||
|     270["Segment<br>[713, 766, 5]"] | ||||
|     271["Segment<br>[774, 799, 5]"] | ||||
|     272["Segment<br>[807, 827, 5]"] | ||||
|     273["Segment<br>[835, 859, 5]"] | ||||
|     274["Segment<br>[867, 919, 5]"] | ||||
|     275["Segment<br>[927, 979, 5]"] | ||||
|     276["Segment<br>[987, 1012, 5]"] | ||||
|     277["Segment<br>[1020, 1044, 5]"] | ||||
|     278["Segment<br>[1052, 1105, 5]"] | ||||
|     279["Segment<br>[1113, 1138, 5]"] | ||||
|     280["Segment<br>[1146, 1173, 5]"] | ||||
|     281["Segment<br>[1181, 1233, 5]"] | ||||
|     282["Segment<br>[1241, 1276, 5]"] | ||||
|     283["Segment<br>[1284, 1291, 5]"] | ||||
|     284[Solid2d] | ||||
|   end | ||||
|   subgraph path349 [Path] | ||||
|     349["Path<br>[361, 394, 4]"] | ||||
|     350["Segment<br>[402, 428, 4]"] | ||||
|     351["Segment<br>[436, 489, 4]"] | ||||
|     352["Segment<br>[497, 550, 4]"] | ||||
|     353["Segment<br>[558, 612, 4]"] | ||||
|     354["Segment<br>[620, 645, 4]"] | ||||
|     355["Segment<br>[653, 673, 4]"] | ||||
|     356["Segment<br>[681, 705, 4]"] | ||||
|     357["Segment<br>[713, 766, 4]"] | ||||
|     358["Segment<br>[774, 799, 4]"] | ||||
|     359["Segment<br>[807, 827, 4]"] | ||||
|     360["Segment<br>[835, 859, 4]"] | ||||
|     361["Segment<br>[867, 919, 4]"] | ||||
|     362["Segment<br>[927, 979, 4]"] | ||||
|     363["Segment<br>[987, 1012, 4]"] | ||||
|     364["Segment<br>[1020, 1044, 4]"] | ||||
|     365["Segment<br>[1052, 1105, 4]"] | ||||
|     366["Segment<br>[1113, 1138, 4]"] | ||||
|     367["Segment<br>[1146, 1173, 4]"] | ||||
|     368["Segment<br>[1181, 1233, 4]"] | ||||
|     369["Segment<br>[1241, 1276, 4]"] | ||||
|     370["Segment<br>[1284, 1291, 4]"] | ||||
|     349["Path<br>[361, 394, 5]"] | ||||
|     350["Segment<br>[402, 428, 5]"] | ||||
|     351["Segment<br>[436, 489, 5]"] | ||||
|     352["Segment<br>[497, 550, 5]"] | ||||
|     353["Segment<br>[558, 612, 5]"] | ||||
|     354["Segment<br>[620, 645, 5]"] | ||||
|     355["Segment<br>[653, 673, 5]"] | ||||
|     356["Segment<br>[681, 705, 5]"] | ||||
|     357["Segment<br>[713, 766, 5]"] | ||||
|     358["Segment<br>[774, 799, 5]"] | ||||
|     359["Segment<br>[807, 827, 5]"] | ||||
|     360["Segment<br>[835, 859, 5]"] | ||||
|     361["Segment<br>[867, 919, 5]"] | ||||
|     362["Segment<br>[927, 979, 5]"] | ||||
|     363["Segment<br>[987, 1012, 5]"] | ||||
|     364["Segment<br>[1020, 1044, 5]"] | ||||
|     365["Segment<br>[1052, 1105, 5]"] | ||||
|     366["Segment<br>[1113, 1138, 5]"] | ||||
|     367["Segment<br>[1146, 1173, 5]"] | ||||
|     368["Segment<br>[1181, 1233, 5]"] | ||||
|     369["Segment<br>[1241, 1276, 5]"] | ||||
|     370["Segment<br>[1284, 1291, 5]"] | ||||
|     371[Solid2d] | ||||
|   end | ||||
|   subgraph path435 [Path] | ||||
|     435["Path<br>[361, 394, 4]"] | ||||
|     436["Segment<br>[402, 428, 4]"] | ||||
|     437["Segment<br>[436, 489, 4]"] | ||||
|     438["Segment<br>[497, 550, 4]"] | ||||
|     439["Segment<br>[558, 612, 4]"] | ||||
|     440["Segment<br>[620, 645, 4]"] | ||||
|     441["Segment<br>[653, 673, 4]"] | ||||
|     442["Segment<br>[681, 705, 4]"] | ||||
|     443["Segment<br>[713, 766, 4]"] | ||||
|     444["Segment<br>[774, 799, 4]"] | ||||
|     445["Segment<br>[807, 827, 4]"] | ||||
|     446["Segment<br>[835, 859, 4]"] | ||||
|     447["Segment<br>[867, 919, 4]"] | ||||
|     448["Segment<br>[927, 979, 4]"] | ||||
|     449["Segment<br>[987, 1012, 4]"] | ||||
|     450["Segment<br>[1020, 1044, 4]"] | ||||
|     451["Segment<br>[1052, 1105, 4]"] | ||||
|     452["Segment<br>[1113, 1138, 4]"] | ||||
|     453["Segment<br>[1146, 1173, 4]"] | ||||
|     454["Segment<br>[1181, 1233, 4]"] | ||||
|     455["Segment<br>[1241, 1276, 4]"] | ||||
|     456["Segment<br>[1284, 1291, 4]"] | ||||
|     435["Path<br>[361, 394, 5]"] | ||||
|     436["Segment<br>[402, 428, 5]"] | ||||
|     437["Segment<br>[436, 489, 5]"] | ||||
|     438["Segment<br>[497, 550, 5]"] | ||||
|     439["Segment<br>[558, 612, 5]"] | ||||
|     440["Segment<br>[620, 645, 5]"] | ||||
|     441["Segment<br>[653, 673, 5]"] | ||||
|     442["Segment<br>[681, 705, 5]"] | ||||
|     443["Segment<br>[713, 766, 5]"] | ||||
|     444["Segment<br>[774, 799, 5]"] | ||||
|     445["Segment<br>[807, 827, 5]"] | ||||
|     446["Segment<br>[835, 859, 5]"] | ||||
|     447["Segment<br>[867, 919, 5]"] | ||||
|     448["Segment<br>[927, 979, 5]"] | ||||
|     449["Segment<br>[987, 1012, 5]"] | ||||
|     450["Segment<br>[1020, 1044, 5]"] | ||||
|     451["Segment<br>[1052, 1105, 5]"] | ||||
|     452["Segment<br>[1113, 1138, 5]"] | ||||
|     453["Segment<br>[1146, 1173, 5]"] | ||||
|     454["Segment<br>[1181, 1233, 5]"] | ||||
|     455["Segment<br>[1241, 1276, 5]"] | ||||
|     456["Segment<br>[1284, 1291, 5]"] | ||||
|     457[Solid2d] | ||||
|   end | ||||
|   subgraph path522 [Path] | ||||
|     522["Path<br>[1685, 1709, 4]"] | ||||
|     522["Path<br>[1685, 1709, 5]"] | ||||
|   end | ||||
|   subgraph path523 [Path] | ||||
|     523["Path<br>[1717, 1847, 4]"] | ||||
|     524["Segment<br>[1717, 1847, 4]"] | ||||
|     525["Segment<br>[1717, 1847, 4]"] | ||||
|     526["Segment<br>[1717, 1847, 4]"] | ||||
|     527["Segment<br>[1717, 1847, 4]"] | ||||
|     528["Segment<br>[1717, 1847, 4]"] | ||||
|     529["Segment<br>[1717, 1847, 4]"] | ||||
|     530["Segment<br>[1717, 1847, 4]"] | ||||
|     523["Path<br>[1717, 1847, 5]"] | ||||
|     524["Segment<br>[1717, 1847, 5]"] | ||||
|     525["Segment<br>[1717, 1847, 5]"] | ||||
|     526["Segment<br>[1717, 1847, 5]"] | ||||
|     527["Segment<br>[1717, 1847, 5]"] | ||||
|     528["Segment<br>[1717, 1847, 5]"] | ||||
|     529["Segment<br>[1717, 1847, 5]"] | ||||
|     530["Segment<br>[1717, 1847, 5]"] | ||||
|     531[Solid2d] | ||||
|   end | ||||
|   subgraph path553 [Path] | ||||
|     553["Path<br>[1685, 1709, 4]"] | ||||
|     553["Path<br>[1685, 1709, 5]"] | ||||
|   end | ||||
|   subgraph path554 [Path] | ||||
|     554["Path<br>[1717, 1847, 4]"] | ||||
|     555["Segment<br>[1717, 1847, 4]"] | ||||
|     556["Segment<br>[1717, 1847, 4]"] | ||||
|     557["Segment<br>[1717, 1847, 4]"] | ||||
|     558["Segment<br>[1717, 1847, 4]"] | ||||
|     559["Segment<br>[1717, 1847, 4]"] | ||||
|     560["Segment<br>[1717, 1847, 4]"] | ||||
|     561["Segment<br>[1717, 1847, 4]"] | ||||
|     554["Path<br>[1717, 1847, 5]"] | ||||
|     555["Segment<br>[1717, 1847, 5]"] | ||||
|     556["Segment<br>[1717, 1847, 5]"] | ||||
|     557["Segment<br>[1717, 1847, 5]"] | ||||
|     558["Segment<br>[1717, 1847, 5]"] | ||||
|     559["Segment<br>[1717, 1847, 5]"] | ||||
|     560["Segment<br>[1717, 1847, 5]"] | ||||
|     561["Segment<br>[1717, 1847, 5]"] | ||||
|     562[Solid2d] | ||||
|   end | ||||
|   subgraph path585 [Path] | ||||
|     585["Path<br>[2123, 2150, 4]"] | ||||
|     586["Segment<br>[2158, 2180, 4]"] | ||||
|     587["Segment<br>[2188, 2210, 4]"] | ||||
|     588["Segment<br>[2218, 2240, 4]"] | ||||
|     589["Segment<br>[2248, 2271, 4]"] | ||||
|     590["Segment<br>[2279, 2302, 4]"] | ||||
|     591["Segment<br>[2310, 2345, 4]"] | ||||
|     592["Segment<br>[2353, 2360, 4]"] | ||||
|     585["Path<br>[2123, 2150, 5]"] | ||||
|     586["Segment<br>[2158, 2180, 5]"] | ||||
|     587["Segment<br>[2188, 2210, 5]"] | ||||
|     588["Segment<br>[2218, 2240, 5]"] | ||||
|     589["Segment<br>[2248, 2271, 5]"] | ||||
|     590["Segment<br>[2279, 2302, 5]"] | ||||
|     591["Segment<br>[2310, 2345, 5]"] | ||||
|     592["Segment<br>[2353, 2360, 5]"] | ||||
|     593[Solid2d] | ||||
|   end | ||||
|   subgraph path618 [Path] | ||||
|     618["Path<br>[2632, 2661, 4]"] | ||||
|     619["Segment<br>[2669, 2692, 4]"] | ||||
|     620["Segment<br>[2700, 2725, 4]"] | ||||
|     621["Segment<br>[2733, 2757, 4]"] | ||||
|     622["Segment<br>[2765, 2789, 4]"] | ||||
|     623["Segment<br>[2797, 2819, 4]"] | ||||
|     624["Segment<br>[2827, 2862, 4]"] | ||||
|     625["Segment<br>[2870, 2877, 4]"] | ||||
|     618["Path<br>[2632, 2661, 5]"] | ||||
|     619["Segment<br>[2669, 2692, 5]"] | ||||
|     620["Segment<br>[2700, 2725, 5]"] | ||||
|     621["Segment<br>[2733, 2757, 5]"] | ||||
|     622["Segment<br>[2765, 2789, 5]"] | ||||
|     623["Segment<br>[2797, 2819, 5]"] | ||||
|     624["Segment<br>[2827, 2862, 5]"] | ||||
|     625["Segment<br>[2870, 2877, 5]"] | ||||
|     626[Solid2d] | ||||
|   end | ||||
|   subgraph path650 [Path] | ||||
|     650["Path<br>[3152, 3179, 4]"] | ||||
|     651["Segment<br>[3187, 3206, 4]"] | ||||
|     652["Segment<br>[3214, 3304, 4]"] | ||||
|     650["Path<br>[3152, 3179, 5]"] | ||||
|     651["Segment<br>[3187, 3206, 5]"] | ||||
|     652["Segment<br>[3214, 3304, 5]"] | ||||
|   end | ||||
|   subgraph path654 [Path] | ||||
|     654["Path<br>[3404, 3437, 4]"] | ||||
|     655["Segment<br>[3445, 3464, 4]"] | ||||
|     656["Segment<br>[3472, 3494, 4]"] | ||||
|     657["Segment<br>[3502, 3525, 4]"] | ||||
|     658["Segment<br>[3533, 3553, 4]"] | ||||
|     659["Segment<br>[3561, 3585, 4]"] | ||||
|     660["Segment<br>[3593, 3616, 4]"] | ||||
|     661["Segment<br>[3624, 3631, 4]"] | ||||
|     654["Path<br>[3404, 3437, 5]"] | ||||
|     655["Segment<br>[3445, 3464, 5]"] | ||||
|     656["Segment<br>[3472, 3494, 5]"] | ||||
|     657["Segment<br>[3502, 3525, 5]"] | ||||
|     658["Segment<br>[3533, 3553, 5]"] | ||||
|     659["Segment<br>[3561, 3585, 5]"] | ||||
|     660["Segment<br>[3593, 3616, 5]"] | ||||
|     661["Segment<br>[3624, 3631, 5]"] | ||||
|     662[Solid2d] | ||||
|   end | ||||
|   subgraph path688 [Path] | ||||
|     688["Path<br>[3152, 3179, 4]"] | ||||
|     689["Segment<br>[3187, 3206, 4]"] | ||||
|     690["Segment<br>[3214, 3304, 4]"] | ||||
|     688["Path<br>[3152, 3179, 5]"] | ||||
|     689["Segment<br>[3187, 3206, 5]"] | ||||
|     690["Segment<br>[3214, 3304, 5]"] | ||||
|   end | ||||
|   subgraph path692 [Path] | ||||
|     692["Path<br>[3404, 3437, 4]"] | ||||
|     693["Segment<br>[3445, 3464, 4]"] | ||||
|     694["Segment<br>[3472, 3494, 4]"] | ||||
|     695["Segment<br>[3502, 3525, 4]"] | ||||
|     696["Segment<br>[3533, 3553, 4]"] | ||||
|     697["Segment<br>[3561, 3585, 4]"] | ||||
|     698["Segment<br>[3593, 3616, 4]"] | ||||
|     699["Segment<br>[3624, 3631, 4]"] | ||||
|     692["Path<br>[3404, 3437, 5]"] | ||||
|     693["Segment<br>[3445, 3464, 5]"] | ||||
|     694["Segment<br>[3472, 3494, 5]"] | ||||
|     695["Segment<br>[3502, 3525, 5]"] | ||||
|     696["Segment<br>[3533, 3553, 5]"] | ||||
|     697["Segment<br>[3561, 3585, 5]"] | ||||
|     698["Segment<br>[3593, 3616, 5]"] | ||||
|     699["Segment<br>[3624, 3631, 5]"] | ||||
|     700[Solid2d] | ||||
|   end | ||||
|   1["Plane<br>[333, 353, 4]"] | ||||
|   25["Sweep Extrusion<br>[1379, 1417, 4]"] | ||||
|   1["Plane<br>[333, 353, 5]"] | ||||
|   25["Sweep Extrusion<br>[1379, 1417, 5]"] | ||||
|   26[Wall] | ||||
|   27[Wall] | ||||
|   28[Wall] | ||||
| @ -296,8 +296,8 @@ flowchart LR | ||||
|   85["SweepEdge Adjacent"] | ||||
|   86["SweepEdge Opposite"] | ||||
|   87["SweepEdge Adjacent"] | ||||
|   88["Plane<br>[333, 353, 4]"] | ||||
|   112["Sweep Extrusion<br>[1455, 1494, 4]"] | ||||
|   88["Plane<br>[333, 353, 5]"] | ||||
|   112["Sweep Extrusion<br>[1455, 1494, 5]"] | ||||
|   113[Wall] | ||||
|   114[Wall] | ||||
|   115[Wall] | ||||
| @ -361,7 +361,7 @@ flowchart LR | ||||
|   173["SweepEdge Opposite"] | ||||
|   174["SweepEdge Adjacent"] | ||||
|   175["Plane<br>[823, 865, 0]"] | ||||
|   199["Sweep Extrusion<br>[1379, 1417, 4]"] | ||||
|   199["Sweep Extrusion<br>[1379, 1417, 5]"] | ||||
|   200[Wall] | ||||
|   201[Wall] | ||||
|   202[Wall] | ||||
| @ -424,7 +424,7 @@ flowchart LR | ||||
|   259["SweepEdge Adjacent"] | ||||
|   260["SweepEdge Opposite"] | ||||
|   261["SweepEdge Adjacent"] | ||||
|   285["Sweep Extrusion<br>[1455, 1494, 4]"] | ||||
|   285["Sweep Extrusion<br>[1455, 1494, 5]"] | ||||
|   286[Wall] | ||||
|   287[Wall] | ||||
|   288[Wall] | ||||
| @ -488,7 +488,7 @@ flowchart LR | ||||
|   346["SweepEdge Opposite"] | ||||
|   347["SweepEdge Adjacent"] | ||||
|   348["Plane<br>[875, 916, 0]"] | ||||
|   372["Sweep Extrusion<br>[1379, 1417, 4]"] | ||||
|   372["Sweep Extrusion<br>[1379, 1417, 5]"] | ||||
|   373[Wall] | ||||
|   374[Wall] | ||||
|   375[Wall] | ||||
| @ -551,7 +551,7 @@ flowchart LR | ||||
|   432["SweepEdge Adjacent"] | ||||
|   433["SweepEdge Opposite"] | ||||
|   434["SweepEdge Adjacent"] | ||||
|   458["Sweep Extrusion<br>[1455, 1494, 4]"] | ||||
|   458["Sweep Extrusion<br>[1455, 1494, 5]"] | ||||
|   459[Wall] | ||||
|   460[Wall] | ||||
|   461[Wall] | ||||
| @ -615,7 +615,7 @@ flowchart LR | ||||
|   519["SweepEdge Opposite"] | ||||
|   520["SweepEdge Adjacent"] | ||||
|   521["Plane<br>[975, 1017, 0]"] | ||||
|   532["Sweep Extrusion<br>[1949, 1973, 4]"] | ||||
|   532["Sweep Extrusion<br>[1949, 1973, 5]"] | ||||
|   533[Wall] | ||||
|   534[Wall] | ||||
|   535[Wall] | ||||
| @ -636,7 +636,7 @@ flowchart LR | ||||
|   550["SweepEdge Adjacent"] | ||||
|   551["SweepEdge Opposite"] | ||||
|   552["SweepEdge Adjacent"] | ||||
|   563["Sweep Extrusion<br>[2015, 2039, 4]"] | ||||
|   563["Sweep Extrusion<br>[2015, 2039, 5]"] | ||||
|   564[Wall] | ||||
|   565[Wall] | ||||
|   566[Wall] | ||||
| @ -658,7 +658,7 @@ flowchart LR | ||||
|   582["SweepEdge Opposite"] | ||||
|   583["SweepEdge Adjacent"] | ||||
|   584["Plane<br>[1068, 1135, 0]"] | ||||
|   594["Sweep Extrusion<br>[2523, 2547, 4]"] | ||||
|   594["Sweep Extrusion<br>[2523, 2547, 5]"] | ||||
|   595[Wall] | ||||
|   596[Wall] | ||||
|   597[Wall] | ||||
| @ -679,10 +679,10 @@ flowchart LR | ||||
|   612["SweepEdge Adjacent"] | ||||
|   613["SweepEdge Opposite"] | ||||
|   614["SweepEdge Adjacent"] | ||||
|   615["Sweep Extrusion<br>[2523, 2547, 4]"] | ||||
|   616["Sweep Extrusion<br>[2523, 2547, 4]"] | ||||
|   615["Sweep Extrusion<br>[2523, 2547, 5]"] | ||||
|   616["Sweep Extrusion<br>[2523, 2547, 5]"] | ||||
|   617["Plane<br>[1205, 1272, 0]"] | ||||
|   627["Sweep Extrusion<br>[3047, 3071, 4]"] | ||||
|   627["Sweep Extrusion<br>[3047, 3071, 5]"] | ||||
|   628[Wall] | ||||
|   629[Wall] | ||||
|   630[Wall] | ||||
| @ -703,10 +703,10 @@ flowchart LR | ||||
|   645["SweepEdge Adjacent"] | ||||
|   646["SweepEdge Opposite"] | ||||
|   647["SweepEdge Adjacent"] | ||||
|   648["Sweep Extrusion<br>[3047, 3071, 4]"] | ||||
|   649["Plane<br>[3712, 3747, 4]"] | ||||
|   653["Plane<br>[3778, 3807, 4]"] | ||||
|   663["Sweep Sweep<br>[3819, 3846, 4]"] | ||||
|   648["Sweep Extrusion<br>[3047, 3071, 5]"] | ||||
|   649["Plane<br>[3712, 3747, 5]"] | ||||
|   653["Plane<br>[3778, 3807, 5]"] | ||||
|   663["Sweep Sweep<br>[3819, 3846, 5]"] | ||||
|   664[Wall] | ||||
|   665[Wall] | ||||
|   666[Wall] | ||||
| @ -730,9 +730,9 @@ flowchart LR | ||||
|   684["SweepEdge Adjacent"] | ||||
|   685["SweepEdge Opposite"] | ||||
|   686["SweepEdge Adjacent"] | ||||
|   687["Plane<br>[3712, 3747, 4]"] | ||||
|   691["Plane<br>[3778, 3807, 4]"] | ||||
|   701["Sweep Sweep<br>[3819, 3846, 4]"] | ||||
|   687["Plane<br>[3712, 3747, 5]"] | ||||
|   691["Plane<br>[3778, 3807, 5]"] | ||||
|   701["Sweep Sweep<br>[3819, 3846, 5]"] | ||||
|   702[Wall] | ||||
|   703[Wall] | ||||
|   704[Wall] | ||||
| @ -756,18 +756,18 @@ flowchart LR | ||||
|   722["SweepEdge Adjacent"] | ||||
|   723["SweepEdge Opposite"] | ||||
|   724["SweepEdge Adjacent"] | ||||
|   725["StartSketchOnPlane<br>[333, 353, 4]"] | ||||
|   726["StartSketchOnPlane<br>[333, 353, 4]"] | ||||
|   727["StartSketchOnPlane<br>[333, 353, 4]"] | ||||
|   728["StartSketchOnPlane<br>[333, 353, 4]"] | ||||
|   729["StartSketchOnPlane<br>[1657, 1677, 4]"] | ||||
|   730["StartSketchOnPlane<br>[1657, 1677, 4]"] | ||||
|   731["StartSketchOnPlane<br>[2095, 2115, 4]"] | ||||
|   732["StartSketchOnPlane<br>[2604, 2624, 4]"] | ||||
|   733["StartSketchOnPlane<br>[3124, 3144, 4]"] | ||||
|   734["StartSketchOnPlane<br>[3376, 3396, 4]"] | ||||
|   735["StartSketchOnPlane<br>[3124, 3144, 4]"] | ||||
|   736["StartSketchOnPlane<br>[3376, 3396, 4]"] | ||||
|   725["StartSketchOnPlane<br>[333, 353, 5]"] | ||||
|   726["StartSketchOnPlane<br>[333, 353, 5]"] | ||||
|   727["StartSketchOnPlane<br>[333, 353, 5]"] | ||||
|   728["StartSketchOnPlane<br>[333, 353, 5]"] | ||||
|   729["StartSketchOnPlane<br>[1657, 1677, 5]"] | ||||
|   730["StartSketchOnPlane<br>[1657, 1677, 5]"] | ||||
|   731["StartSketchOnPlane<br>[2095, 2115, 5]"] | ||||
|   732["StartSketchOnPlane<br>[2604, 2624, 5]"] | ||||
|   733["StartSketchOnPlane<br>[3124, 3144, 5]"] | ||||
|   734["StartSketchOnPlane<br>[3376, 3396, 5]"] | ||||
|   735["StartSketchOnPlane<br>[3124, 3144, 5]"] | ||||
|   736["StartSketchOnPlane<br>[3376, 3396, 5]"] | ||||
|   1 --- 2 | ||||
|   2 --- 3 | ||||
|   2 --- 4 | ||||
|  | ||||
| @ -9,7 +9,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       1331, | ||||
|       1606, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -21,7 +21,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       309, | ||||
|       1312, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -77,7 +77,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       309, | ||||
|       1312, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -248,7 +248,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       1331, | ||||
|       1606, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -260,7 +260,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       309, | ||||
|       1312, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -316,7 +316,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       309, | ||||
|       1312, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -487,7 +487,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       1331, | ||||
|       1606, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -499,7 +499,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       309, | ||||
|       1312, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -555,7 +555,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       309, | ||||
|       1312, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -726,7 +726,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       1889, | ||||
|       2052, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -738,7 +738,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       1626, | ||||
|       1868, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -800,7 +800,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       1626, | ||||
|       1868, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -889,7 +889,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       2474, | ||||
|       2560, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -901,7 +901,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       2071, | ||||
|       2453, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1007,7 +1007,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       2993, | ||||
|       3084, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1019,7 +1019,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       2580, | ||||
|       2972, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1095,7 +1095,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       3671, | ||||
|       3859, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1131,7 +1131,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       3100, | ||||
|       3325, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1191,7 +1191,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       3344, | ||||
|       3652, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1249,7 +1249,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       3671, | ||||
|       3859, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1285,7 +1285,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       3100, | ||||
|       3325, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1345,7 +1345,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       3344, | ||||
|       3652, | ||||
|       4 | ||||
|       5 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
|  | ||||
| @ -1,264 +1,264 @@ | ||||
| ```mermaid | ||||
| flowchart LR | ||||
|   subgraph path2 [Path] | ||||
|     2["Path<br>[567, 618, 5]"] | ||||
|     3["Segment<br>[567, 618, 5]"] | ||||
|     2["Path<br>[567, 618, 6]"] | ||||
|     3["Segment<br>[567, 618, 6]"] | ||||
|     4[Solid2d] | ||||
|   end | ||||
|   subgraph path11 [Path] | ||||
|     11["Path<br>[803, 859, 5]"] | ||||
|     12["Segment<br>[803, 859, 5]"] | ||||
|     11["Path<br>[803, 859, 6]"] | ||||
|     12["Segment<br>[803, 859, 6]"] | ||||
|     13[Solid2d] | ||||
|   end | ||||
|   subgraph path19 [Path] | ||||
|     19["Path<br>[984, 1037, 5]"] | ||||
|     20["Segment<br>[984, 1037, 5]"] | ||||
|     19["Path<br>[984, 1037, 6]"] | ||||
|     20["Segment<br>[984, 1037, 6]"] | ||||
|     21[Solid2d] | ||||
|   end | ||||
|   subgraph path30 [Path] | ||||
|     30["Path<br>[1420, 1460, 5]"] | ||||
|     31["Segment<br>[1420, 1460, 5]"] | ||||
|     30["Path<br>[1420, 1460, 6]"] | ||||
|     31["Segment<br>[1420, 1460, 6]"] | ||||
|     32[Solid2d] | ||||
|   end | ||||
|   subgraph path38 [Path] | ||||
|     38["Path<br>[1564, 1615, 5]"] | ||||
|     39["Segment<br>[1564, 1615, 5]"] | ||||
|     38["Path<br>[1564, 1615, 6]"] | ||||
|     39["Segment<br>[1564, 1615, 6]"] | ||||
|     40[Solid2d] | ||||
|   end | ||||
|   subgraph path47 [Path] | ||||
|     47["Path<br>[1748, 1801, 5]"] | ||||
|     48["Segment<br>[1748, 1801, 5]"] | ||||
|     47["Path<br>[1748, 1801, 6]"] | ||||
|     48["Segment<br>[1748, 1801, 6]"] | ||||
|     49[Solid2d] | ||||
|   end | ||||
|   subgraph path58 [Path] | ||||
|     58["Path<br>[2044, 2116, 5]"] | ||||
|     59["Segment<br>[2044, 2116, 5]"] | ||||
|     58["Path<br>[2044, 2116, 6]"] | ||||
|     59["Segment<br>[2044, 2116, 6]"] | ||||
|     60[Solid2d] | ||||
|   end | ||||
|   subgraph path81 [Path] | ||||
|     81["Path<br>[2373, 2404, 5]"] | ||||
|     82["Segment<br>[2410, 2430, 5]"] | ||||
|     83["Segment<br>[2436, 2456, 5]"] | ||||
|     84["Segment<br>[2462, 2483, 5]"] | ||||
|     85["Segment<br>[2489, 2545, 5]"] | ||||
|     86["Segment<br>[2551, 2558, 5]"] | ||||
|     81["Path<br>[2373, 2404, 6]"] | ||||
|     82["Segment<br>[2410, 2430, 6]"] | ||||
|     83["Segment<br>[2436, 2456, 6]"] | ||||
|     84["Segment<br>[2462, 2483, 6]"] | ||||
|     85["Segment<br>[2489, 2545, 6]"] | ||||
|     86["Segment<br>[2551, 2558, 6]"] | ||||
|     87[Solid2d] | ||||
|   end | ||||
|   subgraph path106 [Path] | ||||
|     106["Path<br>[2860, 2892, 5]"] | ||||
|     107["Segment<br>[2898, 2919, 5]"] | ||||
|     108["Segment<br>[2925, 2945, 5]"] | ||||
|     109["Segment<br>[2951, 2971, 5]"] | ||||
|     110["Segment<br>[2977, 3033, 5]"] | ||||
|     111["Segment<br>[3039, 3046, 5]"] | ||||
|     106["Path<br>[2860, 2892, 6]"] | ||||
|     107["Segment<br>[2898, 2919, 6]"] | ||||
|     108["Segment<br>[2925, 2945, 6]"] | ||||
|     109["Segment<br>[2951, 2971, 6]"] | ||||
|     110["Segment<br>[2977, 3033, 6]"] | ||||
|     111["Segment<br>[3039, 3046, 6]"] | ||||
|     112[Solid2d] | ||||
|   end | ||||
|   subgraph path132 [Path] | ||||
|     132["Path<br>[350, 406, 4]"] | ||||
|     133["Segment<br>[350, 406, 4]"] | ||||
|     132["Path<br>[350, 406, 5]"] | ||||
|     133["Segment<br>[350, 406, 5]"] | ||||
|     134[Solid2d] | ||||
|   end | ||||
|   subgraph path135 [Path] | ||||
|     135["Path<br>[417, 473, 4]"] | ||||
|     136["Segment<br>[417, 473, 4]"] | ||||
|     135["Path<br>[417, 473, 5]"] | ||||
|     136["Segment<br>[417, 473, 5]"] | ||||
|     137[Solid2d] | ||||
|   end | ||||
|   subgraph path144 [Path] | ||||
|     144["Path<br>[638, 694, 4]"] | ||||
|     145["Segment<br>[638, 694, 4]"] | ||||
|     144["Path<br>[638, 694, 5]"] | ||||
|     145["Segment<br>[638, 694, 5]"] | ||||
|     146[Solid2d] | ||||
|   end | ||||
|   subgraph path147 [Path] | ||||
|     147["Path<br>[705, 761, 4]"] | ||||
|     148["Segment<br>[705, 761, 4]"] | ||||
|     147["Path<br>[705, 761, 5]"] | ||||
|     148["Segment<br>[705, 761, 5]"] | ||||
|     149[Solid2d] | ||||
|   end | ||||
|   subgraph path156 [Path] | ||||
|     156["Path<br>[905, 959, 4]"] | ||||
|     157["Segment<br>[905, 959, 4]"] | ||||
|     156["Path<br>[905, 959, 5]"] | ||||
|     157["Segment<br>[905, 959, 5]"] | ||||
|     158[Solid2d] | ||||
|   end | ||||
|   subgraph path167 [Path] | ||||
|     167["Path<br>[1237, 1297, 4]"] | ||||
|     168["Segment<br>[1237, 1297, 4]"] | ||||
|     167["Path<br>[1237, 1297, 5]"] | ||||
|     168["Segment<br>[1237, 1297, 5]"] | ||||
|     169[Solid2d] | ||||
|   end | ||||
|   subgraph path179 [Path] | ||||
|     179["Path<br>[1655, 1701, 4]"] | ||||
|     180["Segment<br>[1707, 1759, 4]"] | ||||
|     181["Segment<br>[1765, 1870, 4]"] | ||||
|     182["Segment<br>[1876, 1898, 4]"] | ||||
|     183["Segment<br>[1904, 1960, 4]"] | ||||
|     184["Segment<br>[1966, 1973, 4]"] | ||||
|     179["Path<br>[1655, 1701, 5]"] | ||||
|     180["Segment<br>[1707, 1759, 5]"] | ||||
|     181["Segment<br>[1765, 1870, 5]"] | ||||
|     182["Segment<br>[1876, 1898, 5]"] | ||||
|     183["Segment<br>[1904, 1960, 5]"] | ||||
|     184["Segment<br>[1966, 1973, 5]"] | ||||
|     185[Solid2d] | ||||
|   end | ||||
|   subgraph path195 [Path] | ||||
|     195["Path<br>[2107, 2153, 4]"] | ||||
|     196["Segment<br>[2159, 2211, 4]"] | ||||
|     197["Segment<br>[2217, 2324, 4]"] | ||||
|     198["Segment<br>[2330, 2367, 4]"] | ||||
|     199["Segment<br>[2373, 2429, 4]"] | ||||
|     200["Segment<br>[2435, 2442, 4]"] | ||||
|     195["Path<br>[2105, 2151, 5]"] | ||||
|     196["Segment<br>[2157, 2209, 5]"] | ||||
|     197["Segment<br>[2215, 2322, 5]"] | ||||
|     198["Segment<br>[2328, 2365, 5]"] | ||||
|     199["Segment<br>[2371, 2427, 5]"] | ||||
|     200["Segment<br>[2433, 2440, 5]"] | ||||
|     201[Solid2d] | ||||
|   end | ||||
|   subgraph path212 [Path] | ||||
|     212["Path<br>[2953, 3000, 4]"] | ||||
|     213["Segment<br>[3008, 3348, 4]"] | ||||
|     214["Segment<br>[3356, 3388, 4]"] | ||||
|     215["Segment<br>[3396, 3740, 4]"] | ||||
|     216["Segment<br>[3748, 3804, 4]"] | ||||
|     217["Segment<br>[3812, 3819, 4]"] | ||||
|     212["Path<br>[2949, 2996, 5]"] | ||||
|     213["Segment<br>[3004, 3344, 5]"] | ||||
|     214["Segment<br>[3352, 3384, 5]"] | ||||
|     215["Segment<br>[3392, 3736, 5]"] | ||||
|     216["Segment<br>[3744, 3800, 5]"] | ||||
|     217["Segment<br>[3808, 3815, 5]"] | ||||
|     218[Solid2d] | ||||
|   end | ||||
|   subgraph path235 [Path] | ||||
|     235["Path<br>[2953, 3000, 4]"] | ||||
|     236["Segment<br>[3008, 3348, 4]"] | ||||
|     237["Segment<br>[3356, 3388, 4]"] | ||||
|     238["Segment<br>[3396, 3740, 4]"] | ||||
|     239["Segment<br>[3748, 3804, 4]"] | ||||
|     240["Segment<br>[3812, 3819, 4]"] | ||||
|     235["Path<br>[2949, 2996, 5]"] | ||||
|     236["Segment<br>[3004, 3344, 5]"] | ||||
|     237["Segment<br>[3352, 3384, 5]"] | ||||
|     238["Segment<br>[3392, 3736, 5]"] | ||||
|     239["Segment<br>[3744, 3800, 5]"] | ||||
|     240["Segment<br>[3808, 3815, 5]"] | ||||
|     241[Solid2d] | ||||
|   end | ||||
|   subgraph path258 [Path] | ||||
|     258["Path<br>[4347, 4442, 4]"] | ||||
|     259["Segment<br>[4448, 4481, 4]"] | ||||
|     260["Segment<br>[4487, 4538, 4]"] | ||||
|     261["Segment<br>[4544, 4577, 4]"] | ||||
|     262["Segment<br>[4583, 4633, 4]"] | ||||
|     263["Segment<br>[4639, 4680, 4]"] | ||||
|     264["Segment<br>[4686, 4735, 4]"] | ||||
|     265["Segment<br>[4741, 4774, 4]"] | ||||
|     266["Segment<br>[4780, 4814, 4]"] | ||||
|     267["Segment<br>[4820, 4854, 4]"] | ||||
|     268["Segment<br>[4860, 4912, 4]"] | ||||
|     269["Segment<br>[4918, 4952, 4]"] | ||||
|     270["Segment<br>[4958, 5034, 4]"] | ||||
|     271["Segment<br>[5040, 5073, 4]"] | ||||
|     272["Segment<br>[5079, 5155, 4]"] | ||||
|     273["Segment<br>[5161, 5195, 4]"] | ||||
|     274["Segment<br>[5201, 5275, 4]"] | ||||
|     275["Segment<br>[5281, 5315, 4]"] | ||||
|     276["Segment<br>[5321, 5372, 4]"] | ||||
|     277["Segment<br>[5378, 5440, 4]"] | ||||
|     278["Segment<br>[5446, 5497, 4]"] | ||||
|     279["Segment<br>[5503, 5537, 4]"] | ||||
|     280["Segment<br>[5543, 5576, 4]"] | ||||
|     281["Segment<br>[5582, 5615, 4]"] | ||||
|     282["Segment<br>[5621, 5628, 4]"] | ||||
|     258["Path<br>[4343, 4438, 5]"] | ||||
|     259["Segment<br>[4444, 4477, 5]"] | ||||
|     260["Segment<br>[4483, 4534, 5]"] | ||||
|     261["Segment<br>[4540, 4573, 5]"] | ||||
|     262["Segment<br>[4579, 4629, 5]"] | ||||
|     263["Segment<br>[4635, 4676, 5]"] | ||||
|     264["Segment<br>[4682, 4731, 5]"] | ||||
|     265["Segment<br>[4737, 4770, 5]"] | ||||
|     266["Segment<br>[4776, 4810, 5]"] | ||||
|     267["Segment<br>[4816, 4850, 5]"] | ||||
|     268["Segment<br>[4856, 4908, 5]"] | ||||
|     269["Segment<br>[4914, 4948, 5]"] | ||||
|     270["Segment<br>[4954, 5030, 5]"] | ||||
|     271["Segment<br>[5036, 5069, 5]"] | ||||
|     272["Segment<br>[5075, 5151, 5]"] | ||||
|     273["Segment<br>[5157, 5191, 5]"] | ||||
|     274["Segment<br>[5197, 5271, 5]"] | ||||
|     275["Segment<br>[5277, 5311, 5]"] | ||||
|     276["Segment<br>[5317, 5368, 5]"] | ||||
|     277["Segment<br>[5374, 5436, 5]"] | ||||
|     278["Segment<br>[5442, 5493, 5]"] | ||||
|     279["Segment<br>[5499, 5533, 5]"] | ||||
|     280["Segment<br>[5539, 5572, 5]"] | ||||
|     281["Segment<br>[5578, 5611, 5]"] | ||||
|     282["Segment<br>[5617, 5624, 5]"] | ||||
|     283[Solid2d] | ||||
|   end | ||||
|   subgraph path334 [Path] | ||||
|     334["Path<br>[740, 780, 7]"] | ||||
|     335["Segment<br>[788, 850, 7]"] | ||||
|     336["Segment<br>[858, 894, 7]"] | ||||
|     337["Segment<br>[902, 932, 7]"] | ||||
|     338["Segment<br>[940, 992, 7]"] | ||||
|     339["Segment<br>[1000, 1040, 7]"] | ||||
|     340["Segment<br>[1048, 1083, 7]"] | ||||
|     341["Segment<br>[1091, 1129, 7]"] | ||||
|     342["Segment<br>[1137, 1159, 7]"] | ||||
|     343["Segment<br>[1167, 1174, 7]"] | ||||
|     334["Path<br>[740, 780, 8]"] | ||||
|     335["Segment<br>[788, 850, 8]"] | ||||
|     336["Segment<br>[858, 894, 8]"] | ||||
|     337["Segment<br>[902, 932, 8]"] | ||||
|     338["Segment<br>[940, 992, 8]"] | ||||
|     339["Segment<br>[1000, 1040, 8]"] | ||||
|     340["Segment<br>[1048, 1083, 8]"] | ||||
|     341["Segment<br>[1091, 1129, 8]"] | ||||
|     342["Segment<br>[1137, 1159, 8]"] | ||||
|     343["Segment<br>[1167, 1174, 8]"] | ||||
|     344[Solid2d] | ||||
|   end | ||||
|   subgraph path365 [Path] | ||||
|     365["Path<br>[507, 588, 6]"] | ||||
|     366["Segment<br>[594, 695, 6]"] | ||||
|     367["Segment<br>[701, 786, 6]"] | ||||
|     368["Segment<br>[792, 876, 6]"] | ||||
|     369["Segment<br>[882, 968, 6]"] | ||||
|     370["Segment<br>[974, 1059, 6]"] | ||||
|     371["Segment<br>[1065, 1151, 6]"] | ||||
|     372["Segment<br>[1157, 1280, 6]"] | ||||
|     373["Segment<br>[1286, 1372, 6]"] | ||||
|     374["Segment<br>[1378, 1513, 6]"] | ||||
|     375["Segment<br>[1519, 1605, 6]"] | ||||
|     376["Segment<br>[1611, 1735, 6]"] | ||||
|     377["Segment<br>[1741, 1827, 6]"] | ||||
|     378["Segment<br>[1833, 1918, 6]"] | ||||
|     379["Segment<br>[1924, 2010, 6]"] | ||||
|     380["Segment<br>[2016, 2101, 6]"] | ||||
|     381["Segment<br>[2107, 2192, 6]"] | ||||
|     382["Segment<br>[2198, 2205, 6]"] | ||||
|     365["Path<br>[507, 588, 7]"] | ||||
|     366["Segment<br>[594, 695, 7]"] | ||||
|     367["Segment<br>[701, 786, 7]"] | ||||
|     368["Segment<br>[792, 876, 7]"] | ||||
|     369["Segment<br>[882, 968, 7]"] | ||||
|     370["Segment<br>[974, 1059, 7]"] | ||||
|     371["Segment<br>[1065, 1151, 7]"] | ||||
|     372["Segment<br>[1157, 1280, 7]"] | ||||
|     373["Segment<br>[1286, 1372, 7]"] | ||||
|     374["Segment<br>[1378, 1513, 7]"] | ||||
|     375["Segment<br>[1519, 1605, 7]"] | ||||
|     376["Segment<br>[1611, 1735, 7]"] | ||||
|     377["Segment<br>[1741, 1827, 7]"] | ||||
|     378["Segment<br>[1833, 1918, 7]"] | ||||
|     379["Segment<br>[1924, 2010, 7]"] | ||||
|     380["Segment<br>[2016, 2101, 7]"] | ||||
|     381["Segment<br>[2107, 2192, 7]"] | ||||
|     382["Segment<br>[2198, 2205, 7]"] | ||||
|     383[Solid2d] | ||||
|   end | ||||
|   subgraph path439 [Path] | ||||
|     439["Path<br>[483, 540, 8]"] | ||||
|     440["Segment<br>[546, 680, 8]"] | ||||
|     441["Segment<br>[686, 741, 8]"] | ||||
|     442["Segment<br>[747, 844, 8]"] | ||||
|     443["Segment<br>[850, 882, 8]"] | ||||
|     444["Segment<br>[888, 920, 8]"] | ||||
|     445["Segment<br>[926, 957, 8]"] | ||||
|     446["Segment<br>[963, 1078, 8]"] | ||||
|     447["Segment<br>[1084, 1116, 8]"] | ||||
|     448["Segment<br>[1122, 1154, 8]"] | ||||
|     449["Segment<br>[1160, 1191, 8]"] | ||||
|     450["Segment<br>[1197, 1290, 8]"] | ||||
|     451["Segment<br>[1296, 1351, 8]"] | ||||
|     452["Segment<br>[1357, 1430, 8]"] | ||||
|     453["Segment<br>[1436, 1443, 8]"] | ||||
|     439["Path<br>[483, 540, 9]"] | ||||
|     440["Segment<br>[546, 680, 9]"] | ||||
|     441["Segment<br>[686, 741, 9]"] | ||||
|     442["Segment<br>[747, 844, 9]"] | ||||
|     443["Segment<br>[850, 882, 9]"] | ||||
|     444["Segment<br>[888, 920, 9]"] | ||||
|     445["Segment<br>[926, 957, 9]"] | ||||
|     446["Segment<br>[963, 1078, 9]"] | ||||
|     447["Segment<br>[1084, 1116, 9]"] | ||||
|     448["Segment<br>[1122, 1154, 9]"] | ||||
|     449["Segment<br>[1160, 1191, 9]"] | ||||
|     450["Segment<br>[1197, 1290, 9]"] | ||||
|     451["Segment<br>[1296, 1351, 9]"] | ||||
|     452["Segment<br>[1357, 1430, 9]"] | ||||
|     453["Segment<br>[1436, 1443, 9]"] | ||||
|     454[Solid2d] | ||||
|   end | ||||
|   1["Plane<br>[544, 561, 5]"] | ||||
|   5["Sweep Extrusion<br>[627, 683, 5]"] | ||||
|   1["Plane<br>[544, 561, 6]"] | ||||
|   5["Sweep Extrusion<br>[627, 683, 6]"] | ||||
|   6[Wall] | ||||
|   7["Cap Start"] | ||||
|   8["Cap End"] | ||||
|   9["SweepEdge Opposite"] | ||||
|   10["SweepEdge Adjacent"] | ||||
|   14["Sweep Extrusion<br>[872, 934, 5]"] | ||||
|   14["Sweep Extrusion<br>[872, 934, 6]"] | ||||
|   15[Wall] | ||||
|   16["Cap End"] | ||||
|   17["SweepEdge Opposite"] | ||||
|   18["SweepEdge Adjacent"] | ||||
|   22["Sweep Extrusion<br>[1184, 1263, 5]"] | ||||
|   22["Sweep Extrusion<br>[1184, 1263, 6]"] | ||||
|   23[Wall] | ||||
|   24["SweepEdge Opposite"] | ||||
|   25["SweepEdge Adjacent"] | ||||
|   26["Sweep Extrusion<br>[1184, 1263, 5]"] | ||||
|   27["Sweep Extrusion<br>[1184, 1263, 5]"] | ||||
|   28["Sweep Extrusion<br>[1184, 1263, 5]"] | ||||
|   29["Sweep Extrusion<br>[1184, 1263, 5]"] | ||||
|   33["Sweep Extrusion<br>[1466, 1499, 5]"] | ||||
|   26["Sweep Extrusion<br>[1184, 1263, 6]"] | ||||
|   27["Sweep Extrusion<br>[1184, 1263, 6]"] | ||||
|   28["Sweep Extrusion<br>[1184, 1263, 6]"] | ||||
|   29["Sweep Extrusion<br>[1184, 1263, 6]"] | ||||
|   33["Sweep Extrusion<br>[1466, 1499, 6]"] | ||||
|   34[Wall] | ||||
|   35["Cap End"] | ||||
|   36["SweepEdge Opposite"] | ||||
|   37["SweepEdge Adjacent"] | ||||
|   41["Sweep Extrusion<br>[1630, 1695, 5]"] | ||||
|   41["Sweep Extrusion<br>[1630, 1695, 6]"] | ||||
|   42[Wall] | ||||
|   43["Cap Start"] | ||||
|   44["Cap End"] | ||||
|   45["SweepEdge Opposite"] | ||||
|   46["SweepEdge Adjacent"] | ||||
|   50["Sweep Extrusion<br>[1948, 1992, 5]"] | ||||
|   50["Sweep Extrusion<br>[1948, 1992, 6]"] | ||||
|   51[Wall] | ||||
|   52["SweepEdge Opposite"] | ||||
|   53["SweepEdge Adjacent"] | ||||
|   54["Sweep Extrusion<br>[1948, 1992, 5]"] | ||||
|   55["Sweep Extrusion<br>[1948, 1992, 5]"] | ||||
|   56["Sweep Extrusion<br>[1948, 1992, 5]"] | ||||
|   57["Sweep Extrusion<br>[1948, 1992, 5]"] | ||||
|   61["Sweep Extrusion<br>[2271, 2315, 5]"] | ||||
|   54["Sweep Extrusion<br>[1948, 1992, 6]"] | ||||
|   55["Sweep Extrusion<br>[1948, 1992, 6]"] | ||||
|   56["Sweep Extrusion<br>[1948, 1992, 6]"] | ||||
|   57["Sweep Extrusion<br>[1948, 1992, 6]"] | ||||
|   61["Sweep Extrusion<br>[2271, 2315, 6]"] | ||||
|   62[Wall] | ||||
|   63["Cap End"] | ||||
|   64["SweepEdge Opposite"] | ||||
|   65["SweepEdge Adjacent"] | ||||
|   66["Sweep Extrusion<br>[2271, 2315, 5]"] | ||||
|   67["Sweep Extrusion<br>[2271, 2315, 5]"] | ||||
|   68["Sweep Extrusion<br>[2271, 2315, 5]"] | ||||
|   69["Sweep Extrusion<br>[2271, 2315, 5]"] | ||||
|   70["Sweep Extrusion<br>[2271, 2315, 5]"] | ||||
|   71["Sweep Extrusion<br>[2271, 2315, 5]"] | ||||
|   72["Sweep Extrusion<br>[2271, 2315, 5]"] | ||||
|   73["Sweep Extrusion<br>[2271, 2315, 5]"] | ||||
|   74["Sweep Extrusion<br>[2271, 2315, 5]"] | ||||
|   75["Sweep Extrusion<br>[2271, 2315, 5]"] | ||||
|   76["Sweep Extrusion<br>[2271, 2315, 5]"] | ||||
|   77["Sweep Extrusion<br>[2271, 2315, 5]"] | ||||
|   78["Sweep Extrusion<br>[2271, 2315, 5]"] | ||||
|   79["Sweep Extrusion<br>[2271, 2315, 5]"] | ||||
|   80["Sweep Extrusion<br>[2271, 2315, 5]"] | ||||
|   88["Sweep Extrusion<br>[2724, 2792, 5]"] | ||||
|   66["Sweep Extrusion<br>[2271, 2315, 6]"] | ||||
|   67["Sweep Extrusion<br>[2271, 2315, 6]"] | ||||
|   68["Sweep Extrusion<br>[2271, 2315, 6]"] | ||||
|   69["Sweep Extrusion<br>[2271, 2315, 6]"] | ||||
|   70["Sweep Extrusion<br>[2271, 2315, 6]"] | ||||
|   71["Sweep Extrusion<br>[2271, 2315, 6]"] | ||||
|   72["Sweep Extrusion<br>[2271, 2315, 6]"] | ||||
|   73["Sweep Extrusion<br>[2271, 2315, 6]"] | ||||
|   74["Sweep Extrusion<br>[2271, 2315, 6]"] | ||||
|   75["Sweep Extrusion<br>[2271, 2315, 6]"] | ||||
|   76["Sweep Extrusion<br>[2271, 2315, 6]"] | ||||
|   77["Sweep Extrusion<br>[2271, 2315, 6]"] | ||||
|   78["Sweep Extrusion<br>[2271, 2315, 6]"] | ||||
|   79["Sweep Extrusion<br>[2271, 2315, 6]"] | ||||
|   80["Sweep Extrusion<br>[2271, 2315, 6]"] | ||||
|   88["Sweep Extrusion<br>[2724, 2792, 6]"] | ||||
|   89[Wall] | ||||
|   90[Wall] | ||||
|   91[Wall] | ||||
| @ -272,11 +272,11 @@ flowchart LR | ||||
|   99["SweepEdge Adjacent"] | ||||
|   100["SweepEdge Opposite"] | ||||
|   101["SweepEdge Adjacent"] | ||||
|   102["Sweep Extrusion<br>[2724, 2792, 5]"] | ||||
|   103["Sweep Extrusion<br>[2724, 2792, 5]"] | ||||
|   104["Sweep Extrusion<br>[2724, 2792, 5]"] | ||||
|   105["Sweep Extrusion<br>[2724, 2792, 5]"] | ||||
|   113["Sweep Extrusion<br>[3198, 3272, 5]"] | ||||
|   102["Sweep Extrusion<br>[2724, 2792, 6]"] | ||||
|   103["Sweep Extrusion<br>[2724, 2792, 6]"] | ||||
|   104["Sweep Extrusion<br>[2724, 2792, 6]"] | ||||
|   105["Sweep Extrusion<br>[2724, 2792, 6]"] | ||||
|   113["Sweep Extrusion<br>[3198, 3272, 6]"] | ||||
|   114[Wall] | ||||
|   115[Wall] | ||||
|   116[Wall] | ||||
| @ -290,41 +290,41 @@ flowchart LR | ||||
|   124["SweepEdge Adjacent"] | ||||
|   125["SweepEdge Opposite"] | ||||
|   126["SweepEdge Adjacent"] | ||||
|   127["Sweep Extrusion<br>[3198, 3272, 5]"] | ||||
|   128["Sweep Extrusion<br>[3198, 3272, 5]"] | ||||
|   129["Sweep Extrusion<br>[3198, 3272, 5]"] | ||||
|   130["Sweep Extrusion<br>[3198, 3272, 5]"] | ||||
|   131["Plane<br>[327, 344, 4]"] | ||||
|   138["Sweep Extrusion<br>[483, 516, 4]"] | ||||
|   127["Sweep Extrusion<br>[3198, 3272, 6]"] | ||||
|   128["Sweep Extrusion<br>[3198, 3272, 6]"] | ||||
|   129["Sweep Extrusion<br>[3198, 3272, 6]"] | ||||
|   130["Sweep Extrusion<br>[3198, 3272, 6]"] | ||||
|   131["Plane<br>[327, 344, 5]"] | ||||
|   138["Sweep Extrusion<br>[483, 516, 5]"] | ||||
|   139[Wall] | ||||
|   140["Cap Start"] | ||||
|   141["Cap End"] | ||||
|   142["SweepEdge Opposite"] | ||||
|   143["SweepEdge Adjacent"] | ||||
|   150["Sweep Extrusion<br>[771, 804, 4]"] | ||||
|   150["Sweep Extrusion<br>[771, 804, 5]"] | ||||
|   151[Wall] | ||||
|   152["Cap Start"] | ||||
|   153["Cap End"] | ||||
|   154["SweepEdge Opposite"] | ||||
|   155["SweepEdge Adjacent"] | ||||
|   159["Sweep Extrusion<br>[1106, 1140, 4]"] | ||||
|   159["Sweep Extrusion<br>[1106, 1140, 5]"] | ||||
|   160[Wall] | ||||
|   161["SweepEdge Opposite"] | ||||
|   162["SweepEdge Adjacent"] | ||||
|   163["Sweep Extrusion<br>[1106, 1140, 4]"] | ||||
|   164["Sweep Extrusion<br>[1106, 1140, 4]"] | ||||
|   165["Sweep Extrusion<br>[1106, 1140, 4]"] | ||||
|   166["Sweep Extrusion<br>[1106, 1140, 4]"] | ||||
|   170["Sweep Extrusion<br>[1444, 1478, 4]"] | ||||
|   163["Sweep Extrusion<br>[1106, 1140, 5]"] | ||||
|   164["Sweep Extrusion<br>[1106, 1140, 5]"] | ||||
|   165["Sweep Extrusion<br>[1106, 1140, 5]"] | ||||
|   166["Sweep Extrusion<br>[1106, 1140, 5]"] | ||||
|   170["Sweep Extrusion<br>[1444, 1478, 5]"] | ||||
|   171[Wall] | ||||
|   172["SweepEdge Opposite"] | ||||
|   173["SweepEdge Adjacent"] | ||||
|   174["Sweep Extrusion<br>[1444, 1478, 4]"] | ||||
|   175["Sweep Extrusion<br>[1444, 1478, 4]"] | ||||
|   176["Sweep Extrusion<br>[1444, 1478, 4]"] | ||||
|   177["Sweep Extrusion<br>[1444, 1478, 4]"] | ||||
|   178["Plane<br>[1632, 1649, 4]"] | ||||
|   186["Sweep Revolve<br>[1979, 1998, 4]"] | ||||
|   174["Sweep Extrusion<br>[1444, 1478, 5]"] | ||||
|   175["Sweep Extrusion<br>[1444, 1478, 5]"] | ||||
|   176["Sweep Extrusion<br>[1444, 1478, 5]"] | ||||
|   177["Sweep Extrusion<br>[1444, 1478, 5]"] | ||||
|   178["Plane<br>[1632, 1649, 5]"] | ||||
|   186["Sweep Revolve<br>[1979, 1996, 5]"] | ||||
|   187[Wall] | ||||
|   188[Wall] | ||||
|   189[Wall] | ||||
| @ -332,8 +332,8 @@ flowchart LR | ||||
|   191["SweepEdge Adjacent"] | ||||
|   192["SweepEdge Adjacent"] | ||||
|   193["SweepEdge Adjacent"] | ||||
|   194["Plane<br>[2084, 2101, 4]"] | ||||
|   202["Sweep Revolve<br>[2448, 2467, 4]"] | ||||
|   194["Plane<br>[2082, 2099, 5]"] | ||||
|   202["Sweep Revolve<br>[2446, 2463, 5]"] | ||||
|   203[Wall] | ||||
|   204[Wall] | ||||
|   205[Wall] | ||||
| @ -342,8 +342,8 @@ flowchart LR | ||||
|   208["SweepEdge Adjacent"] | ||||
|   209["SweepEdge Adjacent"] | ||||
|   210["SweepEdge Adjacent"] | ||||
|   211["Plane<br>[2922, 2945, 4]"] | ||||
|   219["Sweep Extrusion<br>[3867, 3913, 4]"] | ||||
|   211["Plane<br>[2918, 2941, 5]"] | ||||
|   219["Sweep Extrusion<br>[3863, 3909, 5]"] | ||||
|   220[Wall] | ||||
|   221[Wall] | ||||
|   222[Wall] | ||||
| @ -358,8 +358,8 @@ flowchart LR | ||||
|   231["SweepEdge Adjacent"] | ||||
|   232["SweepEdge Opposite"] | ||||
|   233["SweepEdge Adjacent"] | ||||
|   234["Plane<br>[2922, 2945, 4]"] | ||||
|   242["Sweep Extrusion<br>[3867, 3913, 4]"] | ||||
|   234["Plane<br>[2918, 2941, 5]"] | ||||
|   242["Sweep Extrusion<br>[3863, 3909, 5]"] | ||||
|   243[Wall] | ||||
|   244[Wall] | ||||
|   245[Wall] | ||||
| @ -374,8 +374,8 @@ flowchart LR | ||||
|   254["SweepEdge Adjacent"] | ||||
|   255["SweepEdge Opposite"] | ||||
|   256["SweepEdge Adjacent"] | ||||
|   257["Plane<br>[4324, 4341, 4]"] | ||||
|   284["Sweep Revolve<br>[5634, 5653, 4]"] | ||||
|   257["Plane<br>[4320, 4337, 5]"] | ||||
|   284["Sweep Revolve<br>[5630, 5647, 5]"] | ||||
|   285[Wall] | ||||
|   286[Wall] | ||||
|   287[Wall] | ||||
| @ -424,8 +424,8 @@ flowchart LR | ||||
|   330["SweepEdge Adjacent"] | ||||
|   331["SweepEdge Adjacent"] | ||||
|   332["SweepEdge Adjacent"] | ||||
|   333["Plane<br>[706, 732, 7]"] | ||||
|   345["Sweep Revolve<br>[1182, 1201, 7]"] | ||||
|   333["Plane<br>[706, 732, 8]"] | ||||
|   345["Sweep Revolve<br>[1182, 1199, 8]"] | ||||
|   346[Wall] | ||||
|   347[Wall] | ||||
|   348[Wall] | ||||
| @ -444,8 +444,8 @@ flowchart LR | ||||
|   361["SweepEdge Adjacent"] | ||||
|   362["SweepEdge Adjacent"] | ||||
|   363["SweepEdge Adjacent"] | ||||
|   364["Plane<br>[484, 501, 6]"] | ||||
|   384["Sweep Revolve<br>[2243, 2295, 6]"] | ||||
|   364["Plane<br>[484, 501, 7]"] | ||||
|   384["Sweep Revolve<br>[2243, 2293, 7]"] | ||||
|   385[Wall] | ||||
|   386[Wall] | ||||
|   387[Wall] | ||||
| @ -499,8 +499,8 @@ flowchart LR | ||||
|   435["SweepEdge Adjacent"] | ||||
|   436["SweepEdge Opposite"] | ||||
|   437["SweepEdge Adjacent"] | ||||
|   438["Plane<br>[460, 477, 8]"] | ||||
|   455["Sweep Revolve<br>[1486, 1517, 8]"] | ||||
|   438["Plane<br>[460, 477, 9]"] | ||||
|   455["Sweep Revolve<br>[1486, 1515, 9]"] | ||||
|   456[Wall] | ||||
|   457[Wall] | ||||
|   458[Wall] | ||||
| @ -529,17 +529,17 @@ flowchart LR | ||||
|   481["SweepEdge Adjacent"] | ||||
|   482["SweepEdge Adjacent"] | ||||
|   483["SweepEdge Adjacent"] | ||||
|   484["StartSketchOnFace<br>[770, 797, 5]"] | ||||
|   485["StartSketchOnFace<br>[947, 978, 5]"] | ||||
|   486["StartSketchOnFace<br>[1385, 1414, 5]"] | ||||
|   487["StartSketchOnFace<br>[1524, 1558, 5]"] | ||||
|   488["StartSketchOnFace<br>[1709, 1742, 5]"] | ||||
|   489["StartSketchOnFace<br>[2009, 2038, 5]"] | ||||
|   490["StartSketchOnFace<br>[2338, 2367, 5]"] | ||||
|   491["StartSketchOnFace<br>[2821, 2854, 5]"] | ||||
|   492["StartSketchOnFace<br>[603, 632, 4]"] | ||||
|   493["StartSketchOnFace<br>[865, 899, 4]"] | ||||
|   494["StartSketchOnFace<br>[1202, 1231, 4]"] | ||||
|   484["StartSketchOnFace<br>[770, 797, 6]"] | ||||
|   485["StartSketchOnFace<br>[947, 978, 6]"] | ||||
|   486["StartSketchOnFace<br>[1385, 1414, 6]"] | ||||
|   487["StartSketchOnFace<br>[1524, 1558, 6]"] | ||||
|   488["StartSketchOnFace<br>[1709, 1742, 6]"] | ||||
|   489["StartSketchOnFace<br>[2009, 2038, 6]"] | ||||
|   490["StartSketchOnFace<br>[2338, 2367, 6]"] | ||||
|   491["StartSketchOnFace<br>[2821, 2854, 6]"] | ||||
|   492["StartSketchOnFace<br>[603, 632, 5]"] | ||||
|   493["StartSketchOnFace<br>[865, 899, 5]"] | ||||
|   494["StartSketchOnFace<br>[1202, 1231, 5]"] | ||||
|   1 --- 2 | ||||
|   2 --- 3 | ||||
|   2 ---- 5 | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -5,7 +5,7 @@ description: Variables in memory after executing car-wheel-assembly.kcl | ||||
| { | ||||
|   "brakeCaliper": { | ||||
|     "type": "Module", | ||||
|     "value": 6 | ||||
|     "value": 7 | ||||
|   }, | ||||
|   "c1": { | ||||
|     "type": "TagIdentifier", | ||||
| @ -14,15 +14,15 @@ description: Variables in memory after executing car-wheel-assembly.kcl | ||||
|   }, | ||||
|   "carRotor": { | ||||
|     "type": "Module", | ||||
|     "value": 5 | ||||
|     "value": 6 | ||||
|   }, | ||||
|   "carTire": { | ||||
|     "type": "Module", | ||||
|     "value": 8 | ||||
|     "value": 9 | ||||
|   }, | ||||
|   "carWheel": { | ||||
|     "type": "Module", | ||||
|     "value": 4 | ||||
|     "value": 5 | ||||
|   }, | ||||
|   "lugCount": { | ||||
|     "type": "Number", | ||||
| @ -39,6 +39,6 @@ description: Variables in memory after executing car-wheel-assembly.kcl | ||||
|   }, | ||||
|   "lugNut": { | ||||
|     "type": "Module", | ||||
|     "value": 7 | ||||
|     "value": 8 | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -10,118 +10,118 @@ flowchart LR | ||||
|     8[Solid2d] | ||||
|   end | ||||
|   subgraph path18 [Path] | ||||
|     18["Path<br>[984, 1028, 0]"] | ||||
|     19["Segment<br>[1034, 1053, 0]"] | ||||
|     20["Segment<br>[1059, 1093, 0]"] | ||||
|     21["Segment<br>[1099, 1183, 0]"] | ||||
|     22["Segment<br>[1189, 1241, 0]"] | ||||
|     23["Segment<br>[1247, 1331, 0]"] | ||||
|     24["Segment<br>[1337, 1389, 0]"] | ||||
|     25["Segment<br>[1395, 1477, 0]"] | ||||
|     26["Segment<br>[1483, 1523, 0]"] | ||||
|     27["Segment<br>[1529, 1548, 0]"] | ||||
|     28["Segment<br>[1554, 1607, 0]"] | ||||
|     29["Segment<br>[1613, 1695, 0]"] | ||||
|     30["Segment<br>[1701, 1791, 0]"] | ||||
|     31["Segment<br>[1797, 1881, 0]"] | ||||
|     32["Segment<br>[1887, 1977, 0]"] | ||||
|     33["Segment<br>[1983, 2067, 0]"] | ||||
|     34["Segment<br>[2073, 2129, 0]"] | ||||
|     35["Segment<br>[2135, 2142, 0]"] | ||||
|     18["Path<br>[982, 1026, 0]"] | ||||
|     19["Segment<br>[1032, 1051, 0]"] | ||||
|     20["Segment<br>[1057, 1091, 0]"] | ||||
|     21["Segment<br>[1097, 1181, 0]"] | ||||
|     22["Segment<br>[1187, 1239, 0]"] | ||||
|     23["Segment<br>[1245, 1329, 0]"] | ||||
|     24["Segment<br>[1335, 1387, 0]"] | ||||
|     25["Segment<br>[1393, 1475, 0]"] | ||||
|     26["Segment<br>[1481, 1521, 0]"] | ||||
|     27["Segment<br>[1527, 1546, 0]"] | ||||
|     28["Segment<br>[1552, 1605, 0]"] | ||||
|     29["Segment<br>[1611, 1693, 0]"] | ||||
|     30["Segment<br>[1699, 1789, 0]"] | ||||
|     31["Segment<br>[1795, 1879, 0]"] | ||||
|     32["Segment<br>[1885, 1975, 0]"] | ||||
|     33["Segment<br>[1981, 2065, 0]"] | ||||
|     34["Segment<br>[2071, 2127, 0]"] | ||||
|     35["Segment<br>[2133, 2140, 0]"] | ||||
|     36[Solid2d] | ||||
|   end | ||||
|   subgraph path89 [Path] | ||||
|     89["Path<br>[2409, 2468, 0]"] | ||||
|     90["Segment<br>[2409, 2468, 0]"] | ||||
|     89["Path<br>[2407, 2466, 0]"] | ||||
|     90["Segment<br>[2407, 2466, 0]"] | ||||
|     91[Solid2d] | ||||
|   end | ||||
|   subgraph path98 [Path] | ||||
|     98["Path<br>[2569, 2599, 0]"] | ||||
|     99["Segment<br>[2605, 2624, 0]"] | ||||
|     100["Segment<br>[2630, 2713, 0]"] | ||||
|     101["Segment<br>[2719, 2775, 0]"] | ||||
|     102["Segment<br>[2781, 2788, 0]"] | ||||
|     98["Path<br>[2567, 2597, 0]"] | ||||
|     99["Segment<br>[2603, 2622, 0]"] | ||||
|     100["Segment<br>[2628, 2711, 0]"] | ||||
|     101["Segment<br>[2717, 2773, 0]"] | ||||
|     102["Segment<br>[2779, 2786, 0]"] | ||||
|     103[Solid2d] | ||||
|   end | ||||
|   subgraph path117 [Path] | ||||
|     117["Path<br>[3026, 3057, 0]"] | ||||
|     118["Segment<br>[3063, 3108, 0]"] | ||||
|     119["Segment<br>[3114, 3204, 0]"] | ||||
|     120["Segment<br>[3210, 3256, 0]"] | ||||
|     121["Segment<br>[3262, 3315, 0]"] | ||||
|     122["Segment<br>[3321, 3346, 0]"] | ||||
|     123["Segment<br>[3352, 3408, 0]"] | ||||
|     124["Segment<br>[3414, 3421, 0]"] | ||||
|     117["Path<br>[3024, 3055, 0]"] | ||||
|     118["Segment<br>[3061, 3106, 0]"] | ||||
|     119["Segment<br>[3112, 3202, 0]"] | ||||
|     120["Segment<br>[3208, 3254, 0]"] | ||||
|     121["Segment<br>[3260, 3313, 0]"] | ||||
|     122["Segment<br>[3319, 3344, 0]"] | ||||
|     123["Segment<br>[3350, 3406, 0]"] | ||||
|     124["Segment<br>[3412, 3419, 0]"] | ||||
|     125[Solid2d] | ||||
|   end | ||||
|   subgraph path140 [Path] | ||||
|     140["Path<br>[3503, 3530, 0]"] | ||||
|     141["Segment<br>[3536, 3556, 0]"] | ||||
|     142["Segment<br>[3562, 3605, 0]"] | ||||
|     143["Segment<br>[3611, 3629, 0]"] | ||||
|     144["Segment<br>[3635, 3655, 0]"] | ||||
|     145["Segment<br>[3661, 3681, 0]"] | ||||
|     146["Segment<br>[3687, 3735, 0]"] | ||||
|     147["Segment<br>[3741, 3797, 0]"] | ||||
|     148["Segment<br>[3803, 3810, 0]"] | ||||
|     140["Path<br>[3499, 3526, 0]"] | ||||
|     141["Segment<br>[3532, 3552, 0]"] | ||||
|     142["Segment<br>[3558, 3601, 0]"] | ||||
|     143["Segment<br>[3607, 3625, 0]"] | ||||
|     144["Segment<br>[3631, 3651, 0]"] | ||||
|     145["Segment<br>[3657, 3677, 0]"] | ||||
|     146["Segment<br>[3683, 3731, 0]"] | ||||
|     147["Segment<br>[3737, 3793, 0]"] | ||||
|     148["Segment<br>[3799, 3806, 0]"] | ||||
|     149[Solid2d] | ||||
|   end | ||||
|   subgraph path166 [Path] | ||||
|     166["Path<br>[3916, 3975, 0]"] | ||||
|     167["Segment<br>[3916, 3975, 0]"] | ||||
|     166["Path<br>[3910, 3969, 0]"] | ||||
|     167["Segment<br>[3910, 3969, 0]"] | ||||
|     168[Solid2d] | ||||
|   end | ||||
|   subgraph path169 [Path] | ||||
|     169["Path<br>[3986, 4023, 0]"] | ||||
|     170["Segment<br>[3986, 4023, 0]"] | ||||
|     169["Path<br>[3980, 4017, 0]"] | ||||
|     170["Segment<br>[3980, 4017, 0]"] | ||||
|     171[Solid2d] | ||||
|   end | ||||
|   subgraph path178 [Path] | ||||
|     178["Path<br>[4165, 4203, 0]"] | ||||
|     179["Segment<br>[4165, 4203, 0]"] | ||||
|     178["Path<br>[4159, 4197, 0]"] | ||||
|     179["Segment<br>[4159, 4197, 0]"] | ||||
|     180[Solid2d] | ||||
|   end | ||||
|   subgraph path192 [Path] | ||||
|     192["Path<br>[4476, 4514, 0]"] | ||||
|     193["Segment<br>[4476, 4514, 0]"] | ||||
|     192["Path<br>[4470, 4508, 0]"] | ||||
|     193["Segment<br>[4470, 4508, 0]"] | ||||
|     194[Solid2d] | ||||
|   end | ||||
|   subgraph path203 [Path] | ||||
|     203["Path<br>[4766, 4818, 0]"] | ||||
|     204["Segment<br>[4766, 4818, 0]"] | ||||
|     203["Path<br>[4760, 4812, 0]"] | ||||
|     204["Segment<br>[4760, 4812, 0]"] | ||||
|     205[Solid2d] | ||||
|   end | ||||
|   subgraph path213 [Path] | ||||
|     213["Path<br>[5065, 5109, 0]"] | ||||
|     214["Segment<br>[5115, 5155, 0]"] | ||||
|     215["Segment<br>[5161, 5180, 0]"] | ||||
|     216["Segment<br>[5186, 5205, 0]"] | ||||
|     217["Segment<br>[5211, 5230, 0]"] | ||||
|     218["Segment<br>[5236, 5261, 0]"] | ||||
|     219["Segment<br>[5267, 5407, 0]"] | ||||
|     220["Segment<br>[5413, 5469, 0]"] | ||||
|     221["Segment<br>[5475, 5482, 0]"] | ||||
|     213["Path<br>[5059, 5103, 0]"] | ||||
|     214["Segment<br>[5109, 5149, 0]"] | ||||
|     215["Segment<br>[5155, 5174, 0]"] | ||||
|     216["Segment<br>[5180, 5199, 0]"] | ||||
|     217["Segment<br>[5205, 5224, 0]"] | ||||
|     218["Segment<br>[5230, 5255, 0]"] | ||||
|     219["Segment<br>[5261, 5401, 0]"] | ||||
|     220["Segment<br>[5407, 5463, 0]"] | ||||
|     221["Segment<br>[5469, 5476, 0]"] | ||||
|     222[Solid2d] | ||||
|   end | ||||
|   subgraph path239 [Path] | ||||
|     239["Path<br>[5614, 5643, 0]"] | ||||
|     240["Segment<br>[5649, 5670, 0]"] | ||||
|     241["Segment<br>[5676, 5707, 0]"] | ||||
|     242["Segment<br>[5713, 5744, 0]"] | ||||
|     243["Segment<br>[5750, 5782, 0]"] | ||||
|     244["Segment<br>[5788, 5810, 0]"] | ||||
|     245["Segment<br>[5816, 5837, 0]"] | ||||
|     246["Segment<br>[5843, 5868, 0]"] | ||||
|     247["Segment<br>[5874, 5905, 0]"] | ||||
|     248["Segment<br>[5911, 5943, 0]"] | ||||
|     249["Segment<br>[5949, 5981, 0]"] | ||||
|     250["Segment<br>[5987, 6008, 0]"] | ||||
|     251["Segment<br>[6014, 6070, 0]"] | ||||
|     252["Segment<br>[6076, 6083, 0]"] | ||||
|     239["Path<br>[5606, 5635, 0]"] | ||||
|     240["Segment<br>[5641, 5662, 0]"] | ||||
|     241["Segment<br>[5668, 5699, 0]"] | ||||
|     242["Segment<br>[5705, 5736, 0]"] | ||||
|     243["Segment<br>[5742, 5774, 0]"] | ||||
|     244["Segment<br>[5780, 5802, 0]"] | ||||
|     245["Segment<br>[5808, 5829, 0]"] | ||||
|     246["Segment<br>[5835, 5860, 0]"] | ||||
|     247["Segment<br>[5866, 5897, 0]"] | ||||
|     248["Segment<br>[5903, 5935, 0]"] | ||||
|     249["Segment<br>[5941, 5973, 0]"] | ||||
|     250["Segment<br>[5979, 6000, 0]"] | ||||
|     251["Segment<br>[6006, 6062, 0]"] | ||||
|     252["Segment<br>[6068, 6075, 0]"] | ||||
|     253[Solid2d] | ||||
|   end | ||||
|   1["Plane<br>[241, 258, 0]"] | ||||
|   9["Sweep Revolve<br>[674, 706, 0]"] | ||||
|   9["Sweep Revolve<br>[674, 704, 0]"] | ||||
|   10[Wall] | ||||
|   11[Wall] | ||||
|   12[Wall] | ||||
| @ -129,8 +129,8 @@ flowchart LR | ||||
|   14["SweepEdge Adjacent"] | ||||
|   15["SweepEdge Adjacent"] | ||||
|   16["SweepEdge Adjacent"] | ||||
|   17["Plane<br>[955, 978, 0]"] | ||||
|   37["Sweep Extrusion<br>[2148, 2170, 0]"] | ||||
|   17["Plane<br>[953, 976, 0]"] | ||||
|   37["Sweep Extrusion<br>[2146, 2168, 0]"] | ||||
|   38[Wall] | ||||
|   39[Wall] | ||||
|   40[Wall] | ||||
| @ -181,14 +181,14 @@ flowchart LR | ||||
|   85["SweepEdge Adjacent"] | ||||
|   86["SweepEdge Opposite"] | ||||
|   87["SweepEdge Adjacent"] | ||||
|   88["Plane<br>[2375, 2402, 0]"] | ||||
|   92["Sweep Extrusion<br>[2483, 2517, 0]"] | ||||
|   88["Plane<br>[2373, 2400, 0]"] | ||||
|   92["Sweep Extrusion<br>[2481, 2515, 0]"] | ||||
|   93[Wall] | ||||
|   94["Cap Start"] | ||||
|   95["Cap End"] | ||||
|   96["SweepEdge Opposite"] | ||||
|   97["SweepEdge Adjacent"] | ||||
|   104["Sweep Extrusion<br>[2937, 2972, 0]"] | ||||
|   104["Sweep Extrusion<br>[2935, 2970, 0]"] | ||||
|   105[Wall] | ||||
|   106[Wall] | ||||
|   107[Wall] | ||||
| @ -198,10 +198,10 @@ flowchart LR | ||||
|   111["SweepEdge Adjacent"] | ||||
|   112["SweepEdge Opposite"] | ||||
|   113["SweepEdge Adjacent"] | ||||
|   114["Sweep Extrusion<br>[2937, 2972, 0]"] | ||||
|   115["Sweep Extrusion<br>[2937, 2972, 0]"] | ||||
|   116["Plane<br>[3003, 3020, 0]"] | ||||
|   126["Sweep Revolve<br>[3427, 3446, 0]"] | ||||
|   114["Sweep Extrusion<br>[2935, 2970, 0]"] | ||||
|   115["Sweep Extrusion<br>[2935, 2970, 0]"] | ||||
|   116["Plane<br>[3001, 3018, 0]"] | ||||
|   126["Sweep Revolve<br>[3425, 3442, 0]"] | ||||
|   127[Wall] | ||||
|   128[Wall] | ||||
|   129[Wall] | ||||
| @ -214,8 +214,8 @@ flowchart LR | ||||
|   136["SweepEdge Adjacent"] | ||||
|   137["SweepEdge Adjacent"] | ||||
|   138["SweepEdge Adjacent"] | ||||
|   139["Plane<br>[3480, 3497, 0]"] | ||||
|   150["Sweep Revolve<br>[3816, 3835, 0]"] | ||||
|   139["Plane<br>[3476, 3493, 0]"] | ||||
|   150["Sweep Revolve<br>[3812, 3829, 0]"] | ||||
|   151[Wall] | ||||
|   152[Wall] | ||||
|   153[Wall] | ||||
| @ -230,40 +230,40 @@ flowchart LR | ||||
|   162["SweepEdge Adjacent"] | ||||
|   163["SweepEdge Adjacent"] | ||||
|   164["SweepEdge Adjacent"] | ||||
|   165["Plane<br>[3879, 3909, 0]"] | ||||
|   172["Sweep Extrusion<br>[4042, 4076, 0]"] | ||||
|   165["Plane<br>[3873, 3903, 0]"] | ||||
|   172["Sweep Extrusion<br>[4036, 4070, 0]"] | ||||
|   173[Wall] | ||||
|   174["Cap Start"] | ||||
|   175["Cap End"] | ||||
|   176["SweepEdge Opposite"] | ||||
|   177["SweepEdge Adjacent"] | ||||
|   181["Sweep Extrusion<br>[4352, 4387, 0]"] | ||||
|   181["Sweep Extrusion<br>[4346, 4381, 0]"] | ||||
|   182[Wall] | ||||
|   183["SweepEdge Opposite"] | ||||
|   184["SweepEdge Adjacent"] | ||||
|   185["Sweep Extrusion<br>[4352, 4387, 0]"] | ||||
|   186["Sweep Extrusion<br>[4352, 4387, 0]"] | ||||
|   187["Sweep Extrusion<br>[4352, 4387, 0]"] | ||||
|   188["Sweep Extrusion<br>[4352, 4387, 0]"] | ||||
|   189["Sweep Extrusion<br>[4352, 4387, 0]"] | ||||
|   190["Sweep Extrusion<br>[4352, 4387, 0]"] | ||||
|   191["Sweep Extrusion<br>[4352, 4387, 0]"] | ||||
|   195["Sweep Extrusion<br>[4663, 4698, 0]"] | ||||
|   185["Sweep Extrusion<br>[4346, 4381, 0]"] | ||||
|   186["Sweep Extrusion<br>[4346, 4381, 0]"] | ||||
|   187["Sweep Extrusion<br>[4346, 4381, 0]"] | ||||
|   188["Sweep Extrusion<br>[4346, 4381, 0]"] | ||||
|   189["Sweep Extrusion<br>[4346, 4381, 0]"] | ||||
|   190["Sweep Extrusion<br>[4346, 4381, 0]"] | ||||
|   191["Sweep Extrusion<br>[4346, 4381, 0]"] | ||||
|   195["Sweep Extrusion<br>[4657, 4692, 0]"] | ||||
|   196[Wall] | ||||
|   197["SweepEdge Opposite"] | ||||
|   198["SweepEdge Adjacent"] | ||||
|   199["Sweep Extrusion<br>[4663, 4698, 0]"] | ||||
|   200["Sweep Extrusion<br>[4663, 4698, 0]"] | ||||
|   201["Sweep Extrusion<br>[4663, 4698, 0]"] | ||||
|   202["Plane<br>[4743, 4760, 0]"] | ||||
|   206["Sweep Extrusion<br>[4914, 4955, 0]"] | ||||
|   199["Sweep Extrusion<br>[4657, 4692, 0]"] | ||||
|   200["Sweep Extrusion<br>[4657, 4692, 0]"] | ||||
|   201["Sweep Extrusion<br>[4657, 4692, 0]"] | ||||
|   202["Plane<br>[4737, 4754, 0]"] | ||||
|   206["Sweep Extrusion<br>[4908, 4949, 0]"] | ||||
|   207[Wall] | ||||
|   208["Cap Start"] | ||||
|   209["Cap End"] | ||||
|   210["SweepEdge Opposite"] | ||||
|   211["SweepEdge Adjacent"] | ||||
|   212["Plane<br>[5042, 5059, 0]"] | ||||
|   223["Sweep Revolve<br>[5488, 5507, 0]"] | ||||
|   212["Plane<br>[5036, 5053, 0]"] | ||||
|   223["Sweep Revolve<br>[5482, 5499, 0]"] | ||||
|   224[Wall] | ||||
|   225[Wall] | ||||
|   226[Wall] | ||||
| @ -278,8 +278,8 @@ flowchart LR | ||||
|   235["SweepEdge Adjacent"] | ||||
|   236["SweepEdge Adjacent"] | ||||
|   237["SweepEdge Adjacent"] | ||||
|   238["Plane<br>[5562, 5607, 0]"] | ||||
|   254["Sweep Extrusion<br>[6097, 6142, 0]"] | ||||
|   238["Plane<br>[5554, 5599, 0]"] | ||||
|   254["Sweep Extrusion<br>[6089, 6134, 0]"] | ||||
|   255[Wall] | ||||
|   256[Wall] | ||||
|   257[Wall] | ||||
| @ -318,12 +318,12 @@ flowchart LR | ||||
|   290["SweepEdge Adjacent"] | ||||
|   291["SweepEdge Opposite"] | ||||
|   292["SweepEdge Adjacent"] | ||||
|   293["StartSketchOnPlane<br>[2361, 2403, 0]"] | ||||
|   294["StartSketchOnFace<br>[2531, 2563, 0]"] | ||||
|   295["StartSketchOnPlane<br>[3865, 3910, 0]"] | ||||
|   296["StartSketchOnFace<br>[4127, 4159, 0]"] | ||||
|   297["StartSketchOnFace<br>[4438, 4470, 0]"] | ||||
|   298["StartSketchOnPlane<br>[5548, 5608, 0]"] | ||||
|   293["StartSketchOnPlane<br>[2359, 2401, 0]"] | ||||
|   294["StartSketchOnFace<br>[2529, 2561, 0]"] | ||||
|   295["StartSketchOnPlane<br>[3859, 3904, 0]"] | ||||
|   296["StartSketchOnFace<br>[4121, 4153, 0]"] | ||||
|   297["StartSketchOnFace<br>[4432, 4464, 0]"] | ||||
|   298["StartSketchOnPlane<br>[5540, 5600, 0]"] | ||||
|   1 --- 2 | ||||
|   2 --- 3 | ||||
|   2 --- 4 | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	