Property panel: display and edit primvars:displayColor[] as color swatches
DrawVtValueWidget now handles Color-role array attributes (VtArray<GfVec3f> and VtArray<GfVec4f>) that previously fell through to the generic [array N] fallback. - Single element: inline ColorEdit3/4 - Multiple elements: collapsible row with up to 5 swatch previews + [N] count; expanded view shows per-index ColorEdit3/4 (capped at 16 entries) - Editing any element writes the full modified VtArray back via attr.Set() Covers primvars:displayColor, primvars:displayOpacity[], and any other color3f[]/color4f[] primvar. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -577,8 +577,9 @@ static pxr::VtValue DrawVtValueWidget(pxr::UsdAttribute& attr,
|
||||
{
|
||||
using namespace pxr;
|
||||
|
||||
// Color role → ColorEdit3/4
|
||||
// Color role → ColorEdit3/4 (scalar and array)
|
||||
if (attr.GetRoleName() == TfToken("Color")) {
|
||||
// ---- scalar ----
|
||||
if (val.IsHolding<GfVec3f>()) {
|
||||
GfVec3f c = val.UncheckedGet<GfVec3f>();
|
||||
if (ImGui::ColorEdit3("##col", c.data()))
|
||||
@@ -591,6 +592,99 @@ static pxr::VtValue DrawVtValueWidget(pxr::UsdAttribute& attr,
|
||||
return VtValue(c);
|
||||
return VtValue();
|
||||
}
|
||||
|
||||
// ---- color3f[] (e.g. primvars:displayColor) ----
|
||||
if (val.IsHolding<VtArray<GfVec3f>>()) {
|
||||
VtArray<GfVec3f> arr = val.UncheckedGet<VtArray<GfVec3f>>();
|
||||
bool changed = false;
|
||||
if (arr.size() == 1) {
|
||||
GfVec3f c = arr[0];
|
||||
if (ImGui::ColorEdit3("##dc", c.data()))
|
||||
{ arr[0] = c; changed = true; }
|
||||
} else if (!arr.empty()) {
|
||||
// Collapsible: arrow + swatch preview on header line
|
||||
bool open = ImGui::TreeNodeEx("##dcarr",
|
||||
ImGuiTreeNodeFlags_AllowOverlap | ImGuiTreeNodeFlags_SpanAvailWidth);
|
||||
ImGui::SameLine(0, 6);
|
||||
float sz = ImGui::GetTextLineHeight();
|
||||
size_t shown = std::min(arr.size(), (size_t)5);
|
||||
for (size_t i = 0; i < shown; ++i) {
|
||||
if (i > 0) ImGui::SameLine(0, 2);
|
||||
char sid[16]; snprintf(sid, sizeof(sid), "##sv%d", (int)i);
|
||||
ImGui::ColorButton(sid,
|
||||
ImVec4(arr[i][0], arr[i][1], arr[i][2], 1.f),
|
||||
ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip,
|
||||
ImVec2(sz, sz));
|
||||
}
|
||||
ImGui::SameLine(0, 4);
|
||||
ImGui::TextDisabled("[%zu]", arr.size());
|
||||
if (open) {
|
||||
static constexpr size_t kEditLimit = 16;
|
||||
size_t lim = std::min(arr.size(), kEditLimit);
|
||||
for (size_t i = 0; i < lim; ++i) {
|
||||
ImGui::PushID((int)i);
|
||||
ImGui::Text("[%d]", (int)i);
|
||||
ImGui::SameLine();
|
||||
GfVec3f c = arr[i];
|
||||
ImGui::SetNextItemWidth(-FLT_MIN);
|
||||
if (ImGui::ColorEdit3("##ce", c.data()))
|
||||
{ arr[i] = c; changed = true; }
|
||||
ImGui::PopID();
|
||||
}
|
||||
if (arr.size() > kEditLimit)
|
||||
ImGui::TextDisabled(" ... %zu more", arr.size() - kEditLimit);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
if (changed) return VtValue(arr);
|
||||
return VtValue();
|
||||
}
|
||||
|
||||
// ---- color4f[] ----
|
||||
if (val.IsHolding<VtArray<GfVec4f>>()) {
|
||||
VtArray<GfVec4f> arr = val.UncheckedGet<VtArray<GfVec4f>>();
|
||||
bool changed = false;
|
||||
if (arr.size() == 1) {
|
||||
GfVec4f c = arr[0];
|
||||
if (ImGui::ColorEdit4("##dc4", c.data()))
|
||||
{ arr[0] = c; changed = true; }
|
||||
} else if (!arr.empty()) {
|
||||
bool open = ImGui::TreeNodeEx("##dcarr4",
|
||||
ImGuiTreeNodeFlags_AllowOverlap | ImGuiTreeNodeFlags_SpanAvailWidth);
|
||||
ImGui::SameLine(0, 6);
|
||||
float sz = ImGui::GetTextLineHeight();
|
||||
size_t shown = std::min(arr.size(), (size_t)5);
|
||||
for (size_t i = 0; i < shown; ++i) {
|
||||
if (i > 0) ImGui::SameLine(0, 2);
|
||||
char sid[16]; snprintf(sid, sizeof(sid), "##sv4%d", (int)i);
|
||||
ImGui::ColorButton(sid,
|
||||
ImVec4(arr[i][0], arr[i][1], arr[i][2], arr[i][3]),
|
||||
ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip,
|
||||
ImVec2(sz, sz));
|
||||
}
|
||||
ImGui::SameLine(0, 4);
|
||||
ImGui::TextDisabled("[%zu]", arr.size());
|
||||
if (open) {
|
||||
static constexpr size_t kEditLimit = 16;
|
||||
size_t lim = std::min(arr.size(), kEditLimit);
|
||||
for (size_t i = 0; i < lim; ++i) {
|
||||
ImGui::PushID((int)i);
|
||||
ImGui::Text("[%d]", (int)i);
|
||||
ImGui::SameLine();
|
||||
GfVec4f c = arr[i];
|
||||
ImGui::SetNextItemWidth(-FLT_MIN);
|
||||
if (ImGui::ColorEdit4("##ce4", c.data()))
|
||||
{ arr[i] = c; changed = true; }
|
||||
ImGui::PopID();
|
||||
}
|
||||
if (arr.size() > kEditLimit)
|
||||
ImGui::TextDisabled(" ... %zu more", arr.size() - kEditLimit);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
if (changed) return VtValue(arr);
|
||||
return VtValue();
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Scalar types ----
|
||||
|
||||
Reference in New Issue
Block a user