54 std::mutex *mesh_eval_mutex)
56 bool do_lock = r_locked;
60 if (*bvh_cache_p ==
nullptr) {
66 std::lock_guard
lock{*mesh_eval_mutex};
67 if (*bvh_cache_p ==
nullptr) {
79 bool in_cache =
bvhcache_find(bvh_cache_p, type, r_tree,
nullptr,
nullptr);
98 if (bvh_cache ==
nullptr) {
112 BVHCache *cache = MEM_cnew<BVHCache>(__func__);
137 item->
tree =
nullptr;
181#ifdef USE_KDOPBVH_WATERTIGHT
185 ray->origin, ray->direction, v0, v1,
v2, &dist,
nullptr, FLT_EPSILON))
208 return idist * m_dist;
230 const MFace *face = data->face + index;
232 const float *t0, *t1, *t2, *t3;
233 t0 = data->vert_positions[face->v1];
234 t1 = data->vert_positions[face->v2];
235 t2 = data->vert_positions[face->v3];
236 t3 = face->
v4 ? &data->vert_positions[face->v4].x :
nullptr;
239 float nearest_tmp[3], dist_sq;
244 if (dist_sq < nearest->dist_sq) {
245 nearest->index = index;
246 nearest->dist_sq = dist_sq;
264 const int3 &tri = data->corner_tris[index];
265 const float *vtri_co[3] = {
266 data->vert_positions[data->corner_verts[tri[0]]],
267 data->vert_positions[data->corner_verts[tri[1]]],
268 data->vert_positions[data->corner_verts[tri[2]]],
270 float nearest_tmp[3], dist_sq;
275 if (dist_sq < nearest->dist_sq) {
276 nearest->index = index;
277 nearest->dist_sq = dist_sq;
295 const MFace *face = &data->face[index];
297 const float *t0, *t1, *t2, *t3;
298 t0 = data->vert_positions[face->v1];
299 t1 = data->vert_positions[face->v2];
300 t2 = data->vert_positions[face->v3];
301 t3 = face->
v4 ? &data->vert_positions[face->v4].x :
nullptr;
305 if (ray->radius == 0.0f) {
312 if (dist >= 0 && dist < hit->dist) {
334 const int3 &tri = data->corner_tris[index];
335 const float *vtri_co[3] = {
336 positions[data->corner_verts[tri[0]]],
337 positions[data->corner_verts[tri[1]]],
338 positions[data->corner_verts[tri[2]]],
342 if (ray->radius == 0.0f) {
349 if (dist >= 0 && dist < hit->dist) {
372 float nearest_tmp[3], dist_sq;
374 const float *t0, *t1;
375 t0 = positions[edge[0]];
376 t1 = positions[edge[1]];
381 if (dist_sq < nearest->dist_sq) {
382 nearest->index = index;
383 nearest->dist_sq = dist_sq;
424 const float *
v = data->vert_positions[index];
444 const float radius_sq =
square_f(ray->radius);
446 const float *v1, *
v2, *r1;
447 float r2[3], i1[3], i2[3];
448 v1 = positions[edge[0]];
449 v2 = positions[edge[1]];
467 else if (e_fac > 1.0f) {
504 r_data->
edges = edges;
509 switch (bvh_cache_type) {
540 float epsilon,
int tree_type,
int axis,
int elems_num,
int &elems_num_active)
542 if (elems_num_active != -1) {
546 elems_num_active = elems_num;
549 if (elems_num_active == 0) {
566 const BitSpan verts_mask,
567 int verts_num_active)
574 for (
const int i : positions.index_range()) {
575 if (!verts_mask.is_empty() && !verts_mask[i]) {
587 const BitSpan verts_mask,
588 int verts_num_active,
594 epsilon, tree_type, axis, vert_positions, verts_mask, verts_num_active);
614 const BitSpan edges_mask,
615 int edges_num_active,
625 for (
const int i : edges.index_range()) {
626 if (!edges_mask.is_empty() && !edges_mask[i]) {
642 const BitSpan edges_mask,
643 int edges_num_active,
649 vert_positions, edges, edges_mask, edges_num_active, epsilon, tree_type, axis);
674 const BitSpan faces_mask,
675 int faces_num_active)
682 if (!positions.is_empty() && face) {
683 for (
int i = 0; i < faces_num; i++) {
685 if (!faces_mask.is_empty() && !faces_mask[i]) {
716 const BitSpan corner_tris_mask,
717 int corner_tris_num_active)
719 if (positions.is_empty()) {
724 epsilon, tree_type, axis, corner_tris.
size(), corner_tris_num_active);
732 if (!corner_tris_mask.is_empty() && !corner_tris_mask[i]) {
736 copy_v3_v3(co[0], positions[corner_verts[corner_tris[i][0]]]);
737 copy_v3_v3(co[1], positions[corner_verts[corner_tris[i][1]]]);
738 copy_v3_v3(co[2], positions[corner_verts[corner_tris[i][2]]]);
752 const BitSpan corner_tris_mask,
753 int corner_tris_num_active,
765 corner_tris_num_active);
789 int count = mesh.verts_num;
790 BitVector<> verts_mask(
count,
true);
794 const VArray<bool> hide_edge = *attributes.lookup_or_default(
795 ".hide_edge", AttrDomain::Edge,
false);
796 const VArray<bool> hide_vert = *attributes.lookup_or_default(
797 ".hide_vert", AttrDomain::Point,
false);
799 for (
const int i : edges.index_range()) {
803 for (
const int vert : {edges[i][0], edges[i][1]}) {
804 if (verts_mask[vert]) {
805 verts_mask[vert].reset();
812 for (
const int vert : verts_mask.index_range()) {
813 if (verts_mask[vert] && hide_vert[vert]) {
814 verts_mask[vert].reset();
820 *r_elem_active_len =
count;
830 int count = mesh.edges_num;
831 BitVector<> edge_mask(
count,
true);
834 const OffsetIndices faces = mesh.faces();
835 const Span<int> corner_edges = mesh.corner_edges();
836 const VArray<bool> hide_poly = *attributes.lookup_or_default(
837 ".hide_poly", AttrDomain::Face,
false);
838 const VArray<bool> hide_edge = *attributes.lookup_or_default(
839 ".hide_edge", AttrDomain::Edge,
false);
841 for (
const int i : faces.index_range()) {
845 for (
const int edge : corner_edges.
slice(faces[i])) {
846 if (edge_mask[edge]) {
847 edge_mask[edge].reset();
854 for (
const int edge : edge_mask.index_range()) {
855 if (edge_mask[edge] && hide_edge[edge]) {
856 edge_mask[edge].reset();
862 *r_elem_active_len =
count;
869 const int corner_tris_len,
870 int *r_corner_tris_active_len)
875 BitVector<> corner_tris_mask(corner_tris_len);
877 int corner_tris_no_hidden_len = 0;
879 for (
const int64_t i : faces.index_range()) {
882 tri_index += triangles_num;
885 for (
const int i :
IndexRange(triangles_num)) {
887 corner_tris_mask[tri_index].set();
889 corner_tris_no_hidden_len++;
894 *r_corner_tris_active_len = corner_tris_no_hidden_len;
896 return corner_tris_mask;
910 corner_tris = mesh->corner_tris();
915 const Span<int> corner_verts = mesh->corner_verts();
927 bool lock_started =
false;
929 bvh_cache_p, bvh_cache_type, &data->tree, &lock_started, &mesh->runtime->eval_mutex);
940 switch (bvh_cache_type) {
948 int mask_bits_act_len = -1;
951 0.0f, tree_type, 6, positions, mask, mask_bits_act_len);
965 int mask_bits_act_len = -1;
968 positions, edges, mask, mask_bits_act_len, 0.0f, tree_type, 6);
973 positions, edges, {}, -1, 0.0f, tree_type, 6);
977 BLI_assert(!(mesh->totface_legacy == 0 && mesh->faces_num != 0));
984 mesh->totface_legacy,
991 int mask_bits_act_len = -1;
994 *attributes.lookup_or_default(
".hide_poly", AttrDomain::Face,
false),
998 0.0f, tree_type, 6, positions, corner_verts, corner_tris, mask, mask_bits_act_len);
1003 0.0f, tree_type, 6, positions, corner_verts, corner_tris, {}, -1);
1016 data->cached =
true;
1021 if (data->tree !=
nullptr) {
1023 printf(
"tree_type %d obtained instead of %d\n",
1040 if (faces_mask.
size() == mesh.faces_num) {
1048 const Span<int> corner_verts = mesh.corner_verts();
1049 const OffsetIndices faces = mesh.faces();
1050 const Span<int3> corner_tris = mesh.corner_tris();
1062 [&](
const int i) { tris_num += mesh::face_triangles_num(faces[i].
size()); });
1064 int active_num = -1;
1067 if (
tree ==
nullptr) {
1072 const IndexRange triangles_range = mesh::face_triangles_range(faces, face_i);
1073 for (
const int tri_i : triangles_range) {
1075 copy_v3_v3(co[0], positions[corner_verts[corner_tris[tri_i][0]]]);
1076 copy_v3_v3(co[1], positions[corner_verts[corner_tris[tri_i][1]]]);
1077 copy_v3_v3(co[2], positions[corner_verts[corner_tris[tri_i][2]]]);
1093 if (edges_mask.
size() == mesh.edges_num) {
1104 int active_num = -1;
1107 if (
tree ==
nullptr) {
1112 const int2 &edge = edges[edge_i];
1129 if (verts_mask.
size() == mesh.verts_num) {
1139 int active_num = -1;
1142 if (
tree ==
nullptr) {
1147 const float3 &position = positions[vert_i];
1162 if (data->tree && !data->cached) {
1179 int active_num = -1;
1191 r_data.
coords = (
const float(*)[3])positions.data();
1201 memset(data, 0,
sizeof(*data));
@ BVHTREE_FROM_CORNER_TRIS
@ BVHTREE_FROM_CORNER_TRIS_NO_HIDDEN
@ BVHTREE_FROM_LOOSEEDGES
@ BVHTREE_FROM_LOOSEVERTS
@ BVHTREE_FROM_LOOSEEDGES_NO_HIDDEN
@ BVHTREE_FROM_LOOSEVERTS_NO_HIDDEN
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
#define BLI_assert_unreachable()
BVHTree * BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
int BLI_bvhtree_get_tree_type(const BVHTree *tree)
void BLI_bvhtree_balance(BVHTree *tree)
void BLI_bvhtree_free(BVHTree *tree)
void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
int BLI_bvhtree_get_len(const BVHTree *tree)
MINLINE float square_f(float a)
int isect_line_line_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3], float r_i1[3], float r_i2[3])
float closest_to_line_segment_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3])
void closest_on_tri_to_point_v3(float r[3], const float p[3], const float v1[3], const float v2[3], const float v3[3])
bool isect_sweeping_sphere_tri_v3(const float p1[3], const float p2[3], float radius, const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float ipoint[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])
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])
bool isect_ray_tri_epsilon_v3(const float ray_origin[3], const float ray_direction[3], const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2], float epsilon)
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE bool equals_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float dot_v3v3v3(const float p[3], const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
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 void add_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 float normalize_v3(float n[3])
void BLI_task_isolate(void(*func)(void *userdata), void *userdata)
void BLI_mutex_end(ThreadMutex *mutex)
void BLI_mutex_init(ThreadMutex *mutex)
void BLI_mutex_lock(ThreadMutex *mutex)
void BLI_mutex_unlock(ThreadMutex *mutex)
pthread_mutex_t ThreadMutex
#define IN_RANGE_INCL(a, b, c)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
bool bvhcache_has_tree(const BVHCache *bvh_cache, const BVHTree *tree)
static void mesh_faces_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
void free_bvhtree_from_mesh(BVHTreeFromMesh *data)
static BVHTree * bvhtree_from_mesh_faces_create_tree(float epsilon, int tree_type, int axis, const Span< float3 > positions, const MFace *face, const int faces_num, const BitSpan faces_mask, int faces_num_active)
static BVHTree * bvhtree_from_mesh_corner_tris_create_tree(float epsilon, int tree_type, int axis, const Span< float3 > positions, const Span< int > corner_verts, const Span< int3 > corner_tris, const BitSpan corner_tris_mask, int corner_tris_num_active)
BVHCache * bvhcache_init()
static BitVector corner_tris_no_hidden_map_get(const blender::OffsetIndices< int > faces, const VArray< bool > &hide_poly, const int corner_tris_len, int *r_corner_tris_active_len)
void BKE_bvhtree_from_pointcloud_get(const PointCloud &pointcloud, const blender::IndexMask &points_mask, BVHTreeFromPointCloud &r_data)
void free_bvhtree_from_pointcloud(BVHTreeFromPointCloud *data)
static BVHTree * bvhtree_from_mesh_verts_create_tree(float epsilon, int tree_type, int axis, const Span< float3 > positions, const BitSpan verts_mask, int verts_num_active)
static void mesh_corner_tris_nearest_point(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
static void mesh_faces_nearest_point(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
static void bvhtree_balance_isolated(void *userdata)
static void bvhcache_insert(BVHCache *bvh_cache, BVHTree *tree, BVHCacheType type)
static void mesh_verts_spherecast_do(int index, const float v[3], const BVHTreeRay *ray, BVHTreeRayHit *hit)
BVHTree * bvhtree_from_mesh_edges_ex(BVHTreeFromMesh *data, const Span< float3 > vert_positions, const Span< blender::int2 > edges, const BitSpan edges_mask, int edges_num_active, float epsilon, int tree_type, int axis)
static void bvhtree_balance(BVHTree *tree, const bool isolate)
static void mesh_corner_tris_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
static BVHTree * bvhtree_from_mesh_edges_create_tree(const Span< float3 > positions, const blender::Span< blender::int2 > edges, const BitSpan edges_mask, int edges_num_active, float epsilon, int tree_type, int axis)
float bvhtree_ray_tri_intersection(const BVHTreeRay *ray, const float, const float v0[3], const float v1[3], const float v2[3])
static BitVector loose_verts_no_hidden_mask_get(const Mesh &mesh, int *r_elem_active_len)
static void mesh_edges_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
void BKE_bvhtree_from_mesh_verts_init(const Mesh &mesh, const blender::IndexMask &verts_mask, BVHTreeFromMesh &r_data)
static bool bvhcache_find(BVHCache **bvh_cache_p, BVHCacheType type, BVHTree **r_tree, bool *r_locked, std::mutex *mesh_eval_mutex)
static BitVector loose_edges_no_hidden_mask_get(const Mesh &mesh, int *r_elem_active_len)
BVHTree * BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data, const Mesh *mesh, const BVHCacheType bvh_cache_type, const int tree_type)
static BVHTree * bvhtree_new_common(float epsilon, int tree_type, int axis, int elems_num, int &elems_num_active)
BVHTree * bvhtree_from_mesh_verts_ex(BVHTreeFromMesh *data, const Span< float3 > vert_positions, const BitSpan verts_mask, int verts_num_active, float epsilon, int tree_type, int axis)
static void bvhcache_unlock(BVHCache *bvh_cache, bool lock_started)
BVHTree * bvhtree_from_mesh_corner_tris_ex(BVHTreeFromMesh *data, const Span< float3 > vert_positions, const Span< int > corner_verts, const Span< int3 > corner_tris, const BitSpan corner_tris_mask, int corner_tris_num_active, float epsilon, int tree_type, int axis)
static void mesh_edges_nearest_point(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
void BKE_bvhtree_from_mesh_edges_init(const Mesh &mesh, const blender::IndexMask &edges_mask, BVHTreeFromMesh &r_data)
static void bvhtree_from_mesh_setup_data(BVHTree *tree, const BVHCacheType bvh_cache_type, const Span< float3 > positions, const Span< blender::int2 > edges, const Span< int > corner_verts, const Span< int3 > corner_tris, const MFace *face, BVHTreeFromMesh *r_data)
void bvhcache_free(BVHCache *bvh_cache)
static void mesh_verts_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
void BKE_bvhtree_from_mesh_tris_init(const Mesh &mesh, const blender::IndexMask &faces_mask, BVHTreeFromMesh &r_data)
float bvhtree_sphereray_tri_intersection(const BVHTreeRay *ray, float radius, const float m_dist, const float v0[3], const float v1[3], const float v2[3])
constexpr Span slice(int64_t start, int64_t size) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
T get_internal_single() const
void foreach_index(Fn &&fn) const
draw_view in_light_buf[] float
void MEM_freeN(void *vmemh)
int face_triangles_num(const int face_size)
BVHCacheItem items[BVHTREE_MAX_ITEM]
blender::Span< blender::int3 > corner_tris
BVHTree_RayCastCallback raycast_callback
blender::Span< blender::float3 > vert_positions
blender::Span< blender::int2 > edges
blender::Span< int > corner_verts
BVHTree_NearestPointCallback nearest_callback
BVHTree_NearestPointCallback nearest_callback
blender::BitVector is_loose_bits