Skip to content

Commit

Permalink
Using the new 21.02 indexed primvar sampling functions (Autodesk#959)
Browse files Browse the repository at this point in the history
* Adding new functions to sample indexed primvars. (Autodesk#632)
* Track primvar indices. (Autodesk#632)
* More improvements to indexed primvar sampling. (Autodesk#632)
* Adding support for sampling indexed normals. (Autodesk#632)
* Fixing testsuite build errors. (Autodesk#632)
  • Loading branch information
sirpalee authored Dec 16, 2021
1 parent 0d0c377 commit b45b4c5
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 64 deletions.
4 changes: 4 additions & 0 deletions render_delegate/hdarnold.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
#define USD_DO_NOT_BLIT
#endif

#if PXR_VERSION >= 2105
#define USD_HAS_SAMPLE_INDEXED_PRIMVAR
#endif

#if ARNOLD_VERSION_NUMBER > 60201
#define ARNOLD_MULTIPLE_RENDER_SESSIONS
#endif
6 changes: 6 additions & 0 deletions render_delegate/instancer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,14 @@ void HdArnoldInstancer::_SyncPrimvars(
GetDelegate()->SamplePrimvar(id, _tokens->translate, &sample);
_translates.UnboxFrom(sample);
} else {
#ifdef USD_HAS_SAMPLE_INDEXED_PRIMVAR
HdArnoldInsertPrimvar(
_primvars, primvar.name, primvar.role, primvar.interpolation, GetDelegate()->Get(id, primvar.name),
{});
#else
HdArnoldInsertPrimvar(
_primvars, primvar.name, primvar.role, primvar.interpolation, GetDelegate()->Get(id, primvar.name));
#endif
}
}
}
Expand Down
55 changes: 47 additions & 8 deletions render_delegate/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,29 @@ inline void _ConvertVertexPrimvarToBuiltin(

template <typename UsdType, unsigned ArnoldType, typename StorageType>
inline void _ConvertFaceVaryingPrimvarToBuiltin(
AtNode* node, const StorageType& data, const AtString& arnoldName, const AtString& arnoldIndexName,
const VtIntArray* vertexCounts = nullptr, const size_t* vertexCountSum = nullptr)
AtNode* node, const StorageType& data,
#ifdef USD_HAS_SAMPLE_INDEXED_PRIMVAR
const VtIntArray& indices,
#endif
const AtString& arnoldName, const AtString& arnoldIndexName, const VtIntArray* vertexCounts = nullptr,
const size_t* vertexCountSum = nullptr)
{
_ConvertValueToArnoldParameter<UsdType, ArnoldType, StorageType>::convert(
node, data, arnoldName, arnoldIndexName,
[&](unsigned int numValues) -> AtArray* {
return HdArnoldGenerateIdxs(numValues, vertexCounts, vertexCountSum);
},
vertexCountSum);
#ifdef USD_HAS_SAMPLE_INDEXED_PRIMVAR
if (!indices.empty()) {
_ConvertValueToArnoldParameter<UsdType, ArnoldType, StorageType>::convert(
node, data, arnoldName, arnoldIndexName,
[&](unsigned int) -> AtArray* { return HdArnoldGenerateIdxs(indices, vertexCounts); });
} else {
#endif
_ConvertValueToArnoldParameter<UsdType, ArnoldType, StorageType>::convert(
node, data, arnoldName, arnoldIndexName,
[&](unsigned int numValues) -> AtArray* {
return HdArnoldGenerateIdxs(numValues, vertexCounts, vertexCountSum);
},
vertexCountSum);
#ifdef USD_HAS_SAMPLE_INDEXED_PRIMVAR
}
#endif
}

} // namespace
Expand Down Expand Up @@ -358,6 +372,30 @@ void HdArnoldMesh::Sync(
} else if (desc.interpolation == HdInterpolationUniform) {
HdArnoldSetUniformPrimvar(GetArnoldNode(), primvar.first, desc.role, desc.value);
} else if (desc.interpolation == HdInterpolationFaceVarying) {
#ifdef USD_HAS_SAMPLE_INDEXED_PRIMVAR
if (primvar.first == _tokens->st || primvar.first == _tokens->uv) {
_ConvertFaceVaryingPrimvarToBuiltin<GfVec2f, AI_TYPE_VECTOR2>(
GetArnoldNode(), desc.value, desc.valueIndices, str::uvlist, str::uvidxs, &_vertexCounts,
&_vertexCountSum);
} else if (primvar.first == HdTokens->normals) {
if (desc.value.IsEmpty()) {
HdArnoldIndexedSampledPrimvarType sample;
sceneDelegate->SampleIndexedPrimvar(id, primvar.first, &sample);
sample.count = _numberOfPositionKeys;
_ConvertFaceVaryingPrimvarToBuiltin<GfVec3f, AI_TYPE_VECTOR, HdArnoldSampledPrimvarType>(
GetArnoldNode(), sample, sample.indices.empty() ? VtIntArray{} : sample.indices[0],
str::nlist, str::nidxs, &_vertexCounts, &_vertexCountSum);
} else {
_ConvertFaceVaryingPrimvarToBuiltin<GfVec3f, AI_TYPE_VECTOR>(
GetArnoldNode(), desc.value, desc.valueIndices, str::nlist, str::nidxs, &_vertexCounts,
&_vertexCountSum);
}
} else {
HdArnoldSetFaceVaryingPrimvar(
GetArnoldNode(), primvar.first, desc.role, desc.value, desc.valueIndices, &_vertexCounts,
&_vertexCountSum);
}
#else
if (primvar.first == _tokens->st || primvar.first == _tokens->uv) {
_ConvertFaceVaryingPrimvarToBuiltin<GfVec2f, AI_TYPE_VECTOR2>(
GetArnoldNode(), desc.value, str::uvlist, str::uvidxs, &_vertexCounts, &_vertexCountSum);
Expand All @@ -376,6 +414,7 @@ void HdArnoldMesh::Sync(
HdArnoldSetFaceVaryingPrimvar(
GetArnoldNode(), primvar.first, desc.role, desc.value, &_vertexCounts, &_vertexCountSum);
}
#endif
}
}

Expand Down
5 changes: 3 additions & 2 deletions render_delegate/render_delegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ TF_DEFINE_PRIVATE_TOKENS(_tokens,
);
// clang-format on

#define PXR_VERSION_STR ARNOLD_XSTR(PXR_MAJOR_VERSION) "." ARNOLD_XSTR(PXR_MINOR_VERSION) "." ARNOLD_XSTR(PXR_PATCH_VERSION)
#define PXR_VERSION_STR \
ARNOLD_XSTR(PXR_MAJOR_VERSION) "." ARNOLD_XSTR(PXR_MINOR_VERSION) "." ARNOLD_XSTR(PXR_PATCH_VERSION)

namespace {

Expand Down Expand Up @@ -362,7 +363,7 @@ HdArnoldRenderDelegate::HdArnoldRenderDelegate(HdArnoldRenderContext context) :
AiADPAddProductMetadata(AI_ADP_HOSTVERSION, AtString{PXR_VERSION_STR});
// TODO(pal): We need to investigate if it's safe to set session to AI_SESSION_BATCH when rendering in husk for
// example. ie. is husk creating a separate render delegate for each frame, or syncs the changes?
AiBegin(AI_SESSION_INTERACTIVE);
AiBegin(AI_SESSION_INTERACTIVE);
}
_supportedRprimTypes = {HdPrimTypeTokens->mesh, HdPrimTypeTokens->volume, HdPrimTypeTokens->points,
HdPrimTypeTokens->basisCurves};
Expand Down
2 changes: 1 addition & 1 deletion render_delegate/render_pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ AtNode* _CreateFilter(HdArnoldRenderDelegate* renderDelegate, const HdAovSetting
void _DisableBlendOpacity(AtNode* node)
{
if (AiNodeEntryLookUpParameter(AiNodeGetNodeEntry(node), str::blend_opacity) != nullptr) {
AiNodeSetBool(node, str::blend_opacity, false);
AiNodeSetBool(node, str::blend_opacity, false);
}
}

Expand Down
107 changes: 87 additions & 20 deletions render_delegate/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1280,27 +1280,27 @@ void HdArnoldSetVertexPrimvar(
}

void HdArnoldSetFaceVaryingPrimvar(
AtNode* node, const TfToken& name, const TfToken& role, const VtValue& value, const VtIntArray* vertexCounts,
const size_t* vertexCountSum)
AtNode* node, const TfToken& name, const TfToken& role, const VtValue& value,
#ifdef USD_HAS_SAMPLE_INDEXED_PRIMVAR
const VtIntArray& valueIndices,
#endif
const VtIntArray* vertexCounts, const size_t* vertexCountSum)
{
const auto numElements =
_DeclareAndAssignFromArray(node, name, str::t_indexed, value, role == HdPrimvarRoleTokens->color);
if (numElements == 0) {
// 0 means the array can't be extracted from the VtValue.
// 1 means the array had a single element, and it was set as a constant user data.
if (numElements <= 1) {
return;
}

AiNodeSetArray(
node, AtString(TfStringPrintf("%sidxs", name.GetText()).c_str()),
HdArnoldGenerateIdxs(numElements, vertexCounts, vertexCountSum));
}
auto* indices =
#ifdef USD_HAS_SAMPLE_INDEXED_PRIMVAR
!valueIndices.empty() ? HdArnoldGenerateIdxs(valueIndices, vertexCounts) :
#endif
HdArnoldGenerateIdxs(numElements, vertexCounts, vertexCountSum);

void HdArnoldSetFaceVaryingPrimvar(
AtNode* node, const SdfPath& id, HdSceneDelegate* sceneDelegate, const HdPrimvarDescriptor& primvarDesc,
const VtIntArray* vertexCounts, const size_t* vertexCountSum)
{
HdArnoldSetFaceVaryingPrimvar(
node, primvarDesc.name, primvarDesc.role, sceneDelegate->Get(id, primvarDesc.name), vertexCounts,
vertexCountSum);
AiNodeSetArray(node, AtString(TfStringPrintf("%sidxs", name.GetText()).c_str()), indices);
}

void HdArnoldSetInstancePrimvar(
Expand Down Expand Up @@ -1408,15 +1408,55 @@ AtArray* HdArnoldGenerateIdxs(unsigned int numIdxs, const VtIntArray* vertexCoun
return array;
}

AtArray* HdArnoldGenerateIdxs(const VtIntArray& indices, const VtIntArray* vertexCounts)
{
const auto numIdxs = static_cast<uint32_t>(indices.size());
if (numIdxs < 3) {
return AiArrayAllocate(0, 1, AI_TYPE_UINT);
}
auto* array = AiArrayAllocate(numIdxs, 1, AI_TYPE_UINT);
auto* out = static_cast<uint32_t*>(AiArrayMap(array));
if (vertexCounts != nullptr && !vertexCounts->empty()) {
unsigned int vertexId = 0;
for (auto vertexCount : *vertexCounts) {
if (Ai_unlikely(vertexCount <= 0) || Ai_unlikely(vertexId + vertexCount >= numIdxs)) {
continue;
}
for (auto vertex = decltype(vertexCount){0}; vertex < vertexCount; vertex += 1) {
out[vertexId + vertex] = indices[vertexId + vertexCount - vertex - 1];
}
vertexId += vertexCount;
}
} else {
std::copy(indices.begin(), indices.end(), out);
}

AiArrayUnmap(array);
return array;
}

void HdArnoldInsertPrimvar(
HdArnoldPrimvarMap& primvars, const TfToken& name, const TfToken& role, HdInterpolation interpolation,
const VtValue& value)
const VtValue& value
#ifdef USD_HAS_SAMPLE_INDEXED_PRIMVAR
,
const VtIntArray& valueIndices
#endif
)
{
auto it = primvars.find(name);
if (it == primvars.end()) {
primvars.insert({name, {value, role, interpolation}});
primvars.insert({name,
{value,
#ifdef USD_HAS_SAMPLE_INDEXED_PRIMVAR
valueIndices,
#endif
role, interpolation}});
} else {
it->second.value = value;
#ifdef USD_HAS_SAMPLE_INDEXED_PRIMVAR
it->second.valueIndices = valueIndices;
#endif
it->second.role = role;
it->second.interpolation = interpolation;
it->second.dirtied = true;
Expand Down Expand Up @@ -1452,7 +1492,11 @@ bool HdArnoldGetComputedPrimvars(
continue;
}
changed = true;
#ifdef USD_HAS_SAMPLE_INDEXED_PRIMVAR
HdArnoldInsertPrimvar(primvars, primvar.name, primvar.role, primvar.interpolation, itComputed->second, {});
#else
HdArnoldInsertPrimvar(primvars, primvar.name, primvar.role, primvar.interpolation, itComputed->second);
#endif
}

return changed;
Expand All @@ -1472,10 +1516,33 @@ void HdArnoldGetPrimvars(
}
// The number of motion keys has to be matched between points and normals, so if there are multiple
// position keys, so we are forcing the user to use the SamplePrimvars function.
HdArnoldInsertPrimvar(
primvars, primvarDesc.name, primvarDesc.role, primvarDesc.interpolation,
(multiplePositionKeys && primvarDesc.name == HdTokens->normals) ? VtValue{}
: delegate->Get(id, primvarDesc.name));
if (multiplePositionKeys && primvarDesc.name == HdTokens->normals) {
#ifdef USD_HAS_SAMPLE_INDEXED_PRIMVAR
HdArnoldInsertPrimvar(primvars, primvarDesc.name, primvarDesc.role, primvarDesc.interpolation, {}, {});
#else
HdArnoldInsertPrimvar(primvars, primvarDesc.name, primvarDesc.role, primvarDesc.interpolation, {});
#endif
} else {
#ifdef USD_HAS_SAMPLE_INDEXED_PRIMVAR
if (primvarDesc.interpolation == HdInterpolationFaceVarying) {
VtIntArray valueIndices;
const auto value = delegate->GetIndexedPrimvar(id, primvarDesc.name, &valueIndices);
HdArnoldInsertPrimvar(
primvars, primvarDesc.name, primvarDesc.role, primvarDesc.interpolation, value, valueIndices);
} else {
#endif
HdArnoldInsertPrimvar(
primvars, primvarDesc.name, primvarDesc.role, primvarDesc.interpolation,
delegate->Get(id, primvarDesc.name)
#ifdef USD_HAS_SAMPLE_INDEXED_PRIMVAR
,
{}
#endif
);
#ifdef USD_HAS_SAMPLE_INDEXED_PRIMVAR
}
#endif
}
}
}
}
Expand Down
Loading

0 comments on commit b45b4c5

Please sign in to comment.