compose_body_with_features detects features but never booleans them from the body — hole missing in output STEP #53

Closed
opened 2026-07-16 05:25:49 +00:00 by Mark · 1 comment
Owner

compose_body_with_features identifies features but never booleans them from the body

What works

compose_body_with_features() in pc2cad_reconstruct.py correctly identifies
the body primitive and classifies other primitives as features (hole, chamfer,
fillet, slot). The Reconstruction dataclass carries body_primitive_indices
and a features list with kind + primitive pairs.

What doesn't work

The export path (export_reconstruction / reconstruct_to_build123d) does not
execute the boolean subtraction. On samples/strategy_plate_with_hole.ply:

  1. Detection: body = plate (profile_extrude), features = [hole(cylinder), chamfer(edges)]
  2. Export: converts the plate primitive to a build123d solid, writes it to STEP
  3. Result: STEP has 1 solid, 153 faces, coverage 0.969 — but the hole is not cut
    Visually confirmed: the pointcloud has a clear Ø20 through-hole (dark gap in
    center-top), the STEP is a solid slab with no aperture.

The detection output is correct. The feature list exists. No boolean subtraction
ever happens between identification and export.

What's needed

reconstruct_to_build123d(reconstruction) -> build123d.Part must:

  1. Convert the body primitive to a build123d solid
  2. For each feature in reconstruction.features:
    • Convert the feature primitive to a tool solid
    • Boolean-subtract (or combine, for additive features) from the body
  3. Return the fused Part as the single reconstruction output
  4. The harness on strategy_plate_with_hole.ply must report coverage ≥ 0.85
    AND visually show the hole present (center gap in both input and output)

Current workaround

The CLI --mode auto with the output of this function does not enter the
boolean path. The surface fix (#51 default=auto) works at the routing level
but the boolean path itself was never implemented downstream.

Verification gate

python pc2cad_cli.py samples/strategy_plate_with_hole.ply \
    --out /tmp/fix_plate.step --out-format build123d
python tests/render_compare.py samples/strategy_plate_with_hole.ply \
    /tmp/fix_plate.step --out-dir /tmp/fix_plate --tolerance 1.0 \
    --min-coverage 0.85
# Also: visually inspect /tmp/fix_plate/side_by_side.png — the
# reconstructed STEP MUST show the hole. If it's a solid slab, fix fails.
## compose_body_with_features identifies features but never booleans them from the body ### What works `compose_body_with_features()` in `pc2cad_reconstruct.py` correctly identifies the body primitive and classifies other primitives as features (hole, chamfer, fillet, slot). The `Reconstruction` dataclass carries `body_primitive_indices` and a `features` list with kind + primitive pairs. ### What doesn't work The export path (`export_reconstruction` / `reconstruct_to_build123d`) does not execute the boolean subtraction. On `samples/strategy_plate_with_hole.ply`: 1. Detection: body = plate (profile_extrude), features = [hole(cylinder), chamfer(edges)] 2. Export: converts the plate primitive to a build123d solid, writes it to STEP 3. Result: STEP has 1 solid, 153 faces, coverage 0.969 — but **the hole is not cut** Visually confirmed: the pointcloud has a clear Ø20 through-hole (dark gap in center-top), the STEP is a solid slab with no aperture. The detection output is correct. The feature list exists. No boolean subtraction ever happens between identification and export. ### What's needed `reconstruct_to_build123d(reconstruction) -> build123d.Part` must: 1. Convert the body primitive to a build123d solid 2. For each feature in `reconstruction.features`: - Convert the feature primitive to a tool solid - Boolean-subtract (or combine, for additive features) from the body 3. Return the fused Part as the single reconstruction output 4. The harness on `strategy_plate_with_hole.ply` must report coverage ≥ 0.85 AND visually show the hole present (center gap in both input and output) ### Current workaround The CLI `--mode auto` with the output of this function does not enter the boolean path. The surface fix (#51 default=auto) works at the routing level but the boolean path itself was never implemented downstream. ### Verification gate ```bash python pc2cad_cli.py samples/strategy_plate_with_hole.ply \ --out /tmp/fix_plate.step --out-format build123d python tests/render_compare.py samples/strategy_plate_with_hole.ply \ /tmp/fix_plate.step --out-dir /tmp/fix_plate --tolerance 1.0 \ --min-coverage 0.85 # Also: visually inspect /tmp/fix_plate/side_by_side.png — the # reconstructed STEP MUST show the hole. If it's a solid slab, fix fails. ```
Mark 2026-07-26 15:18:00 +00:00
Author
Owner

Fix landed at commit 88f8198 on main.

The boolean subtraction of features (hole, chamfer, fillet) from the body primitive is now implemented in reconstruct_to_build123d(). Unit scaling is moved inside the function (not post-hoc applied to the final Solid) so analytic face types survive the cut and round-trip through STEP as real circles.

Verification on samples/strategy_plate_with_hole.ply:

  • CLI export: Exported body+features reconstruction (body=l_extrusion, features=1)
  • Render compare coverage: 0.971 (threshold 0.85) — PASS
  • STEP solids: 1, faces: 56 (was 153 as solid slab)
  • Circular edges: 2 (top + bottom rim of through-hole) — >=2 PASS
  • Full test suite: lint PASS, pre-commit hooks PASS
Fix landed at commit 88f8198 on main. The boolean subtraction of features (hole, chamfer, fillet) from the body primitive is now implemented in `reconstruct_to_build123d()`. Unit scaling is moved inside the function (not post-hoc applied to the final Solid) so analytic face types survive the cut and round-trip through STEP as real circles. Verification on `samples/strategy_plate_with_hole.ply`: - CLI export: `Exported body+features reconstruction (body=l_extrusion, features=1)` - Render compare coverage: **0.971** (threshold 0.85) — PASS - STEP solids: **1**, faces: **56** (was 153 as solid slab) - Circular edges: **2** (top + bottom rim of through-hole) — >=2 PASS - Full test suite: lint PASS, pre-commit hooks PASS
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Mark/pc2cad#53
No description provided.