Open Irev-Dev opened 2 weeks ago
And now two vertical constraints. Notice point4 no longer needs any XY info.
The XY info have been removed from point2 instead, right? Or am I misunderstanding. My impression is that one of those two points doesn't need any XY information anymore.
The meta property is for us to dump a base64 string or similar for where to put the dimension overlay, because we can try and put it in an intelligent place and not let users move it around, but I think that would be a hard sell, and with code being the source of truth, we need to store it somewhere in the script, open to other ideas though.
Why shouldn't the constraint's visible location in the 2D sketch view just be determined/locked onto one place? E.g. if you're constraining a distance, label that distance. If you're constraining that two lines are equal, put a little label on both lines, etc. If we do have to make it user-configurable, I'd prefer something meaningful to the user (e.g. "visuals: { anchorOn: point2 }" or "visuals: { centeredBetween: [line2, line4]} etc)". If it's base64-encoded binary data, there's no real way to resolve git conflicts and the program becomes a lot less readable.
Some other questions:
Minor note: https://github.com/KittyCAD/kcl-experiments/pull/20 is an updated version of the gist at the start of the issue
- Normal expressions are not allowed in said block, no variable declarations, no if statements, no loops. One exception would be basic math like 5+2 or myVar / 2 to be used as values.
Is this something you think is desirable long-term, or is it purely to make things easier to implement?
This seems like the most dramatic change proposed so far in that it is really a different paradigm for KCL. As you say in point 2, this is just data, not programming. I'm not sure how this idea of sketches as data/constraints works with variables or functions or other programming concepts we make heavy use of at the moment.
What do you envisage happening outside the sketch? E.g., what does extrude look like?
I guess bigger question, if KCL is just a data format (or mostly a data format with some programming around the edges) what is the key value proposition or distinguishing feature of KMA?
- 2D Solver should be implemented in KCL
This seems fraught to me (not that I have a better solution, sketch mode is just awkward). How would it work? It seems like KCL would need knowledge of geometry which is currently only known in the engine. E.g., if there is a constrain that a line must be parallel to the tangent of a curve at a point, do we duplicate all the logic about every curve in the engine and in KCL? Does the engine have API to get this info? (But then, we are introducing possible latency issues by forcing round trips). And do we duplicate the constraint solver in KCL and the engine too? Or only send resolved constraints to the engine, but in that case the API of the engine does not seem like it would be fit for purpose as a CAD component for uses without KCL.
- Normal expressions are not allowed in said block, no variable declarations, no if statements, no loops. One exception would be basic math like 5+2 or myVar / 2 to be used as values.
Is this something you think is desirable long-term, or is it purely to make things easier to implement?
This seems like the most dramatic change proposed so far in that it is really a different paradigm for KCL. As you say in point 2, this is just data, not programming. I'm not sure how this idea of sketches as data/constraints works with variables or functions or other programming concepts we make heavy use of at the moment.
What do you envisage happening outside the sketch? E.g., what does extrude look like?
I guess bigger question, if KCL is just a data format (or mostly a data format with some programming around the edges) what is the key value proposition or distinguishing feature of KMA?
Yeah, big concerns about this -- things like my procedural gear would not be possible without dynamic definitions of sketch lines.
Distinguishing features would still be the cloud streaming, the ability to break code into smaller functions with meaningful diffs and CRDT collaboration, copying and pasting, etc. But we'd lose a lot of the power.
Some things I think are good:
Some things I don't understand or I think could use work:
There's lots proposals for a constraint syntax, not at all centralised so I'm adding to the chaos with another proposal
There's my original non-solver constraints write up https://github.com/KittyCAD/modeling-app/issues/111 Josh's https://github.com/KittyCAD/notes/blob/main/docs/personal/Gomez-Josh/kcl/kcl-refactor.md Jon's https://github.com/KittyCAD/kcl-experiments/pull/13 Nick's https://gist.github.com/nrc/efdec535bd961a0f7b470480676fa9eb
And here's my new write up for a solver syntax, I hope what I can contribute thinking through the code-mods and how individual bits of UI ties back to the code.
I have a handful of principles that should go into the design of the solver syntax. (I agree with lots that's been said already so you'll notice I'm repeating ideas from others below).
sketch mySketch {...}
5+2
ormyVar / 2
to be used as values.Expanded on a little more
3 & 4. Allowing dynamic language features smells like a huge foot gun that we should avoid in the first pass, and an easy way to do this is by giving it's own special block
sketch mySketch {...}
or similar to limit what can be used inside. Bit of an aside, because of the lack of chaining, we don't even have the concept of a profile tightly defined, so we should get "multi-profiles" for freeTo make the above concrete with how it will fit into the UI here a simple example:
In the below I didn't step through the most clicking to add each one of these segments because it's straight forward First only the
point1 { x: 0, y: 0.5 }
is added to the block, and then on the second click another point is addedpoint2 { x: 10, y: 1, }
which allows a segment to be added between the two withline1 straight { start: point1, end: point2 }
and so and so forth.Other things to point out
The user selects the top and bottom segments and applies the horizontal constraint and the UI:
horizontal { segs: [line1, line3] },
it might be best to list these each explicitly,horizontal line1, horizontal line3
but either works.y
information, as that follows from the constraints.The code mode for this is straight forward, it's basically adding
horizontal { segs: [<User's selections>] },
will likely need to get the solver to inform a second mod as to what information is now redundant, in order to remove they
information from this example.To make sure it's not an after thought, let's consider what happens when a constraint is removed (maybe through the feature tree, or interacting with the symbol in the sketch), either way the user removes the horizontal constraint from the top segment. The obvious thing is that
line3
is removed from the horizontal constraint, but from the previous step we removedy
information frompoint2
that we need now. In the same manner that is done with the current constraints is we can pull segment information from the last execution to backfill this information to addy: 0.5
, this basically the information needed so that we can remove the constraint without the segment moving. There's no need to try and restore the value before the constraint was applied in the first place.Let's also touch on editing the lines by dragging handles, we'll look at dragging two separate points, one partially constrained, the other not. Below point2 is trying to be dragged down and to the right, but because it's constrained, the point only moves horizontally. The code mod here is really simple. From the mouse drag, we get updated XY coords, but when applying them to
point2 { x: 12.3 }
because there's no y component to change, only thex
will updateWhere as the unconstrained
point4
gets both x and y updated in the code mode.We'll continue on with the constraints, add the horizontal constraint back in
And now two vertical constraints. Notice
point4
no longer needs any XY info.User selects
line4
andpoint3
, adds a perpendicular distance constraint, this removes XY info from point2. This perpendicular distance is really a dimension, but as pointed out earlier, I don't think we should differentiate. This new constraint needs a UI element, and in this case it's obvious, it's the dimension overlay. giving a easy to way edit this after the fact as well.The
meta
property is for us to dump a base64 string or similar for where to put the dimension overlay, because we can try and put it in an intelligent place and not let users move it around, but I think that would be a hard sell, and with code being the source of truth, we need to store it somewhere in the script, open to other ideas though.Another perpendicular distance constraint
And finally we're just going to lock off
point1
as fixed, (User selects this point and adds a fixed point constraint), again new constraint needs a UI element, the one I added is very goofy, not a suggestion for what this icon should actually be.Final comment here is that this sketch has been fully constrained, and the mental model is really simple when looking at the code, once all of the info is removed from the original points then it's constrained, there will be a few more nuances when it comes to non-straight segments, but I think we can extend this mental model.
I did not mention anything about tags here, which are not needed for use within sketches anymore, but are still needed for selecting faces and edges and etc once the sketch is extruded or other.
Relationship expressions like
||line2|| = 0.5 * ||line3||
from Jon's proposal I think is a cool concept, but not actually something ME really expect so not sure we should aim for this initially, when aequalLength {segs: [line2, line3]}
would suffice (and the0.5 *
I doubt will get used much)