Differential D16893 Diff 59310 source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
| Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||
| /* Add the triangles connected to the bottom vertex. */ | /* Add the triangles connected to the bottom vertex. */ | ||||
| for (MPoly &poly : polys.take_back(segments)) { | for (MPoly &poly : polys.take_back(segments)) { | ||||
| poly.loopstart = loop_index; | poly.loopstart = loop_index; | ||||
| poly.totloop = 3; | poly.totloop = 3; | ||||
| loop_index += 3; | loop_index += 3; | ||||
| } | } | ||||
| } | } | ||||
| BLI_NOINLINE static void calculate_sphere_corners(MutableSpan<MLoop> loops, | BLI_NOINLINE static void calculate_sphere_corners(MutableSpan<int> corner_verts, | ||||
| MutableSpan<int> corner_edges, | |||||
| const int segments, | const int segments, | ||||
| const int rings) | const int rings) | ||||
| { | { | ||||
| auto segment_next_or_first = [&](const int segment) { | auto segment_next_or_first = [&](const int segment) { | ||||
| return segment == segments - 1 ? 0 : segment + 1; | return segment == segments - 1 ? 0 : segment + 1; | ||||
| }; | }; | ||||
| /* Add the triangles connected to the top vertex. */ | /* Add the triangles connected to the top vertex. */ | ||||
| const int first_vert_ring_start = 1; | const int first_vert_ring_start = 1; | ||||
| for (const int segment : IndexRange(segments)) { | for (const int segment : IndexRange(segments)) { | ||||
| const int loop_start = segment * 3; | const int loop_start = segment * 3; | ||||
| const int segment_next = segment_next_or_first(segment); | const int segment_next = segment_next_or_first(segment); | ||||
| loops[loop_start + 0].v = 0; | corner_verts[loop_start + 0] = 0; | ||||
| loops[loop_start + 0].e = segment; | corner_edges[loop_start + 0] = segment; | ||||
| loops[loop_start + 1].v = first_vert_ring_start + segment; | corner_verts[loop_start + 1] = first_vert_ring_start + segment; | ||||
| loops[loop_start + 1].e = segments + segment; | corner_edges[loop_start + 1] = segments + segment; | ||||
| loops[loop_start + 2].v = first_vert_ring_start + segment_next; | corner_verts[loop_start + 2] = first_vert_ring_start + segment_next; | ||||
| loops[loop_start + 2].e = segment_next; | corner_edges[loop_start + 2] = segment_next; | ||||
| } | } | ||||
| const int rings_vert_start = 1; | const int rings_vert_start = 1; | ||||
| const int rings_edge_start = segments; | const int rings_edge_start = segments; | ||||
| const int rings_loop_start = segments * 3; | const int rings_loop_start = segments * 3; | ||||
| for (const int ring : IndexRange(1, rings - 2)) { | for (const int ring : IndexRange(1, rings - 2)) { | ||||
| const int ring_vert_start = rings_vert_start + (ring - 1) * segments; | const int ring_vert_start = rings_vert_start + (ring - 1) * segments; | ||||
| const int ring_edge_start = rings_edge_start + (ring - 1) * segments * 2; | const int ring_edge_start = rings_edge_start + (ring - 1) * segments * 2; | ||||
| const int ring_loop_start = rings_loop_start + (ring - 1) * segments * 4; | const int ring_loop_start = rings_loop_start + (ring - 1) * segments * 4; | ||||
| const int next_ring_vert_start = ring_vert_start + segments; | const int next_ring_vert_start = ring_vert_start + segments; | ||||
| const int next_ring_edge_start = ring_edge_start + segments * 2; | const int next_ring_edge_start = ring_edge_start + segments * 2; | ||||
| const int ring_vertical_edge_start = ring_edge_start + segments; | const int ring_vertical_edge_start = ring_edge_start + segments; | ||||
| for (const int segment : IndexRange(segments)) { | for (const int segment : IndexRange(segments)) { | ||||
| const int loop_start = ring_loop_start + segment * 4; | const int loop_start = ring_loop_start + segment * 4; | ||||
| const int segment_next = segment_next_or_first(segment); | const int segment_next = segment_next_or_first(segment); | ||||
| loops[loop_start + 0].v = ring_vert_start + segment; | corner_verts[loop_start + 0] = ring_vert_start + segment; | ||||
| loops[loop_start + 0].e = ring_vertical_edge_start + segment; | corner_edges[loop_start + 0] = ring_vertical_edge_start + segment; | ||||
| loops[loop_start + 1].v = next_ring_vert_start + segment; | corner_verts[loop_start + 1] = next_ring_vert_start + segment; | ||||
| loops[loop_start + 1].e = next_ring_edge_start + segment; | corner_edges[loop_start + 1] = next_ring_edge_start + segment; | ||||
| loops[loop_start + 2].v = next_ring_vert_start + segment_next; | corner_verts[loop_start + 2] = next_ring_vert_start + segment_next; | ||||
| loops[loop_start + 2].e = ring_vertical_edge_start + segment_next; | corner_edges[loop_start + 2] = ring_vertical_edge_start + segment_next; | ||||
| loops[loop_start + 3].v = ring_vert_start + segment_next; | corner_verts[loop_start + 3] = ring_vert_start + segment_next; | ||||
| loops[loop_start + 3].e = ring_edge_start + segment; | corner_edges[loop_start + 3] = ring_edge_start + segment; | ||||
| } | } | ||||
| } | } | ||||
| /* Add the triangles connected to the bottom vertex. */ | /* Add the triangles connected to the bottom vertex. */ | ||||
| const int bottom_loop_start = rings_loop_start + segments * (rings - 2) * 4; | const int bottom_loop_start = rings_loop_start + segments * (rings - 2) * 4; | ||||
| const int last_edge_ring_start = segments * (rings - 2) * 2 + segments; | const int last_edge_ring_start = segments * (rings - 2) * 2 + segments; | ||||
| const int bottom_edge_fan_start = last_edge_ring_start + 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_index = sphere_vert_total(segments, rings) - 1; | ||||
| const int last_vert_ring_start = last_vert_index - segments; | const int last_vert_ring_start = last_vert_index - segments; | ||||
| for (const int segment : IndexRange(segments)) { | for (const int segment : IndexRange(segments)) { | ||||
| const int loop_start = bottom_loop_start + segment * 3; | const int loop_start = bottom_loop_start + segment * 3; | ||||
| const int segment_next = segment_next_or_first(segment); | const int segment_next = segment_next_or_first(segment); | ||||
| loops[loop_start + 0].v = last_vert_index; | corner_verts[loop_start + 0] = last_vert_index; | ||||
| loops[loop_start + 0].e = bottom_edge_fan_start + segment_next; | corner_edges[loop_start + 0] = bottom_edge_fan_start + segment_next; | ||||
| loops[loop_start + 1].v = last_vert_ring_start + segment_next; | corner_verts[loop_start + 1] = last_vert_ring_start + segment_next; | ||||
| loops[loop_start + 1].e = last_edge_ring_start + segment; | corner_edges[loop_start + 1] = last_edge_ring_start + segment; | ||||
| loops[loop_start + 2].v = last_vert_ring_start + segment; | corner_verts[loop_start + 2] = last_vert_ring_start + segment; | ||||
| loops[loop_start + 2].e = bottom_edge_fan_start + segment; | corner_edges[loop_start + 2] = bottom_edge_fan_start + segment; | ||||
| } | } | ||||
| } | } | ||||
| BLI_NOINLINE static void calculate_sphere_uvs(Mesh *mesh, | BLI_NOINLINE static void calculate_sphere_uvs(Mesh *mesh, | ||||
| const float segments, | const float segments, | ||||
| const float rings, | const float rings, | ||||
| const AttributeIDRef &uv_map_id) | const AttributeIDRef &uv_map_id) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | |||||
| sphere_edge_total(segments, rings), | sphere_edge_total(segments, rings), | ||||
| 0, | 0, | ||||
| sphere_corner_total(segments, rings), | sphere_corner_total(segments, rings), | ||||
| sphere_face_total(segments, rings)); | sphere_face_total(segments, rings)); | ||||
| BKE_id_material_eval_ensure_default_slot(&mesh->id); | BKE_id_material_eval_ensure_default_slot(&mesh->id); | ||||
| MutableSpan<float3> positions = mesh->vert_positions_for_write(); | MutableSpan<float3> positions = mesh->vert_positions_for_write(); | ||||
| MutableSpan<MEdge> edges = mesh->edges_for_write(); | MutableSpan<MEdge> edges = mesh->edges_for_write(); | ||||
| MutableSpan<MPoly> polys = mesh->polys_for_write(); | MutableSpan<MPoly> polys = mesh->polys_for_write(); | ||||
| MutableSpan<MLoop> loops = mesh->loops_for_write(); | MutableSpan<int> corner_verts = mesh->corner_verts_for_write(); | ||||
| MutableSpan<int> corner_edges = mesh->corner_edges_for_write(); | |||||
| threading::parallel_invoke( | threading::parallel_invoke( | ||||
| 1024 < segments * rings, | 1024 < segments * rings, | ||||
| [&]() { | [&]() { | ||||
| MutableSpan vert_normals{ | MutableSpan vert_normals{ | ||||
| reinterpret_cast<float3 *>(BKE_mesh_vertex_normals_for_write(mesh)), mesh->totvert}; | reinterpret_cast<float3 *>(BKE_mesh_vertex_normals_for_write(mesh)), mesh->totvert}; | ||||
| calculate_sphere_vertex_data(positions, vert_normals, radius, segments, rings); | calculate_sphere_vertex_data(positions, vert_normals, radius, segments, rings); | ||||
| BKE_mesh_vertex_normals_clear_dirty(mesh); | BKE_mesh_vertex_normals_clear_dirty(mesh); | ||||
| }, | }, | ||||
| [&]() { calculate_sphere_edge_indices(edges, segments, rings); }, | [&]() { calculate_sphere_edge_indices(edges, segments, rings); }, | ||||
| [&]() { calculate_sphere_faces(polys, segments); }, | [&]() { calculate_sphere_faces(polys, segments); }, | ||||
| [&]() { calculate_sphere_corners(loops, segments, rings); }, | [&]() { calculate_sphere_corners(corner_verts, corner_edges, segments, rings); }, | ||||
| [&]() { | [&]() { | ||||
| if (uv_map_id) { | if (uv_map_id) { | ||||
| calculate_sphere_uvs(mesh, segments, rings, uv_map_id); | calculate_sphere_uvs(mesh, segments, rings, uv_map_id); | ||||
| } | } | ||||
| }); | }); | ||||
| mesh->loose_edges_tag_none(); | mesh->loose_edges_tag_none(); | ||||
| ▲ Show 20 Lines • Show All 47 Lines • Show Last 20 Lines | |||||