From e9528747bf943edf954a475beb6f4908d542b0b7 Mon Sep 17 00:00:00 2001 From: debloip Date: Mon, 27 Jan 2025 10:05:52 -0500 Subject: [PATCH 01/21] HYDRA-1286 : Initial displacement (no updates) --- .../wireframeHighlights/fvpBaseWhSi.cpp | 188 +++++++++++++++++- .../wireframeHighlights/fvpBaseWhSi.h | 8 + .../wireframeHighlights/fvpGeomSubsetWhSi.cpp | 36 +++- .../wireframeHighlights/fvpMeshWhSi.cpp | 2 +- 4 files changed, 229 insertions(+), 5 deletions(-) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index 1609ad7ee..3f7357548 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,18 @@ #include #include #include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include #include @@ -62,6 +75,20 @@ const HdDataSourceLocator reprSelectorLocator( const HdDataSourceLocator primvarsOverrideWireframeColorLocator( HdPrimvarsSchema::GetDefaultLocator().Append(_primVarsTokens->overrideWireframeColor)); +const HdDataSourceLocator pointsValueLocator = HdDataSourceLocator( + HdPrimvarsSchemaTokens->primvars, + HdPrimvarsSchemaTokens->points, + HdPrimvarSchemaTokens->primvarValue); + +const HdDataSourceLocator normalsPrimvarLocator = HdDataSourceLocator( + HdPrimvarsSchemaTokens->primvars, + HdPrimvarsSchemaTokens->normals); + +const HdDataSourceLocator normalsValueLocator = HdDataSourceLocator( + HdPrimvarsSchemaTokens->primvars, + HdPrimvarsSchemaTokens->normals, + HdPrimvarSchemaTokens->primvarValue); + // Returns all paths related to instancing for this prim; this is analogous to getting the edges // connected to the given vertex (in this case a prim) of an instancing graph. SdfPathVector _GetInstancingRelatedPaths(const HdSceneIndexPrim& prim, Fvp::InstancingPathsCollectionDirection direction) @@ -268,6 +295,7 @@ class _RerootingSceneIndexPathArrayDataSource : public HdPathArrayDataSource HdPathArrayDataSourceHandle const _inputDataSource; }; +//TODO :: Move to FVP namespace #if PXR_VERSION >= 2403 // Edits the mesh topology to only only contain its selected GeomSubsets HdContainerDataSourceHandle @@ -281,7 +309,6 @@ _TrimMeshForGeomSubset(const HdContainerDataSourceHandle& meshRootDataSource, co if (!meshTopologySchema.IsDefined()) { return meshRootDataSource; } - HdDataSourceLocator pointsValueLocator = HdDataSourceLocator(HdPrimvarsSchemaTokens->primvars, HdPrimvarsSchemaTokens->points, HdPrimvarSchemaTokens->primvarValue); auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, pointsValueLocator)); if (!pointsValueDataSource) { return meshRootDataSource; @@ -337,12 +364,19 @@ _TrimMeshForGeomSubset(const HdContainerDataSourceHandle& meshRootDataSource, co dataSourceEditor.Set(faceVertexCountsLocator, HdRetainedTypedSampledDataSource::New(trimmedFaceVertexCounts)); dataSourceEditor.Set(faceVertexIndicesLocator, HdRetainedTypedSampledDataSource::New(trimmedFaceVertexIndices)); - // We reduce the points primvar so that it has only the exact number of points required by the trimmed topology; + // We reduce the points and normals primvars so that they have only the exact number of elements required by the trimmed topology; // this avoids a warning from USD. VtArray points = pointsValueDataSource->GetTypedValue(0); points.resize(maxVertexIndex + 1); dataSourceEditor.Set(pointsValueLocator, HdRetainedTypedSampledDataSource>::New(points)); + auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, normalsValueLocator)); + if (normalsValueDataSource) { + auto normals = normalsValueDataSource->GetTypedValue(0); + normals.resize(maxVertexIndex + 1); + dataSourceEditor.Set(normalsValueLocator, HdRetainedTypedSampledDataSource>::New(normals)); + } + return dataSourceEditor.Finish(); } #endif @@ -434,6 +468,103 @@ TrimMeshForGeomSubset(const HdContainerDataSourceHandle& meshRootDataSource, con } #endif +PXR_NS::HdContainerDataSourceHandle ComputeNormals(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource) +{ + // Check if normals are already present + auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, normalsValueLocator)); + if (normalsValueDataSource) { + return meshRootDataSource; + } + + // Get required schemas/dataSources + HdMeshSchema meshSchema = HdMeshSchema::GetFromParent(meshRootDataSource); + if (!meshSchema.IsDefined()) { + return meshRootDataSource; + } + HdMeshTopologySchema meshTopologySchema = meshSchema.GetTopology(); + if (!meshTopologySchema.IsDefined()) { + return meshRootDataSource; + } + auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, pointsValueLocator)); + if (!pointsValueDataSource) { + return meshRootDataSource; + } + + // Setup topology + TfToken subdivScheme = PxOsdOpenSubdivTokens->none; + if (HdTokenDataSourceHandle subdivSchemeDataSource = meshSchema.GetSubdivisionScheme()) { + subdivScheme = subdivSchemeDataSource->GetTypedValue(0.0f); + } + VtIntArray holeIndices; + if (HdIntArrayDataSourceHandle holeIndicesDataSource = meshTopologySchema.GetHoleIndices()) { + holeIndices = holeIndicesDataSource->GetTypedValue(0.0f); + } + TfToken orientation = PxOsdOpenSubdivTokens->rightHanded; + if (HdTokenDataSourceHandle orientationDataSource = meshTopologySchema.GetOrientation()) { + orientation = orientationDataSource->GetTypedValue(0.0f); + } + HdMeshTopology meshTopology( + subdivScheme, + orientation, + meshTopologySchema.GetFaceVertexCounts()->GetTypedValue(0), + meshTopologySchema.GetFaceVertexIndices()->GetTypedValue(0), + holeIndices); + Hd_VertexAdjacency adjacency; + adjacency.BuildAdjacencyTable(&meshTopology); + + // Compute normals + auto points = pointsValueDataSource->GetTypedValue(0); + auto normals = Hd_SmoothNormals::ComputeSmoothNormals( + &adjacency, static_cast(points.size()), points.cdata()); + + // Apply normals + auto normalsDataSource = HdPrimvarSchema::Builder() + .SetInterpolation(HdPrimvarSchema::BuildInterpolationDataSource(HdPrimvarSchemaTokens->vertex)) + .SetRole(HdPrimvarSchema::BuildRoleDataSource(HdPrimvarSchemaTokens->normal)) + .SetPrimvarValue(HdRetainedTypedSampledDataSource::New(normals)) + .Build(); + HdDataSourceLocator normalsPrimvarLocator = HdDataSourceLocator(HdPrimvarsSchemaTokens->primvars, HdPrimvarsSchemaTokens->normals); + HdContainerDataSourceEditor dataSourceEditor(meshRootDataSource); + dataSourceEditor.Set(normalsPrimvarLocator, normalsDataSource); + return dataSourceEditor.Finish(); +} + +PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, float displacement) +{ + std::cout << "displacement = " << displacement << std::endl; + auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, pointsValueLocator)); + if (!pointsValueDataSource) { + return meshRootDataSource; + } + auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, normalsValueLocator)); + if (!normalsValueDataSource) { + return meshRootDataSource; + } + + auto points = pointsValueDataSource->GetTypedValue(0); + auto normals = normalsValueDataSource->GetTypedValue(0); + + if (points.size() > normals.size()) { + return meshRootDataSource; + } + + // Compute displacement + for (size_t iPoint = 0; iPoint < points.size(); iPoint++) { + points[iPoint] += normals[iPoint] * displacement; + } + + // Apply displaced points + HdContainerDataSourceEditor dataSourceEditor(meshRootDataSource); + dataSourceEditor.Set(pointsValueLocator, HdRetainedTypedSampledDataSource>::New(points)); + + // Block materials to prevent displacement from being re-applied + dataSourceEditor.Set(HdDependenciesSchema::GetDefaultLocator(), HdBlockDataSource::New()); + dataSourceEditor.Set(HdMaterialBindingsSchema::GetDefaultLocator(), HdBlockDataSource::New()); + dataSourceEditor.Set(UsdImagingDirectMaterialBindingsSchema::GetDefaultLocator(), HdBlockDataSource::New()); + + return dataSourceEditor.Finish(); +} + Fvp::PrimSelection ConvertHydraToFvpSelection(const SdfPath& primPath, const HdSelectionSchema& selectionSchema) { Fvp::PrimSelection primSelection; primSelection.primPath = primPath; @@ -756,4 +887,57 @@ BaseWhSi::CollectInstancingPaths(const PXR_NS::SdfPath& primPath, InstancingPath } } +float +BaseWhSi::GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle& primDataSource) const +{ + float displacementValue = 0.f; + + if (!primDataSource) { + return displacementValue; + } + + // Step 1: Access the material data source + HdMaterialBindingsSchema materialBindingsSchema = HdMaterialBindingsSchema::GetFromParent(primDataSource); + if (!materialBindingsSchema.IsDefined()) { + return displacementValue; + } + + // Step 2: Get the material path + HdMaterialBindingSchema materialBindingSchema = materialBindingsSchema.GetMaterialBinding(); + if (!materialBindingSchema) { + return displacementValue; + } + + HdPathDataSourceHandle bindingPathDs = materialBindingSchema.GetPath(); + if (!bindingPathDs) { + return displacementValue; + } + + const SdfPath materialPath = bindingPathDs->GetTypedValue(0.0f); + + // Step 3: Retrieve the material + HdSceneIndexPrim materialPrim = GetInputSceneIndex()->GetPrim(materialPath); + if (!materialPrim.dataSource || (materialPrim.primType != HdPrimTypeTokens->material) ){ + return displacementValue; + } + + HdMaterialSchema materialSchema = HdMaterialSchema::GetFromParent(materialPrim.dataSource); + if (!materialSchema.IsDefined()) { + return displacementValue; + } + + // Step 4: Look for the displacement value + HdDataSourceMaterialNetworkInterface materialNetworkInterface( + materialPath, materialSchema.GetMaterialNetwork().GetContainer(), primDataSource); + + for (auto nodeName : materialNetworkInterface.GetNodeNames()) { + VtValue paramValue = materialNetworkInterface.GetNodeParameterValue(nodeName, HdMaterialTerminalTokens->displacement); + if (paramValue.IsHolding()) { + return paramValue.UncheckedGet(); + } + } + + return displacementValue; +} + } diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h index 560e14361..678d98562 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h @@ -217,6 +217,10 @@ class BaseWhSi FVP_API void CollectInstancingPaths(const PXR_NS::SdfPath& primPath, InstancingPathsCollectionDirection direction, PXR_NS::SdfPathSet& outInstancerPaths, PXR_NS::SdfPathSet& outPrototypePaths) const; + // Return the displacement value from the given prim data source's assigned material + FVP_API + float GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle& primDataSource) const; + const PXR_NS::SdfPath _highlightHierarchyPrefix; const std::shared_ptr _wireframeColorInterface; @@ -237,6 +241,10 @@ PXR_NS::HdContainerDataSourceHandle TrimMeshForGeomSubset(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, const PXR_NS::HdContainerDataSourceHandle& geomSubsetRootDataSource); #endif +PXR_NS::HdContainerDataSourceHandle ComputeNormals(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource); + +PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, float displacement); + Fvp::PrimSelection ConvertHydraToFvpSelection(const PXR_NS::SdfPath& primPath, const PXR_NS::HdSelectionSchema& selectionSchema); } diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp index ae965b0ee..f156c1297 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp @@ -14,11 +14,35 @@ // #include "fvpGeomSubsetWhSi.h" +#include "fvpBaseWhSi.h" +#include +#include #include +#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + #if PXR_VERSION >= 2403 PXR_NAMESPACE_USING_DIRECTIVE @@ -50,10 +74,13 @@ HdSceneIndexPrim GeomSubsetWhSi::GetHighlightPrim(const SdfPath &selectionPath, auto originalPath = fullPrimPath.ReplacePrefix(selectionPath, originalMeshPath.GetParentPath()); HdSceneIndexPrim prim = GetInputSceneIndex()->GetPrim(originalPath); - prim.dataSource = RepathingContainerDataSource::New(originalMeshPath.GetParentPath(), selectionPath, prim.dataSource); + //prim.dataSource = RepathingContainerDataSource::New(originalMeshPath.GetParentPath(), selectionPath, prim.dataSource); if (prim.primType == HdPrimTypeTokens->mesh) { prim.dataSource = SetWireframeRepr(prim.dataSource, _wireframeColorInterface->getWireframeColor(selectionKey.first)); - if (originalPath == selectionKey.first.GetParentPath()) { + if (originalPath == originalMeshPath) { + prim.dataSource = ComputeNormals(prim.dataSource); + // TODO : update displacement when displacement is dirtied. + prim.dataSource = ForceDisplacement(prim.dataSource, GetMaterialDisplacementValue(GetInputSceneIndex()->GetPrim(selectionKey.first).dataSource)); prim.dataSource = TrimMeshForGeomSubset(prim.dataSource, GetInputSceneIndex()->GetPrim(selectionKey.first).dataSource); } } @@ -134,6 +161,11 @@ void GeomSubsetWhSi::ProcessDirtiedPrims( if (_primPathsToSelections.find(entry.primPath) != _primPathsToSelections.end()) { auto selectionPath = SelectionPathFromKey(SelectionKey(entry.primPath, "")); auto originalMeshPath = entry.primPath.GetParentPath(); + //std::cout << originalMeshPath << std::endl; + //TODO: Need to store and keep track/update mapping of material paths and geomsubsets associations + // to catch material dirty notifs and dirty points primvarValue + //auto dirtyLocators = entry.dirtyLocators; + //if (dirtyLocators.Intersects(HdMaterialSchema::GetDefaultLocator())) highlightEntries.emplace_back(originalMeshPath.ReplacePrefix(originalMeshPath.GetParentPath(), selectionPath), entry.dirtyLocators); } } diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpMeshWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpMeshWhSi.cpp index efc3ee643..4a6087b0e 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpMeshWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpMeshWhSi.cpp @@ -36,7 +36,7 @@ HdSceneIndexPrim MeshWhSi::GetHighlightPrim(const SdfPath &selectionPath, const auto originalPath = fullPrimPath.ReplacePrefix(selectionPath, SdfPath::AbsoluteRootPath()); HdSceneIndexPrim prim = GetInputSceneIndex()->GetPrim(originalPath); - prim.dataSource = RepathingContainerDataSource::New(SdfPath::AbsoluteRootPath(), selectionPath, prim.dataSource); + //prim.dataSource = RepathingContainerDataSource::New(SdfPath::AbsoluteRootPath(), selectionPath, prim.dataSource); if (prim.primType == HdPrimTypeTokens->mesh) { prim.dataSource = SetWireframeRepr(prim.dataSource, _wireframeColorInterface->getWireframeColor(selectionKey.first)); } From 5f503d49dffbcdab0e9dfc2019bfcf1f840f7135 Mon Sep 17 00:00:00 2001 From: debloip Date: Mon, 27 Jan 2025 12:08:28 -0500 Subject: [PATCH 02/21] HYDRA-1286 : Update GeomSubset highlight on displacement update --- .../wireframeHighlights/fvpBaseWhSi.cpp | 61 +++++++++++-------- .../wireframeHighlights/fvpBaseWhSi.h | 4 ++ .../wireframeHighlights/fvpGeomSubsetWhSi.cpp | 41 +++++++++++-- 3 files changed, 78 insertions(+), 28 deletions(-) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index 3f7357548..2d1789595 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -531,7 +531,6 @@ PXR_NS::HdContainerDataSourceHandle ComputeNormals(const PXR_NS::HdContainerData PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, float displacement) { - std::cout << "displacement = " << displacement << std::endl; auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, pointsValueLocator)); if (!pointsValueDataSource) { return meshRootDataSource; @@ -555,13 +554,40 @@ PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerD // Apply displaced points HdContainerDataSourceEditor dataSourceEditor(meshRootDataSource); - dataSourceEditor.Set(pointsValueLocator, HdRetainedTypedSampledDataSource>::New(points)); - - // Block materials to prevent displacement from being re-applied - dataSourceEditor.Set(HdDependenciesSchema::GetDefaultLocator(), HdBlockDataSource::New()); + dataSourceEditor.Set(pointsValueLocator, HdRetainedTypedSampledDataSource>::New(points)); + return dataSourceEditor.Finish(); +} + + +SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSource) +{ + if (!primDataSource) { + return {}; + } + + HdMaterialBindingsSchema materialBindingsSchema = HdMaterialBindingsSchema::GetFromParent(primDataSource); + if (!materialBindingsSchema.IsDefined()) { + return {}; + } + + HdMaterialBindingSchema materialBindingSchema = materialBindingsSchema.GetMaterialBinding(); + if (!materialBindingSchema) { + return {}; + } + + HdPathDataSourceHandle bindingPathDataSource = materialBindingSchema.GetPath(); + if (!bindingPathDataSource) { + return {}; + } + + return bindingPathDataSource->GetTypedValue(0); +} + +PXR_NS::HdContainerDataSourceHandle BlockMaterials(const PXR_NS::HdContainerDataSourceHandle& primDataSource) +{ + HdContainerDataSourceEditor dataSourceEditor(primDataSource); dataSourceEditor.Set(HdMaterialBindingsSchema::GetDefaultLocator(), HdBlockDataSource::New()); dataSourceEditor.Set(UsdImagingDirectMaterialBindingsSchema::GetDefaultLocator(), HdBlockDataSource::New()); - return dataSourceEditor.Finish(); } @@ -896,26 +922,13 @@ BaseWhSi::GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle return displacementValue; } - // Step 1: Access the material data source - HdMaterialBindingsSchema materialBindingsSchema = HdMaterialBindingsSchema::GetFromParent(primDataSource); - if (!materialBindingsSchema.IsDefined()) { + // Step 1: Get the material path + const SdfPath materialPath = GetMaterialPath(primDataSource); + if (materialPath.IsEmpty()) { return displacementValue; } - // Step 2: Get the material path - HdMaterialBindingSchema materialBindingSchema = materialBindingsSchema.GetMaterialBinding(); - if (!materialBindingSchema) { - return displacementValue; - } - - HdPathDataSourceHandle bindingPathDs = materialBindingSchema.GetPath(); - if (!bindingPathDs) { - return displacementValue; - } - - const SdfPath materialPath = bindingPathDs->GetTypedValue(0.0f); - - // Step 3: Retrieve the material + // Step 2: Retrieve the material HdSceneIndexPrim materialPrim = GetInputSceneIndex()->GetPrim(materialPath); if (!materialPrim.dataSource || (materialPrim.primType != HdPrimTypeTokens->material) ){ return displacementValue; @@ -926,7 +939,7 @@ BaseWhSi::GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle return displacementValue; } - // Step 4: Look for the displacement value + // Step 3: Look for the displacement value HdDataSourceMaterialNetworkInterface materialNetworkInterface( materialPath, materialSchema.GetMaterialNetwork().GetContainer(), primDataSource); diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h index 678d98562..56dcb77c0 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h @@ -245,6 +245,10 @@ PXR_NS::HdContainerDataSourceHandle ComputeNormals(const PXR_NS::HdContainerData PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, float displacement); +PXR_NS::SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSource); + +PXR_NS::HdContainerDataSourceHandle BlockMaterials(const PXR_NS::HdContainerDataSourceHandle& primDataSource); + Fvp::PrimSelection ConvertHydraToFvpSelection(const PXR_NS::SdfPath& primPath, const PXR_NS::HdSelectionSchema& selectionSchema); } diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp index f156c1297..e91b0dc31 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp @@ -55,6 +55,33 @@ bool _IsSelected(const HdSceneIndexPrim& prim) return selectionsSchema.IsDefined() && selectionsSchema.GetNumElements() > 0; } +/// Given a material prim path data source, returns a dependency of primvars +/// on material of that given prim. +HdContainerDataSourceHandle +_ComputePrimvarsToMaterialDependency(const SdfPath &materialPrimPath) +{ + HdDependencySchema::Builder builder; + + builder.SetDependedOnPrimPath( + HdRetainedTypedSampledDataSource::New( + materialPrimPath)); + + static HdLocatorDataSourceHandle dependedOnLocatorDataSource = + HdRetainedTypedSampledDataSource::New( + HdMaterialSchema::GetDefaultLocator()); + builder.SetDependedOnDataSourceLocator(dependedOnLocatorDataSource); + + static HdLocatorDataSourceHandle affectedLocatorDataSource = + HdRetainedTypedSampledDataSource::New( + HdPrimvarsSchema::GetDefaultLocator()); + builder.SetAffectedDataSourceLocator(affectedLocatorDataSource); + + return + HdRetainedContainerDataSource::New( + TfToken("FvpWhSi_MaterialToPrimvars"), + builder.Build()); +} + } namespace FVP_NS_DEF { @@ -77,11 +104,17 @@ HdSceneIndexPrim GeomSubsetWhSi::GetHighlightPrim(const SdfPath &selectionPath, //prim.dataSource = RepathingContainerDataSource::New(originalMeshPath.GetParentPath(), selectionPath, prim.dataSource); if (prim.primType == HdPrimTypeTokens->mesh) { prim.dataSource = SetWireframeRepr(prim.dataSource, _wireframeColorInterface->getWireframeColor(selectionKey.first)); - if (originalPath == originalMeshPath) { + if (originalPath == originalMeshPath) { + HdSceneIndexPrim geomSubsetPrim = GetInputSceneIndex()->GetPrim(selectionKey.first); prim.dataSource = ComputeNormals(prim.dataSource); - // TODO : update displacement when displacement is dirtied. - prim.dataSource = ForceDisplacement(prim.dataSource, GetMaterialDisplacementValue(GetInputSceneIndex()->GetPrim(selectionKey.first).dataSource)); - prim.dataSource = TrimMeshForGeomSubset(prim.dataSource, GetInputSceneIndex()->GetPrim(selectionKey.first).dataSource); + prim.dataSource = ForceDisplacement(prim.dataSource, GetMaterialDisplacementValue(geomSubsetPrim.dataSource)); + prim.dataSource = TrimMeshForGeomSubset(prim.dataSource, geomSubsetPrim.dataSource); + + HdContainerDataSourceEditor dsEditor(prim.dataSource); + dsEditor.Overlay(HdDependenciesSchema::GetDefaultLocator(), _ComputePrimvarsToMaterialDependency(GetMaterialPath(geomSubsetPrim.dataSource))); + prim.dataSource = dsEditor.Finish(); + prim.dataSource = BlockMaterials(prim.dataSource); + } } return prim; From 9c3f4e8a4906129f70931904d85032a8f4a15b8b Mon Sep 17 00:00:00 2001 From: debloip Date: Mon, 27 Jan 2025 12:44:20 -0500 Subject: [PATCH 03/21] HYDRA-1286 : Add utility method to create data source dependencies --- .../wireframeHighlights/fvpBaseWhSi.cpp | 24 +++++++++++++++++++ .../wireframeHighlights/fvpBaseWhSi.h | 8 +++++++ .../wireframeHighlights/fvpGeomSubsetWhSi.cpp | 16 +++++++++---- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index 2d1789595..29ef6ce48 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -591,6 +591,30 @@ PXR_NS::HdContainerDataSourceHandle BlockMaterials(const PXR_NS::HdContainerData return dataSourceEditor.Finish(); } +PXR_NS::HdContainerDataSourceHandle AddDependency( + const PXR_NS::HdContainerDataSourceHandle& primDataSource, + const PXR_NS::TfToken& dependencyToken, + const PXR_NS::SdfPath& dependedOnPrimPath, + const PXR_NS::HdDataSourceLocator& dependedOnDataSourceLocator, + const PXR_NS::HdDataSourceLocator& affectedDataSourceLocator) +{ + HdDependencySchema::Builder builder; + + if (!dependedOnPrimPath.IsEmpty()) { + builder.SetDependedOnPrimPath(HdRetainedTypedSampledDataSource::New(dependedOnPrimPath)); + } + + builder.SetDependedOnDataSourceLocator(HdRetainedTypedSampledDataSource::New(dependedOnDataSourceLocator)); + + builder.SetAffectedDataSourceLocator(HdRetainedTypedSampledDataSource::New(affectedDataSourceLocator)); + + auto dependencyDataSource = HdRetainedContainerDataSource::New(dependencyToken, builder.Build()); + + HdContainerDataSourceEditor dataSourceEditor(primDataSource); + dataSourceEditor.Overlay(HdDependenciesSchema::GetDefaultLocator(), dependencyDataSource); + return dataSourceEditor.Finish(); +} + Fvp::PrimSelection ConvertHydraToFvpSelection(const SdfPath& primPath, const HdSelectionSchema& selectionSchema) { Fvp::PrimSelection primSelection; primSelection.primPath = primPath; diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h index 56dcb77c0..74a8801d8 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -249,6 +250,13 @@ PXR_NS::SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primD PXR_NS::HdContainerDataSourceHandle BlockMaterials(const PXR_NS::HdContainerDataSourceHandle& primDataSource); +PXR_NS::HdContainerDataSourceHandle AddDependency( + const PXR_NS::HdContainerDataSourceHandle& primDataSource, + const PXR_NS::TfToken& dependencyToken, + const PXR_NS::SdfPath& dependedOnPrimPath, + const PXR_NS::HdDataSourceLocator& dependedOnDataSourceLocator, + const PXR_NS::HdDataSourceLocator& affectedDataSourceLocator); + Fvp::PrimSelection ConvertHydraToFvpSelection(const PXR_NS::SdfPath& primPath, const PXR_NS::HdSelectionSchema& selectionSchema); } diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp index e91b0dc31..913a279de 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -106,15 +107,20 @@ HdSceneIndexPrim GeomSubsetWhSi::GetHighlightPrim(const SdfPath &selectionPath, prim.dataSource = SetWireframeRepr(prim.dataSource, _wireframeColorInterface->getWireframeColor(selectionKey.first)); if (originalPath == originalMeshPath) { HdSceneIndexPrim geomSubsetPrim = GetInputSceneIndex()->GetPrim(selectionKey.first); + + // Compute the normals and then trim the mesh + // (normals must be computed before trimming so that they follow the original mesh's topology) prim.dataSource = ComputeNormals(prim.dataSource); - prim.dataSource = ForceDisplacement(prim.dataSource, GetMaterialDisplacementValue(geomSubsetPrim.dataSource)); prim.dataSource = TrimMeshForGeomSubset(prim.dataSource, geomSubsetPrim.dataSource); - HdContainerDataSourceEditor dsEditor(prim.dataSource); - dsEditor.Overlay(HdDependenciesSchema::GetDefaultLocator(), _ComputePrimvarsToMaterialDependency(GetMaterialPath(geomSubsetPrim.dataSource))); - prim.dataSource = dsEditor.Finish(); - prim.dataSource = BlockMaterials(prim.dataSource); + // Force the displacement + prim.dataSource = ForceDisplacement(prim.dataSource, GetMaterialDisplacementValue(geomSubsetPrim.dataSource)); + // Setup the dependency so that material updates also dirty the points & normals primvars, + // and then block materials to prevent them from re-applying displacement + // (the dependency must be added before we block the materials, otherwise we can't know which material was assigned to the geomSubset) + prim.dataSource = AddDependency(prim.dataSource, TfToken("Fvp_WhSi_MaterialToPrimvars"), GetMaterialPath(geomSubsetPrim.dataSource), HdMaterialSchema::GetDefaultLocator(), HdPrimvarsSchema::GetDefaultLocator()); + prim.dataSource = BlockMaterials(prim.dataSource); } } return prim; From 7b62cc977fd0a32da8641855b6e37470879db330 Mon Sep 17 00:00:00 2001 From: debloip Date: Mon, 27 Jan 2025 14:59:39 -0500 Subject: [PATCH 04/21] HYDRA-1286 : Extract method to make geomSubset highlights --- .../wireframeHighlights/fvpBaseWhSi.cpp | 24 +++++++++++++++++++ .../wireframeHighlights/fvpBaseWhSi.h | 6 +++++ .../wireframeHighlights/fvpGeomSubsetWhSi.cpp | 15 +----------- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index 29ef6ce48..4cf8c5274 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -977,4 +977,28 @@ BaseWhSi::GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle return displacementValue; } +PXR_NS::HdContainerDataSourceHandle +BaseWhSi::MakeGeomSubsetHighlight( + const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, + const PXR_NS::HdContainerDataSourceHandle& geomSubsetRootDataSource) const +{ + HdContainerDataSourceHandle editedMeshRootDataSource = meshRootDataSource; + + // Compute the normals and then trim the mesh + // (normals must be computed before trimming so that they follow the original mesh's topology) + editedMeshRootDataSource = ComputeNormals(editedMeshRootDataSource); + editedMeshRootDataSource = TrimMeshForGeomSubset(editedMeshRootDataSource, geomSubsetRootDataSource); + + // Force the displacement + editedMeshRootDataSource = ForceDisplacement(editedMeshRootDataSource, GetMaterialDisplacementValue(geomSubsetRootDataSource)); + + // Setup the dependency so that material updates also dirty the points & normals primvars, + // and then block materials to prevent them from re-applying displacement + // (the dependency must be added before we block the materials, otherwise we can't know which material was assigned to the geomSubset) + editedMeshRootDataSource = AddDependency(editedMeshRootDataSource, TfToken("Fvp_WhSi_MaterialToPrimvars"), GetMaterialPath(geomSubsetRootDataSource), HdMaterialSchema::GetDefaultLocator(), HdPrimvarsSchema::GetDefaultLocator()); + editedMeshRootDataSource = BlockMaterials(editedMeshRootDataSource); + + return editedMeshRootDataSource; +} + } diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h index 74a8801d8..5fb27b6a0 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h @@ -222,6 +222,12 @@ class BaseWhSi FVP_API float GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle& primDataSource) const; + // Given a mesh and geomSubset data sources, edits and returns the mesh data source to fit the given geomSubset + FVP_API + PXR_NS::HdContainerDataSourceHandle MakeGeomSubsetHighlight( + const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, + const PXR_NS::HdContainerDataSourceHandle& geomSubsetRootDataSource) const; + const PXR_NS::SdfPath _highlightHierarchyPrefix; const std::shared_ptr _wireframeColorInterface; diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp index 913a279de..11f11d0b1 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp @@ -107,20 +107,7 @@ HdSceneIndexPrim GeomSubsetWhSi::GetHighlightPrim(const SdfPath &selectionPath, prim.dataSource = SetWireframeRepr(prim.dataSource, _wireframeColorInterface->getWireframeColor(selectionKey.first)); if (originalPath == originalMeshPath) { HdSceneIndexPrim geomSubsetPrim = GetInputSceneIndex()->GetPrim(selectionKey.first); - - // Compute the normals and then trim the mesh - // (normals must be computed before trimming so that they follow the original mesh's topology) - prim.dataSource = ComputeNormals(prim.dataSource); - prim.dataSource = TrimMeshForGeomSubset(prim.dataSource, geomSubsetPrim.dataSource); - - // Force the displacement - prim.dataSource = ForceDisplacement(prim.dataSource, GetMaterialDisplacementValue(geomSubsetPrim.dataSource)); - - // Setup the dependency so that material updates also dirty the points & normals primvars, - // and then block materials to prevent them from re-applying displacement - // (the dependency must be added before we block the materials, otherwise we can't know which material was assigned to the geomSubset) - prim.dataSource = AddDependency(prim.dataSource, TfToken("Fvp_WhSi_MaterialToPrimvars"), GetMaterialPath(geomSubsetPrim.dataSource), HdMaterialSchema::GetDefaultLocator(), HdPrimvarsSchema::GetDefaultLocator()); - prim.dataSource = BlockMaterials(prim.dataSource); + prim.dataSource = MakeGeomSubsetHighlight(prim.dataSource, geomSubsetPrim.dataSource); } } return prim; From 5e3302d8e14469ca9615fad2f38c1923762a80ea Mon Sep 17 00:00:00 2001 From: debloip Date: Mon, 27 Jan 2025 16:25:15 -0500 Subject: [PATCH 05/21] HYDRA-1286 : Support displacement in point instancing --- .../wireframeHighlights/fvpBaseWhSi.cpp | 46 +++++++++++++++++++ .../wireframeHighlights/fvpBaseWhSi.h | 2 + .../wireframeHighlights/fvpGeomSubsetWhSi.cpp | 2 +- .../wireframeHighlights/fvpMeshWhSi.cpp | 2 +- .../wireframeHighlights/fvpNiInstanceWhSi.cpp | 4 +- .../fvpNiPrototypeWhSi.cpp | 3 +- .../fvpPiInstancerWhSi.cpp | 4 +- .../fvpPiPrototypeWhSi.cpp | 4 +- 8 files changed, 58 insertions(+), 9 deletions(-) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index 4cf8c5274..f97487ac9 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -19,8 +19,12 @@ #include #include +#include #include +#include +#include #include +#include #include #include #include @@ -45,6 +49,7 @@ #include #include +#include #include @@ -615,6 +620,47 @@ PXR_NS::HdContainerDataSourceHandle AddDependency( return dataSourceEditor.Finish(); } +PXR_NS::HdContainerDataSourceHandle RepathInstancingDataSources( + const PXR_NS::HdContainerDataSourceHandle& primDataSource, + const PXR_NS::SdfPath& srcPrefix, + const PXR_NS::SdfPath& dstPrefix) +{ + static const std::set kInstancingDataSourceLocators = { + HdInstancerTopologySchema::GetDefaultLocator(), + HdInstancedBySchema::GetDefaultLocator(), + HdInstanceSchema::GetDefaultLocator(), + UsdImagingUsdPrimInfoSchema::GetDefaultLocator().Append(UsdImagingUsdPrimInfoSchemaTokens->piPropagatedPrototypes), + UsdImagingUsdPrimInfoSchema::GetDefaultLocator().Append(UsdImagingUsdPrimInfoSchemaTokens->niPrototypePath), + }; + + HdContainerDataSourceEditor dataSourceEditor(primDataSource); + for (const auto& instancingDataSourceLocator : kInstancingDataSourceLocators) { + auto instancingDataSource = HdContainerDataSource::Get(primDataSource, instancingDataSourceLocator); + + if (auto containerDataSource = HdContainerDataSource::Cast(instancingDataSource)) { + dataSourceEditor.Set( + instancingDataSourceLocator, + RepathingContainerDataSource::New(srcPrefix, dstPrefix, containerDataSource) + ); + } + + if (auto pathDataSource = HdTypedSampledDataSource::Cast(instancingDataSource)) { + dataSourceEditor.Set( + instancingDataSourceLocator, + _RerootingSceneIndexPathDataSource::New(srcPrefix, dstPrefix, pathDataSource) + ); + } + + if (auto pathArrayDataSource = HdTypedSampledDataSource>::Cast(instancingDataSource)) { + dataSourceEditor.Set( + instancingDataSourceLocator, + _RerootingSceneIndexPathArrayDataSource::New(srcPrefix, dstPrefix, pathArrayDataSource) + ); + } + } + return dataSourceEditor.Finish(); +} + Fvp::PrimSelection ConvertHydraToFvpSelection(const SdfPath& primPath, const HdSelectionSchema& selectionSchema) { Fvp::PrimSelection primSelection; primSelection.primPath = primPath; diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h index 5fb27b6a0..ff8074ced 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h @@ -263,6 +263,8 @@ PXR_NS::HdContainerDataSourceHandle AddDependency( const PXR_NS::HdDataSourceLocator& dependedOnDataSourceLocator, const PXR_NS::HdDataSourceLocator& affectedDataSourceLocator); +PXR_NS::HdContainerDataSourceHandle RepathInstancingDataSources(const PXR_NS::HdContainerDataSourceHandle& primDataSource, const PXR_NS::SdfPath& srcPrefix, const PXR_NS::SdfPath& dstPrefix); + Fvp::PrimSelection ConvertHydraToFvpSelection(const PXR_NS::SdfPath& primPath, const PXR_NS::HdSelectionSchema& selectionSchema); } diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp index 11f11d0b1..620150e85 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp @@ -102,7 +102,6 @@ HdSceneIndexPrim GeomSubsetWhSi::GetHighlightPrim(const SdfPath &selectionPath, auto originalPath = fullPrimPath.ReplacePrefix(selectionPath, originalMeshPath.GetParentPath()); HdSceneIndexPrim prim = GetInputSceneIndex()->GetPrim(originalPath); - //prim.dataSource = RepathingContainerDataSource::New(originalMeshPath.GetParentPath(), selectionPath, prim.dataSource); if (prim.primType == HdPrimTypeTokens->mesh) { prim.dataSource = SetWireframeRepr(prim.dataSource, _wireframeColorInterface->getWireframeColor(selectionKey.first)); if (originalPath == originalMeshPath) { @@ -110,6 +109,7 @@ HdSceneIndexPrim GeomSubsetWhSi::GetHighlightPrim(const SdfPath &selectionPath, prim.dataSource = MakeGeomSubsetHighlight(prim.dataSource, geomSubsetPrim.dataSource); } } + prim.dataSource = RepathInstancingDataSources(prim.dataSource, originalMeshPath.GetParentPath(), selectionPath); return prim; }; diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpMeshWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpMeshWhSi.cpp index 4a6087b0e..449c3f39a 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpMeshWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpMeshWhSi.cpp @@ -36,10 +36,10 @@ HdSceneIndexPrim MeshWhSi::GetHighlightPrim(const SdfPath &selectionPath, const auto originalPath = fullPrimPath.ReplacePrefix(selectionPath, SdfPath::AbsoluteRootPath()); HdSceneIndexPrim prim = GetInputSceneIndex()->GetPrim(originalPath); - //prim.dataSource = RepathingContainerDataSource::New(SdfPath::AbsoluteRootPath(), selectionPath, prim.dataSource); if (prim.primType == HdPrimTypeTokens->mesh) { prim.dataSource = SetWireframeRepr(prim.dataSource, _wireframeColorInterface->getWireframeColor(selectionKey.first)); } + prim.dataSource = RepathInstancingDataSources(prim.dataSource, SdfPath::AbsoluteRootPath(), selectionPath); return prim; }; diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpNiInstanceWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpNiInstanceWhSi.cpp index c43263f45..8b70a099e 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpNiInstanceWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpNiInstanceWhSi.cpp @@ -52,10 +52,11 @@ NiInstanceWhSiRefPtr NiInstanceWhSi::New( HdSceneIndexPrim NiInstanceWhSi::GetHighlightPrim(const SdfPath &selectionPath, const SdfPath &fullPrimPath) const { SelectionKey selectionKey = SelectionKeyFromPath(selectionPath); + auto originalPath = fullPrimPath.ReplacePrefix(selectionPath, _selectionPathsToPrototypePrefixes.at(selectionPath)); HdSceneIndexPrim prim = GetInputSceneIndex()->GetPrim(originalPath); - prim.dataSource = RepathingContainerDataSource::New(_selectionPathsToPrototypePrefixes.at(selectionPath), selectionPath, prim.dataSource); HdContainerDataSourceEditor dsEditor(prim.dataSource); + dsEditor.Set(HdInstancedBySchema::GetDefaultLocator(), HdBlockDataSource::New()); HdSceneIndexPrim instancePrim = GetInputSceneIndex()->GetPrim(selectionKey.first); @@ -67,6 +68,7 @@ HdSceneIndexPrim NiInstanceWhSi::GetHighlightPrim(const SdfPath &selectionPath, if (prim.primType == HdPrimTypeTokens->mesh) { prim.dataSource = SetWireframeRepr(prim.dataSource, _wireframeColorInterface->getWireframeColor(selectionKey.first)); } + prim.dataSource = RepathInstancingDataSources(prim.dataSource, _selectionPathsToPrototypePrefixes.at(selectionPath), selectionPath); return prim; }; diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpNiPrototypeWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpNiPrototypeWhSi.cpp index 0f1bc084b..f3fdb54d6 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpNiPrototypeWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpNiPrototypeWhSi.cpp @@ -63,8 +63,6 @@ HdSceneIndexPrim NiPrototypeWhSi::GetHighlightPrim(const SdfPath &selectionPath, auto originalPath = fullPrimPath.ReplacePrefix(selectionPath, _selectionPathsToPrototypePrefixes.at(selectionPath)); HdSceneIndexPrim prim = GetInputSceneIndex()->GetPrim(originalPath); - - prim.dataSource = RepathingContainerDataSource::New(_selectionPathsToPrototypePrefixes.at(selectionPath), selectionPath, prim.dataSource); HdContainerDataSourceEditor dsEditor(prim.dataSource); HdSelectionsSchema activeSelectionsSchema = HdSelectionsSchema::GetFromParent(GetInputSceneIndex()->GetPrim(selectionKey.first).dataSource); @@ -88,6 +86,7 @@ HdSceneIndexPrim NiPrototypeWhSi::GetHighlightPrim(const SdfPath &selectionPath, if (prim.primType == HdPrimTypeTokens->mesh) { prim.dataSource = SetWireframeRepr(prim.dataSource, _wireframeColorInterface->getWireframeColor(ConvertHydraToFvpSelection(selectionKey.first, activeSelection))); } + prim.dataSource = RepathInstancingDataSources(prim.dataSource, _selectionPathsToPrototypePrefixes.at(selectionPath), selectionPath); return prim; }; diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpPiInstancerWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpPiInstancerWhSi.cpp index 2e5c0c01f..a312edb22 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpPiInstancerWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpPiInstancerWhSi.cpp @@ -133,16 +133,16 @@ HdSceneIndexPrim PiInstancerWhSi::GetHighlightPrim(const SdfPath &selectionPath, auto originalPath = fullPrimPath.ReplacePrefix(selectionPath, SdfPath::AbsoluteRootPath()); HdSceneIndexPrim prim = GetInputSceneIndex()->GetPrim(originalPath); - prim.dataSource = RepathingContainerDataSource::New(SdfPath::AbsoluteRootPath(), selectionPath, prim.dataSource); if (prim.primType == HdPrimTypeTokens->mesh) { prim.dataSource = SetWireframeRepr(prim.dataSource, primSelection.nestedInstanceIndices.empty() ? _wireframeColorInterface->getWireframeColor(selectionKey.first) : _wireframeColorInterface->getWireframeColor(primSelection)); } - if (_IsPointInstancer(prim) && originalPath == selectionKey.first && selectionKey.second != kFullHighlight) { + else if (_IsPointInstancer(prim) && originalPath == selectionKey.first && selectionKey.second != kFullHighlight) { // Adjust the instancer mask to only show selected instances HdSelectionsSchema selectionsSchema = HdSelectionsSchema::GetFromParent(prim.dataSource); HdSelectionSchema activeSelection = selectionsSchema.GetElement(std::stoul(selectionKey.second)); prim.dataSource = _GetSelectionHighlightInstancerDataSource(prim.dataSource, activeSelection); } + prim.dataSource = RepathInstancingDataSources(prim.dataSource, SdfPath::AbsoluteRootPath(), selectionPath); return prim; }; diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpPiPrototypeWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpPiPrototypeWhSi.cpp index c04ae65a8..179e47376 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpPiPrototypeWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpPiPrototypeWhSi.cpp @@ -72,11 +72,11 @@ HdSceneIndexPrim PiPrototypeWhSi::GetHighlightPrim(const SdfPath &selectionPath, prim.dataSource = SetWireframeRepr(prim.dataSource, _wireframeColorInterface->getWireframeColor(selectionKey.first)); #if PXR_VERSION >= 2403 if (originalPrototypePrim.primType == HdPrimTypeTokens->geomSubset && originalPath == selectionKey.first.GetParentPath()) { - prim.dataSource = TrimMeshForGeomSubset(prim.dataSource, originalPrototypePrim.dataSource); + prim.dataSource = MakeGeomSubsetHighlight(prim.dataSource, originalPrototypePrim.dataSource); } #endif } - prim.dataSource = RepathingContainerDataSource::New(SdfPath::AbsoluteRootPath(), selectionPath, prim.dataSource); + prim.dataSource = RepathInstancingDataSources(prim.dataSource, SdfPath::AbsoluteRootPath(), selectionPath); return prim; }; From 80c825d3d0a570b492d1161eeb08164640cc5879 Mon Sep 17 00:00:00 2001 From: debloip Date: Mon, 27 Jan 2025 17:02:50 -0500 Subject: [PATCH 06/21] HYDRA-1286 : Cleanup --- .../wireframeHighlights/fvpBaseWhSi.cpp | 19 ++----- .../wireframeHighlights/fvpBaseWhSi.h | 1 - .../wireframeHighlights/fvpGeomSubsetWhSi.cpp | 57 ------------------- 3 files changed, 6 insertions(+), 71 deletions(-) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index f97487ac9..d65e5e56b 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -19,16 +19,17 @@ #include #include -#include #include -#include -#include +#include +#include #include -#include #include #include #include +#include #include +#include +#include #include #include #include @@ -38,21 +39,13 @@ #include #include #include +#include #include #include #include -#include - -#include -#include #include - -#include -#include #include -#include - #include PXR_NAMESPACE_USING_DIRECTIVE diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h index ff8074ced..7c2a71bd0 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h @@ -21,7 +21,6 @@ #include #include -#include #include #include diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp index 620150e85..5ef38c4d1 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpGeomSubsetWhSi.cpp @@ -14,36 +14,11 @@ // #include "fvpGeomSubsetWhSi.h" -#include "fvpBaseWhSi.h" -#include -#include #include -#include -#include -#include #include #include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include - #if PXR_VERSION >= 2403 PXR_NAMESPACE_USING_DIRECTIVE @@ -56,33 +31,6 @@ bool _IsSelected(const HdSceneIndexPrim& prim) return selectionsSchema.IsDefined() && selectionsSchema.GetNumElements() > 0; } -/// Given a material prim path data source, returns a dependency of primvars -/// on material of that given prim. -HdContainerDataSourceHandle -_ComputePrimvarsToMaterialDependency(const SdfPath &materialPrimPath) -{ - HdDependencySchema::Builder builder; - - builder.SetDependedOnPrimPath( - HdRetainedTypedSampledDataSource::New( - materialPrimPath)); - - static HdLocatorDataSourceHandle dependedOnLocatorDataSource = - HdRetainedTypedSampledDataSource::New( - HdMaterialSchema::GetDefaultLocator()); - builder.SetDependedOnDataSourceLocator(dependedOnLocatorDataSource); - - static HdLocatorDataSourceHandle affectedLocatorDataSource = - HdRetainedTypedSampledDataSource::New( - HdPrimvarsSchema::GetDefaultLocator()); - builder.SetAffectedDataSourceLocator(affectedLocatorDataSource); - - return - HdRetainedContainerDataSource::New( - TfToken("FvpWhSi_MaterialToPrimvars"), - builder.Build()); -} - } namespace FVP_NS_DEF { @@ -187,11 +135,6 @@ void GeomSubsetWhSi::ProcessDirtiedPrims( if (_primPathsToSelections.find(entry.primPath) != _primPathsToSelections.end()) { auto selectionPath = SelectionPathFromKey(SelectionKey(entry.primPath, "")); auto originalMeshPath = entry.primPath.GetParentPath(); - //std::cout << originalMeshPath << std::endl; - //TODO: Need to store and keep track/update mapping of material paths and geomsubsets associations - // to catch material dirty notifs and dirty points primvarValue - //auto dirtyLocators = entry.dirtyLocators; - //if (dirtyLocators.Intersects(HdMaterialSchema::GetDefaultLocator())) highlightEntries.emplace_back(originalMeshPath.ReplacePrefix(originalMeshPath.GetParentPath(), selectionPath), entry.dirtyLocators); } } From bb01e29a744c99d21761eeccb368a2bf3a4fa9ac Mon Sep 17 00:00:00 2001 From: debloip Date: Tue, 28 Jan 2025 09:47:11 -0500 Subject: [PATCH 07/21] HYDRA-1286 : Handle scaling --- .../wireframeHighlights/fvpBaseWhSi.cpp | 58 +++++++++++++++++-- .../wireframeHighlights/fvpBaseWhSi.h | 2 + 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index d65e5e56b..8dd0e2801 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -17,7 +17,9 @@ #include +#include #include +#include #include #include #include @@ -42,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -552,10 +555,50 @@ PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerD // Apply displaced points HdContainerDataSourceEditor dataSourceEditor(meshRootDataSource); - dataSourceEditor.Set(pointsValueLocator, HdRetainedTypedSampledDataSource>::New(points)); + dataSourceEditor.Set(pointsValueLocator, HdRetainedTypedSampledDataSource>::New(points)); return dataSourceEditor.Finish(); } +PXR_NS::HdContainerDataSourceHandle ForceScale(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource) +{ + auto xformSchema = HdXformSchema::GetFromParent(meshRootDataSource); + if (!xformSchema.IsDefined() || !xformSchema.GetMatrix()) { + return meshRootDataSource; + } + GfMatrix4d xformMatrix = xformSchema.GetMatrix()->GetTypedValue(0); + + HdContainerDataSourceEditor dataSourceEditor(meshRootDataSource); + + // Scale points + auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, pointsValueLocator)); + if (pointsValueDataSource) { + auto points = pointsValueDataSource->GetTypedValue(0); + for (size_t iPoint = 0; iPoint < points.size(); iPoint++) { + points[iPoint] = GfVec3f(xformMatrix.Transform(points[iPoint])); + } + dataSourceEditor.Set(pointsValueLocator, HdRetainedTypedSampledDataSource>::New(points)); + } + + // Scale normals + auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, normalsValueLocator)); + if (normalsValueDataSource) { + auto normals = normalsValueDataSource->GetTypedValue(0); + for (size_t iNormal = 0; iNormal < normals.size(); iNormal++) { + normals[iNormal] = GfVec3f(xformMatrix.GetInverse().GetTranspose().TransformDir(normals[iNormal])); + normals[iNormal].Normalize(); + } + dataSourceEditor.Set(normalsValueLocator, HdRetainedTypedSampledDataSource>::New(normals)); + } + + // Prevent further scaling by setting the xform to the identity + dataSourceEditor.Set(HdXformSchema::GetDefaultLocator(), + HdXformSchema::Builder() + .SetMatrix(HdRetainedTypedSampledDataSource::New(GfMatrix4d(1))) + .SetResetXformStack(HdRetainedTypedSampledDataSource::New(true)) + .Build() + ); + return dataSourceEditor.Finish(); +} SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSource) { @@ -1023,14 +1066,17 @@ BaseWhSi::MakeGeomSubsetHighlight( { HdContainerDataSourceHandle editedMeshRootDataSource = meshRootDataSource; - // Compute the normals and then trim the mesh - // (normals must be computed before trimming so that they follow the original mesh's topology) + // Manually apply the displacement on the mesh. We need to do this before trimming the mesh; + // otherwise Storm will compute normals and displacement based on the trimmed mesh, which gives + // incorrect results. Providing the normals primvar is not sufficient to fix this, so we must + // do everything manually, including scaling. editedMeshRootDataSource = ComputeNormals(editedMeshRootDataSource); - editedMeshRootDataSource = TrimMeshForGeomSubset(editedMeshRootDataSource, geomSubsetRootDataSource); - - // Force the displacement + editedMeshRootDataSource = ForceScale(editedMeshRootDataSource); editedMeshRootDataSource = ForceDisplacement(editedMeshRootDataSource, GetMaterialDisplacementValue(geomSubsetRootDataSource)); + // Trim the displaced mesh + editedMeshRootDataSource = TrimMeshForGeomSubset(editedMeshRootDataSource, geomSubsetRootDataSource); + // Setup the dependency so that material updates also dirty the points & normals primvars, // and then block materials to prevent them from re-applying displacement // (the dependency must be added before we block the materials, otherwise we can't know which material was assigned to the geomSubset) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h index 7c2a71bd0..96a3547af 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h @@ -251,6 +251,8 @@ PXR_NS::HdContainerDataSourceHandle ComputeNormals(const PXR_NS::HdContainerData PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, float displacement); +PXR_NS::HdContainerDataSourceHandle ForceScale(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource); + PXR_NS::SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSource); PXR_NS::HdContainerDataSourceHandle BlockMaterials(const PXR_NS::HdContainerDataSourceHandle& primDataSource); From 9fe659fb93ac015a4aa2dd30d6aef4b5d690d123 Mon Sep 17 00:00:00 2001 From: debloip Date: Tue, 28 Jan 2025 10:25:42 -0500 Subject: [PATCH 08/21] HYDRA-1286 : Cleanup --- .../wireframeHighlights/fvpBaseWhSi.cpp | 78 +++++++++---------- .../wireframeHighlights/fvpBaseWhSi.h | 26 +++++-- 2 files changed, 55 insertions(+), 49 deletions(-) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index 8dd0e2801..a4e393e9b 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -469,7 +469,7 @@ TrimMeshForGeomSubset(const HdContainerDataSourceHandle& meshRootDataSource, con } #endif -PXR_NS::HdContainerDataSourceHandle ComputeNormals(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource) +PXR_NS::HdContainerDataSourceHandle ComputeSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource) { // Check if normals are already present auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, normalsValueLocator)); @@ -556,6 +556,11 @@ PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerD // Apply displaced points HdContainerDataSourceEditor dataSourceEditor(meshRootDataSource); dataSourceEditor.Set(pointsValueLocator, HdRetainedTypedSampledDataSource>::New(points)); + + // Block materials to prevent displacement from being re-applied + dataSourceEditor.Set(HdMaterialBindingsSchema::GetDefaultLocator(), HdBlockDataSource::New()); + dataSourceEditor.Set(UsdImagingDirectMaterialBindingsSchema::GetDefaultLocator(), HdBlockDataSource::New()); + return dataSourceEditor.Finish(); } @@ -589,14 +594,10 @@ PXR_NS::HdContainerDataSourceHandle ForceScale(const PXR_NS::HdContainerDataSour } dataSourceEditor.Set(normalsValueLocator, HdRetainedTypedSampledDataSource>::New(normals)); } - - // Prevent further scaling by setting the xform to the identity - dataSourceEditor.Set(HdXformSchema::GetDefaultLocator(), - HdXformSchema::Builder() - .SetMatrix(HdRetainedTypedSampledDataSource::New(GfMatrix4d(1))) - .SetResetXformStack(HdRetainedTypedSampledDataSource::New(true)) - .Build() - ); + + // Set xform to the identity to prevent scaling from being re-applied + dataSourceEditor.Set(HdXformSchema::GetDefaultLocator().Append(HdXformSchemaTokens->matrix), HdRetainedTypedSampledDataSource::New(GfMatrix4d(1))); + return dataSourceEditor.Finish(); } @@ -624,14 +625,6 @@ SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSourc return bindingPathDataSource->GetTypedValue(0); } -PXR_NS::HdContainerDataSourceHandle BlockMaterials(const PXR_NS::HdContainerDataSourceHandle& primDataSource) -{ - HdContainerDataSourceEditor dataSourceEditor(primDataSource); - dataSourceEditor.Set(HdMaterialBindingsSchema::GetDefaultLocator(), HdBlockDataSource::New()); - dataSourceEditor.Set(UsdImagingDirectMaterialBindingsSchema::GetDefaultLocator(), HdBlockDataSource::New()); - return dataSourceEditor.Finish(); -} - PXR_NS::HdContainerDataSourceHandle AddDependency( const PXR_NS::HdContainerDataSourceHandle& primDataSource, const PXR_NS::TfToken& dependencyToken, @@ -1019,30 +1012,28 @@ BaseWhSi::CollectInstancingPaths(const PXR_NS::SdfPath& primPath, InstancingPath } } -float +VtValue BaseWhSi::GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle& primDataSource) const { - float displacementValue = 0.f; - if (!primDataSource) { - return displacementValue; + return {}; } // Step 1: Get the material path const SdfPath materialPath = GetMaterialPath(primDataSource); if (materialPath.IsEmpty()) { - return displacementValue; + return {}; } // Step 2: Retrieve the material HdSceneIndexPrim materialPrim = GetInputSceneIndex()->GetPrim(materialPath); if (!materialPrim.dataSource || (materialPrim.primType != HdPrimTypeTokens->material) ){ - return displacementValue; + return {}; } HdMaterialSchema materialSchema = HdMaterialSchema::GetFromParent(materialPrim.dataSource); if (!materialSchema.IsDefined()) { - return displacementValue; + return {}; } // Step 3: Look for the displacement value @@ -1052,11 +1043,11 @@ BaseWhSi::GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle for (auto nodeName : materialNetworkInterface.GetNodeNames()) { VtValue paramValue = materialNetworkInterface.GetNodeParameterValue(nodeName, HdMaterialTerminalTokens->displacement); if (paramValue.IsHolding()) { - return paramValue.UncheckedGet(); + return paramValue; } } - return displacementValue; + return {}; } PXR_NS::HdContainerDataSourceHandle @@ -1066,23 +1057,28 @@ BaseWhSi::MakeGeomSubsetHighlight( { HdContainerDataSourceHandle editedMeshRootDataSource = meshRootDataSource; - // Manually apply the displacement on the mesh. We need to do this before trimming the mesh; - // otherwise Storm will compute normals and displacement based on the trimmed mesh, which gives - // incorrect results. Providing the normals primvar is not sufficient to fix this, so we must - // do everything manually, including scaling. - editedMeshRootDataSource = ComputeNormals(editedMeshRootDataSource); - editedMeshRootDataSource = ForceScale(editedMeshRootDataSource); - editedMeshRootDataSource = ForceDisplacement(editedMeshRootDataSource, GetMaterialDisplacementValue(geomSubsetRootDataSource)); - - // Trim the displaced mesh + VtValue displacementValue = GetMaterialDisplacementValue(geomSubsetRootDataSource); + if (displacementValue.IsHolding()) { + // Manually apply the displacement on the mesh. We need to do this before trimming the mesh; + // otherwise Storm will compute normals and displacement based on the trimmed mesh, which gives + // incorrect results. Providing the normals primvar is not sufficient to fix this, so we must + // do everything manually, including scaling. + editedMeshRootDataSource = ComputeSmoothNormals(editedMeshRootDataSource); + editedMeshRootDataSource = ForceScale(editedMeshRootDataSource); + editedMeshRootDataSource = ForceDisplacement(editedMeshRootDataSource, displacementValue.UncheckedGet()); + + // Setup a dependency so that material updates dirty the points & normals primvars + editedMeshRootDataSource = AddDependency( + editedMeshRootDataSource, + TfToken("Fvp_WhSi_MaterialToPrimvars"), + GetMaterialPath(geomSubsetRootDataSource), + HdMaterialSchema::GetDefaultLocator(), + HdPrimvarsSchema::GetDefaultLocator()); + } + + // Trim the mesh to fit the geomSubset editedMeshRootDataSource = TrimMeshForGeomSubset(editedMeshRootDataSource, geomSubsetRootDataSource); - // Setup the dependency so that material updates also dirty the points & normals primvars, - // and then block materials to prevent them from re-applying displacement - // (the dependency must be added before we block the materials, otherwise we can't know which material was assigned to the geomSubset) - editedMeshRootDataSource = AddDependency(editedMeshRootDataSource, TfToken("Fvp_WhSi_MaterialToPrimvars"), GetMaterialPath(geomSubsetRootDataSource), HdMaterialSchema::GetDefaultLocator(), HdPrimvarsSchema::GetDefaultLocator()); - editedMeshRootDataSource = BlockMaterials(editedMeshRootDataSource); - return editedMeshRootDataSource; } diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h index 96a3547af..47fe11628 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -219,7 +220,7 @@ class BaseWhSi // Return the displacement value from the given prim data source's assigned material FVP_API - float GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle& primDataSource) const; + PXR_NS::VtValue GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle& primDataSource) const; // Given a mesh and geomSubset data sources, edits and returns the mesh data source to fit the given geomSubset FVP_API @@ -241,22 +242,32 @@ class BaseWhSi // Make the given prim be drawn as a wireframe of the given color. PXR_NS::HdContainerDataSourceHandle SetWireframeRepr(const PXR_NS::HdContainerDataSourceHandle& dataSource, const PXR_NS::GfVec4f& color); +// Repath instancing-related data sources by replacing srcPrefix with dstPrefix. +// Mainly used to setup selection highlight instancers and instances. +PXR_NS::HdContainerDataSourceHandle RepathInstancingDataSources( + const PXR_NS::HdContainerDataSourceHandle& primDataSource, + const PXR_NS::SdfPath& srcPrefix, + const PXR_NS::SdfPath& dstPrefix); + #if PXR_VERSION >= 2403 // Edit the given mesh data source such that its topology matches the given geomSubset. PXR_NS::HdContainerDataSourceHandle TrimMeshForGeomSubset(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, const PXR_NS::HdContainerDataSourceHandle& geomSubsetRootDataSource); #endif -PXR_NS::HdContainerDataSourceHandle ComputeNormals(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource); +// Get the path to the prim's bound material. +PXR_NS::SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSource); -PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, float displacement); +// Computes and adds the normals primvar with smooth normals. If normals are already present, does nothing. +PXR_NS::HdContainerDataSourceHandle ComputeSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource); +// Manually apply scaling on the prim. PXR_NS::HdContainerDataSourceHandle ForceScale(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource); -PXR_NS::SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSource); - -PXR_NS::HdContainerDataSourceHandle BlockMaterials(const PXR_NS::HdContainerDataSourceHandle& primDataSource); +// Manually apply displacement on the prim. +PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, float displacement); +// Add an entry to the __dependencies data source PXR_NS::HdContainerDataSourceHandle AddDependency( const PXR_NS::HdContainerDataSourceHandle& primDataSource, const PXR_NS::TfToken& dependencyToken, @@ -264,8 +275,7 @@ PXR_NS::HdContainerDataSourceHandle AddDependency( const PXR_NS::HdDataSourceLocator& dependedOnDataSourceLocator, const PXR_NS::HdDataSourceLocator& affectedDataSourceLocator); -PXR_NS::HdContainerDataSourceHandle RepathInstancingDataSources(const PXR_NS::HdContainerDataSourceHandle& primDataSource, const PXR_NS::SdfPath& srcPrefix, const PXR_NS::SdfPath& dstPrefix); - +// Return a Fvp::PrimSelection equivalent to the given Hydra selection Fvp::PrimSelection ConvertHydraToFvpSelection(const PXR_NS::SdfPath& primPath, const PXR_NS::HdSelectionSchema& selectionSchema); } From 4e65cdcbd5b26e0d40391dd099570fd1a87a1ee8 Mon Sep 17 00:00:00 2001 From: debloip Date: Tue, 28 Jan 2025 10:33:06 -0500 Subject: [PATCH 09/21] HYDRA-1286 : Re-order methods --- .../wireframeHighlights/fvpBaseWhSi.cpp | 233 +++++++++--------- .../wireframeHighlights/fvpBaseWhSi.h | 12 +- 2 files changed, 122 insertions(+), 123 deletions(-) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index a4e393e9b..a5b541707 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -461,6 +461,96 @@ HdContainerDataSourceHandle SetWireframeRepr(const HdContainerDataSourceHandle& return edited.Finish(); } +Fvp::PrimSelection ConvertHydraToFvpSelection(const SdfPath& primPath, const HdSelectionSchema& selectionSchema) { + Fvp::PrimSelection primSelection; + primSelection.primPath = primPath; + + auto nestedInstanceIndicesSchema = +#if HD_API_VERSION < 66 + const_cast(selectionSchema).GetNestedInstanceIndices(); +#else + selectionSchema.GetNestedInstanceIndices(); +#endif + for (size_t iNestedInstanceIndices = 0; iNestedInstanceIndices < nestedInstanceIndicesSchema.GetNumElements(); iNestedInstanceIndices++) { + HdInstanceIndicesSchema instanceIndicesSchema = nestedInstanceIndicesSchema.GetElement(iNestedInstanceIndices); + auto instanceIndices = instanceIndicesSchema.GetInstanceIndices()->GetTypedValue(0); + primSelection.nestedInstanceIndices.push_back( + { + instanceIndicesSchema.GetInstancer()->GetTypedValue(0), + instanceIndicesSchema.GetPrototypeIndex()->GetTypedValue(0), + std::vector(instanceIndices.begin(), instanceIndices.end()) + } + ); + } + + return primSelection; +} + +PXR_NS::HdContainerDataSourceHandle RepathInstancingDataSources( + const PXR_NS::HdContainerDataSourceHandle& primDataSource, + const PXR_NS::SdfPath& srcPrefix, + const PXR_NS::SdfPath& dstPrefix) +{ + static const std::set kInstancingDataSourceLocators = { + HdInstancerTopologySchema::GetDefaultLocator(), + HdInstancedBySchema::GetDefaultLocator(), + HdInstanceSchema::GetDefaultLocator(), + UsdImagingUsdPrimInfoSchema::GetDefaultLocator().Append(UsdImagingUsdPrimInfoSchemaTokens->piPropagatedPrototypes), + UsdImagingUsdPrimInfoSchema::GetDefaultLocator().Append(UsdImagingUsdPrimInfoSchemaTokens->niPrototypePath), + }; + + HdContainerDataSourceEditor dataSourceEditor(primDataSource); + for (const auto& instancingDataSourceLocator : kInstancingDataSourceLocators) { + auto instancingDataSource = HdContainerDataSource::Get(primDataSource, instancingDataSourceLocator); + + if (auto containerDataSource = HdContainerDataSource::Cast(instancingDataSource)) { + dataSourceEditor.Set( + instancingDataSourceLocator, + RepathingContainerDataSource::New(srcPrefix, dstPrefix, containerDataSource) + ); + } + + if (auto pathDataSource = HdTypedSampledDataSource::Cast(instancingDataSource)) { + dataSourceEditor.Set( + instancingDataSourceLocator, + _RerootingSceneIndexPathDataSource::New(srcPrefix, dstPrefix, pathDataSource) + ); + } + + if (auto pathArrayDataSource = HdTypedSampledDataSource>::Cast(instancingDataSource)) { + dataSourceEditor.Set( + instancingDataSourceLocator, + _RerootingSceneIndexPathArrayDataSource::New(srcPrefix, dstPrefix, pathArrayDataSource) + ); + } + } + return dataSourceEditor.Finish(); +} + +SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSource) +{ + if (!primDataSource) { + return {}; + } + + HdMaterialBindingsSchema materialBindingsSchema = HdMaterialBindingsSchema::GetFromParent(primDataSource); + if (!materialBindingsSchema.IsDefined()) { + return {}; + } + + HdMaterialBindingSchema materialBindingSchema = materialBindingsSchema.GetMaterialBinding(); + if (!materialBindingSchema) { + return {}; + } + + HdPathDataSourceHandle bindingPathDataSource = materialBindingSchema.GetPath(); + if (!bindingPathDataSource) { + return {}; + } + + return bindingPathDataSource->GetTypedValue(0); +} + #if PXR_VERSION >= 2403 HdContainerDataSourceHandle TrimMeshForGeomSubset(const HdContainerDataSourceHandle& meshRootDataSource, const HdContainerDataSourceHandle& geomSubsetRootDataSource) @@ -519,48 +609,13 @@ PXR_NS::HdContainerDataSourceHandle ComputeSmoothNormals(const PXR_NS::HdContain &adjacency, static_cast(points.size()), points.cdata()); // Apply normals - auto normalsDataSource = HdPrimvarSchema::Builder() + auto normalsPrimvarDataSource = HdPrimvarSchema::Builder() .SetInterpolation(HdPrimvarSchema::BuildInterpolationDataSource(HdPrimvarSchemaTokens->vertex)) .SetRole(HdPrimvarSchema::BuildRoleDataSource(HdPrimvarSchemaTokens->normal)) .SetPrimvarValue(HdRetainedTypedSampledDataSource::New(normals)) .Build(); - HdDataSourceLocator normalsPrimvarLocator = HdDataSourceLocator(HdPrimvarsSchemaTokens->primvars, HdPrimvarsSchemaTokens->normals); - HdContainerDataSourceEditor dataSourceEditor(meshRootDataSource); - dataSourceEditor.Set(normalsPrimvarLocator, normalsDataSource); - return dataSourceEditor.Finish(); -} - -PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, float displacement) -{ - auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, pointsValueLocator)); - if (!pointsValueDataSource) { - return meshRootDataSource; - } - auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, normalsValueLocator)); - if (!normalsValueDataSource) { - return meshRootDataSource; - } - - auto points = pointsValueDataSource->GetTypedValue(0); - auto normals = normalsValueDataSource->GetTypedValue(0); - - if (points.size() > normals.size()) { - return meshRootDataSource; - } - - // Compute displacement - for (size_t iPoint = 0; iPoint < points.size(); iPoint++) { - points[iPoint] += normals[iPoint] * displacement; - } - - // Apply displaced points HdContainerDataSourceEditor dataSourceEditor(meshRootDataSource); - dataSourceEditor.Set(pointsValueLocator, HdRetainedTypedSampledDataSource>::New(points)); - - // Block materials to prevent displacement from being re-applied - dataSourceEditor.Set(HdMaterialBindingsSchema::GetDefaultLocator(), HdBlockDataSource::New()); - dataSourceEditor.Set(UsdImagingDirectMaterialBindingsSchema::GetDefaultLocator(), HdBlockDataSource::New()); - + dataSourceEditor.Set(normalsPrimvarLocator, normalsPrimvarDataSource); return dataSourceEditor.Finish(); } @@ -601,28 +656,38 @@ PXR_NS::HdContainerDataSourceHandle ForceScale(const PXR_NS::HdContainerDataSour return dataSourceEditor.Finish(); } -SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSource) +PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, float displacement) { - if (!primDataSource) { - return {}; + auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, pointsValueLocator)); + if (!pointsValueDataSource) { + return meshRootDataSource; } - - HdMaterialBindingsSchema materialBindingsSchema = HdMaterialBindingsSchema::GetFromParent(primDataSource); - if (!materialBindingsSchema.IsDefined()) { - return {}; + auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, normalsValueLocator)); + if (!normalsValueDataSource) { + return meshRootDataSource; } - HdMaterialBindingSchema materialBindingSchema = materialBindingsSchema.GetMaterialBinding(); - if (!materialBindingSchema) { - return {}; + auto points = pointsValueDataSource->GetTypedValue(0); + auto normals = normalsValueDataSource->GetTypedValue(0); + + if (points.size() > normals.size()) { + return meshRootDataSource; } - HdPathDataSourceHandle bindingPathDataSource = materialBindingSchema.GetPath(); - if (!bindingPathDataSource) { - return {}; + // Compute displacement + for (size_t iPoint = 0; iPoint < points.size(); iPoint++) { + points[iPoint] += normals[iPoint] * displacement; } - return bindingPathDataSource->GetTypedValue(0); + // Apply displaced points + HdContainerDataSourceEditor dataSourceEditor(meshRootDataSource); + dataSourceEditor.Set(pointsValueLocator, HdRetainedTypedSampledDataSource>::New(points)); + + // Block materials to prevent displacement from being re-applied + dataSourceEditor.Set(HdMaterialBindingsSchema::GetDefaultLocator(), HdBlockDataSource::New()); + dataSourceEditor.Set(UsdImagingDirectMaterialBindingsSchema::GetDefaultLocator(), HdBlockDataSource::New()); + + return dataSourceEditor.Finish(); } PXR_NS::HdContainerDataSourceHandle AddDependency( @@ -649,72 +714,6 @@ PXR_NS::HdContainerDataSourceHandle AddDependency( return dataSourceEditor.Finish(); } -PXR_NS::HdContainerDataSourceHandle RepathInstancingDataSources( - const PXR_NS::HdContainerDataSourceHandle& primDataSource, - const PXR_NS::SdfPath& srcPrefix, - const PXR_NS::SdfPath& dstPrefix) -{ - static const std::set kInstancingDataSourceLocators = { - HdInstancerTopologySchema::GetDefaultLocator(), - HdInstancedBySchema::GetDefaultLocator(), - HdInstanceSchema::GetDefaultLocator(), - UsdImagingUsdPrimInfoSchema::GetDefaultLocator().Append(UsdImagingUsdPrimInfoSchemaTokens->piPropagatedPrototypes), - UsdImagingUsdPrimInfoSchema::GetDefaultLocator().Append(UsdImagingUsdPrimInfoSchemaTokens->niPrototypePath), - }; - - HdContainerDataSourceEditor dataSourceEditor(primDataSource); - for (const auto& instancingDataSourceLocator : kInstancingDataSourceLocators) { - auto instancingDataSource = HdContainerDataSource::Get(primDataSource, instancingDataSourceLocator); - - if (auto containerDataSource = HdContainerDataSource::Cast(instancingDataSource)) { - dataSourceEditor.Set( - instancingDataSourceLocator, - RepathingContainerDataSource::New(srcPrefix, dstPrefix, containerDataSource) - ); - } - - if (auto pathDataSource = HdTypedSampledDataSource::Cast(instancingDataSource)) { - dataSourceEditor.Set( - instancingDataSourceLocator, - _RerootingSceneIndexPathDataSource::New(srcPrefix, dstPrefix, pathDataSource) - ); - } - - if (auto pathArrayDataSource = HdTypedSampledDataSource>::Cast(instancingDataSource)) { - dataSourceEditor.Set( - instancingDataSourceLocator, - _RerootingSceneIndexPathArrayDataSource::New(srcPrefix, dstPrefix, pathArrayDataSource) - ); - } - } - return dataSourceEditor.Finish(); -} - -Fvp::PrimSelection ConvertHydraToFvpSelection(const SdfPath& primPath, const HdSelectionSchema& selectionSchema) { - Fvp::PrimSelection primSelection; - primSelection.primPath = primPath; - - auto nestedInstanceIndicesSchema = -#if HD_API_VERSION < 66 - const_cast(selectionSchema).GetNestedInstanceIndices(); -#else - selectionSchema.GetNestedInstanceIndices(); -#endif - for (size_t iNestedInstanceIndices = 0; iNestedInstanceIndices < nestedInstanceIndicesSchema.GetNumElements(); iNestedInstanceIndices++) { - HdInstanceIndicesSchema instanceIndicesSchema = nestedInstanceIndicesSchema.GetElement(iNestedInstanceIndices); - auto instanceIndices = instanceIndicesSchema.GetInstanceIndices()->GetTypedValue(0); - primSelection.nestedInstanceIndices.push_back( - { - instanceIndicesSchema.GetInstancer()->GetTypedValue(0), - instanceIndicesSchema.GetPrototypeIndex()->GetTypedValue(0), - std::vector(instanceIndices.begin(), instanceIndices.end()) - } - ); - } - - return primSelection; -} - BaseWhSi::BaseWhSi( const PXR_NS::HdSceneIndexBaseRefPtr& inputSceneIndex, const PXR_NS::SdfPath& highlightHierarchyPrefix, diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h index 47fe11628..94d5ccf72 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h @@ -242,6 +242,9 @@ class BaseWhSi // Make the given prim be drawn as a wireframe of the given color. PXR_NS::HdContainerDataSourceHandle SetWireframeRepr(const PXR_NS::HdContainerDataSourceHandle& dataSource, const PXR_NS::GfVec4f& color); +// Return a Fvp::PrimSelection equivalent to the given Hydra selection +Fvp::PrimSelection ConvertHydraToFvpSelection(const PXR_NS::SdfPath& primPath, const PXR_NS::HdSelectionSchema& selectionSchema); + // Repath instancing-related data sources by replacing srcPrefix with dstPrefix. // Mainly used to setup selection highlight instancers and instances. PXR_NS::HdContainerDataSourceHandle RepathInstancingDataSources( @@ -249,15 +252,15 @@ PXR_NS::HdContainerDataSourceHandle RepathInstancingDataSources( const PXR_NS::SdfPath& srcPrefix, const PXR_NS::SdfPath& dstPrefix); +// Get the path to the prim's bound material. +PXR_NS::SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSource); + #if PXR_VERSION >= 2403 // Edit the given mesh data source such that its topology matches the given geomSubset. PXR_NS::HdContainerDataSourceHandle TrimMeshForGeomSubset(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, const PXR_NS::HdContainerDataSourceHandle& geomSubsetRootDataSource); #endif -// Get the path to the prim's bound material. -PXR_NS::SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSource); - // Computes and adds the normals primvar with smooth normals. If normals are already present, does nothing. PXR_NS::HdContainerDataSourceHandle ComputeSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource); @@ -275,9 +278,6 @@ PXR_NS::HdContainerDataSourceHandle AddDependency( const PXR_NS::HdDataSourceLocator& dependedOnDataSourceLocator, const PXR_NS::HdDataSourceLocator& affectedDataSourceLocator); -// Return a Fvp::PrimSelection equivalent to the given Hydra selection -Fvp::PrimSelection ConvertHydraToFvpSelection(const PXR_NS::SdfPath& primPath, const PXR_NS::HdSelectionSchema& selectionSchema); - } #endif // FVP_BASE_WH_SI_H From c7a566394adbd73d932543ddc2b66734ec7b84d4 Mon Sep 17 00:00:00 2001 From: debloip Date: Tue, 28 Jan 2025 10:34:13 -0500 Subject: [PATCH 10/21] HYDRA-1286 : Move TrimMeshForGeomSubset to FVP namespace --- .../wireframeHighlights/fvpBaseWhSi.cpp | 164 ++++++++---------- 1 file changed, 77 insertions(+), 87 deletions(-) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index a5b541707..4e3cdb167 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -296,92 +296,6 @@ class _RerootingSceneIndexPathArrayDataSource : public HdPathArrayDataSource HdPathArrayDataSourceHandle const _inputDataSource; }; -//TODO :: Move to FVP namespace -#if PXR_VERSION >= 2403 -// Edits the mesh topology to only only contain its selected GeomSubsets -HdContainerDataSourceHandle -_TrimMeshForGeomSubset(const HdContainerDataSourceHandle& meshRootDataSource, const HdContainerDataSourceHandle& geomSubsetRootDataSource) -{ - HdMeshSchema meshSchema = HdMeshSchema::GetFromParent(meshRootDataSource); - if (!meshSchema.IsDefined()) { - return meshRootDataSource; - } - HdMeshTopologySchema meshTopologySchema = meshSchema.GetTopology(); - if (!meshTopologySchema.IsDefined()) { - return meshRootDataSource; - } - auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, pointsValueLocator)); - if (!pointsValueDataSource) { - return meshRootDataSource; - } - - // Collect faces to keep based on the GeomSubset - std::unordered_set faceIndicesToKeep; - #if HD_API_VERSION >= 71 // USD 24.08+ - HdGeomSubsetSchema geomSubsetSchema = HdGeomSubsetSchema::GetFromParent(geomSubsetRootDataSource); - #else - HdGeomSubsetSchema geomSubsetSchema = HdGeomSubsetSchema(geomSubsetRootDataSource); - #endif - if (!geomSubsetSchema.IsDefined() || geomSubsetSchema.GetType()->GetTypedValue(0) != HdGeomSubsetSchemaTokens->typeFaceSet) { - return meshRootDataSource; - } - VtArray faceIndices = geomSubsetSchema.GetIndices()->GetTypedValue(0); - for (const auto& faceIndex : faceIndices) { - faceIndicesToKeep.insert(faceIndex); - } - if (faceIndicesToKeep.empty()) { - return meshRootDataSource; - } - - // Edit the mesh topology - HdContainerDataSourceEditor dataSourceEditor = HdContainerDataSourceEditor(meshRootDataSource); - VtArray originalFaceVertexCounts = meshTopologySchema.GetFaceVertexCounts()->GetTypedValue(0); - VtArray originalFaceVertexIndices = meshTopologySchema.GetFaceVertexIndices()->GetTypedValue(0); - VtArray trimmedFaceVertexCounts; - VtArray trimmedFaceVertexIndices; - int maxVertexIndex = 0; - size_t iFaceCounts = 0; - size_t iFaceIndices = 0; - while (iFaceCounts < originalFaceVertexCounts.size() && iFaceIndices < originalFaceVertexIndices.size()) { - int currFaceCount = originalFaceVertexCounts[iFaceCounts]; - - if (faceIndicesToKeep.find(iFaceCounts) != faceIndicesToKeep.end()) { - trimmedFaceVertexCounts.push_back(currFaceCount); - for (int faceIndicesOffset = 0; faceIndicesOffset < currFaceCount; faceIndicesOffset++) { - int vertexIndex = originalFaceVertexIndices[iFaceIndices + faceIndicesOffset]; - trimmedFaceVertexIndices.push_back(vertexIndex); - if (vertexIndex > maxVertexIndex) { - maxVertexIndex = vertexIndex; - } - } - } - - iFaceCounts++; - iFaceIndices += currFaceCount; - } - auto faceVertexCountsLocator = HdMeshTopologySchema::GetDefaultLocator().Append(HdMeshTopologySchemaTokens->faceVertexCounts); - auto faceVertexIndicesLocator = HdMeshTopologySchema::GetDefaultLocator().Append(HdMeshTopologySchemaTokens->faceVertexIndices); - - dataSourceEditor.Set(faceVertexCountsLocator, HdRetainedTypedSampledDataSource::New(trimmedFaceVertexCounts)); - dataSourceEditor.Set(faceVertexIndicesLocator, HdRetainedTypedSampledDataSource::New(trimmedFaceVertexIndices)); - - // We reduce the points and normals primvars so that they have only the exact number of elements required by the trimmed topology; - // this avoids a warning from USD. - VtArray points = pointsValueDataSource->GetTypedValue(0); - points.resize(maxVertexIndex + 1); - dataSourceEditor.Set(pointsValueLocator, HdRetainedTypedSampledDataSource>::New(points)); - - auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, normalsValueLocator)); - if (normalsValueDataSource) { - auto normals = normalsValueDataSource->GetTypedValue(0); - normals.resize(maxVertexIndex + 1); - dataSourceEditor.Set(normalsValueLocator, HdRetainedTypedSampledDataSource>::New(normals)); - } - - return dataSourceEditor.Finish(); -} -#endif - } namespace FVP_NS_DEF { @@ -555,7 +469,83 @@ SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSourc HdContainerDataSourceHandle TrimMeshForGeomSubset(const HdContainerDataSourceHandle& meshRootDataSource, const HdContainerDataSourceHandle& geomSubsetRootDataSource) { - return _TrimMeshForGeomSubset(meshRootDataSource, geomSubsetRootDataSource); + HdMeshSchema meshSchema = HdMeshSchema::GetFromParent(meshRootDataSource); + if (!meshSchema.IsDefined()) { + return meshRootDataSource; + } + HdMeshTopologySchema meshTopologySchema = meshSchema.GetTopology(); + if (!meshTopologySchema.IsDefined()) { + return meshRootDataSource; + } + auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, pointsValueLocator)); + if (!pointsValueDataSource) { + return meshRootDataSource; + } + + // Collect faces to keep based on the GeomSubset + std::unordered_set faceIndicesToKeep; + #if HD_API_VERSION >= 71 // USD 24.08+ + HdGeomSubsetSchema geomSubsetSchema = HdGeomSubsetSchema::GetFromParent(geomSubsetRootDataSource); + #else + HdGeomSubsetSchema geomSubsetSchema = HdGeomSubsetSchema(geomSubsetRootDataSource); + #endif + if (!geomSubsetSchema.IsDefined() || geomSubsetSchema.GetType()->GetTypedValue(0) != HdGeomSubsetSchemaTokens->typeFaceSet) { + return meshRootDataSource; + } + VtArray faceIndices = geomSubsetSchema.GetIndices()->GetTypedValue(0); + for (const auto& faceIndex : faceIndices) { + faceIndicesToKeep.insert(faceIndex); + } + if (faceIndicesToKeep.empty()) { + return meshRootDataSource; + } + + // Edit the mesh topology + HdContainerDataSourceEditor dataSourceEditor = HdContainerDataSourceEditor(meshRootDataSource); + VtArray originalFaceVertexCounts = meshTopologySchema.GetFaceVertexCounts()->GetTypedValue(0); + VtArray originalFaceVertexIndices = meshTopologySchema.GetFaceVertexIndices()->GetTypedValue(0); + VtArray trimmedFaceVertexCounts; + VtArray trimmedFaceVertexIndices; + int maxVertexIndex = 0; + size_t iFaceCounts = 0; + size_t iFaceIndices = 0; + while (iFaceCounts < originalFaceVertexCounts.size() && iFaceIndices < originalFaceVertexIndices.size()) { + int currFaceCount = originalFaceVertexCounts[iFaceCounts]; + + if (faceIndicesToKeep.find(iFaceCounts) != faceIndicesToKeep.end()) { + trimmedFaceVertexCounts.push_back(currFaceCount); + for (int faceIndicesOffset = 0; faceIndicesOffset < currFaceCount; faceIndicesOffset++) { + int vertexIndex = originalFaceVertexIndices[iFaceIndices + faceIndicesOffset]; + trimmedFaceVertexIndices.push_back(vertexIndex); + if (vertexIndex > maxVertexIndex) { + maxVertexIndex = vertexIndex; + } + } + } + + iFaceCounts++; + iFaceIndices += currFaceCount; + } + auto faceVertexCountsLocator = HdMeshTopologySchema::GetDefaultLocator().Append(HdMeshTopologySchemaTokens->faceVertexCounts); + auto faceVertexIndicesLocator = HdMeshTopologySchema::GetDefaultLocator().Append(HdMeshTopologySchemaTokens->faceVertexIndices); + + dataSourceEditor.Set(faceVertexCountsLocator, HdRetainedTypedSampledDataSource::New(trimmedFaceVertexCounts)); + dataSourceEditor.Set(faceVertexIndicesLocator, HdRetainedTypedSampledDataSource::New(trimmedFaceVertexIndices)); + + // We reduce the points and normals primvars so that they have only the exact number of elements required by the trimmed topology; + // this avoids a warning from USD. + VtArray points = pointsValueDataSource->GetTypedValue(0); + points.resize(maxVertexIndex + 1); + dataSourceEditor.Set(pointsValueLocator, HdRetainedTypedSampledDataSource>::New(points)); + + auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, normalsValueLocator)); + if (normalsValueDataSource) { + auto normals = normalsValueDataSource->GetTypedValue(0); + normals.resize(maxVertexIndex + 1); + dataSourceEditor.Set(normalsValueLocator, HdRetainedTypedSampledDataSource>::New(normals)); + } + + return dataSourceEditor.Finish(); } #endif From 9be90b253ccfc0e79ebc364a4a58dec75b237a5c Mon Sep 17 00:00:00 2001 From: debloip Date: Tue, 28 Jan 2025 10:43:17 -0500 Subject: [PATCH 11/21] HYDRA-1286 : Update variable names --- .../wireframeHighlights/fvpBaseWhSi.cpp | 92 +++++++++---------- .../wireframeHighlights/fvpBaseWhSi.h | 12 +-- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index 4e3cdb167..de345d23a 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -467,41 +467,41 @@ SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSourc #if PXR_VERSION >= 2403 HdContainerDataSourceHandle -TrimMeshForGeomSubset(const HdContainerDataSourceHandle& meshRootDataSource, const HdContainerDataSourceHandle& geomSubsetRootDataSource) +TrimMeshForGeomSubset(const HdContainerDataSourceHandle& meshPrimDataSource, const HdContainerDataSourceHandle& geomSubsetPrimDataSource) { - HdMeshSchema meshSchema = HdMeshSchema::GetFromParent(meshRootDataSource); + HdMeshSchema meshSchema = HdMeshSchema::GetFromParent(meshPrimDataSource); if (!meshSchema.IsDefined()) { - return meshRootDataSource; + return meshPrimDataSource; } HdMeshTopologySchema meshTopologySchema = meshSchema.GetTopology(); if (!meshTopologySchema.IsDefined()) { - return meshRootDataSource; + return meshPrimDataSource; } - auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, pointsValueLocator)); + auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshPrimDataSource, pointsValueLocator)); if (!pointsValueDataSource) { - return meshRootDataSource; + return meshPrimDataSource; } // Collect faces to keep based on the GeomSubset std::unordered_set faceIndicesToKeep; #if HD_API_VERSION >= 71 // USD 24.08+ - HdGeomSubsetSchema geomSubsetSchema = HdGeomSubsetSchema::GetFromParent(geomSubsetRootDataSource); + HdGeomSubsetSchema geomSubsetSchema = HdGeomSubsetSchema::GetFromParent(geomSubsetPrimDataSource); #else - HdGeomSubsetSchema geomSubsetSchema = HdGeomSubsetSchema(geomSubsetRootDataSource); + HdGeomSubsetSchema geomSubsetSchema = HdGeomSubsetSchema(geomSubsetPrimDataSource); #endif if (!geomSubsetSchema.IsDefined() || geomSubsetSchema.GetType()->GetTypedValue(0) != HdGeomSubsetSchemaTokens->typeFaceSet) { - return meshRootDataSource; + return meshPrimDataSource; } VtArray faceIndices = geomSubsetSchema.GetIndices()->GetTypedValue(0); for (const auto& faceIndex : faceIndices) { faceIndicesToKeep.insert(faceIndex); } if (faceIndicesToKeep.empty()) { - return meshRootDataSource; + return meshPrimDataSource; } // Edit the mesh topology - HdContainerDataSourceEditor dataSourceEditor = HdContainerDataSourceEditor(meshRootDataSource); + HdContainerDataSourceEditor dataSourceEditor = HdContainerDataSourceEditor(meshPrimDataSource); VtArray originalFaceVertexCounts = meshTopologySchema.GetFaceVertexCounts()->GetTypedValue(0); VtArray originalFaceVertexIndices = meshTopologySchema.GetFaceVertexIndices()->GetTypedValue(0); VtArray trimmedFaceVertexCounts; @@ -538,7 +538,7 @@ TrimMeshForGeomSubset(const HdContainerDataSourceHandle& meshRootDataSource, con points.resize(maxVertexIndex + 1); dataSourceEditor.Set(pointsValueLocator, HdRetainedTypedSampledDataSource>::New(points)); - auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, normalsValueLocator)); + auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshPrimDataSource, normalsValueLocator)); if (normalsValueDataSource) { auto normals = normalsValueDataSource->GetTypedValue(0); normals.resize(maxVertexIndex + 1); @@ -549,26 +549,26 @@ TrimMeshForGeomSubset(const HdContainerDataSourceHandle& meshRootDataSource, con } #endif -PXR_NS::HdContainerDataSourceHandle ComputeSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource) +PXR_NS::HdContainerDataSourceHandle ComputeSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource) { // Check if normals are already present - auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, normalsValueLocator)); + auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshPrimDataSource, normalsValueLocator)); if (normalsValueDataSource) { - return meshRootDataSource; + return meshPrimDataSource; } // Get required schemas/dataSources - HdMeshSchema meshSchema = HdMeshSchema::GetFromParent(meshRootDataSource); + HdMeshSchema meshSchema = HdMeshSchema::GetFromParent(meshPrimDataSource); if (!meshSchema.IsDefined()) { - return meshRootDataSource; + return meshPrimDataSource; } HdMeshTopologySchema meshTopologySchema = meshSchema.GetTopology(); if (!meshTopologySchema.IsDefined()) { - return meshRootDataSource; + return meshPrimDataSource; } - auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, pointsValueLocator)); + auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshPrimDataSource, pointsValueLocator)); if (!pointsValueDataSource) { - return meshRootDataSource; + return meshPrimDataSource; } // Setup topology @@ -604,23 +604,23 @@ PXR_NS::HdContainerDataSourceHandle ComputeSmoothNormals(const PXR_NS::HdContain .SetRole(HdPrimvarSchema::BuildRoleDataSource(HdPrimvarSchemaTokens->normal)) .SetPrimvarValue(HdRetainedTypedSampledDataSource::New(normals)) .Build(); - HdContainerDataSourceEditor dataSourceEditor(meshRootDataSource); + HdContainerDataSourceEditor dataSourceEditor(meshPrimDataSource); dataSourceEditor.Set(normalsPrimvarLocator, normalsPrimvarDataSource); return dataSourceEditor.Finish(); } -PXR_NS::HdContainerDataSourceHandle ForceScale(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource) +PXR_NS::HdContainerDataSourceHandle ForceScale(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource) { - auto xformSchema = HdXformSchema::GetFromParent(meshRootDataSource); + auto xformSchema = HdXformSchema::GetFromParent(meshPrimDataSource); if (!xformSchema.IsDefined() || !xformSchema.GetMatrix()) { - return meshRootDataSource; + return meshPrimDataSource; } GfMatrix4d xformMatrix = xformSchema.GetMatrix()->GetTypedValue(0); - HdContainerDataSourceEditor dataSourceEditor(meshRootDataSource); + HdContainerDataSourceEditor dataSourceEditor(meshPrimDataSource); // Scale points - auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, pointsValueLocator)); + auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshPrimDataSource, pointsValueLocator)); if (pointsValueDataSource) { auto points = pointsValueDataSource->GetTypedValue(0); for (size_t iPoint = 0; iPoint < points.size(); iPoint++) { @@ -630,7 +630,7 @@ PXR_NS::HdContainerDataSourceHandle ForceScale(const PXR_NS::HdContainerDataSour } // Scale normals - auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, normalsValueLocator)); + auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshPrimDataSource, normalsValueLocator)); if (normalsValueDataSource) { auto normals = normalsValueDataSource->GetTypedValue(0); for (size_t iNormal = 0; iNormal < normals.size(); iNormal++) { @@ -646,22 +646,22 @@ PXR_NS::HdContainerDataSourceHandle ForceScale(const PXR_NS::HdContainerDataSour return dataSourceEditor.Finish(); } -PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, float displacement) +PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource, float displacement) { - auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, pointsValueLocator)); + auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshPrimDataSource, pointsValueLocator)); if (!pointsValueDataSource) { - return meshRootDataSource; + return meshPrimDataSource; } - auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshRootDataSource, normalsValueLocator)); + auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshPrimDataSource, normalsValueLocator)); if (!normalsValueDataSource) { - return meshRootDataSource; + return meshPrimDataSource; } auto points = pointsValueDataSource->GetTypedValue(0); auto normals = normalsValueDataSource->GetTypedValue(0); if (points.size() > normals.size()) { - return meshRootDataSource; + return meshPrimDataSource; } // Compute displacement @@ -670,7 +670,7 @@ PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerD } // Apply displaced points - HdContainerDataSourceEditor dataSourceEditor(meshRootDataSource); + HdContainerDataSourceEditor dataSourceEditor(meshPrimDataSource); dataSourceEditor.Set(pointsValueLocator, HdRetainedTypedSampledDataSource>::New(points)); // Block materials to prevent displacement from being re-applied @@ -1041,34 +1041,34 @@ BaseWhSi::GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle PXR_NS::HdContainerDataSourceHandle BaseWhSi::MakeGeomSubsetHighlight( - const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, - const PXR_NS::HdContainerDataSourceHandle& geomSubsetRootDataSource) const + const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource, + const PXR_NS::HdContainerDataSourceHandle& geomSubsetPrimDataSource) const { - HdContainerDataSourceHandle editedMeshRootDataSource = meshRootDataSource; + HdContainerDataSourceHandle editedMeshPrimDataSource = meshPrimDataSource; - VtValue displacementValue = GetMaterialDisplacementValue(geomSubsetRootDataSource); + VtValue displacementValue = GetMaterialDisplacementValue(geomSubsetPrimDataSource); if (displacementValue.IsHolding()) { // Manually apply the displacement on the mesh. We need to do this before trimming the mesh; // otherwise Storm will compute normals and displacement based on the trimmed mesh, which gives // incorrect results. Providing the normals primvar is not sufficient to fix this, so we must // do everything manually, including scaling. - editedMeshRootDataSource = ComputeSmoothNormals(editedMeshRootDataSource); - editedMeshRootDataSource = ForceScale(editedMeshRootDataSource); - editedMeshRootDataSource = ForceDisplacement(editedMeshRootDataSource, displacementValue.UncheckedGet()); + editedMeshPrimDataSource = ComputeSmoothNormals(editedMeshPrimDataSource); + editedMeshPrimDataSource = ForceScale(editedMeshPrimDataSource); + editedMeshPrimDataSource = ForceDisplacement(editedMeshPrimDataSource, displacementValue.UncheckedGet()); // Setup a dependency so that material updates dirty the points & normals primvars - editedMeshRootDataSource = AddDependency( - editedMeshRootDataSource, + editedMeshPrimDataSource = AddDependency( + editedMeshPrimDataSource, TfToken("Fvp_WhSi_MaterialToPrimvars"), - GetMaterialPath(geomSubsetRootDataSource), + GetMaterialPath(geomSubsetPrimDataSource), HdMaterialSchema::GetDefaultLocator(), HdPrimvarsSchema::GetDefaultLocator()); } // Trim the mesh to fit the geomSubset - editedMeshRootDataSource = TrimMeshForGeomSubset(editedMeshRootDataSource, geomSubsetRootDataSource); + editedMeshPrimDataSource = TrimMeshForGeomSubset(editedMeshPrimDataSource, geomSubsetPrimDataSource); - return editedMeshRootDataSource; + return editedMeshPrimDataSource; } } diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h index 94d5ccf72..4a5dd7884 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h @@ -225,8 +225,8 @@ class BaseWhSi // Given a mesh and geomSubset data sources, edits and returns the mesh data source to fit the given geomSubset FVP_API PXR_NS::HdContainerDataSourceHandle MakeGeomSubsetHighlight( - const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, - const PXR_NS::HdContainerDataSourceHandle& geomSubsetRootDataSource) const; + const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource, + const PXR_NS::HdContainerDataSourceHandle& geomSubsetPrimDataSource) const; const PXR_NS::SdfPath _highlightHierarchyPrefix; const std::shared_ptr _wireframeColorInterface; @@ -258,17 +258,17 @@ PXR_NS::SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primD #if PXR_VERSION >= 2403 // Edit the given mesh data source such that its topology matches the given geomSubset. PXR_NS::HdContainerDataSourceHandle -TrimMeshForGeomSubset(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, const PXR_NS::HdContainerDataSourceHandle& geomSubsetRootDataSource); +TrimMeshForGeomSubset(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource, const PXR_NS::HdContainerDataSourceHandle& geomSubsetPrimDataSource); #endif // Computes and adds the normals primvar with smooth normals. If normals are already present, does nothing. -PXR_NS::HdContainerDataSourceHandle ComputeSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource); +PXR_NS::HdContainerDataSourceHandle ComputeSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource); // Manually apply scaling on the prim. -PXR_NS::HdContainerDataSourceHandle ForceScale(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource); +PXR_NS::HdContainerDataSourceHandle ForceScale(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource); // Manually apply displacement on the prim. -PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerDataSourceHandle& meshRootDataSource, float displacement); +PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource, float displacement); // Add an entry to the __dependencies data source PXR_NS::HdContainerDataSourceHandle AddDependency( From 32e8a2922abd24918ee28055c2150720e86ad1e4 Mon Sep 17 00:00:00 2001 From: debloip Date: Tue, 28 Jan 2025 10:48:41 -0500 Subject: [PATCH 12/21] HYDRA-1286 : Update tokens --- .../sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index de345d23a..eaf4be17c 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -54,11 +54,13 @@ PXR_NAMESPACE_USING_DIRECTIVE namespace { -//Handle primsvars:overrideWireframeColor in Storm for wireframe selection highlighting color TF_DEFINE_PRIVATE_TOKENS( - _primVarsTokens, - - (overrideWireframeColor) // Works in HdStorm to override the wireframe color + _tokens, + + // Handle primsvars:overrideWireframeColor in Storm for wireframe selection highlighting color + (overrideWireframeColor) // Works in HdStorm to override the wireframe color + + (fvpWhSiMaterialToPrimvars) ); const HdRetainedContainerDataSourceHandle refinedWireDisplayStyleDataSource @@ -74,7 +76,7 @@ const HdDataSourceLocator reprSelectorLocator( HdLegacyDisplayStyleSchemaTokens->reprSelector); const HdDataSourceLocator primvarsOverrideWireframeColorLocator( - HdPrimvarsSchema::GetDefaultLocator().Append(_primVarsTokens->overrideWireframeColor)); + HdPrimvarsSchema::GetDefaultLocator().Append(_tokens->overrideWireframeColor)); const HdDataSourceLocator pointsValueLocator = HdDataSourceLocator( HdPrimvarsSchemaTokens->primvars, @@ -1059,7 +1061,7 @@ BaseWhSi::MakeGeomSubsetHighlight( // Setup a dependency so that material updates dirty the points & normals primvars editedMeshPrimDataSource = AddDependency( editedMeshPrimDataSource, - TfToken("Fvp_WhSi_MaterialToPrimvars"), + _tokens->fvpWhSiMaterialToPrimvars, GetMaterialPath(geomSubsetPrimDataSource), HdMaterialSchema::GetDefaultLocator(), HdPrimvarsSchema::GetDefaultLocator()); From d2bf39100a5ea87262b8668ea6b406ac24e82dff Mon Sep 17 00:00:00 2001 From: debloip Date: Tue, 28 Jan 2025 10:51:25 -0500 Subject: [PATCH 13/21] HYDRA-1286 : Add GeomSubset displacement test scene --- ...reframeHighlightDisplacementTestScene.usda | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 test/testSamples/testGeomSubsetsWireframeHighlight/GeomSubsetWireframeHighlightDisplacementTestScene.usda diff --git a/test/testSamples/testGeomSubsetsWireframeHighlight/GeomSubsetWireframeHighlightDisplacementTestScene.usda b/test/testSamples/testGeomSubsetsWireframeHighlight/GeomSubsetWireframeHighlightDisplacementTestScene.usda new file mode 100644 index 000000000..95c954ed6 --- /dev/null +++ b/test/testSamples/testGeomSubsetsWireframeHighlight/GeomSubsetWireframeHighlightDisplacementTestScene.usda @@ -0,0 +1,83 @@ +#usda 1.0 +( + metersPerUnit = 0.01 + upAxis = "Y" +) + +def Mesh "Torus" ( + prepend apiSchemas = ["MaterialBindingAPI"] +) +{ + uniform bool doubleSided = 1 + float3[] extent = [(-1.5000005, -0.50000024, -1.5000008), (1.5000001, 0.50000006, 1.5000004)] + int[] faceVertexCounts = [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4] + int[] faceVertexIndices = [1, 0, 20, 21, 2, 1, 21, 22, 3, 2, 22, 23, 4, 3, 23, 24, 5, 4, 24, 25, 6, 5, 25, 26, 7, 6, 26, 27, 8, 7, 27, 28, 9, 8, 28, 29, 10, 9, 29, 30, 11, 10, 30, 31, 12, 11, 31, 32, 13, 12, 32, 33, 14, 13, 33, 34, 15, 14, 34, 35, 16, 15, 35, 36, 17, 16, 36, 37, 18, 17, 37, 38, 19, 18, 38, 39, 0, 19, 39, 20, 21, 20, 40, 41, 22, 21, 41, 42, 23, 22, 42, 43, 24, 23, 43, 44, 25, 24, 44, 45, 26, 25, 45, 46, 27, 26, 46, 47, 28, 27, 47, 48, 29, 28, 48, 49, 30, 29, 49, 50, 31, 30, 50, 51, 32, 31, 51, 52, 33, 32, 52, 53, 34, 33, 53, 54, 35, 34, 54, 55, 36, 35, 55, 56, 37, 36, 56, 57, 38, 37, 57, 58, 39, 38, 58, 59, 20, 39, 59, 40, 41, 40, 60, 61, 42, 41, 61, 62, 43, 42, 62, 63, 44, 43, 63, 64, 45, 44, 64, 65, 46, 45, 65, 66, 47, 46, 66, 67, 48, 47, 67, 68, 49, 48, 68, 69, 50, 49, 69, 70, 51, 50, 70, 71, 52, 51, 71, 72, 53, 52, 72, 73, 54, 53, 73, 74, 55, 54, 74, 75, 56, 55, 75, 76, 57, 56, 76, 77, 58, 57, 77, 78, 59, 58, 78, 79, 40, 59, 79, 60, 61, 60, 80, 81, 62, 61, 81, 82, 63, 62, 82, 83, 64, 63, 83, 84, 65, 64, 84, 85, 66, 65, 85, 86, 67, 66, 86, 87, 68, 67, 87, 88, 69, 68, 88, 89, 70, 69, 89, 90, 71, 70, 90, 91, 72, 71, 91, 92, 73, 72, 92, 93, 74, 73, 93, 94, 75, 74, 94, 95, 76, 75, 95, 96, 77, 76, 96, 97, 78, 77, 97, 98, 79, 78, 98, 99, 60, 79, 99, 80, 81, 80, 100, 101, 82, 81, 101, 102, 83, 82, 102, 103, 84, 83, 103, 104, 85, 84, 104, 105, 86, 85, 105, 106, 87, 86, 106, 107, 88, 87, 107, 108, 89, 88, 108, 109, 90, 89, 109, 110, 91, 90, 110, 111, 92, 91, 111, 112, 93, 92, 112, 113, 94, 93, 113, 114, 95, 94, 114, 115, 96, 95, 115, 116, 97, 96, 116, 117, 98, 97, 117, 118, 99, 98, 118, 119, 80, 99, 119, 100, 101, 100, 120, 121, 102, 101, 121, 122, 103, 102, 122, 123, 104, 103, 123, 124, 105, 104, 124, 125, 106, 105, 125, 126, 107, 106, 126, 127, 108, 107, 127, 128, 109, 108, 128, 129, 110, 109, 129, 130, 111, 110, 130, 131, 112, 111, 131, 132, 113, 112, 132, 133, 114, 113, 133, 134, 115, 114, 134, 135, 116, 115, 135, 136, 117, 116, 136, 137, 118, 117, 137, 138, 119, 118, 138, 139, 100, 119, 139, 120, 121, 120, 140, 141, 122, 121, 141, 142, 123, 122, 142, 143, 124, 123, 143, 144, 125, 124, 144, 145, 126, 125, 145, 146, 127, 126, 146, 147, 128, 127, 147, 148, 129, 128, 148, 149, 130, 129, 149, 150, 131, 130, 150, 151, 132, 131, 151, 152, 133, 132, 152, 153, 134, 133, 153, 154, 135, 134, 154, 155, 136, 135, 155, 156, 137, 136, 156, 157, 138, 137, 157, 158, 139, 138, 158, 159, 120, 139, 159, 140, 141, 140, 160, 161, 142, 141, 161, 162, 143, 142, 162, 163, 144, 143, 163, 164, 145, 144, 164, 165, 146, 145, 165, 166, 147, 146, 166, 167, 148, 147, 167, 168, 149, 148, 168, 169, 150, 149, 169, 170, 151, 150, 170, 171, 152, 151, 171, 172, 153, 152, 172, 173, 154, 153, 173, 174, 155, 154, 174, 175, 156, 155, 175, 176, 157, 156, 176, 177, 158, 157, 177, 178, 159, 158, 178, 179, 140, 159, 179, 160, 161, 160, 180, 181, 162, 161, 181, 182, 163, 162, 182, 183, 164, 163, 183, 184, 165, 164, 184, 185, 166, 165, 185, 186, 167, 166, 186, 187, 168, 167, 187, 188, 169, 168, 188, 189, 170, 169, 189, 190, 171, 170, 190, 191, 172, 171, 191, 192, 173, 172, 192, 193, 174, 173, 193, 194, 175, 174, 194, 195, 176, 175, 195, 196, 177, 176, 196, 197, 178, 177, 197, 198, 179, 178, 198, 199, 160, 179, 199, 180, 181, 180, 200, 201, 182, 181, 201, 202, 183, 182, 202, 203, 184, 183, 203, 204, 185, 184, 204, 205, 186, 185, 205, 206, 187, 186, 206, 207, 188, 187, 207, 208, 189, 188, 208, 209, 190, 189, 209, 210, 191, 190, 210, 211, 192, 191, 211, 212, 193, 192, 212, 213, 194, 193, 213, 214, 195, 194, 214, 215, 196, 195, 215, 216, 197, 196, 216, 217, 198, 197, 217, 218, 199, 198, 218, 219, 180, 199, 219, 200, 201, 200, 220, 221, 202, 201, 221, 222, 203, 202, 222, 223, 204, 203, 223, 224, 205, 204, 224, 225, 206, 205, 225, 226, 207, 206, 226, 227, 208, 207, 227, 228, 209, 208, 228, 229, 210, 209, 229, 230, 211, 210, 230, 231, 212, 211, 231, 232, 213, 212, 232, 233, 214, 213, 233, 234, 215, 214, 234, 235, 216, 215, 235, 236, 217, 216, 236, 237, 218, 217, 237, 238, 219, 218, 238, 239, 200, 219, 239, 220, 221, 220, 240, 241, 222, 221, 241, 242, 223, 222, 242, 243, 224, 223, 243, 244, 225, 224, 244, 245, 226, 225, 245, 246, 227, 226, 246, 247, 228, 227, 247, 248, 229, 228, 248, 249, 230, 229, 249, 250, 231, 230, 250, 251, 232, 231, 251, 252, 233, 232, 252, 253, 234, 233, 253, 254, 235, 234, 254, 255, 236, 235, 255, 256, 237, 236, 256, 257, 238, 237, 257, 258, 239, 238, 258, 259, 220, 239, 259, 240, 241, 240, 260, 261, 242, 241, 261, 262, 243, 242, 262, 263, 244, 243, 263, 264, 245, 244, 264, 265, 246, 245, 265, 266, 247, 246, 266, 267, 248, 247, 267, 268, 249, 248, 268, 269, 250, 249, 269, 270, 251, 250, 270, 271, 252, 251, 271, 272, 253, 252, 272, 273, 254, 253, 273, 274, 255, 254, 274, 275, 256, 255, 275, 276, 257, 256, 276, 277, 258, 257, 277, 278, 259, 258, 278, 279, 240, 259, 279, 260, 261, 260, 280, 281, 262, 261, 281, 282, 263, 262, 282, 283, 264, 263, 283, 284, 265, 264, 284, 285, 266, 265, 285, 286, 267, 266, 286, 287, 268, 267, 287, 288, 269, 268, 288, 289, 270, 269, 289, 290, 271, 270, 290, 291, 272, 271, 291, 292, 273, 272, 292, 293, 274, 273, 293, 294, 275, 274, 294, 295, 276, 275, 295, 296, 277, 276, 296, 297, 278, 277, 297, 298, 279, 278, 298, 299, 260, 279, 299, 280, 281, 280, 300, 301, 282, 281, 301, 302, 283, 282, 302, 303, 284, 283, 303, 304, 285, 284, 304, 305, 286, 285, 305, 306, 287, 286, 306, 307, 288, 287, 307, 308, 289, 288, 308, 309, 290, 289, 309, 310, 291, 290, 310, 311, 292, 291, 311, 312, 293, 292, 312, 313, 294, 293, 313, 314, 295, 294, 314, 315, 296, 295, 315, 316, 297, 296, 316, 317, 298, 297, 317, 318, 299, 298, 318, 319, 280, 299, 319, 300, 301, 300, 320, 321, 302, 301, 321, 322, 303, 302, 322, 323, 304, 303, 323, 324, 305, 304, 324, 325, 306, 305, 325, 326, 307, 306, 326, 327, 308, 307, 327, 328, 309, 308, 328, 329, 310, 309, 329, 330, 311, 310, 330, 331, 312, 311, 331, 332, 313, 312, 332, 333, 314, 313, 333, 334, 315, 314, 334, 335, 316, 315, 335, 336, 317, 316, 336, 337, 318, 317, 337, 338, 319, 318, 338, 339, 300, 319, 339, 320, 321, 320, 340, 341, 322, 321, 341, 342, 323, 322, 342, 343, 324, 323, 343, 344, 325, 324, 344, 345, 326, 325, 345, 346, 327, 326, 346, 347, 328, 327, 347, 348, 329, 328, 348, 349, 330, 329, 349, 350, 331, 330, 350, 351, 332, 331, 351, 352, 333, 332, 352, 353, 334, 333, 353, 354, 335, 334, 354, 355, 336, 335, 355, 356, 337, 336, 356, 357, 338, 337, 357, 358, 339, 338, 358, 359, 320, 339, 359, 340, 341, 340, 360, 361, 342, 341, 361, 362, 343, 342, 362, 363, 344, 343, 363, 364, 345, 344, 364, 365, 346, 345, 365, 366, 347, 346, 366, 367, 348, 347, 367, 368, 349, 348, 368, 369, 350, 349, 369, 370, 351, 350, 370, 371, 352, 351, 371, 372, 353, 352, 372, 373, 354, 353, 373, 374, 355, 354, 374, 375, 356, 355, 375, 376, 357, 356, 376, 377, 358, 357, 377, 378, 359, 358, 378, 379, 340, 359, 379, 360, 361, 360, 380, 381, 362, 361, 381, 382, 363, 362, 382, 383, 364, 363, 383, 384, 365, 364, 384, 385, 366, 365, 385, 386, 367, 366, 386, 387, 368, 367, 387, 388, 369, 368, 388, 389, 370, 369, 389, 390, 371, 370, 390, 391, 372, 371, 391, 392, 373, 372, 392, 393, 374, 373, 393, 394, 375, 374, 394, 395, 376, 375, 395, 396, 377, 376, 396, 397, 378, 377, 397, 398, 379, 378, 398, 399, 360, 379, 399, 380, 381, 380, 0, 1, 382, 381, 1, 2, 383, 382, 2, 3, 384, 383, 3, 4, 385, 384, 4, 5, 386, 385, 5, 6, 387, 386, 6, 7, 388, 387, 7, 8, 389, 388, 8, 9, 390, 389, 9, 10, 391, 390, 10, 11, 392, 391, 11, 12, 393, 392, 12, 13, 394, 393, 13, 14, 395, 394, 14, 15, 396, 395, 15, 16, 397, 396, 16, 17, 398, 397, 17, 18, 399, 398, 18, 19, 380, 399, 19, 0] + rel material:binding = + point3f[] points = [(0.47552857, 0, -0.15450859), (0.40450877, 0, -0.2938928), (0.2938928, 0, -0.40450874), (0.15450858, 0, -0.4755285), (0, 0, -0.50000024), (-0.15450858, 0, -0.47552848), (-0.29389274, 0, -0.40450865), (-0.40450862, 0, -0.2938927), (-0.4755284, 0, -0.15450853), (-0.5000001, 0, 0), (-0.4755284, 0, 0.15450853), (-0.4045086, 0, 0.29389268), (-0.29389268, 0, 0.40450856), (-0.15450853, 0, 0.47552833), (-1.4901161e-8, 0, 0.50000006), (0.15450849, 0, 0.4755283), (0.29389262, 0, 0.40450853), (0.4045085, 0, 0.29389265), (0.47552827, 0, 0.1545085), (0.5, 0, 0), (0.4988026, 0.1545085, -0.16207078), (0.42430684, 0.1545085, -0.30827695), (0.30827695, 0.1545085, -0.4243068), (0.16207077, 0.1545085, -0.49880254), (0, 0.1545085, -0.524472), (-0.16207077, 0.1545085, -0.4988025), (-0.3082769, 0.1545085, -0.42430672), (-0.4243067, 0.1545085, -0.30827686), (-0.49880242, 0.1545085, -0.16207072), (-0.5244719, 0.1545085, 0), (-0.49880242, 0.1545085, 0.16207072), (-0.42430666, 0.1545085, 0.30827683), (-0.30827683, 0.1545085, 0.42430663), (-0.16207072, 0.1545085, 0.49880236), (-1.5630476e-8, 0.1545085, 0.5244718), (0.16207068, 0.1545085, 0.49880233), (0.30827677, 0.1545085, 0.4243066), (0.42430657, 0.1545085, 0.3082768), (0.4988023, 0.1545085, 0.16207069), (0.52447176, 0.1545085, 0), (0.56634647, 0.29389265, -0.1840171), (0.4817631, 0.29389265, -0.35002133), (0.35002133, 0.29389265, -0.48176306), (0.18401709, 0.29389265, -0.5663464), (0, 0.29389265, -0.5954918), (-0.18401709, 0.29389265, -0.56634635), (-0.35002127, 0.29389265, -0.48176295), (-0.48176292, 0.29389265, -0.35002124), (-0.5663462, 0.29389265, -0.18401705), (-0.59549165, 0.29389265, 0), (-0.5663462, 0.29389265, 0.18401705), (-0.4817629, 0.29389265, 0.3500212), (-0.3500212, 0.29389265, 0.48176286), (-0.18401705, 0.29389265, 0.56634617), (-1.774703e-8, 0.29389265, 0.5954916), (0.18401699, 0.29389265, 0.56634617), (0.35002112, 0.29389265, 0.4817628), (0.48176277, 0.29389265, 0.35002118), (0.5663461, 0.29389265, 0.184017), (0.5954915, 0.29389265, 0), (0.6715485, 0.40450853, -0.21819931), (0.57125324, 0.40450853, -0.41503975), (0.41503975, 0.40450853, -0.57125324), (0.2181993, 0.40450853, -0.67154837), (0, 0.40450853, -0.70610774), (-0.2181993, 0.40450853, -0.6715483), (-0.41503966, 0.40450853, -0.57125306), (-0.57125306, 0.40450853, -0.41503963), (-0.6715482, 0.40450853, -0.21819922), (-0.70610756, 0.40450853, 0), (-0.6715482, 0.40450853, 0.21819922), (-0.571253, 0.40450853, 0.41503957), (-0.41503957, 0.40450853, 0.57125294), (-0.21819922, 0.40450853, 0.6715481), (-2.104364e-8, 0.40450853, 0.70610744), (0.21819916, 0.40450853, 0.67154807), (0.4150395, 0.40450853, 0.57125294), (0.5712529, 0.40450853, 0.41503954), (0.67154807, 0.40450853, 0.21819918), (0.7061074, 0.40450853, 0), (0.80411077, 0.4755283, -0.26127142), (0.6840175, 0.4755283, -0.49696773), (0.49696773, 0.4755283, -0.6840174), (0.2612714, 0.4755283, -0.80411065), (0, 0.4755283, -0.84549195), (-0.2612714, 0.4755283, -0.8041106), (-0.49696764, 0.4755283, -0.6840173), (-0.68401724, 0.4755283, -0.49696758), (-0.80411047, 0.4755283, -0.2612713), (-0.8454917, 0.4755283, 0), (-0.80411047, 0.4755283, 0.2612713), (-0.6840172, 0.4755283, 0.49696755), (-0.49696755, 0.4755283, 0.6840171), (-0.2612713, 0.4755283, 0.80411035), (-2.5197611e-8, 0.4755283, 0.84549165), (0.26127124, 0.4755283, 0.8041103), (0.49696743, 0.4755283, 0.68401706), (0.684017, 0.4755283, 0.4969675), (0.8041102, 0.4755283, 0.26127127), (0.8454915, 0.4755283, 0), (0.95105714, 0.50000006, -0.30901718), (0.80901754, 0.50000006, -0.5877856), (0.5877856, 0.50000006, -0.8090175), (0.30901715, 0.50000006, -0.951057), (0, 0.50000006, -1.0000005), (-0.30901715, 0.50000006, -0.95105696), (-0.5877855, 0.50000006, -0.8090173), (-0.80901724, 0.50000006, -0.5877854), (-0.9510568, 0.50000006, -0.30901706), (-1.0000002, 0.50000006, 0), (-0.9510568, 0.50000006, 0.30901706), (-0.8090172, 0.50000006, 0.58778536), (-0.58778536, 0.50000006, 0.8090171), (-0.30901706, 0.50000006, 0.95105666), (-2.9802322e-8, 0.50000006, 1.0000001), (0.30901697, 0.50000006, 0.9510566), (0.58778524, 0.50000006, 0.80901706), (0.809017, 0.50000006, 0.5877853), (0.95105654, 0.50000006, 0.309017), (1, 0.50000006, 0), (1.0980036, 0.47552833, -0.356763), (0.9340177, 0.47552833, -0.67860353), (0.67860353, 0.47552833, -0.93401766), (0.35676295, 0.47552833, -1.0980035), (0, 0.47552833, -1.1545092), (-0.35676295, 0.47552833, -1.0980034), (-0.6786034, 0.47552833, -0.9340174), (-0.93401736, 0.47552833, -0.6786033), (-1.0980033, 0.47552833, -0.35676286), (-1.1545088, 0.47552833, 0), (-1.0980033, 0.47552833, 0.35676286), (-0.9340173, 0.47552833, 0.67860323), (-0.67860323, 0.47552833, 0.93401724), (-0.35676286, 0.47552833, 1.098003), (-3.4407037e-8, 0.47552833, 1.1545087), (0.35676274, 0.47552833, 1.098003), (0.6786031, 0.47552833, 0.9340171), (0.93401706, 0.47552833, 0.6786032), (1.0980029, 0.47552833, 0.3567628), (1.1545086, 0.47552833, 0), (1.2305658, 0.40450856, -0.39983505), (1.0467818, 0.40450856, -0.7605314), (0.7605314, 0.40450856, -1.0467818), (0.39983502, 0.40450856, -1.2305657), (0, 0.40450856, -1.2938932), (-0.39983502, 0.40450856, -1.2305655), (-0.7605313, 0.40450856, -1.0467815), (-1.0467814, 0.40450856, -0.76053125), (-1.2305653, 0.40450856, -0.3998349), (-1.293893, 0.40450856, 0), (-1.2305653, 0.40450856, 0.3998349), (-1.0467814, 0.40450856, 0.7605311), (-0.7605311, 0.40450856, 1.0467813), (-0.3998349, 0.40450856, 1.2305652), (-3.8561005e-8, 0.40450856, 1.2938927), (0.39983478, 0.40450856, 1.2305651), (0.760531, 0.40450856, 1.0467812), (1.0467812, 0.40450856, 0.76053107), (1.2305651, 0.40450856, 0.3998348), (1.2938926, 0.40450856, 0), (1.3357679, 0.29389268, -0.4340173), (1.1362721, 0.29389268, -0.8255499), (0.8255499, 0.29389268, -1.136272), (0.43401724, 0.29389268, -1.3357677), (0, 0.29389268, -1.4045093), (-0.43401724, 0.29389268, -1.3357676), (-0.8255498, 0.29389268, -1.1362717), (-1.1362717, 0.29389268, -0.82554966), (-1.3357674, 0.29389268, -0.43401712), (-1.404509, 0.29389268, 0), (-1.3357674, 0.29389268, 0.43401712), (-1.1362716, 0.29389268, 0.8255496), (-0.8255496, 0.29389268, 1.1362715), (-0.43401712, 0.29389268, 1.3357673), (-4.1857618e-8, 0.29389268, 1.4045087), (0.434017, 0.29389268, 1.3357671), (0.8255494, 0.29389268, 1.1362714), (1.1362714, 0.29389268, 0.8255495), (1.335767, 0.29389268, 0.43401703), (1.4045086, 0.29389268, 0), (1.4033117, 0.15450853, -0.4559636), (1.1937283, 0.15450853, -0.8672943), (0.8672943, 0.15450853, -1.1937282), (0.45596358, 0.15450853, -1.4033116), (0, 0.15450853, -1.4755291), (-0.45596358, 0.15450853, -1.4033115), (-0.86729413, 0.15450853, -1.193728), (-1.1937279, 0.15450853, -0.8672941), (-1.4033113, 0.15450853, -0.45596343), (-1.4755287, 0.15450853, 0), (-1.4033113, 0.15450853, 0.45596343), (-1.1937279, 0.15450853, 0.86729395), (-0.86729395, 0.15450853, 1.1937277), (-0.45596343, 0.15450853, 1.403311), (-4.3974172e-8, 0.15450853, 1.4755285), (0.4559633, 0.15450853, 1.403311), (0.8672938, 0.15450853, 1.1937276), (1.1937275, 0.15450853, 0.8672939), (1.4033109, 0.15450853, 0.45596334), (1.4755284, 0.15450853, 0), (1.4265858, 0, -0.4635258), (1.2135264, 0, -0.88167846), (0.88167846, 0, -1.2135264), (0.46352577, 0, -1.4265857), (0, 0, -1.5000008), (-0.46352577, 0, -1.4265856), (-0.8816783, 0, -1.213526), (-1.213526, 0, -0.8816782), (-1.4265853, 0, -0.46352562), (-1.5000005, 0, 0), (-1.4265853, 0, 0.46352562), (-1.2135259, 0, 0.8816781), (-0.8816781, 0, 1.2135258), (-0.46352562, 0, 1.4265851), (-4.4703487e-8, 0, 1.5000004), (0.4635255, 0, 1.426585), (0.8816779, 0, 1.2135257), (1.2135257, 0, 0.88167804), (1.426585, 0, 0.46352553), (1.5000001, 0, 0), (1.4033117, -0.15450853, -0.4559636), (1.1937283, -0.15450853, -0.8672943), (0.8672943, -0.15450853, -1.1937282), (0.45596358, -0.15450853, -1.4033116), (0, -0.15450853, -1.4755291), (-0.45596358, -0.15450853, -1.4033115), (-0.86729413, -0.15450853, -1.193728), (-1.1937279, -0.15450853, -0.8672941), (-1.4033113, -0.15450853, -0.45596343), (-1.4755287, -0.15450853, 0), (-1.4033113, -0.15450853, 0.45596343), (-1.1937279, -0.15450853, 0.86729395), (-0.86729395, -0.15450853, 1.1937277), (-0.45596343, -0.15450853, 1.403311), (-4.3974172e-8, -0.15450853, 1.4755285), (0.4559633, -0.15450853, 1.403311), (0.8672938, -0.15450853, 1.1937276), (1.1937275, -0.15450853, 0.8672939), (1.4033109, -0.15450853, 0.45596334), (1.4755284, -0.15450853, 0), (1.3357679, -0.2938927, -0.4340173), (1.1362721, -0.2938927, -0.8255499), (0.8255499, -0.2938927, -1.136272), (0.43401724, -0.2938927, -1.3357677), (0, -0.2938927, -1.4045093), (-0.43401724, -0.2938927, -1.3357676), (-0.8255498, -0.2938927, -1.1362717), (-1.1362717, -0.2938927, -0.82554966), (-1.3357674, -0.2938927, -0.43401712), (-1.404509, -0.2938927, 0), (-1.3357674, -0.2938927, 0.43401712), (-1.1362716, -0.2938927, 0.8255496), (-0.8255496, -0.2938927, 1.1362715), (-0.43401712, -0.2938927, 1.3357673), (-4.1857618e-8, -0.2938927, 1.4045087), (0.434017, -0.2938927, 1.3357671), (0.8255494, -0.2938927, 1.1362714), (1.1362714, -0.2938927, 0.8255495), (1.335767, -0.2938927, 0.43401703), (1.4045086, -0.2938927, 0), (1.2305659, -0.40450865, -0.39983508), (1.0467819, -0.40450865, -0.76053154), (0.76053154, -0.40450865, -1.0467819), (0.39983505, -0.40450865, -1.2305658), (0, -0.40450865, -1.2938933), (-0.39983505, -0.40450865, -1.2305657), (-0.76053137, -0.40450865, -1.0467817), (-1.0467815, -0.40450865, -0.7605313), (-1.2305654, -0.40450865, -0.39983493), (-1.2938931, -0.40450865, 0), (-1.2305654, -0.40450865, 0.39983493), (-1.0467814, -0.40450865, 0.7605312), (-0.7605312, -0.40450865, 1.0467814), (-0.39983493, -0.40450865, 1.2305653), (-3.856101e-8, -0.40450865, 1.2938929), (0.3998348, -0.40450865, 1.2305652), (0.76053107, -0.40450865, 1.0467813), (1.0467812, -0.40450865, 0.7605311), (1.2305652, -0.40450865, 0.39983487), (1.2938927, -0.40450865, 0), (1.0980036, -0.47552848, -0.356763), (0.9340177, -0.47552848, -0.67860353), (0.67860353, -0.47552848, -0.93401766), (0.35676295, -0.47552848, -1.0980035), (0, -0.47552848, -1.1545092), (-0.35676295, -0.47552848, -1.0980034), (-0.6786034, -0.47552848, -0.9340174), (-0.93401736, -0.47552848, -0.6786033), (-1.0980033, -0.47552848, -0.35676286), (-1.1545088, -0.47552848, 0), (-1.0980033, -0.47552848, 0.35676286), (-0.9340173, -0.47552848, 0.67860323), (-0.67860323, -0.47552848, 0.93401724), (-0.35676286, -0.47552848, 1.098003), (-3.4407037e-8, -0.47552848, 1.1545087), (0.35676274, -0.47552848, 1.098003), (0.6786031, -0.47552848, 0.9340171), (0.93401706, -0.47552848, 0.6786032), (1.0980029, -0.47552848, 0.3567628), (1.1545086, -0.47552848, 0), (0.95105714, -0.50000024, -0.30901718), (0.80901754, -0.50000024, -0.5877856), (0.5877856, -0.50000024, -0.8090175), (0.30901715, -0.50000024, -0.951057), (0, -0.50000024, -1.0000005), (-0.30901715, -0.50000024, -0.95105696), (-0.5877855, -0.50000024, -0.8090173), (-0.80901724, -0.50000024, -0.5877854), (-0.9510568, -0.50000024, -0.30901706), (-1.0000002, -0.50000024, 0), (-0.9510568, -0.50000024, 0.30901706), (-0.8090172, -0.50000024, 0.58778536), (-0.58778536, -0.50000024, 0.8090171), (-0.30901706, -0.50000024, 0.95105666), (-2.9802322e-8, -0.50000024, 1.0000001), (0.30901697, -0.50000024, 0.9510566), (0.58778524, -0.50000024, 0.80901706), (0.809017, -0.50000024, 0.5877853), (0.95105654, -0.50000024, 0.309017), (1, -0.50000024, 0), (0.80411065, -0.4755285, -0.26127136), (0.68401736, -0.4755285, -0.49696767), (0.49696767, -0.4755285, -0.6840173), (0.26127136, -0.4755285, -0.8041105), (0, -0.4755285, -0.8454918), (-0.26127136, -0.4755285, -0.80411047), (-0.49696758, -0.4755285, -0.6840172), (-0.6840171, -0.4755285, -0.49696752), (-0.80411035, -0.4755285, -0.26127127), (-0.8454916, -0.4755285, 0), (-0.80411035, -0.4755285, 0.26127127), (-0.68401706, -0.4755285, 0.49696746), (-0.49696746, -0.4755285, 0.684017), (-0.26127127, -0.4755285, 0.8041102), (-2.5197608e-8, -0.4755285, 0.8454915), (0.2612712, -0.4755285, 0.80411017), (0.49696738, -0.4755285, 0.684017), (0.68401694, -0.4755285, 0.49696743), (0.8041101, -0.4755285, 0.2612712), (0.8454914, -0.4755285, 0), (0.6715483, -0.40450874, -0.21819925), (0.5712531, -0.40450874, -0.41503966), (0.41503966, -0.40450874, -0.57125306), (0.21819924, -0.40450874, -0.6715482), (0, -0.40450874, -0.70610756), (-0.21819924, -0.40450874, -0.6715482), (-0.41503957, -0.40450874, -0.57125294), (-0.5712529, -0.40450874, -0.4150395), (-0.671548, -0.40450874, -0.21819918), (-0.7061074, -0.40450874, 0), (-0.671548, -0.40450874, 0.21819918), (-0.5712529, -0.40450874, 0.41503948), (-0.41503948, -0.40450874, 0.5712528), (-0.21819918, -0.40450874, 0.67154795), (-2.1043634e-8, -0.40450874, 0.70610726), (0.2181991, -0.40450874, 0.6715479), (0.4150394, -0.40450874, 0.57125276), (0.5712527, -0.40450874, 0.41503942), (0.6715479, -0.40450874, 0.21819913), (0.7061072, -0.40450874, 0), (0.56634617, -0.2938928, -0.18401702), (0.48176286, -0.2938928, -0.35002118), (0.35002118, -0.2938928, -0.48176283), (0.184017, -0.2938928, -0.5663461), (0, -0.2938928, -0.5954915), (-0.184017, -0.2938928, -0.56634605), (-0.3500211, -0.2938928, -0.4817627), (-0.48176268, -0.2938928, -0.35002106), (-0.566346, -0.2938928, -0.18401696), (-0.59549135, -0.2938928, 0), (-0.566346, -0.2938928, 0.18401696), (-0.48176265, -0.2938928, 0.35002103), (-0.35002103, -0.2938928, 0.4817626), (-0.18401696, -0.2938928, 0.5663459), (-1.7747022e-8, -0.2938928, 0.5954913), (0.1840169, -0.2938928, 0.5663459), (0.35002095, -0.2938928, 0.48176256), (0.48176253, -0.2938928, 0.350021), (0.5663458, -0.2938928, 0.18401691), (0.59549123, -0.2938928, 0), (0.49880227, -0.15450859, -0.16207068), (0.42430657, -0.15450859, -0.30827674), (0.30827674, -0.15450859, -0.42430654), (0.16207066, -0.15450859, -0.4988022), (0, -0.15450859, -0.52447164), (-0.16207066, -0.15450859, -0.49880219), (-0.30827668, -0.15450859, -0.42430645), (-0.4243064, -0.15450859, -0.30827665), (-0.4988021, -0.15450859, -0.16207062), (-0.5244715, -0.15450859, 0), (-0.4988021, -0.15450859, 0.16207062), (-0.42430636, -0.15450859, 0.30827662), (-0.30827662, -0.15450859, 0.42430633), (-0.16207062, -0.15450859, 0.498802), (-1.5630466e-8, -0.15450859, 0.52447146), (0.16207057, -0.15450859, 0.49880198), (0.30827656, -0.15450859, 0.4243063), (0.42430627, -0.15450859, 0.3082766), (0.49880195, -0.15450859, 0.16207059), (0.5244714, -0.15450859, 0)] + color3f[] primvars:displayColor = [(1, 1, 1)] ( + customData = { + dictionary Maya = { + bool generated = 1 + } + } + ) + texCoord2f[] primvars:st = [(0, 1), (0.05, 1), (0.1, 1), (0.15, 1), (0.2, 1), (0.25, 1), (0.3, 1), (0.35000002, 1), (0.40000004, 1), (0.45000005, 1), (0.50000006, 1), (0.5500001, 1), (0.6000001, 1), (0.6500001, 1), (0.7000001, 1), (0.7500001, 1), (0.80000013, 1), (0.85000014, 1), (0.90000015, 1), (0.95000017, 1), (1.0000001, 1), (0, 0.95), (0.05, 0.95), (0.1, 0.95), (0.15, 0.95), (0.2, 0.95), (0.25, 0.95), (0.3, 0.95), (0.35000002, 0.95), (0.40000004, 0.95), (0.45000005, 0.95), (0.50000006, 0.95), (0.5500001, 0.95), (0.6000001, 0.95), (0.6500001, 0.95), (0.7000001, 0.95), (0.7500001, 0.95), (0.80000013, 0.95), (0.85000014, 0.95), (0.90000015, 0.95), (0.95000017, 0.95), (1.0000001, 0.95), (0, 0.9), (0.05, 0.9), (0.1, 0.9), (0.15, 0.9), (0.2, 0.9), (0.25, 0.9), (0.3, 0.9), (0.35000002, 0.9), (0.40000004, 0.9), (0.45000005, 0.9), (0.50000006, 0.9), (0.5500001, 0.9), (0.6000001, 0.9), (0.6500001, 0.9), (0.7000001, 0.9), (0.7500001, 0.9), (0.80000013, 0.9), (0.85000014, 0.9), (0.90000015, 0.9), (0.95000017, 0.9), (1.0000001, 0.9), (0, 0.84999996), (0.05, 0.84999996), (0.1, 0.84999996), (0.15, 0.84999996), (0.2, 0.84999996), (0.25, 0.84999996), (0.3, 0.84999996), (0.35000002, 0.84999996), (0.40000004, 0.84999996), (0.45000005, 0.84999996), (0.50000006, 0.84999996), (0.5500001, 0.84999996), (0.6000001, 0.84999996), (0.6500001, 0.84999996), (0.7000001, 0.84999996), (0.7500001, 0.84999996), (0.80000013, 0.84999996), (0.85000014, 0.84999996), (0.90000015, 0.84999996), (0.95000017, 0.84999996), (1.0000001, 0.84999996), (0, 0.79999995), (0.05, 0.79999995), (0.1, 0.79999995), (0.15, 0.79999995), (0.2, 0.79999995), (0.25, 0.79999995), (0.3, 0.79999995), (0.35000002, 0.79999995), (0.40000004, 0.79999995), (0.45000005, 0.79999995), (0.50000006, 0.79999995), (0.5500001, 0.79999995), (0.6000001, 0.79999995), (0.6500001, 0.79999995), (0.7000001, 0.79999995), (0.7500001, 0.79999995), (0.80000013, 0.79999995), (0.85000014, 0.79999995), (0.90000015, 0.79999995), (0.95000017, 0.79999995), (1.0000001, 0.79999995), (0, 0.74999994), (0.05, 0.74999994), (0.1, 0.74999994), (0.15, 0.74999994), (0.2, 0.74999994), (0.25, 0.74999994), (0.3, 0.74999994), (0.35000002, 0.74999994), (0.40000004, 0.74999994), (0.45000005, 0.74999994), (0.50000006, 0.74999994), (0.5500001, 0.74999994), (0.6000001, 0.74999994), (0.6500001, 0.74999994), (0.7000001, 0.74999994), (0.7500001, 0.74999994), (0.80000013, 0.74999994), (0.85000014, 0.74999994), (0.90000015, 0.74999994), (0.95000017, 0.74999994), (1.0000001, 0.74999994), (0, 0.6999999), (0.05, 0.6999999), (0.1, 0.6999999), (0.15, 0.6999999), (0.2, 0.6999999), (0.25, 0.6999999), (0.3, 0.6999999), (0.35000002, 0.6999999), (0.40000004, 0.6999999), (0.45000005, 0.6999999), (0.50000006, 0.6999999), (0.5500001, 0.6999999), (0.6000001, 0.6999999), (0.6500001, 0.6999999), (0.7000001, 0.6999999), (0.7500001, 0.6999999), (0.80000013, 0.6999999), (0.85000014, 0.6999999), (0.90000015, 0.6999999), (0.95000017, 0.6999999), (1.0000001, 0.6999999), (0, 0.6499999), (0.05, 0.6499999), (0.1, 0.6499999), (0.15, 0.6499999), (0.2, 0.6499999), (0.25, 0.6499999), (0.3, 0.6499999), (0.35000002, 0.6499999), (0.40000004, 0.6499999), (0.45000005, 0.6499999), (0.50000006, 0.6499999), (0.5500001, 0.6499999), (0.6000001, 0.6499999), (0.6500001, 0.6499999), (0.7000001, 0.6499999), (0.7500001, 0.6499999), (0.80000013, 0.6499999), (0.85000014, 0.6499999), (0.90000015, 0.6499999), (0.95000017, 0.6499999), (1.0000001, 0.6499999), (0, 0.5999999), (0.05, 0.5999999), (0.1, 0.5999999), (0.15, 0.5999999), (0.2, 0.5999999), (0.25, 0.5999999), (0.3, 0.5999999), (0.35000002, 0.5999999), (0.40000004, 0.5999999), (0.45000005, 0.5999999), (0.50000006, 0.5999999), (0.5500001, 0.5999999), (0.6000001, 0.5999999), (0.6500001, 0.5999999), (0.7000001, 0.5999999), (0.7500001, 0.5999999), (0.80000013, 0.5999999), (0.85000014, 0.5999999), (0.90000015, 0.5999999), (0.95000017, 0.5999999), (1.0000001, 0.5999999), (0, 0.5499999), (0.05, 0.5499999), (0.1, 0.5499999), (0.15, 0.5499999), (0.2, 0.5499999), (0.25, 0.5499999), (0.3, 0.5499999), (0.35000002, 0.5499999), (0.40000004, 0.5499999), (0.45000005, 0.5499999), (0.50000006, 0.5499999), (0.5500001, 0.5499999), (0.6000001, 0.5499999), (0.6500001, 0.5499999), (0.7000001, 0.5499999), (0.7500001, 0.5499999), (0.80000013, 0.5499999), (0.85000014, 0.5499999), (0.90000015, 0.5499999), (0.95000017, 0.5499999), (1.0000001, 0.5499999), (0, 0.49999988), (0.05, 0.49999988), (0.1, 0.49999988), (0.15, 0.49999988), (0.2, 0.49999988), (0.25, 0.49999988), (0.3, 0.49999988), (0.35000002, 0.49999988), (0.40000004, 0.49999988), (0.45000005, 0.49999988), (0.50000006, 0.49999988), (0.5500001, 0.49999988), (0.6000001, 0.49999988), (0.6500001, 0.49999988), (0.7000001, 0.49999988), (0.7500001, 0.49999988), (0.80000013, 0.49999988), (0.85000014, 0.49999988), (0.90000015, 0.49999988), (0.95000017, 0.49999988), (1.0000001, 0.49999988), (0, 0.44999987), (0.05, 0.44999987), (0.1, 0.44999987), (0.15, 0.44999987), (0.2, 0.44999987), (0.25, 0.44999987), (0.3, 0.44999987), (0.35000002, 0.44999987), (0.40000004, 0.44999987), (0.45000005, 0.44999987), (0.50000006, 0.44999987), (0.5500001, 0.44999987), (0.6000001, 0.44999987), (0.6500001, 0.44999987), (0.7000001, 0.44999987), (0.7500001, 0.44999987), (0.80000013, 0.44999987), (0.85000014, 0.44999987), (0.90000015, 0.44999987), (0.95000017, 0.44999987), (1.0000001, 0.44999987), (0, 0.39999986), (0.05, 0.39999986), (0.1, 0.39999986), (0.15, 0.39999986), (0.2, 0.39999986), (0.25, 0.39999986), (0.3, 0.39999986), (0.35000002, 0.39999986), (0.40000004, 0.39999986), (0.45000005, 0.39999986), (0.50000006, 0.39999986), (0.5500001, 0.39999986), (0.6000001, 0.39999986), (0.6500001, 0.39999986), (0.7000001, 0.39999986), (0.7500001, 0.39999986), (0.80000013, 0.39999986), (0.85000014, 0.39999986), (0.90000015, 0.39999986), (0.95000017, 0.39999986), (1.0000001, 0.39999986), (0, 0.34999985), (0.05, 0.34999985), (0.1, 0.34999985), (0.15, 0.34999985), (0.2, 0.34999985), (0.25, 0.34999985), (0.3, 0.34999985), (0.35000002, 0.34999985), (0.40000004, 0.34999985), (0.45000005, 0.34999985), (0.50000006, 0.34999985), (0.5500001, 0.34999985), (0.6000001, 0.34999985), (0.6500001, 0.34999985), (0.7000001, 0.34999985), (0.7500001, 0.34999985), (0.80000013, 0.34999985), (0.85000014, 0.34999985), (0.90000015, 0.34999985), (0.95000017, 0.34999985), (1.0000001, 0.34999985), (0, 0.29999983), (0.05, 0.29999983), (0.1, 0.29999983), (0.15, 0.29999983), (0.2, 0.29999983), (0.25, 0.29999983), (0.3, 0.29999983), (0.35000002, 0.29999983), (0.40000004, 0.29999983), (0.45000005, 0.29999983), (0.50000006, 0.29999983), (0.5500001, 0.29999983), (0.6000001, 0.29999983), (0.6500001, 0.29999983), (0.7000001, 0.29999983), (0.7500001, 0.29999983), (0.80000013, 0.29999983), (0.85000014, 0.29999983), (0.90000015, 0.29999983), (0.95000017, 0.29999983), (1.0000001, 0.29999983), (0, 0.24999984), (0.05, 0.24999984), (0.1, 0.24999984), (0.15, 0.24999984), (0.2, 0.24999984), (0.25, 0.24999984), (0.3, 0.24999984), (0.35000002, 0.24999984), (0.40000004, 0.24999984), (0.45000005, 0.24999984), (0.50000006, 0.24999984), (0.5500001, 0.24999984), (0.6000001, 0.24999984), (0.6500001, 0.24999984), (0.7000001, 0.24999984), (0.7500001, 0.24999984), (0.80000013, 0.24999984), (0.85000014, 0.24999984), (0.90000015, 0.24999984), (0.95000017, 0.24999984), (1.0000001, 0.24999984), (0, 0.19999984), (0.05, 0.19999984), (0.1, 0.19999984), (0.15, 0.19999984), (0.2, 0.19999984), (0.25, 0.19999984), (0.3, 0.19999984), (0.35000002, 0.19999984), (0.40000004, 0.19999984), (0.45000005, 0.19999984), (0.50000006, 0.19999984), (0.5500001, 0.19999984), (0.6000001, 0.19999984), (0.6500001, 0.19999984), (0.7000001, 0.19999984), (0.7500001, 0.19999984), (0.80000013, 0.19999984), (0.85000014, 0.19999984), (0.90000015, 0.19999984), (0.95000017, 0.19999984), (1.0000001, 0.19999984), (0, 0.14999984), (0.05, 0.14999984), (0.1, 0.14999984), (0.15, 0.14999984), (0.2, 0.14999984), (0.25, 0.14999984), (0.3, 0.14999984), (0.35000002, 0.14999984), (0.40000004, 0.14999984), (0.45000005, 0.14999984), (0.50000006, 0.14999984), (0.5500001, 0.14999984), (0.6000001, 0.14999984), (0.6500001, 0.14999984), (0.7000001, 0.14999984), (0.7500001, 0.14999984), (0.80000013, 0.14999984), (0.85000014, 0.14999984), (0.90000015, 0.14999984), (0.95000017, 0.14999984), (1.0000001, 0.14999984), (0, 0.099999845), (0.05, 0.099999845), (0.1, 0.099999845), (0.15, 0.099999845), (0.2, 0.099999845), (0.25, 0.099999845), (0.3, 0.099999845), (0.35000002, 0.099999845), (0.40000004, 0.099999845), (0.45000005, 0.099999845), (0.50000006, 0.099999845), (0.5500001, 0.099999845), (0.6000001, 0.099999845), (0.6500001, 0.099999845), (0.7000001, 0.099999845), (0.7500001, 0.099999845), (0.80000013, 0.099999845), (0.85000014, 0.099999845), (0.90000015, 0.099999845), (0.95000017, 0.099999845), (1.0000001, 0.099999845), (0, 0.049999844), (0.05, 0.049999844), (0.1, 0.049999844), (0.15, 0.049999844), (0.2, 0.049999844), (0.25, 0.049999844), (0.3, 0.049999844), (0.35000002, 0.049999844), (0.40000004, 0.049999844), (0.45000005, 0.049999844), (0.50000006, 0.049999844), (0.5500001, 0.049999844), (0.6000001, 0.049999844), (0.6500001, 0.049999844), (0.7000001, 0.049999844), (0.7500001, 0.049999844), (0.80000013, 0.049999844), (0.85000014, 0.049999844), (0.90000015, 0.049999844), (0.95000017, 0.049999844), (1.0000001, 0.049999844), (0, -1.5646219e-7), (0.05, -1.5646219e-7), (0.1, -1.5646219e-7), (0.15, -1.5646219e-7), (0.2, -1.5646219e-7), (0.25, -1.5646219e-7), (0.3, -1.5646219e-7), (0.35000002, -1.5646219e-7), (0.40000004, -1.5646219e-7), (0.45000005, -1.5646219e-7), (0.50000006, -1.5646219e-7), (0.5500001, -1.5646219e-7), (0.6000001, -1.5646219e-7), (0.6500001, -1.5646219e-7), (0.7000001, -1.5646219e-7), (0.7500001, -1.5646219e-7), (0.80000013, -1.5646219e-7), (0.85000014, -1.5646219e-7), (0.90000015, -1.5646219e-7), (0.95000017, -1.5646219e-7), (1.0000001, -1.5646219e-7)] ( + customData = { + dictionary Maya = { + token name = "map1" + } + } + interpolation = "faceVarying" + ) + int[] primvars:st:indices = [1, 0, 21, 22, 2, 1, 22, 23, 3, 2, 23, 24, 4, 3, 24, 25, 5, 4, 25, 26, 6, 5, 26, 27, 7, 6, 27, 28, 8, 7, 28, 29, 9, 8, 29, 30, 10, 9, 30, 31, 11, 10, 31, 32, 12, 11, 32, 33, 13, 12, 33, 34, 14, 13, 34, 35, 15, 14, 35, 36, 16, 15, 36, 37, 17, 16, 37, 38, 18, 17, 38, 39, 19, 18, 39, 40, 20, 19, 40, 41, 22, 21, 42, 43, 23, 22, 43, 44, 24, 23, 44, 45, 25, 24, 45, 46, 26, 25, 46, 47, 27, 26, 47, 48, 28, 27, 48, 49, 29, 28, 49, 50, 30, 29, 50, 51, 31, 30, 51, 52, 32, 31, 52, 53, 33, 32, 53, 54, 34, 33, 54, 55, 35, 34, 55, 56, 36, 35, 56, 57, 37, 36, 57, 58, 38, 37, 58, 59, 39, 38, 59, 60, 40, 39, 60, 61, 41, 40, 61, 62, 43, 42, 63, 64, 44, 43, 64, 65, 45, 44, 65, 66, 46, 45, 66, 67, 47, 46, 67, 68, 48, 47, 68, 69, 49, 48, 69, 70, 50, 49, 70, 71, 51, 50, 71, 72, 52, 51, 72, 73, 53, 52, 73, 74, 54, 53, 74, 75, 55, 54, 75, 76, 56, 55, 76, 77, 57, 56, 77, 78, 58, 57, 78, 79, 59, 58, 79, 80, 60, 59, 80, 81, 61, 60, 81, 82, 62, 61, 82, 83, 64, 63, 84, 85, 65, 64, 85, 86, 66, 65, 86, 87, 67, 66, 87, 88, 68, 67, 88, 89, 69, 68, 89, 90, 70, 69, 90, 91, 71, 70, 91, 92, 72, 71, 92, 93, 73, 72, 93, 94, 74, 73, 94, 95, 75, 74, 95, 96, 76, 75, 96, 97, 77, 76, 97, 98, 78, 77, 98, 99, 79, 78, 99, 100, 80, 79, 100, 101, 81, 80, 101, 102, 82, 81, 102, 103, 83, 82, 103, 104, 85, 84, 105, 106, 86, 85, 106, 107, 87, 86, 107, 108, 88, 87, 108, 109, 89, 88, 109, 110, 90, 89, 110, 111, 91, 90, 111, 112, 92, 91, 112, 113, 93, 92, 113, 114, 94, 93, 114, 115, 95, 94, 115, 116, 96, 95, 116, 117, 97, 96, 117, 118, 98, 97, 118, 119, 99, 98, 119, 120, 100, 99, 120, 121, 101, 100, 121, 122, 102, 101, 122, 123, 103, 102, 123, 124, 104, 103, 124, 125, 106, 105, 126, 127, 107, 106, 127, 128, 108, 107, 128, 129, 109, 108, 129, 130, 110, 109, 130, 131, 111, 110, 131, 132, 112, 111, 132, 133, 113, 112, 133, 134, 114, 113, 134, 135, 115, 114, 135, 136, 116, 115, 136, 137, 117, 116, 137, 138, 118, 117, 138, 139, 119, 118, 139, 140, 120, 119, 140, 141, 121, 120, 141, 142, 122, 121, 142, 143, 123, 122, 143, 144, 124, 123, 144, 145, 125, 124, 145, 146, 127, 126, 147, 148, 128, 127, 148, 149, 129, 128, 149, 150, 130, 129, 150, 151, 131, 130, 151, 152, 132, 131, 152, 153, 133, 132, 153, 154, 134, 133, 154, 155, 135, 134, 155, 156, 136, 135, 156, 157, 137, 136, 157, 158, 138, 137, 158, 159, 139, 138, 159, 160, 140, 139, 160, 161, 141, 140, 161, 162, 142, 141, 162, 163, 143, 142, 163, 164, 144, 143, 164, 165, 145, 144, 165, 166, 146, 145, 166, 167, 148, 147, 168, 169, 149, 148, 169, 170, 150, 149, 170, 171, 151, 150, 171, 172, 152, 151, 172, 173, 153, 152, 173, 174, 154, 153, 174, 175, 155, 154, 175, 176, 156, 155, 176, 177, 157, 156, 177, 178, 158, 157, 178, 179, 159, 158, 179, 180, 160, 159, 180, 181, 161, 160, 181, 182, 162, 161, 182, 183, 163, 162, 183, 184, 164, 163, 184, 185, 165, 164, 185, 186, 166, 165, 186, 187, 167, 166, 187, 188, 169, 168, 189, 190, 170, 169, 190, 191, 171, 170, 191, 192, 172, 171, 192, 193, 173, 172, 193, 194, 174, 173, 194, 195, 175, 174, 195, 196, 176, 175, 196, 197, 177, 176, 197, 198, 178, 177, 198, 199, 179, 178, 199, 200, 180, 179, 200, 201, 181, 180, 201, 202, 182, 181, 202, 203, 183, 182, 203, 204, 184, 183, 204, 205, 185, 184, 205, 206, 186, 185, 206, 207, 187, 186, 207, 208, 188, 187, 208, 209, 190, 189, 210, 211, 191, 190, 211, 212, 192, 191, 212, 213, 193, 192, 213, 214, 194, 193, 214, 215, 195, 194, 215, 216, 196, 195, 216, 217, 197, 196, 217, 218, 198, 197, 218, 219, 199, 198, 219, 220, 200, 199, 220, 221, 201, 200, 221, 222, 202, 201, 222, 223, 203, 202, 223, 224, 204, 203, 224, 225, 205, 204, 225, 226, 206, 205, 226, 227, 207, 206, 227, 228, 208, 207, 228, 229, 209, 208, 229, 230, 211, 210, 231, 232, 212, 211, 232, 233, 213, 212, 233, 234, 214, 213, 234, 235, 215, 214, 235, 236, 216, 215, 236, 237, 217, 216, 237, 238, 218, 217, 238, 239, 219, 218, 239, 240, 220, 219, 240, 241, 221, 220, 241, 242, 222, 221, 242, 243, 223, 222, 243, 244, 224, 223, 244, 245, 225, 224, 245, 246, 226, 225, 246, 247, 227, 226, 247, 248, 228, 227, 248, 249, 229, 228, 249, 250, 230, 229, 250, 251, 232, 231, 252, 253, 233, 232, 253, 254, 234, 233, 254, 255, 235, 234, 255, 256, 236, 235, 256, 257, 237, 236, 257, 258, 238, 237, 258, 259, 239, 238, 259, 260, 240, 239, 260, 261, 241, 240, 261, 262, 242, 241, 262, 263, 243, 242, 263, 264, 244, 243, 264, 265, 245, 244, 265, 266, 246, 245, 266, 267, 247, 246, 267, 268, 248, 247, 268, 269, 249, 248, 269, 270, 250, 249, 270, 271, 251, 250, 271, 272, 253, 252, 273, 274, 254, 253, 274, 275, 255, 254, 275, 276, 256, 255, 276, 277, 257, 256, 277, 278, 258, 257, 278, 279, 259, 258, 279, 280, 260, 259, 280, 281, 261, 260, 281, 282, 262, 261, 282, 283, 263, 262, 283, 284, 264, 263, 284, 285, 265, 264, 285, 286, 266, 265, 286, 287, 267, 266, 287, 288, 268, 267, 288, 289, 269, 268, 289, 290, 270, 269, 290, 291, 271, 270, 291, 292, 272, 271, 292, 293, 274, 273, 294, 295, 275, 274, 295, 296, 276, 275, 296, 297, 277, 276, 297, 298, 278, 277, 298, 299, 279, 278, 299, 300, 280, 279, 300, 301, 281, 280, 301, 302, 282, 281, 302, 303, 283, 282, 303, 304, 284, 283, 304, 305, 285, 284, 305, 306, 286, 285, 306, 307, 287, 286, 307, 308, 288, 287, 308, 309, 289, 288, 309, 310, 290, 289, 310, 311, 291, 290, 311, 312, 292, 291, 312, 313, 293, 292, 313, 314, 295, 294, 315, 316, 296, 295, 316, 317, 297, 296, 317, 318, 298, 297, 318, 319, 299, 298, 319, 320, 300, 299, 320, 321, 301, 300, 321, 322, 302, 301, 322, 323, 303, 302, 323, 324, 304, 303, 324, 325, 305, 304, 325, 326, 306, 305, 326, 327, 307, 306, 327, 328, 308, 307, 328, 329, 309, 308, 329, 330, 310, 309, 330, 331, 311, 310, 331, 332, 312, 311, 332, 333, 313, 312, 333, 334, 314, 313, 334, 335, 316, 315, 336, 337, 317, 316, 337, 338, 318, 317, 338, 339, 319, 318, 339, 340, 320, 319, 340, 341, 321, 320, 341, 342, 322, 321, 342, 343, 323, 322, 343, 344, 324, 323, 344, 345, 325, 324, 345, 346, 326, 325, 346, 347, 327, 326, 347, 348, 328, 327, 348, 349, 329, 328, 349, 350, 330, 329, 350, 351, 331, 330, 351, 352, 332, 331, 352, 353, 333, 332, 353, 354, 334, 333, 354, 355, 335, 334, 355, 356, 337, 336, 357, 358, 338, 337, 358, 359, 339, 338, 359, 360, 340, 339, 360, 361, 341, 340, 361, 362, 342, 341, 362, 363, 343, 342, 363, 364, 344, 343, 364, 365, 345, 344, 365, 366, 346, 345, 366, 367, 347, 346, 367, 368, 348, 347, 368, 369, 349, 348, 369, 370, 350, 349, 370, 371, 351, 350, 371, 372, 352, 351, 372, 373, 353, 352, 373, 374, 354, 353, 374, 375, 355, 354, 375, 376, 356, 355, 376, 377, 358, 357, 378, 379, 359, 358, 379, 380, 360, 359, 380, 381, 361, 360, 381, 382, 362, 361, 382, 383, 363, 362, 383, 384, 364, 363, 384, 385, 365, 364, 385, 386, 366, 365, 386, 387, 367, 366, 387, 388, 368, 367, 388, 389, 369, 368, 389, 390, 370, 369, 390, 391, 371, 370, 391, 392, 372, 371, 392, 393, 373, 372, 393, 394, 374, 373, 394, 395, 375, 374, 395, 396, 376, 375, 396, 397, 377, 376, 397, 398, 379, 378, 399, 400, 380, 379, 400, 401, 381, 380, 401, 402, 382, 381, 402, 403, 383, 382, 403, 404, 384, 383, 404, 405, 385, 384, 405, 406, 386, 385, 406, 407, 387, 386, 407, 408, 388, 387, 408, 409, 389, 388, 409, 410, 390, 389, 410, 411, 391, 390, 411, 412, 392, 391, 412, 413, 393, 392, 413, 414, 394, 393, 414, 415, 395, 394, 415, 416, 396, 395, 416, 417, 397, 396, 417, 418, 398, 397, 418, 419, 400, 399, 420, 421, 401, 400, 421, 422, 402, 401, 422, 423, 403, 402, 423, 424, 404, 403, 424, 425, 405, 404, 425, 426, 406, 405, 426, 427, 407, 406, 427, 428, 408, 407, 428, 429, 409, 408, 429, 430, 410, 409, 430, 431, 411, 410, 431, 432, 412, 411, 432, 433, 413, 412, 433, 434, 414, 413, 434, 435, 415, 414, 435, 436, 416, 415, 436, 437, 417, 416, 437, 438, 418, 417, 438, 439, 419, 418, 439, 440] + token visibility = "inherited" + float3 xformOp:scale = (1, 1, 3) + uniform token[] xformOpOrder = ["xformOp:scale"] + + def GeomSubset "GeomSubset" ( + prepend apiSchemas = ["MaterialBindingAPI"] + ) + { + uniform token elementType = "face" + uniform token familyName = "materialBind" + int[] indices = [0, 1, 2, 3, 19, 20, 21, 22, 23, 39, 40, 41, 42, 43, 44, 58, 59, 60, 61, 62, 63, 64, 78, 79, 80, 81, 82, 83, 84, 97, 98, 99, 100, 101, 102, 103, 104, 105, 117, 118, 119, 120, 121, 122, 123, 124, 125, 137, 138, 139, 140, 141, 142, 143, 144, 145, 157, 158, 159, 160, 161, 162, 163, 164, 165, 177, 178, 179, 180, 181, 182, 183, 184, 185, 197, 198, 199, 200, 201, 202, 203, 204, 205, 217, 218, 219, 220, 221, 222, 223, 224, 225, 237, 238, 239, 240, 241, 242, 243, 244, 245, 257, 258, 259, 260, 261, 262, 263, 264, 265, 277, 278, 279, 280, 281, 282, 283, 284, 285, 297, 298, 299, 300, 301, 302, 303, 304, 317, 318, 319, 320, 321, 322, 323, 324, 338, 339, 340, 341, 342, 343, 344, 358, 359, 360, 361, 362, 363, 379, 380, 381, 382, 399] + rel material:binding = + } +} + +def PointInstancer "SphereInstancer" +{ + point3f[] positions = [(5, 0, 0), (5, 5, 0)] + int[] protoIndices = [0, 0] + rel prototypes = +} + +def Scope "mtl" +{ + def Material "UsdPreviewSurface1" + { + token outputs:surface.connect = + + def Shader "UsdPreviewSurface1" + { + uniform token info:id = "UsdPreviewSurface" + color3f inputs:diffuseColor = (1, 1, 0) + float inputs:displacement = 1 + token outputs:surface + } + } + + def Material "UsdPreviewSurface2" + { + token outputs:surface.connect = + + def Shader "UsdPreviewSurface1" + { + uniform token info:id = "UsdPreviewSurface" + color3f inputs:diffuseColor = (1, 0, 0) + float inputs:displacement = 0 + token outputs:surface + } + } +} + From 21495762d3d56bc1d3975de01e4d4b90ebfb8e67 Mon Sep 17 00:00:00 2001 From: debloip Date: Tue, 28 Jan 2025 11:10:39 -0500 Subject: [PATCH 14/21] HYDRA-1286 : Add GeomSubset displacement test --- .../displacement.png | Bin 0 -> 56443 bytes .../testGeomSubsetsWireframeHighlight.py | 50 +++++++++++++----- ...reframeHighlightDisplacementTestScene.usda | 3 +- 3 files changed, 39 insertions(+), 14 deletions(-) create mode 100644 test/lib/mayaUsd/render/mayaToHydra/GeomSubsetsWireframeHighlightTest/displacement.png diff --git a/test/lib/mayaUsd/render/mayaToHydra/GeomSubsetsWireframeHighlightTest/displacement.png b/test/lib/mayaUsd/render/mayaToHydra/GeomSubsetsWireframeHighlightTest/displacement.png new file mode 100644 index 0000000000000000000000000000000000000000..9a396a9ce9e46eafab503561b4ad8df15aa4a0a9 GIT binary patch literal 56443 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%0Db#Ut5 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 Date: Tue, 28 Jan 2025 15:21:38 -0500 Subject: [PATCH 15/21] HYDRA-1286 : Go back to using only copy-pasted data sources from rerootingSceneIndex --- .../wireframeHighlights/fvpBaseWhSi.cpp | 90 ++++++++++++------- .../wireframeHighlights/fvpBaseWhSi.h | 26 ------ 2 files changed, 56 insertions(+), 60 deletions(-) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index eaf4be17c..bd3ffb184 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -298,52 +298,74 @@ class _RerootingSceneIndexPathArrayDataSource : public HdPathArrayDataSource HdPathArrayDataSourceHandle const _inputDataSource; }; -} - -namespace FVP_NS_DEF { - -TfTokenVector RepathingContainerDataSource::GetNames() +// Copied over from USD's rerootingSceneIndex.cpp +class _RerootingSceneIndexContainerDataSource : public HdContainerDataSource { - if (!_inputDataSource) { - return {}; +public: + HD_DECLARE_DATASOURCE(_RerootingSceneIndexContainerDataSource) + + _RerootingSceneIndexContainerDataSource( + const SdfPath &srcPrefix, + const SdfPath &dstPrefix, + HdContainerDataSourceHandle const &inputDataSource) + : _srcPrefix(srcPrefix) + , _dstPrefix(dstPrefix) + , _inputDataSource(inputDataSource) + { } - return _inputDataSource->GetNames(); -} + TfTokenVector GetNames() override + { + if (!_inputDataSource) { + return {}; + } -HdDataSourceBaseHandle RepathingContainerDataSource::Get(const TfToken& name) -{ - if (!_inputDataSource) { - return nullptr; + return _inputDataSource->GetNames(); } - // wrap child containers so that we can wrap their children - HdDataSourceBaseHandle const childSource = _inputDataSource->Get(name); - if (!childSource) { - return nullptr; - } + HdDataSourceBaseHandle Get(const TfToken& name) override + { + if (!_inputDataSource) { + return nullptr; + } - if (auto childContainer = - HdContainerDataSource::Cast(childSource)) { - return New(_srcPrefix, _dstPrefix, std::move(childContainer)); - } + // wrap child containers so that we can wrap their children + HdDataSourceBaseHandle const childSource = _inputDataSource->Get(name); + if (!childSource) { + return nullptr; + } - if (auto childPathDataSource = - HdTypedSampledDataSource::Cast(childSource)) { - return _RerootingSceneIndexPathDataSource::New( - _srcPrefix, _dstPrefix, childPathDataSource); - } + if (auto childContainer = + HdContainerDataSource::Cast(childSource)) { + return New(_srcPrefix, _dstPrefix, std::move(childContainer)); + } + + if (auto childPathDataSource = + HdTypedSampledDataSource::Cast(childSource)) { + return _RerootingSceneIndexPathDataSource::New( + _srcPrefix, _dstPrefix, childPathDataSource); + } - if (auto childPathArrayDataSource = - HdTypedSampledDataSource>::Cast( - childSource)) { - return _RerootingSceneIndexPathArrayDataSource::New( - _srcPrefix, _dstPrefix, childPathArrayDataSource); + if (auto childPathArrayDataSource = + HdTypedSampledDataSource>::Cast( + childSource)) { + return _RerootingSceneIndexPathArrayDataSource::New( + _srcPrefix, _dstPrefix, childPathArrayDataSource); + } + + return childSource; } - return childSource; +private: + const SdfPath _srcPrefix; + const SdfPath _dstPrefix; + HdContainerDataSourceHandle const _inputDataSource; +}; + } +namespace FVP_NS_DEF { + //We want to set the displayStyle of the selected prim to refinedWireOnSurf only if the displayStyle of the prim is refined (meaning shaded) HdContainerDataSourceHandle SetWireframeRepr(const HdContainerDataSourceHandle& dataSource, const GfVec4f& color) { @@ -422,7 +444,7 @@ PXR_NS::HdContainerDataSourceHandle RepathInstancingDataSources( if (auto containerDataSource = HdContainerDataSource::Cast(instancingDataSource)) { dataSourceEditor.Set( instancingDataSourceLocator, - RepathingContainerDataSource::New(srcPrefix, dstPrefix, containerDataSource) + _RerootingSceneIndexContainerDataSource::New(srcPrefix, dstPrefix, containerDataSource) ); } diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h index 4a5dd7884..99a799cba 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h @@ -30,32 +30,6 @@ namespace FVP_NS_DEF { -// Essentially a port of USD's _RerootingSceneIndexContainerDataSource in rerootingSceneIndex.cpp -class RepathingContainerDataSource : public PXR_NS::HdContainerDataSource -{ -public: - HD_DECLARE_DATASOURCE(RepathingContainerDataSource) - - RepathingContainerDataSource( - const PXR_NS::SdfPath &srcPrefix, - const PXR_NS::SdfPath &dstPrefix, - PXR_NS::HdContainerDataSourceHandle const &inputDataSource) - : _srcPrefix(srcPrefix) - , _dstPrefix(dstPrefix) - , _inputDataSource(inputDataSource) - { - } - - PXR_NS::TfTokenVector GetNames() override; - - PXR_NS::HdDataSourceBaseHandle Get(const PXR_NS::TfToken& name) override; - -private: - const PXR_NS::SdfPath _srcPrefix; - const PXR_NS::SdfPath _dstPrefix; - PXR_NS::HdContainerDataSourceHandle const _inputDataSource; -}; - using SelectionKey = std::pair; enum InstancingPathsCollectionDirection { From 1045c1593178d0694229e8f6fa677065686eb2f5 Mon Sep 17 00:00:00 2001 From: debloip Date: Tue, 28 Jan 2025 15:24:52 -0500 Subject: [PATCH 16/21] HYDRA-1286 : Handle conditional compilation --- lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp | 2 ++ lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index bd3ffb184..02203e12d 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -1063,6 +1063,7 @@ BaseWhSi::GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle return {}; } +#if PXR_VERSION >= 2403 PXR_NS::HdContainerDataSourceHandle BaseWhSi::MakeGeomSubsetHighlight( const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource, @@ -1094,5 +1095,6 @@ BaseWhSi::MakeGeomSubsetHighlight( return editedMeshPrimDataSource; } +#endif } diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h index 99a799cba..7659bfdb5 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h @@ -196,11 +196,13 @@ class BaseWhSi FVP_API PXR_NS::VtValue GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle& primDataSource) const; +#if PXR_VERSION >= 2403 // Given a mesh and geomSubset data sources, edits and returns the mesh data source to fit the given geomSubset FVP_API PXR_NS::HdContainerDataSourceHandle MakeGeomSubsetHighlight( const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource, const PXR_NS::HdContainerDataSourceHandle& geomSubsetPrimDataSource) const; +#endif const PXR_NS::SdfPath _highlightHierarchyPrefix; const std::shared_ptr _wireframeColorInterface; From 8fe7bd002d2937c8bb3b299ccbe1b635de3453f0 Mon Sep 17 00:00:00 2001 From: debloip Date: Tue, 28 Jan 2025 16:47:45 -0500 Subject: [PATCH 17/21] HYDRA-1286 : Additional conditional compilation --- .../sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index 02203e12d..b7cd0e23d 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -46,7 +46,9 @@ #include #include #include +#if PXR_VERSION >= 2403 #include +#endif #include #include @@ -699,7 +701,9 @@ PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerD // Block materials to prevent displacement from being re-applied dataSourceEditor.Set(HdMaterialBindingsSchema::GetDefaultLocator(), HdBlockDataSource::New()); +#if PXR_VERSION >= 2403 dataSourceEditor.Set(UsdImagingDirectMaterialBindingsSchema::GetDefaultLocator(), HdBlockDataSource::New()); +#endif return dataSourceEditor.Finish(); } From 49b45bfb7ce110b0fe576379f78f98d181cb8b15 Mon Sep 17 00:00:00 2001 From: debloip Date: Tue, 28 Jan 2025 17:12:17 -0500 Subject: [PATCH 18/21] HYDRA-1286 : Additional conditional compilation --- .../sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index b7cd0e23d..165cf4165 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -1054,8 +1054,13 @@ BaseWhSi::GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle } // Step 3: Look for the displacement value +#if PXR_VERSION < 2403 + HdDataSourceMaterialNetworkInterface materialNetworkInterface( + materialPath, materialSchema.GetMaterialNetwork(), primDataSource); +#else HdDataSourceMaterialNetworkInterface materialNetworkInterface( materialPath, materialSchema.GetMaterialNetwork().GetContainer(), primDataSource); +#endif for (auto nodeName : materialNetworkInterface.GetNodeNames()) { VtValue paramValue = materialNetworkInterface.GetNodeParameterValue(nodeName, HdMaterialTerminalTokens->displacement); From 5478876086827a357786ae188e0c17c79979d2ca Mon Sep 17 00:00:00 2001 From: debloip Date: Wed, 29 Jan 2025 11:28:42 -0500 Subject: [PATCH 19/21] HYDRA-1286 : Rename ComputeSmoothNormals --- .../sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp | 4 ++-- lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index 165cf4165..8116a27b0 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -575,7 +575,7 @@ TrimMeshForGeomSubset(const HdContainerDataSourceHandle& meshPrimDataSource, con } #endif -PXR_NS::HdContainerDataSourceHandle ComputeSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource) +PXR_NS::HdContainerDataSourceHandle AddSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource) { // Check if normals are already present auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshPrimDataSource, normalsValueLocator)); @@ -1086,7 +1086,7 @@ BaseWhSi::MakeGeomSubsetHighlight( // otherwise Storm will compute normals and displacement based on the trimmed mesh, which gives // incorrect results. Providing the normals primvar is not sufficient to fix this, so we must // do everything manually, including scaling. - editedMeshPrimDataSource = ComputeSmoothNormals(editedMeshPrimDataSource); + editedMeshPrimDataSource = AddSmoothNormals(editedMeshPrimDataSource); editedMeshPrimDataSource = ForceScale(editedMeshPrimDataSource); editedMeshPrimDataSource = ForceDisplacement(editedMeshPrimDataSource, displacementValue.UncheckedGet()); diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h index 7659bfdb5..d3d6c7989 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h @@ -238,7 +238,7 @@ TrimMeshForGeomSubset(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSou #endif // Computes and adds the normals primvar with smooth normals. If normals are already present, does nothing. -PXR_NS::HdContainerDataSourceHandle ComputeSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource); +PXR_NS::HdContainerDataSourceHandle AddSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource); // Manually apply scaling on the prim. PXR_NS::HdContainerDataSourceHandle ForceScale(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource); From 40f7d9d6425d26c65f9854ce3f4aad38bb917f33 Mon Sep 17 00:00:00 2001 From: debloip Date: Wed, 29 Jan 2025 11:31:41 -0500 Subject: [PATCH 20/21] HYDRA-1286 : Move transpose of inverse matrix out of loop --- .../sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp index 8116a27b0..7636cfc1c 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.cpp @@ -659,8 +659,9 @@ PXR_NS::HdContainerDataSourceHandle ForceScale(const PXR_NS::HdContainerDataSour auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshPrimDataSource, normalsValueLocator)); if (normalsValueDataSource) { auto normals = normalsValueDataSource->GetTypedValue(0); + auto xformMatrixInversedTransposed = xformMatrix.GetInverse().GetTranspose(); for (size_t iNormal = 0; iNormal < normals.size(); iNormal++) { - normals[iNormal] = GfVec3f(xformMatrix.GetInverse().GetTranspose().TransformDir(normals[iNormal])); + normals[iNormal] = GfVec3f(xformMatrixInversedTransposed.TransformDir(normals[iNormal])); normals[iNormal].Normalize(); } dataSourceEditor.Set(normalsValueLocator, HdRetainedTypedSampledDataSource>::New(normals)); From aefa92a7d04465721d7eb7cdb2cc1fe3da6b9d0f Mon Sep 17 00:00:00 2001 From: debloip Date: Wed, 29 Jan 2025 12:02:34 -0500 Subject: [PATCH 21/21] HYDRA-1286 : Extract out utility functions --- lib/flowViewport/fvpUtils.cpp | 206 ++++++++++++++++++ lib/flowViewport/fvpUtils.h | 22 ++ .../wireframeHighlights/fvpBaseWhSi.cpp | 188 +--------------- .../wireframeHighlights/fvpBaseWhSi.h | 21 -- 4 files changed, 229 insertions(+), 208 deletions(-) diff --git a/lib/flowViewport/fvpUtils.cpp b/lib/flowViewport/fvpUtils.cpp index b5e0612ce..b5fecdc47 100644 --- a/lib/flowViewport/fvpUtils.cpp +++ b/lib/flowViewport/fvpUtils.cpp @@ -15,8 +15,39 @@ #include "fvpUtils.h" +#include +#include +#include #include +#include +#include +#include +#include +#include #include +#include +#include +#include + +PXR_NAMESPACE_USING_DIRECTIVE + +namespace { + +const HdDataSourceLocator pointsValueLocator = HdDataSourceLocator( + HdPrimvarsSchemaTokens->primvars, + HdPrimvarsSchemaTokens->points, + HdPrimvarSchemaTokens->primvarValue); + +const HdDataSourceLocator normalsPrimvarLocator = HdDataSourceLocator( + HdPrimvarsSchemaTokens->primvars, + HdPrimvarsSchemaTokens->normals); + +const HdDataSourceLocator normalsValueLocator = HdDataSourceLocator( + HdPrimvarsSchemaTokens->primvars, + HdPrimvarsSchemaTokens->normals, + HdPrimvarSchemaTokens->primvarValue); + +} namespace FVP_NS_DEF { @@ -56,4 +87,179 @@ PXR_NS::HdDataSourceBaseHandle createSelectionDataSource(const Fvp::PrimSelectio return PXR_NS::HdDataSourceBase::Cast(selectionBuilder.Build()); } +Fvp::PrimSelection ConvertHydraToFvpSelection(const SdfPath& primPath, const HdSelectionSchema& selectionSchema) { + Fvp::PrimSelection primSelection; + primSelection.primPath = primPath; + + auto nestedInstanceIndicesSchema = +#if HD_API_VERSION < 66 + const_cast(selectionSchema).GetNestedInstanceIndices(); +#else + selectionSchema.GetNestedInstanceIndices(); +#endif + for (size_t iNestedInstanceIndices = 0; iNestedInstanceIndices < nestedInstanceIndicesSchema.GetNumElements(); iNestedInstanceIndices++) { + HdInstanceIndicesSchema instanceIndicesSchema = nestedInstanceIndicesSchema.GetElement(iNestedInstanceIndices); + auto instanceIndices = instanceIndicesSchema.GetInstanceIndices()->GetTypedValue(0); + primSelection.nestedInstanceIndices.push_back( + { + instanceIndicesSchema.GetInstancer()->GetTypedValue(0), + instanceIndicesSchema.GetPrototypeIndex()->GetTypedValue(0), + std::vector(instanceIndices.begin(), instanceIndices.end()) + } + ); + } + + return primSelection; +} + +SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSource) +{ + if (!primDataSource) { + return {}; + } + + HdMaterialBindingsSchema materialBindingsSchema = HdMaterialBindingsSchema::GetFromParent(primDataSource); + if (!materialBindingsSchema.IsDefined()) { + return {}; + } + + HdMaterialBindingSchema materialBindingSchema = materialBindingsSchema.GetMaterialBinding(); + if (!materialBindingSchema) { + return {}; + } + + HdPathDataSourceHandle bindingPathDataSource = materialBindingSchema.GetPath(); + if (!bindingPathDataSource) { + return {}; + } + + return bindingPathDataSource->GetTypedValue(0); +} + +VtValue GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle& primDataSource, const PXR_NS::HdSceneIndexBase& sceneIndex) +{ + if (!primDataSource) { + return {}; + } + + // Step 1: Get the material path + const SdfPath materialPath = GetMaterialPath(primDataSource); + if (materialPath.IsEmpty()) { + return {}; + } + + // Step 2: Retrieve the material + HdSceneIndexPrim materialPrim = sceneIndex.GetPrim(materialPath); + if (!materialPrim.dataSource || (materialPrim.primType != HdPrimTypeTokens->material) ){ + return {}; + } + + HdMaterialSchema materialSchema = HdMaterialSchema::GetFromParent(materialPrim.dataSource); + if (!materialSchema.IsDefined()) { + return {}; + } + + // Step 3: Look for the displacement value +#if PXR_VERSION < 2403 + HdDataSourceMaterialNetworkInterface materialNetworkInterface( + materialPath, materialSchema.GetMaterialNetwork(), primDataSource); +#else + HdDataSourceMaterialNetworkInterface materialNetworkInterface( + materialPath, materialSchema.GetMaterialNetwork().GetContainer(), primDataSource); +#endif + + for (auto nodeName : materialNetworkInterface.GetNodeNames()) { + VtValue paramValue = materialNetworkInterface.GetNodeParameterValue(nodeName, HdMaterialTerminalTokens->displacement); + if (paramValue.IsHolding()) { + return paramValue; + } + } + + return {}; +} + +PXR_NS::HdContainerDataSourceHandle AddSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource) +{ + // Check if normals are already present + auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshPrimDataSource, normalsValueLocator)); + if (normalsValueDataSource) { + return meshPrimDataSource; + } + + // Get required schemas/dataSources + HdMeshSchema meshSchema = HdMeshSchema::GetFromParent(meshPrimDataSource); + if (!meshSchema.IsDefined()) { + return meshPrimDataSource; + } + HdMeshTopologySchema meshTopologySchema = meshSchema.GetTopology(); + if (!meshTopologySchema.IsDefined()) { + return meshPrimDataSource; + } + auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshPrimDataSource, pointsValueLocator)); + if (!pointsValueDataSource) { + return meshPrimDataSource; + } + + // Setup topology + TfToken subdivScheme = PxOsdOpenSubdivTokens->none; + if (HdTokenDataSourceHandle subdivSchemeDataSource = meshSchema.GetSubdivisionScheme()) { + subdivScheme = subdivSchemeDataSource->GetTypedValue(0.0f); + } + VtIntArray holeIndices; + if (HdIntArrayDataSourceHandle holeIndicesDataSource = meshTopologySchema.GetHoleIndices()) { + holeIndices = holeIndicesDataSource->GetTypedValue(0.0f); + } + TfToken orientation = PxOsdOpenSubdivTokens->rightHanded; + if (HdTokenDataSourceHandle orientationDataSource = meshTopologySchema.GetOrientation()) { + orientation = orientationDataSource->GetTypedValue(0.0f); + } + HdMeshTopology meshTopology( + subdivScheme, + orientation, + meshTopologySchema.GetFaceVertexCounts()->GetTypedValue(0), + meshTopologySchema.GetFaceVertexIndices()->GetTypedValue(0), + holeIndices); + Hd_VertexAdjacency adjacency; + adjacency.BuildAdjacencyTable(&meshTopology); + + // Compute normals + auto points = pointsValueDataSource->GetTypedValue(0); + auto normals = Hd_SmoothNormals::ComputeSmoothNormals( + &adjacency, static_cast(points.size()), points.cdata()); + + // Add normals + auto normalsPrimvarDataSource = HdPrimvarSchema::Builder() + .SetInterpolation(HdPrimvarSchema::BuildInterpolationDataSource(HdPrimvarSchemaTokens->vertex)) + .SetRole(HdPrimvarSchema::BuildRoleDataSource(HdPrimvarSchemaTokens->normal)) + .SetPrimvarValue(HdRetainedTypedSampledDataSource::New(normals)) + .Build(); + HdContainerDataSourceEditor dataSourceEditor(meshPrimDataSource); + dataSourceEditor.Set(normalsPrimvarLocator, normalsPrimvarDataSource); + return dataSourceEditor.Finish(); +} + +PXR_NS::HdContainerDataSourceHandle AddDependency( + const PXR_NS::HdContainerDataSourceHandle& primDataSource, + const PXR_NS::TfToken& dependencyToken, + const PXR_NS::SdfPath& dependedOnPrimPath, + const PXR_NS::HdDataSourceLocator& dependedOnDataSourceLocator, + const PXR_NS::HdDataSourceLocator& affectedDataSourceLocator) +{ + HdDependencySchema::Builder builder; + + if (!dependedOnPrimPath.IsEmpty()) { + builder.SetDependedOnPrimPath(HdRetainedTypedSampledDataSource::New(dependedOnPrimPath)); + } + + builder.SetDependedOnDataSourceLocator(HdRetainedTypedSampledDataSource::New(dependedOnDataSourceLocator)); + + builder.SetAffectedDataSourceLocator(HdRetainedTypedSampledDataSource::New(affectedDataSourceLocator)); + + auto dependencyDataSource = HdRetainedContainerDataSource::New(dependencyToken, builder.Build()); + + HdContainerDataSourceEditor dataSourceEditor(primDataSource); + dataSourceEditor.Overlay(HdDependenciesSchema::GetDefaultLocator(), dependencyDataSource); + return dataSourceEditor.Finish(); +} + } // namespace FVP_NS_DEF diff --git a/lib/flowViewport/fvpUtils.h b/lib/flowViewport/fvpUtils.h index 91e3ac902..997c3647c 100644 --- a/lib/flowViewport/fvpUtils.h +++ b/lib/flowViewport/fvpUtils.h @@ -15,6 +15,7 @@ #ifndef FVP_UTILS_H #define FVP_UTILS_H +#include #include #include @@ -24,6 +25,7 @@ #include #include +#include #include namespace FVP_NS_DEF { @@ -125,6 +127,26 @@ auto FindSelfOrFirstChild(const PXR_NS::SdfPath& path, const std::map #include #include -#include -#include #include #include #include @@ -39,13 +37,9 @@ #include #include #include -#include #include -#include #include -#include #include -#include #if PXR_VERSION >= 2403 #include #endif @@ -85,10 +79,6 @@ const HdDataSourceLocator pointsValueLocator = HdDataSourceLocator( HdPrimvarsSchemaTokens->points, HdPrimvarSchemaTokens->primvarValue); -const HdDataSourceLocator normalsPrimvarLocator = HdDataSourceLocator( - HdPrimvarsSchemaTokens->primvars, - HdPrimvarsSchemaTokens->normals); - const HdDataSourceLocator normalsValueLocator = HdDataSourceLocator( HdPrimvarsSchemaTokens->primvars, HdPrimvarsSchemaTokens->normals, @@ -401,31 +391,6 @@ HdContainerDataSourceHandle SetWireframeRepr(const HdContainerDataSourceHandle& return edited.Finish(); } -Fvp::PrimSelection ConvertHydraToFvpSelection(const SdfPath& primPath, const HdSelectionSchema& selectionSchema) { - Fvp::PrimSelection primSelection; - primSelection.primPath = primPath; - - auto nestedInstanceIndicesSchema = -#if HD_API_VERSION < 66 - const_cast(selectionSchema).GetNestedInstanceIndices(); -#else - selectionSchema.GetNestedInstanceIndices(); -#endif - for (size_t iNestedInstanceIndices = 0; iNestedInstanceIndices < nestedInstanceIndicesSchema.GetNumElements(); iNestedInstanceIndices++) { - HdInstanceIndicesSchema instanceIndicesSchema = nestedInstanceIndicesSchema.GetElement(iNestedInstanceIndices); - auto instanceIndices = instanceIndicesSchema.GetInstanceIndices()->GetTypedValue(0); - primSelection.nestedInstanceIndices.push_back( - { - instanceIndicesSchema.GetInstancer()->GetTypedValue(0), - instanceIndicesSchema.GetPrototypeIndex()->GetTypedValue(0), - std::vector(instanceIndices.begin(), instanceIndices.end()) - } - ); - } - - return primSelection; -} - PXR_NS::HdContainerDataSourceHandle RepathInstancingDataSources( const PXR_NS::HdContainerDataSourceHandle& primDataSource, const PXR_NS::SdfPath& srcPrefix, @@ -467,30 +432,6 @@ PXR_NS::HdContainerDataSourceHandle RepathInstancingDataSources( return dataSourceEditor.Finish(); } -SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSource) -{ - if (!primDataSource) { - return {}; - } - - HdMaterialBindingsSchema materialBindingsSchema = HdMaterialBindingsSchema::GetFromParent(primDataSource); - if (!materialBindingsSchema.IsDefined()) { - return {}; - } - - HdMaterialBindingSchema materialBindingSchema = materialBindingsSchema.GetMaterialBinding(); - if (!materialBindingSchema) { - return {}; - } - - HdPathDataSourceHandle bindingPathDataSource = materialBindingSchema.GetPath(); - if (!bindingPathDataSource) { - return {}; - } - - return bindingPathDataSource->GetTypedValue(0); -} - #if PXR_VERSION >= 2403 HdContainerDataSourceHandle TrimMeshForGeomSubset(const HdContainerDataSourceHandle& meshPrimDataSource, const HdContainerDataSourceHandle& geomSubsetPrimDataSource) @@ -575,66 +516,6 @@ TrimMeshForGeomSubset(const HdContainerDataSourceHandle& meshPrimDataSource, con } #endif -PXR_NS::HdContainerDataSourceHandle AddSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource) -{ - // Check if normals are already present - auto normalsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshPrimDataSource, normalsValueLocator)); - if (normalsValueDataSource) { - return meshPrimDataSource; - } - - // Get required schemas/dataSources - HdMeshSchema meshSchema = HdMeshSchema::GetFromParent(meshPrimDataSource); - if (!meshSchema.IsDefined()) { - return meshPrimDataSource; - } - HdMeshTopologySchema meshTopologySchema = meshSchema.GetTopology(); - if (!meshTopologySchema.IsDefined()) { - return meshPrimDataSource; - } - auto pointsValueDataSource = HdTypedSampledDataSource>::Cast(HdContainerDataSource::Get(meshPrimDataSource, pointsValueLocator)); - if (!pointsValueDataSource) { - return meshPrimDataSource; - } - - // Setup topology - TfToken subdivScheme = PxOsdOpenSubdivTokens->none; - if (HdTokenDataSourceHandle subdivSchemeDataSource = meshSchema.GetSubdivisionScheme()) { - subdivScheme = subdivSchemeDataSource->GetTypedValue(0.0f); - } - VtIntArray holeIndices; - if (HdIntArrayDataSourceHandle holeIndicesDataSource = meshTopologySchema.GetHoleIndices()) { - holeIndices = holeIndicesDataSource->GetTypedValue(0.0f); - } - TfToken orientation = PxOsdOpenSubdivTokens->rightHanded; - if (HdTokenDataSourceHandle orientationDataSource = meshTopologySchema.GetOrientation()) { - orientation = orientationDataSource->GetTypedValue(0.0f); - } - HdMeshTopology meshTopology( - subdivScheme, - orientation, - meshTopologySchema.GetFaceVertexCounts()->GetTypedValue(0), - meshTopologySchema.GetFaceVertexIndices()->GetTypedValue(0), - holeIndices); - Hd_VertexAdjacency adjacency; - adjacency.BuildAdjacencyTable(&meshTopology); - - // Compute normals - auto points = pointsValueDataSource->GetTypedValue(0); - auto normals = Hd_SmoothNormals::ComputeSmoothNormals( - &adjacency, static_cast(points.size()), points.cdata()); - - // Apply normals - auto normalsPrimvarDataSource = HdPrimvarSchema::Builder() - .SetInterpolation(HdPrimvarSchema::BuildInterpolationDataSource(HdPrimvarSchemaTokens->vertex)) - .SetRole(HdPrimvarSchema::BuildRoleDataSource(HdPrimvarSchemaTokens->normal)) - .SetPrimvarValue(HdRetainedTypedSampledDataSource::New(normals)) - .Build(); - HdContainerDataSourceEditor dataSourceEditor(meshPrimDataSource); - dataSourceEditor.Set(normalsPrimvarLocator, normalsPrimvarDataSource); - return dataSourceEditor.Finish(); -} - PXR_NS::HdContainerDataSourceHandle ForceScale(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource) { auto xformSchema = HdXformSchema::GetFromParent(meshPrimDataSource); @@ -709,30 +590,6 @@ PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerD return dataSourceEditor.Finish(); } -PXR_NS::HdContainerDataSourceHandle AddDependency( - const PXR_NS::HdContainerDataSourceHandle& primDataSource, - const PXR_NS::TfToken& dependencyToken, - const PXR_NS::SdfPath& dependedOnPrimPath, - const PXR_NS::HdDataSourceLocator& dependedOnDataSourceLocator, - const PXR_NS::HdDataSourceLocator& affectedDataSourceLocator) -{ - HdDependencySchema::Builder builder; - - if (!dependedOnPrimPath.IsEmpty()) { - builder.SetDependedOnPrimPath(HdRetainedTypedSampledDataSource::New(dependedOnPrimPath)); - } - - builder.SetDependedOnDataSourceLocator(HdRetainedTypedSampledDataSource::New(dependedOnDataSourceLocator)); - - builder.SetAffectedDataSourceLocator(HdRetainedTypedSampledDataSource::New(affectedDataSourceLocator)); - - auto dependencyDataSource = HdRetainedContainerDataSource::New(dependencyToken, builder.Build()); - - HdContainerDataSourceEditor dataSourceEditor(primDataSource); - dataSourceEditor.Overlay(HdDependenciesSchema::GetDefaultLocator(), dependencyDataSource); - return dataSourceEditor.Finish(); -} - BaseWhSi::BaseWhSi( const PXR_NS::HdSceneIndexBaseRefPtr& inputSceneIndex, const PXR_NS::SdfPath& highlightHierarchyPrefix, @@ -1030,49 +887,6 @@ BaseWhSi::CollectInstancingPaths(const PXR_NS::SdfPath& primPath, InstancingPath } } -VtValue -BaseWhSi::GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle& primDataSource) const -{ - if (!primDataSource) { - return {}; - } - - // Step 1: Get the material path - const SdfPath materialPath = GetMaterialPath(primDataSource); - if (materialPath.IsEmpty()) { - return {}; - } - - // Step 2: Retrieve the material - HdSceneIndexPrim materialPrim = GetInputSceneIndex()->GetPrim(materialPath); - if (!materialPrim.dataSource || (materialPrim.primType != HdPrimTypeTokens->material) ){ - return {}; - } - - HdMaterialSchema materialSchema = HdMaterialSchema::GetFromParent(materialPrim.dataSource); - if (!materialSchema.IsDefined()) { - return {}; - } - - // Step 3: Look for the displacement value -#if PXR_VERSION < 2403 - HdDataSourceMaterialNetworkInterface materialNetworkInterface( - materialPath, materialSchema.GetMaterialNetwork(), primDataSource); -#else - HdDataSourceMaterialNetworkInterface materialNetworkInterface( - materialPath, materialSchema.GetMaterialNetwork().GetContainer(), primDataSource); -#endif - - for (auto nodeName : materialNetworkInterface.GetNodeNames()) { - VtValue paramValue = materialNetworkInterface.GetNodeParameterValue(nodeName, HdMaterialTerminalTokens->displacement); - if (paramValue.IsHolding()) { - return paramValue; - } - } - - return {}; -} - #if PXR_VERSION >= 2403 PXR_NS::HdContainerDataSourceHandle BaseWhSi::MakeGeomSubsetHighlight( @@ -1081,7 +895,7 @@ BaseWhSi::MakeGeomSubsetHighlight( { HdContainerDataSourceHandle editedMeshPrimDataSource = meshPrimDataSource; - VtValue displacementValue = GetMaterialDisplacementValue(geomSubsetPrimDataSource); + VtValue displacementValue = GetMaterialDisplacementValue(geomSubsetPrimDataSource, *GetInputSceneIndex()); if (displacementValue.IsHolding()) { // Manually apply the displacement on the mesh. We need to do this before trimming the mesh; // otherwise Storm will compute normals and displacement based on the trimmed mesh, which gives diff --git a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h index d3d6c7989..9a75070f0 100644 --- a/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h +++ b/lib/flowViewport/sceneIndex/wireframeHighlights/fvpBaseWhSi.h @@ -192,10 +192,6 @@ class BaseWhSi FVP_API void CollectInstancingPaths(const PXR_NS::SdfPath& primPath, InstancingPathsCollectionDirection direction, PXR_NS::SdfPathSet& outInstancerPaths, PXR_NS::SdfPathSet& outPrototypePaths) const; - // Return the displacement value from the given prim data source's assigned material - FVP_API - PXR_NS::VtValue GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle& primDataSource) const; - #if PXR_VERSION >= 2403 // Given a mesh and geomSubset data sources, edits and returns the mesh data source to fit the given geomSubset FVP_API @@ -218,9 +214,6 @@ class BaseWhSi // Make the given prim be drawn as a wireframe of the given color. PXR_NS::HdContainerDataSourceHandle SetWireframeRepr(const PXR_NS::HdContainerDataSourceHandle& dataSource, const PXR_NS::GfVec4f& color); -// Return a Fvp::PrimSelection equivalent to the given Hydra selection -Fvp::PrimSelection ConvertHydraToFvpSelection(const PXR_NS::SdfPath& primPath, const PXR_NS::HdSelectionSchema& selectionSchema); - // Repath instancing-related data sources by replacing srcPrefix with dstPrefix. // Mainly used to setup selection highlight instancers and instances. PXR_NS::HdContainerDataSourceHandle RepathInstancingDataSources( @@ -228,32 +221,18 @@ PXR_NS::HdContainerDataSourceHandle RepathInstancingDataSources( const PXR_NS::SdfPath& srcPrefix, const PXR_NS::SdfPath& dstPrefix); -// Get the path to the prim's bound material. -PXR_NS::SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSource); - #if PXR_VERSION >= 2403 // Edit the given mesh data source such that its topology matches the given geomSubset. PXR_NS::HdContainerDataSourceHandle TrimMeshForGeomSubset(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource, const PXR_NS::HdContainerDataSourceHandle& geomSubsetPrimDataSource); #endif -// Computes and adds the normals primvar with smooth normals. If normals are already present, does nothing. -PXR_NS::HdContainerDataSourceHandle AddSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource); - // Manually apply scaling on the prim. PXR_NS::HdContainerDataSourceHandle ForceScale(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource); // Manually apply displacement on the prim. PXR_NS::HdContainerDataSourceHandle ForceDisplacement(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource, float displacement); -// Add an entry to the __dependencies data source -PXR_NS::HdContainerDataSourceHandle AddDependency( - const PXR_NS::HdContainerDataSourceHandle& primDataSource, - const PXR_NS::TfToken& dependencyToken, - const PXR_NS::SdfPath& dependedOnPrimPath, - const PXR_NS::HdDataSourceLocator& dependedOnDataSourceLocator, - const PXR_NS::HdDataSourceLocator& affectedDataSourceLocator); - } #endif // FVP_BASE_WH_SI_H