Skip to content

Commit

Permalink
Adding support for light linking. (#647)
Browse files Browse the repository at this point in the history
Fixes #412
  • Loading branch information
sirpalee authored Feb 1, 2021
1 parent 05009d8 commit 4f5e08d
Show file tree
Hide file tree
Showing 32 changed files with 653 additions and 453 deletions.
2 changes: 1 addition & 1 deletion docs/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Python and Boost are optional if USD was build without Python support.

| Name | Version | Optional |
| --- | --- | --- |
| Arnold | 5.4+ | |
| Arnold | 6.0.3+ | |
| USD | v19.05 - dev | |
| Python | 2.7 | x |
| Boost | 1.55 (Linux), 1.61 (Mac, Windows VS 2015), 1.65.1 (Windows VS 2017) or 1.66.0 (VFX platform) | x |
Expand Down
1 change: 1 addition & 0 deletions render_delegate/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ set(HDR
config.h
constant_strings.h
debug_codes.h
rprim.h
hdarnold.h
instancer.h
light.h
Expand Down
79 changes: 34 additions & 45 deletions render_delegate/basis_curves.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,45 +143,45 @@ inline bool _RemapVertexPrimvar(

HdArnoldBasisCurves::HdArnoldBasisCurves(
HdArnoldRenderDelegate* delegate, const SdfPath& id, const SdfPath& instancerId)
: HdBasisCurves(id, instancerId), _shape(str::curves, delegate, id, GetPrimId()), _interpolation(HdTokens->linear)
: HdArnoldRprim<HdBasisCurves>(str::curves, delegate, id, instancerId), _interpolation(HdTokens->linear)
{
}

void HdArnoldBasisCurves::Sync(
HdSceneDelegate* delegate, HdRenderParam* renderParam, HdDirtyBits* dirtyBits, const TfToken& reprToken)
HdSceneDelegate* sceneDelegate, HdRenderParam* renderParam, HdDirtyBits* dirtyBits, const TfToken& reprToken)
{
TF_UNUSED(reprToken);
auto* param = reinterpret_cast<HdArnoldRenderParam*>(renderParam);
const auto& id = GetId();

// Points can either come through accessing HdTokens->points, or driven by UsdSkel.
const auto dirtyPrimvars = HdArnoldGetComputedPrimvars(delegate, id, *dirtyBits, _primvars) ||
const auto dirtyPrimvars = HdArnoldGetComputedPrimvars(sceneDelegate, id, *dirtyBits, _primvars) ||
(*dirtyBits & HdChangeTracker::DirtyPrimvar);
if (_primvars.count(HdTokens->points) == 0 && HdChangeTracker::IsPrimvarDirty(*dirtyBits, id, HdTokens->points)) {
param->Interrupt();
HdArnoldSetPositionFromPrimvar(_shape.GetShape(), id, delegate, str::points);
HdArnoldSetPositionFromPrimvar(GetArnoldNode(), id, sceneDelegate, str::points);
}

if (HdChangeTracker::IsTopologyDirty(*dirtyBits, id)) {
param->Interrupt();
const auto topology = GetBasisCurvesTopology(delegate);
const auto topology = GetBasisCurvesTopology(sceneDelegate);
const auto curveBasis = topology.GetCurveBasis();
const auto curveType = topology.GetCurveType();
if (curveType == HdTokens->linear) {
AiNodeSetStr(_shape.GetShape(), str::basis, str::linear);
AiNodeSetStr(GetArnoldNode(), str::basis, str::linear);
_interpolation = HdTokens->linear;
} else {
if (curveBasis == HdTokens->bezier) {
AiNodeSetStr(_shape.GetShape(), str::basis, str::bezier);
AiNodeSetStr(GetArnoldNode(), str::basis, str::bezier);
_interpolation = HdTokens->bezier;
} else if (curveBasis == HdTokens->bSpline) {
AiNodeSetStr(_shape.GetShape(), str::basis, str::b_spline);
AiNodeSetStr(GetArnoldNode(), str::basis, str::b_spline);
_interpolation = HdTokens->bSpline;
} else if (curveBasis == HdTokens->catmullRom) {
AiNodeSetStr(_shape.GetShape(), str::basis, str::catmull_rom);
AiNodeSetStr(GetArnoldNode(), str::basis, str::catmull_rom);
_interpolation = HdTokens->catmullRom;
} else {
AiNodeSetStr(_shape.GetShape(), str::basis, str::linear);
AiNodeSetStr(GetArnoldNode(), str::basis, str::linear);
_interpolation = HdTokens->linear;
}
}
Expand All @@ -200,37 +200,37 @@ void HdArnoldBasisCurves::Sync(
return static_cast<uint32_t>(i);
});
AiArrayUnmap(numPointsArray);
AiNodeSetArray(_shape.GetShape(), str::num_points, numPointsArray);
AiNodeSetArray(GetArnoldNode(), str::num_points, numPointsArray);
}

if (HdChangeTracker::IsVisibilityDirty(*dirtyBits, id)) {
param->Interrupt();
_UpdateVisibility(delegate, dirtyBits);
_shape.SetVisibility(_sharedData.visible ? AI_RAY_ALL : uint8_t{0});
_UpdateVisibility(sceneDelegate, dirtyBits);
SetShapeVisibility(_sharedData.visible ? AI_RAY_ALL : uint8_t{0});
}

auto transformDirtied = false;
if (HdChangeTracker::IsTransformDirty(*dirtyBits, id)) {
param->Interrupt();
HdArnoldSetTransform(_shape.GetShape(), delegate, GetId());
HdArnoldSetTransform(GetArnoldNode(), sceneDelegate, GetId());
transformDirtied = true;
}

if (*dirtyBits & HdChangeTracker::DirtyMaterialId) {
param->Interrupt();
const auto* material = reinterpret_cast<const HdArnoldMaterial*>(
delegate->GetRenderIndex().GetSprim(HdPrimTypeTokens->material, delegate->GetMaterialId(id)));
sceneDelegate->GetRenderIndex().GetSprim(HdPrimTypeTokens->material, sceneDelegate->GetMaterialId(id)));
if (material != nullptr) {
AiNodeSetPtr(_shape.GetShape(), str::shader, material->GetSurfaceShader());
AiNodeSetPtr(GetArnoldNode(), str::shader, material->GetSurfaceShader());
} else {
AiNodeSetPtr(_shape.GetShape(), str::shader, _shape.GetDelegate()->GetFallbackShader());
AiNodeSetPtr(GetArnoldNode(), str::shader, GetRenderDelegate()->GetFallbackShader());
}
}

if (dirtyPrimvars) {
HdArnoldGetPrimvars(delegate, id, *dirtyBits, false, _primvars);
HdArnoldGetPrimvars(sceneDelegate, id, *dirtyBits, false, _primvars);
param->Interrupt();
auto visibility = _shape.GetVisibility();
auto visibility = GetShapeVisibility();
const auto vstep = _interpolation == HdTokens->bezier ? 3 : 1;
const auto vmin = _interpolation == HdTokens->linear ? 2 : 4;
// TODO(pal): Should we cache these?
Expand Down Expand Up @@ -265,24 +265,24 @@ void HdArnoldBasisCurves::Sync(
setArnoldVertexCounts();
// Remapping the per vertex parameters to match the arnold requirements.
_RemapVertexPrimvar<float, double>(value, _vertexCounts, arnoldVertexCounts, numPerVertex);
HdArnoldSetRadiusFromValue(_shape.GetShape(), value);
HdArnoldSetRadiusFromValue(GetArnoldNode(), value);
} else {
HdArnoldSetRadiusFromValue(_shape.GetShape(), desc.value);
HdArnoldSetRadiusFromValue(GetArnoldNode(), desc.value);
}
// For constant and
} else if (desc.interpolation == HdInterpolationConstant) {
// We skip reading the basis for now as it would require remapping the vertices, widths and
// all the primvars.
if (primvar.first != _tokens->basis) {
HdArnoldSetConstantPrimvar(_shape.GetShape(), primvar.first, desc.role, desc.value, &visibility);
HdArnoldSetConstantPrimvar(GetArnoldNode(), primvar.first, desc.role, desc.value, &visibility);
}
} else if (desc.interpolation == HdInterpolationUniform) {
if (primvar.first == str::t_uv || primvar.first == str::t_st) {
// This is either a VtVec2fArray or VtVec3fArray (in Solaris).
if (desc.value.IsHolding<VtVec2fArray>()) {
const auto& v = desc.value.UncheckedGet<VtVec2fArray>();
AiNodeSetArray(
_shape.GetShape(), str::uvs, AiArrayConvert(v.size(), 1, AI_TYPE_VECTOR2, v.data()));
GetArnoldNode(), str::uvs, AiArrayConvert(v.size(), 1, AI_TYPE_VECTOR2, v.data()));
} else if (desc.value.IsHolding<VtVec3fArray>()) {
const auto& v = desc.value.UncheckedGet<VtVec3fArray>();
auto* arr = AiArrayAllocate(v.size(), 1, AI_TYPE_VECTOR2);
Expand All @@ -292,20 +292,20 @@ void HdArnoldBasisCurves::Sync(
return {in[0], in[1]};
});
AiArrayUnmap(arr);
AiNodeSetArray(_shape.GetShape(), str::uvs, arr);
AiNodeSetArray(GetArnoldNode(), str::uvs, arr);
} else {
// If it's an unsupported type, just set it as user data.
HdArnoldSetUniformPrimvar(_shape.GetShape(), primvar.first, desc.role, desc.value);
HdArnoldSetUniformPrimvar(GetArnoldNode(), primvar.first, desc.role, desc.value);
}
} else {
HdArnoldSetUniformPrimvar(_shape.GetShape(), primvar.first, desc.role, desc.value);
HdArnoldSetUniformPrimvar(GetArnoldNode(), primvar.first, desc.role, desc.value);
}
} else if (desc.interpolation == HdInterpolationVertex) {
if (primvar.first == HdTokens->points) {
HdArnoldSetPositionFromValue(_shape.GetShape(), str::curves, desc.value);
HdArnoldSetPositionFromValue(GetArnoldNode(), str::curves, desc.value);
} else if (primvar.first == HdTokens->normals) {
// This should be the same number as points.
HdArnoldSetPositionFromValue(_shape.GetShape(), str::orientations, desc.value);
HdArnoldSetPositionFromValue(GetArnoldNode(), str::orientations, desc.value);
} else {
auto value = desc.value;
if (_interpolation != HdTokens->linear) {
Expand All @@ -315,16 +315,16 @@ void HdArnoldBasisCurves::Sync(
bool, VtUCharArray::value_type, unsigned int, int, float, GfVec2f, GfVec3f, GfVec4f,
std::string, TfToken, SdfAssetPath>(value, _vertexCounts, arnoldVertexCounts, numPerVertex);
}
HdArnoldSetVertexPrimvar(_shape.GetShape(), primvar.first, desc.role, value);
HdArnoldSetVertexPrimvar(GetArnoldNode(), primvar.first, desc.role, value);
}
} else if (desc.interpolation == HdInterpolationVarying) {
HdArnoldSetVertexPrimvar(_shape.GetShape(), primvar.first, desc.role, desc.value);
HdArnoldSetVertexPrimvar(GetArnoldNode(), primvar.first, desc.role, desc.value);
}
}
_shape.SetVisibility(visibility);
SetShapeVisibility(visibility);
}

