44 const std::optional<StringRef> &uv_map_id)
47 const int edges_x = verts_x - 1;
48 const int edges_y = verts_y - 1;
50 edges_x * verts_y + edges_y * verts_x,
52 edges_x * edges_y * 4);
57 bke::mesh_smooth_set(*mesh,
false);
59 offset_indices::fill_constant_group_size(4, 0, mesh->face_offsets_for_write());
62 const float dx = edges_x == 0 ? 0.0f : size_x / edges_x;
63 const float dy = edges_y == 0 ? 0.0f : size_y / edges_y;
64 const float x_shift = edges_x / 2.0f;
65 const float y_shift = edges_y / 2.0f;
66 threading::memory_bandwidth_bound_task(positions.size_in_bytes(), [&]() {
67 threading::parallel_for(IndexRange(verts_x), 512, [&](IndexRange x_range) {
68 for (const int x : x_range) {
69 const int y_offset = x * verts_y;
70 threading::parallel_for(IndexRange(verts_y), 512, [&](IndexRange y_range) {
71 for (const int y : y_range) {
72 const int vert_index = y_offset + y;
73 positions[vert_index].x = (x - x_shift) * dx;
74 positions[vert_index].y = (y - y_shift) * dy;
75 positions[vert_index].z = 0.0f;
83 const int y_edges_start = 0;
84 const int x_edges_start = verts_x * edges_y;
87 threading::memory_bandwidth_bound_task(edges.size_in_bytes(), [&]() {
88 threading::parallel_for(IndexRange(verts_x), 512, [&](IndexRange x_range) {
89 for (const int x : x_range) {
90 const int y_vert_offset = x * verts_y;
91 const int y_edge_offset = y_edges_start + x * edges_y;
92 threading::parallel_for(IndexRange(edges_y), 512, [&](IndexRange y_range) {
93 for (const int y : y_range) {
94 const int vert_index = y_vert_offset + y;
95 edges[y_edge_offset + y] = int2(vert_index, vert_index + 1);
103 threading::memory_bandwidth_bound_task(edges.size_in_bytes(), [&]() {
104 threading::parallel_for(IndexRange(verts_y), 512, [&](IndexRange y_range) {
105 for (const int y : y_range) {
106 const int x_edge_offset = x_edges_start + y * edges_x;
107 threading::parallel_for(IndexRange(edges_x), 512, [&](IndexRange x_range) {
108 for (const int x : x_range) {
109 const int vert_index = x * verts_y + y;
110 edges[x_edge_offset + x] = int2(vert_index, vert_index + verts_y);
117 threading::memory_bandwidth_bound_task(
118 corner_edges.size_in_bytes() + corner_verts.size_in_bytes(), [&]() {
119 threading::parallel_for(IndexRange(edges_x), 512, [&](IndexRange x_range) {
120 for (const int x : x_range) {
121 const int y_offset = x * edges_y;
122 threading::parallel_for(IndexRange(edges_y), 512, [&](IndexRange y_range) {
123 for (const int y : y_range) {
124 const int face_index = y_offset + y;
125 const int loop_index = face_index * 4;
126 const int vert_index = x * verts_y + y;
128 corner_verts[loop_index] = vert_index;
129 corner_edges[loop_index] = x_edges_start + edges_x * y + x;
131 corner_verts[loop_index + 1] = vert_index + verts_y;
132 corner_edges[loop_index + 1] = y_edges_start + edges_y * (x + 1) + y;
134 corner_verts[loop_index + 2] = vert_index + verts_y + 1;
135 corner_edges[loop_index + 2] = x_edges_start + edges_x * (y + 1) + x;
137 corner_verts[loop_index + 3] = vert_index + 1;
138 corner_edges[loop_index + 3] = y_edges_start + edges_y * x + y;
145 if (uv_map_id && mesh->faces_num != 0) {
146 calculate_uvs(mesh, positions, corner_verts, size_x, size_y, *uv_map_id);
149 if (verts_x > 1 || verts_y > 1) {
150 mesh->tag_loose_verts_none();
152 if (verts_x > 1 && verts_y > 1) {
153 mesh->tag_loose_edges_none();
155 mesh->tag_overlapping_none();