Plane fitting: improve RANSAC plane segmentation and coverage reporting #11

Closed
opened 2026-06-17 18:14:01 +00:00 by Mark · 1 comment
Owner

Context

Plane fitting is the foundation of pc2cad — every other primitive type depends on plane candidates being cleanly segmented. The current implementation:

  • Uses a single global RANSAC pass with one tolerance
  • Doesn't expose per-segment confidence
  • Doesn't track inlier ratios well when many planes overlap (e.g., a base + a counterbored top + side walls)

This issue tracks general hardening of the plane path. Specific things to investigate:

  1. Per-segment thresholds — large flat regions of the scan should fit with tighter tolerance than small regions. The current FitConfig.tol_mode / tol_k are global.
  2. Adjacent plane separation — when two planes meet at an edge, RANSAC sometimes merges them. Need a penalty or iteration that forces separation.
  3. Coverage reporting — report["planar_segments"] exists but it's not clear what fraction of the scan is covered. Add a planar_coverage_ratio and surface it in the JSON report.
  4. Degenerate plane detection — three points will always fit a plane. Need minimum inlier count + minimum inlier ratio before accepting a plane candidate.

Scope

This is a hardening pass, not a rewrite. Improvements should be additive knobs (FitConfig fields + CLI flags) so existing behavior is preserved by default.

Acceptance

  • New FitConfig fields for per-segment thresholds, minimum inlier count/ratio, with sensible defaults
  • New CLI flags --plane-min-inliers, --plane-min-inlier-ratio, --plane-segment-tol-scale
  • report["planar_coverage_ratio"] added and documented
  • Tests with a known multi-plane synthetic scan covering all four improvements
  • Existing tests pass

Why this matters

pc2cad's analytic reconstruction quality is bounded by plane segmentation quality. Every other primitive (cylinder, cone) assumes planes are correctly partitioned before fitting. Better plane fit → better downstream primitives.

## Context Plane fitting is the foundation of pc2cad — every other primitive type depends on plane candidates being cleanly segmented. The current implementation: - Uses a single global RANSAC pass with one tolerance - Doesn't expose per-segment confidence - Doesn't track inlier ratios well when many planes overlap (e.g., a base + a counterbored top + side walls) This issue tracks general hardening of the plane path. Specific things to investigate: 1. **Per-segment thresholds** — large flat regions of the scan should fit with tighter tolerance than small regions. The current `FitConfig.tol_mode` / `tol_k` are global. 2. **Adjacent plane separation** — when two planes meet at an edge, RANSAC sometimes merges them. Need a penalty or iteration that forces separation. 3. **Coverage reporting** — `report["planar_segments"]` exists but it's not clear what fraction of the scan is covered. Add a `planar_coverage_ratio` and surface it in the JSON report. 4. **Degenerate plane detection** — three points will always fit a plane. Need minimum inlier count + minimum inlier ratio before accepting a plane candidate. ## Scope This is a hardening pass, not a rewrite. Improvements should be additive knobs (FitConfig fields + CLI flags) so existing behavior is preserved by default. ## Acceptance - New `FitConfig` fields for per-segment thresholds, minimum inlier count/ratio, with sensible defaults - New CLI flags `--plane-min-inliers`, `--plane-min-inlier-ratio`, `--plane-segment-tol-scale` - `report["planar_coverage_ratio"]` added and documented - Tests with a known multi-plane synthetic scan covering all four improvements - Existing tests pass ## Why this matters pc2cad's analytic reconstruction quality is bounded by plane segmentation quality. Every other primitive (cylinder, cone) assumes planes are correctly partitioned before fitting. Better plane fit → better downstream primitives.
Author
Owner

Cross-reference: substrate for #22

The hardened plane segmentation this issue delivers is the direct substrate for the new profile extraction work tracked in #22. Specifically:

  • #22 needs a clean set of planar segments with per-segment inlier ratios (so noisy small regions can be down-weighted or rejected before profile extraction).
  • #22's prismatic path consumes a planar segment, projects its inliers to 2D, and fits a closed boundary polygon / line+arc sketch.
  • #22's revolved path still needs plane segmentation indirectly: the axis-of-symmetry detection uses the principal plane(s) of the point cloud as a starting estimate, then refines.

The four acceptance items here (per-segment thresholds, inlier-ratio coverage reporting, minimum inlier count, adjacent-plane separation) are all prerequisites for #22 to produce a sketch from a real scan. When this issue lands, #22's planar input is well-defined.

## Cross-reference: substrate for #22 The hardened plane segmentation this issue delivers is the **direct substrate** for the new profile extraction work tracked in #22. Specifically: - #22 needs a clean set of planar segments with per-segment inlier ratios (so noisy small regions can be down-weighted or rejected before profile extraction). - #22's prismatic path consumes a planar segment, projects its inliers to 2D, and fits a closed boundary polygon / line+arc sketch. - #22's revolved path still needs plane segmentation indirectly: the axis-of-symmetry detection uses the principal plane(s) of the point cloud as a starting estimate, then refines. The four acceptance items here (per-segment thresholds, inlier-ratio coverage reporting, minimum inlier count, adjacent-plane separation) are all prerequisites for #22 to produce a sketch from a real scan. When this issue lands, #22's planar input is well-defined.
Mark closed this issue 2026-06-20 02:56:57 +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#11
No description provided.