Blender  V3.3
node_util.cpp
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/node_util.h"
6 #include "util/transform.h"
7 
8 #include <pxr/base/gf/matrix3d.h>
9 #include <pxr/base/gf/matrix3f.h>
10 #include <pxr/base/gf/matrix4d.h>
11 #include <pxr/base/gf/matrix4f.h>
12 #include <pxr/base/gf/vec2f.h>
13 #include <pxr/base/gf/vec3f.h>
14 #include <pxr/base/vt/array.h>
15 #include <pxr/usd/sdf/assetPath.h>
16 
18 
19 namespace {
20 
21 template<typename DstType> DstType convertToCycles(const VtValue &value)
22 {
23  if (value.IsHolding<DstType>()) {
24  return value.UncheckedGet<DstType>();
25  }
26 
27  VtValue castedValue = VtValue::Cast<DstType>(value);
28  if (castedValue.IsHolding<DstType>()) {
29  return castedValue.UncheckedGet<DstType>();
30  }
31 
32  TF_WARN("Could not convert VtValue to Cycles type");
33  return DstType(0);
34 }
35 
36 template<> float2 convertToCycles<float2>(const VtValue &value)
37 {
38  const GfVec2f convertedValue = convertToCycles<GfVec2f>(value);
39  return make_float2(convertedValue[0], convertedValue[1]);
40 }
41 
42 template<> float3 convertToCycles<float3>(const VtValue &value)
43 {
44  if (value.IsHolding<GfVec3f>()) {
45  const GfVec3f convertedValue = value.UncheckedGet<GfVec3f>();
46  return make_float3(convertedValue[0], convertedValue[1], convertedValue[2]);
47  }
48  if (value.IsHolding<GfVec4f>()) {
49  const GfVec4f convertedValue = value.UncheckedGet<GfVec4f>();
50  return make_float3(convertedValue[0], convertedValue[1], convertedValue[2]);
51  }
52 
53  if (value.CanCast<GfVec3f>()) {
54  const GfVec3f convertedValue = VtValue::Cast<GfVec3f>(value).UncheckedGet<GfVec3f>();
55  return make_float3(convertedValue[0], convertedValue[1], convertedValue[2]);
56  }
57  if (value.CanCast<GfVec4f>()) {
58  const GfVec4f convertedValue = VtValue::Cast<GfVec4f>(value).UncheckedGet<GfVec4f>();
59  return make_float3(convertedValue[0], convertedValue[1], convertedValue[2]);
60  }
61 
62  TF_WARN("Could not convert VtValue to float3");
63  return zero_float3();
64 }
65 
66 template<> ustring convertToCycles<ustring>(const VtValue &value)
67 {
68  if (value.IsHolding<TfToken>()) {
69  return ustring(value.UncheckedGet<TfToken>().GetString());
70  }
71  if (value.IsHolding<std::string>()) {
72  return ustring(value.UncheckedGet<std::string>());
73  }
74  if (value.IsHolding<SdfAssetPath>()) {
75  const SdfAssetPath &path = value.UncheckedGet<SdfAssetPath>();
76  return ustring(path.GetResolvedPath());
77  }
78 
79  if (value.CanCast<TfToken>()) {
80  return convertToCycles<ustring>(VtValue::Cast<TfToken>(value));
81  }
82  if (value.CanCast<std::string>()) {
83  return convertToCycles<ustring>(VtValue::Cast<std::string>(value));
84  }
85  if (value.CanCast<SdfAssetPath>()) {
86  return convertToCycles<ustring>(VtValue::Cast<SdfAssetPath>(value));
87  }
88 
89  TF_WARN("Could not convert VtValue to ustring");
90  return ustring();
91 }
92 
93 template<typename Matrix>
96  &matrix)
97 {
98  return make_transform(matrix[0][0],
99  matrix[1][0],
100  matrix[2][0],
101  0,
102  matrix[0][1],
103  matrix[1][1],
104  matrix[2][1],
105  0,
106  matrix[0][2],
107  matrix[1][2],
108  matrix[2][2],
109  0);
110 }
111 
112 template<typename Matrix>
115  &matrix)
116 {
117  return make_transform(matrix[0][0],
118  matrix[1][0],
119  matrix[2][0],
120  matrix[3][0],
121  matrix[0][1],
122  matrix[1][1],
123  matrix[2][1],
124  matrix[3][1],
125  matrix[0][2],
126  matrix[1][2],
127  matrix[2][2],
128  matrix[3][2]);
129 }
130 
131 template<> Transform convertToCycles<Transform>(const VtValue &value)
132 {
133  if (value.IsHolding<GfMatrix4f>()) {
134  return convertMatrixToCycles<GfMatrix4f>(value.UncheckedGet<GfMatrix4f>());
135  }
136  if (value.IsHolding<GfMatrix3f>()) {
137  return convertMatrixToCycles<GfMatrix3f>(value.UncheckedGet<GfMatrix3f>());
138  }
139  if (value.IsHolding<GfMatrix4d>()) {
140  return convertMatrixToCycles<GfMatrix4d>(value.UncheckedGet<GfMatrix4d>());
141  }
142  if (value.IsHolding<GfMatrix3d>()) {
143  return convertMatrixToCycles<GfMatrix3d>(value.UncheckedGet<GfMatrix3d>());
144  }
145 
146  if (value.CanCast<GfMatrix4f>()) {
147  return convertToCycles<Transform>(VtValue::Cast<GfMatrix4f>(value));
148  }
149  if (value.CanCast<GfMatrix3f>()) {
150  return convertToCycles<Transform>(VtValue::Cast<GfMatrix3f>(value));
151  }
152  if (value.CanCast<GfMatrix4d>()) {
153  return convertToCycles<Transform>(VtValue::Cast<GfMatrix4d>(value));
154  }
155  if (value.CanCast<GfMatrix3d>()) {
156  return convertToCycles<Transform>(VtValue::Cast<GfMatrix3d>(value));
157  }
158 
159  TF_WARN("Could not convert VtValue to Transform");
160  return transform_identity();
161 }
162 
163 template<typename DstType, typename SrcType = DstType>
165 {
166  static_assert(sizeof(DstType) == sizeof(SrcType),
167  "Size mismatch between VtArray and array base type");
168 
169  using SrcArray = VtArray<SrcType>;
170 
171  if (value.IsHolding<SrcArray>()) {
172  const auto &valueData = value.UncheckedGet<SrcArray>();
173  array<DstType> cyclesArray;
174  cyclesArray.resize(valueData.size());
175  std::memcpy(cyclesArray.data(), valueData.data(), valueData.size() * sizeof(DstType));
176  return cyclesArray;
177  }
178 
179  if (value.CanCast<SrcArray>()) {
180  VtValue castedValue = VtValue::Cast<SrcArray>(value);
181  const auto &valueData = castedValue.UncheckedGet<SrcArray>();
182  array<DstType> cyclesArray;
183  cyclesArray.resize(valueData.size());
184  std::memcpy(cyclesArray.data(), valueData.data(), valueData.size() * sizeof(DstType));
185  return cyclesArray;
186  }
187 
188  return array<DstType>();
189 }
190 
191 template<> array<float3> convertToCyclesArray<float3, GfVec3f>(const VtValue &value)
192 {
193  if (value.IsHolding<VtVec3fArray>()) {
194  const auto &valueData = value.UncheckedGet<VtVec3fArray>();
195  array<float3> cyclesArray;
196  cyclesArray.reserve(valueData.size());
197  for (const GfVec3f &vec : valueData) {
198  cyclesArray.push_back_reserved(make_float3(vec[0], vec[1], vec[2]));
199  }
200  return cyclesArray;
201  }
202  if (value.IsHolding<VtVec4fArray>()) {
203  const auto &valueData = value.UncheckedGet<VtVec4fArray>();
204  array<float3> cyclesArray;
205  cyclesArray.reserve(valueData.size());
206  for (const GfVec4f &vec : valueData) {
207  cyclesArray.push_back_reserved(make_float3(vec[0], vec[1], vec[2]));
208  }
209  return cyclesArray;
210  }
211 
212  if (value.CanCast<VtVec3fArray>()) {
213  return convertToCyclesArray<float3, GfVec3f>(VtValue::Cast<VtVec3fArray>(value));
214  }
215  if (value.CanCast<VtVec4fArray>()) {
216  return convertToCyclesArray<float3, GfVec3f>(VtValue::Cast<VtVec4fArray>(value));
217  }
218 
219  return array<float3>();
220 }
221 
222 template<> array<ustring> convertToCyclesArray<ustring, void>(const VtValue &value)
223 {
224  using SdfPathArray = VtArray<SdfAssetPath>;
225 
226  if (value.IsHolding<VtStringArray>()) {
227  const auto &valueData = value.UncheckedGet<VtStringArray>();
228  array<ustring> cyclesArray;
229  cyclesArray.reserve(valueData.size());
230  for (const auto &element : valueData) {
231  cyclesArray.push_back_reserved(ustring(element));
232  }
233  return cyclesArray;
234  }
235  if (value.IsHolding<VtTokenArray>()) {
236  const auto &valueData = value.UncheckedGet<VtTokenArray>();
237  array<ustring> cyclesArray;
238  cyclesArray.reserve(valueData.size());
239  for (const auto &element : valueData) {
240  cyclesArray.push_back_reserved(ustring(element.GetString()));
241  }
242  return cyclesArray;
243  }
244  if (value.IsHolding<SdfPathArray>()) {
245  const auto &valueData = value.UncheckedGet<SdfPathArray>();
246  array<ustring> cyclesArray;
247  cyclesArray.reserve(valueData.size());
248  for (const auto &element : valueData) {
249  cyclesArray.push_back_reserved(ustring(element.GetResolvedPath()));
250  }
251  return cyclesArray;
252  }
253 
254  if (value.CanCast<VtStringArray>()) {
255  return convertToCyclesArray<ustring, void>(VtValue::Cast<VtStringArray>(value));
256  }
257  if (value.CanCast<VtTokenArray>()) {
258  return convertToCyclesArray<ustring, void>(VtValue::Cast<VtTokenArray>(value));
259  }
260  if (value.CanCast<SdfPathArray>()) {
261  return convertToCyclesArray<ustring, void>(VtValue::Cast<SdfPathArray>(value));
262  }
263 
264  TF_WARN("Could not convert VtValue to array<ustring>");
265  return array<ustring>();
266 }
267 
268 template<typename MatrixArray> array<Transform> convertToCyclesTransformArray(const VtValue &value)
269 {
270  assert(value.IsHolding<MatrixArray>());
271 
272  const auto &valueData = value.UncheckedGet<MatrixArray>();
273  array<Transform> cyclesArray;
274  cyclesArray.reserve(valueData.size());
275  for (const auto &element : valueData) {
276  cyclesArray.push_back_reserved(
277  convertMatrixToCycles<typename MatrixArray::value_type>(element));
278  }
279  return cyclesArray;
280 }
281 
282 template<> array<Transform> convertToCyclesArray<Transform, void>(const VtValue &value)
283 {
284  if (value.IsHolding<VtMatrix4fArray>()) {
285  return convertToCyclesTransformArray<VtMatrix4fArray>(value);
286  }
287  if (value.IsHolding<VtMatrix3fArray>()) {
288  return convertToCyclesTransformArray<VtMatrix3fArray>(value);
289  }
290  if (value.IsHolding<VtMatrix4dArray>()) {
291  return convertToCyclesTransformArray<VtMatrix4dArray>(value);
292  }
293  if (value.IsHolding<VtMatrix3dArray>()) {
294  return convertToCyclesTransformArray<VtMatrix3dArray>(value);
295  }
296 
297  if (value.CanCast<VtMatrix4fArray>()) {
298  return convertToCyclesTransformArray<VtMatrix4fArray>(VtValue::Cast<VtMatrix4fArray>(value));
299  }
300  if (value.CanCast<VtMatrix3fArray>()) {
301  return convertToCyclesTransformArray<VtMatrix3fArray>(VtValue::Cast<VtMatrix3fArray>(value));
302  }
303  if (value.CanCast<VtMatrix4dArray>()) {
304  return convertToCyclesTransformArray<VtMatrix4dArray>(VtValue::Cast<VtMatrix4dArray>(value));
305  }
306  if (value.CanCast<VtMatrix3dArray>()) {
307  return convertToCyclesTransformArray<VtMatrix3dArray>(VtValue::Cast<VtMatrix3dArray>(value));
308  }
309 
310  TF_WARN("Could not convert VtValue to array<Transform>");
311  return array<Transform>();
312 }
313 
314 template<typename SrcType> VtValue convertFromCycles(const SrcType &value)
315 {
316  return VtValue(value);
317 }
318 
319 template<> VtValue convertFromCycles<float2>(const float2 &value)
320 {
321  const GfVec2f convertedValue(value.x, value.y);
322  return VtValue(convertedValue);
323 }
324 
325 template<> VtValue convertFromCycles<float3>(const float3 &value)
326 {
327  const GfVec3f convertedValue(value.x, value.y, value.z);
328  return VtValue(convertedValue);
329 }
330 
331 template<> VtValue convertFromCycles<ustring>(const ustring &value)
332 {
333  return VtValue(value.string());
334 }
335 
336 GfMatrix4f convertMatrixFromCycles(const Transform &matrix)
337 {
338  return GfMatrix4f(matrix[0][0],
339  matrix[1][0],
340  matrix[2][0],
341  0.0f,
342  matrix[0][1],
343  matrix[1][1],
344  matrix[2][1],
345  0.0f,
346  matrix[0][2],
347  matrix[1][2],
348  matrix[2][2],
349  0.0f,
350  0.0f,
351  0.0f,
352  0.0f,
353  1.0f);
354 }
355 
356 template<> VtValue convertFromCycles<Transform>(const Transform &value)
357 {
358  return VtValue(convertMatrixFromCycles(value));
359 }
360 
361 template<typename SrcType, typename DstType = SrcType>
363 {
364  static_assert(sizeof(DstType) == sizeof(SrcType),
365  "Size mismatch between VtArray and array base type");
366 
367  VtArray<DstType> convertedValue;
368  convertedValue.resize(value.size());
369  std::memcpy(convertedValue.data(), value.data(), value.size() * sizeof(SrcType));
370  return VtValue(convertedValue);
371 }
372 
374 {
375  VtVec3fArray convertedValue;
376  convertedValue.reserve(value.size());
377  for (const auto &element : value) {
378  convertedValue.push_back(GfVec3f(element.x, element.y, element.z));
379  }
380  return VtValue(convertedValue);
381 }
382 
384 {
385  VtStringArray convertedValue;
386  convertedValue.reserve(value.size());
387  for (const auto &element : value) {
388  convertedValue.push_back(element.string());
389  }
390  return VtValue(convertedValue);
391 }
392 
394 {
395  VtMatrix4fArray convertedValue;
396  convertedValue.reserve(value.size());
397  for (const auto &element : value) {
398  convertedValue.push_back(convertMatrixFromCycles(element));
399  }
400  return VtValue(convertedValue);
401 }
402 
403 } // namespace
404 
405 void SetNodeValue(Node *node, const SocketType &socket, const VtValue &value)
406 {
407  switch (socket.type) {
408  default:
410  TF_RUNTIME_ERROR("Unexpected conversion: SocketType::UNDEFINED");
411  break;
412 
413  case SocketType::BOOLEAN:
414  node->set(socket, convertToCycles<bool>(value));
415  break;
416  case SocketType::FLOAT:
417  node->set(socket, convertToCycles<float>(value));
418  break;
419  case SocketType::INT:
420  node->set(socket, convertToCycles<int>(value));
421  break;
422  case SocketType::UINT:
423  node->set(socket, convertToCycles<unsigned int>(value));
424  break;
425  case SocketType::COLOR:
426  case SocketType::VECTOR:
427  case SocketType::POINT:
428  case SocketType::NORMAL:
429  node->set(socket, convertToCycles<float3>(value));
430  break;
431  case SocketType::POINT2:
432  node->set(socket, convertToCycles<float2>(value));
433  break;
434  case SocketType::CLOSURE:
435  // Handled by node connections
436  break;
437  case SocketType::STRING:
438  node->set(socket, convertToCycles<ustring>(value));
439  break;
440  case SocketType::ENUM:
441  // Enum's can accept a string or an int
442  if (value.IsHolding<TfToken>() || value.IsHolding<std::string>()) {
443  node->set(socket, convertToCycles<ustring>(value));
444  }
445  else {
446  node->set(socket, convertToCycles<int>(value));
447  }
448  break;
450  node->set(socket, convertToCycles<Transform>(value));
451  break;
452  case SocketType::NODE:
453  // TODO: renderIndex->GetRprim()->cycles_node ?
454  TF_WARN("Unimplemented conversion: SocketType::NODE");
455  break;
456 
458  auto cyclesArray = convertToCyclesArray<bool>(value);
459  node->set(socket, cyclesArray);
460  break;
461  }
463  auto cyclesArray = convertToCyclesArray<float>(value);
464  node->set(socket, cyclesArray);
465  break;
466  }
467  case SocketType::INT_ARRAY: {
468  auto cyclesArray = convertToCyclesArray<int>(value);
469  node->set(socket, cyclesArray);
470  break;
471  }
476  auto cyclesArray = convertToCyclesArray<float3, GfVec3f>(value);
477  node->set(socket, cyclesArray);
478  break;
479  }
481  auto cyclesArray = convertToCyclesArray<float2, GfVec2f>(value);
482  node->set(socket, cyclesArray);
483  break;
484  }
486  auto cyclesArray = convertToCyclesArray<ustring, void>(value);
487  node->set(socket, cyclesArray);
488  break;
489  }
491  auto cyclesArray = convertToCyclesArray<Transform, void>(value);
492  node->set(socket, cyclesArray);
493  break;
494  }
495  case SocketType::NODE_ARRAY: {
496  // TODO: renderIndex->GetRprim()->cycles_node ?
497  TF_WARN("Unimplemented conversion: SocketType::NODE_ARRAY");
498  break;
499  }
500  }
501 }
502 
503 VtValue GetNodeValue(const Node *node, const SocketType &socket)
504 {
505  switch (socket.type) {
506  default:
508  TF_RUNTIME_ERROR("Unexpected conversion: SocketType::UNDEFINED");
509  return VtValue();
510 
511  case SocketType::BOOLEAN:
512  return convertFromCycles(node->get_bool(socket));
513  case SocketType::FLOAT:
514  return convertFromCycles(node->get_float(socket));
515  case SocketType::INT:
516  return convertFromCycles(node->get_int(socket));
517  case SocketType::UINT:
518  return convertFromCycles(node->get_uint(socket));
519  case SocketType::COLOR:
520  case SocketType::VECTOR:
521  case SocketType::POINT:
522  case SocketType::NORMAL:
523  return convertFromCycles(node->get_float3(socket));
524  case SocketType::POINT2:
525  return convertFromCycles(node->get_float2(socket));
526  case SocketType::CLOSURE:
527  return VtValue();
528  case SocketType::STRING:
529  return convertFromCycles(node->get_string(socket));
530  case SocketType::ENUM:
531  return convertFromCycles(node->get_int(socket));
533  return convertFromCycles(node->get_transform(socket));
534  case SocketType::NODE:
535  TF_WARN("Unimplemented conversion: SocketType::NODE");
536  return VtValue();
537 
539  return convertFromCyclesArray(node->get_bool_array(socket));
541  return convertFromCyclesArray(node->get_float_array(socket));
543  return convertFromCyclesArray(node->get_int_array(socket));
548  return convertFromCyclesArray<float3, GfVec3f>(node->get_float3_array(socket));
550  return convertFromCyclesArray<float2, GfVec2f>(node->get_float2_array(socket));
552  return convertFromCyclesArray<ustring, void>(node->get_string_array(socket));
554  return convertFromCyclesArray<Transform, void>(node->get_transform_array(socket));
555  case SocketType::NODE_ARRAY: {
556  TF_WARN("Unimplemented conversion: SocketType::NODE_ARRAY");
557  return VtValue();
558  }
559  }
560 }
561 
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
ATTR_WARN_UNUSED_RESULT const void * element
size_t size() const
T * resize(size_t newsize)
void reserve(size_t newcapacity)
OperationNode * node
#define HDCYCLES_NAMESPACE_CLOSE_SCOPE
Definition: hydra/config.h:17
ccl_device_inline Transform transform_identity()
ccl_device_inline Transform make_transform(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l)
ccl_device_inline float3 zero_float3()
Definition: math_float3.h:80
#define make_float2(x, y)
Definition: metal/compat.h:203
#define make_float3(x, y, z)
Definition: metal/compat.h:204
VtValue convertFromCyclesArray< Transform, void >(const array< Transform > &value)
Definition: node_util.cpp:393
array< DstType > convertToCyclesArray(const VtValue &value)
Definition: node_util.cpp:164
VtValue convertFromCycles< float3 >(const float3 &value)
Definition: node_util.cpp:325
ustring convertToCycles< ustring >(const VtValue &value)
Definition: node_util.cpp:66
Transform convertToCycles< Transform >(const VtValue &value)
Definition: node_util.cpp:131
array< Transform > convertToCyclesArray< Transform, void >(const VtValue &value)
Definition: node_util.cpp:282
VtValue convertFromCycles< ustring >(const ustring &value)
Definition: node_util.cpp:331
VtValue convertFromCycles< float2 >(const float2 &value)
Definition: node_util.cpp:319
float3 convertToCycles< float3 >(const VtValue &value)
Definition: node_util.cpp:42
float2 convertToCycles< float2 >(const VtValue &value)
Definition: node_util.cpp:36
GfMatrix4f convertMatrixFromCycles(const Transform &matrix)
Definition: node_util.cpp:336
VtValue convertFromCycles< Transform >(const Transform &value)
Definition: node_util.cpp:356
VtValue convertFromCycles(const SrcType &value)
Definition: node_util.cpp:314
array< ustring > convertToCyclesArray< ustring, void >(const VtValue &value)
Definition: node_util.cpp:222
VtValue convertFromCyclesArray< float3, GfVec3f >(const array< float3 > &value)
Definition: node_util.cpp:373
VtValue convertFromCyclesArray(const array< SrcType > &value)
Definition: node_util.cpp:362
Transform convertMatrixToCycles(const typename std::enable_if< Matrix::numRows==4 &&Matrix::numColumns==4, Matrix >::type &matrix)
Definition: node_util.cpp:113
VtValue convertFromCyclesArray< ustring, void >(const array< ustring > &value)
Definition: node_util.cpp:383
array< Transform > convertToCyclesTransformArray(const VtValue &value)
Definition: node_util.cpp:268
array< float3 > convertToCyclesArray< float3, GfVec3f >(const VtValue &value)
Definition: node_util.cpp:191
DstType convertToCycles(const VtValue &value)
Definition: node_util.cpp:21
void SetNodeValue(Node *node, const SocketType &socket, const VtValue &value)
Definition: node_util.cpp:405
VtValue GetNodeValue(const Node *node, const SocketType &socket)
Definition: node_util.cpp:503
@ BOOLEAN_ARRAY
Definition: node_type.h:41
@ TRANSFORM_ARRAY
Definition: node_type.h:50
@ NODE_ARRAY
Definition: node_type.h:51
@ POINT2_ARRAY
Definition: node_type.h:48
@ FLOAT_ARRAY
Definition: node_type.h:42
@ NORMAL_ARRAY
Definition: node_type.h:47
@ VECTOR_ARRAY
Definition: node_type.h:45
@ POINT_ARRAY
Definition: node_type.h:46
@ STRING_ARRAY
Definition: node_type.h:49
@ COLOR_ARRAY
Definition: node_type.h:44
Type type
Definition: node_type.h:73
float x
Definition: types_float2.h:15
float y
Definition: types_float2.h:15
float z
float y
float x