Freeform Poisson default is wrong for open / non-orientable organic shapes #26

Closed
opened 2026-06-20 19:33:06 +00:00 by Mark · 0 comments
Owner

Freeform Poisson default is wrong for open / non-orientable organic shapes

What this is

A visual assessment of pc2cad's freeform (Poisson) reconstruction on the
three organic sample pointclouds, run on 2026-06-20. The companion
issue is pc2cad#24 (single-plane extrude regression on
sample_plane_cyl.ply); this issue covers the freeform side of the
same picture.

How the assessment was done

For each sample I ran:

python pc2cad_cli.py samples/<name>.ply \
  --out /tmp/<name>.brep \
  --mode hybrid --freeform poisson --freeform-poisson-depth 8 \
  --report /tmp/<name>_freeform_report.json

Then I rendered the input pointcloud and the Poisson-reconstructed
mesh in 3 orthographic views and visually compared them. The
reconstructed mesh shown is the same algorithm (Poisson, depth 8) that
pc2cad runs internally, just executed outside the pipeline so the
mesh is renderable. Screenshots are attached below.

Results

Sample Points Coverage Freeform status Triangles Visual verdict
organic_bunny.ply 15,000 91.6% ok 19,061 Recognizable as a hunched bunny; ears, legs, tail merged into a smooth blob
organic_torus_knot.ply 19,881 0.0% ok 154,021 Topology preserved (3 loops), tube rough/ribbed
organic_vase.ply 20,000 98.4% ok 10,747 Silhouette captured; top opening is sealed — looks like a gourd, not a vase

Per-sample

organic_bunny (15k pts, 91.6% analytic coverage)

  • 7 sphere primitives fit (all low_confidence_primitives) + Poisson
    mesh (19k tris). The sphere fits are noise — they don't correspond
    to any anatomical feature of the bunny and are flagged as
    low-confidence in the report.
  • The Poisson surface is a smooth hunched mass. Ears, legs, tail, and
    face are absent; high-frequency anatomical detail is washed out.
  • The pointcloud is a sparse 15k sample of the original ~360k Stanford
    Bunny, which is the dominant constraint here — Poisson at depth 8
    on 15k points cannot recover the ear geometry.
  • The freeform mesh is the only useful output for this sample; the
    analytic primitives add nothing.

organic_torus_knot (20k pts, 0.0% coverage, 100% residual)

  • The analytic stage fails completely: no_primitives_fit,
    low_coverage, high_residual all flagged. The pipeline correctly
    identifies "no spheres / planes / cylinders to fit" and falls
    through to freeform.
  • Poisson produces 154k triangles — the most complex of the three,
    but topology (3-twist, 3 inner / 3 outer loops) is preserved.
  • Visual: the tube surface is rough and ribbed rather than smooth.
    With coverage = 0.0, the pipeline has effectively given up
    analytically; only the freeform mesh is meaningful, and the
    pipeline produces a FreeCAD-missing placeholder for the .brep.

organic_vase (20k pts, 98.4% coverage)

  • 4 sphere primitives fit (all low_confidence_primitives) + Poisson
    mesh (10.7k tris).
  • Critical visual defect: the vase's hollow interior and rim
    opening are gone. The reconstruction is a sealed solid that reads
    as a gourd or onion.
  • This is a fundamental limitation of Poisson: it produces a
    watertight surface by construction, which is exactly the wrong
    topology for a vessel.
  • The CLI's --freeform flag already exposes poisson /
    ball_pivoting / alpha_shapes — for the vase, alpha_shapes
    or ball_pivoting would preserve the open top. The CLI defaults
    to Poisson.

Visual evidence

Overview (all three stacked)

Overview

organic_bunny — input vs. Poisson

bunny

The 15k-point sparse sample and the Poisson reconstruction side by
side. The reconstruction is a smooth hunched mass; ears, legs, tail,
and face are absent.

organic_torus_knot — input vs. Poisson

torus knot

Topology preserved (3 loops), tube rough/ribbed. The 0% analytic
coverage in the report means only the freeform mesh is meaningful.

organic_vase — input vs. Poisson

vase

Silhouette captured, but the top is sealed — looks like a gourd,
not a vase. Alpha shapes or ball pivoting would do better here.

