Differential D15982 Diff 59259 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 58 Lines • ▼ Show 20 Lines | |||||
| const int triangles = segments * 2; | const int triangles = segments * 2; | ||||
| return quads + triangles; | return quads + triangles; | ||||
| } | } | ||||
| /** | /** | ||||
| * Also calculate vertex normals here, since the calculation is trivial, and it allows avoiding the | * Also calculate vertex normals here, since the calculation is trivial, and it allows avoiding the | ||||
| * calculation later, if it's necessary. The vertex normals are just the normalized positions. | * calculation later, if it's necessary. The vertex normals are just the normalized positions. | ||||
| */ | */ | ||||
| BLI_NOINLINE static void calculate_sphere_vertex_data(MutableSpan<MVert> verts, | BLI_NOINLINE static void calculate_sphere_vertex_data(MutableSpan<float3> positions, | ||||
| MutableSpan<float3> vert_normals, | MutableSpan<float3> vert_normals, | ||||
| const float radius, | const float radius, | ||||
| const int segments, | const int segments, | ||||
| const int rings) | const int rings) | ||||
| { | { | ||||
| const float delta_theta = M_PI / rings; | const float delta_theta = M_PI / rings; | ||||
| const float delta_phi = (2.0f * M_PI) / segments; | const float delta_phi = (2.0f * M_PI) / segments; | ||||
| Array<float, 64> segment_cosines(segments + 1); | Array<float, 64> segment_cosines(segments + 1); | ||||
| for (const int segment : IndexRange(1, segments)) { | for (const int segment : IndexRange(1, segments)) { | ||||
| const float phi = segment * delta_phi; | const float phi = segment * delta_phi; | ||||
| segment_cosines[segment] = std::cos(phi); | segment_cosines[segment] = std::cos(phi); | ||||
| } | } | ||||
| Array<float, 64> segment_sines(segments + 1); | Array<float, 64> segment_sines(segments + 1); | ||||
| for (const int segment : IndexRange(1, segments)) { | for (const int segment : IndexRange(1, segments)) { | ||||
| const float phi = segment * delta_phi; | const float phi = segment * delta_phi; | ||||
| segment_sines[segment] = std::sin(phi); | segment_sines[segment] = std::sin(phi); | ||||
| } | } | ||||
| copy_v3_v3(verts[0].co, float3(0.0f, 0.0f, radius)); | positions[0] = float3(0.0f, 0.0f, radius); | ||||
| vert_normals.first() = float3(0.0f, 0.0f, 1.0f); | vert_normals.first() = float3(0.0f, 0.0f, 1.0f); | ||||
| int vert_index = 1; | int vert_index = 1; | ||||
| for (const int ring : IndexRange(1, rings - 1)) { | for (const int ring : IndexRange(1, rings - 1)) { | ||||
| const float theta = ring * delta_theta; | const float theta = ring * delta_theta; | ||||
| const float sin_theta = std::sin(theta); | const float sin_theta = std::sin(theta); | ||||
| const float z = std::cos(theta); | const float z = std::cos(theta); | ||||
| for (const int segment : IndexRange(1, segments)) { | for (const int segment : IndexRange(1, segments)) { | ||||
| const float x = sin_theta * segment_cosines[segment]; | const float x = sin_theta * segment_cosines[segment]; | ||||
| const float y = sin_theta * segment_sines[segment]; | const float y = sin_theta * segment_sines[segment]; | ||||
| copy_v3_v3(verts[vert_index].co, float3(x, y, z) * radius); | positions[vert_index] = float3(x, y, z) * radius; | ||||
| vert_normals[vert_index] = float3(x, y, z); | vert_normals[vert_index] = float3(x, y, z); | ||||
| vert_index++; | vert_index++; | ||||
| } | } | ||||
| } | } | ||||
| copy_v3_v3(verts.last().co, float3(0.0f, 0.0f, -radius)); | positions.last() = float3(0.0f, 0.0f, -radius); | ||||
| vert_normals.last() = float3(0.0f, 0.0f, -1.0f); | vert_normals.last() = float3(0.0f, 0.0f, -1.0f); | ||||
| } | } | ||||
| BLI_NOINLINE static void calculate_sphere_edge_indices(MutableSpan<MEdge> edges, | BLI_NOINLINE static void calculate_sphere_edge_indices(MutableSpan<MEdge> edges, | ||||
| const int segments, | const int segments, | ||||
| const int rings) | const int rings) | ||||
| { | { | ||||
| int edge_index = 0; | int edge_index = 0; | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| const AttributeIDRef &uv_map_id) | const AttributeIDRef &uv_map_id) | ||||
| { | { | ||||
| Mesh *mesh = BKE_mesh_new_nomain(sphere_vert_total(segments, rings), | Mesh *mesh = BKE_mesh_new_nomain(sphere_vert_total(segments, rings), | ||||
| 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<MVert> verts = mesh->verts_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<MLoop> loops = mesh->loops_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(verts, 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(loops, 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); | ||||
| ▲ Show 20 Lines • Show All 52 Lines • Show Last 20 Lines | |||||