UV Editor: read-only panel (issue #459)#759
Conversation
Introduces UVEditorController + UVEditorPanel.qml with island-colored UV layout, texture preview, pan/zoom/fit, and bottom-dock tab integration alongside Context/Console/Curve Editor. Includes headless island-detection unit tests. Co-authored-by: Cursor <cursoragent@cursor.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughAdds a dockable UV editor panel with a new QML controller, UV layout rendering, pan/zoom controls, texture background support, and MainWindow integration for docking, visibility persistence, and menu access. ChangesUV Editor Panel and Controller
Sequence Diagram(s)sequenceDiagram
participant User
participant MainWindow
participant UVEditorController
participant UVEditorPanel
participant EditableMesh
User->>MainWindow: Open UV Editor dock
MainWindow->>UVEditorController: refresh()
UVEditorController->>EditableMesh: read UV data and build islands
UVEditorController-->>UVEditorPanel: meshDataChanged
UVEditorPanel->>UVEditorPanel: rebuild cache and repaint canvas
User->>UVEditorPanel: pan / zoom / fit
UVEditorPanel->>UVEditorPanel: update transforms and requestPaint
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1a677fbd66
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (1)
src/UVEditorController.cpp (1)
258-299: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd breadcrumbs around preview texture resolution and cache writes.
This code does both import-style lookup and export-style cache generation, but none of it is breadcrumbed. That leaves the new UV preview path pretty opaque when users report missing backgrounds.
As per coding guidelines,
All user-facing actions and significant operations must be tracked with SentryReporter::addBreadcrumb(category, message) using category 'file.import'/'file.export' for I/O operations.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/UVEditorController.cpp` around lines 258 - 299, Add Sentry breadcrumbs in resolveDiffuseTextureSource around each significant texture I/O step so the UV preview path is traceable. Use SentryReporter::addBreadcrumb with category file.import for lookup/resolution attempts and file.export for generating or writing the cached embedded preview. Cover the key branches in UVEditorController::resolveDiffuseTextureSource: loaded texture origin lookup, EmbeddedTextureCache retrieval, preview file creation/saving, and fallback filesystem candidate checks, keeping the messages specific to the texture name and action.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@qml/UVEditorPanel.qml`:
- Around line 71-75: The `onMeshDataChanged()` handler in `UVEditorPanel.qml` is
auto-calling `fitToView()` for every `meshDataChanged()` signal, which also
fires from `UVEditorController::setShowTextureBackground()` and resets the
user’s view. Update the `onMeshDataChanged()` logic so it only fits to view when
the actual mesh/geometry changes, not when texture background visibility
changes; use the existing `UVEditorController`/`meshDataChanged` flow to
distinguish those cases and keep `rebuildTriangleCache()` behavior intact.
- Around line 215-218: The UV texture preview placement in UVEditorPanel.qml is
using parent-space coordinates while the UV mapping itself is based on
viewCanvas dimensions, so the image ends up offset from the wireframe. Update
the Image positioning/sizing logic (the block using root.uvToScreen and the
viewCanvas inset) to align against the canvas content rect instead of the outer
parent, and ensure the 1 px canvas inset is accounted for consistently in both
the preview Image and the canvas-based transform.
In `@src/UVEditorController_test.cpp`:
- Around line 67-70: Move the Ogre mesh-file prerequisite check out of
individual tests and into the fixture setup in UVEditorController_test,
alongside tryInitOgre(). In SetUp(), assert both ASSERT_TRUE(tryInitOgre()) and
ASSERT_TRUE(canLoadMeshFiles()) before any Ogre-dependent setup like
createStandardOgreMaterials(). Remove any GTEST_SKIP() usage for these
prerequisites in the affected tests so failures surface immediately in the
shared fixture setup.
In `@src/UVEditorController.cpp`:
- Around line 403-404: The preview submesh selection in
UVEditorController::resolveDiffuseTextureSource is nondeterministic because
QSet::constBegin() depends on hash iteration order. Change the logic that
computes previewSub to pick a stable submesh index from submeshFilter, such as
the smallest selected index, before passing it to resolveDiffuseTextureSource.
Keep the fix localized to the preview background selection path so multi-submesh
selections always resolve the same texture source.
- Around line 290-293: The texture fallback path search in UVEditorController
currently uses applicationDirPath() on macOS, which resolves under
Contents/MacOS instead of the .app bundle root. Update the candidate list in the
UV preview texture lookup to use macBundlePath() for the macOS-specific fallback
so bundled Ogre textures are resolved relative to the app bundle root, while
keeping the existing non-macOS fallbacks intact.
- Around line 200-211: The computeIslandsFromEditableMesh helper ignores its
uvChannel argument, so callers cannot select which UV set is used. Update
UVEditorController::computeIslandsFromEditableMesh to either remove uvChannel
from the API if it is not needed, or thread it through the mesh-to-half-edge
conversion so computeIslandsFromHalfEdgeMesh operates on the requested channel
instead of always using the default UV data.
- Around line 274-285: Sanitize the texture name before building the preview
cache path in UVEditorController::retrieve preview generation, because texName
is currently appended directly into outPath. Update the logic around the
QDir/QFileInfo and QImage save path construction to strip path separators,
dot-dot segments, and any absolute-path components so the cached PNG stays
inside uv_editor_previews. Use a safe filename derived from texName for the file
written by the preview cache code path.
---
Nitpick comments:
In `@src/UVEditorController.cpp`:
- Around line 258-299: Add Sentry breadcrumbs in resolveDiffuseTextureSource
around each significant texture I/O step so the UV preview path is traceable.
Use SentryReporter::addBreadcrumb with category file.import for
lookup/resolution attempts and file.export for generating or writing the cached
embedded preview. Cover the key branches in
UVEditorController::resolveDiffuseTextureSource: loaded texture origin lookup,
EmbeddedTextureCache retrieval, preview file creation/saving, and fallback
filesystem candidate checks, keeping the messages specific to the texture name
and action.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 49e2e129-a100-4a02-8fd8-51e760b24c8d
📒 Files selected for processing (8)
qml/UVEditorPanel.qmlsrc/CMakeLists.txtsrc/UVEditorController.cppsrc/UVEditorController.hsrc/UVEditorController_test.cppsrc/mainwindow.cppsrc/mainwindow.hsrc/qml_resources.qrc
Link UVEditorController into UnitTests, stabilize preview submesh selection, sanitize texture cache paths, and harden macOS bundle texture resolution. Co-authored-by: Cursor <cursoragent@cursor.com>
Walk face half-edges directly, fan-triangulate canonical n-gon faces, clear stale UVs when a channel is missing, and only auto-fit when mesh revision changes. Co-authored-by: Cursor <cursoragent@cursor.com>
Review feedback addressedFollow-up commits on this branch (
CI is green after re-running |
Cover canonical quad-face island grouping and UV1 channel fallback when the second UV set is absent. Co-authored-by: Cursor <cursoragent@cursor.com>
|



Summary
UVEditorController+UVEditorPanel.qml— read-only UV layout viewer with island-colored triangles, optional diffuse texture background, UV0/UV1 channel picker, and pan/zoom/fit controls (Canvas2D, no GL).QSettings.UVEditorController_test.cppcovering island detection (single tri, multi-submesh, UV seam split) and selection-driven refresh.Closes #459.
Test plan
./build_local/bin/UnitTests --gtest_filter="UVEditorControllerTest.*"(4/4 pass)Made with Cursor
Summary by CodeRabbit