22# pragma optimize("t", on)
61 const int3 &tri = data->corner_tris[index];
62 const float *vtri_co[3] = {
63 positions[data->corner_verts[tri[0]]],
64 positions[data->corner_verts[tri[1]]],
65 positions[data->corner_verts[tri[2]]],
69 if (dist >= 0 && dist < hit->dist) {
82 const Mesh *mesh_eval,
96 float local_scale, local_depth, len_diff = 0.0f;
104 local_depth = depth_max;
106 local_depth *= local_scale;
110 if (std::optional<
Bounds<float3>> bounds = mesh_eval->bounds_min_max()) {
113 ray_start_local, ray_normal_local, bounds->min, bounds->max, &len_diff,
nullptr))
122 if (len_diff > 400.0f) {
124 len_diff -= local_scale;
125 madd_v3_v3fl(ray_start_local, ray_normal_local, len_diff);
126 local_depth -= len_diff;
137 if (treedata.
tree ==
nullptr) {
148 data.len_diff = len_diff;
149 data.local_scale = local_scale;
150 data.ob_uuid = ob_index;
153 void *hit_last_prev = data.hit_list->
last;
155 treedata.
tree, ray_start_local, ray_normal_local, 0.0f, depth_max,
raycast_all_cb, &data);
157 retval = hit_last_prev != data.hit_list->last;
162 hit.dist = local_depth;
174 hit.dist += len_diff;
175 hit.dist /= local_scale;
176 if (hit.dist <= depth_max) {
177 hit.index = tri_faces[hit.index];
195 const Mesh *mesh_eval,
201 if (treedata.
tree ==
nullptr) {
234 this->vert_positions = mesh_eval->vert_positions().data();
235 this->vert_normals = mesh_eval->vert_normals().data();
236 this->edges = mesh_eval->edges().data();
237 this->corner_verts = mesh_eval->corner_verts().data();
238 this->corner_edges = mesh_eval->corner_edges().data();
239 this->corner_tris = mesh_eval->corner_tris().data();
244 *r_co = this->vert_positions[index];
250 r_v_index[0] = edge[0];
251 r_v_index[1] = edge[1];
263 const float (*clip_plane)[4],
264 const int clip_plane_len,
272 for (
int i = 2; i--;) {
273 if (vindex[i] == nearest->index) {
276 cb_snap_vert(userdata, vindex[i], precalc, clip_plane, clip_plane_len, nearest);
283 const float (*clip_plane)[4],
284 const int clip_plane_len,
291 const int3 &tri = data->corner_tris[index];
292 vindex[0] = corner_verts[tri[0]];
293 vindex[1] = corner_verts[tri[1]];
294 vindex[2] = corner_verts[tri[2]];
296 if (data->use_backface_culling) {
297 const float3 *vert_positions = data->vert_positions;
298 const float3 &t0 = vert_positions[vindex[0]];
299 const float3 &t1 = vert_positions[vindex[1]];
300 const float3 &t2 = vert_positions[vindex[2]];
307 for (
int i = 3; i--;) {
308 if (vindex[i] == nearest->index) {
311 cb_snap_vert(userdata, vindex[i], precalc, clip_plane, clip_plane_len, nearest);
318 const float (*clip_plane)[4],
319 const int clip_plane_len,
324 const int3 &tri = data->corner_tris[index];
326 if (data->use_backface_culling) {
327 const float3 *vert_positions = data->vert_positions;
328 const float3 &t0 = vert_positions[corner_verts[tri[0]]];
329 const float3 &t1 = vert_positions[corner_verts[tri[1]]];
330 const float3 &t2 = vert_positions[corner_verts[tri[2]]];
337 const int2 *edges = data->edges;
338 const int *corner_edges = data->corner_edges;
339 for (
int j = 2, j_next = 0; j_next < 3; j = j_next++) {
340 int eindex = corner_edges[tri[j]];
341 const int2 &edge = edges[eindex];
342 const int2 tri_edge = {corner_verts[tri[j]], corner_verts[tri[j_next]]};
343 if (
ELEM(edge[0], tri_edge[0], tri_edge[1]) &&
ELEM(edge[1], tri_edge[0], tri_edge[1])) {
344 if (eindex == nearest->index) {
347 cb_snap_edge(userdata, eindex, precalc, clip_plane, clip_plane_len, nearest);
367 const Mesh *mesh_eval =
reinterpret_cast<const Mesh *
>(id);
386 const int *face_edges = &nearest2d.
corner_edges[face.start()];
387 for (
int i = face.size(); i--;) {
391 reinterpret_cast<float(*)[4]
>(nearest2d.
clip_planes.data()),
398 const int *face_verts = &nearest2d.
corner_verts[face.start()];
399 for (
int i = face.size(); i--;) {
403 reinterpret_cast<float(*)[4]
>(nearest2d.
clip_planes.data()),
409 if (nearest.index != -1) {
422 float dist_px_sq_orig,
440 if (mesh->faces_num) {
443 else if (mesh->edges_num) {
447 return snap_mode_supported;
452 const Mesh *mesh_eval,
464 if (std::optional<
Bounds<float3>> bounds = mesh_eval->bounds_min_max()) {
479 BVHTree *bvhtree[2] = {
nullptr};
505 int last_index = nearest.index;
515 reinterpret_cast<float(*)[4]
>(nearest2d.
clip_planes.data()),
521 if (nearest.index != -1) {
522 last_index = nearest.index;
535 reinterpret_cast<float(*)[4]
>(nearest2d.
clip_planes.data()),
549 reinterpret_cast<float(*)[4]
>(nearest2d.
clip_planes.data()),
556 if (last_index != nearest.index) {
569 reinterpret_cast<float(*)[4]
>(nearest2d.
clip_planes.data()),
583 reinterpret_cast<float(*)[4]
>(nearest2d.
clip_planes.data()),
590 if (last_index != nearest.index) {
595 if (nearest.index != -1) {
615 const Mesh *mesh_eval =
reinterpret_cast<const Mesh *
>(id);
618 elem =
snapMesh(sctx, ob_eval, mesh_eval, obmat, skip_hidden, is_editmesh, snap_to_flag);
BVHTree * BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data, const Mesh *mesh, BVHCacheType bvh_cache_type, int tree_type)
@ 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
float bvhtree_ray_tri_intersection(const BVHTreeRay *ray, float m_dist, const float v0[3], const float v1[3], const float v2[3])
#define BVH_RAYCAST_DIST_MAX
int BLI_bvhtree_find_nearest_projected(const BVHTree *tree, float projmat[4][4], float winsize[2], float mval[2], float(*clip_planes)[4], int clip_plane_len, BVHTreeNearest *nearest, BVHTree_NearestProjectedCallback callback, void *userdata)
void BLI_bvhtree_ray_cast_all(const BVHTree *tree, const float co[3], const float dir[3], float radius, float hit_dist, BVHTree_RayCastCallback callback, void *userdata)
int BLI_bvhtree_ray_cast(const BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
bool isect_ray_aabb_v3_simple(const float orig[3], const float dir[3], const float bb_min[3], const float bb_max[3], float *tmin, float *tmax)
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
@ SCE_SNAP_INDIVIDUAL_NEAREST
@ SCE_SNAP_TO_EDGE_ENDPOINT
@ SCE_SNAP_TO_EDGE_MIDPOINT
@ SCE_SNAP_TO_EDGE_PERPENDICULAR
#define XRAY_FLAG_ENABLED(v3d)
const float3 * vert_positions
void get_vert_co(const int index, const float **r_co) override
void get_edge_verts_index(const int index, int r_v_index[2]) override
void copy_vert_no(const int index, float r_no[3]) override
const float3 * vert_normals
SnapData_Mesh(SnapObjectContext *sctx, const Mesh *mesh_eval, const float4x4 &obmat)
blender::Vector< blender::float4, MAX_CLIPPLANE_LEN+1 > clip_planes
void clip_planes_enable(SnapObjectContext *sctx, const Object *ob_eval, bool skip_occlusion_plane=false)
blender::float4x4 pmat_local
bool use_backface_culling
static void register_result_raycast(SnapObjectContext *sctx, const Object *ob_eval, const ID *id_eval, const blender::float4x4 &obmat, const BVHTreeRayHit *hit, const bool is_in_front)
static void register_result(SnapObjectContext *sctx, const Object *ob_eval, const ID *id_eval, const blender::float4x4 &obmat, BVHTreeNearest *r_nearest)
DistProjectedAABBPrecalc nearest_precalc
BVHTreeNearest nearest_point
eSnapMode snap_edge_points_impl(SnapObjectContext *sctx, int edge_index, float dist_px_sq_orig)
bool snap_boundbox(const blender::float3 &min, const blender::float3 &max)
QuaternionBase< T > normalize_and_get_length(const QuaternionBase< T > &q, T &out_length)
CartesianBasis invert(const CartesianBasis &basis)
VecBase< T, 3 > transform_direction(const MatBase< T, 3, 3 > &mat, const VecBase< T, 3 > &direction)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
BVHTree_RayCastCallback raycast_callback
BVHTree_NearestPointCallback nearest_callback
blender::float3 ray_start
struct SnapObjectContext::@590 ret
struct SnapObjectContext::@589 runtime
float ray_depth_max_in_front
bool use_backface_culling
eSnapOcclusionTest occlusion_test
const c_style_mat & ptr() const