From 781d464f4779057621fd0f4b3959530ebfc40eaf Mon Sep 17 00:00:00 2001 From: indigo Date: Tue, 30 Jun 2026 08:15:20 +0800 Subject: [PATCH] Add per-viewport cull style option Exposes UsdImagingGLCullStyle as a Cull Style sub-menu in the gear popup (Back Unless Double-Sided / Back / Front / Nothing / No Opinion). Defaults to BackUnlessDoubleSided, matching usdview. Setting persists per-viewport to viewport_settings.ini. Co-Authored-By: Claude Sonnet 4.6 --- src/core/UsdSceneRenderer.cpp | 3 ++- src/core/UsdSceneRenderer.h | 13 +++++++++++++ src/ui/ViewportPanel.cpp | 2 ++ src/ui/ViewportTile.cpp | 17 +++++++++++++++++ src/ui/ViewportTile.h | 1 + 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/core/UsdSceneRenderer.cpp b/src/core/UsdSceneRenderer.cpp index a01b953..91c7bc0 100644 --- a/src/core/UsdSceneRenderer.cpp +++ b/src/core/UsdSceneRenderer.cpp @@ -174,6 +174,7 @@ UsdSceneRenderer::UsdSceneRenderer() , m_aaEnabled(false) , m_backgroundColor(0.15f, 0.15f, 0.15f) , m_shadingMode(ShadingMode::SmoothShaded) + , m_cullStyle(CullStyle::BackUnlessDoubleSided) , m_colorCorrectionMode(ColorCorrectionMode::sRGB) , m_ambientLightOnly(true) , m_domeLightEnabled(false) @@ -728,7 +729,7 @@ void UsdSceneRenderer::Render(int width, int height) m_renderParams.showRender = m_showRender; m_renderParams.enableSampleAlphaToCoverage = true; m_renderParams.gammaCorrectColors = false; - m_renderParams.cullStyle = pxr::UsdImagingGLCullStyle::CULL_STYLE_BACK_UNLESS_DOUBLE_SIDED; + m_renderParams.cullStyle = static_cast(m_cullStyle); m_renderParams.enableSceneMaterials = true; m_renderParams.enableSceneLights = true; m_renderParams.highlight = true; diff --git a/src/core/UsdSceneRenderer.h b/src/core/UsdSceneRenderer.h index 4473969..e51c1db 100644 --- a/src/core/UsdSceneRenderer.h +++ b/src/core/UsdSceneRenderer.h @@ -43,6 +43,15 @@ enum class ShadingMode { Unlit, ///< Smooth geometry, lighting disabled }; +/// Back-face culling style — maps directly to UsdImagingGLCullStyle. +enum class CullStyle { + NoOpinion = 0, + Nothing = 1, + Back = 2, + Front = 3, + BackUnlessDoubleSided = 4, +}; + /// Viewport color correction mode — maps to UsdImagingGLRenderParams::colorCorrectionMode. enum class ColorCorrectionMode { Disabled, ///< No correction (raw linear output) @@ -240,6 +249,9 @@ public: ShadingMode GetShadingMode() const { return m_shadingMode; } void SetShadingMode(ShadingMode m) { m_shadingMode = m; m_forceRefresh = true; } + CullStyle GetCullStyle() const { return m_cullStyle; } + void SetCullStyle(CullStyle c) { m_cullStyle = c; m_forceRefresh = true; } + ColorCorrectionMode GetColorCorrectionMode() const { return m_colorCorrectionMode; } void SetColorCorrectionMode(ColorCorrectionMode m) { m_colorCorrectionMode = m; m_forceRefresh = true; } @@ -358,6 +370,7 @@ private: // Lighting settings (mirrors stageView.py viewSettings) ShadingMode m_shadingMode; // draw mode + lighting flags + CullStyle m_cullStyle; // back/front/none face culling ColorCorrectionMode m_colorCorrectionMode; // viewport color correction std::string m_ocioDisplay; std::string m_ocioView; diff --git a/src/ui/ViewportPanel.cpp b/src/ui/ViewportPanel.cpp index 4b0e035..b16cc33 100644 --- a/src/ui/ViewportPanel.cpp +++ b/src/ui/ViewportPanel.cpp @@ -670,6 +670,7 @@ void ViewportPanel::SaveSettings(const std::string& path) const f << "AmbientLightOnly=" << (s.ambientLightOnly ? 1 : 0) << "\n"; f << "DomeLightEnabled=" << (s.domeLightEnabled ? 1 : 0) << "\n"; f << "ShadingMode=" << s.shadingMode << "\n"; + f << "CullStyle=" << s.cullStyle << "\n"; } } @@ -741,6 +742,7 @@ void ViewportPanel::LoadSettings(const std::string& path) else if (key == "AmbientLightOnly") ts.ambientLightOnly = (val == "1"); else if (key == "DomeLightEnabled") ts.domeLightEnabled = (val == "1"); else if (key == "ShadingMode") ts.shadingMode = toInt(val, ts.shadingMode); + else if (key == "CullStyle") ts.cullStyle = toInt(val, ts.cullStyle); } } diff --git a/src/ui/ViewportTile.cpp b/src/ui/ViewportTile.cpp index bf0b7a9..3d7a70d 100644 --- a/src/ui/ViewportTile.cpp +++ b/src/ui/ViewportTile.cpp @@ -106,6 +106,7 @@ ViewportTileSettings ViewportTile::GetSettings() const s.ambientLightOnly = m_renderer.GetAmbientLightOnly(); s.domeLightEnabled = m_renderer.GetDomeLightEnabled(); s.shadingMode = static_cast(m_renderer.GetShadingMode()); + s.cullStyle = static_cast(m_renderer.GetCullStyle()); return s; } @@ -126,6 +127,7 @@ void ViewportTile::ApplySettings(const ViewportTileSettings& s) m_renderer.SetAmbientLightOnly(s.ambientLightOnly); m_renderer.SetDomeLightEnabled(s.domeLightEnabled); m_renderer.SetShadingMode(static_cast(s.shadingMode)); + m_renderer.SetCullStyle(static_cast(s.cullStyle)); } // --------------------------------------------------------------------------- @@ -1018,6 +1020,21 @@ void ViewportTile::RenderCompactToolbar(int tileIndex) ImGui::EndMenu(); } + // -- Cull Style -------------------------------------------------- + if (ImGui::BeginMenu("Cull Style")) { + CullStyle curCull = m_renderer.GetCullStyle(); + auto cullItem = [&](const char* label, CullStyle style) { + if (ImGui::MenuItem(label, nullptr, curCull == style)) + m_renderer.SetCullStyle(style); + }; + cullItem("Back Unless Double-Sided", CullStyle::BackUnlessDoubleSided); + cullItem("Back", CullStyle::Back); + cullItem("Front", CullStyle::Front); + cullItem("Nothing", CullStyle::Nothing); + cullItem("No Opinion", CullStyle::NoOpinion); + ImGui::EndMenu(); + } + // -- AOV --------------------------------------------------------- { pxr::TfTokenVector aovs = m_renderer.GetRendererAovs(); diff --git a/src/ui/ViewportTile.h b/src/ui/ViewportTile.h index 917f31a..a7ccc03 100644 --- a/src/ui/ViewportTile.h +++ b/src/ui/ViewportTile.h @@ -32,6 +32,7 @@ struct ViewportTileSettings { bool ambientLightOnly = true; bool domeLightEnabled = false; int shadingMode = 0; + int cullStyle = 4; // CullStyle::BackUnlessDoubleSided bool showGuides = false; bool showProxy = true; bool showRender = false;