Given a raw LiDAR scan of a pole-like outdoor structure, the pipeline segments the geometry, fits parametric CAD templates to it, reports measurements, and renders a physically based image. It is built so that every heavy GPU dependency has a documented CPU fallback, and the whole thing runs end to end on a laptop.

Stage 1: segment
Points are transformed from ECEF to a local ENU frame. Ground is removed with cloth-simulation filtering. Poles are found with RANSAC fitting of a tapered cone, wires are separated by PCA on local neighbourhoods, and the remainder is clustered with HDBSCAN. An equirectangular projection of the scene feeds a classifier for the clusters that geometry alone cannot label. Grounding DINO, SAM2, and Depth Anything V2 are optional accelerators, not requirements.
Stage 2: fit
Each segmented component is matched against a CAD template built with CadQuery and trimesh. Open3D ICP aligns the template; Nelder-Mead then optimises scale against a Chamfer-distance objective. Wires are fitted as catenaries. The stage emits fitted pole diameters, height, tilt, and catenary parameters, plus point-to-mesh residual statistics (mean, p95, and coverage within 5 cm) so a bad fit is visible in numbers rather than only in a picture.
Stage 3: render
Procedural PBR materials are assigned per component and the scene is rendered with pyrender, including a turntable sequence. Blender is an optional upgrade path behind the same interface.
Testing without a labelled dataset
There is no public ground truth for this kind of scene, so the test suite generates its own: synthetic poles, wires and ground planes with known parameters, run through the full pipeline, with the fitted parameters checked against the values that generated them. That makes the residual statistics in Stage 2 something the tests can assert on, not just report.
| Property | Value |
|---|---|
| Stages | segment, fit, render; each with YAML config and a JSON summary of timing |
| GPU dependencies | all optional, each with a documented CPU fallback |
| Fit quality | point-to-mesh residual mean, p95, and 5 cm coverage per component |
| Tests | pytest over procedurally generated scenes with known parameters |