[Bf-blender-cvs] [c20d7676fc7] geometry-nodes-mesh-primitives: Move cylinder / cone code to cone file
Hans Goudey
noreply at git.blender.org
Sat Mar 13 23:31:49 CET 2021
Commit: c20d7676fc7ddbd342e1fb73127bb8aaf246c7dd
Author: Hans Goudey
Date: Sat Mar 13 17:22:15 2021 -0500
Branches: geometry-nodes-mesh-primitives
https://developer.blender.org/rBc20d7676fc7ddbd342e1fb73127bb8aaf246c7dd
Move cylinder / cone code to cone file
===================================================================
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/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
index fcf1adcfee9..5b66d027b5c 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
@@ -63,6 +63,390 @@ static void geo_node_mesh_primitive_cone_init(bNodeTree *UNUSED(ntree), bNode *n
namespace blender::nodes {
+static int vert_total(const GeometryNodeMeshCircleFillType fill_type,
+ const int verts_num,
+ const bool use_top,
+ const bool use_bottom)
+{
+ int vert_total = 0;
+ if (use_top) {
+ vert_total += verts_num;
+ if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
+ vert_total++;
+ }
+ }
+ else {
+ vert_total++;
+ }
+ if (use_bottom) {
+ vert_total += verts_num;
+ if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
+ vert_total++;
+ }
+ }
+ else {
+ vert_total++;
+ }
+
+ return vert_total;
+}
+
+static int edge_total(const GeometryNodeMeshCircleFillType fill_type,
+ const int verts_num,
+ const bool use_top,
+ const bool use_bottom)
+{
+ if (!use_top && !use_bottom) {
+ return 1;
+ }
+
+ int edge_total = 0;
+ if (use_top) {
+ edge_total += verts_num;
+ if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
+ edge_total += verts_num;
+ }
+ }
+
+ edge_total += verts_num;
+
+ if (use_bottom) {
+ edge_total += verts_num;
+ if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
+ edge_total += verts_num;
+ }
+ }
+
+ return edge_total;
+}
+
+static int corner_total(const GeometryNodeMeshCircleFillType fill_type,
+ const int verts_num,
+ const bool use_top,
+ const bool use_bottom)
+{
+ if (!use_top && !use_bottom) {
+ return 0;
+ }
+
+ int corner_total = 0;
+ if (use_top) {
+ if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
+ corner_total += verts_num;
+ }
+ else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
+ corner_total += verts_num * 3;
+ }
+ }
+
+ if (use_top && use_bottom) {
+ corner_total += verts_num * 4;
+ }
+ else {
+ corner_total += verts_num * 3;
+ }
+
+ if (use_bottom) {
+ if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
+ corner_total += verts_num;
+ }
+ else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
+ corner_total += verts_num * 3;
+ }
+ }
+
+ return corner_total;
+}
+
+static int face_total(const GeometryNodeMeshCircleFillType fill_type,
+ const int verts_num,
+ const bool use_top,
+ const bool use_bottom)
+{
+ if (!use_top && !use_bottom) {
+ return 0;
+ }
+
+ int face_total = 0;
+ if (use_top) {
+ if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
+ face_total++;
+ }
+ else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
+ face_total += verts_num;
+ }
+ }
+
+ face_total += verts_num;
+
+ if (use_bottom) {
+ if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
+ face_total++;
+ }
+ else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
+ face_total += verts_num;
+ }
+ }
+
+ return face_total;
+}
+
+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)
+{
+ 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));
+ }
+
+ /* 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_center_vert_index;
+ edge.v2 = top_verts_start + i;
+ }
+ }
+ }
+
+ /* Create connecting edges. */
+ const int connecting_edges_start = top_fan_edges_start + (use_top ? verts_num : 0);
+ for (const int i : IndexRange(verts_num)) {
+ MEdge &edge = edges[connecting_edges_start + i];
+ edge.v1 = top_verts_start + (use_top ? i : 0);
+ edge.v2 = bottom_verts_start + (use_bottom ? i : 0);
+ }
+
+ /* Create bottom edges. */
+ const int bottom_edges_start = connecting_edges_start + verts_num;
+ const int bottom_fan_edges_start = (use_bottom &&
+ fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) ?
+ bottom_edges_start + verts_num :
+ bottom_edges_start;
+ if (use_bottom) {
+ for (const int i : IndexRange(verts_num)) {
+ MEdge &edge = edges[bottom_edges_start + i];
+ edge.v1 = bottom_verts_start + i;
+ edge.v2 = bottom_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[bottom_fan_edges_start + i];
+ edge.v1 = bottom_center_vert_index;
+ edge.v2 = bottom_verts_start + i;
+ }
+ }
+ }
+
+ /* Create top corners and faces. */
+ int loop_index = 0;
+ int poly_index = 0;
+ if (use_top) {
+ if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
+ MPoly &poly = polys[poly_index++];
+ poly.loopstart = loop_index;
+ poly.totloop = verts_num;
+
+ for (const int i : IndexRange(verts_num)) {
+ MLoop &loop = loops[loop_index++];
+ loop.v = top_verts_start + i;
+ loop.e = top_edges_start + i;
+ }
+ }
+ else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
+ for (const int i : IndexRange(verts_num)) {
+ MPoly &poly = polys[poly_index++];
+ poly.loopstart = loop_index;
+ poly.totloop = 3;
+
+ MLoop &loop1 = loops[loop_index++];
+ loop1.v = top_verts_start + i;
+ loop1.e = top_edges_start + i;
+ MLoop &loop2 = loops[loop_index++];
+ loop2.v = top_verts_start + (i + 1) % verts_num;
+ loop2.e = top_fan_edges_start + (i + 1) % verts_num;
+ MLoop &loop3 = loops[loop_index++];
+ loop3.v = top_center_vert_index;
+ loop3.e = top_fan_edges_start + i;
+ }
+ }
+ }
+
+ /* Create side corners and faces. */
+ if (use_top && use_bottom) {
+ /* Quads connect the top and bottom. */
+ for (const int i : IndexRange(verts_num)) {
+ MPoly &poly = polys[poly_index++];
+ poly.loopstart = loop_index;
+ poly.totloop = 4;
+
+ MLoop &loop1 = loops[loop_index++];
+ loop1.v = top_ve
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list