Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc
| Show All 10 Lines | |||||
| #include "UI_interface.h" | #include "UI_interface.h" | ||||
| #include "UI_resources.h" | #include "UI_resources.h" | ||||
| #include "node_geometry_util.hh" | #include "node_geometry_util.hh" | ||||
| namespace blender::nodes { | namespace blender::nodes { | ||||
| static void calculate_uvs(Mesh *mesh, | static void calculate_uvs(Mesh *mesh, | ||||
| Span<float3> positions, | const Span<float3> positions, | ||||
| Span<MLoop> loops, | const Span<int> corner_verts, | ||||
| const float size_x, | const float size_x, | ||||
| const float size_y, | const float size_y, | ||||
| const AttributeIDRef &uv_map_id) | const AttributeIDRef &uv_map_id) | ||||
| { | { | ||||
| MutableAttributeAccessor attributes = mesh->attributes_for_write(); | MutableAttributeAccessor attributes = mesh->attributes_for_write(); | ||||
| SpanAttributeWriter<float2> uv_attribute = attributes.lookup_or_add_for_write_only_span<float2>( | SpanAttributeWriter<float2> uv_attribute = attributes.lookup_or_add_for_write_only_span<float2>( | ||||
| uv_map_id, ATTR_DOMAIN_CORNER); | uv_map_id, ATTR_DOMAIN_CORNER); | ||||
| const float dx = (size_x == 0.0f) ? 0.0f : 1.0f / size_x; | const float dx = (size_x == 0.0f) ? 0.0f : 1.0f / size_x; | ||||
| const float dy = (size_y == 0.0f) ? 0.0f : 1.0f / size_y; | const float dy = (size_y == 0.0f) ? 0.0f : 1.0f / size_y; | ||||
| threading::parallel_for(loops.index_range(), 1024, [&](IndexRange range) { | threading::parallel_for(corner_verts.index_range(), 1024, [&](IndexRange range) { | ||||
| for (const int i : range) { | for (const int i : range) { | ||||
| const float3 &co = positions[loops[i].v]; | const float3 &co = positions[corner_verts[i]]; | ||||
| uv_attribute.span[i].x = (co.x + size_x * 0.5f) * dx; | uv_attribute.span[i].x = (co.x + size_x * 0.5f) * dx; | ||||
| uv_attribute.span[i].y = (co.y + size_y * 0.5f) * dy; | uv_attribute.span[i].y = (co.y + size_y * 0.5f) * dy; | ||||
| } | } | ||||
| }); | }); | ||||
| uv_attribute.finish(); | uv_attribute.finish(); | ||||
| } | } | ||||
| Show All 9 Lines | Mesh *create_grid_mesh(const int verts_x, | ||||
| Mesh *mesh = BKE_mesh_new_nomain(verts_x * verts_y, | Mesh *mesh = BKE_mesh_new_nomain(verts_x * verts_y, | ||||
| edges_x * verts_y + edges_y * verts_x, | edges_x * verts_y + edges_y * verts_x, | ||||
| 0, | 0, | ||||
| edges_x * edges_y * 4, | edges_x * edges_y * 4, | ||||
| edges_x * edges_y); | edges_x * edges_y); | ||||
| 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(); | |||||
| { | { | ||||
| const float dx = edges_x == 0 ? 0.0f : size_x / edges_x; | const float dx = edges_x == 0 ? 0.0f : size_x / edges_x; | ||||
| const float dy = edges_y == 0 ? 0.0f : size_y / edges_y; | const float dy = edges_y == 0 ? 0.0f : size_y / edges_y; | ||||
| const float x_shift = edges_x / 2.0f; | const float x_shift = edges_x / 2.0f; | ||||
| const float y_shift = edges_y / 2.0f; | const float y_shift = edges_y / 2.0f; | ||||
| threading::parallel_for(IndexRange(verts_x), 512, [&](IndexRange x_range) { | threading::parallel_for(IndexRange(verts_x), 512, [&](IndexRange x_range) { | ||||
| for (const int x : x_range) { | for (const int x : x_range) { | ||||
| ▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | for (const int x : x_range) { | ||||
| for (const int y : y_range) { | for (const int y : y_range) { | ||||
| const int poly_index = y_offset + y; | const int poly_index = y_offset + y; | ||||
| const int loop_index = poly_index * 4; | const int loop_index = poly_index * 4; | ||||
| MPoly &poly = polys[poly_index]; | MPoly &poly = polys[poly_index]; | ||||
| poly.loopstart = loop_index; | poly.loopstart = loop_index; | ||||
| poly.totloop = 4; | poly.totloop = 4; | ||||
| const int vert_index = x * verts_y + y; | const int vert_index = x * verts_y + y; | ||||
| MLoop &loop_a = loops[loop_index]; | corner_verts[loop_index] = vert_index; | ||||
| loop_a.v = vert_index; | corner_edges[loop_index] = x_edges_start + edges_x * y + x; | ||||
| loop_a.e = x_edges_start + edges_x * y + x; | |||||
| MLoop &loop_b = loops[loop_index + 1]; | corner_verts[loop_index + 1] = vert_index + verts_y; | ||||
| loop_b.v = vert_index + verts_y; | corner_edges[loop_index + 1] = y_edges_start + edges_y * (x + 1) + y; | ||||
| loop_b.e = y_edges_start + edges_y * (x + 1) + y; | |||||
| MLoop &loop_c = loops[loop_index + 2]; | corner_verts[loop_index + 2] = vert_index + verts_y + 1; | ||||
| loop_c.v = vert_index + verts_y + 1; | corner_edges[loop_index + 2] = x_edges_start + edges_x * (y + 1) + x; | ||||
| loop_c.e = x_edges_start + edges_x * (y + 1) + x; | |||||
| MLoop &loop_d = loops[loop_index + 3]; | corner_verts[loop_index + 3] = vert_index + 1; | ||||
| loop_d.v = vert_index + 1; | corner_edges[loop_index + 3] = y_edges_start + edges_y * x + y; | ||||
| loop_d.e = y_edges_start + edges_y * x + y; | |||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| }); | }); | ||||
| if (uv_map_id && mesh->totpoly != 0) { | if (uv_map_id && mesh->totpoly != 0) { | ||||
| calculate_uvs(mesh, positions, loops, size_x, size_y, uv_map_id); | calculate_uvs(mesh, positions, corner_verts, size_x, size_y, uv_map_id); | ||||
| } | } | ||||
| mesh->loose_edges_tag_none(); | mesh->loose_edges_tag_none(); | ||||
| return mesh; | return mesh; | ||||
| } | } | ||||
| } // namespace blender::nodes | } // namespace blender::nodes | ||||
| ▲ Show 20 Lines • Show All 68 Lines • Show Last 20 Lines | |||||