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')
-rw-r--r--source/blender/editors/transform/CMakeLists.txt1
-rw-r--r--source/blender/editors/transform/SConscript4
-rw-r--r--source/blender/editors/transform/transform.c170
-rw-r--r--source/blender/editors/transform/transform.h13
-rw-r--r--source/blender/editors/transform/transform_constraints.c14
-rw-r--r--source/blender/editors/transform/transform_conversions.c17
-rw-r--r--source/blender/editors/transform/transform_generics.c27
-rw-r--r--source/blender/editors/transform/transform_manipulator.c12
-rw-r--r--source/blender/editors/transform/transform_ops.c26
-rw-r--r--source/blender/editors/transform/transform_orientations.c62
-rw-r--r--source/blender/editors/transform/transform_snap.c215
11 files changed, 341 insertions, 220 deletions
diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt
index 0bc38f81dd7..42aa6a0a3a3 100644
--- a/source/blender/editors/transform/CMakeLists.txt
+++ b/source/blender/editors/transform/CMakeLists.txt
@@ -23,6 +23,7 @@ set(INC
../../blenfont
../../blenkernel
../../blenlib
+ ../../blentranslation
../../bmesh
../../gpu
../../ikplugin
diff --git a/source/blender/editors/transform/SConscript b/source/blender/editors/transform/SConscript
index 1a2e9ab074a..0f34ce546de 100644
--- a/source/blender/editors/transform/SConscript
+++ b/source/blender/editors/transform/SConscript
@@ -37,6 +37,7 @@ incs = [
'../../blenfont',
'../../blenkernel',
'../../blenlib',
+ '../../blentranslation',
'../../bmesh',
'../../gpu',
'../../ikplugin',
@@ -45,7 +46,8 @@ incs = [
'../../windowmanager',
]
-defs = env['BF_GL_DEFINITIONS']
+defs = []
+defs += env['BF_GL_DEFINITIONS']
if env['WITH_BF_INTERNATIONAL']:
defs.append('WITH_INTERNATIONAL')
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index a889faba9a4..d6ce32f9974 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -86,7 +86,7 @@
#include "RNA_access.h"
#include "BLF_api.h"
-#include "BLF_translation.h"
+#include "BLT_translation.h"
#include "transform.h"
@@ -168,11 +168,12 @@ 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_ex(TransInfo *t, bool use_double_side, bool use_even, bool flipped, bool use_clamp);
static void initEdgeSlide(TransInfo *t);
static eRedrawFlag handleEventEdgeSlide(TransInfo *t, const struct wmEvent *event);
static void applyEdgeSlide(TransInfo *t, const int mval[2]);
+static void initVertSlide_ex(TransInfo *t, bool use_even, bool flipped, bool use_clamp);
static void initVertSlide(TransInfo *t);
static eRedrawFlag handleEventVertSlide(TransInfo *t, const struct wmEvent *event);
static void applyVertSlide(TransInfo *t, const int mval[2]);
@@ -1037,6 +1038,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
/* vert slide can fail on unconnected vertices (rare but possible) */
if (t->state == TRANS_CANCEL) {
+ t->mode = TFM_TRANSLATION;
t->state = TRANS_STARTING;
restoreTransObjects(t);
resetTransRestrictions(t);
@@ -1063,15 +1065,14 @@ int transformEvent(TransInfo *t, const wmEvent *event)
/* only switch when... */
if (!(t->options & CTX_TEXTURE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) {
if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
+ restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
if (t->mode == TFM_ROTATION) {
- restoreTransObjects(t);
initTrackball(t);
}
else {
- restoreTransObjects(t);
initRotation(t);
}
initSnapping(t, NULL); // need to reinit after mode change
@@ -1363,15 +1364,14 @@ int transformEvent(TransInfo *t, const wmEvent *event)
/* only switch when... */
if (!(t->options & CTX_TEXTURE)) {
if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION)) {
+ restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
if (t->mode == TFM_ROTATION) {
- restoreTransObjects(t);
initTrackball(t);
}
else {
- restoreTransObjects(t);
initRotation(t);
}
initSnapping(t, NULL); // need to reinit after mode change
@@ -1721,7 +1721,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
glVertex2fv(cent);
glEnd();
- glTranslatef(mval[0], mval[1], 0);
+ glTranslate2iv(mval);
glRotatef(-RAD2DEGF(atan2f(cent[0] - t->mval[0], cent[1] - t->mval[1])), 0, 0, 1);
setlinestyle(0);
@@ -1733,7 +1733,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
case HLP_HARROW:
UI_ThemeColor(TH_VIEW_OVERLAY);
- glTranslatef(mval[0], mval[1], 0);
+ glTranslate2iv(mval);
glLineWidth(3.0);
drawArrow(RIGHT, 5, 10, 5);
@@ -1743,7 +1743,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
case HLP_VARROW:
UI_ThemeColor(TH_VIEW_OVERLAY);
- glTranslatef(mval[0], mval[1], 0);
+ glTranslate2iv(mval);
glLineWidth(3.0);
drawArrow(UP, 5, 10, 5);
@@ -1794,7 +1794,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
unsigned char col[3], col2[3];
UI_GetThemeColor3ubv(TH_GRID, col);
- glTranslatef(mval[0], mval[1], 0);
+ glTranslate2iv(mval);
glLineWidth(3.0);
@@ -2077,47 +2077,41 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->launch_event = LEFTMOUSE;
}
+ unit_m3(t->spacemtx);
+
initTransInfo(C, t, op, event);
+ initTransformOrientation(C, t);
if (t->spacetype == SPACE_VIEW3D) {
- initTransformOrientation(C, t);
-
t->draw_handle_apply = ED_region_draw_cb_activate(t->ar->type, drawTransformApply, t, REGION_DRAW_PRE_VIEW);
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_IMAGE) {
- 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_CLIP) {
- 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_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), helpline_poll, drawHelpline, t);
}
else if (t->spacetype == SPACE_NODE) {
- unit_m3(t->spacemtx);
/*t->draw_handle_apply = ED_region_draw_cb_activate(t->ar->type, drawTransformApply, t, REGION_DRAW_PRE_VIEW);*/
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);
createTransData(C, t); // make TransData structs from selection
@@ -2234,14 +2228,20 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->mode = TFM_BONE_ENVELOPE_DIST;
break;
case TFM_EDGE_SLIDE:
+ case TFM_VERT_SLIDE:
{
- const bool use_double_side = (op ? !RNA_boolean_get(op->ptr, "single_side") : true);
- initEdgeSlide_ex(t, use_double_side);
+ const bool use_even = (op ? RNA_boolean_get(op->ptr, "use_even") : false);
+ const bool flipped = (op ? RNA_boolean_get(op->ptr, "flipped") : false);
+ const bool use_clamp = (op ? RNA_boolean_get(op->ptr, "use_clamp") : true);
+ if (mode == TFM_EDGE_SLIDE) {
+ const bool use_double_side = (op ? !RNA_boolean_get(op->ptr, "single_side") : true);
+ initEdgeSlide_ex(t, use_double_side, use_even, flipped, use_clamp);
+ }
+ else {
+ initVertSlide_ex(t, use_even, flipped, use_clamp);
+ }
break;
}
- case TFM_VERT_SLIDE:
- initVertSlide(t);
- break;
case TFM_BONE_ROLL:
initBoneRoll(t);
break;
@@ -3092,6 +3092,7 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
float value;
int i;
char str[MAX_INFO_LEN];
+ const bool is_local_center = transdata_check_local_center(t, t->around);
copy_m3_m4(persmat, t->viewmat);
invert_m3_m3(persinv, persmat);
@@ -3127,8 +3128,10 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
mul_m3_m3m3(tmat, smat, persmat);
mul_m3_m3m3(totmat, persinv, tmat);
-
+
for (i = 0; i < t->total; i++, td++) {
+ const float *center, *co;
+
if (td->flag & TD_NOACTION)
break;
@@ -3143,12 +3146,22 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
else {
copy_m3_m3(tmat, totmat);
}
- sub_v3_v3v3(vec, td->center, t->center);
+
+ if (is_local_center) {
+ center = td->center;
+ co = td->loc;
+ }
+ else {
+ center = t->center;
+ co = td->center;
+ }
+
+ sub_v3_v3v3(vec, co, center);
mul_m3_v3(tmat, vec);
- add_v3_v3(vec, t->center);
- sub_v3_v3(vec, td->center);
+ add_v3_v3(vec, center);
+ sub_v3_v3(vec, co);
mul_v3_fl(vec, td->factor);
@@ -5967,7 +5980,7 @@ static void calcEdgeSlide_mval_range(
}
}
-static void calcEdgeSlide_non_proportional(
+static void calcEdgeSlide_even(
TransInfo *t, EdgeSlideData *sld, const float mval[2])
{
TransDataEdgeSlideVert *sv = sld->sv;
@@ -6013,7 +6026,7 @@ static void calcEdgeSlide_non_proportional(
}
}
-static bool createEdgeSlideVerts_double_side(TransInfo *t)
+static bool createEdgeSlideVerts_double_side(TransInfo *t, bool use_even, bool flipped, bool use_clamp)
{
BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
BMesh *bm = em->bm;
@@ -6032,9 +6045,11 @@ static bool createEdgeSlideVerts_double_side(TransInfo *t)
slide_origdata_init_flag(t, &sld->orig_data);
- sld->is_proportional = true;
+ sld->use_even = use_even;
sld->curr_sv_index = 0;
- sld->flipped_vtx = false;
+ sld->flipped = flipped;
+ if (!use_clamp)
+ t->flag |= T_ALT_TRANSFORM;
/*ensure valid selection*/
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
@@ -6340,7 +6355,7 @@ static bool createEdgeSlideVerts_double_side(TransInfo *t)
slide_origdata_create_data(t, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
if (rv3d) {
- calcEdgeSlide_non_proportional(t, sld, mval);
+ calcEdgeSlide_even(t, sld, mval);
}
sld->em = em;
@@ -6358,7 +6373,7 @@ static bool createEdgeSlideVerts_double_side(TransInfo *t)
* A simple version of #createEdgeSlideVerts_double_side
* Which assumes the longest unselected.
*/
-static bool createEdgeSlideVerts_single_side(TransInfo *t)
+static bool createEdgeSlideVerts_single_side(TransInfo *t, bool use_even, bool flipped, bool use_clamp)
{
BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
BMesh *bm = em->bm;
@@ -6383,10 +6398,12 @@ static bool createEdgeSlideVerts_single_side(TransInfo *t)
slide_origdata_init_flag(t, &sld->orig_data);
- sld->is_proportional = true;
+ sld->use_even = use_even;
sld->curr_sv_index = 0;
- /* heppans to be best for single-sided */
- sld->flipped_vtx = true;
+ /* happens to be best for single-sided */
+ sld->flipped = !flipped;
+ if (!use_clamp)
+ t->flag |= T_ALT_TRANSFORM;
/* ensure valid selection */
j = 0;
@@ -6532,7 +6549,7 @@ static bool createEdgeSlideVerts_single_side(TransInfo *t)
slide_origdata_create_data(t, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
if (rv3d) {
- calcEdgeSlide_non_proportional(t, sld, mval);
+ calcEdgeSlide_even(t, sld, mval);
}
sld->em = em;
@@ -6580,7 +6597,7 @@ void freeEdgeSlideVerts(TransInfo *t)
t->customData = NULL;
}
-static void initEdgeSlide_ex(TransInfo *t, bool use_double_side)
+static void initEdgeSlide_ex(TransInfo *t, bool use_double_side, bool use_even, bool flipped, bool use_clamp)
{
EdgeSlideData *sld;
bool ok;
@@ -6590,10 +6607,10 @@ static void initEdgeSlide_ex(TransInfo *t, bool use_double_side)
t->handleEvent = handleEventEdgeSlide;
if (use_double_side) {
- ok = createEdgeSlideVerts_double_side(t);
+ ok = createEdgeSlideVerts_double_side(t, use_even, flipped, use_clamp);
}
else {
- ok = createEdgeSlideVerts_single_side(t);
+ ok = createEdgeSlideVerts_single_side(t, use_even, flipped, use_clamp);
}
if (!ok) {
@@ -6627,7 +6644,7 @@ static void initEdgeSlide_ex(TransInfo *t, bool use_double_side)
static void initEdgeSlide(TransInfo *t)
{
- initEdgeSlide_ex(t, true);
+ initEdgeSlide_ex(t, true, false, false, true);
}
static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEvent *event)
@@ -6639,16 +6656,14 @@ static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEven
switch (event->type) {
case EKEY:
if (event->val == KM_PRESS) {
- sld->is_proportional = !sld->is_proportional;
+ sld->use_even = !sld->use_even;
calcEdgeSlideCustomPoints(t);
return TREDRAW_HARD;
}
break;
case FKEY:
if (event->val == KM_PRESS) {
- if (sld->is_proportional == false) {
- sld->flipped_vtx = !sld->flipped_vtx;
- }
+ sld->flipped = !sld->flipped;
calcEdgeSlideCustomPoints(t);
return TREDRAW_HARD;
}
@@ -6688,8 +6703,8 @@ static void drawEdgeSlide(TransInfo *t)
EdgeSlideData *sld = t->customData;
const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
- /* Non-Prop mode */
- if ((sld->is_proportional == false) || (is_clamp == false)) {
+ /* Even mode */
+ if ((sld->use_even == true) || (is_clamp == false)) {
View3D *v3d = t->view;
const float line_size = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.5f;
@@ -6704,7 +6719,7 @@ static void drawEdgeSlide(TransInfo *t)
glMultMatrixf(t->obedit->obmat);
- if (sld->is_proportional == false) {
+ if (sld->use_even == true) {
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;
@@ -6731,7 +6746,7 @@ static void drawEdgeSlide(TransInfo *t)
UI_ThemeColorShadeAlpha(TH_SELECT, -30, alpha_shade);
glPointSize(ctrl_size);
bglBegin(GL_POINTS);
- if (sld->flipped_vtx) {
+ if (sld->flipped) {
if (curr_sv->v_side[1]) bglVertex3fv(curr_sv->v_side[1]->co);
}
else {
@@ -6807,7 +6822,7 @@ static void doEdgeSlide(TransInfo *t, float perc)
sld->perc = perc;
sv = svlist;
- if (sld->is_proportional == true) {
+ if (sld->use_even == false) {
const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
if (is_clamp) {
const int side_index = (perc < 0.0f);
@@ -6837,7 +6852,7 @@ static void doEdgeSlide(TransInfo *t, float perc)
}
else {
/**
- * Implementation note, non proportional mode ignores the starting positions and uses only the
+ * Implementation note, even mode ignores the starting positions and uses only the
* 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
*
@@ -6845,7 +6860,7 @@ static void doEdgeSlide(TransInfo *t, float perc)
* 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];
- const float curr_length_perc = curr_sv->edge_len * (((sld->flipped_vtx ? perc : -perc) + 1.0f) / 2.0f);
+ const float curr_length_perc = curr_sv->edge_len * (((sld->flipped ? perc : -perc) + 1.0f) / 2.0f);
float co_a[3];
float co_b[3];
@@ -6857,7 +6872,7 @@ static void doEdgeSlide(TransInfo *t, float perc)
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) {
+ if (sld->flipped) {
interp_line_v3_v3v3v3(sv->v->co, co_b, sv->v_co_orig, co_a, fac);
}
else {
@@ -6874,8 +6889,8 @@ static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
size_t ofs = 0;
float final;
EdgeSlideData *sld = t->customData;
- bool flipped = sld->flipped_vtx;
- bool is_proportional = sld->is_proportional;
+ bool flipped = sld->flipped;
+ bool use_even = sld->use_even;
const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
const bool is_constrained = !(is_clamp == false || hasNumInput(&t->num));
@@ -6902,8 +6917,8 @@ static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
else {
ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "%.4f ", 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_("(E)ven: %s, "), WM_bool_as_string(use_even));
+ if (use_even) {
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));
@@ -6944,7 +6959,7 @@ static void calcVertSlideCustomPoints(struct TransInfo *t)
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) {
+ if (sld->flipped && sld->use_even) {
setCustomPoints(t, &t->mouse, mval_start, mval_end);
}
else {
@@ -7035,7 +7050,7 @@ static void calcVertSlideMouseActiveEdges(struct TransInfo *t, const int mval[2]
}
}
-static bool createVertSlideVerts(TransInfo *t)
+static bool createVertSlideVerts(TransInfo *t, bool use_even, bool flipped, bool use_clamp)
{
BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
BMesh *bm = em->bm;
@@ -7049,9 +7064,11 @@ static bool createVertSlideVerts(TransInfo *t)
slide_origdata_init_flag(t, &sld->orig_data);
- sld->is_proportional = true;
+ sld->use_even = use_even;
sld->curr_sv_index = 0;
- sld->flipped_vtx = false;
+ sld->flipped = flipped;
+ if (!use_clamp)
+ t->flag |= T_ALT_TRANSFORM;
j = 0;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
@@ -7185,7 +7202,7 @@ void freeVertSlideVerts(TransInfo *t)
t->customData = NULL;
}
-static void initVertSlide(TransInfo *t)
+static void initVertSlide_ex(TransInfo *t, bool use_even, bool flipped, bool use_clamp)
{
VertSlideData *sld;
@@ -7193,7 +7210,7 @@ static void initVertSlide(TransInfo *t)
t->transform = applyVertSlide;
t->handleEvent = handleEventVertSlide;
- if (!createVertSlideVerts(t)) {
+ if (!createVertSlideVerts(t, use_even, flipped, use_clamp)) {
t->state = TRANS_CANCEL;
return;
}
@@ -7222,6 +7239,11 @@ static void initVertSlide(TransInfo *t)
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
+static void initVertSlide(TransInfo *t)
+{
+ initVertSlide_ex(t, false, false, true);
+}
+
static eRedrawFlag handleEventVertSlide(struct TransInfo *t, const struct wmEvent *event)
{
if (t->mode == TFM_VERT_SLIDE) {
@@ -7231,8 +7253,8 @@ static eRedrawFlag handleEventVertSlide(struct TransInfo *t, const struct wmEven
switch (event->type) {
case EKEY:
if (event->val == KM_PRESS) {
- sld->is_proportional = !sld->is_proportional;
- if (sld->flipped_vtx) {
+ sld->use_even = !sld->use_even;
+ if (sld->flipped) {
calcVertSlideCustomPoints(t);
}
return TREDRAW_HARD;
@@ -7240,7 +7262,7 @@ static eRedrawFlag handleEventVertSlide(struct TransInfo *t, const struct wmEven
break;
case FKEY:
if (event->val == KM_PRESS) {
- sld->flipped_vtx = !sld->flipped_vtx;
+ sld->flipped = !sld->flipped;
calcVertSlideCustomPoints(t);
return TREDRAW_HARD;
}
@@ -7339,7 +7361,7 @@ static void drawVertSlide(TransInfo *t)
glPointSize(ctrl_size);
bglBegin(GL_POINTS);
- bglVertex3fv((sld->flipped_vtx && sld->is_proportional == false) ?
+ bglVertex3fv((sld->flipped && sld->use_even) ?
curr_sv->co_link_orig_3d[curr_sv->co_link_curr] :
curr_sv->co_orig_3d);
bglEnd();
@@ -7397,7 +7419,7 @@ static void doVertSlide(TransInfo *t, float perc)
sld->perc = perc;
sv = svlist;
- if (sld->is_proportional == true) {
+ if (sld->use_even == false) {
for (i = 0; i < sld->totsv; i++, sv++) {
interp_v3_v3v3(sv->v->co, sv->co_orig_3d, sv->co_link_orig_3d[sv->co_link_curr], perc);
}
@@ -7415,7 +7437,7 @@ static void doVertSlide(TransInfo *t, float perc)
edge_len = normalize_v3(dir);
if (edge_len > FLT_EPSILON) {
- if (sld->flipped_vtx) {
+ if (sld->flipped) {
madd_v3_v3v3fl(sv->v->co, sv->co_link_orig_3d[sv->co_link_curr], dir, -tperc);
}
else {
@@ -7435,8 +7457,8 @@ static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2]))
size_t ofs = 0;
float final;
VertSlideData *sld = t->customData;
- const bool flipped = sld->flipped_vtx;
- const bool is_proportional = sld->is_proportional;
+ const bool flipped = sld->flipped;
+ const bool use_even = sld->use_even;
const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
const bool is_constrained = !(is_clamp == false || hasNumInput(&t->num));
@@ -7463,8 +7485,8 @@ static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2]))
else {
ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "%.4f ", 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_("(E)ven: %s, "), WM_bool_as_string(use_even));
+ if (use_even) {
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));
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index cdd260b3edb..e77ebfc4532 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -252,8 +252,8 @@ typedef struct EdgeSlideData {
float perc;
- bool is_proportional;
- bool flipped_vtx;
+ bool use_even;
+ bool flipped;
int curr_sv_index;
@@ -284,8 +284,8 @@ typedef struct VertSlideData {
float perc;
- bool is_proportional;
- bool flipped_vtx;
+ bool use_even;
+ bool flipped;
int curr_sv_index;
@@ -727,7 +727,7 @@ bool createSpaceNormalTangent(float mat[3][3], const float normal[3], const floa
struct TransformOrientation *addMatrixSpace(struct bContext *C, float mat[3][3],
const char *name, const bool overwrite);
-bool applyTransformOrientation(const struct bContext *C, float mat[3][3], char r_name[64]);
+bool applyTransformOrientation(const struct bContext *C, float mat[3][3], char r_name[64], int index);
#define ORIENTATION_NONE 0
#define ORIENTATION_NORMAL 1
@@ -735,7 +735,8 @@ bool applyTransformOrientation(const struct bContext *C, float mat[3][3], char r
#define ORIENTATION_EDGE 3
#define ORIENTATION_FACE 4
-int getTransformOrientation(const struct bContext *C, float normal[3], float plane[3], const bool activeOnly);
+int getTransformOrientation_ex(const struct bContext *C, float normal[3], float plane[3], const short around);
+int getTransformOrientation(const struct bContext *C, float normal[3], float plane[3]);
void freeEdgeSlideTempFaces(EdgeSlideData *sld);
void freeEdgeSlideVerts(TransInfo *t);
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index b546ff9449c..895c8a81044 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -53,7 +53,7 @@
#include "ED_image.h"
#include "ED_view3d.h"
-#include "BLF_translation.h"
+#include "BLT_translation.h"
#include "UI_resources.h"
@@ -855,21 +855,15 @@ void getConstraintMatrix(TransInfo *t)
unit_m3(t->con.pmtx);
if (!(t->con.mode & CON_AXIS0)) {
- t->con.pmtx[0][0] =
- t->con.pmtx[0][1] =
- t->con.pmtx[0][2] = 0.0f;
+ zero_v3(t->con.pmtx[0]);
}
if (!(t->con.mode & CON_AXIS1)) {
- t->con.pmtx[1][0] =
- t->con.pmtx[1][1] =
- t->con.pmtx[1][2] = 0.0f;
+ zero_v3(t->con.pmtx[1]);
}
if (!(t->con.mode & CON_AXIS2)) {
- t->con.pmtx[2][0] =
- t->con.pmtx[2][1] =
- t->con.pmtx[2][2] = 0.0f;
+ zero_v3(t->con.pmtx[2]);
}
mul_m3_m3m3(mat, t->con.pmtx, t->con.imtx);
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 687cf2f69e4..5e13afdc152 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -1252,7 +1252,18 @@ static void createTransArmatureVerts(TransInfo *t)
else {
if (ebo->flag & BONE_TIPSEL) {
copy_v3_v3(td->iloc, ebo->tail);
- copy_v3_v3(td->center, (t->around == V3D_LOCAL) ? ebo->head : td->iloc);
+
+ /* Don't allow single selected tips to have a modified center,
+ * causes problem with snapping (see T45974).
+ * However, in rotation mode, we want to keep that 'rotate bone around root with
+ * only its tip selected' behavior (see T46325). */
+ if ((t->around == V3D_LOCAL) && ((t->mode == TFM_ROTATION) || (ebo->flag & BONE_ROOTSEL))) {
+ copy_v3_v3(td->center, ebo->head);
+ }
+ else {
+ copy_v3_v3(td->center, td->iloc);
+ }
+
td->loc = ebo->tail;
td->flag = TD_SELECTED;
if (ebo->flag & BONE_EDITMODE_LOCKED)
@@ -1655,7 +1666,7 @@ static void createTransCurveVerts(TransInfo *t)
/* TODO - in the case of tilt and radius we can also avoid allocating the initTransDataCurveHandles
* but for now just don't change handle types */
- if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT) == 0) {
+ if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT, TFM_DUMMY) == 0) {
/* sets the handles based on their selection, do this after the data is copied to the TransData */
BKE_nurb_handles_test(nu, !hide_handles);
}
@@ -5548,7 +5559,7 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob,
if (IS_AUTOKEY_FLAG(scene, ONLYKEYINGSET) && (active_ks)) {
/* only insert into active keyingset
- * NOTE: we assume here that the active Keying Set does not need to have its iterator overridden spe
+ * NOTE: we assume here that the active Keying Set does not need to have its iterator overridden
*/
ANIM_apply_keyingset(C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra);
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index d57d4fb3ca8..dc541c6da42 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -57,7 +57,7 @@
#include "BLI_rand.h"
#include "BLI_utildefines.h"
-#include "BLF_translation.h"
+#include "BLT_translation.h"
#include "RNA_access.h"
@@ -1207,18 +1207,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->around = V3D_CURSOR;
}
- if (op && ((prop = RNA_struct_find_property(op->ptr, "constraint_orientation")) &&
- RNA_property_is_set(op->ptr, prop)))
- {
- t->current_orientation = RNA_property_enum_get(op->ptr, prop);
-
- if (t->current_orientation >= V3D_MANIP_CUSTOM + BIF_countTransformOrientation(C)) {
- t->current_orientation = V3D_MANIP_GLOBAL;
- }
- }
- else {
- t->current_orientation = v3d->twmode;
- }
+ t->current_orientation = v3d->twmode;
/* exceptional case */
if (t->around == V3D_LOCAL) {
@@ -1305,6 +1294,16 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
}
t->around = V3D_CENTER;
}
+
+ if (op && ((prop = RNA_struct_find_property(op->ptr, "constraint_orientation")) &&
+ RNA_property_is_set(op->ptr, prop)))
+ {
+ t->current_orientation = RNA_property_enum_get(op->ptr, prop);
+
+ if (t->current_orientation >= V3D_MANIP_CUSTOM + BIF_countTransformOrientation(C)) {
+ t->current_orientation = V3D_MANIP_GLOBAL;
+ }
+ }
if (op && ((prop = RNA_struct_find_property(op->ptr, "release_confirm")) &&
RNA_property_is_set(op->ptr, prop)))
@@ -1832,7 +1831,7 @@ void calculateCenter(TransInfo *t)
/* zfac is only used convertViewVec only in cases operator was invoked in RGN_TYPE_WINDOW
* and never used in other cases.
*
- * We need special case here as well, since ED_view3d_calc_zfac will crahs when called
+ * We need special case here as well, since ED_view3d_calc_zfac will crash when called
* for a region different from RGN_TYPE_WINDOW.
*/
if (t->ar->regiontype == RGN_TYPE_WINDOW) {
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index acc6108f264..f13bc6b6b55 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -568,7 +568,7 @@ static int calc_manipulator_stats(const bContext *C)
{
if (obedit || ob->mode & OB_MODE_POSE) {
float mat[3][3];
- ED_getTransformOrientationMatrix(C, mat, (v3d->around == V3D_ACTIVE));
+ ED_getTransformOrientationMatrix(C, mat, v3d->around);
copy_m4_m3(rv3d->twmat, mat);
break;
}
@@ -583,7 +583,7 @@ static int calc_manipulator_stats(const bContext *C)
* and users who select many bones will understand whats going on and what local means
* when they start transforming */
float mat[3][3];
- ED_getTransformOrientationMatrix(C, mat, (v3d->around == V3D_ACTIVE));
+ ED_getTransformOrientationMatrix(C, mat, v3d->around);
copy_m4_m3(rv3d->twmat, mat);
break;
}
@@ -602,7 +602,7 @@ static int calc_manipulator_stats(const bContext *C)
default: /* V3D_MANIP_CUSTOM */
{
float mat[3][3];
- if (applyTransformOrientation(C, mat, NULL)) {
+ if (applyTransformOrientation(C, mat, NULL, v3d->twmode - V3D_MANIP_CUSTOM)) {
copy_m4_m3(rv3d->twmat, mat);
}
break;
@@ -643,7 +643,7 @@ static void test_manipulator_axis(const bContext *C)
static float screen_aligned(RegionView3D *rv3d, float mat[4][4])
{
- glTranslatef(mat[3][0], mat[3][1], mat[3][2]);
+ glTranslate3fv(mat[3]);
/* sets view screen aligned */
glRotatef(-360.0f * saacos(rv3d->viewquat[0]) / (float)M_PI, rv3d->viewquat[1], rv3d->viewquat[2], rv3d->viewquat[3]);
@@ -923,7 +923,7 @@ static void draw_manipulator_rotate(
/* prepare for screen aligned draw */
size = len_v3(rv3d->twmat[0]);
glPushMatrix();
- glTranslatef(rv3d->twmat[3][0], rv3d->twmat[3][1], rv3d->twmat[3][2]);
+ glTranslate3fv(rv3d->twmat[3]);
if (arcs) {
/* clipplane makes nice handles, calc here because of multmatrix but with translate! */
@@ -1362,7 +1362,7 @@ static void draw_manipulator_translate(
manipulator_axis_order(rv3d, axis_order);
- // XXX if (moving) glTranslatef(t->vec[0], t->vec[1], t->vec[2]);
+ // XXX if (moving) glTranslate3fv(t->vec);
glDisable(GL_DEPTH_TEST);
/* center circle, do not add to selection when shift is pressed (planar constraint) */
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 013e47886eb..45afeeb7da9 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -33,7 +33,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLF_translation.h"
+#include "BLT_translation.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -527,7 +527,7 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
RNA_def_enum(ot->srna, "proportional", proportional_editing_items, 0, "Proportional Editing", "");
prop = RNA_def_enum(ot->srna, "proportional_edit_falloff", proportional_falloff_items, 0,
"Proportional Editing Falloff", "Falloff type for proportional editing mode");
- RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
RNA_def_float(ot->srna, "proportional_size", 1, 0.00001f, FLT_MAX, "Proportional Size", "", 0.001, 100);
}
@@ -643,8 +643,6 @@ static void TRANSFORM_OT_skin_resize(struct wmOperatorType *ot)
static void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
{
- PropertyRNA *prop;
-
/* identifiers */
ot->name = "Trackball";
ot->description = "Trackball style rotation of selected items";
@@ -659,16 +657,13 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
ot->poll = ED_operator_screenactive;
/* Maybe we could use float_vector_xyz here too? */
- prop = RNA_def_float_vector(ot->srna, "value", 2, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
- RNA_def_property_subtype(prop, PROP_ANGLE);
+ RNA_def_float_rotation(ot->srna, "value", 2, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT);
}
static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
{
- PropertyRNA *prop;
-
/* identifiers */
ot->name = "Rotate";
ot->description = "Rotate selected items";
@@ -682,8 +677,7 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
- prop = RNA_def_float(ot->srna, "value", 0.0f, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
- RNA_def_property_subtype(prop, PROP_ANGLE);
+ RNA_def_float_rotation(ot->srna, "value", 0, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_GPENCIL_EDIT);
}
@@ -857,6 +851,12 @@ static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot)
prop = RNA_def_boolean(ot->srna, "single_side", false, "Single Side", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ RNA_def_boolean(ot->srna, "use_even", false, "Even",
+ "Make the edge loop match the shape of the adjacent edge loop");
+ RNA_def_boolean(ot->srna, "flipped", false, "Flipped",
+ "When Even mode is active, flips between the two adjacent edge loops");
+ RNA_def_boolean(ot->srna, "use_clamp", true, "Clamp",
+ "Clamp within the edge extents");
Transform_Properties(ot, P_MIRROR | P_SNAP | P_CORRECT_UV);
}
@@ -877,6 +877,12 @@ static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot)
ot->poll = ED_operator_editmesh_region_view3d;
RNA_def_float_factor(ot->srna, "value", 0, -10.0f, 10.0f, "Factor", "", -1.0f, 1.0f);
+ RNA_def_boolean(ot->srna, "use_even", false, "Even",
+ "Make the edge loop match the shape of the adjacent edge loop");
+ RNA_def_boolean(ot->srna, "flipped", false, "Flipped",
+ "When Even mode is active, flips between the two adjacent edge loops");
+ RNA_def_boolean(ot->srna, "use_clamp", true, "Clamp",
+ "Clamp within the edge extents");
Transform_Properties(ot, P_MIRROR | P_SNAP | P_CORRECT_UV);
}
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 7fea8e163fd..a1bb6f4e0f3 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -36,6 +36,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
#include "BLI_math.h"
@@ -52,7 +53,7 @@
#include "BKE_main.h"
#include "BKE_screen.h"
-#include "BLF_translation.h"
+#include "BLT_translation.h"
#include "ED_armature.h"
@@ -85,7 +86,7 @@ static bool uniqueOrientationNameCheck(void *arg, const char *name)
static void uniqueOrientationName(ListBase *lb, char *name)
{
- BLI_uniquename_cb(uniqueOrientationNameCheck, lb, CTX_DATA_(BLF_I18NCONTEXT_ID_SCENE, "Space"), '.', name,
+ BLI_uniquename_cb(uniqueOrientationNameCheck, lb, CTX_DATA_(BLT_I18NCONTEXT_ID_SCENE, "Space"), '.', name,
sizeof(((TransformOrientation *)NULL)->name));
}
@@ -144,7 +145,7 @@ static TransformOrientation *createBoneSpace(bContext *C, ReportList *reports,
float mat[3][3];
float normal[3], plane[3];
- getTransformOrientation(C, normal, plane, 0);
+ getTransformOrientation(C, normal, plane);
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
BKE_reports_prepend(reports, "Cannot use zero-length bone");
@@ -164,7 +165,7 @@ static TransformOrientation *createCurveSpace(bContext *C, ReportList *reports,
float mat[3][3];
float normal[3], plane[3];
- getTransformOrientation(C, normal, plane, 0);
+ getTransformOrientation(C, normal, plane);
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
BKE_reports_prepend(reports, "Cannot use zero-length curve");
@@ -186,7 +187,7 @@ static TransformOrientation *createMeshSpace(bContext *C, ReportList *reports,
float normal[3], plane[3];
int type;
- type = getTransformOrientation(C, normal, plane, 0);
+ type = getTransformOrientation(C, normal, plane);
switch (type) {
case ORIENTATION_VERT:
@@ -390,15 +391,12 @@ int BIF_countTransformOrientation(const bContext *C)
return BLI_listbase_count(transform_spaces);
}
-bool applyTransformOrientation(const bContext *C, float mat[3][3], char *r_name)
+bool applyTransformOrientation(const bContext *C, float mat[3][3], char *r_name, int index)
{
- View3D *v3d = CTX_wm_view3d(C);
- int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
-
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
- TransformOrientation *ts = BLI_findlink(transform_spaces, selected_index);
+ TransformOrientation *ts = BLI_findlink(transform_spaces, index);
- BLI_assert(selected_index >= 0);
+ BLI_assert(index >= 0);
if (ts) {
if (r_name) {
@@ -442,7 +440,6 @@ static int count_bone_select(bArmature *arm, ListBase *lb, const bool do_it)
void initTransformOrientation(bContext *C, TransInfo *t)
{
- View3D *v3d = CTX_wm_view3d(C);
Object *ob = CTX_data_active_object(C);
Object *obedit = CTX_data_active_object(C);
@@ -462,7 +459,7 @@ void initTransformOrientation(bContext *C, TransInfo *t)
case V3D_MANIP_NORMAL:
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
BLI_strncpy(t->spacename, IFACE_("normal"), sizeof(t->spacename));
- ED_getTransformOrientationMatrix(C, t->spacemtx, (v3d->around == V3D_ACTIVE));
+ ED_getTransformOrientationMatrix(C, t->spacemtx, t->around);
break;
}
/* fall-through */ /* we define 'normal' as 'local' in Object mode */
@@ -480,7 +477,9 @@ void initTransformOrientation(bContext *C, TransInfo *t)
break;
case V3D_MANIP_VIEW:
- if (t->ar->regiontype == RGN_TYPE_WINDOW) {
+ if ((t->spacetype == SPACE_VIEW3D) &&
+ (t->ar->regiontype == RGN_TYPE_WINDOW))
+ {
RegionView3D *rv3d = t->ar->regiondata;
float mat[3][3];
@@ -494,7 +493,7 @@ void initTransformOrientation(bContext *C, TransInfo *t)
}
break;
default: /* V3D_MANIP_CUSTOM */
- if (applyTransformOrientation(C, t->spacemtx, t->spacename)) {
+ if (applyTransformOrientation(C, t->spacemtx, t->spacename, t->current_orientation - V3D_MANIP_CUSTOM)) {
/* pass */
}
else {
@@ -585,14 +584,14 @@ static unsigned int bm_mesh_faces_select_get_n(BMesh *bm, BMVert **elems, const
}
#endif
-int getTransformOrientation(const bContext *C, float normal[3], float plane[3], const bool activeOnly)
+int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3], const short around)
{
Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
Object *obedit = CTX_data_edit_object(C);
Base *base;
Object *ob = OBACT;
int result = ORIENTATION_NONE;
+ const bool activeOnly = (around == V3D_ACTIVE);
zero_v3(normal);
zero_v3(plane);
@@ -718,7 +717,6 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
/* should never fail */
if (LIKELY(v_pair[0] && v_pair[1])) {
bool v_pair_swap = false;
- float tvec[3];
/**
* Logic explained:
*
@@ -749,11 +747,6 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
sub_v3_v3v3(plane, v_pair[0]->co, v_pair[1]->co);
/* flip the plane normal so we point outwards */
negate_v3(plane);
-
- /* align normal to edge direction (so normal is perpendicular to the plane).
- * 'ORIENTATION_EDGE' will do the other way around */
- project_v3_v3v3(tvec, normal, plane);
- sub_v3_v3(normal, tvec);
}
result = ORIENTATION_EDGE;
@@ -861,7 +854,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
/* exception */
if (flag) {
float tvec[3];
- if ((v3d->around == V3D_LOCAL) ||
+ if ((around == V3D_LOCAL) ||
ELEM(flag, SEL_F2, SEL_F1 | SEL_F3, SEL_F1 | SEL_F2 | SEL_F3))
{
BKE_nurb_bezt_calc_normal(nu, bezt, tvec);
@@ -962,8 +955,16 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
/* Vectors from edges don't need the special transpose inverse multiplication */
if (result == ORIENTATION_EDGE) {
+ float tvec[3];
+
mul_mat3_m4_v3(ob->obmat, normal);
mul_mat3_m4_v3(ob->obmat, plane);
+
+ /* align normal to edge direction (so normal is perpendicular to the plane).
+ * 'ORIENTATION_EDGE' will do the other way around.
+ * This has to be done **after** applying obmat, see T45775! */
+ project_v3_v3v3(tvec, normal, plane);
+ sub_v3_v3(normal, tvec);
}
else {
mul_m3_v3(mat, normal);
@@ -1015,6 +1016,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
}
else {
/* we need the one selected object, if its not active */
+ View3D *v3d = CTX_wm_view3d(C);
ob = OBACT;
if (ob && (ob->flag & SELECT)) {
/* pass */
@@ -1040,14 +1042,22 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
return result;
}
-void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[3][3], const bool activeOnly)
+int getTransformOrientation(const bContext *C, float normal[3], float plane[3])
+{
+ /* dummy value, not V3D_ACTIVE and not V3D_LOCAL */
+ short around = V3D_CENTER;
+
+ return getTransformOrientation_ex(C, normal, plane, around);
+}
+
+void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[3][3], const short around)
{
float normal[3] = {0.0, 0.0, 0.0};
float plane[3] = {0.0, 0.0, 0.0};
int type;
- type = getTransformOrientation(C, normal, plane, activeOnly);
+ type = getTransformOrientation_ex(C, normal, plane, around);
switch (type) {
case ORIENTATION_NORMAL:
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 3b488fde2b3..0e954d40c18 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -85,6 +85,8 @@
#define TRANSFORM_DIST_MAX_PX 1000.0f
#define TRANSFORM_SNAP_MAX_PX 100.0f
+#define TRANSFORM_DIST_INVALID NAN_FLT
+
/* use half of flt-max so we can scale up without an exception */
/********************* PROTOTYPES ***********************/
@@ -220,7 +222,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
h = (((float)hi) / IMG_SIZE_FALLBACK) * G.sima->zoom * yuser_asp;
cpack(0xFFFFFF);
- glTranslatef(t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], 0.0f);
+ glTranslate2fv(t->tsnap.snapPoint);
//glRectf(0, 0, 1, 1);
@@ -810,14 +812,18 @@ static void ApplySnapRotation(TransInfo *t, float *value)
static void ApplySnapResize(TransInfo *t, float vec[3])
{
+ float dist;
+
if (t->tsnap.target == SCE_SNAP_TARGET_CLOSEST) {
- vec[0] = vec[1] = vec[2] = t->tsnap.dist;
+ dist = t->tsnap.dist;
}
else {
float point[3];
getSnapPoint(t, point);
- vec[0] = vec[1] = vec[2] = ResizeBetween(t, t->tsnap.snapTarget, point);
+ dist = ResizeBetween(t, t->tsnap.snapTarget, point);
}
+
+ copy_v3_fl(vec, dist);
}
/********************** DISTANCE **************************/
@@ -884,6 +890,8 @@ static float ResizeBetween(TransInfo *t, const float p1[3], const float p2[3])
sub_v3_v3v3(d1, p1, t->center_global);
sub_v3_v3v3(d2, p2, t->center_global);
+ project_v3_v3v3(d1, d1, d2);
+
if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) {
mul_m3_v3(t->con.pmtx, d1);
mul_m3_v3(t->con.pmtx, d2);
@@ -891,7 +899,10 @@ static float ResizeBetween(TransInfo *t, const float p1[3], const float p2[3])
len_d1 = len_v3(d1);
- return len_d1 != 0.0f ? len_v3(d2) / len_d1 : 1;
+ /* Use 'invalid' dist when `center == p1` (after projecting),
+ * in this case scale will _never_ move the point in relation to the center,
+ * so it makes no sense to take it into account when scaling. see: T46503 */
+ return len_d1 != 0.0f ? len_v3(d2) / len_d1 : TRANSFORM_DIST_INVALID;
}
/********************** CALC **************************/
@@ -975,7 +986,7 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
break;
}
- new_dist = len_v3v3(last_p, vec);
+ new_dist = len_squared_v3v3(last_p, vec);
if (new_dist < max_dist) {
copy_v3_v3(p, vec);
@@ -996,6 +1007,7 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
BLI_freelistN(&depth_peels);
}
else {
+ zero_v3(no); /* objects won't set this */
found = snapObjectsTransform(t, mval, &dist_px, loc, no, t->tsnap.modeSelect);
}
@@ -1170,8 +1182,10 @@ static void TargetSnapClosest(TransInfo *t)
mul_m4_v3(td->ext->obmat, loc);
dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);
-
- if (closest == NULL || fabsf(dist) < fabsf(t->tsnap.dist)) {
+
+ if ((dist != TRANSFORM_DIST_INVALID) &&
+ (closest == NULL || fabsf(dist) < fabsf(t->tsnap.dist)))
+ {
copy_v3_v3(t->tsnap.snapTarget, loc);
closest = td;
t->tsnap.dist = dist;
@@ -1186,8 +1200,10 @@ static void TargetSnapClosest(TransInfo *t)
copy_v3_v3(loc, td->center);
dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);
-
- if (closest == NULL || fabsf(dist) < fabsf(t->tsnap.dist)) {
+
+ if ((dist != TRANSFORM_DIST_INVALID) &&
+ (closest == NULL || fabsf(dist) < fabsf(t->tsnap.dist)))
+ {
copy_v3_v3(t->tsnap.snapTarget, loc);
closest = td;
t->tsnap.dist = dist;
@@ -1210,7 +1226,9 @@ static void TargetSnapClosest(TransInfo *t)
dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);
- if (closest == NULL || fabsf(dist) < fabsf(t->tsnap.dist)) {
+ if ((dist != TRANSFORM_DIST_INVALID) &&
+ (closest == NULL || fabsf(dist) < fabsf(t->tsnap.dist)))
+ {
copy_v3_v3(t->tsnap.snapTarget, loc);
closest = td;
t->tsnap.dist = dist;
@@ -1520,8 +1538,17 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes
if (do_bb) {
BoundBox *bb = BKE_object_boundbox_get(ob);
- if (!BKE_boundbox_ray_hit_check(bb, ray_start_local, ray_normal_local, &len_diff)) {
- return retval;
+
+ if (bb) {
+ BoundBox bb_temp;
+
+ /* We cannot aford a bbox with some null dimension, which may happen in some cases...
+ * Threshold is rather high, but seems to be needed to get good behavior, see T46099. */
+ bb = BKE_boundbox_ensure_minimum_dimensions(bb, &bb_temp, 1e-1f);
+
+ if (!BKE_boundbox_ray_hit_check(bb, ray_start_local, ray_normal_local, &len_diff)) {
+ return retval;
+ }
}
}
else if (do_ray_start_correction) {
@@ -1533,6 +1560,7 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes
len_diff = 0.0f; /* In case BVHTree would fail for some reason... */
treeData.em_evil = em;
+ treeData.em_evil_all = false;
bvhtree_from_mesh_looptri(&treeData, dm, 0.0f, 2, 6);
if (treeData.tree != NULL) {
nearest.index = -1;
@@ -1575,6 +1603,7 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes
}
treeData.em_evil = em;
+ treeData.em_evil_all = false;
bvhtree_from_mesh_looptri(&treeData, dm, 0.0f, 4, 6);
hit.index = -1;
@@ -1847,8 +1876,16 @@ static bool snapObject(Scene *scene, short snap_mode, ARegion *ar, Object *ob, f
do_bb = false;
}
else {
+ /* in this case we want the mesh from the editmesh, avoids stale data. see: T45978.
+ * still set the 'em' to NULL, since we only want the 'dm'. */
+ em = BKE_editmesh_from_object(ob);
+ if (em) {
+ editbmesh_get_derived_cage_and_final(scene, ob, em, CD_MASK_BAREMESH, &dm);
+ }
+ else {
+ dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
+ }
em = NULL;
- dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
}
retval = snapDerivedMesh(snap_mode, ar, ob, dm, em, obmat, ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_depth, do_bb);
@@ -1968,8 +2005,20 @@ static bool snapObjects(Scene *scene, short snap_mode, Base *base_act, View3D *v
bool snapObjectsTransform(TransInfo *t, const float mval[2], float *r_dist_px, float r_loc[3], float r_no[3], SnapMode mode)
{
float ray_dist = TRANSFORM_DIST_MAX_RAY;
- return snapObjects(t->scene, t->scene->toolsettings->snap_mode, t->scene->basact, t->view, t->ar, t->obedit,
- mval, r_dist_px, r_loc, r_no, &ray_dist, mode);
+ Object *obedit = NULL;
+ Base *base_act = NULL;
+
+ if (t->flag & T_EDIT) {
+ obedit = t->obedit;
+ }
+
+ if ((t->options & CTX_GPENCIL_STROKES) == 0) {
+ base_act = t->scene->basact;
+ }
+
+ return snapObjects(
+ t->scene, t->scene->toolsettings->snap_mode, base_act, t->view, t->ar, obedit,
+ mval, r_dist_px, r_loc, r_no, &ray_dist, mode);
}
bool snapObjectsContext(bContext *C, const float mval[2], float *r_dist_px, float r_loc[3], float r_no[3], SnapMode mode)
@@ -2056,21 +2105,62 @@ static void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float n
peel->flag = 0;
}
-static bool peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[4][4],
- const float ray_start[3], const float ray_normal[3], const float UNUSED(mval[2]),
- ListBase *depth_peels)
+struct PeelRayCast_Data {
+ BVHTreeFromMesh bvhdata;
+
+ /* internal vars for adding peel */
+ Object *ob;
+ const float (*obmat)[4];
+ const float (*timat)[3];
+
+ const float *ray_start; /* globalspace */
+
+ const MLoopTri *looptri;
+ const float (*polynors)[3]; /* optional, can be NULL */
+
+ /* output list */
+ ListBase *depth_peels;
+};
+
+static void peelRayCast_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
+{
+ struct PeelRayCast_Data *data = userdata;
+
+ data->bvhdata.raycast_callback(&data->bvhdata, index, ray, hit);
+
+ if (hit->index != -1) {
+ /* get all values in worldspace */
+ float location[3], normal[3];
+ float depth;
+
+ /* worldspace location */
+ mul_v3_m4v3(location, (float (*)[4])data->obmat, hit->co);
+ depth = len_v3v3(location, data->ray_start);
+
+ /* worldspace normal */
+ copy_v3_v3(normal, data->polynors ? data->polynors[data->looptri[hit->index].poly] : hit->no);
+ mul_m3_v3((float (*)[3])data->timat, normal);
+ normalize_v3(normal);
+
+ addDepthPeel(data->depth_peels, depth, location, normal, data->ob);
+ }
+}
+
+static bool peelDerivedMesh(
+ Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[4][4],
+ const float ray_start[3], const float ray_normal[3], const float UNUSED(mval[2]),
+ ListBase *depth_peels)
{
bool retval = false;
int totvert = dm->getNumVerts(dm);
if (totvert > 0) {
const MLoopTri *looptri = dm->getLoopTriArray(dm);
- const MLoop *mloop = dm->getLoopArray(dm);
- int looptri_num = dm->getNumLoopTri(dm);
+ const int looptri_num = dm->getNumLoopTri(dm);
float imat[4][4];
float timat[3][3]; /* transpose inverse matrix for normals */
float ray_start_local[3], ray_normal_local[3];
- int test = 1;
+ bool test = true;
invert_m4_m4(imat, obmat);
@@ -2083,56 +2173,41 @@ static bool peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[4][4],
* test against boundbox first
* */
if (looptri_num > 16) {
- struct BoundBox *bb = BKE_object_boundbox_get(ob);
- test = BKE_boundbox_ray_hit_check(bb, ray_start_local, ray_normal_local, NULL);
- }
-
- if (test == 1) {
- const MLoopTri *lt;
- MVert *verts = dm->getVertArray(dm);
- float (*polynors)[3] = dm->getPolyDataArray(dm, CD_NORMAL);
- int i;
-
- for (i = 0, lt = looptri; i < looptri_num; i++, lt++) {
- const unsigned int vtri[3] = {mloop[lt->tri[0]].v, mloop[lt->tri[1]].v, mloop[lt->tri[2]].v};
- float lambda;
- int result;
-
-
- result = isect_ray_tri_threshold_v3(
- ray_start_local, ray_normal_local,
- verts[vtri[0]].co, verts[vtri[1]].co, verts[vtri[2]].co,
- &lambda, NULL, 0.001);
-
- if (result) {
- float location[3], normal[3];
- float intersect[3];
- float new_depth;
-
- copy_v3_v3(intersect, ray_normal_local);
- mul_v3_fl(intersect, lambda);
- add_v3_v3(intersect, ray_start_local);
-
- copy_v3_v3(location, intersect);
+ BoundBox *bb = BKE_object_boundbox_get(ob);
- if (polynors) {
- copy_v3_v3(normal, polynors[lt->poly]);
- }
- else {
- normal_tri_v3(normal, verts[vtri[0]].co, verts[vtri[1]].co, verts[vtri[2]].co);
- }
+ if (bb) {
+ BoundBox bb_temp;
- mul_m4_v3(obmat, location);
-
- new_depth = len_v3v3(location, ray_start);
-
- mul_m3_v3(timat, normal);
- normalize_v3(normal);
+ /* We cannot aford a bbox with some null dimension, which may happen in some cases...
+ * Threshold is rather high, but seems to be needed to get good behavior, see T46099. */
+ bb = BKE_boundbox_ensure_minimum_dimensions(bb, &bb_temp, 1e-1f);
- addDepthPeel(depth_peels, new_depth, location, normal, ob);
- }
+ test = BKE_boundbox_ray_hit_check(bb, ray_start_local, ray_normal_local, NULL);
}
}
+
+ if (test == true) {
+ struct PeelRayCast_Data data;
+
+ data.bvhdata.em_evil = em;
+ data.bvhdata.em_evil_all = false;
+ bvhtree_from_mesh_looptri(&data.bvhdata, dm, 0.0f, 4, 6);
+
+ if (data.bvhdata.tree != NULL) {
+ data.ob = ob;
+ data.obmat = (const float (*)[4])obmat;
+ data.timat = (const float (*)[3])timat;
+ data.ray_start = ray_start;
+ data.looptri = looptri;
+ data.polynors = dm->getPolyDataArray(dm, CD_NORMAL); /* can be NULL */
+ data.depth_peels = depth_peels;
+
+ BLI_bvhtree_ray_cast_all(data.bvhdata.tree, ray_start_local, ray_normal_local, 0.0f,
+ peelRayCast_cb, &data);
+ }
+
+ free_bvhtree_from_mesh(&data.bvhdata);
+ }
}
return retval;
@@ -2168,13 +2243,13 @@ static bool peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit,
if (dob != obedit) {
dm = mesh_get_derived_final(scene, dob, CD_MASK_BAREMESH);
- val = peelDerivedMesh(dob, dm, dob->obmat, ray_start, ray_normal, mval, depth_peels);
+ val = peelDerivedMesh(dob, dm, NULL, dob->obmat, ray_start, ray_normal, mval, depth_peels);
}
else {
em = BKE_editmesh_from_object(dob);
dm = editbmesh_get_derived_cage(scene, obedit, em, CD_MASK_BAREMESH);
- val = peelDerivedMesh(dob, dm, dob->obmat, ray_start, ray_normal, mval, depth_peels);
+ val = peelDerivedMesh(dob, dm, em, dob->obmat, ray_start, ray_normal, mval, depth_peels);
}
retval = retval || val;
@@ -2192,14 +2267,14 @@ static bool peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit,
if (ob != obedit && ((mode == SNAP_NOT_SELECTED && (base->flag & (SELECT | BA_WAS_SEL)) == 0) || ELEM(mode, SNAP_ALL, SNAP_NOT_OBEDIT))) {
DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
- val = peelDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, depth_peels);
+ val = peelDerivedMesh(ob, dm, NULL, ob->obmat, ray_start, ray_normal, mval, depth_peels);
dm->release(dm);
}
else if (ob == obedit && mode != SNAP_NOT_OBEDIT) {
BMEditMesh *em = BKE_editmesh_from_object(ob);
DerivedMesh *dm = editbmesh_get_derived_cage(scene, obedit, em, CD_MASK_BAREMESH);
- val = peelDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, depth_peels);
+ val = peelDerivedMesh(ob, dm, NULL, ob->obmat, ray_start, ray_normal, mval, depth_peels);
dm->release(dm);
}