Skip to content

Shape boolean transformation#59

Open
timschmidt wants to merge 38 commits into
jbuckmccready:masterfrom
timschmidt:shape-boolean-transformation
Open

Shape boolean transformation#59
timschmidt wants to merge 38 commits into
jbuckmccready:masterfrom
timschmidt:shape-boolean-transformation

Conversation

@timschmidt

Copy link
Copy Markdown

This PR implements axis aligned bounding box index accelerated Shape level booleans, transformations, a transformation builder for reducing unnecessary recomputation of the axis aligned bounding box index, tests, and a Shape boolean demo.

timschmidt and others added 21 commits March 4, 2025 19:52
…lts to determine if used or not instead of just the boudning box test
…boolean library’s result will naturally return some polylines in pos_plines or neg_plines. If the shapes truly intersect, the boolean library’s result will return some polylines in pos_plines or neg_plines. If the shapes are disjoint, the underlying boolean routine may return the two disjoint loops in pos_plines anyway—if so, then you have them already (and they’re used). If not (some libraries return “Disjoint” and no polylines), then we let the “unused leftover” logic handle it.
@TimTheBig

Copy link
Copy Markdown

This seems like the better chose for offset in csgrs

@timschmidt

timschmidt commented Apr 12, 2025

Copy link
Copy Markdown
Author

Still some unresolved issues in the results of the MultiPolyLine booleans. Should be easy enough to see in the GUI demo. Maybe you want to take a stab at fixing them up? Much work is done already. If we can get the MultiPolyLine booleans working properly, the https://github.com/timschmidt/csgrs/tree/cavalier_contours branch uses cavalier_contours in place of geo for all 2D ops.

@timschmidt

timschmidt commented May 15, 2026

Copy link
Copy Markdown
Author

(I jumped the gun, still another bug hiding in here, working at it)

@timschmidt

Copy link
Copy Markdown
Author

This branch hardens and extends the shape boolean layer, especially for multi-polyline shapes with holes, nested islands/lakes, open linework, and interactive UI drag cases.

Key changes:

  • Added shape-level boolean support and fixes for OR, AND, NOT, and XOR across signed CCW material loops and CW hole loops.
  • Fixed clipping/assembly failures where open polylines or closed loops leaked into filled material.
  • Added support for deeper nested island/lake structures.
  • Improved robustness around degenerate and adversarial geometry: shared boundaries, tangencies, near-coincident loops, large coordinates, slivers,
    arc-heavy cases, and UI vertex-drag scenarios.
  • Added ShapeView and BorrowedIndexedPolyline for borrowed shape inputs, with borrowed fast paths for common boolean cases.
  • Added a benchmark harness for owned vs borrowed shape construction and boolean operation costs.
  • Expanded docs and docs.rs readiness across public APIs, FFI structs/constants, UI helpers, and shape boolean rationale.
  • Hid polyline::internal from generated docs while preserving diagnostic visibility.
  • Added extensive regression, adversarial, property, differential, and fuzz-oriented tests for shape booleans.
  • Imported/adapted useful regression-style coverage inspired by geo/overlay-style boolean edge cases.

Validation performed:

  • cargo fmt --all --check
  • cargo clippy --all-targets --all-features -- -D warnings
  • cargo test --workspace
  • env RUSTDOCFLAGS="-D warnings -D missing_docs" cargo doc --workspace --all-features --no-deps
  • cargo bench -p cavalier_contours --bench shape_borrowed_api
  • git diff --check

@jbuckmccready

Copy link
Copy Markdown
Owner

Hey, looks like you've been cooking. I gave it a first pass skim, I haven't played with it yet, here's some initial feedback.

  • It would help if you could provide:
    • Your approach to building this up at a high level and your workflow with LLMs (sources used, general prompting/iteration, review process, testing, etc.)
    • Detailed summary of algorithm and how it works, deals with different inputs, and handles edge cases (ideally citing back to code)
    • Your recommended approach for reviewing the changes (where to start, what is critical/most important, etc.)
    • Anything not included in this PR that is useful contextually, this could be features/changes you left out that you think should be made, or ideas you had that you decided to skip
  • I see there is bibliography with some sources, how were these sources used:
    • Are they direct approaches in them that were implemented, or just related and helpful to solving the problem?
    • How much were you diving in vs. just utilized as a source for LLM implementation and/or fixes?
  • Fuzzing was added that looks reasonable at a glance, but does add a lot of code. What was the decision process for adding it, were there bugs caught by using it, and if so what bugs and how were they fixed? Should these maybe be added for other parts of the project?
  • For changes that normalize xy values to be near the origin: I know why this is beneficial for the floating point ops, but similarly to the fuzzing changes, how did this come about, and should this be added to other parts of the project?
  • There are added constants for fuzzy float comparisons, how were these constant values decided? They also do not match other parts of the project which allows configuring the values as part of the arguments.

The reason for all this high level/non-code specific requests for information is I don't want to waste time crawling through details and (mis)interpret what you've done, or what your intent was.

I know what the algorithm intends to do, but there is a lot of details in the algorithm. And I understand the high level reason for most of the changes (fuzzing, testing, bibliography, etc.), but I don't have the context for the "why" which would allow me to review.

@timschmidt

timschmidt commented May 17, 2026 via email

Copy link
Copy Markdown
Author

@timschmidt

Copy link
Copy Markdown
Author

I should also say that it's possible there's a better way to do this. I am decidedly a non-expert. I read all the references I cite in these projects. And I understand enough. But I often find myself in the same shoes as you. Mystified as to how the solution was arrived at. This is where the approach I took led me. But if there's a better way, I'm all ears.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants