diff options
Diffstat (limited to 'source/blender/editors/transform')
6 files changed, 164 insertions, 79 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 822ab0b9e70..d2354a4a7ad 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -57,6 +57,8 @@ #include "BIF_gl.h" #include "BIF_glutil.h" +#include "BLF_api.h" + #include "BKE_nla.h" #include "BKE_bmesh.h" #include "BKE_context.h" @@ -88,12 +90,14 @@ #include "BLI_linklist.h" #include "BLI_smallhash.h" #include "BLI_array.h" +#include "PIL_time.h" +#include "UI_interface_icons.h" #include "UI_resources.h" #include "transform.h" -#include <stdio.h> +#include <stdio.h> // XXX: duplicated??? static void drawTransformApply(const struct bContext *C, ARegion *ar, void *arg); static int doEdgeSlide(TransInfo *t, float perc); @@ -225,8 +229,12 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) void projectIntView(TransInfo *t, const float vec[3], int adr[2]) { if (t->spacetype == SPACE_VIEW3D) { - if (t->ar->regiontype == RGN_TYPE_WINDOW) - ED_view3d_project_int_noclip(t->ar, vec, adr); + if (t->ar->regiontype == RGN_TYPE_WINDOW) { + if (ED_view3d_project_int_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + adr[0] = (int)2140000000.0f; /* this is what was done in 2.64, perhaps we can be smarter? */ + adr[1] = (int)2140000000.0f; + } + } } else if (t->spacetype == SPACE_IMAGE) { SpaceImage *sima = t->sa->spacedata.first; @@ -347,7 +355,11 @@ void projectFloatView(TransInfo *t, const float vec[3], float adr[2]) case SPACE_VIEW3D: { if (t->ar->regiontype == RGN_TYPE_WINDOW) { - ED_view3d_project_float_noclip(t->ar, vec, adr); + if (ED_view3d_project_float_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + /* XXX, 2.64 and prior did this, weak! */ + adr[0] = t->ar->winx / 2.0f; + adr[1] = t->ar->winy / 2.0f; + } return; } break; @@ -819,7 +831,7 @@ int transformEvent(TransInfo *t, wmEvent *event) float mati[3][3] = MAT3_UNITY; char cmode = constraintModeToChar(t); int handled = 1; - + t->redraw |= handleMouseInput(t, &t->mouse, event); if (event->type == MOUSEMOVE) { @@ -1260,10 +1272,13 @@ int transformEvent(TransInfo *t, wmEvent *event) if (t->handleEvent) t->redraw |= t->handleEvent(t, event); - if (handled || t->redraw) + if (handled || t->redraw) { + t->last_update = PIL_check_seconds_timer(); return 0; - else + } + else { return OPERATOR_PASS_THROUGH; + } } int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], int cent2d[2]) @@ -1546,14 +1561,63 @@ static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), voi drawNonPropEdge(C, t); } -#if 0 -static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), void *UNUSED(arg)) +/* just draw a little warning message in the top-right corner of the viewport to warn that autokeying is enabled */ +static void drawAutoKeyWarning(TransInfo *t, ARegion *ar) { -// TransInfo *t = arg; -// -// drawHelpline(C, t->mval[0], t->mval[1], t); + int show_warning; + + /* red border around the viewport */ + UI_ThemeColor(TH_REDALERT); + + glBegin(GL_LINE_LOOP); + glVertex2f(1, 1); + glVertex2f(1, ar->winy-1); + glVertex2f(ar->winx-1, ar->winy-1); + glVertex2f(ar->winx-1, 1); + glEnd(); + + /* Entire warning should "blink" to catch periphery attention without being overly distracting + * much like how a traditional recording sign in the corner of a camcorder works + * + * - Blink frequency here is 0.5 secs (i.e. a compromise between epilepsy-inducing flicker + too slow to notice). + * We multiply by two to speed up the odd/even time-in-seconds = on/off toggle. + * - Always start with warning shown so that animators are more likely to notice when starting to transform + */ + show_warning = (int)(t->last_update * 2.0) & 1; + + if ((show_warning) || (t->state == TRANS_STARTING)) { + const char printable[] = "Auto Keying On"; + int xco, yco; + + xco = ar->winx - BLF_width_default(printable) - 10; + yco = ar->winy - BLF_height_default(printable) - 10; + + /* red warning text */ + UI_ThemeColor(TH_REDALERT); + BLF_draw_default_ascii(xco, ar->winy - 17, 0.0f, printable, sizeof(printable)); + + /* autokey recording icon... */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + xco -= (ICON_DEFAULT_WIDTH + 2); + UI_icon_draw(xco, yco, ICON_REC); + + glDisable(GL_BLEND); + } +} + +static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *ar, void *arg) +{ + TransInfo *t = arg; + Scene *scene = t->scene; + Object *ob = OBACT; + + /* draw autokeyframing hint in the corner */ + if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) { + drawAutoKeyWarning(t, ar); + } } -#endif void saveTransform(bContext *C, TransInfo *t, wmOperator *op) { @@ -1723,7 +1787,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int 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_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) { @@ -4789,12 +4853,12 @@ static void calcNonProportionalEdgeSlide(TransInfo *t, SlideData *sld, const flo sv->edge_len = len_v3v3(dw_p, up_p); mul_v3_m4v3(v_proj, t->obedit->obmat, sv->v->co); - ED_view3d_project_float_noclip(t->ar, v_proj, v_proj); - - dist = len_squared_v2v2(mval, v_proj); - if (dist < min_dist) { - min_dist = dist; - sld->curr_sv_index = i; + if (ED_view3d_project_float_global(t->ar, v_proj, v_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + dist = len_squared_v2v2(mval, v_proj); + if (dist < min_dist) { + min_dist = dist; + sld->curr_sv_index = i; + } } } } @@ -5529,42 +5593,42 @@ static int doEdgeSlide(TransInfo *t, float perc) int i; sld->perc = perc; - sv = svlist; - for (i = 0; i < sld->totsv; i++, sv++) { - if (sld->is_proportional == FALSE) { - TransDataSlideVert *curr_sv = &sld->sv[sld->curr_sv_index]; - float cur_sel = curr_sv->edge_len; - float cur_sv = sv->edge_len; - float extd = 0.0f; - float recip_cur_sv = 0.0f; - - if (cur_sel == 0.0f) cur_sel = 1.0f; - if (cur_sv == 0.0f) cur_sv = 1.0f; - - recip_cur_sv = 1.0f / cur_sv; - if (!sld->flipped_vtx) { - extd = (cur_sv - cur_sel) * recip_cur_sv; + if (sld->is_proportional == TRUE) { + for (i = 0; i < sld->totsv; i++, sv++) { + if (perc > 0.0f) { + copy_v3_v3(vec, sv->upvec); + mul_v3_fl(vec, perc); + add_v3_v3v3(sv->v->co, sv->origvert.co, vec); } else { - extd = (cur_sel - cur_sv) * recip_cur_sv; + copy_v3_v3(vec, sv->downvec); + mul_v3_fl(vec, -perc); + add_v3_v3v3(sv->v->co, sv->origvert.co, vec); } - - extd += (sld->perc * cur_sel) * recip_cur_sv; - CLAMP(extd, -1.0f, 1.0f); - perc = extd; } + } + else { + /** + * Implementation note, non proportional mode ignores the starting positions and uses only the + * up/down 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 + */ + TransDataSlideVert *curr_sv = &sld->sv[sld->curr_sv_index]; + const float curr_length_perc = len_v3v3(curr_sv->up->co, curr_sv->down->co) * + (((sld->flipped_vtx ? perc : -perc) + 1.0f) / 2.0f); - if (perc > 0.0f) { - copy_v3_v3(vec, sv->upvec); - mul_v3_fl(vec, perc); - add_v3_v3v3(sv->v->co, sv->origvert.co, vec); - } - else { - copy_v3_v3(vec, sv->downvec); - mul_v3_fl(vec, -perc); - add_v3_v3v3(sv->v->co, sv->origvert.co, vec); + for (i = 0; i < sld->totsv; i++, sv++) { + const float sv_length = len_v3v3(sv->up->co, sv->down->co); + const float fac = minf(sv_length, curr_length_perc) / sv_length; + + if (sld->flipped_vtx) { + interp_v3_v3v3(sv->v->co, sv->down->co, sv->up->co, fac); + } + else { + interp_v3_v3v3(sv->v->co, sv->up->co, sv->down->co, fac); + } } } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index e645cb2fed6..40f53423d37 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -322,6 +322,8 @@ typedef struct TransInfo { float auto_values[4]; float axis[3]; float axis_orig[3]; /* TransCon can change 'axis', store the original value here */ + + double last_update; /* Time of last update (in seconds) */ void *view; struct bContext *context; /* Only valid (non null) during an operator called function. */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 540cbb97609..39a5da94798 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1489,6 +1489,8 @@ static void createTransCurveVerts(TransInfo *t) count++; tail++; } + + (void)hdata; /* quiet warning */ } else if (propmode && head != tail) { calc_distanceCurveVerts(head, tail - 1); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index b8db0b575cf..a9d9ec7b010 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -895,16 +895,20 @@ static void recalcData_view3d(TransInfo *t) /* helper for recalcData() - for sequencer transforms */ static void recalcData_sequencer(TransInfo *t) { - Editing *ed = BKE_sequencer_editing_get(t->scene, FALSE); - Sequence *seq; + TransData *td; + int a; + Sequence *seq_prev = NULL; - SEQ_BEGIN(ed, seq) - { - if (seq->flag & SELECT) { - BKE_sequence_invalidate_deendent(t->scene, seq); + for (a = 0, td = t->data; a < t->total; a++, td++) { + TransDataSeq *tdsq = (TransDataSeq *) td->extra; + Sequence *seq = tdsq->seq; + + if (seq != seq_prev) { + BKE_sequence_invalidate_dependent(t->scene, seq); } + + seq_prev = seq; } - SEQ_END BKE_sequencer_preprocessed_cache_cleanup(); diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index a155ff7786a..0e25739c34a 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -402,7 +402,7 @@ EnumPropertyItem *BIF_enumTransformOrientation(bContext *C) const char *BIF_menustringTransformOrientation(const bContext *C, const char *title) { - const char *menu = IFACE_("%t|Global%x0|Local%x1|Gimbal%x4|Normal%x2|View%x3"); + const char *menu = IFACE_("%t|Global %x0|Local %x1|Gimbal %x4|Normal %x2|View %x3"); ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; TransformOrientation *ts; int i = V3D_MANIP_CUSTOM; @@ -411,14 +411,14 @@ const char *BIF_menustringTransformOrientation(const bContext *C, const char *ti title = IFACE_(title); - str_menu = MEM_callocN(strlen(menu) + strlen(title) + 1 + elem_size * BIF_countTransformOrientation(C), TIP_("UserTransSpace from matrix")); + str_menu = MEM_callocN(strlen(menu) + strlen(title) + 1 + elem_size * BIF_countTransformOrientation(C), "UserTransSpace from matrix"); p = str_menu; p += sprintf(str_menu, "%s", title); p += sprintf(p, "%s", menu); for (ts = transform_spaces->first; ts; ts = ts->next) { - p += sprintf(p, "|%s%%x%d", ts->name, i++); + p += sprintf(p, "|%s %%x%d", ts->name, i++); } return str_menu; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 1d75be05534..2f2b31de89d 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -80,6 +80,8 @@ #define USE_BVH_FACE_SNAP +#define TRANSFORM_DIST_MAX_PX 1000 + /********************* PROTOTYPES ***********************/ static void setSnappingCallback(TransInfo *t); @@ -296,7 +298,7 @@ void applyProject(TransInfo *t) for (i = 0; i < t->total; i++, td++) { float iloc[3], loc[3], no[3]; float mval[2]; - int dist = 1000; + int dist = TRANSFORM_DIST_MAX_PX; if (td->flag & TD_NOACTION) break; @@ -315,18 +317,18 @@ void applyProject(TransInfo *t) copy_v3_v3(iloc, td->ob->obmat[3]); } - ED_view3d_project_float(t->ar, iloc, mval); - - if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.modeSelect)) { -// if (t->flag & (T_EDIT|T_POSE)) { -// mul_m4_v3(imat, loc); -// } -// - sub_v3_v3v3(tvec, loc, iloc); - - mul_m3_v3(td->smtx, tvec); - - add_v3_v3(td->loc, tvec); + if (ED_view3d_project_float_global(t->ar, iloc, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.modeSelect)) { +// if (t->flag & (T_EDIT|T_POSE)) { +// mul_m4_v3(imat, loc); +// } + + sub_v3_v3v3(tvec, loc, iloc); + + mul_m3_v3(td->smtx, tvec); + + add_v3_v3(td->loc, tvec); + } } //XXX constraintTransLim(t, td); @@ -601,7 +603,9 @@ int updateSelectedSnapPoint(TransInfo *t) int dx, dy; int dist; - ED_view3d_project_int(t->ar, p->co, screen_loc); + if (ED_view3d_project_int_global(t->ar, p->co, screen_loc, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + continue; + } dx = t->mval[0] - screen_loc[0]; dy = t->mval[1] - screen_loc[1]; @@ -1232,8 +1236,12 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh new_depth = len_v3v3(location, ray_start); - ED_view3d_project_int(ar, location, screen_loc); - new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); + if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); + } + else { + new_dist = TRANSFORM_DIST_MAX_PX; + } /* 10% threshold if edge is closer but a bit further * this takes care of series of connected edges a bit slanted w.r.t the viewport @@ -1289,8 +1297,13 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4], new_depth = len_v3v3(location, ray_start); - ED_view3d_project_int(ar, location, screen_loc); - new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); + if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); + } + else { + new_dist = TRANSFORM_DIST_MAX_PX; + } + if (new_dist <= *r_dist && new_depth < *r_depth) { *r_depth = new_depth; @@ -1697,7 +1710,7 @@ static int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, c if (ob->transflag & OB_DUPLI) { DupliObject *dupli_ob; - ListBase *lb = object_duplilist(scene, ob); + ListBase *lb = object_duplilist(scene, ob, FALSE); for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { Object *dob = dupli_ob->ob; @@ -1903,7 +1916,7 @@ static int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, L if (ob->transflag & OB_DUPLI) { DupliObject *dupli_ob; - ListBase *lb = object_duplilist(scene, ob); + ListBase *lb = object_duplilist(scene, ob, FALSE); for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { Object *dob = dupli_ob->ob; |