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