Blender V4.5
draw_cache_extract_mesh.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2017 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#include "BKE_attribute.hh"
12
13#include "DNA_mesh_types.h"
14#include "DNA_scene_types.h"
15
16#include "BLI_map.hh"
17#include "BLI_set.hh"
18#include "BLI_task.hh"
19
20#include "GPU_capabilities.hh"
21
22#include "draw_cache_extract.hh"
23#include "draw_subdivision.hh"
24
26
27// #define DEBUG_TIME
28
29#ifdef DEBUG_TIME
30# include "BLI_time_utildefines.h"
31#endif
32
33namespace blender::draw {
34
36 Span<IBOType> ibo_requests,
37 Span<VBOType> vbo_requests,
38 MeshBufferCache &cache)
39{
40 const bool request_face_normals = vbo_requests.contains(VBOType::CornerNormal) ||
41 vbo_requests.contains(VBOType::FaceDotNormal) ||
42 vbo_requests.contains(VBOType::EdgeFactor) ||
43 vbo_requests.contains(VBOType::MeshAnalysis);
44 const bool request_corner_normals = vbo_requests.contains(VBOType::CornerNormal);
45 const bool force_corner_normals = vbo_requests.contains(VBOType::Tangents);
46
47 if (request_face_normals) {
49 }
50 if ((request_corner_normals && mr.normals_domain == bke::MeshNormalDomain::Corner &&
52 force_corner_normals)
53 {
55 }
56
57 const bool calc_loose_geom = ibo_requests.contains(IBOType::Lines) ||
58 ibo_requests.contains(IBOType::LinesLoose) ||
59 ibo_requests.contains(IBOType::Points) ||
60 vbo_requests.contains(VBOType::Position) ||
61 vbo_requests.contains(VBOType::EditData) ||
62 vbo_requests.contains(VBOType::VertexNormal) ||
63 vbo_requests.contains(VBOType::IndexVert) ||
64 vbo_requests.contains(VBOType::IndexEdge) ||
65 vbo_requests.contains(VBOType::EdgeFactor);
66
67 if (calc_loose_geom) {
69 }
70}
71
73
74/* ---------------------------------------------------------------------- */
77
83static bool use_normals_simplify(const Scene &scene, const MeshRenderData &mr)
84{
85 if (!(scene.r.mode & R_SIMPLIFY) || !(scene.r.mode & R_SIMPLIFY_NORMALS)) {
86 return false;
87 }
88 if (!mr.mesh) {
89 return true;
90 }
91 const Mesh &mesh = *mr.mesh;
92 const std::optional<bke::AttributeMetaData> meta_data = mesh.attributes().lookup_meta_data(
93 "custom_normal");
94 if (!meta_data) {
95 return false;
96 }
97 if (meta_data->domain == bke::AttrDomain::Corner && meta_data->data_type == CD_PROP_INT16_2D) {
98 return true;
99 }
100 return false;
101}
102
104 const Scene &scene,
105 MeshBatchCache &cache,
106 MeshBufferCache &mbc,
107 const Span<IBOType> ibo_requests,
108 const Span<VBOType> vbo_requests,
109 Object &object,
110 Mesh &mesh,
111 const bool is_editmode,
112 const bool is_paint_mode,
113 const bool do_final,
114 const bool do_uvedit,
115 const bool use_hide)
116{
117 if (ibo_requests.is_empty() && vbo_requests.is_empty()) {
118 return;
119 }
120
122
123 Vector<IBOType, 16> ibos_to_create;
124 for (const IBOType request : ibo_requests) {
125 if (!buffers.ibos.contains(request)) {
126 ibos_to_create.append(request);
127 }
128 }
129
130 Vector<VBOType, 16> vbos_to_create;
131 for (const VBOType request : vbo_requests) {
132 if (!buffers.vbos.contains(request)) {
133 vbos_to_create.append(request);
134 }
135 }
136
137 if (ibos_to_create.is_empty() && vbos_to_create.is_empty()) {
138 return;
139 }
140
141#ifdef DEBUG_TIME
142 SCOPED_TIMER(__func__);
143#endif
144
146 object, mesh, is_editmode, is_paint_mode, do_final, do_uvedit, use_hide, scene.toolsettings);
147
148 mr.use_subsurf_fdots = mr.mesh && !mr.mesh->runtime->subsurf_face_dot_tags.is_empty();
150
151 ensure_dependency_data(mr, ibo_requests, vbo_requests, mbc);
152
153 Array<gpu::IndexBufPtr, 16> created_ibos(ibos_to_create.size());
154
155 {
156 /* Because lines and loose lines are stored in the same buffer, they're handled separately
157 * rather than from potentially multiple threads in the parallel_for_each loop below. */
158 const int lines_index = ibos_to_create.as_span().first_index_try(IBOType::Lines);
159 const int loose_lines_index = ibos_to_create.as_span().first_index_try(IBOType::LinesLoose);
160 if (lines_index != -1 || loose_lines_index != -1) {
161 extract_lines(mr,
162 lines_index == -1 ? nullptr : &created_ibos[lines_index],
163 loose_lines_index == -1 ? nullptr : &created_ibos[loose_lines_index],
164 cache.no_loose_wire);
165 }
166 }
167
168 threading::parallel_for_each(ibos_to_create.index_range(), [&](const int i) {
169 switch (ibos_to_create[i]) {
170 case IBOType::Tris:
171 created_ibos[i] = extract_tris(mr, mesh_render_data_faces_sorted_ensure(mr, mbc));
172 break;
173 case IBOType::Lines:
174 case IBOType::LinesLoose:
175 /* Handled as a special case above. */
176 break;
177 case IBOType::Points:
178 created_ibos[i] = extract_points(mr);
179 break;
180 case IBOType::FaceDots:
181 created_ibos[i] = extract_face_dots(mr);
182 break;
183 case IBOType::LinesPaintMask:
184 created_ibos[i] = extract_lines_paint_mask(mr);
185 break;
186 case IBOType::LinesAdjacency:
187 created_ibos[i] = extract_lines_adjacency(mr, cache.is_manifold);
188 break;
189 case IBOType::UVTris:
190 created_ibos[i] = extract_edituv_tris(mr, false);
191 break;
192 case IBOType::EditUVTris:
193 created_ibos[i] = extract_edituv_tris(mr, true);
194 break;
195 case IBOType::AllUVLines:
196 created_ibos[i] = extract_edituv_lines(mr, UvExtractionMode::All);
197 break;
198 case IBOType::UVLines:
199 created_ibos[i] = extract_edituv_lines(mr, UvExtractionMode::Selection);
200 break;
201 case IBOType::EditUVLines:
202 created_ibos[i] = extract_edituv_lines(mr, UvExtractionMode::Edit);
203 break;
204 case IBOType::EditUVPoints:
205 created_ibos[i] = extract_edituv_points(mr);
206 break;
207 case IBOType::EditUVFaceDots:
208 created_ibos[i] = extract_edituv_face_dots(mr);
209 break;
210 }
211 });
212
213 Array<gpu::VertBufPtr, 16> created_vbos(vbos_to_create.size());
214
215 const bool do_hq_normals = (scene.r.perf_flag & SCE_PERF_HQ_NORMALS) != 0 ||
217
218 threading::parallel_for_each(vbos_to_create.index_range(), [&](const int i) {
219 switch (vbos_to_create[i]) {
220 case VBOType::Position:
221 created_vbos[i] = extract_positions(mr);
222 break;
223 case VBOType::CornerNormal:
224 created_vbos[i] = extract_normals(mr, do_hq_normals);
225 break;
226 case VBOType::EdgeFactor:
227 created_vbos[i] = extract_edge_factor(mr);
228 break;
229 case VBOType::VertexGroupWeight:
230 created_vbos[i] = extract_weights(mr, cache);
231 break;
232 case VBOType::UVs:
233 created_vbos[i] = extract_uv_maps(mr, cache);
234 break;
235 case VBOType::Tangents:
236 created_vbos[i] = extract_tangents(mr, cache, do_hq_normals);
237 break;
238 case VBOType::SculptData:
239 created_vbos[i] = extract_sculpt_data(mr);
240 break;
241 case VBOType::Orco:
242 created_vbos[i] = extract_orco(mr);
243 break;
244 case VBOType::EditData:
245 created_vbos[i] = extract_edit_data(mr);
246 break;
247 case VBOType::EditUVData:
248 created_vbos[i] = extract_edituv_data(mr);
249 break;
250 case VBOType::EditUVStretchArea:
251 created_vbos[i] = extract_edituv_stretch_area(mr, cache.tot_area, cache.tot_uv_area);
252 break;
253 case VBOType::EditUVStretchAngle:
254 created_vbos[i] = extract_edituv_stretch_angle(mr);
255 break;
256 case VBOType::MeshAnalysis:
257 created_vbos[i] = extract_mesh_analysis(mr, object.object_to_world());
258 break;
259 case VBOType::FaceDotPosition:
260 created_vbos[i] = extract_face_dots_position(mr);
261 break;
262 case VBOType::FaceDotNormal:
263 created_vbos[i] = extract_face_dot_normals(mr, do_hq_normals);
264 break;
265 case VBOType::FaceDotUV:
266 created_vbos[i] = extract_face_dots_uv(mr);
267 break;
268 case VBOType::FaceDotEditUVData:
269 created_vbos[i] = extract_face_dots_edituv_data(mr);
270 break;
271 case VBOType::SkinRoots:
272 created_vbos[i] = extract_skin_roots(mr);
273 break;
274 case VBOType::IndexVert:
275 created_vbos[i] = extract_vert_index(mr);
276 break;
277 case VBOType::IndexEdge:
278 created_vbos[i] = extract_edge_index(mr);
279 break;
280 case VBOType::IndexFace:
281 created_vbos[i] = extract_face_index(mr);
282 break;
283 case VBOType::IndexFaceDot:
284 created_vbos[i] = extract_face_dot_index(mr);
285 break;
286 case VBOType::Attr0:
287 case VBOType::Attr1:
288 case VBOType::Attr2:
289 case VBOType::Attr3:
290 case VBOType::Attr5:
291 case VBOType::Attr6:
292 case VBOType::Attr7:
293 case VBOType::Attr8:
294 case VBOType::Attr9:
295 case VBOType::Attr10:
296 case VBOType::Attr11:
297 case VBOType::Attr12:
298 case VBOType::Attr13:
299 case VBOType::Attr14:
300 case VBOType::Attr15: {
301 const int8_t attr_index = int8_t(vbos_to_create[i]) - int8_t(VBOType::Attr0);
302 created_vbos[i] = extract_attribute(mr, cache.attr_used[attr_index]);
303 break;
304 }
305 case VBOType::AttrViewer:
306 created_vbos[i] = extract_attr_viewer(mr);
307 break;
308 case VBOType::VertexNormal:
309 created_vbos[i] = extract_vert_normals(mr);
310 break;
311 }
312 });
313
314 for (const int i : ibos_to_create.index_range()) {
315 buffers.ibos.add_new(ibos_to_create[i], std::move(created_ibos[i]));
316 }
317 for (const int i : vbos_to_create.index_range()) {
318 buffers.vbos.add_new(vbos_to_create[i], std::move(created_vbos[i]));
319 }
320}
321
323
324/* ---------------------------------------------------------------------- */
327
329 MeshBufferCache &mbc,
330 const Span<IBOType> ibo_requests,
331 const Span<VBOType> vbo_requests,
332 DRWSubdivCache &subdiv_cache,
333 MeshRenderData &mr)
334{
335 if (ibo_requests.is_empty() && vbo_requests.is_empty()) {
336 return;
337 }
339
342 DRW_subdivide_loose_geom(subdiv_cache, mbc);
343
344 Set<IBOType, 16> ibos_to_create;
345 for (const IBOType request : ibo_requests) {
346 if (!buffers.ibos.contains(request)) {
347 ibos_to_create.add_new(request);
348 }
349 }
350
351 Set<VBOType, 16> vbos_to_create;
352 for (const VBOType request : vbo_requests) {
353 if (!buffers.vbos.contains(request)) {
354 vbos_to_create.add_new(request);
355 }
356 }
357
358 if (ibos_to_create.is_empty() && vbos_to_create.is_empty()) {
359 return;
360 }
361
362 if (vbos_to_create.contains(VBOType::Position) || vbos_to_create.contains(VBOType::Orco)) {
363 gpu::VertBufPtr orco_vbo;
364 /* Don't use `add_new` because #VBOType::Orco might be requested after #VBOType::Position
365 * already exists. It's inefficient to build the position VBO a second time but that's the API
366 * that GPU subdivision provides. */
367 buffers.vbos.add(
370 subdiv_cache, mr, vbos_to_create.contains(VBOType::Orco) ? &orco_vbo : nullptr));
371 if (orco_vbo) {
372 buffers.vbos.add_new(VBOType::Orco, std::move(orco_vbo));
373 }
374 }
375 if (vbos_to_create.contains(VBOType::CornerNormal)) {
376 /* The corner normals calculation uses positions and normals stored in the `pos` VBO. */
377 buffers.vbos.add_new(
379 extract_normals_subdiv(mr, subdiv_cache, *buffers.vbos.lookup(VBOType::Position)));
380 }
381 if (vbos_to_create.contains(VBOType::EdgeFactor)) {
382 buffers.vbos.add_new(
384 extract_edge_factor_subdiv(subdiv_cache, mr, *buffers.vbos.lookup(VBOType::Position)));
385 }
386 if (ibos_to_create.contains(IBOType::Lines) || ibos_to_create.contains(IBOType::LinesLoose)) {
387 gpu::IndexBufPtr lines_ibo;
388 gpu::IndexBufPtr lines_loose_ibo;
389 extract_lines_subdiv(subdiv_cache,
390 mr,
391 ibos_to_create.contains(IBOType::Lines) ? &lines_ibo : nullptr,
392 ibos_to_create.contains(IBOType::LinesLoose) ? &lines_loose_ibo : nullptr,
393 cache.no_loose_wire);
394 if (lines_ibo) {
395 buffers.ibos.add_new(IBOType::Lines, std::move(lines_ibo));
396 }
397 if (lines_loose_ibo) {
398 buffers.ibos.add_new(IBOType::LinesLoose, std::move(lines_loose_ibo));
399 }
400 }
401 if (ibos_to_create.contains(IBOType::Tris)) {
402 buffers.ibos.add_new(IBOType::Tris, extract_tris_subdiv(subdiv_cache, cache));
403 }
404 if (ibos_to_create.contains(IBOType::Points)) {
405 buffers.ibos.add_new(IBOType::Points, extract_points_subdiv(mr, subdiv_cache));
406 }
407 if (vbos_to_create.contains(VBOType::EditData)) {
408 buffers.vbos.add_new(VBOType::EditData, extract_edit_data_subdiv(mr, subdiv_cache));
409 }
410 if (vbos_to_create.contains(VBOType::Tangents)) {
411 buffers.vbos.add_new(VBOType::Tangents, extract_tangents_subdiv(mr, subdiv_cache, cache));
412 }
413 if (vbos_to_create.contains(VBOType::IndexVert)) {
414 buffers.vbos.add_new(VBOType::IndexVert, extract_vert_index_subdiv(subdiv_cache, mr));
415 }
416 if (vbos_to_create.contains(VBOType::IndexEdge)) {
417 buffers.vbos.add_new(VBOType::IndexEdge, extract_edge_index_subdiv(subdiv_cache, mr));
418 }
419 if (vbos_to_create.contains(VBOType::IndexFace)) {
420 buffers.vbos.add_new(VBOType::IndexFace, extract_face_index_subdiv(subdiv_cache, mr));
421 }
422 if (vbos_to_create.contains(VBOType::VertexGroupWeight)) {
424 extract_weights_subdiv(mr, subdiv_cache, cache));
425 }
426 if (vbos_to_create.contains(VBOType::FaceDotNormal) ||
427 vbos_to_create.contains(VBOType::FaceDotPosition) ||
428 ibos_to_create.contains(IBOType::FaceDots))
429 {
430 gpu::VertBufPtr face_dot_position_vbo;
431 gpu::VertBufPtr face_dot_normal_vbo;
432 gpu::IndexBufPtr face_dot_ibo;
433
434 /* We use only one extractor for face dots, as the work is done in a single compute shader. */
436 subdiv_cache,
437 face_dot_position_vbo,
438 vbos_to_create.contains(VBOType::FaceDotNormal) ? &face_dot_normal_vbo : nullptr,
439 face_dot_ibo);
440 buffers.vbos.add_new(VBOType::FaceDotPosition, std::move(face_dot_position_vbo));
441 if (face_dot_normal_vbo) {
442 buffers.vbos.add_new(VBOType::FaceDotNormal, std::move(face_dot_normal_vbo));
443 }
444 buffers.ibos.add_new(IBOType::FaceDots, std::move(face_dot_ibo));
445 }
446 if (ibos_to_create.contains(IBOType::LinesPaintMask)) {
447 buffers.ibos.add_new(IBOType::LinesPaintMask,
448 extract_lines_paint_mask_subdiv(mr, subdiv_cache));
449 }
450 if (ibos_to_create.contains(IBOType::LinesAdjacency)) {
451 buffers.ibos.add_new(IBOType::LinesAdjacency,
452 extract_lines_adjacency_subdiv(subdiv_cache, cache.is_manifold));
453 }
454 if (vbos_to_create.contains(VBOType::SculptData)) {
455 buffers.vbos.add_new(VBOType::SculptData, extract_sculpt_data_subdiv(mr, subdiv_cache));
456 }
457 if (vbos_to_create.contains(VBOType::UVs)) {
458 /* Make sure UVs are computed before edituv stuffs. */
459 buffers.vbos.add_new(VBOType::UVs, extract_uv_maps_subdiv(subdiv_cache, cache));
460 }
461 if (ibos_to_create.contains(IBOType::AllUVLines)) {
462 buffers.ibos.add_new(IBOType::AllUVLines,
464 }
465 if (ibos_to_create.contains(IBOType::UVLines)) {
466 buffers.ibos.add_new(
469 }
470 if (vbos_to_create.contains(VBOType::EditUVStretchArea)) {
471 buffers.vbos.add_new(
473 extract_edituv_stretch_area_subdiv(mr, subdiv_cache, cache.tot_area, cache.tot_uv_area));
474 }
475 if (vbos_to_create.contains(VBOType::EditUVStretchAngle)) {
477 extract_edituv_stretch_angle_subdiv(mr, subdiv_cache, cache));
478 }
479 if (vbos_to_create.contains(VBOType::EditUVData)) {
480 buffers.vbos.add_new(VBOType::EditUVData, extract_edituv_data_subdiv(mr, subdiv_cache));
481 }
482 if (ibos_to_create.contains(IBOType::EditUVTris)) {
483 buffers.ibos.add_new(IBOType::EditUVTris, extract_edituv_tris_subdiv(mr, subdiv_cache));
484 }
485 if (ibos_to_create.contains(IBOType::EditUVLines)) {
486 buffers.ibos.add_new(IBOType::EditUVLines,
488 }
489 if (ibos_to_create.contains(IBOType::EditUVPoints)) {
490 buffers.ibos.add_new(IBOType::EditUVPoints, extract_edituv_points_subdiv(mr, subdiv_cache));
491 }
492 for (const int8_t i : IndexRange(GPU_MAX_ATTR)) {
493 const VBOType request = VBOType(int8_t(VBOType::Attr0) + i);
494 if (vbos_to_create.contains(request)) {
495 buffers.vbos.add_new(request,
496 extract_attribute_subdiv(mr, subdiv_cache, cache.attr_used[i]));
497 }
498 }
499}
500
502
503} // namespace blender::draw
Utility defines for timing/benchmarks.
#define SCOPED_TIMER(name)
Definition BLI_timeit.hh:70
@ CD_PROP_INT16_2D
@ SCE_PERF_HQ_NORMALS
@ R_SIMPLIFY
@ R_SIMPLIFY_NORMALS
bool GPU_use_hq_normals_workaround()
static constexpr int GPU_MAX_ATTR
Definition GPU_shader.hh:34
AttributeSet attributes
bool contains(const Key &key) const
Definition BLI_set.hh:310
bool is_empty() const
Definition BLI_set.hh:595
void add_new(const Key &key)
Definition BLI_set.hh:233
constexpr bool is_empty() const
Definition BLI_span.hh:260
constexpr bool contains(const T &value) const
Definition BLI_span.hh:277
int64_t size() const
void append(const T &value)
bool is_empty() const
IndexRange index_range() const
Span< T > as_span() const
Extraction of Mesh data into VBO to feed to GPU.
void mesh_render_data_update_face_normals(MeshRenderData &mr)
gpu::VertBufPtr extract_attribute_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, StringRef name)
gpu::IndexBufPtr extract_lines_adjacency_subdiv(const DRWSubdivCache &subdiv_cache, bool &r_is_manifold)
gpu::VertBufPtr extract_edit_data_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
static void ensure_dependency_data(MeshRenderData &mr, Span< IBOType > ibo_requests, Span< VBOType > vbo_requests, MeshBufferCache &cache)
gpu::IndexBufPtr extract_edituv_lines_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, UvExtractionMode mode)
gpu::IndexBufPtr extract_points_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
gpu::VertBufPtr extract_normals_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, gpu::VertBuf &pos_nor)
gpu::VertBufPtr extract_tangents_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const MeshBatchCache &cache)
gpu::VertBufPtr extract_edituv_stretch_angle_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const MeshBatchCache &cache)
void DRW_subdivide_loose_geom(DRWSubdivCache &subdiv_cache, const MeshBufferCache &cache)
gpu::VertBufPtr extract_vert_index_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr)
gpu::VertBufPtr extract_sculpt_data_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
gpu::IndexBufPtr extract_edituv_tris_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
void extract_lines(const MeshRenderData &mr, gpu::IndexBufPtr *lines, gpu::IndexBufPtr *lines_loose, bool &no_loose_wire)
gpu::VertBufPtr extract_positions_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr, gpu::VertBufPtr *orco_vbo)
gpu::IndexBufPtr extract_edituv_points_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
gpu::VertBufPtr extract_face_index_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr)
void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache, MeshBufferCache &mbc, Span< IBOType > ibo_requests, Span< VBOType > vbo_requests, DRWSubdivCache &subdiv_cache, MeshRenderData &mr)
gpu::VertBufPtr extract_edge_index_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr)
gpu::VertBufPtr extract_edge_factor_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr, gpu::VertBuf &pos_nor)
gpu::IndexBufPtr extract_tris_subdiv(const DRWSubdivCache &subdiv_cache, MeshBatchCache &cache)
void mesh_render_data_update_corner_normals(MeshRenderData &mr)
void extract_face_dots_subdiv(const DRWSubdivCache &subdiv_cache, gpu::VertBufPtr &fdots_pos, gpu::VertBufPtr *fdots_nor, gpu::IndexBufPtr &fdots)
void mesh_buffer_cache_create_requested(TaskGraph &task_graph, const Scene &scene, MeshBatchCache &cache, MeshBufferCache &mbc, Span< IBOType > ibo_requests, Span< VBOType > vbo_requests, Object &object, Mesh &mesh, bool is_editmode, bool is_paint_mode, bool do_final, bool do_uvedit, bool use_hide)
gpu::VertBufPtr extract_weights_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const MeshBatchCache &cache)
static bool use_normals_simplify(const Scene &scene, const MeshRenderData &mr)
gpu::VertBufPtr extract_edituv_stretch_area_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, float &tot_area, float &tot_uv_area)
MeshRenderData mesh_render_data_create(Object &object, Mesh &mesh, const bool is_editmode, const bool is_paint_mode, const bool do_final, const bool do_uvedit, const bool use_hide, const ToolSettings *ts)
void mesh_render_data_update_loose_geom(MeshRenderData &mr, MeshBufferCache &cache)
gpu::IndexBufPtr extract_lines_paint_mask_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
gpu::VertBufPtr extract_uv_maps_subdiv(const DRWSubdivCache &subdiv_cache, const MeshBatchCache &cache)
gpu::VertBufPtr extract_edituv_data_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
void extract_lines_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr, gpu::IndexBufPtr *lines, gpu::IndexBufPtr *lines_loose, bool &no_loose_wire)
std::unique_ptr< IndexBuf, IndexBufDeleter > IndexBufPtr
std::unique_ptr< gpu::VertBuf, gpu::VertBufDeleter > VertBufPtr
void parallel_for_each(Range &&range, const Function &function)
Definition BLI_task.hh:56
MeshRuntimeHandle * runtime
struct ToolSettings * toolsettings
struct RenderData r
VectorSet< std::string > attr_used
bke::MeshNormalDomain normals_domain
i
Definition text_draw.cc:230
char * buffers[2]