Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/hydra/node_util.cpp')
-rw-r--r--intern/cycles/hydra/node_util.cpp561
1 files changed, 561 insertions, 0 deletions
diff --git a/intern/cycles/hydra/node_util.cpp b/intern/cycles/hydra/node_util.cpp
new file mode 100644
index 00000000000..c7e49688f5c
--- /dev/null
+++ b/intern/cycles/hydra/node_util.cpp
@@ -0,0 +1,561 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2022 NVIDIA Corporation
+ * Copyright 2022 Blender Foundation */
+
+#include "hydra/node_util.h"
+#include "util/transform.h"
+
+#include <pxr/base/gf/matrix3d.h>
+#include <pxr/base/gf/matrix3f.h>
+#include <pxr/base/gf/matrix4d.h>
+#include <pxr/base/gf/matrix4f.h>
+#include <pxr/base/gf/vec2f.h>
+#include <pxr/base/gf/vec3f.h>
+#include <pxr/base/vt/array.h>
+#include <pxr/usd/sdf/assetPath.h>
+
+HDCYCLES_NAMESPACE_OPEN_SCOPE
+
+namespace {
+
+template<typename DstType> DstType convertToCycles(const VtValue &value)
+{
+ if (value.IsHolding<DstType>()) {
+ return value.UncheckedGet<DstType>();
+ }
+
+ VtValue castedValue = VtValue::Cast<DstType>(value);
+ if (castedValue.IsHolding<DstType>()) {
+ return castedValue.UncheckedGet<DstType>();
+ }
+
+ TF_WARN("Could not convert VtValue to Cycles type");
+ return DstType(0);
+}
+
+template<> float2 convertToCycles<float2>(const VtValue &value)
+{
+ const GfVec2f convertedValue = convertToCycles<GfVec2f>(value);
+ return make_float2(convertedValue[0], convertedValue[1]);
+}
+
+template<> float3 convertToCycles<float3>(const VtValue &value)
+{
+ if (value.IsHolding<GfVec3f>()) {
+ const GfVec3f convertedValue = value.UncheckedGet<GfVec3f>();
+ return make_float3(convertedValue[0], convertedValue[1], convertedValue[2]);
+ }
+ if (value.IsHolding<GfVec4f>()) {
+ const GfVec4f convertedValue = value.UncheckedGet<GfVec4f>();
+ return make_float3(convertedValue[0], convertedValue[1], convertedValue[2]);
+ }
+
+ if (value.CanCast<GfVec3f>()) {
+ const GfVec3f convertedValue = VtValue::Cast<GfVec3f>(value).UncheckedGet<GfVec3f>();
+ return make_float3(convertedValue[0], convertedValue[1], convertedValue[2]);
+ }
+ if (value.CanCast<GfVec4f>()) {
+ const GfVec4f convertedValue = VtValue::Cast<GfVec4f>(value).UncheckedGet<GfVec4f>();
+ return make_float3(convertedValue[0], convertedValue[1], convertedValue[2]);
+ }
+
+ TF_WARN("Could not convert VtValue to float3");
+ return zero_float3();
+}
+
+template<> ustring convertToCycles<ustring>(const VtValue &value)
+{
+ if (value.IsHolding<TfToken>()) {
+ return ustring(value.UncheckedGet<TfToken>().GetString());
+ }
+ if (value.IsHolding<std::string>()) {
+ return ustring(value.UncheckedGet<std::string>());
+ }
+ if (value.IsHolding<SdfAssetPath>()) {
+ const SdfAssetPath &path = value.UncheckedGet<SdfAssetPath>();
+ return ustring(path.GetResolvedPath());
+ }
+
+ if (value.CanCast<TfToken>()) {
+ return convertToCycles<ustring>(VtValue::Cast<TfToken>(value));
+ }
+ if (value.CanCast<std::string>()) {
+ return convertToCycles<ustring>(VtValue::Cast<std::string>(value));
+ }
+ if (value.CanCast<SdfAssetPath>()) {
+ return convertToCycles<ustring>(VtValue::Cast<SdfAssetPath>(value));
+ }
+
+ TF_WARN("Could not convert VtValue to ustring");
+ return ustring();
+}
+
+template<typename Matrix>
+Transform convertMatrixToCycles(
+ const typename std::enable_if<Matrix::numRows == 3 && Matrix::numColumns == 3, Matrix>::type
+ &matrix)
+{
+ return make_transform(matrix[0][0],
+ matrix[1][0],
+ matrix[2][0],
+ 0,
+ matrix[0][1],
+ matrix[1][1],
+ matrix[2][1],
+ 0,
+ matrix[0][2],
+ matrix[1][2],
+ matrix[2][2],
+ 0);
+}
+
+template<typename Matrix>
+Transform convertMatrixToCycles(
+ const typename std::enable_if<Matrix::numRows == 4 && Matrix::numColumns == 4, Matrix>::type
+ &matrix)
+{
+ return make_transform(matrix[0][0],
+ matrix[1][0],
+ matrix[2][0],
+ matrix[3][0],
+ matrix[0][1],
+ matrix[1][1],
+ matrix[2][1],
+ matrix[3][1],
+ matrix[0][2],
+ matrix[1][2],
+ matrix[2][2],
+ matrix[3][2]);
+}
+
+template<> Transform convertToCycles<Transform>(const VtValue &value)
+{
+ if (value.IsHolding<GfMatrix4f>()) {
+ return convertMatrixToCycles<GfMatrix4f>(value.UncheckedGet<GfMatrix4f>());
+ }
+ if (value.IsHolding<GfMatrix3f>()) {
+ return convertMatrixToCycles<GfMatrix3f>(value.UncheckedGet<GfMatrix3f>());
+ }
+ if (value.IsHolding<GfMatrix4d>()) {
+ return convertMatrixToCycles<GfMatrix4d>(value.UncheckedGet<GfMatrix4d>());
+ }
+ if (value.IsHolding<GfMatrix3d>()) {
+ return convertMatrixToCycles<GfMatrix3d>(value.UncheckedGet<GfMatrix3d>());
+ }
+
+ if (value.CanCast<GfMatrix4f>()) {
+ return convertToCycles<Transform>(VtValue::Cast<GfMatrix4f>(value));
+ }
+ if (value.CanCast<GfMatrix3f>()) {
+ return convertToCycles<Transform>(VtValue::Cast<GfMatrix3f>(value));
+ }
+ if (value.CanCast<GfMatrix4d>()) {
+ return convertToCycles<Transform>(VtValue::Cast<GfMatrix4d>(value));
+ }
+ if (value.CanCast<GfMatrix3d>()) {
+ return convertToCycles<Transform>(VtValue::Cast<GfMatrix3d>(value));
+ }
+
+ TF_WARN("Could not convert VtValue to Transform");
+ return transform_identity();
+}
+
+template<typename DstType, typename SrcType = DstType>
+array<DstType> convertToCyclesArray(const VtValue &value)
+{
+ static_assert(sizeof(DstType) == sizeof(SrcType),
+ "Size mismatch between VtArray and array base type");
+
+ using SrcArray = VtArray<SrcType>;
+
+ if (value.IsHolding<SrcArray>()) {
+ const auto &valueData = value.UncheckedGet<SrcArray>();
+ array<DstType> cyclesArray;
+ cyclesArray.resize(valueData.size());
+ std::memcpy(cyclesArray.data(), valueData.data(), valueData.size() * sizeof(DstType));
+ return cyclesArray;
+ }
+
+ if (value.CanCast<SrcArray>()) {
+ VtValue castedValue = VtValue::Cast<SrcArray>(value);
+ const auto &valueData = castedValue.UncheckedGet<SrcArray>();
+ array<DstType> cyclesArray;
+ cyclesArray.resize(valueData.size());
+ std::memcpy(cyclesArray.data(), valueData.data(), valueData.size() * sizeof(DstType));
+ return cyclesArray;
+ }
+
+ return array<DstType>();
+}
+
+template<> array<float3> convertToCyclesArray<float3, GfVec3f>(const VtValue &value)
+{
+ if (value.IsHolding<VtVec3fArray>()) {
+ const auto &valueData = value.UncheckedGet<VtVec3fArray>();
+ array<float3> cyclesArray;
+ cyclesArray.reserve(valueData.size());
+ for (const GfVec3f &vec : valueData) {
+ cyclesArray.push_back_reserved(make_float3(vec[0], vec[1], vec[2]));
+ }
+ return cyclesArray;
+ }
+ if (value.IsHolding<VtVec4fArray>()) {
+ const auto &valueData = value.UncheckedGet<VtVec4fArray>();
+ array<float3> cyclesArray;
+ cyclesArray.reserve(valueData.size());
+ for (const GfVec4f &vec : valueData) {
+ cyclesArray.push_back_reserved(make_float3(vec[0], vec[1], vec[2]));
+ }
+ return cyclesArray;
+ }
+
+ if (value.CanCast<VtVec3fArray>()) {
+ return convertToCyclesArray<float3, GfVec3f>(VtValue::Cast<VtVec3fArray>(value));
+ }
+ if (value.CanCast<VtVec4fArray>()) {
+ return convertToCyclesArray<float3, GfVec3f>(VtValue::Cast<VtVec4fArray>(value));
+ }
+
+ return array<float3>();
+}
+
+template<> array<ustring> convertToCyclesArray<ustring, void>(const VtValue &value)
+{
+ using SdfPathArray = VtArray<SdfAssetPath>;
+
+ if (value.IsHolding<VtStringArray>()) {
+ const auto &valueData = value.UncheckedGet<VtStringArray>();
+ array<ustring> cyclesArray;
+ cyclesArray.reserve(valueData.size());
+ for (const auto &element : valueData) {
+ cyclesArray.push_back_reserved(ustring(element));
+ }
+ return cyclesArray;
+ }
+ if (value.IsHolding<VtTokenArray>()) {
+ const auto &valueData = value.UncheckedGet<VtTokenArray>();
+ array<ustring> cyclesArray;
+ cyclesArray.reserve(valueData.size());
+ for (const auto &element : valueData) {
+ cyclesArray.push_back_reserved(ustring(element.GetString()));
+ }
+ return cyclesArray;
+ }
+ if (value.IsHolding<SdfPathArray>()) {
+ const auto &valueData = value.UncheckedGet<SdfPathArray>();
+ array<ustring> cyclesArray;
+ cyclesArray.reserve(valueData.size());
+ for (const auto &element : valueData) {
+ cyclesArray.push_back_reserved(ustring(element.GetResolvedPath()));
+ }
+ return cyclesArray;
+ }
+
+ if (value.CanCast<VtStringArray>()) {
+ return convertToCyclesArray<ustring, void>(VtValue::Cast<VtStringArray>(value));
+ }
+ if (value.CanCast<VtTokenArray>()) {
+ return convertToCyclesArray<ustring, void>(VtValue::Cast<VtTokenArray>(value));
+ }
+ if (value.CanCast<SdfPathArray>()) {
+ return convertToCyclesArray<ustring, void>(VtValue::Cast<SdfPathArray>(value));
+ }
+
+ TF_WARN("Could not convert VtValue to array<ustring>");
+ return array<ustring>();
+}
+
+template<typename MatrixArray> array<Transform> convertToCyclesTransformArray(const VtValue &value)
+{
+ assert(value.IsHolding<MatrixArray>());
+
+ const auto &valueData = value.UncheckedGet<MatrixArray>();
+ array<Transform> cyclesArray;
+ cyclesArray.reserve(valueData.size());
+ for (const auto &element : valueData) {
+ cyclesArray.push_back_reserved(convertMatrixToCycles<MatrixArray::value_type>(element));
+ }
+ return cyclesArray;
+}
+
+template<> array<Transform> convertToCyclesArray<Transform, void>(const VtValue &value)
+{
+ if (value.IsHolding<VtMatrix4fArray>()) {
+ return convertToCyclesTransformArray<VtMatrix4fArray>(value);
+ }
+ if (value.IsHolding<VtMatrix3fArray>()) {
+ return convertToCyclesTransformArray<VtMatrix3fArray>(value);
+ }
+ if (value.IsHolding<VtMatrix4dArray>()) {
+ return convertToCyclesTransformArray<VtMatrix4dArray>(value);
+ }
+ if (value.IsHolding<VtMatrix3dArray>()) {
+ return convertToCyclesTransformArray<VtMatrix3dArray>(value);
+ }
+
+ if (value.CanCast<VtMatrix4fArray>()) {
+ return convertToCyclesTransformArray<VtMatrix4fArray>(VtValue::Cast<VtMatrix4fArray>(value));
+ }
+ if (value.CanCast<VtMatrix3fArray>()) {
+ return convertToCyclesTransformArray<VtMatrix3fArray>(VtValue::Cast<VtMatrix3fArray>(value));
+ }
+ if (value.CanCast<VtMatrix4dArray>()) {
+ return convertToCyclesTransformArray<VtMatrix4dArray>(VtValue::Cast<VtMatrix4dArray>(value));
+ }
+ if (value.CanCast<VtMatrix3dArray>()) {
+ return convertToCyclesTransformArray<VtMatrix3dArray>(VtValue::Cast<VtMatrix3dArray>(value));
+ }
+
+ TF_WARN("Could not convert VtValue to array<Transform>");
+ return array<Transform>();
+}
+
+template<typename SrcType> VtValue convertFromCycles(const SrcType &value)
+{
+ return VtValue(value);
+}
+
+template<> VtValue convertFromCycles<float2>(const float2 &value)
+{
+ const GfVec2f convertedValue(value.x, value.y);
+ return VtValue(convertedValue);
+}
+
+template<> VtValue convertFromCycles<float3>(const float3 &value)
+{
+ const GfVec3f convertedValue(value.x, value.y, value.z);
+ return VtValue(convertedValue);
+}
+
+template<> VtValue convertFromCycles<ustring>(const ustring &value)
+{
+ return VtValue(value.string());
+}
+
+GfMatrix4f convertMatrixFromCycles(const Transform &matrix)
+{
+ return GfMatrix4f(matrix[0][0],
+ matrix[1][0],
+ matrix[2][0],
+ 0.0f,
+ matrix[0][1],
+ matrix[1][1],
+ matrix[2][1],
+ 0.0f,
+ matrix[0][2],
+ matrix[1][2],
+ matrix[2][2],
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f);
+}
+
+template<> VtValue convertFromCycles<Transform>(const Transform &value)
+{
+ return VtValue(convertMatrixFromCycles(value));
+}
+
+template<typename SrcType, typename DstType = SrcType>
+VtValue convertFromCyclesArray(const array<SrcType> &value)
+{
+ static_assert(sizeof(DstType) == sizeof(SrcType),
+ "Size mismatch between VtArray and array base type");
+
+ VtArray<DstType> convertedValue;
+ convertedValue.resize(value.size());
+ std::memcpy(convertedValue.data(), value.data(), value.size() * sizeof(SrcType));
+ return VtValue(convertedValue);
+}
+
+template<> VtValue convertFromCyclesArray<float3, GfVec3f>(const array<float3> &value)
+{
+ VtVec3fArray convertedValue;
+ convertedValue.reserve(value.size());
+ for (const auto &element : value) {
+ convertedValue.push_back(GfVec3f(element.x, element.y, element.z));
+ }
+ return VtValue(convertedValue);
+}
+
+template<> VtValue convertFromCyclesArray<ustring, void>(const array<ustring> &value)
+{
+ VtStringArray convertedValue;
+ convertedValue.reserve(value.size());
+ for (const auto &element : value) {
+ convertedValue.push_back(element.string());
+ }
+ return VtValue(convertedValue);
+}
+
+template<> VtValue convertFromCyclesArray<Transform, void>(const array<Transform> &value)
+{
+ VtMatrix4fArray convertedValue;
+ convertedValue.reserve(value.size());
+ for (const auto &element : value) {
+ convertedValue.push_back(convertMatrixFromCycles(element));
+ }
+ return VtValue(convertedValue);
+}
+
+} // namespace
+
+void SetNodeValue(Node *node, const SocketType &socket, const VtValue &value)
+{
+ switch (socket.type) {
+ default:
+ case SocketType::UNDEFINED:
+ TF_RUNTIME_ERROR("Unexpected conversion: SocketType::UNDEFINED");
+ break;
+
+ case SocketType::BOOLEAN:
+ node->set(socket, convertToCycles<bool>(value));
+ break;
+ case SocketType::FLOAT:
+ node->set(socket, convertToCycles<float>(value));
+ break;
+ case SocketType::INT:
+ node->set(socket, convertToCycles<int>(value));
+ break;
+ case SocketType::UINT:
+ node->set(socket, convertToCycles<unsigned int>(value));
+ break;
+ case SocketType::COLOR:
+ case SocketType::VECTOR:
+ case SocketType::POINT:
+ case SocketType::NORMAL:
+ node->set(socket, convertToCycles<float3>(value));
+ break;
+ case SocketType::POINT2:
+ node->set(socket, convertToCycles<float2>(value));
+ break;
+ case SocketType::CLOSURE:
+ // Handled by node connections
+ break;
+ case SocketType::STRING:
+ node->set(socket, convertToCycles<ustring>(value));
+ break;
+ case SocketType::ENUM:
+ // Enum's can accept a string or an int
+ if (value.IsHolding<TfToken>() || value.IsHolding<std::string>()) {
+ node->set(socket, convertToCycles<ustring>(value));
+ }
+ else {
+ node->set(socket, convertToCycles<int>(value));
+ }
+ break;
+ case SocketType::TRANSFORM:
+ node->set(socket, convertToCycles<Transform>(value));
+ break;
+ case SocketType::NODE:
+ // TODO: renderIndex->GetRprim()->cycles_node ?
+ TF_WARN("Unimplemented conversion: SocketType::NODE");
+ break;
+
+ case SocketType::BOOLEAN_ARRAY: {
+ auto cyclesArray = convertToCyclesArray<bool>(value);
+ node->set(socket, cyclesArray);
+ break;
+ }
+ case SocketType::FLOAT_ARRAY: {
+ auto cyclesArray = convertToCyclesArray<float>(value);
+ node->set(socket, cyclesArray);
+ break;
+ }
+ case SocketType::INT_ARRAY: {
+ auto cyclesArray = convertToCyclesArray<int>(value);
+ node->set(socket, cyclesArray);
+ break;
+ }
+ case SocketType::COLOR_ARRAY:
+ case SocketType::VECTOR_ARRAY:
+ case SocketType::POINT_ARRAY:
+ case SocketType::NORMAL_ARRAY: {
+ auto cyclesArray = convertToCyclesArray<float3, GfVec3f>(value);
+ node->set(socket, cyclesArray);
+ break;
+ }
+ case SocketType::POINT2_ARRAY: {
+ auto cyclesArray = convertToCyclesArray<float2, GfVec2f>(value);
+ node->set(socket, cyclesArray);
+ break;
+ }
+ case SocketType::STRING_ARRAY: {
+ auto cyclesArray = convertToCyclesArray<ustring, void>(value);
+ node->set(socket, cyclesArray);
+ break;
+ }
+ case SocketType::TRANSFORM_ARRAY: {
+ auto cyclesArray = convertToCyclesArray<Transform, void>(value);
+ node->set(socket, cyclesArray);
+ break;
+ }
+ case SocketType::NODE_ARRAY: {
+ // TODO: renderIndex->GetRprim()->cycles_node ?
+ TF_WARN("Unimplemented conversion: SocketType::NODE_ARRAY");
+ break;
+ }
+ }
+}
+
+VtValue GetNodeValue(const Node *node, const SocketType &socket)
+{
+ switch (socket.type) {
+ default:
+ case SocketType::UNDEFINED:
+ TF_RUNTIME_ERROR("Unexpected conversion: SocketType::UNDEFINED");
+ return VtValue();
+
+ case SocketType::BOOLEAN:
+ return convertFromCycles(node->get_bool(socket));
+ case SocketType::FLOAT:
+ return convertFromCycles(node->get_float(socket));
+ case SocketType::INT:
+ return convertFromCycles(node->get_int(socket));
+ case SocketType::UINT:
+ return convertFromCycles(node->get_uint(socket));
+ case SocketType::COLOR:
+ case SocketType::VECTOR:
+ case SocketType::POINT:
+ case SocketType::NORMAL:
+ return convertFromCycles(node->get_float3(socket));
+ case SocketType::POINT2:
+ return convertFromCycles(node->get_float2(socket));
+ case SocketType::CLOSURE:
+ return VtValue();
+ case SocketType::STRING:
+ return convertFromCycles(node->get_string(socket));
+ case SocketType::ENUM:
+ return convertFromCycles(node->get_int(socket));
+ case SocketType::TRANSFORM:
+ return convertFromCycles(node->get_transform(socket));
+ case SocketType::NODE:
+ TF_WARN("Unimplemented conversion: SocketType::NODE");
+ return VtValue();
+
+ case SocketType::BOOLEAN_ARRAY:
+ return convertFromCyclesArray(node->get_bool_array(socket));
+ case SocketType::FLOAT_ARRAY:
+ return convertFromCyclesArray(node->get_float_array(socket));
+ case SocketType::INT_ARRAY:
+ return convertFromCyclesArray(node->get_int_array(socket));
+ case SocketType::COLOR_ARRAY:
+ case SocketType::VECTOR_ARRAY:
+ case SocketType::POINT_ARRAY:
+ case SocketType::NORMAL_ARRAY:
+ return convertFromCyclesArray<float3, GfVec3f>(node->get_float3_array(socket));
+ case SocketType::POINT2_ARRAY:
+ return convertFromCyclesArray<float2, GfVec2f>(node->get_float2_array(socket));
+ case SocketType::STRING_ARRAY:
+ return convertFromCyclesArray<ustring, void>(node->get_string_array(socket));
+ case SocketType::TRANSFORM_ARRAY:
+ return convertFromCyclesArray<Transform, void>(node->get_transform_array(socket));
+ case SocketType::NODE_ARRAY: {
+ TF_WARN("Unimplemented conversion: SocketType::NODE_ARRAY");
+ return VtValue();
+ }
+ }
+}
+
+HDCYCLES_NAMESPACE_CLOSE_SCOPE