Files
modeling-app/src/wasm-lib/kcl/tests/function_sketch/program_memory.snap
Adam Chalmers 6ac9c49773 KCL: Patterns of patterns can use the original sketch/solid as target (#5284)
Right now, if you model something like this box with a button:

<img width="413" alt="Screenshot 2025-02-06 at 3 08 03 PM" src="https://github.com/user-attachments/assets/04818a70-7cf3-4ee3-b8c5-df5959ac10db" />

Let's say you want to pattern the button, and repeat it a second time. If you try, you'll actually pattern the entire model (box + button).

<img width="486" alt="Screenshot 2025-02-06 at 3 08 52 PM" src="https://github.com/user-attachments/assets/09fc28d9-5d80-4ab3-b4dc-b8de2945fcba" />

Why? Because right now, when you sketch on a face (like the button was), both the box and the button share the same ID. All extrusions from a solid will share the same ID, because they all refer to the same composite solid.

This is helpful in some ways -- arguably the solid _is_ just one big complex shape now -- but it's not helpful in other ways. What if I want to only pattern the button? Luckily there's an original ID for the button part, which is still stored. So we just need a way to tell the pattern stdlib functions whether to use the target's main ID or its original ID. This PR adds a new optional bool, `useOriginal`, to patterns. It's false by default, to keep backwards-compatibility (make sure that old KCL code doesn't change).

This PR is based on https://github.com/KittyCAD/modeling-app/pull/3914. It's based on work Serena and I are doing to fix a bug (engine does not allow patterning a 3D solid which was sketched on a face of another solid). @gserena01 our test program is now:

```
w = 400

case = startSketchOn('XY')
  |> startProfileAt([-w, -w], %)
  |> line(endAbsolute = [-w, w])
  |> line(endAbsolute = [w, -w])
  |> line(endAbsolute = [-w, -w])
  |> close()
  |> extrude(length = 200)

bump1 = startSketchOn(case, 'end')
  |> circle({ center = [-50, -50], radius = 40 }, %)
  |> extrude(length = 20)

// We pass in "bump1" here since we want to pattern just this object on the face.
useOriginal = true
target = bump1
transform = {
  axis = [1, 0, 0],
  instances = 3,
  distance = -100
}
patternLinear3d(transform, target, useOriginal)
```

If you change the `useOriginal = true` to `false` you can see the difference.
2025-02-06 17:46:47 -06:00

664 lines
21 KiB
Plaintext

---
source: kcl/src/simulation_tests.rs
description: Program memory after executing function_sketch.kcl
snapshot_kind: text
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
"__meta": []
},
"QUARTER_TURN": {
"type": "Number",
"value": 90.0,
"__meta": []
},
"THREE_QUARTER_TURN": {
"type": "Number",
"value": 270.0,
"__meta": []
},
"ZERO": {
"type": "Number",
"value": 0.0,
"__meta": []
},
"box": {
"type": "Function",
"expression": {
"body": {
"body": [
{
"declaration": {
"end": 202,
"id": {
"end": 25,
"name": "myBox",
"start": 20,
"type": "Identifier"
},
"init": {
"body": [
{
"arguments": [
{
"end": 46,
"raw": "'XY'",
"start": 42,
"type": "Literal",
"type": "Literal",
"value": "XY"
}
],
"callee": {
"end": 41,
"name": "startSketchOn",
"start": 28,
"type": "Identifier"
},
"end": 47,
"start": 28,
"type": "CallExpression",
"type": "CallExpression"
},
{
"arguments": [
{
"elements": [
{
"end": 72,
"raw": "0",
"start": 71,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 75,
"raw": "0",
"start": 74,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 76,
"start": 70,
"type": "ArrayExpression",
"type": "ArrayExpression"
},
{
"end": 79,
"start": 78,
"type": "PipeSubstitution",
"type": "PipeSubstitution"
}
],
"callee": {
"end": 69,
"name": "startProfileAt",
"start": 55,
"type": "Identifier"
},
"end": 80,
"start": 55,
"type": "CallExpression",
"type": "CallExpression"
},
{
"arguments": [
{
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "end"
},
"arg": {
"elements": [
{
"end": 101,
"raw": "0",
"start": 100,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 104,
"name": "l",
"start": 103,
"type": "Identifier",
"type": "Identifier"
}
],
"end": 105,
"start": 99,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
}
],
"callee": {
"end": 92,
"name": "line",
"start": 88,
"type": "Identifier"
},
"end": 106,
"start": 88,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
},
{
"arguments": [
{
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "end"
},
"arg": {
"elements": [
{
"end": 127,
"name": "w",
"start": 126,
"type": "Identifier",
"type": "Identifier"
},
{
"end": 130,
"raw": "0",
"start": 129,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 131,
"start": 125,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
}
],
"callee": {
"end": 118,
"name": "line",
"start": 114,
"type": "Identifier"
},
"end": 132,
"start": 114,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
},
{
"arguments": [
{
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "end"
},
"arg": {
"elements": [
{
"end": 153,
"raw": "0",
"start": 152,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"argument": {
"end": 157,
"name": "l",
"start": 156,
"type": "Identifier",
"type": "Identifier"
},
"end": 157,
"operator": "-",
"start": 155,
"type": "UnaryExpression",
"type": "UnaryExpression"
}
],
"end": 158,
"start": 151,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
}
],
"callee": {
"end": 144,
"name": "line",
"start": 140,
"type": "Identifier"
},
"end": 159,
"start": 140,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
},
{
"arguments": [
{
"end": 174,
"start": 173,
"type": "PipeSubstitution",
"type": "PipeSubstitution"
}
],
"callee": {
"end": 172,
"name": "close",
"start": 167,
"type": "Identifier"
},
"end": 175,
"start": 167,
"type": "CallExpression",
"type": "CallExpression"
},
{
"arguments": [
{
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "length"
},
"arg": {
"end": 201,
"name": "h",
"start": 200,
"type": "Identifier",
"type": "Identifier"
}
}
],
"callee": {
"end": 190,
"name": "extrude",
"start": 183,
"type": "Identifier"
},
"end": 202,
"start": 183,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
}
],
"end": 202,
"start": 28,
"type": "PipeExpression",
"type": "PipeExpression"
},
"start": 20,
"type": "VariableDeclarator"
},
"end": 202,
"kind": "const",
"start": 20,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"argument": {
"end": 218,
"name": "myBox",
"start": 213,
"type": "Identifier",
"type": "Identifier"
},
"end": 218,
"start": 206,
"type": "ReturnStatement",
"type": "ReturnStatement"
}
],
"end": 220,
"nonCodeMeta": {
"nonCodeNodes": {
"0": [
{
"end": 206,
"start": 202,
"type": "NonCodeNode",
"value": {
"type": "newLine"
}
}
]
},
"startNodes": []
},
"start": 16
},
"end": 220,
"params": [
{
"type": "Parameter",
"identifier": {
"end": 8,
"name": "h",
"start": 7,
"type": "Identifier"
}
},
{
"type": "Parameter",
"identifier": {
"end": 11,
"name": "l",
"start": 10,
"type": "Identifier"
}
},
{
"type": "Parameter",
"identifier": {
"end": 14,
"name": "w",
"start": 13,
"type": "Identifier"
}
}
],
"start": 6,
"type": "FunctionExpression"
},
"memory": {
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
"__meta": []
},
"QUARTER_TURN": {
"type": "Number",
"value": 90.0,
"__meta": []
},
"THREE_QUARTER_TURN": {
"type": "Number",
"value": 270.0,
"__meta": []
},
"ZERO": {
"type": "Number",
"value": 0.0,
"__meta": []
}
},
"parent": null
}
],
"currentEnv": 0,
"return": null
},
"__meta": [
{
"sourceRange": [
6,
220,
0
]
}
]
},
"fnBox": {
"type": "Solid",
"value": {
"type": "Solid",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": [
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [
88,
106,
0
],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [
114,
132,
0
],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [
140,
159,
0
],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [
167,
175,
0
],
"tag": null,
"type": "extrudePlane"
}
],
"sketch": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
88,
106,
0
]
},
"from": [
0.0,
0.0
],
"tag": null,
"to": [
0.0,
6.0
],
"type": "ToPoint"
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
114,
132,
0
]
},
"from": [
0.0,
6.0
],
"tag": null,
"to": [
10.0,
6.0
],
"type": "ToPoint"
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
140,
159,
0
]
},
"from": [
10.0,
6.0
],
"tag": null,
"to": [
10.0,
0.0
],
"type": "ToPoint"
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
167,
175,
0
]
},
"from": [
10.0,
0.0
],
"tag": null,
"to": [
0.0,
0.0
],
"type": "ToPoint"
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"units": {
"type": "Mm"
},
"__meta": []
},
"start": {
"from": [
0.0,
0.0
],
"to": [
0.0,
0.0
],
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
55,
80,
0
]
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
"__meta": [
{
"sourceRange": [
55,
80,
0
]
}
]
},
"height": 3.0,
"startCapId": "[uuid]",
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"__meta": [
{
"sourceRange": [
55,
80,
0
]
}
]
}
}
},
"parent": null
}
],
"currentEnv": 0,
"return": null
}