Mac os build#1
Merged
Merged
Conversation
added 3 commits
January 10, 2023 16:38
* master: Update README.md Update README.md cleaned use of Ogre Deprecated code Update README.md minor fixes Added script validation to avoid crashing Change Editor Palette Removed deprecated calls and minor improvements Update README.md Update README.md Update README.md Update README.md Update README.md Added Polygon Mode and Scroll Anim to Material Editor # Conflicts: # src/CMakeLists.txt # src/PrimitiveObject.cpp
fernandotonon
added a commit
that referenced
this pull request
Apr 28, 2026
Three issues from the PR review:
1. Codex P1: buildClosedEdgeLoop only checked graph degree, so any
closed cycle of selected edges (e.g. the perimeter of an existing
face) passed through. Filling such a cycle stacked overlapping
triangles on the live geometry. Added a per-edge boundary check
(each selected edge must touch exactly one face) before the loop
walk, refusing interior-edge cycles upfront.
2. CodeRabbit Major: HalfEdgeMesh::fillSelection's duplicate-triangle
check was gated on n == 3, leaving n > 3 fans free to recreate
existing tris on their first sub-triangle. Replaced the gate with a
per-fan-triangle check: every (apex, v_i, v_{i+1}) tri is checked
against existing faces incident to the apex. Added a regression
test (FillSelectionRejectsLargerFanThatDuplicatesExistingTri).
3. Codex P2 / CodeRabbit Major: the F shortcut accepted the event
whenever the selection looked fillable, even when fillSelection()
returned 0 (e.g. interior edge loop after fix #1, or duplicate-
triangle rejection after fix #2). Now only swallows the keypress on
a non-zero return — so F still falls back to Frame-Selection when
the fill is rejected.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fernandotonon
added a commit
that referenced
this pull request
Apr 28, 2026
* feat(edit): subdivide + fill (Phase 4 topology ops) Implements the remaining Subdivide and Fill items from issue #259. HalfEdgeMesh: - subdivideFaces: 1-to-4 split with shared midpoints between selected faces and T-junction-aware retriangulation of adjacent triangles (1/2/3 split-edge cases all handled). - fillSelection: 3-N vertex fan-triangulation for vertex fills and closed boundary edge loops; refuses cross-submesh, duplicate-tri, and orphaned-only inputs. EditModeController: - subdivideSelection wires Face mode (selected tris) and Edge mode (incident tris of selected edges) to the HE primitive, captures midpoint positions to re-select after the round-trip pack, and pushes one EditMeshTopologyCommand for undo. - fillSelection wires Vertex mode (set order = fan order) and Edge mode (closed-loop detection via degree-2 walk). UI: - Two new toolbar buttons (Subdivide ⊞, Fill ◆) with mode-aware enable/visibility. - F shortcut fills in edit mode when the selection is fillable; otherwise falls through to the existing Frame-Selection behavior. Tests: - 15 new HalfEdgeMesh standalone tests covering both ops, including T-junction handling, UV interpolation, cross-submesh rejection, and round-trip safety. - 7 new controller tests guarded by tryInitOgre (skip on macOS, run on Linux CI). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(rtss): register only one RTShaderLib path to avoid duplicate parse addRTSSResources() registered up to 4 candidate directories, deduplicated only by canonical path. On macOS dev builds the bundle's interior media/ and the dev-copy at bin/media/ are distinct paths with identical contents, so both got registered. Ogre re-parses .program scripts per resource location, and the second pass over ShadowVolumeExtude.program raised ItemIdentityException on the duplicate Ogre/ShadowBlendVP GpuProgram, aborting startup. Pick the FIRST existing RTShaderLib + sibling Main pair and stop. Both copies hold the same files, so the order doesn't matter functionally — this just avoids the double-registration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(edit): expand subdivide/fill coverage + document Phase 4 HalfEdgeMesh tests (+8): - subdivide every cube face stays closed-manifold - subdivide preserves blended bone weights at midpoints - splitMask=2 path verified on the quad neighbor - cross-submesh subdivide leaves submesh 1 untouched - non-adjacent multi-face selection on a cube - fill caps a deleted cube face back to closed - fill accepts orphaned vertices (post-delete hole-cap flow) - fill round-trip safe through toEditableMesh/buildFromEditableMesh Controller tests (+3): - subdivideSelection in edge mode promotes incident faces - fillSelection in vertex mode produces a new triangle - fillSelection pushes an undo command Docs: - CLAUDE.md keyboard shortcut line notes F's dual role and X/Ctrl+X in Edit Mode - New "Edit Mode (Phase 4 topology)" section summarising the EditModeController + HalfEdgeMesh op set, with a targeted note on Subdivide and Fill Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(edit): address Codex P1/P2 + CodeRabbit Major review Three issues from the PR review: 1. Codex P1: buildClosedEdgeLoop only checked graph degree, so any closed cycle of selected edges (e.g. the perimeter of an existing face) passed through. Filling such a cycle stacked overlapping triangles on the live geometry. Added a per-edge boundary check (each selected edge must touch exactly one face) before the loop walk, refusing interior-edge cycles upfront. 2. CodeRabbit Major: HalfEdgeMesh::fillSelection's duplicate-triangle check was gated on n == 3, leaving n > 3 fans free to recreate existing tris on their first sub-triangle. Replaced the gate with a per-fan-triangle check: every (apex, v_i, v_{i+1}) tri is checked against existing faces incident to the apex. Added a regression test (FillSelectionRejectsLargerFanThatDuplicatesExistingTri). 3. Codex P2 / CodeRabbit Major: the F shortcut accepted the event whenever the selection looked fillable, even when fillSelection() returned 0 (e.g. interior edge loop after fix #1, or duplicate- triangle rejection after fix #2). Now only swallows the keypress on a non-zero return — so F still falls back to Frame-Selection when the fill is rejected. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Apr 29, 2026
18 tasks
fernandotonon
added a commit
that referenced
this pull request
May 17, 2026
Addresses Codex P1 findings on PR #578: ## P1 #1 — diff against captured bind positions, not the live buffer `addMorphTargetFromCurrentEdit` was diffing `EditableMesh` against positions read from the entity's current GPU vertex buffer. But edit-mode ops (translate / rotate / scale) call `commitToEntity` during the gesture — both sides of the subtraction end up identical in the common flow, so `slice.offsets` stays empty and the command incorrectly returns no-op even after visible edits. Fix: snapshot the bind positions once at `EditableMesh::loadFromOgreMesh` time (`EditableSubMesh::originalPositions`). The snapshot is never mutated by edit-mode ops, so `vertices[i].position - originalPositions[i]` recovers the right delta regardless of how many commits have run since enter-edit-mode. ## P1 #2 — shared-vertex submeshes The old `readBindPositions` rejected any submesh with `useSharedVertices=true` (vertexData null in that case). Most Mixamo-style assets use shared vertices, so morph authoring silently skipped them. Fix is implicit in #1: `loadFromOgreMesh` already copies the shared vertex pool into each affected submesh's `vertices` array; the new `originalPositions` snapshot is built from that same source, so shared-vertex submeshes carry their own baseline. The GPU-buffer read path goes away entirely. ## CodeRabbit minor — null-assert SelectionSet in tests Added `ASSERT_NE(sel, nullptr)` before `sel->append(entity)` in the three new authoring tests, matching the slice-A1 pattern. If the singleton ever fails to initialize, we get a clear assertion failure instead of a null-deref crash. ## Tests - `LoadFromEntityTriangleMesh` extended to assert (a) the snapshot matches `vertices[].position` after load and (b) mutating `vertices[].position` does NOT touch `originalPositions`. Exercises the shared-vertex case (the triangle fixture uses shared verts). - New `AddMorphTargetUndoableViaUndoManager` exercises the full add → undo → redo loop through the shared `UndoManager`, with a hand-built slice that mirrors what `addMorphTargetFromCurrentEdit` will produce once edit-mode capture is wired up end-to-end. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fernandotonon
added a commit
that referenced
this pull request
May 17, 2026
…#578) * feat(morph): sub-slice A3 — authoring (add from edit, rename, delete) Last remaining sub-slice of #518. Closes the morph epic's authoring loop: users can save the current edit-mode geometry as a new morph target, rename existing targets, and delete unwanted ones. All three operations are undoable. ## What ships ### `commands/MorphCommands.{h,cpp}` — three QUndoCommand subclasses - `AddMorphTargetCommand` — create N same-named Ogre::Pose entries (one per submesh) plus a matching VAT_POSE Animation. Slices come in as sparse `{submeshHandle, {vertexIndex: Vector3f}}` maps so the command doesn't depend on EditableMesh — anything that produces deltas can drive it (current edit, MCP, future "fix mirror axis" rules…). - `DeleteMorphTargetCommand` — snapshot the same-named pose offsets at construction, drop the pose(s) + Animation + AnimationState on redo, rebuild from the snapshot on undo. - `RenameMorphTargetCommand` — same snapshot-and-rebuild pattern, just with a different name on the rebuild side. Ogre 14.5 doesn't expose Pose::setName, so destroy-and-recreate is the only path. ### `MorphAnimationManager` — three new Q_INVOKABLE methods - `addMorphTargetFromCurrentEdit(name)` — reads `EditModeController`'s live EditableMesh, diffs every submesh against the mesh's bind positions on the GPU buffer, builds the slice list, pushes an AddMorphTargetCommand. Falls back to no-op if not in edit mode, no vertices moved, or name collides. - `renameMorphTarget(old, new)` — name-trim, collision check, push. - `deleteMorphTarget(name)` — existence check, push. All three resolve the entity from SelectionSet's first entity (same pattern as the A1/A2 setters), push onto the shared `UndoManager` stack so Ctrl+Z reverses, and emit `morphTargetsChanged` so the Inspector re-fetches. ## Tests 8 new GTest cases on `MorphAnimationManager_test.cpp`: - Add command creates + undoes pose and Animation cleanly. - Delete command round-trips (poses restored on undo). - Rename command round-trips (old name restored on undo). - Rename rejects target-name collisions, no-op self-renames, blank names. - Delete rejects unknown / empty names; succeeds on a real target. - Add-from-edit rejects empty / whitespace names before edit-mode check. - Add-from-edit returns false when no EditableMesh is available (i.e. user isn't in edit mode). - All three methods reject when nothing is selected. The command path is what's actually under test — the manager wrappers are thin selection + name-validation glue. We keep direct command tests because that's where the undo / redo contract lives and it exercises the pose snapshot / rebuild path without needing an Inspector. ## What's deferred - **Inspector UI** (Add / Rename / Delete buttons in the Morph Targets subgroup) — small but lives in QML, and the last QML change in this epic (A5's dope-sheet integration) deterministically crashed unrelated tests for reasons I never fully isolated. Doing the UI in a separate PR keeps blast radius contained. - **MCP tools** `add_morph_target` / `rename_morph_target` / `delete_morph_target` — straightforward but adds surface; can land alongside the Inspector UI. - **CLI** `qtmesh morph --rename / --delete` — needs export-after-edit plumbing through the FBX/glTF morph exporters from A4a/A4b. #518 status after this slice: | Sub-slice | Status | |-|-| | A1 — Importer + manager + CLI list | shipped (#569) | | A2 — Inspector subgroup | shipped (#570) | | A3 — Authoring | **this PR** | | A4a — glTF export | shipped (#573) | | A4b — FBX export | shipped (#575) | | A5 — Controller API | shipped (#576) | | A5b — Dope-sheet UI | follow-up | | A6 — MCP tools | shipped (#571) | | A3b — Inspector / MCP / CLI authoring surface | follow-up | Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(build): add MorphCommands.cpp to tests/ source list Linker errors on the secondary test binaries (MaterialEditorQML_test, MaterialEditorQML_qml_test, MaterialEditorQML_perf_test) because they compile MorphAnimationManager.cpp (which now references the three MorphCommand constructors) but didn't pick up MorphCommands.cpp. src/CMakeLists.txt has it; tests/CMakeLists.txt was missing the line. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * review(morph): A3 — capture bind positions on EditableMesh load Addresses Codex P1 findings on PR #578: ## P1 #1 — diff against captured bind positions, not the live buffer `addMorphTargetFromCurrentEdit` was diffing `EditableMesh` against positions read from the entity's current GPU vertex buffer. But edit-mode ops (translate / rotate / scale) call `commitToEntity` during the gesture — both sides of the subtraction end up identical in the common flow, so `slice.offsets` stays empty and the command incorrectly returns no-op even after visible edits. Fix: snapshot the bind positions once at `EditableMesh::loadFromOgreMesh` time (`EditableSubMesh::originalPositions`). The snapshot is never mutated by edit-mode ops, so `vertices[i].position - originalPositions[i]` recovers the right delta regardless of how many commits have run since enter-edit-mode. ## P1 #2 — shared-vertex submeshes The old `readBindPositions` rejected any submesh with `useSharedVertices=true` (vertexData null in that case). Most Mixamo-style assets use shared vertices, so morph authoring silently skipped them. Fix is implicit in #1: `loadFromOgreMesh` already copies the shared vertex pool into each affected submesh's `vertices` array; the new `originalPositions` snapshot is built from that same source, so shared-vertex submeshes carry their own baseline. The GPU-buffer read path goes away entirely. ## CodeRabbit minor — null-assert SelectionSet in tests Added `ASSERT_NE(sel, nullptr)` before `sel->append(entity)` in the three new authoring tests, matching the slice-A1 pattern. If the singleton ever fails to initialize, we get a clear assertion failure instead of a null-deref crash. ## Tests - `LoadFromEntityTriangleMesh` extended to assert (a) the snapshot matches `vertices[].position` after load and (b) mutating `vertices[].position` does NOT touch `originalPositions`. Exercises the shared-vertex case (the triangle fixture uses shared verts). - New `AddMorphTargetUndoableViaUndoManager` exercises the full add → undo → redo loop through the shared `UndoManager`, with a hand-built slice that mirrors what `addMorphTargetFromCurrentEdit` will produce once edit-mode capture is wired up end-to-end. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
No description provided.