Merge branch 'blender-v2.93-release'
authorJacques Lucke <jacques@blender.org>
Wed, 26 May 2021 14:20:24 +0000 (16:20 +0200)
committerJacques Lucke <jacques@blender.org>
Wed, 26 May 2021 14:20:24 +0000 (16:20 +0200)
1  2 
source/blender/modifiers/intern/MOD_nodes.cc

index 37a21a3c14bcdfadd124c38abd722f1a7cbbb395,fd3634ad2780390aa4a3c53f76f35449d48869ce..f927f4b1bcd16e1786ce26fcf5920533cd830fd5
  
  #include "MOD_modifiertypes.h"
  #include "MOD_nodes.h"
 +#include "MOD_nodes_evaluator.hh"
  #include "MOD_ui_common.h"
  
  #include "ED_spreadsheet.h"
  
  #include "NOD_derived_node_tree.hh"
  #include "NOD_geometry.h"
 -#include "NOD_geometry_exec.hh"
  #include "NOD_node_tree_multi_function.hh"
 -#include "NOD_type_callbacks.hh"
 -#include "NOD_type_conversions.hh"
  
  using blender::float3;
  using blender::FunctionRef;
@@@ -93,8 -95,12 +93,8 @@@ using blender::Span
  using blender::StringRef;
  using blender::StringRefNull;
  using blender::Vector;
 -using blender::bke::PersistentCollectionHandle;
 -using blender::bke::PersistentDataHandleMap;
 -using blender::bke::PersistentObjectHandle;
  using blender::fn::GMutablePointer;
  using blender::fn::GPointer;
 -using blender::fn::GValueMap;
  using blender::nodes::GeoNodeExecParams;
  using namespace blender::fn::multi_function_types;
  using namespace blender::nodes::derived_node_tree_types;
