[Bf-blender-cvs] [a71d2b26017] master: Geometry Nodes: Curve Fill Node

Erik Abrahamsson noreply at git.blender.org
Mon Aug 30 06:28:00 CEST 2021


Commit: a71d2b26017090e1cf329631d831d11f5b84de0a
Author: Erik Abrahamsson
Date:   Sun Aug 29 23:27:35 2021 -0500
Branches: master
https://developer.blender.org/rBa71d2b26017090e1cf329631d831d11f5b84de0a

Geometry Nodes: Curve Fill Node

This node takes a curve geometry input and creates a filled mesh at Z=0
using a constrained Delaunay triangulation algorithm. Because of the
choice of algorithm, the results should be higher quality than the
filling for 2D curve objects.

This commit adds an initial fairly simple version of the node, but more
features may be added in the future, like transferring attributes when
necessary, or an index attribute input to break up the calculations
into smaller chunks to improve performance.

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

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

M	release/scripts/startup/nodeitems_builtins.py
M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/node.cc
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/CMakeLists.txt
M	source/blender/nodes/NOD_geometry.h
M	source/blender/nodes/NOD_static_types.h
A	source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc

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

diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 6f9b222571c..d78023b4e0e 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -508,6 +508,7 @@ geometry_node_categories = [
         NodeItem("GeometryNodeMeshToCurve"),
         NodeItem("GeometryNodeCurveToPoints"),
         NodeItem("GeometryNodeCurveEndpoints"),
+        NodeItem("GeometryNodeCurveFill"),
         NodeItem("GeometryNodeCurveTrim"),
         NodeItem("GeometryNodeCurveLength"),
         NodeItem("GeometryNodeCurveReverse"),
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 06528cd213c..379d4332473 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1472,6 +1472,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
 #define GEO_NODE_CURVE_SET_HANDLES 1072
 #define GEO_NODE_CURVE_SPLINE_TYPE 1073
 #define GEO_NODE_CURVE_SELECT_HANDLES 1074
+#define GEO_NODE_CURVE_FILL 1075
 
 /** \} */
 
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 2a0e05a2616..fb43d1fc87f 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -5138,6 +5138,7 @@ static void registerGeometryNodes()
   register_node_type_geo_collection_info();
   register_node_type_geo_convex_hull();
   register_node_type_geo_curve_endpoints();
+  register_node_type_geo_curve_fill();
   register_node_type_geo_curve_length();
   register_node_type_geo_curve_primitive_bezier_segment();
   register_node_type_geo_curve_primitive_circle();
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 361fefa59d2..43dd4b4270e 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1437,6 +1437,10 @@ typedef struct NodeGeometryRaycast {
   char _pad[1];
 } NodeGeometryRaycast;
 
+typedef struct NodeGeometryCurveFill {
+  uint8_t mode;
+} NodeGeometryCurveFill;
+
 /* script node mode */
 #define NODE_SCRIPT_INTERNAL 0
 #define NODE_SCRIPT_EXTERNAL 1
@@ -2008,6 +2012,11 @@ typedef enum GeometryNodeRaycastMapMode {
   GEO_NODE_RAYCAST_NEAREST = 1,
 } GeometryNodeRaycastMapMode;
 
+typedef enum GeometryNodeCurveFillMode {
+  GEO_NODE_CURVE_FILL_MODE_TRIANGULATED = 0,
+  GEO_NODE_CURVE_FILL_MODE_NGONS = 1,
+} GeometryNodeCurveFillMode;
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 8d672e9b570..9e24a36915e 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -10261,6 +10261,24 @@ static void def_geo_raycast(StructRNA *srna)
   RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
 }
 
