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.c')
-rw-r--r--source/blender/editors/transform/transform.c1423
1 files changed, 930 insertions, 493 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index f4cb8f724bb..68d77dec619 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -54,6 +54,7 @@
#include "BLI_memarena.h"
#include "BKE_nla.h"
+#include "BKE_editmesh.h"
#include "BKE_editmesh_bvh.h"
#include "BKE_context.h"
#include "BKE_constraint.h"
@@ -98,11 +99,13 @@ static void drawTransformApply(const struct bContext *C, ARegion *ar, void *arg)
static void doEdgeSlide(TransInfo *t, float perc);
static void doVertSlide(TransInfo *t, float perc);
-static void drawEdgeSlide(const struct bContext *C, TransInfo *t);
-static void drawVertSlide(const struct bContext *C, TransInfo *t);
+static void drawEdgeSlide(TransInfo *t);
+static void drawVertSlide(TransInfo *t);
static void len_v3_ensure(float v[3], const float length);
static void postInputRotation(TransInfo *t, float values[3]);
+static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short around);
+
/* Transform Callbacks */
static void initBend(TransInfo *t);
@@ -164,6 +167,7 @@ static void applyBoneEnvelope(TransInfo *t, const int mval[2]);
static void initBoneRoll(TransInfo *t);
static void applyBoneRoll(TransInfo *t, const int mval[2]);
+static void initEdgeSlide_ex(TransInfo *t, bool use_double_side);
static void initEdgeSlide(TransInfo *t);
static eRedrawFlag handleEventEdgeSlide(TransInfo *t, const struct wmEvent *event);
static void applyEdgeSlide(TransInfo *t, const int mval[2]);
@@ -235,6 +239,38 @@ void setTransformViewMatrices(TransInfo *t)
calculateCenter2D(t);
}
+void setTransformViewAspect(TransInfo *t, float r_aspect[3])
+{
+ copy_v3_fl(r_aspect, 1.0f);
+
+ if (t->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = t->sa->spacedata.first;
+
+ if (t->options & CTX_MASK) {
+ ED_space_image_get_aspect(sima, &r_aspect[0], &r_aspect[1]);
+ }
+ else if (t->options & CTX_PAINT_CURVE) {
+ /* pass */
+ }
+ else {
+ ED_space_image_get_uv_aspect(sima, &r_aspect[0], &r_aspect[1]);
+ }
+ }
+ else if (t->spacetype == SPACE_CLIP) {
+ SpaceClip *sclip = t->sa->spacedata.first;
+
+ if (t->options & CTX_MOVIECLIP) {
+ ED_space_clip_get_aspect_dimension_aware(sclip, &r_aspect[0], &r_aspect[1]);
+ }
+ else {
+ ED_space_clip_get_aspect(sclip, &r_aspect[0], &r_aspect[1]);
+ }
+ }
+ else if (t->spacetype == SPACE_IPO) {
+ /* depemds on context of usage */
+ }
+}
+
static void convertViewVec2D(View2D *v2d, float r_vec[3], int dx, int dy)
{
float divx, divy;
@@ -288,25 +324,19 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy)
}
}
else if (t->spacetype == SPACE_IMAGE) {
- float aspx, aspy;
-
if (t->options & CTX_MASK) {
convertViewVec2D_mask(t->view, r_vec, dx, dy);
- ED_space_image_get_aspect(t->sa->spacedata.first, &aspx, &aspy);
}
else if (t->options & CTX_PAINT_CURVE) {
r_vec[0] = dx;
r_vec[1] = dy;
-
- aspx = aspy = 1.0;
}
else {
convertViewVec2D(t->view, r_vec, dx, dy);
- ED_space_image_get_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
}
- r_vec[0] *= aspx;
- r_vec[1] *= aspy;
+ r_vec[0] *= t->aspect[0];
+ r_vec[1] *= t->aspect[1];
}
else if (ELEM(t->spacetype, SPACE_IPO, SPACE_NLA)) {
convertViewVec2D(t->view, r_vec, dx, dy);
@@ -315,8 +345,6 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy)
convertViewVec2D(&t->ar->v2d, r_vec, dx, dy);
}
else if (t->spacetype == SPACE_CLIP) {
- float aspx, aspy;
-
if (t->options & CTX_MASK) {
convertViewVec2D_mask(t->view, r_vec, dx, dy);
}
@@ -324,21 +352,8 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy)
convertViewVec2D(t->view, r_vec, dx, dy);
}
- if (t->options & CTX_MOVIECLIP) {
- ED_space_clip_get_aspect_dimension_aware(t->sa->spacedata.first, &aspx, &aspy);
- }
- else if (t->options & CTX_MASK) {
- /* TODO - NOT WORKING, this isnt so bad since its only display aspect */
- ED_space_clip_get_aspect(t->sa->spacedata.first, &aspx, &aspy);
- }
- else {
- /* should never happen, quiet warnings */
- BLI_assert(0);
- aspx = aspy = 1.0f;
- }
-
- r_vec[0] *= aspx;
- r_vec[1] *= aspy;
+ r_vec[0] *= t->aspect[0];
+ r_vec[1] *= t->aspect[1];
}
else {
printf("%s: called in an invalid context\n", __func__);
@@ -360,15 +375,10 @@ void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DPr
SpaceImage *sima = t->sa->spacedata.first;
if (t->options & CTX_MASK) {
- float aspx, aspy;
float v[2];
- ED_space_image_get_aspect(sima, &aspx, &aspy);
-
- copy_v2_v2(v, vec);
-
- v[0] = v[0] / aspx;
- v[1] = v[1] / aspy;
+ v[0] = vec[0] / t->aspect[0];
+ v[1] = vec[1] / t->aspect[1];
BKE_mask_coord_to_image(sima->image, &sima->iuser, v, v);
@@ -382,11 +392,10 @@ void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DPr
adr[1] = vec[1];
}
else {
- float aspx, aspy, v[2];
+ float v[2];
- ED_space_image_get_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
- v[0] = vec[0] / aspx;
- v[1] = vec[1] / aspy;
+ v[0] = vec[0] / t->aspect[0];
+ v[1] = vec[1] / t->aspect[1];
UI_view2d_view_to_region(t->view, v[0], v[1], &adr[0], &adr[1]);
}
@@ -431,15 +440,10 @@ void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DPr
MovieClip *clip = ED_space_clip_get_clip(sc);
if (clip) {
- float aspx, aspy;
float v[2];
- ED_space_clip_get_aspect(sc, &aspx, &aspy);
-
- copy_v2_v2(v, vec);
-
- v[0] = v[0] / aspx;
- v[1] = v[1] / aspy;
+ v[0] = vec[0] / t->aspect[0];
+ v[1] = vec[1] / t->aspect[1];
BKE_mask_coord_to_movieclip(sc->clip, &sc->user, v, v);
@@ -454,13 +458,10 @@ void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DPr
}
}
else if (t->options & CTX_MOVIECLIP) {
- float v[2], aspx, aspy;
-
- copy_v2_v2(v, vec);
- ED_space_clip_get_aspect_dimension_aware(t->sa->spacedata.first, &aspx, &aspy);
+ float v[2];
- v[0] /= aspx;
- v[1] /= aspy;
+ v[0] = vec[0] / t->aspect[0];
+ v[1] = vec[1] / t->aspect[1];
UI_view2d_view_to_region(t->view, v[0], v[1], &adr[0], &adr[1]);
}
@@ -516,7 +517,6 @@ void applyAspectRatio(TransInfo *t, float vec[2])
{
if ((t->spacetype == SPACE_IMAGE) && (t->mode == TFM_TRANSLATION) && !(t->options & CTX_PAINT_CURVE)) {
SpaceImage *sima = t->sa->spacedata.first;
- float aspx, aspy;
if ((sima->flag & SI_COORDFLOATS) == 0) {
int width, height;
@@ -526,28 +526,13 @@ void applyAspectRatio(TransInfo *t, float vec[2])
vec[1] *= height;
}
- ED_space_image_get_uv_aspect(sima, &aspx, &aspy);
- vec[0] /= aspx;
- vec[1] /= aspy;
+ vec[0] /= t->aspect[0];
+ vec[1] /= t->aspect[1];
}
else if ((t->spacetype == SPACE_CLIP) && (t->mode == TFM_TRANSLATION)) {
if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
- SpaceClip *sc = t->sa->spacedata.first;
- float aspx, aspy;
-
-
- if (t->options & CTX_MOVIECLIP) {
- ED_space_clip_get_aspect_dimension_aware(sc, &aspx, &aspy);
-
- vec[0] /= aspx;
- vec[1] /= aspy;
- }
- else if (t->options & CTX_MASK) {
- ED_space_clip_get_aspect(sc, &aspx, &aspy);
-
- vec[0] /= aspx;
- vec[1] /= aspy;
- }
+ vec[0] /= t->aspect[0];
+ vec[1] /= t->aspect[1];
}
}
}
@@ -556,7 +541,6 @@ void removeAspectRatio(TransInfo *t, float vec[2])
{
if ((t->spacetype == SPACE_IMAGE) && (t->mode == TFM_TRANSLATION)) {
SpaceImage *sima = t->sa->spacedata.first;
- float aspx, aspy;
if ((sima->flag & SI_COORDFLOATS) == 0) {
int width, height;
@@ -566,24 +550,13 @@ void removeAspectRatio(TransInfo *t, float vec[2])
vec[1] /= height;
}
- ED_space_image_get_uv_aspect(sima, &aspx, &aspy);
- vec[0] *= aspx;
- vec[1] *= aspy;
+ vec[0] *= t->aspect[0];
+ vec[1] *= t->aspect[1];
}
else if ((t->spacetype == SPACE_CLIP) && (t->mode == TFM_TRANSLATION)) {
if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
- SpaceClip *sc = t->sa->spacedata.first;
- float aspx = 1.0f, aspy = 1.0f;
-
- if (t->options & CTX_MOVIECLIP) {
- ED_space_clip_get_aspect_dimension_aware(sc, &aspx, &aspy);
- }
- else if (t->options & CTX_MASK) {
- ED_space_clip_get_aspect(sc, &aspx, &aspy);
- }
-
- vec[0] *= aspx;
- vec[1] *= aspy;
+ vec[0] *= t->aspect[0];
+ vec[1] *= t->aspect[1];
}
}
}
@@ -729,7 +702,6 @@ static void view_editmove(unsigned short UNUSED(event))
switch (event) {
case WHEELUPMOUSE:
-
if (G.qual & LR_SHIFTKEY) {
if (G.qual & LR_ALTKEY) {
G.qual &= ~LR_SHIFTKEY;
@@ -795,35 +767,38 @@ static void view_editmove(unsigned short UNUSED(event))
/* ************************************************* */
/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
-#define TFM_MODAL_CANCEL 1
-#define TFM_MODAL_CONFIRM 2
-#define TFM_MODAL_TRANSLATE 3
-#define TFM_MODAL_ROTATE 4
-#define TFM_MODAL_RESIZE 5
-#define TFM_MODAL_SNAP_INV_ON 6
-#define TFM_MODAL_SNAP_INV_OFF 7
-#define TFM_MODAL_SNAP_TOGGLE 8
-#define TFM_MODAL_AXIS_X 9
-#define TFM_MODAL_AXIS_Y 10
-#define TFM_MODAL_AXIS_Z 11
-#define TFM_MODAL_PLANE_X 12
-#define TFM_MODAL_PLANE_Y 13
-#define TFM_MODAL_PLANE_Z 14
-#define TFM_MODAL_CONS_OFF 15
-#define TFM_MODAL_ADD_SNAP 16
-#define TFM_MODAL_REMOVE_SNAP 17
-/* 18 and 19 used by numinput, defined in transform.h
- * */
-#define TFM_MODAL_PROPSIZE_UP 20
-#define TFM_MODAL_PROPSIZE_DOWN 21
-#define TFM_MODAL_AUTOIK_LEN_INC 22
-#define TFM_MODAL_AUTOIK_LEN_DEC 23
-
-#define TFM_MODAL_EDGESLIDE_UP 24
-#define TFM_MODAL_EDGESLIDE_DOWN 25
+enum {
+ TFM_MODAL_CANCEL = 1,
+ TFM_MODAL_CONFIRM = 2,
+ TFM_MODAL_TRANSLATE = 3,
+ TFM_MODAL_ROTATE = 4,
+ TFM_MODAL_RESIZE = 5,
+ TFM_MODAL_SNAP_INV_ON = 6,
+ TFM_MODAL_SNAP_INV_OFF = 7,
+ TFM_MODAL_SNAP_TOGGLE = 8,
+ TFM_MODAL_AXIS_X = 9,
+ TFM_MODAL_AXIS_Y = 10,
+ TFM_MODAL_AXIS_Z = 11,
+ TFM_MODAL_PLANE_X = 12,
+ TFM_MODAL_PLANE_Y = 13,
+ TFM_MODAL_PLANE_Z = 14,
+ TFM_MODAL_CONS_OFF = 15,
+ TFM_MODAL_ADD_SNAP = 16,
+ TFM_MODAL_REMOVE_SNAP = 17,
+
+/* 18 and 19 used by numinput, defined in transform.h */
+
+ TFM_MODAL_PROPSIZE_UP = 20,
+ TFM_MODAL_PROPSIZE_DOWN = 21,
+ TFM_MODAL_AUTOIK_LEN_INC = 22,
+ TFM_MODAL_AUTOIK_LEN_DEC = 23,
+
+ TFM_MODAL_EDGESLIDE_UP = 24,
+ TFM_MODAL_EDGESLIDE_DOWN = 25,
/* for analog input, like trackpad */
-#define TFM_MODAL_PROPSIZE 26
+ TFM_MODAL_PROPSIZE = 26,
+};
/* called in transform_ops.c, on each regeneration of keymaps */
wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
@@ -868,8 +843,8 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
/* items for modal map */
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_CANCEL);
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM);
- WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM);
- WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM);
WM_modalkeymap_add_item(keymap, GKEY, KM_PRESS, 0, 0, TFM_MODAL_TRANSLATE);
WM_modalkeymap_add_item(keymap, RKEY, KM_PRESS, 0, 0, TFM_MODAL_ROTATE);
@@ -911,7 +886,7 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm
{
if (!(t->flag & T_NO_CONSTRAINT)) {
int constraint_axis, constraint_plane;
- int edit_2d = (t->flag & T_2D_EDIT);
+ const bool edit_2d = (t->flag & T_2D_EDIT) != 0;
const char *msg1 = "", *msg2 = "", *msg3 = "";
char axis;
@@ -1250,11 +1225,6 @@ int transformEvent(TransInfo *t, const wmEvent *event)
handled = true;
}
break;
- case TFM_MODAL_EDGESLIDE_UP:
- case TFM_MODAL_EDGESLIDE_DOWN:
- t->redraw |= TREDRAW_HARD;
- handled = true;
- break;
case TFM_MODAL_AUTOIK_LEN_INC:
if (t->flag & T_AUTOIK) {
transform_autoik_update(t, 1);
@@ -1269,6 +1239,9 @@ int transformEvent(TransInfo *t, const wmEvent *event)
handled = true;
}
break;
+ /* Those two are only handled in transform's own handler, see T44634! */
+ case TFM_MODAL_EDGESLIDE_UP:
+ case TFM_MODAL_EDGESLIDE_DOWN:
default:
break;
}
@@ -1575,7 +1548,7 @@ bool calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], floa
if (cent3d) {
// Copy center from constraint center. Transform center can be local
- copy_v3_v3(cent3d, t->con.center);
+ copy_v3_v3(cent3d, t->center_global);
}
}
@@ -1828,8 +1801,8 @@ static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), voi
drawSnapping(C, t);
/* edge slide, vert slide */
- drawEdgeSlide(C, t);
- drawVertSlide(C, t);
+ drawEdgeSlide(t);
+ drawVertSlide(t);
}
/* just draw a little warning message in the top-right corner of the viewport to warn that autokeying is enabled */
@@ -1938,7 +1911,11 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
if ((prop = RNA_struct_find_property(op->ptr, "proportional")) &&
!RNA_property_is_set(op->ptr, prop))
{
- if (t->obedit)
+ if (t->spacetype == SPACE_IPO)
+ ts->proportional_fcurve = proportional;
+ else if (t->spacetype == SPACE_ACTION)
+ ts->proportional_action = proportional;
+ else if (t->obedit)
ts->proportional = proportional;
else if (t->options & CTX_MASK)
ts->proportional_mask = (proportional != PROP_EDIT_OFF);
@@ -1989,7 +1966,7 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
if ((prop = RNA_struct_find_property(op->ptr, "mirror"))) {
- RNA_property_boolean_set(op->ptr, prop, t->flag & T_MIRROR);
+ RNA_property_boolean_set(op->ptr, prop, (t->flag & T_MIRROR) != 0);
}
if ((prop = RNA_struct_find_property(op->ptr, "constraint_axis"))) {
@@ -2017,6 +1994,18 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
RNA_property_boolean_set_array(op->ptr, prop, constraint_axis);
}
+
+ {
+ const char *prop_id = NULL;
+ if (t->mode == TFM_SHRINKFATTEN) {
+ prop_id = "use_even_offset";
+ }
+
+ if (prop_id && (prop = RNA_struct_find_property(op->ptr, prop_id))) {
+
+ RNA_property_boolean_set(op->ptr, prop, (t->flag & T_ALT_TRANSFORM) != 0);
+ }
+ }
}
/* note: caller needs to free 't' on a 0 return */
@@ -2089,6 +2078,18 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), helpline_poll, drawHelpline, t);
}
+ else if (t->spacetype == SPACE_IPO) {
+ unit_m3(t->spacemtx);
+ t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
+ //t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
+ t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), helpline_poll, drawHelpline, t);
+ }
+ else if (t->spacetype == SPACE_ACTION) {
+ unit_m3(t->spacemtx);
+ t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
+ //t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
+ t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), helpline_poll, drawHelpline, t);
+ }
else
unit_m3(t->spacemtx);
@@ -2188,18 +2189,28 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
case TFM_BONESIZE:
{ /* used for both B-Bone width (bonesize) as for deform-dist (envelope) */
bArmature *arm = t->poseobj->data;
- if (arm->drawtype == ARM_ENVELOPE)
+ if (arm->drawtype == ARM_ENVELOPE) {
initBoneEnvelope(t);
- else
+ t->mode = TFM_BONE_ENVELOPE_DIST;
+ }
+ else {
initBoneSize(t);
+ }
break;
}
case TFM_BONE_ENVELOPE:
initBoneEnvelope(t);
break;
+ case TFM_BONE_ENVELOPE_DIST:
+ initBoneEnvelope(t);
+ t->mode = TFM_BONE_ENVELOPE_DIST;
+ break;
case TFM_EDGE_SLIDE:
- initEdgeSlide(t);
+ {
+ const bool use_double_side = (op ? !RNA_boolean_get(op->ptr, "single_side") : true);
+ initEdgeSlide_ex(t, use_double_side);
break;
+ }
case TFM_VERT_SLIDE:
initVertSlide(t);
break;
@@ -2258,7 +2269,6 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
return 0;
}
-
/* overwrite initial values if operator supplied a non-null vector */
if ((prop = RNA_struct_find_property(op->ptr, "value")) && RNA_property_is_set(op->ptr, prop)) {
float values[4] = {0}; /* in case value isn't length 4, avoid uninitialized memory */
@@ -2516,8 +2526,8 @@ static void protectedQuaternionBits(short protectflag, float quat[4], const floa
static void constraintTransLim(TransInfo *t, TransData *td)
{
if (td->con) {
- bConstraintTypeInfo *ctiLoc = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_LOCLIMIT);
- bConstraintTypeInfo *ctiDist = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_DISTLIMIT);
+ const bConstraintTypeInfo *ctiLoc = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_LOCLIMIT);
+ const bConstraintTypeInfo *ctiDist = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_DISTLIMIT);
bConstraintOb cob = {NULL};
bConstraint *con;
@@ -2532,7 +2542,7 @@ static void constraintTransLim(TransInfo *t, TransData *td)
/* Evaluate valid constraints */
for (con = td->con; con; con = con->next) {
- bConstraintTypeInfo *cti = NULL;
+ const bConstraintTypeInfo *cti = NULL;
ListBase targets = {NULL, NULL};
/* only consider constraint if enabled */
@@ -2619,7 +2629,7 @@ static void constraintob_from_transdata(bConstraintOb *cob, TransData *td)
static void constraintRotLim(TransInfo *UNUSED(t), TransData *td)
{
if (td->con) {
- bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_ROTLIMIT);
+ const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_ROTLIMIT);
bConstraintOb cob;
bConstraint *con;
bool do_limit = false;
@@ -2686,7 +2696,7 @@ static void constraintRotLim(TransInfo *UNUSED(t), TransData *td)
static void constraintSizeLim(TransInfo *t, TransData *td)
{
if (td->con && td->ext) {
- bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_SIZELIMIT);
+ const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_SIZELIMIT);
bConstraintOb cob = {NULL};
bConstraint *con;
float size_sign[3], size_abs[3];
@@ -2810,10 +2820,11 @@ static void initBend(TransInfo *t)
t->num.unit_type[0] = B_UNIT_ROTATION;
t->num.unit_type[1] = B_UNIT_LENGTH;
- t->flag |= T_NO_CONSTRAINT;
+ t->flag |= T_NO_CONSTRAINT | T_FREE_CUSTOMDATA;
//copy_v3_v3(t->center, ED_view3d_cursor3d_get(t->scene, t->view));
calculateCenterCursor(t, t->center);
+ calculateCenterGlobal(t);
t->val = 0.0f;
@@ -2888,6 +2899,8 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
values.scale = values.scale / data->warp_init_dist;
}
+ copy_v2_v2(t->values, values.vector);
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN * 2];
@@ -2905,8 +2918,6 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
WM_bool_as_string(is_clamp));
}
- copy_v2_v2(t->values, values.vector);
-
values.angle *= -1.0f;
values.scale *= data->warp_init_dist;
@@ -2961,6 +2972,13 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
add_v3_v3(vec, pivot);
mul_m3_v3(td->smtx, vec);
+
+ /* rotation */
+ if ((t->flag & T_POINTS) == 0) {
+ ElementRotation(t, td, mat, V3D_LOCAL);
+ }
+
+ /* location */
copy_v3_v3(td->loc, vec);
}
@@ -3056,6 +3074,8 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
applyNumInput(&t->num, &value);
+ t->values[0] = value;
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
@@ -3069,8 +3089,6 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Shear: %.3f %s (Press X or Y to set shear axis)"), value, t->proptext);
}
- t->values[0] = value;
-
unit_m3(smat);
// Custom data signals shear direction
@@ -3333,7 +3351,7 @@ static void applyResize(TransInfo *t, const int mval[2])
ratio = t->values[0];
}
- size[0] = size[1] = size[2] = ratio;
+ copy_v3_fl(size, ratio);
snapGridIncrement(t, size);
@@ -3439,12 +3457,10 @@ static void applySkinResize(TransInfo *t, const int UNUSED(mval[2]))
{
TransData *td;
float size[3], mat[3][3];
- float ratio;
int i;
char str[MAX_INFO_LEN];
- ratio = t->values[0];
- size[0] = size[1] = size[2] = ratio;
+ copy_v3_fl(size, t->values[0]);
snapGridIncrement(t, size);
@@ -3549,10 +3565,7 @@ static void applyToSphere(TransInfo *t, const int UNUSED(mval[2]))
applyNumInput(&t->num, &ratio);
- if (ratio < 0)
- ratio = 0.0f;
- else if (ratio > 1)
- ratio = 1.0f;
+ CLAMP(ratio, 0.0f, 1.0f);
t->values[0] = ratio;
@@ -3921,6 +3934,8 @@ static void applyRotation(TransInfo *t, const int UNUSED(mval[2]))
final = angle_wrap_rad(final);
}
+ t->values[0] = final;
+
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
@@ -3937,8 +3952,6 @@ static void applyRotation(TransInfo *t, const int UNUSED(mval[2]))
ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
- t->values[0] = final;
-
applyRotationValue(t, final, t->axis);
recalcData(t);
@@ -4010,7 +4023,9 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2]))
char str[MAX_INFO_LEN];
size_t ofs = 0;
float axis1[3], axis2[3];
+#if 0 /* UNUSED */
float mat[3][3], totmat[3][3], smat[3][3];
+#endif
float phi[2];
copy_v3_v3(axis1, t->persinv[0]);
@@ -4018,13 +4033,14 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2]))
normalize_v3(axis1);
normalize_v3(axis2);
- phi[0] = t->values[0];
- phi[1] = t->values[1];
+ copy_v2_v2(phi, t->values);
snapGridIncrement(t, phi);
applyNumInput(&t->num, phi);
+ copy_v2_v2(t->values, phi);
+
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN * 2];
@@ -4042,6 +4058,7 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2]))
ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
+#if 0 /* UNUSED */
axis_angle_normalized_to_mat3(smat, axis1, phi[0]);
axis_angle_normalized_to_mat3(totmat, axis2, phi[1]);
@@ -4049,6 +4066,7 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2]))
// TRANSFORM_FIX_ME
//copy_m3_m3(t->mat, mat); // used in manipulator
+#endif
applyTrackballValue(t, axis1, axis2, phi);
@@ -4374,6 +4392,8 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
applyNumInput(&t->num, &distance);
+ t->values[0] = -distance;
+
/* header print for NumInput */
ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Shrink/Fatten:"), MAX_INFO_LEN - ofs);
if (hasNumInput(&t->num)) {
@@ -4401,9 +4421,6 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
WM_bool_as_string((t->flag & T_ALT_TRANSFORM) != 0));
/* done with header string */
-
- t->values[0] = -distance;
-
for (i = 0; i < t->total; i++, td++) {
float tdistance; /* temp dist */
if (td->flag & TD_NOACTION)
@@ -4470,6 +4487,8 @@ static void applyTilt(TransInfo *t, const int UNUSED(mval[2]))
applyNumInput(&t->num, &final);
+ t->values[0] = final;
+
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
@@ -4547,6 +4566,8 @@ static void applyCurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
applyNumInput(&t->num, &ratio);
+ t->values[0] = ratio;
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
@@ -4625,6 +4646,8 @@ static void applyMaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
applyNumInput(&t->num, &ratio);
+ t->values[0] = ratio;
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
@@ -4723,6 +4746,8 @@ static void applyGPShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
applyNumInput(&t->num, &ratio);
+ t->values[0] = ratio;
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
@@ -4795,6 +4820,8 @@ static void applyPushPull(TransInfo *t, const int UNUSED(mval[2]))
applyNumInput(&t->num, &distance);
+ t->values[0] = distance;
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
@@ -4808,8 +4835,6 @@ static void applyPushPull(TransInfo *t, const int UNUSED(mval[2]))
BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Push/Pull: %.4f%s %s"), distance, t->con.text, t->proptext);
}
- t->values[0] = distance;
-
if (t->con.applyRot && t->con.mode & CON_APPLY) {
t->con.applyRot(t, NULL, axis, NULL);
}
@@ -4882,12 +4907,14 @@ static void applyBevelWeight(TransInfo *t, const int UNUSED(mval[2]))
weight = t->values[0];
- if (weight > 1.0f) weight = 1.0f;
+ CLAMP_MAX(weight, 1.0f);
snapGridIncrement(t, &weight);
applyNumInput(&t->num, &weight);
+ t->values[0] = weight;
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
@@ -4960,12 +4987,14 @@ static void applyCrease(TransInfo *t, const int UNUSED(mval[2]))
crease = t->values[0];
- if (crease > 1.0f) crease = 1.0f;
+ CLAMP_MAX(crease, 1.0f);
snapGridIncrement(t, &crease);
applyNumInput(&t->num, &crease);
+ t->values[0] = crease;
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
@@ -5099,7 +5128,7 @@ static void applyBoneSize(TransInfo *t, const int mval[2])
ratio = t->values[0];
}
- size[0] = size[1] = size[2] = ratio;
+ copy_v3_fl(size, ratio);
snapGridIncrement(t, size);
@@ -5107,6 +5136,8 @@ static void applyBoneSize(TransInfo *t, const int mval[2])
constraintNumInput(t, size);
}
+ copy_v3_v3(t->values, size);
+
size_to_mat3(mat, size);
if (t->con.applySize) {
@@ -5173,6 +5204,8 @@ static void applyBoneEnvelope(TransInfo *t, const int UNUSED(mval[2]))
applyNumInput(&t->num, &ratio);
+ t->values[0] = ratio;
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
@@ -5260,11 +5293,22 @@ static void slide_origdata_create_data_vert(
loop_weights = BLI_array_alloca(loop_weights, l_num);
for (j = 0; j < l_num; j++) {
BMLoop *l = BM_iter_step(&liter);
- if (!BLI_ghash_haskey(sod->origfaces, l->f)) {
+ BMLoop *l_prev, *l_next;
+ void **val_p;
+ if (!BLI_ghash_ensure_p(sod->origfaces, l->f, &val_p)) {
BMFace *f_copy = BM_face_copy(sod->bm_origfaces, bm, l->f, true, true);
- BLI_ghash_insert(sod->origfaces, l->f, f_copy);
+ *val_p = f_copy;
+ }
+
+ if ((l_prev = BM_loop_find_prev_nodouble(l, l->next, FLT_EPSILON)) &&
+ (l_next = BM_loop_find_next_nodouble(l, l_prev, FLT_EPSILON)))
+ {
+ loop_weights[j] = angle_v3v3v3(l_prev->v->co, l->v->co, l_next->v->co);
}
- loop_weights[j] = BM_loop_calc_face_angle(l);
+ else {
+ loop_weights[j] = 0.0f;
+ }
+
}
/* store cd_loop_groups */
@@ -5332,6 +5376,13 @@ static void slide_origdata_interp_data_vert(
int j, l_num;
float *loop_weights;
const bool do_loop_weight = (len_squared_v3v3(sv->v->co, sv->co_orig_3d) > FLT_EPSILON);
+ const float *v_proj_axis = sv->v->no;
+ /* original (l->prev, l, l->next) projections for each loop ('l' remains unchanged) */
+ float v_proj[3][3];
+
+ if (do_loop_weight) {
+ project_plane_v3_v3v3(v_proj[1], sv->co_orig_3d, v_proj_axis);
+ }
// BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) {
BM_iter_init(&liter, bm, BM_LOOPS_OF_VERT, sv->v);
@@ -5352,11 +5403,44 @@ static void slide_origdata_interp_data_vert(
/* weight the loop */
if (do_loop_weight) {
- const float *v_prev = slide_origdata_orig_vert_co(sod, l->prev->v);
- const float *v_next = slide_origdata_orig_vert_co(sod, l->next->v);
- const float dist = dist_signed_squared_to_corner_v3v3v3(sv->v->co, v_prev, sv->co_orig_3d, v_next, f_copy->no);
- const float eps = 0.00001f;
- loop_weights[j] = (dist >= 0.0f) ? 1.0f : ((dist <= -eps) ? 0.0f : (1.0f + (dist / eps)));
+ const float eps = 1.0e-8f;
+ const BMLoop *l_prev = l->prev;
+ const BMLoop *l_next = l->next;
+ const float *co_prev = slide_origdata_orig_vert_co(sod, l_prev->v);
+ const float *co_next = slide_origdata_orig_vert_co(sod, l_next->v);
+ bool co_prev_ok;
+ bool co_next_ok;
+
+
+ /* In the unlikely case that we're next to a zero length edge - walk around the to the next.
+ * Since we only need to check if the vertex is in this corner,
+ * its not important _which_ loop - as long as its not overlapping 'sv->co_orig_3d', see: T45096. */
+ project_plane_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
+ while (UNLIKELY(((co_prev_ok = (len_squared_v3v3(v_proj[1], v_proj[0]) > eps)) == false) &&
+ ((l_prev = l_prev->prev) != l->next)))
+ {
+ co_prev = slide_origdata_orig_vert_co(sod, l_prev->v);
+ project_plane_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
+ }
+ project_plane_v3_v3v3(v_proj[2], co_next, v_proj_axis);
+ while (UNLIKELY(((co_next_ok = (len_squared_v3v3(v_proj[1], v_proj[2]) > eps)) == false) &&
+ ((l_next = l_next->next) != l->prev)))
+ {
+ co_next = slide_origdata_orig_vert_co(sod, l_next->v);
+ project_plane_v3_v3v3(v_proj[2], co_next, v_proj_axis);
+ }
+
+ if (co_prev_ok && co_next_ok) {
+ const float dist = dist_signed_squared_to_corner_v3v3v3(sv->v->co, UNPACK3(v_proj), v_proj_axis);
+
+ loop_weights[j] = (dist >= 0.0f) ? 1.0f : ((dist <= -eps) ? 0.0f : (1.0f + (dist / eps)));
+ if (UNLIKELY(!isfinite(loop_weights[j]))) {
+ loop_weights[j] = 0.0f;
+ }
+ }
+ else {
+ loop_weights[j] = 0.0f;
+ }
}
}
@@ -5427,6 +5511,19 @@ static void slide_origdata_free_date(
/** \name Transform Edge Slide
* \{ */
+static void calcEdgeSlideCustomPoints(struct TransInfo *t)
+{
+ EdgeSlideData *sld = t->customData;
+
+ setCustomPoints(t, &t->mouse, sld->mval_end, sld->mval_start);
+
+ /* setCustomPoints isn't normally changing as the mouse moves,
+ * in this case apply mouse input immediatly so we don't refresh
+ * with the value from the previous points */
+ applyMouseInput(t, &t->mouse, t->mval, t->values);
+}
+
+
static BMEdge *get_other_edge(BMVert *v, BMEdge *e)
{
BMIter iter;
@@ -5442,7 +5539,7 @@ static BMEdge *get_other_edge(BMVert *v, BMEdge *e)
}
/* interpoaltes along a line made up of 2 segments (used for edge slide) */
-static void interp_line_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float t)
+static void interp_line_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], float t)
{
float t_mid, t_delta;
@@ -5450,17 +5547,28 @@ static void interp_line_v3_v3v3v3(float p[3], const float v1[3], const float v2[
t_mid = line_point_factor_v3(v2, v1, v3);
t_delta = t - t_mid;
- if (fabsf(t_delta) < FLT_EPSILON) {
- copy_v3_v3(p, v2);
- }
- else if (t_delta < 0.0f) {
- interp_v3_v3v3(p, v1, v2, t / t_mid);
+ if (t_delta < 0.0f) {
+ if (UNLIKELY(fabsf(t_mid) < FLT_EPSILON)) {
+ copy_v3_v3(p, v2);
+ }
+ else {
+ interp_v3_v3v3(p, v1, v2, t / t_mid);
+ }
}
else {
- interp_v3_v3v3(p, v2, v3, (t - t_mid) / (1.0f - t_mid));
+ t = t - t_mid;
+ t_mid = 1.0f - t_mid;
+
+ if (UNLIKELY(fabsf(t_mid) < FLT_EPSILON)) {
+ copy_v3_v3(p, v3);
+ }
+ else {
+ interp_v3_v3v3(p, v2, v3, t / t_mid);
+ }
}
}
+
static void len_v3_ensure(float v[3], const float length)
{
normalize_v3(v);
@@ -5605,7 +5713,171 @@ static BMLoop *get_next_loop(BMVert *v, BMLoop *l,
return NULL;
}
-static void calcNonProportionalEdgeSlide(TransInfo *t, EdgeSlideData *sld, const float mval[2])
+/**
+ * Calculate screenspace `mval_start` / `mval_end`, optionally slide direction.
+ */
+static void calcEdgeSlide_mval_range(
+ TransInfo *t, EdgeSlideData *sld, const int *sv_table, const int loop_nr,
+ const float mval[2], const bool use_btree_disp, const bool use_calc_direction)
+{
+ TransDataEdgeSlideVert *sv_array = sld->sv;
+ BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
+ BMesh *bm = em->bm;
+ ARegion *ar = t->ar;
+ View3D *v3d = NULL;
+ RegionView3D *rv3d = NULL;
+ float projectMat[4][4];
+ BMBVHTree *btree;
+
+ /* only for use_calc_direction */
+ float (*loop_dir)[3] = NULL, *loop_maxdist = NULL;
+
+ float mval_start[2], mval_end[2];
+ float mval_dir[3], dist_best_sq;
+ BMIter iter;
+ BMEdge *e;
+
+ if (t->spacetype == SPACE_VIEW3D) {
+ /* background mode support */
+ v3d = t->sa ? t->sa->spacedata.first : NULL;
+ rv3d = t->ar ? t->ar->regiondata : NULL;
+ }
+
+ if (!rv3d) {
+ /* ok, let's try to survive this */
+ unit_m4(projectMat);
+ }
+ else {
+ ED_view3d_ob_project_mat_get(rv3d, t->obedit, projectMat);
+ }
+
+ if (use_btree_disp) {
+ btree = BKE_bmbvh_new_from_editmesh(em, BMBVH_RESPECT_HIDDEN, NULL, false);
+ }
+ else {
+ btree = NULL;
+ }
+
+ /* find mouse vectors, the global one, and one per loop in case we have
+ * multiple loops selected, in case they are oriented different */
+ zero_v3(mval_dir);
+ dist_best_sq = -1.0f;
+
+ if (use_calc_direction) {
+ loop_dir = MEM_callocN(sizeof(float[3]) * loop_nr, "sv loop_dir");
+ loop_maxdist = MEM_mallocN(sizeof(float) * loop_nr, "sv loop_maxdist");
+ copy_vn_fl(loop_maxdist, loop_nr, -1.0f);
+ }
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ int i;
+
+ /* search cross edges for visible edge to the mouse cursor,
+ * then use the shared vertex to calculate screen vector*/
+ for (i = 0; i < 2; i++) {
+ BMIter iter_other;
+ BMEdge *e_other;
+
+ BMVert *v = i ? e->v1 : e->v2;
+ BM_ITER_ELEM (e_other, &iter_other, v, BM_EDGES_OF_VERT) {
+ /* screen-space coords */
+ float sco_a[3], sco_b[3];
+ float dist_sq;
+ int j, l_nr;
+
+ if (BM_elem_flag_test(e_other, BM_ELEM_SELECT))
+ continue;
+
+ /* This test is only relevant if object is not wire-drawn! See [#32068]. */
+ if (use_btree_disp && !BMBVH_EdgeVisible(btree, e_other, ar, v3d, t->obedit)) {
+ continue;
+ }
+
+ BLI_assert(sv_table[BM_elem_index_get(v)] != -1);
+ j = sv_table[BM_elem_index_get(v)];
+
+ if (sv_array[j].v_side[1]) {
+ ED_view3d_project_float_v3_m4(ar, sv_array[j].v_side[1]->co, sco_b, projectMat);
+ }
+ else {
+ add_v3_v3v3(sco_b, v->co, sv_array[j].dir_side[1]);
+ ED_view3d_project_float_v3_m4(ar, sco_b, sco_b, projectMat);
+ }
+
+ if (sv_array[j].v_side[0]) {
+ ED_view3d_project_float_v3_m4(ar, sv_array[j].v_side[0]->co, sco_a, projectMat);
+ }
+ else {
+ add_v3_v3v3(sco_a, v->co, sv_array[j].dir_side[0]);
+ ED_view3d_project_float_v3_m4(ar, sco_a, sco_a, projectMat);
+ }
+
+ /* global direction */
+ dist_sq = dist_squared_to_line_segment_v2(mval, sco_b, sco_a);
+ if ((dist_best_sq == -1.0f) ||
+ /* intentionally use 2d size on 3d vector */
+ (dist_sq < dist_best_sq && (len_squared_v2v2(sco_b, sco_a) > 0.1f)))
+ {
+ dist_best_sq = dist_sq;
+ sub_v3_v3v3(mval_dir, sco_b, sco_a);
+ }
+
+ if (use_calc_direction) {
+ /* per loop direction */
+ l_nr = sv_array[j].loop_nr;
+ if (loop_maxdist[l_nr] == -1.0f || dist_sq < loop_maxdist[l_nr]) {
+ loop_maxdist[l_nr] = dist_sq;
+ sub_v3_v3v3(loop_dir[l_nr], sco_b, sco_a);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (use_calc_direction) {
+ int i;
+ sv_array = sld->sv;
+ for (i = 0; i < sld->totsv; i++, sv_array++) {
+ /* switch a/b if loop direction is different from global direction */
+ int l_nr = sv_array->loop_nr;
+ if (dot_v3v3(loop_dir[l_nr], mval_dir) < 0.0f) {
+ swap_v3_v3(sv_array->dir_side[0], sv_array->dir_side[1]);
+ SWAP(BMVert *, sv_array->v_side[0], sv_array->v_side[1]);
+ }
+ }
+
+ MEM_freeN(loop_dir);
+ MEM_freeN(loop_maxdist);
+ }
+
+ /* possible all of the edge loops are pointing directly at the view */
+ if (UNLIKELY(len_squared_v2(mval_dir) < 0.1f)) {
+ mval_dir[0] = 0.0f;
+ mval_dir[1] = 100.0f;
+ }
+
+ /* zero out start */
+ zero_v2(mval_start);
+
+ /* dir holds a vector along edge loop */
+ copy_v2_v2(mval_end, mval_dir);
+ mul_v2_fl(mval_end, 0.5f);
+
+ sld->mval_start[0] = t->mval[0] + mval_start[0];
+ sld->mval_start[1] = t->mval[1] + mval_start[1];
+
+ sld->mval_end[0] = t->mval[0] + mval_end[0];
+ sld->mval_end[1] = t->mval[1] + mval_end[1];
+
+ if (btree) {
+ BKE_bmbvh_free(btree);
+ }
+}
+
+static void calcEdgeSlide_non_proportional(
+ TransInfo *t, EdgeSlideData *sld, const float mval[2])
{
TransDataEdgeSlideVert *sv = sld->sv;
@@ -5635,7 +5907,7 @@ static void calcNonProportionalEdgeSlide(TransInfo *t, EdgeSlideData *sld, const
for (i = 0; i < sld->totsv; i++, sv++) {
/* Set length */
- sv->edge_len = len_v3v3(sv->dir_a, sv->dir_b);
+ sv->edge_len = len_v3v3(sv->dir_side[0], sv->dir_side[1]);
ED_view3d_project_float_v2_m4(ar, sv->v->co, v_proj, projectMat);
dist_sq = len_squared_v2v2(mval, v_proj);
@@ -5650,7 +5922,7 @@ static void calcNonProportionalEdgeSlide(TransInfo *t, EdgeSlideData *sld, const
}
}
-static bool createEdgeSlideVerts(TransInfo *t)
+static bool createEdgeSlideVerts_double_side(TransInfo *t)
{
BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
BMesh *bm = em->bm;
@@ -5659,24 +5931,13 @@ static bool createEdgeSlideVerts(TransInfo *t)
BMVert *v;
TransDataEdgeSlideVert *sv_array;
int sv_tot;
- BMBVHTree *btree;
int *sv_table; /* BMVert -> sv_array index */
EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld");
+ float mval[2] = {(float)t->mval[0], (float)t->mval[1]};
+ int numsel, i, j, loop_nr;
+ bool use_btree_disp = false;
View3D *v3d = NULL;
RegionView3D *rv3d = NULL;
- ARegion *ar = t->ar;
- float projectMat[4][4];
- float mval[2] = {(float)t->mval[0], (float)t->mval[1]};
- float mval_start[2], mval_end[2];
- float mval_dir[3], maxdist, (*loop_dir)[3], *loop_maxdist;
- int numsel, i, j, loop_nr, l_nr;
- int use_btree_disp;
-
- if (t->spacetype == SPACE_VIEW3D) {
- /* background mode support */
- v3d = t->sa ? t->sa->spacedata.first : NULL;
- rv3d = t->ar ? t->ar->regiondata : NULL;
- }
slide_origdata_init_flag(t, &sld->orig_data);
@@ -5684,14 +5945,6 @@ static bool createEdgeSlideVerts(TransInfo *t)
sld->curr_sv_index = 0;
sld->flipped_vtx = false;
- if (!rv3d) {
- /* ok, let's try to survive this */
- unit_m4(projectMat);
- }
- else {
- ED_view3d_ob_project_mat_get(rv3d, t->obedit, projectMat);
- }
-
/*ensure valid selection*/
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
@@ -5863,14 +6116,14 @@ static bool createEdgeSlideVerts(TransInfo *t)
if (l_a || l_a_prev) {
BMLoop *l_tmp = BM_loop_other_edge_loop(l_a ? l_a : l_a_prev, v);
- sv->v_a = BM_edge_other_vert(l_tmp->e, v);
- copy_v3_v3(sv->dir_a, vec_a);
+ sv->v_side[0] = BM_edge_other_vert(l_tmp->e, v);
+ copy_v3_v3(sv->dir_side[0], vec_a);
}
if (l_b || l_b_prev) {
BMLoop *l_tmp = BM_loop_other_edge_loop(l_b ? l_b : l_b_prev, v);
- sv->v_b = BM_edge_other_vert(l_tmp->e, v);
- copy_v3_v3(sv->dir_b, vec_b);
+ sv->v_side[1] = BM_edge_other_vert(l_tmp->e, v);
+ copy_v3_v3(sv->dir_side[1], vec_b);
}
v_prev = v;
@@ -5889,23 +6142,23 @@ static bool createEdgeSlideVerts(TransInfo *t)
if (l_a) {
BMLoop *l_tmp = BM_loop_other_edge_loop(l_a, v);
- sv->v_a = BM_edge_other_vert(l_tmp->e, v);
+ sv->v_side[0] = BM_edge_other_vert(l_tmp->e, v);
if (EDGESLIDE_VERT_IS_INNER(v, l_tmp->e)) {
- get_next_loop(v, l_a, e_prev, l_tmp->e, sv->dir_a);
+ get_next_loop(v, l_a, e_prev, l_tmp->e, sv->dir_side[0]);
}
else {
- sub_v3_v3v3(sv->dir_a, BM_edge_other_vert(l_tmp->e, v)->co, v->co);
+ sub_v3_v3v3(sv->dir_side[0], sv->v_side[0]->co, v->co);
}
}
if (l_b) {
BMLoop *l_tmp = BM_loop_other_edge_loop(l_b, v);
- sv->v_b = BM_edge_other_vert(l_tmp->e, v);
+ sv->v_side[1] = BM_edge_other_vert(l_tmp->e, v);
if (EDGESLIDE_VERT_IS_INNER(v, l_tmp->e)) {
- get_next_loop(v, l_b, e_prev, l_tmp->e, sv->dir_b);
+ get_next_loop(v, l_b, e_prev, l_tmp->e, sv->dir_side[1]);
}
else {
- sub_v3_v3v3(sv->dir_b, BM_edge_other_vert(l_tmp->e, v)->co, v->co);
+ sub_v3_v3v3(sv->dir_side[1], sv->v_side[1]->co, v->co);
}
}
@@ -5976,142 +6229,228 @@ static bool createEdgeSlideVerts(TransInfo *t)
#undef EDGESLIDE_VERT_IS_INNER
}
- /* use for visibility checks */
- use_btree_disp = (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE);
+ /* EDBM_flag_disable_all(em, BM_ELEM_SELECT); */
- if (use_btree_disp) {
- btree = BKE_bmbvh_new_from_editmesh(em, BMBVH_RESPECT_HIDDEN, NULL, false);
- }
- else {
- btree = NULL;
+ sld->sv = sv_array;
+ sld->totsv = sv_tot;
+
+ /* use for visibility checks */
+ if (t->spacetype == SPACE_VIEW3D) {
+ v3d = t->sa ? t->sa->spacedata.first : NULL;
+ rv3d = t->ar ? t->ar->regiondata : NULL;
+ use_btree_disp = (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE);
}
+ calcEdgeSlide_mval_range(t, sld, sv_table, loop_nr, mval, use_btree_disp, true);
- /* EDBM_flag_disable_all(em, BM_ELEM_SELECT); */
+ /* create copies of faces for customdata projection */
+ bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
+ slide_origdata_init_data(t, &sld->orig_data);
+ slide_origdata_create_data(t, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
- sld->sv = sv_array;
- sld->totsv = sv_tot;
+ if (rv3d) {
+ calcEdgeSlide_non_proportional(t, sld, mval);
+ }
+
+ sld->em = em;
- /* find mouse vectors, the global one, and one per loop in case we have
- * multiple loops selected, in case they are oriented different */
- zero_v3(mval_dir);
- maxdist = -1.0f;
+ sld->perc = 0.0f;
+
+ t->customData = sld;
+
+ MEM_freeN(sv_table);
- loop_dir = MEM_callocN(sizeof(float) * 3 * loop_nr, "sv loop_dir");
- loop_maxdist = MEM_mallocN(sizeof(float) * loop_nr, "sv loop_maxdist");
- fill_vn_fl(loop_maxdist, loop_nr, -1.0f);
+ return true;
+}
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- BMIter iter2;
- BMEdge *e2;
- float d;
+/**
+ * A simple version of #createEdgeSlideVerts
+ * Which assumes the longest unselected.
+ */
+static bool createEdgeSlideVerts_single_side(TransInfo *t)
+{
+ BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
+ BMesh *bm = em->bm;
+ BMIter iter;
+ BMEdge *e;
+ BMVert *v;
+ TransDataEdgeSlideVert *sv_array;
+ int sv_tot;
+ int *sv_table; /* BMVert -> sv_array index */
+ EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld");
+ float mval[2] = {(float)t->mval[0], (float)t->mval[1]};
+ int i, j, loop_nr;
+ bool use_btree_disp = false;
+ View3D *v3d = NULL;
+ RegionView3D *rv3d = NULL;
- /* search cross edges for visible edge to the mouse cursor,
- * then use the shared vertex to calculate screen vector*/
- for (i = 0; i < 2; i++) {
- v = i ? e->v1 : e->v2;
- BM_ITER_ELEM (e2, &iter2, v, BM_EDGES_OF_VERT) {
- /* screen-space coords */
- float sco_a[3], sco_b[3];
+ if (t->spacetype == SPACE_VIEW3D) {
+ /* background mode support */
+ v3d = t->sa ? t->sa->spacedata.first : NULL;
+ rv3d = t->ar ? t->ar->regiondata : NULL;
+ }
- if (BM_elem_flag_test(e2, BM_ELEM_SELECT))
- continue;
+ slide_origdata_init_flag(t, &sld->orig_data);
- /* This test is only relevant if object is not wire-drawn! See [#32068]. */
- if (use_btree_disp && !BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit)) {
- continue;
+ sld->is_proportional = true;
+ sld->curr_sv_index = 0;
+ /* heppans to be best for single-sided */
+ sld->flipped_vtx = true;
+
+ /* ensure valid selection */
+ j = 0;
+ BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ float len_sq_max = -1.0f;
+ BMIter iter2;
+ BM_ITER_ELEM (e, &iter2, v, BM_EDGES_OF_VERT) {
+ if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ float len_sq = BM_edge_calc_length_squared(e);
+ if (len_sq > len_sq_max) {
+ len_sq_max = len_sq;
+ v->e = e;
}
+ }
+ }
- BLI_assert(sv_table[BM_elem_index_get(v)] != -1);
- j = sv_table[BM_elem_index_get(v)];
+ if (len_sq_max != -1.0f) {
+ j++;
+ }
+ }
+ BM_elem_index_set(v, i); /* set_inline */
+ }
+ bm->elem_index_dirty &= ~BM_VERT;
- if (sv_array[j].v_b) {
- ED_view3d_project_float_v3_m4(ar, sv_array[j].v_b->co, sco_b, projectMat);
- }
- else {
- add_v3_v3v3(sco_b, v->co, sv_array[j].dir_b);
- ED_view3d_project_float_v3_m4(ar, sco_b, sco_b, projectMat);
- }
-
- if (sv_array[j].v_a) {
- ED_view3d_project_float_v3_m4(ar, sv_array[j].v_a->co, sco_a, projectMat);
+ if (!j) {
+ return false;
+ }
+
+
+ sv_tot = j;
+ BLI_assert(sv_tot != 0);
+ /* over alloc */
+ sv_array = MEM_callocN(sizeof(TransDataEdgeSlideVert) * bm->totvertsel, "sv_array");
+
+ /* same loop for all loops, weak but we dont connect loops in this case */
+ loop_nr = 1;
+
+ sv_table = MEM_mallocN(sizeof(*sv_table) * bm->totvert, __func__);
+
+ j = 0;
+ BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
+ sv_table[i] = -1;
+ if ((v->e != NULL) && (BM_elem_flag_test(v, BM_ELEM_SELECT))) {
+ if (BM_elem_flag_test(v->e, BM_ELEM_SELECT) == 0) {
+ TransDataEdgeSlideVert *sv;
+ sv = &sv_array[j];
+ sv->v = v;
+ copy_v3_v3(sv->v_co_orig, v->co);
+ sv->v_side[0] = BM_edge_other_vert(v->e, v);
+ sub_v3_v3v3(sv->dir_side[0], sv->v_side[0]->co, v->co);
+ sv->loop_nr = 0;
+ sv_table[i] = j;
+ j += 1;
+ }
+ }
+ }
+
+ /* check for wire vertices,
+ * interpolate the directions of wire verts between non-wire verts */
+ if (sv_tot != bm->totvert) {
+ const int sv_tot_nowire = sv_tot;
+ TransDataEdgeSlideVert *sv_iter = sv_array;
+ int i;
+ for (i = 0; i < sv_tot_nowire; i++, sv_iter++) {
+ BMIter eiter;
+ BM_ITER_ELEM (e, &eiter, sv_iter->v, BM_EDGES_OF_VERT) {
+ /* walk over wire */
+ TransDataEdgeSlideVert *sv_end = NULL;
+ BMEdge *e_step = e;
+ BMVert *v = sv_iter->v;
+
+ j = sv_tot;
+
+ while (1) {
+ BMVert *v_other = BM_edge_other_vert(e_step, v);
+ int endpoint = (
+ (sv_table[BM_elem_index_get(v_other)] != -1) +
+ (BM_vert_is_edge_pair(v_other) == false));
+
+ if ((BM_elem_flag_test(e_step, BM_ELEM_SELECT) &&
+ BM_elem_flag_test(v_other, BM_ELEM_SELECT)) &&
+ (endpoint == 0))
+ {
+ /* scan down the list */
+ TransDataEdgeSlideVert *sv;
+ BLI_assert(sv_table[BM_elem_index_get(v_other)] == -1);
+ sv_table[BM_elem_index_get(v_other)] = j;
+ sv = &sv_array[j];
+ sv->v = v_other;
+ copy_v3_v3(sv->v_co_orig, v_other->co);
+ copy_v3_v3(sv->dir_side[0], sv_iter->dir_side[0]);
+ j++;
+
+ /* advance! */
+ v = v_other;
+ e_step = BM_DISK_EDGE_NEXT(e_step, v_other);
}
else {
- add_v3_v3v3(sco_a, v->co, sv_array[j].dir_a);
- ED_view3d_project_float_v3_m4(ar, sco_a, sco_a, projectMat);
- }
-
- /* global direction */
- d = dist_to_line_segment_v2(mval, sco_b, sco_a);
- if ((maxdist == -1.0f) ||
- /* intentionally use 2d size on 3d vector */
- (d < maxdist && (len_squared_v2v2(sco_b, sco_a) > 0.1f)))
- {
- maxdist = d;
- sub_v3_v3v3(mval_dir, sco_b, sco_a);
+ if ((endpoint == 2) && (sv_tot != j)) {
+ BLI_assert(BM_elem_index_get(v_other) != -1);
+ sv_end = &sv_array[sv_table[BM_elem_index_get(v_other)]];
+ }
+ break;
}
+ }
- /* per loop direction */
- l_nr = sv_array[j].loop_nr;
- if (loop_maxdist[l_nr] == -1.0f || d < loop_maxdist[l_nr]) {
- loop_maxdist[l_nr] = d;
- sub_v3_v3v3(loop_dir[l_nr], sco_b, sco_a);
+ if (sv_end) {
+ int sv_tot_prev = sv_tot;
+ const float *co_src = sv_iter->v->co;
+ const float *co_dst = sv_end->v->co;
+ const float *dir_src = sv_iter->dir_side[0];
+ const float *dir_dst = sv_end->dir_side[0];
+ sv_tot = j;
+
+ while (j-- != sv_tot_prev) {
+ float factor;
+ factor = line_point_factor_v3(sv_array[j].v->co, co_src, co_dst);
+ interp_v3_v3v3(sv_array[j].dir_side[0], dir_src, dir_dst, factor);
}
}
}
}
}
- /* possible all of the edge loops are pointing directly at the view */
- if (UNLIKELY(len_squared_v2(mval_dir) < 0.1f)) {
- mval_dir[0] = 0.0f;
- mval_dir[1] = 100.0f;
+ /* EDBM_flag_disable_all(em, BM_ELEM_SELECT); */
+
+ sld->sv = sv_array;
+ sld->totsv = sv_tot;
+
+ /* use for visibility checks */
+ if (t->spacetype == SPACE_VIEW3D) {
+ v3d = t->sa ? t->sa->spacedata.first : NULL;
+ rv3d = t->ar ? t->ar->regiondata : NULL;
+ use_btree_disp = (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE);
}
+ calcEdgeSlide_mval_range(t, sld, sv_table, loop_nr, mval, use_btree_disp, false);
+
+ /* create copies of faces for customdata projection */
bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
slide_origdata_init_data(t, &sld->orig_data);
slide_origdata_create_data(t, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
- /*create copies of faces for customdata projection*/
- sv_array = sld->sv;
- for (i = 0; i < sld->totsv; i++, sv_array++) {
- /* switch a/b if loop direction is different from global direction */
- l_nr = sv_array->loop_nr;
- if (dot_v3v3(loop_dir[l_nr], mval_dir) < 0.0f) {
- swap_v3_v3(sv_array->dir_a, sv_array->dir_b);
- SWAP(BMVert *, sv_array->v_a, sv_array->v_b);
- }
+ if (rv3d) {
+ calcEdgeSlide_non_proportional(t, sld, mval);
}
- if (rv3d)
- calcNonProportionalEdgeSlide(t, sld, mval);
-
sld->em = em;
- /*zero out start*/
- zero_v2(mval_start);
-
- /*dir holds a vector along edge loop*/
- copy_v2_v2(mval_end, mval_dir);
- mul_v2_fl(mval_end, 0.5f);
-
- sld->mval_start[0] = t->mval[0] + mval_start[0];
- sld->mval_start[1] = t->mval[1] + mval_start[1];
-
- sld->mval_end[0] = t->mval[0] + mval_end[0];
- sld->mval_end[1] = t->mval[1] + mval_end[1];
-
sld->perc = 0.0f;
-
+
t->customData = sld;
-
+
MEM_freeN(sv_table);
- if (btree) {
- BKE_bmbvh_free(btree);
- }
- MEM_freeN(loop_dir);
- MEM_freeN(loop_maxdist);
return true;
}
@@ -6152,15 +6491,23 @@ void freeEdgeSlideVerts(TransInfo *t)
recalcData(t);
}
-static void initEdgeSlide(TransInfo *t)
+static void initEdgeSlide_ex(TransInfo *t, bool use_double_side)
{
EdgeSlideData *sld;
+ bool ok;
t->mode = TFM_EDGE_SLIDE;
t->transform = applyEdgeSlide;
t->handleEvent = handleEventEdgeSlide;
- if (!createEdgeSlideVerts(t)) {
+ if (use_double_side) {
+ ok = createEdgeSlideVerts_double_side(t);
+ }
+ else {
+ ok = createEdgeSlideVerts_single_side(t);
+ }
+
+ if (!ok) {
t->state = TRANS_CANCEL;
return;
}
@@ -6173,7 +6520,7 @@ static void initEdgeSlide(TransInfo *t)
t->customFree = freeEdgeSlideVerts;
/* set custom point first if you want value to be initialized by init */
- setCustomPoints(t, &t->mouse, sld->mval_end, sld->mval_start);
+ calcEdgeSlideCustomPoints(t);
initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO_FLIP);
t->idx_max = 0;
@@ -6189,6 +6536,11 @@ static void initEdgeSlide(TransInfo *t)
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
+static void initEdgeSlide(TransInfo *t)
+{
+ initEdgeSlide_ex(t, true);
+}
+
static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEvent *event)
{
if (t->mode == TFM_EDGE_SLIDE) {
@@ -6199,35 +6551,40 @@ static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEven
case EKEY:
if (event->val == KM_PRESS) {
sld->is_proportional = !sld->is_proportional;
+ calcEdgeSlideCustomPoints(t);
return TREDRAW_HARD;
}
break;
case FKEY:
- {
if (event->val == KM_PRESS) {
if (sld->is_proportional == false) {
sld->flipped_vtx = !sld->flipped_vtx;
}
+ calcEdgeSlideCustomPoints(t);
+ return TREDRAW_HARD;
+ }
+ break;
+ case CKEY:
+ /* use like a modifier key */
+ if (event->val == KM_PRESS) {
+ t->flag ^= T_ALT_TRANSFORM;
+ calcEdgeSlideCustomPoints(t);
return TREDRAW_HARD;
}
break;
- }
case EVT_MODAL_MAP:
- {
switch (event->val) {
case TFM_MODAL_EDGESLIDE_DOWN:
- {
sld->curr_sv_index = ((sld->curr_sv_index - 1) + sld->totsv) % sld->totsv;
- break;
- }
+ return TREDRAW_HARD;
case TFM_MODAL_EDGESLIDE_UP:
- {
sld->curr_sv_index = (sld->curr_sv_index + 1) % sld->totsv;
- break;
- }
+ return TREDRAW_HARD;
}
break;
- }
+ case MOUSEMOVE:
+ calcEdgeSlideCustomPoints(t);
+ break;
default:
break;
}
@@ -6236,23 +6593,16 @@ static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEven
return TREDRAW_NOTHING;
}
-static void drawEdgeSlide(const struct bContext *C, TransInfo *t)
+static void drawEdgeSlide(TransInfo *t)
{
- if (t->mode == TFM_EDGE_SLIDE) {
- EdgeSlideData *sld = (EdgeSlideData *)t->customData;
+ if ((t->mode == TFM_EDGE_SLIDE) && t->customData) {
+ EdgeSlideData *sld = t->customData;
+ const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
+
/* Non-Prop mode */
- if (sld && sld->is_proportional == false) {
- View3D *v3d = CTX_wm_view3d(C);
- float co_a[3], co_b[3], co_mark[3];
- TransDataEdgeSlideVert *curr_sv = &sld->sv[sld->curr_sv_index];
- const float fac = (sld->perc + 1.0f) / 2.0f;
- const float ctrl_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 1.5f;
- const float guide_size = ctrl_size - 0.5f;
+ if ((sld->is_proportional == false) || (is_clamp == false)) {
+ View3D *v3d = t->view;
const float line_size = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.5f;
- const int alpha_shade = -30;
-
- add_v3_v3v3(co_a, curr_sv->v_co_orig, curr_sv->dir_a);
- add_v3_v3v3(co_b, curr_sv->v_co_orig, curr_sv->dir_b);
if (v3d && v3d->zbuf)
glDisable(GL_DEPTH_TEST);
@@ -6265,42 +6615,88 @@ static void drawEdgeSlide(const struct bContext *C, TransInfo *t)
glMultMatrixf(t->obedit->obmat);
- glLineWidth(line_size);
- UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
- glBegin(GL_LINES);
- if (curr_sv->v_a) {
- glVertex3fv(curr_sv->v_a->co);
- glVertex3fv(curr_sv->v_co_orig);
- }
- if (curr_sv->v_b) {
- glVertex3fv(curr_sv->v_b->co);
- glVertex3fv(curr_sv->v_co_orig);
- }
- bglEnd();
+ if (sld->is_proportional == false) {
+ float co_a[3], co_b[3], co_mark[3];
+ TransDataEdgeSlideVert *curr_sv = &sld->sv[sld->curr_sv_index];
+ const float fac = (sld->perc + 1.0f) / 2.0f;
+ const float ctrl_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 1.5f;
+ const float guide_size = ctrl_size - 0.5f;
+ const int alpha_shade = -30;
+
+ add_v3_v3v3(co_a, curr_sv->v_co_orig, curr_sv->dir_side[0]);
+ add_v3_v3v3(co_b, curr_sv->v_co_orig, curr_sv->dir_side[1]);
+
+ glLineWidth(line_size);
+ UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
+ glBegin(GL_LINES);
+ if (curr_sv->v_side[0]) {
+ glVertex3fv(curr_sv->v_side[0]->co);
+ glVertex3fv(curr_sv->v_co_orig);
+ }
+ if (curr_sv->v_side[1]) {
+ glVertex3fv(curr_sv->v_side[1]->co);
+ glVertex3fv(curr_sv->v_co_orig);
+ }
+ glEnd();
+ UI_ThemeColorShadeAlpha(TH_SELECT, -30, alpha_shade);
+ glPointSize(ctrl_size);
+ bglBegin(GL_POINTS);
+ if (sld->flipped_vtx) {
+ if (curr_sv->v_side[1]) bglVertex3fv(curr_sv->v_side[1]->co);
+ }
+ else {
+ if (curr_sv->v_side[0]) bglVertex3fv(curr_sv->v_side[0]->co);
+ }
+ bglEnd();
- UI_ThemeColorShadeAlpha(TH_SELECT, -30, alpha_shade);
- glPointSize(ctrl_size);
- bglBegin(GL_POINTS);
- if (sld->flipped_vtx) {
- if (curr_sv->v_b) bglVertex3fv(curr_sv->v_b->co);
+ UI_ThemeColorShadeAlpha(TH_SELECT, 255, alpha_shade);
+ glPointSize(guide_size);
+ bglBegin(GL_POINTS);
+#if 0
+ interp_v3_v3v3(co_mark, co_b, co_a, fac);
+ bglVertex3fv(co_mark);
+#endif
+ interp_line_v3_v3v3v3(co_mark, co_b, curr_sv->v_co_orig, co_a, fac);
+ bglVertex3fv(co_mark);
+ bglEnd();
}
else {
- if (curr_sv->v_a) bglVertex3fv(curr_sv->v_a->co);
- }
- bglEnd();
+ if (is_clamp == false) {
+ const int side_index = sld->curr_side_unclamp;
+ TransDataEdgeSlideVert *sv;
+ int i;
+ const int alpha_shade = -160;
+
+ glLineWidth(line_size);
+ UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
+ glBegin(GL_LINES);
+
+ sv = sld->sv;
+ for (i = 0; i < sld->totsv; i++, sv++) {
+ float a[3], b[3];
+
+ if (!is_zero_v3(sv->dir_side[side_index])) {
+ copy_v3_v3(a, sv->dir_side[side_index]);
+ }
+ else {
+ copy_v3_v3(a, sv->dir_side[!side_index]);
+ }
- UI_ThemeColorShadeAlpha(TH_SELECT, 255, alpha_shade);
- glPointSize(guide_size);
- bglBegin(GL_POINTS);
-#if 0
- interp_v3_v3v3(co_mark, co_b, co_a, fac);
- bglVertex3fv(co_mark);
-#endif
- interp_line_v3_v3v3v3(co_mark, co_b, curr_sv->v_co_orig, co_a, fac);
- bglVertex3fv(co_mark);
- bglEnd();
+ mul_v3_fl(a, 100.0f);
+ negate_v3_v3(b, a);
+ add_v3_v3(a, sv->v_co_orig);
+ add_v3_v3(b, sv->v_co_orig);
+ glVertex3fv(a);
+ glVertex3fv(b);
+ }
+ glEnd();
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
glPopMatrix();
glPopAttrib();
@@ -6323,17 +6719,30 @@ static void doEdgeSlide(TransInfo *t, float perc)
sv = svlist;
if (sld->is_proportional == true) {
- for (i = 0; i < sld->totsv; i++, sv++) {
- float vec[3];
- if (perc > 0.0f) {
- copy_v3_v3(vec, sv->dir_a);
- mul_v3_fl(vec, perc);
- add_v3_v3v3(sv->v->co, sv->v_co_orig, vec);
+ const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
+ if (is_clamp) {
+ const int side_index = (perc < 0.0f);
+ const float perc_final = fabsf(perc);
+ for (i = 0; i < sld->totsv; i++, sv++) {
+ madd_v3_v3v3fl(sv->v->co, sv->v_co_orig, sv->dir_side[side_index], perc_final);
}
- else {
- copy_v3_v3(vec, sv->dir_b);
- mul_v3_fl(vec, -perc);
- add_v3_v3v3(sv->v->co, sv->v_co_orig, vec);
+
+ sld->curr_side_unclamp = side_index;
+ }
+ else {
+ const int side_index = sld->curr_side_unclamp;
+ const float perc_init = fabsf(perc) * ((sld->curr_side_unclamp == (perc < 0.0f)) ? 1 : -1);
+ for (i = 0; i < sld->totsv; i++, sv++) {
+ float dir_flip[3];
+ float perc_final = perc_init;
+ if (!is_zero_v3(sv->dir_side[side_index])) {
+ copy_v3_v3(dir_flip, sv->dir_side[side_index]);
+ }
+ else {
+ copy_v3_v3(dir_flip, sv->dir_side[!side_index]);
+ perc_final *= -1;
+ }
+ madd_v3_v3v3fl(sv->v->co, sv->v_co_orig, dir_flip, perc_final);
}
}
}
@@ -6343,7 +6752,7 @@ static void doEdgeSlide(TransInfo *t, float perc)
* a/b verts, this could be changed/improved so the distance is still met but the verts are moved along
* their original path (which may not be straight), however how it works now is OK and matches 2.4x - Campbell
*
- * \note len_v3v3(curr_sv->dir_a, curr_sv->dir_b)
+ * \note len_v3v3(curr_sv->dir_side[0], curr_sv->dir_side[1])
* is the same as the distance between the original vert locations, same goes for the lines below.
*/
TransDataEdgeSlideVert *curr_sv = &sld->sv[sld->curr_sv_index];
@@ -6356,8 +6765,8 @@ static void doEdgeSlide(TransInfo *t, float perc)
if (sv->edge_len > FLT_EPSILON) {
const float fac = min_ff(sv->edge_len, curr_length_perc) / sv->edge_len;
- add_v3_v3v3(co_a, sv->v_co_orig, sv->dir_a);
- add_v3_v3v3(co_b, sv->v_co_orig, sv->dir_b);
+ add_v3_v3v3(co_a, sv->v_co_orig, sv->dir_side[0]);
+ add_v3_v3v3(co_b, sv->v_co_orig, sv->dir_side[1]);
if (sld->flipped_vtx) {
interp_line_v3_v3v3v3(sv->v->co, co_b, sv->v_co_orig, co_a, fac);
@@ -6375,46 +6784,43 @@ static void doEdgeSlide(TransInfo *t, float perc)
static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
{
char str[MAX_INFO_LEN];
+ size_t ofs = 0;
float final;
EdgeSlideData *sld = t->customData;
bool flipped = sld->flipped_vtx;
bool is_proportional = sld->is_proportional;
+ const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
+ const bool is_constrained = !(is_clamp == false || hasNumInput(&t->num));
final = t->values[0];
snapGridIncrement(t, &final);
/* only do this so out of range values are not displayed */
- CLAMP(final, -1.0f, 1.0f);
+ if (is_constrained) {
+ CLAMP(final, -1.0f, 1.0f);
+ }
applyNumInput(&t->num, &final);
+ t->values[0] = final;
+
+ /* header string */
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Edge Slide: "), MAX_INFO_LEN - ofs);
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
-
outputNumInput(&(t->num), c, &t->scene->unit);
-
- if (is_proportional) {
- BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Edge Slide: %s (E)ven: %s"),
- &c[0], WM_bool_as_string(!is_proportional));
- }
- else {
- BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Edge Slide: %s (E)ven: %s, (F)lipped: %s"),
- &c[0], WM_bool_as_string(!is_proportional), WM_bool_as_string(flipped));
- }
- }
- else if (is_proportional) {
- BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Edge Slide: %.4f (E)ven: %s"),
- final, WM_bool_as_string(!is_proportional));
+ ofs += BLI_strncpy_rlen(str + ofs, &c[0], MAX_INFO_LEN - ofs);
}
else {
- BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Edge Slide: %.4f (E)ven: %s, (F)lipped: %s"),
- final, WM_bool_as_string(!is_proportional), WM_bool_as_string(flipped));
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "%.4f ", final);
}
-
- CLAMP(final, -1.0f, 1.0f);
-
- t->values[0] = final;
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("(E)ven: %s, "), WM_bool_as_string(!is_proportional));
+ if (!is_proportional) {
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("(F)lipped: %s, "), WM_bool_as_string(flipped));
+ }
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Alt or (C)lamp: %s"), WM_bool_as_string(is_clamp));
+ /* done with header string */
/* do stuff here */
doEdgeSlide(t, final);
@@ -6436,10 +6842,20 @@ static void calcVertSlideCustomPoints(struct TransInfo *t)
{
VertSlideData *sld = t->customData;
TransDataVertSlideVert *sv = &sld->sv[sld->curr_sv_index];
- const float *co_orig = sv->co_orig_2d;
- const float *co_curr = sv->co_link_orig_2d[sv->co_link_curr];
- const int mval_start[2] = {co_orig[0], co_orig[1]};
- const int mval_end[2] = {co_curr[0], co_curr[1]};
+
+ const float *co_orig_3d = sv->co_orig_3d;
+ const float *co_curr_3d = sv->co_link_orig_3d[sv->co_link_curr];
+
+ float co_curr_2d[2], co_orig_2d[2];
+
+ int mval_ofs[2], mval_start[2], mval_end[2];
+
+ ED_view3d_project_float_v2_m4(t->ar, co_orig_3d, co_orig_2d, sld->proj_mat);
+ ED_view3d_project_float_v2_m4(t->ar, co_curr_3d, co_curr_2d, sld->proj_mat);
+
+ ARRAY_SET_ITEMS(mval_ofs, t->imval[0] - co_orig_2d[0], t->imval[1] - co_orig_2d[1]);
+ ARRAY_SET_ITEMS(mval_start, co_orig_2d[0] + mval_ofs[0], co_orig_2d[1] + mval_ofs[1]);
+ ARRAY_SET_ITEMS(mval_end, co_curr_2d[0] + mval_ofs[0], co_curr_2d[1] + mval_ofs[1]);
if (sld->flipped_vtx && sld->is_proportional == false) {
setCustomPoints(t, &t->mouse, mval_start, mval_end);
@@ -6447,6 +6863,11 @@ static void calcVertSlideCustomPoints(struct TransInfo *t)
else {
setCustomPoints(t, &t->mouse, mval_end, mval_start);
}
+
+ /* setCustomPoints isn't normally changing as the mouse moves,
+ * in this case apply mouse input immediatly so we don't refresh
+ * with the value from the previous points */
+ applyMouseInput(t, &t->mouse, t->mval, t->values);
}
/**
@@ -6464,28 +6885,39 @@ static void calcVertSlideMouseActiveVert(struct TransInfo *t, const int mval[2])
int i;
for (i = 0, sv = sld->sv; i < sld->totsv; i++, sv++) {
- dist_sq = len_squared_v2v2(mval_fl, sv->co_orig_2d);
+ float co_2d[2];
+
+ ED_view3d_project_float_v2_m4(t->ar, sv->co_orig_3d, co_2d, sld->proj_mat);
+
+ dist_sq = len_squared_v2v2(mval_fl, co_2d);
if (dist_sq < dist_min_sq) {
dist_min_sq = dist_sq;
sld->curr_sv_index = i;
}
}
}
+
/**
* Run while moving the mouse to slide along the edge matching the mouse direction
*/
static void calcVertSlideMouseActiveEdges(struct TransInfo *t, const int mval[2])
{
VertSlideData *sld = t->customData;
- float mval_fl[2] = {UNPACK2(mval)};
+ float imval_fl[2] = {UNPACK2(t->imval)};
+ float mval_fl[2] = {UNPACK2(mval)};
- float dir[2];
+ float dir[3];
TransDataVertSlideVert *sv;
int i;
- /* first get the direction of the original vertex */
- sub_v2_v2v2(dir, sld->sv[sld->curr_sv_index].co_orig_2d, mval_fl);
- normalize_v2(dir);
+ /* first get the direction of the original mouse position */
+ sub_v2_v2v2(dir, imval_fl, mval_fl);
+ ED_view3d_win_to_delta(t->ar, dir, dir, t->zfac);
+
+ invert_m4_m4(t->obedit->imat, t->obedit->obmat);
+ mul_mat3_m4_v3(t->obedit->imat, dir);
+
+ normalize_v3(dir);
for (i = 0, sv = sld->sv; i < sld->totsv; i++, sv++) {
if (sv->co_link_tot > 1) {
@@ -6494,11 +6926,14 @@ static void calcVertSlideMouseActiveEdges(struct TransInfo *t, const int mval[2]
int j;
for (j = 0; j < sv->co_link_tot; j++) {
- float tdir[2];
+ float tdir[3];
float dir_dot;
- sub_v2_v2v2(tdir, sv->co_orig_2d, sv->co_link_orig_2d[j]);
- normalize_v2(tdir);
- dir_dot = dot_v2v2(dir, tdir);
+
+ sub_v3_v3v3(tdir, sv->co_orig_3d, sv->co_link_orig_3d[j]);
+ project_plane_v3_v3v3(tdir, tdir, t->viewinv[2]);
+
+ normalize_v3(tdir);
+ dir_dot = dot_v3v3(dir, tdir);
if (dir_dot > dir_dot_best) {
dir_dot_best = dir_dot;
co_link_curr_best = j;
@@ -6522,32 +6957,14 @@ static bool createVertSlideVerts(TransInfo *t)
BMVert *v;
TransDataVertSlideVert *sv_array;
VertSlideData *sld = MEM_callocN(sizeof(*sld), "sld");
-// View3D *v3d = NULL;
- RegionView3D *rv3d = NULL;
- ARegion *ar = t->ar;
- float projectMat[4][4];
int j;
- if (t->spacetype == SPACE_VIEW3D) {
- /* background mode support */
-// v3d = t->sa ? t->sa->spacedata.first : NULL;
- rv3d = ar ? ar->regiondata : NULL;
- }
-
slide_origdata_init_flag(t, &sld->orig_data);
sld->is_proportional = true;
sld->curr_sv_index = 0;
sld->flipped_vtx = false;
- if (!rv3d) {
- /* ok, let's try to survive this */
- unit_m4(projectMat);
- }
- else {
- ED_view3d_ob_project_mat_get(rv3d, t->obedit, projectMat);
- }
-
j = 0;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
bool ok = false;
@@ -6591,7 +7008,6 @@ static bool createVertSlideVerts(TransInfo *t)
}
sv_array[j].co_link_orig_3d = MEM_mallocN(sizeof(*sv_array[j].co_link_orig_3d) * k, __func__);
- sv_array[j].co_link_orig_2d = MEM_mallocN(sizeof(*sv_array[j].co_link_orig_2d) * k, __func__);
sv_array[j].co_link_tot = k;
k = 0;
@@ -6599,31 +7015,9 @@ static bool createVertSlideVerts(TransInfo *t)
if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
BMVert *v_other = BM_edge_other_vert(e, v);
copy_v3_v3(sv_array[j].co_link_orig_3d[k], v_other->co);
- if (ar) {
- ED_view3d_project_float_v2_m4(ar,
- sv_array[j].co_link_orig_3d[k],
- sv_array[j].co_link_orig_2d[k],
- projectMat);
- }
- else {
- copy_v2_v2(sv_array[j].co_link_orig_2d[k],
- sv_array[j].co_link_orig_3d[k]);
- }
k++;
}
}
-
- if (ar) {
- ED_view3d_project_float_v2_m4(ar,
- sv_array[j].co_orig_3d,
- sv_array[j].co_orig_2d,
- projectMat);
- }
- else {
- copy_v2_v2(sv_array[j].co_orig_2d,
- sv_array[j].co_orig_3d);
- }
-
j++;
}
}
@@ -6641,7 +7035,19 @@ static bool createVertSlideVerts(TransInfo *t)
t->customData = sld;
- if (rv3d) {
+ /* most likely will be set below */
+ unit_m4(sld->proj_mat);
+
+ if (t->spacetype == SPACE_VIEW3D) {
+ /* view vars */
+ RegionView3D *rv3d = NULL;
+ ARegion *ar = t->ar;
+
+ rv3d = ar ? ar->regiondata : NULL;
+ if (rv3d) {
+ ED_view3d_ob_project_mat_get(rv3d, t->obedit, sld->proj_mat);
+ }
+
calcVertSlideMouseActiveVert(t, t->mval);
calcVertSlideMouseActiveEdges(t, t->mval);
}
@@ -6681,7 +7087,6 @@ void freeVertSlideVerts(TransInfo *t)
TransDataVertSlideVert *sv = sld->sv;
int i = 0;
for (i = 0; i < sld->totsv; i++, sv++) {
- MEM_freeN(sv->co_link_orig_2d);
MEM_freeN(sv->co_link_orig_3d);
}
}
@@ -6748,16 +7153,13 @@ static eRedrawFlag handleEventVertSlide(struct TransInfo *t, const struct wmEven
}
break;
case FKEY:
- {
if (event->val == KM_PRESS) {
sld->flipped_vtx = !sld->flipped_vtx;
calcVertSlideCustomPoints(t);
return TREDRAW_HARD;
}
break;
- }
case CKEY:
- {
/* use like a modifier key */
if (event->val == KM_PRESS) {
t->flag ^= T_ALT_TRANSFORM;
@@ -6765,23 +7167,17 @@ static eRedrawFlag handleEventVertSlide(struct TransInfo *t, const struct wmEven
return TREDRAW_HARD;
}
break;
- }
#if 0
case EVT_MODAL_MAP:
- {
switch (event->val) {
case TFM_MODAL_EDGESLIDE_DOWN:
- {
sld->curr_sv_index = ((sld->curr_sv_index - 1) + sld->totsv) % sld->totsv;
break;
- }
case TFM_MODAL_EDGESLIDE_UP:
- {
sld->curr_sv_index = (sld->curr_sv_index + 1) % sld->totsv;
break;
- }
}
- }
+ break;
#endif
case MOUSEMOVE:
{
@@ -6801,19 +7197,20 @@ static eRedrawFlag handleEventVertSlide(struct TransInfo *t, const struct wmEven
return TREDRAW_NOTHING;
}
-static void drawVertSlide(const struct bContext *C, TransInfo *t)
+static void drawVertSlide(TransInfo *t)
{
- if (t->mode == TFM_VERT_SLIDE) {
- VertSlideData *sld = (VertSlideData *)t->customData;
+ if ((t->mode == TFM_VERT_SLIDE) && t->customData) {
+ VertSlideData *sld = t->customData;
+ const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
+
/* Non-Prop mode */
- if (sld) {
- View3D *v3d = CTX_wm_view3d(C);
+ {
+ View3D *v3d = t->view;
TransDataVertSlideVert *curr_sv = &sld->sv[sld->curr_sv_index];
TransDataVertSlideVert *sv;
const float ctrl_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 1.5f;
const float line_size = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.5f;
const int alpha_shade = -160;
- const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
int i;
if (v3d && v3d->zbuf)
@@ -6861,11 +7258,40 @@ static void drawVertSlide(const struct bContext *C, TransInfo *t)
curr_sv->co_orig_3d);
bglEnd();
+ glDisable(GL_BLEND);
+
+ /* direction from active vertex! */
+ if ((t->mval[0] != t->imval[0]) ||
+ (t->mval[1] != t->imval[1]))
+ {
+ float zfac = ED_view3d_calc_zfac(t->ar->regiondata, curr_sv->co_orig_3d, NULL);
+ float mval_ofs[2];
+ float co_dest_3d[3];
+
+ mval_ofs[0] = t->mval[0] - t->imval[0];
+ mval_ofs[1] = t->mval[1] - t->imval[1];
+
+ ED_view3d_win_to_delta(t->ar, mval_ofs, co_dest_3d, zfac);
+
+ invert_m4_m4(t->obedit->imat, t->obedit->obmat);
+ mul_mat3_m4_v3(t->obedit->imat, co_dest_3d);
+
+ add_v3_v3(co_dest_3d, curr_sv->co_orig_3d);
+
+ glLineWidth(1);
+ setlinestyle(1);
+
+ cpack(0xffffff);
+ glBegin(GL_LINES);
+ glVertex3fv(curr_sv->co_orig_3d);
+ glVertex3fv(co_dest_3d);
+
+ glEnd();
+ }
+
glPopMatrix();
glPopAttrib();
- glDisable(GL_BLEND);
-
if (v3d && v3d->zbuf)
glEnable(GL_DEPTH_TEST);
}
@@ -6937,6 +7363,8 @@ static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2]))
applyNumInput(&t->num, &final);
+ t->values[0] = final;
+
/* header string */
ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Vert Slide: "), MAX_INFO_LEN - ofs);
if (hasNumInput(&t->num)) {
@@ -7005,6 +7433,8 @@ static void applyBoneRoll(TransInfo *t, const int UNUSED(mval[2]))
applyNumInput(&t->num, &final);
+ t->values[0] = final;
+
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
@@ -7277,7 +7707,7 @@ static void initSeqSlide(TransInfo *t)
t->num.idx_max = t->idx_max;
t->snap[0] = 0.0f;
- t->snap[1] = floor(t->scene->r.frs_sec / t->scene->r.frs_sec_base);
+ t->snap[1] = floorf(t->scene->r.frs_sec / t->scene->r.frs_sec_base);
t->snap[2] = 10.0f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
@@ -7344,8 +7774,8 @@ static void applySeqSlide(TransInfo *t, const int mval[2])
applyNumInput(&t->num, t->values);
}
- t->values[0] = floor(t->values[0] + 0.5f);
- t->values[1] = floor(t->values[1] + 0.5f);
+ t->values[0] = floorf(t->values[0] + 0.5f);
+ t->values[1] = floorf(t->values[1] + 0.5f);
headerSeqSlide(t, t->values, str);
applySeqSlideValue(t, t->values);
@@ -7511,6 +7941,7 @@ static void initTimeTranslate(TransInfo *t)
static void headerTimeTranslate(TransInfo *t, char str[MAX_INFO_LEN])
{
char tvec[NUM_STR_REP_LEN * 3];
+ int ofs = 0;
/* if numeric input is active, use results from that, otherwise apply snapping to result */
if (hasNumInput(&t->num)) {
@@ -7546,10 +7977,14 @@ static void headerTimeTranslate(TransInfo *t, char str[MAX_INFO_LEN])
BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", val);
}
- BLI_snprintf(str, MAX_INFO_LEN, IFACE_("DeltaX: %s"), &tvec[0]);
+ ofs += BLI_snprintf(str, MAX_INFO_LEN, IFACE_("DeltaX: %s"), &tvec[0]);
+
+ if (t->flag & T_PROP_EDIT_ALL) {
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
+ }
}
-static void applyTimeTranslateValue(TransInfo *t, float UNUSED(sval))
+static void applyTimeTranslateValue(TransInfo *t)
{
TransData *td = t->data;
TransData2D *td2d = t->data2d;
@@ -7579,11 +8014,11 @@ static void applyTimeTranslateValue(TransInfo *t, float UNUSED(sval))
deltax = (float)(floor(((double)deltax / secf) + 0.5) * secf);
}
else if (autosnap == SACTSNAP_STEP) {
- deltax = (float)(floor(deltax + 0.5f));
+ deltax = floorf(deltax + 0.5f);
}
val = BKE_nla_tweakedit_remap(adt, td->ival, NLATIME_CONVERT_MAP);
- val += deltax;
+ val += deltax * td->factor;
*(td->val) = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP);
}
else {
@@ -7593,7 +8028,7 @@ static void applyTimeTranslateValue(TransInfo *t, float UNUSED(sval))
val = (float)(floor(((double)deltax / secf) + 0.5) * secf);
}
else if (autosnap == SACTSNAP_STEP) {
- val = (float)(floor(val + 0.5f));
+ val = floorf(val + 0.5f);
}
*(td->val) = td->ival + val;
@@ -7607,15 +8042,17 @@ static void applyTimeTranslateValue(TransInfo *t, float UNUSED(sval))
static void applyTimeTranslate(TransInfo *t, const int mval[2])
{
View2D *v2d = (View2D *)t->view;
- float cval[2], sval[2];
char str[MAX_INFO_LEN];
/* calculate translation amount from mouse movement - in 'time-grid space' */
- UI_view2d_region_to_view(v2d, mval[0], mval[0], &cval[0], &cval[1]);
- UI_view2d_region_to_view(v2d, t->imval[0], t->imval[0], &sval[0], &sval[1]);
+ if (t->flag & T_MODAL) {
+ float cval[2], sval[2];
+ UI_view2d_region_to_view(v2d, mval[0], mval[0], &cval[0], &cval[1]);
+ UI_view2d_region_to_view(v2d, t->imval[0], t->imval[0], &sval[0], &sval[1]);
- /* we only need to calculate effect for time (applyTimeTranslate only needs that) */
- t->values[0] = cval[0] - sval[0];
+ /* we only need to calculate effect for time (applyTimeTranslate only needs that) */
+ t->values[0] = cval[0] - sval[0];
+ }
/* handle numeric-input stuff */
t->vec[0] = t->values[0];
@@ -7623,7 +8060,7 @@ static void applyTimeTranslate(TransInfo *t, const int mval[2])
t->values[0] = t->vec[0];
headerTimeTranslate(t, str);
- applyTimeTranslateValue(t, sval[0]);
+ applyTimeTranslateValue(t);
recalcData(t);
@@ -7756,7 +8193,7 @@ static void applyTimeSlide(TransInfo *t, const int mval[2])
/* t->values[0] stores cval[0], which is the current mouse-pointer location (in frames) */
// XXX Need to be able to repeat this
- t->values[0] = cval[0];
+ /* t->values[0] = cval[0]; */ /* UNUSED (reset again later). */
/* handle numeric-input stuff */
t->vec[0] = 2.0f * (cval[0] - sval[0]) / (maxx - minx);
@@ -7857,7 +8294,7 @@ static void applyTimeScaleValue(TransInfo *t)
fac = (float)(floor((double)fac / secf + 0.5) * secf);
}
else if (autosnap == SACTSNAP_STEP) {
- fac = (float)(floor(fac + 0.5f));
+ fac = floorf(fac + 0.5f);
}
/* check if any need to apply nla-mapping */