* KCL: Update patternTransform and 2d to use kwargs
* Update docs
* Convert segment functions to use keyword args
* Regenerate docs, change branch of kcl-samples
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.
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
* Make `=` and `=>` optional in function declarations
And requires `:` for return types
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Tests
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Format types in function decls
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Require in anon function decls
Signed-off-by: Nick Cameron <nrc@ncameron.org>
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Previously, this was the output of the formatter:
```
fn f = () => {
return () => {
return 1
}
}
```
Now the above will be reformatted as
```
fn f = () => {
return () => {
return 1
}
}
```
Much better!
* Log any Errors to stderr
This isn't perfect -- in fact, this is maybe not even very good at all,
but it's better than what we have today.
Currently, when we get an Erorr back from the WebSocket, we drop it in
kcl-lib. The web-app logs these to the console (I can't find my commit
doing that off the top of my head, but I remember doing it) -- so this
is some degree of partity.
This won't be very useful at all for wasm usage, but it will fix issues
with the zoo cli silently breaking with a "WebSocket Closed" error --
which is the same issue I was solving for in the desktop app too.
In the future perhaps this can be a real Error? I'm not totally sure
yet, since we can't align to the request-id, so we can't really tie it
to a specific call (yet).
* add to responses
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)
* add a test
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* clippy[
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)
* empty
* fix error
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* updates tests
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* docs
Signed-off-by: Jess Frazelle <github@jessfraz.com>
---------
Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
Previously variable declaration required a keyword, e.g.
```kcl
let x = 4
const x = 4
var x = 4
```
These were all valid, and did the exact same thing. As of this PR, they're all still valid, but the KCL formatter will change them all to just:
```kcl
x = 4
```
which is the new preferred way to declare a constant.
But the formatter will remove the var/let/const keywords.
Closes https://github.com/KittyCAD/modeling-app/issues/3985
* Preserve paragraph breaks in the KCL docs
The KCL docs on the website are hard to read, because they concatenate all
the paragraphs in my nicely-formatted docstrings in the stdlib functions
into one big paragraph. PR should fix this.
* Fix arc docs being split into two lines
The 'summary' section of the docs has a maximum line length, and if you
go over that length, your summary gets split into two lines weirdly.
Makes the arc docs shorter, so the summary is back to one line like
it should be.
* Update docs for pattern transform
Also, there were some executor unit tests to test pattern transform. I realized they make more sense as example tests in the KCL stdlib for pattern transform. This way, they show up in the docs too. So I removed the unit tests (the examples now test these features instead).
Big thanks to Serena for fixing this on the engine side!
Also looks like the pictures from artifact graph were deleted, so GH Actions wants to put it back.
Pattern transforms now have a new `rotation` parameter, letting you rotate each instance of the shape. Currently only rotation around the local origin (i.e. rotating the object around the center of its own bounding box) works correctly. Rotating around a global origin (i.e. center of the scene) will be fixed on the server side soon.
* circle
* fix another example
* fix bad comment
* toPoint fix
* cargo fmt
* resolve most of the tests
* fix last test
* missed circle in bracket
* remove console error
* fmt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)
* trigger ci
* remove three dot menu for circle
* make sure circle can be extruded
* fix up after merge
* add extrude test for circle
* clean up
* typo
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)
* Revert "A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)"
This reverts commit 03f8eeb542.
* update docs again
* cmd bar test serialisation improvements
* tiny clean up
* fix after: Replace kittycad crate with kittycad-modeling-cmds
* fmt
* rename fix
* Update src/lib/toolbar.ts
Co-authored-by: Frank Noirot <frank@zoo.dev>
* add another error to list
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)
* image updates
* Revert "A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)"
This reverts commit 505bb20bea.
* update markdown
* skip un reproducable windows test failure
* rust review
* leave issue todo comment
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@zoo.dev>
* updated tangentArc math
* Add a test case showing tan arc then xLineTo
* Fix compile errors
* Tweaking the math
* Use + on angles
* atan2 outputs radians, not degrees
* Track ccw and center of all tan arcs
* re-sequenced atan2 arcTan
* Remove print statements
* Update the test
* Update kittycad in tauri
* New arc fields
---------
Co-authored-by: Jordan Noone <jordan@kittycad.io>
Each AST node contains an Option<Digest> which can be optionally set by running compute_digest() over the AST. This will mutate the AST and set the Digest. Fundamentally, the digest is computed from the digest of AST children nodes (using compute_digest) or the explicit raw underlying value.
The underlying hash is changeable by modifying the macro and Digest type alias, and should enable us to determine when an AST -- or fragment of AST -- is the same.
This won't hash the start/end of the AST fragment, so it's, to some extent, position independent. It will hash newlines, comments, etc, which may change in the future depending on how we wind up using this.