[Bf-blender-cvs] [0bfae1b1207] master: Geometry Nodes: geometry component type warning system

Jacques Lucke noreply at git.blender.org
Tue Oct 26 20:00:33 CEST 2021


Commit: 0bfae1b12078ef278a56c6e932c13be5bc9781aa
Author: Jacques Lucke
Date:   Tue Oct 26 20:00:03 2021 +0200
Branches: master
https://developer.blender.org/rB0bfae1b12078ef278a56c6e932c13be5bc9781aa

Geometry Nodes: geometry component type warning system

Previously, every node had to create warnings for unsupported input
geometry manually. Now this is automated. Nodes just have to specify
the geometry types they support in the node declaration.

Differential Revision: https://developer.blender.org/D12899

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

M	source/blender/blenkernel/BKE_geometry_set.hh
M	source/blender/blenkernel/intern/geometry_set.cc
M	source/blender/nodes/CMakeLists.txt
M	source/blender/nodes/NOD_geometry_exec.hh
M	source/blender/nodes/NOD_socket_declarations.hh
A	source/blender/nodes/NOD_socket_declarations_geometry.hh
M	source/blender/nodes/geometry/node_geometry_util.hh
M	source/blender/nodes/geometry/nodes/node_geo_boolean.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_length.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_set_handles.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
M	source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
M	source/blender/nodes/geometry/nodes/node_geo_edge_split.cc
M	source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
M	source/blender/nodes/geometry/nodes/node_geo_material_replace.cc
M	source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc
M	source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc
M	source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc
M	source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc
M	source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
M	source/blender/nodes/geometry/nodes/node_geo_proximity.cc
M	source/blender/nodes/geometry/nodes/node_geo_raycast.cc
M	source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc
M	source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_material.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
M	source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
M	source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc
M	source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc
M	source/blender/nodes/geometry/nodes/node_geo_triangulate.cc
M	source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
M	source/blender/nodes/intern/extern_implementations.cc
M	source/blender/nodes/intern/node_geometry_exec.cc
M	source/blender/nodes/intern/node_socket_declarations.cc

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

diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 429c37e9c9b..d273fe74310 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -318,6 +318,8 @@ struct GeometrySet {
       bool include_instances,
       blender::Map<blender::bke::AttributeIDRef, AttributeKind> &r_attributes) const;
 
+  blender::Vector<GeometryComponentType> gather_component_types(bool include_instances, bool ignore_empty) const;
+
   using ForeachSubGeometryCallback = blender::FunctionRef<void(GeometrySet &geometry_set)>;
 
   void modify_geometry_sets(ForeachSubGeometryCallback callback);
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index 4753a9e0768..cd1bafe445a 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -527,6 +527,40 @@ void GeometrySet::gather_attributes_for_propagation(
   delete dummy_component;
 }
 
+static void gather_component_types_recursive(const GeometrySet &geometry_set,
+                                             const bool include_instances,
+                                             const bool ignore_empty,
+                                             Vector<GeometryComponentType> &r_types)
+{
+  for (const GeometryComponent *component : geometry_set.get_components_for_read()) {
+    if (ignore_empty) {
+      if (component->is_empty()) {
+        continue;
+      }
+    }
+    r_types.append_non_duplicates(component->type());
+  }
+  if (!include_instances) {
+    return;
+  }
+  const InstancesComponent *instances = geometry_set.get_component_for_read<InstancesComponent>();
+  if (instances == nullptr) {
+    return;
+  }
+  instances->foreach_referenced_geometry([&](const GeometrySet &instance_geometry_set) {
+    gather_component_types_recursive(
+        instance_geometry_set, include_instances, ignore_empty, r_types);
+  });
+}
+
+blender::Vector<GeometryComponentType> GeometrySet::gather_component_types(
+    const bool include_instances, bool ignore_empty) const
+{
+  Vector<GeometryComponentType> types;
+  gather_component_types_recursive(*this, include_instances, ignore_empty, types);
+  return types;
+}
+
 static void gather_mutable_geometry_sets(GeometrySet &geometry_set,
                                          Vector<GeometrySet *> &r_geometry_sets)
 {
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index acf0ab9b224..9d35b7b9bff 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -448,6 +448,7 @@ set(SRC
   NOD_shader.h
   NOD_socket.h
   NOD_socket_declarations.hh
+  NOD_socket_declarations_geometry.hh
   NOD_static_types.h
   NOD_texture.h
   NOD_type_conversions.hh
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh
index f5775b8a6e0..6e1f21dbae0 100644
--- a/source/blender/nodes/NOD_geometry_exec.hh
+++ b/source/blender/nodes/NOD_geometry_exec.hh
@@ -171,10 +171,16 @@ class GeoNodeExecParams {
       this->check_input_access(identifier, &CPPType::get<T>());
 #endif
       GMutablePointer gvalue = this->extract_input(identifier);
-      return gvalue.relocate_out<T>();
+      T value = gvalue.relocate_out<T>();
+      if constexpr (std::is_same_v<T, GeometrySet>) {
+        this->check_input_geometry_set(identifier, value);
+      }
+      return value;
     }
   }
 
+  void check_input_geometry_set(StringRef identifier, const GeometrySet &geometry_set) const;
+
   /**
    * Get input as vector for multi input socket with the given identifier.
    *
@@ -211,7 +217,11 @@ class GeoNodeExecParams {
 #endif
       GPointer gvalue = provider_->get_input(identifier);
       BLI_assert(gvalue.is_type<T>());
-      return *(const T *)gvalue.get();
+      const T &value = *(const T *)gvalue.get();
+      if constexpr (std::is_same_v<T, GeometrySet>) {
+        this->check_input_geometry_set(identifier, value);
+      }
+      return value;
     }
   }
 
diff --git a/source/blender/nodes/NOD_socket_declarations.hh b/source/blender/nodes/NOD_socket_declarations.hh
index d4958f433d6..f7aea212f73 100644
--- a/source/blender/nodes/NOD_socket_declarations.hh
+++ b/source/blender/nodes/NOD_socket_declarations.hh
@@ -212,14 +212,6 @@ class Image : public IDSocketDeclaration {
   Image();
 };
 
-class Geometry : public SocketDeclaration {
- public:
-  using Builder = SocketDeclarationBuilder<Geometry>;
-
-  bNodeSocket &build(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_out) const override;
-  bool matches(const bNodeSocket &socket) const override;
-};
-
 /* -------------------------------------------------------------------- */
 /** \name #FloatBuilder Inline Methods
  * \{ */
@@ -396,9 +388,7 @@ MAKE_EXTERN_SOCKET_DECLARATION(decl::Vector)
 MAKE_EXTERN_SOCKET_DECLARATION(decl::Bool)
 MAKE_EXTERN_SOCKET_DECLARATION(decl::Color)
 MAKE_EXTERN_SOCKET_DECLARATION(decl::String)
-MAKE_EXTERN_SOCKET_DECLARATION(decl::Geometry)
 
-#undef MAKE_EXTERN_SOCKET_DECLARATION
 }  // namespace blender::nodes
 
 /** \} */
