Handle ambiguous region tags in edge specifiers#12302
Open
jtran wants to merge 9 commits into
Open
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Allow face API edge specifiers to resolve a single KCL face reference to multiple concrete face IDs. This lets region-derived tags, such as a circle segment that becomes multiple swept side faces, expand into the corresponding flat engine edge-reference payloads for fillet/chamfer. Keep index as engine-side disambiguation by forwarding it unchanged on expanded payloads rather than consuming it in KCL. Add simulation coverage for the broad ambiguous region tag case and the endFaces disambiguation case.
7e97e28 to
2a9929f
Compare
jtran
commented
Jun 30, 2026
| Ok(references) | ||
| } | ||
|
|
||
| fn face_id_combinations(groups: &[Vec<Uuid>]) -> Vec<Vec<Uuid>> { |
Contributor
Author
There was a problem hiding this comment.
Quadratic runtime here is making me nervous. I'm working on adding some checks to prevent pathological cases.
Contributor
Author
There was a problem hiding this comment.
I added a maximum limit of 256 that causes an error.
Irev-Dev
approved these changes
Jul 1, 2026
Merging this PR will not alter performance
Comparing Footnotes
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Revive #12201.
Original PR description below. The only difference is that we now generate an error if the user specifies an
indexwithsideFacesorendFacesthat have been split. We need this engine API to do it correctly, without making theindexparameter have a confusing double meaning.This fixes a face API edge-specifier case where a region-derived tag can map to more than one swept face after
region()andextrude().The concrete case is something like:
edges = [ { sideFaces = [band.tags.circle1, capStart001] } ]Here
band.tags.circle1looks like one logical KCL reference, but the circle segment can contribute two curved side faces in the swept result. Before this change, resolving that tag as a face could fail withTag circle1 is ambiguous, even though this is a reasonable query from the user's point of view.This PR keeps the KCL syntax/API the same. It does not add a new user-facing way to name these region pieces. Instead, when KCL resolves face API edge specifiers for
filletandchamfer, a single logical face reference is allowed to resolve to multiple concrete face IDs. KCL then expands the combinations into multiple flat engineEdgeSpecifierpayloads.That means the broad case can work as intended: if
sideFaces = [band.tags.circle1, capStart001]describes two concrete edges, both edge references are sent through and both edges can be filleted/chamfered.The same expansion also works with
endFaces. If the user writes:edges = [ { sideFaces = [band.tags.circle1, capStart001], endFaces = [band.tags.line1] } ]KCL still expands the ambiguous
sideFacescandidates, but the engine gets to resolve each candidate with the extraendFacesdisambiguator. In practice, the candidate that does not touchline1resolves to nothing, and the candidate that does touchline1resolves to the intended edge.One important thing this PR does not do is consume
indexlocally. That was the part of the earlier version that felt wrong.indexis supposed to be engine-side disambiguation, so this PR forwardsindexunchangedon each expanded engine payload[jtran: only if there's one] rather than using it to pick one expanded candidate in KCL. That is not a perfect long-term shape, because a flatEdgeSpecifiercannot preserve the grouping of “this one logical KCL face reference maps to these concrete face IDs”, but it avoids changing the meaning ofindexbehind the user's back.The longer-term follow-up is to change the lower-level modeling-commands/API shape so each
sideFacesorendFacesentry can represent one logical face reference with one or more concrete face IDs. That would let KCL send one grouped topology query instead of expanding to several flatEdgeSpecifiers. I filed that as an ongoing modeling-api issue here: KittyCAD/modeling-api#1252.So this PR should be read as a practical fix for the current flat API shape, not the final design for logical face references. The underlying issue is still that the lower-level API cannot preserve the grouping of “one KCL face reference resolved to multiple concrete faces”. That is the part tracked in KittyCAD/modeling-api#1252.
There is also a reverse point-and-click consideration for that follow-up. When the engine returns a payload for a selected edge, it does not necessarily need to return grouped logical face references. But it does need to return enough specifiers that the generated KCL still resolves to the clicked edge after modeling-app converts concrete face IDs back into KCL tags. If a concrete side face maps back to a region-derived tag that can expand to multiple faces, then
sideFacesalone may be under-specified in KCL and the returned payload may needendFacesorindex.This PR is deliberately narrower than that full API design. It fixes the immediate KCL resolution problem without introducing new KCL syntax, and it leaves a clear TODO for replacing the flat expansion once the lower-level API can represent grouped logical face references.
I added simulation coverage for the broad ambiguous region tag case and the
endFacesdisambiguation case, because the original problem involved real edge-reference resolution rather than just parsing or mock execution.Case where it fillets both edges still

Case where endFaces resolves to single edge
