Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 209 additions & 0 deletions lib/flowViewport/sceneIndex/fvpSceneIndexUtils.cpp

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved from testUtils.cpp, to be used in non-test code.

Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,212 @@
//

#include "flowViewport/sceneIndex/fvpSceneIndexUtils.h"

#include <pxr/imaging/hd/version.h>
#include <pxr/imaging/hd/dataSourceLegacyPrim.h>
#if defined(HD_API_VERSION) && HD_API_VERSION >= 74 // For USD 24.11+
#include <pxr/imaging/hd/extComputationSchema.h>
#endif

PXR_NAMESPACE_USING_DIRECTIVE

namespace FVP_NS_DEF {

SceneIndexInspector::SceneIndexInspector(HdSceneIndexBasePtr sceneIndex)
: _sceneIndex(sceneIndex)
{
}

SceneIndexInspector::~SceneIndexInspector() { }

HdSceneIndexBasePtr SceneIndexInspector::GetSceneIndex() { return _sceneIndex; }

PrimEntriesVector SceneIndexInspector::FindPrims(FindPrimPredicate predicate, size_t maxPrims) const
{
PrimEntriesVector searchResults;
_FindPrims(predicate, SdfPath::AbsoluteRootPath(), searchResults, maxPrims);
return searchResults;
}

void SceneIndexInspector::_FindPrims(
FindPrimPredicate predicate,
const SdfPath& primPath,
PrimEntriesVector& primEntries,
size_t maxPrims) const
{
HdSceneIndexPrim prim = _sceneIndex->GetPrim(primPath);
if (predicate(_sceneIndex, primPath)) {
primEntries.push_back({ primPath, prim });
if (maxPrims > 0 && primEntries.size() >= maxPrims) {
return;
}
} else {
auto childPaths = _sceneIndex->GetChildPrimPaths(primPath);
for (auto childPath : childPaths) {
_FindPrims(predicate, childPath, primEntries, maxPrims);
if (maxPrims > 0 && primEntries.size() >= maxPrims) {
return;
}
}
}
}

void SceneIndexInspector::WriteHierarchy(std::ostream& outStream) const
{
_WritePrimHierarchy(SdfPath::AbsoluteRootPath(), "", "", outStream);
}

void SceneIndexInspector::_WritePrimHierarchy(
SdfPath primPath,
std::string selfPrefix,
std::string childrenPrefix,
std::ostream& outStream) const
{
HdSceneIndexPrim prim = _sceneIndex->GetPrim(primPath);

outStream << selfPrefix << "@ Prim : " << primPath.MakeRelativePath(primPath.GetParentPath())
<< " --- Type : " << prim.primType.GetString() << "\n";

_WriteContainerDataSource(
prim.dataSource, "", childrenPrefix + "|___", childrenPrefix + " ", outStream);

auto childPaths = _sceneIndex->GetChildPrimPaths(primPath);
for (auto childPath : childPaths) {
bool isLastChild = childPath == childPaths.back();
_WritePrimHierarchy(
childPath,
childrenPrefix + "|___",
childrenPrefix + (isLastChild ? " " : "| "),
outStream);
}
}

void SceneIndexInspector::_WriteContainerDataSource(
HdContainerDataSourceHandle dataSource,
std::string dataSourceName,
std::string selfPrefix,
std::string childrenPrefix,
std::ostream& outStream) const
{
if (!dataSource) {
return;
}

outStream << selfPrefix << "# ContainerDataSource : " << dataSourceName << "\n";

auto childNames = dataSource->GetNames();
for (auto childName : childNames) {
bool isLastChild = childName == childNames.back();
auto child = dataSource->Get(childName);
if (auto childContainer = HdContainerDataSource::Cast(child)) {
_WriteContainerDataSource(
childContainer,
childName.GetString(),
childrenPrefix + "|___",
childrenPrefix + (isLastChild ? " " : "| "),
outStream);
} else if (auto childVector = HdVectorDataSource::Cast(child)) {
_WriteVectorDataSource(
childVector,
childName.GetString(),
childrenPrefix + "|___",
childrenPrefix + (isLastChild ? " " : "| "),
outStream);
} else {
_WriteLeafDataSource(child, childName, childrenPrefix + "|___", outStream);
}
}
}

void SceneIndexInspector::_WriteVectorDataSource(
HdVectorDataSourceHandle dataSource,
std::string dataSourceName,
std::string selfPrefix,
std::string childrenPrefix,
std::ostream& outStream) const
{
if (!dataSource) {
return;
}

outStream << selfPrefix << "# VectorDataSource : " << dataSourceName << "\n";

auto numElements = dataSource->GetNumElements();
for (size_t iElement = 0; iElement < numElements; iElement++) {
std::string childName = "Element " + std::to_string(iElement);
bool isLastElement = iElement == numElements - 1;
auto child = dataSource->GetElement(iElement);
if (auto childContainer = HdContainerDataSource::Cast(child)) {
_WriteContainerDataSource(
childContainer,
childName,
childrenPrefix + "|___",
childrenPrefix + (isLastElement ? " " : "| "),
outStream);
} else if (auto childVector = HdVectorDataSource::Cast(child)) {
_WriteVectorDataSource(
childVector,
childName,
childrenPrefix + "|___",
childrenPrefix + (isLastElement ? " " : "| "),
outStream);
} else {
_WriteLeafDataSource(child, childName, childrenPrefix + "|___", outStream);
}
}
}

void SceneIndexInspector::_WriteLeafDataSource(
HdDataSourceBaseHandle dataSource,
std::string dataSourceName,
std::string selfPrefix,
std::ostream& outStream) const
{
std::string dataSourceDescription;
// HdOverlayContainerDataSource::Get() will return a nullptr if its child
// is an HdBlockDataSource. GetNames() will still include such a child.
if (!dataSource) {
dataSourceDescription = "Blocked or absent data source";
}
else if (auto blockDataSource = HdBlockDataSource::Cast(dataSource)) {
dataSourceDescription = "BlockDataSource";
} else if (auto sampledDataSource = HdSampledDataSource::Cast(dataSource)) {
dataSourceDescription
= "SampledDataSource -> " + sampledDataSource->GetValue(0).GetTypeName();
} else if (
auto extComputationCallbackDataSource
#if defined(HD_API_VERSION) && HD_API_VERSION >= 74 // For USD 24.11+
= HdExtComputationCpuCallbackDataSource::Cast(dataSource)) {
#else
= HdExtComputationCallbackDataSource::Cast(dataSource)) {
#endif
dataSourceDescription = "ExtComputationCallbackDataSource";
} else {
dataSourceDescription = "Unidentified data source type";
}
outStream << selfPrefix << dataSourceDescription << " : " << dataSourceName << "\n";
}

HdSceneIndexBaseRefPtr findSceneIndexInTree(
const HdSceneIndexBaseRefPtr& sceneIndex,
const std::function<bool(const HdSceneIndexBaseRefPtr&)>& predicate
)
{
if (predicate(sceneIndex)) {
return sceneIndex;
}
auto filteringSi = TfDynamic_cast<HdFilteringSceneIndexBaseRefPtr>(sceneIndex);
if (!filteringSi) {
return {};
}

auto sceneIndices = filteringSi->GetInputScenes();
for (const auto& childSceneIndex : sceneIndices) {
if (auto si = findSceneIndexInTree(childSceneIndex, predicate)) {
return si;
}
}
return {};
}

} // namespace FVP_NS_DEF
126 changes: 126 additions & 0 deletions lib/flowViewport/sceneIndex/fvpSceneIndexUtils.h

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved from testUtils.h, to be used in non-test code.

Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
#include <flowViewport/api.h>

