Blender V4.3
pbvh.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "MEM_guardedalloc.h"
10
11#include <climits>
12
13#include "BLI_array_utils.hh"
14#include "BLI_bit_span_ops.hh"
15#include "BLI_bitmap.h"
16#include "BLI_bounds.hh"
18#include "BLI_math_geom.h"
19#include "BLI_math_matrix.h"
20#include "BLI_math_vector.h"
21#include "BLI_math_vector.hh"
22#include "BLI_rand.h"
23#include "BLI_stack.hh"
24#include "BLI_task.h"
25#include "BLI_task.hh"
26#include "BLI_time.h"
27#include "BLI_timeit.hh"
28#include "BLI_utildefines.h"
29#include "BLI_vector.hh"
30#include "BLI_vector_set.hh"
31
32#include "DNA_object_types.h"
33
34#include "BKE_attribute.hh"
35#include "BKE_ccg.hh"
36#include "BKE_mesh.hh"
37#include "BKE_mesh_mapping.hh"
38#include "BKE_object.hh"
39#include "BKE_paint.hh"
40#include "BKE_pbvh_api.hh"
41#include "BKE_subdiv_ccg.hh"
42
44
45#include "bmesh.hh"
46
47#include "atomic_ops.h"
48
49#include "pbvh_intern.hh"
50
51namespace blender::bke::pbvh {
52
53// #define DEBUG_BUILD_TIME
54
55#define STACK_FIXED_DEPTH 100
56
59{
60 return {float3(std::numeric_limits<float>::max()), float3(std::numeric_limits<float>::lowest())};
61}
62
64{
65 return bounds::merge(a, b);
66}
67
68static int partition_along_axis(const Span<float3> face_centers,
69 MutableSpan<int> faces,
70 const int axis,
71 const float middle)
72{
73 const int *split = std::partition(faces.begin(), faces.end(), [&](const int face) {
74 return face_centers[face][axis] >= middle;
75 });
76 return split - faces.begin();
77}
78
79static int partition_material_indices(const Span<int> material_indices, MutableSpan<int> faces)
80{
81 const int first = material_indices[faces.first()];
82 const int *split = std::partition(
83 faces.begin(), faces.end(), [&](const int face) { return material_indices[face] == first; });
84 return split - faces.begin();
85}
86
87BLI_NOINLINE static void build_mesh_leaf_nodes(const int verts_num,
88 const OffsetIndices<int> faces,
89 const Span<int> corner_verts,
91{
92#ifdef DEBUG_BUILD_TIME
93 SCOPED_TIMER_AVERAGED(__func__);
94#endif
95 Array<Array<int>> verts_per_node(nodes.size(), NoInitialization());
96 threading::parallel_for(nodes.index_range(), 8, [&](const IndexRange range) {
97 Set<int> verts;
98 for (const int i : range) {
99 MeshNode &node = nodes[i];
100
101 verts.clear();
102 int corners_count = 0;
103 for (const int face_index : node.face_indices_) {
104 const IndexRange face = faces[face_index];
105 verts.add_multiple(corner_verts.slice(face));
106 corners_count += face.size();
107 }
108 nodes[i].corners_num_ = corners_count;
109
110 new (&verts_per_node[i]) Array<int>(verts.size());
111 std::copy(verts.begin(), verts.end(), verts_per_node[i].begin());
112 std::sort(verts_per_node[i].begin(), verts_per_node[i].end());
113 }
114 });
115
116 Vector<int> owned_verts;
117 Vector<int> shared_verts;
118 BitVector<> vert_used(verts_num);
119 for (const int i : nodes.index_range()) {
120 MeshNode &node = nodes[i];
121
122 owned_verts.clear();
123 shared_verts.clear();
124 for (const int vert : verts_per_node[i]) {
125 if (vert_used[vert]) {
126 shared_verts.append(vert);
127 }
128 else {
129 vert_used[vert].set();
130 owned_verts.append(vert);
131 }
132 }
133 node.unique_verts_num_ = owned_verts.size();
134 node.vert_indices_.reserve(owned_verts.size() + shared_verts.size());
135 node.vert_indices_.add_multiple(owned_verts);
136 node.vert_indices_.add_multiple(shared_verts);
137 }
138}
139
140static bool leaf_needs_material_split(const Span<int> faces, const Span<int> material_indices)
141{
142 if (material_indices.is_empty()) {
143 return false;
144 }
145 const int first = material_indices[faces.first()];
146 return std::any_of(
147 faces.begin(), faces.end(), [&](const int face) { return material_indices[face] != first; });
148 return false;
149}
150
151static void build_nodes_recursive_mesh(const Span<int> material_indices,
152 const int leaf_limit,
153 const int node_index,
154 const std::optional<Bounds<float3>> &bounds_precalc,
155 const Span<float3> face_centers,
156 const int depth,
157 MutableSpan<int> faces,
158 Vector<MeshNode> &nodes)
159{
160 /* Decide whether this is a leaf or not */
161 const bool below_leaf_limit = faces.size() <= leaf_limit || depth >= STACK_FIXED_DEPTH - 1;
162 if (below_leaf_limit) {
163 if (!leaf_needs_material_split(faces, material_indices)) {
164 MeshNode &node = nodes[node_index];
165 node.flag_ |= PBVH_Leaf;
166 node.face_indices_ = faces;
167 return;
168 }
169 }
170
171 /* Add two child nodes */
172 nodes[node_index].children_offset_ = nodes.size();
173 nodes.resize(nodes.size() + 2);
174
175 int split;
176 if (!below_leaf_limit) {
178 if (bounds_precalc) {
179 bounds = *bounds_precalc;
180 }
181 else {
182 bounds = threading::parallel_reduce(
183 faces.index_range(),
184 1024,
186 [&](const IndexRange range, Bounds<float3> value) {
187 for (const int face : faces.slice(range)) {
188 math::min_max(face_centers[face], value.min, value.max);
189 }
190 return value;
191 },
193 }
194 const int axis = math::dominant_axis(bounds.max - bounds.min);
195
196 /* Partition primitives along that axis */
197 split = partition_along_axis(
198 face_centers, faces, axis, math::midpoint(bounds.min[axis], bounds.max[axis]));
199 }
200 else {
201 /* Partition primitives by material */
202 split = partition_material_indices(material_indices, faces);
203 }
204
205 /* Build children */
206 build_nodes_recursive_mesh(material_indices,
208 nodes[node_index].children_offset_,
209 std::nullopt,
210 face_centers,
211 depth + 1,
212 faces.take_front(split),
213 nodes);
214 build_nodes_recursive_mesh(material_indices,
216 nodes[node_index].children_offset_ + 1,
217 std::nullopt,
218 face_centers,
219 depth + 1,
220 faces.drop_front(split),
221 nodes);
222}
223
224inline Bounds<float3> calc_face_bounds(const Span<float3> vert_positions,
225 const Span<int> face_verts)
226{
227 Bounds<float3> bounds{vert_positions[face_verts.first()]};
228 for (const int vert : face_verts.slice(1, face_verts.size() - 1)) {
229 math::min_max(vert_positions[vert], bounds.min, bounds.max);
230 }
231 return bounds;
232}
233
234Tree Tree::from_mesh(const Mesh &mesh)
235{
236#ifdef DEBUG_BUILD_TIME
237 SCOPED_TIMER_AVERAGED(__func__);
238#endif
239 Tree pbvh(Type::Mesh);
240 const Span<float3> vert_positions = mesh.vert_positions();
241 const OffsetIndices<int> faces = mesh.faces();
242 const Span<int> corner_verts = mesh.corner_verts();
243 if (faces.is_empty()) {
244 return pbvh;
245 }
246
247 constexpr int leaf_limit = 10000;
248 static_assert(leaf_limit < std::numeric_limits<MeshNode::LocalVertMapIndexT>::max());
249
250 Array<float3> face_centers(faces.size());
251 const Bounds<float3> bounds = threading::parallel_reduce(
252 faces.index_range(),
253 1024,
255 [&](const IndexRange range, const Bounds<float3> &init) {
256 Bounds<float3> current = init;
257 for (const int face : range) {
258 const Bounds<float3> bounds = calc_face_bounds(vert_positions,
259 corner_verts.slice(faces[face]));
260 face_centers[face] = bounds.center();
261 current = bounds::merge(current, bounds);
262 }
263 return current;
264 },
266
267 const AttributeAccessor attributes = mesh.attributes();
268 const VArraySpan hide_vert = *attributes.lookup<bool>(".hide_vert", AttrDomain::Point);
269 const VArraySpan material_index = *attributes.lookup<int>("material_index", AttrDomain::Face);
270
271 pbvh.prim_indices_.reinitialize(faces.size());
272 array_utils::fill_index_range<int>(pbvh.prim_indices_);
273
274 Vector<MeshNode> &nodes = std::get<Vector<MeshNode>>(pbvh.nodes_);
275 nodes.resize(1);
276 {
277#ifdef DEBUG_BUILD_TIME
278 SCOPED_TIMER_AVERAGED("build_nodes_recursive_mesh");
279#endif
281 material_index, leaf_limit, 0, bounds, face_centers, 0, pbvh.prim_indices_, nodes);
282 }
283
284 build_mesh_leaf_nodes(mesh.verts_num, faces, corner_verts, nodes);
285
286 pbvh.tag_positions_changed(nodes.index_range());
287
288 update_bounds_mesh(vert_positions, pbvh);
289 store_bounds_orig(pbvh);
290
291 if (!hide_vert.is_empty()) {
292 threading::parallel_for(nodes.index_range(), 8, [&](const IndexRange range) {
293 for (const int i : range) {
294 node_update_visibility_mesh(hide_vert, nodes[i]);
295 }
296 });
297 }
298
299 update_mask_mesh(mesh, nodes.index_range(), pbvh);
300
301 return pbvh;
302}
303
304static void build_nodes_recursive_grids(const Span<int> material_indices,
305 const int leaf_limit,
306 const int node_index,
307 const std::optional<Bounds<float3>> &bounds_precalc,
308 const Span<float3> face_centers,
309 const int depth,
310 MutableSpan<int> faces,
311 Vector<GridsNode> &nodes)
312{
313 /* Decide whether this is a leaf or not */
314 const bool below_leaf_limit = faces.size() <= leaf_limit || depth >= STACK_FIXED_DEPTH - 1;
315 if (below_leaf_limit) {
316 if (!leaf_needs_material_split(faces, material_indices)) {
317 GridsNode &node = nodes[node_index];
318 node.flag_ |= PBVH_Leaf;
319 node.prim_indices_ = faces;
320 return;
321 }
322 }
323
324 /* Add two child nodes */
325 nodes[node_index].children_offset_ = nodes.size();
326 nodes.resize(nodes.size() + 2);
327
328 int split;
329 if (!below_leaf_limit) {
331 if (bounds_precalc) {
332 bounds = *bounds_precalc;
333 }
334 else {
335 bounds = threading::parallel_reduce(
336 faces.index_range(),
337 1024,
339 [&](const IndexRange range, Bounds<float3> value) {
340 for (const int face : faces.slice(range)) {
341 math::min_max(face_centers[face], value.min, value.max);
342 }
343 return value;
344 },
346 }
347 const int axis = math::dominant_axis(bounds.max - bounds.min);
348
349 /* Partition primitives along that axis */
350 split = partition_along_axis(
351 face_centers, faces, axis, math::midpoint(bounds.min[axis], bounds.max[axis]));
352 }
353 else {
354 /* Partition primitives by material */
355 split = partition_material_indices(material_indices, faces);
356 }
357
358 /* Build children */
359 build_nodes_recursive_grids(material_indices,
361 nodes[node_index].children_offset_,
362 std::nullopt,
363 face_centers,
364 depth + 1,
365 faces.take_front(split),
366 nodes);
367 build_nodes_recursive_grids(material_indices,
369 nodes[node_index].children_offset_ + 1,
370 std::nullopt,
371 face_centers,
372 depth + 1,
373 faces.drop_front(split),
374 nodes);
375}
376
378 const Span<float3> positions,
379 const CCGKey &key,
380 const int face)
381{
383 for (const float3 &position : positions.slice(ccg::face_range(faces, key, face))) {
384 math::min_max(position, bounds.min, bounds.max);
385 }
386 return bounds;
387}
388
389Tree Tree::from_grids(const Mesh &base_mesh, const SubdivCCG &subdiv_ccg)
390{
391#ifdef DEBUG_BUILD_TIME
392 SCOPED_TIMER_AVERAGED(__func__);
393#endif
394 Tree pbvh(Type::Grids);
395 const OffsetIndices faces = base_mesh.faces();
396 if (faces.is_empty()) {
397 return pbvh;
398 }
399
400 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
401 const Span<float3> positions = subdiv_ccg.positions;
402 if (positions.is_empty()) {
403 return pbvh;
404 }
405
406 const int leaf_limit = std::max(2500 / key.grid_area, 1);
407
408 Array<float3> face_centers(faces.size());
409 const Bounds<float3> bounds = threading::parallel_reduce(
410 faces.index_range(),
413 [&](const IndexRange range, const Bounds<float3> &init) {
414 Bounds<float3> current = init;
415 for (const int face : range) {
416 const Bounds<float3> bounds = calc_face_grid_bounds(faces, positions, key, face);
417 face_centers[face] = bounds.center();
418 current = bounds::merge(current, bounds);
419 }
420 return current;
421 },
423
424 const AttributeAccessor attributes = base_mesh.attributes();
425 const VArraySpan material_index = *attributes.lookup<int>("material_index", AttrDomain::Face);
426
427 Array<int> face_indices(faces.size());
428 array_utils::fill_index_range<int>(face_indices);
429
430 Vector<GridsNode> &nodes = std::get<Vector<GridsNode>>(pbvh.nodes_);
431 nodes.resize(1);
432 {
433#ifdef DEBUG_BUILD_TIME
434 SCOPED_TIMER_AVERAGED("build_nodes_recursive_grids");
435#endif
437 material_index, leaf_limit, 0, bounds, face_centers, 0, face_indices, nodes);
438 }
439
440 /* Convert face indices into grid indices. */
441 pbvh.prim_indices_.reinitialize(faces.total_size());
442 {
443 int offset = 0;
444 for (const int i : nodes.index_range()) {
445 for (const int face : nodes[i].prim_indices_) {
446 for (const int corner : faces[face]) {
447 pbvh.prim_indices_[offset] = corner;
448 offset++;
449 }
450 }
451 }
452 }
453
454 /* Change the nodes to reference the BVH prim_indices array instead of the local face indices. */
455 Array<int> node_grids_num(nodes.size() + 1);
456 threading::parallel_for(nodes.index_range(), 16, [&](const IndexRange range) {
457 for (const int i : range) {
458 node_grids_num[i] = offset_indices::sum_group_sizes(faces, nodes[i].prim_indices_);
459 }
460 });
461 const OffsetIndices<int> node_grid_offsets = offset_indices::accumulate_counts_to_offsets(
462 node_grids_num);
463
464 threading::parallel_for(nodes.index_range(), 512, [&](const IndexRange range) {
465 for (const int i : range) {
466 nodes[i].prim_indices_ = pbvh.prim_indices_.as_span().slice(node_grid_offsets[i]);
467 }
468 });
469
470 pbvh.tag_positions_changed(nodes.index_range());
471
472 update_bounds_grids(key, positions, pbvh);
473 store_bounds_orig(pbvh);
474
475 const BitGroupVector<> &grid_hidden = subdiv_ccg.grid_hidden;
476 if (!grid_hidden.is_empty()) {
477 threading::parallel_for(nodes.index_range(), 8, [&](const IndexRange range) {
478 for (const int i : range) {
479 node_update_visibility_grids(grid_hidden, nodes[i]);
480 }
481 });
482 }
483
484 update_mask_grids(subdiv_ccg, nodes.index_range(), pbvh);
485
486 return pbvh;
487}
488
489Tree::Tree(const Type type) : type_(type)
490{
491 switch (type) {
494 break;
497 break;
500 break;
501 }
502}
503
505{
506 return std::visit([](const auto &nodes) { return nodes.size(); }, this->nodes_);
507}
508
509template<> Span<MeshNode> Tree::nodes() const
510{
511 return std::get<Vector<MeshNode>>(this->nodes_);
512}
513template<> Span<GridsNode> Tree::nodes() const
514{
515 return std::get<Vector<GridsNode>>(this->nodes_);
516}
517template<> Span<BMeshNode> Tree::nodes() const
518{
519 return std::get<Vector<BMeshNode>>(this->nodes_);
520}
522{
523 return std::get<Vector<MeshNode>>(this->nodes_);
524}
526{
527 return std::get<Vector<GridsNode>>(this->nodes_);
528}
530{
531 return std::get<Vector<BMeshNode>>(this->nodes_);
532}
533
535{
536 std::visit(
537 [](auto &nodes) {
538 for (Node &node : nodes) {
539 if (node.flag_ & (PBVH_Leaf | PBVH_TexLeaf)) {
540 node_pixels_free(&node);
541 }
542 }
543 },
544 this->nodes_);
545
546 pixels_free(this);
547}
548
550{
551 this->bounds_dirty_.resize(std::max(this->bounds_dirty_.size(), node_mask.min_array_size()),
552 false);
553 this->normals_dirty_.resize(std::max(this->normals_dirty_.size(), node_mask.min_array_size()),
554 false);
555 node_mask.set_bits(this->bounds_dirty_);
556 node_mask.set_bits(this->normals_dirty_);
557 if (this->draw_data) {
558 this->draw_data->tag_positions_changed(node_mask);
559 }
560}
561
563{
564 this->visibility_dirty_.resize(std::max(this->bounds_dirty_.size(), node_mask.min_array_size()),
565 false);
566 node_mask.set_bits(this->visibility_dirty_);
567 if (this->draw_data) {
568 this->draw_data->tag_visibility_changed(node_mask);
569 }
570}
571
573{
574 if (this->draw_data) {
575 this->draw_data->tag_topology_changed(node_mask);
576 }
577}
578
580{
581 if (this->draw_data) {
582 this->draw_data->tag_face_sets_changed(node_mask);
583 }
584}
585
586void Tree::tag_masks_changed(const IndexMask &node_mask)
587{
588 if (this->draw_data) {
589 this->draw_data->tag_masks_changed(node_mask);
590 }
591}
592
593void Tree::tag_attribute_changed(const IndexMask &node_mask, const StringRef attribute_name)
594{
595 if (this->draw_data) {
596 this->draw_data->tag_attribute_changed(node_mask, attribute_name);
597 }
598}
599
600static bool tree_is_empty(const Tree &pbvh)
601{
602 return std::visit([](const auto &nodes) { return nodes.is_empty(); }, pbvh.nodes_);
603}
604
605static Node &first_node(Tree &pbvh)
606{
608 return std::visit([](auto &nodes) -> Node & { return nodes.first(); }, pbvh.nodes_);
609}
610
611struct StackItem {
614};
615
622
623static void pbvh_iter_begin(PBVHIter *iter, Tree &pbvh, FunctionRef<bool(Node &)> scb)
624{
625 iter->pbvh = &pbvh;
626 iter->scb = scb;
627 iter->stack.push({&first_node(pbvh), false});
628}
629
630static Node *pbvh_iter_next(PBVHIter *iter, PBVHNodeFlags leaf_flag)
631{
632 /* purpose here is to traverse tree, visiting child nodes before their
633 * parents, this order is necessary for e.g. computing bounding boxes */
634
635 while (!iter->stack.is_empty()) {
636 StackItem item = iter->stack.pop();
637 Node *node = item.node;
638 bool revisiting = item.revisiting;
639
640 /* on a mesh with no faces this can happen
641 * can remove this check if we know meshes have at least 1 face */
642 if (node == nullptr) {
643 return nullptr;
644 }
645
646 /* revisiting node already checked */
647 if (revisiting) {
648 return node;
649 }
650
651 if (iter->scb && !iter->scb(*node)) {
652 continue; /* don't traverse, outside of search zone */
653 }
654
655 if (node->flag_ & leaf_flag) {
656 /* immediately hit leaf node */
657 return node;
658 }
659
660 /* come back later when children are done */
661 iter->stack.push({node, true});
662
663 /* push two child nodes on the stack */
664 std::visit(
665 [&](auto &nodes) {
666 iter->stack.push({&nodes[node->children_offset_ + 1], false});
667 iter->stack.push({&nodes[node->children_offset_], false});
668 },
669 iter->pbvh->nodes_);
670 }
671
672 return nullptr;
673}
674
676{
677 while (!iter->stack.is_empty()) {
678 StackItem item = iter->stack.pop();
679 Node *node = item.node;
680
681 /* on a mesh with no faces this can happen
682 * can remove this check if we know meshes have at least 1 face */
683 if (node == nullptr) {
684 return nullptr;
685 }
686
687 if (iter->scb && !iter->scb(*node)) {
688 continue; /* don't traverse, outside of search zone */
689 }
690
691 if (node->flag_ & PBVH_Leaf) {
692 /* immediately hit leaf node */
693 return node;
694 }
695
696 std::visit(
697 [&](auto &nodes) {
698 iter->stack.push({&nodes[node->children_offset_ + 1], false});
699 iter->stack.push({&nodes[node->children_offset_], false});
700 },
701 iter->pbvh->nodes_);
702 }
703
704 return nullptr;
705}
706
713
714static void node_tree_insert(node_tree *tree, node_tree *new_node)
715{
716 if (new_node->data->tmin_ < tree->data->tmin_) {
717 if (tree->left) {
718 node_tree_insert(tree->left, new_node);
719 }
720 else {
721 tree->left = new_node;
722 }
723 }
724 else {
725 if (tree->right) {
726 node_tree_insert(tree->right, new_node);
727 }
728 else {
729 tree->right = new_node;
730 }
731 }
732}
733
735 const FunctionRef<void(Node &node, float *tmin)> hit_fn,
736 float *tmin)
737{
738 if (tree->left) {
739 traverse_tree(tree->left, hit_fn, tmin);
740 }
741
742 hit_fn(*tree->data, tmin);
743
744 if (tree->right) {
745 traverse_tree(tree->right, hit_fn, tmin);
746 }
747}
748
750{
751 if (tree->left) {
752 free_tree(tree->left);
753 tree->left = nullptr;
754 }
755
756 if (tree->right) {
757 free_tree(tree->right);
758 tree->right = nullptr;
759 }
760
761 ::free(tree);
762}
763
764} // namespace blender::bke::pbvh
765
767{
768 return node->tmin_;
769}
770
771namespace blender::bke::pbvh {
772
774 const FunctionRef<bool(Node &)> scb,
775 const FunctionRef<void(Node &node, float *tmin)> hit_fn)
776{
777 if (tree_is_empty(pbvh)) {
778 return;
779 }
780 PBVHIter iter;
781 Node *node;
782 node_tree *tree = nullptr;
783
784 pbvh_iter_begin(&iter, pbvh, scb);
785
786 while ((node = pbvh_iter_next_occluded(&iter))) {
787 if (node->flag_ & PBVH_Leaf) {
788 node_tree *new_node = static_cast<node_tree *>(malloc(sizeof(node_tree)));
789
790 new_node->data = node;
791
792 new_node->left = nullptr;
793 new_node->right = nullptr;
794
795 if (tree) {
796 node_tree_insert(tree, new_node);
797 }
798 else {
799 tree = new_node;
800 }
801 }
802 }
803
804 if (tree) {
805 float tmin = FLT_MAX;
806 traverse_tree(tree, hit_fn, &tmin);
808 }
809}
810
816static bool mesh_topology_count_matches(const Mesh &a, const Mesh &b)
817{
818 return a.faces_num == b.faces_num && a.corners_num == b.corners_num &&
819 a.verts_num == b.verts_num;
820}
821
823 const Object &object_eval)
824{
825 const SculptSession &ss = *object_orig.sculpt;
826 const Mesh &mesh_orig = *static_cast<const Mesh *>(object_orig.data);
827 BLI_assert(bke::object::pbvh_get(object_orig)->type() == Type::Mesh);
828 if (object_orig.mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
829 if (const Mesh *mesh_eval = BKE_object_get_evaluated_mesh_no_subsurf(&object_eval)) {
830 if (mesh_topology_count_matches(*mesh_eval, mesh_orig)) {
831 return mesh_eval->runtime->vert_normals_cache;
832 }
833 }
834 if (const Mesh *mesh_eval = BKE_object_get_mesh_deform_eval(&object_eval)) {
835 return mesh_eval->runtime->vert_normals_cache;
836 }
837 }
838
839 if (!ss.deform_cos.is_empty()) {
840 BLI_assert(ss.deform_cos.size() == mesh_orig.verts_num);
841 return ss.vert_normals_deform;
842 }
843
844 return mesh_orig.runtime->vert_normals_cache;
845}
847 Object &object_eval)
848{
849 return const_cast<SharedCache<Vector<float3>> &>(
850 vert_normals_cache_eval(object_orig, object_eval));
851}
852
854 const Object &object_eval)
855{
856 const SculptSession &ss = *object_orig.sculpt;
857 const Mesh &mesh_orig = *static_cast<const Mesh *>(object_orig.data);
858 BLI_assert(bke::object::pbvh_get(object_orig)->type() == Type::Mesh);
859 if (object_orig.mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
860 if (const Mesh *mesh_eval = BKE_object_get_evaluated_mesh_no_subsurf(&object_eval)) {
861 if (mesh_topology_count_matches(*mesh_eval, mesh_orig)) {
862 return mesh_eval->runtime->face_normals_cache;
863 }
864 }
865 if (const Mesh *mesh_eval = BKE_object_get_mesh_deform_eval(&object_eval)) {
866 return mesh_eval->runtime->face_normals_cache;
867 }
868 }
869
870 if (!ss.deform_cos.is_empty()) {
871 BLI_assert(ss.deform_cos.size() == mesh_orig.verts_num);
872 return ss.face_normals_deform;
873 }
874
875 return mesh_orig.runtime->face_normals_cache;
876}
878 Object &object_eval)
879{
880 return const_cast<SharedCache<Vector<float3>> &>(
881 face_normals_cache_eval(object_orig, object_eval));
882}
883
884static void normals_calc_faces(const Span<float3> positions,
885 const OffsetIndices<int> faces,
886 const Span<int> corner_verts,
887 const Span<int> face_indices,
888 MutableSpan<float3> face_normals)
889{
890 for (const int i : face_indices) {
891 face_normals[i] = mesh::face_normal_calc(positions, corner_verts.slice(faces[i]));
892 }
893}
894
895static void calc_boundary_face_normals(const Span<float3> positions,
896 const OffsetIndices<int> faces,
897 const Span<int> corner_verts,
898 const Span<int> face_indices,
899 MutableSpan<float3> face_normals)
900{
901 threading::parallel_for(face_indices.index_range(), 512, [&](const IndexRange range) {
902 normals_calc_faces(positions, faces, corner_verts, face_indices.slice(range), face_normals);
903 });
904}
905
906static void calc_node_face_normals(const Span<float3> positions,
907 const OffsetIndices<int> faces,
908 const Span<int> corner_verts,
909 const Span<MeshNode> nodes,
910 const IndexMask &nodes_to_update,
911 MutableSpan<float3> face_normals)
912{
913 nodes_to_update.foreach_index(GrainSize(1), [&](const int i) {
914 normals_calc_faces(positions, faces, corner_verts, nodes[i].faces(), face_normals);
915 });
916}
917
918static void normals_calc_verts_simple(const GroupedSpan<int> vert_to_face_map,
919 const Span<float3> face_normals,
920 const Span<int> verts,
921 MutableSpan<float3> vert_normals)
922{
923 for (const int vert : verts) {
924 float3 normal(0.0f);
925 for (const int face : vert_to_face_map[vert]) {
926 normal += face_normals[face];
927 }
928 vert_normals[vert] = math::normalize(normal);
929 }
930}
931
932static void calc_boundary_vert_normals(const GroupedSpan<int> vert_to_face_map,
933 const Span<float3> face_normals,
934 const Span<int> verts,
935 MutableSpan<float3> vert_normals)
936{
937 threading::parallel_for(verts.index_range(), 1024, [&](const IndexRange range) {
938 normals_calc_verts_simple(vert_to_face_map, face_normals, verts.slice(range), vert_normals);
939 });
940}
941
942static void calc_node_vert_normals(const GroupedSpan<int> vert_to_face_map,
943 const Span<float3> face_normals,
944 const Span<MeshNode> nodes,
945 const IndexMask &nodes_to_update,
946 MutableSpan<float3> vert_normals)
947{
948 nodes_to_update.foreach_index(GrainSize(1), [&](const int i) {
949 normals_calc_verts_simple(vert_to_face_map, face_normals, nodes[i].verts(), vert_normals);
950 });
951}
952
953static void update_normals_mesh(Object &object_orig,
954 Object &object_eval,
955 const Span<MeshNode> nodes,
956 const IndexMask &nodes_to_update)
957{
958 /* Position changes are tracked on a per-node level, so all the vertex and face normals for every
959 * affected node are recalculated. However, the additional complexity comes from the fact that
960 * changing vertex normals also changes surrounding face normals. Those changed face normals then
961 * change the normals of all connected vertices, which can be in other nodes. So the set of
962 * vertices that need recalculated normals can propagate into unchanged/untagged Tree nodes.
963 *
964 * Currently we have no good way of finding neighboring Tree nodes, so we use the vertex to
965 * face topology map to find the neighboring vertices that need normal recalculation.
966 *
967 * Those boundary face and vertex indices are deduplicated with #VectorSet in order to avoid
968 * duplicate work recalculation for the same vertex, and to make parallel storage for vertices
969 * during recalculation thread-safe. */
970 Mesh &mesh = *static_cast<Mesh *>(object_orig.data);
971 const Span<float3> positions = bke::pbvh::vert_positions_eval_from_eval(object_eval);
972 const OffsetIndices faces = mesh.faces();
973 const Span<int> corner_verts = mesh.corner_verts();
974 const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
975
976 SharedCache<Vector<float3>> &vert_normals_cache = vert_normals_cache_eval_for_write(object_orig,
977 object_eval);
978 SharedCache<Vector<float3>> &face_normals_cache = face_normals_cache_eval_for_write(object_orig,
979 object_eval);
980
981 VectorSet<int> boundary_faces;
982 nodes_to_update.foreach_index([&](const int i) {
983 const MeshNode &node = nodes[i];
984 for (const int vert : node.vert_indices_.as_span().drop_front(node.unique_verts_num_)) {
985 boundary_faces.add_multiple(vert_to_face_map[vert]);
986 }
987 });
988
989 VectorSet<int> boundary_verts;
990
992 [&]() {
993 if (face_normals_cache.is_dirty()) {
994 face_normals_cache.ensure([&](Vector<float3> &r_data) {
995 r_data.resize(faces.size());
996 bke::mesh::normals_calc_faces(positions, faces, corner_verts, r_data);
997 });
998 }
999 else {
1000 face_normals_cache.update([&](Vector<float3> &r_data) {
1001 calc_node_face_normals(positions, faces, corner_verts, nodes, nodes_to_update, r_data);
1002 calc_boundary_face_normals(positions, faces, corner_verts, boundary_faces, r_data);
1003 });
1004 }
1005 },
1006 [&]() {
1007 /* Update all normals connected to affected faces, even if not explicitly tagged. */
1008 boundary_verts.reserve(boundary_faces.size());
1009 for (const int face : boundary_faces) {
1010 boundary_verts.add_multiple(corner_verts.slice(faces[face]));
1011 }
1012 });
1013 const Span<float3> face_normals = face_normals_cache.data();
1014
1015 if (vert_normals_cache.is_dirty()) {
1016 vert_normals_cache.ensure([&](Vector<float3> &r_data) {
1017 r_data.resize(positions.size());
1019 positions, faces, corner_verts, vert_to_face_map, face_normals, r_data);
1020 });
1021 }
1022 else {
1023 vert_normals_cache.update([&](Vector<float3> &r_data) {
1024 calc_node_vert_normals(vert_to_face_map, face_normals, nodes, nodes_to_update, r_data);
1025 calc_boundary_vert_normals(vert_to_face_map, face_normals, boundary_verts, r_data);
1026 });
1027 }
1028}
1029
1030static void update_normals(Object &object_orig, Object &object_eval, Tree &pbvh)
1031{
1032 IndexMaskMemory memory;
1033 const IndexMask nodes_to_update = IndexMask::from_bits(pbvh.normals_dirty_, memory);
1034
1035 switch (pbvh.type()) {
1036 case Type::Mesh: {
1037 update_normals_mesh(object_orig, object_eval, pbvh.nodes<MeshNode>(), nodes_to_update);
1038 break;
1039 }
1040 case Type::Grids: {
1041 SculptSession &ss = *object_orig.sculpt;
1042 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
1043 MutableSpan<GridsNode> nodes = pbvh.nodes<GridsNode>();
1044 IndexMaskMemory memory;
1045 const IndexMask faces_to_update = nodes_to_face_selection_grids(
1046 subdiv_ccg, nodes, nodes_to_update, memory);
1047 BKE_subdiv_ccg_update_normals(subdiv_ccg, faces_to_update);
1048 break;
1049 }
1050 case Type::BMesh: {
1051 bmesh_normals_update(pbvh, nodes_to_update);
1052 break;
1053 }
1054 }
1056}
1057
1058void update_normals(const Depsgraph &depsgraph, Object &object_orig, Tree &pbvh)
1059{
1060 BLI_assert(DEG_is_original_object(&object_orig));
1061 Object &object_eval = *DEG_get_evaluated_object(&depsgraph, &object_orig);
1062 update_normals(object_orig, object_eval, pbvh);
1063}
1064
1065void update_normals_from_eval(Object &object_eval, Tree &pbvh)
1066{
1067 /* Updating the original object's mesh normals caches is necessary because we skip dependency
1068 * graph updates for sculpt deformations in some cases (so the evaluated object doesn't contain
1069 * their result), and also because (currently) sculpt deformations skip tagging the mesh normals
1070 * caches dirty. */
1071 Object &object_orig = *DEG_get_original_object(&object_eval);
1072 update_normals(object_orig, object_eval, pbvh);
1073}
1074
1076{
1078 for (const int vert : node.all_verts()) {
1079 math::min_max(positions[vert], bounds.min, bounds.max);
1080 }
1081 node.bounds_ = bounds;
1082}
1083
1084void update_node_bounds_grids(const int grid_area, const Span<float3> positions, GridsNode &node)
1085{
1087 for (const int grid : node.grids()) {
1088 for (const float3 &position : positions.slice(bke::ccg::grid_range(grid_area, grid))) {
1089 math::min_max(position, bounds.min, bounds.max);
1090 }
1091 }
1092 node.bounds_ = bounds;
1093}
1094
1096{
1098 for (const BMVert *vert : node.bm_unique_verts_) {
1099 math::min_max(float3(vert->co), bounds.min, bounds.max);
1100 }
1101 for (const BMVert *vert : node.bm_other_verts_) {
1102 math::min_max(float3(vert->co), bounds.min, bounds.max);
1103 }
1104 node.bounds_ = bounds;
1105}
1106
1111
1112template<typename NodeT>
1114 const BitSpan dirty,
1115 const int node_index)
1116{
1117 NodeT &node = nodes[node_index];
1118 if (node.flag_ & PBVH_Leaf) {
1119 const bool update = node_index < dirty.size() && dirty[node_index];
1120 return {node.bounds_, update};
1121 }
1122
1123 const BoundsMergeInfo info_0 = merge_child_bounds(nodes, dirty, node.children_offset_ + 0);
1124 const BoundsMergeInfo info_1 = merge_child_bounds(nodes, dirty, node.children_offset_ + 1);
1125 const bool update = info_0.update || info_1.update;
1126 if (update) {
1127 node.bounds_ = bounds::merge(info_0.bounds, info_1.bounds);
1128 }
1129 return {node.bounds_, update};
1130}
1131
1133{
1134 std::visit(
1135 [&](auto &nodes) {
1136 nodes.first().bounds_ =
1137 merge_child_bounds(nodes.as_mutable_span(), pbvh.bounds_dirty_, 0).bounds;
1138 },
1139 pbvh.nodes_);
1141}
1142
1143void update_bounds_mesh(const Span<float3> vert_positions, Tree &pbvh)
1144{
1145 IndexMaskMemory memory;
1146 const IndexMask nodes_to_update = IndexMask::from_bits(pbvh.bounds_dirty_, memory);
1147 if (nodes_to_update.is_empty()) {
1148 return;
1149 }
1150 MutableSpan<MeshNode> nodes = pbvh.nodes<MeshNode>();
1151 nodes_to_update.foreach_index(
1152 GrainSize(1), [&](const int i) { update_node_bounds_mesh(vert_positions, nodes[i]); });
1154}
1155
1156void update_bounds_grids(const CCGKey &key, const Span<float3> positions, Tree &pbvh)
1157{
1158 IndexMaskMemory memory;
1159 const IndexMask nodes_to_update = IndexMask::from_bits(pbvh.bounds_dirty_, memory);
1160 if (nodes_to_update.is_empty()) {
1161 return;
1162 }
1163 MutableSpan<GridsNode> nodes = pbvh.nodes<GridsNode>();
1164 nodes_to_update.foreach_index(GrainSize(1), [&](const int i) {
1165 update_node_bounds_grids(key.grid_area, positions, nodes[i]);
1166 });
1168}
1169
1170void update_bounds_bmesh(const BMesh & /*bm*/, Tree &pbvh)
1171{
1172 IndexMaskMemory memory;
1173 const IndexMask nodes_to_update = IndexMask::from_bits(pbvh.bounds_dirty_, memory);
1174 if (nodes_to_update.is_empty()) {
1175 return;
1176 }
1177 MutableSpan<BMeshNode> nodes = pbvh.nodes<BMeshNode>();
1178 nodes_to_update.foreach_index(GrainSize(1),
1179 [&](const int i) { update_node_bounds_bmesh(nodes[i]); });
1181}
1182
1183void update_bounds(const Depsgraph &depsgraph, const Object &object, Tree &pbvh)
1184{
1185 switch (pbvh.type()) {
1186 case Type::Mesh: {
1187 const Span<float3> positions = bke::pbvh::vert_positions_eval(depsgraph, object);
1188 update_bounds_mesh(positions, pbvh);
1189 break;
1190 }
1191 case Type::Grids: {
1192 const SculptSession &ss = *object.sculpt;
1193 const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
1194 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
1195 update_bounds_grids(key, subdiv_ccg.positions, pbvh);
1196 break;
1197 }
1198 case Type::BMesh: {
1199 const SculptSession &ss = *object.sculpt;
1200 update_bounds_bmesh(*ss.bm, pbvh);
1201 break;
1202 }
1203 }
1204}
1205
1207{
1208 std::visit(
1209 [](auto &nodes) {
1210 threading::parallel_for(nodes.index_range(), 256, [&](const IndexRange range) {
1211 for (const int i : range) {
1212 nodes[i].bounds_orig_ = nodes[i].bounds_;
1213 }
1214 });
1215 },
1216 pbvh.nodes_);
1217}
1218
1220{
1221 const Span<int> verts = node.all_verts();
1222 const bool fully_masked = std::all_of(
1223 verts.begin(), verts.end(), [&](const int vert) { return mask[vert] == 1.0f; });
1224 const bool fully_unmasked = std::all_of(
1225 verts.begin(), verts.end(), [&](const int vert) { return mask[vert] <= 0.0f; });
1226 SET_FLAG_FROM_TEST(node.flag_, fully_masked, PBVH_FullyMasked);
1227 SET_FLAG_FROM_TEST(node.flag_, fully_unmasked, PBVH_FullyUnmasked);
1228}
1229
1230void update_mask_mesh(const Mesh &mesh, const IndexMask &node_mask, Tree &pbvh)
1231{
1232 const MutableSpan<MeshNode> nodes = pbvh.nodes<MeshNode>();
1233 const AttributeAccessor attributes = mesh.attributes();
1234 const VArraySpan<float> mask = *attributes.lookup<float>(".sculpt_mask", AttrDomain::Point);
1235 if (mask.is_empty()) {
1236 node_mask.foreach_index([&](const int i) {
1237 nodes[i].flag_ &= ~PBVH_FullyMasked;
1238 nodes[i].flag_ |= PBVH_FullyUnmasked;
1239 });
1240 return;
1241 }
1242
1243 node_mask.foreach_index(GrainSize(1),
1244 [&](const int i) { node_update_mask_mesh(mask, nodes[i]); });
1245}
1246
1247void node_update_mask_grids(const CCGKey &key, const Span<float> masks, GridsNode &node)
1248{
1249 bool fully_masked = true;
1250 bool fully_unmasked = true;
1251 for (const int grid : node.grids()) {
1252 for (const float mask : masks.slice(bke::ccg::grid_range(key, grid))) {
1253 fully_masked &= mask == 1.0f;
1254 fully_unmasked &= mask <= 0.0f;
1255 }
1256 }
1257 SET_FLAG_FROM_TEST(node.flag_, fully_masked, PBVH_FullyMasked);
1258 SET_FLAG_FROM_TEST(node.flag_, fully_unmasked, PBVH_FullyUnmasked);
1259}
1260
1261void update_mask_grids(const SubdivCCG &subdiv_ccg, const IndexMask &node_mask, Tree &pbvh)
1262{
1263 const MutableSpan<GridsNode> nodes = pbvh.nodes<GridsNode>();
1264 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
1265 if (subdiv_ccg.masks.is_empty()) {
1266 node_mask.foreach_index([&](const int i) {
1267 nodes[i].flag_ &= ~PBVH_FullyMasked;
1268 nodes[i].flag_ |= PBVH_FullyUnmasked;
1269 });
1270 return;
1271 }
1272
1273 node_mask.foreach_index(
1274 GrainSize(1), [&](const int i) { node_update_mask_grids(key, subdiv_ccg.masks, nodes[i]); });
1275}
1276
1277void node_update_mask_bmesh(const int mask_offset, BMeshNode &node)
1278{
1279 BLI_assert(mask_offset != -1);
1280 bool fully_masked = true;
1281 bool fully_unmasked = true;
1282 for (const BMVert *vert : node.bm_unique_verts_) {
1283 fully_masked &= BM_ELEM_CD_GET_FLOAT(vert, mask_offset) == 1.0f;
1284 fully_unmasked &= BM_ELEM_CD_GET_FLOAT(vert, mask_offset) <= 0.0f;
1285 }
1286 for (const BMVert *vert : node.bm_other_verts_) {
1287 fully_masked &= BM_ELEM_CD_GET_FLOAT(vert, mask_offset) == 1.0f;
1288 fully_unmasked &= BM_ELEM_CD_GET_FLOAT(vert, mask_offset) <= 0.0f;
1289 }
1290 SET_FLAG_FROM_TEST(node.flag_, fully_masked, PBVH_FullyMasked);
1291 SET_FLAG_FROM_TEST(node.flag_, fully_unmasked, PBVH_FullyUnmasked);
1292}
1293
1294void update_mask_bmesh(const BMesh &bm, const IndexMask &node_mask, Tree &pbvh)
1295{
1296 const MutableSpan<BMeshNode> nodes = pbvh.nodes<BMeshNode>();
1297 const int offset = CustomData_get_offset_named(&bm.vdata, CD_PROP_FLOAT, ".sculpt_mask");
1298 if (offset == -1) {
1299 node_mask.foreach_index([&](const int i) {
1300 nodes[i].flag_ &= ~PBVH_FullyMasked;
1301 nodes[i].flag_ |= PBVH_FullyUnmasked;
1302 });
1303 return;
1304 }
1305
1306 node_mask.foreach_index(GrainSize(1),
1307 [&](const int i) { node_update_mask_bmesh(offset, nodes[i]); });
1308}
1309
1311{
1312 BLI_assert(!hide_vert.is_empty());
1313 const Span<int> verts = node.all_verts();
1314 const bool fully_hidden = std::all_of(
1315 verts.begin(), verts.end(), [&](const int vert) { return hide_vert[vert]; });
1316 SET_FLAG_FROM_TEST(node.flag_, fully_hidden, PBVH_FullyHidden);
1317}
1318
1319static void update_visibility_faces(const Mesh &mesh,
1320 const MutableSpan<MeshNode> nodes,
1321 const IndexMask &node_mask)
1322{
1323 const AttributeAccessor attributes = mesh.attributes();
1324 const VArraySpan<bool> hide_vert = *attributes.lookup<bool>(".hide_vert", AttrDomain::Point);
1325 if (hide_vert.is_empty()) {
1326 node_mask.foreach_index([&](const int i) { nodes[i].flag_ &= ~PBVH_FullyHidden; });
1327 return;
1328 }
1329
1330 node_mask.foreach_index(GrainSize(1),
1331 [&](const int i) { node_update_visibility_mesh(hide_vert, nodes[i]); });
1332}
1333
1335{
1336 BLI_assert(!grid_hidden.is_empty());
1337 const bool fully_hidden = std::none_of(
1338 node.prim_indices_.begin(), node.prim_indices_.end(), [&](const int grid) {
1339 return bits::any_bit_unset(grid_hidden[grid]);
1340 });
1341 SET_FLAG_FROM_TEST(node.flag_, fully_hidden, PBVH_FullyHidden);
1342}
1343
1344static void update_visibility_grids(const SubdivCCG &subdiv_ccg,
1345 const MutableSpan<GridsNode> nodes,
1346 const IndexMask &node_mask)
1347{
1348 const BitGroupVector<> &grid_hidden = subdiv_ccg.grid_hidden;
1349 if (grid_hidden.is_empty()) {
1350 node_mask.foreach_index([&](const int i) { nodes[i].flag_ &= ~PBVH_FullyHidden; });
1351 return;
1352 }
1353
1354 node_mask.foreach_index(
1355 GrainSize(1), [&](const int i) { node_update_visibility_grids(grid_hidden, nodes[i]); });
1356}
1357
1359{
1360 const bool unique_hidden = std::all_of(
1361 node.bm_unique_verts_.begin(), node.bm_unique_verts_.end(), [&](const BMVert *vert) {
1362 return BM_elem_flag_test(vert, BM_ELEM_HIDDEN);
1363 });
1364 const bool other_hidden = std::all_of(
1365 node.bm_other_verts_.begin(), node.bm_other_verts_.end(), [&](const BMVert *vert) {
1366 return BM_elem_flag_test(vert, BM_ELEM_HIDDEN);
1367 });
1368 SET_FLAG_FROM_TEST(node.flag_, unique_hidden && other_hidden, PBVH_FullyHidden);
1369}
1370
1371static void update_visibility_bmesh(const MutableSpan<BMeshNode> nodes, const IndexMask &node_mask)
1372{
1373 node_mask.foreach_index(GrainSize(1),
1374 [&](const int i) { node_update_visibility_bmesh(nodes[i]); });
1375}
1376
1377void update_visibility(const Object &object, Tree &pbvh)
1378{
1379 IndexMaskMemory memory;
1380 const IndexMask node_mask = IndexMask::from_bits(pbvh.visibility_dirty_, memory);
1381 if (node_mask.is_empty()) {
1382 return;
1383 }
1385 switch (pbvh.type()) {
1386 case Type::Mesh: {
1387 const Mesh &mesh = *static_cast<const Mesh *>(object.data);
1388 update_visibility_faces(mesh, pbvh.nodes<MeshNode>(), node_mask);
1389 break;
1390 }
1391 case Type::Grids: {
1392 const SculptSession &ss = *object.sculpt;
1393 update_visibility_grids(*ss.subdiv_ccg, pbvh.nodes<GridsNode>(), node_mask);
1394 break;
1395 }
1396 case Type::BMesh: {
1397 update_visibility_bmesh(pbvh.nodes<BMeshNode>(), node_mask);
1398 break;
1399 }
1400 }
1401}
1402
1403int count_grid_quads(const BitGroupVector<> &grid_hidden,
1404 const Span<int> grid_indices,
1405 int gridsize,
1406 int display_gridsize)
1407{
1408 const int gridarea = (gridsize - 1) * (gridsize - 1);
1409 if (grid_hidden.is_empty()) {
1410 return gridarea * grid_indices.size();
1411 }
1412
1413 /* grid hidden layer is present, so have to check each grid for
1414 * visibility */
1415
1416 int depth1 = int(log2(double(gridsize) - 1.0) + DBL_EPSILON);
1417 int depth2 = int(log2(double(display_gridsize) - 1.0) + DBL_EPSILON);
1418
1419 int skip = depth2 < depth1 ? 1 << (depth1 - depth2 - 1) : 1;
1420
1421 int totquad = 0;
1422 for (const int grid : grid_indices) {
1423 const blender::BoundedBitSpan gh = grid_hidden[grid];
1424 /* grid hidden are present, have to check each element */
1425 for (int y = 0; y < gridsize - skip; y += skip) {
1426 for (int x = 0; x < gridsize - skip; x += skip) {
1427 if (!paint_is_grid_face_hidden(gh, gridsize, x, y)) {
1428 totquad++;
1429 }
1430 }
1431 }
1432 }
1433
1434 return totquad;
1435}
1436
1437} // namespace blender::bke::pbvh
1438
1440{
1441 using namespace blender;
1442 using namespace blender::bke::pbvh;
1443 if (tree_is_empty(pbvh)) {
1444 return {};
1445 }
1447
1448 PBVHIter iter;
1449 pbvh_iter_begin(&iter, const_cast<blender::bke::pbvh::Tree &>(pbvh), {});
1450 Node *node;
1451 while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) {
1452 if (node->flag_ & PBVH_UpdateRedraw) {
1453 bounds = bounds::merge(bounds, node->bounds_);
1454 }
1455 }
1456
1457 return bounds;
1458}
1459
1460namespace blender::bke::pbvh {
1461
1463 const Span<GridsNode> nodes,
1464 const IndexMask &nodes_mask,
1465 IndexMaskMemory &memory)
1466{
1467 const Span<int> grid_to_face_map = subdiv_ccg.grid_to_face_map;
1468 /* Using a #VectorSet for index deduplication would also work, but the performance gets much
1469 * worse with large selections since the loop would be single-threaded. A boolean array has an
1470 * overhead regardless of selection size, but that is small. */
1471 Array<bool> faces_to_update(subdiv_ccg.faces.size(), false);
1472 nodes_mask.foreach_index(GrainSize(1), [&](const int i) {
1473 for (const int grid : nodes[i].grids()) {
1474 faces_to_update[grid_to_face_map[grid]] = true;
1475 }
1476 });
1477 return IndexMask::from_bools(faces_to_update, memory);
1478}
1479
1481{
1482 return std::visit(
1483 [](auto &nodes) -> Bounds<float3> {
1484 if (nodes.is_empty()) {
1485 return float3(0);
1486 }
1487 return nodes.first().bounds_;
1488 },
1489 pbvh.nodes_);
1490}
1491
1492} // namespace blender::bke::pbvh
1493
1495{
1496 const SculptSession &ss = *object.sculpt;
1499 return ss.subdiv_ccg->grids_num * key.grid_area;
1500}
1501
1503{
1504 const SculptSession &ss = *object.sculpt;
1507 return ss.subdiv_ccg->grids_num * square_i(key.grid_size - 1);
1508}
1509
1510/***************************** Node Access ***********************************/
1511
1516
1518{
1519 std::visit(
1520 [](auto &nodes) {
1521 for (blender::bke::pbvh::Node &node : nodes) {
1522 if (node.flag_ & PBVH_Leaf) {
1523 node.flag_ |= PBVH_RebuildPixels;
1524 }
1525 }
1526 },
1527 pbvh.nodes_);
1528}
1529
1531{
1532 BLI_assert(node.flag_ & PBVH_Leaf);
1533
1534 if (fully_hidden) {
1535 node.flag_ |= PBVH_FullyHidden;
1536 }
1537 else {
1538 node.flag_ &= ~PBVH_FullyHidden;
1539 }
1540}
1541
1543{
1544 return (node.flag_ & PBVH_Leaf) && (node.flag_ & PBVH_FullyHidden);
1545}
1546
1548{
1549 BLI_assert(node.flag_ & PBVH_Leaf);
1550
1551 if (fully_masked) {
1552 node.flag_ |= PBVH_FullyMasked;
1553 }
1554 else {
1555 node.flag_ &= ~PBVH_FullyMasked;
1556 }
1557}
1558
1560{
1561 return (node.flag_ & PBVH_Leaf) && (node.flag_ & PBVH_FullyMasked);
1562}
1563
1565{
1566 BLI_assert(node.flag_ & PBVH_Leaf);
1567
1568 if (fully_masked) {
1569 node.flag_ |= PBVH_FullyUnmasked;
1570 }
1571 else {
1572 node.flag_ &= ~PBVH_FullyUnmasked;
1573 }
1574}
1575
1577{
1578 return (node.flag_ & PBVH_Leaf) && (node.flag_ & PBVH_FullyUnmasked);
1579}
1580
1581namespace blender::bke::pbvh {
1582
1584 const GridsNode &node,
1585 Vector<int> &faces)
1586{
1587 faces.clear();
1588 const Span<int> grid_to_face_map = subdiv_ccg.grid_to_face_map;
1589 int prev_face = -1;
1590 for (const int grid : node.grids()) {
1591 const int face = grid_to_face_map[grid];
1592 if (face != prev_face) {
1593 faces.append(face);
1594 prev_face = face;
1595 }
1596 }
1597 return faces.as_span();
1598}
1599
1600} // namespace blender::bke::pbvh
1601
1602namespace blender::bke::pbvh {
1603
1605{
1606 return node.bounds_;
1607}
1608
1609} // namespace blender::bke::pbvh
1610
1612 const blender::bke::pbvh::Node *node)
1613{
1614 return node->bounds_orig_;
1615}
1616
1618 blender::Span<blender::float3> &r_orig_positions,
1619 blender::Span<blender::int3> &r_orig_tris)
1620{
1621 r_orig_positions = node.orig_positions_;
1622 r_orig_tris = node.orig_tris_;
1623}
1624
1625/********************************* Ray-cast ***********************************/
1626
1627namespace blender::bke::pbvh {
1628
1633
1634static bool ray_aabb_intersect(Node &node, const RaycastData &rcd)
1635{
1636 if (rcd.original) {
1637 return isect_ray_aabb_v3(&rcd.ray, node.bounds_orig_.min, node.bounds_orig_.max, &node.tmin_);
1638 }
1639 return isect_ray_aabb_v3(&rcd.ray, node.bounds_.min, node.bounds_.max, &node.tmin_);
1640}
1641
1642void raycast(Tree &pbvh,
1643 const FunctionRef<void(Node &node, float *tmin)> hit_fn,
1644 const float3 &ray_start,
1645 const float3 &ray_normal,
1646 bool original)
1647{
1648 RaycastData rcd;
1649
1650 isect_ray_aabb_v3_precalc(&rcd.ray, ray_start, ray_normal);
1651 rcd.original = original;
1652
1654 pbvh, [&](Node &node) { return ray_aabb_intersect(node, rcd); }, hit_fn);
1655}
1656
1658 const IsectRayPrecalc *isect_precalc,
1659 const float3 &t0,
1660 const float3 &t1,
1661 const float3 &t2,
1662 const float3 &t3,
1663 float *depth)
1664{
1665 float depth_test;
1666
1667 if ((isect_ray_tri_watertight_v3(ray_start, isect_precalc, t0, t1, t2, &depth_test, nullptr) &&
1668 (depth_test < *depth)) ||
1669 (isect_ray_tri_watertight_v3(ray_start, isect_precalc, t0, t2, t3, &depth_test, nullptr) &&
1670 (depth_test < *depth)))
1671 {
1672 *depth = depth_test;
1673 return true;
1674 }
1675
1676 return false;
1677}
1678
1679bool ray_face_intersection_tri(const float3 &ray_start,
1680 const IsectRayPrecalc *isect_precalc,
1681 const float3 &t0,
1682 const float3 &t1,
1683 const float3 &t2,
1684 float *depth)
1685{
1686 float depth_test;
1687 if (isect_ray_tri_watertight_v3(ray_start, isect_precalc, t0, t1, t2, &depth_test, nullptr) &&
1688 (depth_test < *depth))
1689 {
1690 *depth = depth_test;
1691 return true;
1692 }
1693
1694 return false;
1695}
1696
1697/* Take advantage of the fact we know this won't be an intersection.
1698 * Just handle ray-tri edges. */
1699static float dist_squared_ray_to_tri_v3_fast(const float3 &ray_origin,
1700 const float3 &ray_direction,
1701 const float3 &v0,
1702 const float3 &v1,
1703 const float3 &v2,
1704 float3 &r_point,
1705 float *r_depth)
1706{
1707 const float *tri[3] = {v0, v1, v2};
1708 float dist_sq_best = FLT_MAX;
1709 for (int i = 0, j = 2; i < 3; j = i++) {
1710 float3 point_test;
1711 float depth_test = FLT_MAX;
1712 const float dist_sq_test = dist_squared_ray_to_seg_v3(
1713 ray_origin, ray_direction, tri[i], tri[j], point_test, &depth_test);
1714 if (dist_sq_test < dist_sq_best || i == 0) {
1715 copy_v3_v3(r_point, point_test);
1716 *r_depth = depth_test;
1717 dist_sq_best = dist_sq_test;
1718 }
1719 }
1720 return dist_sq_best;
1721}
1722
1723bool ray_face_nearest_quad(const float3 &ray_start,
1724 const float3 &ray_normal,
1725 const float3 &t0,
1726 const float3 &t1,
1727 const float3 &t2,
1728 const float3 &t3,
1729 float *r_depth,
1730 float *dist_sq)
1731{
1732 float dist_sq_test;
1733 float3 co;
1734 float depth_test;
1735
1736 if ((dist_sq_test = dist_squared_ray_to_tri_v3_fast(
1737 ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq)
1738 {
1739 *dist_sq = dist_sq_test;
1740 *r_depth = depth_test;
1741 if ((dist_sq_test = dist_squared_ray_to_tri_v3_fast(
1742 ray_start, ray_normal, t0, t2, t3, co, &depth_test)) < *dist_sq)
1743 {
1744 *dist_sq = dist_sq_test;
1745 *r_depth = depth_test;
1746 }
1747 return true;
1748 }
1749
1750 return false;
1751}
1752
1753bool ray_face_nearest_tri(const float3 &ray_start,
1754 const float3 &ray_normal,
1755 const float3 &t0,
1756 const float3 &t1,
1757 const float3 &t2,
1758 float *r_depth,
1759 float *dist_sq)
1760{
1761 float dist_sq_test;
1762 float3 co;
1763 float depth_test;
1764
1765 if ((dist_sq_test = dist_squared_ray_to_tri_v3_fast(
1766 ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq)
1767 {
1768 *dist_sq = dist_sq_test;
1769 *r_depth = depth_test;
1770 return true;
1771 }
1772
1773 return false;
1774}
1775
1776static void calc_mesh_intersect_data(const Span<int> corner_verts,
1777 const Span<int3> corner_tris,
1778 const float3 &ray_start,
1779 const float3 &ray_normal,
1780 const int face_index,
1781 const int tri_index,
1782 const std::array<const float *, 3> co,
1783 const float *depth,
1784 int &r_active_vertex,
1785 int &r_active_face_index,
1786 float3 &r_face_normal)
1787
1788{
1789 float3 nearest_vertex_co(0.0f);
1790 normal_tri_v3(r_face_normal, co[0], co[1], co[2]);
1791
1792 const float3 location = ray_start + ray_normal * *depth;
1793 for (int i = 0; i < co.size(); i++) {
1794 /* Always assign nearest_vertex_co in the first iteration to avoid comparison against
1795 * uninitialized values. This stores the closest vertex in the current intersecting
1796 * triangle. */
1797 if (i == 0 ||
1798 len_squared_v3v3(location, co[i]) < len_squared_v3v3(location, nearest_vertex_co))
1799 {
1800 nearest_vertex_co = co[i];
1801 r_active_vertex = corner_verts[corner_tris[tri_index][i]];
1802 r_active_face_index = face_index;
1803 }
1804 }
1805}
1806
1808 const Span<float3> node_positions,
1809 const Span<float3> vert_positions,
1810 const OffsetIndices<int> faces,
1811 const Span<int> corner_verts,
1812 const Span<int3> corner_tris,
1813 const Span<bool> hide_poly,
1814 const float3 &ray_start,
1815 const float3 &ray_normal,
1816 IsectRayPrecalc *isect_precalc,
1817 float *depth,
1818 int &r_active_vertex,
1819 int &r_active_face_index,
1820 float3 &r_face_normal)
1821{
1822 const Span<int> face_indices = node.faces();
1823
1824 bool hit = false;
1825 if (node_positions.is_empty()) {
1826 for (const int i : face_indices.index_range()) {
1827 const int face_i = face_indices[i];
1828 if (!hide_poly.is_empty() && hide_poly[face_i]) {
1829 continue;
1830 }
1831
1832 for (const int tri_i : bke::mesh::face_triangles_range(faces, face_i)) {
1833 const int3 &tri = corner_tris[tri_i];
1834 const std::array<const float *, 3> co{{vert_positions[corner_verts[tri[0]]],
1835 vert_positions[corner_verts[tri[1]]],
1836 vert_positions[corner_verts[tri[2]]]}};
1837 if (ray_face_intersection_tri(ray_start, isect_precalc, co[0], co[1], co[2], depth)) {
1838 hit = true;
1839 calc_mesh_intersect_data(corner_verts,
1840 corner_tris,
1841 ray_start,
1842 ray_normal,
1843 face_i,
1844 tri_i,
1845 co,
1846 depth,
1847 r_active_vertex,
1848 r_active_face_index,
1849 r_face_normal);
1850 }
1851 }
1852 }
1853 }
1854 else {
1855 const MeshNode::LocalVertMap &vert_map = node.vert_indices_;
1856 for (const int i : face_indices.index_range()) {
1857 const int face_i = face_indices[i];
1858 if (!hide_poly.is_empty() && hide_poly[face_i]) {
1859 continue;
1860 }
1861
1862 for (const int tri_i : bke::mesh::face_triangles_range(faces, face_i)) {
1863 const int3 &tri = corner_tris[tri_i];
1864 const std::array<const float *, 3> co{
1865 {node_positions[vert_map.index_of(corner_verts[tri[0]])],
1866 node_positions[vert_map.index_of(corner_verts[tri[1]])],
1867 node_positions[vert_map.index_of(corner_verts[tri[2]])]}};
1868 if (ray_face_intersection_tri(ray_start, isect_precalc, co[0], co[1], co[2], depth)) {
1869 hit = true;
1870 calc_mesh_intersect_data(corner_verts,
1871 corner_tris,
1872 ray_start,
1873 ray_normal,
1874 face_i,
1875 tri_i,
1876 co,
1877 depth,
1878 r_active_vertex,
1879 r_active_face_index,
1880 r_face_normal);
1881 }
1882 }
1883 }
1884 }
1885
1886 return hit;
1887}
1888
1889static void calc_grids_intersect_data(const float3 &ray_start,
1890 const float3 &ray_normal,
1891 const int grid,
1892 const short x,
1893 const short y,
1894 const std::array<const float *, 4> co,
1895 float *depth,
1896 SubdivCCGCoord &r_active_vertex,
1897 int &r_active_grid_index,
1898 float3 &r_face_normal)
1899
1900{
1901 float3 nearest_vertex_co;
1902 normal_quad_v3(r_face_normal, co[0], co[1], co[2], co[3]);
1903
1904 const float3 location = ray_start + ray_normal * *depth;
1905
1906 constexpr short x_it[4] = {0, 1, 1, 0};
1907 constexpr short y_it[4] = {1, 1, 0, 0};
1908
1909 for (int i = 0; i < co.size(); i++) {
1910 /* Always assign nearest_vertex_co in the first iteration to avoid comparison against
1911 * uninitialized values. This stores the closest vertex in the current intersecting
1912 * quad. */
1913 if (i == 0 ||
1914 len_squared_v3v3(location, co[i]) < len_squared_v3v3(location, nearest_vertex_co))
1915 {
1916 copy_v3_v3(nearest_vertex_co, co[i]);
1917 r_active_vertex = SubdivCCGCoord{grid, short(x + x_it[i]), short(y + y_it[i])};
1918 }
1919 }
1920 r_active_grid_index = grid;
1921}
1922
1923bool node_raycast_grids(const SubdivCCG &subdiv_ccg,
1924 GridsNode &node,
1925 const Span<float3> node_positions,
1926 const float3 &ray_start,
1927 const float3 &ray_normal,
1928 const IsectRayPrecalc *isect_precalc,
1929 float *depth,
1930 SubdivCCGCoord &r_active_vertex,
1931 int &r_active_grid_index,
1932 float3 &r_face_normal)
1933{
1934 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
1935 const Span<int> grids = node.grids();
1936 const int grid_size = key.grid_size;
1937 bool hit = false;
1938 const BitGroupVector<> &grid_hidden = subdiv_ccg.grid_hidden;
1939 const Span<float3> positions = subdiv_ccg.positions;
1940
1941 if (node_positions.is_empty()) {
1942 for (const int grid : grids) {
1943 const Span<float3> grid_positions = positions.slice(bke::ccg::grid_range(key, grid));
1944 for (const short y : IndexRange(grid_size - 1)) {
1945 for (const short x : IndexRange(grid_size - 1)) {
1946 if (!grid_hidden.is_empty()) {
1947 if (paint_is_grid_face_hidden(grid_hidden[grid], grid_size, x, y)) {
1948 continue;
1949 }
1950 }
1951 const std::array<const float *, 4> co{
1952 {grid_positions[CCG_grid_xy_to_index(grid_size, x, y + 1)],
1953 grid_positions[CCG_grid_xy_to_index(grid_size, x + 1, y + 1)],
1954 grid_positions[CCG_grid_xy_to_index(grid_size, x + 1, y)],
1955 grid_positions[CCG_grid_xy_to_index(grid_size, x, y)]}};
1957 ray_start, isect_precalc, co[0], co[1], co[2], co[3], depth))
1958 {
1959 hit = true;
1960 calc_grids_intersect_data(ray_start,
1961 ray_normal,
1962 grid,
1963 x,
1964 y,
1965 co,
1966 depth,
1967 r_active_vertex,
1968 r_active_grid_index,
1969 r_face_normal);
1970 }
1971 }
1972 }
1973 }
1974 }
1975 else {
1976 for (const int i : grids.index_range()) {
1977 const int grid = grids[i];
1978 const Span<float3> grid_positions = node_positions.slice(bke::ccg::grid_range(key, i));
1979 for (const short y : IndexRange(grid_size - 1)) {
1980 for (const short x : IndexRange(grid_size - 1)) {
1981 if (!grid_hidden.is_empty()) {
1982 if (paint_is_grid_face_hidden(grid_hidden[grid], grid_size, x, y)) {
1983 continue;
1984 }
1985 }
1986 const std::array<const float *, 4> co{grid_positions[(y + 1) * grid_size + x],
1987 grid_positions[(y + 1) * grid_size + x + 1],
1988 grid_positions[y * grid_size + x + 1],
1989 grid_positions[y * grid_size + x]};
1991 ray_start, isect_precalc, co[0], co[1], co[2], co[3], depth))
1992 {
1993 hit = true;
1994 calc_grids_intersect_data(ray_start,
1995 ray_normal,
1996 grid,
1997 x,
1998 y,
1999 co,
2000 depth,
2001 r_active_vertex,
2002 r_active_grid_index,
2003 r_face_normal);
2004 }
2005 }
2006 }
2007 }
2008 }
2009
2010 return hit;
2011}
2012
2014 Tree &pbvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3])
2015{
2016 if (tree_is_empty(pbvh)) {
2017 return;
2018 }
2019 float rootmin_start, rootmin_end;
2020 Bounds<float3> bb_root;
2021 float bb_center[3], bb_diff[3];
2023 float ray_normal_inv[3];
2024 float offset = 1.0f + 1e-3f;
2025 const float offset_vec[3] = {1e-3f, 1e-3f, 1e-3f};
2026
2027 if (original) {
2028 bb_root = BKE_pbvh_node_get_original_BB(&first_node(pbvh));
2029 }
2030 else {
2031 bb_root = node_bounds(first_node(pbvh));
2032 }
2033
2034 /* Calc rough clipping to avoid overflow later. See #109555. */
2035 float mat[3][3];
2036 axis_dominant_v3_to_m3(mat, ray_normal);
2037 float a[3], b[3], min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {FLT_MIN, FLT_MIN, FLT_MIN};
2038
2039 /* Compute AABB bounds rotated along ray_normal. */
2040 copy_v3_v3(a, bb_root.min);
2041 copy_v3_v3(b, bb_root.max);
2042 mul_m3_v3(mat, a);
2043 mul_m3_v3(mat, b);
2044 minmax_v3v3_v3(min, max, a);
2045 minmax_v3v3_v3(min, max, b);
2046
2047 float cent[3];
2048
2049 /* Find midpoint of aabb on ray. */
2050 mid_v3_v3v3(cent, bb_root.min, bb_root.max);
2051 float t = line_point_factor_v3(cent, ray_start, ray_end);
2052 interp_v3_v3v3(cent, ray_start, ray_end, t);
2053
2054 /* Compute rough interval. */
2055 float dist = max[2] - min[2];
2056 madd_v3_v3v3fl(ray_start, cent, ray_normal, -dist);
2057 madd_v3_v3v3fl(ray_end, cent, ray_normal, dist);
2058
2059 /* Slightly offset min and max in case we have a zero width node
2060 * (due to a plane mesh for instance), or faces very close to the bounding box boundary. */
2061 mid_v3_v3v3(bb_center, bb_root.max, bb_root.min);
2062 /* Diff should be same for both min/max since it's calculated from center. */
2063 sub_v3_v3v3(bb_diff, bb_root.max, bb_center);
2064 /* Handles case of zero width bb. */
2065 add_v3_v3(bb_diff, offset_vec);
2066 madd_v3_v3v3fl(bb_root.max, bb_center, bb_diff, offset);
2067 madd_v3_v3v3fl(bb_root.min, bb_center, bb_diff, -offset);
2068
2069 /* Final projection of start ray. */
2070 isect_ray_aabb_v3_precalc(&ray, ray_start, ray_normal);
2071 if (!isect_ray_aabb_v3(&ray, bb_root.min, bb_root.max, &rootmin_start)) {
2072 return;
2073 }
2074
2075 /* Final projection of end ray. */
2076 mul_v3_v3fl(ray_normal_inv, ray_normal, -1.0);
2077 isect_ray_aabb_v3_precalc(&ray, ray_end, ray_normal_inv);
2078 /* Unlikely to fail exiting if entering succeeded, still keep this here. */
2079 if (!isect_ray_aabb_v3(&ray, bb_root.min, bb_root.max, &rootmin_end)) {
2080 return;
2081 }
2082
2083 /*
2084 * As a last-ditch effort to correct floating point overflow compute
2085 * and add an epsilon if rootmin_start == rootmin_end.
2086 */
2087
2088 float epsilon = (std::nextafter(rootmin_start, rootmin_start + 1000.0f) - rootmin_start) *
2089 5000.0f;
2090
2091 if (rootmin_start == rootmin_end) {
2092 rootmin_start -= epsilon;
2093 rootmin_end += epsilon;
2094 }
2095
2096 madd_v3_v3v3fl(ray_start, ray_start, ray_normal, rootmin_start);
2097 madd_v3_v3v3fl(ray_end, ray_end, ray_normal_inv, rootmin_end);
2098}
2099
2100/* -------------------------------------------------------------------- */
2101
2103 const DistRayAABB_Precalc &dist_ray_to_aabb_precalc,
2104 const bool original)
2105{
2106 const float *bb_min, *bb_max;
2107
2108 if (original) {
2109 /* BKE_pbvh_node_get_original_BB */
2110 bb_min = node->bounds_orig_.min;
2111 bb_max = node->bounds_orig_.max;
2112 }
2113 else {
2114 bb_min = node->bounds_.min;
2115 bb_max = node->bounds_.max;
2116 }
2117
2118 float co_dummy[3], depth;
2119 node->tmin_ = dist_squared_ray_to_aabb_v3(
2120 &dist_ray_to_aabb_precalc, bb_min, bb_max, co_dummy, &depth);
2121 /* Ideally we would skip distances outside the range. */
2122 return depth > 0.0f;
2123}
2124
2126 const FunctionRef<void(Node &node, float *tmin)> fn,
2127 const float3 &ray_start,
2128 const float3 &ray_normal,
2129 const bool original)
2130{
2131 const DistRayAABB_Precalc ray_dist_precalc = dist_squared_ray_to_aabb_v3_precalc(ray_start,
2132 ray_normal);
2133
2135 pbvh,
2136 [&](Node &node) { return nearest_to_ray_aabb_dist_sq(&node, ray_dist_precalc, original); },
2137 fn);
2138}
2139
2141 const Span<float3> node_positions,
2142 const Span<float3> vert_positions,
2143 const OffsetIndices<int> faces,
2144 const Span<int> corner_verts,
2145 const Span<int3> corner_tris,
2146 const Span<bool> hide_poly,
2147 const float3 &ray_start,
2148 const float3 &ray_normal,
2149 float *r_depth,
2150 float *dist_sq)
2151{
2152 const Span<int> face_indices = node.faces();
2153
2154 bool hit = false;
2155 if (node_positions.is_empty()) {
2156 for (const int i : face_indices.index_range()) {
2157 const int face_i = face_indices[i];
2158 if (!hide_poly.is_empty() && hide_poly[face_i]) {
2159 continue;
2160 }
2161
2162 for (const int tri_i : bke::mesh::face_triangles_range(faces, face_i)) {
2163 const int3 &corner_tri = corner_tris[tri_i];
2164 hit |= ray_face_nearest_tri(ray_start,
2165 ray_normal,
2166 vert_positions[corner_verts[corner_tri[0]]],
2167 vert_positions[corner_verts[corner_tri[1]]],
2168 vert_positions[corner_verts[corner_tri[2]]],
2169 r_depth,
2170 dist_sq);
2171 }
2172 }
2173 }
2174 else {
2175 const MeshNode::LocalVertMap &vert_map = node.vert_indices_;
2176 for (const int i : face_indices.index_range()) {
2177 const int face_i = face_indices[i];
2178 if (!hide_poly.is_empty() && hide_poly[face_i]) {
2179 continue;
2180 }
2181
2182 for (const int tri_i : bke::mesh::face_triangles_range(faces, face_i)) {
2183 const int3 &corner_tri = corner_tris[tri_i];
2184 hit |= ray_face_nearest_tri(ray_start,
2185 ray_normal,
2186 node_positions[vert_map.index_of(corner_verts[corner_tri[0]])],
2187 node_positions[vert_map.index_of(corner_verts[corner_tri[1]])],
2188 node_positions[vert_map.index_of(corner_verts[corner_tri[2]])],
2189 r_depth,
2190 dist_sq);
2191 }
2192 }
2193 }
2194
2195 return hit;
2196}
2197
2198static bool pbvh_grids_node_nearest_to_ray(const SubdivCCG &subdiv_ccg,
2199 GridsNode &node,
2200 const Span<float3> node_positions,
2201 const float ray_start[3],
2202 const float ray_normal[3],
2203 float *r_depth,
2204 float *dist_sq)
2205{
2206 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
2207 const Span<int> grids = node.grids();
2208 const int grid_size = key.grid_size;
2209 const BitGroupVector<> &grid_hidden = subdiv_ccg.grid_hidden;
2210 const Span<float3> positions = subdiv_ccg.positions;
2211
2212 bool hit = false;
2213 if (node_positions.is_empty()) {
2214 for (const int grid : grids) {
2215 const Span<float3> grid_positions = positions.slice(bke::ccg::grid_range(key, grid));
2216 for (const short y : IndexRange(grid_size - 1)) {
2217 for (const short x : IndexRange(grid_size - 1)) {
2218 if (!grid_hidden.is_empty()) {
2219 if (paint_is_grid_face_hidden(grid_hidden[grid], grid_size, x, y)) {
2220 continue;
2221 }
2222 }
2223 hit |= ray_face_nearest_quad(
2224 ray_start,
2225 ray_normal,
2226 grid_positions[CCG_grid_xy_to_index(grid_size, x, y)],
2227 grid_positions[CCG_grid_xy_to_index(grid_size, x + 1, y)],
2228 grid_positions[CCG_grid_xy_to_index(grid_size, x + 1, y + 1)],
2229 grid_positions[CCG_grid_xy_to_index(grid_size, x, y + 1)],
2230 r_depth,
2231 dist_sq);
2232 }
2233 }
2234 }
2235 }
2236 else {
2237 for (const int i : grids.index_range()) {
2238 const int grid = grids[i];
2239 const Span<float3> grid_positions = node_positions.slice(bke::ccg::grid_range(key, i));
2240 for (const short y : IndexRange(grid_size - 1)) {
2241 for (const short x : IndexRange(grid_size - 1)) {
2242 if (!grid_hidden.is_empty()) {
2243 if (paint_is_grid_face_hidden(grid_hidden[grid], grid_size, x, y)) {
2244 continue;
2245 }
2246 }
2247 hit |= ray_face_nearest_quad(ray_start,
2248 ray_normal,
2249 grid_positions[y * grid_size + x],
2250 grid_positions[y * grid_size + x + 1],
2251 grid_positions[(y + 1) * grid_size + x + 1],
2252 grid_positions[(y + 1) * grid_size + x],
2253 r_depth,
2254 dist_sq);
2255 }
2256 }
2257 }
2258 }
2259
2260 return hit;
2261}
2262
2264 Node &node,
2265 const Span<float3> node_positions,
2266 bool use_origco,
2267 const Span<float3> vert_positions,
2268 const OffsetIndices<int> faces,
2269 const Span<int> corner_verts,
2270 const Span<int3> corner_tris,
2271 const Span<bool> hide_poly,
2272 const SubdivCCG *subdiv_ccg,
2273 const float ray_start[3],
2274 const float ray_normal[3],
2275 float *depth,
2276 float *dist_sq)
2277{
2278 if (node.flag_ & PBVH_FullyHidden) {
2279 return false;
2280 }
2281 switch (pbvh.type()) {
2282 case Type::Mesh:
2283 return pbvh_faces_node_nearest_to_ray(static_cast<MeshNode &>(node),
2284 node_positions,
2285 vert_positions,
2286 faces,
2287 corner_verts,
2288 corner_tris,
2289 hide_poly,
2290 ray_start,
2291 ray_normal,
2292 depth,
2293 dist_sq);
2294 case Type::Grids:
2295 return pbvh_grids_node_nearest_to_ray(*subdiv_ccg,
2296 static_cast<GridsNode &>(node),
2297 node_positions,
2298 ray_start,
2299 ray_normal,
2300 depth,
2301 dist_sq);
2302 case Type::BMesh:
2304 static_cast<BMeshNode &>(node), ray_start, ray_normal, depth, dist_sq, use_origco);
2305 }
2307 return false;
2308}
2309
2315
2316/* Adapted from:
2317 * http://www.gamedev.net/community/forums/topic.asp?topic_id=512123
2318 * Returns true if the AABB is at least partially within the frustum
2319 * (ok, not a real frustum), false otherwise.
2320 */
2322 const PBVHFrustumPlanes *frustum)
2323{
2325 const float(*planes)[4] = frustum->planes;
2326
2327 for (int i = 0; i < frustum->num_planes; i++) {
2328 float vmin[3], vmax[3];
2329
2330 for (int axis = 0; axis < 3; axis++) {
2331 if (planes[i][axis] < 0) {
2332 vmin[axis] = bounds.min[axis];
2333 vmax[axis] = bounds.max[axis];
2334 }
2335 else {
2336 vmin[axis] = bounds.max[axis];
2337 vmax[axis] = bounds.min[axis];
2338 }
2339 }
2340
2341 if (dot_v3v3(planes[i], vmin) + planes[i][3] < 0) {
2342 return ISECT_OUTSIDE;
2343 }
2344 if (dot_v3v3(planes[i], vmax) + planes[i][3] <= 0) {
2346 }
2347 }
2348
2349 return ret;
2350}
2351
2352} // namespace blender::bke::pbvh
2353
2360
2367
2369 void (*draw_fn)(blender::bke::pbvh::Node *node,
2370 void *user_data,
2371 const float bmin[3],
2372 const float bmax[3],
2374 void *user_data)
2375{
2377
2378 std::visit(
2379 [&](auto &nodes) {
2380 for (blender::bke::pbvh::Node &node : nodes) {
2381 if (node.flag_ & PBVH_TexLeaf) {
2383 break;
2384 }
2385 }
2386
2387 for (blender::bke::pbvh::Node &node : nodes) {
2388 if (!(node.flag_ & flag)) {
2389 continue;
2390 }
2391
2392 draw_fn(&node, user_data, node.bounds_.min, node.bounds_.max, node.flag_);
2393 }
2394 },
2395 pbvh.nodes_);
2396}
2397
2399 const blender::Span<blender::float3> vert_positions)
2400{
2401 using namespace blender::bke::pbvh;
2403 update_bounds_mesh(vert_positions, pbvh);
2404 store_bounds_orig(pbvh);
2405}
2406
2407namespace blender::bke::pbvh {
2408
2410{
2411 pbvh.num_planes_ = planes->num_planes;
2412 for (int i = 0; i < pbvh.num_planes_; i++) {
2413 copy_v4_v4(pbvh.planes_[i], planes->planes[i]);
2414 }
2415}
2416
2418{
2419 planes->num_planes = pbvh.num_planes_;
2420 for (int i = 0; i < planes->num_planes; i++) {
2421 copy_v4_v4(planes->planes[i], pbvh.planes_[i]);
2422 }
2423}
2424
2425static Span<float3> vert_positions_eval(const Object &object_orig, const Object &object_eval)
2426{
2427 const SculptSession &ss = *object_orig.sculpt;
2428 const Mesh &mesh_orig = *static_cast<const Mesh *>(object_orig.data);
2429 BLI_assert(bke::object::pbvh_get(object_orig)->type() == Type::Mesh);
2430 if (object_orig.mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
2431 if (const Mesh *mesh_eval = BKE_object_get_evaluated_mesh_no_subsurf(&object_eval)) {
2432 if (mesh_topology_count_matches(*mesh_eval, mesh_orig)) {
2433 return mesh_eval->vert_positions();
2434 }
2435 }
2436 if (!ss.deform_cos.is_empty()) {
2437 BLI_assert(ss.deform_cos.size() == mesh_orig.verts_num);
2438 return ss.deform_cos;
2439 }
2440 if (const Mesh *mesh_eval = BKE_object_get_mesh_deform_eval(&object_eval)) {
2441 return mesh_eval->vert_positions();
2442 }
2443 }
2444
2445 if (!ss.deform_cos.is_empty()) {
2446 BLI_assert(ss.deform_cos.size() == mesh_orig.verts_num);
2447 return ss.deform_cos;
2448 }
2449
2450 return mesh_orig.vert_positions();
2451}
2453{
2454 SculptSession &ss = *object_orig.sculpt;
2455 Mesh &mesh_orig = *static_cast<Mesh *>(object_orig.data);
2456 BLI_assert(bke::object::pbvh_get(object_orig)->type() == Type::Mesh);
2457 if (object_orig.mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
2458 if (const Mesh *mesh_eval = BKE_object_get_evaluated_mesh_no_subsurf(&object_eval)) {
2459 if (mesh_topology_count_matches(*mesh_eval, mesh_orig)) {
2460 Mesh *mesh_eval_mut = const_cast<Mesh *>(mesh_eval);
2461 return mesh_eval_mut->vert_positions_for_write();
2462 }
2463 }
2464 if (!ss.deform_cos.is_empty()) {
2465 BLI_assert(ss.deform_cos.size() == mesh_orig.verts_num);
2466 return ss.deform_cos;
2467 }
2468 if (const Mesh *mesh_eval = BKE_object_get_mesh_deform_eval(&object_eval)) {
2469 Mesh *mesh_eval_mut = const_cast<Mesh *>(mesh_eval);
2470 return mesh_eval_mut->vert_positions_for_write();
2471 }
2472 }
2473
2474 if (!ss.deform_cos.is_empty()) {
2475 BLI_assert(ss.deform_cos.size() == mesh_orig.verts_num);
2476 return ss.deform_cos;
2477 }
2478
2479 return mesh_orig.vert_positions_for_write();
2480}
2481
2482Span<float3> vert_positions_eval(const Depsgraph &depsgraph, const Object &object_orig)
2483{
2484 const Object &object_eval = *DEG_get_evaluated_object(&depsgraph,
2485 &const_cast<Object &>(object_orig));
2486 return vert_positions_eval(object_orig, object_eval);
2487}
2488
2490{
2491 BLI_assert(!DEG_is_original_object(&object_eval));
2492 const Object &object_orig = *DEG_get_original_object(&const_cast<Object &>(object_eval));
2493 return vert_positions_eval(object_orig, object_eval);
2494}
2495
2497{
2498 Object &object_eval = *DEG_get_evaluated_object(&depsgraph, &object_orig);
2499 return vert_positions_eval_for_write(object_orig, object_eval);
2500}
2501
2502Span<float3> vert_normals_eval(const Depsgraph &depsgraph, const Object &object_orig)
2503{
2504 const Object &object_eval = *DEG_get_evaluated_object(&depsgraph,
2505 &const_cast<Object &>(object_orig));
2506 return vert_normals_cache_eval(object_orig, object_eval).data();
2507}
2508
2510{
2511 BLI_assert(!DEG_is_original_object(&object_eval));
2512 Object &object_orig = *DEG_get_original_object(&const_cast<Object &>(object_eval));
2513 return vert_normals_cache_eval(object_orig, object_eval).data();
2514}
2515
2517{
2518 BLI_assert(!DEG_is_original_object(&object_eval));
2519 Object &object_orig = *DEG_get_original_object(&const_cast<Object &>(object_eval));
2520 return face_normals_cache_eval(object_orig, object_eval).data();
2521}
2522
2523} // namespace blender::bke::pbvh
2524
2526{
2527 return node.debug_draw_gen_;
2528}
2529
2531{
2532 using namespace blender;
2533 using namespace blender::bke;
2534 const SculptSession &ss = *object.sculpt;
2535 switch (object::pbvh_get(object)->type()) {
2537 Mesh &mesh = *static_cast<Mesh *>(object.data);
2539 break;
2540 }
2542 BMesh &bm = *ss.bm;
2543 BMIter iter;
2544 BMVert *v;
2545 BMEdge *e;
2546 BMFace *f;
2547
2548 BM_ITER_MESH (f, &iter, &bm, BM_FACES_OF_MESH) {
2550 }
2551
2552 BM_ITER_MESH (e, &iter, &bm, BM_EDGES_OF_MESH) {
2554 }
2555
2556 BM_ITER_MESH (v, &iter, &bm, BM_VERTS_OF_MESH) {
2558 continue;
2559 }
2560 BMIter iter_l;
2561 BMLoop *l;
2562
2563 BM_ITER_ELEM (l, &iter_l, v, BM_LOOPS_OF_VERT) {
2566 }
2567 }
2568 break;
2569 }
2571 Mesh &mesh = *static_cast<Mesh *>(object.data);
2572 const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
2573 const BitGroupVector<> &grid_hidden = subdiv_ccg.grid_hidden;
2574 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
2575 const OffsetIndices faces = mesh.faces();
2576
2577 IndexMaskMemory memory;
2578 const IndexMask hidden_faces =
2579 !grid_hidden.is_empty() ?
2580 IndexMask::from_predicate(faces.index_range(),
2581 GrainSize(1024),
2582 memory,
2583 [&](const int i) {
2584 const IndexRange face = faces[i];
2585 return std::any_of(
2586 face.begin(), face.end(), [&](const int corner) {
2587 return grid_hidden[corner][key.grid_area - 1];
2588 });
2589 }) :
2590 IndexMask();
2591
2592 MutableAttributeAccessor attributes = mesh.attributes_for_write();
2593 if (hidden_faces.is_empty()) {
2594 attributes.remove(".hide_poly");
2595 }
2596 else {
2597 SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_span<bool>(
2598 ".hide_poly", AttrDomain::Face, AttributeInitConstruct());
2599 hide_poly.span.fill(false);
2600 index_mask::masked_fill(hide_poly.span, true, hidden_faces);
2601 hide_poly.finish();
2602 }
2603
2605 break;
2606 }
2607 }
2608}
2609
2610namespace blender::bke::pbvh {
2611
2613{
2614 return std::visit(
2615 [&](const auto &nodes) {
2617 nodes.index_range(), GrainSize(1024), memory, [&](const int i) {
2618 return (nodes[i].flag_ & PBVH_Leaf) != 0;
2619 });
2620 },
2621 pbvh.nodes_);
2622}
2623
2625 const FunctionRef<bool(Node &)> scb,
2626 PBVHNodeFlags leaf_flag)
2627{
2628 if (tree_is_empty(pbvh)) {
2629 return {};
2630 }
2631
2632 PBVHIter iter;
2633 Vector<Node *> nodes;
2634
2635 pbvh_iter_begin(&iter, pbvh, scb);
2636
2637 Node *node;
2638 while ((node = pbvh_iter_next(&iter, leaf_flag))) {
2639 if (node->flag_ & leaf_flag) {
2640 nodes.append(node);
2641 }
2642 }
2643
2644 return nodes;
2645}
2646
2648 IndexMaskMemory &memory,
2649 FunctionRef<bool(const Node &)> filter_fn)
2650{
2652 const_cast<Tree &>(pbvh), [&](Node &node) { return filter_fn(node); }, PBVH_Leaf);
2653 Array<int> indices(nodes.size());
2654 std::visit(
2655 [&](const auto &pbvh_nodes) {
2656 using VectorT = std::decay_t<decltype(pbvh_nodes)>;
2657 for (const int i : nodes.index_range()) {
2658 indices[i] = static_cast<typename VectorT::value_type *>(nodes[i]) - pbvh_nodes.data();
2659 }
2660 },
2661 pbvh.nodes_);
2662 std::sort(indices.begin(), indices.end());
2663 return IndexMask::from_indices(indices.as_span(), memory);
2664}
2665
2666} // namespace blender::bke::pbvh
int CCG_grid_xy_to_index(const int grid_size, const int x, const int y)
Definition BKE_ccg.hh:77
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_evaluated_mesh_no_subsurf(const Object *object_eval)
const Mesh * BKE_object_get_mesh_deform_eval(const Object *object)
bool paint_is_grid_face_hidden(blender::BoundedBitSpan grid_hidden, int gridsize, int x, int y)
Definition paint.cc:1940
void BKE_pbvh_draw_debug_cb(blender::bke::pbvh::Tree &pbvh, void(*draw_fn)(blender::bke::pbvh::Node *node, void *user_data, const float bmin[3], const float bmax[3], PBVHNodeFlags flag), void *user_data)
Definition pbvh.cc:2368
PBVHNodeFlags
Definition BKE_pbvh.hh:29
@ PBVH_RebuildPixels
Definition BKE_pbvh.hh:39
@ PBVH_FullyMasked
Definition BKE_pbvh.hh:35
@ PBVH_TexLeaf
Definition BKE_pbvh.hh:40
@ PBVH_FullyHidden
Definition BKE_pbvh.hh:34
@ PBVH_Leaf
Definition BKE_pbvh.hh:30
@ PBVH_UpdateRedraw
Definition BKE_pbvh.hh:32
@ PBVH_FullyUnmasked
Definition BKE_pbvh.hh:36
A BVH for high poly meshes.
bool BKE_pbvh_node_fully_hidden_get(const blender::bke::pbvh::Node &node)
Definition pbvh.cc:1542
blender::Bounds< blender::float3 > BKE_pbvh_redraw_BB(const blender::bke::pbvh::Tree &pbvh)
Definition pbvh.cc:1439
blender::Bounds< blender::float3 > BKE_pbvh_node_get_original_BB(const blender::bke::pbvh::Node *node)
Definition pbvh.cc:1611
void BKE_pbvh_mark_rebuild_pixels(blender::bke::pbvh::Tree &pbvh)
Definition pbvh.cc:1517
bool BKE_pbvh_node_frustum_exclude_AABB(const blender::bke::pbvh::Node *node, const PBVHFrustumPlanes *frustum)
Definition pbvh.cc:2361
void BKE_pbvh_node_fully_unmasked_set(blender::bke::pbvh::Node &node, int fully_masked)
Definition pbvh.cc:1564
int BKE_pbvh_debug_draw_gen_get(blender::bke::pbvh::Node &node)
Definition pbvh.cc:2525
int BKE_pbvh_get_grid_num_verts(const Object &object)
Definition pbvh.cc:1494
float BKE_pbvh_node_get_tmin(const blender::bke::pbvh::Node *node)
Definition pbvh.cc:766
void BKE_pbvh_node_mark_update(blender::bke::pbvh::Node &node)
Definition pbvh.cc:1512
bool BKE_pbvh_node_frustum_contain_AABB(const blender::bke::pbvh::Node *node, const PBVHFrustumPlanes *frustum)
Definition pbvh.cc:2354
bool BKE_pbvh_node_fully_masked_get(const blender::bke::pbvh::Node &node)
Definition pbvh.cc:1559
void BKE_pbvh_node_fully_hidden_set(blender::bke::pbvh::Node &node, int fully_hidden)
Definition pbvh.cc:1530
int BKE_pbvh_get_grid_num_faces(const Object &object)
Definition pbvh.cc:1502
void BKE_pbvh_node_fully_masked_set(blender::bke::pbvh::Node &node, int fully_masked)
Definition pbvh.cc:1547
bool BKE_pbvh_node_fully_unmasked_get(const blender::bke::pbvh::Node &node)
Definition pbvh.cc:1576
void BKE_pbvh_vert_coords_apply(blender::bke::pbvh::Tree &pbvh, blender::Span< blender::float3 > vert_positions)
Definition pbvh.cc:2398
void BKE_pbvh_sync_visibility_from_verts(Object &object)
Definition pbvh.cc:2530
void BKE_pbvh_node_get_bm_orco_data(const blender::bke::pbvh::BMeshNode &node, blender::Span< blender::float3 > &r_orig_positions, blender::Span< blender::int3 > &r_orig_tris)
Definition pbvh.cc:1617
CCGKey BKE_subdiv_ccg_key_top_level(const SubdivCCG &subdiv_ccg)
void BKE_subdiv_ccg_update_normals(SubdivCCG &subdiv_ccg, const blender::IndexMask &face_mask)
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_NOINLINE
void BLI_kdtree_nd_ free(KDTree *tree)
MINLINE int square_i(int a)
bool isect_ray_aabb_v3(const struct IsectRayAABB_Precalc *data, const float bb_min[3], const float bb_max[3], float *r_tmin)
struct DistRayAABB_Precalc dist_squared_ray_to_aabb_v3_precalc(const float ray_origin[3], const float ray_direction[3])
Definition math_geom.cc:683
float normal_quad_v3(float n[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
Definition math_geom.cc:56
void isect_ray_aabb_v3_precalc(struct IsectRayAABB_Precalc *data, const float ray_origin[3], const float ray_direction[3])
bool isect_ray_tri_watertight_v3(const float ray_origin[3], const struct IsectRayPrecalc *isect_precalc, const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2])
void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
Normal to x,y matrix.
float dist_squared_ray_to_seg_v3(const float ray_origin[3], const float ray_direction[3], const float v0[3], const float v1[3], float r_point[3], float *r_depth)
Definition math_geom.cc:611
float dist_squared_ray_to_aabb_v3(const struct DistRayAABB_Precalc *data, const float bb_min[3], const float bb_max[3], float r_point[3], float *r_depth)
float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3])
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
Definition math_geom.cc:39
void mul_m3_v3(const float M[3][3], float r[3])
MINLINE void copy_v4_v4(float r[4], const float a[4])
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
Definition math_vector.c:36
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
Random number functions.
Platform independent time functions.
#define SCOPED_TIMER_AVERAGED(name)
Definition BLI_timeit.hh:67
#define SET_FLAG_FROM_TEST(value, test, flag)
bool DEG_is_original_object(const Object *object)
Object * DEG_get_original_object(Object *object)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ CD_PROP_FLOAT
@ OB_MODE_WEIGHT_PAINT
@ OB_MODE_VERTEX_PAINT
Object is a sort of wrapper for general info.
static void split(const char *text, const char *seps, char ***str, int *count)
Read Guarded memory(de)allocation.
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
#define BM_ELEM_CD_GET_FLOAT(ele, offset)
@ BM_ELEM_HIDDEN
#define BM_elem_flag_disable(ele, hflag)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_enable(ele, hflag)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_EDGES_OF_MESH
@ BM_VERTS_OF_MESH
@ BM_FACES_OF_MESH
@ BM_LOOPS_OF_VERT
ATTR_WARN_UNUSED_RESULT BMesh * bm
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
void init()
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition btDbvt.cpp:299
AttributeSet attributes
void reinitialize(const int64_t new_size)
Definition BLI_array.hh:388
bool is_empty() const
Definition BLI_array.hh:253
void update(FunctionRef< void(T &data)> compute_cache)
constexpr Span drop_front(int64_t n) const
Definition BLI_span.hh:172
constexpr Span slice(int64_t start, int64_t size) const
Definition BLI_span.hh:138
constexpr const T & first() const
Definition BLI_span.hh:316
constexpr int64_t size() const
Definition BLI_span.hh:253
constexpr IndexRange index_range() const
Definition BLI_span.hh:402
constexpr Span take_front(int64_t n) const
Definition BLI_span.hh:194
constexpr bool is_empty() const
Definition BLI_span.hh:261
int64_t index_of(const Key &key) const
void add_multiple(Span< Key > keys)
int64_t size() const
void append(const T &value)
void resize(const int64_t new_size)
int64_t size() const
void resize(const int64_t new_size_in_bits, const bool value=false)
bool remove(const StringRef attribute_id)
void tag_attribute_changed(const IndexMask &node_mask, StringRef attribute_name)
Definition pbvh.cc:593
void tag_positions_changed(const IndexMask &node_mask)
Definition pbvh.cc:549
Span< NodeT > nodes() const
int nodes_num() const
Definition pbvh.cc:504
void tag_face_sets_changed(const IndexMask &node_mask)
Definition pbvh.cc:579
void tag_masks_changed(const IndexMask &node_mask)
Definition pbvh.cc:586
std::unique_ptr< DrawCache > draw_data
void tag_visibility_changed(const IndexMask &node_mask)
Definition pbvh.cc:562
void tag_topology_changed(const IndexMask &node_mask)
Definition pbvh.cc:572
std::variant< Vector< MeshNode >, Vector< GridsNode >, Vector< BMeshNode > > nodes_
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
static IndexMask from_bits(BitSpan bits, IndexMaskMemory &memory)
static IndexMask from_indices(Span< T > indices, IndexMaskMemory &memory)
void set_bits(MutableBitSpan r_bits, int64_t offset=0) const
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
void foreach_index(Fn &&fn) const
local_group_size(16, 16) .push_constant(Type b
OperationNode * node
const Depsgraph * depsgraph
KDTree_3d * tree
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
static ushort indices[]
static float verts[][3]
IndexRange range
static char faces[256]
IndexRange grid_range(const int grid_area, const int grid)
float3 face_normal_calc(Span< float3 > vert_positions, Span< int > face_verts)
IndexRange face_triangles_range(OffsetIndices< int > faces, int face_i)
Definition BKE_mesh.hh:296
void normals_calc_verts(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, GroupedSpan< int > vert_to_face_map, Span< float3 > face_normals, MutableSpan< float3 > vert_normals)
pbvh::Tree * pbvh_get(Object &object)
Definition paint.cc:2846
static void update_visibility_grids(const SubdivCCG &subdiv_ccg, const MutableSpan< GridsNode > nodes, const IndexMask &node_mask)
Definition pbvh.cc:1344
IndexMask search_nodes(const Tree &pbvh, IndexMaskMemory &memory, FunctionRef< bool(const Node &)> filter_fn)
Definition pbvh.cc:2647
static bool nearest_to_ray_aabb_dist_sq(Node *node, const DistRayAABB_Precalc &dist_ray_to_aabb_precalc, const bool original)
Definition pbvh.cc:2102
static void normals_calc_faces(const Span< float3 > positions, const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< int > face_indices, MutableSpan< float3 > face_normals)
Definition pbvh.cc:884
static const SharedCache< Vector< float3 > > & vert_normals_cache_eval(const Object &object_orig, const Object &object_eval)
Definition pbvh.cc:822
Bounds< float3 > calc_face_bounds(const Span< float3 > vert_positions, const Span< int > face_verts)
Definition pbvh.cc:224
void node_pixels_free(blender::bke::pbvh::Node *node)
void update_mask_bmesh(const BMesh &bm, const IndexMask &node_mask, Tree &pbvh)
Definition pbvh.cc:1294
void update_normals(const Depsgraph &depsgraph, Object &object_orig, Tree &pbvh)
Definition pbvh.cc:1058
static void node_tree_insert(node_tree *tree, node_tree *new_node)
Definition pbvh.cc:714
static BLI_NOINLINE void build_mesh_leaf_nodes(const int verts_num, const OffsetIndices< int > faces, const Span< int > corner_verts, MutableSpan< MeshNode > nodes)
Definition pbvh.cc:87
void update_bounds_grids(const CCGKey &key, Span< float3 > positions, Tree &pbvh)
Definition pbvh.cc:1156
void set_frustum_planes(Tree &pbvh, PBVHFrustumPlanes *planes)
Definition pbvh.cc:2409
static void free_tree(node_tree *tree)
Definition pbvh.cc:749
void update_bounds(const Depsgraph &depsgraph, const Object &object, Tree &pbvh)
Definition pbvh.cc:1183
static Bounds< float3 > calc_face_grid_bounds(const OffsetIndices< int > faces, const Span< float3 > positions, const CCGKey &key, const int face)
Definition pbvh.cc:377
void update_mask_mesh(const Mesh &mesh, const IndexMask &node_mask, Tree &pbvh)
Definition pbvh.cc:1230
Span< float3 > vert_normals_eval_from_eval(const Object &object_eval)
Definition pbvh.cc:2509
static void calc_grids_intersect_data(const float3 &ray_start, const float3 &ray_normal, const int grid, const short x, const short y, const std::array< const float *, 4 > co, float *depth, SubdivCCGCoord &r_active_vertex, int &r_active_grid_index, float3 &r_face_normal)
Definition pbvh.cc:1889
IndexMask all_leaf_nodes(const Tree &pbvh, IndexMaskMemory &memory)
Definition pbvh.cc:2612
static void calc_node_vert_normals(const GroupedSpan< int > vert_to_face_map, const Span< float3 > face_normals, const Span< MeshNode > nodes, const IndexMask &nodes_to_update, MutableSpan< float3 > vert_normals)
Definition pbvh.cc:942
void clip_ray_ortho(Tree &pbvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3])
Definition pbvh.cc:2013
static BoundsMergeInfo merge_child_bounds(MutableSpan< NodeT > nodes, const BitSpan dirty, const int node_index)
Definition pbvh.cc:1113
static bool pbvh_grids_node_nearest_to_ray(const SubdivCCG &subdiv_ccg, GridsNode &node, const Span< float3 > node_positions, const float ray_start[3], const float ray_normal[3], float *r_depth, float *dist_sq)
Definition pbvh.cc:2198
bool node_raycast_mesh(const MeshNode &node, Span< float3 > node_positions, Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, Span< int3 > corner_tris, Span< bool > hide_poly, const float3 &ray_start, const float3 &ray_normal, IsectRayPrecalc *isect_precalc, float *depth, int &r_active_vertex, int &r_active_face_index, float3 &r_face_normal)
Definition pbvh.cc:1807
void update_node_bounds_bmesh(BMeshNode &node)
Definition pbvh.cc:1095
static void calc_boundary_vert_normals(const GroupedSpan< int > vert_to_face_map, const Span< float3 > face_normals, const Span< int > verts, MutableSpan< float3 > vert_normals)
Definition pbvh.cc:932
static void update_visibility_faces(const Mesh &mesh, const MutableSpan< MeshNode > nodes, const IndexMask &node_mask)
Definition pbvh.cc:1319
static void pbvh_iter_begin(PBVHIter *iter, Tree &pbvh, FunctionRef< bool(Node &)> scb)
Definition pbvh.cc:623
static float dist_squared_ray_to_tri_v3_fast(const float3 &ray_origin, const float3 &ray_direction, const float3 &v0, const float3 &v1, const float3 &v2, float3 &r_point, float *r_depth)
Definition pbvh.cc:1699
static bool leaf_needs_material_split(const Span< int > faces, const Span< int > material_indices)
Definition pbvh.cc:140
bool ray_face_nearest_tri(const float3 &ray_start, const float3 &ray_normal, const float3 &t0, const float3 &t1, const float3 &t2, float *r_depth, float *dist_sq)
Definition pbvh.cc:1753
static void normals_calc_verts_simple(const GroupedSpan< int > vert_to_face_map, const Span< float3 > face_normals, const Span< int > verts, MutableSpan< float3 > vert_normals)
Definition pbvh.cc:918
Span< float3 > vert_positions_eval_from_eval(const Object &object_eval)
Definition pbvh.cc:2489
static bool tree_is_empty(const Tree &pbvh)
Definition pbvh.cc:600
void node_update_mask_bmesh(int mask_offset, BMeshNode &node)
Definition pbvh.cc:1277
void node_update_mask_mesh(Span< float > mask, MeshNode &node)
Definition pbvh.cc:1219
void node_update_visibility_grids(const BitGroupVector<> &grid_hidden, GridsNode &node)
Definition pbvh.cc:1334
void update_bounds_mesh(Span< float3 > vert_positions, Tree &pbvh)
Definition pbvh.cc:1143
static bool ray_aabb_intersect(Node &node, const RaycastData &rcd)
Definition pbvh.cc:1634
void bmesh_normals_update(Tree &pbvh, const IndexMask &nodes_to_update)
bool ray_face_nearest_quad(const float3 &ray_start, const float3 &ray_normal, const float3 &t0, const float3 &t1, const float3 &t2, const float3 &t3, float *r_depth, float *dist_sq)
Definition pbvh.cc:1723
static void traverse_tree(node_tree *tree, const FunctionRef< void(Node &node, float *tmin)> hit_fn, float *tmin)
Definition pbvh.cc:734
static void calc_mesh_intersect_data(const Span< int > corner_verts, const Span< int3 > corner_tris, const float3 &ray_start, const float3 &ray_normal, const int face_index, const int tri_index, const std::array< const float *, 3 > co, const float *depth, int &r_active_vertex, int &r_active_face_index, float3 &r_face_normal)
Definition pbvh.cc:1776
static Node & first_node(Tree &pbvh)
Definition pbvh.cc:605
void update_visibility(const Object &object, Tree &pbvh)
Definition pbvh.cc:1377
void node_update_mask_grids(const CCGKey &key, Span< float > masks, GridsNode &node)
Definition pbvh.cc:1247
static int partition_along_axis(const Span< float3 > face_centers, MutableSpan< int > faces, const int axis, const float middle)
Definition pbvh.cc:68
bool node_raycast_grids(const SubdivCCG &subdiv_ccg, GridsNode &node, Span< float3 > node_positions, const float3 &ray_start, const float3 &ray_normal, const IsectRayPrecalc *isect_precalc, float *depth, SubdivCCGCoord &r_active_vertex, int &r_active_grid_index, float3 &r_face_normal)
Definition pbvh.cc:1923
static Node * pbvh_iter_next_occluded(PBVHIter *iter)
Definition pbvh.cc:675
static Bounds< float3 > negative_bounds()
Definition pbvh.cc:58
void update_node_bounds_mesh(Span< float3 > positions, MeshNode &node)
Definition pbvh.cc:1075
void node_update_visibility_bmesh(BMeshNode &node)
Definition pbvh.cc:1358
static SharedCache< Vector< float3 > > & vert_normals_cache_eval_for_write(Object &object_orig, Object &object_eval)
Definition pbvh.cc:846
Bounds< float3 > bounds_get(const Tree &pbvh)
Definition pbvh.cc:1480
void update_normals_from_eval(Object &object_eval, Tree &pbvh)
Definition pbvh.cc:1065
Span< float3 > vert_normals_eval(const Depsgraph &depsgraph, const Object &object_orig)
Definition pbvh.cc:2502
bool bmesh_node_nearest_to_ray(BMeshNode &node, const float3 &ray_start, const float3 &ray_normal, float *r_depth, float *dist_sq, bool use_original)
IndexMask nodes_to_face_selection_grids(const SubdivCCG &subdiv_ccg, Span< GridsNode > nodes, const IndexMask &nodes_mask, IndexMaskMemory &memory)
Definition pbvh.cc:1462
int count_grid_quads(const BitGroupVector<> &grid_visibility, Span< int > grid_indices, int gridsize, int display_gridsize)
Definition pbvh.cc:1403
static SharedCache< Vector< float3 > > & face_normals_cache_eval_for_write(Object &object_orig, Object &object_eval)
Definition pbvh.cc:877
void update_mask_grids(const SubdivCCG &subdiv_ccg, const IndexMask &node_mask, Tree &pbvh)
Definition pbvh.cc:1261
MutableSpan< float3 > vert_positions_eval_for_write(const Depsgraph &depsgraph, Object &object_orig)
Definition pbvh.cc:2496
static bool pbvh_faces_node_nearest_to_ray(const MeshNode &node, const Span< float3 > node_positions, const Span< float3 > vert_positions, const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< int3 > corner_tris, const Span< bool > hide_poly, const float3 &ray_start, const float3 &ray_normal, float *r_depth, float *dist_sq)
Definition pbvh.cc:2140
bool ray_face_intersection_quad(const float3 &ray_start, const IsectRayPrecalc *isect_precalc, const float3 &t0, const float3 &t1, const float3 &t2, const float3 &t3, float *depth)
Definition pbvh.cc:1657
static Bounds< float3 > merge_bounds(const Bounds< float3 > &a, const Bounds< float3 > &b)
Definition pbvh.cc:63
void pixels_free(blender::bke::pbvh::Tree *pbvh)
static PlaneAABBIsect test_frustum_aabb(const Bounds< float3 > &bounds, const PBVHFrustumPlanes *frustum)
Definition pbvh.cc:2321
static const SharedCache< Vector< float3 > > & face_normals_cache_eval(const Object &object_orig, const Object &object_eval)
Definition pbvh.cc:853
static void build_nodes_recursive_grids(const Span< int > material_indices, const int leaf_limit, const int node_index, const std::optional< Bounds< float3 > > &bounds_precalc, const Span< float3 > face_centers, const int depth, MutableSpan< int > faces, Vector< GridsNode > &nodes)
Definition pbvh.cc:304
static Vector< Node * > search_gather(Tree &pbvh, const FunctionRef< bool(Node &)> scb, PBVHNodeFlags leaf_flag)
Definition pbvh.cc:2624
Bounds< float3 > node_bounds(const Node &node)
Definition pbvh.cc:1604
void get_frustum_planes(const Tree &pbvh, PBVHFrustumPlanes *planes)
Definition pbvh.cc:2417
static int partition_material_indices(const Span< int > material_indices, MutableSpan< int > faces)
Definition pbvh.cc:79
Span< float3 > face_normals_eval_from_eval(const Object &object_eval)
Definition pbvh.cc:2516
static void update_visibility_bmesh(const MutableSpan< BMeshNode > nodes, const IndexMask &node_mask)
Definition pbvh.cc:1371
void update_bounds_bmesh(const BMesh &bm, Tree &pbvh)
Definition pbvh.cc:1170
bool ray_face_intersection_tri(const float3 &ray_start, const IsectRayPrecalc *isect_precalc, const float3 &t0, const float3 &t1, const float3 &t2, float *depth)
Definition pbvh.cc:1679
void update_node_bounds_grids(int grid_area, Span< float3 > positions, GridsNode &node)
Definition pbvh.cc:1084
static void update_normals_mesh(Object &object_orig, Object &object_eval, const Span< MeshNode > nodes, const IndexMask &nodes_to_update)
Definition pbvh.cc:953
bool find_nearest_to_ray_node(Tree &pbvh, Node &node, Span< float3 > node_positions, bool use_origco, Span< float3 > vert_positions, const OffsetIndices< int > faces, Span< int > corner_verts, Span< int3 > corner_tris, Span< bool > hide_poly, const SubdivCCG *subdiv_ccg, const float ray_start[3], const float ray_normal[3], float *depth, float *dist_sq)
Definition pbvh.cc:2263
void store_bounds_orig(Tree &pbvh)
Definition pbvh.cc:1206
constexpr int leaf_limit
Definition pbvh_bmesh.cc:62
static bool mesh_topology_count_matches(const Mesh &a, const Mesh &b)
Definition pbvh.cc:816
Span< int > node_face_indices_calc_grids(const SubdivCCG &subdiv_ccg, const GridsNode &node, Vector< int > &faces)
Definition pbvh.cc:1583
Span< float3 > vert_positions_eval(const Depsgraph &depsgraph, const Object &object_orig)
Definition pbvh.cc:2482
static Node * pbvh_iter_next(PBVHIter *iter, PBVHNodeFlags leaf_flag)
Definition pbvh.cc:630
static void search_callback_occluded(Tree &pbvh, const FunctionRef< bool(Node &)> scb, const FunctionRef< void(Node &node, float *tmin)> hit_fn)
Definition pbvh.cc:773
void node_update_visibility_mesh(Span< bool > hide_vert, MeshNode &node)
Definition pbvh.cc:1310
static void build_nodes_recursive_mesh(const Span< int > material_indices, const int leaf_limit, const int node_index, const std::optional< Bounds< float3 > > &bounds_precalc, const Span< float3 > face_centers, const int depth, MutableSpan< int > faces, Vector< MeshNode > &nodes)
Definition pbvh.cc:151
static void calc_boundary_face_normals(const Span< float3 > positions, const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< int > face_indices, MutableSpan< float3 > face_normals)
Definition pbvh.cc:895
void flush_bounds_to_parents(Tree &pbvh)
Definition pbvh.cc:1132
void find_nearest_to_ray(Tree &pbvh, const FunctionRef< void(Node &node, float *tmin)> fn, const float3 &ray_start, const float3 &ray_normal, bool original)
Definition pbvh.cc:2125
static void calc_node_face_normals(const Span< float3 > positions, const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< MeshNode > nodes, const IndexMask &nodes_to_update, MutableSpan< float3 > face_normals)
Definition pbvh.cc:906
void raycast(Tree &pbvh, FunctionRef< void(Node &node, float *tmin)> cb, const float3 &ray_start, const float3 &ray_normal, bool original)
void mesh_hide_vert_flush(Mesh &mesh)
void mesh_hide_face_flush(Mesh &mesh)
Bounds< T > merge(const Bounds< T > &a, const Bounds< T > &b)
Definition BLI_bounds.hh:24
void masked_fill(MutableSpan< T > data, const T &value, const IndexMask &mask)
T midpoint(const T &a, const T &b)
void min_max(const T &value, T &min, T &max)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
int dominant_axis(const VecBase< T, 3 > &a)
void parallel_invoke(Functions &&...functions)
Definition BLI_task.hh:199
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:95
VecBase< float, 3 > float3
static void update(bNodeTree *ntree)
#define STACK_FIXED_DEPTH
Definition pbvh.cc:55
return ret
#define min(a, b)
Definition sort.c:32
#define FLT_MAX
Definition stdcycles.h:14
struct BMEdge * e
struct BMFace * f
CustomData vdata
int grid_size
Definition BKE_ccg.hh:33
int grid_area
Definition BKE_ccg.hh:35
MeshRuntimeHandle * runtime
int verts_num
struct SculptSession * sculpt
blender::SharedCache< blender::Vector< blender::float3 > > face_normals_deform
Definition BKE_paint.hh:422
SubdivCCG * subdiv_ccg
Definition BKE_paint.hh:405
blender::Array< blender::float3, 0 > deform_cos
Definition BKE_paint.hh:413
blender::SharedCache< blender::Vector< blender::float3 > > vert_normals_deform
Definition BKE_paint.hh:421
blender::BitGroupVector grid_hidden
blender::Array< float > masks
blender::OffsetIndices< int > faces
blender::Span< int > grid_to_face_map
blender::Array< blender::float3 > positions
blender::FunctionRef< bool(Node &)> scb
Definition pbvh.cc:618
Stack< StackItem, 100 > stack
Definition pbvh.cc:620
IsectRayAABB_Precalc ray
Definition pbvh.cc:1630
uint8_t flag
Definition wm_window.cc:138