[Bf-blender-cvs] [f95214e9aeb] temp-geometry-nodes-fields-prototype: support implicit conversion of fields

Jacques Lucke noreply at git.blender.org
Wed Jul 28 14:14:24 CEST 2021


Commit: f95214e9aebc4c14a2c15dc56b2e5b4ca849fd04
Author: Jacques Lucke
Date:   Wed Jul 28 14:04:14 2021 +0200
Branches: temp-geometry-nodes-fields-prototype
https://developer.blender.org/rBf95214e9aebc4c14a2c15dc56b2e5b4ca849fd04

support implicit conversion of fields

===================================================================

M	source/blender/blenkernel/BKE_field.hh
M	source/blender/modifiers/intern/MOD_nodes_evaluator.cc

===================================================================

diff --git a/source/blender/blenkernel/BKE_field.hh b/source/blender/blenkernel/BKE_field.hh
index fa3f06da402..23f1fa5c4e4 100644
--- a/source/blender/blenkernel/BKE_field.hh
+++ b/source/blender/blenkernel/BKE_field.hh
@@ -397,29 +397,51 @@ template<typename T> class FieldRef : public FieldRefBase {
 
 class FieldRefCPPType : public CPPType {
  private:
-  const CPPType &type_;
+  FieldPtr (*get_field_)(const void *field_ref);
+  void (*construct_)(void *dst, FieldPtr field);
+  const CPPType &field_type_;
 
  public:
-  FieldRefCPPType(fn::CPPTypeMembers members, const CPPType &base_type)
-      : CPPType(members), type_(base_type)
+  FieldRefCPPType(fn::CPPTypeMembers members,
+                  FieldPtr (*get_field)(const void *field_ref),
+                  void (*construct)(void *dst, FieldPtr field),
+                  const CPPType &field_type)
+      : CPPType(members), get_field_(get_field), construct_(construct), field_type_(field_type)
   {
   }
 
-  const CPPType &type() const
+  const CPPType &field_type() const
   {
-    return type_;
+    return field_type_;
   };
+
+  FieldPtr get_field(const void *field_ref) const
+  {
+    return get_field_(field_ref);
+  }
+
+  void construct(void *dst, FieldPtr field) const
+  {
+    construct_(dst, std::move(field));
+  }
 };
 
 }  // namespace blender::bke
 
-#define MAKE_FIELD_REF_CPP_TYPE(DEBUG_NAME, BASE_TYPE) \
+#define MAKE_FIELD_REF_CPP_TYPE(DEBUG_NAME, FIELD_TYPE) \
   template<> \
-  const blender::fn::CPPType &blender::fn::CPPType::get_impl<blender::bke::FieldRef<BASE_TYPE>>() \
+  const blender::fn::CPPType & \
+  blender::fn::CPPType::get_impl<blender::bke::FieldRef<FIELD_TYPE>>() \
   { \
     static blender::bke::FieldRefCPPType cpp_type{ \
-        blender::fn::create_cpp_type_members<blender::bke::FieldRef<BASE_TYPE>, \
+        blender::fn::create_cpp_type_members<blender::bke::FieldRef<FIELD_TYPE>, \
                                              CPPTypeFlags::BasicType>(#DEBUG_NAME), \
-        blender::fn::CPPType::get<BASE_TYPE>()}; \
+        [](const void *field_ref) { \
+          return ((const blender::bke::FieldRef<FIELD_TYPE> *)field_ref)->field(); \
+        }, \
+        [](void *dst, blender::bke::FieldPtr field) { \
+          new (dst) blender::bke::FieldRef<FIELD_TYPE>(std::move(field)); \
+        }, \
+        blender::fn::CPPType::get<FIELD_TYPE>()}; \
     return cpp_type; \
   }
diff --git a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
index ebe92a53381..298931fd1a2 100644
--- a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
+++ b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
@@ -1341,7 +1341,21 @@ class GeometryNodesEvaluator {
     void *buffer = allocator.allocate(to_type.size(), to_type.alignment());
     GMutablePointer value{to_type, buffer};
 
-    if (conversions_.is_convertible(from_type, to_type)) {
+    const bke::FieldRefCPPType *from_field_type = dynamic_cast<const bke::FieldRefCPPType *>(
+        &from_type);
+    const bke::FieldRefCPPType *to_field_type = dynamic_cast<const bke::FieldRefCPPType *>(
+        &to_type);
+
+    if (from_field_type != nullptr && to_field_type != nullptr &&
+        conversions_.is_convertible(from_field_type->field_type(), to_field_type->field_type())) {
+      const MultiFunction &fn = *conversions_.get_conversion_multi_function(
+          MFDataType::ForSingle(from_field_type->field_type()),
+          MFDataType::ForSingle(to_field_type->field_type()));
+      FieldPtr old_field = from_field_type->get_field(value_to_forward.get());
+      FieldPtr new_field = new bke::MultiFunctionField({old_field}, fn, 1);
+      to_field_type->construct(buffer, std::move(new_field));
+    }
+    else if (conversions_.is_convertible(from_type, to_type)) {
       /* Do the conversion if possible. */
       conversions_.convert_to_uninitialized(from_type, to_type, value_to_forward.get(), buffer);
     }



More information about the Bf-blender-cvs mailing list