_shape.Sync(this, *dirtyBits, delegate, param, transformDirtied);
SyncShape(*dirtyBits, sceneDelegate, param, transformDirtied);

*dirtyBits = HdChangeTracker::Clean;
}
Expand All @@ -333,19 +333,8 @@ HdDirtyBits HdArnoldBasisCurves::GetInitialDirtyBitsMask() const
{
return HdChangeTracker::Clean | HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyTopology |
HdChangeTracker::DirtyTransform | HdChangeTracker::DirtyVisibility | HdChangeTracker::DirtyPrimvar |
HdChangeTracker::DirtyNormals | HdChangeTracker::DirtyWidths | HdChangeTracker::DirtyInstancer |
HdChangeTracker::DirtyMaterialId;
}

HdDirtyBits HdArnoldBasisCurves::_PropagateDirtyBits(HdDirtyBits bits) const
{
return bits & HdChangeTracker::AllDirty;
}

void HdArnoldBasisCurves::_InitRepr(const TfToken& reprToken, HdDirtyBits* dirtyBits)
{
TF_UNUSED(reprToken);
TF_UNUSED(dirtyBits);
HdChangeTracker::DirtyNormals | HdChangeTracker::DirtyWidths | HdChangeTracker::DirtyMaterialId |
HdArnoldShape::GetInitialDirtyBitsMask();
}

