Snap: Refactor Face Nearest approach
- Use C++ types for matrices and vectors; - Deduplicate code with `SnapData::register_result`; This commit also improves the way of detecting supported snap types.
This commit is contained in:
@@ -272,29 +272,38 @@ eSnapMode SnapData::snap_edge_points_impl(SnapObjectContext *sctx,
|
||||
return elem;
|
||||
}
|
||||
|
||||
void SnapData::register_result(SnapObjectContext *sctx, Object *ob_eval, const ID *id_eval)
|
||||
void SnapData::register_result(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
const ID *id_eval,
|
||||
const float4x4 &obmat,
|
||||
BVHTreeNearest *r_nearest)
|
||||
{
|
||||
BLI_assert(this->nearest_point.index != -2);
|
||||
BLI_assert(r_nearest->index != -2);
|
||||
|
||||
copy_v3_v3(sctx->ret.loc, this->nearest_point.co);
|
||||
copy_v3_v3(sctx->ret.no, this->nearest_point.no);
|
||||
sctx->ret.index = this->nearest_point.index;
|
||||
copy_m4_m4(sctx->ret.obmat, this->obmat_.ptr());
|
||||
copy_v3_v3(sctx->ret.loc, r_nearest->co);
|
||||
copy_v3_v3(sctx->ret.no, r_nearest->no);
|
||||
sctx->ret.index = r_nearest->index;
|
||||
copy_m4_m4(sctx->ret.obmat, obmat.ptr());
|
||||
sctx->ret.ob = ob_eval;
|
||||
sctx->ret.data = id_eval;
|
||||
sctx->ret.dist_px_sq = this->nearest_point.dist_sq;
|
||||
sctx->ret.dist_px_sq = r_nearest->dist_sq;
|
||||
|
||||
/* Global space. */
|
||||
mul_m4_v3(this->obmat_.ptr(), sctx->ret.loc);
|
||||
mul_mat3_m4_v3(this->obmat_.ptr(), sctx->ret.no);
|
||||
mul_m4_v3(obmat.ptr(), sctx->ret.loc);
|
||||
mul_mat3_m4_v3(obmat.ptr(), sctx->ret.no);
|
||||
normalize_v3(sctx->ret.no);
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Make sure this is only called once. */
|
||||
this->nearest_point.index = -2;
|
||||
r_nearest->index = -2;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SnapData::register_result(SnapObjectContext *sctx, Object *ob_eval, const ID *id_eval)
|
||||
{
|
||||
this->register_result(sctx, ob_eval, id_eval, this->obmat_, &this->nearest_point);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Utilities
|
||||
* \{ */
|
||||
@@ -605,89 +614,57 @@ static bool raycastObjects(SnapObjectContext *sctx)
|
||||
static void nearest_world_tree_co(BVHTree *tree,
|
||||
BVHTree_NearestPointCallback nearest_cb,
|
||||
void *treedata,
|
||||
float co[3],
|
||||
float r_co[3],
|
||||
float r_no[3],
|
||||
int *r_index,
|
||||
float *r_dist_sq)
|
||||
const float3 &co,
|
||||
BVHTreeNearest *r_nearest)
|
||||
{
|
||||
BVHTreeNearest nearest = {};
|
||||
nearest.index = -1;
|
||||
copy_v3_fl(nearest.co, FLT_MAX);
|
||||
nearest.dist_sq = FLT_MAX;
|
||||
r_nearest->index = -1;
|
||||
copy_v3_fl(r_nearest->co, FLT_MAX);
|
||||
r_nearest->dist_sq = FLT_MAX;
|
||||
|
||||
BLI_bvhtree_find_nearest(tree, co, &nearest, nearest_cb, treedata);
|
||||
BLI_bvhtree_find_nearest(tree, co, r_nearest, nearest_cb, treedata);
|
||||
|
||||
if (r_co) {
|
||||
copy_v3_v3(r_co, nearest.co);
|
||||
}
|
||||
if (r_no) {
|
||||
copy_v3_v3(r_no, nearest.no);
|
||||
}
|
||||
if (r_index) {
|
||||
*r_index = nearest.index;
|
||||
}
|
||||
if (r_dist_sq) {
|
||||
float diff[3];
|
||||
sub_v3_v3v3(diff, co, nearest.co);
|
||||
*r_dist_sq = len_squared_v3(diff);
|
||||
}
|
||||
float diff[3];
|
||||
sub_v3_v3v3(diff, co, r_nearest->co);
|
||||
r_nearest->dist_sq = len_squared_v3(diff);
|
||||
}
|
||||
|
||||
bool nearest_world_tree(SnapObjectContext *sctx,
|
||||
BVHTree *tree,
|
||||
BVHTree_NearestPointCallback nearest_cb,
|
||||
const float3 &init_co,
|
||||
const float3 &curr_co,
|
||||
void *treedata,
|
||||
const float (*obmat)[4])
|
||||
BVHTreeNearest *r_nearest)
|
||||
{
|
||||
float imat[4][4];
|
||||
invert_m4_m4(imat, obmat);
|
||||
|
||||
/* compute offset between init co and prev co in local space */
|
||||
float init_co_local[3], curr_co_local[3];
|
||||
float delta_local[3];
|
||||
mul_v3_m4v3(init_co_local, imat, sctx->runtime.init_co);
|
||||
mul_v3_m4v3(curr_co_local, imat, sctx->runtime.curr_co);
|
||||
sub_v3_v3v3(delta_local, curr_co_local, init_co_local);
|
||||
|
||||
float dist_sq;
|
||||
BVHTreeNearest nearest{};
|
||||
if (sctx->runtime.params.keep_on_same_target) {
|
||||
nearest_world_tree_co(
|
||||
tree, nearest_cb, treedata, init_co_local, nullptr, nullptr, nullptr, &dist_sq);
|
||||
nearest_world_tree_co(tree, nearest_cb, treedata, init_co, &nearest);
|
||||
}
|
||||
else {
|
||||
/* NOTE: when `params->face_nearest_steps == 1`, the return variables of function below contain
|
||||
* the answer. We could return immediately after updating r_loc, r_no, r_index, but that would
|
||||
* also complicate the code. Foregoing slight optimization for code clarity. */
|
||||
nearest_world_tree_co(
|
||||
tree, nearest_cb, treedata, curr_co_local, nullptr, nullptr, nullptr, &dist_sq);
|
||||
nearest_world_tree_co(tree, nearest_cb, treedata, curr_co, &nearest);
|
||||
}
|
||||
if (sctx->ret.dist_px_sq <= dist_sq) {
|
||||
|
||||
if (r_nearest->dist_sq <= nearest.dist_sq) {
|
||||
return false;
|
||||
}
|
||||
sctx->ret.dist_px_sq = dist_sq;
|
||||
|
||||
/* scale to make `snap_face_nearest_steps` steps */
|
||||
/* Scale to make `snap_face_nearest_steps` steps. */
|
||||
float step_scale_factor = 1.0f / max_ff(1.0f, float(sctx->runtime.params.face_nearest_steps));
|
||||
mul_v3_fl(delta_local, step_scale_factor);
|
||||
|
||||
float co_local[3];
|
||||
float no_local[3];
|
||||
|
||||
copy_v3_v3(co_local, init_co_local);
|
||||
/* Compute offset between init co and prev co. */
|
||||
float3 delta = (curr_co - init_co) * step_scale_factor;
|
||||
|
||||
float3 co = init_co;
|
||||
for (int i = 0; i < sctx->runtime.params.face_nearest_steps; i++) {
|
||||
add_v3_v3(co_local, delta_local);
|
||||
nearest_world_tree_co(
|
||||
tree, nearest_cb, treedata, co_local, co_local, no_local, &sctx->ret.index, nullptr);
|
||||
co += delta;
|
||||
nearest_world_tree_co(tree, nearest_cb, treedata, co, &nearest);
|
||||
co = nearest.co;
|
||||
}
|
||||
|
||||
mul_v3_m4v3(sctx->ret.loc, obmat, co_local);
|
||||
|
||||
copy_v3_v3(sctx->ret.no, no_local);
|
||||
mul_mat3_m4_v3(obmat, sctx->ret.no);
|
||||
normalize_v3(sctx->ret.no);
|
||||
|
||||
*r_nearest = nearest;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -864,7 +841,7 @@ eSnapMode snap_object_center(SnapObjectContext *sctx,
|
||||
|
||||
if (nearest2d.snap_point(float3(0.0f))) {
|
||||
nearest2d.register_result(sctx, ob_eval, static_cast<const ID *>(ob_eval->data));
|
||||
return SCE_SNAP_TO_VERTEX;
|
||||
return SCE_SNAP_TO_POINT;
|
||||
}
|
||||
|
||||
return SCE_SNAP_TO_NONE;
|
||||
|
||||
@@ -119,6 +119,11 @@ class SnapData {
|
||||
bool snap_point(const blender::float3 &co, int index = -1);
|
||||
bool snap_edge(const blender::float3 &va, const blender::float3 &vb, int edge_index = -1);
|
||||
eSnapMode snap_edge_points_impl(SnapObjectContext *sctx, int edge_index, float dist_px_sq_orig);
|
||||
static void register_result(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
const ID *id_eval,
|
||||
const blender::float4x4 &obmat,
|
||||
BVHTreeNearest *r_nearest);
|
||||
void register_result(SnapObjectContext *sctx, Object *ob_eval, const ID *id_eval);
|
||||
|
||||
virtual void get_vert_co(const int /*index*/, const float ** /*r_co*/){};
|
||||
@@ -152,8 +157,10 @@ void cb_snap_edge(void *userdata,
|
||||
bool nearest_world_tree(SnapObjectContext *sctx,
|
||||
BVHTree *tree,
|
||||
BVHTree_NearestPointCallback nearest_cb,
|
||||
const blender::float3 &init_co,
|
||||
const blender::float3 &curr_co,
|
||||
void *treedata,
|
||||
const float (*obmat)[4]);
|
||||
BVHTreeNearest *r_nearest);
|
||||
|
||||
eSnapMode snap_object_center(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
|
||||
@@ -108,7 +108,7 @@ eSnapMode snapCurve(SnapObjectContext *sctx, Object *ob_eval, const float obmat[
|
||||
}
|
||||
if (has_snap) {
|
||||
nearest2d.register_result(sctx, ob_eval, &cu->id);
|
||||
return SCE_SNAP_TO_VERTEX;
|
||||
return SCE_SNAP_TO_POINT;
|
||||
}
|
||||
return SCE_SNAP_TO_NONE;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
#include "BLI_math_matrix.hh"
|
||||
|
||||
#include "BKE_bvhutils.h"
|
||||
#include "BKE_editmesh.h"
|
||||
@@ -196,18 +196,18 @@ static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapCache_Edi
|
||||
/** \name Snap Object Data
|
||||
* \{ */
|
||||
|
||||
static eSnapMode editmesh_snap_mode_supported(BMEditMesh *em)
|
||||
static eSnapMode editmesh_snap_mode_supported(BMesh *bm)
|
||||
{
|
||||
eSnapMode snap_mode_supported = SCE_SNAP_TO_NONE;
|
||||
if (em->bm->totface) {
|
||||
snap_mode_supported |= SCE_SNAP_TO_FACE | SCE_SNAP_INDIVIDUAL_NEAREST;
|
||||
if (bm->totface) {
|
||||
snap_mode_supported |= SCE_SNAP_TO_FACE | SCE_SNAP_INDIVIDUAL_NEAREST | SNAP_TO_EDGE_ELEMENTS |
|
||||
SCE_SNAP_TO_POINT;
|
||||
}
|
||||
if (em->bm->totedge) {
|
||||
snap_mode_supported |= SCE_SNAP_TO_EDGE | SCE_SNAP_TO_EDGE_MIDPOINT |
|
||||
SCE_SNAP_TO_EDGE_PERPENDICULAR;
|
||||
else if (bm->totedge) {
|
||||
snap_mode_supported |= SNAP_TO_EDGE_ELEMENTS | SCE_SNAP_TO_POINT;
|
||||
}
|
||||
if (em->bm->totvert) {
|
||||
snap_mode_supported |= SCE_SNAP_TO_VERTEX;
|
||||
else if (bm->totvert) {
|
||||
snap_mode_supported |= SCE_SNAP_TO_POINT;
|
||||
}
|
||||
return snap_mode_supported;
|
||||
}
|
||||
@@ -226,7 +226,7 @@ static SnapCache_EditMesh *editmesh_snapdata_init(SnapObjectContext *sctx,
|
||||
return em_cache;
|
||||
}
|
||||
|
||||
eSnapMode snap_mode_used = snap_to_flag & editmesh_snap_mode_supported(em);
|
||||
eSnapMode snap_mode_used = snap_to_flag & editmesh_snap_mode_supported(em->bm);
|
||||
if (snap_mode_used == SCE_SNAP_TO_NONE) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -389,15 +389,27 @@ static bool raycastEditMesh(SnapCache_EditMesh *em_cache,
|
||||
|
||||
static bool nearest_world_editmesh(SnapCache_EditMesh *em_cache,
|
||||
SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
BMEditMesh *em,
|
||||
const float (*obmat)[4])
|
||||
const float4x4 &obmat)
|
||||
{
|
||||
BVHTreeFromEditMesh *treedata = snap_object_data_editmesh_treedata_get(em_cache, sctx, em);
|
||||
if (treedata == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return nearest_world_tree(sctx, treedata->tree, treedata->nearest_callback, treedata, obmat);
|
||||
float3 init_co = math::transform_point(obmat, float3(sctx->runtime.init_co));
|
||||
float3 curr_co = math::transform_point(obmat, float3(sctx->runtime.curr_co));
|
||||
|
||||
BVHTreeNearest nearest{};
|
||||
nearest.dist_sq = sctx->ret.dist_px_sq;
|
||||
if (nearest_world_tree(
|
||||
sctx, treedata->tree, treedata->nearest_callback, init_co, curr_co, treedata, &nearest))
|
||||
{
|
||||
SnapData::register_result(sctx, ob_eval, nullptr, obmat, &nearest);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -664,9 +676,9 @@ eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
|
||||
|
||||
BMEditMesh *em = em_cache->treedata_editmesh.em;
|
||||
|
||||
eSnapMode snap_mode_used = snap_to_flag & editmesh_snap_mode_supported(em);
|
||||
eSnapMode snap_mode_used = snap_to_flag & editmesh_snap_mode_supported(em->bm);
|
||||
if (snap_mode_used & (SNAP_TO_EDGE_ELEMENTS | SCE_SNAP_TO_POINT)) {
|
||||
elem = snapEditMesh(em_cache, sctx, ob_eval, em, obmat, snap_to_flag);
|
||||
elem = snapEditMesh(em_cache, sctx, ob_eval, em, obmat, snap_mode_used);
|
||||
if (elem) {
|
||||
return elem;
|
||||
}
|
||||
@@ -679,7 +691,7 @@ eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
if (snap_mode_used & SCE_SNAP_INDIVIDUAL_NEAREST) {
|
||||
if (nearest_world_editmesh(em_cache, sctx, em, obmat)) {
|
||||
if (nearest_world_editmesh(em_cache, sctx, ob_eval, em, float4x4(obmat))) {
|
||||
return SCE_SNAP_INDIVIDUAL_NEAREST;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
#include "BLI_math_matrix.hh"
|
||||
|
||||
#include "BKE_bvhutils.h"
|
||||
#include "BKE_editmesh.h"
|
||||
@@ -220,8 +220,9 @@ static bool raycastMesh(SnapObjectContext *sctx,
|
||||
* \{ */
|
||||
|
||||
static bool nearest_world_mesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
const Mesh *me_eval,
|
||||
const float (*obmat)[4],
|
||||
const float4x4 obmat,
|
||||
bool use_hide)
|
||||
{
|
||||
BVHTreeFromMesh treedata;
|
||||
@@ -230,7 +231,18 @@ static bool nearest_world_mesh(SnapObjectContext *sctx,
|
||||
return false;
|
||||
}
|
||||
|
||||
return nearest_world_tree(sctx, treedata.tree, treedata.nearest_callback, &treedata, obmat);
|
||||
float3 init_co = math::transform_point(obmat, float3(sctx->runtime.init_co));
|
||||
float3 curr_co = math::transform_point(obmat, float3(sctx->runtime.curr_co));
|
||||
|
||||
BVHTreeNearest nearest{};
|
||||
nearest.dist_sq = sctx->ret.dist_px_sq;
|
||||
if (nearest_world_tree(
|
||||
sctx, treedata.tree, treedata.nearest_callback, init_co, curr_co, &treedata, &nearest))
|
||||
{
|
||||
SnapData::register_result(sctx, ob_eval, &me_eval->id, obmat, &nearest);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -467,20 +479,27 @@ eSnapMode snap_edge_points_mesh(SnapObjectContext *sctx,
|
||||
return elem;
|
||||
}
|
||||
|
||||
static eSnapMode mesh_snap_mode_supported(const Mesh *mesh)
|
||||
{
|
||||
eSnapMode snap_mode_supported = mesh->loose_verts().count ? SCE_SNAP_TO_POINT : SCE_SNAP_TO_NONE;
|
||||
if (mesh->totpoly) {
|
||||
snap_mode_supported |= SCE_SNAP_TO_FACE | SCE_SNAP_INDIVIDUAL_NEAREST | SNAP_TO_EDGE_ELEMENTS;
|
||||
}
|
||||
else if (mesh->totedge) {
|
||||
snap_mode_supported |= SNAP_TO_EDGE_ELEMENTS;
|
||||
}
|
||||
|
||||
return snap_mode_supported;
|
||||
}
|
||||
|
||||
static eSnapMode snapMesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
const Mesh *me_eval,
|
||||
const float obmat[4][4],
|
||||
bool use_hide)
|
||||
bool use_hide,
|
||||
eSnapMode snap_to)
|
||||
{
|
||||
BLI_assert(sctx->runtime.snap_to_flag != SCE_SNAP_TO_FACE);
|
||||
if (me_eval->totvert == 0) {
|
||||
return SCE_SNAP_TO_NONE;
|
||||
}
|
||||
if (me_eval->totedge == 0 && !(sctx->runtime.snap_to_flag & SCE_SNAP_TO_POINT)) {
|
||||
return SCE_SNAP_TO_NONE;
|
||||
}
|
||||
|
||||
BLI_assert(snap_to != SCE_SNAP_TO_FACE);
|
||||
SnapData_Mesh nearest2d(sctx, me_eval, float4x4(obmat));
|
||||
|
||||
if (ob_eval->data == me_eval) {
|
||||
@@ -490,13 +509,18 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
|
||||
}
|
||||
}
|
||||
|
||||
snap_to &= mesh_snap_mode_supported(me_eval) & (SNAP_TO_EDGE_ELEMENTS | SCE_SNAP_TO_POINT);
|
||||
if (snap_to == SCE_SNAP_TO_NONE) {
|
||||
return SCE_SNAP_TO_NONE;
|
||||
}
|
||||
|
||||
BVHTreeFromMesh treedata, treedata_dummy;
|
||||
snap_object_data_mesh_get(me_eval, use_hide, &treedata);
|
||||
|
||||
BVHTree *bvhtree[2] = {nullptr};
|
||||
bvhtree[0] = BKE_bvhtree_from_mesh_get(&treedata_dummy, me_eval, BVHTREE_FROM_LOOSEEDGES, 2);
|
||||
BLI_assert(treedata_dummy.cached);
|
||||
if (sctx->runtime.snap_to_flag & SCE_SNAP_TO_POINT) {
|
||||
if (snap_to & SCE_SNAP_TO_POINT) {
|
||||
bvhtree[1] = BKE_bvhtree_from_mesh_get(&treedata_dummy, me_eval, BVHTREE_FROM_LOOSEVERTS, 2);
|
||||
BLI_assert(treedata_dummy.cached);
|
||||
}
|
||||
@@ -511,7 +535,7 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
|
||||
eSnapMode elem = SCE_SNAP_TO_POINT;
|
||||
|
||||
if (bvhtree[1]) {
|
||||
BLI_assert(sctx->runtime.snap_to_flag & SCE_SNAP_TO_POINT);
|
||||
BLI_assert(snap_to & SCE_SNAP_TO_POINT);
|
||||
/* snap to loose verts */
|
||||
BLI_bvhtree_find_nearest_projected(bvhtree[1],
|
||||
nearest2d.pmat_local.ptr(),
|
||||
@@ -526,7 +550,7 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
|
||||
last_index = nearest.index;
|
||||
}
|
||||
|
||||
if (sctx->runtime.snap_to_flag & (SNAP_TO_EDGE_ELEMENTS & ~SCE_SNAP_TO_EDGE_ENDPOINT)) {
|
||||
if (snap_to & (SNAP_TO_EDGE_ELEMENTS & ~SCE_SNAP_TO_EDGE_ENDPOINT)) {
|
||||
if (bvhtree[0]) {
|
||||
/* Snap to loose edges. */
|
||||
BLI_bvhtree_find_nearest_projected(
|
||||
@@ -560,7 +584,7 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_assert(sctx->runtime.snap_to_flag & SCE_SNAP_TO_EDGE_ENDPOINT);
|
||||
BLI_assert(snap_to & SCE_SNAP_TO_EDGE_ENDPOINT);
|
||||
if (bvhtree[0]) {
|
||||
/* Snap to loose edge verts. */
|
||||
BLI_bvhtree_find_nearest_projected(
|
||||
@@ -601,22 +625,6 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
|
||||
|
||||
/** \} */
|
||||
|
||||
static eSnapMode mesh_snap_mode_supported(const Mesh *mesh)
|
||||
{
|
||||
eSnapMode snap_mode_supported = SCE_SNAP_TO_NONE;
|
||||
if (mesh->totpoly) {
|
||||
snap_mode_supported |= SCE_SNAP_TO_FACE | SCE_SNAP_INDIVIDUAL_NEAREST;
|
||||
}
|
||||
if (mesh->totedge) {
|
||||
snap_mode_supported |= SCE_SNAP_TO_EDGE | SCE_SNAP_TO_EDGE_MIDPOINT |
|
||||
SCE_SNAP_TO_EDGE_PERPENDICULAR;
|
||||
}
|
||||
if (mesh->totvert) {
|
||||
snap_mode_supported |= SCE_SNAP_TO_VERTEX;
|
||||
}
|
||||
return snap_mode_supported;
|
||||
}
|
||||
|
||||
eSnapMode snap_object_mesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
const ID *id,
|
||||
@@ -625,25 +633,23 @@ eSnapMode snap_object_mesh(SnapObjectContext *sctx,
|
||||
bool use_hide)
|
||||
{
|
||||
eSnapMode elem = SCE_SNAP_TO_NONE;
|
||||
|
||||
const Mesh *mesh_eval = reinterpret_cast<const Mesh *>(id);
|
||||
|
||||
eSnapMode snap_mode_used = snap_to_flag & mesh_snap_mode_supported(mesh_eval);
|
||||
if (snap_mode_used & (SNAP_TO_EDGE_ELEMENTS | SCE_SNAP_TO_POINT)) {
|
||||
elem = snapMesh(sctx, ob_eval, mesh_eval, obmat, use_hide);
|
||||
if (snap_to_flag & (SNAP_TO_EDGE_ELEMENTS | SCE_SNAP_TO_POINT)) {
|
||||
elem = snapMesh(sctx, ob_eval, mesh_eval, obmat, use_hide, snap_to_flag);
|
||||
if (elem) {
|
||||
return elem;
|
||||
}
|
||||
}
|
||||
|
||||
if (snap_mode_used & SCE_SNAP_TO_FACE) {
|
||||
if (snap_to_flag & SCE_SNAP_TO_FACE) {
|
||||
if (raycastMesh(sctx, ob_eval, mesh_eval, obmat, sctx->runtime.object_index++, use_hide)) {
|
||||
return SCE_SNAP_TO_FACE;
|
||||
}
|
||||
}
|
||||
|
||||
if (snap_mode_used & SCE_SNAP_INDIVIDUAL_NEAREST) {
|
||||
if (nearest_world_mesh(sctx, mesh_eval, obmat, use_hide)) {
|
||||
if (snap_to_flag & SCE_SNAP_INDIVIDUAL_NEAREST) {
|
||||
if (nearest_world_mesh(sctx, ob_eval, mesh_eval, float4x4(obmat), use_hide)) {
|
||||
return SCE_SNAP_INDIVIDUAL_NEAREST;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user