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_aaEnabled(false)
|
||||
, m_backgroundColor(0.15f, 0.15f, 0.15f)
|
||||
, m_shadingMode(ShadingMode::SmoothShaded)
|
||||
, m_ambientLightOnly(true)
|
||||
, m_domeLightEnabled(false)
|
||||
, m_stageIsZup(false)
|
||||
@@ -616,11 +617,27 @@ void UsdSceneRenderer::Render(int width, int height)
|
||||
m_renderParams = pxr::UsdImagingGLRenderParams();
|
||||
m_renderParams.frame = m_currentTime;
|
||||
m_renderParams.complexity = 1.0f;
|
||||
// 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.showProxy = true;
|
||||
m_renderParams.showRender = false;
|
||||
m_renderParams.enableLighting = true;
|
||||
m_renderParams.enableSampleAlphaToCoverage = true;
|
||||
m_renderParams.gammaCorrectColors = false;
|
||||
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
|
||||
};
|
||||
|
||||
/// 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 {
|
||||
public:
|
||||
UsdSceneRenderer();
|
||||
@@ -199,6 +208,9 @@ public:
|
||||
bool GetDomeLightEnabled() const { return m_domeLightEnabled; }
|
||||
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).
|
||||
float GetDefaultMaterialAmbient() const { return m_defaultMaterialAmbient; }
|
||||
void SetDefaultMaterialAmbient(float v) { m_defaultMaterialAmbient = v; }
|
||||
@@ -298,6 +310,7 @@ private:
|
||||
pxr::GfVec3f m_backgroundColor;
|
||||
|
||||
// Lighting settings (mirrors stageView.py viewSettings)
|
||||
ShadingMode m_shadingMode; // draw mode + lighting flags
|
||||
bool m_ambientLightOnly; // camera headlight
|
||||
bool m_domeLightEnabled; // dome/IBL light
|
||||
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::FilePlus: return "file-plus.svg";
|
||||
case Icon::Pen: return "pen.svg";
|
||||
case Icon::Settings: return "gear.svg";
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -75,7 +76,7 @@ static constexpr Icon kAllIcons[] = {
|
||||
Icon::LayoutSingle, Icon::LayoutHSplit, Icon::LayoutVSplit, Icon::LayoutQuad,
|
||||
Icon::SkipBack, Icon::StepBack, Icon::PlayBack, Icon::Play, Icon::Pause,
|
||||
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
|
||||
FilePlus, // create new file
|
||||
Pen, // edit / edit target
|
||||
Settings, // gear / viewport options
|
||||
};
|
||||
|
||||
/// 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 << "AmbientLightOnly=" << (s.ambientLightOnly ? 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 == "AmbientLightOnly") ts.ambientLightOnly = (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.ambientLightOnly = m_renderer.GetAmbientLightOnly();
|
||||
s.domeLightEnabled = m_renderer.GetDomeLightEnabled();
|
||||
s.shadingMode = static_cast<int>(m_renderer.GetShadingMode());
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -112,6 +113,7 @@ void ViewportTile::ApplySettings(const ViewportTileSettings& s)
|
||||
m_renderer.SetBBoxMode(static_cast<BBoxMode>(s.bboxMode));
|
||||
m_renderer.SetAmbientLightOnly(s.ambientLightOnly);
|
||||
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"))
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ struct ViewportTileSettings {
|
||||
int bboxMode = 0; ///< BBoxMode cast to int
|
||||
bool ambientLightOnly = false;
|
||||
bool domeLightEnabled = false;
|
||||
int shadingMode = 0; ///< ShadingMode cast to int (0 = SmoothShaded)
|
||||
};
|
||||
|
||||
/// Named orthographic view directions.
|
||||
|
||||
Reference in New Issue
Block a user