Blender V5.0
extract_mesh.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#pragma once
12
15#include "BLI_task.hh"
16#include "BLI_virtual_array.hh"
17
18#include "DNA_scene_types.h"
19
20#include "BKE_mesh.hh"
21#include "BKE_object.hh"
22
23#include "bmesh.hh"
24
25#include "GPU_vertex_buffer.hh"
26
27#include "draw_cache_extract.hh"
28
29struct DRWSubdivCache;
30struct BMVert;
31struct BMEdge;
32struct BMEditMesh;
33struct BMFace;
34struct BMLoop;
35
36namespace blender::draw {
37
38/* ---------------------------------------------------------------------- */
41
42enum class MeshExtractType {
45};
46
49
54
58
61
66
72
73 /* For deformed edit-mesh data. */
74 /* Use for #ME_WRAPPER_TYPE_BMESH. */
82
83 const int *orig_index_vert;
84 const int *orig_index_edge;
85 const int *orig_index_face;
92 const Mesh *mesh;
98
104
108
116
119
120 const char *active_color_name;
122};
123
124inline const Mesh &editmesh_final_or_this(const Object &object, const Mesh &mesh)
125{
126 if (mesh.runtime->edit_mesh != nullptr) {
127 if (const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(&object)) {
128 return *editmesh_eval_final;
129 }
130 }
131
132 return mesh;
133}
134
139
141{
142 return ((mr.orig_index_face != nullptr) && (mr.orig_index_face[idx] != ORIGINDEX_NONE) &&
143 mr.bm) ?
144 BM_face_at_index(mr.bm, mr.orig_index_face[idx]) :
145 nullptr;
146}
147
149{
150 return ((mr.orig_index_edge != nullptr) && (mr.orig_index_edge[idx] != ORIGINDEX_NONE) &&
151 mr.bm) ?
152 BM_edge_at_index(mr.bm, mr.orig_index_edge[idx]) :
153 nullptr;
154}
155
157{
158 return ((mr.orig_index_vert != nullptr) && (mr.orig_index_vert[idx] != ORIGINDEX_NONE) &&
159 mr.bm) ?
160 BM_vert_at_index(mr.bm, mr.orig_index_vert[idx]) :
161 nullptr;
162}
163
164BLI_INLINE const float *bm_vert_co_get(const MeshRenderData &mr, const BMVert *eve)
165{
166 if (!mr.bm_vert_coords.is_empty()) {
167 return mr.bm_vert_coords[BM_elem_index_get(eve)];
168 }
169 return eve->co;
170}
171
172BLI_INLINE const float *bm_vert_no_get(const MeshRenderData &mr, const BMVert *eve)
173{
174 if (mr.bm_free_normal_offset_vert != -1) {
176 }
177 if (!mr.bm_vert_normals.is_empty()) {
178 return mr.bm_vert_normals[BM_elem_index_get(eve)];
179 }
180 return eve->no;
181}
182
183BLI_INLINE const float *bm_face_no_get(const MeshRenderData &mr, const BMFace *efa)
184{
185 if (mr.bm_free_normal_offset_face != -1) {
187 }
188 if (!mr.bm_face_normals.is_empty()) {
189 return mr.bm_face_normals[BM_elem_index_get(efa)];
190 }
191 return efa->no;
192}
193
195
196/* `draw_cache_extract_mesh_render_data.cc` */
197
202MeshRenderData mesh_render_data_create(Object &object,
203 Mesh &mesh,
204 bool is_editmode,
205 bool is_paint_mode,
206 bool do_final,
207 bool do_uvedit,
208 bool use_hide,
209 const ToolSettings *ts);
210void mesh_render_data_update_corner_normals(MeshRenderData &mr);
211void mesh_render_data_update_face_normals(MeshRenderData &mr);
212void mesh_render_data_update_loose_geom(MeshRenderData &mr, MeshBufferCache &cache);
213const SortedFaceData &mesh_render_data_faces_sorted_ensure(const MeshRenderData &mr,
214 MeshBufferCache &cache);
215
216/* draw_cache_extract_mesh_extractors.c */
217
221 /* This is used for both vertex and edge creases. The edge crease value is stored in the bottom 4
222 * bits, while the vertex crease is stored in the upper 4 bits. */
225};
226
228 const BMFace *efa,
229 const BMUVOffsets &offsets,
230 EditLoopData &eattr);
232 const BMLoop *l,
233 const BMUVOffsets &offsets,
234 EditLoopData &eattr);
236 const BMLoop *l,
237 const BMUVOffsets &offsets,
238 EditLoopData &eattr);
239
240/* In the GPU vertex buffers, the value for each vertex is duplicated to each of its vertex
241 * corners. So the edges on the GPU connect face corners rather than vertices. */
242inline uint2 edge_from_corners(const IndexRange face, const int corner)
243{
244 const int corner_next = bke::mesh::face_corner_next(face, corner);
245 return uint2(corner, corner_next);
246}
247
248template<typename T>
250 const Span<int2> edges,
251 const Span<int> loose_edges,
252 MutableSpan<T> gpu_data)
253{
254 threading::parallel_for(loose_edges.index_range(), 4096, [&](const IndexRange range) {
255 for (const int i : range) {
256 const int2 edge = edges[loose_edges[i]];
257 gpu_data[i * 2 + 0] = vert_data[edge[0]];
258 gpu_data[i * 2 + 1] = vert_data[edge[1]];
259 }
260 });
261}
262
263gpu::VertBufPtr extract_positions(const MeshRenderData &mr);
264gpu::VertBufPtr extract_positions_subdiv(const DRWSubdivCache &subdiv_cache,
265 const MeshRenderData &mr,
266 gpu::VertBufPtr *orco_vbo);
267
268gpu::VertBufPtr extract_face_dots_position(const MeshRenderData &mr);
269void extract_face_dots_subdiv(const DRWSubdivCache &subdiv_cache,
270 gpu::VertBufPtr &fdots_pos,
271 gpu::VertBufPtr *fdots_nor,
272 gpu::IndexBufPtr &fdots);
273
274gpu::VertBufPtr extract_normals(const MeshRenderData &mr, bool use_hq);
275gpu::VertBufPtr extract_normals_subdiv(const MeshRenderData &mr,
276 const DRWSubdivCache &subdiv_cache,
277 gpu::VertBuf &pos);
278gpu::VertBufPtr extract_vert_normals(const MeshRenderData &mr);
279gpu::VertBufPtr extract_face_dot_normals(const MeshRenderData &mr, bool use_hq);
280gpu::VertBufPtr extract_edge_factor(const MeshRenderData &mr);
281gpu::VertBufPtr extract_edge_factor_subdiv(const DRWSubdivCache &subdiv_cache,
282 const MeshRenderData &mr,
283 gpu::VertBuf &pos);
284
285gpu::IndexBufPtr extract_tris(const MeshRenderData &mr, const SortedFaceData &face_sorted);
286void create_material_subranges(const SortedFaceData &face_sorted,
287 gpu::IndexBuf &tris_ibo,
289gpu::IndexBufPtr extract_tris_subdiv(const DRWSubdivCache &subdiv_cache, MeshBatchCache &cache);
290
291void extract_lines(const MeshRenderData &mr,
292 gpu::IndexBufPtr *lines,
293 gpu::IndexBufPtr *lines_loose,
294 bool &no_loose_wire);
295void extract_lines_subdiv(const DRWSubdivCache &subdiv_cache,
296 const MeshRenderData &mr,
297 gpu::IndexBufPtr *lines,
298 gpu::IndexBufPtr *lines_loose,
299 bool &no_loose_wire);
300
301gpu::IndexBufPtr extract_points(const MeshRenderData &mr);
302gpu::IndexBufPtr extract_points_subdiv(const MeshRenderData &mr,
303 const DRWSubdivCache &subdiv_cache);
304
305gpu::VertBufPtr extract_edit_data(const MeshRenderData &mr);
306gpu::VertBufPtr extract_edit_data_subdiv(const MeshRenderData &mr,
307 const DRWSubdivCache &subdiv_cache);
308
309gpu::VertBufPtr extract_tangents(const MeshRenderData &mr,
310 const MeshBatchCache &cache,
311 bool use_hq);
312gpu::VertBufPtr extract_tangents_subdiv(const MeshRenderData &mr,
313 const DRWSubdivCache &subdiv_cache,
314 const MeshBatchCache &cache);
315
316gpu::VertBufPtr extract_vert_index(const MeshRenderData &mr);
317gpu::VertBufPtr extract_edge_index(const MeshRenderData &mr);
318gpu::VertBufPtr extract_face_index(const MeshRenderData &mr);
319gpu::VertBufPtr extract_face_dot_index(const MeshRenderData &mr);
320
321gpu::VertBufPtr extract_vert_index_subdiv(const DRWSubdivCache &subdiv_cache,
322 const MeshRenderData &mr);
323gpu::VertBufPtr extract_edge_index_subdiv(const DRWSubdivCache &subdiv_cache,
324 const MeshRenderData &mr);
325gpu::VertBufPtr extract_face_index_subdiv(const DRWSubdivCache &subdiv_cache,
326 const MeshRenderData &mr);
327
328gpu::VertBufPtr extract_weights(const MeshRenderData &mr, const MeshBatchCache &cache);
329gpu::VertBufPtr extract_weights_subdiv(const MeshRenderData &mr,
330 const DRWSubdivCache &subdiv_cache,
331 const MeshBatchCache &cache);
332
333gpu::IndexBufPtr extract_face_dots(const MeshRenderData &mr);
334
335gpu::VertBufPtr extract_face_dots_uv(const MeshRenderData &mr);
336gpu::VertBufPtr extract_face_dots_edituv_data(const MeshRenderData &mr);
337
338gpu::IndexBufPtr extract_lines_paint_mask(const MeshRenderData &mr);
339gpu::IndexBufPtr extract_lines_paint_mask_subdiv(const MeshRenderData &mr,
340 const DRWSubdivCache &subdiv_cache);
341
342gpu::IndexBufPtr extract_lines_adjacency(const MeshRenderData &mr, bool &r_is_manifold);
343gpu::IndexBufPtr extract_lines_adjacency_subdiv(const DRWSubdivCache &subdiv_cache,
344 bool &r_is_manifold);
345
346gpu::VertBufPtr extract_uv_maps(const MeshRenderData &mr, const MeshBatchCache &cache);
347gpu::VertBufPtr extract_uv_maps_subdiv(const DRWSubdivCache &subdiv_cache,
348 const MeshBatchCache &cache);
349gpu::VertBufPtr extract_edituv_stretch_area(const MeshRenderData &mr,
350 float &tot_area,
351 float &tot_uv_area);
352gpu::VertBufPtr extract_edituv_stretch_area_subdiv(const MeshRenderData &mr,
353 const DRWSubdivCache &subdiv_cache,
354 float &tot_area,
355 float &tot_uv_area);
356gpu::VertBufPtr extract_edituv_stretch_angle(const MeshRenderData &mr);
357gpu::VertBufPtr extract_edituv_stretch_angle_subdiv(const MeshRenderData &mr,
358 const DRWSubdivCache &subdiv_cache,
359 const MeshBatchCache &cache);
360gpu::VertBufPtr extract_edituv_data(const MeshRenderData &mr);
361gpu::VertBufPtr extract_edituv_data_subdiv(const MeshRenderData &mr,
362 const DRWSubdivCache &subdiv_cache);
363gpu::IndexBufPtr extract_edituv_tris(const MeshRenderData &mr, bool edit_uvs);
364gpu::IndexBufPtr extract_edituv_tris_subdiv(const MeshRenderData &mr,
365 const DRWSubdivCache &subdiv_cache);
366
367enum class UvExtractionMode : int8_t {
370 All,
371};
372
373gpu::IndexBufPtr extract_edituv_lines(const MeshRenderData &mr, UvExtractionMode mode);
374gpu::IndexBufPtr extract_edituv_lines_subdiv(const MeshRenderData &mr,
375 const DRWSubdivCache &subdiv_cache,
376 UvExtractionMode mode);
377gpu::IndexBufPtr extract_edituv_points(const MeshRenderData &mr);
378gpu::IndexBufPtr extract_edituv_points_subdiv(const MeshRenderData &mr,
379 const DRWSubdivCache &subdiv_cache);
380gpu::IndexBufPtr extract_edituv_face_dots(const MeshRenderData &mr);
381
382gpu::VertBufPtr extract_mesh_analysis(const MeshRenderData &mr, const float4x4 &object_to_world);
383
384gpu::VertBufPtr extract_skin_roots(const MeshRenderData &mr);
385
386gpu::VertBufPtr extract_sculpt_data(const MeshRenderData &mr);
387gpu::VertBufPtr extract_sculpt_data_subdiv(const MeshRenderData &mr,
388 const DRWSubdivCache &subdiv_cache);
389
390gpu::VertBufPtr extract_orco(const MeshRenderData &mr);
391
392gpu::VertBufPtr extract_attribute(const MeshRenderData &mr, StringRef name);
393gpu::VertBufPtr extract_attribute_subdiv(const MeshRenderData &mr,
394 const DRWSubdivCache &subdiv_cache,
396gpu::VertBufPtr extract_attr_viewer(const MeshRenderData &mr);
397
398gpu::VertBufPtr extract_paint_overlay_flags(const MeshRenderData &mr);
399gpu::VertBufPtr extract_paint_overlay_flags_subdiv(const MeshRenderData &mr,
400 const DRWSubdivCache &subdiv_cache);
401
402} // namespace blender::draw
#define ORIGINDEX_NONE
General operations, lookup, etc. for blender objects.
const Mesh * BKE_object_get_editmesh_eval_final(const Object *object)
#define BLI_INLINE
unsigned char uchar
#define BM_ELEM_CD_GET_FLOAT_P(ele, offset)
#define BM_elem_index_get(ele)
BLI_INLINE BMEdge * BM_edge_at_index(BMesh *bm, const int index)
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
BLI_INLINE BMFace * BM_face_at_index(BMesh *bm, const int index)
ATTR_WARN_UNUSED_RESULT const BMLoop * l
constexpr IndexRange index_range() const
Definition BLI_span.hh:401
uint pos
int face_corner_next(const IndexRange face, const int corner)
Definition BKE_mesh.hh:315
const CustomData & mesh_cd_ldata_get_from_mesh(const Mesh &mesh)
BLI_INLINE BMFace * bm_original_face_get(const MeshRenderData &mr, int idx)
void mesh_render_data_update_face_normals(MeshRenderData &mr)
BLI_INLINE BMVert * bm_original_vert_get(const MeshRenderData &mr, int idx)
BLI_INLINE BMEdge * bm_original_edge_get(const MeshRenderData &mr, int idx)
void mesh_render_data_loop_flag(const MeshRenderData &mr, const BMLoop *l, const BMUVOffsets &offsets, EditLoopData &eattr)
const CustomData & mesh_cd_edata_get_from_mesh(const Mesh &mesh)
uint2 edge_from_corners(const IndexRange face, const int corner)
void mesh_render_data_face_flag(const MeshRenderData &mr, const BMFace *efa, const BMUVOffsets &offsets, EditLoopData &eattr)
void mesh_render_data_loop_edge_flag(const MeshRenderData &mr, const BMLoop *l, const BMUVOffsets &offsets, EditLoopData &eattr)
const Mesh & editmesh_final_or_this(const Object &object, const Mesh &mesh)
BLI_INLINE const float * bm_face_no_get(const MeshRenderData &mr, const BMFace *efa)
void mesh_render_data_update_corner_normals(MeshRenderData &mr)
const SortedFaceData & mesh_render_data_faces_sorted_ensure(const MeshRenderData &mr, MeshBufferCache &cache)
const CustomData & mesh_cd_vdata_get_from_mesh(const Mesh &mesh)
BLI_INLINE const float * bm_vert_no_get(const MeshRenderData &mr, const BMVert *eve)
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)
void extract_mesh_loose_edge_data(const Span< T > vert_data, const Span< int2 > edges, const Span< int > loose_edges, MutableSpan< T > gpu_data)
BLI_INLINE const float * bm_vert_co_get(const MeshRenderData &mr, const BMVert *eve)
const CustomData & mesh_cd_pdata_get_from_mesh(const Mesh &mesh)
std::unique_ptr< IndexBuf, IndexBufDeleter > IndexBufPtr
std::unique_ptr< gpu::VertBuf, gpu::VertBufDeleter > VertBufPtr
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:93
VecBase< uint32_t, 2 > uint2
MatBase< float, 4, 4 > float4x4
const char * name
float no[3]
float co[3]
float no[3]
MeshRuntimeHandle * runtime
bke::EditMeshData * edit_data
const ToolSettings * toolsettings
VArraySpan< bool > select_vert
VArraySpan< bool > sharp_faces
VArraySpan< bool > select_poly
VArraySpan< bool > select_edge
VArraySpan< int > material_indices
OffsetIndices< int > faces
bke::MeshNormalDomain normals_domain