[Bf-blender-cvs] [e9d5b767e86] geometry-nodes-mesh-primitives: Revert "Use BMesh for cone, cylinder, and sphere"

Hans Goudey noreply at git.blender.org
Tue Mar 16 00:12:42 CET 2021


Commit: e9d5b767e86817f8cfbd8e6f8b8315d64a25f0be
Author: Hans Goudey
Date:   Mon Mar 15 18:27:04 2021 -0400
Branches: geometry-nodes-mesh-primitives
https://developer.blender.org/rBe9d5b767e86817f8cfbd8e6f8b8315d64a25f0be

Revert "Use BMesh for cone, cylinder, and sphere"

This reverts commit 167a2d19a900eb5e2f5030c233430672599fc60f.

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

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
M	source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc

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

diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh
index 8eac8bc0a20..fb80bd08797 100644
--- a/source/blender/nodes/geometry/node_geometry_util.hh
+++ b/source/blender/nodes/geometry/node_geometry_util.hh
@@ -52,9 +52,7 @@ void transform_mesh(Mesh *mesh,
                     const float3 rotation,
                     const float3 scale);
 
-Mesh *create_cylinder_or_cone_mesh(const float3 location,
-                                   const float3 rotation,
-                                   const float radius_top,
+Mesh *create_cylinder_or_cone_mesh(const float radius_top,
                                    const float radius_bottom,
                                    const float depth,
                                    const int verts_num,
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 ee1661cf43c..1fb5144b981 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
@@ -17,14 +17,11 @@
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 
-#include "BKE_lib_id.h"
 #include "BKE_mesh.h"
 
 #include "UI_interface.h"
 #include "UI_resources.h"
 
-#include "bmesh.h"
-
 #include "node_geometry_util.hh"
 
 static bNodeSocketTemplate geo_node_mesh_primitive_cone_in[] = {
@@ -191,45 +188,350 @@ static int face_total(const GeometryNodeMeshCircleFillType fill_type,
   return face_total;
 }
 
-Mesh *create_cylinder_or_cone_mesh(const float3 location,
-                                   const float3 rotation,
-                                   const float radius_top,
+static void calculate_uvs(Mesh *mesh,
+                          const bool use_top,
+                          const bool use_bottom,
+                          const int verts_num,
+                          const GeometryNodeMeshCircleFillType fill_type)
+{
+  MeshComponent mesh_component;
+  mesh_component.replace(mesh, GeometryOwnershipType::Editable);
+  OutputAttributePtr uv_attribute = mesh_component.attribute_try_get_for_output(
+      "uv", ATTR_DOMAIN_CORNER, CD_PROP_FLOAT2, nullptr);
+  MutableSpan<float2> uvs = uv_attribute->get_span_for_write_only<float2>();
+
+  Array<float2> circle(verts_num);
+  float angle = 0.0f;
+  const float angle_delta = 2.0f * M_PI / static_cast<float>(verts_num);
+  for (const int i : IndexRange(verts_num)) {
+    circle[i].x = std::cos(angle) * 0.225f + 0.25f;
+    circle[i].y = std::sin(angle) * 0.225f + 0.25f;
+    angle += angle_delta;
+  }
+
+  int loop_index = 0;
+  if (use_top) {
+    if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
+      for (const int i : IndexRange(verts_num)) {
+        uvs[loop_index++] = circle[i];
+      }
+    }
+    else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
+      for (const int i : IndexRange(verts_num)) {
+        uvs[loop_index++] = circle[i];
+        uvs[loop_index++] = circle[(i + 1) % verts_num];
+        uvs[loop_index++] = float2(0.25f, 0.25f);
+      }
+    }
+  }
+
+  /* Create side corners and faces. */
+  if (use_top && use_bottom) {
+    const float bottom = (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NONE) ? 0.0f : 0.5f;
+    /* Quads connect the top and bottom. */
+    for (const int i : IndexRange(verts_num)) {
+      const float vert = static_cast<float>(i);
+      uvs[loop_index++] = float2(vert / verts_num, bottom);
+      uvs[loop_index++] = float2((vert + 1.0f) / verts_num, bottom);
+      uvs[loop_index++] = float2((vert + 1.0f) / verts_num, 1.0f);
+      uvs[loop_index++] = float2(vert / verts_num, 1.0f);
+    }
+  }
+  else {
+    /* Triangles connect the top and bottom section. */
+    if (use_top) {
+      for (const int i : IndexRange(verts_num)) {
+        uvs[loop_index++] = circle[i] + float2(0.5f, 0.0f);
+        uvs[loop_index++] = float2(0.75f, 0.25f);
+        uvs[loop_index++] = circle[(i + 1) % verts_num] + float2(0.5f, 0.0f);
+      }
+    }
+    else {
+      BLI_assert(use_bottom);
+      for (const int i : IndexRange(verts_num)) {
+        uvs[loop_index++] = circle[i];
+        uvs[loop_index++] = circle[(i + 1) % verts_num];
+        uvs[loop_index++] = float2(0.25f, 0.25f);
+      }
+    }
+  }
+
+  /* Create bottom corners and faces. */
+  if (use_bottom) {
+    if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
+      for (const int i : IndexRange(verts_num)) {
+        /* Go backwards because of reversed face normal. */
+        uvs[loop_index++] = circle[verts_num - 1 - i] + float2(0.5f, 0.0f);
+      }
+    }
+    else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
+      for (const int i : IndexRange(verts_num)) {
+        uvs[loop_index++] = circle[i] + float2(0.5f, 0.0f);
+        uvs[loop_index++] = float2(0.75f, 0.25f);
+        uvs[loop_index++] = circle[(i + 1) % verts_num] + float2(0.5f, 0.0f);
+      }
+    }
+  }
+
+  uv_attribute.apply_span_and_save();
+}
+
+Mesh *create_cylinder_or_cone_mesh(const float radius_top,
                                    const float radius_bottom,
                                    const float depth,
                                    const int verts_num,
                                    const GeometryNodeMeshCircleFillType fill_type)
 {
-  float4x4 transform;
-  loc_eul_size_to_mat4(transform.values, location, rotation, float3(1));
-
   const bool use_top = radius_top != 0.0f;
   const bool use_bottom = radius_bottom != 0.0f;
+  /* Handle the case of a line / single point before everything else to avoid
+   * the need to check for it later. */
+  if (!use_top && !use_bottom) {
+    const bool single_vertex = depth == 0.0f;
+    Mesh *mesh = BKE_mesh_new_nomain(single_vertex ? 1 : 2, single_vertex ? 0 : 1, 0, 0, 0);
+    copy_v3_v3(mesh->mvert[0].co, float3(0.0f, 0.0f, depth));
+    if (single_vertex) {
+      short up[3] = {0, 0, SHRT_MAX};
+      copy_v3_v3_short(mesh->mvert[0].no, up);
+      return mesh;
+    }
+    copy_v3_v3(mesh->mvert[1].co, float3(0.0f, 0.0f, -depth));
+    mesh->medge[0].v1 = 0;
+    mesh->medge[0].v2 = 1;
+    mesh->medge[0].flag |= ME_LOOSEEDGE;
+    BKE_mesh_calc_normals(mesh);
+    return mesh;
+  }
+
+  Mesh *mesh = BKE_mesh_new_nomain(vert_total(fill_type, verts_num, use_top, use_bottom),
+                                   edge_total(fill_type, verts_num, use_top, use_bottom),
+                                   0,
+                                   corner_total(fill_type, verts_num, use_top, use_bottom),
+                                   face_total(fill_type, verts_num, use_top, use_bottom));
+  MutableSpan<MVert> verts = MutableSpan<MVert>(mesh->mvert, mesh->totvert);
+  MutableSpan<MEdge> edges = MutableSpan<MEdge>(mesh->medge, mesh->totedge);
+  MutableSpan<MLoop> loops = MutableSpan<MLoop>(mesh->mloop, mesh->totloop);
+  MutableSpan<MPoly> polys = MutableSpan<MPoly>(mesh->mpoly, mesh->totpoly);
+
+  /* Calculate vertex positions. */
+  const int top_verts_start = 0;
+  const int bottom_verts_start = top_verts_start + (use_top ? verts_num : 1);
+  float angle = 0.0f;
+  const float angle_delta = 2.0f * M_PI / static_cast<float>(verts_num);
+  for (const int i : IndexRange(verts_num)) {
+    const float x = std::cos(angle);
+    const float y = std::sin(angle);
+    if (use_top) {
+      copy_v3_v3(verts[top_verts_start + i].co, float3(x * radius_top, y * radius_top, depth));
+    }
+    if (use_bottom) {
+      copy_v3_v3(verts[bottom_verts_start + i].co,
+                 float3(x * radius_bottom, y * radius_bottom, -depth));
+    }
+    angle += angle_delta;
+  }
+  if (!use_top) {
+    copy_v3_v3(verts[top_verts_start].co, float3(0.0f, 0.0f, depth));
+  }
+  if (!use_bottom) {
+    copy_v3_v3(verts[bottom_verts_start].co, float3(0.0f, 0.0f, -depth));
+  }
 
-  const BMeshCreateParams bmcp = {true};
-  const BMAllocTemplate allocsize = {vert_total(fill_type, verts_num, use_top, use_bottom),
-                                     edge_total(fill_type, verts_num, use_top, use_bottom),
-                                     corner_total(fill_type, verts_num, use_top, use_bottom),
-                                     face_total(fill_type, verts_num, use_top, use_bottom)};
-  BMesh *bm = BM_mesh_create(&allocsize, &bmcp);
-
-  const bool cap_end = (fill_type != 0);
-  const bool cap_tri = (fill_type == 2);
-  BMO_op_callf(bm,
-               BMO_FLAG_DEFAULTS,
-               "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b "
-               "cap_tris=%b depth=%f matrix=%m4 calc_uvs=%b",
-               verts_num,
-               radius_bottom,
-               radius_top,
-               cap_end,
-               cap_tri,
-               depth,
-               transform.values,
-               true);
-
-  Mesh *mesh = (Mesh *)BKE_id_new_nomain(ID_ME, NULL);
-  BM_mesh_bm_to_me_for_eval(bm, mesh, NULL);
-  BM_mesh_free(bm);
+  /* Add center vertices for the triangle fans at the end. */
+  const int top_center_vert_index = bottom_verts_start + (use_bottom ? verts_num : 1);
+  const int bottom_center_vert_index = top_center_vert_index + (use_top ? 1 : 0);
+  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
+    if (use_top) {
+      copy_v3_v3(verts[top_center_vert_index].co, float3(0.0f, 0.0f, depth));
+    }
+    if (use_bottom) {
+      copy_v3_v3(verts[bottom_center_vert_index].co, float3(0.0f, 0.0f, -depth));
+    }
+  }
+
+  /* Create top edges. */
+  const int top_edges_start = 0;
+  const int top_fan_edges_start = (use_top &&
+                                   fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) ?
+                                      top_edges_start + verts_num :
+                                      top_edges_start;
+  if (use_top) {
+    for (const int i : IndexRange(verts_num)) {
+      MEdge &edge = edges[top_edges_start + i];
+      edge.v1 = top_verts_start + i;
+      edge.v2 = top_verts_start + (i + 1) % verts_num;
+    }
+    if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
+      for (const int i : IndexRange(verts_num)) {
+        MEdge &edge = edges[top_fan_edges_start + i];
+        edge.v1 = top_c

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list