#include <pxr/imaging/hd/filteringSceneIndex.h>
#include <pxr/imaging/hd/sceneIndex.h>

#include <functional>
#include <ostream>
#include <string>
#include <vector>

namespace FVP_NS_DEF {

Expand Down Expand Up @@ -56,6 +62,126 @@ class InputSceneIndexUtils
#endif
};

// ============================================================================
// SceneIndexInspector and associated types
// ============================================================================

struct FVP_API PrimEntry
{
PXR_NS::SdfPath primPath;
PXR_NS::HdSceneIndexPrim prim;
};

using FindPrimPredicate
= std::function<bool(const PXR_NS::HdSceneIndexBasePtr& sceneIndex, const PXR_NS::SdfPath& primPath)>;

using PrimEntriesVector = std::vector<PrimEntry>;

/// \class SceneIndexInspector
///
/// Utility class for inspecting a Hydra scene index hierarchy. Provides
/// methods to search for prims by predicate and to dump the full hierarchy
/// (including data sources) as a text tree.
///
class FVP_API SceneIndexInspector
{
public:
SceneIndexInspector(PXR_NS::HdSceneIndexBasePtr sceneIndex);
~SceneIndexInspector();

/// Retrieve the underlying scene index of this inspector.
PXR_NS::HdSceneIndexBasePtr GetSceneIndex();

/**
* @brief Retrieve all prims that match the given predicate, up until the maximum amount
*
* A maximum amount of 0 means unlimited (all matching prims will be returned).
*
* @param[in] predicate is the callable predicate used to determine whether a given prim is
* desired
* @param[in] maxPrims is the maximum amount of prims to be retrieved. The default value is 0
* (unlimited).
*
* @return A vector of the prim entries that matched the given predicate.
*/
PrimEntriesVector FindPrims(FindPrimPredicate predicate, size_t maxPrims = 0) const;

/**
* @brief Print the scene index's hierarchy in a tree-like format
*
* Print the scene index's hierarchy in a tree-like format, down to the individual data
* source level.
*
* @param[out] outStream is the stream in which to print the hierarchy
*/
void WriteHierarchy(std::ostream& outStream) const;

private:
void _FindPrims(
FindPrimPredicate predicate,
const PXR_NS::SdfPath& primPath,
PrimEntriesVector& primEntries,
size_t maxPrims) const;

void _WritePrimHierarchy(
PXR_NS::SdfPath primPath,
std::string selfPrefix,
std::string childrenPrefix,
std::ostream& outStream) const;

void _WriteContainerDataSource(
PXR_NS::HdContainerDataSourceHandle dataSource,
std::string dataSourceName,
std::string selfPrefix,
std::string childrenPrefix,
std::ostream& outStream) const;

void _WriteVectorDataSource(
PXR_NS::HdVectorDataSourceHandle dataSource,
std::string dataSourceName,
std::string selfPrefix,
std::string childrenPrefix,
std::ostream& outStream) const;

void _WriteLeafDataSource(
PXR_NS::HdDataSourceBaseHandle dataSource,
std::string dataSourceName,
std::string selfPrefix,
std::ostream& outStream) const;

PXR_NS::HdSceneIndexBasePtr _sceneIndex;
};

// ============================================================================
// Scene index tree search utilities
// ============================================================================

/// \class SceneIndexDisplayNamePred
///
/// Predicate to match a scene index by its display name string.
///
class FVP_API SceneIndexDisplayNamePred {
const std::string _name;
public:
SceneIndexDisplayNamePred(const std::string& name) : _name(name) {}

bool operator()(const PXR_NS::HdSceneIndexBaseRefPtr& sceneIndex) {
return sceneIndex->GetDisplayName() == _name;
}
};

/// Find the first scene index matching the given predicate via depth-first
/// search of the scene index tree.
///
/// \param sceneIndex The root of the scene index tree to search.
/// \param predicate The predicate that determines a match.
/// \return Scene index pointer if the predicate succeeds, otherwise nullptr.
FVP_API
PXR_NS::HdSceneIndexBaseRefPtr findSceneIndexInTree(
const PXR_NS::HdSceneIndexBaseRefPtr& sceneIndex,
const std::function<bool(const PXR_NS::HdSceneIndexBaseRefPtr&)>& predicate
);

}

#endif
Loading
Loading