Add gear icon toolbar button with viewport options dropdown
Adds a ⚙ icon button to the right of the AA toggle in each viewport
tile's compact toolbar. Clicking it opens a dropdown with:
- Shading submenu: Smooth Shaded / Flat Shaded / Wireframe on Surface /
Wireframe / Unlit (new ShadingMode enum driving UsdImagingGLDrawMode)
- Lighting submenu: Camera Headlight / Scene Lights + Dome Light toggle
- Show Grid and Anti-Aliasing toggles (mirrored from icon buttons)
- Bounding Box submenu: None / Per Object / All Selection
- Background submenu: Dark Gray / Black / Light Gray / Midnight Blue
ShadingMode is persisted in viewport_settings.ini alongside the existing
per-tile settings (saved on shutdown, restored on startup).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||||
|
<path fill="white" d="M495.9 166.6c3.2 8.7.5 18.4-6.4 24.6l-43.3 39.4c1.1 8.3 1.7 16.8 1.7 25.4s-.6 17.1-1.7 25.4l43.3 39.4c6.9 6.2 9.6 15.9 6.4 24.6-4.4 11.9-9.7 23.3-15.8 34.3l-4.7 8.1c-6.6 11-14 21.4-22.1 31.2-5.9 7.2-15.7 9.6-24.5 6.8l-55.7-17.7c-13.4 10.3-28.2 18.9-44 25.4l-12.5 57.1c-2 9.1-9 16.3-18.2 17.8C283.7 510.8 269.5 512 255 512s-28.7-1.2-42.5-3.5c-9.2-1.5-16.2-8.7-18.2-17.8l-12.5-57.1c-15.8-6.5-30.6-15.1-44-25.4l-55.7 17.7c-8.8 2.8-18.6.3-24.5-6.8-8.1-9.8-15.5-20.2-22.1-31.2l-4.7-8.1C25.1 368.8 19.8 357.4 15.4 345.5c-3.2-8.7-.5-18.4 6.4-24.6l43.3-39.4C64.0 273.1 63.4 264.6 63.4 256s.6-17.1 1.7-25.4L21.8 191.2c-6.9-6.2-9.6-15.9-6.4-24.6 4.4-11.9 9.7-23.3 15.8-34.3l4.7-8.1c6.6-11 14-21.4 22.1-31.2 5.9-7.2 15.7-9.6 24.5-6.8l55.7 17.7c13.4-10.3 28.2-18.9 44-25.4l12.5-57.1C196.5 12.3 203.5 5.1 212.7 3.6 226.5 1.2 240.7 0 255.2 0s28.7 1.2 42.5 3.5c9.2 1.5 16.2 8.7 18.2 17.8l12.5 57.1c15.8 6.5 30.6 15.1 44 25.4l55.7-17.7c8.8-2.8 18.6-.3 24.5 6.8 8.1 9.8 15.5 20.2 22.1 31.2l4.7 8.1c6.1 11 11.4 22.4 15.8 34.3zM255.2 336a80 80 0 1 0 0-160 80 80 0 1 0 0 160z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -131,6 +131,7 @@ UsdSceneRenderer::UsdSceneRenderer()
|
|||||||
: m_showGrid(true)
|
: m_showGrid(true)
|
||||||
, m_aaEnabled(false)
|
, m_aaEnabled(false)
|
||||||
, m_backgroundColor(0.15f, 0.15f, 0.15f)
|
, m_backgroundColor(0.15f, 0.15f, 0.15f)
|
||||||
|
, m_shadingMode(ShadingMode::SmoothShaded)
|
||||||
, m_ambientLightOnly(true)
|
, m_ambientLightOnly(true)
|
||||||
, m_domeLightEnabled(false)
|
, m_domeLightEnabled(false)
|
||||||
, m_stageIsZup(false)
|
, m_stageIsZup(false)
|
||||||
@@ -616,11 +617,27 @@ void UsdSceneRenderer::Render(int width, int height)
|
|||||||
m_renderParams = pxr::UsdImagingGLRenderParams();
|
m_renderParams = pxr::UsdImagingGLRenderParams();
|
||||||
m_renderParams.frame = m_currentTime;
|
m_renderParams.frame = m_currentTime;
|
||||||
m_renderParams.complexity = 1.0f;
|
m_renderParams.complexity = 1.0f;
|
||||||
m_renderParams.drawMode = pxr::UsdImagingGLDrawMode::DRAW_SHADED_SMOOTH;
|
// Apply shading mode → drawMode + enableLighting
|
||||||
|
switch (m_shadingMode) {
|
||||||
|
case ShadingMode::FlatShaded:
|
||||||
|
m_renderParams.drawMode = pxr::UsdImagingGLDrawMode::DRAW_SHADED_FLAT;
|
||||||
|
m_renderParams.enableLighting = true; break;
|
||||||
|
case ShadingMode::WireframeOnSurface:
|
||||||
|
m_renderParams.drawMode = pxr::UsdImagingGLDrawMode::DRAW_WIREFRAME_ON_SURFACE;
|
||||||
|
m_renderParams.enableLighting = true; break;
|
||||||
|
case ShadingMode::Wireframe:
|
||||||
|
m_renderParams.drawMode = pxr::UsdImagingGLDrawMode::DRAW_WIREFRAME;
|
||||||
|
m_renderParams.enableLighting = false; break;
|
||||||
|
case ShadingMode::Unlit:
|
||||||
|
m_renderParams.drawMode = pxr::UsdImagingGLDrawMode::DRAW_SHADED_SMOOTH;
|
||||||
|
m_renderParams.enableLighting = false; break;
|
||||||
|
default: // SmoothShaded
|
||||||
|
m_renderParams.drawMode = pxr::UsdImagingGLDrawMode::DRAW_SHADED_SMOOTH;
|
||||||
|
m_renderParams.enableLighting = true; break;
|
||||||
|
}
|
||||||
m_renderParams.showGuides = true;
|
m_renderParams.showGuides = true;
|
||||||
m_renderParams.showProxy = true;
|
m_renderParams.showProxy = true;
|
||||||
m_renderParams.showRender = false;
|
m_renderParams.showRender = false;
|
||||||
m_renderParams.enableLighting = true;
|
|
||||||
m_renderParams.enableSampleAlphaToCoverage = true;
|
m_renderParams.enableSampleAlphaToCoverage = true;
|
||||||
m_renderParams.gammaCorrectColors = false;
|
m_renderParams.gammaCorrectColors = false;
|
||||||
m_renderParams.cullStyle = pxr::UsdImagingGLCullStyle::CULL_STYLE_BACK_UNLESS_DOUBLE_SIDED;
|
m_renderParams.cullStyle = pxr::UsdImagingGLCullStyle::CULL_STYLE_BACK_UNLESS_DOUBLE_SIDED;
|
||||||
|
|||||||
@@ -31,6 +31,15 @@ enum class BBoxMode {
|
|||||||
AllSelection ///< One combined box for the entire selection
|
AllSelection ///< One combined box for the entire selection
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Surface shading mode — maps to UsdImagingGLDrawMode + enableLighting.
|
||||||
|
enum class ShadingMode {
|
||||||
|
SmoothShaded, ///< Smooth shading with materials (default)
|
||||||
|
FlatShaded, ///< Flat shading with materials
|
||||||
|
WireframeOnSurface, ///< Wireframe overlay on solid surface
|
||||||
|
Wireframe, ///< Wireframe only, no fill
|
||||||
|
Unlit, ///< Smooth geometry, lighting disabled
|
||||||
|
};
|
||||||
|
|
||||||
class UsdSceneRenderer {
|
class UsdSceneRenderer {
|
||||||
public:
|
public:
|
||||||
UsdSceneRenderer();
|
UsdSceneRenderer();
|
||||||
@@ -199,6 +208,9 @@ public:
|
|||||||
bool GetDomeLightEnabled() const { return m_domeLightEnabled; }
|
bool GetDomeLightEnabled() const { return m_domeLightEnabled; }
|
||||||
void SetDomeLightEnabled(bool val) { m_domeLightEnabled = val; }
|
void SetDomeLightEnabled(bool val) { m_domeLightEnabled = val; }
|
||||||
|
|
||||||
|
ShadingMode GetShadingMode() const { return m_shadingMode; }
|
||||||
|
void SetShadingMode(ShadingMode m) { m_shadingMode = m; m_forceRefresh = true; }
|
||||||
|
|
||||||
/// Default material ambient (kA, default 0.2 — matches viewSettingsDataModel.py).
|
/// Default material ambient (kA, default 0.2 — matches viewSettingsDataModel.py).
|
||||||
float GetDefaultMaterialAmbient() const { return m_defaultMaterialAmbient; }
|
float GetDefaultMaterialAmbient() const { return m_defaultMaterialAmbient; }
|
||||||
void SetDefaultMaterialAmbient(float v) { m_defaultMaterialAmbient = v; }
|
void SetDefaultMaterialAmbient(float v) { m_defaultMaterialAmbient = v; }
|
||||||
@@ -298,6 +310,7 @@ private:
|
|||||||
pxr::GfVec3f m_backgroundColor;
|
pxr::GfVec3f m_backgroundColor;
|
||||||
|
|
||||||
// Lighting settings (mirrors stageView.py viewSettings)
|
// Lighting settings (mirrors stageView.py viewSettings)
|
||||||
|
ShadingMode m_shadingMode; // draw mode + lighting flags
|
||||||
bool m_ambientLightOnly; // camera headlight
|
bool m_ambientLightOnly; // camera headlight
|
||||||
bool m_domeLightEnabled; // dome/IBL light
|
bool m_domeLightEnabled; // dome/IBL light
|
||||||
bool m_stageIsZup; // used for dome light rotation
|
bool m_stageIsZup; // used for dome light rotation
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ static const char* IconFilename(Icon icon) {
|
|||||||
case Icon::Refresh: return "arrows-rotate.svg";
|
case Icon::Refresh: return "arrows-rotate.svg";
|
||||||
case Icon::FilePlus: return "file-plus.svg";
|
case Icon::FilePlus: return "file-plus.svg";
|
||||||
case Icon::Pen: return "pen.svg";
|
case Icon::Pen: return "pen.svg";
|
||||||
|
case Icon::Settings: return "gear.svg";
|
||||||
default: return nullptr;
|
default: return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,7 +76,7 @@ static constexpr Icon kAllIcons[] = {
|
|||||||
Icon::LayoutSingle, Icon::LayoutHSplit, Icon::LayoutVSplit, Icon::LayoutQuad,
|
Icon::LayoutSingle, Icon::LayoutHSplit, Icon::LayoutVSplit, Icon::LayoutQuad,
|
||||||
Icon::SkipBack, Icon::StepBack, Icon::PlayBack, Icon::Play, Icon::Pause,
|
Icon::SkipBack, Icon::StepBack, Icon::PlayBack, Icon::Play, Icon::Pause,
|
||||||
Icon::StepForward, Icon::SkipEnd, Icon::Loop, Icon::Bounce,
|
Icon::StepForward, Icon::SkipEnd, Icon::Loop, Icon::Bounce,
|
||||||
Icon::Refresh, Icon::FilePlus, Icon::Pen,
|
Icon::Refresh, Icon::FilePlus, Icon::Pen, Icon::Settings,
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ enum class Icon {
|
|||||||
Refresh, // reload / refresh
|
Refresh, // reload / refresh
|
||||||
FilePlus, // create new file
|
FilePlus, // create new file
|
||||||
Pen, // edit / edit target
|
Pen, // edit / edit target
|
||||||
|
Settings, // gear / viewport options
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Loads SVG files from disk, rasterizes them with NanoSVG, uploads them as
|
/// Loads SVG files from disk, rasterizes them with NanoSVG, uploads them as
|
||||||
|
|||||||
@@ -635,6 +635,7 @@ void ViewportPanel::SaveSettings(const std::string& path) const
|
|||||||
f << "BBoxMode=" << s.bboxMode << "\n";
|
f << "BBoxMode=" << s.bboxMode << "\n";
|
||||||
f << "AmbientLightOnly=" << (s.ambientLightOnly ? 1 : 0) << "\n";
|
f << "AmbientLightOnly=" << (s.ambientLightOnly ? 1 : 0) << "\n";
|
||||||
f << "DomeLightEnabled=" << (s.domeLightEnabled ? 1 : 0) << "\n";
|
f << "DomeLightEnabled=" << (s.domeLightEnabled ? 1 : 0) << "\n";
|
||||||
|
f << "ShadingMode=" << s.shadingMode << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -700,6 +701,7 @@ void ViewportPanel::LoadSettings(const std::string& path)
|
|||||||
else if (key == "BBoxMode") ts.bboxMode = toInt(val, ts.bboxMode);
|
else if (key == "BBoxMode") ts.bboxMode = toInt(val, ts.bboxMode);
|
||||||
else if (key == "AmbientLightOnly") ts.ambientLightOnly = (val == "1");
|
else if (key == "AmbientLightOnly") ts.ambientLightOnly = (val == "1");
|
||||||
else if (key == "DomeLightEnabled") ts.domeLightEnabled = (val == "1");
|
else if (key == "DomeLightEnabled") ts.domeLightEnabled = (val == "1");
|
||||||
|
else if (key == "ShadingMode") ts.shadingMode = toInt(val, ts.shadingMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ ViewportTileSettings ViewportTile::GetSettings() const
|
|||||||
s.bboxMode = static_cast<int>(m_renderer.GetBBoxMode());
|
s.bboxMode = static_cast<int>(m_renderer.GetBBoxMode());
|
||||||
s.ambientLightOnly = m_renderer.GetAmbientLightOnly();
|
s.ambientLightOnly = m_renderer.GetAmbientLightOnly();
|
||||||
s.domeLightEnabled = m_renderer.GetDomeLightEnabled();
|
s.domeLightEnabled = m_renderer.GetDomeLightEnabled();
|
||||||
|
s.shadingMode = static_cast<int>(m_renderer.GetShadingMode());
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,6 +113,7 @@ void ViewportTile::ApplySettings(const ViewportTileSettings& s)
|
|||||||
m_renderer.SetBBoxMode(static_cast<BBoxMode>(s.bboxMode));
|
m_renderer.SetBBoxMode(static_cast<BBoxMode>(s.bboxMode));
|
||||||
m_renderer.SetAmbientLightOnly(s.ambientLightOnly);
|
m_renderer.SetAmbientLightOnly(s.ambientLightOnly);
|
||||||
m_renderer.SetDomeLightEnabled(s.domeLightEnabled);
|
m_renderer.SetDomeLightEnabled(s.domeLightEnabled);
|
||||||
|
m_renderer.SetShadingMode(static_cast<ShadingMode>(s.shadingMode));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -963,6 +965,100 @@ void ViewportTile::RenderCompactToolbar(int tileIndex)
|
|||||||
if (iconToggle(aaId.c_str(), "AA", Icon::Antialias, aa, "Toggle anti-aliasing"))
|
if (iconToggle(aaId.c_str(), "AA", Icon::Antialias, aa, "Toggle anti-aliasing"))
|
||||||
m_renderer.SetAAEnabled(!aa);
|
m_renderer.SetAAEnabled(!aa);
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextDisabled("|");
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
// -- Gear / viewport options popup ---------------------------------------
|
||||||
|
{
|
||||||
|
std::string gearId = "##gear_" + std::to_string(tileIndex);
|
||||||
|
std::string gearPopupId = "GearPopup_" + std::to_string(tileIndex);
|
||||||
|
|
||||||
|
if (m_iconManager) {
|
||||||
|
ImTextureID tex = m_iconManager->Get(Icon::Settings);
|
||||||
|
ImGui::ImageButton(gearId.c_str(), ImTextureRef(tex), ImVec2(16.f, 16.f));
|
||||||
|
} else {
|
||||||
|
ImGui::Button("*");
|
||||||
|
}
|
||||||
|
if (ImGui::IsItemHovered()) ImGui::SetTooltip("Viewport options");
|
||||||
|
|
||||||
|
if (ImGui::BeginPopupContextItem(gearPopupId.c_str(),
|
||||||
|
ImGuiPopupFlags_MouseButtonLeft))
|
||||||
|
{
|
||||||
|
// -- Shading mode ------------------------------------------------
|
||||||
|
if (ImGui::BeginMenu("Shading")) {
|
||||||
|
ShadingMode cur = m_renderer.GetShadingMode();
|
||||||
|
auto shadingItem = [&](const char* label, ShadingMode mode) {
|
||||||
|
if (ImGui::MenuItem(label, nullptr, cur == mode))
|
||||||
|
m_renderer.SetShadingMode(mode);
|
||||||
|
};
|
||||||
|
shadingItem("Smooth Shaded", ShadingMode::SmoothShaded);
|
||||||
|
shadingItem("Flat Shaded", ShadingMode::FlatShaded);
|
||||||
|
shadingItem("Wireframe on Surface", ShadingMode::WireframeOnSurface);
|
||||||
|
shadingItem("Wireframe", ShadingMode::Wireframe);
|
||||||
|
shadingItem("Unlit", ShadingMode::Unlit);
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Lighting ----------------------------------------------------
|
||||||
|
if (ImGui::BeginMenu("Lighting")) {
|
||||||
|
bool ambient = m_renderer.GetAmbientLightOnly();
|
||||||
|
if (ImGui::MenuItem("Camera Headlight", nullptr, ambient))
|
||||||
|
m_renderer.SetAmbientLightOnly(true);
|
||||||
|
if (ImGui::MenuItem("Scene Lights", nullptr, !ambient))
|
||||||
|
m_renderer.SetAmbientLightOnly(false);
|
||||||
|
ImGui::Separator();
|
||||||
|
bool dome = m_renderer.GetDomeLightEnabled();
|
||||||
|
if (ImGui::MenuItem("Dome Light", nullptr, dome))
|
||||||
|
m_renderer.SetDomeLightEnabled(!dome);
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
// -- Display toggles ---------------------------------------------
|
||||||
|
{
|
||||||
|
bool grid = m_renderer.ShowGrid();
|
||||||
|
if (ImGui::MenuItem("Show Grid", nullptr, grid))
|
||||||
|
m_renderer.SetShowGrid(!grid);
|
||||||
|
|
||||||
|
bool aaItem = m_renderer.GetAAEnabled();
|
||||||
|
if (ImGui::MenuItem("Anti-Aliasing", nullptr, aaItem))
|
||||||
|
m_renderer.SetAAEnabled(!aaItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
// -- BBox --------------------------------------------------------
|
||||||
|
if (ImGui::BeginMenu("Bounding Box")) {
|
||||||
|
BBoxMode bbox = m_renderer.GetBBoxMode();
|
||||||
|
if (ImGui::MenuItem("None", nullptr, bbox == BBoxMode::None))
|
||||||
|
m_renderer.SetBBoxMode(BBoxMode::None);
|
||||||
|
if (ImGui::MenuItem("Per Object", nullptr, bbox == BBoxMode::PerObject))
|
||||||
|
m_renderer.SetBBoxMode(BBoxMode::PerObject);
|
||||||
|
if (ImGui::MenuItem("All Selection", nullptr, bbox == BBoxMode::AllSelection))
|
||||||
|
m_renderer.SetBBoxMode(BBoxMode::AllSelection);
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Background --------------------------------------------------
|
||||||
|
if (ImGui::BeginMenu("Background")) {
|
||||||
|
auto& bg = m_renderer.GetBackgroundColor();
|
||||||
|
if (ImGui::MenuItem("Dark Gray", nullptr, bg == pxr::GfVec3f(0.15f, 0.15f, 0.15f)))
|
||||||
|
m_renderer.SetBackgroundColor(pxr::GfVec3f(0.15f, 0.15f, 0.15f));
|
||||||
|
if (ImGui::MenuItem("Black", nullptr, bg == pxr::GfVec3f(0.0f, 0.0f, 0.0f)))
|
||||||
|
m_renderer.SetBackgroundColor(pxr::GfVec3f(0.0f, 0.0f, 0.0f));
|
||||||
|
if (ImGui::MenuItem("Light Gray", nullptr, bg == pxr::GfVec3f(0.45f, 0.45f, 0.45f)))
|
||||||
|
m_renderer.SetBackgroundColor(pxr::GfVec3f(0.45f, 0.45f, 0.45f));
|
||||||
|
if (ImGui::MenuItem("Midnight Blue", nullptr, bg == pxr::GfVec3f(0.1f, 0.1f, 0.2f)))
|
||||||
|
m_renderer.SetBackgroundColor(pxr::GfVec3f(0.1f, 0.1f, 0.2f));
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::PopStyleVar(); // ItemSpacing
|
ImGui::PopStyleVar(); // ItemSpacing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ struct ViewportTileSettings {
|
|||||||
int bboxMode = 0; ///< BBoxMode cast to int
|
int bboxMode = 0; ///< BBoxMode cast to int
|
||||||
bool ambientLightOnly = false;
|
bool ambientLightOnly = false;
|
||||||
bool domeLightEnabled = false;
|
bool domeLightEnabled = false;
|
||||||
|
int shadingMode = 0; ///< ShadingMode cast to int (0 = SmoothShaded)
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Named orthographic view directions.
|
/// Named orthographic view directions.
|
||||||
|
|||||||
Reference in New Issue
Block a user