Add hole detection (blind and through) for mechanical parts #14

Closed
opened 2026-06-17 18:15:23 +00:00 by Mark · 0 comments
Owner

Context

The user's primary use case for pc2cad is mechanical parts: scan → editable CAD. Mechanical parts almost always have holes (through-holes for fasteners, blind holes for tapped threads, counterbored holes for socket heads, countersinks for flat-head screws).

The current pipeline detects cylinders but doesn't reason about whether a cylinder is a hole (negative feature, subtracts material) or a boss/shaft (positive feature, adds material). Without that reasoning, the output CAD is missing one of the most common features.

The PLAN.md mentions feature detection in Milestone 2:

Milestone 2 — Feature Detection

  • Detect: holes (blind/through), slots, pockets, bosses, fillets/chamfers, patterns
  • Acceptance: feature classification with bounded false-positive rates

This issue is just the hole part of that milestone. Slots/pockets/bosses/fillets are separate issues.

Scope

Detection criteria

A fitted cylinder is a hole if:

  1. Orientation match: the cylinder axis is aligned with one of the dominant scan normals (typically the part's primary machining axis — Z for flat-machined parts).
  2. Boundary match: the cylinder's two end-faces, when projected onto a cross-section, match planar regions in the residual (i.e., the top/bottom of the hole is a flat face, not open material).
  3. Surrounded by material: a point sampled at radius r + epsilon from the axis lies inside the convex hull of the model — the hole is in the middle of material, not at an edge.
  4. Radius range: holes for fasteners are typically 1mm–20mm. Cylinders outside that range are likely bores/shafts.

A hole is through if both end-faces are flat AND the cylinder length equals the part thickness (within tolerance).
A hole is blind if only one end-face is flat AND the other end is open (no planar region).
A hole is counterbored if a second concentric cylinder with larger radius and shorter length is fitted nearby.
A hole is countersunk if a second concentric cone is fitted at one end.

CAD reconstruction

Once detected, holes must be applied as boolean cuts to the analytic solid, not just listed in the report:

  1. Build a cylinder solid from the fitted parameters
  2. If counterbored/countersunk: build the counterbore/cone and fuse it onto the cylinder
  3. Boolean-subtract the (counterbore + hole) from the main body
  4. Verify the result is still a single watertight solid

Output

  • report["features"]["holes"]: list of {type: "through"|"blind"|"counterbored"|"countersunk", center, axis, radius, depth, ...}
  • The STEP output should contain the holes as subtracted features (not just listed)

Acceptance

  • Detection accuracy on synthetic test cases: ≥90% precision, ≥85% recall on a benchmark with 20 known-hole scans (mixture of through/blind/counterbored/countersunk)
  • Boolean subtraction produces a single watertight solid (validate with FreeCAD Shape.isValid())
  • New CLI flag --detect-holes {off,auto,strict} defaulting to auto
  • New CLI flag --hole-radius-min, --hole-radius-max to constrain detection
  • Tests for each hole type using synthetic data

Why this matters

The user's primary workflow is "find the holes in this scanned part." Without hole detection, the analytic reconstruction is missing the most defining feature of a mechanical part. The user has explicitly said this — the scan in question has a counterbored through-hole that the current pipeline doesn't reconstruct.

## Context The user's primary use case for pc2cad is mechanical parts: scan → editable CAD. Mechanical parts almost always have holes (through-holes for fasteners, blind holes for tapped threads, counterbored holes for socket heads, countersinks for flat-head screws). The current pipeline detects cylinders but doesn't reason about whether a cylinder is a hole (negative feature, subtracts material) or a boss/shaft (positive feature, adds material). Without that reasoning, the output CAD is missing one of the most common features. The PLAN.md mentions feature detection in Milestone 2: > ### Milestone 2 — Feature Detection > - Detect: holes (blind/through), slots, pockets, bosses, fillets/chamfers, patterns > - Acceptance: feature classification with bounded false-positive rates This issue is just the hole part of that milestone. Slots/pockets/bosses/fillets are separate issues. ## Scope ### Detection criteria A fitted cylinder is a **hole** if: 1. **Orientation match**: the cylinder axis is aligned with one of the dominant scan normals (typically the part's primary machining axis — Z for flat-machined parts). 2. **Boundary match**: the cylinder's two end-faces, when projected onto a cross-section, match planar regions in the residual (i.e., the top/bottom of the hole is a flat face, not open material). 3. **Surrounded by material**: a point sampled at radius `r + epsilon` from the axis lies inside the convex hull of the model — the hole is in the middle of material, not at an edge. 4. **Radius range**: holes for fasteners are typically 1mm–20mm. Cylinders outside that range are likely bores/shafts. A hole is **through** if both end-faces are flat AND the cylinder length equals the part thickness (within tolerance). A hole is **blind** if only one end-face is flat AND the other end is open (no planar region). A hole is **counterbored** if a second concentric cylinder with larger radius and shorter length is fitted nearby. A hole is **countersunk** if a second concentric cone is fitted at one end. ### CAD reconstruction Once detected, holes must be applied as **boolean cuts** to the analytic solid, not just listed in the report: 1. Build a cylinder solid from the fitted parameters 2. If counterbored/countersunk: build the counterbore/cone and fuse it onto the cylinder 3. Boolean-subtract the (counterbore + hole) from the main body 4. Verify the result is still a single watertight solid ### Output - `report["features"]["holes"]`: list of `{type: "through"|"blind"|"counterbored"|"countersunk", center, axis, radius, depth, ...}` - The STEP output should contain the holes as subtracted features (not just listed) ## Acceptance - Detection accuracy on synthetic test cases: ≥90% precision, ≥85% recall on a benchmark with 20 known-hole scans (mixture of through/blind/counterbored/countersunk) - Boolean subtraction produces a single watertight solid (validate with FreeCAD `Shape.isValid()`) - New CLI flag `--detect-holes {off,auto,strict}` defaulting to `auto` - New CLI flag `--hole-radius-min`, `--hole-radius-max` to constrain detection - Tests for each hole type using synthetic data ## Why this matters The user's primary workflow is "find the holes in this scanned part." Without hole detection, the analytic reconstruction is missing the most defining feature of a mechanical part. The user has explicitly said this — the scan in question has a counterbored through-hole that the current pipeline doesn't reconstruct.
Mark closed this issue 2026-06-20 04:28:51 +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#14
No description provided.