Skip to content

Commit aefa92a

Browse files
committed
HYDRA-1286 : Extract out utility functions
1 parent 40f7d9d commit aefa92a

File tree

4 files changed

+229
-208
lines changed

4 files changed

+229
-208
lines changed

lib/flowViewport/fvpUtils.cpp

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,39 @@
1515

1616
#include "fvpUtils.h"
1717

18+
#include <pxr/imaging/hd/containerDataSourceEditor.h>
19+
#include <pxr/imaging/hd/dataSourceMaterialNetworkInterface.h>
20+
#include <pxr/imaging/hd/dependenciesSchema.h>
1821
#include <pxr/imaging/hd/instanceIndicesSchema.h>
22+
#include <pxr/imaging/hd/materialBindingsSchema.h>
23+
#include <pxr/imaging/hd/materialSchema.h>
24+
#include <pxr/imaging/hd/meshSchema.h>
25+
#include <pxr/imaging/hd/meshTopology.h>
26+
#include <pxr/imaging/hd/sceneIndex.h>
1927
#include <pxr/imaging/hd/selectionSchema.h>
28+
#include <pxr/imaging/hd/smoothNormals.h>
29+
#include <pxr/imaging/hd/vertexAdjacency.h>
30+
#include <pxr/imaging/pxOsd/tokens.h>
31+
32+
PXR_NAMESPACE_USING_DIRECTIVE
33+
34+
namespace {
35+
36+
const HdDataSourceLocator pointsValueLocator = HdDataSourceLocator(
37+
HdPrimvarsSchemaTokens->primvars,
38+
HdPrimvarsSchemaTokens->points,
39+
HdPrimvarSchemaTokens->primvarValue);
40+
41+
const HdDataSourceLocator normalsPrimvarLocator = HdDataSourceLocator(
42+
HdPrimvarsSchemaTokens->primvars,
43+
HdPrimvarsSchemaTokens->normals);
44+
45+
const HdDataSourceLocator normalsValueLocator = HdDataSourceLocator(
46+
HdPrimvarsSchemaTokens->primvars,
47+
HdPrimvarsSchemaTokens->normals,
48+
HdPrimvarSchemaTokens->primvarValue);
49+
50+
}
2051

