Blender V4.3
extract_mesh_ibo_edituv.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "BKE_editmesh.hh"
10
11#include "extract_mesh.hh"
12
13#include "GPU_index_buffer.hh"
14
15#include "draw_subdivision.hh"
16
17namespace blender::draw {
18
19/* ---------------------------------------------------------------------- */
23inline bool skip_bm_face(const BMFace &face, const bool sync_selection)
24{
26 return true;
27 }
28 if (!sync_selection) {
30 return true;
31 }
32 }
33 return false;
34}
35
37 const bool sync_selection,
38 GPUIndexBufBuilder &builder)
39{
41 for (const int i : looptris.index_range()) {
42 const std::array<BMLoop *, 3> &tri = looptris[i];
43 if (skip_bm_face(*tri[0]->f, sync_selection)) {
44 continue;
45 }
47 &builder, BM_elem_index_get(tri[0]), BM_elem_index_get(tri[1]), BM_elem_index_get(tri[2]));
48 }
49}
50
52 const bool sync_selection,
53 GPUIndexBufBuilder &builder)
54{
55 const OffsetIndices faces = mr.faces;
56 const Span<int3> corner_tris = mr.mesh->corner_tris();
57 for (const int face : faces.index_range()) {
58 const BMFace *face_orig = bm_original_face_get(mr, face);
59 if (!face_orig) {
60 continue;
61 }
62 if (skip_bm_face(*face_orig, sync_selection)) {
63 continue;
64 }
65 const IndexRange tris = bke::mesh::face_triangles_range(faces, face);
66 for (const int3 &tri : corner_tris.slice(tris)) {
67 GPU_indexbuf_add_tri_verts(&builder, tri[0], tri[1], tri[2]);
68 }
69 }
70}
71
73{
74 const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
75
76 GPUIndexBufBuilder builder;
79 extract_edituv_tris_bm(mr, sync_selection, builder);
80 }
81 else {
82 extract_edituv_tris_mesh(mr, sync_selection, builder);
83 }
84
85 GPU_indexbuf_build_in_place(&builder, &ibo);
86}
87
89 const DRWSubdivCache &subdiv_cache,
90 const bool sync_selection,
91 GPUIndexBufBuilder &builder)
92{
93 const BMesh &bm = *mr.bm;
94 const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index,
95 subdiv_cache.num_subdiv_loops);
96 for (const int subdiv_quad_index : IndexRange(subdiv_cache.num_subdiv_quads)) {
97 const uint corner_start = subdiv_quad_index * 4;
98 const int coarse_face = subdiv_loop_face_index[corner_start];
99 const BMFace &face_orig = *BM_face_at_index(&const_cast<BMesh &>(bm), coarse_face);
100 if (skip_bm_face(face_orig, sync_selection)) {
101 continue;
102 }
103 GPU_indexbuf_add_tri_verts(&builder, corner_start, corner_start + 1, corner_start + 2);
104 GPU_indexbuf_add_tri_verts(&builder, corner_start, corner_start + 2, corner_start + 3);
105 }
106}
107
109 const DRWSubdivCache &subdiv_cache,
110 const bool sync_selection,
111 GPUIndexBufBuilder &builder)
112{
113 const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index,
114 subdiv_cache.num_subdiv_loops);
115 for (const int subdiv_quad_index : IndexRange(subdiv_cache.num_subdiv_quads)) {
116 const uint corner_start = subdiv_quad_index * 4;
117 const int coarse_face = subdiv_loop_face_index[corner_start];
118 const BMFace *face_orig = bm_original_face_get(mr, coarse_face);
119 if (!face_orig) {
120 continue;
121 }
122 if (skip_bm_face(*face_orig, sync_selection)) {
123 continue;
124 }
125 GPU_indexbuf_add_tri_verts(&builder, corner_start, corner_start + 1, corner_start + 2);
126 GPU_indexbuf_add_tri_verts(&builder, corner_start, corner_start + 2, corner_start + 3);
127 }
128}
129
131 const DRWSubdivCache &subdiv_cache,
132 gpu::IndexBuf &ibo)
133{
134 const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
135
136 GPUIndexBufBuilder builder;
138 &builder, GPU_PRIM_TRIS, subdiv_cache.num_subdiv_triangles, subdiv_cache.num_subdiv_loops);
139 if (mr.extract_type == MR_EXTRACT_BMESH) {
140 extract_edituv_tris_subdiv_bm(mr, subdiv_cache, sync_selection, builder);
141 }
142 else {
143 extract_edituv_tris_subdiv_mesh(mr, subdiv_cache, sync_selection, builder);
144 }
145
146 GPU_indexbuf_build_in_place(&builder, &ibo);
147}
148
151/* ---------------------------------------------------------------------- */
156 const bool sync_selection,
157 GPUIndexBufBuilder &builder)
158{
159 const BMesh &bm = *mr.bm;
160 const BMFace *face;
161 BMIter f_iter;
162 BM_ITER_MESH (face, &f_iter, &const_cast<BMesh &>(bm), BM_FACES_OF_MESH) {
163 if (skip_bm_face(*face, sync_selection)) {
164 continue;
165 }
166 const BMLoop *loop = BM_FACE_FIRST_LOOP(face);
167 for ([[maybe_unused]] const int i : IndexRange(face->len)) {
169 &builder, BM_elem_index_get(loop), BM_elem_index_get(loop->next));
170 loop = loop->next;
171 }
172 }
173}
174
176 const bool sync_selection,
177 GPUIndexBufBuilder &builder)
178{
179 const OffsetIndices faces = mr.faces;
180 const Span<int> corner_edges = mr.corner_edges;
181 const Span<int> orig_index_edge = mr.orig_index_edge ?
183 Span<int>();
184 if (mr.bm) {
185 for (const int face_index : faces.index_range()) {
186 const IndexRange face = faces[face_index];
187 const BMFace *face_orig = bm_original_face_get(mr, face_index);
188 if (!face_orig) {
189 continue;
190 }
191 if (skip_bm_face(*face_orig, sync_selection)) {
192 continue;
193 }
194 for (const int corner : face) {
195 const int edge = corner_edges[corner];
196 if (!orig_index_edge.is_empty() && orig_index_edge[edge] == ORIGINDEX_NONE) {
197 continue;
198 }
199 const int corner_next = bke::mesh::face_corner_next(face, corner);
200 GPU_indexbuf_add_line_verts(&builder, corner, corner_next);
201 }
202 }
203 }
204 else {
205 IndexMaskMemory memory;
206 IndexMask visible = faces.index_range();
207 if (!mr.hide_poly.is_empty()) {
208 visible = IndexMask::from_bools_inverse(visible, mr.hide_poly, memory);
209 }
210 if (!sync_selection) {
211 if (mr.select_poly.is_empty()) {
212 visible = {};
213 }
214 else {
215 visible = IndexMask::from_bools(visible, mr.select_poly, memory);
216 }
217 }
218 visible.foreach_index([&](const int face_index) {
219 const IndexRange face = faces[face_index];
220 for (const int corner : face) {
221 const int edge = corner_edges[corner];
222 if (!orig_index_edge.is_empty() && orig_index_edge[edge] == ORIGINDEX_NONE) {
223 continue;
224 }
225 const int corner_next = bke::mesh::face_corner_next(face, corner);
226 GPU_indexbuf_add_line_verts(&builder, corner, corner_next);
227 }
228 });
229 }
230}
231
233{
234 const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
235
236 GPUIndexBufBuilder builder;
238 if (mr.extract_type == MR_EXTRACT_BMESH) {
239 extract_edituv_lines_bm(mr, sync_selection, builder);
240 }
241 else {
242 extract_edituv_lines_mesh(mr, sync_selection, builder);
243 }
244
245 GPU_indexbuf_build_in_place(&builder, &ibo);
246}
247
249 const DRWSubdivCache &subdiv_cache,
250 const bool sync_selection,
251 GPUIndexBufBuilder &builder)
252{
253 const BMesh &bm = *mr.bm;
254 const Span<int> subdiv_loop_edge_index = subdiv_cache.edges_orig_index->data<int>();
255 const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index,
256 subdiv_cache.num_subdiv_loops);
257
258 for (const int subdiv_quad : IndexRange(subdiv_cache.num_subdiv_quads)) {
259 const int coarse_face = subdiv_loop_face_index[subdiv_quad * 4];
260 const BMFace &face_orig = *BM_face_at_index(&const_cast<BMesh &>(bm), coarse_face);
261 if (skip_bm_face(face_orig, sync_selection)) {
262 continue;
263 }
264 const IndexRange subdiv_face(subdiv_quad * 4, 4);
265 for (const int subdiv_corner : subdiv_face) {
266 const int coarse_edge = subdiv_loop_edge_index[subdiv_corner];
267 if (coarse_edge == -1) {
268 continue;
269 }
270 const int subdiv_corner_next = bke::mesh::face_corner_next(subdiv_face, subdiv_corner);
271 GPU_indexbuf_add_line_verts(&builder, subdiv_corner, subdiv_corner_next);
272 }
273 }
274}
275
277 const DRWSubdivCache &subdiv_cache,
278 const bool sync_selection,
279 GPUIndexBufBuilder &builder)
280{
281 /* NOTE: #subdiv_loop_edge_index already has the #CD_ORIGINDEX layer baked in. */
282 const Span<int> subdiv_loop_edge_index = subdiv_cache.edges_orig_index->data<int>();
283 const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index,
284 subdiv_cache.num_subdiv_loops);
285 /* TODO: Replace subdiv quad iteration with coarse face iteration. */
286 for (const int subdiv_quad : IndexRange(subdiv_cache.num_subdiv_quads)) {
287 const int coarse_face = subdiv_loop_face_index[subdiv_quad * 4];
288 if (const BMesh *bm = mr.bm) {
289 const BMFace &face_orig = *BM_face_at_index(const_cast<BMesh *>(bm), coarse_face);
290 if (skip_bm_face(face_orig, sync_selection)) {
291 continue;
292 }
293 }
294 else {
295 if (!mr.hide_poly.is_empty() && mr.hide_poly[coarse_face]) {
296 continue;
297 }
298 if (!sync_selection) {
299 if (mr.select_poly.is_empty() || !mr.select_poly[coarse_face]) {
300 continue;
301 }
302 }
303 }
304 const IndexRange subdiv_face(subdiv_quad * 4, 4);
305 for (const int subdiv_corner : subdiv_face) {
306 const int coarse_edge = subdiv_loop_edge_index[subdiv_corner];
307 if (coarse_edge == -1) {
308 continue;
309 }
310 const int subdiv_corner_next = bke::mesh::face_corner_next(subdiv_face, subdiv_corner);
311 GPU_indexbuf_add_line_verts(&builder, subdiv_corner, subdiv_corner_next);
312 }
313 }
314}
315
317 const DRWSubdivCache &subdiv_cache,
318 gpu::IndexBuf &ibo)
319{
320 const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
321
322 GPUIndexBufBuilder builder;
324 &builder, GPU_PRIM_LINES, subdiv_cache.num_subdiv_loops, subdiv_cache.num_subdiv_loops);
325 if (mr.extract_type == MR_EXTRACT_BMESH) {
326 extract_edituv_lines_subdiv_bm(mr, subdiv_cache, sync_selection, builder);
327 }
328 else {
329 extract_edituv_lines_subdiv_mesh(mr, subdiv_cache, sync_selection, builder);
330 }
331
332 GPU_indexbuf_build_in_place(&builder, &ibo);
333}
334
337/* ---------------------------------------------------------------------- */
342 const bool sync_selection,
343 GPUIndexBufBuilder &builder)
344{
345 const BMesh &bm = *mr.bm;
346 const BMFace *face;
347 BMIter f_iter;
348 BM_ITER_MESH (face, &f_iter, &const_cast<BMesh &>(bm), BM_FACES_OF_MESH) {
349 if (skip_bm_face(*face, sync_selection)) {
350 continue;
351 }
352 const BMLoop *loop = BM_FACE_FIRST_LOOP(face);
353 for ([[maybe_unused]] const int i : IndexRange(face->len)) {
355 loop = loop->next;
356 }
357 }
358}
359
361 const bool sync_selection,
362 GPUIndexBufBuilder &builder)
363{
364 const OffsetIndices faces = mr.faces;
365 const Span<int> corner_verts = mr.corner_verts;
366 const Span<int> orig_index_vert = mr.orig_index_vert ?
368 Span<int>();
369 for (const int face_index : faces.index_range()) {
370 const BMFace *face_orig = bm_original_face_get(mr, face_index);
371 if (!face_orig) {
372 continue;
373 }
374 if (skip_bm_face(*face_orig, sync_selection)) {
375 continue;
376 }
377 for (const int corner : faces[face_index]) {
378 const int vert = corner_verts[corner];
379 if (!orig_index_vert.is_empty() && orig_index_vert[vert] == ORIGINDEX_NONE) {
380 continue;
381 }
382 GPU_indexbuf_add_point_vert(&builder, corner);
383 }
384 }
385}
386
388{
389 const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
390
391 GPUIndexBufBuilder builder;
393 if (mr.extract_type == MR_EXTRACT_BMESH) {
394 extract_edituv_points_bm(mr, sync_selection, builder);
395 }
396 else {
397 extract_edituv_points_mesh(mr, sync_selection, builder);
398 }
399 GPU_indexbuf_build_in_place(&builder, &ibo);
400}
401
403 const DRWSubdivCache &subdiv_cache,
404 const bool sync_selection,
405 GPUIndexBufBuilder &builder)
406{
407 const BMesh &bm = *mr.bm;
408 const Span<int> subdiv_loop_vert_index = subdiv_cache.verts_orig_index->data<int>();
409 const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index,
410 subdiv_cache.num_subdiv_loops);
411
412 for (const int subdiv_quad : IndexRange(subdiv_cache.num_subdiv_quads)) {
413 const int coarse_face = subdiv_loop_face_index[subdiv_quad * 4];
414 const BMFace &face_orig = *BM_face_at_index(&const_cast<BMesh &>(bm), coarse_face);
415 if (skip_bm_face(face_orig, sync_selection)) {
416 continue;
417 }
418 for (const int subdiv_corner : IndexRange(subdiv_quad * 4, 4)) {
419 const int coarse_vert = subdiv_loop_vert_index[subdiv_corner];
420 if (coarse_vert == -1) {
421 continue;
422 }
423 GPU_indexbuf_add_point_vert(&builder, subdiv_corner);
424 }
425 }
426}
427
429 const DRWSubdivCache &subdiv_cache,
430 const bool sync_selection,
431 GPUIndexBufBuilder &builder)
432{
433 const Span<int> subdiv_loop_vert_index = subdiv_cache.verts_orig_index->data<int>();
434 const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index,
435 subdiv_cache.num_subdiv_loops);
436
437 for (const int subdiv_quad : IndexRange(subdiv_cache.num_subdiv_quads)) {
438 const int coarse_face = subdiv_loop_face_index[subdiv_quad * 4];
439 const BMFace *face_orig = bm_original_face_get(mr, coarse_face);
440 if (!face_orig) {
441 continue;
442 }
443 if (skip_bm_face(*face_orig, sync_selection)) {
444 continue;
445 }
446 for (const int subdiv_corner : IndexRange(subdiv_quad * 4, 4)) {
447 const int coarse_vert = subdiv_loop_vert_index[subdiv_corner];
448 if (coarse_vert == -1) {
449 continue;
450 }
451 GPU_indexbuf_add_point_vert(&builder, subdiv_corner);
452 }
453 }
454}
455
457 const DRWSubdivCache &subdiv_cache,
458 gpu::IndexBuf &ibo)
459{
460 const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
461
462 GPUIndexBufBuilder builder;
464 &builder, GPU_PRIM_POINTS, subdiv_cache.num_subdiv_loops, subdiv_cache.num_subdiv_loops);
465 if (mr.extract_type == MR_EXTRACT_BMESH) {
466 extract_edituv_points_subdiv_bm(mr, subdiv_cache, sync_selection, builder);
467 }
468 else {
469 extract_edituv_points_subdiv_mesh(mr, subdiv_cache, sync_selection, builder);
470 }
471 GPU_indexbuf_build_in_place(&builder, &ibo);
472}
473
476/* ---------------------------------------------------------------------- */
481 const bool sync_selection,
482 gpu::IndexBuf &ibo)
483{
484 const BMesh &bm = *mr.bm;
485 IndexMaskMemory memory;
486 const IndexMask visible = IndexMask::from_predicate(
487 IndexMask(bm.totface), GrainSize(4096), memory, [&](const int i) {
488 return !skip_bm_face(*BM_face_at_index(&const_cast<BMesh &>(bm), i), sync_selection);
489 });
490
491 GPUIndexBufBuilder builder;
492 GPU_indexbuf_init(&builder, GPU_PRIM_POINTS, visible.size(), bm.totface);
493 visible.to_indices(GPU_indexbuf_get_data(&builder).cast<int>());
494 GPU_indexbuf_build_in_place_ex(&builder, 0, bm.totface, false, &ibo);
495}
496
498 const bool sync_selection,
499 gpu::IndexBuf &ibo)
500{
501 const OffsetIndices faces = mr.faces;
502 IndexMaskMemory memory;
504 faces.index_range(), GrainSize(4096), memory, [&](const int i) {
505 const BMFace *face_orig = bm_original_face_get(mr, i);
506 if (!face_orig) {
507 return false;
508 }
509 if (skip_bm_face(*face_orig, sync_selection)) {
510 return false;
511 }
512 return true;
513 });
514 if (mr.use_subsurf_fdots) {
515 const BitSpan facedot_tags = mr.mesh->runtime->subsurf_face_dot_tags;
516 const Span<int> corner_verts = mr.corner_verts;
517 visible = IndexMask::from_predicate(visible, GrainSize(4096), memory, [&](const int i) {
518 const Span<int> face_verts = corner_verts.slice(faces[i]);
519 return std::any_of(face_verts.begin(), face_verts.end(), [&](const int vert) {
520 return facedot_tags[vert];
521 });
522 });
523 }
524
525 GPUIndexBufBuilder builder;
526 GPU_indexbuf_init(&builder, GPU_PRIM_POINTS, visible.size(), faces.size());
527 visible.to_indices(GPU_indexbuf_get_data(&builder).cast<int>());
528 GPU_indexbuf_build_in_place_ex(&builder, 0, faces.size(), false, &ibo);
529}
530
532{
533 const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
534 if (mr.extract_type == MR_EXTRACT_BMESH) {
535 extract_edituv_face_dots_bm(mr, sync_selection, ibo);
536 }
537 else {
538 extract_edituv_face_dots_mesh(mr, sync_selection, ibo);
539 }
540}
541
544} // namespace blender::draw
#define ORIGINDEX_NONE
unsigned int uint
@ UV_SYNC_SELECTION
void GPU_indexbuf_build_in_place_ex(GPUIndexBufBuilder *builder, uint index_min, uint index_max, bool uses_restart_indices, blender::gpu::IndexBuf *elem)
blender::MutableSpan< uint32_t > GPU_indexbuf_get_data(GPUIndexBufBuilder *)
void GPU_indexbuf_init(GPUIndexBufBuilder *, GPUPrimType, uint prim_len, uint vertex_len)
void GPU_indexbuf_add_point_vert(GPUIndexBufBuilder *, uint v)
void GPU_indexbuf_add_line_verts(GPUIndexBufBuilder *, uint v1, uint v2)
void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *, blender::gpu::IndexBuf *)
void GPU_indexbuf_add_tri_verts(GPUIndexBufBuilder *, uint v1, uint v2, uint v3)
@ GPU_PRIM_LINES
@ GPU_PRIM_POINTS
@ GPU_PRIM_TRIS
@ BM_ELEM_HIDDEN
@ BM_ELEM_SELECT
#define BM_FACE_FIRST_LOOP(p)
#define BM_elem_index_get(ele)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_test_bool(ele, hflag)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_FACES_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
BLI_INLINE BMFace * BM_face_at_index(BMesh *bm, const int index)
constexpr Span slice(int64_t start, int64_t size) const
Definition BLI_span.hh:138
constexpr const T * end() const
Definition BLI_span.hh:225
constexpr IndexRange index_range() const
Definition BLI_span.hh:402
constexpr const T * begin() const
Definition BLI_span.hh:221
constexpr bool is_empty() const
Definition BLI_span.hh:261
MutableSpan< T > data()
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
static IndexMask from_bools_inverse(const IndexMask &universe, Span< bool > bools, IndexMaskMemory &memory)
void to_indices(MutableSpan< T > r_indices) const
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
void foreach_index(Fn &&fn) const
Extraction of Mesh data into VBO to feed to GPU.
IndexRange face_triangles_range(OffsetIndices< int > faces, int face_i)
Definition BKE_mesh.hh:296
int face_corner_next(const IndexRange face, const int corner)
Definition BKE_mesh.hh:252
BLI_INLINE BMFace * bm_original_face_get(const MeshRenderData &mr, int idx)
void extract_edituv_lines(const MeshRenderData &mr, gpu::IndexBuf &ibo)
void extract_edituv_lines_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, gpu::IndexBuf &ibo)
static void extract_edituv_tris_subdiv_bm(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const bool sync_selection, GPUIndexBufBuilder &builder)
static void extract_edituv_tris_mesh(const MeshRenderData &mr, const bool sync_selection, GPUIndexBufBuilder &builder)
static void extract_edituv_lines_mesh(const MeshRenderData &mr, const bool sync_selection, GPUIndexBufBuilder &builder)
static void extract_edituv_face_dots_bm(const MeshRenderData &mr, const bool sync_selection, gpu::IndexBuf &ibo)
static void extract_edituv_tris_bm(const MeshRenderData &mr, const bool sync_selection, GPUIndexBufBuilder &builder)
static void extract_edituv_points_subdiv_bm(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const bool sync_selection, GPUIndexBufBuilder &builder)
void extract_edituv_tris(const MeshRenderData &mr, gpu::IndexBuf &ibo)
static void extract_edituv_lines_bm(const MeshRenderData &mr, const bool sync_selection, GPUIndexBufBuilder &builder)
static void extract_edituv_tris_subdiv_mesh(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const bool sync_selection, GPUIndexBufBuilder &builder)
void extract_edituv_points_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, gpu::IndexBuf &ibo)
static void extract_edituv_lines_subdiv_bm(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const bool sync_selection, GPUIndexBufBuilder &builder)
static void extract_edituv_points_subdiv_mesh(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const bool sync_selection, GPUIndexBufBuilder &builder)
static void extract_edituv_points_mesh(const MeshRenderData &mr, const bool sync_selection, GPUIndexBufBuilder &builder)
static void extract_edituv_points_bm(const MeshRenderData &mr, const bool sync_selection, GPUIndexBufBuilder &builder)
void extract_edituv_tris_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, gpu::IndexBuf &ibo)
static void extract_edituv_lines_subdiv_mesh(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const bool sync_selection, GPUIndexBufBuilder &builder)
void extract_edituv_face_dots(const MeshRenderData &mr, gpu::IndexBuf &ibo)
static void extract_edituv_face_dots_mesh(const MeshRenderData &mr, const bool sync_selection, gpu::IndexBuf &ibo)
bool skip_bm_face(const BMFace &face, const bool sync_selection)
void extract_edituv_points(const MeshRenderData &mr, gpu::IndexBuf &ibo)
blender::Array< std::array< BMLoop *, 3 > > looptris
struct BMLoop * next
int totface
MeshRuntimeHandle * runtime
const ToolSettings * toolsettings
VArraySpan< bool > select_poly
OffsetIndices< int > faces