From f5c2c725c8871f70e341758e0c6b24023a48f3e4 Mon Sep 17 00:00:00 2001 From: bherbruck Date: Wed, 7 Oct 2026 21:58:17 +0000 Subject: [PATCH] Extrude/revolve "all profiles" means the drawn ones: auto-projected face edges only count when the drawn curves make no profile Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL --- crates/doc/src/eval.rs | 7 ++++++- crates/sketch/src/lib.rs | 2 +- crates/sketch/src/profiles.rs | 14 ++++++++++++++ docs/oracle.md | 18 +++++++++--------- docs/parity.md | 28 ++++++++++++++-------------- 5 files changed, 44 insertions(+), 25 deletions(-) diff --git a/crates/doc/src/eval.rs b/crates/doc/src/eval.rs index 60c82fd9..d4c6a536 100644 --- a/crates/doc/src/eval.rs +++ b/crates/doc/src/eval.rs @@ -210,7 +210,12 @@ fn select_profiles(ss: &SolvedSketch, sel: &ProfileSel) -> Result> return Err(DocError::Invalid(format!("{} has no closed profiles", ss.name))); } let out: Vec = match sel { - ProfileSel::All => ps.iter().map(|p| p.region.clone()).collect(), + // "All" means what was drawn: projected reference geometry (a face's auto-projected + // edges) only counts when the drawn curves alone make no profile. + ProfileSel::All => { + let drawn = solvecraft_sketch::find_drawn_profiles(&ss.sketch); + if drawn.is_empty() { ps.iter().map(|p| p.region.clone()).collect() } else { drawn.into_iter().map(|p| p.region).collect() } + } ProfileSel::Indices { indices } => { let mut v = Vec::new(); for i in indices { diff --git a/crates/sketch/src/lib.rs b/crates/sketch/src/lib.rs index b1e5b73b..7c6f8513 100644 --- a/crates/sketch/src/lib.rs +++ b/crates/sketch/src/lib.rs @@ -16,7 +16,7 @@ mod solver; pub use link::{Link, LinkGeom, LinkKind, LinkSource, MAX_LINK_ENTITIES}; pub use model::{Constraint, ConstraintKind, Curve, CurveKind, SPoint, Sketch, SketchError}; -pub use profiles::{Profile, find_profiles, merge_regions}; +pub use profiles::{Profile, find_drawn_profiles, find_profiles, merge_regions}; pub use solver::{SolveReport, SolveStatus, solve}; #[cfg(test)] diff --git a/crates/sketch/src/profiles.rs b/crates/sketch/src/profiles.rs index 6535584e..b6bf4a3f 100644 --- a/crates/sketch/src/profiles.rs +++ b/crates/sketch/src/profiles.rs @@ -178,6 +178,20 @@ fn curvature(s: &Seg2) -> f64 { /// Find all closed profiles of a sketch. Curves are split where other curves end on them or /// cross them, like a drawing would be read. +/// Profiles of the drawn geometry only (linked reference curves left out). +pub fn find_drawn_profiles(sk: &Sketch) -> Vec { + if sk.links.is_empty() { + return find_profiles(sk); + } + let mut d = sk.clone(); + for c in &mut d.curves { + if c.link.is_some() { + c.construction = true; + } + } + find_profiles(&d) +} + pub fn find_profiles(sk: &Sketch) -> Vec { let tol = MERGE_TOL * 10.0; // Analytic shapes of the profile curves. diff --git a/docs/oracle.md b/docs/oracle.md index 1d2477d8..2ca2894c 100644 --- a/docs/oracle.md +++ b/docs/oracle.md @@ -2,7 +2,7 @@ Generated by `cargo xtask oracle`. Each case is a part built in Fusion (recipe and measurements kept locally in `plan/fusion/oracle/`, not committed). SolveCraft replays the recipe through its command engine and compares body count, volume and area (relative tolerance 1e-3) and face/edge/vertex counts (exact). -**19 / 29 cases pass** (4 need features not implemented yet). +**25 / 29 cases pass** (0 need features not implemented yet). | Case | Result | Notes | |---|---|---| @@ -14,21 +14,21 @@ Generated by `cargo xtask oracle`. Each case is a part built in Fusion (recipe a | 06-symmetric-extrude | pass | | | 07-fillet-all-edges | FAIL | step 8 (FusionFilletEdgesCommand): not supported yet: the faces at the edge ends must be planar | | 08-chamfer | pass | | -| 09-shell | not yet | recipe: feature op `shell` is not supported yet | +| 09-shell | pass | | | 10-rect-pattern-holes | pass | | | 11-circular-pattern-flange | pass | | | 12-mirror-feature | pass | | -| 13-combine-join | FAIL | step 12 (FusionCombineCommand): boolean Union: kernel internal error: boolean: This shell is not oriented and closed. | -| 14-combine-cut | FAIL | step 13 (FusionCombineCommand): boolean Cut: the operation failed: no result | -| 15-combine-intersect | FAIL | step 13 (FusionCombineCommand): boolean Intersect: the operation failed: no result | -| 16-sweep | not yet | recipe: feature op `sweep` is not supported yet | -| 17-loft | not yet | recipe: feature op `loft` is not supported yet | +| 13-combine-join | FAIL | step 12 (FusionCombineCommand): boolean Union: kernel internal error: boolean: This shell is not oriented and closed.; the operation failed: not supported yet: coincident faces on curved bodies | +| 14-combine-cut | pass | | +| 15-combine-intersect | pass | | +| 16-sweep | pass | | +| 17-loft | pass | | | 18-hole-features | pass | | | 19-l-bracket-constrained | pass | | | 20-slot-constrained | pass | | -| 21-draft | not yet | recipe: feature op `draft` is not supported yet | +| 21-draft | pass | | | 22-split-body | pass | | -| 23-bracket-multifeature | FAIL | step 14 (Extrude): boolean Union: the operation failed: no result | +| 23-bracket-multifeature | FAIL | step 15 (FusionFilletEdgesCommand): not supported yet: each end of the edge must touch exactly one more face | | 24-user-parameters | pass | | | 25-sketch-triangle | pass | | | 26-sketch-belt | pass | | diff --git a/docs/parity.md b/docs/parity.md index 84ebb69a..e24a8ea9 100644 --- a/docs/parity.md +++ b/docs/parity.md @@ -2,7 +2,7 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the toolbar commands of Fusion's Design workspace, ids and names only) and the live command registry (`solvecraft-cli commands`). A command counts as live when SolveCraft registers the same command id. This measures breadth, not depth; see ROADMAP.md and docs/oracle.md for depth. -**SOLID + SKETCH: 59 / 291 commands live (20%).** All Design tabs: 145 / 1175 (12%). Registered commands: 83. +**SOLID + SKETCH: 64 / 291 commands live (22%).** All Design tabs: 155 / 1175 (13%). Registered commands: 89. | Tab | Panel | Live | Total | % | |---|---|---:|---:|---:| @@ -12,15 +12,15 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool | SOLID | CONFIGURE | 0 | 3 | 0% | | SOLID | CONSTRUCT | 2 | 20 | 10% | | SOLID | INSPECT | 1 | 25 | 4% | -| SOLID | INSERT | 0 | 11 | 0% | +| SOLID | INSERT | 1 | 11 | 9% | | SOLID | SELECT | 0 | 15 | 0% | | SOLID | POSITION | 0 | 2 | 0% | -| SKETCH | CREATE | 16 | 41 | 39% | +| SKETCH | CREATE | 19 | 41 | 46% | | SKETCH | MODIFY | 2 | 12 | 17% | | SKETCH | CONSTRAINTS | 11 | 15 | 73% | | SKETCH | CONFIGURE | 0 | 3 | 0% | | SKETCH | INSPECT | 1 | 25 | 4% | -| SKETCH | INSERT | 1 | 13 | 8% | +| SKETCH | INSERT | 2 | 13 | 15% | | SKETCH | ASSEMBLE | 0 | 1 | 0% | | SKETCH | SELECT | 0 | 15 | 0% | | SKETCH | FINISH SKETCH | 1 | 2 | 50% | @@ -30,10 +30,10 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool | SURFACE | CONFIGURE | 0 | 3 | 0% | | SURFACE | CONSTRUCT | 2 | 20 | 10% | | SURFACE | INSPECT | 1 | 25 | 4% | -| SURFACE | INSERT | 0 | 11 | 0% | +| SURFACE | INSERT | 1 | 11 | 9% | | SURFACE | SELECT | 0 | 15 | 0% | | SURFACE | POSITION | 0 | 2 | 0% | -| MESH | CREATE | 0 | 5 | 0% | +| MESH | CREATE | 1 | 5 | 20% | | MESH | PREPARE | 0 | 4 | 0% | | MESH | MODIFY | 4 | 30 | 13% | | MESH | ASSEMBLE | 1 | 21 | 5% | @@ -50,7 +50,7 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool | FORM | UTILITIES | 0 | 5 | 0% | | FORM | CONSTRUCT | 2 | 20 | 10% | | FORM | INSPECT | 1 | 25 | 4% | -| FORM | INSERT | 1 | 13 | 8% | +| FORM | INSERT | 2 | 13 | 15% | | FORM | ASSEMBLE | 0 | 1 | 0% | | FORM | SELECT | 0 | 15 | 0% | | FORM | FINISH FORM | 0 | 1 | 0% | @@ -60,7 +60,7 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool | SHEET METAL | CONFIGURE | 0 | 3 | 0% | | SHEET METAL | CONSTRUCT | 2 | 20 | 10% | | SHEET METAL | INSPECT | 1 | 25 | 4% | -| SHEET METAL | INSERT | 0 | 11 | 0% | +| SHEET METAL | INSERT | 1 | 11 | 9% | | SHEET METAL | SELECT | 0 | 15 | 0% | | SHEET METAL | REFOLD | 0 | 1 | 0% | | SHEET METAL | POSITION | 0 | 2 | 0% | @@ -71,7 +71,7 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool | PLASTIC | CONFIGURE | 0 | 3 | 0% | | PLASTIC | CONSTRUCT | 2 | 20 | 10% | | PLASTIC | INSPECT | 1 | 26 | 4% | -| PLASTIC | INSERT | 0 | 11 | 0% | +| PLASTIC | INSERT | 1 | 11 | 9% | | PLASTIC | SELECT | 0 | 15 | 0% | | PLASTIC | POSITION | 0 | 2 | 0% | | ASSEMBLY | INSERT | 1 | 8 | 12% | @@ -129,6 +129,7 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool - SOLID › CONSTRUCT › Offset Plane (`ConstructionPlaneOffsetFromPlaneCommand`) - SOLID › CONSTRUCT › Plane at Angle (`ConstructionPlaneAtAngleCommand`) - SOLID › INSPECT › Measure (`MeasureCommand`) +- SOLID › INSERT › Insert Mesh (`ParaMeshInsertAlignCommand`) - SKETCH › CREATE › Line (`DrawPolyline`) - SKETCH › CREATE › 2-Point Rectangle (`ShapeRectangleTwoPoint`) - SKETCH › CREATE › 3-Point Rectangle (`ShapeRectangleThreePoint`) @@ -144,6 +145,9 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool - SKETCH › CREATE › Center to Center Slot (`ShapeSlotCenterToCenter`) - SKETCH › CREATE › Overall Slot (`ShapeSlotOverall`) - SKETCH › CREATE › Point (`DrawPoint`) +- SKETCH › CREATE › Project (`ProjectNewCmd`) +- SKETCH › CREATE › Intersect (`IntersectCmd`) +- SKETCH › CREATE › Include 3D Geometry (`Include3DGeometry`) - SKETCH › CREATE › Sketch Dimension (`SketchDimension`) - SKETCH › MODIFY › Move/Copy (`FusionMoveCommand`) - SKETCH › MODIFY › Change Parameters (`ChangeParameterCommand`) @@ -159,6 +163,7 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool - SKETCH › CONSTRAINTS › Collinear (`ConstraintCollinear`) - SKETCH › CONSTRAINTS › Symmetry (`ConstraintSymmetry`) - SKETCH › INSPECT › Measure (`MeasureCommand`) +- SKETCH › INSERT › Insert Mesh (`ParaMeshInsertAlignCommand`) - SKETCH › INSERT › Insert Component (`FusionImportCommandFromToolbar`) - SKETCH › FINISH SKETCH › Finish Sketch (`SketchStop`) @@ -277,7 +282,6 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool - SOLID › INSERT › Insert T-Spline (`TSplineImportCommand`) - SOLID › INSERT › Insert SVG (`SketchImportSVG`) - SOLID › INSERT › Insert DXF (`ImportDxfFileCommand`) -- SOLID › INSERT › Insert Mesh (`ParaMeshInsertAlignCommand`) - SOLID › INSERT › Insert Fastener (`FusionFastenersCommand`) - SOLID › INSERT › Insert Derive (`PullDeriveCommand`) - SOLID › INSERT › Insert McMaster-Carr Component (`InsertMcMasterCarrComponentCommand`) @@ -319,10 +323,7 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool - SKETCH › CREATE › Mirror (`MirrorSketchCommand`) - SKETCH › CREATE › Circular Pattern (`CircularSketchPatternCommand`) - SKETCH › CREATE › Rectangular Pattern (`RectangularSketchPatternCommand`) -- SKETCH › CREATE › Project (`ProjectNewCmd`) -- SKETCH › CREATE › Intersect (`IntersectCmd`) - SKETCH › CREATE › Spun Profile (`SpunProfileCmd`) -- SKETCH › CREATE › Include 3D Geometry (`Include3DGeometry`) - SKETCH › CREATE › Project To Surface (`ProjectToSurface`) - SKETCH › CREATE › Intersection Curve (`IntersectionCurve`) - SKETCH › CREATE › Isoparametric Curve (`SketchIsoparametricCurve`) @@ -372,7 +373,6 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool - SKETCH › INSERT › Insert T-Spline (`TSplineImportCommand`) - SKETCH › INSERT › Insert SVG (`SketchImportSVG`) - SKETCH › INSERT › Insert DXF (`ImportDxfFileCommand`) -- SKETCH › INSERT › Insert Mesh (`ParaMeshInsertAlignCommand`) - SKETCH › INSERT › Insert Fastener (`FusionFastenersCommand`) - SKETCH › INSERT › Duplicate With Joints (`FusionDuplicateWithJointsCommand`) - SKETCH › INSERT › Insert Derive (`PullDeriveCommand`)