2152
namespace FVP_NS_DEF {
2253

@@ -56,4 +87,179 @@ PXR_NS::HdDataSourceBaseHandle createSelectionDataSource(const Fvp::PrimSelectio
5687
return PXR_NS::HdDataSourceBase::Cast(selectionBuilder.Build());
5788
}
5889

90+
Fvp::PrimSelection ConvertHydraToFvpSelection(const SdfPath& primPath, const HdSelectionSchema& selectionSchema) {
91+
Fvp::PrimSelection primSelection;
92+
primSelection.primPath = primPath;
93+
94+
auto nestedInstanceIndicesSchema =
95+
#if HD_API_VERSION < 66
96+
const_cast<HdSelectionSchema&>(selectionSchema).GetNestedInstanceIndices();
97+
#else
98+
selectionSchema.GetNestedInstanceIndices();
99+
#endif
100+
for (size_t iNestedInstanceIndices = 0; iNestedInstanceIndices < nestedInstanceIndicesSchema.GetNumElements(); iNestedInstanceIndices++) {
101+
HdInstanceIndicesSchema instanceIndicesSchema = nestedInstanceIndicesSchema.GetElement(iNestedInstanceIndices);
102+
auto instanceIndices = instanceIndicesSchema.GetInstanceIndices()->GetTypedValue(0);
103+
primSelection.nestedInstanceIndices.push_back(
104+
{
105+
instanceIndicesSchema.GetInstancer()->GetTypedValue(0),
106+
instanceIndicesSchema.GetPrototypeIndex()->GetTypedValue(0),
107+
std::vector<int>(instanceIndices.begin(), instanceIndices.end())
108+
}
109+
);
110+
}
111+
112+
return primSelection;
113+
}
114+
115+
SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSource)
116+
{
117+
if (!primDataSource) {
118+
return {};
119+
}
120+
121+
HdMaterialBindingsSchema materialBindingsSchema = HdMaterialBindingsSchema::GetFromParent(primDataSource);
122+
if (!materialBindingsSchema.IsDefined()) {
123+
return {};
124+
}
125+
126+
HdMaterialBindingSchema materialBindingSchema = materialBindingsSchema.GetMaterialBinding();
127+
if (!materialBindingSchema) {
128+
return {};
129+
}
130+
131+
HdPathDataSourceHandle bindingPathDataSource = materialBindingSchema.GetPath();
132+
if (!bindingPathDataSource) {
133+
return {};
134+
}
135+
136+
return bindingPathDataSource->GetTypedValue(0);
137+
}
138+
139+
VtValue GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle& primDataSource, const PXR_NS::HdSceneIndexBase& sceneIndex)
140+
{
141+
if (!primDataSource) {
142+
return {};
143+
}
144+
145+
// Step 1: Get the material path
146+
const SdfPath materialPath = GetMaterialPath(primDataSource);
147+
if (materialPath.IsEmpty()) {
148+
return {};
149+
}
150+
151+
// Step 2: Retrieve the material
152+
HdSceneIndexPrim materialPrim = sceneIndex.GetPrim(materialPath);
153+
if (!materialPrim.dataSource || (materialPrim.primType != HdPrimTypeTokens->material) ){
154+
return {};
155+
}
156+
157+
HdMaterialSchema materialSchema = HdMaterialSchema::GetFromParent(materialPrim.dataSource);
158+
if (!materialSchema.IsDefined()) {
159+
return {};
160+
}
161+
162+
// Step 3: Look for the displacement value
163+
#if PXR_VERSION < 2403
164+
HdDataSourceMaterialNetworkInterface materialNetworkInterface(
165+
materialPath, materialSchema.GetMaterialNetwork(), primDataSource);
166+
#else
167+
HdDataSourceMaterialNetworkInterface materialNetworkInterface(
168+
materialPath, materialSchema.GetMaterialNetwork().GetContainer(), primDataSource);
169+
#endif
170+
171+
for (auto nodeName : materialNetworkInterface.GetNodeNames()) {
172+
VtValue paramValue = materialNetworkInterface.GetNodeParameterValue(nodeName, HdMaterialTerminalTokens->displacement);
173+
if (paramValue.IsHolding<float>()) {
174+
return paramValue;
175+
}
176+
}
177+
178+
return {};
179+
}
180+
181+
PXR_NS::HdContainerDataSourceHandle AddSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource)
182+
{
183+
// Check if normals are already present
184+
auto normalsValueDataSource = HdTypedSampledDataSource<VtArray<GfVec3f>>::Cast(HdContainerDataSource::Get(meshPrimDataSource, normalsValueLocator));
185+
if (normalsValueDataSource) {
186+
return meshPrimDataSource;
187+
}
188+
189+
// Get required schemas/dataSources
190+
HdMeshSchema meshSchema = HdMeshSchema::GetFromParent(meshPrimDataSource);
191+
if (!meshSchema.IsDefined()) {
192+
return meshPrimDataSource;
193+
}
194+
HdMeshTopologySchema meshTopologySchema = meshSchema.GetTopology();
195+
if (!meshTopologySchema.IsDefined()) {
196+
return meshPrimDataSource;
197+
}
198+
auto pointsValueDataSource = HdTypedSampledDataSource<VtArray<GfVec3f>>::Cast(HdContainerDataSource::Get(meshPrimDataSource, pointsValueLocator));
199+
if (!pointsValueDataSource) {
200+
return meshPrimDataSource;
201+
}
202+
203+
// Setup topology
204+
TfToken subdivScheme = PxOsdOpenSubdivTokens->none;
205+
if (HdTokenDataSourceHandle subdivSchemeDataSource = meshSchema.GetSubdivisionScheme()) {
206+
subdivScheme = subdivSchemeDataSource->GetTypedValue(0.0f);
207+
}
208+
VtIntArray holeIndices;
209+
if (HdIntArrayDataSourceHandle holeIndicesDataSource = meshTopologySchema.GetHoleIndices()) {
210+
holeIndices = holeIndicesDataSource->GetTypedValue(0.0f);
211+
}
212+
TfToken orientation = PxOsdOpenSubdivTokens->rightHanded;
213+
if (HdTokenDataSourceHandle orientationDataSource = meshTopologySchema.GetOrientation()) {
214+
orientation = orientationDataSource->GetTypedValue(0.0f);
215+
}
216+
HdMeshTopology meshTopology(
217+
subdivScheme,
218+
orientation,
219+
meshTopologySchema.GetFaceVertexCounts()->GetTypedValue(0),
220+
meshTopologySchema.GetFaceVertexIndices()->GetTypedValue(0),
221+
holeIndices);
222+
Hd_VertexAdjacency adjacency;
223+
adjacency.BuildAdjacencyTable(&meshTopology);
224+
225+
// Compute normals
226+
auto points = pointsValueDataSource->GetTypedValue(0);
227+
auto normals = Hd_SmoothNormals::ComputeSmoothNormals(
228+
&adjacency, static_cast<int>(points.size()), points.cdata());
229+
230+
// Add normals
231+
auto normalsPrimvarDataSource = HdPrimvarSchema::Builder()
232+
.SetInterpolation(HdPrimvarSchema::BuildInterpolationDataSource(HdPrimvarSchemaTokens->vertex))
233+
.SetRole(HdPrimvarSchema::BuildRoleDataSource(HdPrimvarSchemaTokens->normal))
234+
.SetPrimvarValue(HdRetainedTypedSampledDataSource<decltype(normals)>::New(normals))
235+
.Build();
236+
HdContainerDataSourceEditor dataSourceEditor(meshPrimDataSource);
237+
dataSourceEditor.Set(normalsPrimvarLocator, normalsPrimvarDataSource);
238+
return dataSourceEditor.Finish();
239+
}
240+
241+
PXR_NS::HdContainerDataSourceHandle AddDependency(
242+
const PXR_NS::HdContainerDataSourceHandle& primDataSource,
243+
const PXR_NS::TfToken& dependencyToken,
244+
const PXR_NS::SdfPath& dependedOnPrimPath,
245+
const PXR_NS::HdDataSourceLocator& dependedOnDataSourceLocator,
246+
const PXR_NS::HdDataSourceLocator& affectedDataSourceLocator)
247+
{
248+
HdDependencySchema::Builder builder;
249+
250+
if (!dependedOnPrimPath.IsEmpty()) {
251+
builder.SetDependedOnPrimPath(HdRetainedTypedSampledDataSource<SdfPath>::New(dependedOnPrimPath));
252+
}
253+
254+
builder.SetDependedOnDataSourceLocator(HdRetainedTypedSampledDataSource<HdDataSourceLocator>::New(dependedOnDataSourceLocator));
255+
256+
builder.SetAffectedDataSourceLocator(HdRetainedTypedSampledDataSource<HdDataSourceLocator>::New(affectedDataSourceLocator));
257+
258+
auto dependencyDataSource = HdRetainedContainerDataSource::New(dependencyToken, builder.Build());
259+
260+
HdContainerDataSourceEditor dataSourceEditor(primDataSource);
261+
dataSourceEditor.Overlay(HdDependenciesSchema::GetDefaultLocator(), dependencyDataSource);
262+
return dataSourceEditor.Finish();
263+
}
264+
59265
} // namespace FVP_NS_DEF