diff --git a/source/blender/nodes/NOD_socket_declarations_geometry.hh b/source/blender/nodes/NOD_socket_declarations_geometry.hh
new file mode 100644
index 00000000000..1531f82d67d
--- /dev/null
+++ b/source/blender/nodes/NOD_socket_declarations_geometry.hh
@@ -0,0 +1,58 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "BKE_geometry_set.hh"
+
+#include "NOD_socket_declarations.hh"
+
+namespace blender::nodes::decl {
+
+class GeometryBuilder;
+
+class Geometry : public SocketDeclaration {
+ private:
+  blender::Vector<GeometryComponentType> supported_types_;
+  bool only_realized_data_ = false;
+  bool only_instances_ = false;
+
+  friend GeometryBuilder;
+
+ public:
+  using Builder = GeometryBuilder;
+
+  bNodeSocket &build(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_out) const override;
+  bool matches(const bNodeSocket &socket) const override;
+
+  Span<GeometryComponentType> supported_types() const;
+  bool only_realized_data() const;
+  bool only_instances() const;
+};
+
+class GeometryBuilder : public SocketDeclarationBuilder<Geometry> {
+ public:
+  GeometryBuilder &supported_type(GeometryComponentType supported_type);
+  GeometryBuilder &supported_type(blender::Vector<GeometryComponentType> supported_types);
+  GeometryBuilder &only_realized_data(bool value = true);
+  GeometryBuilder &only_instances(bool value = true);
+};
+
+}  // namespace blender::nodes::decl
+
+namespace blender::nodes {
+MAKE_EXTERN_SOCKET_DECLARATION(decl::Geometry)
+}
diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh
index f382ff6c132..167765fa131 100644
--- a/source/blender/nodes/geometry/node_geometry_util.hh
+++ b/source/blender/nodes/geometry/node_geometry_util.hh
@@ -32,6 +32,7 @@
 #include "NOD_geometry.h"
 #include "NOD_geometry_exec.hh"
 #include "NOD_socket_declarations.hh"
+#include "NOD_socket_declarations_geometry.hh"
 
 #include "node_util.h"
 
diff --git a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
index 27e18f16bad..dae7eb4bed1 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
@@ -27,8 +27,10 @@ namespace blender::nodes {
 
 static void geo_node_boolean_declare(NodeDeclarationBuilder &b)
 {
-  b.add_input<decl::Geometry>("Geometry 1");
-  b.add_input<decl::Geometry>("Geometry 2").multi_input();
+  b.add_input<decl::Geometry>("Geometry 1")
+      .only_realized_data()
+      .supported_type(GEO_COMPONENT_TYPE_MESH);
+  b.add_input<decl::Geometry>("Geometry 2").multi_input().supported_type(GEO_COMPONENT_TYPE_MESH);
   b.add_input<decl::Bool>("Self Intersection");
   b.add_input<decl::Bool>("Hole Tolerant");
   b.add_output<decl::Geometry>("Geometry");
@@ -83,11 +85,6 @@ static void geo_node_boolean_exec(GeoNodeExecParams params)
   GeometrySet set_a;
   if (operation == GEO_NODE_BOOLEAN_DIFFERENCE) {
     set_a = params.extract_input<GeometrySet>("Geometry 1");
-    if (set_a.has_instances()) {
-      params.error_message_add(
-          NodeWarningType::Info,
-          TIP_("Instances are not supported for the first geometry input, and will not be used"));
-    }
     /* Note that it technically wouldn't be necessary to realize the instances for the first
      * geometry input, but the boolean code expects the first shape for the difference operation
      * to be a single mesh. */
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
index 953922531c1..75459a97816 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
@@ -35,7 +35,7 @@ namespace blender::nodes {
 
 static void geo_node_curve_fill_declare(NodeDeclarationBuilder &b)
 {
-  b.add_input<decl::Geometry>("Curve");
+  b.add_input<decl::Geometry>("Curve").supported_type(GEO_COMPONENT_TYPE_CURVE);
   b.add_output<decl::Geometry>("Mesh");
 }
 
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
index 67ce5b00d6b..5b6dfb01f38 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
+++ b/source/blender/nodes/geom

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list