Bug A: pc2cad has no top-down body+features decomposition #47

Closed
opened 2026-06-24 22:25:57 +00:00 by Mark · 1 comment
Owner

Strategy gap: pc2cad has no top-down body+features decomposition

What is missing

pc2cad.py::_fit_primitives_on_points returns a flat list of primitives.
There is no algorithm that takes the input pointcloud, decides which
primitive is the body, and which primitives are features to
boolean-cut from the body
. The export path (export_step,
export_stl, export_brep) consumes the flat list and emits each
primitive as a separate solid or compound member.

_derive_profile_features_from_sections exists but handles exactly one
narrow case: a single plane profile with a revolve operation. It is not
a general body+features composition.

_collect_feature_tools iterates feature primitives (holes, fillets,
chamfers, slots) but it does so independently of body identification
— it does not ask "which primitive owns this feature?" or "does this
feature lie inside the body's bounding volume?". This is the root
cause of pc2cad#34 (closed without a real strategy fix in commit
404f173 — the verify step doesn't address the strategy gap).

Sample

samples/strategy_plate_with_hole.ply (7000 points, σ=0.2 mm)

Parametric ground truth (build123d):

  • Body: 100 × 100 × 10 mm plate
  • Features: one Ø20 through-hole (boolean subtract) + 1 mm chamfer on
    the four top edges
  • See samples/specs/strategy_plate_with_hole_spec.py

samples/strategy_l_bracket.ply (9000 points, σ=0.3 mm)

Parametric ground truth (build123d):

  • Body: L-shape (80 × 80 × 10 wall + 80 × 60 × 10 foot)
  • Features: two Ø8 bolt holes through the foot, 2 mm fillet on the
    inner corner, 1 mm chamfer on the four outer top edges
  • See samples/specs/strategy_l_bracket_spec.py

What a real fix has to produce

A new module (e.g. pc2cad_reconstruct.py) that consumes
fit_primitives(...) output and emits a Reconstruction structure
with explicit body and features fields. The export path must
consume this structure and produce a STEP that contains one solid
per reconstruction
, not one solid per primitive.

Acceptance — agentic / visual verification

The implementer must run this command and attach both output PNGs to
the closing comment:

python tests/render_compare.py \
    samples/strategy_plate_with_hole.ply /tmp/bug_A_plate.step \
    --spec samples/specs/strategy_plate_with_hole_spec.py \
    --out-dir /tmp/bug_A_plate --tolerance 1.0 --min-coverage 0.85
python tests/render_compare.py \
    samples/strategy_l_bracket.ply /tmp/bug_A_bracket.step \
    --spec samples/specs/strategy_l_bracket_spec.py \
    --out-dir /tmp/bug_A_bracket --tolerance 1.0 --min-coverage 0.80

Both commands must report coverage ≥ 0.85 (plate) and coverage ≥ 0.80 (bracket), AND the closing comment must include:

  • /tmp/bug_A_plate/side_by_side.png and /tmp/bug_A_bracket/side_by_side.png
  • A STEP solids count for each sample — must be 1, not "1 per
    primitive"
  • A 3-line text description of how the agent verified the body+features
    composition is real (e.g. by reading the build123d spec and
    computing the boolean difference between the emitted STEP and the
    ground truth)

A commit that ships a compose_body_with_features function but does
not demonstrate ≥85% coverage on the plate sample with the rendered
PNGs is not a real fix — closing requires both the unit test and
the visual/behavioral evidence.

Why this is a strategy gap and not a function bug

Previous pc2cad strategy bugs (#32 "profile-extrude does not compose
compound shapes", #33 "no top-down decomposition into body + features")
were closed by commit-level workarounds (CLI flags, fallback commits)
that did not change the underlying capability. This bug describes the
underlying capability gap: there is no algorithm in pc2cad that
identifies a body primitive and routes features against it. Closing
this bug requires that algorithm to exist and to be demonstrably
correct on both synthetic samples.

  • pc2cad#32, pc2cad#33, pc2cad#34 (closed without real strategy fixes)
  • pc2cad#47 (Bug B — inlier coverage metric) and pc2cad#48 (Bug C —
    organic vs mechanical routing) target adjacent strategy gaps
  • pc2cad#49 (Bug D) commits the visual harness used for verification

How to regenerate the samples

