Blender  V3.3
geometry.inl
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2022 NVIDIA Corporation
3  * Copyright 2022 Blender Foundation */
4 
5 #include "hydra/attribute.h"
6 #include "hydra/geometry.h"
7 #include "hydra/instancer.h"
8 #include "hydra/material.h"
9 #include "hydra/session.h"
10 #include "scene/geometry.h"
11 #include "scene/object.h"
12 #include "scene/scene.h"
13 #include "util/hash.h"
14 
15 #include <pxr/imaging/hd/sceneDelegate.h>
16 
18 
19 extern Transform convert_transform(const GfMatrix4d &matrix);
20 
21 template<typename Base, typename CyclesBase>
23 #if PXR_VERSION < 2102
24  ,
25  const SdfPath &instancerId
26 #endif
27  )
28  : Base(rprimId
29 #if PXR_VERSION < 2102
30 
31  ,
32  instancerId
33 #endif
34  ),
35  _geomTransform(1.0)
36 {
37 }
38 
39 template<typename Base, typename CyclesBase>
40 void HdCyclesGeometry<Base, CyclesBase>::_InitRepr(const TfToken &reprToken,
41  HdDirtyBits *dirtyBits)
42 {
43  TF_UNUSED(reprToken);
44  TF_UNUSED(dirtyBits);
45 }
46 
47 template<typename Base, typename CyclesBase>
49 {
50  return HdChangeTracker::DirtyPrimID | HdChangeTracker::DirtyTransform |
51  HdChangeTracker::DirtyMaterialId | HdChangeTracker::DirtyVisibility |
52  HdChangeTracker::DirtyInstancer;
53 }
54 
55 template<typename Base, typename CyclesBase>
57 {
58  return bits;
59 }
60 
61 template<typename Base, typename CyclesBase>
62 void HdCyclesGeometry<Base, CyclesBase>::Sync(HdSceneDelegate *sceneDelegate,
63  HdRenderParam *renderParam,
64  HdDirtyBits *dirtyBits,
65  const TfToken &reprToken)
66 {
67  TF_UNUSED(reprToken);
68 
69  if (*dirtyBits == HdChangeTracker::Clean) {
70  return;
71  }
72 
73  Initialize(renderParam);
74 
75 #if PXR_VERSION >= 2102
76  Base::_UpdateInstancer(sceneDelegate, dirtyBits);
77  HdInstancer::_SyncInstancerAndParents(sceneDelegate->GetRenderIndex(), Base::GetInstancerId());
78 #endif
79  Base::_UpdateVisibility(sceneDelegate, dirtyBits);
80 
81  const SceneLock lock(renderParam);
82 
83  if (*dirtyBits & HdChangeTracker::DirtyMaterialId) {
84 #if HD_API_VERSION >= 37 && PXR_VERSION >= 2105
85  Base::SetMaterialId(sceneDelegate->GetMaterialId(Base::GetId()));
86 #else
87  Base::_SetMaterialId(sceneDelegate->GetRenderIndex().GetChangeTracker(),
88  sceneDelegate->GetMaterialId(Base::GetId()));
89 #endif
90 
91  const auto material = static_cast<const HdCyclesMaterial *>(
92  sceneDelegate->GetRenderIndex().GetSprim(HdPrimTypeTokens->material,
93  Base::GetMaterialId()));
94 
95  array<Node *> usedShaders(1);
96  if (material && material->GetCyclesShader()) {
97  usedShaders[0] = material->GetCyclesShader();
98  }
99  else {
100  usedShaders[0] = lock.scene->default_surface;
101  }
102 
103  for (Node *shader : usedShaders) {
104  static_cast<Shader *>(shader)->tag_used(lock.scene);
105  }
106 
107  _geom->set_used_shaders(usedShaders);
108  }
109 
110  const SdfPath &id = Base::GetId();
111 
112  if (HdChangeTracker::IsPrimIdDirty(*dirtyBits, id)) {
113  // This needs to be corrected in the AOV
114  _instances[0]->set_pass_id(Base::GetPrimId() + 1);
115  }
116 
117  if (HdChangeTracker::IsTransformDirty(*dirtyBits, id)) {
118  _geomTransform = sceneDelegate->GetTransform(id);
119  }
120 
121  if (HdChangeTracker::IsTransformDirty(*dirtyBits, id) ||
122  HdChangeTracker::IsInstancerDirty(*dirtyBits, id)) {
123  const auto instancer = static_cast<HdCyclesInstancer *>(
124  sceneDelegate->GetRenderIndex().GetInstancer(Base::GetInstancerId()));
125 
126  // Make sure the first object attribute is the instanceId
127  assert(_instances[0]->attributes.size() >= 1 &&
128  _instances[0]->attributes.front().name() == HdAovTokens->instanceId.GetString());
129 
130  VtMatrix4dArray transforms;
131  if (instancer) {
132  transforms = instancer->ComputeInstanceTransforms(id);
133  _instances[0]->attributes.front() = ParamValue(HdAovTokens->instanceId.GetString(), +0.0f);
134  }
135  else {
136  // Default to a single instance with an identity transform
137  transforms.push_back(GfMatrix4d(1.0));
138  _instances[0]->attributes.front() = ParamValue(HdAovTokens->instanceId.GetString(), -1.0f);
139  }
140 
141  const size_t oldSize = _instances.size();
142  const size_t newSize = transforms.size();
143 
144  // Resize instance list
145  for (size_t i = newSize; i < oldSize; ++i) {
146  lock.scene->delete_node(_instances[i]);
147  }
148  _instances.resize(newSize);
149  for (size_t i = oldSize; i < newSize; ++i) {
150  _instances[i] = lock.scene->create_node<Object>();
151  InitializeInstance(static_cast<int>(i));
152  }
153 
154  // Update transforms of all instances
155  for (size_t i = 0; i < transforms.size(); ++i) {
156  const float metersPerUnit =
157  static_cast<HdCyclesSession *>(renderParam)->GetStageMetersPerUnit();
158 
159  const Transform tfm = transform_scale(make_float3(metersPerUnit)) *
160  convert_transform(_geomTransform * transforms[i]);
161  _instances[i]->set_tfm(tfm);
162  }
163  }
164 
165  if (HdChangeTracker::IsVisibilityDirty(*dirtyBits, id)) {
166  for (Object *instance : _instances) {
167  instance->set_visibility(Base::IsVisible() ? ~0 : 0);
168  }
169  }
170 
171  // Must happen after material ID update, so that attribute decisions can be made
172  // based on it (e.g. check whether an attribute is actually needed)
173  bool rebuild = false;
174  Populate(sceneDelegate, *dirtyBits, rebuild);
175 
176  if (_geom->is_modified() || rebuild) {
177  _geom->tag_update(lock.scene, rebuild);
178  }
179 
180  for (Object *instance : _instances) {
181  instance->tag_update(lock.scene);
182  }
183 
184  *dirtyBits = HdChangeTracker::Clean;
185 }
186 
187 template<typename Base, typename CyclesBase>
188 void HdCyclesGeometry<Base, CyclesBase>::Finalize(HdRenderParam *renderParam)
189 {
190  if (!_geom && _instances.empty()) {
191  return;
192  }
193 
194  const SceneLock lock(renderParam);
195  const bool keep_nodes = static_cast<const HdCyclesSession *>(renderParam)->keep_nodes;
196 
197  if (!keep_nodes) {
198  lock.scene->delete_node(_geom);
199  }
200  _geom = nullptr;
201 
202  if (!keep_nodes) {
203  lock.scene->delete_nodes(set<Object *>(_instances.begin(), _instances.end()));
204  }
205  _instances.clear();
206  _instances.shrink_to_fit();
207 }
208 
209 template<typename Base, typename CyclesBase>
210 void HdCyclesGeometry<Base, CyclesBase>::Initialize(HdRenderParam *renderParam)
211 {
212  if (_geom) {
213  return;
214  }
215 
216  const SceneLock lock(renderParam);
217 
218  // Create geometry
219  _geom = lock.scene->create_node<CyclesBase>();
220  _geom->name = Base::GetId().GetString();
221 
222  // Create default instance
223  _instances.push_back(lock.scene->create_node<Object>());
224  InitializeInstance(0);
225 }
226 
227 template<typename Base, typename CyclesBase>
229 {
230  Object *instance = _instances[index];
231  instance->set_geometry(_geom);
232 
233  instance->attributes.emplace_back(HdAovTokens->instanceId.GetString(),
234  _instances.size() == 1 ? -1.0f : static_cast<float>(index));
235 
236  instance->set_color(make_float3(0.8f, 0.8f, 0.8f));
237  instance->set_random_id(hash_uint2(hash_string(_geom->name.c_str()), index));
238 }
239 
240 template<typename Base, typename CyclesBase>
242  HdSceneDelegate *sceneDelegate, const TfToken &name) const
243 {
244  for (int i = 0; i < HdInterpolationCount; ++i) {
245  for (const HdPrimvarDescriptor &desc :
246  Base::GetPrimvarDescriptors(sceneDelegate, static_cast<HdInterpolation>(i))) {
247  if (desc.name == name) {
248  return static_cast<HdInterpolation>(i);
249  }
250  }
251  }
252 
253  return HdInterpolationCount;
254 }
255 
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object instance
volatile int lock
static void Initialize(const btConvexTemplate &a, const btConvexTemplate &b, btGjkEpaSolver3::sResults &results, MinkowskiDiff< btConvexTemplate > &shape)
Definition: btGjkEpa3.h:878
HdCyclesGeometry(const PXR_NS::SdfPath &rprimId, const PXR_NS::SdfPath &instancerId)
Definition: geometry.inl:22
PXR_NS::HdDirtyBits _PropagateDirtyBits(PXR_NS::HdDirtyBits bits) const override
Definition: geometry.inl:56
virtual void Finalize(PXR_NS::HdRenderParam *renderParam) override
Definition: geometry.inl:188
void _InitRepr(const PXR_NS::TfToken &reprToken, PXR_NS::HdDirtyBits *dirtyBits) override
Definition: geometry.inl:40
PXR_NS::HdInterpolation GetPrimvarInterpolation(PXR_NS::HdSceneDelegate *sceneDelegate, const PXR_NS::TfToken &name) const
Definition: geometry.inl:241
PXR_NS::HdDirtyBits GetInitialDirtyBitsMask() const override
Definition: geometry.inl:48
void Sync(PXR_NS::HdSceneDelegate *sceneDelegate, PXR_NS::HdRenderParam *renderParam, PXR_NS::HdDirtyBits *dirtyBits, const PXR_NS::TfToken &reprToken) override
Definition: geometry.inl:62
Material material
HDCYCLES_NAMESPACE_OPEN_SCOPE Transform convert_transform(const GfMatrix4d &matrix)
Definition: hydra/mesh.cpp:65
static uint hash_string(const char *str)
Definition: hash.h:363
ccl_device_inline uint hash_uint2(uint kx, uint ky)
Definition: hash.h:70
#define HDCYCLES_NAMESPACE_CLOSE_SCOPE
Definition: hydra/config.h:17
ccl_device_inline Transform transform_scale(float3 s)
#define make_float3(x, y, z)
Definition: metal/compat.h:204