+static void def_geo_curve_fill(StructRNA *srna)
+{
+  static const EnumPropertyItem mode_items[] = {
+      {GEO_NODE_CURVE_FILL_MODE_TRIANGULATED, "TRIANGLES", 0, "Triangles", ""},
+      {GEO_NODE_CURVE_FILL_MODE_NGONS, "NGONS", 0, "N-gons", ""},
+      {0, NULL, 0, NULL, NULL},
+  };
+
+  PropertyRNA *prop;
+  RNA_def_struct_sdna_from(srna, "NodeGeometryCurveFill", "storage");
+
+  prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+  RNA_def_property_enum_sdna(prop, NULL, "mode");
+  RNA_def_property_enum_items(prop, mode_items);
+  RNA_def_property_ui_text(prop, "Mode", "");
+  RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+}
+
 /* -------------------------------------------------------------------------- */
 
 static void rna_def_shader_node(BlenderRNA *brna)
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 8680fcee49a..8dfab671565 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -165,6 +165,7 @@ set(SRC
   geometry/nodes/node_geo_common.cc
   geometry/nodes/node_geo_convex_hull.cc
   geometry/nodes/node_geo_curve_endpoints.cc
+  geometry/nodes/node_geo_curve_fill.cc
   geometry/nodes/node_geo_curve_length.cc
   geometry/nodes/node_geo_curve_primitive_bezier_segment.cc
   geometry/nodes/node_geo_curve_primitive_circle.cc
diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h
index 856d787c8d0..00062400eee 100644
--- a/source/blender/nodes/NOD_geometry.h
+++ b/source/blender/nodes/NOD_geometry.h
@@ -52,6 +52,7 @@ void register_node_type_geo_bounding_box(void);
 void register_node_type_geo_collection_info(void);
 void register_node_type_geo_convex_hull(void);
 void register_node_type_geo_curve_endpoints(void);
+void register_node_type_geo_curve_fill(void);
 void register_node_type_geo_curve_length(void);
 void register_node_type_geo_curve_primitive_bezier_segment(void);
 void register_node_type_geo_curve_primitive_circle(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 4da8648173d..8028350418a 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -292,6 +292,7 @@ DefNode(GeometryNode, GEO_NODE_BOUNDING_BOX, 0, "BOUNDING_BOX", BoundBox, "Bound
 DefNode(GeometryNode, GEO_NODE_COLLECTION_INFO, def_geo_collection_info, "COLLECTION_INFO", CollectionInfo, "Collection Info", "")
 DefNode(GeometryNode, GEO_NODE_CONVEX_HULL, 0, "CONVEX_HULL", ConvexHull, "Convex Hull", "")
 DefNode(GeometryNode, GEO_NODE_CURVE_ENDPOINTS, 0, "CURVE_ENDPOINTS", CurveEndpoints, "Curve Endpoints", "")
+DefNode(GeometryNode, GEO_NODE_CURVE_FILL, def_geo_curve_fill, "CURVE_FILL", CurveFill, "Curve Fill", "")
 DefNode(GeometryNode, GEO_NODE_CURVE_LENGTH, 0, "CURVE_LENGTH", CurveLength, "Curve Length", "")
 DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_BEZIER_SEGMENT, def_geo_curve_primitive_bezier_segment, "CURVE_PRIMITIVE_BEZIER_SEGMENT", CurvePrimitiveBezierSegment, "Bezier Segment", "")
 DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_CIRCLE, def_geo_curve_primitive_circle, "CURVE_PRIMITIVE_CIRCLE", CurvePrimitiveCircle, "Curve Circle", "")
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
new file mode 100644
index 00000000000..d01fd35bafe
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
@@ -0,0 +1,178 @@
+/*
+ * 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.
+ */
+
+#include "BLI_array.hh"
+#include "BLI_delaunay_2d.h"
+#include "BLI_double2.hh"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_mesh.h"
+#include "BKE_spline.hh"
+
+#include "BLI_task.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "node_geometry_util.hh"
+
+static bNodeSocketTemplate geo_node_curve_fill_in[] = {
+    {SOCK_GEOMETRY, N_("Curve")},
+    {-1, ""},
+};
+
+static bNodeSocketTemplate geo_node_curve_fill_out[] = {
+    {SOCK_GEOMETRY, N_("Mesh")},
+    {-1, ""},
+};
+
+static void geo_node_curve_fill_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
+{
+  uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
+}
+
+namespace blender::nodes {
+
+static void geo_node_curve_fill_init(bNodeTree *, bNode *node)
+{
+  NodeGeometryCurveFill *data = (NodeGeometryCurveFill *)MEM_callocN(sizeof(NodeGeometryCurveFill),
+                                                                     __func__);
+
+  data->mode = GEO_NODE_CURVE_FILL_MODE_TRIANGULATED;
+  node->storage = data;
+}
+
+static blender::meshintersect::CDT_result<double> do_cdt(const CurveEval &curve,
+                                                         const CDT_output_type output_type)
+{
+  Span<SplinePtr> splines = curve.splines();
+  blender::meshintersect::CDT_input<double> input;
+  input.need_ids = false;
+  Array<int> offsets = curve.evaluated_point_offsets();
+  input.vert.reinitialize(offsets.last());
+  input.face.reinitialize(splines.size());
+
+  for (const int i_spline : splines.index_range()) {
+    const SplinePtr &spline = splines[i_spline];
+    const int vert_offset = offsets[i_spline];
+
+    Span<float3> positions = spline->evaluated_positions();
+    for (const int i : positions.index_range()) {
+      input.vert[vert_offset + i] = double2(positions[i].x, positions[i].y);
+    }
+
+    input.face[i_spline].resize(spline->evaluated_edges_size());
+    MutableSpan<int> face_verts = input.face[i_spline];
+    for (const int i : IndexRange(spline->evaluated_edges_size())) {
+      face_verts[i] = vert_offset + i;
+    }
+  }
+  blender::meshintersect::CDT_result<double> result = delaunay_2d_calc(input, output_type);
+  return result;
+}
+
+/* Converts the CDT result into a Mesh. */
+static Mesh *cdt_to_mesh(const blender::meshintersect::CDT_result<double> &result)
+{
+  int vert_len = result.vert.size();
+  int edge_len = result.edge.size();
+  int poly_len = result.face.size();
+  int loop_len = 0;
+
+  for (const Vector<int> &face : result.face) {
+    loop_len += face.size();
+  }
+
+  Mesh *mesh = BKE_mesh_new_nomain(vert_len, edge_len, 0, loop_len, poly_len);
+  MutableSpan<MVert> verts{mesh->mvert, mesh->totvert};
+  MutableSpan<MEdge> edges{mesh->medge, mesh->totedge};
+  MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop};
+  MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly};
+
+  for (const int i : IndexRange(result.vert.size())) {
+    copy_v3_v3(verts[i].co, float3((float)result.vert[i].x, (float)result.vert[i].y, 0.0f));
+  }
+  f

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list