1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 */
16
17 /** \file
18 * \ingroup bli
19 */
20
21 #include "MEM_guardedalloc.h"
22
23 #include "BLI_buffer.h"
24 #include "BLI_ghash.h"
25 #include "BLI_heap_simple.h"
26 #include "BLI_math.h"
27 #include "BLI_memarena.h"
28 #include "BLI_utildefines.h"
29
30 #include "BKE_DerivedMesh.h"
31 #include "BKE_ccg.h"
32 #include "BKE_pbvh.h"
33
34 #include "GPU_buffers.h"
35
36 #include "bmesh.h"
37 #include "pbvh_intern.h"
38
39 /* Avoid skinny faces */
40 #define USE_EDGEQUEUE_EVEN_SUBDIV
41 #ifdef USE_EDGEQUEUE_EVEN_SUBDIV
42 # include "BKE_global.h"
43 #endif
44
45 /* Support for only operating on front-faces */
46 #define USE_EDGEQUEUE_FRONTFACE
47
48 /* don't add edges into the queue multiple times */
49 #define USE_EDGEQUEUE_TAG
50 /**
51 * Ensure we don't have dirty tags for the edge queue, and that they are left cleared.
52 * (slow, even for debug mode, so leave disabled for now).
53 */
54 #if defined(USE_EDGEQUEUE_TAG) && 0
55 # if !defined(NDEBUG)
56 # define USE_EDGEQUEUE_TAG_VERIFY
57 # endif
58 #endif
59
60 // #define USE_VERIFY
61
62 #ifdef USE_VERIFY
63 static void pbvh_bmesh_verify(PBVH *pbvh);
64 #endif
65
66 /** \name BMesh Utility API
67 *
68 * Use some local functions which assume triangles.
69 * \{ */
70
71 /**
72 * Typically using BM_LOOPS_OF_VERT and BM_FACES_OF_VERT iterators are fine,
73 * however this is an area where performance matters so do it in-line.
74 *
75 * Take care since 'break' won't works as expected within these macros!
76 */
77
78 #define BM_LOOPS_OF_VERT_ITER_BEGIN(l_iter_radial_, v_) \
79 { \
80 struct { \
81 BMVert *v; \
82 BMEdge *e_iter, *e_first; \
83 BMLoop *l_iter_radial; \
84 } _iter; \
85 _iter.v = v_; \
86 if (_iter.v->e) { \
87 _iter.e_iter = _iter.e_first = _iter.v->e; \
88 do { \
89 if (_iter.e_iter->l) { \
90 _iter.l_iter_radial = _iter.e_iter->l; \
91 do { \
92 if (_iter.l_iter_radial->v == _iter.v) { \
93 l_iter_radial_ = _iter.l_iter_radial;
94
95 #define BM_LOOPS_OF_VERT_ITER_END \
96 } \
97 } \
98 while ((_iter.l_iter_radial = _iter.l_iter_radial->radial_next) != _iter.e_iter->l) \
99 ; \
100 } \
101 } \
102 while ((_iter.e_iter = BM_DISK_EDGE_NEXT(_iter.e_iter, _iter.v)) != _iter.e_first) \
103 ; \
104 } \
105 } \
106 ((void)0)
107
108 #define BM_FACES_OF_VERT_ITER_BEGIN(f_iter_, v_) \
109 { \
110 BMLoop *l_iter_radial_; \
111 BM_LOOPS_OF_VERT_ITER_BEGIN (l_iter_radial_, v_) { \
112 f_iter_ = l_iter_radial_->f;
113
114 #define BM_FACES_OF_VERT_ITER_END \
115 } \
116 BM_LOOPS_OF_VERT_ITER_END; \
117 } \
118 ((void)0)
119
bm_edges_from_tri(BMesh * bm,BMVert * v_tri[3],BMEdge * e_tri[3])120 static void bm_edges_from_tri(BMesh *bm, BMVert *v_tri[3], BMEdge *e_tri[3])
121 {
122 e_tri[0] = BM_edge_create(bm, v_tri[0], v_tri[1], NULL, BM_CREATE_NO_DOUBLE);
123 e_tri[1] = BM_edge_create(bm, v_tri[1], v_tri[2], NULL, BM_CREATE_NO_DOUBLE);
124 e_tri[2] = BM_edge_create(bm, v_tri[2], v_tri[0], NULL, BM_CREATE_NO_DOUBLE);
125 }
126
bm_face_as_array_index_tri(BMFace * f,int r_index[3])127 BLI_INLINE void bm_face_as_array_index_tri(BMFace *f, int r_index[3])
128 {
129 BMLoop *l = BM_FACE_FIRST_LOOP(f);
130
131 BLI_assert(f->len == 3);
132
133 r_index[0] = BM_elem_index_get(l->v);
134 l = l->next;
135 r_index[1] = BM_elem_index_get(l->v);
136 l = l->next;
137 r_index[2] = BM_elem_index_get(l->v);
138 }
139
140 /**
141 * A version of #BM_face_exists, optimized for triangles
142 * when we know the loop and the opposite vertex.
143 *
144 * Check if any triangle is formed by (l_radial_first->v, l_radial_first->next->v, v_opposite),
145 * at either winding (since its a triangle no special checks are needed).
146 *
147 * <pre>
148 * l_radial_first->v & l_radial_first->next->v
149 * +---+
150 * | /
151 * | /
152 * + v_opposite
153 * </pre>
154 *
155 * Its assumed that \a l_radial_first is never forming the target face.
156 */
bm_face_exists_tri_from_loop_vert(BMLoop * l_radial_first,BMVert * v_opposite)157 static BMFace *bm_face_exists_tri_from_loop_vert(BMLoop *l_radial_first, BMVert *v_opposite)
158 {
159 BLI_assert(
160 !ELEM(v_opposite, l_radial_first->v, l_radial_first->next->v, l_radial_first->prev->v));
161 if (l_radial_first->radial_next != l_radial_first) {
162 BMLoop *l_radial_iter = l_radial_first->radial_next;
163 do {
164 BLI_assert(l_radial_iter->f->len == 3);
165 if (l_radial_iter->prev->v == v_opposite) {
166 return l_radial_iter->f;
167 }
168 } while ((l_radial_iter = l_radial_iter->radial_next) != l_radial_first);
169 }
170 return NULL;
171 }
172
173 /**
174 * Uses a map of vertices to lookup the final target.
175 * References can't point to previous items (would cause infinite loop).
176 */
bm_vert_hash_lookup_chain(GHash * deleted_verts,BMVert * v)177 static BMVert *bm_vert_hash_lookup_chain(GHash *deleted_verts, BMVert *v)
178 {
179 while (true) {
180 BMVert **v_next_p = (BMVert **)BLI_ghash_lookup_p(deleted_verts, v);
181 if (v_next_p == NULL) {
182 /* not remapped*/
183 return v;
184 }
185 if (*v_next_p == NULL) {
186 /* removed and not remapped */
187 return NULL;
188 }
189
190 /* remapped */
191 v = *v_next_p;
192 }
193 }
194
195 /** \} */
196
197 /****************************** Building ******************************/
198
199 /* Update node data after splitting */
pbvh_bmesh_node_finalize(PBVH * pbvh,const int node_index,const int cd_vert_node_offset,const int cd_face_node_offset)200 static void pbvh_bmesh_node_finalize(PBVH *pbvh,
201 const int node_index,
202 const int cd_vert_node_offset,
203 const int cd_face_node_offset)
204 {
205 GSetIterator gs_iter;
206 PBVHNode *n = &pbvh->nodes[node_index];
207 bool has_visible = false;
208
209 /* Create vert hash sets */
210 n->bm_unique_verts = BLI_gset_ptr_new("bm_unique_verts");
211 n->bm_other_verts = BLI_gset_ptr_new("bm_other_verts");
212
213 BB_reset(&n->vb);
214
215 GSET_ITER (gs_iter, n->bm_faces) {
216 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
217
218 /* Update ownership of faces */
219 BM_ELEM_CD_SET_INT(f, cd_face_node_offset, node_index);
220
221 /* Update vertices */
222 BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
223 BMLoop *l_iter = l_first;
224
225 do {
226 BMVert *v = l_iter->v;
227 if (!BLI_gset_haskey(n->bm_unique_verts, v)) {
228 if (BM_ELEM_CD_GET_INT(v, cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
229 BLI_gset_add(n->bm_other_verts, v);
230 }
231 else {
232 BLI_gset_insert(n->bm_unique_verts, v);
233 BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, node_index);
234 }
235 }
236 /* Update node bounding box */
237 BB_expand(&n->vb, v->co);
238 } while ((l_iter = l_iter->next) != l_first);
239
240 if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
241 has_visible = true;
242 }
243 }
244
245 BLI_assert(n->vb.bmin[0] <= n->vb.bmax[0] && n->vb.bmin[1] <= n->vb.bmax[1] &&
246 n->vb.bmin[2] <= n->vb.bmax[2]);
247
248 n->orig_vb = n->vb;
249
250 /* Build GPU buffers for new node and update vertex normals */
251 BKE_pbvh_node_mark_rebuild_draw(n);
252
253 BKE_pbvh_node_fully_hidden_set(n, !has_visible);
254 n->flag |= PBVH_UpdateNormals;
255 }
256
257 /* Recursively split the node if it exceeds the leaf_limit */
pbvh_bmesh_node_split(PBVH * pbvh,const BBC * bbc_array,int node_index)258 static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_index)
259 {
260 const int cd_vert_node_offset = pbvh->cd_vert_node_offset;
261 const int cd_face_node_offset = pbvh->cd_face_node_offset;
262 PBVHNode *n = &pbvh->nodes[node_index];
263
264 if (BLI_gset_len(n->bm_faces) <= pbvh->leaf_limit) {
265 /* Node limit not exceeded */
266 pbvh_bmesh_node_finalize(pbvh, node_index, cd_vert_node_offset, cd_face_node_offset);
267 return;
268 }
269
270 /* Calculate bounding box around primitive centroids */
271 BB cb;
272 BB_reset(&cb);
273 GSetIterator gs_iter;
274 GSET_ITER (gs_iter, n->bm_faces) {
275 const BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
276 const BBC *bbc = &bbc_array[BM_elem_index_get(f)];
277
278 BB_expand(&cb, bbc->bcentroid);
279 }
280
281 /* Find widest axis and its midpoint */
282 const int axis = BB_widest_axis(&cb);
283 const float mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
284
285 /* Add two new child nodes */
286 const int children = pbvh->totnode;
287 n->children_offset = children;
288 pbvh_grow_nodes(pbvh, pbvh->totnode + 2);
289
290 /* Array reallocated, update current node pointer */
291 n = &pbvh->nodes[node_index];
292
293 /* Initialize children */
294 PBVHNode *c1 = &pbvh->nodes[children], *c2 = &pbvh->nodes[children + 1];
295 c1->flag |= PBVH_Leaf;
296 c2->flag |= PBVH_Leaf;
297 c1->bm_faces = BLI_gset_ptr_new_ex("bm_faces", BLI_gset_len(n->bm_faces) / 2);
298 c2->bm_faces = BLI_gset_ptr_new_ex("bm_faces", BLI_gset_len(n->bm_faces) / 2);
299
300 /* Partition the parent node's faces between the two children */
301 GSET_ITER (gs_iter, n->bm_faces) {
302 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
303 const BBC *bbc = &bbc_array[BM_elem_index_get(f)];
304
305 if (bbc->bcentroid[axis] < mid) {
306 BLI_gset_insert(c1->bm_faces, f);
307 }
308 else {
309 BLI_gset_insert(c2->bm_faces, f);
310 }
311 }
312
313 /* Enforce at least one primitive in each node */
314 GSet *empty = NULL, *other;
315 if (BLI_gset_len(c1->bm_faces) == 0) {
316 empty = c1->bm_faces;
317 other = c2->bm_faces;
318 }
319 else if (BLI_gset_len(c2->bm_faces) == 0) {
320 empty = c2->bm_faces;
321 other = c1->bm_faces;
322 }
323 if (empty) {
324 GSET_ITER (gs_iter, other) {
325 void *key = BLI_gsetIterator_getKey(&gs_iter);
326 BLI_gset_insert(empty, key);
327 BLI_gset_remove(other, key, NULL);
328 break;
329 }
330 }
331
332 /* Clear this node */
333
334 /* Mark this node's unique verts as unclaimed */
335 if (n->bm_unique_verts) {
336 GSET_ITER (gs_iter, n->bm_unique_verts) {
337 BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
338 BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, DYNTOPO_NODE_NONE);
339 }
340 BLI_gset_free(n->bm_unique_verts, NULL);
341 }
342
343 /* Unclaim faces */
344 GSET_ITER (gs_iter, n->bm_faces) {
345 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
346 BM_ELEM_CD_SET_INT(f, cd_face_node_offset, DYNTOPO_NODE_NONE);
347 }
348 BLI_gset_free(n->bm_faces, NULL);
349
350 if (n->bm_other_verts) {
351 BLI_gset_free(n->bm_other_verts, NULL);
352 }
353
354 if (n->layer_disp) {
355 MEM_freeN(n->layer_disp);
356 }
357
358 n->bm_faces = NULL;
359 n->bm_unique_verts = NULL;
360 n->bm_other_verts = NULL;
361 n->layer_disp = NULL;
362
363 if (n->draw_buffers) {
364 GPU_pbvh_buffers_free(n->draw_buffers);
365 n->draw_buffers = NULL;
366 }
367 n->flag &= ~PBVH_Leaf;
368
369 /* Recurse */
370 pbvh_bmesh_node_split(pbvh, bbc_array, children);
371 pbvh_bmesh_node_split(pbvh, bbc_array, children + 1);
372
373 /* Array maybe reallocated, update current node pointer */
374 n = &pbvh->nodes[node_index];
375
376 /* Update bounding box */
377 BB_reset(&n->vb);
378 BB_expand_with_bb(&n->vb, &pbvh->nodes[n->children_offset].vb);
379 BB_expand_with_bb(&n->vb, &pbvh->nodes[n->children_offset + 1].vb);
380 n->orig_vb = n->vb;
381 }
382
383 /* Recursively split the node if it exceeds the leaf_limit */
pbvh_bmesh_node_limit_ensure(PBVH * pbvh,int node_index)384 static bool pbvh_bmesh_node_limit_ensure(PBVH *pbvh, int node_index)
385 {
386 GSet *bm_faces = pbvh->nodes[node_index].bm_faces;
387 const int bm_faces_size = BLI_gset_len(bm_faces);
388 if (bm_faces_size <= pbvh->leaf_limit) {
389 /* Node limit not exceeded */
390 return false;
391 }
392
393 /* For each BMFace, store the AABB and AABB centroid */
394 BBC *bbc_array = MEM_mallocN(sizeof(BBC) * bm_faces_size, "BBC");
395
396 GSetIterator gs_iter;
397 int i;
398 GSET_ITER_INDEX (gs_iter, bm_faces, i) {
399 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
400 BBC *bbc = &bbc_array[i];
401
402 BB_reset((BB *)bbc);
403 BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
404 BMLoop *l_iter = l_first;
405 do {
406 BB_expand((BB *)bbc, l_iter->v->co);
407 } while ((l_iter = l_iter->next) != l_first);
408 BBC_update_centroid(bbc);
409
410 /* so we can do direct lookups on 'bbc_array' */
411 BM_elem_index_set(f, i); /* set_dirty! */
412 }
413 /* Likely this is already dirty. */
414 pbvh->bm->elem_index_dirty |= BM_FACE;
415
416 pbvh_bmesh_node_split(pbvh, bbc_array, node_index);
417
418 MEM_freeN(bbc_array);
419
420 return true;
421 }
422
423 /**********************************************************************/
424
425 #if 0
426 static int pbvh_bmesh_node_offset_from_elem(PBVH *pbvh, BMElem *ele)
427 {
428 switch (ele->head.htype) {
429 case BM_VERT:
430 return pbvh->cd_vert_node_offset;
431 default:
432 BLI_assert(ele->head.htype == BM_FACE);
433 return pbvh->cd_face_node_offset;
434 }
435 }
436
437 static int pbvh_bmesh_node_index_from_elem(PBVH *pbvh, void *key)
438 {
439 const int cd_node_offset = pbvh_bmesh_node_offset_from_elem(pbvh, key);
440 const int node_index = BM_ELEM_CD_GET_INT((BMElem *)key, cd_node_offset);
441
442 BLI_assert(node_index != DYNTOPO_NODE_NONE);
443 BLI_assert(node_index < pbvh->totnode);
444 (void)pbvh;
445
446 return node_index;
447 }
448
449 static PBVHNode *pbvh_bmesh_node_from_elem(PBVH *pbvh, void *key)
450 {
451 return &pbvh->nodes[pbvh_bmesh_node_index_from_elem(pbvh, key)];
452 }
453
454 /* typecheck */
455 # define pbvh_bmesh_node_index_from_elem(pbvh, key) \
456 (CHECK_TYPE_ANY(key, BMFace *, BMVert *), pbvh_bmesh_node_index_from_elem(pbvh, key))
457 # define pbvh_bmesh_node_from_elem(pbvh, key) \
458 (CHECK_TYPE_ANY(key, BMFace *, BMVert *), pbvh_bmesh_node_from_elem(pbvh, key))
459 #endif
460
pbvh_bmesh_node_index_from_vert(PBVH * pbvh,const BMVert * key)461 BLI_INLINE int pbvh_bmesh_node_index_from_vert(PBVH *pbvh, const BMVert *key)
462 {
463 const int node_index = BM_ELEM_CD_GET_INT((const BMElem *)key, pbvh->cd_vert_node_offset);
464 BLI_assert(node_index != DYNTOPO_NODE_NONE);
465 BLI_assert(node_index < pbvh->totnode);
466 return node_index;
467 }
468
pbvh_bmesh_node_index_from_face(PBVH * pbvh,const BMFace * key)469 BLI_INLINE int pbvh_bmesh_node_index_from_face(PBVH *pbvh, const BMFace *key)
470 {
471 const int node_index = BM_ELEM_CD_GET_INT((const BMElem *)key, pbvh->cd_face_node_offset);
472 BLI_assert(node_index != DYNTOPO_NODE_NONE);
473 BLI_assert(node_index < pbvh->totnode);
474 return node_index;
475 }
476
pbvh_bmesh_node_from_vert(PBVH * pbvh,const BMVert * key)477 BLI_INLINE PBVHNode *pbvh_bmesh_node_from_vert(PBVH *pbvh, const BMVert *key)
478 {
479 return &pbvh->nodes[pbvh_bmesh_node_index_from_vert(pbvh, key)];
480 }
481
pbvh_bmesh_node_from_face(PBVH * pbvh,const BMFace * key)482 BLI_INLINE PBVHNode *pbvh_bmesh_node_from_face(PBVH *pbvh, const BMFace *key)
483 {
484 return &pbvh->nodes[pbvh_bmesh_node_index_from_face(pbvh, key)];
485 }
486
pbvh_bmesh_vert_create(PBVH * pbvh,int node_index,const float co[3],const float no[3],const int cd_vert_mask_offset)487 static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
488 int node_index,
489 const float co[3],
490 const float no[3],
491 const int cd_vert_mask_offset)
492 {
493 PBVHNode *node = &pbvh->nodes[node_index];
494
495 BLI_assert((pbvh->totnode == 1 || node_index) && node_index <= pbvh->totnode);
496
497 /* avoid initializing customdata because its quite involved */
498 BMVert *v = BM_vert_create(pbvh->bm, co, NULL, BM_CREATE_SKIP_CD);
499 CustomData_bmesh_set_default(&pbvh->bm->vdata, &v->head.data);
500
501 /* This value is logged below */
502 copy_v3_v3(v->no, no);
503
504 BLI_gset_insert(node->bm_unique_verts, v);
505 BM_ELEM_CD_SET_INT(v, pbvh->cd_vert_node_offset, node_index);
506
507 node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
508
509 /* Log the new vertex */
510 BM_log_vert_added(pbvh->bm_log, v, cd_vert_mask_offset);
511
512 return v;
513 }
514
515 /**
516 * \note Callers are responsible for checking if the face exists before adding.
517 */
pbvh_bmesh_face_create(PBVH * pbvh,int node_index,BMVert * v_tri[3],BMEdge * e_tri[3],const BMFace * f_example)518 static BMFace *pbvh_bmesh_face_create(
519 PBVH *pbvh, int node_index, BMVert *v_tri[3], BMEdge *e_tri[3], const BMFace *f_example)
520 {
521 PBVHNode *node = &pbvh->nodes[node_index];
522
523 /* ensure we never add existing face */
524 BLI_assert(!BM_face_exists(v_tri, 3));
525
526 BMFace *f = BM_face_create(pbvh->bm, v_tri, e_tri, 3, f_example, BM_CREATE_NOP);
527 f->head.hflag = f_example->head.hflag;
528
529 BLI_gset_insert(node->bm_faces, f);
530 BM_ELEM_CD_SET_INT(f, pbvh->cd_face_node_offset, node_index);
531
532 /* mark node for update */
533 node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals;
534 node->flag &= ~PBVH_FullyHidden;
535
536 /* Log the new face */
537 BM_log_face_added(pbvh->bm_log, f);
538
539 return f;
540 }
541
542 /* Return the number of faces in 'node' that use vertex 'v' */
543 #if 0
544 static int pbvh_bmesh_node_vert_use_count(PBVH *pbvh, PBVHNode *node, BMVert *v)
545 {
546 BMFace *f;
547 int count = 0;
548
549 BM_FACES_OF_VERT_ITER_BEGIN (f, v) {
550 PBVHNode *f_node = pbvh_bmesh_node_from_face(pbvh, f);
551 if (f_node == node) {
552 count++;
553 }
554 }
555 BM_FACES_OF_VERT_ITER_END;
556
557 return count;
558 }
559 #endif
560
561 #define pbvh_bmesh_node_vert_use_count_is_equal(pbvh, node, v, n) \
562 (pbvh_bmesh_node_vert_use_count_at_most(pbvh, node, v, (n) + 1) == n)
563
pbvh_bmesh_node_vert_use_count_at_most(PBVH * pbvh,PBVHNode * node,BMVert * v,const int count_max)564 static int pbvh_bmesh_node_vert_use_count_at_most(PBVH *pbvh,
565 PBVHNode *node,
566 BMVert *v,
567 const int count_max)
568 {
569 int count = 0;
570 BMFace *f;
571
572 BM_FACES_OF_VERT_ITER_BEGIN (f, v) {
573 PBVHNode *f_node = pbvh_bmesh_node_from_face(pbvh, f);
574 if (f_node == node) {
575 count++;
576 if (count == count_max) {
577 return count;
578 }
579 }
580 }
581 BM_FACES_OF_VERT_ITER_END;
582
583 return count;
584 }
585
586 /* Return a node that uses vertex 'v' other than its current owner */
pbvh_bmesh_vert_other_node_find(PBVH * pbvh,BMVert * v)587 static PBVHNode *pbvh_bmesh_vert_other_node_find(PBVH *pbvh, BMVert *v)
588 {
589 PBVHNode *current_node = pbvh_bmesh_node_from_vert(pbvh, v);
590 BMFace *f;
591
592 BM_FACES_OF_VERT_ITER_BEGIN (f, v) {
593 PBVHNode *f_node = pbvh_bmesh_node_from_face(pbvh, f);
594
595 if (f_node != current_node) {
596 return f_node;
597 }
598 }
599 BM_FACES_OF_VERT_ITER_END;
600
601 return NULL;
602 }
603
pbvh_bmesh_vert_ownership_transfer(PBVH * pbvh,PBVHNode * new_owner,BMVert * v)604 static void pbvh_bmesh_vert_ownership_transfer(PBVH *pbvh, PBVHNode *new_owner, BMVert *v)
605 {
606 PBVHNode *current_owner = pbvh_bmesh_node_from_vert(pbvh, v);
607 /* mark node for update */
608 current_owner->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
609
610 BLI_assert(current_owner != new_owner);
611
612 /* Remove current ownership */
613 BLI_gset_remove(current_owner->bm_unique_verts, v, NULL);
614
615 /* Set new ownership */
616 BM_ELEM_CD_SET_INT(v, pbvh->cd_vert_node_offset, new_owner - pbvh->nodes);
617 BLI_gset_insert(new_owner->bm_unique_verts, v);
618 BLI_gset_remove(new_owner->bm_other_verts, v, NULL);
619 BLI_assert(!BLI_gset_haskey(new_owner->bm_other_verts, v));
620
621 /* mark node for update */
622 new_owner->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
623 }
624
pbvh_bmesh_vert_remove(PBVH * pbvh,BMVert * v)625 static void pbvh_bmesh_vert_remove(PBVH *pbvh, BMVert *v)
626 {
627 /* never match for first time */
628 int f_node_index_prev = DYNTOPO_NODE_NONE;
629
630 PBVHNode *v_node = pbvh_bmesh_node_from_vert(pbvh, v);
631 BLI_gset_remove(v_node->bm_unique_verts, v, NULL);
632 BM_ELEM_CD_SET_INT(v, pbvh->cd_vert_node_offset, DYNTOPO_NODE_NONE);
633
634 /* Have to check each neighboring face's node */
635 BMFace *f;
636 BM_FACES_OF_VERT_ITER_BEGIN (f, v) {
637 const int f_node_index = pbvh_bmesh_node_index_from_face(pbvh, f);
638
639 /* faces often share the same node,
640 * quick check to avoid redundant #BLI_gset_remove calls */
641 if (f_node_index_prev != f_node_index) {
642 f_node_index_prev = f_node_index;
643
644 PBVHNode *f_node = &pbvh->nodes[f_node_index];
645 f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
646
647 /* Remove current ownership */
648 BLI_gset_remove(f_node->bm_other_verts, v, NULL);
649
650 BLI_assert(!BLI_gset_haskey(f_node->bm_unique_verts, v));
651 BLI_assert(!BLI_gset_haskey(f_node->bm_other_verts, v));
652 }
653 }
654 BM_FACES_OF_VERT_ITER_END;
655 }
656
pbvh_bmesh_face_remove(PBVH * pbvh,BMFace * f)657 static void pbvh_bmesh_face_remove(PBVH *pbvh, BMFace *f)
658 {
659 PBVHNode *f_node = pbvh_bmesh_node_from_face(pbvh, f);
660
661 /* Check if any of this face's vertices need to be removed
662 * from the node */
663 BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
664 BMLoop *l_iter = l_first;
665 do {
666 BMVert *v = l_iter->v;
667 if (pbvh_bmesh_node_vert_use_count_is_equal(pbvh, f_node, v, 1)) {
668 if (BLI_gset_haskey(f_node->bm_unique_verts, v)) {
669 /* Find a different node that uses 'v' */
670 PBVHNode *new_node;
671
672 new_node = pbvh_bmesh_vert_other_node_find(pbvh, v);
673 BLI_assert(new_node || BM_vert_face_count_is_equal(v, 1));
674
675 if (new_node) {
676 pbvh_bmesh_vert_ownership_transfer(pbvh, new_node, v);
677 }
678 }
679 else {
680 /* Remove from other verts */
681 BLI_gset_remove(f_node->bm_other_verts, v, NULL);
682 }
683 }
684 } while ((l_iter = l_iter->next) != l_first);
685
686 /* Remove face from node and top level */
687 BLI_gset_remove(f_node->bm_faces, f, NULL);
688 BM_ELEM_CD_SET_INT(f, pbvh->cd_face_node_offset, DYNTOPO_NODE_NONE);
689
690 /* Log removed face */
691 BM_log_face_removed(pbvh->bm_log, f);
692
693 /* mark node for update */
694 f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals;
695 }
696
pbvh_bmesh_edge_loops(BLI_Buffer * buf,BMEdge * e)697 static void pbvh_bmesh_edge_loops(BLI_Buffer *buf, BMEdge *e)
698 {
699 /* fast-path for most common case where an edge has 2 faces,
700 * no need to iterate twice.
701 * This assumes that the buffer */
702 BMLoop **data = buf->data;
703 BLI_assert(buf->alloc_count >= 2);
704 if (LIKELY(BM_edge_loop_pair(e, &data[0], &data[1]))) {
705 buf->count = 2;
706 }
707 else {
708 BLI_buffer_reinit(buf, BM_edge_face_count(e));
709 BM_iter_as_array(NULL, BM_LOOPS_OF_EDGE, e, buf->data, buf->count);
710 }
711 }
712
pbvh_bmesh_node_drop_orig(PBVHNode * node)713 static void pbvh_bmesh_node_drop_orig(PBVHNode *node)
714 {
715 if (node->bm_orco) {
716 MEM_freeN(node->bm_orco);
717 }
718 if (node->bm_ortri) {
719 MEM_freeN(node->bm_ortri);
720 }
721 node->bm_orco = NULL;
722 node->bm_ortri = NULL;
723 node->bm_tot_ortri = 0;
724 }
725
726 /****************************** EdgeQueue *****************************/
727
728 struct EdgeQueue;
729
730 typedef struct EdgeQueue {
731 HeapSimple *heap;
732 const float *center;
733 float center_proj[3]; /* for when we use projected coords. */
734 float radius_squared;
735 float limit_len_squared;
736 #ifdef USE_EDGEQUEUE_EVEN_SUBDIV
737 float limit_len;
738 #endif
739
740 bool (*edge_queue_tri_in_range)(const struct EdgeQueue *q, BMFace *f);
741
742 const float *view_normal;
743 #ifdef USE_EDGEQUEUE_FRONTFACE
744 unsigned int use_view_normal : 1;
745 #endif
746 } EdgeQueue;
747
748 typedef struct {
749 EdgeQueue *q;
750 BLI_mempool *pool;
751 BMesh *bm;
752 int cd_vert_mask_offset;
753 int cd_vert_node_offset;
754 int cd_face_node_offset;
755 } EdgeQueueContext;
756
757 /* only tag'd edges are in the queue */
758 #ifdef USE_EDGEQUEUE_TAG
759 # define EDGE_QUEUE_TEST(e) (BM_elem_flag_test((CHECK_TYPE_INLINE(e, BMEdge *), e), BM_ELEM_TAG))
760 # define EDGE_QUEUE_ENABLE(e) \
761 BM_elem_flag_enable((CHECK_TYPE_INLINE(e, BMEdge *), e), BM_ELEM_TAG)
762 # define EDGE_QUEUE_DISABLE(e) \
763 BM_elem_flag_disable((CHECK_TYPE_INLINE(e, BMEdge *), e), BM_ELEM_TAG)
764 #endif
765
766 #ifdef USE_EDGEQUEUE_TAG_VERIFY
767 /* simply check no edges are tagged
768 * (it's a requirement that edges enter and leave a clean tag state) */
pbvh_bmesh_edge_tag_verify(PBVH * pbvh)769 static void pbvh_bmesh_edge_tag_verify(PBVH *pbvh)
770 {
771 for (int n = 0; n < pbvh->totnode; n++) {
772 PBVHNode *node = &pbvh->nodes[n];
773 if (node->bm_faces) {
774 GSetIterator gs_iter;
775 GSET_ITER (gs_iter, node->bm_faces) {
776 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
777 BMEdge *e_tri[3];
778 BMLoop *l_iter;
779
780 BLI_assert(f->len == 3);
781 l_iter = BM_FACE_FIRST_LOOP(f);
782 e_tri[0] = l_iter->e;
783 l_iter = l_iter->next;
784 e_tri[1] = l_iter->e;
785 l_iter = l_iter->next;
786 e_tri[2] = l_iter->e;
787
788 BLI_assert((EDGE_QUEUE_TEST(e_tri[0]) == false) && (EDGE_QUEUE_TEST(e_tri[1]) == false) &&
789 (EDGE_QUEUE_TEST(e_tri[2]) == false));
790 }
791 }
792 }
793 }
794 #endif
795
edge_queue_tri_in_sphere(const EdgeQueue * q,BMFace * f)796 static bool edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
797 {
798 BMVert *v_tri[3];
799 float c[3];
800
801 /* Get closest point in triangle to sphere center */
802 BM_face_as_array_vert_tri(f, v_tri);
803
804 closest_on_tri_to_point_v3(c, q->center, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co);
805
806 /* Check if triangle intersects the sphere */
807 return len_squared_v3v3(q->center, c) <= q->radius_squared;
808 }
809
edge_queue_tri_in_circle(const EdgeQueue * q,BMFace * f)810 static bool edge_queue_tri_in_circle(const EdgeQueue *q, BMFace *f)
811 {
812 BMVert *v_tri[3];
813 float c[3];
814 float tri_proj[3][3];
815
816 /* Get closest point in triangle to sphere center */
817 BM_face_as_array_vert_tri(f, v_tri);
818
819 project_plane_normalized_v3_v3v3(tri_proj[0], v_tri[0]->co, q->view_normal);
820 project_plane_normalized_v3_v3v3(tri_proj[1], v_tri[1]->co, q->view_normal);
821 project_plane_normalized_v3_v3v3(tri_proj[2], v_tri[2]->co, q->view_normal);
822
823 closest_on_tri_to_point_v3(c, q->center_proj, tri_proj[0], tri_proj[1], tri_proj[2]);
824
825 /* Check if triangle intersects the sphere */
826 return len_squared_v3v3(q->center_proj, c) <= q->radius_squared;
827 }
828
829 /* Return true if the vertex mask is less than 1.0, false otherwise */
check_mask(EdgeQueueContext * eq_ctx,BMVert * v)830 static bool check_mask(EdgeQueueContext *eq_ctx, BMVert *v)
831 {
832 return BM_ELEM_CD_GET_FLOAT(v, eq_ctx->cd_vert_mask_offset) < 1.0f;
833 }
834
edge_queue_insert(EdgeQueueContext * eq_ctx,BMEdge * e,float priority)835 static void edge_queue_insert(EdgeQueueContext *eq_ctx, BMEdge *e, float priority)
836 {
837 /* Don't let topology update affect fully masked vertices. This used to
838 * have a 50% mask cutoff, with the reasoning that you can't do a 50%
839 * topology update. But this gives an ugly border in the mesh. The mask
840 * should already make the brush move the vertices only 50%, which means
841 * that topology updates will also happen less frequent, that should be
842 * enough. */
843 if (((eq_ctx->cd_vert_mask_offset == -1) ||
844 (check_mask(eq_ctx, e->v1) || check_mask(eq_ctx, e->v2))) &&
845 !(BM_elem_flag_test_bool(e->v1, BM_ELEM_HIDDEN) ||
846 BM_elem_flag_test_bool(e->v2, BM_ELEM_HIDDEN))) {
847 BMVert **pair = BLI_mempool_alloc(eq_ctx->pool);
848 pair[0] = e->v1;
849 pair[1] = e->v2;
850 BLI_heapsimple_insert(eq_ctx->q->heap, priority, pair);
851 #ifdef USE_EDGEQUEUE_TAG
852 BLI_assert(EDGE_QUEUE_TEST(e) == false);
853 EDGE_QUEUE_ENABLE(e);
854 #endif
855 }
856 }
857
long_edge_queue_edge_add(EdgeQueueContext * eq_ctx,BMEdge * e)858 static void long_edge_queue_edge_add(EdgeQueueContext *eq_ctx, BMEdge *e)
859 {
860 #ifdef USE_EDGEQUEUE_TAG
861 if (EDGE_QUEUE_TEST(e) == false)
862 #endif
863 {
864 const float len_sq = BM_edge_calc_length_squared(e);
865 if (len_sq > eq_ctx->q->limit_len_squared) {
866 edge_queue_insert(eq_ctx, e, -len_sq);
867 }
868 }
869 }
870
871 #ifdef USE_EDGEQUEUE_EVEN_SUBDIV
long_edge_queue_edge_add_recursive(EdgeQueueContext * eq_ctx,BMLoop * l_edge,BMLoop * l_end,const float len_sq,float limit_len)872 static void long_edge_queue_edge_add_recursive(
873 EdgeQueueContext *eq_ctx, BMLoop *l_edge, BMLoop *l_end, const float len_sq, float limit_len)
874 {
875 BLI_assert(len_sq > square_f(limit_len));
876
877 # ifdef USE_EDGEQUEUE_FRONTFACE
878 if (eq_ctx->q->use_view_normal) {
879 if (dot_v3v3(l_edge->f->no, eq_ctx->q->view_normal) < 0.0f) {
880 return;
881 }
882 }
883 # endif
884
885 # ifdef USE_EDGEQUEUE_TAG
886 if (EDGE_QUEUE_TEST(l_edge->e) == false)
887 # endif
888 {
889 edge_queue_insert(eq_ctx, l_edge->e, -len_sq);
890 }
891
892 /* temp support previous behavior! */
893 if (UNLIKELY(G.debug_value == 1234)) {
894 return;
895 }
896
897 if ((l_edge->radial_next != l_edge)) {
898 /* How much longer we need to be to consider for subdividing
899 * (avoids subdividing faces which are only *slightly* skinny) */
900 # define EVEN_EDGELEN_THRESHOLD 1.2f
901 /* How much the limit increases per recursion
902 * (avoids performing subdivisions too far away). */
903 # define EVEN_GENERATION_SCALE 1.6f
904
905 const float len_sq_cmp = len_sq * EVEN_EDGELEN_THRESHOLD;
906
907 limit_len *= EVEN_GENERATION_SCALE;
908 const float limit_len_sq = square_f(limit_len);
909
910 BMLoop *l_iter = l_edge;
911 do {
912 BMLoop *l_adjacent[2] = {l_iter->next, l_iter->prev};
913 for (int i = 0; i < ARRAY_SIZE(l_adjacent); i++) {
914 float len_sq_other = BM_edge_calc_length_squared(l_adjacent[i]->e);
915 if (len_sq_other > max_ff(len_sq_cmp, limit_len_sq)) {
916 // edge_queue_insert(eq_ctx, l_adjacent[i]->e, -len_sq_other);
917 long_edge_queue_edge_add_recursive(
918 eq_ctx, l_adjacent[i]->radial_next, l_adjacent[i], len_sq_other, limit_len);
919 }
920 }
921 } while ((l_iter = l_iter->radial_next) != l_end);
922
923 # undef EVEN_EDGELEN_THRESHOLD
924 # undef EVEN_GENERATION_SCALE
925 }
926 }
927 #endif /* USE_EDGEQUEUE_EVEN_SUBDIV */
928
short_edge_queue_edge_add(EdgeQueueContext * eq_ctx,BMEdge * e)929 static void short_edge_queue_edge_add(EdgeQueueContext *eq_ctx, BMEdge *e)
930 {
931 #ifdef USE_EDGEQUEUE_TAG
932 if (EDGE_QUEUE_TEST(e) == false)
933 #endif
934 {
935 const float len_sq = BM_edge_calc_length_squared(e);
936 if (len_sq < eq_ctx->q->limit_len_squared) {
937 edge_queue_insert(eq_ctx, e, len_sq);
938 }
939 }
940 }
941
long_edge_queue_face_add(EdgeQueueContext * eq_ctx,BMFace * f)942 static void long_edge_queue_face_add(EdgeQueueContext *eq_ctx, BMFace *f)
943 {
944 #ifdef USE_EDGEQUEUE_FRONTFACE
945 if (eq_ctx->q->use_view_normal) {
946 if (dot_v3v3(f->no, eq_ctx->q->view_normal) < 0.0f) {
947 return;
948 }
949 }
950 #endif
951
952 if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, f)) {
953 /* Check each edge of the face */
954 BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
955 BMLoop *l_iter = l_first;
956 do {
957 #ifdef USE_EDGEQUEUE_EVEN_SUBDIV
958 const float len_sq = BM_edge_calc_length_squared(l_iter->e);
959 if (len_sq > eq_ctx->q->limit_len_squared) {
960 long_edge_queue_edge_add_recursive(
961 eq_ctx, l_iter->radial_next, l_iter, len_sq, eq_ctx->q->limit_len);
962 }
963 #else
964 long_edge_queue_edge_add(eq_ctx, l_iter->e);
965 #endif
966 } while ((l_iter = l_iter->next) != l_first);
967 }
968 }
969
short_edge_queue_face_add(EdgeQueueContext * eq_ctx,BMFace * f)970 static void short_edge_queue_face_add(EdgeQueueContext *eq_ctx, BMFace *f)
971 {
972 #ifdef USE_EDGEQUEUE_FRONTFACE
973 if (eq_ctx->q->use_view_normal) {
974 if (dot_v3v3(f->no, eq_ctx->q->view_normal) < 0.0f) {
975 return;
976 }
977 }
978 #endif
979
980 if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, f)) {
981 BMLoop *l_iter;
982 BMLoop *l_first;
983
984 /* Check each edge of the face */
985 l_iter = l_first = BM_FACE_FIRST_LOOP(f);
986 do {
987 short_edge_queue_edge_add(eq_ctx, l_iter->e);
988 } while ((l_iter = l_iter->next) != l_first);
989 }
990 }
991
992 /* Create a priority queue containing vertex pairs connected by a long
993 * edge as defined by PBVH.bm_max_edge_len.
994 *
995 * Only nodes marked for topology update are checked, and in those
996 * nodes only edges used by a face intersecting the (center, radius)
997 * sphere are checked.
998 *
999 * The highest priority (lowest number) is given to the longest edge.
1000 */
long_edge_queue_create(EdgeQueueContext * eq_ctx,PBVH * pbvh,const float center[3],const float view_normal[3],float radius,const bool use_frontface,const bool use_projected)1001 static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
1002 PBVH *pbvh,
1003 const float center[3],
1004 const float view_normal[3],
1005 float radius,
1006 const bool use_frontface,
1007 const bool use_projected)
1008 {
1009 eq_ctx->q->heap = BLI_heapsimple_new();
1010 eq_ctx->q->center = center;
1011 eq_ctx->q->radius_squared = radius * radius;
1012 eq_ctx->q->limit_len_squared = pbvh->bm_max_edge_len * pbvh->bm_max_edge_len;
1013 #ifdef USE_EDGEQUEUE_EVEN_SUBDIV
1014 eq_ctx->q->limit_len = pbvh->bm_max_edge_len;
1015 #endif
1016
1017 eq_ctx->q->view_normal = view_normal;
1018
1019 #ifdef USE_EDGEQUEUE_FRONTFACE
1020 eq_ctx->q->use_view_normal = use_frontface;
1021 #else
1022 UNUSED_VARS(use_frontface);
1023 #endif
1024
1025 if (use_projected) {
1026 eq_ctx->q->edge_queue_tri_in_range = edge_queue_tri_in_circle;
1027 project_plane_normalized_v3_v3v3(eq_ctx->q->center_proj, center, view_normal);
1028 }
1029 else {
1030 eq_ctx->q->edge_queue_tri_in_range = edge_queue_tri_in_sphere;
1031 }
1032
1033 #ifdef USE_EDGEQUEUE_TAG_VERIFY
1034 pbvh_bmesh_edge_tag_verify(pbvh);
1035 #endif
1036
1037 for (int n = 0; n < pbvh->totnode; n++) {
1038 PBVHNode *node = &pbvh->nodes[n];
1039
1040 /* Check leaf nodes marked for topology update */
1041 if ((node->flag & PBVH_Leaf) && (node->flag & PBVH_UpdateTopology) &&
1042 !(node->flag & PBVH_FullyHidden)) {
1043 GSetIterator gs_iter;
1044
1045 /* Check each face */
1046 GSET_ITER (gs_iter, node->bm_faces) {
1047 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
1048
1049 long_edge_queue_face_add(eq_ctx, f);
1050 }
1051 }
1052 }
1053 }
1054
1055 /* Create a priority queue containing vertex pairs connected by a
1056 * short edge as defined by PBVH.bm_min_edge_len.
1057 *
1058 * Only nodes marked for topology update are checked, and in those
1059 * nodes only edges used by a face intersecting the (center, radius)
1060 * sphere are checked.
1061 *
1062 * The highest priority (lowest number) is given to the shortest edge.
1063 */
short_edge_queue_create(EdgeQueueContext * eq_ctx,PBVH * pbvh,const float center[3],const float view_normal[3],float radius,const bool use_frontface,const bool use_projected)1064 static void short_edge_queue_create(EdgeQueueContext *eq_ctx,
1065 PBVH *pbvh,
1066 const float center[3],
1067 const float view_normal[3],
1068 float radius,
1069 const bool use_frontface,
1070 const bool use_projected)
1071 {
1072 eq_ctx->q->heap = BLI_heapsimple_new();
1073 eq_ctx->q->center = center;
1074 eq_ctx->q->radius_squared = radius * radius;
1075 eq_ctx->q->limit_len_squared = pbvh->bm_min_edge_len * pbvh->bm_min_edge_len;
1076 #ifdef USE_EDGEQUEUE_EVEN_SUBDIV
1077 eq_ctx->q->limit_len = pbvh->bm_min_edge_len;
1078 #endif
1079
1080 eq_ctx->q->view_normal = view_normal;
1081
1082 #ifdef USE_EDGEQUEUE_FRONTFACE
1083 eq_ctx->q->use_view_normal = use_frontface;
1084 #else
1085 UNUSED_VARS(use_frontface);
1086 #endif
1087
1088 if (use_projected) {
1089 eq_ctx->q->edge_queue_tri_in_range = edge_queue_tri_in_circle;
1090 project_plane_normalized_v3_v3v3(eq_ctx->q->center_proj, center, view_normal);
1091 }
1092 else {
1093 eq_ctx->q->edge_queue_tri_in_range = edge_queue_tri_in_sphere;
1094 }
1095
1096 for (int n = 0; n < pbvh->totnode; n++) {
1097 PBVHNode *node = &pbvh->nodes[n];
1098
1099 /* Check leaf nodes marked for topology update */
1100 if ((node->flag & PBVH_Leaf) && (node->flag & PBVH_UpdateTopology) &&
1101 !(node->flag & PBVH_FullyHidden)) {
1102 GSetIterator gs_iter;
1103
1104 /* Check each face */
1105 GSET_ITER (gs_iter, node->bm_faces) {
1106 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
1107
1108 short_edge_queue_face_add(eq_ctx, f);
1109 }
1110 }
1111 }
1112 }
1113
1114 /*************************** Topology update **************************/
1115
pbvh_bmesh_split_edge(EdgeQueueContext * eq_ctx,PBVH * pbvh,BMEdge * e,BLI_Buffer * edge_loops)1116 static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
1117 PBVH *pbvh,
1118 BMEdge *e,
1119 BLI_Buffer *edge_loops)
1120 {
1121 float co_mid[3], no_mid[3];
1122
1123 /* Get all faces adjacent to the edge */
1124 pbvh_bmesh_edge_loops(edge_loops, e);
1125
1126 /* Create a new vertex in current node at the edge's midpoint */
1127 mid_v3_v3v3(co_mid, e->v1->co, e->v2->co);
1128 mid_v3_v3v3(no_mid, e->v1->no, e->v2->no);
1129 normalize_v3(no_mid);
1130
1131 int node_index = BM_ELEM_CD_GET_INT(e->v1, eq_ctx->cd_vert_node_offset);
1132 BMVert *v_new = pbvh_bmesh_vert_create(
1133 pbvh, node_index, co_mid, no_mid, eq_ctx->cd_vert_mask_offset);
1134
1135 /* update paint mask */
1136 if (eq_ctx->cd_vert_mask_offset != -1) {
1137 float mask_v1 = BM_ELEM_CD_GET_FLOAT(e->v1, eq_ctx->cd_vert_mask_offset);
1138 float mask_v2 = BM_ELEM_CD_GET_FLOAT(e->v2, eq_ctx->cd_vert_mask_offset);
1139 float mask_v_new = 0.5f * (mask_v1 + mask_v2);
1140
1141 BM_ELEM_CD_SET_FLOAT(v_new, eq_ctx->cd_vert_mask_offset, mask_v_new);
1142 }
1143
1144 /* For each face, add two new triangles and delete the original */
1145 for (int i = 0; i < edge_loops->count; i++) {
1146 BMLoop *l_adj = BLI_buffer_at(edge_loops, BMLoop *, i);
1147 BMFace *f_adj = l_adj->f;
1148 BMFace *f_new;
1149 BMVert *v_opp, *v1, *v2;
1150 BMVert *v_tri[3];
1151 BMEdge *e_tri[3];
1152
1153 BLI_assert(f_adj->len == 3);
1154 int ni = BM_ELEM_CD_GET_INT(f_adj, eq_ctx->cd_face_node_offset);
1155
1156 /* Find the vertex not in the edge */
1157 v_opp = l_adj->prev->v;
1158
1159 /* Get e->v1 and e->v2 in the order they appear in the
1160 * existing face so that the new faces' winding orders
1161 * match */
1162 v1 = l_adj->v;
1163 v2 = l_adj->next->v;
1164
1165 if (ni != node_index && i == 0) {
1166 pbvh_bmesh_vert_ownership_transfer(pbvh, &pbvh->nodes[ni], v_new);
1167 }
1168
1169 /**
1170 * The 2 new faces created and assigned to ``f_new`` have their
1171 * verts & edges shuffled around.
1172 *
1173 * - faces wind anticlockwise in this example.
1174 * - original edge is ``(v1, v2)``
1175 * - original face is ``(v1, v2, v3)``
1176 *
1177 * <pre>
1178 * + v3(v_opp)
1179 * /|\
1180 * / | \
1181 * / | \
1182 * e4/ | \ e3
1183 * / |e5 \
1184 * / | \
1185 * / e1 | e2 \
1186 * +-------+-------+
1187 * v1 v4(v_new) v2
1188 * (first) (second)
1189 * </pre>
1190 *
1191 * - f_new (first): ``v_tri=(v1, v4, v3), e_tri=(e1, e5, e4)``
1192 * - f_new (second): ``v_tri=(v4, v2, v3), e_tri=(e2, e3, e5)``
1193 */
1194
1195 /* Create two new faces */
1196 v_tri[0] = v1;
1197 v_tri[1] = v_new;
1198 v_tri[2] = v_opp;
1199 bm_edges_from_tri(pbvh->bm, v_tri, e_tri);
1200 f_new = pbvh_bmesh_face_create(pbvh, ni, v_tri, e_tri, f_adj);
1201 long_edge_queue_face_add(eq_ctx, f_new);
1202
1203 v_tri[0] = v_new;
1204 v_tri[1] = v2;
1205 /* v_tri[2] = v_opp; */ /* unchanged */
1206 e_tri[0] = BM_edge_create(pbvh->bm, v_tri[0], v_tri[1], NULL, BM_CREATE_NO_DOUBLE);
1207 e_tri[2] = e_tri[1]; /* switched */
1208 e_tri[1] = BM_edge_create(pbvh->bm, v_tri[1], v_tri[2], NULL, BM_CREATE_NO_DOUBLE);
1209 f_new = pbvh_bmesh_face_create(pbvh, ni, v_tri, e_tri, f_adj);
1210 long_edge_queue_face_add(eq_ctx, f_new);
1211
1212 /* Delete original */
1213 pbvh_bmesh_face_remove(pbvh, f_adj);
1214 BM_face_kill(pbvh->bm, f_adj);
1215
1216 /* Ensure new vertex is in the node */
1217 if (!BLI_gset_haskey(pbvh->nodes[ni].bm_unique_verts, v_new)) {
1218 BLI_gset_add(pbvh->nodes[ni].bm_other_verts, v_new);
1219 }
1220
1221 if (BM_vert_edge_count_is_over(v_opp, 8)) {
1222 BMIter bm_iter;
1223 BMEdge *e2;
1224
1225 BM_ITER_ELEM (e2, &bm_iter, v_opp, BM_EDGES_OF_VERT) {
1226 long_edge_queue_edge_add(eq_ctx, e2);
1227 }
1228 }
1229 }
1230
1231 BM_edge_kill(pbvh->bm, e);
1232 }
1233
pbvh_bmesh_subdivide_long_edges(EdgeQueueContext * eq_ctx,PBVH * pbvh,BLI_Buffer * edge_loops)1234 static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx,
1235 PBVH *pbvh,
1236 BLI_Buffer *edge_loops)
1237 {
1238 bool any_subdivided = false;
1239
1240 while (!BLI_heapsimple_is_empty(eq_ctx->q->heap)) {
1241 BMVert **pair = BLI_heapsimple_pop_min(eq_ctx->q->heap);
1242 BMVert *v1 = pair[0], *v2 = pair[1];
1243 BMEdge *e;
1244
1245 BLI_mempool_free(eq_ctx->pool, pair);
1246 pair = NULL;
1247
1248 /* Check that the edge still exists */
1249 if (!(e = BM_edge_exists(v1, v2))) {
1250 continue;
1251 }
1252 #ifdef USE_EDGEQUEUE_TAG
1253 EDGE_QUEUE_DISABLE(e);
1254 #endif
1255
1256 /* At the moment edges never get shorter (subdiv will make new edges)
1257 * unlike collapse where edges can become longer. */
1258 #if 0
1259 if (len_squared_v3v3(v1->co, v2->co) <= eq_ctx->q->limit_len_squared) {
1260 continue;
1261 }
1262 #else
1263 BLI_assert(len_squared_v3v3(v1->co, v2->co) > eq_ctx->q->limit_len_squared);
1264 #endif
1265
1266 /* Check that the edge's vertices are still in the PBVH. It's
1267 * possible that an edge collapse has deleted adjacent faces
1268 * and the node has been split, thus leaving wire edges and
1269 * associated vertices. */
1270 if ((BM_ELEM_CD_GET_INT(e->v1, eq_ctx->cd_vert_node_offset) == DYNTOPO_NODE_NONE) ||
1271 (BM_ELEM_CD_GET_INT(e->v2, eq_ctx->cd_vert_node_offset) == DYNTOPO_NODE_NONE)) {
1272 continue;
1273 }
1274
1275 any_subdivided = true;
1276
1277 pbvh_bmesh_split_edge(eq_ctx, pbvh, e, edge_loops);
1278 }
1279
1280 #ifdef USE_EDGEQUEUE_TAG_VERIFY
1281 pbvh_bmesh_edge_tag_verify(pbvh);
1282 #endif
1283
1284 return any_subdivided;
1285 }
1286
pbvh_bmesh_collapse_edge(PBVH * pbvh,BMEdge * e,BMVert * v1,BMVert * v2,GHash * deleted_verts,BLI_Buffer * deleted_faces,EdgeQueueContext * eq_ctx)1287 static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
1288 BMEdge *e,
1289 BMVert *v1,
1290 BMVert *v2,
1291 GHash *deleted_verts,
1292 BLI_Buffer *deleted_faces,
1293 EdgeQueueContext *eq_ctx)
1294 {
1295 BMVert *v_del, *v_conn;
1296
1297 /* one of the two vertices may be masked, select the correct one for deletion */
1298 if (BM_ELEM_CD_GET_FLOAT(v1, eq_ctx->cd_vert_mask_offset) <
1299 BM_ELEM_CD_GET_FLOAT(v2, eq_ctx->cd_vert_mask_offset)) {
1300 v_del = v1;
1301 v_conn = v2;
1302 }
1303 else {
1304 v_del = v2;
1305 v_conn = v1;
1306 }
1307
1308 /* Remove the merge vertex from the PBVH */
1309 pbvh_bmesh_vert_remove(pbvh, v_del);
1310
1311 /* Remove all faces adjacent to the edge */
1312 BMLoop *l_adj;
1313 while ((l_adj = e->l)) {
1314 BMFace *f_adj = l_adj->f;
1315
1316 pbvh_bmesh_face_remove(pbvh, f_adj);
1317 BM_face_kill(pbvh->bm, f_adj);
1318 }
1319
1320 /* Kill the edge */
1321 BLI_assert(BM_edge_is_wire(e));
1322 BM_edge_kill(pbvh->bm, e);
1323
1324 /* For all remaining faces of v_del, create a new face that is the
1325 * same except it uses v_conn instead of v_del */
1326 /* Note: this could be done with BM_vert_splice(), but that
1327 * requires handling other issues like duplicate edges, so doesn't
1328 * really buy anything. */
1329 BLI_buffer_clear(deleted_faces);
1330
1331 BMLoop *l;
1332
1333 BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_del) {
1334 BMFace *existing_face;
1335
1336 /* Get vertices, replace use of v_del with v_conn */
1337 // BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v_tri, 3);
1338 BMFace *f = l->f;
1339 #if 0
1340 BMVert *v_tri[3];
1341 BM_face_as_array_vert_tri(f, v_tri);
1342 for (int i = 0; i < 3; i++) {
1343 if (v_tri[i] == v_del) {
1344 v_tri[i] = v_conn;
1345 }
1346 }
1347 #endif
1348
1349 /* Check if a face using these vertices already exists. If so,
1350 * skip adding this face and mark the existing one for
1351 * deletion as well. Prevents extraneous "flaps" from being
1352 * created. */
1353 #if 0
1354 if (UNLIKELY(existing_face = BM_face_exists(v_tri, 3)))
1355 #else
1356 if (UNLIKELY(existing_face = bm_face_exists_tri_from_loop_vert(l->next, v_conn)))
1357 #endif
1358 {
1359 BLI_buffer_append(deleted_faces, BMFace *, existing_face);
1360 }
1361 else
1362 {
1363 BMVert *v_tri[3] = {v_conn, l->next->v, l->prev->v};
1364
1365 BLI_assert(!BM_face_exists(v_tri, 3));
1366 BMEdge *e_tri[3];
1367 PBVHNode *n = pbvh_bmesh_node_from_face(pbvh, f);
1368 int ni = n - pbvh->nodes;
1369 bm_edges_from_tri(pbvh->bm, v_tri, e_tri);
1370 pbvh_bmesh_face_create(pbvh, ni, v_tri, e_tri, f);
1371
1372 /* Ensure that v_conn is in the new face's node */
1373 if (!BLI_gset_haskey(n->bm_unique_verts, v_conn)) {
1374 BLI_gset_add(n->bm_other_verts, v_conn);
1375 }
1376 }
1377
1378 BLI_buffer_append(deleted_faces, BMFace *, f);
1379 }
1380 BM_LOOPS_OF_VERT_ITER_END;
1381
1382 /* Delete the tagged faces */
1383 for (int i = 0; i < deleted_faces->count; i++) {
1384 BMFace *f_del = BLI_buffer_at(deleted_faces, BMFace *, i);
1385
1386 /* Get vertices and edges of face */
1387 BLI_assert(f_del->len == 3);
1388 BMLoop *l_iter = BM_FACE_FIRST_LOOP(f_del);
1389 BMVert *v_tri[3];
1390 BMEdge *e_tri[3];
1391 v_tri[0] = l_iter->v;
1392 e_tri[0] = l_iter->e;
1393 l_iter = l_iter->next;
1394 v_tri[1] = l_iter->v;
1395 e_tri[1] = l_iter->e;
1396 l_iter = l_iter->next;
1397 v_tri[2] = l_iter->v;
1398 e_tri[2] = l_iter->e;
1399
1400 /* Remove the face */
1401 pbvh_bmesh_face_remove(pbvh, f_del);
1402 BM_face_kill(pbvh->bm, f_del);
1403
1404 /* Check if any of the face's edges are now unused by any
1405 * face, if so delete them */
1406 for (int j = 0; j < 3; j++) {
1407 if (BM_edge_is_wire(e_tri[j])) {
1408 BM_edge_kill(pbvh->bm, e_tri[j]);
1409 }
1410 }
1411
1412 /* Check if any of the face's vertices are now unused, if so
1413 * remove them from the PBVH */
1414 for (int j = 0; j < 3; j++) {
1415 if ((v_tri[j] != v_del) && (v_tri[j]->e == NULL)) {
1416 pbvh_bmesh_vert_remove(pbvh, v_tri[j]);
1417
1418 BM_log_vert_removed(pbvh->bm_log, v_tri[j], eq_ctx->cd_vert_mask_offset);
1419
1420 if (v_tri[j] == v_conn) {
1421 v_conn = NULL;
1422 }
1423 BLI_ghash_insert(deleted_verts, v_tri[j], NULL);
1424 BM_vert_kill(pbvh->bm, v_tri[j]);
1425 }
1426 }
1427 }
1428
1429 /* Move v_conn to the midpoint of v_conn and v_del (if v_conn still exists, it
1430 * may have been deleted above) */
1431 if (v_conn != NULL) {
1432 BM_log_vert_before_modified(pbvh->bm_log, v_conn, eq_ctx->cd_vert_mask_offset);
1433 mid_v3_v3v3(v_conn->co, v_conn->co, v_del->co);
1434 add_v3_v3(v_conn->no, v_del->no);
1435 normalize_v3(v_conn->no);
1436
1437 /* update boundboxes attached to the connected vertex
1438 * note that we can often get-away without this but causes T48779 */
1439 BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_conn) {
1440 PBVHNode *f_node = pbvh_bmesh_node_from_face(pbvh, l->f);
1441 f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals | PBVH_UpdateBB;
1442 }
1443 BM_LOOPS_OF_VERT_ITER_END;
1444 }
1445
1446 /* Delete v_del */
1447 BLI_assert(!BM_vert_face_check(v_del));
1448 BM_log_vert_removed(pbvh->bm_log, v_del, eq_ctx->cd_vert_mask_offset);
1449 /* v_conn == NULL is OK */
1450 BLI_ghash_insert(deleted_verts, v_del, v_conn);
1451 BM_vert_kill(pbvh->bm, v_del);
1452 }
1453
pbvh_bmesh_collapse_short_edges(EdgeQueueContext * eq_ctx,PBVH * pbvh,BLI_Buffer * deleted_faces)1454 static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
1455 PBVH *pbvh,
1456 BLI_Buffer *deleted_faces)
1457 {
1458 const float min_len_squared = pbvh->bm_min_edge_len * pbvh->bm_min_edge_len;
1459 bool any_collapsed = false;
1460 /* deleted verts point to vertices they were merged into, or NULL when removed. */
1461 GHash *deleted_verts = BLI_ghash_ptr_new("deleted_verts");
1462
1463 while (!BLI_heapsimple_is_empty(eq_ctx->q->heap)) {
1464 BMVert **pair = BLI_heapsimple_pop_min(eq_ctx->q->heap);
1465 BMVert *v1 = pair[0], *v2 = pair[1];
1466 BLI_mempool_free(eq_ctx->pool, pair);
1467 pair = NULL;
1468
1469 /* Check the verts still exist */
1470 if (!(v1 = bm_vert_hash_lookup_chain(deleted_verts, v1)) ||
1471 !(v2 = bm_vert_hash_lookup_chain(deleted_verts, v2)) || (v1 == v2)) {
1472 continue;
1473 }
1474
1475 /* Check that the edge still exists */
1476 BMEdge *e;
1477 if (!(e = BM_edge_exists(v1, v2))) {
1478 continue;
1479 }
1480 #ifdef USE_EDGEQUEUE_TAG
1481 EDGE_QUEUE_DISABLE(e);
1482 #endif
1483
1484 if (len_squared_v3v3(v1->co, v2->co) >= min_len_squared) {
1485 continue;
1486 }
1487
1488 /* Check that the edge's vertices are still in the PBVH. It's
1489 * possible that an edge collapse has deleted adjacent faces
1490 * and the node has been split, thus leaving wire edges and
1491 * associated vertices. */
1492 if ((BM_ELEM_CD_GET_INT(e->v1, eq_ctx->cd_vert_node_offset) == DYNTOPO_NODE_NONE) ||
1493 (BM_ELEM_CD_GET_INT(e->v2, eq_ctx->cd_vert_node_offset) == DYNTOPO_NODE_NONE)) {
1494 continue;
1495 }
1496
1497 any_collapsed = true;
1498
1499 pbvh_bmesh_collapse_edge(pbvh, e, v1, v2, deleted_verts, deleted_faces, eq_ctx);
1500 }
1501
1502 BLI_ghash_free(deleted_verts, NULL, NULL);
1503
1504 return any_collapsed;
1505 }
1506
1507 /************************* Called from pbvh.c *************************/
1508
pbvh_bmesh_node_raycast(PBVHNode * node,const float ray_start[3],const float ray_normal[3],struct IsectRayPrecalc * isect_precalc,float * depth,bool use_original,int * r_active_vertex_index,float * r_face_normal)1509 bool pbvh_bmesh_node_raycast(PBVHNode *node,
1510 const float ray_start[3],
1511 const float ray_normal[3],
1512 struct IsectRayPrecalc *isect_precalc,
1513 float *depth,
1514 bool use_original,
1515 int *r_active_vertex_index,
1516 float *r_face_normal)
1517 {
1518 bool hit = false;
1519 float nearest_vertex_co[3] = {0.0f};
1520
1521 if (use_original && node->bm_tot_ortri) {
1522 for (int i = 0; i < node->bm_tot_ortri; i++) {
1523 const int *t = node->bm_ortri[i];
1524 hit |= ray_face_intersection_tri(ray_start,
1525 isect_precalc,
1526 node->bm_orco[t[0]],
1527 node->bm_orco[t[1]],
1528 node->bm_orco[t[2]],
1529 depth);
1530 }
1531 }
1532 else {
1533 GSetIterator gs_iter;
1534
1535 GSET_ITER (gs_iter, node->bm_faces) {
1536 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
1537
1538 BLI_assert(f->len == 3);
1539 if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
1540 BMVert *v_tri[3];
1541
1542 BM_face_as_array_vert_tri(f, v_tri);
1543
1544 if (ray_face_intersection_tri(
1545 ray_start, isect_precalc, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co, depth)) {
1546 hit = true;
1547
1548 if (r_face_normal) {
1549 normal_tri_v3(r_face_normal, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co);
1550 }
1551
1552 if (r_active_vertex_index) {
1553 float location[3] = {0.0f};
1554 madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
1555 for (int j = 0; j < 3; j++) {
1556 if (len_squared_v3v3(location, v_tri[j]->co) <
1557 len_squared_v3v3(location, nearest_vertex_co)) {
1558 copy_v3_v3(nearest_vertex_co, v_tri[j]->co);
1559 *r_active_vertex_index = BM_elem_index_get(v_tri[j]);
1560 }
1561 }
1562 }
1563 }
1564 }
1565 }
1566 }
1567
1568 return hit;
1569 }
1570
BKE_pbvh_bmesh_node_raycast_detail(PBVHNode * node,const float ray_start[3],struct IsectRayPrecalc * isect_precalc,float * depth,float * r_edge_length)1571 bool BKE_pbvh_bmesh_node_raycast_detail(PBVHNode *node,
1572 const float ray_start[3],
1573 struct IsectRayPrecalc *isect_precalc,
1574 float *depth,
1575 float *r_edge_length)
1576 {
1577 if (node->flag & PBVH_FullyHidden) {
1578 return 0;
1579 }
1580
1581 GSetIterator gs_iter;
1582 bool hit = false;
1583 BMFace *f_hit = NULL;
1584
1585 GSET_ITER (gs_iter, node->bm_faces) {
1586 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
1587
1588 BLI_assert(f->len == 3);
1589 if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
1590 BMVert *v_tri[3];
1591 bool hit_local;
1592 BM_face_as_array_vert_tri(f, v_tri);
1593 hit_local = ray_face_intersection_tri(
1594 ray_start, isect_precalc, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co, depth);
1595
1596 if (hit_local) {
1597 f_hit = f;
1598 hit = true;
1599 }
1600 }
1601 }
1602
1603 if (hit) {
1604 BMVert *v_tri[3];
1605 BM_face_as_array_vert_tri(f_hit, v_tri);
1606 float len1 = len_squared_v3v3(v_tri[0]->co, v_tri[1]->co);
1607 float len2 = len_squared_v3v3(v_tri[1]->co, v_tri[2]->co);
1608 float len3 = len_squared_v3v3(v_tri[2]->co, v_tri[0]->co);
1609
1610 /* detail returned will be set to the maximum allowed size, so take max here */
1611 *r_edge_length = sqrtf(max_fff(len1, len2, len3));
1612 }
1613
1614 return hit;
1615 }
1616
pbvh_bmesh_node_nearest_to_ray(PBVHNode * node,const float ray_start[3],const float ray_normal[3],float * depth,float * dist_sq,bool use_original)1617 bool pbvh_bmesh_node_nearest_to_ray(PBVHNode *node,
1618 const float ray_start[3],
1619 const float ray_normal[3],
1620 float *depth,
1621 float *dist_sq,
1622 bool use_original)
1623 {
1624 bool hit = false;
1625
1626 if (use_original && node->bm_tot_ortri) {
1627 for (int i = 0; i < node->bm_tot_ortri; i++) {
1628 const int *t = node->bm_ortri[i];
1629 hit |= ray_face_nearest_tri(ray_start,
1630 ray_normal,
1631 node->bm_orco[t[0]],
1632 node->bm_orco[t[1]],
1633 node->bm_orco[t[2]],
1634 depth,
1635 dist_sq);
1636 }
1637 }
1638 else {
1639 GSetIterator gs_iter;
1640
1641 GSET_ITER (gs_iter, node->bm_faces) {
1642 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
1643
1644 BLI_assert(f->len == 3);
1645 if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
1646 BMVert *v_tri[3];
1647
1648 BM_face_as_array_vert_tri(f, v_tri);
1649 hit |= ray_face_nearest_tri(
1650 ray_start, ray_normal, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co, depth, dist_sq);
1651 }
1652 }
1653 }
1654
1655 return hit;
1656 }
1657
pbvh_bmesh_normals_update(PBVHNode ** nodes,int totnode)1658 void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode)
1659 {
1660 for (int n = 0; n < totnode; n++) {
1661 PBVHNode *node = nodes[n];
1662
1663 if (node->flag & PBVH_UpdateNormals) {
1664 GSetIterator gs_iter;
1665
1666 GSET_ITER (gs_iter, node->bm_faces) {
1667 BM_face_normal_update(BLI_gsetIterator_getKey(&gs_iter));
1668 }
1669 GSET_ITER (gs_iter, node->bm_unique_verts) {
1670 BM_vert_normal_update(BLI_gsetIterator_getKey(&gs_iter));
1671 }
1672 /* This should be unneeded normally */
1673 GSET_ITER (gs_iter, node->bm_other_verts) {
1674 BM_vert_normal_update(BLI_gsetIterator_getKey(&gs_iter));
1675 }
1676 node->flag &= ~PBVH_UpdateNormals;
1677 }
1678 }
1679 }
1680
1681 struct FastNodeBuildInfo {
1682 int totface; /* number of faces */
1683 int start; /* start of faces in array */
1684 struct FastNodeBuildInfo *child1;
1685 struct FastNodeBuildInfo *child2;
1686 };
1687
1688 /**
1689 * Recursively split the node if it exceeds the leaf_limit.
1690 * This function is multi-thread-able since each invocation applies
1691 * to a sub part of the arrays.
1692 */
pbvh_bmesh_node_limit_ensure_fast(PBVH * pbvh,BMFace ** nodeinfo,BBC * bbc_array,struct FastNodeBuildInfo * node,MemArena * arena)1693 static void pbvh_bmesh_node_limit_ensure_fast(
1694 PBVH *pbvh, BMFace **nodeinfo, BBC *bbc_array, struct FastNodeBuildInfo *node, MemArena *arena)
1695 {
1696 struct FastNodeBuildInfo *child1, *child2;
1697
1698 if (node->totface <= pbvh->leaf_limit) {
1699 return;
1700 }
1701
1702 /* Calculate bounding box around primitive centroids */
1703 BB cb;
1704 BB_reset(&cb);
1705 for (int i = 0; i < node->totface; i++) {
1706 BMFace *f = nodeinfo[i + node->start];
1707 BBC *bbc = &bbc_array[BM_elem_index_get(f)];
1708
1709 BB_expand(&cb, bbc->bcentroid);
1710 }
1711
1712 /* initialize the children */
1713
1714 /* Find widest axis and its midpoint */
1715 const int axis = BB_widest_axis(&cb);
1716 const float mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
1717
1718 int num_child1 = 0, num_child2 = 0;
1719
1720 /* split vertices along the middle line */
1721 const int end = node->start + node->totface;
1722 for (int i = node->start; i < end - num_child2; i++) {
1723 BMFace *f = nodeinfo[i];
1724 BBC *bbc = &bbc_array[BM_elem_index_get(f)];
1725
1726 if (bbc->bcentroid[axis] > mid) {
1727 int i_iter = end - num_child2 - 1;
1728 int candidate = -1;
1729 /* found a face that should be part of another node, look for a face to substitute with */
1730
1731 for (; i_iter > i; i_iter--) {
1732 BMFace *f_iter = nodeinfo[i_iter];
1733 const BBC *bbc_iter = &bbc_array[BM_elem_index_get(f_iter)];
1734 if (bbc_iter->bcentroid[axis] <= mid) {
1735 candidate = i_iter;
1736 break;
1737 }
1738
1739 num_child2++;
1740 }
1741
1742 if (candidate != -1) {
1743 BMFace *tmp = nodeinfo[i];
1744 nodeinfo[i] = nodeinfo[candidate];
1745 nodeinfo[candidate] = tmp;
1746 /* increase both counts */
1747 num_child1++;
1748 num_child2++;
1749 }
1750 else {
1751 /* not finding candidate means second half of array part is full of
1752 * second node parts, just increase the number of child nodes for it */
1753 num_child2++;
1754 }
1755 }
1756 else {
1757 num_child1++;
1758 }
1759 }
1760
1761 /* ensure at least one child in each node */
1762 if (num_child2 == 0) {
1763 num_child2++;
1764 num_child1--;
1765 }
1766 else if (num_child1 == 0) {
1767 num_child1++;
1768 num_child2--;
1769 }
1770
1771 /* at this point, faces should have been split along the array range sequentially,
1772 * each sequential part belonging to one node only */
1773 BLI_assert((num_child1 + num_child2) == node->totface);
1774
1775 node->child1 = child1 = BLI_memarena_alloc(arena, sizeof(struct FastNodeBuildInfo));
1776 node->child2 = child2 = BLI_memarena_alloc(arena, sizeof(struct FastNodeBuildInfo));
1777
1778 child1->totface = num_child1;
1779 child1->start = node->start;
1780 child2->totface = num_child2;
1781 child2->start = node->start + num_child1;
1782 child1->child1 = child1->child2 = child2->child1 = child2->child2 = NULL;
1783
1784 pbvh_bmesh_node_limit_ensure_fast(pbvh, nodeinfo, bbc_array, child1, arena);
1785 pbvh_bmesh_node_limit_ensure_fast(pbvh, nodeinfo, bbc_array, child2, arena);
1786 }
1787
pbvh_bmesh_create_nodes_fast_recursive(PBVH * pbvh,BMFace ** nodeinfo,BBC * bbc_array,struct FastNodeBuildInfo * node,int node_index)1788 static void pbvh_bmesh_create_nodes_fast_recursive(
1789 PBVH *pbvh, BMFace **nodeinfo, BBC *bbc_array, struct FastNodeBuildInfo *node, int node_index)
1790 {
1791 PBVHNode *n = pbvh->nodes + node_index;
1792 /* two cases, node does not have children or does have children */
1793 if (node->child1) {
1794 int children_offset = pbvh->totnode;
1795
1796 n->children_offset = children_offset;
1797 pbvh_grow_nodes(pbvh, pbvh->totnode + 2);
1798 pbvh_bmesh_create_nodes_fast_recursive(
1799 pbvh, nodeinfo, bbc_array, node->child1, children_offset);
1800 pbvh_bmesh_create_nodes_fast_recursive(
1801 pbvh, nodeinfo, bbc_array, node->child2, children_offset + 1);
1802
1803 n = &pbvh->nodes[node_index];
1804
1805 /* Update bounding box */
1806 BB_reset(&n->vb);
1807 BB_expand_with_bb(&n->vb, &pbvh->nodes[n->children_offset].vb);
1808 BB_expand_with_bb(&n->vb, &pbvh->nodes[n->children_offset + 1].vb);
1809 n->orig_vb = n->vb;
1810 }
1811 else {
1812 /* node does not have children so it's a leaf node, populate with faces and tag accordingly
1813 * this is an expensive part but it's not so easily thread-able due to vertex node indices */
1814 const int cd_vert_node_offset = pbvh->cd_vert_node_offset;
1815 const int cd_face_node_offset = pbvh->cd_face_node_offset;
1816
1817 bool has_visible = false;
1818
1819 n->flag = PBVH_Leaf;
1820 n->bm_faces = BLI_gset_ptr_new_ex("bm_faces", node->totface);
1821
1822 /* Create vert hash sets */
1823 n->bm_unique_verts = BLI_gset_ptr_new("bm_unique_verts");
1824 n->bm_other_verts = BLI_gset_ptr_new("bm_other_verts");
1825
1826 BB_reset(&n->vb);
1827
1828 const int end = node->start + node->totface;
1829
1830 for (int i = node->start; i < end; i++) {
1831 BMFace *f = nodeinfo[i];
1832 BBC *bbc = &bbc_array[BM_elem_index_get(f)];
1833
1834 /* Update ownership of faces */
1835 BLI_gset_insert(n->bm_faces, f);
1836 BM_ELEM_CD_SET_INT(f, cd_face_node_offset, node_index);
1837
1838 /* Update vertices */
1839 BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
1840 BMLoop *l_iter = l_first;
1841 do {
1842 BMVert *v = l_iter->v;
1843 if (!BLI_gset_haskey(n->bm_unique_verts, v)) {
1844 if (BM_ELEM_CD_GET_INT(v, cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
1845 BLI_gset_add(n->bm_other_verts, v);
1846 }
1847 else {
1848 BLI_gset_insert(n->bm_unique_verts, v);
1849 BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, node_index);
1850 }
1851 }
1852 /* Update node bounding box */
1853 } while ((l_iter = l_iter->next) != l_first);
1854
1855 if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
1856 has_visible = true;
1857 }
1858
1859 BB_expand_with_bb(&n->vb, (BB *)bbc);
1860 }
1861
1862 BLI_assert(n->vb.bmin[0] <= n->vb.bmax[0] && n->vb.bmin[1] <= n->vb.bmax[1] &&
1863 n->vb.bmin[2] <= n->vb.bmax[2]);
1864
1865 n->orig_vb = n->vb;
1866
1867 /* Build GPU buffers for new node and update vertex normals */
1868 BKE_pbvh_node_mark_rebuild_draw(n);
1869
1870 BKE_pbvh_node_fully_hidden_set(n, !has_visible);
1871 n->flag |= PBVH_UpdateNormals;
1872 }
1873 }
1874
1875 /***************************** Public API *****************************/
1876
1877 /* Build a PBVH from a BMesh */
BKE_pbvh_build_bmesh(PBVH * pbvh,BMesh * bm,bool smooth_shading,BMLog * log,const int cd_vert_node_offset,const int cd_face_node_offset)1878 void BKE_pbvh_build_bmesh(PBVH *pbvh,
1879 BMesh *bm,
1880 bool smooth_shading,
1881 BMLog *log,
1882 const int cd_vert_node_offset,
1883 const int cd_face_node_offset)
1884 {
1885 pbvh->cd_vert_node_offset = cd_vert_node_offset;
1886 pbvh->cd_face_node_offset = cd_face_node_offset;
1887 pbvh->bm = bm;
1888
1889 BKE_pbvh_bmesh_detail_size_set(pbvh, 0.75);
1890
1891 pbvh->type = PBVH_BMESH;
1892 pbvh->bm_log = log;
1893
1894 /* TODO: choose leaf limit better */
1895 pbvh->leaf_limit = 100;
1896
1897 if (smooth_shading) {
1898 pbvh->flags |= PBVH_DYNTOPO_SMOOTH_SHADING;
1899 }
1900
1901 /* bounding box array of all faces, no need to recalculate every time */
1902 BBC *bbc_array = MEM_mallocN(sizeof(BBC) * bm->totface, "BBC");
1903 BMFace **nodeinfo = MEM_mallocN(sizeof(*nodeinfo) * bm->totface, "nodeinfo");
1904 MemArena *arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "fast PBVH node storage");
1905
1906 BMIter iter;
1907 BMFace *f;
1908 int i;
1909 BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
1910 BBC *bbc = &bbc_array[i];
1911 BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
1912 BMLoop *l_iter = l_first;
1913
1914 BB_reset((BB *)bbc);
1915 do {
1916 BB_expand((BB *)bbc, l_iter->v->co);
1917 } while ((l_iter = l_iter->next) != l_first);
1918 BBC_update_centroid(bbc);
1919
1920 /* so we can do direct lookups on 'bbc_array' */
1921 BM_elem_index_set(f, i); /* set_dirty! */
1922 nodeinfo[i] = f;
1923 BM_ELEM_CD_SET_INT(f, cd_face_node_offset, DYNTOPO_NODE_NONE);
1924 }
1925 /* Likely this is already dirty. */
1926 bm->elem_index_dirty |= BM_FACE;
1927
1928 BMVert *v;
1929 BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
1930 BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, DYNTOPO_NODE_NONE);
1931 }
1932
1933 /* setup root node */
1934 struct FastNodeBuildInfo rootnode = {0};
1935 rootnode.totface = bm->totface;
1936
1937 /* start recursion, assign faces to nodes accordingly */
1938 pbvh_bmesh_node_limit_ensure_fast(pbvh, nodeinfo, bbc_array, &rootnode, arena);
1939
1940 /* We now have all faces assigned to a node,
1941 * next we need to assign those to the gsets of the nodes. */
1942
1943 /* Start with all faces in the root node */
1944 pbvh->nodes = MEM_callocN(sizeof(PBVHNode), "PBVHNode");
1945 pbvh->totnode = 1;
1946
1947 /* take root node and visit and populate children recursively */
1948 pbvh_bmesh_create_nodes_fast_recursive(pbvh, nodeinfo, bbc_array, &rootnode, 0);
1949
1950 BLI_memarena_free(arena);
1951 MEM_freeN(bbc_array);
1952 MEM_freeN(nodeinfo);
1953 }
1954
1955 /* Collapse short edges, subdivide long edges */
BKE_pbvh_bmesh_update_topology(PBVH * pbvh,PBVHTopologyUpdateMode mode,const float center[3],const float view_normal[3],float radius,const bool use_frontface,const bool use_projected)1956 bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
1957 PBVHTopologyUpdateMode mode,
1958 const float center[3],
1959 const float view_normal[3],
1960 float radius,
1961 const bool use_frontface,
1962 const bool use_projected)
1963 {
1964 /* 2 is enough for edge faces - manifold edge */
1965 BLI_buffer_declare_static(BMLoop *, edge_loops, BLI_BUFFER_NOP, 2);
1966 BLI_buffer_declare_static(BMFace *, deleted_faces, BLI_BUFFER_NOP, 32);
1967 const int cd_vert_mask_offset = CustomData_get_offset(&pbvh->bm->vdata, CD_PAINT_MASK);
1968 const int cd_vert_node_offset = pbvh->cd_vert_node_offset;
1969 const int cd_face_node_offset = pbvh->cd_face_node_offset;
1970
1971 bool modified = false;
1972
1973 if (view_normal) {
1974 BLI_assert(len_squared_v3(view_normal) != 0.0f);
1975 }
1976
1977 if (mode & PBVH_Collapse) {
1978 EdgeQueue q;
1979 BLI_mempool *queue_pool = BLI_mempool_create(sizeof(BMVert *) * 2, 0, 128, BLI_MEMPOOL_NOP);
1980 EdgeQueueContext eq_ctx = {
1981 &q,
1982 queue_pool,
1983 pbvh->bm,
1984 cd_vert_mask_offset,
1985 cd_vert_node_offset,
1986 cd_face_node_offset,
1987 };
1988
1989 short_edge_queue_create(
1990 &eq_ctx, pbvh, center, view_normal, radius, use_frontface, use_projected);
1991 modified |= pbvh_bmesh_collapse_short_edges(&eq_ctx, pbvh, &deleted_faces);
1992 BLI_heapsimple_free(q.heap, NULL);
1993 BLI_mempool_destroy(queue_pool);
1994 }
1995
1996 if (mode & PBVH_Subdivide) {
1997 EdgeQueue q;
1998 BLI_mempool *queue_pool = BLI_mempool_create(sizeof(BMVert *) * 2, 0, 128, BLI_MEMPOOL_NOP);
1999 EdgeQueueContext eq_ctx = {
2000 &q,
2001 queue_pool,
2002 pbvh->bm,
2003 cd_vert_mask_offset,
2004 cd_vert_node_offset,
2005 cd_face_node_offset,
2006 };
2007
2008 long_edge_queue_create(
2009 &eq_ctx, pbvh, center, view_normal, radius, use_frontface, use_projected);
2010 modified |= pbvh_bmesh_subdivide_long_edges(&eq_ctx, pbvh, &edge_loops);
2011 BLI_heapsimple_free(q.heap, NULL);
2012 BLI_mempool_destroy(queue_pool);
2013 }
2014
2015 /* Unmark nodes */
2016 for (int n = 0; n < pbvh->totnode; n++) {
2017 PBVHNode *node = &pbvh->nodes[n];
2018
2019 if (node->flag & PBVH_Leaf && node->flag & PBVH_UpdateTopology) {
2020 node->flag &= ~PBVH_UpdateTopology;
2021 }
2022 }
2023 BLI_buffer_free(&edge_loops);
2024 BLI_buffer_free(&deleted_faces);
2025
2026 #ifdef USE_VERIFY
2027 pbvh_bmesh_verify(pbvh);
2028 #endif
2029
2030 return modified;
2031 }
2032
2033 /* In order to perform operations on the original node coordinates
2034 * (currently just raycast), store the node's triangles and vertices.
2035 *
2036 * Skips triangles that are hidden. */
BKE_pbvh_bmesh_node_save_orig(BMesh * bm,PBVHNode * node)2037 void BKE_pbvh_bmesh_node_save_orig(BMesh *bm, PBVHNode *node)
2038 {
2039 /* Skip if original coords/triangles are already saved */
2040 if (node->bm_orco) {
2041 return;
2042 }
2043
2044 const int totvert = BLI_gset_len(node->bm_unique_verts) + BLI_gset_len(node->bm_other_verts);
2045
2046 const int tottri = BLI_gset_len(node->bm_faces);
2047
2048 node->bm_orco = MEM_mallocN(sizeof(*node->bm_orco) * totvert, __func__);
2049 node->bm_ortri = MEM_mallocN(sizeof(*node->bm_ortri) * tottri, __func__);
2050
2051 /* Copy out the vertices and assign a temporary index */
2052 int i = 0;
2053 GSetIterator gs_iter;
2054 GSET_ITER (gs_iter, node->bm_unique_verts) {
2055 BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
2056 copy_v3_v3(node->bm_orco[i], v->co);
2057 BM_elem_index_set(v, i); /* set_dirty! */
2058 i++;
2059 }
2060 GSET_ITER (gs_iter, node->bm_other_verts) {
2061 BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
2062 copy_v3_v3(node->bm_orco[i], v->co);
2063 BM_elem_index_set(v, i); /* set_dirty! */
2064 i++;
2065 }
2066 /* Likely this is already dirty. */
2067 bm->elem_index_dirty |= BM_VERT;
2068
2069 /* Copy the triangles */
2070 i = 0;
2071 GSET_ITER (gs_iter, node->bm_faces) {
2072 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
2073
2074 if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
2075 continue;
2076 }
2077
2078 #if 0
2079 BMIter bm_iter;
2080 BMVert *v;
2081 int j = 0;
2082 BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
2083 node->bm_ortri[i][j] = BM_elem_index_get(v);
2084 j++;
2085 }
2086 #else
2087 bm_face_as_array_index_tri(f, node->bm_ortri[i]);
2088 #endif
2089 i++;
2090 }
2091 node->bm_tot_ortri = i;
2092 }
2093
BKE_pbvh_bmesh_after_stroke(PBVH * pbvh)2094 void BKE_pbvh_bmesh_after_stroke(PBVH *pbvh)
2095 {
2096 for (int i = 0; i < pbvh->totnode; i++) {
2097 PBVHNode *n = &pbvh->nodes[i];
2098 if (n->flag & PBVH_Leaf) {
2099 /* Free orco/ortri data */
2100 pbvh_bmesh_node_drop_orig(n);
2101
2102 /* Recursively split nodes that have gotten too many
2103 * elements */
2104 pbvh_bmesh_node_limit_ensure(pbvh, i);
2105 }
2106 }
2107 }
2108
BKE_pbvh_bmesh_detail_size_set(PBVH * pbvh,float detail_size)2109 void BKE_pbvh_bmesh_detail_size_set(PBVH *pbvh, float detail_size)
2110 {
2111 pbvh->bm_max_edge_len = detail_size;
2112 pbvh->bm_min_edge_len = pbvh->bm_max_edge_len * 0.4f;
2113 }
2114
BKE_pbvh_node_mark_topology_update(PBVHNode * node)2115 void BKE_pbvh_node_mark_topology_update(PBVHNode *node)
2116 {
2117 node->flag |= PBVH_UpdateTopology;
2118 }
2119
BKE_pbvh_bmesh_node_unique_verts(PBVHNode * node)2120 GSet *BKE_pbvh_bmesh_node_unique_verts(PBVHNode *node)
2121 {
2122 return node->bm_unique_verts;
2123 }
2124
BKE_pbvh_bmesh_node_other_verts(PBVHNode * node)2125 GSet *BKE_pbvh_bmesh_node_other_verts(PBVHNode *node)
2126 {
2127 return node->bm_other_verts;
2128 }
2129
BKE_pbvh_bmesh_node_faces(PBVHNode * node)2130 struct GSet *BKE_pbvh_bmesh_node_faces(PBVHNode *node)
2131 {
2132 return node->bm_faces;
2133 }
2134
2135 /****************************** Debugging *****************************/
2136
2137 #if 0
2138
2139 static void pbvh_bmesh_print(PBVH *pbvh)
2140 {
2141 fprintf(stderr, "\npbvh=%p\n", pbvh);
2142 fprintf(stderr, "bm_face_to_node:\n");
2143
2144 BMIter iter;
2145 BMFace *f;
2146 BM_ITER_MESH (f, &iter, pbvh->bm, BM_FACES_OF_MESH) {
2147 fprintf(stderr, " %d -> %d\n", BM_elem_index_get(f), pbvh_bmesh_node_index_from_face(pbvh, f));
2148 }
2149
2150 fprintf(stderr, "bm_vert_to_node:\n");
2151 BMVert *v;
2152 BM_ITER_MESH (v, &iter, pbvh->bm, BM_FACES_OF_MESH) {
2153 fprintf(stderr, " %d -> %d\n", BM_elem_index_get(v), pbvh_bmesh_node_index_from_vert(pbvh, v));
2154 }
2155
2156 for (int n = 0; n < pbvh->totnode; n++) {
2157 PBVHNode *node = &pbvh->nodes[n];
2158 if (!(node->flag & PBVH_Leaf)) {
2159 continue;
2160 }
2161
2162 GSetIterator gs_iter;
2163 fprintf(stderr, "node %d\n faces:\n", n);
2164 GSET_ITER (gs_iter, node->bm_faces)
2165 fprintf(stderr, " %d\n", BM_elem_index_get((BMFace *)BLI_gsetIterator_getKey(&gs_iter)));
2166 fprintf(stderr, " unique verts:\n");
2167 GSET_ITER (gs_iter, node->bm_unique_verts)
2168 fprintf(stderr, " %d\n", BM_elem_index_get((BMVert *)BLI_gsetIterator_getKey(&gs_iter)));
2169 fprintf(stderr, " other verts:\n");
2170 GSET_ITER (gs_iter, node->bm_other_verts)
2171 fprintf(stderr, " %d\n", BM_elem_index_get((BMVert *)BLI_gsetIterator_getKey(&gs_iter)));
2172 }
2173 }
2174
2175 static void print_flag_factors(int flag)
2176 {
2177 printf("flag=0x%x:\n", flag);
2178 for (int i = 0; i < 32; i++) {
2179 if (flag & (1 << i)) {
2180 printf(" %d (1 << %d)\n", 1 << i, i);
2181 }
2182 }
2183 }
2184 #endif
2185
2186 #ifdef USE_VERIFY
2187
pbvh_bmesh_verify(PBVH * pbvh)2188 static void pbvh_bmesh_verify(PBVH *pbvh)
2189 {
2190 /* build list of faces & verts to lookup */
2191 GSet *faces_all = BLI_gset_ptr_new_ex(__func__, pbvh->bm->totface);
2192 BMIter iter;
2193
2194 {
2195 BMFace *f;
2196 BM_ITER_MESH (f, &iter, pbvh->bm, BM_FACES_OF_MESH) {
2197 BLI_assert(BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset) != DYNTOPO_NODE_NONE);
2198 BLI_gset_insert(faces_all, f);
2199 }
2200 }
2201
2202 GSet *verts_all = BLI_gset_ptr_new_ex(__func__, pbvh->bm->totvert);
2203 {
2204 BMVert *v;
2205 BM_ITER_MESH (v, &iter, pbvh->bm, BM_VERTS_OF_MESH) {
2206 if (BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
2207 BLI_gset_insert(verts_all, v);
2208 }
2209 }
2210 }
2211
2212 /* Check vert/face counts */
2213 {
2214 int totface = 0, totvert = 0;
2215 for (int i = 0; i < pbvh->totnode; i++) {
2216 PBVHNode *n = &pbvh->nodes[i];
2217 totface += n->bm_faces ? BLI_gset_len(n->bm_faces) : 0;
2218 totvert += n->bm_unique_verts ? BLI_gset_len(n->bm_unique_verts) : 0;
2219 }
2220
2221 BLI_assert(totface == BLI_gset_len(faces_all));
2222 BLI_assert(totvert == BLI_gset_len(verts_all));
2223 }
2224
2225 {
2226 BMFace *f;
2227 BM_ITER_MESH (f, &iter, pbvh->bm, BM_FACES_OF_MESH) {
2228 BMIter bm_iter;
2229 BMVert *v;
2230 PBVHNode *n = pbvh_bmesh_node_lookup(pbvh, f);
2231
2232 /* Check that the face's node is a leaf */
2233 BLI_assert(n->flag & PBVH_Leaf);
2234
2235 /* Check that the face's node knows it owns the face */
2236 BLI_assert(BLI_gset_haskey(n->bm_faces, f));
2237
2238 /* Check the face's vertices... */
2239 BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
2240 PBVHNode *nv;
2241
2242 /* Check that the vertex is in the node */
2243 BLI_assert(BLI_gset_haskey(n->bm_unique_verts, v) ^ BLI_gset_haskey(n->bm_other_verts, v));
2244
2245 /* Check that the vertex has a node owner */
2246 nv = pbvh_bmesh_node_lookup(pbvh, v);
2247
2248 /* Check that the vertex's node knows it owns the vert */
2249 BLI_assert(BLI_gset_haskey(nv->bm_unique_verts, v));
2250
2251 /* Check that the vertex isn't duplicated as an 'other' vert */
2252 BLI_assert(!BLI_gset_haskey(nv->bm_other_verts, v));
2253 }
2254 }
2255 }
2256
2257 /* Check verts */
2258 {
2259 BMVert *v;
2260 BM_ITER_MESH (v, &iter, pbvh->bm, BM_VERTS_OF_MESH) {
2261 /* vertex isn't tracked */
2262 if (BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset) == DYNTOPO_NODE_NONE) {
2263 continue;
2264 }
2265
2266 PBVHNode *n = pbvh_bmesh_node_lookup(pbvh, v);
2267
2268 /* Check that the vert's node is a leaf */
2269 BLI_assert(n->flag & PBVH_Leaf);
2270
2271 /* Check that the vert's node knows it owns the vert */
2272 BLI_assert(BLI_gset_haskey(n->bm_unique_verts, v));
2273
2274 /* Check that the vertex isn't duplicated as an 'other' vert */
2275 BLI_assert(!BLI_gset_haskey(n->bm_other_verts, v));
2276
2277 /* Check that the vert's node also contains one of the vert's
2278 * adjacent faces */
2279 bool found = false;
2280 BMIter bm_iter;
2281 BMFace *f = NULL;
2282 BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
2283 if (pbvh_bmesh_node_lookup(pbvh, f) == n) {
2284 found = true;
2285 break;
2286 }
2287 }
2288 BLI_assert(found || f == NULL);
2289
2290 # if 1
2291 /* total freak stuff, check if node exists somewhere else */
2292 /* Slow */
2293 for (int i = 0; i < pbvh->totnode; i++) {
2294 PBVHNode *n_other = &pbvh->nodes[i];
2295 if ((n != n_other) && (n_other->bm_unique_verts)) {
2296 BLI_assert(!BLI_gset_haskey(n_other->bm_unique_verts, v));
2297 }
2298 }
2299 # endif
2300 }
2301 }
2302
2303 # if 0
2304 /* check that every vert belongs somewhere */
2305 /* Slow */
2306 BM_ITER_MESH (vi, &iter, pbvh->bm, BM_VERTS_OF_MESH) {
2307 bool has_unique = false;
2308 for (int i = 0; i < pbvh->totnode; i++) {
2309 PBVHNode *n = &pbvh->nodes[i];
2310 if ((n->bm_unique_verts != NULL) && BLI_gset_haskey(n->bm_unique_verts, vi)) {
2311 has_unique = true;
2312 }
2313 }
2314 BLI_assert(has_unique);
2315 vert_count++;
2316 }
2317
2318 /* if totvert differs from number of verts inside the hash. hash-totvert is checked above */
2319 BLI_assert(vert_count == pbvh->bm->totvert);
2320 # endif
2321
2322 /* Check that node elements are recorded in the top level */
2323 for (int i = 0; i < pbvh->totnode; i++) {
2324 PBVHNode *n = &pbvh->nodes[i];
2325 if (n->flag & PBVH_Leaf) {
2326 GSetIterator gs_iter;
2327
2328 GSET_ITER (gs_iter, n->bm_faces) {
2329 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
2330 PBVHNode *n_other = pbvh_bmesh_node_lookup(pbvh, f);
2331 BLI_assert(n == n_other);
2332 BLI_assert(BLI_gset_haskey(faces_all, f));
2333 }
2334
2335 GSET_ITER (gs_iter, n->bm_unique_verts) {
2336 BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
2337 PBVHNode *n_other = pbvh_bmesh_node_lookup(pbvh, v);
2338 BLI_assert(!BLI_gset_haskey(n->bm_other_verts, v));
2339 BLI_assert(n == n_other);
2340 BLI_assert(BLI_gset_haskey(verts_all, v));
2341 }
2342
2343 GSET_ITER (gs_iter, n->bm_other_verts) {
2344 BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
2345 /* this happens sometimes and seems harmless */
2346 // BLI_assert(!BM_vert_face_check(v));
2347 BLI_assert(BLI_gset_haskey(verts_all, v));
2348 }
2349 }
2350 }
2351
2352 BLI_gset_free(faces_all, NULL);
2353 BLI_gset_free(verts_all, NULL);
2354 }
2355
2356 #endif
2357