| --- |
| license: cc-by-4.0 |
| tags: |
| - mesh-segmentation |
| - part-segmentation |
| - point-cloud |
| - vegetation |
| - onnx |
| - 3d |
| - qtmesheditor |
| library_name: onnx |
| pipeline_tag: other |
| --- |
| |
| # QtMeshEditor β Vegetation Part Segmentation |
|
|
| A point-cloud part-segmentation network (PointNet++-style) that labels each |
| point of a **tree / plant** mesh as `trunk`, `branch`, `foliage`, `root`, or |
| `flower` (fruit), exported to **ONNX** for local inference via ONNX Runtime. |
|
|
| One of the category-specialised segmentation models built for |
| **[QtMeshEditor](https://github.com/fernandotonon/QtMeshEditor)** (epic #818, |
| Track B2) β a free, open-source 3D mesh & animation editor. The app |
| auto-detects the mesh category with a companion |
| [point-cloud classifier](https://huggingface.co/fernandotonon/QtMeshEditor-mesh-segmentation-category) |
| and dispatches to this model for vegetation; the |
| [body model](https://huggingface.co/fernandotonon/QtMeshEditor-mesh-segmentation) |
| covers characters, with |
| [vehicle](https://huggingface.co/fernandotonon/QtMeshEditor-mesh-segmentation-vehicle) |
| and |
| [building](https://huggingface.co/fernandotonon/QtMeshEditor-mesh-segmentation-building) |
| siblings. The aggregate download source used by the app is |
| [QtMeshEditor-models](https://huggingface.co/fernandotonon/QtMeshEditor-models) |
| (`segment/meshseg_vegetation.onnx`). |
|
|
| ## Model |
|
|
| - **Input:** a sampled point cloud `float32 [1, N, 3]` (normalised to a centred |
| unit box; +Y up). |
| - **Output:** per-point class logits over 6 channels |
| (`unknown, trunk, branch, foliage, root, flower`); argmax β label, scattered |
| back to mesh vertices/faces by nearest sampled point. |
| - **Architecture:** shared per-point MLP + two kNN local-aggregation blocks |
| (in-graph `cdist`+`topk`, ONNX-exportable) + a global max-pooled feature; |
| ~0.78 MB. Trained at the app's inference sample size (4096 points). |
|
|
| ## Training data & license |
|
|
| Trained **from scratch, 100% on procedurally generated synthetic trees we |
| own** (no third-party data at all): parametric broadleaf / pine / palm / |
| dead-tree / bush regimes with surface-sampled capsule trunks and branches, |
| canopy-vs-per-tip foliage blobs, surface roots, and flower/fruit clusters β |
| labels are exact by construction. Weights released under **CC-BY-4.0**; |
| please credit *QtMeshEditor*. |
|
|
| ## Evaluation |
|
|
| - Held-out synthetic validation accuracy: **93.3%** (v1.1 β a harder |
| big-canopy / drooping-oak distribution; v1.0 scored 93.8% on the narrower |
| set), per-point, unknown masked. Real-world CC0 vegetation packs are the |
| planned next data slice (mined via material/submesh-name labels). |
| - Per-class recall on held-out synthetic trees (v1.2 β v1.3): |
| branch 0.58 β **0.92**, root 0.57 β **0.80**, trunk 0.71 β 0.79, |
| foliage 0.94, flower 0.78; overall 0.85 β **0.92**. |
| - Real-world check (stylized oak FBX, huge low canopy + stubby trunk): |
| v1.0 mislabelled ~63k canopy verts as trunk β v1.3 gives trunk 4.5k, |
| branch 16.6k (full skeleton through the canopy), **root 0** (this oak |
| models no root β correct), foliage intact. Root/trunk on real meshes |
| stays the hardest class β the durable fix is the planned CC0 |
| real-vegetation data slice. |
|
|
| ## Reproducing |
|
|
| `scripts/export-meshseg-onnx.py --category vegetation` in the QtMeshEditor |
| repo (one-time, offline; the app never runs Python). Strategy + roadmap: |
| `docs/MESH_SEGMENTATION_STRATEGY.md`. |
|
|
| ## Versions |
|
|
| - **v1.2.0** (current) β root/trunk/branch balance: |
| - roots appear in only ~20% of trees (most real tree meshes model no roots β |
| they're underground) and, when present, are thick / buttress-like / |
| strictly ground-hugging (not twig-thin); |
| - a new trunk base FLARE is labelled trunk so a widening base isn't read as |
| root; |
| - branches are strengthened β more primary branches, sub-branches that thread |
| up into the canopy, and 3Γ branch sample weight β so the trunk/root |
| tightening doesn't eat branch recall. |
| Net on the real oak: root over-prediction gone (1980β0 for a rootless tree), |
| branch skeleton recovered (3kβ16.6k verts), trunk tightened to the real trunk |
| (10kβ4.5k). Held-out branch recall 0.58β0.92, root 0.57β0.80, overall |
| 0.85β0.92. |
| - **v1.1.0** β big-canopy robustness: added an `oak` regime |
| (stubby trunk, canopy 1.1β2.2Γ larger, foliage drooping down around/below |
| the trunk top with a low skirt) and solid-VOLUME canopy fill (real leaf-card |
| canopies are dense volumes, not the hollow shells v1.0 trained on). Fixes |
| the verified real-world failure where a stylized oak's low canopy was |
| labelled trunk. |
| - **v1.0.0** β initial synthetic-only release (#818 Track B2). |
| |