python scripts/gen_strategy_samples.py
## Strategy gap: pc2cad has no top-down body+features decomposition ### What is missing `pc2cad.py::_fit_primitives_on_points` returns a flat list of primitives. There is no algorithm that takes the input pointcloud, decides which primitive is the **body**, and which primitives are **features to boolean-cut from the body**. The export path (`export_step`, `export_stl`, `export_brep`) consumes the flat list and emits each primitive as a separate solid or compound member. `_derive_profile_features_from_sections` exists but handles exactly one narrow case: a single plane profile with a revolve operation. It is not a general body+features composition. `_collect_feature_tools` iterates feature primitives (holes, fillets, chamfers, slots) but it does so **independently of body identification** — it does not ask "which primitive owns this feature?" or "does this feature lie inside the body's bounding volume?". This is the root cause of pc2cad#34 (closed without a real strategy fix in commit `404f173` — the verify step doesn't address the strategy gap). ### Sample `samples/strategy_plate_with_hole.ply` (7000 points, σ=0.2 mm) Parametric ground truth (build123d): - Body: 100 × 100 × 10 mm plate - Features: one Ø20 through-hole (boolean subtract) + 1 mm chamfer on the four top edges - See `samples/specs/strategy_plate_with_hole_spec.py` `samples/strategy_l_bracket.ply` (9000 points, σ=0.3 mm) Parametric ground truth (build123d): - Body: L-shape (80 × 80 × 10 wall + 80 × 60 × 10 foot) - Features: two Ø8 bolt holes through the foot, 2 mm fillet on the inner corner, 1 mm chamfer on the four outer top edges - See `samples/specs/strategy_l_bracket_spec.py` ### What a real fix has to produce A new module (e.g. `pc2cad_reconstruct.py`) that consumes `fit_primitives(...)` output and emits a `Reconstruction` structure with explicit `body` and `features` fields. The export path must consume this structure and produce a STEP that contains **one solid per reconstruction**, not one solid per primitive. ### Acceptance — agentic / visual verification The implementer must run this command and attach both output PNGs to the closing comment: ```bash python tests/render_compare.py \ samples/strategy_plate_with_hole.ply /tmp/bug_A_plate.step \ --spec samples/specs/strategy_plate_with_hole_spec.py \ --out-dir /tmp/bug_A_plate --tolerance 1.0 --min-coverage 0.85 python tests/render_compare.py \ samples/strategy_l_bracket.ply /tmp/bug_A_bracket.step \ --spec samples/specs/strategy_l_bracket_spec.py \ --out-dir /tmp/bug_A_bracket --tolerance 1.0 --min-coverage 0.80 ``` Both commands must report `coverage ≥ 0.85` (plate) and `coverage ≥ 0.80` (bracket), AND the closing comment must include: - `/tmp/bug_A_plate/side_by_side.png` and `/tmp/bug_A_bracket/side_by_side.png` - A STEP solids count for each sample — must be **1**, not "1 per primitive" - A 3-line text description of how the agent verified the body+features composition is real (e.g. by reading the build123d spec and computing the boolean difference between the emitted STEP and the ground truth) A commit that ships a `compose_body_with_features` function but does not demonstrate ≥85% coverage on the plate sample with the rendered PNGs is **not** a real fix — closing requires both the unit test and the visual/behavioral evidence. ### Why this is a strategy gap and not a function bug Previous pc2cad strategy bugs (#32 "profile-extrude does not compose compound shapes", #33 "no top-down decomposition into body + features") were closed by commit-level workarounds (CLI flags, fallback commits) that did not change the underlying capability. This bug describes the underlying capability gap: there is no algorithm in pc2cad that identifies a body primitive and routes features against it. Closing this bug requires that algorithm to exist and to be demonstrably correct on both synthetic samples. ### Related - pc2cad#32, pc2cad#33, pc2cad#34 (closed without real strategy fixes) - pc2cad#47 (Bug B — inlier coverage metric) and pc2cad#48 (Bug C — organic vs mechanical routing) target adjacent strategy gaps - pc2cad#49 (Bug D) commits the visual harness used for verification ### How to regenerate the samples ```bash python scripts/gen_strategy_samples.py ```
Author
Owner

This bug is part of a four-bug batch on the pc2cad reconstruction
strategy gaps. They are designed to be solved together because each
one's verification gate depends on the harness from Bug D and the
synthetic samples from Bug A.

Bug Title Depends on
Bug D (#50) render-compare harness committed —
Bug A (#47) body+features composition Bug D
Bug B (#48) inlier-coverage gate Bug D
Bug C (#49) organic vs mechanical routing Bug A + Bug B

Closing this bug requires running the verification commands in its body
and attaching the resulting side-by-side PNGs to the closing comment.
Closing any of A/B/C without Bug D's harness producing falsifiable
evidence is a workaround, not a fix.

## Cross-references — related strategy bugs This bug is part of a four-bug batch on the pc2cad reconstruction strategy gaps. They are designed to be solved together because each one's verification gate depends on the harness from Bug D and the synthetic samples from Bug A. | Bug | Title | Depends on | |---|---|---| | Bug D (#50) | render-compare harness committed | — | | Bug A (#47) | body+features composition | Bug D | | Bug B (#48) | inlier-coverage gate | Bug D | | Bug C (#49) | organic vs mechanical routing | Bug A + Bug B | Closing this bug requires running the verification commands in its body and attaching the resulting side-by-side PNGs to the closing comment. Closing any of A/B/C without Bug D's harness producing falsifiable evidence is a workaround, not a fix.
Mark closed this issue 2026-07-04 18:10:21 +00:00
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#47
No description provided.