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