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( | static void calculate_uvs( | ||||
| Mesh *mesh, Span<MVert> verts, Span<MLoop> loops, const float size_x, const float size_y) | Mesh *mesh, Span<float3> positions, Span<MLoop> loops, const float size_x, const float size_y) | ||||
| { | { | ||||
| 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", ATTR_DOMAIN_CORNER); | "uv_map", 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(loops.index_range(), 1024, [&](IndexRange range) { | ||||
| for (const int i : range) { | for (const int i : range) { | ||||
| const float3 &co = verts[loops[i].v].co; | const float3 &co = positions[loops[i].v]; | ||||
| 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(); | ||||
| } | } | ||||
| Mesh *create_grid_mesh(const int verts_x, | Mesh *create_grid_mesh(const int verts_x, | ||||
| const int verts_y, | const int verts_y, | ||||
| const float size_x, | const float size_x, | ||||
| const float size_y) | const float size_y) | ||||
| { | { | ||||
| BLI_assert(verts_x > 0 && verts_y > 0); | BLI_assert(verts_x > 0 && verts_y > 0); | ||||
| const int edges_x = verts_x - 1; | const int edges_x = verts_x - 1; | ||||
| const int edges_y = verts_y - 1; | const int edges_y = verts_y - 1; | ||||
| 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<MVert> verts = mesh->verts_for_write(); | MutableSpan<float3> positions = mesh->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(); | ||||
| { | { | ||||
| 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) { | ||||
| const int y_offset = x * verts_y; | const int y_offset = x * verts_y; | ||||
| threading::parallel_for(IndexRange(verts_y), 512, [&](IndexRange y_range) { | threading::parallel_for(IndexRange(verts_y), 512, [&](IndexRange y_range) { | ||||
| for (const int y : y_range) { | for (const int y : y_range) { | ||||
| const int vert_index = y_offset + y; | const int vert_index = y_offset + y; | ||||
| verts[vert_index].co[0] = (x - x_shift) * dx; | positions[vert_index].x = (x - x_shift) * dx; | ||||
| verts[vert_index].co[1] = (y - y_shift) * dy; | positions[vert_index].y = (y - y_shift) * dy; | ||||
| verts[vert_index].co[2] = 0.0f; | positions[vert_index].z = 0.0f; | ||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| const int y_edges_start = 0; | const int y_edges_start = 0; | ||||
| const int x_edges_start = verts_x * edges_y; | const int x_edges_start = verts_x * edges_y; | ||||
| ▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | for (const int x : x_range) { | ||||
| loop_d.v = vert_index + 1; | loop_d.v = vert_index + 1; | ||||
| loop_d.e = y_edges_start + edges_y * x + y; | loop_d.e = y_edges_start + edges_y * x + y; | ||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| }); | }); | ||||
| if (mesh->totpoly != 0) { | if (mesh->totpoly != 0) { | ||||
| calculate_uvs(mesh, verts, loops, size_x, size_y); | calculate_uvs(mesh, positions, loops, size_x, size_y); | ||||
| } | } | ||||
| return mesh; | return mesh; | ||||
| } | } | ||||
| } // namespace blender::nodes | } // namespace blender::nodes | ||||
| namespace blender::nodes::node_geo_mesh_primitive_grid_cc { | namespace blender::nodes::node_geo_mesh_primitive_grid_cc { | ||||
| ▲ Show 20 Lines • Show All 56 Lines • Show Last 20 Lines | |||||