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
8
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/* ---------------------------------------------------------------------- */
22
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 }
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
150
151/* ---------------------------------------------------------------------- */
154
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 int orig_coarse_face = mr.orig_index_face ? mr.orig_index_face[coarse_face] :
290 coarse_face;
291 const BMFace &face_orig = *BM_face_at_index(const_cast<BMesh *>(bm), orig_coarse_face);
292 if (skip_bm_face(face_orig, sync_selection)) {
293 continue;
294 }
295 }
296 else {
297 if (!mr.hide_poly.is_empty() && mr.hide_poly[coarse_face]) {
298 continue;
299 }
300 if (!sync_selection) {
301 if (mr.select_poly.is_empty() || !mr.select_poly[coarse_face]) {
302 continue;
303 }
304 }
305 }
306 const IndexRange subdiv_face(subdiv_quad * 4, 4);
307 for (const int subdiv_corner : subdiv_face) {
308 const int coarse_edge = subdiv_loop_edge_index[subdiv_corner];
309 if (coarse_edge == -1) {
310 continue;
311 }
312 const int subdiv_corner_next = bke::mesh::face_corner_next(subdiv_face, subdiv_corner);
313 GPU_indexbuf_add_line_verts(&builder, subdiv_corner, subdiv_corner_next);
314 }
315 }
316}
317
319 const DRWSubdivCache &subdiv_cache,
320 gpu::IndexBuf &ibo)
321{
322 const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
323
324 GPUIndexBufBuilder builder;
326 &builder, GPU_PRIM_LINES, subdiv_cache.num_subdiv_loops, subdiv_cache.num_subdiv_loops);
327 if (mr.extract_type == MR_EXTRACT_BMESH) {
328 extract_edituv_lines_subdiv_bm(mr, subdiv_cache, sync_selection, builder);
329 }
330 else {
331 extract_edituv_lines_subdiv_mesh(mr, subdiv_cache, sync_selection, builder);
332 }
333
334 GPU_indexbuf_build_in_place(&builder, &ibo);
335}
336
338
339/* ---------------------------------------------------------------------- */
342
344 const bool sync_selection,
345 GPUIndexBufBuilder &builder)
346{
347 const BMesh &bm = *mr.bm;
348 const BMFace *face;
349 BMIter f_iter;
350 BM_ITER_MESH (face, &f_iter, &const_cast<BMesh &>(bm), BM_FACES_OF_MESH) {
351 if (skip_bm_face(*face, sync_selection)) {
352 continue;
353 }
354 const BMLoop *loop = BM_FACE_FIRST_LOOP(face);
355 for ([[maybe_unused]] const int i : IndexRange(face->len)) {
357 loop = loop->next;
358 }
359 }
360}
361
363 const bool sync_selection,
364 GPUIndexBufBuilder &builder)
365{
366 const OffsetIndices faces = mr.faces;
367 const Span<int> corner_verts = mr.corner_verts;
368 const Span<int> orig_index_vert = mr.orig_index_vert ?
370 Span<int>();
371 for (const int face_index : faces.index_range()) {
372 const BMFace *face_orig = bm_original_face_get(mr, face_index);
373 if (!face_orig) {
374 continue;
375 }
376 if (skip_bm_face(*face_orig, sync_selection)) {
377 continue;
378 }
379 for (const int corner : faces[face_index]) {
380 const int vert = corner_verts[corner];
381 if (!orig_index_vert.is_empty() && orig_index_vert[vert] == ORIGINDEX_NONE) {
382 continue;
383 }
384 GPU_indexbuf_add_point_vert(&builder, corner);
385 }
386 }
387}
388
390{
391 const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
392
393 GPUIndexBufBuilder builder;
395 if (mr.extract_type == MR_EXTRACT_BMESH) {
396 extract_edituv_points_bm(mr, sync_selection, builder);
397 }
398 else {
399 extract_edituv_points_mesh(mr, sync_selection, builder);
400 }
401 GPU_indexbuf_build_in_place(&builder, &ibo);
402}
403
405 const DRWSubdivCache &subdiv_cache,
406 const bool sync_selection,
407 GPUIndexBufBuilder &builder)
408{
409 const BMesh &bm = *mr.bm;
410 const Span<int> subdiv_loop_vert_index = subdiv_cache.verts_orig_index->data<int>();
411 const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index,
412 subdiv_cache.num_subdiv_loops);
413
414 for (const int subdiv_quad : IndexRange(subdiv_cache.num_subdiv_quads)) {
415 const int coarse_face = subdiv_loop_face_index[subdiv_quad * 4];
416 const BMFace &face_orig = *BM_face_at_index(&const_cast<BMesh &>(bm), coarse_face);
417 if (skip_bm_face(face_orig, sync_selection)) {
418 continue;
419 }
420 for (const int subdiv_corner : IndexRange(subdiv_quad * 4, 4)) {
421 const int coarse_vert = subdiv_loop_vert_index[subdiv_corner];
422 if (coarse_vert == -1) {
423 continue;
424 }
425 GPU_indexbuf_add_point_vert(&builder, subdiv_corner);
426 }
427 }
428}
429
431 const DRWSubdivCache &subdiv_cache,
432 const bool sync_selection,
433 GPUIndexBufBuilder &builder)
434{
435 const Span<int> subdiv_loop_vert_index = subdiv_cache.verts_orig_index->data<int>();
436 const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index,
437 subdiv_cache.num_subdiv_loops);
438
439 for (const int subdiv_quad : IndexRange(subdiv_cache.num_subdiv_quads)) {
440 const int coarse_face = subdiv_loop_face_index[subdiv_quad * 4];
441 const BMFace *face_orig = bm_original_face_get(mr, coarse_face);
442 if (!face_orig) {
443 continue;
444 }
445 if (skip_bm_face(*face_orig, sync_selection)) {
446 continue;
447 }
448 for (const int subdiv_corner : IndexRange(subdiv_quad * 4, 4)) {
449 const int coarse_vert = subdiv_loop_vert_index[subdiv_corner];
450 if (coarse_vert == -1) {
451 continue;
452 }
453 GPU_indexbuf_add_point_vert(&builder, subdiv_corner);
454 }
455 }
456}
457
459 const DRWSubdivCache &subdiv_cache,
460 gpu::IndexBuf &ibo)
461{
462 const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
463
464 GPUIndexBufBuilder builder;
466 &builder, GPU_PRIM_POINTS, subdiv_cache.num_subdiv_loops, subdiv_cache.num_subdiv_loops);
467 if (mr.extract_type == MR_EXTRACT_BMESH) {
468 extract_edituv_points_subdiv_bm(mr, subdiv_cache, sync_selection, builder);
469 }
470 else {
471 extract_edituv_points_subdiv_mesh(mr, subdiv_cache, sync_selection, builder);
472 }
473 GPU_indexbuf_build_in_place(&builder, &ibo);
474}
475
477
478/* ---------------------------------------------------------------------- */
481
483 const bool sync_selection,
484 gpu::IndexBuf &ibo)
485{
486 const BMesh &bm = *mr.bm;
487 IndexMaskMemory memory;
488 const IndexMask visible = IndexMask::from_predicate(
489 IndexMask(bm.totface), GrainSize(4096), memory, [&](const int i) {
490 return !skip_bm_face(*BM_face_at_index(&const_cast<BMesh &>(bm), i), sync_selection);
491 });
492
493 GPUIndexBufBuilder builder;
494 GPU_indexbuf_init(&builder, GPU_PRIM_POINTS, visible.size(), bm.totface);
495 visible.to_indices(GPU_indexbuf_get_data(&builder).cast<int>());
496 GPU_indexbuf_build_in_place_ex(&builder, 0, bm.totface, false, &ibo);
497}
498
500 const bool sync_selection,
501 gpu::IndexBuf &ibo)
502{
503 const OffsetIndices faces = mr.faces;
504 IndexMaskMemory memory;
506 faces.index_range(), GrainSize(4096), memory, [&](const int i) {
507 const BMFace *face_orig = bm_original_face_get(mr, i);
508 if (!face_orig) {
509 return false;
510 }
511 if (skip_bm_face(*face_orig, sync_selection)) {
512 return false;
513 }
514 return true;
515 });
516 if (mr.use_subsurf_fdots) {
517 const BitSpan facedot_tags = mr.mesh->runtime->subsurf_face_dot_tags;
518 const Span<int> corner_verts = mr.corner_verts;
519 visible = IndexMask::from_predicate(visible, GrainSize(4096), memory, [&](const int i) {
520 const Span<int> face_verts = corner_verts.slice(faces[i]);
521 return std::any_of(face_verts.begin(), face_verts.end(), [&](const int vert) {
522 return facedot_tags[vert];
523 });
524 });
525 }
526
527 GPUIndexBufBuilder builder;
528 GPU_indexbuf_init(&builder, GPU_PRIM_POINTS, visible.size(), faces.size());
529 visible.to_indices(GPU_indexbuf_get_data(&builder).cast<int>());
530 GPU_indexbuf_build_in_place_ex(&builder, 0, faces.size(), false, &ibo);
531}
532
534{
535 const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
536 if (mr.extract_type == MR_EXTRACT_BMESH) {
537 extract_edituv_face_dots_bm(mr, sync_selection, ibo);
538 }
539 else {
540 extract_edituv_face_dots_mesh(mr, sync_selection, ibo);
541 }
542}
543
545
546} // 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
#define BM_FACE_FIRST_LOOP(p)
@ BM_ELEM_HIDDEN
@ BM_ELEM_SELECT
#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 bool is_empty() const
Definition BLI_span.hh:261
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)
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
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()
void to_indices(MutableSpan< T > r_indices) const
void foreach_index(Fn &&fn) const
Extraction of Mesh data into VBO to feed to GPU.
ccl_device_inline int4 cast(const float4 a)
Definition math_float4.h:29
static char faces[256]
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)
VecBase< int32_t, 3 > int3
blender::Array< std::array< BMLoop *, 3 > > looptris
struct BMLoop * next
MeshRuntimeHandle * runtime
const ToolSettings * toolsettings
VArraySpan< bool > select_poly
OffsetIndices< int > faces