Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/transform/transform_snap.c')
-rw-r--r--source/blender/editors/transform/transform_snap.c457
1 files changed, 304 insertions, 153 deletions
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 769fd28c57b..22d062a71dc 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -79,8 +79,8 @@ static void TargetSnapActive(TransInfo *t);
/** \name Implementations
* \{ */
-static bool snapNodeTest(View2D *v2d, bNode *node, eSnapSelect snap_select);
-static NodeBorder snapNodeBorder(int snap_node_mode);
+static bool snapNodeTest(View2D *v2d, bNode *node, eSnapTargetSelect snap_target_select);
+static NodeBorder snapNodeBorder(eSnapMode snap_node_mode);
#if 0
int BIF_snappingSupported(Object *obedit)
@@ -126,8 +126,12 @@ bool activeSnap(const TransInfo *t)
((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP_INVERT);
}
-bool activeSnap_with_project(const TransInfo *t)
+bool activeSnap_SnappingIndividual(const TransInfo *t)
{
+ if (activeSnap(t) && t->tsnap.mode & SCE_SNAP_MODE_FACE_NEAREST) {
+ return true;
+ }
+
if (!t->tsnap.project) {
return false;
}
@@ -143,6 +147,27 @@ bool activeSnap_with_project(const TransInfo *t)
return true;
}
+bool activeSnap_SnappingAsGroup(const TransInfo *t)
+{
+ if (!activeSnap(t)) {
+ return false;
+ }
+
+ if (t->tsnap.mode == SCE_SNAP_MODE_FACE_RAYCAST && t->tsnap.project) {
+ return false;
+ }
+
+ if (t->tsnap.mode == SCE_SNAP_MODE_FACE_NEAREST) {
+ return false;
+ }
+
+ if (doForceIncrementSnap(t)) {
+ return false;
+ }
+
+ return true;
+}
+
bool transformModeUseSnap(const TransInfo *t)
{
ToolSettings *ts = t->settings;
@@ -343,88 +368,155 @@ eRedrawFlag handleSnapping(TransInfo *t, const wmEvent *event)
return status;
}
-void applyProject(TransInfo *t)
+static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td)
{
- if (!activeSnap_with_project(t)) {
- return;
+ if (!(t->tsnap.mode & SCE_SNAP_MODE_FACE_RAYCAST)) {
+ return false;
+ }
+
+ float iloc[3], loc[3], no[3];
+ float mval_fl[2];
+
+ copy_v3_v3(iloc, td->loc);
+ if (tc->use_local_mat) {
+ mul_m4_v3(tc->mat, iloc);
+ }
+ else if (t->options & CTX_OBJECT) {
+ BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob);
+ copy_v3_v3(iloc, td->ob->obmat[3]);
+ }
+
+ if (ED_view3d_project_float_global(t->region, iloc, mval_fl, V3D_PROJ_TEST_NOP) !=
+ V3D_PROJ_RET_OK) {
+ return false;
+ }
+
+ eSnapMode hit = ED_transform_snap_object_project_view3d(
+ t->tsnap.object_context,
+ t->depsgraph,
+ t->region,
+ t->view,
+ SCE_SNAP_MODE_FACE_RAYCAST,
+ &(const struct SnapObjectParams){
+ .snap_target_select = t->tsnap.target_select,
+ .edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL,
+ .use_occlusion_test = false,
+ .use_backface_culling = t->tsnap.use_backface_culling,
+ },
+ NULL,
+ mval_fl,
+ NULL,
+ 0,
+ loc,
+ no);
+ if (hit != SCE_SNAP_MODE_FACE_RAYCAST) {
+ return false;
}
float tvec[3];
- int i;
+ sub_v3_v3v3(tvec, loc, iloc);
- /* XXX FLICKER IN OBJECT MODE */
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- for (i = 0; i < tc->data_len; i++, td++) {
- float iloc[3], loc[3], no[3];
- float mval_fl[2];
- if (td->flag & TD_SKIP) {
- continue;
- }
+ mul_m3_v3(td->smtx, tvec);
- if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f)) {
- continue;
- }
+ add_v3_v3(td->loc, tvec);
- copy_v3_v3(iloc, td->loc);
- if (tc->use_local_mat) {
- mul_m4_v3(tc->mat, iloc);
- }
- else if (t->options & CTX_OBJECT) {
- BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob);
- copy_v3_v3(iloc, td->ob->obmat[3]);
- }
+ if (t->tsnap.align && (t->options & CTX_OBJECT)) {
+ /* handle alignment as well */
+ const float *original_normal;
+ float mat[3][3];
- if (ED_view3d_project_float_global(t->region, iloc, mval_fl, V3D_PROJ_TEST_NOP) ==
- V3D_PROJ_RET_OK) {
- if (ED_transform_snap_object_project_view3d(
- t->tsnap.object_context,
- t->depsgraph,
- t->region,
- t->view,
- SCE_SNAP_MODE_FACE,
- &(const struct SnapObjectParams){
- .snap_select = t->tsnap.modeSelect,
- .edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL,
- .use_occlusion_test = false,
- .use_backface_culling = t->tsnap.use_backface_culling,
- },
- mval_fl,
- NULL,
- 0,
- loc,
- no)) {
-#if 0
- if (tc->use_local_mat) {
- mul_m4_v3(tc->imat, loc);
- }
-#endif
+ /* In pose mode, we want to align normals with Y axis of bones. */
+ original_normal = td->axismtx[2];
+
+ rotation_between_vecs_to_mat3(mat, original_normal, no);
+
+ transform_data_ext_rotate(td, mat, true);
+
+ /* TODO: support constraints for rotation too? see #ElementRotation. */
+ }
+ return true;
+}
- sub_v3_v3v3(tvec, loc, iloc);
+static void applyFaceNearest(TransInfo *t, TransDataContainer *tc, TransData *td)
+{
+ if (!(t->tsnap.mode & SCE_SNAP_MODE_FACE_NEAREST)) {
+ return;
+ }
+
+ float init_loc[3];
+ float prev_loc[3];
+ float snap_loc[3], snap_no[3];
- mul_m3_v3(td->smtx, tvec);
+ copy_v3_v3(init_loc, td->iloc);
+ copy_v3_v3(prev_loc, td->loc);
+ if (tc->use_local_mat) {
+ mul_m4_v3(tc->mat, init_loc);
+ mul_m4_v3(tc->mat, prev_loc);
+ }
+ else if (t->options & CTX_OBJECT) {
+ BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob);
+ copy_v3_v3(init_loc, td->ob->obmat[3]);
+ }
- add_v3_v3(td->loc, tvec);
+ eSnapMode hit = ED_transform_snap_object_project_view3d(
+ t->tsnap.object_context,
+ t->depsgraph,
+ t->region,
+ t->view,
+ SCE_SNAP_MODE_FACE_NEAREST,
+ &(const struct SnapObjectParams){
+ .snap_target_select = t->tsnap.target_select,
+ .edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL,
+ .use_occlusion_test = false,
+ .use_backface_culling = false,
+ .face_nearest_steps = t->tsnap.face_nearest_steps,
+ .keep_on_same_target = t->tsnap.flag & SCE_SNAP_KEEP_ON_SAME_OBJECT,
+ },
+ init_loc,
+ NULL,
+ prev_loc,
+ 0,
+ snap_loc,
+ snap_no);
+
+ if (hit != SCE_SNAP_MODE_FACE_NEAREST) {
+ return;
+ }
- if (t->tsnap.align && (t->options & CTX_OBJECT)) {
- /* handle alignment as well */
- const float *original_normal;
- float mat[3][3];
+ float tvec[3];
+ sub_v3_v3v3(tvec, snap_loc, prev_loc);
+ mul_m3_v3(td->smtx, tvec);
+ add_v3_v3(td->loc, tvec);
- /* In pose mode, we want to align normals with Y axis of bones... */
- original_normal = td->axismtx[2];
+ /* TODO: support snap alignment similar to #SCE_SNAP_MODE_FACE_RAYCAST? */
+}
- rotation_between_vecs_to_mat3(mat, original_normal, no);
+void applySnappingIndividual(TransInfo *t)
+{
+ if (!activeSnap_SnappingIndividual(t)) {
+ return;
+ }
- transform_data_ext_rotate(td, mat, true);
+ /* XXX FLICKER IN OBJECT MODE */
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ TransData *td = tc->data;
+ for (int i = 0; i < tc->data_len; i++, td++) {
+ if (td->flag & TD_SKIP) {
+ continue;
+ }
- /* TODO: support constraints for rotation too? see #ElementRotation. */
- }
- }
+ if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f)) {
+ continue;
}
+ /* If both face ray-cast and face nearest methods are enabled, start with face ray-cast and
+ * fallback to face nearest ray-cast does not hit. */
+ bool hit = applyFaceProject(t, tc, td);
+ if (!hit) {
+ applyFaceNearest(t, tc, td);
+ }
#if 0 /* TODO: support this? */
- constraintTransLim(t, td);
+ constraintTransLim(t, td);
#endif
}
}
@@ -480,15 +572,9 @@ void applyGridAbsolute(TransInfo *t)
}
}
-void applySnapping(TransInfo *t, float *vec)
+void applySnappingAsGroup(TransInfo *t, float *vec)
{
- /* Each Trans Data already makes the snap to face */
- if (doForceIncrementSnap(t)) {
- return;
- }
-
- if (t->tsnap.project && t->tsnap.mode == SCE_SNAP_MODE_FACE) {
- /* A similar snap will be applied to each transdata in `applyProject`. */
+ if (!activeSnap_SnappingAsGroup(t)) {
return;
}
@@ -522,13 +608,13 @@ void applySnapping(TransInfo *t, float *vec)
void resetSnapping(TransInfo *t)
{
- t->tsnap.status = 0;
- t->tsnap.snapElem = 0;
+ t->tsnap.status = SNAP_RESETTED;
+ t->tsnap.snapElem = SCE_SNAP_MODE_NONE;
t->tsnap.align = false;
- t->tsnap.project = 0;
- t->tsnap.mode = 0;
- t->tsnap.modeSelect = 0;
- t->tsnap.target = 0;
+ t->tsnap.project = false;
+ t->tsnap.mode = SCE_SNAP_MODE_NONE;
+ t->tsnap.target_select = SCE_SNAP_TARGET_ALL;
+ t->tsnap.source_select = SCE_SNAP_SOURCE_CLOSEST;
t->tsnap.last = 0;
t->tsnap.snapNormal[0] = 0;
@@ -581,7 +667,7 @@ static bool bm_face_is_snap_target(BMFace *f, void *UNUSED(user_data))
return true;
}
-static char snap_flag_from_spacetype(TransInfo *t)
+static eSnapFlag snap_flag_from_spacetype(TransInfo *t)
{
ToolSettings *ts = t->settings;
if (t->spacetype == SPACE_NODE) {
@@ -596,7 +682,7 @@ static char snap_flag_from_spacetype(TransInfo *t)
return ts->snap_flag;
}
-static short snap_mode_from_spacetype(TransInfo *t)
+static eSnapMode snap_mode_from_spacetype(TransInfo *t)
{
ToolSettings *ts = t->settings;
@@ -605,7 +691,7 @@ static short snap_mode_from_spacetype(TransInfo *t)
}
if (t->spacetype == SPACE_IMAGE) {
- short snap_mode = ts->snap_uv_mode;
+ eSnapMode snap_mode = ts->snap_uv_mode;
if ((snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_uv_flag & SCE_SNAP_ABS_GRID) &&
(t->mode == TFM_TRANSLATION)) {
snap_mode &= ~SCE_SNAP_MODE_INCREMENT;
@@ -623,7 +709,7 @@ static short snap_mode_from_spacetype(TransInfo *t)
return SCE_SNAP_MODE_INCREMENT;
}
- short snap_mode = ts->snap_mode;
+ eSnapMode snap_mode = ts->snap_mode;
if ((snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_flag & SCE_SNAP_ABS_GRID) &&
(t->mode == TFM_TRANSLATION)) {
/* Special case in which snap to increments is transformed to snap to grid. */
@@ -641,72 +727,78 @@ static short snap_mode_from_spacetype(TransInfo *t)
return SCE_SNAP_MODE_INCREMENT;
}
-static short snap_select_type_get(TransInfo *t)
+static eSnapTargetSelect snap_target_select_from_spacetype(TransInfo *t)
{
ViewLayer *view_layer = t->view_layer;
Base *base_act = view_layer->basact;
+
+ eSnapTargetSelect ret = SCE_SNAP_TARGET_ALL;
+
+ bool use_snap_active = (t->tsnap.target_select & SCE_SNAP_TARGET_NOT_ACTIVE) == 0;
+ bool use_snap_edit = (t->tsnap.target_select & SCE_SNAP_TARGET_NOT_EDITED) == 0;
+ bool use_snap_nonedit = (t->tsnap.target_select & SCE_SNAP_TARGET_NOT_NONEDITED) == 0;
+ bool use_snap_selectable_only = (t->tsnap.target_select & SCE_SNAP_TARGET_ONLY_SELECTABLE) != 0;
+
if (ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE) && !(t->options & CTX_CAMERA)) {
+ if (base_act && (base_act->object->mode & OB_MODE_PARTICLE_EDIT)) {
+ /* Particles edit mode. */
+ return ret;
+ }
+
+ if (use_snap_selectable_only) {
+ ret |= SCE_SNAP_TARGET_ONLY_SELECTABLE;
+ }
+
if (t->options & (CTX_GPENCIL_STROKES | CTX_CURSOR | CTX_OBMODE_XFORM_OBDATA)) {
/* In "Edit Strokes" mode,
* snap tool can perform snap to selected or active objects (see T49632)
* TODO: perform self snap in gpencil_strokes.
*
* When we're moving the origins, allow snapping onto our own geometry (see T69132). */
- return SNAP_ALL;
+ return ret;
}
const int obedit_type = t->obedit_type;
if (obedit_type != -1) {
/* Edit mode */
- if (ELEM(obedit_type,
- OB_MESH,
- OB_ARMATURE,
- OB_CURVES_LEGACY,
- OB_SURF,
- OB_LATTICE,
- OB_MBALL)) {
- /* Temporary limited to edit mode meshes, armature, curves, lattice and metaballs. */
-
- if ((obedit_type == OB_MESH) && (t->flag & T_PROP_EDIT)) {
- /* Exclude editmesh if using proportional edit */
- return SNAP_NOT_EDITED;
+ if (obedit_type == OB_MESH) {
+ /* Editing a mesh */
+ if ((t->flag & T_PROP_EDIT) != 0) {
+ /* Exclude editmesh when using proportional edit */
+ ret |= SCE_SNAP_TARGET_NOT_EDITED;
}
-
- if (!t->tsnap.snap_self) {
- return SNAP_NOT_ACTIVE;
+ if (!use_snap_active) {
+ ret |= SCE_SNAP_TARGET_NOT_ACTIVE;
+ }
+ if (!use_snap_edit) {
+ ret |= SCE_SNAP_TARGET_NOT_EDITED;
+ }
+ if (!use_snap_nonedit) {
+ ret |= SCE_SNAP_TARGET_NOT_NONEDITED;
}
-
- return SNAP_NOT_SELECTED;
}
-
- return SNAP_ALL;
+ else if (ELEM(obedit_type, OB_ARMATURE, OB_CURVES_LEGACY, OB_SURF, OB_LATTICE, OB_MBALL)) {
+ /* Temporary limited to edit mode armature, curves, surfaces, lattices, and metaballs. */
+ ret |= SCE_SNAP_TARGET_NOT_SELECTED;
+ }
}
-
- if (base_act && (base_act->object->mode & OB_MODE_PARTICLE_EDIT)) {
- /* Particles edit mode. */
- return SNAP_ALL;
+ else {
+ /* Object or pose mode. */
+ ret |= SCE_SNAP_TARGET_NOT_SELECTED | SCE_SNAP_TARGET_NOT_ACTIVE;
}
-
- /* Object or pose mode. */
- return SNAP_NOT_SELECTED;
}
-
- if (ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) {
- return SNAP_NOT_SELECTED;
+ else if (ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) {
+ ret |= SCE_SNAP_TARGET_NOT_SELECTED;
}
- return SNAP_ALL;
+ return ret;
}
static void initSnappingMode(TransInfo *t)
{
- ToolSettings *ts = t->settings;
- t->tsnap.mode = snap_mode_from_spacetype(t);
- t->tsnap.modeSelect = snap_select_type_get(t);
-
- if ((t->spacetype != SPACE_VIEW3D) || !(ts->snap_mode & SCE_SNAP_MODE_FACE)) {
+ if ((t->spacetype != SPACE_VIEW3D) || !(t->tsnap.mode & SCE_SNAP_MODE_FACE_RAYCAST)) {
/* Force project off when not supported. */
- t->tsnap.project = 0;
+ t->tsnap.project = false;
}
if (ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE, SPACE_NODE, SPACE_SEQ)) {
@@ -750,9 +842,14 @@ static void initSnappingMode(TransInfo *t)
void initSnapping(TransInfo *t, wmOperator *op)
{
+ ToolSettings *ts = t->settings;
+ eSnapSourceSelect snap_source = ts->snap_target;
+
resetSnapping(t);
+ t->tsnap.mode = snap_mode_from_spacetype(t);
t->tsnap.flag = snap_flag_from_spacetype(t);
- short snap_target = t->settings->snap_target;
+ t->tsnap.target_select = snap_target_select_from_spacetype(t);
+ t->tsnap.face_nearest_steps = max_ii(ts->snap_face_nearest_steps, 1);
/* if snap property exists */
PropertyRNA *prop;
@@ -761,9 +858,17 @@ void initSnapping(TransInfo *t, wmOperator *op)
if (RNA_property_boolean_get(op->ptr, prop)) {
t->modifiers |= MOD_SNAP;
+ if ((prop = RNA_struct_find_property(op->ptr, "snap_elements")) &&
+ RNA_property_is_set(op->ptr, prop)) {
+ t->tsnap.mode = RNA_property_enum_get(op->ptr, prop);
+ }
+
+ /* TODO(@gfxcoder): Rename `snap_target` to `snap_source` to avoid previous ambiguity of
+ * "target" (now, "source" is geometry to be moved and "target" is geometry to which moved
+ * geometry is snapped). */
if ((prop = RNA_struct_find_property(op->ptr, "snap_target")) &&
RNA_property_is_set(op->ptr, prop)) {
- snap_target = RNA_property_enum_get(op->ptr, prop);
+ snap_source = RNA_property_enum_get(op->ptr, prop);
}
if ((prop = RNA_struct_find_property(op->ptr, "snap_point")) &&
@@ -785,9 +890,33 @@ void initSnapping(TransInfo *t, wmOperator *op)
t->tsnap.project = RNA_property_boolean_get(op->ptr, prop);
}
+ /* use_snap_self is misnamed and should be use_snap_active */
if ((prop = RNA_struct_find_property(op->ptr, "use_snap_self")) &&
RNA_property_is_set(op->ptr, prop)) {
- t->tsnap.snap_self = RNA_property_boolean_get(op->ptr, prop);
+ SET_FLAG_FROM_TEST(t->tsnap.target_select,
+ !RNA_property_boolean_get(op->ptr, prop),
+ SCE_SNAP_TARGET_NOT_ACTIVE);
+ }
+
+ if ((prop = RNA_struct_find_property(op->ptr, "use_snap_edit")) &&
+ RNA_property_is_set(op->ptr, prop)) {
+ SET_FLAG_FROM_TEST(t->tsnap.target_select,
+ !RNA_property_boolean_get(op->ptr, prop),
+ SCE_SNAP_TARGET_NOT_EDITED);
+ }
+
+ if ((prop = RNA_struct_find_property(op->ptr, "use_snap_nonedit")) &&
+ RNA_property_is_set(op->ptr, prop)) {
+ SET_FLAG_FROM_TEST(t->tsnap.target_select,
+ !RNA_property_boolean_get(op->ptr, prop),
+ SCE_SNAP_TARGET_NOT_NONEDITED);
+ }
+
+ if ((prop = RNA_struct_find_property(op->ptr, "use_snap_selectable")) &&
+ RNA_property_is_set(op->ptr, prop)) {
+ SET_FLAG_FROM_TEST(t->tsnap.target_select,
+ RNA_property_boolean_get(op->ptr, prop),
+ SCE_SNAP_TARGET_ONLY_SELECTABLE);
}
}
}
@@ -799,11 +928,22 @@ void initSnapping(TransInfo *t, wmOperator *op)
t->tsnap.align = ((t->tsnap.flag & SCE_SNAP_ROTATE) != 0);
t->tsnap.project = ((t->tsnap.flag & SCE_SNAP_PROJECT) != 0);
- t->tsnap.snap_self = !((t->tsnap.flag & SCE_SNAP_NO_SELF) != 0);
t->tsnap.peel = ((t->tsnap.flag & SCE_SNAP_PROJECT) != 0);
- }
-
- t->tsnap.target = snap_target;
+ SET_FLAG_FROM_TEST(t->tsnap.target_select,
+ (ts->snap_flag & SCE_SNAP_NOT_TO_ACTIVE),
+ SCE_SNAP_TARGET_NOT_ACTIVE);
+ SET_FLAG_FROM_TEST(t->tsnap.target_select,
+ !(ts->snap_flag & SCE_SNAP_TO_INCLUDE_EDITED),
+ SCE_SNAP_TARGET_NOT_EDITED);
+ SET_FLAG_FROM_TEST(t->tsnap.target_select,
+ !(ts->snap_flag & SCE_SNAP_TO_INCLUDE_NONEDITED),
+ SCE_SNAP_TARGET_NOT_NONEDITED);
+ SET_FLAG_FROM_TEST(t->tsnap.target_select,
+ (ts->snap_flag & SCE_SNAP_TO_ONLY_SELECTABLE),
+ SCE_SNAP_TARGET_ONLY_SELECTABLE);
+ }
+
+ t->tsnap.source_select = snap_source;
initSnappingMode(t);
}
@@ -844,11 +984,11 @@ static void setSnappingCallback(TransInfo *t)
return;
}
- switch (t->tsnap.target) {
- case SCE_SNAP_TARGET_CLOSEST:
+ switch (t->tsnap.source_select) {
+ case SCE_SNAP_SOURCE_CLOSEST:
t->tsnap.targetSnap = TargetSnapClosest;
break;
- case SCE_SNAP_TARGET_CENTER:
+ case SCE_SNAP_SOURCE_CENTER:
if (!ELEM(t->mode, TFM_ROTATION, TFM_RESIZE)) {
t->tsnap.targetSnap = TargetSnapCenter;
break;
@@ -856,10 +996,10 @@ static void setSnappingCallback(TransInfo *t)
/* Can't do TARGET_CENTER with these modes,
* use TARGET_MEDIAN instead. */
ATTR_FALLTHROUGH;
- case SCE_SNAP_TARGET_MEDIAN:
+ case SCE_SNAP_SOURCE_MEDIAN:
t->tsnap.targetSnap = TargetSnapMedian;
break;
- case SCE_SNAP_TARGET_ACTIVE:
+ case SCE_SNAP_SOURCE_ACTIVE:
t->tsnap.targetSnap = TargetSnapActive;
break;
}
@@ -973,7 +1113,7 @@ static void snap_calc_view3d_fn(TransInfo *t, float *UNUSED(vec))
float no[3];
float mval[2];
bool found = false;
- short snap_elem = 0;
+ eSnapMode snap_elem = SCE_SNAP_MODE_NONE;
float dist_px = SNAP_MIN_DISTANCE; /* Use a user defined value here. */
mval[0] = t->mval[0];
@@ -982,11 +1122,11 @@ static void snap_calc_view3d_fn(TransInfo *t, float *UNUSED(vec))
if (t->tsnap.mode & SCE_SNAP_MODE_GEOM) {
zero_v3(no); /* objects won't set this */
snap_elem = snapObjectsTransform(t, mval, &dist_px, loc, no);
- found = snap_elem != 0;
+ found = (snap_elem != SCE_SNAP_MODE_NONE);
}
if ((found == false) && (t->tsnap.mode & SCE_SNAP_MODE_VOLUME)) {
- found = peelObjectsTransform(
- t, mval, (t->settings->snap_flag & SCE_SNAP_PEEL_OBJECT) != 0, loc, no, NULL);
+ bool use_peel = (t->settings->snap_flag & SCE_SNAP_PEEL_OBJECT) != 0;
+ found = peelObjectsTransform(t, mval, use_peel, loc, no, NULL);
if (found) {
snap_elem = SCE_SNAP_MODE_VOLUME;
@@ -1003,7 +1143,7 @@ static void snap_calc_view3d_fn(TransInfo *t, float *UNUSED(vec))
t->tsnap.status &= ~POINT_INIT;
}
- t->tsnap.snapElem = (char)snap_elem;
+ t->tsnap.snapElem = snap_elem;
}
static void snap_calc_uv_fn(TransInfo *t, float *UNUSED(vec))
@@ -1020,7 +1160,7 @@ static void snap_calc_uv_fn(TransInfo *t, float *UNUSED(vec))
objects,
objects_len,
t->mval,
- t->tsnap.modeSelect == SNAP_NOT_SELECTED,
+ t->tsnap.target_select & SCE_SNAP_TARGET_NOT_SELECTED,
&dist_sq,
t->tsnap.snapPoint)) {
t->tsnap.snapPoint[0] *= t->aspect[0];
@@ -1190,7 +1330,7 @@ static void TargetSnapActive(TransInfo *t)
}
/* No active, default to median */
else {
- t->tsnap.target = SCE_SNAP_TARGET_MEDIAN;
+ t->tsnap.source_select = SCE_SNAP_SOURCE_MEDIAN;
t->tsnap.targetSnap = TargetSnapMedian;
TargetSnapMedian(t);
}
@@ -1302,7 +1442,7 @@ static void TargetSnapClosest(TransInfo *t)
/** \name Snap Objects
* \{ */
-short snapObjectsTransform(
+eSnapMode snapObjectsTransform(
TransInfo *t, const float mval[2], float *dist_px, float r_loc[3], float r_no[3])
{
float *target = (t->tsnap.status & TARGET_INIT) ? t->tsnap.snapTarget : t->center_global;
@@ -1313,11 +1453,12 @@ short snapObjectsTransform(
t->view,
t->tsnap.mode,
&(const struct SnapObjectParams){
- .snap_select = t->tsnap.modeSelect,
+ .snap_target_select = t->tsnap.target_select,
.edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL,
- .use_occlusion_test = t->settings->snap_mode != SCE_SNAP_MODE_FACE,
+ .use_occlusion_test = t->settings->snap_mode != SCE_SNAP_MODE_FACE_RAYCAST,
.use_backface_culling = t->tsnap.use_backface_culling,
},
+ NULL,
mval,
target,
dist_px,
@@ -1346,7 +1487,7 @@ bool peelObjectsTransform(TransInfo *t,
t->region,
t->view,
&(const struct SnapObjectParams){
- .snap_select = t->tsnap.modeSelect,
+ .snap_target_select = t->tsnap.target_select,
.edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL,
},
mval,
@@ -1414,16 +1555,16 @@ bool peelObjectsTransform(TransInfo *t,
/** \name snap Nodes
* \{ */
-static bool snapNodeTest(View2D *v2d, bNode *node, eSnapSelect snap_select)
+static bool snapNodeTest(View2D *v2d, bNode *node, eSnapTargetSelect snap_target_select)
{
/* node is use for snapping only if a) snap mode matches and b) node is inside the view */
- return ((snap_select == SNAP_NOT_SELECTED && !(node->flag & NODE_SELECT)) ||
- (snap_select == SNAP_ALL && !(node->flag & NODE_ACTIVE))) &&
+ return (((snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED) && !(node->flag & NODE_SELECT)) ||
+ (snap_target_select == SCE_SNAP_TARGET_ALL && !(node->flag & NODE_ACTIVE))) &&
(node->totr.xmin < v2d->cur.xmax && node->totr.xmax > v2d->cur.xmin &&
node->totr.ymin < v2d->cur.ymax && node->totr.ymax > v2d->cur.ymin);
}
-static NodeBorder snapNodeBorder(int snap_node_mode)
+static NodeBorder snapNodeBorder(eSnapMode snap_node_mode)
{
NodeBorder flag = 0;
if (snap_node_mode & SCE_SNAP_MODE_NODE_X) {
@@ -1499,7 +1640,7 @@ static bool snapNodes(ToolSettings *ts,
SpaceNode *snode,
ARegion *region,
const int mval[2],
- eSnapSelect snap_select,
+ eSnapTargetSelect snap_target_select,
float r_loc[2],
float *r_dist_px,
char *r_node_border)
@@ -1511,7 +1652,7 @@ static bool snapNodes(ToolSettings *ts,
*r_node_border = 0;
for (node = ntree->nodes.first; node; node = node->next) {
- if (snapNodeTest(&region->v2d, node, snap_select)) {
+ if (snapNodeTest(&region->v2d, node, snap_target_select)) {
retval |= snapNode(ts, snode, region, node, mval, r_loc, r_dist_px, r_node_border);
}
}
@@ -1526,7 +1667,7 @@ bool snapNodesTransform(
t->area->spacedata.first,
t->region,
mval,
- t->tsnap.modeSelect,
+ t->tsnap.target_select,
r_loc,
r_dist_px,
r_node_border);
@@ -1548,7 +1689,7 @@ static void snap_grid_apply(
float in[3];
if (t->con.mode & CON_APPLY) {
- BLI_assert(t->tsnap.snapElem == 0);
+ BLI_assert(t->tsnap.snapElem == SCE_SNAP_MODE_NONE);
t->con.applyVec(t, NULL, NULL, loc, in);
}
else {
@@ -1676,6 +1817,16 @@ bool transform_snap_increment(const TransInfo *t, float *r_val)
return transform_snap_increment_ex(t, false, r_val);
}
+float transform_snap_increment_get(const TransInfo *t)
+{
+ if (activeSnap(t) && (!transformModeUseSnap(t) ||
+ (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) {
+ return (t->modifiers & MOD_PRECISION) ? t->snap[1] : t->snap[0];
+ }
+
+ return 0.0f;
+}
+
/** \} */
/* -------------------------------------------------------------------- */