Cleanup: various tweaks to the transform_snap_object code
This commit implements several changes aimed at enhancing the readability of the transform snap object code. The changes are: - Reduce number of parameters in functions; - Unify functions; - Replace enum `eViewProj` with a bool; - Remove unused members; - Deduplicate code; Pull Request: https://projects.blender.org/blender/blender/pulls/109012
This commit is contained in:
committed by
Germano Cavalcante
parent
45b9542e6c
commit
3df2110abd
@@ -94,13 +94,11 @@ static ID *data_for_snap(Object *ob_eval, eSnapEditType edit_mode_type, bool *r_
|
||||
* \{ */
|
||||
|
||||
using IterSnapObjsCallback = eSnapMode (*)(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
Object *ob_eval,
|
||||
ID *ob_data,
|
||||
const float obmat[4][4],
|
||||
bool is_object_active,
|
||||
bool use_hide,
|
||||
void *data);
|
||||
bool use_hide);
|
||||
|
||||
static bool snap_object_is_snappable(const SnapObjectContext *sctx,
|
||||
const eSnapTargetOP snap_target_select,
|
||||
@@ -161,17 +159,14 @@ static bool snap_object_is_snappable(const SnapObjectContext *sctx,
|
||||
/**
|
||||
* Walks through all objects in the scene to create the list of objects to snap.
|
||||
*/
|
||||
static eSnapMode iter_snap_objects(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
IterSnapObjsCallback sob_callback,
|
||||
void *data)
|
||||
static eSnapMode iter_snap_objects(SnapObjectContext *sctx, IterSnapObjsCallback sob_callback)
|
||||
{
|
||||
eSnapMode ret = SCE_SNAP_MODE_NONE;
|
||||
eSnapMode tmp;
|
||||
|
||||
Scene *scene = DEG_get_input_scene(sctx->runtime.depsgraph);
|
||||
ViewLayer *view_layer = DEG_get_input_view_layer(sctx->runtime.depsgraph);
|
||||
const eSnapTargetOP snap_target_select = params->snap_target_select;
|
||||
const eSnapTargetOP snap_target_select = sctx->runtime.params.snap_target_select;
|
||||
BKE_view_layer_synced_ensure(scene, view_layer);
|
||||
Base *base_act = BKE_view_layer_active_base_get(view_layer);
|
||||
|
||||
@@ -186,14 +181,9 @@ static eSnapMode iter_snap_objects(SnapObjectContext *sctx,
|
||||
ListBase *lb = object_duplilist(sctx->runtime.depsgraph, sctx->scene, obj_eval);
|
||||
LISTBASE_FOREACH (DupliObject *, dupli_ob, lb) {
|
||||
BLI_assert(DEG_is_evaluated_object(dupli_ob->ob));
|
||||
if ((tmp = sob_callback(sctx,
|
||||
params,
|
||||
dupli_ob->ob,
|
||||
dupli_ob->ob_data,
|
||||
dupli_ob->mat,
|
||||
is_object_active,
|
||||
false,
|
||||
data)) != SCE_SNAP_MODE_NONE)
|
||||
if ((tmp = sob_callback(
|
||||
sctx, dupli_ob->ob, dupli_ob->ob_data, dupli_ob->mat, is_object_active, false)) !=
|
||||
SCE_SNAP_MODE_NONE)
|
||||
{
|
||||
ret = tmp;
|
||||
}
|
||||
@@ -202,15 +192,10 @@ static eSnapMode iter_snap_objects(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
bool use_hide = false;
|
||||
ID *ob_data = data_for_snap(obj_eval, params->edit_mode_type, &use_hide);
|
||||
if ((tmp = sob_callback(sctx,
|
||||
params,
|
||||
obj_eval,
|
||||
ob_data,
|
||||
obj_eval->object_to_world,
|
||||
is_object_active,
|
||||
use_hide,
|
||||
data)) != SCE_SNAP_MODE_NONE)
|
||||
ID *ob_data = data_for_snap(obj_eval, sctx->runtime.params.edit_mode_type, &use_hide);
|
||||
if ((tmp = sob_callback(
|
||||
sctx, obj_eval, ob_data, obj_eval->object_to_world, is_object_active, use_hide)) !=
|
||||
SCE_SNAP_MODE_NONE)
|
||||
{
|
||||
ret = tmp;
|
||||
}
|
||||
@@ -296,61 +281,26 @@ bool raycast_tri_backface_culling_test(
|
||||
return dot_v3v3(no, dir) < 0.0f;
|
||||
}
|
||||
|
||||
struct RaycastObjUserData {
|
||||
const float *ray_start;
|
||||
const float *ray_dir;
|
||||
uint ob_index;
|
||||
/* read/write args */
|
||||
float *ray_depth;
|
||||
|
||||
uint use_occlusion_test : 1;
|
||||
uint use_occlusion_test_edit : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* \note Duplicate args here are documented at #snapObjectsRay
|
||||
*/
|
||||
static eSnapMode raycast_obj_fn(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
Object *ob_eval,
|
||||
ID *ob_data,
|
||||
const float obmat[4][4],
|
||||
bool is_object_active,
|
||||
bool use_hide,
|
||||
void *data)
|
||||
bool use_hide)
|
||||
{
|
||||
RaycastObjUserData *dt = static_cast<RaycastObjUserData *>(data);
|
||||
const uint ob_index = dt->ob_index++;
|
||||
/* read/write args */
|
||||
float *ray_depth = dt->ray_depth;
|
||||
|
||||
bool retval = false;
|
||||
bool is_edit = false;
|
||||
|
||||
if (ob_data == nullptr) {
|
||||
if (dt->use_occlusion_test_edit && ELEM(ob_eval->dt, OB_BOUNDBOX, OB_WIRE)) {
|
||||
if (sctx->runtime.use_occlusion_test_edit && ELEM(ob_eval->dt, OB_BOUNDBOX, OB_WIRE)) {
|
||||
/* Do not hit objects that are in wire or bounding box display mode. */
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
if (ob_eval->type == OB_MESH) {
|
||||
BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
|
||||
if (UNLIKELY(!em)) { /* See #mesh_for_snap doc-string. */
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
if (raycastEditMesh(sctx,
|
||||
params,
|
||||
dt->ray_start,
|
||||
dt->ray_dir,
|
||||
ob_eval,
|
||||
em,
|
||||
obmat,
|
||||
ob_index,
|
||||
ray_depth,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index,
|
||||
sctx->ret.hit_list))
|
||||
{
|
||||
if (snap_object_editmesh(sctx, ob_eval, nullptr, obmat, SCE_SNAP_MODE_FACE, use_hide)) {
|
||||
retval = true;
|
||||
is_edit = true;
|
||||
}
|
||||
@@ -359,7 +309,7 @@ static eSnapMode raycast_obj_fn(SnapObjectContext *sctx,
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
}
|
||||
else if (dt->use_occlusion_test && ELEM(ob_eval->dt, OB_BOUNDBOX, OB_WIRE)) {
|
||||
else if (sctx->runtime.params.use_occlusion_test && ELEM(ob_eval->dt, OB_BOUNDBOX, OB_WIRE)) {
|
||||
/* Do not hit objects that are in wire or bounding box display mode. */
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
@@ -370,20 +320,7 @@ static eSnapMode raycast_obj_fn(SnapObjectContext *sctx,
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
else {
|
||||
const Mesh *me_eval = (const Mesh *)ob_data;
|
||||
retval = raycastMesh(params,
|
||||
dt->ray_start,
|
||||
dt->ray_dir,
|
||||
ob_eval,
|
||||
me_eval,
|
||||
obmat,
|
||||
ob_index,
|
||||
use_hide,
|
||||
ray_depth,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index,
|
||||
sctx->ret.hit_list);
|
||||
retval = snap_object_mesh(sctx, ob_eval, ob_data, obmat, SCE_SNAP_MODE_FACE, use_hide);
|
||||
}
|
||||
|
||||
if (retval) {
|
||||
@@ -410,26 +347,9 @@ static eSnapMode raycast_obj_fn(SnapObjectContext *sctx,
|
||||
* \param ray_depth: maximum depth allowed for r_co,
|
||||
* elements deeper than this value will be ignored.
|
||||
*/
|
||||
static bool raycastObjects(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
const float ray_start[3],
|
||||
const float ray_dir[3],
|
||||
const bool use_occlusion_test,
|
||||
const bool use_occlusion_test_edit,
|
||||
/* read/write args */
|
||||
/* Parameters below cannot be const, because they are assigned to a
|
||||
* non-const variable (readability-non-const-parameter). */
|
||||
float *ray_depth /* NOLINT */)
|
||||
static bool raycastObjects(SnapObjectContext *sctx)
|
||||
{
|
||||
RaycastObjUserData data = {};
|
||||
data.ray_start = ray_start;
|
||||
data.ray_dir = ray_dir;
|
||||
data.ob_index = 0;
|
||||
data.ray_depth = ray_depth;
|
||||
data.use_occlusion_test = use_occlusion_test;
|
||||
data.use_occlusion_test_edit = use_occlusion_test_edit;
|
||||
|
||||
return iter_snap_objects(sctx, params, raycast_obj_fn, &data) != SCE_SNAP_MODE_NONE;
|
||||
return iter_snap_objects(sctx, raycast_obj_fn) != SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -475,8 +395,7 @@ static void nearest_world_tree_co(BVHTree *tree,
|
||||
}
|
||||
}
|
||||
|
||||
bool nearest_world_tree(SnapObjectContext * /*sctx*/,
|
||||
const SnapObjectParams *params,
|
||||
bool nearest_world_tree(SnapObjectContext *sctx,
|
||||
BVHTree *tree,
|
||||
BVHTree_NearestPointCallback nearest_cb,
|
||||
void *treedata,
|
||||
@@ -507,7 +426,7 @@ bool nearest_world_tree(SnapObjectContext * /*sctx*/,
|
||||
sub_v3_v3v3(delta_local, curr_co_local, init_co_local);
|
||||
|
||||
float dist_sq;
|
||||
if (params->keep_on_same_target) {
|
||||
if (sctx->runtime.params.keep_on_same_target) {
|
||||
nearest_world_tree_co(
|
||||
tree, nearest_cb, treedata, init_co_local, nullptr, nullptr, nullptr, &dist_sq);
|
||||
}
|
||||
@@ -524,7 +443,7 @@ bool nearest_world_tree(SnapObjectContext * /*sctx*/,
|
||||
*r_dist_sq = dist_sq;
|
||||
|
||||
/* scale to make `snap_face_nearest_steps` steps */
|
||||
float step_scale_factor = 1.0f / max_ff(1.0f, float(params->face_nearest_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];
|
||||
@@ -532,7 +451,7 @@ bool nearest_world_tree(SnapObjectContext * /*sctx*/,
|
||||
|
||||
copy_v3_v3(co_local, init_co_local);
|
||||
|
||||
for (int i = 0; i < params->face_nearest_steps; i++) {
|
||||
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, r_index, nullptr);
|
||||
@@ -549,37 +468,19 @@ bool nearest_world_tree(SnapObjectContext * /*sctx*/,
|
||||
}
|
||||
|
||||
static eSnapMode nearest_world_object_fn(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
Object *ob_eval,
|
||||
ID *ob_data,
|
||||
const float obmat[4][4],
|
||||
bool is_object_active,
|
||||
bool use_hide,
|
||||
void *data)
|
||||
bool use_hide)
|
||||
{
|
||||
NearestWorldObjUserData *dt = static_cast<NearestWorldObjUserData *>(data);
|
||||
|
||||
bool retval = false;
|
||||
bool is_edit = false;
|
||||
|
||||
if (ob_data == nullptr) {
|
||||
if (ob_eval->type == OB_MESH) {
|
||||
BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
|
||||
if (UNLIKELY(!em)) { /* See #data_for_snap doc-string. */
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
if (nearest_world_editmesh(sctx,
|
||||
params,
|
||||
ob_eval,
|
||||
em,
|
||||
obmat,
|
||||
dt->init_co,
|
||||
dt->curr_co,
|
||||
&sctx->ret.dist_sq,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index))
|
||||
{
|
||||
if (snap_object_editmesh(
|
||||
sctx, ob_eval, nullptr, obmat, SCE_SNAP_MODE_FACE_NEAREST, use_hide)) {
|
||||
retval = true;
|
||||
is_edit = true;
|
||||
}
|
||||
@@ -594,19 +495,8 @@ static eSnapMode nearest_world_object_fn(SnapObjectContext *sctx,
|
||||
else if (is_object_active && ELEM(ob_eval->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
else {
|
||||
const Mesh *me_eval = (const Mesh *)ob_data;
|
||||
retval = nearest_world_mesh(sctx,
|
||||
params,
|
||||
me_eval,
|
||||
obmat,
|
||||
use_hide,
|
||||
dt->init_co,
|
||||
dt->curr_co,
|
||||
&sctx->ret.dist_sq,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index);
|
||||
else if (snap_object_mesh(sctx, ob_eval, ob_data, obmat, SCE_SNAP_MODE_FACE_NEAREST, use_hide)) {
|
||||
retval = true;
|
||||
}
|
||||
|
||||
if (retval) {
|
||||
@@ -630,16 +520,9 @@ static eSnapMode nearest_world_object_fn(SnapObjectContext *sctx,
|
||||
* \param init_co: Initial location of source point.
|
||||
* \param prev_co: Current location of source point after transformation but before snapping.
|
||||
*/
|
||||
static bool nearestWorldObjects(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
const float init_co[3],
|
||||
const float curr_co[3])
|
||||
static bool nearestWorldObjects(SnapObjectContext *sctx)
|
||||
{
|
||||
NearestWorldObjUserData data = {};
|
||||
data.init_co = init_co;
|
||||
data.curr_co = curr_co;
|
||||
|
||||
return iter_snap_objects(sctx, params, nearest_world_object_fn, &data) != SCE_SNAP_MODE_NONE;
|
||||
return iter_snap_objects(sctx, nearest_world_object_fn) != SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -793,10 +676,7 @@ void cb_snap_edge(void *userdata,
|
||||
/** \name Internal Object Snapping API
|
||||
* \{ */
|
||||
|
||||
static eSnapMode snap_polygon(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
/* read/write args */
|
||||
float *dist_px)
|
||||
static eSnapMode snap_polygon(SnapObjectContext *sctx, eSnapMode snap_to_flag)
|
||||
{
|
||||
float lpmat[4][4];
|
||||
mul_m4_m4m4(lpmat, sctx->runtime.pmat, sctx->ret.obmat);
|
||||
@@ -812,36 +692,27 @@ static eSnapMode snap_polygon(SnapObjectContext *sctx,
|
||||
nullptr;
|
||||
if (mesh) {
|
||||
return snap_polygon_mesh(sctx,
|
||||
params,
|
||||
mesh,
|
||||
sctx->ret.ob,
|
||||
sctx->ret.data,
|
||||
sctx->ret.obmat,
|
||||
clip_planes_local,
|
||||
dist_px,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index);
|
||||
snap_to_flag,
|
||||
sctx->ret.index,
|
||||
clip_planes_local);
|
||||
}
|
||||
else if (sctx->ret.is_edit) {
|
||||
return snap_polygon_editmesh(sctx,
|
||||
params,
|
||||
BKE_editmesh_from_object(sctx->ret.ob),
|
||||
sctx->ret.ob,
|
||||
sctx->ret.data,
|
||||
sctx->ret.obmat,
|
||||
clip_planes_local,
|
||||
dist_px,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index);
|
||||
snap_to_flag,
|
||||
sctx->ret.index,
|
||||
clip_planes_local);
|
||||
}
|
||||
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
||||
static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
float original_dist_px,
|
||||
const float prev_co[3],
|
||||
/* read/write args */
|
||||
float *dist_px)
|
||||
static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, float original_dist_px)
|
||||
{
|
||||
eSnapMode elem = SCE_SNAP_MODE_EDGE;
|
||||
|
||||
@@ -855,16 +726,14 @@ static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
|
||||
(const Mesh *)sctx->ret.data :
|
||||
nullptr;
|
||||
if (mesh) {
|
||||
nearest2d_data_init_mesh(mesh,
|
||||
sctx->runtime.view_proj == VIEW_PROJ_PERSP,
|
||||
params->use_backface_culling,
|
||||
&nearest2d);
|
||||
nearest2d_data_init_mesh(
|
||||
mesh, sctx->runtime.is_persp, sctx->runtime.params.use_backface_culling, &nearest2d);
|
||||
}
|
||||
else if (sctx->ret.is_edit) {
|
||||
/* The object's #BMEditMesh was used to snap instead. */
|
||||
nearest2d_data_init_editmesh(BKE_editmesh_from_object(sctx->ret.ob),
|
||||
sctx->runtime.view_proj == VIEW_PROJ_PERSP,
|
||||
params->use_backface_culling,
|
||||
sctx->runtime.is_persp,
|
||||
sctx->runtime.params.use_backface_culling,
|
||||
&nearest2d);
|
||||
}
|
||||
else {
|
||||
@@ -953,17 +822,17 @@ static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
|
||||
}
|
||||
}
|
||||
|
||||
if (prev_co && (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
|
||||
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE_PERPENDICULAR) {
|
||||
float v_near[3], va_g[3], vb_g[3];
|
||||
|
||||
mul_v3_m4v3(va_g, sctx->ret.obmat, v_pair[0]);
|
||||
mul_v3_m4v3(vb_g, sctx->ret.obmat, v_pair[1]);
|
||||
lambda = line_point_factor_v3(prev_co, va_g, vb_g);
|
||||
lambda = line_point_factor_v3(sctx->runtime.curr_co, va_g, vb_g);
|
||||
|
||||
if (IN_RANGE(lambda, 0.0f, 1.0f)) {
|
||||
interp_v3_v3v3(v_near, va_g, vb_g, lambda);
|
||||
|
||||
if (len_squared_v3v3(prev_co, v_near) > FLT_EPSILON) {
|
||||
if (len_squared_v3v3(sctx->runtime.curr_co, v_near) > FLT_EPSILON) {
|
||||
dist_squared_to_projected_aabb_precalc(
|
||||
&neasrest_precalc, sctx->runtime.pmat, sctx->runtime.win_size, sctx->runtime.mval);
|
||||
|
||||
@@ -984,7 +853,7 @@ static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
if (nearest.index != -1) {
|
||||
*dist_px = sqrtf(nearest.dist_sq);
|
||||
sctx->ret.dist_px_sq = nearest.dist_sq;
|
||||
|
||||
copy_v3_v3(sctx->ret.loc, nearest.co);
|
||||
if (elem != SCE_SNAP_MODE_EDGE_PERPENDICULAR) {
|
||||
@@ -998,16 +867,9 @@ static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
static eSnapMode snapArmature(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
Object *ob_eval,
|
||||
const float obmat[4][4],
|
||||
bool is_object_active,
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float * /*r_no*/,
|
||||
int *r_index)
|
||||
bool is_object_active)
|
||||
{
|
||||
eSnapMode retval = SCE_SNAP_MODE_NONE;
|
||||
|
||||
@@ -1016,7 +878,7 @@ static eSnapMode snapArmature(SnapObjectContext *sctx,
|
||||
return retval;
|
||||
}
|
||||
|
||||
float lpmat[4][4], dist_px_sq = square_f(*dist_px);
|
||||
float lpmat[4][4];
|
||||
mul_m4_m4m4(lpmat, sctx->runtime.pmat, obmat);
|
||||
|
||||
DistProjectedAABBPrecalc neasrest_precalc;
|
||||
@@ -1029,9 +891,12 @@ static eSnapMode snapArmature(SnapObjectContext *sctx,
|
||||
if (is_editmode == false) {
|
||||
/* Test BoundBox. */
|
||||
const BoundBox *bb = BKE_armature_boundbox_get(ob_eval);
|
||||
if (bb &&
|
||||
!snap_bound_box_check_dist(
|
||||
bb->vec[0], bb->vec[6], lpmat, sctx->runtime.win_size, sctx->runtime.mval, dist_px_sq))
|
||||
if (bb && !snap_bound_box_check_dist(bb->vec[0],
|
||||
bb->vec[6],
|
||||
lpmat,
|
||||
sctx->runtime.win_size,
|
||||
sctx->runtime.mval,
|
||||
sctx->ret.dist_px_sq))
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
@@ -1045,8 +910,9 @@ static eSnapMode snapArmature(SnapObjectContext *sctx,
|
||||
|
||||
const bool is_posemode = is_object_active && (ob_eval->mode & OB_MODE_POSE);
|
||||
const bool skip_selected = (is_editmode || is_posemode) &&
|
||||
(params->snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED);
|
||||
const bool is_persp = sctx->runtime.view_proj == VIEW_PROJ_PERSP;
|
||||
(sctx->runtime.params.snap_target_select &
|
||||
SCE_SNAP_TARGET_NOT_SELECTED);
|
||||
const bool is_persp = sctx->runtime.is_persp;
|
||||
|
||||
if (arm->edbo) {
|
||||
LISTBASE_FOREACH (EditBone *, eBone, arm->edbo) {
|
||||
@@ -1068,16 +934,16 @@ static eSnapMode snapArmature(SnapObjectContext *sctx,
|
||||
sctx->runtime.clip_plane_len,
|
||||
is_persp,
|
||||
eBone->head,
|
||||
&dist_px_sq,
|
||||
r_loc);
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc);
|
||||
has_vert_snap |= test_projected_vert_dist(&neasrest_precalc,
|
||||
clip_planes_local,
|
||||
sctx->runtime.clip_plane_len,
|
||||
is_persp,
|
||||
eBone->tail,
|
||||
|
||||
&dist_px_sq,
|
||||
r_loc);
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc);
|
||||
|
||||
if (has_vert_snap) {
|
||||
retval = SCE_SNAP_MODE_VERTEX;
|
||||
@@ -1090,8 +956,8 @@ static eSnapMode snapArmature(SnapObjectContext *sctx,
|
||||
is_persp,
|
||||
eBone->head,
|
||||
eBone->tail,
|
||||
&dist_px_sq,
|
||||
r_loc))
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc))
|
||||
{
|
||||
retval = SCE_SNAP_MODE_EDGE;
|
||||
}
|
||||
@@ -1122,15 +988,15 @@ static eSnapMode snapArmature(SnapObjectContext *sctx,
|
||||
sctx->runtime.clip_plane_len,
|
||||
is_persp,
|
||||
head_vec,
|
||||
&dist_px_sq,
|
||||
r_loc);
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc);
|
||||
has_vert_snap |= test_projected_vert_dist(&neasrest_precalc,
|
||||
clip_planes_local,
|
||||
sctx->runtime.clip_plane_len,
|
||||
is_persp,
|
||||
tail_vec,
|
||||
&dist_px_sq,
|
||||
r_loc);
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc);
|
||||
|
||||
if (has_vert_snap) {
|
||||
retval = SCE_SNAP_MODE_VERTEX;
|
||||
@@ -1143,8 +1009,8 @@ static eSnapMode snapArmature(SnapObjectContext *sctx,
|
||||
is_persp,
|
||||
head_vec,
|
||||
tail_vec,
|
||||
&dist_px_sq,
|
||||
r_loc))
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc))
|
||||
{
|
||||
retval = SCE_SNAP_MODE_EDGE;
|
||||
}
|
||||
@@ -1153,28 +1019,16 @@ static eSnapMode snapArmature(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
if (retval) {
|
||||
*dist_px = sqrtf(dist_px_sq);
|
||||
mul_m4_v3(obmat, r_loc);
|
||||
if (r_index) {
|
||||
/* Does not support index. */
|
||||
*r_index = -1;
|
||||
}
|
||||
mul_m4_v3(obmat, sctx->ret.loc);
|
||||
/* Does not support index. */
|
||||
sctx->ret.index = -1;
|
||||
return retval;
|
||||
}
|
||||
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
||||
static eSnapMode snapCurve(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
Object *ob_eval,
|
||||
const float obmat[4][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float * /*r_no*/,
|
||||
int *r_index)
|
||||
static eSnapMode snapCurve(SnapObjectContext *sctx, Object *ob_eval, const float obmat[4][4])
|
||||
{
|
||||
bool has_snap = false;
|
||||
|
||||
@@ -1184,7 +1038,6 @@ static eSnapMode snapCurve(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
Curve *cu = static_cast<Curve *>(ob_eval->data);
|
||||
float dist_px_sq = square_f(*dist_px);
|
||||
|
||||
float lpmat[4][4];
|
||||
mul_m4_m4m4(lpmat, sctx->runtime.pmat, obmat);
|
||||
@@ -1198,9 +1051,12 @@ static eSnapMode snapCurve(SnapObjectContext *sctx,
|
||||
if (use_obedit == false) {
|
||||
/* Test BoundBox */
|
||||
BoundBox *bb = BKE_curve_boundbox_get(ob_eval);
|
||||
if (bb &&
|
||||
!snap_bound_box_check_dist(
|
||||
bb->vec[0], bb->vec[6], lpmat, sctx->runtime.win_size, sctx->runtime.mval, dist_px_sq))
|
||||
if (bb && !snap_bound_box_check_dist(bb->vec[0],
|
||||
bb->vec[6],
|
||||
lpmat,
|
||||
sctx->runtime.win_size,
|
||||
sctx->runtime.mval,
|
||||
sctx->ret.dist_px_sq))
|
||||
{
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
@@ -1223,8 +1079,9 @@ static eSnapMode snapCurve(SnapObjectContext *sctx,
|
||||
mul_v4_m4v4(clip_planes_local[i], tobmat, clip_planes[i]);
|
||||
}
|
||||
|
||||
bool is_persp = sctx->runtime.view_proj == VIEW_PROJ_PERSP;
|
||||
bool skip_selected = params->snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED;
|
||||
bool is_persp = sctx->runtime.is_persp;
|
||||
bool skip_selected = (sctx->runtime.params.snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED) !=
|
||||
0;
|
||||
|
||||
LISTBASE_FOREACH (Nurb *, nu, (use_obedit ? &cu->editnurb->nurbs : &cu->nurb)) {
|
||||
for (int u = 0; u < nu->pntsu; u++) {
|
||||
@@ -1245,8 +1102,8 @@ static eSnapMode snapCurve(SnapObjectContext *sctx,
|
||||
clip_plane_len,
|
||||
is_persp,
|
||||
nu->bezt[u].vec[1],
|
||||
&dist_px_sq,
|
||||
r_loc);
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc);
|
||||
|
||||
/* Don't snap if handle is selected (moving),
|
||||
* or if it is aligning to a moving handle. */
|
||||
@@ -1260,8 +1117,8 @@ static eSnapMode snapCurve(SnapObjectContext *sctx,
|
||||
clip_plane_len,
|
||||
is_persp,
|
||||
nu->bezt[u].vec[0],
|
||||
&dist_px_sq,
|
||||
r_loc);
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc);
|
||||
}
|
||||
|
||||
if (!skip_selected || !(is_selected_h2 || (is_autoalign_h2 && is_selected_h1))) {
|
||||
@@ -1270,8 +1127,8 @@ static eSnapMode snapCurve(SnapObjectContext *sctx,
|
||||
clip_plane_len,
|
||||
is_persp,
|
||||
nu->bezt[u].vec[2],
|
||||
&dist_px_sq,
|
||||
r_loc);
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1290,8 +1147,8 @@ static eSnapMode snapCurve(SnapObjectContext *sctx,
|
||||
clip_plane_len,
|
||||
is_persp,
|
||||
nu->bp[u].vec,
|
||||
&dist_px_sq,
|
||||
r_loc);
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1303,8 +1160,8 @@ static eSnapMode snapCurve(SnapObjectContext *sctx,
|
||||
clip_plane_len,
|
||||
is_persp,
|
||||
nu->bezt[u].vec[1],
|
||||
&dist_px_sq,
|
||||
r_loc);
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc);
|
||||
}
|
||||
else {
|
||||
has_snap |= test_projected_vert_dist(&neasrest_precalc,
|
||||
@@ -1312,8 +1169,8 @@ static eSnapMode snapCurve(SnapObjectContext *sctx,
|
||||
clip_plane_len,
|
||||
is_persp,
|
||||
nu->bp[u].vec,
|
||||
&dist_px_sq,
|
||||
r_loc);
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1321,12 +1178,9 @@ static eSnapMode snapCurve(SnapObjectContext *sctx,
|
||||
}
|
||||
}
|
||||
if (has_snap) {
|
||||
*dist_px = sqrtf(dist_px_sq);
|
||||
mul_m4_v3(obmat, r_loc);
|
||||
if (r_index) {
|
||||
/* Does not support index yet. */
|
||||
*r_index = -1;
|
||||
}
|
||||
mul_m4_v3(obmat, sctx->ret.loc);
|
||||
/* Does not support index yet. */
|
||||
sctx->ret.index = -1;
|
||||
return SCE_SNAP_MODE_VERTEX;
|
||||
}
|
||||
|
||||
@@ -1334,15 +1188,10 @@ static eSnapMode snapCurve(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
/* may extend later (for now just snaps to empty center) */
|
||||
static eSnapMode snap_object_center(const SnapObjectContext *sctx,
|
||||
static eSnapMode snap_object_center(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
const float obmat[4][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float * /*r_no*/,
|
||||
int *r_index)
|
||||
eSnapMode snap_to_flag)
|
||||
{
|
||||
eSnapMode retval = SCE_SNAP_MODE_NONE;
|
||||
|
||||
@@ -1351,7 +1200,7 @@ static eSnapMode snap_object_center(const SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
/* For now only vertex supported. */
|
||||
if ((sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) == 0) {
|
||||
if ((snap_to_flag & SCE_SNAP_MODE_VERTEX) == 0) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -1359,55 +1208,44 @@ static eSnapMode snap_object_center(const SnapObjectContext *sctx,
|
||||
dist_squared_to_projected_aabb_precalc(
|
||||
&neasrest_precalc, sctx->runtime.pmat, sctx->runtime.win_size, sctx->runtime.mval);
|
||||
|
||||
bool is_persp = sctx->runtime.view_proj == VIEW_PROJ_PERSP;
|
||||
float dist_px_sq = square_f(*dist_px);
|
||||
bool is_persp = sctx->runtime.is_persp;
|
||||
|
||||
if (test_projected_vert_dist(&neasrest_precalc,
|
||||
sctx->runtime.clip_plane,
|
||||
sctx->runtime.clip_plane_len,
|
||||
is_persp,
|
||||
obmat[3],
|
||||
&dist_px_sq,
|
||||
r_loc))
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc))
|
||||
{
|
||||
*dist_px = sqrtf(dist_px_sq);
|
||||
retval = SCE_SNAP_MODE_VERTEX;
|
||||
}
|
||||
|
||||
if (retval) {
|
||||
if (r_index) {
|
||||
/* Does not support index. */
|
||||
*r_index = -1;
|
||||
}
|
||||
sctx->ret.index = -1;
|
||||
return retval;
|
||||
}
|
||||
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
||||
static eSnapMode snapCamera(const SnapObjectContext *sctx,
|
||||
static eSnapMode snapCamera(SnapObjectContext *sctx,
|
||||
Object *object,
|
||||
const float obmat[4][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float *r_no,
|
||||
int *r_index)
|
||||
eSnapMode snap_to_flag)
|
||||
{
|
||||
eSnapMode retval = SCE_SNAP_MODE_NONE;
|
||||
|
||||
Scene *scene = sctx->scene;
|
||||
|
||||
bool is_persp = sctx->runtime.view_proj == VIEW_PROJ_PERSP;
|
||||
float dist_px_sq = square_f(*dist_px);
|
||||
bool is_persp = sctx->runtime.is_persp;
|
||||
|
||||
float orig_camera_mat[4][4], orig_camera_imat[4][4], imat[4][4];
|
||||
MovieClip *clip = BKE_object_movieclip_get(scene, object, false);
|
||||
MovieTracking *tracking;
|
||||
|
||||
if (clip == nullptr) {
|
||||
return snap_object_center(sctx, object, obmat, dist_px, r_loc, r_no, r_index);
|
||||
return snap_object_center(sctx, object, obmat, snap_to_flag);
|
||||
}
|
||||
if (object->transflag & OB_DUPLI) {
|
||||
return retval;
|
||||
@@ -1458,8 +1296,8 @@ static eSnapMode snapCamera(const SnapObjectContext *sctx,
|
||||
sctx->runtime.clip_plane_len,
|
||||
is_persp,
|
||||
bundle_pos,
|
||||
&dist_px_sq,
|
||||
r_loc))
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc))
|
||||
{
|
||||
retval = SCE_SNAP_MODE_VERTEX;
|
||||
}
|
||||
@@ -1468,59 +1306,36 @@ static eSnapMode snapCamera(const SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
if (retval) {
|
||||
*dist_px = sqrtf(dist_px_sq);
|
||||
if (r_index) {
|
||||
/* Does not support index. */
|
||||
*r_index = -1;
|
||||
}
|
||||
/* Does not support index. */
|
||||
sctx->ret.index = -1;
|
||||
return retval;
|
||||
}
|
||||
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
||||
struct SnapObjUserData {
|
||||
/* read/write args */
|
||||
float *dist_px;
|
||||
};
|
||||
|
||||
/**
|
||||
* \note Duplicate args here are documented at #snapObjectsRay
|
||||
*/
|
||||
static eSnapMode snap_obj_fn(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
Object *ob_eval,
|
||||
ID *ob_data,
|
||||
const float obmat[4][4],
|
||||
bool is_object_active,
|
||||
bool use_hide,
|
||||
void *data)
|
||||
bool use_hide)
|
||||
{
|
||||
SnapObjUserData *dt = static_cast<SnapObjUserData *>(data);
|
||||
eSnapMode retval = SCE_SNAP_MODE_NONE;
|
||||
bool is_edit = false;
|
||||
|
||||
if (ob_data == nullptr && (ob_eval->type == OB_MESH)) {
|
||||
BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
|
||||
if (UNLIKELY(!em)) { /* See #data_for_snap doc-string. */
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
retval = snapEditMesh(sctx,
|
||||
params,
|
||||
ob_eval,
|
||||
em,
|
||||
obmat,
|
||||
dt->dist_px,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index);
|
||||
retval = snap_object_editmesh(
|
||||
sctx, ob_eval, nullptr, obmat, sctx->runtime.snap_to_flag, use_hide);
|
||||
if (retval) {
|
||||
is_edit = true;
|
||||
}
|
||||
}
|
||||
else if (ob_data == nullptr) {
|
||||
retval = snap_object_center(
|
||||
sctx, ob_eval, obmat, dt->dist_px, sctx->ret.loc, sctx->ret.no, &sctx->ret.index);
|
||||
retval = snap_object_center(sctx, ob_eval, obmat, sctx->runtime.snap_to_flag);
|
||||
}
|
||||
else {
|
||||
switch (ob_eval->type) {
|
||||
@@ -1530,42 +1345,19 @@ static eSnapMode snap_obj_fn(SnapObjectContext *sctx,
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
if (GS(ob_data->name) == ID_ME) {
|
||||
retval = snapMesh(sctx,
|
||||
params,
|
||||
ob_eval,
|
||||
(const Mesh *)ob_data,
|
||||
obmat,
|
||||
use_hide,
|
||||
dt->dist_px,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index);
|
||||
retval = snap_object_mesh(
|
||||
sctx, ob_eval, ob_data, obmat, sctx->runtime.snap_to_flag, use_hide);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OB_ARMATURE:
|
||||
retval = snapArmature(sctx,
|
||||
params,
|
||||
ob_eval,
|
||||
obmat,
|
||||
is_object_active,
|
||||
dt->dist_px,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index);
|
||||
retval = snapArmature(sctx, ob_eval, obmat, is_object_active);
|
||||
break;
|
||||
case OB_CURVES_LEGACY:
|
||||
case OB_SURF:
|
||||
if (ob_eval->type == OB_CURVES_LEGACY || BKE_object_is_in_editmode(ob_eval)) {
|
||||
retval = snapCurve(sctx,
|
||||
params,
|
||||
ob_eval,
|
||||
obmat,
|
||||
dt->dist_px,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index);
|
||||
if (params->edit_mode_type != SNAP_GEOM_FINAL) {
|
||||
retval = snapCurve(sctx, ob_eval, obmat);
|
||||
if (sctx->runtime.params.edit_mode_type != SNAP_GEOM_FINAL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1573,28 +1365,18 @@ static eSnapMode snap_obj_fn(SnapObjectContext *sctx,
|
||||
case OB_FONT: {
|
||||
const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
|
||||
if (mesh_eval) {
|
||||
retval |= snapMesh(sctx,
|
||||
params,
|
||||
ob_eval,
|
||||
mesh_eval,
|
||||
obmat,
|
||||
false,
|
||||
dt->dist_px,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index);
|
||||
retval |= snap_object_mesh(
|
||||
sctx, ob_eval, (ID *)mesh_eval, obmat, sctx->runtime.snap_to_flag, use_hide);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OB_EMPTY:
|
||||
case OB_GPENCIL_LEGACY:
|
||||
case OB_LAMP:
|
||||
retval = snap_object_center(
|
||||
sctx, ob_eval, obmat, dt->dist_px, sctx->ret.loc, sctx->ret.no, &sctx->ret.index);
|
||||
retval = snap_object_center(sctx, ob_eval, obmat, sctx->runtime.snap_to_flag);
|
||||
break;
|
||||
case OB_CAMERA:
|
||||
retval = snapCamera(
|
||||
sctx, ob_eval, obmat, dt->dist_px, sctx->ret.loc, sctx->ret.no, &sctx->ret.index);
|
||||
retval = snapCamera(sctx, ob_eval, obmat, sctx->runtime.snap_to_flag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1621,17 +1403,9 @@ static eSnapMode snap_obj_fn(SnapObjectContext *sctx,
|
||||
*
|
||||
* \param dist_px: Maximum threshold distance (in pixels).
|
||||
*/
|
||||
static eSnapMode snapObjectsRay(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
/* read/write args */
|
||||
/* Parameters below cannot be const, because they are assigned to a
|
||||
* non-const variable (readability-non-const-parameter). */
|
||||
float *dist_px /* NOLINT */)
|
||||
static eSnapMode snapObjectsRay(SnapObjectContext *sctx)
|
||||
{
|
||||
SnapObjUserData data = {};
|
||||
data.dist_px = dist_px;
|
||||
|
||||
return iter_snap_objects(sctx, params, snap_obj_fn, &data);
|
||||
return iter_snap_objects(sctx, snap_obj_fn);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -1640,12 +1414,10 @@ static eSnapMode snapObjectsRay(SnapObjectContext *sctx,
|
||||
/** \name Public Object Snapping API
|
||||
* \{ */
|
||||
|
||||
SnapObjectContext *ED_transform_snap_object_context_create(Scene *scene, int flag)
|
||||
SnapObjectContext *ED_transform_snap_object_context_create(Scene *scene, int /*flag*/)
|
||||
{
|
||||
SnapObjectContext *sctx = MEM_new<SnapObjectContext>(__func__);
|
||||
|
||||
sctx->flag = flag;
|
||||
|
||||
sctx->scene = scene;
|
||||
|
||||
return sctx;
|
||||
@@ -1686,6 +1458,99 @@ void ED_transform_snap_object_context_set_editmesh_callbacks(
|
||||
}
|
||||
}
|
||||
|
||||
static bool snap_object_context_runtime_init(SnapObjectContext *sctx,
|
||||
Depsgraph *depsgraph,
|
||||
const ARegion *region,
|
||||
const View3D *v3d,
|
||||
eSnapMode snap_to_flag,
|
||||
const SnapObjectParams *params,
|
||||
const float ray_start[3],
|
||||
const float ray_dir[3],
|
||||
const float ray_depth,
|
||||
const float mval[2],
|
||||
const float init_co[3],
|
||||
const float prev_co[3],
|
||||
const float dist_px_sq,
|
||||
ListBase *hit_list,
|
||||
bool use_occlusion_test)
|
||||
{
|
||||
if (use_occlusion_test && XRAY_ENABLED(v3d) && (snap_to_flag & SCE_SNAP_MODE_FACE)) {
|
||||
if (snap_to_flag != SCE_SNAP_MODE_FACE) {
|
||||
/* In theory everything is visible in X-Ray except faces. */
|
||||
snap_to_flag &= ~SCE_SNAP_MODE_FACE;
|
||||
use_occlusion_test = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (snap_to_flag & (SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_FACE_NEAREST)) {
|
||||
if (prev_co) {
|
||||
copy_v3_v3(sctx->runtime.curr_co, prev_co);
|
||||
if (init_co) {
|
||||
copy_v3_v3(sctx->runtime.init_co, init_co);
|
||||
}
|
||||
else {
|
||||
snap_to_flag &= ~SCE_SNAP_MODE_FACE_NEAREST;
|
||||
}
|
||||
}
|
||||
else {
|
||||
snap_to_flag &= ~(SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_FACE_NEAREST);
|
||||
}
|
||||
}
|
||||
|
||||
if (snap_to_flag == SCE_SNAP_MODE_NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sctx->runtime.depsgraph = depsgraph;
|
||||
sctx->runtime.region = region;
|
||||
sctx->runtime.v3d = v3d;
|
||||
sctx->runtime.snap_to_flag = snap_to_flag;
|
||||
sctx->runtime.params = *params;
|
||||
sctx->runtime.params.use_occlusion_test = use_occlusion_test;
|
||||
sctx->runtime.use_occlusion_test_edit = use_occlusion_test &&
|
||||
(snap_to_flag & SCE_SNAP_MODE_FACE) == 0;
|
||||
sctx->runtime.has_occlusion_plane = false;
|
||||
sctx->runtime.object_index = 0;
|
||||
|
||||
copy_v3_v3(sctx->runtime.ray_start, ray_start);
|
||||
copy_v3_v3(sctx->runtime.ray_dir, ray_dir);
|
||||
|
||||
if (mval) {
|
||||
copy_v2_v2(sctx->runtime.mval, mval);
|
||||
}
|
||||
|
||||
if (region) {
|
||||
const RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
|
||||
copy_m4_m4(sctx->runtime.pmat, rv3d->persmat);
|
||||
sctx->runtime.win_size[0] = region->winx;
|
||||
sctx->runtime.win_size[1] = region->winy;
|
||||
|
||||
planes_from_projmat(sctx->runtime.pmat,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
sctx->runtime.clip_plane[0],
|
||||
sctx->runtime.clip_plane[1]);
|
||||
|
||||
sctx->runtime.clip_plane_len = 2;
|
||||
sctx->runtime.is_persp = rv3d->is_persp;
|
||||
}
|
||||
|
||||
sctx->ret.ray_depth_max = ray_depth;
|
||||
zero_v3(sctx->ret.loc);
|
||||
zero_v3(sctx->ret.no);
|
||||
sctx->ret.index = -1;
|
||||
zero_m4(sctx->ret.obmat);
|
||||
sctx->ret.hit_list = hit_list;
|
||||
sctx->ret.ob = nullptr;
|
||||
sctx->ret.data = nullptr;
|
||||
sctx->ret.dist_px_sq = dist_px_sq;
|
||||
sctx->ret.is_edit = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ED_transform_snap_object_project_ray_ex(SnapObjectContext *sctx,
|
||||
Depsgraph *depsgraph,
|
||||
const View3D *v3d,
|
||||
@@ -1699,27 +1564,27 @@ bool ED_transform_snap_object_project_ray_ex(SnapObjectContext *sctx,
|
||||
Object **r_ob,
|
||||
float r_obmat[4][4])
|
||||
{
|
||||
sctx->runtime.depsgraph = depsgraph;
|
||||
sctx->runtime.v3d = v3d;
|
||||
|
||||
zero_v3(sctx->ret.loc);
|
||||
zero_v3(sctx->ret.no);
|
||||
sctx->ret.index = -1;
|
||||
zero_m4(sctx->ret.obmat);
|
||||
sctx->ret.hit_list = nullptr;
|
||||
sctx->ret.ob = nullptr;
|
||||
sctx->ret.data = nullptr;
|
||||
sctx->ret.dist_sq = FLT_MAX;
|
||||
sctx->ret.is_edit = false;
|
||||
|
||||
if (raycastObjects(sctx,
|
||||
params,
|
||||
ray_start,
|
||||
ray_normal,
|
||||
params->use_occlusion_test,
|
||||
params->use_occlusion_test,
|
||||
ray_depth))
|
||||
if (!snap_object_context_runtime_init(sctx,
|
||||
depsgraph,
|
||||
nullptr,
|
||||
v3d,
|
||||
SCE_SNAP_MODE_FACE,
|
||||
params,
|
||||
ray_start,
|
||||
ray_normal,
|
||||
!ray_depth || *ray_depth == -1.0f ? BVH_RAYCAST_DIST_MAX :
|
||||
*ray_depth,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
params->use_occlusion_test))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (raycastObjects(sctx)) {
|
||||
copy_v3_v3(r_loc, sctx->ret.loc);
|
||||
if (r_no) {
|
||||
copy_v3_v3(r_no, sctx->ret.no);
|
||||
@@ -1733,6 +1598,9 @@ bool ED_transform_snap_object_project_ray_ex(SnapObjectContext *sctx,
|
||||
if (r_obmat) {
|
||||
copy_m4_m4(r_obmat, sctx->ret.obmat);
|
||||
}
|
||||
if (ray_depth) {
|
||||
*ray_depth = sctx->ret.ray_depth_max;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -1748,41 +1616,35 @@ bool ED_transform_snap_object_project_ray_all(SnapObjectContext *sctx,
|
||||
bool sort,
|
||||
ListBase *r_hit_list)
|
||||
{
|
||||
sctx->runtime.depsgraph = depsgraph;
|
||||
sctx->runtime.v3d = v3d;
|
||||
|
||||
zero_v3(sctx->ret.loc);
|
||||
zero_v3(sctx->ret.no);
|
||||
sctx->ret.index = -1;
|
||||
zero_m4(sctx->ret.obmat);
|
||||
sctx->ret.hit_list = r_hit_list;
|
||||
sctx->ret.ob = nullptr;
|
||||
sctx->ret.data = nullptr;
|
||||
sctx->ret.dist_sq = FLT_MAX;
|
||||
sctx->ret.is_edit = false;
|
||||
|
||||
if (ray_depth == -1.0f) {
|
||||
ray_depth = BVH_RAYCAST_DIST_MAX;
|
||||
if (!snap_object_context_runtime_init(sctx,
|
||||
depsgraph,
|
||||
nullptr,
|
||||
v3d,
|
||||
SCE_SNAP_MODE_FACE,
|
||||
params,
|
||||
ray_start,
|
||||
ray_normal,
|
||||
ray_depth == -1.0f ? BVH_RAYCAST_DIST_MAX : ray_depth,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
0,
|
||||
r_hit_list,
|
||||
params->use_occlusion_test))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
float ray_depth_prev = ray_depth;
|
||||
float ray_depth_prev = sctx->ret.ray_depth_max;
|
||||
#endif
|
||||
|
||||
if (raycastObjects(sctx,
|
||||
params,
|
||||
ray_start,
|
||||
ray_normal,
|
||||
params->use_occlusion_test,
|
||||
params->use_occlusion_test,
|
||||
&ray_depth))
|
||||
{
|
||||
if (raycastObjects(sctx)) {
|
||||
if (sort) {
|
||||
BLI_listbase_sort(r_hit_list, hit_depth_cmp);
|
||||
}
|
||||
/* meant to be readonly for 'all' hits, ensure it is */
|
||||
#ifdef DEBUG
|
||||
BLI_assert(ray_depth_prev == ray_depth);
|
||||
BLI_assert(ray_depth_prev == sctx->ret.ray_depth_max);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
@@ -1796,115 +1658,94 @@ bool ED_transform_snap_object_project_ray_all(SnapObjectContext *sctx,
|
||||
*
|
||||
* \return Snap success
|
||||
*/
|
||||
static bool transform_snap_context_project_ray_impl(SnapObjectContext *sctx,
|
||||
Depsgraph *depsgraph,
|
||||
const View3D *v3d,
|
||||
const SnapObjectParams *params,
|
||||
const float ray_start[3],
|
||||
const float ray_normal[3],
|
||||
float *ray_depth,
|
||||
float r_co[3],
|
||||
float r_no[3])
|
||||
{
|
||||
bool ret;
|
||||
|
||||
/* try snap edge, then face if it fails */
|
||||
ret = ED_transform_snap_object_project_ray_ex(sctx,
|
||||
depsgraph,
|
||||
v3d,
|
||||
params,
|
||||
ray_start,
|
||||
ray_normal,
|
||||
ray_depth,
|
||||
r_co,
|
||||
r_no,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ED_transform_snap_object_project_ray(SnapObjectContext *sctx,
|
||||
Depsgraph *depsgraph,
|
||||
const View3D *v3d,
|
||||
const SnapObjectParams *params,
|
||||
const float ray_origin[3],
|
||||
const float ray_direction[3],
|
||||
const float ray_start[3],
|
||||
const float ray_normal[3],
|
||||
float *ray_depth,
|
||||
float r_co[3],
|
||||
float r_no[3])
|
||||
{
|
||||
float ray_depth_fallback;
|
||||
if (ray_depth == nullptr) {
|
||||
ray_depth_fallback = BVH_RAYCAST_DIST_MAX;
|
||||
ray_depth = &ray_depth_fallback;
|
||||
}
|
||||
|
||||
return transform_snap_context_project_ray_impl(
|
||||
sctx, depsgraph, v3d, params, ray_origin, ray_direction, ray_depth, r_co, r_no);
|
||||
return ED_transform_snap_object_project_ray_ex(sctx,
|
||||
depsgraph,
|
||||
v3d,
|
||||
params,
|
||||
ray_start,
|
||||
ray_normal,
|
||||
ray_depth,
|
||||
r_co,
|
||||
r_no,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectContext *sctx,
|
||||
Depsgraph *depsgraph,
|
||||
const ARegion *region,
|
||||
const View3D *v3d,
|
||||
eSnapMode snap_to_flag,
|
||||
const SnapObjectParams *params,
|
||||
const float init_co[3],
|
||||
const float mval[2],
|
||||
const float prev_co[3],
|
||||
float *dist_px,
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index,
|
||||
Object **r_ob,
|
||||
float r_obmat[4][4],
|
||||
float r_face_nor[3])
|
||||
eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
|
||||
Depsgraph *depsgraph,
|
||||
const ARegion *region,
|
||||
const View3D *v3d,
|
||||
eSnapMode snap_to_flag,
|
||||
const SnapObjectParams *params,
|
||||
const float init_co[3],
|
||||
const float mval[2],
|
||||
const float prev_co[3],
|
||||
float *dist_px,
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index,
|
||||
Object **r_ob,
|
||||
float r_obmat[4][4],
|
||||
float r_face_nor[3])
|
||||
{
|
||||
sctx->runtime.depsgraph = depsgraph;
|
||||
sctx->runtime.region = region;
|
||||
sctx->runtime.v3d = v3d;
|
||||
|
||||
zero_v3(sctx->ret.loc);
|
||||
zero_v3(sctx->ret.no);
|
||||
sctx->ret.index = -1;
|
||||
zero_m4(sctx->ret.obmat);
|
||||
sctx->ret.hit_list = nullptr;
|
||||
sctx->ret.ob = nullptr;
|
||||
sctx->ret.data = nullptr;
|
||||
sctx->ret.dist_sq = FLT_MAX;
|
||||
sctx->ret.is_edit = false;
|
||||
|
||||
BLI_assert(snap_to_flag & (SCE_SNAP_MODE_GEOM | SCE_SNAP_MODE_FACE_NEAREST));
|
||||
|
||||
eSnapMode retval = SCE_SNAP_MODE_NONE;
|
||||
|
||||
bool has_hit = false;
|
||||
|
||||
const RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
|
||||
|
||||
bool use_occlusion_test = params->use_occlusion_test;
|
||||
|
||||
if (use_occlusion_test && XRAY_ENABLED(v3d) && (snap_to_flag & SCE_SNAP_MODE_FACE)) {
|
||||
if (snap_to_flag != SCE_SNAP_MODE_FACE) {
|
||||
/* In theory everything is visible in X-Ray except faces. */
|
||||
if (use_occlusion_test || (snap_to_flag & SCE_SNAP_MODE_FACE)) {
|
||||
if (!ED_view3d_win_to_ray_clipped_ex(depsgraph,
|
||||
region,
|
||||
v3d,
|
||||
mval,
|
||||
nullptr,
|
||||
sctx->runtime.ray_dir,
|
||||
sctx->runtime.ray_start,
|
||||
true))
|
||||
{
|
||||
snap_to_flag &= ~SCE_SNAP_MODE_FACE;
|
||||
use_occlusion_test = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (prev_co == nullptr) {
|
||||
snap_to_flag &= ~(SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_FACE_NEAREST);
|
||||
}
|
||||
else if (init_co == nullptr) {
|
||||
snap_to_flag &= ~SCE_SNAP_MODE_FACE_NEAREST;
|
||||
if (!snap_object_context_runtime_init(sctx,
|
||||
depsgraph,
|
||||
region,
|
||||
v3d,
|
||||
snap_to_flag,
|
||||
params,
|
||||
sctx->runtime.ray_start,
|
||||
sctx->runtime.ray_dir,
|
||||
BVH_RAYCAST_DIST_MAX,
|
||||
mval,
|
||||
init_co,
|
||||
prev_co,
|
||||
square_f(*dist_px),
|
||||
nullptr,
|
||||
use_occlusion_test))
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
snap_to_flag = sctx->runtime.snap_to_flag;
|
||||
|
||||
BLI_assert(snap_to_flag & (SCE_SNAP_MODE_GEOM | SCE_SNAP_MODE_FACE_NEAREST));
|
||||
|
||||
bool has_hit = false;
|
||||
|
||||
/* NOTE: if both face ray-cast and face nearest are enabled, first find result of nearest, then
|
||||
* override with ray-cast. */
|
||||
if ((snap_to_flag & SCE_SNAP_MODE_FACE_NEAREST) && !has_hit) {
|
||||
has_hit = nearestWorldObjects(sctx, params, init_co, prev_co);
|
||||
has_hit = nearestWorldObjects(sctx);
|
||||
|
||||
if (has_hit) {
|
||||
retval = SCE_SNAP_MODE_FACE_NEAREST;
|
||||
@@ -1925,23 +1766,8 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
|
||||
}
|
||||
}
|
||||
|
||||
if ((snap_to_flag & SCE_SNAP_MODE_FACE) || use_occlusion_test) {
|
||||
float ray_start[3], ray_normal[3];
|
||||
if (!ED_view3d_win_to_ray_clipped_ex(
|
||||
depsgraph, region, v3d, mval, nullptr, ray_normal, ray_start, true))
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
float dummy_ray_depth = BVH_RAYCAST_DIST_MAX;
|
||||
|
||||
has_hit = raycastObjects(sctx,
|
||||
params,
|
||||
ray_start,
|
||||
ray_normal,
|
||||
use_occlusion_test,
|
||||
use_occlusion_test && (snap_to_flag & SCE_SNAP_MODE_FACE) == 0,
|
||||
&dummy_ray_depth);
|
||||
if ((snap_to_flag & SCE_SNAP_MODE_FACE) || sctx->runtime.params.use_occlusion_test) {
|
||||
has_hit = raycastObjects(sctx);
|
||||
|
||||
if (has_hit) {
|
||||
if (r_face_nor) {
|
||||
@@ -1972,33 +1798,13 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
|
||||
SCE_SNAP_MODE_EDGE_PERPENDICULAR))
|
||||
{
|
||||
eSnapMode elem_test, elem = SCE_SNAP_MODE_NONE;
|
||||
float dist_px_tmp = *dist_px;
|
||||
|
||||
copy_m4_m4(sctx->runtime.pmat, rv3d->persmat);
|
||||
sctx->runtime.win_size[0] = region->winx;
|
||||
sctx->runtime.win_size[1] = region->winy;
|
||||
copy_v2_v2(sctx->runtime.mval, mval);
|
||||
sctx->runtime.view_proj = rv3d->is_persp ? VIEW_PROJ_PERSP : VIEW_PROJ_ORTHO;
|
||||
|
||||
/* First snap to edge instead of middle or perpendicular. */
|
||||
sctx->runtime.snap_to_flag = static_cast<eSnapMode>(
|
||||
snap_to_flag & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE));
|
||||
sctx->runtime.snap_to_flag &= (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE);
|
||||
if (snap_to_flag & (SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
|
||||
sctx->runtime.snap_to_flag = static_cast<eSnapMode>(sctx->runtime.snap_to_flag |
|
||||
SCE_SNAP_MODE_EDGE);
|
||||
sctx->runtime.snap_to_flag |= SCE_SNAP_MODE_EDGE;
|
||||
}
|
||||
|
||||
planes_from_projmat(sctx->runtime.pmat,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
sctx->runtime.clip_plane[0],
|
||||
sctx->runtime.clip_plane[1]);
|
||||
|
||||
sctx->runtime.clip_plane_len = 2;
|
||||
sctx->runtime.has_occlusion_plane = false;
|
||||
|
||||
/* By convention we only snap to the original elements of a curve. */
|
||||
if (has_hit && sctx->ret.ob->type != OB_CURVES_LEGACY) {
|
||||
/* Compute the new clip_pane but do not add it yet. */
|
||||
@@ -2014,7 +1820,7 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
|
||||
new_clipplane[3] += 0.01f;
|
||||
|
||||
/* Try to snap only to the polygon. */
|
||||
elem_test = snap_polygon(sctx, params, &dist_px_tmp);
|
||||
elem_test = snap_polygon(sctx, sctx->runtime.snap_to_flag);
|
||||
if (elem_test) {
|
||||
elem = elem_test;
|
||||
}
|
||||
@@ -2028,7 +1834,7 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
|
||||
sctx->runtime.has_occlusion_plane = true;
|
||||
}
|
||||
|
||||
elem_test = snapObjectsRay(sctx, params, &dist_px_tmp);
|
||||
elem_test = snapObjectsRay(sctx);
|
||||
if (elem_test) {
|
||||
elem = elem_test;
|
||||
}
|
||||
@@ -2038,7 +1844,7 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
|
||||
(SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)))
|
||||
{
|
||||
sctx->runtime.snap_to_flag = snap_to_flag;
|
||||
elem = snap_mesh_edge_verts_mixed(sctx, params, *dist_px, prev_co, &dist_px_tmp);
|
||||
elem = snap_mesh_edge_verts_mixed(sctx, *dist_px);
|
||||
}
|
||||
|
||||
if (elem & snap_to_flag) {
|
||||
@@ -2058,48 +1864,13 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
|
||||
*r_index = sctx->ret.index;
|
||||
}
|
||||
|
||||
*dist_px = dist_px_tmp;
|
||||
*dist_px = blender::math::sqrt(sctx->ret.dist_px_sq);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
|
||||
Depsgraph *depsgraph,
|
||||
const ARegion *region,
|
||||
const View3D *v3d,
|
||||
const eSnapMode snap_to,
|
||||
const SnapObjectParams *params,
|
||||
const float init_co[3],
|
||||
const float mval[2],
|
||||
const float prev_co[3],
|
||||
float *dist_px,
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index,
|
||||
Object **r_ob,
|
||||
float r_obmat[4][4],
|
||||
float r_face_nor[3])
|
||||
{
|
||||
return transform_snap_context_project_view3d_mixed_impl(sctx,
|
||||
depsgraph,
|
||||
region,
|
||||
v3d,
|
||||
snap_to,
|
||||
params,
|
||||
init_co,
|
||||
mval,
|
||||
prev_co,
|
||||
dist_px,
|
||||
r_loc,
|
||||
r_no,
|
||||
r_index,
|
||||
r_ob,
|
||||
r_obmat,
|
||||
r_face_nor);
|
||||
}
|
||||
|
||||
eSnapMode ED_transform_snap_object_project_view3d(SnapObjectContext *sctx,
|
||||
Depsgraph *depsgraph,
|
||||
const ARegion *region,
|
||||
|
||||
@@ -10,12 +10,6 @@
|
||||
|
||||
#define MAX_CLIPPLANE_LEN 3
|
||||
|
||||
enum eViewProj {
|
||||
VIEW_PROJ_NONE = -1,
|
||||
VIEW_PROJ_ORTHO = 0,
|
||||
VIEW_PROJ_PERSP = -1,
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Internal Data Types
|
||||
* \{ */
|
||||
@@ -58,8 +52,6 @@ struct SnapData_EditMesh {
|
||||
struct SnapObjectContext {
|
||||
struct Scene *scene;
|
||||
|
||||
int flag;
|
||||
|
||||
blender::Map<const BMEditMesh *, std::unique_ptr<SnapData_EditMesh>> editmesh_caches;
|
||||
|
||||
/* Filter data, returns true to check this value */
|
||||
@@ -77,14 +69,27 @@ struct SnapObjectContext {
|
||||
const ARegion *region;
|
||||
const View3D *v3d;
|
||||
|
||||
eSnapMode snap_to_flag;
|
||||
SnapObjectParams params;
|
||||
|
||||
float ray_start[3];
|
||||
float ray_dir[3];
|
||||
float mval[2];
|
||||
|
||||
float init_co[3];
|
||||
float curr_co[3];
|
||||
|
||||
float pmat[4][4]; /* perspective matrix */
|
||||
float win_size[2]; /* win x and y */
|
||||
enum eViewProj view_proj;
|
||||
float clip_plane[MAX_CLIPPLANE_LEN][4];
|
||||
short clip_plane_len;
|
||||
eSnapMode snap_to_flag;
|
||||
int clip_plane_len;
|
||||
|
||||
/* read/write */
|
||||
uint object_index;
|
||||
|
||||
bool is_persp;
|
||||
bool has_occlusion_plane; /* Ignore plane of occlusion in curves. */
|
||||
bool use_occlusion_test_edit;
|
||||
} runtime;
|
||||
|
||||
/* Output. */
|
||||
@@ -104,7 +109,8 @@ struct SnapObjectContext {
|
||||
/* Snapped data. */
|
||||
ID *data;
|
||||
|
||||
float dist_sq;
|
||||
float ray_depth_max;
|
||||
float dist_px_sq;
|
||||
|
||||
bool is_edit;
|
||||
} ret;
|
||||
@@ -203,7 +209,6 @@ void cb_snap_edge(void *userdata,
|
||||
BVHTreeNearest *nearest);
|
||||
|
||||
bool nearest_world_tree(SnapObjectContext *sctx,
|
||||
const struct SnapObjectParams *params,
|
||||
BVHTree *tree,
|
||||
BVHTree_NearestPointCallback nearest_cb,
|
||||
void *treedata,
|
||||
@@ -217,57 +222,20 @@ bool nearest_world_tree(SnapObjectContext *sctx,
|
||||
|
||||
/* transform_snap_object_editmesh.cc */
|
||||
|
||||
bool raycastEditMesh(SnapObjectContext *sctx,
|
||||
const struct SnapObjectParams *params,
|
||||
const float ray_start[3],
|
||||
const float ray_dir[3],
|
||||
Object *ob_eval,
|
||||
BMEditMesh *em,
|
||||
const float obmat[4][4],
|
||||
const uint ob_index,
|
||||
/* read/write args */
|
||||
float *ray_depth,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index,
|
||||
ListBase *r_hit_list);
|
||||
eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
ID *id,
|
||||
const float obmat[4][4],
|
||||
eSnapMode snap_to_flag,
|
||||
bool use_hide);
|
||||
|
||||
eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
BMEditMesh *em,
|
||||
Object *ob_eval,
|
||||
ID *id,
|
||||
const float obmat[4][4],
|
||||
float clip_planes_local[MAX_CLIPPLANE_LEN][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index);
|
||||
|
||||
eSnapMode snapEditMesh(struct SnapObjectContext *sctx,
|
||||
const struct SnapObjectParams *params,
|
||||
struct Object *ob_eval,
|
||||
struct BMEditMesh *em,
|
||||
const float obmat[4][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index);
|
||||
|
||||
bool nearest_world_editmesh(struct SnapObjectContext *sctx,
|
||||
const struct SnapObjectParams *params,
|
||||
struct Object *ob_eval,
|
||||
struct BMEditMesh *em,
|
||||
const float (*obmat)[4],
|
||||
const float init_co[3],
|
||||
const float curr_co[3],
|
||||
float *r_dist_sq,
|
||||
float *r_loc,
|
||||
float *r_no,
|
||||
int *r_index);
|
||||
eSnapMode snap_to_flag,
|
||||
int polygon,
|
||||
const float clip_planes_local[MAX_CLIPPLANE_LEN][4]);
|
||||
|
||||
void nearest2d_data_init_editmesh(struct BMEditMesh *em,
|
||||
bool is_persp,
|
||||
@@ -276,60 +244,22 @@ void nearest2d_data_init_editmesh(struct BMEditMesh *em,
|
||||
|
||||
/* transform_snap_object_mesh.cc */
|
||||
|
||||
bool raycastMesh(const struct SnapObjectParams *params,
|
||||
const float ray_start[3],
|
||||
const float ray_dir[3],
|
||||
struct Object *ob_eval,
|
||||
const struct Mesh *me_eval,
|
||||
const float obmat[4][4],
|
||||
const uint ob_index,
|
||||
bool use_hide,
|
||||
/* read/write args */
|
||||
float *ray_depth,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index,
|
||||
struct ListBase *r_hit_list);
|
||||
eSnapMode snap_object_mesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
ID *id,
|
||||
const float obmat[4][4],
|
||||
eSnapMode snap_to_flag,
|
||||
bool use_hide);
|
||||
|
||||
bool nearest_world_mesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
const Mesh *me_eval,
|
||||
const float (*obmat)[4],
|
||||
bool use_hide,
|
||||
const float init_co[3],
|
||||
const float curr_co[3],
|
||||
float *r_dist_sq,
|
||||
float *r_loc,
|
||||
float *r_no,
|
||||
int *r_index);
|
||||
eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
ID *id,
|
||||
const float obmat[4][4],
|
||||
eSnapMode snap_to_flag,
|
||||
int polygon,
|
||||
const float clip_planes_local[MAX_CLIPPLANE_LEN][4]);
|
||||
|
||||
void nearest2d_data_init_mesh(const Mesh *mesh,
|
||||
bool is_persp,
|
||||
bool use_backface_culling,
|
||||
Nearest2dUserData *r_nearest2d);
|
||||
|
||||
eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
const Mesh *mesh,
|
||||
const float obmat[4][4],
|
||||
float clip_planes_local[MAX_CLIPPLANE_LEN][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index);
|
||||
|
||||
eSnapMode snapMesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
Object *ob_eval,
|
||||
const Mesh *me_eval,
|
||||
const float obmat[4][4],
|
||||
bool use_hide,
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index);
|
||||
|
||||
@@ -66,9 +66,10 @@ static blender::bke::MeshRuntime *snap_object_data_editmesh_runtime_get(Object *
|
||||
|
||||
static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
BMEditMesh *em)
|
||||
BMEditMesh *em,
|
||||
const bool create)
|
||||
{
|
||||
SnapData_EditMesh *sod;
|
||||
SnapData_EditMesh *sod = nullptr;
|
||||
bool init = false;
|
||||
|
||||
if (std::unique_ptr<SnapData_EditMesh> *sod_p = sctx->editmesh_caches.lookup_ptr(em)) {
|
||||
@@ -114,7 +115,7 @@ static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
|
||||
init = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (create) {
|
||||
std::unique_ptr<SnapData_EditMesh> sod_ptr = std::make_unique<SnapData_EditMesh>();
|
||||
sod = sod_ptr.get();
|
||||
sctx->editmesh_caches.add_new(em, std::move(sod_ptr));
|
||||
@@ -122,6 +123,9 @@ static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
if (init) {
|
||||
/* Operators only update the editmesh looptris of the original mesh. */
|
||||
BLI_assert(em == BKE_editmesh_from_object(DEG_get_original_object(ob_eval)));
|
||||
|
||||
sod->treedata_editmesh.em = em;
|
||||
sod->mesh_runtime = snap_object_data_editmesh_runtime_get(ob_eval);
|
||||
snap_editmesh_minmax(sctx, em->bm, sod->min, sod->max);
|
||||
@@ -130,18 +134,13 @@ static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
|
||||
return sod;
|
||||
}
|
||||
|
||||
static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapData_EditMesh *sod,
|
||||
SnapObjectContext *sctx,
|
||||
BMEditMesh *em)
|
||||
{
|
||||
SnapData_EditMesh *sod = snap_object_data_editmesh_get(sctx, ob_eval, em);
|
||||
|
||||
BVHTreeFromEditMesh *treedata = &sod->treedata_editmesh;
|
||||
|
||||
if (treedata->tree == nullptr) {
|
||||
/* Operators only update the editmesh looptris of the original mesh. */
|
||||
BLI_assert(sod->treedata_editmesh.em ==
|
||||
BKE_editmesh_from_object(DEG_get_original_object(ob_eval)));
|
||||
em = sod->treedata_editmesh.em;
|
||||
|
||||
if (sctx->callbacks.edit_mesh.test_face_fn) {
|
||||
@@ -178,6 +177,50 @@ static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapObjectCon
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Snap Object Data
|
||||
* \{ */
|
||||
|
||||
static eSnapMode editmesh_snap_mode_supported(BMEditMesh *em)
|
||||
{
|
||||
eSnapMode snap_mode_supported = SCE_SNAP_MODE_NONE;
|
||||
if (em->bm->totface) {
|
||||
snap_mode_supported |= SCE_SNAP_MODE_FACE | SCE_SNAP_MODE_FACE_NEAREST;
|
||||
}
|
||||
if (em->bm->totedge) {
|
||||
snap_mode_supported |= SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT |
|
||||
SCE_SNAP_MODE_EDGE_PERPENDICULAR;
|
||||
}
|
||||
if (em->bm->totvert) {
|
||||
snap_mode_supported |= SCE_SNAP_MODE_VERTEX;
|
||||
}
|
||||
return snap_mode_supported;
|
||||
}
|
||||
|
||||
static SnapData_EditMesh *editmesh_snapdata_init(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
eSnapMode snap_to_flag)
|
||||
{
|
||||
BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
|
||||
if (em == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SnapData_EditMesh *sod = snap_object_data_editmesh_get(sctx, ob_eval, em, false);
|
||||
if (sod != nullptr) {
|
||||
return sod;
|
||||
}
|
||||
|
||||
eSnapMode snap_mode_used = snap_to_flag & editmesh_snap_mode_supported(em);
|
||||
if (snap_mode_used == SCE_SNAP_MODE_NONE) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return snap_object_data_editmesh_get(sctx, ob_eval, em, true);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Ray Cast Functions
|
||||
* \{ */
|
||||
@@ -212,26 +255,21 @@ static void editmesh_looptri_raycast_backface_culling_cb(void *userdata,
|
||||
}
|
||||
}
|
||||
|
||||
bool raycastEditMesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
const float ray_start[3],
|
||||
const float ray_dir[3],
|
||||
Object *ob_eval,
|
||||
BMEditMesh *em,
|
||||
const float obmat[4][4],
|
||||
const uint ob_index,
|
||||
/* read/write args */
|
||||
float *ray_depth,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index,
|
||||
ListBase *r_hit_list)
|
||||
static bool raycastEditMesh(SnapData_EditMesh *sod,
|
||||
SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
BMEditMesh *em,
|
||||
const float obmat[4][4],
|
||||
const uint ob_index,
|
||||
/* read/write args */
|
||||
float *ray_depth,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index,
|
||||
ListBase *r_hit_list)
|
||||
{
|
||||
bool retval = false;
|
||||
if (em->bm->totface == 0) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
float imat[4][4];
|
||||
float ray_start_local[3], ray_normal_local[3];
|
||||
@@ -239,8 +277,8 @@ bool raycastEditMesh(SnapObjectContext *sctx,
|
||||
|
||||
invert_m4_m4(imat, obmat);
|
||||
|
||||
copy_v3_v3(ray_start_local, ray_start);
|
||||
copy_v3_v3(ray_normal_local, ray_dir);
|
||||
copy_v3_v3(ray_start_local, sctx->runtime.ray_start);
|
||||
copy_v3_v3(ray_normal_local, sctx->runtime.ray_dir);
|
||||
|
||||
mul_m4_v3(imat, ray_start_local);
|
||||
mul_mat3_m4_v3(imat, ray_normal_local);
|
||||
@@ -252,8 +290,6 @@ bool raycastEditMesh(SnapObjectContext *sctx,
|
||||
local_depth *= local_scale;
|
||||
}
|
||||
|
||||
SnapData_EditMesh *sod = snap_object_data_editmesh_get(sctx, ob_eval, em);
|
||||
|
||||
/* Test BoundBox */
|
||||
|
||||
/* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
|
||||
@@ -275,7 +311,7 @@ bool raycastEditMesh(SnapObjectContext *sctx,
|
||||
len_diff = 0.0f;
|
||||
}
|
||||
|
||||
BVHTreeFromEditMesh *treedata = snap_object_data_editmesh_treedata_get(sctx, ob_eval, em);
|
||||
BVHTreeFromEditMesh *treedata = snap_object_data_editmesh_treedata_get(sod, sctx, em);
|
||||
if (treedata == nullptr) {
|
||||
return retval;
|
||||
}
|
||||
@@ -317,7 +353,7 @@ bool raycastEditMesh(SnapObjectContext *sctx,
|
||||
ray_normal_local,
|
||||
0.0f,
|
||||
&hit,
|
||||
params->use_backface_culling ?
|
||||
sctx->runtime.params.use_backface_culling ?
|
||||
editmesh_looptri_raycast_backface_culling_cb :
|
||||
treedata->raycast_callback,
|
||||
treedata) != -1)
|
||||
@@ -355,25 +391,23 @@ bool raycastEditMesh(SnapObjectContext *sctx,
|
||||
/** \name Surface Snap Functions
|
||||
* \{ */
|
||||
|
||||
bool nearest_world_editmesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
Object *ob_eval,
|
||||
BMEditMesh *em,
|
||||
const float (*obmat)[4],
|
||||
const float init_co[3],
|
||||
const float curr_co[3],
|
||||
float *r_dist_sq,
|
||||
float *r_loc,
|
||||
float *r_no,
|
||||
int *r_index)
|
||||
static bool nearest_world_editmesh(SnapData_EditMesh *sod,
|
||||
SnapObjectContext *sctx,
|
||||
BMEditMesh *em,
|
||||
const float (*obmat)[4],
|
||||
const float init_co[3],
|
||||
const float curr_co[3],
|
||||
float *r_dist_sq,
|
||||
float *r_loc,
|
||||
float *r_no,
|
||||
int *r_index)
|
||||
{
|
||||
BVHTreeFromEditMesh *treedata = snap_object_data_editmesh_treedata_get(sctx, ob_eval, em);
|
||||
BVHTreeFromEditMesh *treedata = snap_object_data_editmesh_treedata_get(sod, sctx, em);
|
||||
if (treedata == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return nearest_world_tree(sctx,
|
||||
params,
|
||||
treedata->tree,
|
||||
treedata->nearest_callback,
|
||||
treedata,
|
||||
@@ -437,21 +471,22 @@ void nearest2d_data_init_editmesh(BMEditMesh *em,
|
||||
* \{ */
|
||||
|
||||
eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
BMEditMesh *em,
|
||||
Object *ob_eval,
|
||||
ID * /*id*/,
|
||||
const float obmat[4][4],
|
||||
float clip_planes_local[MAX_CLIPPLANE_LEN][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index)
|
||||
eSnapMode snap_to_flag,
|
||||
int polygon,
|
||||
const float clip_planes_local[MAX_CLIPPLANE_LEN][4])
|
||||
{
|
||||
BLI_assert(sctx->editmesh_caches.lookup(em).get()->treedata_editmesh.em == em);
|
||||
|
||||
eSnapMode elem = SCE_SNAP_MODE_NONE;
|
||||
|
||||
SnapData_EditMesh *sod = editmesh_snapdata_init(sctx, ob_eval, snap_to_flag);
|
||||
if (sod == nullptr) {
|
||||
return elem;
|
||||
}
|
||||
|
||||
BMEditMesh *em = sod->treedata_editmesh.em;
|
||||
|
||||
float lpmat[4][4];
|
||||
mul_m4_m4m4(lpmat, sctx->runtime.pmat, obmat);
|
||||
|
||||
@@ -461,18 +496,18 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
|
||||
|
||||
BVHTreeNearest nearest{};
|
||||
nearest.index = -1;
|
||||
nearest.dist_sq = square_f(*dist_px);
|
||||
nearest.dist_sq = sctx->ret.dist_px_sq;
|
||||
|
||||
Nearest2dUserData nearest2d;
|
||||
|
||||
nearest2d_data_init_editmesh(
|
||||
em, sctx->runtime.view_proj == VIEW_PROJ_PERSP, params->use_backface_culling, &nearest2d);
|
||||
em, sctx->runtime.is_persp, sctx->runtime.params.use_backface_culling, &nearest2d);
|
||||
|
||||
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
|
||||
BMFace *f = BM_face_at_index(em->bm, sctx->ret.index);
|
||||
BMFace *f = BM_face_at_index(em->bm, polygon);
|
||||
BMLoop *l_iter, *l_first;
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) {
|
||||
if (snap_to_flag & SCE_SNAP_MODE_EDGE) {
|
||||
elem = SCE_SNAP_MODE_EDGE;
|
||||
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_EDGE);
|
||||
BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE);
|
||||
@@ -500,10 +535,10 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
if (nearest.index != -1) {
|
||||
*dist_px = sqrtf(nearest.dist_sq);
|
||||
sctx->ret.dist_px_sq = nearest.dist_sq;
|
||||
|
||||
mul_m4_v3(obmat, nearest.co);
|
||||
copy_v3_v3(r_loc, nearest.co);
|
||||
copy_v3_v3(sctx->ret.loc, nearest.co);
|
||||
|
||||
{
|
||||
float imat[4][4];
|
||||
@@ -511,58 +546,42 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
|
||||
mul_transposed_mat3_m4_v3(imat, nearest.no);
|
||||
normalize_v3(nearest.no);
|
||||
|
||||
copy_v3_v3(r_no, nearest.no);
|
||||
copy_v3_v3(sctx->ret.no, nearest.no);
|
||||
}
|
||||
|
||||
*r_index = nearest.index;
|
||||
sctx->ret.index = nearest.index;
|
||||
return elem;
|
||||
}
|
||||
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
||||
eSnapMode snapEditMesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
Object *ob_eval,
|
||||
BMEditMesh *em,
|
||||
const float obmat[4][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index)
|
||||
static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
|
||||
SnapObjectContext *sctx,
|
||||
BMEditMesh *em,
|
||||
const float obmat[4][4],
|
||||
eSnapMode snap_to_flag,
|
||||
/* read/write args */
|
||||
float *dist_px_sq,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index)
|
||||
{
|
||||
BLI_assert(sctx->runtime.snap_to_flag != SCE_SNAP_MODE_FACE);
|
||||
|
||||
if ((sctx->runtime.snap_to_flag & ~SCE_SNAP_MODE_FACE) == SCE_SNAP_MODE_VERTEX) {
|
||||
if (em->bm->totvert == 0) {
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (em->bm->totedge == 0) {
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
BLI_assert(snap_to_flag != SCE_SNAP_MODE_FACE);
|
||||
float lpmat[4][4];
|
||||
mul_m4_m4m4(lpmat, sctx->runtime.pmat, obmat);
|
||||
|
||||
float dist_px_sq = square_f(*dist_px);
|
||||
|
||||
SnapData_EditMesh *sod = snap_object_data_editmesh_get(sctx, ob_eval, em);
|
||||
|
||||
/* Test BoundBox */
|
||||
|
||||
/* Was BKE_boundbox_ray_hit_check, see: cf6ca226fa58. */
|
||||
if (!snap_bound_box_check_dist(
|
||||
sod->min, sod->max, lpmat, sctx->runtime.win_size, sctx->runtime.mval, dist_px_sq))
|
||||
sod->min, sod->max, lpmat, sctx->runtime.win_size, sctx->runtime.mval, *dist_px_sq))
|
||||
{
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
||||
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) {
|
||||
if (snap_to_flag & SCE_SNAP_MODE_VERTEX) {
|
||||
BVHTreeFromEditMesh treedata{};
|
||||
treedata.tree = sod->bvhtree[0];
|
||||
|
||||
@@ -592,7 +611,7 @@ eSnapMode snapEditMesh(SnapObjectContext *sctx,
|
||||
}
|
||||
}
|
||||
|
||||
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) {
|
||||
if (snap_to_flag & SCE_SNAP_MODE_EDGE) {
|
||||
BVHTreeFromEditMesh treedata{};
|
||||
treedata.tree = sod->bvhtree[1];
|
||||
|
||||
@@ -624,13 +643,13 @@ eSnapMode snapEditMesh(SnapObjectContext *sctx,
|
||||
|
||||
Nearest2dUserData nearest2d;
|
||||
nearest2d_data_init_editmesh(sod->treedata_editmesh.em,
|
||||
sctx->runtime.view_proj == VIEW_PROJ_PERSP,
|
||||
params->use_backface_culling,
|
||||
sctx->runtime.is_persp,
|
||||
sctx->runtime.params.use_backface_culling,
|
||||
&nearest2d);
|
||||
|
||||
BVHTreeNearest nearest{};
|
||||
nearest.index = -1;
|
||||
nearest.dist_sq = dist_px_sq;
|
||||
nearest.dist_sq = *dist_px_sq;
|
||||
|
||||
eSnapMode elem = SCE_SNAP_MODE_VERTEX;
|
||||
|
||||
@@ -641,7 +660,7 @@ eSnapMode snapEditMesh(SnapObjectContext *sctx,
|
||||
mul_v4_m4v4(clip_planes_local[i], tobmat, sctx->runtime.clip_plane[i]);
|
||||
}
|
||||
|
||||
if (sod->bvhtree[0] && (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX)) {
|
||||
if (sod->bvhtree[0] && (snap_to_flag & SCE_SNAP_MODE_VERTEX)) {
|
||||
BM_mesh_elem_table_ensure(em->bm, BM_VERT);
|
||||
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
|
||||
BLI_bvhtree_find_nearest_projected(sod->bvhtree[0],
|
||||
@@ -655,7 +674,7 @@ eSnapMode snapEditMesh(SnapObjectContext *sctx,
|
||||
&nearest2d);
|
||||
}
|
||||
|
||||
if (sod->bvhtree[1] && (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE)) {
|
||||
if (sod->bvhtree[1] && (snap_to_flag & SCE_SNAP_MODE_EDGE)) {
|
||||
int last_index = nearest.index;
|
||||
nearest.index = -1;
|
||||
BM_mesh_elem_table_ensure(em->bm, BM_EDGE | BM_VERT);
|
||||
@@ -679,7 +698,7 @@ eSnapMode snapEditMesh(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
if (nearest.index != -1) {
|
||||
*dist_px = sqrtf(nearest.dist_sq);
|
||||
*dist_px_sq = nearest.dist_sq;
|
||||
|
||||
copy_v3_v3(r_loc, nearest.co);
|
||||
mul_m4_v3(obmat, r_loc);
|
||||
@@ -702,3 +721,75 @@ eSnapMode snapEditMesh(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
ID * /*id*/,
|
||||
const float obmat[4][4],
|
||||
eSnapMode snap_to_flag,
|
||||
bool /*use_hide*/)
|
||||
{
|
||||
eSnapMode elem = SCE_SNAP_MODE_NONE;
|
||||
|
||||
SnapData_EditMesh *sod = editmesh_snapdata_init(sctx, ob_eval, snap_to_flag);
|
||||
if (sod == nullptr) {
|
||||
return elem;
|
||||
}
|
||||
|
||||
BMEditMesh *em = sod->treedata_editmesh.em;
|
||||
|
||||
eSnapMode snap_mode_used = snap_to_flag & editmesh_snap_mode_supported(em);
|
||||
if (snap_mode_used & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT |
|
||||
SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_VERTEX))
|
||||
{
|
||||
elem = snapEditMesh(sod,
|
||||
sctx,
|
||||
em,
|
||||
obmat,
|
||||
snap_to_flag,
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index);
|
||||
if (elem) {
|
||||
return elem;
|
||||
}
|
||||
}
|
||||
|
||||
if (snap_mode_used & SCE_SNAP_MODE_FACE) {
|
||||
if (raycastEditMesh(sod,
|
||||
sctx,
|
||||
ob_eval,
|
||||
em,
|
||||
obmat,
|
||||
sctx->runtime.object_index++,
|
||||
/* read/write args */
|
||||
&sctx->ret.ray_depth_max,
|
||||
/* return args */
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index,
|
||||
sctx->ret.hit_list))
|
||||
{
|
||||
return SCE_SNAP_MODE_FACE;
|
||||
}
|
||||
}
|
||||
|
||||
if (snap_mode_used & SCE_SNAP_MODE_FACE_NEAREST) {
|
||||
if (nearest_world_editmesh(sod,
|
||||
sctx,
|
||||
em,
|
||||
obmat,
|
||||
sctx->runtime.init_co,
|
||||
sctx->runtime.curr_co,
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index))
|
||||
{
|
||||
return SCE_SNAP_MODE_FACE_NEAREST;
|
||||
}
|
||||
}
|
||||
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
||||
@@ -82,21 +82,19 @@ static void mesh_looptri_raycast_backface_culling_cb(void *userdata,
|
||||
}
|
||||
}
|
||||
|
||||
bool raycastMesh(const SnapObjectParams *params,
|
||||
const float ray_start[3],
|
||||
const float ray_dir[3],
|
||||
Object *ob_eval,
|
||||
const Mesh *me_eval,
|
||||
const float obmat[4][4],
|
||||
const uint ob_index,
|
||||
bool use_hide,
|
||||
/* read/write args */
|
||||
float *ray_depth,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index,
|
||||
ListBase *r_hit_list)
|
||||
static bool raycastMesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
const Mesh *me_eval,
|
||||
const float obmat[4][4],
|
||||
const uint ob_index,
|
||||
bool use_hide,
|
||||
/* read/write args */
|
||||
float *ray_depth,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index,
|
||||
ListBase *r_hit_list)
|
||||
{
|
||||
bool retval = false;
|
||||
|
||||
@@ -110,8 +108,8 @@ bool raycastMesh(const SnapObjectParams *params,
|
||||
|
||||
invert_m4_m4(imat, obmat);
|
||||
|
||||
copy_v3_v3(ray_start_local, ray_start);
|
||||
copy_v3_v3(ray_normal_local, ray_dir);
|
||||
copy_v3_v3(ray_start_local, sctx->runtime.ray_start);
|
||||
copy_v3_v3(ray_normal_local, sctx->runtime.ray_dir);
|
||||
|
||||
mul_m4_v3(imat, ray_start_local);
|
||||
mul_mat3_m4_v3(imat, ray_normal_local);
|
||||
@@ -191,7 +189,7 @@ bool raycastMesh(const SnapObjectParams *params,
|
||||
ray_normal_local,
|
||||
0.0f,
|
||||
&hit,
|
||||
params->use_backface_culling ?
|
||||
sctx->runtime.params.use_backface_culling ?
|
||||
mesh_looptri_raycast_backface_culling_cb :
|
||||
treedata.raycast_callback,
|
||||
&treedata) != -1)
|
||||
@@ -229,17 +227,16 @@ bool raycastMesh(const SnapObjectParams *params,
|
||||
/** \name Surface Snap Functions
|
||||
* \{ */
|
||||
|
||||
bool nearest_world_mesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
const Mesh *me_eval,
|
||||
const float (*obmat)[4],
|
||||
bool use_hide,
|
||||
const float init_co[3],
|
||||
const float curr_co[3],
|
||||
float *r_dist_sq,
|
||||
float *r_loc,
|
||||
float *r_no,
|
||||
int *r_index)
|
||||
static bool nearest_world_mesh(SnapObjectContext *sctx,
|
||||
const Mesh *me_eval,
|
||||
const float (*obmat)[4],
|
||||
bool use_hide,
|
||||
const float init_co[3],
|
||||
const float curr_co[3],
|
||||
float *r_dist_sq,
|
||||
float *r_loc,
|
||||
float *r_no,
|
||||
int *r_index)
|
||||
{
|
||||
BVHTreeFromMesh treedata;
|
||||
snap_object_data_mesh_get(me_eval, use_hide, &treedata);
|
||||
@@ -248,7 +245,6 @@ bool nearest_world_mesh(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
return nearest_world_tree(sctx,
|
||||
params,
|
||||
treedata.tree,
|
||||
treedata.nearest_callback,
|
||||
&treedata,
|
||||
@@ -429,19 +425,17 @@ void nearest2d_data_init_mesh(const Mesh *mesh,
|
||||
* \{ */
|
||||
|
||||
eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
const Mesh *mesh,
|
||||
Object * /*ob_eval*/,
|
||||
ID *id,
|
||||
const float obmat[4][4],
|
||||
float clip_planes_local[MAX_CLIPPLANE_LEN][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index)
|
||||
eSnapMode snap_to_flag,
|
||||
int polygon,
|
||||
const float clip_planes_local[MAX_CLIPPLANE_LEN][4])
|
||||
{
|
||||
eSnapMode elem = SCE_SNAP_MODE_NONE;
|
||||
|
||||
Mesh *mesh_eval = reinterpret_cast<Mesh *>(id);
|
||||
|
||||
float lpmat[4][4];
|
||||
mul_m4_m4m4(lpmat, sctx->runtime.pmat, obmat);
|
||||
|
||||
@@ -451,15 +445,15 @@ eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
|
||||
|
||||
BVHTreeNearest nearest{};
|
||||
nearest.index = -1;
|
||||
nearest.dist_sq = square_f(*dist_px);
|
||||
nearest.dist_sq = sctx->ret.dist_px_sq;
|
||||
|
||||
Nearest2dUserData nearest2d;
|
||||
nearest2d_data_init_mesh(
|
||||
mesh, sctx->runtime.view_proj == VIEW_PROJ_PERSP, params->use_backface_culling, &nearest2d);
|
||||
mesh_eval, sctx->runtime.is_persp, sctx->runtime.params.use_backface_culling, &nearest2d);
|
||||
|
||||
const blender::IndexRange poly = mesh->polys()[sctx->ret.index];
|
||||
const blender::IndexRange poly = mesh_eval->polys()[polygon];
|
||||
|
||||
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) {
|
||||
if (snap_to_flag & SCE_SNAP_MODE_EDGE) {
|
||||
elem = SCE_SNAP_MODE_EDGE;
|
||||
BLI_assert(nearest2d.edges != nullptr);
|
||||
const int *poly_edges = &nearest2d.corner_edges[poly.start()];
|
||||
@@ -486,10 +480,10 @@ eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
if (nearest.index != -1) {
|
||||
*dist_px = sqrtf(nearest.dist_sq);
|
||||
sctx->ret.dist_px_sq = sqrtf(nearest.dist_sq);
|
||||
|
||||
mul_m4_v3(obmat, nearest.co);
|
||||
copy_v3_v3(r_loc, nearest.co);
|
||||
copy_v3_v3(sctx->ret.loc, nearest.co);
|
||||
|
||||
{
|
||||
float imat[4][4];
|
||||
@@ -497,28 +491,27 @@ eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
|
||||
mul_transposed_mat3_m4_v3(imat, nearest.no);
|
||||
normalize_v3(nearest.no);
|
||||
|
||||
copy_v3_v3(r_no, nearest.no);
|
||||
copy_v3_v3(sctx->ret.no, nearest.no);
|
||||
}
|
||||
|
||||
*r_index = nearest.index;
|
||||
sctx->ret.index = nearest.index;
|
||||
return elem;
|
||||
}
|
||||
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
||||
eSnapMode snapMesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
Object *ob_eval,
|
||||
const Mesh *me_eval,
|
||||
const float obmat[4][4],
|
||||
bool use_hide,
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index)
|
||||
static eSnapMode snapMesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
const Mesh *me_eval,
|
||||
const float obmat[4][4],
|
||||
bool use_hide,
|
||||
/* read/write args */
|
||||
float *dist_px_sq,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index)
|
||||
{
|
||||
BLI_assert(sctx->runtime.snap_to_flag != SCE_SNAP_MODE_FACE);
|
||||
if (me_eval->totvert == 0) {
|
||||
@@ -531,13 +524,15 @@ eSnapMode snapMesh(SnapObjectContext *sctx,
|
||||
float lpmat[4][4];
|
||||
mul_m4_m4m4(lpmat, sctx->runtime.pmat, obmat);
|
||||
|
||||
float dist_px_sq = square_f(*dist_px);
|
||||
|
||||
/* Test BoundBox */
|
||||
if (ob_eval->data == me_eval) {
|
||||
const BoundBox *bb = BKE_object_boundbox_get(ob_eval);
|
||||
if (!snap_bound_box_check_dist(
|
||||
bb->vec[0], bb->vec[6], lpmat, sctx->runtime.win_size, sctx->runtime.mval, dist_px_sq))
|
||||
if (!snap_bound_box_check_dist(bb->vec[0],
|
||||
bb->vec[6],
|
||||
lpmat,
|
||||
sctx->runtime.win_size,
|
||||
sctx->runtime.mval,
|
||||
*dist_px_sq))
|
||||
{
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
@@ -555,14 +550,12 @@ eSnapMode snapMesh(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
Nearest2dUserData nearest2d;
|
||||
nearest2d_data_init_mesh(me_eval,
|
||||
sctx->runtime.view_proj == VIEW_PROJ_PERSP,
|
||||
params->use_backface_culling,
|
||||
&nearest2d);
|
||||
nearest2d_data_init_mesh(
|
||||
me_eval, sctx->runtime.is_persp, sctx->runtime.params.use_backface_culling, &nearest2d);
|
||||
|
||||
BVHTreeNearest nearest{};
|
||||
nearest.index = -1;
|
||||
nearest.dist_sq = dist_px_sq;
|
||||
nearest.dist_sq = *dist_px_sq;
|
||||
|
||||
int last_index = nearest.index;
|
||||
eSnapMode elem = SCE_SNAP_MODE_VERTEX;
|
||||
@@ -650,7 +643,7 @@ eSnapMode snapMesh(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
if (nearest.index != -1) {
|
||||
*dist_px = sqrtf(nearest.dist_sq);
|
||||
*dist_px_sq = nearest.dist_sq;
|
||||
|
||||
copy_v3_v3(r_loc, nearest.co);
|
||||
mul_m4_v3(obmat, r_loc);
|
||||
@@ -674,3 +667,86 @@ eSnapMode snapMesh(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
static eSnapMode mesh_snap_mode_supported(Mesh *mesh)
|
||||
{
|
||||
eSnapMode snap_mode_supported = SCE_SNAP_MODE_NONE;
|
||||
if (mesh->totpoly) {
|
||||
snap_mode_supported |= SCE_SNAP_MODE_FACE | SCE_SNAP_MODE_FACE_NEAREST;
|
||||
}
|
||||
if (mesh->totedge) {
|
||||
snap_mode_supported |= SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT |
|
||||
SCE_SNAP_MODE_EDGE_PERPENDICULAR;
|
||||
}
|
||||
if (mesh->totvert) {
|
||||
snap_mode_supported |= SCE_SNAP_MODE_VERTEX;
|
||||
}
|
||||
return snap_mode_supported;
|
||||
}
|
||||
|
||||
eSnapMode snap_object_mesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
ID *id,
|
||||
const float obmat[4][4],
|
||||
eSnapMode snap_to_flag,
|
||||
bool use_hide)
|
||||
{
|
||||
eSnapMode elem = SCE_SNAP_MODE_NONE;
|
||||
|
||||
Mesh *mesh_eval = reinterpret_cast<Mesh *>(id);
|
||||
|
||||
eSnapMode snap_mode_used = snap_to_flag & mesh_snap_mode_supported(mesh_eval);
|
||||
if (snap_mode_used & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT |
|
||||
SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_VERTEX))
|
||||
{
|
||||
elem = snapMesh(sctx,
|
||||
ob_eval,
|
||||
mesh_eval,
|
||||
obmat,
|
||||
use_hide,
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index);
|
||||
if (elem) {
|
||||
return elem;
|
||||
}
|
||||
}
|
||||
|
||||
if (snap_mode_used & SCE_SNAP_MODE_FACE) {
|
||||
if (raycastMesh(sctx,
|
||||
ob_eval,
|
||||
mesh_eval,
|
||||
obmat,
|
||||
sctx->runtime.object_index++,
|
||||
use_hide,
|
||||
/* read/write args */
|
||||
&sctx->ret.ray_depth_max,
|
||||
/* return args */
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index,
|
||||
sctx->ret.hit_list))
|
||||
{
|
||||
return SCE_SNAP_MODE_FACE;
|
||||
}
|
||||
}
|
||||
|
||||
if (snap_mode_used & SCE_SNAP_MODE_FACE_NEAREST) {
|
||||
if (nearest_world_mesh(sctx,
|
||||
mesh_eval,
|
||||
obmat,
|
||||
use_hide,
|
||||
sctx->runtime.init_co,
|
||||
sctx->runtime.curr_co,
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index))
|
||||
{
|
||||
return SCE_SNAP_MODE_FACE_NEAREST;
|
||||
}
|
||||
}
|
||||
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user