Blender V4.5
extract_mesh_vbo_edituv_data.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_mesh.hh"
10
11#include "extract_mesh.hh"
12
13#include "draw_cache_impl.hh"
14
15#include "draw_subdivision.hh"
16
17namespace blender::draw {
18
19/* ---------------------------------------------------------------------- */
22
24{
25 static const GPUVertFormat format = []() {
27 /* WARNING: Adjust #EditLoopData struct accordingly. */
30 return format;
31 }();
32 return format;
33}
34
36{
37 const BMesh &bm = *mr.bm;
38 const BMUVOffsets offsets = BM_uv_map_offsets_get(&bm);
39 threading::parallel_for(IndexRange(bm.totface), 2048, [&](const IndexRange range) {
40 for (const int face_index : range) {
41 const BMFace &face = *BM_face_at_index(&const_cast<BMesh &>(bm), face_index);
42 const BMLoop *loop = BM_FACE_FIRST_LOOP(&face);
43 for ([[maybe_unused]] const int i : IndexRange(face.len)) {
44 const int index = BM_elem_index_get(loop);
45 EditLoopData &value = vbo_data[index];
46 value = {};
47 mesh_render_data_loop_flag(mr, loop, offsets, value);
48 mesh_render_data_face_flag(mr, &face, offsets, value);
49 mesh_render_data_loop_edge_flag(mr, loop, offsets, value);
50 loop = loop->next;
51 }
52 }
53 });
54}
55
57{
58 const BMesh &bm = *mr.bm;
59 const BMUVOffsets offsets = BM_uv_map_offsets_get(&bm);
60 const OffsetIndices faces = mr.faces;
61 const Span<int> corner_verts = mr.corner_verts;
62 const Span<int> corner_edges = mr.corner_edges;
63 threading::parallel_for(faces.index_range(), 2048, [&](const IndexRange range) {
64 for (const int face_index : range) {
65 const IndexRange face = faces[face_index];
66 BMFace *face_orig = bm_original_face_get(mr, face_index);
67 if (!face_orig) {
68 vbo_data.slice(face).fill({});
69 continue;
70 }
71 for (const int corner : face) {
72 EditLoopData &value = vbo_data[corner];
73 value = {};
74 BMVert *vert = bm_original_vert_get(mr, corner_verts[corner]);
75 BMEdge *edge = bm_original_edge_get(mr, corner_edges[corner]);
76 if (edge && vert) {
77 /* Loop on an edge endpoint. */
78 BMLoop *l = BM_face_edge_share_loop(face_orig, edge);
79 mesh_render_data_loop_flag(mr, l, offsets, value);
80 mesh_render_data_loop_edge_flag(mr, l, offsets, value);
81 }
82 else {
83 if (edge == nullptr) {
84 /* Find if the loop's vert is not part of an edit edge.
85 * For this, we check if the previous loop was on an edge. */
86 const int corner_prev = bke::mesh::face_corner_prev(face, corner);
87 edge = bm_original_edge_get(mr, corner_edges[corner_prev]);
88 }
89 if (edge) {
90 /* Mapped points on an edge between two edit verts. */
91 BMLoop *l = BM_face_edge_share_loop(face_orig, edge);
92 mesh_render_data_loop_edge_flag(mr, l, offsets, value);
93 }
94 }
95 }
96 }
97 });
98}
99
101{
104 MutableSpan vbo_data = vbo->data<EditLoopData>();
105
107 extract_edituv_data_bm(mr, vbo_data);
108 }
109 else {
110 extract_edituv_data_mesh(mr, vbo_data);
111 }
112 return vbo;
113}
114
116 const BMUVOffsets &offsets,
117 const Span<int> subdiv_loop_vert_index,
118 const Span<int> subdiv_loop_edge_index,
119 const int subdiv_quad_index,
120 const BMFace *coarse_quad,
122{
123
124 uint start_loop_idx = subdiv_quad_index * 4;
125 uint end_loop_idx = (subdiv_quad_index + 1) * 4;
126 for (uint i = start_loop_idx; i < end_loop_idx; i++) {
127 const int vert_origindex = subdiv_loop_vert_index[i];
128 int edge_origindex = subdiv_loop_edge_index[i];
129
130 EditLoopData *edit_loop_data = &vbo_data[i];
131 memset(edit_loop_data, 0, sizeof(EditLoopData));
132
133 if (vert_origindex != -1 && edge_origindex != -1) {
134 BMEdge *eed = BM_edge_at_index(mr.bm, edge_origindex);
135 /* Loop on an edge endpoint. */
136 BMLoop *l = BM_face_edge_share_loop(const_cast<BMFace *>(coarse_quad), eed);
137 mesh_render_data_loop_flag(mr, l, offsets, *edit_loop_data);
138 mesh_render_data_loop_edge_flag(mr, l, offsets, *edit_loop_data);
139 }
140 else {
141 if (edge_origindex == -1) {
142 /* Find if the loop's vert is not part of an edit edge.
143 * For this, we check if the previous loop was on an edge. */
144 const uint loop_index_last = (i == start_loop_idx) ? end_loop_idx - 1 : i - 1;
145 edge_origindex = subdiv_loop_edge_index[loop_index_last];
146 }
147 if (edge_origindex != -1) {
148 /* Mapped points on an edge between two edit verts. */
149 BMEdge *eed = BM_edge_at_index(mr.bm, edge_origindex);
150 BMLoop *l = BM_face_edge_share_loop(const_cast<BMFace *>(coarse_quad), eed);
151 mesh_render_data_loop_edge_flag(mr, l, offsets, *edit_loop_data);
152 }
153 }
154
155 mesh_render_data_face_flag(mr, coarse_quad, offsets, *edit_loop_data);
156 }
157}
158
160 const DRWSubdivCache &subdiv_cache,
162{
163 const int corners_num = subdiv_cache.num_subdiv_loops;
164 const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index, corners_num);
165 const Span<int> subdiv_loop_vert_index = subdiv_cache.verts_orig_index->data<int>();
166 /* NOTE: #subdiv_loop_edge_index already has the origindex layer baked in. */
167 const Span<int> subdiv_loop_edge_index = subdiv_cache.edges_orig_index->data<int>();
168
169 const BMUVOffsets offsets = BM_uv_map_offsets_get(mr.bm);
170 threading::parallel_for(IndexRange(subdiv_cache.num_subdiv_quads), 2048, [&](IndexRange range) {
171 for (const int subdiv_quad : range) {
172 const int coarse_face = subdiv_loop_face_index[subdiv_quad * 4];
173 extract_edituv_data_iter_subdiv_bm(mr,
174 offsets,
175 subdiv_loop_vert_index,
176 subdiv_loop_edge_index,
177 subdiv_quad,
178 BM_face_at_index(mr.bm, coarse_face),
179 vbo_data);
180 }
181 });
182}
183
185 const DRWSubdivCache &subdiv_cache,
187{
188 const int corners_num = subdiv_cache.num_subdiv_loops;
189 const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index, corners_num);
190 const Span<int> subdiv_loop_vert_index = subdiv_cache.verts_orig_index->data<int>();
191 /* NOTE: #subdiv_loop_edge_index already has the origindex layer baked in. */
192 const Span<int> subdiv_loop_edge_index = subdiv_cache.edges_orig_index->data<int>();
193
194 const BMUVOffsets offsets = BM_uv_map_offsets_get(mr.bm);
195 threading::parallel_for(IndexRange(subdiv_cache.num_subdiv_quads), 2048, [&](IndexRange range) {
196 for (const int subdiv_quad : range) {
197 const int coarse_face = subdiv_loop_face_index[subdiv_quad * 4];
198 extract_edituv_data_iter_subdiv_bm(mr,
199 offsets,
200 subdiv_loop_vert_index,
201 subdiv_loop_edge_index,
202 subdiv_quad,
203 bm_original_face_get(mr, coarse_face),
204 vbo_data);
205 }
206 });
207}
208
210 const DRWSubdivCache &subdiv_cache)
211{
213 const int size = subdiv_cache.num_subdiv_loops;
215 MutableSpan vbo_data = vbo->data<EditLoopData>();
216
218 extract_edituv_subdiv_data_bm(mr, subdiv_cache, vbo_data);
219 }
220 else {
221 extract_edituv_subdiv_data_mesh(mr, subdiv_cache, vbo_data);
222 }
223 return vbo;
224}
225
226} // namespace blender::draw
unsigned int uint
#define GPU_vertbuf_create_with_format(format)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
@ GPU_FETCH_INT
void GPU_vertformat_alias_add(GPUVertFormat *, blender::StringRef alias)
uint GPU_vertformat_attr_add(GPUVertFormat *, blender::StringRef name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_U8
BMesh * bm
BLI_INLINE BMEdge * BM_edge_at_index(BMesh *bm, const int index)
BMLoop * BM_face_edge_share_loop(BMFace *f, BMEdge *e)
Return the Loop Shared by Face and Edge.
ATTR_WARN_UNUSED_RESULT const BMLoop * l
BMUVOffsets BM_uv_map_offsets_get(const BMesh *bm)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
constexpr T * data() const
Definition BLI_span.hh:539
MutableSpan< T > data()
Extraction of Mesh data into VBO to feed to GPU.
format
static char faces[256]
static void extract_edituv_data_bm(const MeshRenderData &mr, MutableSpan< EditLoopData > vbo_data)
void mesh_render_data_loop_flag(const MeshRenderData &mr, const BMLoop *l, const BMUVOffsets &offsets, EditLoopData &eattr)
static const GPUVertFormat & edituv_data_format()
static void extract_edituv_data_mesh(const MeshRenderData &mr, MutableSpan< EditLoopData > vbo_data)
void mesh_render_data_face_flag(const MeshRenderData &mr, const BMFace *efa, const BMUVOffsets &offsets, EditLoopData &eattr)
static void extract_edituv_subdiv_data_mesh(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, MutableSpan< EditLoopData > vbo_data)
void mesh_render_data_loop_edge_flag(const MeshRenderData &mr, const BMLoop *l, const BMUVOffsets &offsets, EditLoopData &eattr)
gpu::VertBufPtr extract_edituv_data(const MeshRenderData &mr)
static void extract_edituv_subdiv_data_bm(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, MutableSpan< EditLoopData > vbo_data)
static void extract_edituv_data_iter_subdiv_bm(const MeshRenderData &mr, const BMUVOffsets &offsets, const Span< int > subdiv_loop_vert_index, const Span< int > subdiv_loop_edge_index, const int subdiv_quad_index, const BMFace *coarse_quad, MutableSpan< EditLoopData > vbo_data)
gpu::VertBufPtr extract_edituv_data_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
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
OffsetIndices< int > faces
i
Definition text_draw.cc:230