Blender V4.5
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 return gpu::IndexBufPtr(GPU_indexbuf_build(&builder));
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{
133 const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
134
135 GPUIndexBufBuilder builder;
137 &builder, GPU_PRIM_TRIS, subdiv_cache.num_subdiv_triangles, subdiv_cache.num_subdiv_loops);
139 extract_edituv_tris_subdiv_bm(mr, subdiv_cache, sync_selection, builder);
140 }
141 else {
142 extract_edituv_tris_subdiv_mesh(mr, subdiv_cache, sync_selection, builder);
143 }
144
145 return gpu::IndexBufPtr(GPU_indexbuf_build(&builder));
146}
147
149
150/* ---------------------------------------------------------------------- */
153
155 const bool sync_selection)
156{
157 GPUIndexBufBuilder builder;
158 /* The entire data array might not be used. It might be beneficial to count the number of visible
159 * edges first, especially if that allows parallelizing filling the data array. */
162 int line_index = 0;
163
164 const BMFace *face;
165 BMIter f_iter;
166 BM_ITER_MESH (face, &f_iter, mr.bm, BM_FACES_OF_MESH) {
167 if (skip_bm_face(*face, sync_selection)) {
168 continue;
169 }
170 const BMLoop *loop = BM_FACE_FIRST_LOOP(face);
171 for ([[maybe_unused]] const int i : IndexRange(face->len)) {
172 data[line_index++] = uint2(BM_elem_index_get(loop), BM_elem_index_get(loop->next));
173 loop = loop->next;
174 }
175 }
176
177 return gpu::IndexBufPtr(GPU_indexbuf_build_ex(&builder, 0, mr.corners_num, false));
178}
179
181 const bool sync_selection)
182{
183 const OffsetIndices faces = mr.faces;
184 const Span<int> corner_edges = mr.corner_edges;
185 const Span<int> orig_index_edge = mr.orig_index_edge ?
187 Span<int>();
188
189 GPUIndexBufBuilder builder;
192 int line_index = 0;
193
194 if (mr.bm) {
195 for (const int face_index : faces.index_range()) {
196 const IndexRange face = faces[face_index];
197 const BMFace *face_orig = bm_original_face_get(mr, face_index);
198 if (!face_orig) {
199 continue;
200 }
201 if (skip_bm_face(*face_orig, sync_selection)) {
202 continue;
203 }
204 for (const int corner : face) {
205 const int edge = corner_edges[corner];
206 if (!orig_index_edge.is_empty() && orig_index_edge[edge] == ORIGINDEX_NONE) {
207 continue;
208 }
209 data[line_index++] = edge_from_corners(face, corner);
210 }
211 }
212 }
213 else {
214 IndexMaskMemory memory;
215 IndexMask visible = faces.index_range();
216 if (!mr.hide_poly.is_empty()) {
217 visible = IndexMask::from_bools_inverse(visible, mr.hide_poly, memory);
218 }
219 if (!sync_selection) {
220 if (mr.select_poly.is_empty()) {
221 visible = {};
222 }
223 else {
224 visible = IndexMask::from_bools(visible, mr.select_poly, memory);
225 }
226 }
227 visible.foreach_index([&](const int face_index) {
228 const IndexRange face = faces[face_index];
229 for (const int corner : face) {
230 const int edge = corner_edges[corner];
231 if (!orig_index_edge.is_empty() && orig_index_edge[edge] == ORIGINDEX_NONE) {
232 continue;
233 }
234 data[line_index++] = edge_from_corners(face, corner);
235 }
236 });
237 }
238
239 return gpu::IndexBufPtr(GPU_indexbuf_build_ex(&builder, 0, mr.corners_num, false));
240}
241
243{
244 const bool sync_selection = ((mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0) || !edit_uvs;
245
247 return extract_edituv_lines_bm(mr, sync_selection);
248 }
249 return extract_edituv_lines_mesh(mr, sync_selection);
250}
251
253 const DRWSubdivCache &subdiv_cache,
254 const bool sync_selection)
255{
256 const BMesh &bm = *mr.bm;
257 const Span<int> subdiv_loop_edge_index = subdiv_cache.edges_orig_index->data<int>();
258 const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index,
259 subdiv_cache.num_subdiv_loops);
260
261 GPUIndexBufBuilder builder;
263 &builder, GPU_PRIM_LINES, subdiv_cache.num_subdiv_loops, subdiv_cache.num_subdiv_loops);
265 int line_index = 0;
266
267 for (const int subdiv_quad : IndexRange(subdiv_cache.num_subdiv_quads)) {
268 const int coarse_face = subdiv_loop_face_index[subdiv_quad * 4];
269 const BMFace &face_orig = *BM_face_at_index(&const_cast<BMesh &>(bm), coarse_face);
270 if (skip_bm_face(face_orig, sync_selection)) {
271 continue;
272 }
273 const IndexRange subdiv_face(subdiv_quad * 4, 4);
274 for (const int subdiv_corner : subdiv_face) {
275 const int coarse_edge = subdiv_loop_edge_index[subdiv_corner];
276 if (coarse_edge == -1) {
277 continue;
278 }
279 data[line_index++] = edge_from_corners(subdiv_face, subdiv_corner);
280 }
281 }
282
283 return gpu::IndexBufPtr(
284 GPU_indexbuf_build_ex(&builder, 0, subdiv_cache.num_subdiv_loops, false));
285}
286
288 const DRWSubdivCache &subdiv_cache,
289 const bool sync_selection)
290{
291 GPUIndexBufBuilder builder;
293 &builder, GPU_PRIM_LINES, subdiv_cache.num_subdiv_loops, subdiv_cache.num_subdiv_loops);
295 int line_index = 0;
296
297 /* NOTE: #subdiv_loop_edge_index already has the #CD_ORIGINDEX layer baked in. */
298 const Span<int> subdiv_loop_edge_index = subdiv_cache.edges_orig_index->data<int>();
299 const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index,
300 subdiv_cache.num_subdiv_loops);
301 /* TODO: Replace subdiv quad iteration with coarse face iteration. */
302 for (const int subdiv_quad : IndexRange(subdiv_cache.num_subdiv_quads)) {
303 const int coarse_face = subdiv_loop_face_index[subdiv_quad * 4];
304 if (const BMesh *bm = mr.bm) {
305 const int orig_coarse_face = mr.orig_index_face ? mr.orig_index_face[coarse_face] :
306 coarse_face;
307 const BMFace &face_orig = *BM_face_at_index(const_cast<BMesh *>(bm), orig_coarse_face);
308 if (skip_bm_face(face_orig, sync_selection)) {
309 continue;
310 }
311 }
312 else {
313 if (!mr.hide_poly.is_empty() && mr.hide_poly[coarse_face]) {
314 continue;
315 }
316 if (!sync_selection) {
317 if (mr.select_poly.is_empty() || !mr.select_poly[coarse_face]) {
318 continue;
319 }
320 }
321 }
322 const IndexRange subdiv_face(subdiv_quad * 4, 4);
323 for (const int subdiv_corner : subdiv_face) {
324 const int coarse_edge = subdiv_loop_edge_index[subdiv_corner];
325 if (coarse_edge == -1) {
326 continue;
327 }
328 data[line_index++] = edge_from_corners(subdiv_face, subdiv_corner);
329 }
330 }
331
332 return gpu::IndexBufPtr(
333 GPU_indexbuf_build_ex(&builder, 0, subdiv_cache.num_subdiv_loops, false));
334}
335
337 const DRWSubdivCache &subdiv_cache,
338 bool edit_uvs)
339{
340 const bool sync_selection = ((mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0) || !edit_uvs;
341
343 return extract_edituv_lines_subdiv_bm(mr, subdiv_cache, sync_selection);
344 }
345 return extract_edituv_lines_subdiv_mesh(mr, subdiv_cache, sync_selection);
346}
347
349
350/* ---------------------------------------------------------------------- */
353
355 const bool sync_selection,
356 GPUIndexBufBuilder &builder)
357{
358 const BMesh &bm = *mr.bm;
359 const BMFace *face;
360 BMIter f_iter;
361 BM_ITER_MESH (face, &f_iter, &const_cast<BMesh &>(bm), BM_FACES_OF_MESH) {
362 if (skip_bm_face(*face, sync_selection)) {
363 continue;
364 }
365 const BMLoop *loop = BM_FACE_FIRST_LOOP(face);
366 for ([[maybe_unused]] const int i : IndexRange(face->len)) {
368 loop = loop->next;
369 }
370 }
371}
372
374 const bool sync_selection,
375 GPUIndexBufBuilder &builder)
376{
377 const OffsetIndices faces = mr.faces;
378 const Span<int> corner_verts = mr.corner_verts;
379 const Span<int> orig_index_vert = mr.orig_index_vert ?
381 Span<int>();
382 for (const int face_index : faces.index_range()) {
383 const BMFace *face_orig = bm_original_face_get(mr, face_index);
384 if (!face_orig) {
385 continue;
386 }
387 if (skip_bm_face(*face_orig, sync_selection)) {
388 continue;
389 }
390 for (const int corner : faces[face_index]) {
391 const int vert = corner_verts[corner];
392 if (!orig_index_vert.is_empty() && orig_index_vert[vert] == ORIGINDEX_NONE) {
393 continue;
394 }
395 GPU_indexbuf_add_point_vert(&builder, corner);
396 }
397 }
398}
399
401{
402 const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
403
404 GPUIndexBufBuilder builder;
407 extract_edituv_points_bm(mr, sync_selection, builder);
408 }
409 else {
410 extract_edituv_points_mesh(mr, sync_selection, builder);
411 }
412 return gpu::IndexBufPtr(GPU_indexbuf_build(&builder));
413}
414
416 const DRWSubdivCache &subdiv_cache,
417 const bool sync_selection,
418 GPUIndexBufBuilder &builder)
419{
420 const BMesh &bm = *mr.bm;
421 const Span<int> subdiv_loop_vert_index = subdiv_cache.verts_orig_index->data<int>();
422 const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index,
423 subdiv_cache.num_subdiv_loops);
424
425 for (const int subdiv_quad : IndexRange(subdiv_cache.num_subdiv_quads)) {
426 const int coarse_face = subdiv_loop_face_index[subdiv_quad * 4];
427 const BMFace &face_orig = *BM_face_at_index(&const_cast<BMesh &>(bm), coarse_face);
428 if (skip_bm_face(face_orig, sync_selection)) {
429 continue;
430 }
431 for (const int subdiv_corner : IndexRange(subdiv_quad * 4, 4)) {
432 const int coarse_vert = subdiv_loop_vert_index[subdiv_corner];
433 if (coarse_vert == -1) {
434 continue;
435 }
436 GPU_indexbuf_add_point_vert(&builder, subdiv_corner);
437 }
438 }
439}
440
442 const DRWSubdivCache &subdiv_cache,
443 const bool sync_selection,
444 GPUIndexBufBuilder &builder)
445{
446 const Span<int> subdiv_loop_vert_index = subdiv_cache.verts_orig_index->data<int>();
447 const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index,
448 subdiv_cache.num_subdiv_loops);
449
450 for (const int subdiv_quad : IndexRange(subdiv_cache.num_subdiv_quads)) {
451 const int coarse_face = subdiv_loop_face_index[subdiv_quad * 4];
452 const BMFace *face_orig = bm_original_face_get(mr, coarse_face);
453 if (!face_orig) {
454 continue;
455 }
456 if (skip_bm_face(*face_orig, sync_selection)) {
457 continue;
458 }
459 for (const int subdiv_corner : IndexRange(subdiv_quad * 4, 4)) {
460 const int coarse_vert = subdiv_loop_vert_index[subdiv_corner];
461 if (coarse_vert == -1) {
462 continue;
463 }
464 GPU_indexbuf_add_point_vert(&builder, subdiv_corner);
465 }
466 }
467}
468
470 const DRWSubdivCache &subdiv_cache)
471{
472 const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
473
474 GPUIndexBufBuilder builder;
476 &builder, GPU_PRIM_POINTS, subdiv_cache.num_subdiv_loops, subdiv_cache.num_subdiv_loops);
478 extract_edituv_points_subdiv_bm(mr, subdiv_cache, sync_selection, builder);
479 }
480 else {
481 extract_edituv_points_subdiv_mesh(mr, subdiv_cache, sync_selection, builder);
482 }
483 return gpu::IndexBufPtr(GPU_indexbuf_build(&builder));
484}
485
487
488/* ---------------------------------------------------------------------- */
491
493 const bool sync_selection)
494{
495 const BMesh &bm = *mr.bm;
496 IndexMaskMemory memory;
497 const IndexMask visible = IndexMask::from_predicate(
498 IndexMask(bm.totface), GrainSize(4096), memory, [&](const int i) {
499 return !skip_bm_face(*BM_face_at_index(&const_cast<BMesh &>(bm), i), sync_selection);
500 });
501
502 GPUIndexBufBuilder builder;
503 GPU_indexbuf_init(&builder, GPU_PRIM_POINTS, visible.size(), bm.totface);
504 visible.to_indices(GPU_indexbuf_get_data(&builder).cast<int>());
505 return gpu::IndexBufPtr(GPU_indexbuf_build_ex(&builder, 0, bm.totface, false));
506}
507
509 const bool sync_selection)
510{
511 const OffsetIndices faces = mr.faces;
512 IndexMaskMemory memory;
514 faces.index_range(), GrainSize(4096), memory, [&](const int i) {
515 const BMFace *face_orig = bm_original_face_get(mr, i);
516 if (!face_orig) {
517 return false;
518 }
519 if (skip_bm_face(*face_orig, sync_selection)) {
520 return false;
521 }
522 return true;
523 });
524 if (mr.use_subsurf_fdots) {
525 const BitSpan facedot_tags = mr.mesh->runtime->subsurf_face_dot_tags;
526 const Span<int> corner_verts = mr.corner_verts;
527 visible = IndexMask::from_predicate(visible, GrainSize(4096), memory, [&](const int i) {
528 const Span<int> face_verts = corner_verts.slice(faces[i]);
529 return std::any_of(face_verts.begin(), face_verts.end(), [&](const int vert) {
530 return facedot_tags[vert];
531 });
532 });
533 }
534
535 GPUIndexBufBuilder builder;
536 GPU_indexbuf_init(&builder, GPU_PRIM_POINTS, visible.size(), faces.size());
537 visible.to_indices(GPU_indexbuf_get_data(&builder).cast<int>());
538 return gpu::IndexBufPtr(GPU_indexbuf_build_ex(&builder, 0, faces.size(), false));
539}
540
542{
543 const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
545 return extract_edituv_face_dots_bm(mr, sync_selection);
546 }
547 return extract_edituv_face_dots_mesh(mr, sync_selection);
548}
549
551
552} // namespace blender::draw
#define ORIGINDEX_NONE
unsigned int uint
@ UV_SYNC_SELECTION
blender::MutableSpan< uint32_t > GPU_indexbuf_get_data(GPUIndexBufBuilder *)
void GPU_indexbuf_init(GPUIndexBufBuilder *, GPUPrimType, uint prim_len, uint vertex_len)
blender::gpu::IndexBuf * GPU_indexbuf_build_ex(GPUIndexBufBuilder *builder, uint index_min, uint index_max, bool uses_restart_indices)
void GPU_indexbuf_add_point_vert(GPUIndexBufBuilder *, uint v)
blender::gpu::IndexBuf * GPU_indexbuf_build(GPUIndexBufBuilder *)
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
BMesh const char void * data
BMesh * bm
BLI_INLINE BMFace * BM_face_at_index(BMesh *bm, const int index)
constexpr bool is_empty() const
Definition BLI_span.hh:260
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
static IndexMask from_bools_inverse(const VArray< bool > &bools, IndexMaskMemory &memory)
constexpr Span slice(int64_t start, int64_t size) const
Definition BLI_span.hh:137
constexpr const T * end() const
Definition BLI_span.hh:224
constexpr IndexRange index_range() const
Definition BLI_span.hh:401
constexpr const T * begin() const
Definition BLI_span.hh:220
constexpr bool is_empty() const
Definition BLI_span.hh:260
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.
#define cast
static char faces[256]
IndexRange face_triangles_range(OffsetIndices< int > faces, int face_i)
Definition BKE_mesh.hh:343
BLI_INLINE BMFace * bm_original_face_get(const MeshRenderData &mr, int idx)
gpu::IndexBufPtr extract_edituv_face_dots(const MeshRenderData &mr)
static gpu::IndexBufPtr extract_edituv_face_dots_bm(const MeshRenderData &mr, const bool sync_selection)
static void extract_edituv_tris_subdiv_bm(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const bool sync_selection, GPUIndexBufBuilder &builder)
static gpu::IndexBufPtr extract_edituv_lines_subdiv_mesh(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const bool sync_selection)
static void extract_edituv_tris_mesh(const MeshRenderData &mr, const bool sync_selection, GPUIndexBufBuilder &builder)
static void extract_edituv_tris_bm(const MeshRenderData &mr, const bool sync_selection, GPUIndexBufBuilder &builder)
gpu::IndexBufPtr extract_edituv_points(const MeshRenderData &mr)
gpu::IndexBufPtr extract_edituv_tris_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
uint2 edge_from_corners(const IndexRange face, const int corner)
static void extract_edituv_points_subdiv_bm(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const bool sync_selection, GPUIndexBufBuilder &builder)
gpu::IndexBufPtr extract_edituv_points_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
static void extract_edituv_tris_subdiv_mesh(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 gpu::IndexBufPtr extract_edituv_face_dots_mesh(const MeshRenderData &mr, const bool sync_selection)
static void extract_edituv_points_mesh(const MeshRenderData &mr, const bool sync_selection, GPUIndexBufBuilder &builder)
static gpu::IndexBufPtr extract_edituv_lines_bm(const MeshRenderData &mr, const bool sync_selection)
gpu::IndexBufPtr extract_edituv_lines(const MeshRenderData &mr, bool edit_uvs)
static void extract_edituv_points_bm(const MeshRenderData &mr, const bool sync_selection, GPUIndexBufBuilder &builder)
gpu::IndexBufPtr extract_edituv_tris(const MeshRenderData &mr)
gpu::IndexBufPtr extract_edituv_lines_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, bool edit_uvs)
static gpu::IndexBufPtr extract_edituv_lines_subdiv_bm(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const bool sync_selection)
bool skip_bm_face(const BMFace &face, const bool sync_selection)
static gpu::IndexBufPtr extract_edituv_lines_mesh(const MeshRenderData &mr, const bool sync_selection)
std::unique_ptr< IndexBuf, IndexBufDeleter > IndexBufPtr
VecBase< uint32_t, 2 > uint2
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
i
Definition text_draw.cc:230