PXR_NAMESPACE_CLOSE_SCOPE
31 changes: 11 additions & 20 deletions render_delegate/basis_curves.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,46 +24,37 @@

#include <pxr/imaging/hd/basisCurves.h>

#include "shape.h"
#include "rprim.h"
#include "utils.h"

PXR_NAMESPACE_OPEN_SCOPE

class HdArnoldBasisCurves : public HdBasisCurves {
class HdArnoldBasisCurves : public HdArnoldRprim<HdBasisCurves> {
public:
HDARNOLD_API
HdArnoldBasisCurves(HdArnoldRenderDelegate* delegate, const SdfPath& id, const SdfPath& instancerId = SdfPath());

/// Destructor for HdArnoldBasisCurves.
///
/// Destory all Arnold curves and ginstances.
~HdArnoldBasisCurves() override = default;

/// Syncs the Hydra Basis Curves to the Arnold Curves.
///
/// @param sceneDelegate Pointer to the Scene Delegate.
/// @param renderPaaram Pointer to a HdArnoldRenderParam instance.
/// @param renderParam Pointer to a HdArnoldRenderParam instance.
/// @param dirtyBits Dirty Bits to sync.
/// @param reprToken Token describing the representation of the mesh.
void Sync(HdSceneDelegate* delegate, HdRenderParam* renderParam, HdDirtyBits* dirtyBits, const TfToken& reprToken)
override;
void Sync(
HdSceneDelegate* sceneDelegate, HdRenderParam* renderParam, HdDirtyBits* dirtyBits,
const TfToken& reprToken) override;

/// Returns the initial Dirty Bits for the Primitive.
///
/// @return Initial Dirty Bits.
HdDirtyBits GetInitialDirtyBitsMask() const override;

protected:
/// Allows setting additional Dirty Bits based on the ones already set.
///
/// @param bits The current Dirty Bits.
/// @return The new set of Dirty Bits which replace the original one.
HdDirtyBits _PropagateDirtyBits(HdDirtyBits bits) const override;

/// Initialize a given representation for the curves.
///
/// @param reprName Name of the representation to initialize.
/// @param dirtyBits In/Out HdDirtyBits value, that allows the _InitRepr
/// function to set additional Dirty Bits if required for a given
/// representation.
void _InitRepr(const TfToken& reprToken, HdDirtyBits* dirtyBits) override;

HdArnoldShape _shape; ///< Utility class for the curves and instances.
HdArnoldPrimvarMap _primvars; ///< Precomputed list of primvars.
TfToken _interpolation; ///< Interpolation of the curve.
VtIntArray _vertexCounts; ///< Stored vertex counts for curves.
Expand Down
4 changes: 2 additions & 2 deletions render_delegate/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ TF_DEFINE_PRIVATE_TOKENS(_tokens,
);
// clang-format on

HdArnoldCamera::HdArnoldCamera(HdArnoldRenderDelegate* delegate, const SdfPath& id) : HdCamera(id)
HdArnoldCamera::HdArnoldCamera(HdArnoldRenderDelegate* renderDelegate, const SdfPath& id) : HdCamera(id)
{
// We create a persp_camera by default and optionally replace the node in ::Sync.
_camera = AiNode(delegate->GetUniverse(), str::persp_camera);
_camera = AiNode(renderDelegate->GetUniverse(), str::persp_camera);
if (!id.IsEmpty()) {
AiNodeSetStr(_camera, str::name, id.GetText());
}
Expand Down
4 changes: 2 additions & 2 deletions render_delegate/camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ class HdArnoldCamera : public HdCamera {
public:
/// Constructor for HdArnoldCamera.
///
/// @param delegate Pointer to the Render Delegate.
/// @param renderDelegate Pointer to the Render Delegate.
/// @param id Path to the material.
HDARNOLD_API
HdArnoldCamera(HdArnoldRenderDelegate* delegate, const SdfPath& id);
HdArnoldCamera(HdArnoldRenderDelegate* renderDelegate, const SdfPath& id);

/// Destructor for HdArnoldCamera.
///
Expand Down
10 changes: 7 additions & 3 deletions render_delegate/constant_strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ ASTR(interactive_target_fps);
ASTR(interactive_target_fps_min);
ASTR(ior);
ASTR(latlong);
ASTR(light_group);
ASTR(light_path_expressions);
ASTR(linear);
ASTR(log_file);
Expand Down Expand Up @@ -272,16 +273,17 @@ ASTR(roughness);
ASTR(scale);
ASTR(shade_mode);
ASTR(shader);
ASTR(shadow_group);
ASTR(shidxs);
ASTR(shutter_end);
ASTR(shutter_start);
ASTR(sidedness);
ASTR(skydome_light);
ASTR(specular);
ASTR(specularColor);
ASTR(specular_IOR);
ASTR(specular_color);
ASTR(specular_IOR);
ASTR(specular_roughness);
ASTR(specularColor);
ASTR(spot_light);
ASTR(st);
ASTR(standard_surface);
Expand All @@ -302,12 +304,14 @@ ASTR(thread_priority);
ASTR(threads);
ASTR(total_progress);
ASTR(translation);
ASTR(useSpecularWorkflow);
ASTR(use_light_group);
ASTR(use_shadow_group);
ASTR(user_data_float);
ASTR(user_data_int);
ASTR(user_data_rgb);
ASTR(user_data_rgba);
ASTR(user_data_string);
ASTR(useSpecularWorkflow);
ASTR(utility);
ASTR(uv);
ASTR(uvcoords);
Expand Down
5 changes: 0 additions & 5 deletions render_delegate/hdarnold.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,3 @@
/// Not blitting to a hardware buffer anymore, following the example of HdEmbree.
#define USD_DO_NOT_BLIT
#endif

#if AI_VERSION_NUMBER >= 60003
/// Using the core instancer procedural instead of inline instances.
#define HDARNOLD_USE_INSTANCER
#endif
2 changes: 1 addition & 1 deletion render_delegate/instancer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ inline const VtArray<T>& _LookupInstancePrimvar(const HdArnoldPrimvarMap& primva
HdArnoldInstancer::HdArnoldInstancer(
HdArnoldRenderDelegate* renderDelegate, HdSceneDelegate* sceneDelegate, const SdfPath& id,
const SdfPath& parentInstancerId)
: HdInstancer(sceneDelegate, id, parentInstancerId), _delegate(renderDelegate)
: HdInstancer(sceneDelegate, id, parentInstancerId)
{
}

Expand Down
4 changes: 1 addition & 3 deletions render_delegate/instancer.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,7 @@ class HdArnoldInstancer : public HdInstancer {
HDARNOLD_API
void _SyncPrimvars();

HdArnoldRenderDelegate* _delegate; ///< The active render delegate.
std::mutex _mutex; ///< Mutex to safe-guard calls to _SyncPrimvars.

std::mutex _mutex; ///< Mutex to safe-guard calls to _SyncPrimvars.
HdArnoldPrimvarMap _primvars; ///< Unordered map to store all the primvars.
};

Expand Down
Loading

0 comments on commit 4f5e08d

Please sign in to comment.