Repository navigation
feat(brep): wrapped curves and surfaces (exact geometry bent around an axis) - #38
Open
Basnederveen wants to merge 2 commits into
Open
Basnederveen wants to merge 2 commits into
Basnederveen wants to merge 2 commits into
Conversation
…n axis) A Wrap maps flat space onto a cylinder the way a sheet metal bend wraps a flat sheet: (x, y, z) -> frame.point([z cos(x/r), z sin(x/r), y]). x is arc length on radius r, y runs along the axis, z is the distance from it. CurveGeometry::Wrapped and SurfaceGeometry::Wrapped wrap a line, circle, ellipse or any elementary surface exactly and keep its parameters and charts. A hole through a bend is a wrapped cylinder bounded by wrapped circles; a slanted cut is a wrapped plane bounded by helices. - geometry: point, derivatives (chain rule), normal (cofactor), projection (exact on the surface), conservative bounds for curves and surfaces. - tessellation: grid sizes and chord deviation from the exact second derivatives, sampled with a 1.5x margin; arcs keep the per-turn floor. - query: ray roots on wrapped faces by UV subdivision plus Newton. - STEP: wrapped surfaces as bicubic B-splines over the support's face UV, reaching 10% past the faces (never around a period onto itself) so readers that rebuild trims by intersecting neighbouring surfaces don't trim short; wrapped edges as cubic B-splines; both Hermite fits checked against the exact geometry and charged to the exchange budget. - placement moves wrapped geometry rigidly; scaling, mirroring, booleans, shells, SSI and IFC refuse it with UnsupportedGeometry. Tests: wrapped families in the per-family geometry tests, fitting tests, and a bend sector with a slanted wrapped side that meshes to its exact volume, classifies points on both sides of the wall, exports to STEP within budget, and refuses scaling, mirroring, booleans and shelling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VFZvqx1RmXzPtbL9VXP4H7
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VFZvqx1RmXzPtbL9VXP4H7
Author
|
Heads-up for merging this together with #37: there's no textual conflict, but the build fails once both are in. #37 adds A wrapped curve is curved in 3D, so it should be raised in a non-planar loop just like an intersection curve: CurveGeometry::Intersection { .. } | CurveGeometry::Wrapped { .. } => !planar,With that one line, all seven open PRs (#35–#41) merged together pass fmt, clippy, the full test suite, I also pushed 8a22f57 to this PR. It puts the |
This was referenced Nov 1, 2026
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.
What
New curve and surface family: geometry given in a flat space and bent around a cylinder axis, the way a sheet metal bend wraps a flat sheet.
Wrap { frame, radius }maps a flat point(x, y, z)toframe.point([z cos(x/r), z sin(x/r), y]).xis arc length on radiusr,yruns along the axis,zis the distance from the axis, so lines along flatzbecome radial lines. The map is exact and preserves orientation (Jacobian determinantz / r).CurveGeometry::Wrapped { wrap, curve }wraps a line, circle or ellipse.SurfaceGeometry::Wrapped { wrap, surface }wraps any elementary surface.Both keep the flat geometry's parameters and charts, so pcurves are written in the flat surface's UV.
Why: a cut through a bend has no analytic support. A round hole through a bend has a wrapped cylinder as its wall and wrapped circles as its edges. A slanted cut is a wrapped plane bounded by helices (wrapped lines). With this family such parts are exact B-reps rather than approximations.
Support across the kernel:
frame.xunless a hint picks the turn), and conservative interval bounds for curves and surfaces.B_SPLINE_SURFACE_WITH_KNOTSover the UV of all faces on that support. The knots are the surface's own parameters, so pcurves stay valid.B_SPLINE_CURVE_WITH_KNOTSover every range an edge uses.UnsupportedGeometry: booleans, shells, SSI, mirroring and IFC export of wrapped geometry.Compatibility:
"kind": "Wrapped"for curves and surfaces, and existing bodies read unchanged.CurveGeometryandSurfaceGeometrygain a variant, so an exhaustivematchover them in downstream code needs a new arm. Two integration tests in this repo did (tests/primitives.rs,tests/creating/sweep_bends.rs).Robustness
SingularParameterization) on the axis, wherez <= 0.Unknownafter 50,000 boxes rather than guessing.LimitExceeded, and STEP refuses when the exchange budget leaves no room for fitting.Tests
flatten, and that a wrapped line is a constant-speed helix with a correct tangent and box. Another checks that wrapped circle samples meet their chord error.z / r) to 1e-4;CI=true:cargo fmt --check,cargo clippy --all-targets -D warnings(kernel and test-support) andcargo test --all-targetspass, including thesource_rulesbinary. That's 382 crate tests here, against 373 onmain.npm run check:source,check:duplicatesandcheck:cyclespass. Browser runs and the golden comparison were not run, because golden files are only recorded on macOS.Files
src/brep/geometry/wrap.rssrc/query/wrapped_roots.rssrc/tessellation/wrapped.rssrc/exchange/fit_bezier/src/exchange/step/wrapped.rssrc/brep/builder/fixtures.rs(test only)brep/geometry/{curve,surface,store,turned}.rs,brep/placement/,query/{classify,ray_roots}.rs,tessellation/{area_bound,deviation,grid,trim}.rs,intersection/ssi/,intersection/universal_ssi/implicit_bounds.rs,operations/modifying/boolean/{dispatch,batch,shell,handlers/sphere_sphere},exchange/{preflight,step,ifc_body}.liftmoved fromsurface.rstoturned.rs, sowrap.rscan share it without a sibling import cycle.tests/primitives.rs,tests/creating/sweep_bends.rs: a"wrapped"arm in their surface-kind helpers.🤖 Generated with Claude Code