lib/flowViewport/fvpUtils.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef FVP_UTILS_H
1616
#define FVP_UTILS_H
1717

18+
#include <pxr/imaging/hd/sceneIndexObserver.h>
1819
#include <flowViewport/api.h>
1920
#include <flowViewport/selection/fvpSelectionTypes.h>
2021

@@ -24,6 +25,7 @@
2425

2526
#include <pxr/imaging/hd/tokens.h>
2627
#include <pxr/imaging/hd/retainedDataSource.h>
28+
#include <pxr/imaging/hd/selectionSchema.h>
2729
#include <pxr/imaging/hd/primvarsSchema.h>
2830

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

130+
// Return a Fvp::PrimSelection equivalent to the given Hydra selection
131+
Fvp::PrimSelection ConvertHydraToFvpSelection(const PXR_NS::SdfPath& primPath, const PXR_NS::HdSelectionSchema& selectionSchema);
132+
133+
// Get the path to the prim's bound material.
134+
PXR_NS::SdfPath GetMaterialPath(const PXR_NS::HdContainerDataSourceHandle& primDataSource);
135+
136+
// Return the displacement value from the given prim data source's assigned material
137+
PXR_NS::VtValue GetMaterialDisplacementValue(const PXR_NS::HdContainerDataSourceHandle& primDataSource, const PXR_NS::HdSceneIndexBase& sceneIndex);
138+
139+
// Computes and adds the normals primvar with smooth normals. If normals are already present, does nothing.
140+
PXR_NS::HdContainerDataSourceHandle AddSmoothNormals(const PXR_NS::HdContainerDataSourceHandle& meshPrimDataSource);
141+
142+
// Add an entry to the __dependencies data source
143+
PXR_NS::HdContainerDataSourceHandle AddDependency(
144+
const PXR_NS::HdContainerDataSourceHandle& primDataSource,
145+
const PXR_NS::TfToken& dependencyToken,
146+
const PXR_NS::SdfPath& dependedOnPrimPath,
147+
const PXR_NS::HdDataSourceLocator& dependedOnDataSourceLocator,
148+
const PXR_NS::HdDataSourceLocator& affectedDataSourceLocator);
149+
128150
} // namespace FVP_NS_DEF
129151

130152
#endif // FVP_UTILS_H

0 commit comments

Comments
 (0)