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 206be90fcbf..c0ca92bb4b9 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 @@ -372,45 +372,51 @@ static void calculate_cone_faces(const ConeConfig &config, MutableSpan loops, MutableSpan polys) { - int loop_index = 0; - int poly_index = 0; - + int rings_poly_start; + int rings_loop_start; if (config.top_has_center_vert) { + rings_poly_start = config.circle_segments; + rings_loop_start = config.circle_segments * 3; + /* Top cone tip or center triangle fan in the fill. */ const int top_center_vert = 0; const int top_fan_edges_start = 0; for (const int i : IndexRange(config.circle_segments)) { - MPoly &poly = polys[poly_index++]; - poly.loopstart = loop_index; + const int loop_start = i * 3; + MPoly &poly = polys[i]; + poly.loopstart = loop_start; poly.totloop = 3; - MLoop &loop_a = loops[loop_index++]; - loop_a.v = config.first_ring_verts_start + i; - loop_a.e = config.first_ring_edges_start + i; - MLoop &loop_b = loops[loop_index++]; - loop_b.v = config.first_ring_verts_start + ((i + 1) % config.circle_segments); - loop_b.e = top_fan_edges_start + ((i + 1) % config.circle_segments); - MLoop &loop_c = loops[loop_index++]; - loop_c.v = top_center_vert; - loop_c.e = top_fan_edges_start + i; + loops[loop_start + 0].v = config.first_ring_verts_start + i; + loops[loop_start + 0].e = config.first_ring_edges_start + i; + + loops[loop_start + 1].v = config.first_ring_verts_start + ((i + 1) % config.circle_segments); + loops[loop_start + 1].e = top_fan_edges_start + ((i + 1) % config.circle_segments); + + loops[loop_start + 2].v = top_center_vert; + loops[loop_start + 2].e = top_fan_edges_start + i; } } else if (config.fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) { + rings_poly_start = 1; + rings_loop_start = config.circle_segments; + /* Center n-gon in the fill. */ - MPoly &poly = polys[poly_index++]; - poly.loopstart = loop_index; + MPoly &poly = polys[0]; + poly.loopstart = 0; poly.totloop = config.circle_segments; for (const int i : IndexRange(config.circle_segments)) { - MLoop &loop = loops[loop_index++]; - loop.v = i; - loop.e = i; + loops[i].v = i; + loops[i].e = i; } } /* Quads connect one edge ring to the next one. */ if (config.tot_quad_rings > 0) { for (const int i : IndexRange(config.tot_quad_rings)) { + const int this_ring_poly_start = rings_poly_start + i * config.circle_segments; + const int this_ring_loop_start = rings_loop_start + i * config.circle_segments * 4; const int this_ring_vert_start = config.first_ring_verts_start + (i * config.circle_segments); const int next_ring_vert_start = this_ring_vert_start + config.circle_segments; @@ -421,55 +427,58 @@ static void calculate_cone_faces(const ConeConfig &config, const int ring_connections_start = this_ring_edges_start + config.circle_segments; for (const int j : IndexRange(config.circle_segments)) { - MPoly &poly = polys[poly_index++]; - poly.loopstart = loop_index; + const int loop_start = this_ring_loop_start + j * 4; + MPoly &poly = polys[this_ring_poly_start + j]; + poly.loopstart = loop_start; poly.totloop = 4; - MLoop &loop_a = loops[loop_index++]; - loop_a.v = this_ring_vert_start + j; - loop_a.e = ring_connections_start + j; - MLoop &loop_b = loops[loop_index++]; - loop_b.v = next_ring_vert_start + j; - loop_b.e = next_ring_edges_start + j; - MLoop &loop_c = loops[loop_index++]; - loop_c.v = next_ring_vert_start + ((j + 1) % config.circle_segments); - loop_c.e = ring_connections_start + ((j + 1) % config.circle_segments); - MLoop &loop_d = loops[loop_index++]; - loop_d.v = this_ring_vert_start + ((j + 1) % config.circle_segments); - loop_d.e = this_ring_edges_start + j; + loops[loop_start + 0].v = this_ring_vert_start + j; + loops[loop_start + 0].e = ring_connections_start + j; + + loops[loop_start + 1].v = next_ring_vert_start + j; + loops[loop_start + 1].e = next_ring_edges_start + j; + + loops[loop_start + 2].v = next_ring_vert_start + ((j + 1) % config.circle_segments); + loops[loop_start + 2].e = ring_connections_start + ((j + 1) % config.circle_segments); + + loops[loop_start + 3].v = this_ring_vert_start + ((j + 1) % config.circle_segments); + loops[loop_start + 3].e = this_ring_edges_start + j; } } } + const int bottom_poly_start = rings_poly_start + config.tot_quad_rings * config.circle_segments; + const int bottom_loop_start = rings_loop_start + + config.tot_quad_rings * config.circle_segments * 4; + if (config.bottom_has_center_vert) { /* Bottom cone tip or center triangle fan in the fill. */ for (const int i : IndexRange(config.circle_segments)) { - MPoly &poly = polys[poly_index++]; - poly.loopstart = loop_index; + const int loop_start = bottom_loop_start + i * 3; + MPoly &poly = polys[bottom_poly_start + i]; + poly.loopstart = loop_start; poly.totloop = 3; - MLoop &loop_a = loops[loop_index++]; - loop_a.v = config.last_ring_verts_start + i; - loop_a.e = config.last_fan_edges_start + i; - MLoop &loop_b = loops[loop_index++]; - loop_b.v = config.last_vert; - loop_b.e = config.last_fan_edges_start + (i + 1) % config.circle_segments; - MLoop &loop_c = loops[loop_index++]; - loop_c.v = config.last_ring_verts_start + (i + 1) % config.circle_segments; - loop_c.e = config.last_ring_edges_start + i; + loops[loop_start + 0].v = config.last_ring_verts_start + i; + loops[loop_start + 0].e = config.last_fan_edges_start + i; + + loops[loop_start + 1].v = config.last_vert; + loops[loop_start + 1].e = config.last_fan_edges_start + (i + 1) % config.circle_segments; + + loops[loop_start + 2].v = config.last_ring_verts_start + (i + 1) % config.circle_segments; + loops[loop_start + 2].e = config.last_ring_edges_start + i; } } else if (config.fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) { /* Center n-gon in the fill. */ - MPoly &poly = polys[poly_index++]; - poly.loopstart = loop_index; + MPoly &poly = polys[bottom_poly_start]; + poly.loopstart = bottom_loop_start; poly.totloop = config.circle_segments; for (const int i : IndexRange(config.circle_segments)) { /* Go backwards to reverse surface normal. */ - MLoop &loop = loops[loop_index++]; - loop.v = config.last_vert - i; - loop.e = config.last_edge - ((i + 1) % config.circle_segments); + loops[bottom_loop_start + i].v = config.last_vert - i; + loops[bottom_loop_start + i].e = config.last_edge - ((i + 1) % config.circle_segments); } } } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc index 0f693aff876..539c4107270 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc @@ -184,7 +184,6 @@ BLI_NOINLINE static void calculate_sphere_corners(MutableSpan loops, const int segments, const int rings) { - int loop_index = 0; auto segment_next_or_first = [&](const int segment) { return segment == segments - 1 ? 0 : segment + 1; }; @@ -192,63 +191,67 @@ BLI_NOINLINE static void calculate_sphere_corners(MutableSpan loops, /* Add the triangles connected to the top vertex. */ const int first_vert_ring_index_start = 1; for (const int segment : IndexRange(segments)) { + const int loop_start = segment * 3; const int segment_next = segment_next_or_first(segment); - MLoop &loop_a = loops[loop_index++]; - loop_a.v = 0; - loop_a.e = segment; - MLoop &loop_b = loops[loop_index++]; - loop_b.v = first_vert_ring_index_start + segment; - loop_b.e = segments + segment; - MLoop &loop_c = loops[loop_index++]; - loop_c.v = first_vert_ring_index_start + segment_next; - loop_c.e = segment_next; + loops[loop_start + 0].v = 0; + loops[loop_start + 0].e = segment; + + loops[loop_start + 1].v = first_vert_ring_index_start + segment; + loops[loop_start + 1].e = segments + segment; + + loops[loop_start + 2].v = first_vert_ring_index_start + segment_next; + loops[loop_start + 2].e = segment_next; } - int ring_vert_index_start = 1; - int ring_edge_index_start = segments; - for ([[maybe_unused]] const int ring : IndexRange(1, rings - 2)) { + const int rings_vert_index_start = 1; + const int rings_edge_index_start = segments; + const int rings_loop_index_start = segments * 3; + for (const int ring : IndexRange(1, rings - 2)) { + const int ring_vert_index_start = rings_vert_index_start + (ring - 1) * segments; + const int ring_edge_index_start = rings_edge_index_start + (ring - 1) * segments * 2; + const int ring_loop_index_start = rings_loop_index_start + (ring - 1) * segments * 4; + const int next_ring_vert_index_start = ring_vert_index_start + segments; const int next_ring_edge_index_start = ring_edge_index_start + segments * 2; const int ring_vertical_edge_index_start = ring_edge_index_start + segments; for (const int segment : IndexRange(segments)) { + const int loop_start = ring_loop_index_start + segment * 4; const int segment_next = segment_next_or_first(segment); - MLoop &loop_a = loops[loop_index++]; - loop_a.v = ring_vert_index_start + segment; - loop_a.e = ring_vertical_edge_index_start + segment; - MLoop &loop_b = loops[loop_index++]; - loop_b.v = next_ring_vert_index_start + segment; - loop_b.e = next_ring_edge_index_start + segment; - MLoop &loop_c = loops[loop_index++]; - loop_c.v = next_ring_vert_index_start + segment_next; - loop_c.e = ring_vertical_edge_index_start + segment_next; - MLoop &loop_d = loops[loop_index++]; - loop_d.v = ring_vert_index_start + segment_next; - loop_d.e = ring_edge_index_start + segment; + loops[loop_start + 0].v = ring_vert_index_start + segment; + loops[loop_start + 0].e = ring_vertical_edge_index_start + segment; + + loops[loop_start + 1].v = next_ring_vert_index_start + segment; + loops[loop_start + 1].e = next_ring_edge_index_start + segment; + + loops[loop_start + 2].v = next_ring_vert_index_start + segment_next; + loops[loop_start + 2].e = ring_vertical_edge_index_start + segment_next; + + loops[loop_start + 3].v = ring_vert_index_start + segment_next; + loops[loop_start + 3].e = ring_edge_index_start + segment; } - ring_vert_index_start += segments; - ring_edge_index_start += segments * 2; } /* Add the triangles connected to the bottom vertex. */ + const int bottom_loop_index_start = rings_loop_index_start + segments * (rings - 2) * 4; const int last_edge_ring_start = segments * (rings - 2) * 2 + segments; const int bottom_edge_fan_start = last_edge_ring_start + segments; const int last_vert_index = sphere_vert_total(segments, rings) - 1; const int last_vert_ring_start = last_vert_index - segments; for (const int segment : IndexRange(segments)) { + const int loop_start = bottom_loop_index_start + segment * 3; const int segment_next = segment_next_or_first(segment); - MLoop &loop_a = loops[loop_index++]; - loop_a.v = last_vert_index; - loop_a.e = bottom_edge_fan_start + segment_next; - MLoop &loop_b = loops[loop_index++]; - loop_b.v = last_vert_ring_start + segment_next; - loop_b.e = last_edge_ring_start + segment; - MLoop &loop_c = loops[loop_index++]; - loop_c.v = last_vert_ring_start + segment; - loop_c.e = bottom_edge_fan_start + segment; + loops[loop_start + 0].v = last_vert_index; + loops[loop_start + 0].e = bottom_edge_fan_start + segment_next; + + loops[loop_start + 1].v = last_vert_ring_start + segment_next; + loops[loop_start + 1].e = last_edge_ring_start + segment; + + loops[loop_start + 2].v = last_vert_ring_start + segment; + loops[loop_start + 2].e = bottom_edge_fan_start + segment; } } @@ -260,34 +263,39 @@ BLI_NOINLINE static void calculate_sphere_uvs(Mesh *mesh, const float segments, "uv_map", ATTR_DOMAIN_CORNER); MutableSpan uvs = uv_attribute.span; - int loop_index = 0; const float dy = 1.0f / rings; const float segments_inv = 1.0f / segments; for (const int i_segment : IndexRange(segments)) { + const int loop_start = i_segment * 3; const float segment = float(i_segment); - uvs[loop_index++] = float2((segment + 0.5f) * segments_inv, 0.0f); - uvs[loop_index++] = float2(segment * segments_inv, dy); - uvs[loop_index++] = float2((segment + 1.0f) * segments_inv, dy); + uvs[loop_start + 0] = float2((segment + 0.5f) * segments_inv, 0.0f); + uvs[loop_start + 1] = float2(segment * segments_inv, dy); + uvs[loop_start + 2] = float2((segment + 1.0f) * segments_inv, dy); } + const int rings_loop_index_start = segments * 3; for (const int i_ring : IndexRange(1, rings - 2)) { + const int ring_loop_index_start = rings_loop_index_start + (i_ring - 1) * segments * 4; const float ring = float(i_ring); for (const int i_segment : IndexRange(segments)) { + const int loop_start = ring_loop_index_start + i_segment * 4; const float segment = float(i_segment); - uvs[loop_index++] = float2(segment * segments_inv, ring / rings); - uvs[loop_index++] = float2(segment * segments_inv, (ring + 1.0f) / rings); - uvs[loop_index++] = float2((segment + 1.0f) * segments_inv, (ring + 1.0f) / rings); - uvs[loop_index++] = float2((segment + 1.0f) * segments_inv, ring / rings); + uvs[loop_start + 0] = float2(segment * segments_inv, ring / rings); + uvs[loop_start + 1] = float2(segment * segments_inv, (ring + 1.0f) / rings); + uvs[loop_start + 2] = float2((segment + 1.0f) * segments_inv, (ring + 1.0f) / rings); + uvs[loop_start + 3] = float2((segment + 1.0f) * segments_inv, ring / rings); } } + const int bottom_loop_index_start = rings_loop_index_start + segments * (rings - 2) * 4; for (const int i_segment : IndexRange(segments)) { + const int loop_start = bottom_loop_index_start + i_segment * 3; const float segment = float(i_segment); - uvs[loop_index++] = float2((segment + 0.5f) * segments_inv, 1.0f); - uvs[loop_index++] = float2((segment + 1.0f) * segments_inv, 1.0f - dy); - uvs[loop_index++] = float2(segment * segments_inv, 1.0f - dy); + uvs[loop_start + 0] = float2((segment + 0.5f) * segments_inv, 1.0f); + uvs[loop_start + 1] = float2((segment + 1.0f) * segments_inv, 1.0f - dy); + uvs[loop_start + 2] = float2(segment * segments_inv, 1.0f - dy); } uv_attribute.finish(); @@ -321,6 +329,8 @@ static Mesh *create_uv_sphere_mesh(const float radius, const int segments, const mesh->loose_edges_tag_none(); + BLI_assert(BKE_mesh_is_valid(mesh)); + return mesh; }