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:
authormano-wii <germano.costa@ig.com.br>2020-02-14 14:42:17 +0300
committermano-wii <germano.costa@ig.com.br>2020-02-14 14:42:59 +0300
commite277e8d085037414f34b27f9c1a26cbbf2507c3e (patch)
treecb37b0a9332a23e09a6717d68894f481542f3d67 /source/blender/editors/transform/transform_mode_translate.c
parent897f943ca0c93a46bdb767e4c47c4bddfa7149c2 (diff)
Cleanup: Split transform.c in multiple files
Differential Revision: https://developer.blender.org/D5819
Diffstat (limited to 'source/blender/editors/transform/transform_mode_translate.c')
-rw-r--r--source/blender/editors/transform/transform_mode_translate.c413
1 files changed, 413 insertions, 0 deletions
diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c
new file mode 100644
index 00000000000..8a6954f18f7
--- /dev/null
+++ b/source/blender/editors/transform/transform_mode_translate.c
@@ -0,0 +1,413 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup edtransform
+ */
+
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_gpencil_types.h"
+
+#include "BLI_math.h"
+#include "BLI_string.h"
+
+#include "BKE_context.h"
+#include "BKE_report.h"
+#include "BKE_unit.h"
+
+#include "ED_screen.h"
+
+#include "WM_api.h"
+
+#include "UI_interface.h"
+
+#include "BLT_translation.h"
+
+#include "transform.h"
+#include "transform_convert.h"
+#include "transform_snap.h"
+#include "transform_mode.h"
+
+/* -------------------------------------------------------------------- */
+/* Transform (Translation) */
+
+/** \name Transform Translation
+ * \{ */
+
+static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR])
+{
+ size_t ofs = 0;
+ char tvec[NUM_STR_REP_LEN * 3];
+ char distvec[NUM_STR_REP_LEN];
+ char autoik[NUM_STR_REP_LEN];
+ float dist;
+
+ if (hasNumInput(&t->num)) {
+ outputNumInput(&(t->num), tvec, &t->scene->unit);
+ dist = len_v3(t->num.val);
+ }
+ else {
+ float dvec[3];
+
+ copy_v3_v3(dvec, vec);
+ applyAspectRatio(t, dvec);
+
+ dist = len_v3(vec);
+ if (!(t->flag & T_2D_EDIT) && t->scene->unit.system) {
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ bUnit_AsString2(&tvec[NUM_STR_REP_LEN * i],
+ NUM_STR_REP_LEN,
+ dvec[i] * t->scene->unit.scale_length,
+ 4,
+ B_UNIT_LENGTH,
+ &t->scene->unit,
+ true);
+ }
+ }
+ else {
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", dvec[0]);
+ BLI_snprintf(&tvec[NUM_STR_REP_LEN], NUM_STR_REP_LEN, "%.4f", dvec[1]);
+ BLI_snprintf(&tvec[NUM_STR_REP_LEN * 2], NUM_STR_REP_LEN, "%.4f", dvec[2]);
+ }
+ }
+
+ if (!(t->flag & T_2D_EDIT) && t->scene->unit.system) {
+ bUnit_AsString2(distvec,
+ sizeof(distvec),
+ dist * t->scene->unit.scale_length,
+ 4,
+ B_UNIT_LENGTH,
+ &t->scene->unit,
+ false);
+ }
+ else if (dist > 1e10f || dist < -1e10f) {
+ /* prevent string buffer overflow */
+ BLI_snprintf(distvec, NUM_STR_REP_LEN, "%.4e", dist);
+ }
+ else {
+ BLI_snprintf(distvec, NUM_STR_REP_LEN, "%.4f", dist);
+ }
+
+ if (t->flag & T_AUTOIK) {
+ short chainlen = t->settings->autoik_chainlen;
+
+ if (chainlen) {
+ BLI_snprintf(autoik, NUM_STR_REP_LEN, TIP_("AutoIK-Len: %d"), chainlen);
+ }
+ else {
+ autoik[0] = '\0';
+ }
+ }
+ else {
+ autoik[0] = '\0';
+ }
+
+ if (t->con.mode & CON_APPLY) {
+ switch (t->num.idx_max) {
+ case 0:
+ ofs += BLI_snprintf(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ "D: %s (%s)%s %s %s",
+ &tvec[0],
+ distvec,
+ t->con.text,
+ t->proptext,
+ autoik);
+ break;
+ case 1:
+ ofs += BLI_snprintf(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ "D: %s D: %s (%s)%s %s %s",
+ &tvec[0],
+ &tvec[NUM_STR_REP_LEN],
+ distvec,
+ t->con.text,
+ t->proptext,
+ autoik);
+ break;
+ case 2:
+ ofs += BLI_snprintf(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ "D: %s D: %s D: %s (%s)%s %s %s",
+ &tvec[0],
+ &tvec[NUM_STR_REP_LEN],
+ &tvec[NUM_STR_REP_LEN * 2],
+ distvec,
+ t->con.text,
+ t->proptext,
+ autoik);
+ break;
+ }
+ }
+ else {
+ if (t->flag & T_2D_EDIT) {
+ ofs += BLI_snprintf(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ "Dx: %s Dy: %s (%s)%s %s",
+ &tvec[0],
+ &tvec[NUM_STR_REP_LEN],
+ distvec,
+ t->con.text,
+ t->proptext);
+ }
+ else {
+ ofs += BLI_snprintf(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ "Dx: %s Dy: %s Dz: %s (%s)%s %s %s",
+ &tvec[0],
+ &tvec[NUM_STR_REP_LEN],
+ &tvec[NUM_STR_REP_LEN * 2],
+ distvec,
+ t->con.text,
+ t->proptext,
+ autoik);
+ }
+ }
+
+ if (t->flag & T_PROP_EDIT_ALL) {
+ ofs += BLI_snprintf(
+ str + ofs, UI_MAX_DRAW_STR - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
+ }
+
+ if (t->spacetype == SPACE_NODE) {
+ SpaceNode *snode = (SpaceNode *)t->sa->spacedata.first;
+
+ if ((snode->flag & SNODE_SKIP_INSOFFSET) == 0) {
+ const char *str_old = BLI_strdup(str);
+ const char *str_dir = (snode->insert_ofs_dir == SNODE_INSERTOFS_DIR_RIGHT) ? TIP_("right") :
+ TIP_("left");
+ char str_km[64];
+
+ WM_modalkeymap_items_to_string(
+ t->keymap, TFM_MODAL_INSERTOFS_TOGGLE_DIR, true, str_km, sizeof(str_km));
+
+ ofs += BLI_snprintf(str,
+ UI_MAX_DRAW_STR,
+ TIP_("Auto-offset set to %s - press %s to toggle direction | %s"),
+ str_dir,
+ str_km,
+ str_old);
+
+ MEM_freeN((void *)str_old);
+ }
+ }
+}
+
+static void applyTranslationValue(TransInfo *t, const float vec[3])
+{
+ const bool apply_snap_align_rotation = usingSnappingNormal(
+ t); // && (t->tsnap.status & POINT_INIT);
+ float tvec[3];
+
+ /* The ideal would be "apply_snap_align_rotation" only when a snap point is found
+ * so, maybe inside this function is not the best place to apply this rotation.
+ * but you need "handle snapping rotation before doing the translation" (really?) */
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+
+ float pivot[3];
+ if (apply_snap_align_rotation) {
+ copy_v3_v3(pivot, t->tsnap.snapTarget);
+ /* The pivot has to be in local-space (see T49494) */
+ if (tc->use_local_mat) {
+ mul_m4_v3(tc->imat, pivot);
+ }
+ }
+
+ TransData *td = tc->data;
+ for (int i = 0; i < tc->data_len; i++, td++) {
+ if (td->flag & TD_NOACTION) {
+ break;
+ }
+
+ if (td->flag & TD_SKIP) {
+ continue;
+ }
+
+ float rotate_offset[3] = {0};
+ bool use_rotate_offset = false;
+
+ /* handle snapping rotation before doing the translation */
+ if (apply_snap_align_rotation) {
+ float mat[3][3];
+
+ if (validSnappingNormal(t)) {
+ const float *original_normal;
+
+ /* In pose mode, we want to align normals with Y axis of bones... */
+ if (t->flag & T_POSE) {
+ original_normal = td->axismtx[1];
+ }
+ else {
+ original_normal = td->axismtx[2];
+ }
+
+ rotation_between_vecs_to_mat3(mat, original_normal, t->tsnap.snapNormal);
+ }
+ else {
+ unit_m3(mat);
+ }
+
+ ElementRotation_ex(t, tc, td, mat, pivot);
+
+ if (td->loc) {
+ use_rotate_offset = true;
+ sub_v3_v3v3(rotate_offset, td->loc, td->iloc);
+ }
+ }
+
+ if (t->con.applyVec) {
+ float pvec[3];
+ t->con.applyVec(t, tc, td, vec, tvec, pvec);
+ }
+ else {
+ copy_v3_v3(tvec, vec);
+ }
+
+ mul_m3_v3(td->smtx, tvec);
+
+ if (use_rotate_offset) {
+ add_v3_v3(tvec, rotate_offset);
+ }
+
+ if (t->options & CTX_GPENCIL_STROKES) {
+ /* grease pencil multiframe falloff */
+ bGPDstroke *gps = (bGPDstroke *)td->extra;
+ if (gps != NULL) {
+ mul_v3_fl(tvec, td->factor * gps->runtime.multi_frame_falloff);
+ }
+ else {
+ mul_v3_fl(tvec, td->factor);
+ }
+ }
+ else {
+ /* proportional editing falloff */
+ mul_v3_fl(tvec, td->factor);
+ }
+
+ protectedTransBits(td->protectflag, tvec);
+
+ if (td->loc) {
+ add_v3_v3v3(td->loc, td->iloc, tvec);
+ }
+
+ constraintTransLim(t, td);
+ }
+ }
+}
+
+static void applyTranslation(TransInfo *t, const int UNUSED(mval[2]))
+{
+ char str[UI_MAX_DRAW_STR];
+ float values_final[3];
+
+ if (t->flag & T_INPUT_IS_VALUES_FINAL) {
+ copy_v3_v3(t->values_final, t->values);
+ }
+ else {
+ copy_v3_v3(t->values_final, t->values);
+ if ((t->con.mode & CON_APPLY) == 0) {
+ snapGridIncrement(t, t->values_final);
+ }
+
+ if (applyNumInput(&t->num, t->values_final)) {
+ removeAspectRatio(t, t->values_final);
+ }
+
+ applySnapping(t, t->values_final);
+ }
+ copy_v3_v3(values_final, t->values_final);
+
+ if (t->con.mode & CON_APPLY) {
+ float pvec[3] = {0.0f, 0.0f, 0.0f};
+ t->con.applyVec(t, NULL, NULL, t->values_final, values_final, pvec);
+ headerTranslation(t, pvec, str);
+
+ /* only so we have re-usable value with redo, see T46741. */
+ mul_v3_m3v3(t->values_final, t->con.imtx, values_final);
+ }
+ else {
+ headerTranslation(t, t->values_final, str);
+ copy_v3_v3(values_final, t->values_final);
+ }
+
+ /* don't use 't->values' now on */
+
+ applyTranslationValue(t, values_final);
+
+ /* evil hack - redo translation if clipping needed */
+ if (t->flag & T_CLIP_UV && clipUVTransform(t, values_final, 0)) {
+ applyTranslationValue(t, values_final);
+
+ /* In proportional edit it can happen that */
+ /* vertices in the radius of the brush end */
+ /* outside the clipping area */
+ /* XXX HACK - dg */
+ if (t->flag & T_PROP_EDIT_ALL) {
+ clipUVData(t);
+ }
+ }
+
+ recalcData(t);
+
+ ED_area_status_text(t->sa, str);
+}
+
+void initTranslation(TransInfo *t)
+{
+ if (t->spacetype == SPACE_ACTION) {
+ /* this space uses time translate */
+ BKE_report(t->reports,
+ RPT_ERROR,
+ "Use 'Time_Translate' transform mode instead of 'Translation' mode "
+ "for translating keyframes in Dope Sheet Editor");
+ t->state = TRANS_CANCEL;
+ }
+
+ t->mode = TFM_TRANSLATION;
+ t->transform = applyTranslation;
+
+ initMouseInputMode(t, &t->mouse, INPUT_VECTOR);
+
+ t->idx_max = (t->flag & T_2D_EDIT) ? 1 : 2;
+ t->num.flag = 0;
+ t->num.idx_max = t->idx_max;
+
+ copy_v3_v3(t->snap, t->snap_spatial);
+
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ if (t->spacetype == SPACE_VIEW3D) {
+ /* Handling units makes only sense in 3Dview... See T38877. */
+ t->num.unit_type[0] = B_UNIT_LENGTH;
+ t->num.unit_type[1] = B_UNIT_LENGTH;
+ t->num.unit_type[2] = B_UNIT_LENGTH;
+ }
+ else {
+ /* SPACE_GRAPH, SPACE_ACTION, etc. could use some time units, when we have them... */
+ t->num.unit_type[0] = B_UNIT_NONE;
+ t->num.unit_type[1] = B_UNIT_NONE;
+ t->num.unit_type[2] = B_UNIT_NONE;
+ }
+}
+/** \} */