Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HYDRA-1286 : Support displacement on GeomSubset wireframe highlights #242

Open
wants to merge 21 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e952874
HYDRA-1286 : Initial displacement (no updates)
debloip-adsk Jan 27, 2025
5f503d4
HYDRA-1286 : Update GeomSubset highlight on displacement update
debloip-adsk Jan 27, 2025
9c3f4e8
HYDRA-1286 : Add utility method to create data source dependencies
debloip-adsk Jan 27, 2025
7b62cc9
HYDRA-1286 : Extract method to make geomSubset highlights
debloip-adsk Jan 27, 2025
5e3302d
HYDRA-1286 : Support displacement in point instancing
debloip-adsk Jan 27, 2025
80c825d
HYDRA-1286 : Cleanup
debloip-adsk Jan 27, 2025
bb01e29
HYDRA-1286 : Handle scaling
debloip-adsk Jan 28, 2025
9fe659f
HYDRA-1286 : Cleanup
debloip-adsk Jan 28, 2025
4e65cdc
HYDRA-1286 : Re-order methods
debloip-adsk Jan 28, 2025
c7a5663
HYDRA-1286 : Move TrimMeshForGeomSubset to FVP namespace
debloip-adsk Jan 28, 2025
9be90b2
HYDRA-1286 : Update variable names
debloip-adsk Jan 28, 2025
32e8a29
HYDRA-1286 : Update tokens
debloip-adsk Jan 28, 2025
d2bf391
HYDRA-1286 : Add GeomSubset displacement test scene
debloip-adsk Jan 28, 2025
2149576
HYDRA-1286 : Add GeomSubset displacement test
debloip-adsk Jan 28, 2025
a9d252c
HYDRA-1286 : Go back to using only copy-pasted data sources from rero…
debloip-adsk Jan 28, 2025
1045c15
HYDRA-1286 : Handle conditional compilation
debloip-adsk Jan 28, 2025
8fe7bd0
HYDRA-1286 : Additional conditional compilation
debloip-adsk Jan 28, 2025
49b45bf
HYDRA-1286 : Additional conditional compilation
debloip-adsk Jan 28, 2025
5478876
HYDRA-1286 : Rename ComputeSmoothNormals
debloip-adsk Jan 29, 2025
40f7d9d
HYDRA-1286 : Move transpose of inverse matrix out of loop
debloip-adsk Jan 29, 2025
aefa92a
HYDRA-1286 : Extract out utility functions
debloip-adsk Jan 29, 2025
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
206 changes: 206 additions & 0 deletions lib/flowViewport/fvpUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,39 @@

#include "fvpUtils.h"

#include <pxr/imaging/hd/containerDataSourceEditor.h>
#include <pxr/imaging/hd/dataSourceMaterialNetworkInterface.h>
#include <pxr/imaging/hd/dependenciesSchema.h>
#include <pxr/imaging/hd/instanceIndicesSchema.h>
#include <pxr/imaging/hd/materialBindingsSchema.h>
#include <pxr/imaging/hd/materialSchema.h>
#include <pxr/imaging/hd/meshSchema.h>
#include <pxr/imaging/hd/meshTopology.h>
#include <pxr/imaging/hd/sceneIndex.h>
#include <pxr/imaging/hd/selectionSchema.h>
#include <pxr/imaging/hd/smoothNormals.h>
#include <pxr/imaging/hd/vertexAdjacency.h>
#include <pxr/imaging/pxOsd/tokens.h>

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 {

Expand Down Expand Up @@ -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<HdSelectionSchema&>(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<int>(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<float>()) {
return paramValue;
}
}

return {};
}

PXR_NS::HdContainerDataSourceHandle AddSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource)
{
// Check if normals are already present
auto normalsValueDataSource = HdTypedSampledDataSource<VtArray<GfVec3f>>::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<VtArray<GfVec3f>>::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<int>(points.size()), points.cdata());

// Add normals
auto normalsPrimvarDataSource = HdPrimvarSchema::Builder()
.SetInterpolation(HdPrimvarSchema::BuildInterpolationDataSource(HdPrimvarSchemaTokens->vertex))
.SetRole(HdPrimvarSchema::BuildRoleDataSource(HdPrimvarSchemaTokens->normal))
.SetPrimvarValue(HdRetainedTypedSampledDataSource<decltype(normals)>::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<SdfPath>::New(dependedOnPrimPath));
}

builder.SetDependedOnDataSourceLocator(HdRetainedTypedSampledDataSource<HdDataSourceLocator>::New(dependedOnDataSourceLocator));

builder.SetAffectedDataSourceLocator(HdRetainedTypedSampledDataSource<HdDataSourceLocator>::New(affectedDataSourceLocator));

auto dependencyDataSource = HdRetainedContainerDataSource::New(dependencyToken, builder.Build());

HdContainerDataSourceEditor dataSourceEditor(primDataSource);
dataSourceEditor.Overlay(HdDependenciesSchema::GetDefaultLocator(), dependencyDataSource);
return dataSourceEditor.Finish();
}

} // namespace FVP_NS_DEF
22 changes: 22 additions & 0 deletions lib/flowViewport/fvpUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#ifndef FVP_UTILS_H
#define FVP_UTILS_H

#include <pxr/imaging/hd/sceneIndexObserver.h>
#include <flowViewport/api.h>
#include <flowViewport/selection/fvpSelectionTypes.h>

Expand All @@ -24,6 +25,7 @@

#include <pxr/imaging/hd/tokens.h>
#include <pxr/imaging/hd/retainedDataSource.h>
#include <pxr/imaging/hd/selectionSchema.h>
#include <pxr/imaging/hd/primvarsSchema.h>

namespace FVP_NS_DEF {
Expand Down Expand Up @@ -125,6 +127,26 @@ auto FindSelfOrFirstChild(const PXR_NS::SdfPath& path, const std::map<PXR_NS::Sd
return pathMap.cend();
}

// Return a Fvp::PrimSelection equivalent to the given Hydra selection
Fvp::PrimSelection ConvertHydraToFvpSelection(const PXR_NS::SdfPath& primPath, const PXR_NS::HdSelectionSchema& selectionSchema);

// Get the path to the prim's bound material.
PXR_NS::SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSource);

// Return the displacement value from the given prim data source's assigned material
PXR_NS::VtValue GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle& primDataSource, const PXR_NS::HdSceneIndexBase& sceneIndex);

// 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);

// 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);

} // namespace FVP_NS_DEF

#endif // FVP_UTILS_H
Loading