Cross-sample issues

  1. Poisson is the wrong default for open / non-orientable surfaces.
    The vase shows this clearly. Alpha shapes or ball pivoting handle
    the open top correctly. The CLI exposes both via --freeform alpha_shapes and --freeform ball_pivoting, but Poisson is the
    default. A small wrapper heuristic ("is the convex hull fully
    filled, or does the pointcloud have interior concavities?") could
    pick a better default per-sample, or the user needs to know to
    pick a different method for open objects.

  2. Analytic fitting on organic inputs is noise. All three samples
    produce meaningless sphere-fits with low_confidence_primitives
    warnings. These fits add nothing useful and clutter the report. A
    pre-fit check (e.g. "is this organic?") could skip the analytic
    stage entirely for organic samples, or move the analytic results
    to a less prominent place in the report (e.g. behind a
    --show-analytics flag).

  3. coverage=0.0 and no_primitives_fit are framed as failures
    when they're really "this is freeform-only territory."
    The
    warning array on the torus_knot sample is technically correct
    (no analytic primitives fit) but misleading in the context of a
    freeform-only output. A warning reformulation or a separate
    "analytic skipped: sample is freeform-suitable" message would be
    clearer.

  • pc2cad#24 — single-plane profile_extrude regression
    (companion issue, same assessment cycle)
  • pc2cad#22 — build123d export path
  • pc2cad#23 — full FreeCAD→OCP port

Suggested next step (for the human picking this up)

A small, low-risk enhancement: change the default for --freeform on
organic samples from poisson to alpha_shapes, OR add a
"shape-type detector" that picks Poisson for solid closed shapes and
alpha_shapes / ball_pivoting for shells / open surfaces. The CLI
already exposes all three methods; only the default needs work.

Reproduction

cd ~/Projects/pc2cad
for f in samples/organic_*.ply; do
  name=$(basename "$f" .ply)
  python pc2cad_cli.py "$f" \
    --out /tmp/${name}_freeform.brep \
    --mode hybrid --freeform poisson --freeform-poisson-depth 8 \
    --report /tmp/${name}_freeform_report.json
done

Then re-render the input / output pointcloud vs. Poisson mesh in 3
views and compare. The screenshots in this issue were produced by
/tmp/render_organic.py (renders the same Poisson mesh outside the
pipeline so it's a renderable mesh file).

# Freeform Poisson default is wrong for open / non-orientable organic shapes ## What this is A visual assessment of pc2cad's freeform (Poisson) reconstruction on the three organic sample pointclouds, run on 2026-06-20. The companion issue is pc2cad#24 (single-plane extrude regression on `sample_plane_cyl.ply`); this issue covers the freeform side of the same picture. ## How the assessment was done For each sample I ran: ```bash python pc2cad_cli.py samples/<name>.ply \ --out /tmp/<name>.brep \ --mode hybrid --freeform poisson --freeform-poisson-depth 8 \ --report /tmp/<name>_freeform_report.json ``` Then I rendered the input pointcloud and the Poisson-reconstructed mesh in 3 orthographic views and visually compared them. The reconstructed mesh shown is the same algorithm (Poisson, depth 8) that pc2cad runs internally, just executed outside the pipeline so the mesh is renderable. Screenshots are attached below. ## Results | Sample | Points | Coverage | Freeform status | Triangles | Visual verdict | |---|---|---|---|---|---| | `organic_bunny.ply` | 15,000 | 91.6% | ok | 19,061 | Recognizable as a hunched bunny; ears, legs, tail merged into a smooth blob | | `organic_torus_knot.ply` | 19,881 | **0.0%** | ok | 154,021 | Topology preserved (3 loops), tube rough/ribbed | | `organic_vase.ply` | 20,000 | 98.4% | ok | 10,747 | Silhouette captured; **top opening is sealed** — looks like a gourd, not a vase | ### Per-sample **`organic_bunny`** (15k pts, 91.6% analytic coverage) - 7 sphere primitives fit (all `low_confidence_primitives`) + Poisson mesh (19k tris). The sphere fits are noise — they don't correspond to any anatomical feature of the bunny and are flagged as low-confidence in the report. - The Poisson surface is a smooth hunched mass. Ears, legs, tail, and face are absent; high-frequency anatomical detail is washed out. - The pointcloud is a sparse 15k sample of the original ~360k Stanford Bunny, which is the dominant constraint here — Poisson at depth 8 on 15k points cannot recover the ear geometry. - The freeform mesh is the only useful output for this sample; the analytic primitives add nothing. **`organic_torus_knot`** (20k pts, **0.0% coverage**, 100% residual) - The analytic stage fails completely: `no_primitives_fit`, `low_coverage`, `high_residual` all flagged. The pipeline correctly identifies "no spheres / planes / cylinders to fit" and falls through to freeform. - Poisson produces 154k triangles — the most complex of the three, but topology (3-twist, 3 inner / 3 outer loops) is preserved. - Visual: the tube surface is rough and ribbed rather than smooth. With `coverage = 0.0`, the pipeline has effectively given up analytically; only the freeform mesh is meaningful, and the pipeline produces a FreeCAD-missing placeholder for the .brep. **`organic_vase`** (20k pts, 98.4% coverage) - 4 sphere primitives fit (all `low_confidence_primitives`) + Poisson mesh (10.7k tris). - **Critical visual defect:** the vase's hollow interior and rim opening are gone. The reconstruction is a sealed solid that reads as a gourd or onion. - This is a fundamental limitation of Poisson: it produces a watertight surface by construction, which is exactly the wrong topology for a vessel. - The CLI's `--freeform` flag already exposes `poisson` / `ball_pivoting` / `alpha_shapes` — for the vase, **alpha_shapes** or **ball_pivoting** would preserve the open top. The CLI defaults to Poisson. ## Visual evidence ### Overview (all three stacked) ![Overview](https://forgejo.tail018ac4.ts.net/attachments/2c6812cd-b4f2-4a08-b39b-a47ed6935d8b) ### `organic_bunny` — input vs. Poisson ![bunny](https://forgejo.tail018ac4.ts.net/attachments/24152943-3e0a-4b07-bc51-e773645abb81) The 15k-point sparse sample and the Poisson reconstruction side by side. The reconstruction is a smooth hunched mass; ears, legs, tail, and face are absent. ### `organic_torus_knot` — input vs. Poisson ![torus knot](https://forgejo.tail018ac4.ts.net/attachments/b232354d-8dfe-423a-b3d2-28950b03021c) Topology preserved (3 loops), tube rough/ribbed. The 0% analytic coverage in the report means only the freeform mesh is meaningful. ### `organic_vase` — input vs. Poisson ![vase](https://forgejo.tail018ac4.ts.net/attachments/e17527be-7582-4bdf-b4ea-95216c931062) Silhouette captured, but the top is sealed — looks like a gourd, not a vase. Alpha shapes or ball pivoting would do better here. ## Cross-sample issues 1. **Poisson is the wrong default for open / non-orientable surfaces.** The vase shows this clearly. Alpha shapes or ball pivoting handle the open top correctly. The CLI exposes both via `--freeform alpha_shapes` and `--freeform ball_pivoting`, but Poisson is the default. A small wrapper heuristic ("is the convex hull fully filled, or does the pointcloud have interior concavities?") could pick a better default per-sample, or the user needs to know to pick a different method for open objects. 2. **Analytic fitting on organic inputs is noise.** All three samples produce meaningless sphere-fits with `low_confidence_primitives` warnings. These fits add nothing useful and clutter the report. A pre-fit check (e.g. "is this organic?") could skip the analytic stage entirely for organic samples, or move the analytic results to a less prominent place in the report (e.g. behind a `--show-analytics` flag). 3. **`coverage=0.0` and `no_primitives_fit` are framed as failures when they're really "this is freeform-only territory."** The warning array on the torus_knot sample is technically correct (no analytic primitives fit) but misleading in the context of a freeform-only output. A warning reformulation or a separate "analytic skipped: sample is freeform-suitable" message would be clearer. ## Related - pc2cad#24 — single-plane profile_extrude regression (companion issue, same assessment cycle) - pc2cad#22 — build123d export path - pc2cad#23 — full FreeCAD→OCP port ## Suggested next step (for the human picking this up) A small, low-risk enhancement: change the default for `--freeform` on organic samples from `poisson` to `alpha_shapes`, OR add a "shape-type detector" that picks Poisson for solid closed shapes and alpha_shapes / ball_pivoting for shells / open surfaces. The CLI already exposes all three methods; only the default needs work. ## Reproduction ```bash cd ~/Projects/pc2cad for f in samples/organic_*.ply; do name=$(basename "$f" .ply) python pc2cad_cli.py "$f" \ --out /tmp/${name}_freeform.brep \ --mode hybrid --freeform poisson --freeform-poisson-depth 8 \ --report /tmp/${name}_freeform_report.json done ``` Then re-render the input / output pointcloud vs. Poisson mesh in 3 views and compare. The screenshots in this issue were produced by `/tmp/render_organic.py` (renders the same Poisson mesh outside the pipeline so it's a renderable mesh file).
Mark 2026-06-21 14:35:47 +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#26
No description provided.