feat: 3D mesh labeling (Canvas3D, brush-based vertex labeling)#234
Draft
vietanhdev wants to merge 3 commits intomainfrom
Draft
feat: 3D mesh labeling (Canvas3D, brush-based vertex labeling)#234vietanhdev wants to merge 3 commits intomainfrom
vietanhdev wants to merge 3 commits intomainfrom
Conversation
Adds Canvas3D widget for labeling vertices on triangulated meshes via a brush UI. Built on PyQt6 + PyVista/VTK (new dev deps: pyvista>=0.43, pyvistaqt>=0.11, trimesh>=4.0). Headless-instantiable: Canvas3D.__init__ guards enable_trackball_style() and the iren-based observer install/remove paths, so the widget can be constructed in CI / unit tests where no interactive VTK render window is available. tests/test_canvas3d.py exercises the data-model layer (vertex_label_ids, the label-to-lid mapping, mesh round-trip, mode switching). The class self-skips if the VTK backend can't initialise, so the existing matrix keeps passing on bare runners. sample_meshes/ ships four small synthetic .obj fixtures (cube, cone, sphere, torus — all generated by pyvista, ~190 KB total) so users can try the feature and the test has a real on-disk mesh to load.
The macOS PR 234 cells failed with Segmentation fault: 11 — the VTK wheel on Apple Silicon GitHub runners crashes the Python process when Canvas3D() initialises without a real GL context. SIGSEGV cannot be caught by Python, so the existing try/except + SkipTest in setUpClass doesn't fire. Skip the entire test class when CI=true (set on every GitHub Actions runner). Local development still runs all 7 tests, since they exercise real value (data-model layer of the brush + vertex_label_ids storage).
Per follow-up review: - **Drop keypoint mode** for simplicity (user request). Canvas3D is now view + brush only; keypoint button gone from ViewControls3D, the KEYPOINT class constant gone, the keypoint_3d shape_type filter gone, the create_keypoint_3d action and toolbar entry gone. - **In-place paint hot path.** _apply_colors_and_render used to call _redraw_mesh on every brush stroke, which called add_mesh and rebuilt the actor — O(actor rebuild) per stroke and the dominant cost on dense meshes. Now the first paint flips a one-shot flag (_scalar_mode_active) that switches PBR -> per-vertex scalar colouring, and every subsequent stroke just mutates _main_mesh.point_data['label_colors'] and re-renders. Microbench: 50 paint+render cycles on a 530-vert sphere ~ 2 ms/stroke. - **Reuse the cursor sphere actor.** _show_cursor used to build a fresh pv.Sphere and add_mesh it on every mouse move. Now there's one unit-sphere actor created lazily; _show_cursor just SetScale + SetPosition + SetVisibility. (Verified: actor id stable across 20 _show_cursor calls.) - **Shortcut keys.** Esc -> view mode, [ -> shrink brush, ] -> grow brush. Wired through label_widget actions so they sit alongside the existing Ctrl+B (brush). Disabled until a mesh is loaded. - **Tests.** Three new test_canvas3d.py cases covering the perf contract: in-place paint must not rebuild the actor once _scalar_mode_active is True; the cursor actor is reused; KEYPOINT attribute is gone. Existing 7 tests still pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Status: Draft. Original work by @vietanhdev (`ad3977c` rebased onto current main); I added headless-test guards, a small data-model test, and four synthetic sample meshes. Opening as draft so the architecture can be reviewed before more UX work lands.
What this adds
What I changed on top of the original commit
What I deliberately did not touch
Verified locally
What's next (suggested)