[Bf-blender-cvs] [54927caf4fc] master: Geometry Nodes: Add side and fill segments to Cone/Cylinder nodes

Leon Leno noreply at git.blender.org
Sun Oct 3 00:30:25 CEST 2021


Commit: 54927caf4fcf214428e2fcb05d378d96fde54025
Author: Leon Leno
Date:   Sat Oct 2 17:29:25 2021 -0500
Branches: master
https://developer.blender.org/rB54927caf4fcf214428e2fcb05d378d96fde54025

Geometry Nodes: Add side and fill segments to Cone/Cylinder nodes

This commit extends the 'Cone' and 'Cylinder' mesh primitive nodes,
with two inputs to control the segments along the side and in the fill.
This makes the nodes more flexible and brings them more in line with
the improved cube node.

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

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

M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/geometry/node_geometry_util.hh
M	source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
M	source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc

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

diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index f7ba32cf639..20fcff58990 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -10152,7 +10152,7 @@ static void def_geo_mesh_cylinder(StructRNA *srna)
   prop = RNA_def_property(srna, "fill_type", PROP_ENUM, PROP_NONE);
   RNA_def_property_enum_items(prop, rna_node_geometry_mesh_circle_fill_type_items);
   RNA_def_property_ui_text(prop, "Fill Type", "");
-  RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+  RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
 }
 
 static void def_geo_mesh_cone(StructRNA *srna)
@@ -10164,7 +10164,7 @@ static void def_geo_mesh_cone(StructRNA *srna)
   prop = RNA_def_property(srna, "fill_type", PROP_ENUM, PROP_NONE);
   RNA_def_property_enum_items(prop, rna_node_geometry_mesh_circle_fill_type_items);
   RNA_def_property_ui_text(prop, "Fill Type", "");
-  RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+  RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
 }
 
 static void def_geo_mesh_line(StructRNA *srna)
diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh
index 015ac0de002..5896b5bd6cc 100644
--- a/source/blender/nodes/geometry/node_geometry_util.hh
+++ b/source/blender/nodes/geometry/node_geometry_util.hh
@@ -65,7 +65,9 @@ Mesh *create_grid_mesh(const int verts_x,
 Mesh *create_cylinder_or_cone_mesh(const float radius_top,
                                    const float radius_bottom,
                                    const float depth,
-                                   const int verts_num,
+                                   const int circle_segments,
+                                   const int side_segments,
+                                   const int fill_segments,
                                    const GeometryNodeMeshCircleFillType fill_type);
 
 Mesh *create_cuboid_mesh(float3 size, int verts_x, int verts_y, int verts_z);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
index 0d58476fc58..a710f9d6190 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
@@ -29,13 +29,38 @@ namespace blender::nodes {
 
 static void geo_node_mesh_primitive_cone_declare(NodeDeclarationBuilder &b)
 {
-  b.add_input<decl::Int>("Vertices").default_value(32).min(3);
+  b.add_input<decl::Int>("Vertices").default_value(32).min(3).max(512);
+  b.add_input<decl::Int>("Side Segments").default_value(1).min(1).max(512);
+  b.add_input<decl::Int>("Fill Segments").default_value(1).min(1).max(512);
   b.add_input<decl::Float>("Radius Top").min(0.0f).subtype(PROP_DISTANCE);
   b.add_input<decl::Float>("Radius Bottom").default_value(1.0f).min(0.0f).subtype(PROP_DISTANCE);
   b.add_input<decl::Float>("Depth").default_value(2.0f).min(0.0f).subtype(PROP_DISTANCE);
   b.add_output<decl::Geometry>("Geometry");
 }
 
+static void geo_node_mesh_primitive_cone_init(bNodeTree *UNUSED(ntree), bNode *node)
+{
+  NodeGeometryMeshCone *node_storage = (NodeGeometryMeshCone *)MEM_callocN(
+      sizeof(NodeGeometryMeshCone), __func__);
+
+  node_storage->fill_type = GEO_NODE_MESH_CIRCLE_FILL_NGON;
+
+  node->storage = node_storage;
+}
+
+static void geo_node_mesh_primitive_cone_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+  bNodeSocket *vertices_socket = (bNodeSocket *)node->inputs.first;
+  bNodeSocket *rings_socket = vertices_socket->next;
+  bNodeSocket *fill_subdiv_socket = rings_socket->next;
+
+  const NodeGeometryMeshCone &storage = *(const NodeGeometryMeshCone *)node->storage;
+  const GeometryNodeMeshCircleFillType fill_type =
+      static_cast<const GeometryNodeMeshCircleFillType>(storage.fill_type);
+  const bool has_fill = fill_type != GEO_NODE_MESH_CIRCLE_FILL_NONE;
+  nodeSetSocketAvailability(fill_subdiv_socket, has_fill);
+}
+
 static void geo_node_mesh_primitive_cone_layout(uiLayout *layout,
                                                 bContext *UNUSED(C),
                                                 PointerRNA *ptr)
@@ -45,493 +70,632 @@ static void geo_node_mesh_primitive_cone_layout(uiLayout *layout,
   uiItemR(layout, ptr, "fill_type", 0, nullptr, ICON_NONE);
 }
 
-static void geo_node_mesh_primitive_cone_init(bNodeTree *UNUSED(ntree), bNode *node)
+struct ConeConfig {
+  float radius_top;
+  float radius_bottom;
+  float height;
+  int circle_segments;
+  int side_segments;
+  int fill_segments;
+  GeometryNodeMeshCircleFillType fill_type;
+
+  bool top_is_point;
+  bool bottom_is_point;
+  /* The cone tip and a triangle fan filling are topologically identical.
+   * This simplifies the logic in some cases. */
+  bool top_has_center_vert;
+  bool bottom_has_center_vert;
+
+  /* Helpful quantitites. */
+  int tot_quad_rings;
+  int tot_edge_rings;
+  int tot_verts;
+  int tot_edges;
+
+  /* Helpful vertex indices. */
+  int first_vert;
+  int first_ring_verts_start;
+  int last_ring_verts_start;
+  int last_vert;
+
+  /* Helpful edge indices. */
+  int first_ring_edges_start;
+  int last_ring_edges_start;
+  int last_fan_edges_start;
+  int last_edge;
+
+  ConeConfig(float radius_top,
+             float radius_bottom,
+             float depth,
+             int circle_segments,
+             int side_segments,
+             int fill_segments,
+             GeometryNodeMeshCircleFillType fill_type)
+      : radius_top(radius_top),
+        radius_bottom(radius_bottom),
+        height(0.5f * depth),
+        circle_segments(circle_segments),
+        side_segments(side_segments),
+        fill_segments(fill_segments),
+        fill_type(fill_type)
+  {
+    this->top_is_point = this->radius_top == 0.0f;
+    this->bottom_is_point = this->radius_bottom == 0.0f;
+    this->top_has_center_vert = this->top_is_point ||
+                                this->fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN;
+    this->bottom_has_center_vert = this->bottom_is_point ||
+                                   this->fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN;
+
+    this->tot_quad_rings = this->calculate_total_quad_rings();
+    this->tot_edge_rings = this->calculate_total_edge_rings();
+    this->tot_verts = this->calculate_total_verts();
+    this->tot_edges = this->calculate_total_edges();
+
+    this->first_vert = 0;
+    this->first_ring_verts_start = this->top_has_center_vert ? 1 : first_vert;
+    this->last_vert = this->tot_verts - 1;
+    this->last_ring_verts_start = this->last_vert - this->circle_segments;
+
+    this->first_ring_edges_start = this->top_has_center_vert ? this->circle_segments : 0;
+    this->last_ring_edges_start = this->first_ring_edges_start +
+                                  this->tot_quad_rings * this->circle_segments * 2;
+    this->last_fan_edges_start = this->tot_edges - this->circle_segments;
+    this->last_edge = this->tot_edges - 1;
+  }
+
+ private:
+  int calculate_total_quad_rings();
+  int calculate_total_edge_rings();
+  int calculate_total_verts();
+  int calculate_total_edges();
+
+ public:
+  int get_tot_corners() const;
+  int get_tot_faces() const;
+};
+
+int ConeConfig::calculate_total_quad_rings()
 {
-  NodeGeometryMeshCone *node_storage = (NodeGeometryMeshCone *)MEM_callocN(
-      sizeof(NodeGeometryMeshCone), __func__);
+  if (top_is_point && bottom_is_point) {
+    return 0;
+  }
 
-  node_storage->fill_type = GEO_NODE_MESH_CIRCLE_FILL_NGON;
+  int quad_rings = 0;
 
-  node->storage = node_storage;
+  if (!top_is_point) {
+    quad_rings += fill_segments - 1;
+  }
+
+  quad_rings += (!top_is_point && !bottom_is_point) ? side_segments : (side_segments - 1);
+
+  if (!bottom_is_point) {
+    quad_rings += fill_segments - 1;
+  }
+
+  return quad_rings;
 }
 
-static int vert_total(const GeometryNodeMeshCircleFillType fill_type,
-                      const int verts_num,
-                      const bool top_is_point,
-                      const bool bottom_is_point)
+int ConeConfig::calculate_total_edge_rings()
 {
-  int vert_total = 0;
+  if (top_is_point && bottom_is_point) {
+    return 0;
+  }
+
+  int edge_rings = 0;
+
   if (!top_is_point) {
-    vert_total += verts_num;
-    if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
-      vert_total++;
-    }
+    edge_rings += fill_segments;
   }
-  else {
+
+  edge_rings += side_segments - 1;
+
+  if (!bottom_is_point) {
+    edge_rings += fill_segments;
+  }
+
+  return edge_rings;
+}
+
+int ConeConfig::calculate_total_verts()
+{
+  if (top_is_point && bottom_is_point) {
+    return side_segments + 1;
+  }
+
+  int vert_total = 0;
+
+  if (top_has_center_vert) {
     vert_total++;
   }
+
+  if (!top_is_point) {
+    vert_total += circle_segments * fill_segments;
+  }
+
+  vert_total += circle_segments * (side_segments - 1);
+
   if (!bottom_is_point) {
-    vert_total += verts_num;
-    if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
-      vert_total++;
-    }
+    vert_total += circle_segments * fill_segments;
   }
-  else {
+
+  if (bottom_has_center_vert) {
     vert_total++;
   }
 
   return vert_total;
 }
 
-static int edge_total(const GeometryNodeMeshCircleFillType fill_type,
-                      const int verts_num,
-                      const bool top_is_point,
-                      const bool bottom_is_point)
+int ConeConfig::calculate_total_edges()
 {
   if (top_is_point && bottom_is_point) {
-    return 1;
+    return side_segments;
   }
 
   int edge_total = 0;
-  if (!top_is_point) {
-    edge_total += verts_num;
-    if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
-      edge_total += verts_num;
-    }
+  if (top_has_center_vert) {
+    edge_total += circle_segments;
   }
 
-  edge_total += verts_num;
+  edge_total += circle_segments * (tot_quad_rings * 2 + 1);
 
-  if (!bottom_is_point) {
-    edge_total += verts_num;
-    if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
-      edge_total += verts_num;
-    }
+  i

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list