From a0a47972201e6addbfe3bb0e0226ec074e75ac74 Mon Sep 17 00:00:00 2001 From: debloip Date: Wed, 15 May 2024 11:21:25 -0400 Subject: [PATCH 001/112] Working point instancer highlighting with the different nested/propagated cases --- .../fvpDataProducerSceneIndexExample.cpp | 35 +- ...pWireframeSelectionHighlightSceneIndex.cpp | 974 +++++++++++++++++- ...fvpWireframeSelectionHighlightSceneIndex.h | 37 + 3 files changed, 1030 insertions(+), 16 deletions(-) diff --git a/lib/flowViewport/API/samples/fvpDataProducerSceneIndexExample.cpp b/lib/flowViewport/API/samples/fvpDataProducerSceneIndexExample.cpp index 56a0e22eec..a87f377096 100644 --- a/lib/flowViewport/API/samples/fvpDataProducerSceneIndexExample.cpp +++ b/lib/flowViewport/API/samples/fvpDataProducerSceneIndexExample.cpp @@ -21,6 +21,10 @@ //Local headers #include "fvpDataProducerSceneIndexExample.h" +#include +#include +#include +#include #ifdef CODE_COVERAGE_WORKAROUND #include @@ -223,13 +227,26 @@ void DataProducerSceneIndexExample::_AddAllPrims() void DataProducerSceneIndexExample::_AddAllPrimsWithInstancing() { static const bool instancing = true; - + GfMatrix4d instanceeTransform; + instanceeTransform.SetTranslate(GfVec3d(1.67, 1.67, 1.67)); //Copy the main cube primitive in the array, we will update only the SdfPath and the transform, all others attributes are identical - HdRetainedSceneIndex::AddedPrimEntry cubePrimEntry = _CreateCubePrim(_cubeRootPath, _currentCubeGridParams._halfSize, + SdfPath cubePath = _cubeRootPath.AppendElementString("_mesh"); + HdRetainedSceneIndex::AddedPrimEntry cubePrimEntry = _CreateCubePrim(cubePath, _currentCubeGridParams._halfSize, _currentCubeGridParams._color, _currentCubeGridParams._opacity, - _currentCubeGridParams._initalTransform, instancing); + instanceeTransform, instancing); + const HdDataSourceBaseHandle cubeRootInstancedByData = + HdInstancedBySchema::Builder() + .SetPaths(HdRetainedTypedSampledDataSource>::New(VtArray({ _instancerPath }))) + .SetPrototypeRoots(HdRetainedTypedSampledDataSource>::New(VtArray({ _cubeRootPath }))) + .Build(); + HdRetainedSceneIndex::AddedPrimEntry cubeRoot; + cubeRoot.primPath = _cubeRootPath; + cubeRoot.dataSource = HdRetainedContainerDataSource::New( + HdInstancedBySchema::GetSchemaToken(), cubeRootInstancedByData + ); //Add the cube to the retained scene index + _retainedSceneIndex->AddPrims({cubeRoot}); _retainedSceneIndex->AddPrims({cubePrimEntry}); const size_t totalSize = _currentCubeGridParams._numLevelsX * _currentCubeGridParams._numLevelsY * _currentCubeGridParams._numLevelsZ; @@ -258,7 +275,7 @@ void DataProducerSceneIndexExample::_AddAllPrimsWithInstancing() prototypeIndices[index] = index; //Update translation - matrices[index].SetTranslate(initTrans + (GfCompMult(_currentCubeGridParams._deltaTrans, GfVec3f(x,y,z)))); + matrices[index].SetTranslate(initTrans + (GfCompMult(_currentCubeGridParams._deltaTrans, GfVec3f(x + 2,y + 2,z + 2)))); } } } @@ -267,6 +284,9 @@ void DataProducerSceneIndexExample::_AddAllPrimsWithInstancing() //Add new prims to the scene index PrototypeInstancing::createInstancer(_instancerPath, _cubeRootPath, prototypeIndices, matrices, _retainedSceneIndex); + //SdfPath cubePath = _instancerPath.AppendElementString("MyCube"); + //auto cube = _CreateCubePrim(cubePath, 2, GfVec3f(1, 0, 0), 1.0, GfMatrix4d(1), false); + //_retainedSceneIndex->AddPrims({cube}); } void DataProducerSceneIndexExample::_AddAllPrimsNoInstancing() @@ -494,9 +514,10 @@ HdRetainedSceneIndex::AddedPrimEntry DataProducerSceneIndexExample::_CreateCubeP addedPrim.primType = HdPrimTypeTokens->mesh; if (instanced){ - const HdDataSourceBaseHandle instancedByData = + const HdDataSourceBaseHandle cubeInstancedByData = HdInstancedBySchema::Builder() .SetPaths(HdRetainedTypedSampledDataSource>::New(VtArray({ _instancerPath }))) + .SetPrototypeRoots(HdRetainedTypedSampledDataSource>::New(VtArray({ _cubeRootPath }))) .Build(); addedPrim.dataSource = HdRetainedContainerDataSource::New( @@ -523,8 +544,8 @@ HdRetainedSceneIndex::AddedPrimEntry DataProducerSceneIndexExample::_CreateCubeP HdPrimvarsSchemaTokens->primvars, primvarsDs, - HdInstancedBySchema::GetSchemaToken(), //Add the instancer path in the HdInstancedBySchema - instancedByData + HdInstancedBySchema::GetSchemaToken(), + cubeInstancedByData ); }else{ diff --git a/lib/flowViewport/sceneIndex/fvpWireframeSelectionHighlightSceneIndex.cpp b/lib/flowViewport/sceneIndex/fvpWireframeSelectionHighlightSceneIndex.cpp index dfaf66b3ce..893cad2a4a 100644 --- a/lib/flowViewport/sceneIndex/fvpWireframeSelectionHighlightSceneIndex.cpp +++ b/lib/flowViewport/sceneIndex/fvpWireframeSelectionHighlightSceneIndex.cpp @@ -19,12 +19,35 @@ #include "flowViewport/fvpUtils.h" #include "flowViewport/debugCodes.h" +#include "fvpWireframeSelectionHighlightSceneIndex.h" +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include PXR_NAMESPACE_USING_DIRECTIVE @@ -50,10 +73,370 @@ const HdDataSourceLocator reprSelectorLocator( const HdDataSourceLocator primvarsOverrideWireframeColorLocator( HdPrimvarsSchema::GetDefaultLocator().Append(_primVarsTokens->overrideWireframeColor)); + +const std::string testInstancer = "ParentPointInstancer"; + +const std::string shMirrorTag = "_SHMirror"; + +class SelectionHighlightDataSource : public HdContainerDataSource +{ +public: + HD_DECLARE_DATASOURCE(SelectionHighlightDataSource); + + SelectionHighlightDataSource(const HdContainerDataSourceHandle& originalDataSource) : _originalDataSource(originalDataSource) + { + } + + TfTokenVector GetNames() override { + TfTokenVector names = _originalDataSource->GetNames(); + /*names.erase(std::remove_if(names.begin(), names.end(), [](const TfToken& token) -> bool { + return token == HdSelectionsSchemaTokens->selections; + }));*/ + return names; + } + + HdDataSourceBaseHandle Get(const TfToken &name) override + { + return _originalDataSource->Get(name); + } + +private: + HdContainerDataSourceHandle _originalDataSource; +}; + +bool _IsSelectionHighlightMirrorPath(const SdfPath& path) +{ + return path.GetElementString().find(shMirrorTag) != std::string::npos; +} + +SdfPath _GetSelectionHighlightMirrorPathFromOriginal(const SdfPath& originalPath) +{ + return originalPath.GetParentPath().AppendElementString(originalPath.GetElementString() + shMirrorTag); +} + +SdfPath _GetOriginalPathFromSelectionHighlightMirror(const SdfPath& mirrorPath) +{ + return mirrorPath.GetParentPath().AppendElementString(mirrorPath.GetElementString().substr(0, mirrorPath.GetElementString().size() - shMirrorTag.size())); +} + +VtBoolArray _GetSelectionHighlightMask(const VtBoolArray& originalMask, const HdSelectionsSchema& selections) +{ + VtBoolArray selectionHighlightMask(originalMask.size(), false); + + for (size_t iSelection = 0; iSelection < selections.GetNumElements(); iSelection++) { + HdSelectionSchema selection = selections.GetElement(iSelection); + if (!selection.GetFullySelected() || !selection.GetFullySelected()->GetTypedValue(0)) { + continue; + } + HdInstanceIndicesVectorSchema nestedInstanceIndices = selection.GetNestedInstanceIndices(); + for (size_t iInstanceIndices = 0; iInstanceIndices < nestedInstanceIndices.GetNumElements(); iInstanceIndices++) { + HdInstanceIndicesSchema instanceIndices = nestedInstanceIndices.GetElement(0); + for (const auto& instanceIndex : instanceIndices.GetInstanceIndices()->GetTypedValue(0)) { + selectionHighlightMask[instanceIndex] = originalMask[instanceIndex]; + } + } + } + + return selectionHighlightMask; +} + +HdContainerDataSourceHandle _CreateSelectionHighlightInstancer(const SdfPath& originalPath, const HdContainerDataSourceHandle& originalDataSource) +{ + +} + +HdContainerDataSourceHandle _GetSelectionHighlightInstancerDataSource(const HdContainerDataSourceHandle& originalDataSource) +{ + HdInstancerTopologySchema instancerTopology = HdInstancerTopologySchema::GetFromParent(originalDataSource); + HdSelectionsSchema selections = HdSelectionsSchema::GetFromParent(originalDataSource); + + HdContainerDataSourceEditor editedDataSource = HdContainerDataSourceEditor(originalDataSource); + + + HdDataSourceLocator maskLocator(TfToken("instancerTopology"), TfToken("mask")); + VtBoolArray originalMask = instancerTopology.GetMask()->GetTypedValue(0); + //VtBoolArray selectionHighlightMask = _GetSelectionHighlightMask(originalMask, selections); + VtBoolArray selectionHighlightMask = {true, false}; + auto selectionHighlightMaskDataSource = HdRetainedTypedSampledDataSource::New(selectionHighlightMask); + editedDataSource.Set(maskLocator, selectionHighlightMaskDataSource); + + HdDataSourceLocator prototypesLocator(TfToken("instancerTopology"), TfToken("prototypes")); + VtArray originalPrototypes = instancerTopology.GetPrototypes()->GetTypedValue(0); + VtArray selectionHighlightPrototypes = originalPrototypes; + for (auto& shProtoPath : selectionHighlightPrototypes) { + shProtoPath = _GetSelectionHighlightMirrorPathFromOriginal(shProtoPath); + } + editedDataSource.Set(prototypesLocator, HdRetainedTypedSampledDataSource>::New(selectionHighlightPrototypes)); + + return SelectionHighlightDataSource::New(editedDataSource.Finish()); +} + + + +// HdContainerDataSourceHandle _FilterInstances(const HdContainerDataSourceHandle& dataSource) +// { +// auto edited = HdContainerDataSourceEditor(dataSource); +// HdDataSourceLocator maskLocator(TfToken("instancerTopology"), TfToken("mask")); +// auto replacementDataSource = HdRetainedTypedSampledDataSource::New(VtBoolArray({true, false, true, false, true, true, false, false})); +// edited.Set(maskLocator, replacementDataSource); + + +// // //Is the prim in refined displayStyle (meaning shaded) ? +// // if (HdLegacyDisplayStyleSchema styleSchema = +// // HdLegacyDisplayStyleSchema::GetFromParent(dataSource)) { + +// // if (HdTokenArrayDataSourceHandle ds = +// // styleSchema.GetReprSelector()) { +// // VtArray ar = ds->GetTypedValue(0.0f); +// // TfToken refinedToken = ar[0]; +// // if(HdReprTokens->refined == refinedToken){ +// // //Is in refined display style, apply the wire on top of shaded reprselector +// // return HdOverlayContainerDataSource::New({ edited.Finish(), sRefinedWireOnSurfaceDisplayStyleDataSource}); +// // } +// // }else{ +// // //No reprSelector found, assume it's in the Collection that we have set HdReprTokens->refined +// // return HdOverlayContainerDataSource::New({ edited.Finish(), sRefinedWireOnSurfaceDisplayStyleDataSource}); +// // } +// // } + +// //For the other case, we are only updating the wireframe color assuming we are already drawing lines +// return edited.Finish(); +// } + +bool _IsInstancerWithSelections(const HdSceneIndexPrim& prim) +{ + if (prim.primType != HdPrimTypeTokens->instancer) { + return false; + } + auto selections = HdSelectionsSchema::GetFromParent(prim.dataSource); + return selections.IsDefined() && selections.GetNumElements() > 0; +} + +bool _IsConcretePrototype(const SdfPath& primPath, const HdSceneIndexPrim& prim) +{ + HdInstancedBySchema instancedBy = HdInstancedBySchema::GetFromParent(prim.dataSource); + return instancedBy.IsDefined() && instancedBy.GetPrototypeRoots(); +} + +bool _IsPartOfSelectionHighlightMirror(const SdfPath& path) +{ + auto ancestorsRange = path.GetAncestorsRange(); + for (auto ancestor : ancestorsRange) { + if (_IsSelectionHighlightMirrorPath(ancestor)) { + return true; + } + } + return false; +} + } namespace FVP_NS_DEF { +SdfPath +WireframeSelectionHighlightSceneIndex::_FindSelectionHighlightMirrorAncestor(const SdfPath& path) const +{ + auto ancestorsRange = path.GetAncestorsRange(); + for (auto ancestor : ancestorsRange) { + if (_shMirrorsUseCount.find(ancestor) != _shMirrorsUseCount.end()) { + return ancestor; + } + } + return SdfPath::EmptyPath(); +} + +SdfPath +WireframeSelectionHighlightSceneIndex::_RepathToSelectionHighlightMirror(const SdfPath& path) const +{ + auto ancestorsRange = path.GetAncestorsRange(); + for (auto ancestor : ancestorsRange) { + const SdfPath mirrorPath = _GetSelectionHighlightMirrorPathFromOriginal(ancestor); + if (_shMirrorsUseCount.find(mirrorPath) != _shMirrorsUseCount.end()) { + return path.ReplacePrefix(ancestor, mirrorPath); + } + } + return SdfPath::EmptyPath(); +} + +class WireframeSelectionHighlightSceneIndex::_RerootingSceneIndexPathDataSource : public HdPathDataSource +{ +public: + HD_DECLARE_DATASOURCE(_RerootingSceneIndexPathDataSource) + + _RerootingSceneIndexPathDataSource( + HdPathDataSourceHandle const &inputDataSource, + WireframeSelectionHighlightSceneIndex const * const inputSceneIndex) + : _inputDataSource(inputDataSource), + _inputSceneIndex(inputSceneIndex) + { + } + + VtValue GetValue(const Time shutterOffset) override + { + return VtValue(GetTypedValue(shutterOffset)); + } + + bool GetContributingSampleTimesForInterval( + const Time startTime, + const Time endTime, + std::vector