@@@ -179,7 -185,7 +179,7 @@@ static void add_object_relation(const M
      if (object.type == OB_EMPTY && object.instance_collection != nullptr) {
        add_collection_relation(ctx, *object.instance_collection);
      }
-     else if (ELEM(object.type, OB_MESH, OB_POINTCLOUD, OB_VOLUME, OB_CURVE)) {
+     else if (DEG_object_has_geometry_component(&object)) {
        DEG_add_object_relation(ctx->node, &object, DEG_OB_COMP_GEOMETRY, "Nodes Modifier");
        DEG_add_customdata_mask(ctx->node, &object, &dependency_data_mask);
      }
@@@ -262,6 -268,368 +262,6 @@@ static bool logging_enabled(const Modif
    return true;
  }
  
 -class GeometryNodesEvaluator {
 - public:
 -  using LogSocketValueFn = std::function<void(DSocket, Span<GPointer>)>;
 -
 - private:
 -  blender::LinearAllocator<> allocator_;
 -  Map<std::pair<DInputSocket, DOutputSocket>, GMutablePointer> value_by_input_;
 -  Vector<DInputSocket> group_outputs_;
 -  blender::nodes::MultiFunctionByNode &mf_by_node_;
 -  const blender::nodes::DataTypeConversions &conversions_;
 -  const PersistentDataHandleMap &handle_map_;
 -  const Object *self_object_;
 -  const ModifierData *modifier_;
 -  Depsgraph *depsgraph_;
 -  LogSocketValueFn log_socket_value_fn_;
 -
 - public:
 -  GeometryNodesEvaluator(const Map<DOutputSocket, GMutablePointer> &group_input_data,
 -                         Vector<DInputSocket> group_outputs,
 -                         blender::nodes::MultiFunctionByNode &mf_by_node,
 -                         const PersistentDataHandleMap &handle_map,
 -                         const Object *self_object,
 -                         const ModifierData *modifier,
 -                         Depsgraph *depsgraph,
 -                         LogSocketValueFn log_socket_value_fn)
 -      : group_outputs_(std::move(group_outputs)),
 -        mf_by_node_(mf_by_node),
 -        conversions_(blender::nodes::get_implicit_type_conversions()),
 -        handle_map_(handle_map),
 -        self_object_(self_object),
 -        modifier_(modifier),
 -        depsgraph_(depsgraph),
 -        log_socket_value_fn_(std::move(log_socket_value_fn))
 -  {
 -    for (auto item : group_input_data.items()) {
 -      this->log_socket_value(item.key, item.value);
 -      this->forward_to_inputs(item.key, item.value);
 -    }
 -  }
 -
 -  Vector<GMutablePointer> execute()
 -  {
 -    Vector<GMutablePointer> results;
 -    for (const DInputSocket &group_output : group_outputs_) {
 -      Vector<GMutablePointer> result = this->get_input_values(group_output);
 -      this->log_socket_value(group_output, result);
 -      results.append(result[0]);
 -    }
 -    for (GMutablePointer value : value_by_input_.values()) {
 -      value.destruct();
 -    }
 -    return results;
 -  }
 -
 - private:
 -  Vector<GMutablePointer> get_input_values(const DInputSocket socket_to_compute)
 -  {
 -    Vector<DSocket> from_sockets;
 -    socket_to_compute.foreach_origin_socket([&](DSocket socket) { from_sockets.append(socket); });
 -
 -    if (from_sockets.is_empty()) {
 -      /* The input is not connected, use the value from the socket itself. */
 -      const CPPType &type = *blender::nodes::socket_cpp_type_get(*socket_to_compute->typeinfo());
 -      return {get_unlinked_input_value(socket_to_compute, type)};
 -    }
 -
 -    /* Multi-input sockets contain a vector of inputs. */
 -    if (socket_to_compute->is_multi_input_socket()) {
 -      return this->get_inputs_from_incoming_links(socket_to_compute, from_sockets);
 -    }
 -
 -    const DSocket from_socket = from_sockets[0];
 -    GMutablePointer value = this->get_input_from_incoming_link(socket_to_compute, from_socket);
 -    return {value};
 -  }
 -
 -  Vector<GMutablePointer> get_inputs_from_incoming_links(const DInputSocket socket_to_compute,
 -                                                         const Span<DSocket> from_sockets)
 -  {
 -    Vector<GMutablePointer> values;
 -    for (const int i : from_sockets.index_range()) {
 -      const DSocket from_socket = from_sockets[i];
 -      const int first_occurence = from_sockets.take_front(i).first_index_try(from_socket);
 -      if (first_occurence == -1) {
 -        values.append(this->get_input_from_incoming_link(socket_to_compute, from_socket));
 -      }
 -      else {
 -        /* If the same from-socket occurs more than once, we make a copy of the first value. This
 -         * can happen when a node linked to a multi-input-socket is muted. */
 -        GMutablePointer value = values[first_occurence];
 -        const CPPType *type = value.type();
 -        void *copy_buffer = allocator_.allocate(type->size(), type->alignment());
 -        type->copy_to_uninitialized(value.get(), copy_buffer);
 -        values.append({type, copy_buffer});
 -      }
 -    }
 -    return values;
 -  }
 -
 -  GMutablePointer get_input_from_incoming_link(const DInputSocket socket_to_compute,
 -                                               const DSocket from_socket)
 -  {
 -    if (from_socket->is_output()) {
 -      const DOutputSocket from_output_socket{from_socket};
 -      const std::pair<DInputSocket, DOutputSocket> key = std::make_pair(socket_to_compute,
 -                                                                        from_output_socket);
 -      std::optional<GMutablePointer> value = value_by_input_.pop_try(key);
 -      if (value.has_value()) {
 -        /* This input has been computed before, return it directly. */
 -        return {*value};
 -      }
 -
 -      /* Compute the socket now. */
 -      this->compute_output_and_forward(from_output_socket);
 -      return {value_by_input_.pop(key)};
 -    }
 -
 -    /* Get value from an unlinked input socket. */
 -    const CPPType &type = *blender::nodes::socket_cpp_type_get(*socket_to_compute->typeinfo());
 -    const DInputSocket from_input_socket{from_socket};
 -    return {get_unlinked_input_value(from_input_socket, type)};
 -  }
 -
 -  void compute_output_and_forward(const DOutputSocket socket_to_compute)
 -  {
 -    const DNode node{socket_to_compute.context(), &socket_to_compute->node()};
 -
 -    if (!socket_to_compute->is_available()) {
 -      /* If the output is not available, use a default value. */
 -      const CPPType &type = *blender::nodes::socket_cpp_type_get(*socket_to_compute->typeinfo());
 -      void *buffer = allocator_.allocate(type.size(), type.alignment());
 -      type.copy_to_uninitialized(type.default_value(), buffer);
 -      this->forward_to_inputs(socket_to_compute, {type, buffer});
 -      return;
 -    }
 -
 -    /* Prepare inputs required to execute the node. */
 -    GValueMap<StringRef> node_inputs_map{allocator_};
 -    for (const InputSocketRef *input_socket : node->inputs()) {
 -      if (input_socket->is_available()) {
 -        DInputSocket dsocket{node.context(), input_socket};
 -        Vector<GMutablePointer> values = this->get_input_values(dsocket);
 -        this->log_socket_value(dsocket, values);
 -        for (int i = 0; i < values.size(); ++i) {
 -          /* Values from Multi Input Sockets are stored in input map with the format
 -           * <identifier>[<index>]. */
 -          blender::StringRefNull key = allocator_.copy_string(
 -              input_socket->identifier() + (i > 0 ? ("[" + std::to_string(i)) + "]" : ""));
 -          node_inputs_map.add_new_direct(key, std::move(values[i]));
 -        }
 -      }
 -    }
 -
 -    /* Execute the node. */
 -    GValueMap<StringRef> node_outputs_map{allocator_};
 -    GeoNodeExecParams params{
 -        node, node_inputs_map, node_outputs_map, handle_map_, self_object_, modifier_, depsgraph_};
 -    this->execute_node(node, params);
 -
 -    /* Forward computed outputs to linked input sockets. */
 -    for (const OutputSocketRef *output_socket : node->outputs()) {
 -      if (output_socket->is_available()) {
 -        const DOutputSocket dsocket{node.context(), output_socket};
 -        GMutablePointer value = node_outputs_map.extract(output_socket->identifier());
 -        this->log_socket_value(dsocket, value);
 -        this->forward_to_inputs(dsocket, value);
 -      }
 -    }
 -  }
 -
 -  void log_socket_value(const DSocket socket, Span<GPointer> values)
 -  {
 -    if (log_socket_value_fn_) {
 -      log_socket_value_fn_(socket, values);
 -    }
 -  }
 -
 -  void log_socket_value(const DSocket socket, Span<GMutablePointer> values)
 -  {
 -    this->log_socket_value(socket, values.cast<GPointer>());
 -  }
 -
 -  void log_socket_value(const DSocket socket, GPointer value)
 -  {
 -    this->log_socket_value(socket, Span<GPointer>(&value, 1));
 -  }
 -
 -  void execute_node(const DNode node, GeoNodeExecParams params)
 -  {
 -    const bNode &bnode = params.node();
 -
 -    /* Use the geometry-node-execute callback if it exists. */
 -    if (bnode.typeinfo->geometry_node_execute != nullptr) {
 -      bnode.typeinfo->geometry_node_execute(params);
 -      return;
 -    }
 -
 -    /* Use the multi-function implementation if it exists. */
 -    const MultiFunction *multi_function = mf_by_node_.lookup_default(node, nullptr);
 -    if (multi_function != nullptr) {
 -      this->execute_multi_function_node(node, params, *multi_function);
 -      return;
 -    }
 -
 -    /* Just output default values if no implementation exists. */
 -    this->execute_unknown_node(node, params);
 -  }
 -
 -  void execute_multi_function_node(const DNode node,
 -                                   GeoNodeExecParams params,
 -                                   const MultiFunction &fn)
 -  {
 -    MFContextBuilder fn_context;
 -    MFParamsBuilder fn_params{fn, 1};
 -    Vector<GMutablePointer> input_data;
 -    for (const InputSocketRef *socket_ref : node->inputs()) {
 -      if (socket_ref->is_available()) {
 -        GMutablePointer data = params.extract_input(socket_ref->identifier());
 -        fn_params.add_readonly_single_input(GSpan(*data.type(), data.get(), 1));
 -        input_data.append(data);
 -      }
 -    }
 -    Vector<GMutablePointer> output_data;
 -    for (const OutputSocketRef *socket_ref : node->outputs()) {
 -      if (socket_ref->is_available()) {
 -        const CPPType &type = *blender::nodes::socket_cpp_type_get(*socket_ref->typeinfo());
 -        void *buffer = allocator_.allocate(type.size(), type.alignment());
 -        fn_params.add_uninitialized_single_output(GMutableSpan(type, buffer, 1));
 -        output_data.append(GMutablePointer(type, buffer));
 -      }
 -    }
 -    fn.call(IndexRange(1), fn_params, fn_context);
 -    for (GMutablePointer value : input_data) {
 -      value.destruct();
 -    }
 -    int output_index = 0;
 -    for (const int i : node->outputs().index_range()) {
 -      if (node->output(i).is_available()) {
 -        GMutablePointer value = output_data[output_index];
 -        params.set_output_by_move(node->output(i).identifier(), value);
 -        value.destruct();
 -        output_index++;
 -      }
 -    }
 -  }
 -
 -  void execute_unknown_node(const DNode node, GeoNodeExecParams params)
 -  {
 -    for (const OutputSocketRef *socket : node->outputs()) {
 -      if (socket->is_available()) {
 -        const CPPType &type = *blender::nodes::socket_cpp_type_get(*socket->typeinfo());
 -        params.set_output_by_copy(socket->identifier(), {type, type.default_value()});
 -      }
 -    }
 -  }
 -
 -  void forward_to_inputs(const DOutputSocket from_socket, GMutablePointer value_to_forward)
 -  {
 -    /* For all sockets that are linked with the from_socket push the value to their node. */
 -    Vector<DInputSocket> to_sockets_all;
 -
 -    auto handle_target_socket_fn = [&](DInputSocket to_socket) {
 -      to_sockets_all.append_non_duplicates(to_socket);
 -    };
 -    auto handle_skipped_socket_fn = [&, this](DSocket socket) {
 -      this->log_socket_value(socket, value_to_forward);
 -    };
 -
 -    from_socket.foreach_target_socket(handle_target_socket_fn, handle_skipped_socket_fn);
 -
 -    const CPPType &from_type = *value_to_forward.type();
 -    Vector<DInputSocket> to_sockets_same_type;
 -    for (const DInputSocket &to_socket : to_sockets_all) {
 -      const CPPType &to_type = *blender::nodes::socket_cpp_type_get(*to_socket->typeinfo());
 -      const std::pair<DInputSocket, DOutputSocket> key = std::make_pair(to_socket, from_socket);
 -      if (from_type == to_type) {
 -        to_sockets_same_type.append(to_socket);
 -      }
 -      else {
 -        void *buffer = allocator_.allocate(to_type.size(), to_type.alignment());
 -        if (conversions_.is_convertible(from_type, to_type)) {
 -          conversions_.convert_to_uninitialized(
 -              from_type, to_type, value_to_forward.get(), buffer);
 -        }
 -        else {
 -          to_type.copy_to_uninitialized(to_type.default_value(), buffer);
 -        }
 -        add_value_to_input_socket(key, GMutablePointer{to_type, buffer});
 -      }
 -    }
 -
 -    if (to_sockets_same_type.size() == 0) {
 -      /* This value is not further used, so destruct it. */
 -      value_to_forward.destruct();
 -    }
 -    else if (to_sockets_same_type.size() == 1) {
 -      /* This value is only used on one input socket, no need to copy it. */
 -      const DInputSocket to_socket = to_sockets_same_type[0];
 -      const std::pair<DInputSocket, DOutputSocket> key = std::make_pair(to_socket, from_socket);
 -
 -      add_value_to_input_socket(key, value_to_forward);
 -    }
 -    else {
 -      /* Multiple inputs use the value, make a copy for every input except for one. */
 -      const DInputSocket first_to_socket = to_sockets_same_type[0];
 -      Span<DInputSocket> other_to_sockets = to_sockets_same_type.as_span().drop_front(1);
 -      const CPPType &type = *value_to_forward.type();
 -      const std::pair<DInputSocket, DOutputSocket> first_key = std::make_pair(first_to_socket,
 -                                                                              from_socket);
 -      add_value_to_input_socket(first_key, value_to_forward);
 -      for (const DInputSocket &to_socket : other_to_sockets) {
 -        const std::pair<DInputSocket, DOutputSocket> key = std::make_pair(to_socket, from_socket);
 -        void *buffer = allocator_.allocate(type.size(), type.alignment());
 -        type.copy_to_uninitialized(value_to_forward.get(), buffer);
 -        add_value_to_input_socket(key, GMutablePointer{type, buffer});
 -      }
 -    }
 -  }
 -
 -  void add_value_to_input_socket(const std::pair<DInputSocket, DOutputSocket> key,
 -                                 GMutablePointer value)
 -  {
 -    value_by_input_.add_new(key, value);
 -  }
 -
 -  GMutablePointer get_unlinked_input_value(const DInputSocket &socket,
 -                                           const CPPType &required_type)
 -  {
 -    bNodeSocket *bsocket = socket->bsocket();
 -    const CPPType &type = *blender::nodes::socket_cpp_type_get(*socket->typeinfo());
 -    void *buffer = allocator_.allocate(type.size(), type.alignment());
 -
 -    if (bsocket->type == SOCK_OBJECT) {
 -      Object *object = socket->default_value<bNodeSocketValueObject>()->value;
 -      PersistentObjectHandle object_handle = handle_map_.lookup(object);
 -      new (buffer) PersistentObjectHandle(object_handle);
 -    }
 -    else if (bsocket->type == SOCK_COLLECTION) {
 -      Collection *collection = socket->default_value<bNodeSocketValueCollection>()->value;
 -      PersistentCollectionHandle collection_handle = handle_map_.lookup(collection);
 -      new (buffer) PersistentCollectionHandle(collection_handle);
 -    }
 -    else {
 -      blender::nodes::socket_cpp_value_get(*bsocket, buffer);
 -    }
 -
 -    if (type == required_type) {
 -      return {type, buffer};
 -    }
 -    if (conversions_.is_convertible(type, required_type)) {
 -      void *converted_buffer = allocator_.allocate(required_type.size(),
 -                                                   required_type.alignment());
 -      conversions_.convert_to_uninitialized(type, required_type, buffer, converted_buffer);
 -      type.destruct(buffer);
 -      return {required_type, converted_buffer};
 -    }
 -    void *default_buffer = allocator_.allocate(required_type.size(), required_type.alignment());
 -    required_type.copy_to_uninitialized(required_type.default_value(), default_buffer);
 -    return {required_type, default_buffer};
 -  }
 -};
 -
  /**
   * This code is responsible for creating the new property and also creating the group of
   * properties in the prop_ui_container group for the UI info, the mapping for which is
@@@ -281,7 -649,9 +281,7 @@@ struct SocketPropertyType 
    IDProperty *(*create_default_ui_prop)(const bNodeSocket &socket, const char *name);
    PropertyType (*rna_subtype_get)(const bNodeSocket &socket);
    bool (*is_correct_type)(const IDProperty &property);
 -  void (*init_cpp_value)(const IDProperty &property,
 -                         const PersistentDataHandleMap &handles,
 -                         void *r_value);
 +  void (*init_cpp_value)(const IDProperty &property, void *r_value);
  };
  
  static IDProperty *socket_add_property(IDProperty *settings_prop_group,
@@@ -374,7 -744,9 +374,7 @@@ static const SocketPropertyType *get_so
              return (PropertyType)((bNodeSocketValueFloat *)socket.default_value)->subtype;
            },
            [](const IDProperty &property) { return ELEM(property.type, IDP_FLOAT, IDP_DOUBLE); },
 -          [](const IDProperty &property,
 -             const PersistentDataHandleMap &UNUSED(handles),
 -             void *r_value) {
 +          [](const IDProperty &property, void *r_value) {
              if (property.type == IDP_FLOAT) {
                *(float *)r_value = IDP_Float(&property);
              }
              return (PropertyType)((bNodeSocketValueInt *)socket.default_value)->subtype;
            },
            [](const IDProperty &property) { return property.type == IDP_INT; },
 -          [](const IDProperty &property,
 -             const PersistentDataHandleMap &UNUSED(handles),
 -             void *r_value) { *(int *)r_value = IDP_Int(&property); },
 +          [](const IDProperty &property, void *r_value) { *(int *)r_value = IDP_Int(&property); },
        };
        return &int_type;
      }
              return property.type == IDP_ARRAY && property.subtype == IDP_FLOAT &&
                     property.len == 3;
            },
 -          [](const IDProperty &property,
 -             const PersistentDataHandleMap &UNUSED(handles),
 -             void *r_value) { copy_v3_v3((float *)r_value, (const float *)IDP_Array(&property)); },
 +          [](const IDProperty &property, void *r_value) {
 +            copy_v3_v3((float *)r_value, (const float *)IDP_Array(&property));
 +          },
        };
        return &vector_type;
      }
            },
            nullptr,
            [](const IDProperty &property) { return property.type == IDP_INT; },
 -          [](const IDProperty &property,
 -             const PersistentDataHandleMap &UNUSED(handles),
 -             void *r_value) { *(bool *)r_value = IDP_Int(&property) != 0; },
 +          [](const IDProperty &property, void *r_value) {
 +            *(bool *)r_value = IDP_Int(&property) != 0;
 +          },
        };
        return &boolean_type;
      }
            },
            nullptr,
            [](const IDProperty &property) { return property.type == IDP_STRING; },
 -          [](const IDProperty &property,
 -             const PersistentDataHandleMap &UNUSED(handles),
 -             void *r_value) { new (r_value) std::string(IDP_String(&property)); },
 +          [](const IDProperty &property, void *r_value) {
 +            new (r_value) std::string(IDP_String(&property));
 +          },
        };
        return &string_type;
      }
            nullptr,
            nullptr,
            [](const IDProperty &property) { return property.type == IDP_ID; },
 -          [](const IDProperty &property, const PersistentDataHandleMap &handles, void *r_value) {
 +          [](const IDProperty &property, void *r_value) {
              ID *id = IDP_Id(&property);
              Object *object = (id && GS(id->name) == ID_OB) ? (Object *)id : nullptr;
 -            new (r_value) PersistentObjectHandle(handles.lookup(object));
 +            *(Object **)r_value = object;
            },
        };
        return &object_type;
            nullptr,
            nullptr,
            [](const IDProperty &property) { return property.type == IDP_ID; },
 -          [](const IDProperty &property, const PersistentDataHandleMap &handles, void *r_value) {
 +          [](const IDProperty &property, void *r_value) {
              ID *id = IDP_Id(&property);
              Collection *collection = (id && GS(id->name) == ID_GR) ? (Collection *)id : nullptr;
 -            new (r_value) PersistentCollectionHandle(handles.lookup(collection));
 +            *(Collection **)r_value = collection;
            },
        };
        return &collection_type;
@@@ -643,6 -1017,7 +643,6 @@@ void MOD_nodes_init(Main *bmain, NodesM
  }
  
  static void initialize_group_input(NodesModifierData &nmd,
 -                                   const PersistentDataHandleMap &handle_map,
                                     const bNodeSocket &socket,
                                     const CPPType &cpp_type,
                                     void *r_value)
      blender::nodes::socket_cpp_value_get(socket, r_value);
      return;
    }
 -  property_type->init_cpp_value(*property, handle_map, r_value);
 -}
 -
 -static void fill_data_handle_map(const NodesModifierSettings &settings,
 -                                 const DerivedNodeTree &tree,
 -                                 PersistentDataHandleMap &handle_map)
 -{
 -  Set<ID *> used_ids;
 -  find_used_ids_from_settings(settings, used_ids);
 -  find_used_ids_from_nodes(*tree.root_context().tree().btree(), used_ids);
 -
 -  int current_handle = 0;
 -  for (ID *id : used_ids) {
 -    handle_map.add(current_handle, *id);
 -    current_handle++;
 -  }
 +  property_type->init_cpp_value(*property, r_value);
  }
  
  static void reset_tree_ui_storage(Span<const blender::nodes::NodeTreeRef *> trees,
@@@ -857,6 -1247,9 +857,6 @@@ static GeometrySet compute_geometry(con
    blender::LinearAllocator<> &allocator = scope.linear_allocator();
    blender::nodes::MultiFunctionByNode mf_by_node = get_multi_function_per_node(tree, scope);
  
 -  PersistentDataHandleMap handle_map;
 -  fill_data_handle_map(nmd->settings, tree, handle_map);
 -
    Map<DOutputSocket, GMutablePointer> group_inputs;
  
    const DTreeContext *root_context = &tree.root_context();
      for (const OutputSocketRef *socket : remaining_input_sockets) {
        const CPPType &cpp_type = *blender::nodes::socket_cpp_type_get(*socket->typeinfo());
        void *value_in = allocator.allocate(cpp_type.size(), cpp_type.alignment());
 -      initialize_group_input(*nmd, handle_map, *socket->bsocket(), cpp_type, value_in);
 +      initialize_group_input(*nmd, *socket->bsocket(), cpp_type, value_in);
        group_inputs.add_new({root_context, socket}, {cpp_type, value_in});
      }
    }
      log_ui_hints(socket, values, ctx->object, nmd);
    };
  
 -  GeometryNodesEvaluator evaluator{group_inputs,
 -                                   group_outputs,
 -                                   mf_by_node,
 -                                   handle_map,
 -                                   ctx->object,
 -                                   (ModifierData *)nmd,
 -                                   ctx->depsgraph,
 -                                   log_socket_value};
 -
 -  Vector<GMutablePointer> results = evaluator.execute();
 -  BLI_assert(results.size() == 1);
 -  GMutablePointer result = results[0];
 -
 -  GeometrySet output_geometry = std::move(*(GeometrySet *)result.get());
 -  return output_geometry;
 +  blender::modifiers::geometry_nodes::GeometryNodesEvaluationParams eval_params;
 +  eval_params.input_values = group_inputs;
 +  eval_params.output_sockets = group_outputs;
 +  eval_params.mf_by_node = &mf_by_node;
 +  eval_params.modifier_ = nmd;
 +  eval_params.depsgraph = ctx->depsgraph;
 +  eval_params.self_object = ctx->object;
 +  eval_params.log_socket_value_fn = log_socket_value;
 +  blender::modifiers::geometry_nodes::evaluate_geometry_nodes(eval_params);
 +
 +  BLI_assert(eval_params.r_output_values.size() == 1);
 +  GMutablePointer result = eval_params.r_output_values[0];
 +  return result.relocate_out<GeometrySet>();
  }
  
  /**
@@@ -1058,37 -1453,36 +1058,37 @@@ static void draw_property_for_socket(ui
  
    /* IDProperties can be removed with python, so there could be a situation where
     * there isn't a property for a socket or it doesn't have the correct type. */
 -  if (property != nullptr && property_type->is_correct_type(*property)) {
 +  if (property == nullptr || !property_type->is_correct_type(*property)) {
 +    return;
 +  }
  
 -    char socket_id_esc[sizeof(socket.identifier) * 2];
 -    BLI_str_escape(socket_id_esc, socket.identifier, sizeof(socket_id_esc));
 +  char socket_id_esc[sizeof(socket.identifier) * 2];
 +  BLI_str_escape(socket_id_esc, socket.identifier, sizeof(socket_id_esc));
  
 -    char rna_path[sizeof(socket_id_esc) + 4];
 -    BLI_snprintf(rna_path, ARRAY_SIZE(rna_path), "[\"%s\"]", socket_id_esc);
 +  char rna_path[sizeof(socket_id_esc) + 4];
 +  BLI_snprintf(rna_path, ARRAY_SIZE(rna_path), "[\"%s\"]", socket_id_esc);
  
 -    /* Use #uiItemPointerR to draw pointer properties because #uiItemR would not have enough
 -     * information about what type of ID to select for editing the values. This is because
 -     * pointer IDProperties contain no information about their type. */
 -    switch (socket.type) {
 -      case SOCK_OBJECT: {
 -        uiItemPointerR(
 -            layout, md_ptr, rna_path, bmain_ptr, "objects", socket.name, ICON_OBJECT_DATA);
 -        break;
 -      }
 -      case SOCK_COLLECTION: {
 -        uiItemPointerR(layout,
 -                       md_ptr,
 -                       rna_path,
 -                       bmain_ptr,
 -                       "collections",
 -                       socket.name,
 -                       ICON_OUTLINER_COLLECTION);
 -        break;
 -      }
 -      default:
 -        uiItemR(layout, md_ptr, rna_path, 0, socket.name, ICON_NONE);
 +  /* Use #uiItemPointerR to draw pointer properties because #uiItemR would not have enough
 +   * information about what type of ID to select for editing the values. This is because
 +   * pointer IDProperties contain no information about their type. */
 +  switch (socket.type) {
 +    case SOCK_OBJECT: {
 +      uiItemPointerR(
 +          layout, md_ptr, rna_path, bmain_ptr, "objects", socket.name, ICON_OBJECT_DATA);
 +      break;
      }
 +    case SOCK_COLLECTION: {
 +      uiItemPointerR(layout,
 +                     md_ptr,
 +                     rna_path,
 +                     bmain_ptr,
 +                     "collections",
 +                     socket.name,
 +                     ICON_OUTLINER_COLLECTION);
 +      break;
 +    }
 +    default:
 +      uiItemR(layout, md_ptr, rna_path, 0, socket.name, ICON_NONE);
    }
  }
  
@@@ -1200,6 -1594,7 +1200,6 @@@ ModifierTypeInfo modifierType_Nodes = 
      /* modifyMesh */ modifyMesh,
      /* modifyHair */ nullptr,
      /* modifyGeometrySet */ modifyGeometrySet,
 -    /* modifyVolume */ nullptr,
  
      /* initData */ initData,
      /* requiredDataMask */ requiredDataMask,