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_utildefines.h"
24 
25 #include "BLI_bitmap.h"
26 #include "BLI_ghash.h"
27 #include "BLI_math.h"
28 #include "BLI_rand.h"
29 #include "BLI_task.h"
30 
31 #include "DNA_mesh_types.h"
32 #include "DNA_meshdata_types.h"
33 
34 #include "BKE_ccg.h"
35 #include "BKE_mesh.h" /* for BKE_mesh_calc_normals */
36 #include "BKE_paint.h"
37 #include "BKE_pbvh.h"
38 #include "BKE_subdiv_ccg.h"
39 
40 #include "PIL_time.h"
41 
42 #include "GPU_buffers.h"
43 
44 #include "bmesh.h"
45 
46 #include "atomic_ops.h"
47 
48 #include "pbvh_intern.h"
49 
50 #include <limits.h>
51 
52 #define LEAF_LIMIT 10000
53 
54 //#define PERFCNTRS
55 
56 #define STACK_FIXED_DEPTH 100
57 
58 typedef struct PBVHStack {
59   PBVHNode *node;
60   bool revisiting;
61 } PBVHStack;
62 
63 typedef struct PBVHIter {
64   PBVH *pbvh;
65   BKE_pbvh_SearchCallback scb;
66   void *search_data;
67 
68   PBVHStack *stack;
69   int stacksize;
70 
71   PBVHStack stackfixed[STACK_FIXED_DEPTH];
72   int stackspace;
73 } PBVHIter;
74 
BB_reset(BB * bb)75 void BB_reset(BB *bb)
76 {
77   bb->bmin[0] = bb->bmin[1] = bb->bmin[2] = FLT_MAX;
78   bb->bmax[0] = bb->bmax[1] = bb->bmax[2] = -FLT_MAX;
79 }
80 
81 /* Expand the bounding box to include a new coordinate */
BB_expand(BB * bb,const float co[3])82 void BB_expand(BB *bb, const float co[3])
83 {
84   for (int i = 0; i < 3; i++) {
85     bb->bmin[i] = min_ff(bb->bmin[i], co[i]);
86     bb->bmax[i] = max_ff(bb->bmax[i], co[i]);
87   }
88 }
89 
90 /* Expand the bounding box to include another bounding box */
BB_expand_with_bb(BB * bb,BB * bb2)91 void BB_expand_with_bb(BB *bb, BB *bb2)
92 {
93   for (int i = 0; i < 3; i++) {
94     bb->bmin[i] = min_ff(bb->bmin[i], bb2->bmin[i]);
95     bb->bmax[i] = max_ff(bb->bmax[i], bb2->bmax[i]);
96   }
97 }
98 
99 /* Return 0, 1, or 2 to indicate the widest axis of the bounding box */
BB_widest_axis(const BB * bb)100 int BB_widest_axis(const BB *bb)
101 {
102   float dim[3];
103 
104   for (int i = 0; i < 3; i++) {
105     dim[i] = bb->bmax[i] - bb->bmin[i];
106   }
107 
108   if (dim[0] > dim[1]) {
109     if (dim[0] > dim[2]) {
110       return 0;
111     }
112 
113     return 2;
114   }
115 
116   if (dim[1] > dim[2]) {
117     return 1;
118   }
119 
120   return 2;
121 }
122 
BBC_update_centroid(BBC * bbc)123 void BBC_update_centroid(BBC *bbc)
124 {
125   for (int i = 0; i < 3; i++) {
126     bbc->bcentroid[i] = (bbc->bmin[i] + bbc->bmax[i]) * 0.5f;
127   }
128 }
129 
130 /* Not recursive */
update_node_vb(PBVH * pbvh,PBVHNode * node)131 static void update_node_vb(PBVH *pbvh, PBVHNode *node)
132 {
133   BB vb;
134 
135   BB_reset(&vb);
136 
137   if (node->flag & PBVH_Leaf) {
138     PBVHVertexIter vd;
139 
140     BKE_pbvh_vertex_iter_begin(pbvh, node, vd, PBVH_ITER_ALL)
141     {
142       BB_expand(&vb, vd.co);
143     }
144     BKE_pbvh_vertex_iter_end;
145   }
146   else {
147     BB_expand_with_bb(&vb, &pbvh->nodes[node->children_offset].vb);
148     BB_expand_with_bb(&vb, &pbvh->nodes[node->children_offset + 1].vb);
149   }
150 
151   node->vb = vb;
152 }
153 
154 // void BKE_pbvh_node_BB_reset(PBVHNode *node)
155 //{
156 //  BB_reset(&node->vb);
157 //}
158 //
159 // void BKE_pbvh_node_BB_expand(PBVHNode *node, float co[3])
160 //{
161 //  BB_expand(&node->vb, co);
162 //}
163 
face_materials_match(const MPoly * f1,const MPoly * f2)164 static bool face_materials_match(const MPoly *f1, const MPoly *f2)
165 {
166   return ((f1->flag & ME_SMOOTH) == (f2->flag & ME_SMOOTH) && (f1->mat_nr == f2->mat_nr));
167 }
168 
grid_materials_match(const DMFlagMat * f1,const DMFlagMat * f2)169 static bool grid_materials_match(const DMFlagMat *f1, const DMFlagMat *f2)
170 {
171   return ((f1->flag & ME_SMOOTH) == (f2->flag & ME_SMOOTH) && (f1->mat_nr == f2->mat_nr));
172 }
173 
174 /* Adapted from BLI_kdopbvh.c */
175 /* Returns the index of the first element on the right of the partition */
partition_indices(int * prim_indices,int lo,int hi,int axis,float mid,BBC * prim_bbc)176 static int partition_indices(int *prim_indices, int lo, int hi, int axis, float mid, BBC *prim_bbc)
177 {
178   int i = lo, j = hi;
179   for (;;) {
180     for (; prim_bbc[prim_indices[i]].bcentroid[axis] < mid; i++) {
181       /* pass */
182     }
183     for (; mid < prim_bbc[prim_indices[j]].bcentroid[axis]; j--) {
184       /* pass */
185     }
186 
187     if (!(i < j)) {
188       return i;
189     }
190 
191     SWAP(int, prim_indices[i], prim_indices[j]);
192     i++;
193   }
194 }
195 
196 /* Returns the index of the first element on the right of the partition */
partition_indices_material(PBVH * pbvh,int lo,int hi)197 static int partition_indices_material(PBVH *pbvh, int lo, int hi)
198 {
199   const MPoly *mpoly = pbvh->mpoly;
200   const MLoopTri *looptri = pbvh->looptri;
201   const DMFlagMat *flagmats = pbvh->grid_flag_mats;
202   const int *indices = pbvh->prim_indices;
203   const void *first;
204   int i = lo, j = hi;
205 
206   if (pbvh->looptri) {
207     first = &mpoly[looptri[pbvh->prim_indices[lo]].poly];
208   }
209   else {
210     first = &flagmats[pbvh->prim_indices[lo]];
211   }
212 
213   for (;;) {
214     if (pbvh->looptri) {
215       for (; face_materials_match(first, &mpoly[looptri[indices[i]].poly]); i++) {
216         /* pass */
217       }
218       for (; !face_materials_match(first, &mpoly[looptri[indices[j]].poly]); j--) {
219         /* pass */
220       }
221     }
222     else {
223       for (; grid_materials_match(first, &flagmats[indices[i]]); i++) {
224         /* pass */
225       }
226       for (; !grid_materials_match(first, &flagmats[indices[j]]); j--) {
227         /* pass */
228       }
229     }
230 
231     if (!(i < j)) {
232       return i;
233     }
234 
235     SWAP(int, pbvh->prim_indices[i], pbvh->prim_indices[j]);
236     i++;
237   }
238 }
239 
pbvh_grow_nodes(PBVH * pbvh,int totnode)240 void pbvh_grow_nodes(PBVH *pbvh, int totnode)
241 {
242   if (UNLIKELY(totnode > pbvh->node_mem_count)) {
243     pbvh->node_mem_count = pbvh->node_mem_count + (pbvh->node_mem_count / 3);
244     if (pbvh->node_mem_count < totnode) {
245       pbvh->node_mem_count = totnode;
246     }
247     pbvh->nodes = MEM_recallocN(pbvh->nodes, sizeof(PBVHNode) * pbvh->node_mem_count);
248   }
249 
250   pbvh->totnode = totnode;
251 }
252 
253 /* Add a vertex to the map, with a positive value for unique vertices and
254  * a negative value for additional vertices */
map_insert_vert(PBVH * pbvh,GHash * map,unsigned int * face_verts,unsigned int * uniq_verts,int vertex)255 static int map_insert_vert(
256     PBVH *pbvh, GHash *map, unsigned int *face_verts, unsigned int *uniq_verts, int vertex)
257 {
258   void *key, **value_p;
259 
260   key = POINTER_FROM_INT(vertex);
261   if (!BLI_ghash_ensure_p(map, key, &value_p)) {
262     int value_i;
263     if (BLI_BITMAP_TEST(pbvh->vert_bitmap, vertex) == 0) {
264       BLI_BITMAP_ENABLE(pbvh->vert_bitmap, vertex);
265       value_i = *uniq_verts;
266       (*uniq_verts)++;
267     }
268     else {
269       value_i = ~(*face_verts);
270       (*face_verts)++;
271     }
272     *value_p = POINTER_FROM_INT(value_i);
273     return value_i;
274   }
275 
276   return POINTER_AS_INT(*value_p);
277 }
278 
279 /* Find vertices used by the faces in this node and update the draw buffers */
build_mesh_leaf_node(PBVH * pbvh,PBVHNode * node)280 static void build_mesh_leaf_node(PBVH *pbvh, PBVHNode *node)
281 {
282   bool has_visible = false;
283 
284   node->uniq_verts = node->face_verts = 0;
285   const int totface = node->totprim;
286 
287   /* reserve size is rough guess */
288   GHash *map = BLI_ghash_int_new_ex("build_mesh_leaf_node gh", 2 * totface);
289 
290   int(*face_vert_indices)[3] = MEM_mallocN(sizeof(int[3]) * totface, "bvh node face vert indices");
291 
292   node->face_vert_indices = (const int(*)[3])face_vert_indices;
293 
294   if (pbvh->respect_hide == false) {
295     has_visible = true;
296   }
297 
298   for (int i = 0; i < totface; i++) {
299     const MLoopTri *lt = &pbvh->looptri[node->prim_indices[i]];
300     for (int j = 0; j < 3; j++) {
301       face_vert_indices[i][j] = map_insert_vert(
302           pbvh, map, &node->face_verts, &node->uniq_verts, pbvh->mloop[lt->tri[j]].v);
303     }
304 
305     if (has_visible == false) {
306       if (!paint_is_face_hidden(lt, pbvh->verts, pbvh->mloop)) {
307         has_visible = true;
308       }
309     }
310   }
311 
312   int *vert_indices = MEM_callocN(sizeof(int) * (node->uniq_verts + node->face_verts),
313                                   "bvh node vert indices");
314   node->vert_indices = vert_indices;
315 
316   /* Build the vertex list, unique verts first */
317   GHashIterator gh_iter;
318   GHASH_ITER (gh_iter, map) {
319     void *value = BLI_ghashIterator_getValue(&gh_iter);
320     int ndx = POINTER_AS_INT(value);
321 
322     if (ndx < 0) {
323       ndx = -ndx + node->uniq_verts - 1;
324     }
325 
326     vert_indices[ndx] = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter));
327   }
328 
329   for (int i = 0; i < totface; i++) {
330     const int sides = 3;
331 
332     for (int j = 0; j < sides; j++) {
333       if (face_vert_indices[i][j] < 0) {
334         face_vert_indices[i][j] = -face_vert_indices[i][j] + node->uniq_verts - 1;
335       }
336     }
337   }
338 
339   BKE_pbvh_node_mark_rebuild_draw(node);
340 
341   BKE_pbvh_node_fully_hidden_set(node, !has_visible);
342 
343   BLI_ghash_free(map, NULL, NULL);
344 }
345 
update_vb(PBVH * pbvh,PBVHNode * node,BBC * prim_bbc,int offset,int count)346 static void update_vb(PBVH *pbvh, PBVHNode *node, BBC *prim_bbc, int offset, int count)
347 {
348   BB_reset(&node->vb);
349   for (int i = offset + count - 1; i >= offset; i--) {
350     BB_expand_with_bb(&node->vb, (BB *)(&prim_bbc[pbvh->prim_indices[i]]));
351   }
352   node->orig_vb = node->vb;
353 }
354 
355 /* Returns the number of visible quads in the nodes' grids. */
BKE_pbvh_count_grid_quads(BLI_bitmap ** grid_hidden,const int * grid_indices,int totgrid,int gridsize)356 int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
357                               const int *grid_indices,
358                               int totgrid,
359                               int gridsize)
360 {
361   const int gridarea = (gridsize - 1) * (gridsize - 1);
362   int totquad = 0;
363 
364   /* grid hidden layer is present, so have to check each grid for
365    * visibility */
366 
367   for (int i = 0; i < totgrid; i++) {
368     const BLI_bitmap *gh = grid_hidden[grid_indices[i]];
369 
370     if (gh) {
371       /* grid hidden are present, have to check each element */
372       for (int y = 0; y < gridsize - 1; y++) {
373         for (int x = 0; x < gridsize - 1; x++) {
374           if (!paint_is_grid_face_hidden(gh, gridsize, x, y)) {
375             totquad++;
376           }
377         }
378       }
379     }
380     else {
381       totquad += gridarea;
382     }
383   }
384 
385   return totquad;
386 }
387 
BKE_pbvh_sync_face_sets_to_grids(PBVH * pbvh)388 void BKE_pbvh_sync_face_sets_to_grids(PBVH *pbvh)
389 {
390   const int gridsize = pbvh->gridkey.grid_size;
391   for (int i = 0; i < pbvh->totgrid; i++) {
392     BLI_bitmap *gh = pbvh->grid_hidden[i];
393     const int face_index = BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, i);
394     if (!gh && pbvh->face_sets[face_index] < 0) {
395       gh = pbvh->grid_hidden[i] = BLI_BITMAP_NEW(pbvh->gridkey.grid_area,
396                                                  "partialvis_update_grids");
397     }
398     if (gh) {
399       for (int y = 0; y < gridsize; y++) {
400         for (int x = 0; x < gridsize; x++) {
401           BLI_BITMAP_SET(gh, y * gridsize + x, pbvh->face_sets[face_index] < 0);
402         }
403       }
404     }
405   }
406 }
407 
build_grid_leaf_node(PBVH * pbvh,PBVHNode * node)408 static void build_grid_leaf_node(PBVH *pbvh, PBVHNode *node)
409 {
410   int totquads = BKE_pbvh_count_grid_quads(
411       pbvh->grid_hidden, node->prim_indices, node->totprim, pbvh->gridkey.grid_size);
412   BKE_pbvh_node_fully_hidden_set(node, (totquads == 0));
413   BKE_pbvh_node_mark_rebuild_draw(node);
414 }
415 
build_leaf(PBVH * pbvh,int node_index,BBC * prim_bbc,int offset,int count)416 static void build_leaf(PBVH *pbvh, int node_index, BBC *prim_bbc, int offset, int count)
417 {
418   pbvh->nodes[node_index].flag |= PBVH_Leaf;
419 
420   pbvh->nodes[node_index].prim_indices = pbvh->prim_indices + offset;
421   pbvh->nodes[node_index].totprim = count;
422 
423   /* Still need vb for searches */
424   update_vb(pbvh, &pbvh->nodes[node_index], prim_bbc, offset, count);
425 
426   if (pbvh->looptri) {
427     build_mesh_leaf_node(pbvh, pbvh->nodes + node_index);
428   }
429   else {
430     build_grid_leaf_node(pbvh, pbvh->nodes + node_index);
431   }
432 }
433 
434 /* Return zero if all primitives in the node can be drawn with the
435  * same material (including flat/smooth shading), non-zero otherwise */
leaf_needs_material_split(PBVH * pbvh,int offset,int count)436 static bool leaf_needs_material_split(PBVH *pbvh, int offset, int count)
437 {
438   if (count <= 1) {
439     return false;
440   }
441 
442   if (pbvh->looptri) {
443     const MLoopTri *first = &pbvh->looptri[pbvh->prim_indices[offset]];
444     const MPoly *mp = &pbvh->mpoly[first->poly];
445 
446     for (int i = offset + count - 1; i > offset; i--) {
447       int prim = pbvh->prim_indices[i];
448       const MPoly *mp_other = &pbvh->mpoly[pbvh->looptri[prim].poly];
449       if (!face_materials_match(mp, mp_other)) {
450         return true;
451       }
452     }
453   }
454   else {
455     const DMFlagMat *first = &pbvh->grid_flag_mats[pbvh->prim_indices[offset]];
456 
457     for (int i = offset + count - 1; i > offset; i--) {
458       int prim = pbvh->prim_indices[i];
459       if (!grid_materials_match(first, &pbvh->grid_flag_mats[prim])) {
460         return true;
461       }
462     }
463   }
464 
465   return false;
466 }
467 
468 /* Recursively build a node in the tree
469  *
470  * vb is the voxel box around all of the primitives contained in
471  * this node.
472  *
473  * cb is the bounding box around all the centroids of the primitives
474  * contained in this node
475  *
476  * offset and start indicate a range in the array of primitive indices
477  */
478 
build_sub(PBVH * pbvh,int node_index,BB * cb,BBC * prim_bbc,int offset,int count)479 static void build_sub(PBVH *pbvh, int node_index, BB *cb, BBC *prim_bbc, int offset, int count)
480 {
481   int end;
482   BB cb_backing;
483 
484   /* Decide whether this is a leaf or not */
485   const bool below_leaf_limit = count <= pbvh->leaf_limit;
486   if (below_leaf_limit) {
487     if (!leaf_needs_material_split(pbvh, offset, count)) {
488       build_leaf(pbvh, node_index, prim_bbc, offset, count);
489       return;
490     }
491   }
492 
493   /* Add two child nodes */
494   pbvh->nodes[node_index].children_offset = pbvh->totnode;
495   pbvh_grow_nodes(pbvh, pbvh->totnode + 2);
496 
497   /* Update parent node bounding box */
498   update_vb(pbvh, &pbvh->nodes[node_index], prim_bbc, offset, count);
499 
500   if (!below_leaf_limit) {
501     /* Find axis with widest range of primitive centroids */
502     if (!cb) {
503       cb = &cb_backing;
504       BB_reset(cb);
505       for (int i = offset + count - 1; i >= offset; i--) {
506         BB_expand(cb, prim_bbc[pbvh->prim_indices[i]].bcentroid);
507       }
508     }
509     const int axis = BB_widest_axis(cb);
510 
511     /* Partition primitives along that axis */
512     end = partition_indices(pbvh->prim_indices,
513                             offset,
514                             offset + count - 1,
515                             axis,
516                             (cb->bmax[axis] + cb->bmin[axis]) * 0.5f,
517                             prim_bbc);
518   }
519   else {
520     /* Partition primitives by material */
521     end = partition_indices_material(pbvh, offset, offset + count - 1);
522   }
523 
524   /* Build children */
525   build_sub(pbvh, pbvh->nodes[node_index].children_offset, NULL, prim_bbc, offset, end - offset);
526   build_sub(pbvh,
527             pbvh->nodes[node_index].children_offset + 1,
528             NULL,
529             prim_bbc,
530             end,
531             offset + count - end);
532 }
533 
pbvh_build(PBVH * pbvh,BB * cb,BBC * prim_bbc,int totprim)534 static void pbvh_build(PBVH *pbvh, BB *cb, BBC *prim_bbc, int totprim)
535 {
536   if (totprim != pbvh->totprim) {
537     pbvh->totprim = totprim;
538     if (pbvh->nodes) {
539       MEM_freeN(pbvh->nodes);
540     }
541     if (pbvh->prim_indices) {
542       MEM_freeN(pbvh->prim_indices);
543     }
544     pbvh->prim_indices = MEM_mallocN(sizeof(int) * totprim, "bvh prim indices");
545     for (int i = 0; i < totprim; i++) {
546       pbvh->prim_indices[i] = i;
547     }
548     pbvh->totnode = 0;
549     if (pbvh->node_mem_count < 100) {
550       pbvh->node_mem_count = 100;
551       pbvh->nodes = MEM_callocN(sizeof(PBVHNode) * pbvh->node_mem_count, "bvh initial nodes");
552     }
553   }
554 
555   pbvh->totnode = 1;
556   build_sub(pbvh, 0, cb, prim_bbc, 0, totprim);
557 }
558 
559 /**
560  * Do a full rebuild with on Mesh data structure.
561  *
562  * \note Unlike mpoly/mloop/verts, looptri is **totally owned** by PBVH
563  * (which means it may rewrite it if needed, see #BKE_pbvh_vert_coords_apply().
564  */
BKE_pbvh_build_mesh(PBVH * pbvh,const Mesh * mesh,const MPoly * mpoly,const MLoop * mloop,MVert * verts,int totvert,struct CustomData * vdata,struct CustomData * ldata,struct CustomData * pdata,const MLoopTri * looptri,int looptri_num)565 void BKE_pbvh_build_mesh(PBVH *pbvh,
566                          const Mesh *mesh,
567                          const MPoly *mpoly,
568                          const MLoop *mloop,
569                          MVert *verts,
570                          int totvert,
571                          struct CustomData *vdata,
572                          struct CustomData *ldata,
573                          struct CustomData *pdata,
574                          const MLoopTri *looptri,
575                          int looptri_num)
576 {
577   BBC *prim_bbc = NULL;
578   BB cb;
579 
580   pbvh->mesh = mesh;
581   pbvh->type = PBVH_FACES;
582   pbvh->mpoly = mpoly;
583   pbvh->mloop = mloop;
584   pbvh->looptri = looptri;
585   pbvh->verts = verts;
586   pbvh->vert_bitmap = BLI_BITMAP_NEW(totvert, "bvh->vert_bitmap");
587   pbvh->totvert = totvert;
588   pbvh->leaf_limit = LEAF_LIMIT;
589   pbvh->vdata = vdata;
590   pbvh->ldata = ldata;
591   pbvh->pdata = pdata;
592 
593   pbvh->face_sets_color_seed = mesh->face_sets_color_seed;
594   pbvh->face_sets_color_default = mesh->face_sets_color_default;
595 
596   BB_reset(&cb);
597 
598   /* For each face, store the AABB and the AABB centroid */
599   prim_bbc = MEM_mallocN(sizeof(BBC) * looptri_num, "prim_bbc");
600 
601   for (int i = 0; i < looptri_num; i++) {
602     const MLoopTri *lt = &looptri[i];
603     const int sides = 3;
604     BBC *bbc = prim_bbc + i;
605 
606     BB_reset((BB *)bbc);
607 
608     for (int j = 0; j < sides; j++) {
609       BB_expand((BB *)bbc, verts[pbvh->mloop[lt->tri[j]].v].co);
610     }
611 
612     BBC_update_centroid(bbc);
613 
614     BB_expand(&cb, bbc->bcentroid);
615   }
616 
617   if (looptri_num) {
618     pbvh_build(pbvh, &cb, prim_bbc, looptri_num);
619   }
620 
621   MEM_freeN(prim_bbc);
622   MEM_freeN(pbvh->vert_bitmap);
623 }
624 
625 /* Do a full rebuild with on Grids data structure */
BKE_pbvh_build_grids(PBVH * pbvh,CCGElem ** grids,int totgrid,CCGKey * key,void ** gridfaces,DMFlagMat * flagmats,BLI_bitmap ** grid_hidden)626 void BKE_pbvh_build_grids(PBVH *pbvh,
627                           CCGElem **grids,
628                           int totgrid,
629                           CCGKey *key,
630                           void **gridfaces,
631                           DMFlagMat *flagmats,
632                           BLI_bitmap **grid_hidden)
633 {
634   const int gridsize = key->grid_size;
635 
636   pbvh->type = PBVH_GRIDS;
637   pbvh->grids = grids;
638   pbvh->gridfaces = gridfaces;
639   pbvh->grid_flag_mats = flagmats;
640   pbvh->totgrid = totgrid;
641   pbvh->gridkey = *key;
642   pbvh->grid_hidden = grid_hidden;
643   pbvh->leaf_limit = max_ii(LEAF_LIMIT / (gridsize * gridsize), 1);
644 
645   BB cb;
646   BB_reset(&cb);
647 
648   /* For each grid, store the AABB and the AABB centroid */
649   BBC *prim_bbc = MEM_mallocN(sizeof(BBC) * totgrid, "prim_bbc");
650 
651   for (int i = 0; i < totgrid; i++) {
652     CCGElem *grid = grids[i];
653     BBC *bbc = prim_bbc + i;
654 
655     BB_reset((BB *)bbc);
656 
657     for (int j = 0; j < gridsize * gridsize; j++) {
658       BB_expand((BB *)bbc, CCG_elem_offset_co(key, grid, j));
659     }
660 
661     BBC_update_centroid(bbc);
662 
663     BB_expand(&cb, bbc->bcentroid);
664   }
665 
666   if (totgrid) {
667     pbvh_build(pbvh, &cb, prim_bbc, totgrid);
668   }
669 
670   MEM_freeN(prim_bbc);
671 }
672 
BKE_pbvh_new(void)673 PBVH *BKE_pbvh_new(void)
674 {
675   PBVH *pbvh = MEM_callocN(sizeof(PBVH), "pbvh");
676   pbvh->respect_hide = true;
677   return pbvh;
678 }
679 
BKE_pbvh_free(PBVH * pbvh)680 void BKE_pbvh_free(PBVH *pbvh)
681 {
682   for (int i = 0; i < pbvh->totnode; i++) {
683     PBVHNode *node = &pbvh->nodes[i];
684 
685     if (node->flag & PBVH_Leaf) {
686       if (node->draw_buffers) {
687         GPU_pbvh_buffers_free(node->draw_buffers);
688       }
689       if (node->vert_indices) {
690         MEM_freeN((void *)node->vert_indices);
691       }
692       if (node->face_vert_indices) {
693         MEM_freeN((void *)node->face_vert_indices);
694       }
695       if (node->bm_faces) {
696         BLI_gset_free(node->bm_faces, NULL);
697       }
698       if (node->bm_unique_verts) {
699         BLI_gset_free(node->bm_unique_verts, NULL);
700       }
701       if (node->bm_other_verts) {
702         BLI_gset_free(node->bm_other_verts, NULL);
703       }
704     }
705   }
706 
707   if (pbvh->deformed) {
708     if (pbvh->verts) {
709       /* if pbvh was deformed, new memory was allocated for verts/faces -- free it */
710 
711       MEM_freeN((void *)pbvh->verts);
712     }
713   }
714 
715   if (pbvh->looptri) {
716     MEM_freeN((void *)pbvh->looptri);
717   }
718 
719   if (pbvh->nodes) {
720     MEM_freeN(pbvh->nodes);
721   }
722 
723   if (pbvh->prim_indices) {
724     MEM_freeN(pbvh->prim_indices);
725   }
726 
727   MEM_freeN(pbvh);
728 }
729 
pbvh_iter_begin(PBVHIter * iter,PBVH * pbvh,BKE_pbvh_SearchCallback scb,void * search_data)730 static void pbvh_iter_begin(PBVHIter *iter,
731                             PBVH *pbvh,
732                             BKE_pbvh_SearchCallback scb,
733                             void *search_data)
734 {
735   iter->pbvh = pbvh;
736   iter->scb = scb;
737   iter->search_data = search_data;
738 
739   iter->stack = iter->stackfixed;
740   iter->stackspace = STACK_FIXED_DEPTH;
741 
742   iter->stack[0].node = pbvh->nodes;
743   iter->stack[0].revisiting = false;
744   iter->stacksize = 1;
745 }
746 
pbvh_iter_end(PBVHIter * iter)747 static void pbvh_iter_end(PBVHIter *iter)
748 {
749   if (iter->stackspace > STACK_FIXED_DEPTH) {
750     MEM_freeN(iter->stack);
751   }
752 }
753 
pbvh_stack_push(PBVHIter * iter,PBVHNode * node,bool revisiting)754 static void pbvh_stack_push(PBVHIter *iter, PBVHNode *node, bool revisiting)
755 {
756   if (UNLIKELY(iter->stacksize == iter->stackspace)) {
757     iter->stackspace *= 2;
758     if (iter->stackspace != (STACK_FIXED_DEPTH * 2)) {
759       iter->stack = MEM_reallocN(iter->stack, sizeof(PBVHStack) * iter->stackspace);
760     }
761     else {
762       iter->stack = MEM_mallocN(sizeof(PBVHStack) * iter->stackspace, "PBVHStack");
763       memcpy(iter->stack, iter->stackfixed, sizeof(PBVHStack) * iter->stacksize);
764     }
765   }
766 
767   iter->stack[iter->stacksize].node = node;
768   iter->stack[iter->stacksize].revisiting = revisiting;
769   iter->stacksize++;
770 }
771 
pbvh_iter_next(PBVHIter * iter)772 static PBVHNode *pbvh_iter_next(PBVHIter *iter)
773 {
774   /* purpose here is to traverse tree, visiting child nodes before their
775    * parents, this order is necessary for e.g. computing bounding boxes */
776 
777   while (iter->stacksize) {
778     /* pop node */
779     iter->stacksize--;
780     PBVHNode *node = iter->stack[iter->stacksize].node;
781 
782     /* on a mesh with no faces this can happen
783      * can remove this check if we know meshes have at least 1 face */
784     if (node == NULL) {
785       return NULL;
786     }
787 
788     bool revisiting = iter->stack[iter->stacksize].revisiting;
789 
790     /* revisiting node already checked */
791     if (revisiting) {
792       return node;
793     }
794 
795     if (iter->scb && !iter->scb(node, iter->search_data)) {
796       continue; /* don't traverse, outside of search zone */
797     }
798 
799     if (node->flag & PBVH_Leaf) {
800       /* immediately hit leaf node */
801       return node;
802     }
803 
804     /* come back later when children are done */
805     pbvh_stack_push(iter, node, true);
806 
807     /* push two child nodes on the stack */
808     pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset + 1, false);
809     pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset, false);
810   }
811 
812   return NULL;
813 }
814 
pbvh_iter_next_occluded(PBVHIter * iter)815 static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
816 {
817   while (iter->stacksize) {
818     /* pop node */
819     iter->stacksize--;
820     PBVHNode *node = iter->stack[iter->stacksize].node;
821 
822     /* on a mesh with no faces this can happen
823      * can remove this check if we know meshes have at least 1 face */
824     if (node == NULL) {
825       return NULL;
826     }
827 
828     if (iter->scb && !iter->scb(node, iter->search_data)) {
829       continue; /* don't traverse, outside of search zone */
830     }
831 
832     if (node->flag & PBVH_Leaf) {
833       /* immediately hit leaf node */
834       return node;
835     }
836 
837     pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset + 1, false);
838     pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset, false);
839   }
840 
841   return NULL;
842 }
843 
BKE_pbvh_search_gather(PBVH * pbvh,BKE_pbvh_SearchCallback scb,void * search_data,PBVHNode *** r_array,int * r_tot)844 void BKE_pbvh_search_gather(
845     PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***r_array, int *r_tot)
846 {
847   PBVHIter iter;
848   PBVHNode **array = NULL, *node;
849   int tot = 0, space = 0;
850 
851   pbvh_iter_begin(&iter, pbvh, scb, search_data);
852 
853   while ((node = pbvh_iter_next(&iter))) {
854     if (node->flag & PBVH_Leaf) {
855       if (UNLIKELY(tot == space)) {
856         /* resize array if needed */
857         space = (tot == 0) ? 32 : space * 2;
858         array = MEM_recallocN_id(array, sizeof(PBVHNode *) * space, __func__);
859       }
860 
861       array[tot] = node;
862       tot++;
863     }
864   }
865 
866   pbvh_iter_end(&iter);
867 
868   if (tot == 0 && array) {
869     MEM_freeN(array);
870     array = NULL;
871   }
872 
873   *r_array = array;
874   *r_tot = tot;
875 }
876 
BKE_pbvh_search_callback(PBVH * pbvh,BKE_pbvh_SearchCallback scb,void * search_data,BKE_pbvh_HitCallback hcb,void * hit_data)877 void BKE_pbvh_search_callback(PBVH *pbvh,
878                               BKE_pbvh_SearchCallback scb,
879                               void *search_data,
880                               BKE_pbvh_HitCallback hcb,
881                               void *hit_data)
882 {
883   PBVHIter iter;
884   PBVHNode *node;
885 
886   pbvh_iter_begin(&iter, pbvh, scb, search_data);
887 
888   while ((node = pbvh_iter_next(&iter))) {
889     if (node->flag & PBVH_Leaf) {
890       hcb(node, hit_data);
891     }
892   }
893 
894   pbvh_iter_end(&iter);
895 }
896 
897 typedef struct node_tree {
898   PBVHNode *data;
899 
900   struct node_tree *left;
901   struct node_tree *right;
902 } node_tree;
903 
node_tree_insert(node_tree * tree,node_tree * new_node)904 static void node_tree_insert(node_tree *tree, node_tree *new_node)
905 {
906   if (new_node->data->tmin < tree->data->tmin) {
907     if (tree->left) {
908       node_tree_insert(tree->left, new_node);
909     }
910     else {
911       tree->left = new_node;
912     }
913   }
914   else {
915     if (tree->right) {
916       node_tree_insert(tree->right, new_node);
917     }
918     else {
919       tree->right = new_node;
920     }
921   }
922 }
923 
traverse_tree(node_tree * tree,BKE_pbvh_HitOccludedCallback hcb,void * hit_data,float * tmin)924 static void traverse_tree(node_tree *tree,
925                           BKE_pbvh_HitOccludedCallback hcb,
926                           void *hit_data,
927                           float *tmin)
928 {
929   if (tree->left) {
930     traverse_tree(tree->left, hcb, hit_data, tmin);
931   }
932 
933   hcb(tree->data, hit_data, tmin);
934 
935   if (tree->right) {
936     traverse_tree(tree->right, hcb, hit_data, tmin);
937   }
938 }
939 
free_tree(node_tree * tree)940 static void free_tree(node_tree *tree)
941 {
942   if (tree->left) {
943     free_tree(tree->left);
944     tree->left = NULL;
945   }
946 
947   if (tree->right) {
948     free_tree(tree->right);
949     tree->right = NULL;
950   }
951 
952   free(tree);
953 }
954 
BKE_pbvh_node_get_tmin(PBVHNode * node)955 float BKE_pbvh_node_get_tmin(PBVHNode *node)
956 {
957   return node->tmin;
958 }
959 
BKE_pbvh_search_callback_occluded(PBVH * pbvh,BKE_pbvh_SearchCallback scb,void * search_data,BKE_pbvh_HitOccludedCallback hcb,void * hit_data)960 static void BKE_pbvh_search_callback_occluded(PBVH *pbvh,
961                                               BKE_pbvh_SearchCallback scb,
962                                               void *search_data,
963                                               BKE_pbvh_HitOccludedCallback hcb,
964                                               void *hit_data)
965 {
966   PBVHIter iter;
967   PBVHNode *node;
968   node_tree *tree = NULL;
969 
970   pbvh_iter_begin(&iter, pbvh, scb, search_data);
971 
972   while ((node = pbvh_iter_next_occluded(&iter))) {
973     if (node->flag & PBVH_Leaf) {
974       node_tree *new_node = malloc(sizeof(node_tree));
975 
976       new_node->data = node;
977 
978       new_node->left = NULL;
979       new_node->right = NULL;
980 
981       if (tree) {
982         node_tree_insert(tree, new_node);
983       }
984       else {
985         tree = new_node;
986       }
987     }
988   }
989 
990   pbvh_iter_end(&iter);
991 
992   if (tree) {
993     float tmin = FLT_MAX;
994     traverse_tree(tree, hcb, hit_data, &tmin);
995     free_tree(tree);
996   }
997 }
998 
update_search_cb(PBVHNode * node,void * data_v)999 static bool update_search_cb(PBVHNode *node, void *data_v)
1000 {
1001   int flag = POINTER_AS_INT(data_v);
1002 
1003   if (node->flag & PBVH_Leaf) {
1004     return (node->flag & flag) != 0;
1005   }
1006 
1007   return true;
1008 }
1009 
1010 typedef struct PBVHUpdateData {
1011   PBVH *pbvh;
1012   PBVHNode **nodes;
1013   int totnode;
1014 
1015   float (*vnors)[3];
1016   int flag;
1017   bool show_sculpt_face_sets;
1018 } PBVHUpdateData;
1019 
pbvh_update_normals_accum_task_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))1020 static void pbvh_update_normals_accum_task_cb(void *__restrict userdata,
1021                                               const int n,
1022                                               const TaskParallelTLS *__restrict UNUSED(tls))
1023 {
1024   PBVHUpdateData *data = userdata;
1025 
1026   PBVH *pbvh = data->pbvh;
1027   PBVHNode *node = data->nodes[n];
1028   float(*vnors)[3] = data->vnors;
1029 
1030   if ((node->flag & PBVH_UpdateNormals)) {
1031     unsigned int mpoly_prev = UINT_MAX;
1032     float fn[3];
1033 
1034     const int *faces = node->prim_indices;
1035     const int totface = node->totprim;
1036 
1037     for (int i = 0; i < totface; i++) {
1038       const MLoopTri *lt = &pbvh->looptri[faces[i]];
1039       const unsigned int vtri[3] = {
1040           pbvh->mloop[lt->tri[0]].v,
1041           pbvh->mloop[lt->tri[1]].v,
1042           pbvh->mloop[lt->tri[2]].v,
1043       };
1044       const int sides = 3;
1045 
1046       /* Face normal and mask */
1047       if (lt->poly != mpoly_prev) {
1048         const MPoly *mp = &pbvh->mpoly[lt->poly];
1049         BKE_mesh_calc_poly_normal(mp, &pbvh->mloop[mp->loopstart], pbvh->verts, fn);
1050         mpoly_prev = lt->poly;
1051       }
1052 
1053       for (int j = sides; j--;) {
1054         const int v = vtri[j];
1055 
1056         if (pbvh->verts[v].flag & ME_VERT_PBVH_UPDATE) {
1057           /* Note: This avoids `lock, add_v3_v3, unlock`
1058            * and is five to ten times quicker than a spin-lock.
1059            * Not exact equivalent though, since atomicity is only ensured for one component
1060            * of the vector at a time, but here it shall not make any sensible difference. */
1061           for (int k = 3; k--;) {
1062             atomic_add_and_fetch_fl(&vnors[v][k], fn[k]);
1063           }
1064         }
1065       }
1066     }
1067   }
1068 }
1069 
pbvh_update_normals_store_task_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))1070 static void pbvh_update_normals_store_task_cb(void *__restrict userdata,
1071                                               const int n,
1072                                               const TaskParallelTLS *__restrict UNUSED(tls))
1073 {
1074   PBVHUpdateData *data = userdata;
1075   PBVH *pbvh = data->pbvh;
1076   PBVHNode *node = data->nodes[n];
1077   float(*vnors)[3] = data->vnors;
1078 
1079   if (node->flag & PBVH_UpdateNormals) {
1080     const int *verts = node->vert_indices;
1081     const int totvert = node->uniq_verts;
1082 
1083     for (int i = 0; i < totvert; i++) {
1084       const int v = verts[i];
1085       MVert *mvert = &pbvh->verts[v];
1086 
1087       /* No atomics necessary because we are iterating over uniq_verts only,
1088        * so we know only this thread will handle this vertex. */
1089       if (mvert->flag & ME_VERT_PBVH_UPDATE) {
1090         normalize_v3(vnors[v]);
1091         normal_float_to_short_v3(mvert->no, vnors[v]);
1092         mvert->flag &= ~ME_VERT_PBVH_UPDATE;
1093       }
1094     }
1095 
1096     node->flag &= ~PBVH_UpdateNormals;
1097   }
1098 }
1099 
pbvh_faces_update_normals(PBVH * pbvh,PBVHNode ** nodes,int totnode)1100 static void pbvh_faces_update_normals(PBVH *pbvh, PBVHNode **nodes, int totnode)
1101 {
1102   /* could be per node to save some memory, but also means
1103    * we have to store for each vertex which node it is in */
1104   float(*vnors)[3] = MEM_callocN(sizeof(*vnors) * pbvh->totvert, __func__);
1105 
1106   /* subtle assumptions:
1107    * - We know that for all edited vertices, the nodes with faces
1108    *   adjacent to these vertices have been marked with PBVH_UpdateNormals.
1109    *   This is true because if the vertex is inside the brush radius, the
1110    *   bounding box of its adjacent faces will be as well.
1111    * - However this is only true for the vertices that have actually been
1112    *   edited, not for all vertices in the nodes marked for update, so we
1113    *   can only update vertices marked with ME_VERT_PBVH_UPDATE.
1114    */
1115 
1116   PBVHUpdateData data = {
1117       .pbvh = pbvh,
1118       .nodes = nodes,
1119       .vnors = vnors,
1120   };
1121 
1122   TaskParallelSettings settings;
1123   BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1124 
1125   BLI_task_parallel_range(0, totnode, &data, pbvh_update_normals_accum_task_cb, &settings);
1126   BLI_task_parallel_range(0, totnode, &data, pbvh_update_normals_store_task_cb, &settings);
1127 
1128   MEM_freeN(vnors);
1129 }
1130 
pbvh_update_mask_redraw_task_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))1131 static void pbvh_update_mask_redraw_task_cb(void *__restrict userdata,
1132                                             const int n,
1133                                             const TaskParallelTLS *__restrict UNUSED(tls))
1134 {
1135 
1136   PBVHUpdateData *data = userdata;
1137   PBVH *pbvh = data->pbvh;
1138   PBVHNode *node = data->nodes[n];
1139   if (node->flag & PBVH_UpdateMask) {
1140 
1141     bool has_unmasked = false;
1142     bool has_masked = true;
1143     if (node->flag & PBVH_Leaf) {
1144       PBVHVertexIter vd;
1145 
1146       BKE_pbvh_vertex_iter_begin(pbvh, node, vd, PBVH_ITER_ALL)
1147       {
1148         if (vd.mask && *vd.mask < 1.0f) {
1149           has_unmasked = true;
1150         }
1151         if (vd.mask && *vd.mask > 0.0f) {
1152           has_masked = false;
1153         }
1154       }
1155       BKE_pbvh_vertex_iter_end;
1156     }
1157     else {
1158       has_unmasked = true;
1159       has_masked = true;
1160     }
1161     BKE_pbvh_node_fully_masked_set(node, !has_unmasked);
1162     BKE_pbvh_node_fully_unmasked_set(node, has_masked);
1163 
1164     node->flag &= ~PBVH_UpdateMask;
1165   }
1166 }
1167 
pbvh_update_mask_redraw(PBVH * pbvh,PBVHNode ** nodes,int totnode,int flag)1168 static void pbvh_update_mask_redraw(PBVH *pbvh, PBVHNode **nodes, int totnode, int flag)
1169 {
1170   PBVHUpdateData data = {
1171       .pbvh = pbvh,
1172       .nodes = nodes,
1173       .flag = flag,
1174   };
1175 
1176   TaskParallelSettings settings;
1177   BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1178   BLI_task_parallel_range(0, totnode, &data, pbvh_update_mask_redraw_task_cb, &settings);
1179 }
1180 
pbvh_update_visibility_redraw_task_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))1181 static void pbvh_update_visibility_redraw_task_cb(void *__restrict userdata,
1182                                                   const int n,
1183                                                   const TaskParallelTLS *__restrict UNUSED(tls))
1184 {
1185 
1186   PBVHUpdateData *data = userdata;
1187   PBVH *pbvh = data->pbvh;
1188   PBVHNode *node = data->nodes[n];
1189   if (node->flag & PBVH_UpdateVisibility) {
1190     node->flag &= ~PBVH_UpdateVisibility;
1191     BKE_pbvh_node_fully_hidden_set(node, true);
1192     if (node->flag & PBVH_Leaf) {
1193       PBVHVertexIter vd;
1194       BKE_pbvh_vertex_iter_begin(pbvh, node, vd, PBVH_ITER_ALL)
1195       {
1196         if (vd.visible) {
1197           BKE_pbvh_node_fully_hidden_set(node, false);
1198           return;
1199         }
1200       }
1201       BKE_pbvh_vertex_iter_end;
1202     }
1203   }
1204 }
1205 
pbvh_update_visibility_redraw(PBVH * pbvh,PBVHNode ** nodes,int totnode,int flag)1206 static void pbvh_update_visibility_redraw(PBVH *pbvh, PBVHNode **nodes, int totnode, int flag)
1207 {
1208   PBVHUpdateData data = {
1209       .pbvh = pbvh,
1210       .nodes = nodes,
1211       .flag = flag,
1212   };
1213 
1214   TaskParallelSettings settings;
1215   BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1216   BLI_task_parallel_range(0, totnode, &data, pbvh_update_visibility_redraw_task_cb, &settings);
1217 }
1218 
pbvh_update_BB_redraw_task_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))1219 static void pbvh_update_BB_redraw_task_cb(void *__restrict userdata,
1220                                           const int n,
1221                                           const TaskParallelTLS *__restrict UNUSED(tls))
1222 {
1223   PBVHUpdateData *data = userdata;
1224   PBVH *pbvh = data->pbvh;
1225   PBVHNode *node = data->nodes[n];
1226   const int flag = data->flag;
1227 
1228   if ((flag & PBVH_UpdateBB) && (node->flag & PBVH_UpdateBB)) {
1229     /* don't clear flag yet, leave it for flushing later */
1230     /* Note that bvh usage is read-only here, so no need to thread-protect it. */
1231     update_node_vb(pbvh, node);
1232   }
1233 
1234   if ((flag & PBVH_UpdateOriginalBB) && (node->flag & PBVH_UpdateOriginalBB)) {
1235     node->orig_vb = node->vb;
1236   }
1237 
1238   if ((flag & PBVH_UpdateRedraw) && (node->flag & PBVH_UpdateRedraw)) {
1239     node->flag &= ~PBVH_UpdateRedraw;
1240   }
1241 }
1242 
pbvh_update_BB_redraw(PBVH * pbvh,PBVHNode ** nodes,int totnode,int flag)1243 void pbvh_update_BB_redraw(PBVH *pbvh, PBVHNode **nodes, int totnode, int flag)
1244 {
1245   /* update BB, redraw flag */
1246   PBVHUpdateData data = {
1247       .pbvh = pbvh,
1248       .nodes = nodes,
1249       .flag = flag,
1250   };
1251 
1252   TaskParallelSettings settings;
1253   BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1254   BLI_task_parallel_range(0, totnode, &data, pbvh_update_BB_redraw_task_cb, &settings);
1255 }
1256 
pbvh_get_buffers_update_flags(PBVH * UNUSED (pbvh))1257 static int pbvh_get_buffers_update_flags(PBVH *UNUSED(pbvh))
1258 {
1259   int update_flags = GPU_PBVH_BUFFERS_SHOW_VCOL | GPU_PBVH_BUFFERS_SHOW_MASK |
1260                      GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS;
1261   return update_flags;
1262 }
1263 
pbvh_update_draw_buffer_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))1264 static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
1265                                        const int n,
1266                                        const TaskParallelTLS *__restrict UNUSED(tls))
1267 {
1268   /* Create and update draw buffers. The functions called here must not
1269    * do any OpenGL calls. Flags are not cleared immediately, that happens
1270    * after GPU_pbvh_buffer_flush() which does the final OpenGL calls. */
1271   PBVHUpdateData *data = userdata;
1272   PBVH *pbvh = data->pbvh;
1273   PBVHNode *node = data->nodes[n];
1274 
1275   if (node->flag & PBVH_RebuildDrawBuffers) {
1276     switch (pbvh->type) {
1277       case PBVH_GRIDS:
1278         node->draw_buffers = GPU_pbvh_grid_buffers_build(node->totprim, pbvh->grid_hidden);
1279         break;
1280       case PBVH_FACES:
1281         node->draw_buffers = GPU_pbvh_mesh_buffers_build(
1282             pbvh->mpoly,
1283             pbvh->mloop,
1284             pbvh->looptri,
1285             pbvh->verts,
1286             node->prim_indices,
1287             CustomData_get_layer(pbvh->pdata, CD_SCULPT_FACE_SETS),
1288             node->totprim,
1289             pbvh->mesh);
1290         break;
1291       case PBVH_BMESH:
1292         node->draw_buffers = GPU_pbvh_bmesh_buffers_build(pbvh->flags &
1293                                                           PBVH_DYNTOPO_SMOOTH_SHADING);
1294         break;
1295     }
1296   }
1297 
1298   if (node->flag & PBVH_UpdateDrawBuffers) {
1299     const int update_flags = pbvh_get_buffers_update_flags(pbvh);
1300     switch (pbvh->type) {
1301       case PBVH_GRIDS:
1302         GPU_pbvh_grid_buffers_update(node->draw_buffers,
1303                                      pbvh->subdiv_ccg,
1304                                      pbvh->grids,
1305                                      pbvh->grid_flag_mats,
1306                                      node->prim_indices,
1307                                      node->totprim,
1308                                      pbvh->face_sets,
1309                                      pbvh->face_sets_color_seed,
1310                                      pbvh->face_sets_color_default,
1311                                      &pbvh->gridkey,
1312                                      update_flags);
1313         break;
1314       case PBVH_FACES:
1315         GPU_pbvh_mesh_buffers_update(node->draw_buffers,
1316                                      pbvh->verts,
1317                                      CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK),
1318                                      CustomData_get_layer(pbvh->ldata, CD_MLOOPCOL),
1319                                      CustomData_get_layer(pbvh->pdata, CD_SCULPT_FACE_SETS),
1320                                      pbvh->face_sets_color_seed,
1321                                      pbvh->face_sets_color_default,
1322                                      CustomData_get_layer(pbvh->vdata, CD_PROP_COLOR),
1323                                      update_flags);
1324         break;
1325       case PBVH_BMESH:
1326         GPU_pbvh_bmesh_buffers_update(node->draw_buffers,
1327                                       pbvh->bm,
1328                                       node->bm_faces,
1329                                       node->bm_unique_verts,
1330                                       node->bm_other_verts,
1331                                       update_flags);
1332         break;
1333     }
1334   }
1335 }
1336 
pbvh_update_draw_buffers(PBVH * pbvh,PBVHNode ** nodes,int totnode,int update_flag)1337 static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode, int update_flag)
1338 {
1339   if ((update_flag & PBVH_RebuildDrawBuffers) || ELEM(pbvh->type, PBVH_GRIDS, PBVH_BMESH)) {
1340     /* Free buffers uses OpenGL, so not in parallel. */
1341     for (int n = 0; n < totnode; n++) {
1342       PBVHNode *node = nodes[n];
1343       if (node->flag & PBVH_RebuildDrawBuffers) {
1344         GPU_pbvh_buffers_free(node->draw_buffers);
1345         node->draw_buffers = NULL;
1346       }
1347       else if ((node->flag & PBVH_UpdateDrawBuffers) && node->draw_buffers) {
1348         if (pbvh->type == PBVH_GRIDS) {
1349           GPU_pbvh_grid_buffers_update_free(
1350               node->draw_buffers, pbvh->grid_flag_mats, node->prim_indices);
1351         }
1352         else if (pbvh->type == PBVH_BMESH) {
1353           GPU_pbvh_bmesh_buffers_update_free(node->draw_buffers);
1354         }
1355       }
1356     }
1357   }
1358 
1359   /* Parallel creation and update of draw buffers. */
1360   PBVHUpdateData data = {
1361       .pbvh = pbvh,
1362       .nodes = nodes,
1363   };
1364 
1365   TaskParallelSettings settings;
1366   BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1367   BLI_task_parallel_range(0, totnode, &data, pbvh_update_draw_buffer_cb, &settings);
1368 }
1369 
pbvh_flush_bb(PBVH * pbvh,PBVHNode * node,int flag)1370 static int pbvh_flush_bb(PBVH *pbvh, PBVHNode *node, int flag)
1371 {
1372   int update = 0;
1373 
1374   /* difficult to multithread well, we just do single threaded recursive */
1375   if (node->flag & PBVH_Leaf) {
1376     if (flag & PBVH_UpdateBB) {
1377       update |= (node->flag & PBVH_UpdateBB);
1378       node->flag &= ~PBVH_UpdateBB;
1379     }
1380 
1381     if (flag & PBVH_UpdateOriginalBB) {
1382       update |= (node->flag & PBVH_UpdateOriginalBB);
1383       node->flag &= ~PBVH_UpdateOriginalBB;
1384     }
1385 
1386     return update;
1387   }
1388 
1389   update |= pbvh_flush_bb(pbvh, pbvh->nodes + node->children_offset, flag);
1390   update |= pbvh_flush_bb(pbvh, pbvh->nodes + node->children_offset + 1, flag);
1391 
1392   if (update & PBVH_UpdateBB) {
1393     update_node_vb(pbvh, node);
1394   }
1395   if (update & PBVH_UpdateOriginalBB) {
1396     node->orig_vb = node->vb;
1397   }
1398 
1399   return update;
1400 }
1401 
BKE_pbvh_update_bounds(PBVH * pbvh,int flag)1402 void BKE_pbvh_update_bounds(PBVH *pbvh, int flag)
1403 {
1404   if (!pbvh->nodes) {
1405     return;
1406   }
1407 
1408   PBVHNode **nodes;
1409   int totnode;
1410 
1411   BKE_pbvh_search_gather(pbvh, update_search_cb, POINTER_FROM_INT(flag), &nodes, &totnode);
1412 
1413   if (flag & (PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw)) {
1414     pbvh_update_BB_redraw(pbvh, nodes, totnode, flag);
1415   }
1416 
1417   if (flag & (PBVH_UpdateBB | PBVH_UpdateOriginalBB)) {
1418     pbvh_flush_bb(pbvh, pbvh->nodes, flag);
1419   }
1420 
1421   MEM_SAFE_FREE(nodes);
1422 }
1423 
BKE_pbvh_update_vertex_data(PBVH * pbvh,int flag)1424 void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flag)
1425 {
1426   if (!pbvh->nodes) {
1427     return;
1428   }
1429 
1430   PBVHNode **nodes;
1431   int totnode;
1432 
1433   BKE_pbvh_search_gather(pbvh, update_search_cb, POINTER_FROM_INT(flag), &nodes, &totnode);
1434 
1435   if (flag & (PBVH_UpdateMask)) {
1436     pbvh_update_mask_redraw(pbvh, nodes, totnode, flag);
1437   }
1438 
1439   if (flag & (PBVH_UpdateColor)) {
1440     /* Do nothing */
1441   }
1442 
1443   if (flag & (PBVH_UpdateVisibility)) {
1444     pbvh_update_visibility_redraw(pbvh, nodes, totnode, flag);
1445   }
1446 
1447   if (nodes) {
1448     MEM_freeN(nodes);
1449   }
1450 }
1451 
pbvh_faces_node_visibility_update(PBVH * pbvh,PBVHNode * node)1452 static void pbvh_faces_node_visibility_update(PBVH *pbvh, PBVHNode *node)
1453 {
1454   MVert *mvert;
1455   const int *vert_indices;
1456   int totvert, i;
1457   BKE_pbvh_node_num_verts(pbvh, node, NULL, &totvert);
1458   BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
1459 
1460   for (i = 0; i < totvert; i++) {
1461     MVert *v = &mvert[vert_indices[i]];
1462     if (!(v->flag & ME_HIDE)) {
1463       BKE_pbvh_node_fully_hidden_set(node, false);
1464       return;
1465     }
1466   }
1467 
1468   BKE_pbvh_node_fully_hidden_set(node, true);
1469 }
1470 
pbvh_grids_node_visibility_update(PBVH * pbvh,PBVHNode * node)1471 static void pbvh_grids_node_visibility_update(PBVH *pbvh, PBVHNode *node)
1472 {
1473   CCGElem **grids;
1474   BLI_bitmap **grid_hidden;
1475   int *grid_indices, totgrid, i;
1476 
1477   BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, NULL, NULL, &grids);
1478   grid_hidden = BKE_pbvh_grid_hidden(pbvh);
1479   CCGKey key = *BKE_pbvh_get_grid_key(pbvh);
1480 
1481   for (i = 0; i < totgrid; i++) {
1482     int g = grid_indices[i], x, y;
1483     BLI_bitmap *gh = grid_hidden[g];
1484 
1485     if (!gh) {
1486       BKE_pbvh_node_fully_hidden_set(node, false);
1487       return;
1488     }
1489 
1490     for (y = 0; y < key.grid_size; y++) {
1491       for (x = 0; x < key.grid_size; x++) {
1492         if (!BLI_BITMAP_TEST(gh, y * key.grid_size + x)) {
1493           BKE_pbvh_node_fully_hidden_set(node, false);
1494           return;
1495         }
1496       }
1497     }
1498   }
1499   BKE_pbvh_node_fully_hidden_set(node, true);
1500 }
1501 
pbvh_bmesh_node_visibility_update(PBVHNode * node)1502 static void pbvh_bmesh_node_visibility_update(PBVHNode *node)
1503 {
1504   GSet *unique, *other;
1505 
1506   unique = BKE_pbvh_bmesh_node_unique_verts(node);
1507   other = BKE_pbvh_bmesh_node_other_verts(node);
1508 
1509   GSetIterator gs_iter;
1510 
1511   GSET_ITER (gs_iter, unique) {
1512     BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
1513     if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
1514       BKE_pbvh_node_fully_hidden_set(node, false);
1515       return;
1516     }
1517   }
1518 
1519   GSET_ITER (gs_iter, other) {
1520     BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
1521     if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
1522       BKE_pbvh_node_fully_hidden_set(node, false);
1523       return;
1524     }
1525   }
1526 
1527   BKE_pbvh_node_fully_hidden_set(node, true);
1528 }
1529 
pbvh_update_visibility_task_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))1530 static void pbvh_update_visibility_task_cb(void *__restrict userdata,
1531                                            const int n,
1532                                            const TaskParallelTLS *__restrict UNUSED(tls))
1533 {
1534 
1535   PBVHUpdateData *data = userdata;
1536   PBVH *pbvh = data->pbvh;
1537   PBVHNode *node = data->nodes[n];
1538   if (node->flag & PBVH_UpdateVisibility) {
1539     switch (BKE_pbvh_type(pbvh)) {
1540       case PBVH_FACES:
1541         pbvh_faces_node_visibility_update(pbvh, node);
1542         break;
1543       case PBVH_GRIDS:
1544         pbvh_grids_node_visibility_update(pbvh, node);
1545         break;
1546       case PBVH_BMESH:
1547         pbvh_bmesh_node_visibility_update(node);
1548         break;
1549     }
1550     node->flag &= ~PBVH_UpdateVisibility;
1551   }
1552 }
1553 
pbvh_update_visibility(PBVH * pbvh,PBVHNode ** nodes,int totnode)1554 static void pbvh_update_visibility(PBVH *pbvh, PBVHNode **nodes, int totnode)
1555 {
1556   PBVHUpdateData data = {
1557       .pbvh = pbvh,
1558       .nodes = nodes,
1559   };
1560 
1561   TaskParallelSettings settings;
1562   BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1563   BLI_task_parallel_range(0, totnode, &data, pbvh_update_visibility_task_cb, &settings);
1564 }
1565 
BKE_pbvh_update_visibility(PBVH * pbvh)1566 void BKE_pbvh_update_visibility(PBVH *pbvh)
1567 {
1568   if (!pbvh->nodes) {
1569     return;
1570   }
1571 
1572   PBVHNode **nodes;
1573   int totnode;
1574 
1575   BKE_pbvh_search_gather(
1576       pbvh, update_search_cb, POINTER_FROM_INT(PBVH_UpdateVisibility), &nodes, &totnode);
1577   pbvh_update_visibility(pbvh, nodes, totnode);
1578 
1579   if (nodes) {
1580     MEM_freeN(nodes);
1581   }
1582 }
1583 
BKE_pbvh_redraw_BB(PBVH * pbvh,float bb_min[3],float bb_max[3])1584 void BKE_pbvh_redraw_BB(PBVH *pbvh, float bb_min[3], float bb_max[3])
1585 {
1586   PBVHIter iter;
1587   PBVHNode *node;
1588   BB bb;
1589 
1590   BB_reset(&bb);
1591 
1592   pbvh_iter_begin(&iter, pbvh, NULL, NULL);
1593 
1594   while ((node = pbvh_iter_next(&iter))) {
1595     if (node->flag & PBVH_UpdateRedraw) {
1596       BB_expand_with_bb(&bb, &node->vb);
1597     }
1598   }
1599 
1600   pbvh_iter_end(&iter);
1601 
1602   copy_v3_v3(bb_min, bb.bmin);
1603   copy_v3_v3(bb_max, bb.bmax);
1604 }
1605 
BKE_pbvh_get_grid_updates(PBVH * pbvh,bool clear,void *** r_gridfaces,int * r_totface)1606 void BKE_pbvh_get_grid_updates(PBVH *pbvh, bool clear, void ***r_gridfaces, int *r_totface)
1607 {
1608   GSet *face_set = BLI_gset_ptr_new(__func__);
1609   PBVHNode *node;
1610   PBVHIter iter;
1611 
1612   pbvh_iter_begin(&iter, pbvh, NULL, NULL);
1613 
1614   while ((node = pbvh_iter_next(&iter))) {
1615     if (node->flag & PBVH_UpdateNormals) {
1616       for (uint i = 0; i < node->totprim; i++) {
1617         void *face = pbvh->gridfaces[node->prim_indices[i]];
1618         BLI_gset_add(face_set, face);
1619       }
1620 
1621       if (clear) {
1622         node->flag &= ~PBVH_UpdateNormals;
1623       }
1624     }
1625   }
1626 
1627   pbvh_iter_end(&iter);
1628 
1629   const int tot = BLI_gset_len(face_set);
1630   if (tot == 0) {
1631     *r_totface = 0;
1632     *r_gridfaces = NULL;
1633     BLI_gset_free(face_set, NULL);
1634     return;
1635   }
1636 
1637   void **faces = MEM_mallocN(sizeof(*faces) * tot, "PBVH Grid Faces");
1638 
1639   GSetIterator gs_iter;
1640   int i;
1641   GSET_ITER_INDEX (gs_iter, face_set, i) {
1642     faces[i] = BLI_gsetIterator_getKey(&gs_iter);
1643   }
1644 
1645   BLI_gset_free(face_set, NULL);
1646 
1647   *r_totface = tot;
1648   *r_gridfaces = faces;
1649 }
1650 
1651 /***************************** PBVH Access ***********************************/
1652 
BKE_pbvh_type(const PBVH * pbvh)1653 PBVHType BKE_pbvh_type(const PBVH *pbvh)
1654 {
1655   return pbvh->type;
1656 }
1657 
BKE_pbvh_has_faces(const PBVH * pbvh)1658 bool BKE_pbvh_has_faces(const PBVH *pbvh)
1659 {
1660   if (pbvh->type == PBVH_BMESH) {
1661     return (pbvh->bm->totface != 0);
1662   }
1663 
1664   return (pbvh->totprim != 0);
1665 }
1666 
BKE_pbvh_bounding_box(const PBVH * pbvh,float min[3],float max[3])1667 void BKE_pbvh_bounding_box(const PBVH *pbvh, float min[3], float max[3])
1668 {
1669   if (pbvh->totnode) {
1670     const BB *bb = &pbvh->nodes[0].vb;
1671     copy_v3_v3(min, bb->bmin);
1672     copy_v3_v3(max, bb->bmax);
1673   }
1674   else {
1675     zero_v3(min);
1676     zero_v3(max);
1677   }
1678 }
1679 
BKE_pbvh_grid_hidden(const PBVH * pbvh)1680 BLI_bitmap **BKE_pbvh_grid_hidden(const PBVH *pbvh)
1681 {
1682   BLI_assert(pbvh->type == PBVH_GRIDS);
1683   return pbvh->grid_hidden;
1684 }
1685 
BKE_pbvh_get_grid_key(const PBVH * pbvh)1686 const CCGKey *BKE_pbvh_get_grid_key(const PBVH *pbvh)
1687 {
1688   BLI_assert(pbvh->type == PBVH_GRIDS);
1689   return &pbvh->gridkey;
1690 }
1691 
BKE_pbvh_get_grids(const PBVH * pbvh)1692 struct CCGElem **BKE_pbvh_get_grids(const PBVH *pbvh)
1693 {
1694   BLI_assert(pbvh->type == PBVH_GRIDS);
1695   return pbvh->grids;
1696 }
1697 
BKE_pbvh_get_grid_visibility(const PBVH * pbvh)1698 BLI_bitmap **BKE_pbvh_get_grid_visibility(const PBVH *pbvh)
1699 {
1700   BLI_assert(pbvh->type == PBVH_GRIDS);
1701   return pbvh->grid_hidden;
1702 }
1703 
BKE_pbvh_get_grid_num_vertices(const PBVH * pbvh)1704 int BKE_pbvh_get_grid_num_vertices(const PBVH *pbvh)
1705 {
1706   BLI_assert(pbvh->type == PBVH_GRIDS);
1707   return pbvh->totgrid * pbvh->gridkey.grid_area;
1708 }
1709 
BKE_pbvh_get_bmesh(PBVH * pbvh)1710 BMesh *BKE_pbvh_get_bmesh(PBVH *pbvh)
1711 {
1712   BLI_assert(pbvh->type == PBVH_BMESH);
1713   return pbvh->bm;
1714 }
1715 
1716 /***************************** Node Access ***********************************/
1717 
BKE_pbvh_node_mark_update(PBVHNode * node)1718 void BKE_pbvh_node_mark_update(PBVHNode *node)
1719 {
1720   node->flag |= PBVH_UpdateNormals | PBVH_UpdateBB | PBVH_UpdateOriginalBB |
1721                 PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
1722 }
1723 
BKE_pbvh_node_mark_update_mask(PBVHNode * node)1724 void BKE_pbvh_node_mark_update_mask(PBVHNode *node)
1725 {
1726   node->flag |= PBVH_UpdateMask | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
1727 }
1728 
BKE_pbvh_node_mark_update_color(PBVHNode * node)1729 void BKE_pbvh_node_mark_update_color(PBVHNode *node)
1730 {
1731   node->flag |= PBVH_UpdateColor | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
1732 }
1733 
BKE_pbvh_node_mark_update_visibility(PBVHNode * node)1734 void BKE_pbvh_node_mark_update_visibility(PBVHNode *node)
1735 {
1736   node->flag |= PBVH_UpdateVisibility | PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers |
1737                 PBVH_UpdateRedraw;
1738 }
1739 
BKE_pbvh_node_mark_rebuild_draw(PBVHNode * node)1740 void BKE_pbvh_node_mark_rebuild_draw(PBVHNode *node)
1741 {
1742   node->flag |= PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
1743 }
1744 
BKE_pbvh_node_mark_redraw(PBVHNode * node)1745 void BKE_pbvh_node_mark_redraw(PBVHNode *node)
1746 {
1747   node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
1748 }
1749 
BKE_pbvh_node_mark_normals_update(PBVHNode * node)1750 void BKE_pbvh_node_mark_normals_update(PBVHNode *node)
1751 {
1752   node->flag |= PBVH_UpdateNormals;
1753 }
1754 
BKE_pbvh_node_fully_hidden_set(PBVHNode * node,int fully_hidden)1755 void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden)
1756 {
1757   BLI_assert(node->flag & PBVH_Leaf);
1758 
1759   if (fully_hidden) {
1760     node->flag |= PBVH_FullyHidden;
1761   }
1762   else {
1763     node->flag &= ~PBVH_FullyHidden;
1764   }
1765 }
1766 
BKE_pbvh_node_fully_hidden_get(PBVHNode * node)1767 bool BKE_pbvh_node_fully_hidden_get(PBVHNode *node)
1768 {
1769   return (node->flag & PBVH_Leaf) && (node->flag & PBVH_FullyHidden);
1770 }
1771 
BKE_pbvh_node_fully_masked_set(PBVHNode * node,int fully_masked)1772 void BKE_pbvh_node_fully_masked_set(PBVHNode *node, int fully_masked)
1773 {
1774   BLI_assert(node->flag & PBVH_Leaf);
1775 
1776   if (fully_masked) {
1777     node->flag |= PBVH_FullyMasked;
1778   }
1779   else {
1780     node->flag &= ~PBVH_FullyMasked;
1781   }
1782 }
1783 
BKE_pbvh_node_fully_masked_get(PBVHNode * node)1784 bool BKE_pbvh_node_fully_masked_get(PBVHNode *node)
1785 {
1786   return (node->flag & PBVH_Leaf) && (node->flag & PBVH_FullyMasked);
1787 }
1788 
BKE_pbvh_node_fully_unmasked_set(PBVHNode * node,int fully_masked)1789 void BKE_pbvh_node_fully_unmasked_set(PBVHNode *node, int fully_masked)
1790 {
1791   BLI_assert(node->flag & PBVH_Leaf);
1792 
1793   if (fully_masked) {
1794     node->flag |= PBVH_FullyUnmasked;
1795   }
1796   else {
1797     node->flag &= ~PBVH_FullyUnmasked;
1798   }
1799 }
1800 
BKE_pbvh_node_fully_unmasked_get(PBVHNode * node)1801 bool BKE_pbvh_node_fully_unmasked_get(PBVHNode *node)
1802 {
1803   return (node->flag & PBVH_Leaf) && (node->flag & PBVH_FullyUnmasked);
1804 }
1805 
BKE_pbvh_node_get_verts(PBVH * pbvh,PBVHNode * node,const int ** r_vert_indices,MVert ** r_verts)1806 void BKE_pbvh_node_get_verts(PBVH *pbvh,
1807                              PBVHNode *node,
1808                              const int **r_vert_indices,
1809                              MVert **r_verts)
1810 {
1811   if (r_vert_indices) {
1812     *r_vert_indices = node->vert_indices;
1813   }
1814 
1815   if (r_verts) {
1816     *r_verts = pbvh->verts;
1817   }
1818 }
1819 
BKE_pbvh_node_num_verts(PBVH * pbvh,PBVHNode * node,int * r_uniquevert,int * r_totvert)1820 void BKE_pbvh_node_num_verts(PBVH *pbvh, PBVHNode *node, int *r_uniquevert, int *r_totvert)
1821 {
1822   int tot;
1823 
1824   switch (pbvh->type) {
1825     case PBVH_GRIDS:
1826       tot = node->totprim * pbvh->gridkey.grid_area;
1827       if (r_totvert) {
1828         *r_totvert = tot;
1829       }
1830       if (r_uniquevert) {
1831         *r_uniquevert = tot;
1832       }
1833       break;
1834     case PBVH_FACES:
1835       if (r_totvert) {
1836         *r_totvert = node->uniq_verts + node->face_verts;
1837       }
1838       if (r_uniquevert) {
1839         *r_uniquevert = node->uniq_verts;
1840       }
1841       break;
1842     case PBVH_BMESH:
1843       tot = BLI_gset_len(node->bm_unique_verts);
1844       if (r_totvert) {
1845         *r_totvert = tot + BLI_gset_len(node->bm_other_verts);
1846       }
1847       if (r_uniquevert) {
1848         *r_uniquevert = tot;
1849       }
1850       break;
1851   }
1852 }
1853 
BKE_pbvh_node_get_grids(PBVH * pbvh,PBVHNode * node,int ** r_grid_indices,int * r_totgrid,int * r_maxgrid,int * r_gridsize,CCGElem *** r_griddata)1854 void BKE_pbvh_node_get_grids(PBVH *pbvh,
1855                              PBVHNode *node,
1856                              int **r_grid_indices,
1857                              int *r_totgrid,
1858                              int *r_maxgrid,
1859                              int *r_gridsize,
1860                              CCGElem ***r_griddata)
1861 {
1862   switch (pbvh->type) {
1863     case PBVH_GRIDS:
1864       if (r_grid_indices) {
1865         *r_grid_indices = node->prim_indices;
1866       }
1867       if (r_totgrid) {
1868         *r_totgrid = node->totprim;
1869       }
1870       if (r_maxgrid) {
1871         *r_maxgrid = pbvh->totgrid;
1872       }
1873       if (r_gridsize) {
1874         *r_gridsize = pbvh->gridkey.grid_size;
1875       }
1876       if (r_griddata) {
1877         *r_griddata = pbvh->grids;
1878       }
1879       break;
1880     case PBVH_FACES:
1881     case PBVH_BMESH:
1882       if (r_grid_indices) {
1883         *r_grid_indices = NULL;
1884       }
1885       if (r_totgrid) {
1886         *r_totgrid = 0;
1887       }
1888       if (r_maxgrid) {
1889         *r_maxgrid = 0;
1890       }
1891       if (r_gridsize) {
1892         *r_gridsize = 0;
1893       }
1894       if (r_griddata) {
1895         *r_griddata = NULL;
1896       }
1897       break;
1898   }
1899 }
1900 
BKE_pbvh_node_get_BB(PBVHNode * node,float bb_min[3],float bb_max[3])1901 void BKE_pbvh_node_get_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
1902 {
1903   copy_v3_v3(bb_min, node->vb.bmin);
1904   copy_v3_v3(bb_max, node->vb.bmax);
1905 }
1906 
BKE_pbvh_node_get_original_BB(PBVHNode * node,float bb_min[3],float bb_max[3])1907 void BKE_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
1908 {
1909   copy_v3_v3(bb_min, node->orig_vb.bmin);
1910   copy_v3_v3(bb_max, node->orig_vb.bmax);
1911 }
1912 
BKE_pbvh_node_get_proxies(PBVHNode * node,PBVHProxyNode ** proxies,int * proxy_count)1913 void BKE_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *proxy_count)
1914 {
1915   if (node->proxy_count > 0) {
1916     if (proxies) {
1917       *proxies = node->proxies;
1918     }
1919     if (proxy_count) {
1920       *proxy_count = node->proxy_count;
1921     }
1922   }
1923   else {
1924     if (proxies) {
1925       *proxies = NULL;
1926     }
1927     if (proxy_count) {
1928       *proxy_count = 0;
1929     }
1930   }
1931 }
1932 
BKE_pbvh_node_get_bm_orco_data(PBVHNode * node,int (** r_orco_tris)[3],int * r_orco_tris_num,float (** r_orco_coords)[3])1933 void BKE_pbvh_node_get_bm_orco_data(PBVHNode *node,
1934                                     int (**r_orco_tris)[3],
1935                                     int *r_orco_tris_num,
1936                                     float (**r_orco_coords)[3])
1937 {
1938   *r_orco_tris = node->bm_ortri;
1939   *r_orco_tris_num = node->bm_tot_ortri;
1940   *r_orco_coords = node->bm_orco;
1941 }
1942 
1943 /**
1944  * \note doing a full search on all vertices here seems expensive,
1945  * however this is important to avoid having to recalculate bound-box & sync the buffers to the
1946  * GPU (which is far more expensive!) See: T47232.
1947  */
BKE_pbvh_node_vert_update_check_any(PBVH * pbvh,PBVHNode * node)1948 bool BKE_pbvh_node_vert_update_check_any(PBVH *pbvh, PBVHNode *node)
1949 {
1950   BLI_assert(pbvh->type == PBVH_FACES);
1951   const int *verts = node->vert_indices;
1952   const int totvert = node->uniq_verts + node->face_verts;
1953 
1954   for (int i = 0; i < totvert; i++) {
1955     const int v = verts[i];
1956     const MVert *mvert = &pbvh->verts[v];
1957 
1958     if (mvert->flag & ME_VERT_PBVH_UPDATE) {
1959       return true;
1960     }
1961   }
1962 
1963   return false;
1964 }
1965 
1966 /********************************* Raycast ***********************************/
1967 
1968 typedef struct {
1969   struct IsectRayAABB_Precalc ray;
1970   bool original;
1971 } RaycastData;
1972 
ray_aabb_intersect(PBVHNode * node,void * data_v)1973 static bool ray_aabb_intersect(PBVHNode *node, void *data_v)
1974 {
1975   RaycastData *rcd = data_v;
1976   const float *bb_min, *bb_max;
1977 
1978   if (rcd->original) {
1979     /* BKE_pbvh_node_get_original_BB */
1980     bb_min = node->orig_vb.bmin;
1981     bb_max = node->orig_vb.bmax;
1982   }
1983   else {
1984     /* BKE_pbvh_node_get_BB */
1985     bb_min = node->vb.bmin;
1986     bb_max = node->vb.bmax;
1987   }
1988 
1989   return isect_ray_aabb_v3(&rcd->ray, bb_min, bb_max, &node->tmin);
1990 }
1991 
BKE_pbvh_raycast(PBVH * pbvh,BKE_pbvh_HitOccludedCallback cb,void * data,const float ray_start[3],const float ray_normal[3],bool original)1992 void BKE_pbvh_raycast(PBVH *pbvh,
1993                       BKE_pbvh_HitOccludedCallback cb,
1994                       void *data,
1995                       const float ray_start[3],
1996                       const float ray_normal[3],
1997                       bool original)
1998 {
1999   RaycastData rcd;
2000 
2001   isect_ray_aabb_v3_precalc(&rcd.ray, ray_start, ray_normal);
2002   rcd.original = original;
2003 
2004   BKE_pbvh_search_callback_occluded(pbvh, ray_aabb_intersect, &rcd, cb, data);
2005 }
2006 
ray_face_intersection_quad(const float ray_start[3],struct IsectRayPrecalc * isect_precalc,const float t0[3],const float t1[3],const float t2[3],const float t3[3],float * depth)2007 bool ray_face_intersection_quad(const float ray_start[3],
2008                                 struct IsectRayPrecalc *isect_precalc,
2009                                 const float t0[3],
2010                                 const float t1[3],
2011                                 const float t2[3],
2012                                 const float t3[3],
2013                                 float *depth)
2014 {
2015   float depth_test;
2016 
2017   if ((isect_ray_tri_watertight_v3(ray_start, isect_precalc, t0, t1, t2, &depth_test, NULL) &&
2018        (depth_test < *depth)) ||
2019       (isect_ray_tri_watertight_v3(ray_start, isect_precalc, t0, t2, t3, &depth_test, NULL) &&
2020        (depth_test < *depth))) {
2021     *depth = depth_test;
2022     return true;
2023   }
2024 
2025   return false;
2026 }
2027 
ray_face_intersection_tri(const float ray_start[3],struct IsectRayPrecalc * isect_precalc,const float t0[3],const float t1[3],const float t2[3],float * depth)2028 bool ray_face_intersection_tri(const float ray_start[3],
2029                                struct IsectRayPrecalc *isect_precalc,
2030                                const float t0[3],
2031                                const float t1[3],
2032                                const float t2[3],
2033                                float *depth)
2034 {
2035   float depth_test;
2036   if ((isect_ray_tri_watertight_v3(ray_start, isect_precalc, t0, t1, t2, &depth_test, NULL) &&
2037        (depth_test < *depth))) {
2038     *depth = depth_test;
2039     return true;
2040   }
2041 
2042   return false;
2043 }
2044 
2045 /* Take advantage of the fact we know this wont be an intersection.
2046  * Just handle ray-tri edges. */
dist_squared_ray_to_tri_v3_fast(const float ray_origin[3],const float ray_direction[3],const float v0[3],const float v1[3],const float v2[3],float r_point[3],float * r_depth)2047 static float dist_squared_ray_to_tri_v3_fast(const float ray_origin[3],
2048                                              const float ray_direction[3],
2049                                              const float v0[3],
2050                                              const float v1[3],
2051                                              const float v2[3],
2052                                              float r_point[3],
2053                                              float *r_depth)
2054 {
2055   const float *tri[3] = {v0, v1, v2};
2056   float dist_sq_best = FLT_MAX;
2057   for (int i = 0, j = 2; i < 3; j = i++) {
2058     float point_test[3], depth_test = FLT_MAX;
2059     const float dist_sq_test = dist_squared_ray_to_seg_v3(
2060         ray_origin, ray_direction, tri[i], tri[j], point_test, &depth_test);
2061     if (dist_sq_test < dist_sq_best || i == 0) {
2062       copy_v3_v3(r_point, point_test);
2063       *r_depth = depth_test;
2064       dist_sq_best = dist_sq_test;
2065     }
2066   }
2067   return dist_sq_best;
2068 }
2069 
ray_face_nearest_quad(const float ray_start[3],const float ray_normal[3],const float t0[3],const float t1[3],const float t2[3],const float t3[3],float * depth,float * dist_sq)2070 bool ray_face_nearest_quad(const float ray_start[3],
2071                            const float ray_normal[3],
2072                            const float t0[3],
2073                            const float t1[3],
2074                            const float t2[3],
2075                            const float t3[3],
2076                            float *depth,
2077                            float *dist_sq)
2078 {
2079   float dist_sq_test;
2080   float co[3], depth_test;
2081 
2082   if (((dist_sq_test = dist_squared_ray_to_tri_v3_fast(
2083             ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq)) {
2084     *dist_sq = dist_sq_test;
2085     *depth = depth_test;
2086     if (((dist_sq_test = dist_squared_ray_to_tri_v3_fast(
2087               ray_start, ray_normal, t0, t2, t3, co, &depth_test)) < *dist_sq)) {
2088       *dist_sq = dist_sq_test;
2089       *depth = depth_test;
2090     }
2091     return true;
2092   }
2093 
2094   return false;
2095 }
2096 
ray_face_nearest_tri(const float ray_start[3],const float ray_normal[3],const float t0[3],const float t1[3],const float t2[3],float * depth,float * dist_sq)2097 bool ray_face_nearest_tri(const float ray_start[3],
2098                           const float ray_normal[3],
2099                           const float t0[3],
2100                           const float t1[3],
2101                           const float t2[3],
2102                           float *depth,
2103                           float *dist_sq)
2104 {
2105   float dist_sq_test;
2106   float co[3], depth_test;
2107 
2108   if (((dist_sq_test = dist_squared_ray_to_tri_v3_fast(
2109             ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq)) {
2110     *dist_sq = dist_sq_test;
2111     *depth = depth_test;
2112     return true;
2113   }
2114 
2115   return false;
2116 }
2117 
pbvh_faces_node_raycast(PBVH * pbvh,const PBVHNode * node,float (* origco)[3],const float ray_start[3],const float ray_normal[3],struct IsectRayPrecalc * isect_precalc,float * depth,int * r_active_vertex_index,int * r_active_face_index,float * r_face_normal)2118 static bool pbvh_faces_node_raycast(PBVH *pbvh,
2119                                     const PBVHNode *node,
2120                                     float (*origco)[3],
2121                                     const float ray_start[3],
2122                                     const float ray_normal[3],
2123                                     struct IsectRayPrecalc *isect_precalc,
2124                                     float *depth,
2125                                     int *r_active_vertex_index,
2126                                     int *r_active_face_index,
2127                                     float *r_face_normal)
2128 {
2129   const MVert *vert = pbvh->verts;
2130   const MLoop *mloop = pbvh->mloop;
2131   const int *faces = node->prim_indices;
2132   int totface = node->totprim;
2133   bool hit = false;
2134   float nearest_vertex_co[3] = {0.0f};
2135 
2136   for (int i = 0; i < totface; i++) {
2137     const MLoopTri *lt = &pbvh->looptri[faces[i]];
2138     const int *face_verts = node->face_vert_indices[i];
2139 
2140     if (pbvh->respect_hide && paint_is_face_hidden(lt, vert, mloop)) {
2141       continue;
2142     }
2143 
2144     const float *co[3];
2145     if (origco) {
2146       /* intersect with backuped original coordinates */
2147       co[0] = origco[face_verts[0]];
2148       co[1] = origco[face_verts[1]];
2149       co[2] = origco[face_verts[2]];
2150     }
2151     else {
2152       /* intersect with current coordinates */
2153       co[0] = vert[mloop[lt->tri[0]].v].co;
2154       co[1] = vert[mloop[lt->tri[1]].v].co;
2155       co[2] = vert[mloop[lt->tri[2]].v].co;
2156     }
2157 
2158     if (ray_face_intersection_tri(ray_start, isect_precalc, co[0], co[1], co[2], depth)) {
2159       hit = true;
2160 
2161       if (r_face_normal) {
2162         normal_tri_v3(r_face_normal, co[0], co[1], co[2]);
2163       }
2164 
2165       if (r_active_vertex_index) {
2166         float location[3] = {0.0f};
2167         madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
2168         for (int j = 0; j < 3; j++) {
2169           /* Always assign nearest_vertex_co in the first iteration to avoid comparison against
2170            * uninitialized values. This stores the closest vertex in the current intersecting
2171            * triangle. */
2172           if (j == 0 ||
2173               len_squared_v3v3(location, co[j]) < len_squared_v3v3(location, nearest_vertex_co)) {
2174             copy_v3_v3(nearest_vertex_co, co[j]);
2175             *r_active_vertex_index = mloop[lt->tri[j]].v;
2176             *r_active_face_index = lt->poly;
2177           }
2178         }
2179       }
2180     }
2181   }
2182 
2183   return hit;
2184 }
2185 
pbvh_grids_node_raycast(PBVH * pbvh,PBVHNode * node,float (* origco)[3],const float ray_start[3],const float ray_normal[3],struct IsectRayPrecalc * isect_precalc,float * depth,int * r_active_vertex_index,int * r_active_grid_index,float * r_face_normal)2186 static bool pbvh_grids_node_raycast(PBVH *pbvh,
2187                                     PBVHNode *node,
2188                                     float (*origco)[3],
2189                                     const float ray_start[3],
2190                                     const float ray_normal[3],
2191                                     struct IsectRayPrecalc *isect_precalc,
2192                                     float *depth,
2193                                     int *r_active_vertex_index,
2194                                     int *r_active_grid_index,
2195                                     float *r_face_normal)
2196 {
2197   const int totgrid = node->totprim;
2198   const int gridsize = pbvh->gridkey.grid_size;
2199   bool hit = false;
2200   float nearest_vertex_co[3] = {0.0};
2201   const CCGKey *gridkey = &pbvh->gridkey;
2202 
2203   for (int i = 0; i < totgrid; i++) {
2204     const int grid_index = node->prim_indices[i];
2205     CCGElem *grid = pbvh->grids[grid_index];
2206     BLI_bitmap *gh;
2207 
2208     if (!grid) {
2209       continue;
2210     }
2211 
2212     gh = pbvh->grid_hidden[grid_index];
2213 
2214     for (int y = 0; y < gridsize - 1; y++) {
2215       for (int x = 0; x < gridsize - 1; x++) {
2216         /* check if grid face is hidden */
2217         if (gh) {
2218           if (paint_is_grid_face_hidden(gh, gridsize, x, y)) {
2219             continue;
2220           }
2221         }
2222 
2223         const float *co[4];
2224         if (origco) {
2225           co[0] = origco[y * gridsize + x];
2226           co[1] = origco[y * gridsize + x + 1];
2227           co[2] = origco[(y + 1) * gridsize + x + 1];
2228           co[3] = origco[(y + 1) * gridsize + x];
2229         }
2230         else {
2231           co[0] = CCG_grid_elem_co(gridkey, grid, x, y);
2232           co[1] = CCG_grid_elem_co(gridkey, grid, x + 1, y);
2233           co[2] = CCG_grid_elem_co(gridkey, grid, x + 1, y + 1);
2234           co[3] = CCG_grid_elem_co(gridkey, grid, x, y + 1);
2235         }
2236 
2237         if (ray_face_intersection_quad(
2238                 ray_start, isect_precalc, co[0], co[1], co[2], co[3], depth)) {
2239           hit = true;
2240 
2241           if (r_face_normal) {
2242             normal_quad_v3(r_face_normal, co[0], co[1], co[2], co[3]);
2243           }
2244 
2245           if (r_active_vertex_index) {
2246             float location[3] = {0.0};
2247             madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
2248 
2249             const int x_it[4] = {0, 1, 1, 0};
2250             const int y_it[4] = {0, 0, 1, 1};
2251 
2252             for (int j = 0; j < 4; j++) {
2253               /* Always assign nearest_vertex_co in the first iteration to avoid comparison against
2254                * uninitialized values. This stores the closest vertex in the current intersecting
2255                * quad. */
2256               if (j == 0 || len_squared_v3v3(location, co[j]) <
2257                                 len_squared_v3v3(location, nearest_vertex_co)) {
2258                 copy_v3_v3(nearest_vertex_co, co[j]);
2259 
2260                 *r_active_vertex_index = gridkey->grid_area * grid_index +
2261                                          (y + y_it[j]) * gridkey->grid_size + (x + x_it[j]);
2262               }
2263             }
2264           }
2265           if (r_active_grid_index) {
2266             *r_active_grid_index = grid_index;
2267           }
2268         }
2269       }
2270     }
2271 
2272     if (origco) {
2273       origco += gridsize * gridsize;
2274     }
2275   }
2276 
2277   return hit;
2278 }
2279 
BKE_pbvh_node_raycast(PBVH * pbvh,PBVHNode * node,float (* origco)[3],bool use_origco,const float ray_start[3],const float ray_normal[3],struct IsectRayPrecalc * isect_precalc,float * depth,int * active_vertex_index,int * active_face_grid_index,float * face_normal)2280 bool BKE_pbvh_node_raycast(PBVH *pbvh,
2281                            PBVHNode *node,
2282                            float (*origco)[3],
2283                            bool use_origco,
2284                            const float ray_start[3],
2285                            const float ray_normal[3],
2286                            struct IsectRayPrecalc *isect_precalc,
2287                            float *depth,
2288                            int *active_vertex_index,
2289                            int *active_face_grid_index,
2290                            float *face_normal)
2291 {
2292   bool hit = false;
2293 
2294   if (node->flag & PBVH_FullyHidden) {
2295     return false;
2296   }
2297 
2298   switch (pbvh->type) {
2299     case PBVH_FACES:
2300       hit |= pbvh_faces_node_raycast(pbvh,
2301                                      node,
2302                                      origco,
2303                                      ray_start,
2304                                      ray_normal,
2305                                      isect_precalc,
2306                                      depth,
2307                                      active_vertex_index,
2308                                      active_face_grid_index,
2309                                      face_normal);
2310       break;
2311     case PBVH_GRIDS:
2312       hit |= pbvh_grids_node_raycast(pbvh,
2313                                      node,
2314                                      origco,
2315                                      ray_start,
2316                                      ray_normal,
2317                                      isect_precalc,
2318                                      depth,
2319                                      active_vertex_index,
2320                                      active_face_grid_index,
2321                                      face_normal);
2322       break;
2323     case PBVH_BMESH:
2324       BM_mesh_elem_index_ensure(pbvh->bm, BM_VERT);
2325       hit = pbvh_bmesh_node_raycast(node,
2326                                     ray_start,
2327                                     ray_normal,
2328                                     isect_precalc,
2329                                     depth,
2330                                     use_origco,
2331                                     active_vertex_index,
2332                                     face_normal);
2333       break;
2334   }
2335 
2336   return hit;
2337 }
2338 
BKE_pbvh_raycast_project_ray_root(PBVH * pbvh,bool original,float ray_start[3],float ray_end[3],float ray_normal[3])2339 void BKE_pbvh_raycast_project_ray_root(
2340     PBVH *pbvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3])
2341 {
2342   if (pbvh->nodes) {
2343     float rootmin_start, rootmin_end;
2344     float bb_min_root[3], bb_max_root[3], bb_center[3], bb_diff[3];
2345     struct IsectRayAABB_Precalc ray;
2346     float ray_normal_inv[3];
2347     float offset = 1.0f + 1e-3f;
2348     const float offset_vec[3] = {1e-3f, 1e-3f, 1e-3f};
2349 
2350     if (original) {
2351       BKE_pbvh_node_get_original_BB(pbvh->nodes, bb_min_root, bb_max_root);
2352     }
2353     else {
2354       BKE_pbvh_node_get_BB(pbvh->nodes, bb_min_root, bb_max_root);
2355     }
2356 
2357     /* Slightly offset min and max in case we have a zero width node
2358      * (due to a plane mesh for instance), or faces very close to the bounding box boundary. */
2359     mid_v3_v3v3(bb_center, bb_max_root, bb_min_root);
2360     /* diff should be same for both min/max since it's calculated from center */
2361     sub_v3_v3v3(bb_diff, bb_max_root, bb_center);
2362     /* handles case of zero width bb */
2363     add_v3_v3(bb_diff, offset_vec);
2364     madd_v3_v3v3fl(bb_max_root, bb_center, bb_diff, offset);
2365     madd_v3_v3v3fl(bb_min_root, bb_center, bb_diff, -offset);
2366 
2367     /* first project start ray */
2368     isect_ray_aabb_v3_precalc(&ray, ray_start, ray_normal);
2369     if (!isect_ray_aabb_v3(&ray, bb_min_root, bb_max_root, &rootmin_start)) {
2370       return;
2371     }
2372 
2373     /* then the end ray */
2374     mul_v3_v3fl(ray_normal_inv, ray_normal, -1.0);
2375     isect_ray_aabb_v3_precalc(&ray, ray_end, ray_normal_inv);
2376     /* unlikely to fail exiting if entering succeeded, still keep this here */
2377     if (!isect_ray_aabb_v3(&ray, bb_min_root, bb_max_root, &rootmin_end)) {
2378       return;
2379     }
2380 
2381     madd_v3_v3v3fl(ray_start, ray_start, ray_normal, rootmin_start);
2382     madd_v3_v3v3fl(ray_end, ray_end, ray_normal_inv, rootmin_end);
2383   }
2384 }
2385 
2386 /* -------------------------------------------------------------------- */
2387 
2388 typedef struct {
2389   struct DistRayAABB_Precalc dist_ray_to_aabb_precalc;
2390   bool original;
2391 } FindNearestRayData;
2392 
nearest_to_ray_aabb_dist_sq(PBVHNode * node,void * data_v)2393 static bool nearest_to_ray_aabb_dist_sq(PBVHNode *node, void *data_v)
2394 {
2395   FindNearestRayData *rcd = data_v;
2396   const float *bb_min, *bb_max;
2397 
2398   if (rcd->original) {
2399     /* BKE_pbvh_node_get_original_BB */
2400     bb_min = node->orig_vb.bmin;
2401     bb_max = node->orig_vb.bmax;
2402   }
2403   else {
2404     /* BKE_pbvh_node_get_BB */
2405     bb_min = node->vb.bmin;
2406     bb_max = node->vb.bmax;
2407   }
2408 
2409   float co_dummy[3], depth;
2410   node->tmin = dist_squared_ray_to_aabb_v3(
2411       &rcd->dist_ray_to_aabb_precalc, bb_min, bb_max, co_dummy, &depth);
2412   /* Ideally we would skip distances outside the range. */
2413   return depth > 0.0f;
2414 }
2415 
BKE_pbvh_find_nearest_to_ray(PBVH * pbvh,BKE_pbvh_SearchNearestCallback cb,void * data,const float ray_start[3],const float ray_normal[3],bool original)2416 void BKE_pbvh_find_nearest_to_ray(PBVH *pbvh,
2417                                   BKE_pbvh_SearchNearestCallback cb,
2418                                   void *data,
2419                                   const float ray_start[3],
2420                                   const float ray_normal[3],
2421                                   bool original)
2422 {
2423   FindNearestRayData ncd;
2424 
2425   dist_squared_ray_to_aabb_v3_precalc(&ncd.dist_ray_to_aabb_precalc, ray_start, ray_normal);
2426   ncd.original = original;
2427 
2428   BKE_pbvh_search_callback_occluded(pbvh, nearest_to_ray_aabb_dist_sq, &ncd, cb, data);
2429 }
2430 
pbvh_faces_node_nearest_to_ray(PBVH * pbvh,const PBVHNode * node,float (* origco)[3],const float ray_start[3],const float ray_normal[3],float * depth,float * dist_sq)2431 static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh,
2432                                            const PBVHNode *node,
2433                                            float (*origco)[3],
2434                                            const float ray_start[3],
2435                                            const float ray_normal[3],
2436                                            float *depth,
2437                                            float *dist_sq)
2438 {
2439   const MVert *vert = pbvh->verts;
2440   const MLoop *mloop = pbvh->mloop;
2441   const int *faces = node->prim_indices;
2442   int i, totface = node->totprim;
2443   bool hit = false;
2444 
2445   for (i = 0; i < totface; i++) {
2446     const MLoopTri *lt = &pbvh->looptri[faces[i]];
2447     const int *face_verts = node->face_vert_indices[i];
2448 
2449     if (pbvh->respect_hide && paint_is_face_hidden(lt, vert, mloop)) {
2450       continue;
2451     }
2452 
2453     if (origco) {
2454       /* intersect with backuped original coordinates */
2455       hit |= ray_face_nearest_tri(ray_start,
2456                                   ray_normal,
2457                                   origco[face_verts[0]],
2458                                   origco[face_verts[1]],
2459                                   origco[face_verts[2]],
2460                                   depth,
2461                                   dist_sq);
2462     }
2463     else {
2464       /* intersect with current coordinates */
2465       hit |= ray_face_nearest_tri(ray_start,
2466                                   ray_normal,
2467                                   vert[mloop[lt->tri[0]].v].co,
2468                                   vert[mloop[lt->tri[1]].v].co,
2469                                   vert[mloop[lt->tri[2]].v].co,
2470                                   depth,
2471                                   dist_sq);
2472     }
2473   }
2474 
2475   return hit;
2476 }
2477 
pbvh_grids_node_nearest_to_ray(PBVH * pbvh,PBVHNode * node,float (* origco)[3],const float ray_start[3],const float ray_normal[3],float * depth,float * dist_sq)2478 static bool pbvh_grids_node_nearest_to_ray(PBVH *pbvh,
2479                                            PBVHNode *node,
2480                                            float (*origco)[3],
2481                                            const float ray_start[3],
2482                                            const float ray_normal[3],
2483                                            float *depth,
2484                                            float *dist_sq)
2485 {
2486   const int totgrid = node->totprim;
2487   const int gridsize = pbvh->gridkey.grid_size;
2488   bool hit = false;
2489 
2490   for (int i = 0; i < totgrid; i++) {
2491     CCGElem *grid = pbvh->grids[node->prim_indices[i]];
2492     BLI_bitmap *gh;
2493 
2494     if (!grid) {
2495       continue;
2496     }
2497 
2498     gh = pbvh->grid_hidden[node->prim_indices[i]];
2499 
2500     for (int y = 0; y < gridsize - 1; y++) {
2501       for (int x = 0; x < gridsize - 1; x++) {
2502         /* check if grid face is hidden */
2503         if (gh) {
2504           if (paint_is_grid_face_hidden(gh, gridsize, x, y)) {
2505             continue;
2506           }
2507         }
2508 
2509         if (origco) {
2510           hit |= ray_face_nearest_quad(ray_start,
2511                                        ray_normal,
2512                                        origco[y * gridsize + x],
2513                                        origco[y * gridsize + x + 1],
2514                                        origco[(y + 1) * gridsize + x + 1],
2515                                        origco[(y + 1) * gridsize + x],
2516                                        depth,
2517                                        dist_sq);
2518         }
2519         else {
2520           hit |= ray_face_nearest_quad(ray_start,
2521                                        ray_normal,
2522                                        CCG_grid_elem_co(&pbvh->gridkey, grid, x, y),
2523                                        CCG_grid_elem_co(&pbvh->gridkey, grid, x + 1, y),
2524                                        CCG_grid_elem_co(&pbvh->gridkey, grid, x + 1, y + 1),
2525                                        CCG_grid_elem_co(&pbvh->gridkey, grid, x, y + 1),
2526                                        depth,
2527                                        dist_sq);
2528         }
2529       }
2530     }
2531 
2532     if (origco) {
2533       origco += gridsize * gridsize;
2534     }
2535   }
2536 
2537   return hit;
2538 }
2539 
BKE_pbvh_node_find_nearest_to_ray(PBVH * pbvh,PBVHNode * node,float (* origco)[3],bool use_origco,const float ray_start[3],const float ray_normal[3],float * depth,float * dist_sq)2540 bool BKE_pbvh_node_find_nearest_to_ray(PBVH *pbvh,
2541                                        PBVHNode *node,
2542                                        float (*origco)[3],
2543                                        bool use_origco,
2544                                        const float ray_start[3],
2545                                        const float ray_normal[3],
2546                                        float *depth,
2547                                        float *dist_sq)
2548 {
2549   bool hit = false;
2550 
2551   if (node->flag & PBVH_FullyHidden) {
2552     return false;
2553   }
2554 
2555   switch (pbvh->type) {
2556     case PBVH_FACES:
2557       hit |= pbvh_faces_node_nearest_to_ray(
2558           pbvh, node, origco, ray_start, ray_normal, depth, dist_sq);
2559       break;
2560     case PBVH_GRIDS:
2561       hit |= pbvh_grids_node_nearest_to_ray(
2562           pbvh, node, origco, ray_start, ray_normal, depth, dist_sq);
2563       break;
2564     case PBVH_BMESH:
2565       hit = pbvh_bmesh_node_nearest_to_ray(
2566           node, ray_start, ray_normal, depth, dist_sq, use_origco);
2567       break;
2568   }
2569 
2570   return hit;
2571 }
2572 
2573 typedef enum {
2574   ISECT_INSIDE,
2575   ISECT_OUTSIDE,
2576   ISECT_INTERSECT,
2577 } PlaneAABBIsect;
2578 
2579 /* Adapted from:
2580  * http://www.gamedev.net/community/forums/topic.asp?topic_id=512123
2581  * Returns true if the AABB is at least partially within the frustum
2582  * (ok, not a real frustum), false otherwise.
2583  */
test_frustum_aabb(const float bb_min[3],const float bb_max[3],PBVHFrustumPlanes * frustum)2584 static PlaneAABBIsect test_frustum_aabb(const float bb_min[3],
2585                                         const float bb_max[3],
2586                                         PBVHFrustumPlanes *frustum)
2587 {
2588   PlaneAABBIsect ret = ISECT_INSIDE;
2589   float(*planes)[4] = frustum->planes;
2590 
2591   for (int i = 0; i < frustum->num_planes; i++) {
2592     float vmin[3], vmax[3];
2593 
2594     for (int axis = 0; axis < 3; axis++) {
2595       if (planes[i][axis] < 0) {
2596         vmin[axis] = bb_min[axis];
2597         vmax[axis] = bb_max[axis];
2598       }
2599       else {
2600         vmin[axis] = bb_max[axis];
2601         vmax[axis] = bb_min[axis];
2602       }
2603     }
2604 
2605     if (dot_v3v3(planes[i], vmin) + planes[i][3] < 0) {
2606       return ISECT_OUTSIDE;
2607     }
2608     if (dot_v3v3(planes[i], vmax) + planes[i][3] <= 0) {
2609       ret = ISECT_INTERSECT;
2610     }
2611   }
2612 
2613   return ret;
2614 }
2615 
BKE_pbvh_node_frustum_contain_AABB(PBVHNode * node,void * data)2616 bool BKE_pbvh_node_frustum_contain_AABB(PBVHNode *node, void *data)
2617 {
2618   const float *bb_min, *bb_max;
2619   /* BKE_pbvh_node_get_BB */
2620   bb_min = node->vb.bmin;
2621   bb_max = node->vb.bmax;
2622 
2623   return test_frustum_aabb(bb_min, bb_max, data) != ISECT_OUTSIDE;
2624 }
2625 
BKE_pbvh_node_frustum_exclude_AABB(PBVHNode * node,void * data)2626 bool BKE_pbvh_node_frustum_exclude_AABB(PBVHNode *node, void *data)
2627 {
2628   const float *bb_min, *bb_max;
2629   /* BKE_pbvh_node_get_BB */
2630   bb_min = node->vb.bmin;
2631   bb_max = node->vb.bmax;
2632 
2633   return test_frustum_aabb(bb_min, bb_max, data) != ISECT_INSIDE;
2634 }
2635 
BKE_pbvh_update_normals(PBVH * pbvh,struct SubdivCCG * subdiv_ccg)2636 void BKE_pbvh_update_normals(PBVH *pbvh, struct SubdivCCG *subdiv_ccg)
2637 {
2638   /* Update normals */
2639   PBVHNode **nodes;
2640   int totnode;
2641 
2642   BKE_pbvh_search_gather(
2643       pbvh, update_search_cb, POINTER_FROM_INT(PBVH_UpdateNormals), &nodes, &totnode);
2644 
2645   if (totnode > 0) {
2646     if (pbvh->type == PBVH_BMESH) {
2647       pbvh_bmesh_normals_update(nodes, totnode);
2648     }
2649     else if (pbvh->type == PBVH_FACES) {
2650       pbvh_faces_update_normals(pbvh, nodes, totnode);
2651     }
2652     else if (pbvh->type == PBVH_GRIDS) {
2653       struct CCGFace **faces;
2654       int num_faces;
2655       BKE_pbvh_get_grid_updates(pbvh, true, (void ***)&faces, &num_faces);
2656       if (num_faces > 0) {
2657         BKE_subdiv_ccg_update_normals(subdiv_ccg, faces, num_faces);
2658         MEM_freeN(faces);
2659       }
2660     }
2661   }
2662 
2663   MEM_SAFE_FREE(nodes);
2664 }
2665 
BKE_pbvh_face_sets_color_set(PBVH * pbvh,int seed,int color_default)2666 void BKE_pbvh_face_sets_color_set(PBVH *pbvh, int seed, int color_default)
2667 {
2668   pbvh->face_sets_color_seed = seed;
2669   pbvh->face_sets_color_default = color_default;
2670 }
2671 
2672 /**
2673  * PBVH drawing, updating draw buffers as needed and culling any nodes outside
2674  * the specified frustum.
2675  */
2676 typedef struct PBVHDrawSearchData {
2677   PBVHFrustumPlanes *frustum;
2678   int accum_update_flag;
2679 } PBVHDrawSearchData;
2680 
pbvh_draw_search_cb(PBVHNode * node,void * data_v)2681 static bool pbvh_draw_search_cb(PBVHNode *node, void *data_v)
2682 {
2683   PBVHDrawSearchData *data = data_v;
2684   if (data->frustum && !BKE_pbvh_node_frustum_contain_AABB(node, data->frustum)) {
2685     return false;
2686   }
2687 
2688   data->accum_update_flag |= node->flag;
2689   return true;
2690 }
2691 
BKE_pbvh_draw_cb(PBVH * pbvh,bool update_only_visible,PBVHFrustumPlanes * update_frustum,PBVHFrustumPlanes * draw_frustum,void (* draw_fn)(void * user_data,GPU_PBVH_Buffers * buffers),void * user_data)2692 void BKE_pbvh_draw_cb(PBVH *pbvh,
2693                       bool update_only_visible,
2694                       PBVHFrustumPlanes *update_frustum,
2695                       PBVHFrustumPlanes *draw_frustum,
2696                       void (*draw_fn)(void *user_data, GPU_PBVH_Buffers *buffers),
2697                       void *user_data)
2698 {
2699   PBVHNode **nodes;
2700   int totnode;
2701 
2702   const int update_flag = PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers;
2703 
2704   if (!update_only_visible) {
2705     /* Update all draw buffers, also those outside the view. */
2706     BKE_pbvh_search_gather(
2707         pbvh, update_search_cb, POINTER_FROM_INT(update_flag), &nodes, &totnode);
2708 
2709     if (totnode) {
2710       pbvh_update_draw_buffers(pbvh, nodes, totnode, update_flag);
2711     }
2712 
2713     MEM_SAFE_FREE(nodes);
2714   }
2715 
2716   /* Gather visible nodes. */
2717   PBVHDrawSearchData data = {.frustum = update_frustum, .accum_update_flag = 0};
2718   BKE_pbvh_search_gather(pbvh, pbvh_draw_search_cb, &data, &nodes, &totnode);
2719 
2720   if (update_only_visible && (data.accum_update_flag & update_flag)) {
2721     /* Update draw buffers in visible nodes. */
2722     pbvh_update_draw_buffers(pbvh, nodes, totnode, data.accum_update_flag);
2723   }
2724 
2725   /* Draw. */
2726   for (int a = 0; a < totnode; a++) {
2727     PBVHNode *node = nodes[a];
2728 
2729     if (node->flag & PBVH_UpdateDrawBuffers) {
2730       /* Flush buffers uses OpenGL, so not in parallel. */
2731       GPU_pbvh_buffers_update_flush(node->draw_buffers);
2732     }
2733 
2734     node->flag &= ~(PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers);
2735   }
2736 
2737   MEM_SAFE_FREE(nodes);
2738 
2739   PBVHDrawSearchData draw_data = {.frustum = draw_frustum, .accum_update_flag = 0};
2740   BKE_pbvh_search_gather(pbvh, pbvh_draw_search_cb, &draw_data, &nodes, &totnode);
2741 
2742   for (int a = 0; a < totnode; a++) {
2743     PBVHNode *node = nodes[a];
2744     if (!(node->flag & PBVH_FullyHidden)) {
2745       draw_fn(user_data, node->draw_buffers);
2746     }
2747   }
2748 
2749   MEM_SAFE_FREE(nodes);
2750 }
2751 
BKE_pbvh_draw_debug_cb(PBVH * pbvh,void (* draw_fn)(void * user_data,const float bmin[3],const float bmax[3],PBVHNodeFlags flag),void * user_data)2752 void BKE_pbvh_draw_debug_cb(
2753     PBVH *pbvh,
2754     void (*draw_fn)(void *user_data, const float bmin[3], const float bmax[3], PBVHNodeFlags flag),
2755     void *user_data)
2756 {
2757   for (int a = 0; a < pbvh->totnode; a++) {
2758     PBVHNode *node = &pbvh->nodes[a];
2759 
2760     draw_fn(user_data, node->vb.bmin, node->vb.bmax, node->flag);
2761   }
2762 }
2763 
BKE_pbvh_grids_update(PBVH * pbvh,CCGElem ** grids,void ** gridfaces,DMFlagMat * flagmats,BLI_bitmap ** grid_hidden)2764 void BKE_pbvh_grids_update(
2765     PBVH *pbvh, CCGElem **grids, void **gridfaces, DMFlagMat *flagmats, BLI_bitmap **grid_hidden)
2766 {
2767   pbvh->grids = grids;
2768   pbvh->gridfaces = gridfaces;
2769 
2770   if (flagmats != pbvh->grid_flag_mats || pbvh->grid_hidden != grid_hidden) {
2771     pbvh->grid_flag_mats = flagmats;
2772     pbvh->grid_hidden = grid_hidden;
2773 
2774     for (int a = 0; a < pbvh->totnode; a++) {
2775       BKE_pbvh_node_mark_rebuild_draw(&pbvh->nodes[a]);
2776     }
2777   }
2778 }
2779 
BKE_pbvh_vert_coords_alloc(PBVH * pbvh)2780 float (*BKE_pbvh_vert_coords_alloc(PBVH *pbvh))[3]
2781 {
2782   float(*vertCos)[3] = NULL;
2783 
2784   if (pbvh->verts) {
2785     MVert *mvert = pbvh->verts;
2786 
2787     vertCos = MEM_callocN(3 * pbvh->totvert * sizeof(float), "BKE_pbvh_get_vertCoords");
2788     float *co = (float *)vertCos;
2789 
2790     for (int a = 0; a < pbvh->totvert; a++, mvert++, co += 3) {
2791       copy_v3_v3(co, mvert->co);
2792     }
2793   }
2794 
2795   return vertCos;
2796 }
2797 
BKE_pbvh_vert_coords_apply(PBVH * pbvh,const float (* vertCos)[3],const int totvert)2798 void BKE_pbvh_vert_coords_apply(PBVH *pbvh, const float (*vertCos)[3], const int totvert)
2799 {
2800   if (totvert != pbvh->totvert) {
2801     BLI_assert(!"PBVH: Given deforming vcos number does not natch PBVH vertex number!");
2802     return;
2803   }
2804 
2805   if (!pbvh->deformed) {
2806     if (pbvh->verts) {
2807       /* if pbvh is not already deformed, verts/faces points to the */
2808       /* original data and applying new coords to this arrays would lead to */
2809       /* unneeded deformation -- duplicate verts/faces to avoid this */
2810 
2811       pbvh->verts = MEM_dupallocN(pbvh->verts);
2812       /* No need to dupalloc pbvh->looptri, this one is 'totally owned' by pbvh,
2813        * it's never some mesh data. */
2814 
2815       pbvh->deformed = true;
2816     }
2817   }
2818 
2819   if (pbvh->verts) {
2820     MVert *mvert = pbvh->verts;
2821     /* copy new verts coords */
2822     for (int a = 0; a < pbvh->totvert; a++, mvert++) {
2823       /* no need for float comparison here (memory is exactly equal or not) */
2824       if (memcmp(mvert->co, vertCos[a], sizeof(float[3])) != 0) {
2825         copy_v3_v3(mvert->co, vertCos[a]);
2826         mvert->flag |= ME_VERT_PBVH_UPDATE;
2827       }
2828     }
2829 
2830     /* coordinates are new -- normals should also be updated */
2831     BKE_mesh_calc_normals_looptri(
2832         pbvh->verts, pbvh->totvert, pbvh->mloop, pbvh->looptri, pbvh->totprim, NULL);
2833 
2834     for (int a = 0; a < pbvh->totnode; a++) {
2835       BKE_pbvh_node_mark_update(&pbvh->nodes[a]);
2836     }
2837 
2838     BKE_pbvh_update_bounds(pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB);
2839   }
2840 }
2841 
BKE_pbvh_is_deformed(PBVH * pbvh)2842 bool BKE_pbvh_is_deformed(PBVH *pbvh)
2843 {
2844   return pbvh->deformed;
2845 }
2846 /* Proxies */
2847 
BKE_pbvh_node_add_proxy(PBVH * pbvh,PBVHNode * node)2848 PBVHProxyNode *BKE_pbvh_node_add_proxy(PBVH *pbvh, PBVHNode *node)
2849 {
2850   int index, totverts;
2851 
2852   index = node->proxy_count;
2853 
2854   node->proxy_count++;
2855 
2856   if (node->proxies) {
2857     node->proxies = MEM_reallocN(node->proxies, node->proxy_count * sizeof(PBVHProxyNode));
2858   }
2859   else {
2860     node->proxies = MEM_mallocN(sizeof(PBVHProxyNode), "PBVHNodeProxy");
2861   }
2862 
2863   BKE_pbvh_node_num_verts(pbvh, node, &totverts, NULL);
2864   node->proxies[index].co = MEM_callocN(sizeof(float[3]) * totverts, "PBVHNodeProxy.co");
2865 
2866   return node->proxies + index;
2867 }
2868 
BKE_pbvh_node_free_proxies(PBVHNode * node)2869 void BKE_pbvh_node_free_proxies(PBVHNode *node)
2870 {
2871   for (int p = 0; p < node->proxy_count; p++) {
2872     MEM_freeN(node->proxies[p].co);
2873     node->proxies[p].co = NULL;
2874   }
2875 
2876   MEM_freeN(node->proxies);
2877   node->proxies = NULL;
2878 
2879   node->proxy_count = 0;
2880 }
2881 
BKE_pbvh_gather_proxies(PBVH * pbvh,PBVHNode *** r_array,int * r_tot)2882 void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot)
2883 {
2884   PBVHNode **array = NULL;
2885   int tot = 0, space = 0;
2886 
2887   for (int n = 0; n < pbvh->totnode; n++) {
2888     PBVHNode *node = pbvh->nodes + n;
2889 
2890     if (node->proxy_count > 0) {
2891       if (tot == space) {
2892         /* resize array if needed */
2893         space = (tot == 0) ? 32 : space * 2;
2894         array = MEM_recallocN_id(array, sizeof(PBVHNode *) * space, __func__);
2895       }
2896 
2897       array[tot] = node;
2898       tot++;
2899     }
2900   }
2901 
2902   if (tot == 0 && array) {
2903     MEM_freeN(array);
2904     array = NULL;
2905   }
2906 
2907   *r_array = array;
2908   *r_tot = tot;
2909 }
2910 
BKE_pbvh_node_color_buffer_get(PBVHNode * node)2911 PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node)
2912 {
2913 
2914   if (!node->color_buffer.color) {
2915     node->color_buffer.color = MEM_callocN(sizeof(float[4]) * node->uniq_verts, "Color buffer");
2916   }
2917   return &node->color_buffer;
2918 }
2919 
BKE_pbvh_node_color_buffer_free(PBVH * pbvh)2920 void BKE_pbvh_node_color_buffer_free(PBVH *pbvh)
2921 {
2922   PBVHNode **nodes;
2923   int totnode;
2924   BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
2925   for (int i = 0; i < totnode; i++) {
2926     MEM_SAFE_FREE(nodes[i]->color_buffer.color);
2927   }
2928   MEM_SAFE_FREE(nodes);
2929 }
2930 
pbvh_vertex_iter_init(PBVH * pbvh,PBVHNode * node,PBVHVertexIter * vi,int mode)2931 void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int mode)
2932 {
2933   struct CCGElem **grids;
2934   struct MVert *verts;
2935   const int *vert_indices;
2936   int *grid_indices;
2937   int totgrid, gridsize, uniq_verts, totvert;
2938 
2939   vi->grid = NULL;
2940   vi->no = NULL;
2941   vi->fno = NULL;
2942   vi->mvert = NULL;
2943 
2944   vi->respect_hide = pbvh->respect_hide;
2945   if (pbvh->respect_hide == false) {
2946     /* The same value for all vertices. */
2947     vi->visible = true;
2948   }
2949 
2950   BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, NULL, &gridsize, &grids);
2951   BKE_pbvh_node_num_verts(pbvh, node, &uniq_verts, &totvert);
2952   BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &verts);
2953   vi->key = pbvh->gridkey;
2954 
2955   vi->grids = grids;
2956   vi->grid_indices = grid_indices;
2957   vi->totgrid = (grids) ? totgrid : 1;
2958   vi->gridsize = gridsize;
2959 
2960   if (mode == PBVH_ITER_ALL) {
2961     vi->totvert = totvert;
2962   }
2963   else {
2964     vi->totvert = uniq_verts;
2965   }
2966   vi->vert_indices = vert_indices;
2967   vi->mverts = verts;
2968 
2969   if (pbvh->type == PBVH_BMESH) {
2970     BLI_gsetIterator_init(&vi->bm_unique_verts, node->bm_unique_verts);
2971     BLI_gsetIterator_init(&vi->bm_other_verts, node->bm_other_verts);
2972     vi->bm_vdata = &pbvh->bm->vdata;
2973     vi->cd_vert_mask_offset = CustomData_get_offset(vi->bm_vdata, CD_PAINT_MASK);
2974   }
2975 
2976   vi->gh = NULL;
2977   if (vi->grids && mode == PBVH_ITER_UNIQUE) {
2978     vi->grid_hidden = pbvh->grid_hidden;
2979   }
2980 
2981   vi->mask = NULL;
2982   if (pbvh->type == PBVH_FACES) {
2983     vi->vmask = CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK);
2984     vi->vcol = CustomData_get_layer(pbvh->vdata, CD_PROP_COLOR);
2985   }
2986 }
2987 
pbvh_has_mask(PBVH * pbvh)2988 bool pbvh_has_mask(PBVH *pbvh)
2989 {
2990   switch (pbvh->type) {
2991     case PBVH_GRIDS:
2992       return (pbvh->gridkey.has_mask != 0);
2993     case PBVH_FACES:
2994       return (pbvh->vdata && CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK));
2995     case PBVH_BMESH:
2996       return (pbvh->bm && (CustomData_get_offset(&pbvh->bm->vdata, CD_PAINT_MASK) != -1));
2997   }
2998 
2999   return false;
3000 }
3001 
pbvh_has_face_sets(PBVH * pbvh)3002 bool pbvh_has_face_sets(PBVH *pbvh)
3003 {
3004   switch (pbvh->type) {
3005     case PBVH_GRIDS:
3006       return (pbvh->pdata && CustomData_get_layer(pbvh->pdata, CD_SCULPT_FACE_SETS));
3007     case PBVH_FACES:
3008       return (pbvh->pdata && CustomData_get_layer(pbvh->pdata, CD_SCULPT_FACE_SETS));
3009     case PBVH_BMESH:
3010       return false;
3011   }
3012 
3013   return false;
3014 }
3015 
pbvh_show_mask_set(PBVH * pbvh,bool show_mask)3016 void pbvh_show_mask_set(PBVH *pbvh, bool show_mask)
3017 {
3018   pbvh->show_mask = show_mask;
3019 }
3020 
pbvh_show_face_sets_set(PBVH * pbvh,bool show_face_sets)3021 void pbvh_show_face_sets_set(PBVH *pbvh, bool show_face_sets)
3022 {
3023   pbvh->show_face_sets = show_face_sets;
3024 }
3025 
BKE_pbvh_set_frustum_planes(PBVH * pbvh,PBVHFrustumPlanes * planes)3026 void BKE_pbvh_set_frustum_planes(PBVH *pbvh, PBVHFrustumPlanes *planes)
3027 {
3028   pbvh->num_planes = planes->num_planes;
3029   for (int i = 0; i < pbvh->num_planes; i++) {
3030     copy_v4_v4(pbvh->planes[i], planes->planes[i]);
3031   }
3032 }
3033 
BKE_pbvh_get_frustum_planes(PBVH * pbvh,PBVHFrustumPlanes * planes)3034 void BKE_pbvh_get_frustum_planes(PBVH *pbvh, PBVHFrustumPlanes *planes)
3035 {
3036   planes->num_planes = pbvh->num_planes;
3037   for (int i = 0; i < planes->num_planes; i++) {
3038     copy_v4_v4(planes->planes[i], pbvh->planes[i]);
3039   }
3040 }
3041 
BKE_pbvh_parallel_range_settings(TaskParallelSettings * settings,bool use_threading,int totnode)3042 void BKE_pbvh_parallel_range_settings(TaskParallelSettings *settings,
3043                                       bool use_threading,
3044                                       int totnode)
3045 {
3046   memset(settings, 0, sizeof(*settings));
3047   settings->use_threading = use_threading && totnode > 1;
3048 }
3049 
BKE_pbvh_get_verts(const PBVH * pbvh)3050 MVert *BKE_pbvh_get_verts(const PBVH *pbvh)
3051 {
3052   BLI_assert(pbvh->type == PBVH_FACES);
3053   return pbvh->verts;
3054 }
3055 
BKE_pbvh_subdiv_cgg_set(PBVH * pbvh,SubdivCCG * subdiv_ccg)3056 void BKE_pbvh_subdiv_cgg_set(PBVH *pbvh, SubdivCCG *subdiv_ccg)
3057 {
3058   pbvh->subdiv_ccg = subdiv_ccg;
3059 }
3060 
BKE_pbvh_face_sets_set(PBVH * pbvh,int * face_sets)3061 void BKE_pbvh_face_sets_set(PBVH *pbvh, int *face_sets)
3062 {
3063   pbvh->face_sets = face_sets;
3064 }
3065 
BKE_pbvh_respect_hide_set(PBVH * pbvh,bool respect_hide)3066 void BKE_pbvh_respect_hide_set(PBVH *pbvh, bool respect_hide)
3067 {
3068   pbvh->respect_hide = respect_hide;
3069 }
3070