mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-05 19:45:54 +00:00
kernel: planar region booleans are SMLib's exact 2D boolean
planar_regions_boolean replaced each free-form loop (a font's curves, an ellipse) with arcs
fitted within PLANAR_FIT_TOL before its own line/arc arrangement, and a loop the operation
cut kept those arcs: a cut free-form outline was extruded inexactly. Now each operand is a
sheet of planar faces built from its loops' own curves (Brep::planar_faces; lines, arcs and
the Béziers and conics as NURBS, exactly) and SM_API's 2D boolean combines them
(Brep::boolean2d): SMLib's topology intersector, the one the solid booleans use, splits the
operands' edges where they cross and the result's edges are copies of those curves. The
faces read back exactly (prism_curve::projected: lines, arcs, each Bézier span as the
segment it is). The Rust arrangement (crossings, ray parity, chaining, the fit and the
"exact again" restoration) is deleted: one source, no fitting.
extrude_planar_regions unites its regions the same way (balanced unions of one-region
sheets) and refuses pieces of the union that share a vertex, read off the result's
topology instead of a line/arc crossing test on fitted arcs.
Signatures stay (doc/sheet.rs and mesh_convert call them as before); `tolerance` is the gap
a loop may close within and the least tolerance edges are read back at. PLANAR_FIT_TOL
stays for doc/engine's flat patterns, which fit their own loops. smlib_sweeps::curve (the
Seg2 to SMLib curve conversion) is made pub(crate) for the sheets.
Tests: those of the deleted helpers (crossings, ray parity, closest_param, segment boxes)
are gone; the free-form test now asserts what the exact boolean gives (the half-ellipse
notch is the ellipse's own conics, area exact to 1e-6; the joined ellipses are conics), and
the fitted-arc budget assertion is dropped. Without the smlib feature the booleans are
refused ("not supported yet").
(not built: base in progress; cargo check shows no errors in prism.rs or smlib_sweeps.rs
with and without the smlib feature)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017itGh5fpMEousnZ91cYcVt
This commit is contained in:
+196
-1296
File diff suppressed because it is too large
Load Diff
@@ -71,7 +71,7 @@ pub(crate) struct Draft {
|
||||
}
|
||||
|
||||
#[cfg(feature = "smlib")]
|
||||
pub(crate) use imp::{body_from_record, extrude, loft, loft_rails, loft_to_point, revolve, screw, sphere, sweep, sweep_controlled};
|
||||
pub(crate) use imp::{body_from_record, curve, extrude, loft, loft_rails, loft_to_point, revolve, screw, sphere, sweep, sweep_controlled};
|
||||
|
||||
/// The error of an SMLib operation in a build without SMLib.
|
||||
#[cfg(not(feature = "smlib"))]
|
||||
@@ -145,7 +145,7 @@ mod imp {
|
||||
}
|
||||
|
||||
/// The segment in 3D on `plane`, as SMLib's curve.
|
||||
fn curve(plane: &Plane, s: &Seg2) -> Result<Curve> {
|
||||
pub(crate) fn curve(plane: &Plane, s: &Seg2) -> Result<Curve> {
|
||||
let w = |q: Vec2| p(plane.to_world(q));
|
||||
let n = plane.x.cross(plane.y).normalized().ok_or_else(|| KernelError::Invalid("profile plane".into()))?;
|
||||
let bezier = |pts: &[Vec2], weights: &[f64]| {
|
||||
|
||||
Reference in New Issue
Block a user