Cleanup: Split transform.c in multiple files

Differential Revision: https://developer.blender.org/D5819
This commit is contained in:
2020-02-14 08:42:17 -03:00
parent 897f943ca0
commit e277e8d085
37 changed files with 8129 additions and 6786 deletions

View File

@@ -67,12 +67,44 @@ set(SRC
transform_input.c
transform_ops.c
transform_orientations.c
transform_mode.c
transform_mode_align.c
transform_mode_baketime.c
transform_mode_bend.c
transform_mode_boneenvelope.c
transform_mode_boneroll.c
transform_mode_bonesize.c
transform_mode_curveshrinkfatten.c
transform_mode_edge_bevelweight.c
transform_mode_edge_crease.c
transform_mode_edge_rotate_normal.c
transform_mode_edge_seq_slide.c
transform_mode_edge_slide.c
transform_mode_gpopacity.c
transform_mode_gpshrinkfatten.c
transform_mode_maskshrinkfatten.c
transform_mode_mirror.c
transform_mode_push_pull.c
transform_mode_resize.c
transform_mode_rotate.c
transform_mode_shear.c
transform_mode_shrink_fatten.c
transform_mode_skin_resize.c
transform_mode_tilt.c
transform_mode_timescale.c
transform_mode_timeslide.c
transform_mode_timetranslate.c
transform_mode_tosphere.c
transform_mode_trackball.c
transform_mode_translate.c
transform_mode_vert_slide.c
transform_snap.c
transform_snap_object.c
transform.h
transform_convert.h
transform_draw_cursors.h
transform_mode.h
transform_snap.h
)

File diff suppressed because it is too large Load Diff

View File

@@ -875,6 +875,43 @@ enum {
MULTI_POINTS = 1 << 3,
};
/** keymap modal items */
/* NOTE: these values are saved in keymap files, do not change then but just add new ones. */
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 */
TFM_MODAL_PROPSIZE = 26,
/* node editor insert offset (aka auto-offset) direction toggle */
TFM_MODAL_INSERTOFS_TOGGLE_DIR = 27,
};
/* Hard min/max for proportional size. */
#define T_PROP_SIZE_MIN 1e-6f
#define T_PROP_SIZE_MAX 1e12f
@@ -1052,12 +1089,6 @@ int getTransformOrientation(const struct bContext *C, float normal[3], float pla
void freeCustomNormalArray(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data);
void freeEdgeSlideVerts(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data);
void projectEdgeSlideData(TransInfo *t, bool is_final);
void freeVertSlideVerts(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data);
void projectVertSlideData(TransInfo *t, bool is_final);
/* TODO. transform_query.c */
bool checkUseAxisMatrix(TransInfo *t);

View File

@@ -79,6 +79,7 @@
#include "transform.h"
#include "transform_convert.h"
#include "transform_mode.h"
/**
* Transforming around ourselves is no use, fallback to individual origins,

View File

@@ -112,6 +112,7 @@
#include "transform.h"
#include "transform_convert.h"
#include "transform_mode.h"
#include "transform_snap.h"
/* ************************** Functions *************************** */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,150 @@
/*
* 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
* \brief transform modes used by different operators.
*/
#ifndef __TRANSFORM_MODE_H__
#define __TRANSFORM_MODE_H__
struct AnimData;
struct TransInfo;
struct TransDataContainer;
struct TransData;
/* transform_mode.c */
bool transdata_check_local_center(TransInfo *t, short around);
void protectedTransBits(short protectflag, float vec[3]);
void constraintTransLim(TransInfo *t, TransData *td);
void postInputRotation(TransInfo *t, float values[3]);
void headerRotation(TransInfo *t, char *str, float final);
void ElementRotation_ex(TransInfo *t,
TransDataContainer *tc,
TransData *td,
const float mat[3][3],
const float *center);
void ElementRotation(
TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3], const short around);
void headerResize(TransInfo *t, const float vec[3], char *str);
void ElementResize(TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3]);
short getAnimEdit_SnapMode(TransInfo *t);
void doAnimEdit_SnapFrame(
TransInfo *t, TransData *td, TransData2D *td2d, struct AnimData *adt, short autosnap);
/* transform_mode_align.c */
void initAlign(TransInfo *t);
/* transform_mode_baketime.c */
void initBakeTime(TransInfo *t);
/* transform_mode_bend.c */
void initBend(TransInfo *t);
/* transform_mode_boneenvelope.c */
void initBoneEnvelope(TransInfo *t);
/* transform_mode_boneroll.c */
void initBoneRoll(TransInfo *t);
/* transform_mode_bonesize.c */
void initBoneSize(TransInfo *t);
/* transform_mode_curveshrinkfatten.c */
void initCurveShrinkFatten(TransInfo *t);
/* transform_mode_edge_bevelweight.c */
void initBevelWeight(TransInfo *t);
/* transform_mode_edge_crease.c */
void initCrease(TransInfo *t);
/* transform_mode_edge_rotate_normal.c */
void initNormalRotation(TransInfo *t);
/* transform_mode_edge_seq_slide.c */
void initSeqSlide(TransInfo *t);
/* transform_mode_edge_slide.c */
void projectEdgeSlideData(TransInfo *t, bool is_final);
void drawEdgeSlide(TransInfo *t);
void doEdgeSlide(TransInfo *t, float perc);
void initEdgeSlide_ex(
TransInfo *t, bool use_double_side, bool use_even, bool flipped, bool use_clamp);
void initEdgeSlide(TransInfo *t);
/* transform_mode_gpopacity.c */
void initGPOpacity(TransInfo *t);
/* transform_mode_gpshrinkfatten.c */
void initGPShrinkFatten(TransInfo *t);
/* transform_mode_maskshrinkfatten.c */
void initMaskShrinkFatten(TransInfo *t);
/* transform_mode_mirror.c */
void initMirror(TransInfo *t);
/* transform_mode_push_pull.c */
void initPushPull(TransInfo *t);
/* transform_mode_resize.c */
void initResize(TransInfo *t);
/* transform_mode_rotate.c */
void initRotation(TransInfo *t);
/* transform_mode_shear.c */
void initShear(TransInfo *t);
/* transform_mode_shrink_fatten.c */
void initShrinkFatten(TransInfo *t);
/* transform_mode_skin_resize.c */
void initSkinResize(TransInfo *t);
/* transform_mode_tilt.c */
void initTilt(TransInfo *t);
/* transform_mode_timescale.c */
void initTimeScale(TransInfo *t);
/* transform_mode_timeslide.c */
void initTimeSlide(TransInfo *t);
/* transform_mode_timetranslate.c */
void initTimeTranslate(TransInfo *t);
/* transform_mode_tosphere.c */
void initToSphere(TransInfo *t);
/* transform_mode_trackball.c */
void initTrackball(TransInfo *t);
/* transform_mode_translate.c */
void initTranslation(TransInfo *t);
/* transform_mode_vert_slide.c */
void projectVertSlideData(TransInfo *t, bool is_final);
void drawVertSlide(TransInfo *t);
void doVertSlide(TransInfo *t, float perc);
void initVertSlide_ex(TransInfo *t, bool use_even, bool flipped, bool use_clamp);
void initVertSlide(TransInfo *t);
#endif

View File

@@ -0,0 +1,96 @@
/*
* 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 "BLI_math.h"
#include "BKE_context.h"
#include "ED_screen.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Align) */
/** \name Transform Align
* \{ */
static void applyAlign(TransInfo *t, const int UNUSED(mval[2]))
{
float center[3];
int i;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
/* saving original center */
copy_v3_v3(center, tc->center_local);
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
float mat[3][3], invmat[3][3];
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
/* around local centers */
if (t->flag & (T_OBJECT | T_POSE)) {
copy_v3_v3(tc->center_local, td->center);
}
else {
if (t->settings->selectmode & SCE_SELECT_FACE) {
copy_v3_v3(tc->center_local, td->center);
}
}
invert_m3_m3(invmat, td->axismtx);
mul_m3_m3m3(mat, t->spacemtx, invmat);
ElementRotation(t, tc, td, mat, t->around);
}
/* restoring original center */
copy_v3_v3(tc->center_local, center);
}
recalcData(t);
ED_area_status_text(t->sa, TIP_("Align"));
}
void initAlign(TransInfo *t)
{
t->flag |= T_NO_CONSTRAINT;
t->transform = applyAlign;
initMouseInputMode(t, &t->mouse, INPUT_NONE);
}
/** \} */

View File

@@ -0,0 +1,140 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Bake-Time) */
/** \name Transform Bake-Time
* \{ */
static void applyBakeTime(TransInfo *t, const int mval[2])
{
float time;
int i;
char str[UI_MAX_DRAW_STR];
float fac = 0.1f;
/* XXX, disable precision for now,
* this isn't even accessible by the user */
#if 0
if (t->mouse.precision) {
/* calculate ratio for shiftkey pos, and for total, and blend these for precision */
time = (float)(t->center2d[0] - t->mouse.precision_mval[0]) * fac;
time += 0.1f * ((float)(t->center2d[0] * fac - mval[0]) - time);
}
else
#endif
{
time = (float)(t->center2d[0] - mval[0]) * fac;
}
snapGridIncrement(t, &time);
applyNumInput(&t->num, &time);
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, &t->scene->unit);
if (time >= 0.0f) {
BLI_snprintf(str, sizeof(str), TIP_("Time: +%s %s"), c, t->proptext);
}
else {
BLI_snprintf(str, sizeof(str), TIP_("Time: %s %s"), c, t->proptext);
}
}
else {
/* default header print */
if (time >= 0.0f) {
BLI_snprintf(str, sizeof(str), TIP_("Time: +%.3f %s"), time, t->proptext);
}
else {
BLI_snprintf(str, sizeof(str), TIP_("Time: %.3f %s"), time, t->proptext);
}
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
if (td->val) {
*td->val = td->ival + time * td->factor;
if (td->ext->size && *td->val < *td->ext->size) {
*td->val = *td->ext->size;
}
if (td->ext->quat && *td->val > *td->ext->quat) {
*td->val = *td->ext->quat;
}
}
}
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initBakeTime(TransInfo *t)
{
t->transform = applyBakeTime;
initMouseInputMode(t, &t->mouse, INPUT_NONE);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE; /* Don't think this uses units? */
}
/** \} */

View File

@@ -0,0 +1,307 @@
/*
* 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_unit.h"
#include "ED_screen.h"
#include "WM_api.h"
#include "WM_types.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Bend) */
/** \name Transform Bend
* \{ */
struct BendCustomData {
/* All values are in global space. */
float warp_sta[3];
float warp_end[3];
float warp_nor[3];
float warp_tan[3];
/* for applying the mouse distance */
float warp_init_dist;
};
static eRedrawFlag handleEventBend(TransInfo *UNUSED(t), const wmEvent *event)
{
eRedrawFlag status = TREDRAW_NOTHING;
if (event->type == MIDDLEMOUSE && event->val == KM_PRESS) {
status = TREDRAW_HARD;
}
return status;
}
static void Bend(TransInfo *t, const int UNUSED(mval[2]))
{
float vec[3];
float pivot_global[3];
float warp_end_radius_global[3];
int i;
char str[UI_MAX_DRAW_STR];
const struct BendCustomData *data = t->custom.mode.data;
const bool is_clamp = (t->flag & T_ALT_TRANSFORM) == 0;
union {
struct {
float angle, scale;
};
float vector[2];
} values;
/* amount of radians for bend */
copy_v2_v2(values.vector, t->values);
#if 0
snapGrid(t, angle_rad);
#else
/* hrmf, snapping radius is using 'angle' steps, need to convert to something else
* this isnt essential but nicer to give reasonable snapping values for radius */
if (t->tsnap.mode & SCE_SNAP_MODE_INCREMENT) {
const float radius_snap = 0.1f;
const float snap_hack = (t->snap[1] * data->warp_init_dist) / radius_snap;
values.scale *= snap_hack;
snapGridIncrement(t, values.vector);
values.scale /= snap_hack;
}
#endif
if (applyNumInput(&t->num, values.vector)) {
values.scale = values.scale / data->warp_init_dist;
}
copy_v2_v2(t->values_final, values.vector);
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN * 2];
outputNumInput(&(t->num), c, &t->scene->unit);
BLI_snprintf(str,
sizeof(str),
TIP_("Bend Angle: %s Radius: %s Alt, Clamp %s"),
&c[0],
&c[NUM_STR_REP_LEN],
WM_bool_as_string(is_clamp));
}
else {
/* default header print */
BLI_snprintf(str,
sizeof(str),
TIP_("Bend Angle: %.3f Radius: %.4f, Alt, Clamp %s"),
RAD2DEGF(values.angle),
values.scale * data->warp_init_dist,
WM_bool_as_string(is_clamp));
}
values.angle *= -1.0f;
values.scale *= data->warp_init_dist;
/* calc 'data->warp_end' from 'data->warp_end_init' */
copy_v3_v3(warp_end_radius_global, data->warp_end);
dist_ensure_v3_v3fl(warp_end_radius_global, data->warp_sta, values.scale);
/* done */
/* calculate pivot */
copy_v3_v3(pivot_global, data->warp_sta);
if (values.angle > 0.0f) {
madd_v3_v3fl(pivot_global,
data->warp_tan,
-values.scale * shell_angle_to_dist((float)M_PI_2 - values.angle));
}
else {
madd_v3_v3fl(pivot_global,
data->warp_tan,
+values.scale * shell_angle_to_dist((float)M_PI_2 + values.angle));
}
/* TODO(campbell): xform, compensate object center. */
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
float warp_sta_local[3];
float warp_end_local[3];
float warp_end_radius_local[3];
float pivot_local[3];
if (tc->use_local_mat) {
sub_v3_v3v3(warp_sta_local, data->warp_sta, tc->mat[3]);
sub_v3_v3v3(warp_end_local, data->warp_end, tc->mat[3]);
sub_v3_v3v3(warp_end_radius_local, warp_end_radius_global, tc->mat[3]);
sub_v3_v3v3(pivot_local, pivot_global, tc->mat[3]);
}
else {
copy_v3_v3(warp_sta_local, data->warp_sta);
copy_v3_v3(warp_end_local, data->warp_end);
copy_v3_v3(warp_end_radius_local, warp_end_radius_global);
copy_v3_v3(pivot_local, pivot_global);
}
for (i = 0; i < tc->data_len; i++, td++) {
float mat[3][3];
float delta[3];
float fac, fac_scaled;
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
if (UNLIKELY(values.angle == 0.0f)) {
copy_v3_v3(td->loc, td->iloc);
continue;
}
copy_v3_v3(vec, td->iloc);
mul_m3_v3(td->mtx, vec);
fac = line_point_factor_v3(vec, warp_sta_local, warp_end_radius_local);
if (is_clamp) {
CLAMP(fac, 0.0f, 1.0f);
}
if (t->options & CTX_GPENCIL_STROKES) {
/* grease pencil multiframe falloff */
bGPDstroke *gps = (bGPDstroke *)td->extra;
if (gps != NULL) {
fac_scaled = fac * td->factor * gps->runtime.multi_frame_falloff;
}
else {
fac_scaled = fac * td->factor;
}
}
else {
fac_scaled = fac * td->factor;
}
axis_angle_normalized_to_mat3(mat, data->warp_nor, values.angle * fac_scaled);
interp_v3_v3v3(delta, warp_sta_local, warp_end_radius_local, fac_scaled);
sub_v3_v3(delta, warp_sta_local);
/* delta is subtracted, rotation adds back this offset */
sub_v3_v3(vec, delta);
sub_v3_v3(vec, pivot_local);
mul_m3_v3(mat, vec);
add_v3_v3(vec, pivot_local);
mul_m3_v3(td->smtx, vec);
/* rotation */
if ((t->flag & T_POINTS) == 0) {
ElementRotation(t, tc, td, mat, V3D_AROUND_LOCAL_ORIGINS);
}
/* location */
copy_v3_v3(td->loc, vec);
}
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initBend(TransInfo *t)
{
const float mval_fl[2] = {UNPACK2(t->mval)};
const float *curs;
float tvec[3];
struct BendCustomData *data;
t->mode = TFM_BEND;
t->transform = Bend;
t->handleEvent = handleEventBend;
setInputPostFct(&t->mouse, postInputRotation);
initMouseInputMode(t, &t->mouse, INPUT_ANGLE_SPRING);
t->idx_max = 1;
t->num.idx_max = 1;
t->snap[0] = 0.0f;
t->snap[1] = SNAP_INCREMENTAL_ANGLE;
t->snap[2] = t->snap[1] * 0.2;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_use_radians = (t->scene->unit.system_rotation == USER_UNIT_ROT_RADIANS);
t->num.unit_type[0] = B_UNIT_ROTATION;
t->num.unit_type[1] = B_UNIT_LENGTH;
t->flag |= T_NO_CONSTRAINT;
// copy_v3_v3(t->center, ED_view3d_cursor3d_get(t->scene, t->view));
if ((t->flag & T_OVERRIDE_CENTER) == 0) {
calculateCenterCursor(t, t->center_global);
}
calculateCenterLocal(t, t->center_global);
t->val = 0.0f;
data = MEM_callocN(sizeof(*data), __func__);
curs = t->scene->cursor.location;
copy_v3_v3(data->warp_sta, curs);
ED_view3d_win_to_3d((View3D *)t->sa->spacedata.first, t->ar, curs, mval_fl, data->warp_end);
copy_v3_v3(data->warp_nor, t->viewinv[2]);
normalize_v3(data->warp_nor);
/* tangent */
sub_v3_v3v3(tvec, data->warp_end, data->warp_sta);
cross_v3_v3v3(data->warp_tan, tvec, data->warp_nor);
normalize_v3(data->warp_tan);
data->warp_init_dist = len_v3v3(data->warp_end, data->warp_sta);
t->custom.mode.data = data;
t->custom.mode.use_free = true;
}
/** \} */

View File

@@ -0,0 +1,121 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Bone Envelope) */
/** \name Transform Bone Envelope
* \{ */
static void applyBoneEnvelope(TransInfo *t, const int UNUSED(mval[2]))
{
float ratio;
int i;
char str[UI_MAX_DRAW_STR];
ratio = t->values[0];
snapGridIncrement(t, &ratio);
applyNumInput(&t->num, &ratio);
t->values_final[0] = ratio;
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, &t->scene->unit);
BLI_snprintf(str, sizeof(str), TIP_("Envelope: %s"), c);
}
else {
BLI_snprintf(str, sizeof(str), TIP_("Envelope: %3f"), ratio);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
if (td->val) {
/* if the old/original value was 0.0f, then just use ratio */
if (td->ival) {
*td->val = td->ival * ratio;
}
else {
*td->val = ratio;
}
}
}
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initBoneEnvelope(TransInfo *t)
{
t->mode = TFM_BONE_ENVELOPE;
t->transform = applyBoneEnvelope;
initMouseInputMode(t, &t->mouse, INPUT_SPRING);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE;
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
/** \} */

View File

@@ -0,0 +1,115 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (EditBone Roll) */
/** \name Transform EditBone Roll
* \{ */
static void applyBoneRoll(TransInfo *t, const int UNUSED(mval[2]))
{
int i;
char str[UI_MAX_DRAW_STR];
float final;
final = t->values[0];
snapGridIncrement(t, &final);
applyNumInput(&t->num, &final);
t->values_final[0] = final;
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, &t->scene->unit);
BLI_snprintf(str, sizeof(str), TIP_("Roll: %s"), &c[0]);
}
else {
BLI_snprintf(str, sizeof(str), TIP_("Roll: %.2f"), RAD2DEGF(final));
}
/* set roll values */
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
*(td->val) = td->ival - final;
}
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initBoneRoll(TransInfo *t)
{
t->mode = TFM_BONE_ROLL;
t->transform = applyBoneRoll;
initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = DEG2RAD(5.0);
t->snap[2] = DEG2RAD(1.0);
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_use_radians = (t->scene->unit.system_rotation == USER_UNIT_ROT_RADIANS);
t->num.unit_type[0] = B_UNIT_ROTATION;
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
/** \} */

View File

@@ -0,0 +1,179 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (EditBone (B-bone) width scaling) */
/** \name Transform B-bone width scaling
* \{ */
static void headerBoneSize(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR])
{
char tvec[NUM_STR_REP_LEN * 3];
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec, &t->scene->unit);
}
else {
BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", vec[0]);
BLI_snprintf(&tvec[NUM_STR_REP_LEN], NUM_STR_REP_LEN, "%.4f", vec[1]);
BLI_snprintf(&tvec[NUM_STR_REP_LEN * 2], NUM_STR_REP_LEN, "%.4f", vec[2]);
}
/* hmm... perhaps the y-axis values don't need to be shown? */
if (t->con.mode & CON_APPLY) {
if (t->num.idx_max == 0) {
BLI_snprintf(
str, UI_MAX_DRAW_STR, TIP_("ScaleB: %s%s %s"), &tvec[0], t->con.text, t->proptext);
}
else {
BLI_snprintf(str,
UI_MAX_DRAW_STR,
TIP_("ScaleB: %s : %s : %s%s %s"),
&tvec[0],
&tvec[NUM_STR_REP_LEN],
&tvec[NUM_STR_REP_LEN * 2],
t->con.text,
t->proptext);
}
}
else {
BLI_snprintf(str,
UI_MAX_DRAW_STR,
TIP_("ScaleB X: %s Y: %s Z: %s%s %s"),
&tvec[0],
&tvec[NUM_STR_REP_LEN],
&tvec[NUM_STR_REP_LEN * 2],
t->con.text,
t->proptext);
}
}
static void ElementBoneSize(TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3])
{
float tmat[3][3], smat[3][3], oldy;
float sizemat[3][3];
mul_m3_m3m3(smat, mat, td->mtx);
mul_m3_m3m3(tmat, td->smtx, smat);
if (t->con.applySize) {
t->con.applySize(t, tc, td, tmat);
}
/* we've tucked the scale in loc */
oldy = td->iloc[1];
size_to_mat3(sizemat, td->iloc);
mul_m3_m3m3(tmat, tmat, sizemat);
mat3_to_size(td->loc, tmat);
td->loc[1] = oldy;
}
static void applyBoneSize(TransInfo *t, const int UNUSED(mval[2]))
{
float size[3], mat[3][3];
float ratio = t->values[0];
int i;
char str[UI_MAX_DRAW_STR];
copy_v3_fl(size, ratio);
snapGridIncrement(t, size);
if (applyNumInput(&t->num, size)) {
constraintNumInput(t, size);
}
copy_v3_v3(t->values_final, size);
size_to_mat3(mat, size);
if (t->con.applySize) {
t->con.applySize(t, NULL, NULL, mat);
}
copy_m3_m3(t->mat, mat); // used in gizmo
headerBoneSize(t, size, str);
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
ElementBoneSize(t, tc, td, mat);
}
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initBoneSize(TransInfo *t)
{
t->mode = TFM_BONESIZE;
t->transform = applyBoneSize;
initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
t->idx_max = 2;
t->num.idx_max = 2;
t->num.val_flag[0] |= NUM_NULL_ONE;
t->num.val_flag[1] |= NUM_NULL_ONE;
t->num.val_flag[2] |= NUM_NULL_ONE;
t->num.flag |= NUM_AFFECT_ALL;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE;
t->num.unit_type[1] = B_UNIT_NONE;
t->num.unit_type[2] = B_UNIT_NONE;
}
/** \} */

View File

@@ -0,0 +1,124 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Curve Shrink/Fatten) */
/** \name Transform Curve Shrink/Fatten
* \{ */
static void applyCurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
{
float ratio;
int i;
char str[UI_MAX_DRAW_STR];
ratio = t->values[0];
snapGridIncrement(t, &ratio);
applyNumInput(&t->num, &ratio);
t->values_final[0] = ratio;
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, &t->scene->unit);
BLI_snprintf(str, sizeof(str), TIP_("Shrink/Fatten: %s"), c);
}
else {
BLI_snprintf(str, sizeof(str), TIP_("Shrink/Fatten: %3f"), ratio);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
if (td->val) {
*td->val = td->ival * ratio;
/* apply PET */
*td->val = (*td->val * td->factor) + ((1.0f - td->factor) * td->ival);
if (*td->val <= 0.0f) {
*td->val = 0.001f;
}
}
}
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initCurveShrinkFatten(TransInfo *t)
{
t->mode = TFM_CURVE_SHRINKFATTEN;
t->transform = applyCurveShrinkFatten;
initMouseInputMode(t, &t->mouse, INPUT_SPRING);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE;
t->flag |= T_NO_ZERO;
#ifdef USE_NUM_NO_ZERO
t->num.val_flag[0] |= NUM_NO_ZERO;
#endif
t->flag |= T_NO_CONSTRAINT;
}
/** \} */

View File

@@ -0,0 +1,130 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Bevel Weight) */
/** \name Transform Bevel Weight
* \{ */
static void applyBevelWeight(TransInfo *t, const int UNUSED(mval[2]))
{
float weight;
int i;
char str[UI_MAX_DRAW_STR];
weight = t->values[0];
CLAMP_MAX(weight, 1.0f);
snapGridIncrement(t, &weight);
applyNumInput(&t->num, &weight);
t->values_final[0] = weight;
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, &t->scene->unit);
if (weight >= 0.0f) {
BLI_snprintf(str, sizeof(str), TIP_("Bevel Weight: +%s %s"), c, t->proptext);
}
else {
BLI_snprintf(str, sizeof(str), TIP_("Bevel Weight: %s %s"), c, t->proptext);
}
}
else {
/* default header print */
if (weight >= 0.0f) {
BLI_snprintf(str, sizeof(str), TIP_("Bevel Weight: +%.3f %s"), weight, t->proptext);
}
else {
BLI_snprintf(str, sizeof(str), TIP_("Bevel Weight: %.3f %s"), weight, t->proptext);
}
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->val) {
*td->val = td->ival + weight * td->factor;
if (*td->val < 0.0f) {
*td->val = 0.0f;
}
if (*td->val > 1.0f) {
*td->val = 1.0f;
}
}
}
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initBevelWeight(TransInfo *t)
{
t->mode = TFM_BWEIGHT;
t->transform = applyBevelWeight;
initMouseInputMode(t, &t->mouse, INPUT_SPRING_DELTA);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE;
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
/** \} */

View File

@@ -0,0 +1,134 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Crease) */
/** \name Transform Crease
* \{ */
static void applyCrease(TransInfo *t, const int UNUSED(mval[2]))
{
float crease;
int i;
char str[UI_MAX_DRAW_STR];
crease = t->values[0];
CLAMP_MAX(crease, 1.0f);
snapGridIncrement(t, &crease);
applyNumInput(&t->num, &crease);
t->values_final[0] = crease;
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, &t->scene->unit);
if (crease >= 0.0f) {
BLI_snprintf(str, sizeof(str), TIP_("Crease: +%s %s"), c, t->proptext);
}
else {
BLI_snprintf(str, sizeof(str), TIP_("Crease: %s %s"), c, t->proptext);
}
}
else {
/* default header print */
if (crease >= 0.0f) {
BLI_snprintf(str, sizeof(str), TIP_("Crease: +%.3f %s"), crease, t->proptext);
}
else {
BLI_snprintf(str, sizeof(str), TIP_("Crease: %.3f %s"), crease, t->proptext);
}
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
if (td->val) {
*td->val = td->ival + crease * td->factor;
if (*td->val < 0.0f) {
*td->val = 0.0f;
}
if (*td->val > 1.0f) {
*td->val = 1.0f;
}
}
}
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initCrease(TransInfo *t)
{
t->mode = TFM_CREASE;
t->transform = applyCrease;
initMouseInputMode(t, &t->mouse, INPUT_SPRING_DELTA);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE;
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
/** \} */

View File

@@ -0,0 +1,156 @@
/*
* 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 "BLI_math.h"
#include "BKE_editmesh.h"
#include "BKE_context.h"
#include "BKE_mesh.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Normal Rotation) */
/** \name Transform Normal Rotation
* \{ */
static void storeCustomLNorValue(TransDataContainer *tc, BMesh *bm)
{
BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm, false);
// BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
tc->custom.mode.data = lnors_ed_arr;
tc->custom.mode.free_cb = freeCustomNormalArray;
}
void freeCustomNormalArray(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data)
{
BMLoopNorEditDataArray *lnors_ed_arr = custom_data->data;
if (t->state == TRANS_CANCEL) {
BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
BMesh *bm = em->bm;
/* Restore custom loop normal on cancel */
for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
BKE_lnor_space_custom_normal_to_data(
bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->niloc, lnor_ed->clnors_data);
}
}
BM_loop_normal_editdata_array_free(lnors_ed_arr);
tc->custom.mode.data = NULL;
tc->custom.mode.free_cb = NULL;
}
/* Works by getting custom normal from clnor_data, transform, then store */
static void applyNormalRotation(TransInfo *t, const int UNUSED(mval[2]))
{
char str[UI_MAX_DRAW_STR];
float axis_final[3];
copy_v3_v3(axis_final, t->orient_matrix[t->orient_axis]);
if ((t->con.mode & CON_APPLY) && t->con.applyRot) {
t->con.applyRot(t, NULL, NULL, axis_final, NULL);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
BMesh *bm = em->bm;
BMLoopNorEditDataArray *lnors_ed_arr = tc->custom.mode.data;
BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
float axis[3];
float mat[3][3];
float angle = t->values[0];
copy_v3_v3(axis, axis_final);
snapGridIncrement(t, &angle);
applySnapping(t, &angle);
applyNumInput(&t->num, &angle);
headerRotation(t, str, angle);
axis_angle_normalized_to_mat3(mat, axis, angle);
for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
mul_v3_m3v3(lnor_ed->nloc, mat, lnor_ed->niloc);
BKE_lnor_space_custom_normal_to_data(
bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->nloc, lnor_ed->clnors_data);
}
t->values_final[0] = angle;
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initNormalRotation(TransInfo *t)
{
t->mode = TFM_NORMAL_ROTATION;
t->transform = applyNormalRotation;
setInputPostFct(&t->mouse, postInputRotation);
initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = DEG2RAD(5.0);
t->snap[2] = DEG2RAD(1.0);
copy_v3_fl(t->num.val_inc, t->snap[2]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_use_radians = (t->scene->unit.system_rotation == USER_UNIT_ROT_RADIANS);
t->num.unit_type[0] = B_UNIT_ROTATION;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
BMesh *bm = em->bm;
BKE_editmesh_ensure_autosmooth(em, tc->obedit->data);
BKE_editmesh_lnorspace_update(em, tc->obedit->data);
storeCustomLNorValue(tc, bm);
}
}
/** \} */

View File

@@ -0,0 +1,147 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.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_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Sequencer Slide) */
/** \name Transform Sequencer Slide
* \{ */
static void headerSeqSlide(TransInfo *t, const float val[2], char str[UI_MAX_DRAW_STR])
{
char tvec[NUM_STR_REP_LEN * 3];
size_t ofs = 0;
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec, &t->scene->unit);
}
else {
BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.0f, %.0f", val[0], val[1]);
}
ofs += BLI_snprintf(
str + ofs, UI_MAX_DRAW_STR - ofs, TIP_("Sequence Slide: %s%s, ("), &tvec[0], t->con.text);
if (t->keymap) {
wmKeyMapItem *kmi = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_TRANSLATE);
if (kmi) {
ofs += WM_keymap_item_to_string(kmi, false, str + ofs, UI_MAX_DRAW_STR - ofs);
}
}
ofs += BLI_snprintf(str + ofs,
UI_MAX_DRAW_STR - ofs,
TIP_(" or Alt) Expand to fit %s"),
WM_bool_as_string((t->flag & T_ALT_TRANSFORM) != 0));
}
static void applySeqSlideValue(TransInfo *t, const float val[2])
{
int i;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
madd_v2_v2v2fl(td->loc, td->iloc, val, td->factor);
}
}
}
static void applySeqSlide(TransInfo *t, const int mval[2])
{
char str[UI_MAX_DRAW_STR];
snapSequenceBounds(t, mval);
if (t->con.mode & CON_APPLY) {
float pvec[3] = {0.0f, 0.0f, 0.0f};
float tvec[3];
t->con.applyVec(t, NULL, NULL, t->values, tvec, pvec);
copy_v3_v3(t->values_final, tvec);
}
else {
// snapGridIncrement(t, t->values);
applyNumInput(&t->num, t->values);
copy_v3_v3(t->values_final, t->values);
}
t->values_final[0] = floorf(t->values_final[0] + 0.5f);
t->values_final[1] = floorf(t->values_final[1] + 0.5f);
headerSeqSlide(t, t->values_final, str);
applySeqSlideValue(t, t->values_final);
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initSeqSlide(TransInfo *t)
{
t->transform = applySeqSlide;
initMouseInputMode(t, &t->mouse, INPUT_VECTOR);
t->idx_max = 1;
t->num.flag = 0;
t->num.idx_max = t->idx_max;
t->snap[0] = 0.0f;
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]);
t->num.unit_sys = t->scene->unit.system;
/* Would be nice to have a time handling in units as well
* (supporting frames in addition to "natural" time...). */
t->num.unit_type[0] = B_UNIT_NONE;
t->num.unit_type[1] = B_UNIT_NONE;
}
/** \} */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,120 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (GPencil Opacity) */
/** \name Transform GPencil Strokes Opacity
* \{ */
static void applyGPOpacity(TransInfo *t, const int UNUSED(mval[2]))
{
float ratio;
int i;
char str[UI_MAX_DRAW_STR];
ratio = t->values[0];
snapGridIncrement(t, &ratio);
applyNumInput(&t->num, &ratio);
t->values_final[0] = ratio;
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, &t->scene->unit);
BLI_snprintf(str, sizeof(str), TIP_("Opacity: %s"), c);
}
else {
BLI_snprintf(str, sizeof(str), TIP_("Opacity: %3f"), ratio);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
if (td->val) {
*td->val = td->ival * ratio;
/* apply PET */
*td->val = (*td->val * td->factor) + ((1.0f - td->factor) * td->ival);
CLAMP(*td->val, 0.0f, 1.0f);
}
}
}
ED_area_status_text(t->sa, str);
}
void initGPOpacity(TransInfo *t)
{
t->mode = TFM_GPENCIL_OPACITY;
t->transform = applyGPOpacity;
initMouseInputMode(t, &t->mouse, INPUT_SPRING);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE;
t->flag |= T_NO_ZERO;
#ifdef USE_NUM_NO_ZERO
t->num.val_flag[0] |= NUM_NO_ZERO;
#endif
t->flag |= T_NO_CONSTRAINT;
}
/** \} */

View File

@@ -0,0 +1,122 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (GPencil Shrink/Fatten) */
/** \name Transform GPencil Strokes Shrink/Fatten
* \{ */
static void applyGPShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
{
float ratio;
int i;
char str[UI_MAX_DRAW_STR];
ratio = t->values[0];
snapGridIncrement(t, &ratio);
applyNumInput(&t->num, &ratio);
t->values_final[0] = ratio;
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, &t->scene->unit);
BLI_snprintf(str, sizeof(str), TIP_("Shrink/Fatten: %s"), c);
}
else {
BLI_snprintf(str, sizeof(str), TIP_("Shrink/Fatten: %3f"), ratio);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
if (td->val) {
*td->val = td->ival * ratio;
/* apply PET */
*td->val = (*td->val * td->factor) + ((1.0f - td->factor) * td->ival);
if (*td->val <= 0.0f) {
*td->val = 0.001f;
}
}
}
}
ED_area_status_text(t->sa, str);
}
void initGPShrinkFatten(TransInfo *t)
{
t->mode = TFM_GPENCIL_SHRINKFATTEN;
t->transform = applyGPShrinkFatten;
initMouseInputMode(t, &t->mouse, INPUT_SPRING);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE;
t->flag |= T_NO_ZERO;
#ifdef USE_NUM_NO_ZERO
t->num.val_flag[0] |= NUM_NO_ZERO;
#endif
t->flag |= T_NO_CONSTRAINT;
}
/** \} */

View File

@@ -0,0 +1,154 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Mask Shrink/Fatten) */
/** \name Transform Mask Shrink/Fatten
* \{ */
static void applyMaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
{
float ratio;
int i;
bool initial_feather = false;
char str[UI_MAX_DRAW_STR];
ratio = t->values[0];
snapGridIncrement(t, &ratio);
applyNumInput(&t->num, &ratio);
t->values_final[0] = ratio;
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, &t->scene->unit);
BLI_snprintf(str, sizeof(str), TIP_("Feather Shrink/Fatten: %s"), c);
}
else {
BLI_snprintf(str, sizeof(str), TIP_("Feather Shrink/Fatten: %3f"), ratio);
}
/* detect if no points have feather yet */
if (ratio > 1.0f) {
initial_feather = true;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
if (td->ival >= 0.001f) {
initial_feather = false;
}
}
}
}
/* apply shrink/fatten */
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (td = tc->data, i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
if (td->val) {
if (initial_feather) {
*td->val = td->ival + (ratio - 1.0f) * 0.01f;
}
else {
*td->val = td->ival * ratio;
}
/* apply PET */
*td->val = (*td->val * td->factor) + ((1.0f - td->factor) * td->ival);
if (*td->val <= 0.0f) {
*td->val = 0.001f;
}
}
}
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initMaskShrinkFatten(TransInfo *t)
{
t->mode = TFM_MASK_SHRINKFATTEN;
t->transform = applyMaskShrinkFatten;
initMouseInputMode(t, &t->mouse, INPUT_SPRING);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE;
t->flag |= T_NO_ZERO;
#ifdef USE_NUM_NO_ZERO
t->num.val_flag[0] |= NUM_NO_ZERO;
#endif
t->flag |= T_NO_CONSTRAINT;
}
/** \} */

View File

@@ -0,0 +1,131 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Mirror) */
/** \name Transform Mirror
* \{ */
static void applyMirror(TransInfo *t, const int UNUSED(mval[2]))
{
float size[3], mat[3][3];
int i;
char str[UI_MAX_DRAW_STR];
copy_v3_v3(t->values_final, t->values);
/*
* OPTIMIZATION:
* This still recalcs transformation on mouse move
* while it should only recalc on constraint change
* */
/* if an axis has been selected */
if (t->con.mode & CON_APPLY) {
size[0] = size[1] = size[2] = -1;
size_to_mat3(mat, size);
if (t->con.applySize) {
t->con.applySize(t, NULL, NULL, mat);
}
BLI_snprintf(str, sizeof(str), TIP_("Mirror%s"), t->con.text);
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
ElementResize(t, tc, td, mat);
}
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
else {
size[0] = size[1] = size[2] = 1;
size_to_mat3(mat, size);
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
ElementResize(t, tc, td, mat);
}
}
recalcData(t);
if (t->flag & T_2D_EDIT) {
ED_area_status_text(t->sa, TIP_("Select a mirror axis (X, Y)"));
}
else {
ED_area_status_text(t->sa, TIP_("Select a mirror axis (X, Y, Z)"));
}
}
}
void initMirror(TransInfo *t)
{
t->transform = applyMirror;
initMouseInputMode(t, &t->mouse, INPUT_NONE);
t->flag |= T_NULL_ONE;
if ((t->flag & T_EDIT) == 0) {
t->flag |= T_NO_ZERO;
}
}
/** \} */

View File

@@ -0,0 +1,136 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Push/Pull) */
/** \name Transform Push/Pull
* \{ */
static void applyPushPull(TransInfo *t, const int UNUSED(mval[2]))
{
float vec[3], axis_global[3];
float distance;
int i;
char str[UI_MAX_DRAW_STR];
distance = t->values[0];
snapGridIncrement(t, &distance);
applyNumInput(&t->num, &distance);
t->values_final[0] = distance;
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, &t->scene->unit);
BLI_snprintf(str, sizeof(str), TIP_("Push/Pull: %s%s %s"), c, t->con.text, t->proptext);
}
else {
/* default header print */
BLI_snprintf(
str, sizeof(str), TIP_("Push/Pull: %.4f%s %s"), distance, t->con.text, t->proptext);
}
if (t->con.applyRot && t->con.mode & CON_APPLY) {
t->con.applyRot(t, NULL, NULL, axis_global, NULL);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
sub_v3_v3v3(vec, tc->center_local, td->center);
if (t->con.applyRot && t->con.mode & CON_APPLY) {
float axis[3];
copy_v3_v3(axis, axis_global);
t->con.applyRot(t, tc, td, axis, NULL);
mul_m3_v3(td->smtx, axis);
if (isLockConstraint(t)) {
float dvec[3];
project_v3_v3v3(dvec, vec, axis);
sub_v3_v3(vec, dvec);
}
else {
project_v3_v3v3(vec, vec, axis);
}
}
normalize_v3_length(vec, distance * td->factor);
add_v3_v3v3(td->loc, td->iloc, vec);
}
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initPushPull(TransInfo *t)
{
t->mode = TFM_PUSHPULL;
t->transform = applyPushPull;
initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_LENGTH;
}
/** \} */

View File

@@ -0,0 +1,169 @@
/*
* 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 "BLI_math.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "transform.h"
#include "transform_convert.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Resize) */
/** \name Transform Resize
* \{ */
static void applyResize(TransInfo *t, const int UNUSED(mval[2]))
{
float mat[3][3];
int i;
char str[UI_MAX_DRAW_STR];
if (t->flag & T_INPUT_IS_VALUES_FINAL) {
copy_v3_v3(t->values_final, t->values);
}
else {
float ratio = t->values[0];
copy_v3_fl(t->values_final, ratio);
snapGridIncrement(t, t->values_final);
if (applyNumInput(&t->num, t->values_final)) {
constraintNumInput(t, t->values_final);
}
applySnapping(t, t->values_final);
}
size_to_mat3(mat, t->values_final);
if (t->con.mode & CON_APPLY) {
t->con.applySize(t, NULL, NULL, mat);
/* Only so we have re-usable value with redo. */
float pvec[3] = {0.0f, 0.0f, 0.0f};
int j = 0;
for (i = 0; i < 3; i++) {
if (!(t->con.mode & (CON_AXIS0 << i))) {
t->values_final[i] = 1.0f;
}
else {
pvec[j++] = t->values_final[i];
}
}
headerResize(t, pvec, str);
}
else {
headerResize(t, t->values_final, str);
}
copy_m3_m3(t->mat, mat); // used in gizmo
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
ElementResize(t, tc, td, mat);
}
}
/* evil hack - redo resize if cliping needed */
if (t->flag & T_CLIP_UV && clipUVTransform(t, t->values_final, 1)) {
size_to_mat3(mat, t->values_final);
if (t->con.mode & CON_APPLY) {
t->con.applySize(t, NULL, NULL, mat);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
ElementResize(t, tc, td, mat);
}
/* 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 initResize(TransInfo *t)
{
t->mode = TFM_RESIZE;
t->transform = applyResize;
initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
t->flag |= T_NULL_ONE;
t->num.val_flag[0] |= NUM_NULL_ONE;
t->num.val_flag[1] |= NUM_NULL_ONE;
t->num.val_flag[2] |= NUM_NULL_ONE;
t->num.flag |= NUM_AFFECT_ALL;
if ((t->flag & T_EDIT) == 0) {
t->flag |= T_NO_ZERO;
#ifdef USE_NUM_NO_ZERO
t->num.val_flag[0] |= NUM_NO_ZERO;
t->num.val_flag[1] |= NUM_NO_ZERO;
t->num.val_flag[2] |= NUM_NO_ZERO;
#endif
}
t->idx_max = 2;
t->num.idx_max = 2;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE;
t->num.unit_type[1] = B_UNIT_NONE;
t->num.unit_type[2] = B_UNIT_NONE;
}
/** \} */

View File

@@ -0,0 +1,198 @@
/*
* 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 "BLI_math.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Rotation) */
/** \name Transform Rotation
* \{ */
static float large_rotation_limit(float angle)
{
/* Limit rotation to 1001 turns max
* (otherwise iterative handling of 'large' rotations would become too slow). */
const float angle_max = (float)(M_PI * 2000.0);
if (fabsf(angle) > angle_max) {
const float angle_sign = angle < 0.0f ? -1.0f : 1.0f;
angle = angle_sign * (fmodf(fabsf(angle), (float)(M_PI * 2.0)) + angle_max);
}
return angle;
}
static void applyRotationValue(TransInfo *t,
float angle,
float axis[3],
const bool is_large_rotation)
{
float mat[3][3];
int i;
const float angle_sign = angle < 0.0f ? -1.0f : 1.0f;
/* We cannot use something too close to 180°, or 'continuous' rotation may fail
* due to computing error... */
const float angle_step = angle_sign * (float)(0.9 * M_PI);
if (is_large_rotation) {
/* Just in case, calling code should have already done that in practice
* (for UI feedback reasons). */
angle = large_rotation_limit(angle);
}
axis_angle_normalized_to_mat3(mat, axis, angle);
/* Counter for needed updates (when we need to update to non-default matrix,
* we also need another update on next iteration to go back to default matrix,
* hence the '2' value used here, instead of a mere boolean). */
short do_update_matrix = 0;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
float angle_final = angle;
if (t->con.applyRot) {
t->con.applyRot(t, tc, td, axis, NULL);
angle_final = angle * td->factor;
/* Even though final angle might be identical to orig value,
* we have to update the rotation matrix in that case... */
do_update_matrix = 2;
}
else if (t->flag & T_PROP_EDIT) {
angle_final = angle * td->factor;
}
/* Rotation is very likely to be above 180°, we need to do rotation by steps.
* Note that this is only needed when doing 'absolute' rotation
* (i.e. from initial rotation again, typically when using numinput).
* regular incremental rotation (from mouse/widget/...) will be called often enough,
* hence steps are small enough to be properly handled without that complicated trick.
* Note that we can only do that kind of stepped rotation if we have initial rotation values
* (and access to some actual rotation value storage).
* Otherwise, just assume it's useless (e.g. in case of mesh/UV/etc. editing).
* Also need to be in Euler rotation mode, the others never allow more than one turn anyway.
*/
if (is_large_rotation && td->ext != NULL && td->ext->rotOrder == ROT_MODE_EUL) {
copy_v3_v3(td->ext->rot, td->ext->irot);
for (float angle_progress = angle_step; fabsf(angle_progress) < fabsf(angle_final);
angle_progress += angle_step) {
axis_angle_normalized_to_mat3(mat, axis, angle_progress);
ElementRotation(t, tc, td, mat, t->around);
}
do_update_matrix = 2;
}
else if (angle_final != angle) {
do_update_matrix = 2;
}
if (do_update_matrix > 0) {
axis_angle_normalized_to_mat3(mat, axis, angle_final);
do_update_matrix--;
}
ElementRotation(t, tc, td, mat, t->around);
}
}
}
static void applyRotation(TransInfo *t, const int UNUSED(mval[2]))
{
char str[UI_MAX_DRAW_STR];
float final;
final = t->values[0];
snapGridIncrement(t, &final);
float axis_final[3];
copy_v3_v3(axis_final, t->orient_matrix[t->orient_axis]);
if ((t->con.mode & CON_APPLY) && t->con.applyRot) {
t->con.applyRot(t, NULL, NULL, axis_final, NULL);
}
applySnapping(t, &final);
if (applyNumInput(&t->num, &final)) {
/* We have to limit the amount of turns to a reasonable number here,
* to avoid things getting *very* slow, see how applyRotationValue() handles those... */
final = large_rotation_limit(final);
}
t->values_final[0] = final;
headerRotation(t, str, final);
const bool is_large_rotation = hasNumInput(&t->num);
applyRotationValue(t, final, axis_final, is_large_rotation);
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initRotation(TransInfo *t)
{
t->mode = TFM_ROTATION;
t->transform = applyRotation;
setInputPostFct(&t->mouse, postInputRotation);
initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = DEG2RAD(5.0);
t->snap[2] = DEG2RAD(1.0);
copy_v3_fl(t->num.val_inc, t->snap[2]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_use_radians = (t->scene->unit.system_rotation == USER_UNIT_ROT_RADIANS);
t->num.unit_type[0] = B_UNIT_ROTATION;
if (t->flag & T_2D_EDIT) {
t->flag |= T_NO_CONSTRAINT;
}
}
/** \} */

View File

@@ -0,0 +1,248 @@
/*
* 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 "DNA_gpencil_types.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "WM_types.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Shear) */
/** \name Transform Shear
* \{ */
static void initShear_mouseInputMode(TransInfo *t)
{
float dir[3];
bool dir_flip = false;
copy_v3_v3(dir, t->orient_matrix[t->orient_axis_ortho]);
/* Needed for axis aligned view gizmo. */
if (t->orientation.user == V3D_ORIENT_VIEW) {
if (t->orient_axis_ortho == 0) {
if (t->center2d[1] > t->mouse.imval[1]) {
dir_flip = !dir_flip;
}
}
else if (t->orient_axis_ortho == 1) {
if (t->center2d[0] > t->mouse.imval[0]) {
dir_flip = !dir_flip;
}
}
}
/* Without this, half the gizmo handles move in the opposite direction. */
if ((t->orient_axis_ortho + 1) % 3 != t->orient_axis) {
dir_flip = !dir_flip;
}
if (dir_flip) {
negate_v3(dir);
}
mul_mat3_m4_v3(t->viewmat, dir);
if (normalize_v2(dir) == 0.0f) {
dir[0] = 1.0f;
}
setCustomPointsFromDirection(t, &t->mouse, dir);
initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO);
}
static eRedrawFlag handleEventShear(TransInfo *t, const wmEvent *event)
{
eRedrawFlag status = TREDRAW_NOTHING;
if (event->type == MIDDLEMOUSE && event->val == KM_PRESS) {
/* Use custom.mode.data pointer to signal Shear direction */
do {
t->orient_axis_ortho = (t->orient_axis_ortho + 1) % 3;
} while (t->orient_axis_ortho == t->orient_axis);
initShear_mouseInputMode(t);
status = TREDRAW_HARD;
}
else if (event->type == XKEY && event->val == KM_PRESS) {
t->orient_axis_ortho = (t->orient_axis + 1) % 3;
initShear_mouseInputMode(t);
status = TREDRAW_HARD;
}
else if (event->type == YKEY && event->val == KM_PRESS) {
t->orient_axis_ortho = (t->orient_axis + 2) % 3;
initShear_mouseInputMode(t);
status = TREDRAW_HARD;
}
return status;
}
static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
{
float vec[3];
float smat[3][3], tmat[3][3], totmat[3][3], axismat[3][3], axismat_inv[3][3];
float value;
int i;
char str[UI_MAX_DRAW_STR];
const bool is_local_center = transdata_check_local_center(t, t->around);
value = t->values[0];
snapGridIncrement(t, &value);
applyNumInput(&t->num, &value);
t->values_final[0] = value;
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, &t->scene->unit);
BLI_snprintf(str, sizeof(str), TIP_("Shear: %s %s"), c, t->proptext);
}
else {
/* default header print */
BLI_snprintf(str,
sizeof(str),
TIP_("Shear: %.3f %s (Press X or Y to set shear axis)"),
value,
t->proptext);
}
unit_m3(smat);
smat[1][0] = value;
copy_v3_v3(axismat_inv[0], t->orient_matrix[t->orient_axis_ortho]);
copy_v3_v3(axismat_inv[2], t->orient_matrix[t->orient_axis]);
cross_v3_v3v3(axismat_inv[1], axismat_inv[0], axismat_inv[2]);
invert_m3_m3(axismat, axismat_inv);
mul_m3_series(totmat, axismat_inv, smat, axismat);
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
const float *center, *co;
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
if (t->flag & T_EDIT) {
mul_m3_series(tmat, td->smtx, totmat, td->mtx);
}
else {
copy_m3_m3(tmat, totmat);
}
if (is_local_center) {
center = td->center;
co = td->loc;
}
else {
center = tc->center_local;
co = td->center;
}
sub_v3_v3v3(vec, co, center);
mul_m3_v3(tmat, vec);
add_v3_v3(vec, center);
sub_v3_v3(vec, co);
if (t->options & CTX_GPENCIL_STROKES) {
/* grease pencil multiframe falloff */
bGPDstroke *gps = (bGPDstroke *)td->extra;
if (gps != NULL) {
mul_v3_fl(vec, td->factor * gps->runtime.multi_frame_falloff);
}
else {
mul_v3_fl(vec, td->factor);
}
}
else {
mul_v3_fl(vec, td->factor);
}
add_v3_v3v3(td->loc, td->iloc, vec);
}
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initShear(TransInfo *t)
{
t->mode = TFM_SHEAR;
t->transform = applyShear;
t->handleEvent = handleEventShear;
if (t->orient_axis == t->orient_axis_ortho) {
t->orient_axis = 2;
t->orient_axis_ortho = 1;
}
initShear_mouseInputMode(t);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE; /* Don't think we have any unit here? */
t->flag |= T_NO_CONSTRAINT;
}
/** \} */

View File

@@ -0,0 +1,146 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.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_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Shrink-Fatten) */
/** \name Transform Shrink-Fatten
* \{ */
static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
{
float distance;
int i;
char str[UI_MAX_DRAW_STR];
size_t ofs = 0;
distance = -t->values[0];
snapGridIncrement(t, &distance);
applyNumInput(&t->num, &distance);
t->values_final[0] = -distance;
/* header print for NumInput */
ofs += BLI_strncpy_rlen(str + ofs, TIP_("Shrink/Fatten:"), sizeof(str) - ofs);
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, &t->scene->unit);
ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, " %s", c);
}
else {
/* default header print */
ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, " %.4f", distance);
}
if (t->proptext[0]) {
ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, " %s", t->proptext);
}
ofs += BLI_strncpy_rlen(str + ofs, ", (", sizeof(str) - ofs);
if (t->keymap) {
wmKeyMapItem *kmi = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE);
if (kmi) {
ofs += WM_keymap_item_to_string(kmi, false, str + ofs, sizeof(str) - ofs);
}
}
BLI_snprintf(str + ofs,
sizeof(str) - ofs,
TIP_(" or Alt) Even Thickness %s"),
WM_bool_as_string((t->flag & T_ALT_TRANSFORM) != 0));
/* done with header string */
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
float tdistance; /* temp dist */
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
/* get the final offset */
tdistance = distance * td->factor;
if (td->ext && (t->flag & T_ALT_TRANSFORM) != 0) {
tdistance *= td->ext->isize[0]; /* shell factor */
}
madd_v3_v3v3fl(td->loc, td->iloc, td->axismtx[2], tdistance);
}
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initShrinkFatten(TransInfo *t)
{
// If not in mesh edit mode, fallback to Resize
if ((t->flag & T_EDIT) == 0 || (t->obedit_type != OB_MESH)) {
initResize(t);
}
else {
t->mode = TFM_SHRINKFATTEN;
t->transform = applyShrinkFatten;
initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_LENGTH;
t->flag |= T_NO_CONSTRAINT;
}
}
/** \} */

View File

@@ -0,0 +1,140 @@
/*
* 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 "BLI_math.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Skin) */
/** \name Transform Skin
* \{ */
static void applySkinResize(TransInfo *t, const int UNUSED(mval[2]))
{
float mat[3][3];
int i;
char str[UI_MAX_DRAW_STR];
if (t->flag & T_INPUT_IS_VALUES_FINAL) {
copy_v3_v3(t->values_final, t->values);
}
else {
copy_v3_fl(t->values_final, t->values[0]);
snapGridIncrement(t, t->values_final);
if (applyNumInput(&t->num, t->values_final)) {
constraintNumInput(t, t->values_final);
}
applySnapping(t, t->values_final);
}
size_to_mat3(mat, t->values_final);
headerResize(t, t->values_final, str);
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
float tmat[3][3], smat[3][3];
float fsize[3];
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
if (t->flag & T_EDIT) {
mul_m3_m3m3(smat, mat, td->mtx);
mul_m3_m3m3(tmat, td->smtx, smat);
}
else {
copy_m3_m3(tmat, mat);
}
if (t->con.applySize) {
t->con.applySize(t, NULL, NULL, tmat);
}
mat3_to_size(fsize, tmat);
td->val[0] = td->ext->isize[0] * (1 + (fsize[0] - 1) * td->factor);
td->val[1] = td->ext->isize[1] * (1 + (fsize[1] - 1) * td->factor);
}
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initSkinResize(TransInfo *t)
{
t->mode = TFM_SKIN_RESIZE;
t->transform = applySkinResize;
initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
t->flag |= T_NULL_ONE;
t->num.val_flag[0] |= NUM_NULL_ONE;
t->num.val_flag[1] |= NUM_NULL_ONE;
t->num.val_flag[2] |= NUM_NULL_ONE;
t->num.flag |= NUM_AFFECT_ALL;
if ((t->flag & T_EDIT) == 0) {
t->flag |= T_NO_ZERO;
#ifdef USE_NUM_NO_ZERO
t->num.val_flag[0] |= NUM_NO_ZERO;
t->num.val_flag[1] |= NUM_NO_ZERO;
t->num.val_flag[2] |= NUM_NO_ZERO;
#endif
}
t->idx_max = 2;
t->num.idx_max = 2;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE;
t->num.unit_type[1] = B_UNIT_NONE;
t->num.unit_type[2] = B_UNIT_NONE;
}
/** \} */

View File

@@ -0,0 +1,119 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Tilt) */
/** \name Transform Tilt
* \{ */
static void applyTilt(TransInfo *t, const int UNUSED(mval[2]))
{
int i;
char str[UI_MAX_DRAW_STR];
float final;
final = t->values[0];
snapGridIncrement(t, &final);
applyNumInput(&t->num, &final);
t->values_final[0] = final;
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, &t->scene->unit);
BLI_snprintf(str, sizeof(str), TIP_("Tilt: %s° %s"), &c[0], t->proptext);
/* XXX For some reason, this seems needed for this op, else RNA prop is not updated... :/ */
t->values_final[0] = final;
}
else {
BLI_snprintf(str, sizeof(str), TIP_("Tilt: %.2f° %s"), RAD2DEGF(final), t->proptext);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
if (td->val) {
*td->val = td->ival + final * td->factor;
}
}
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initTilt(TransInfo *t)
{
t->mode = TFM_TILT;
t->transform = applyTilt;
initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = DEG2RAD(5.0);
t->snap[2] = DEG2RAD(1.0);
copy_v3_fl(t->num.val_inc, t->snap[2]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_use_radians = (t->scene->unit.system_rotation == USER_UNIT_ROT_RADIANS);
t->num.unit_type[0] = B_UNIT_ROTATION;
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
/** \} */

View File

@@ -0,0 +1,168 @@
/*
* 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 "DNA_anim_types.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_nla.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Animation Time Scale) */
/** \name Transform Animation Time Scale
* \{ */
static void headerTimeScale(TransInfo *t, char str[UI_MAX_DRAW_STR])
{
char tvec[NUM_STR_REP_LEN * 3];
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec, &t->scene->unit);
}
else {
BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", t->values_final[0]);
}
BLI_snprintf(str, UI_MAX_DRAW_STR, TIP_("ScaleX: %s"), &tvec[0]);
}
static void applyTimeScaleValue(TransInfo *t, float value)
{
Scene *scene = t->scene;
int i;
const short autosnap = getAnimEdit_SnapMode(t);
const double secf = FPS;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
TransData2D *td2d = tc->data_2d;
for (i = 0; i < tc->data_len; i++, td++, td2d++) {
/* it is assumed that td->extra is a pointer to the AnimData,
* whose active action is where this keyframe comes from
* (this is only valid when not in NLA)
*/
AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
float startx = CFRA;
float fac = value;
if (autosnap == SACTSNAP_TSTEP) {
fac = (float)(floor((double)fac / secf + 0.5) * secf);
}
else if (autosnap == SACTSNAP_STEP) {
fac = floorf(fac + 0.5f);
}
/* take proportional editing into account */
fac = ((fac - 1.0f) * td->factor) + 1;
/* check if any need to apply nla-mapping */
if (adt) {
startx = BKE_nla_tweakedit_remap(adt, startx, NLATIME_CONVERT_UNMAP);
}
/* now, calculate the new value */
*(td->val) = ((td->ival - startx) * fac) + startx;
/* apply nearest snapping */
doAnimEdit_SnapFrame(t, td, td2d, adt, autosnap);
}
}
}
static void applyTimeScale(TransInfo *t, const int UNUSED(mval[2]))
{
char str[UI_MAX_DRAW_STR];
/* handle numeric-input stuff */
t->vec[0] = t->values[0];
applyNumInput(&t->num, &t->vec[0]);
t->values_final[0] = t->vec[0];
headerTimeScale(t, str);
applyTimeScaleValue(t, t->values_final[0]);
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initTimeScale(TransInfo *t)
{
float center[2];
/* this tool is only really available in the Action Editor
* AND NLA Editor (for strip scaling)
*/
if (ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA) == 0) {
t->state = TRANS_CANCEL;
}
t->mode = TFM_TIME_SCALE;
t->transform = applyTimeScale;
/* recalculate center2d to use CFRA and mouse Y, since that's
* what is used in time scale */
if ((t->flag & T_OVERRIDE_CENTER) == 0) {
t->center_global[0] = t->scene->r.cfra;
projectFloatView(t, t->center_global, center);
center[1] = t->mouse.imval[1];
}
/* force a reinit with the center2d used here */
initMouseInput(t, &t->mouse, center, t->mouse.imval, false);
initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
t->flag |= T_NULL_ONE;
t->num.val_flag[0] |= NUM_NULL_ONE;
/* num-input has max of (n-1) */
t->idx_max = 0;
t->num.flag = 0;
t->num.idx_max = t->idx_max;
/* initialize snap like for everything else */
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE;
}
/** \} */

View File

@@ -0,0 +1,236 @@
/*
* 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_anim_types.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_nla.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "UI_view2d.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Animation Time Slide) */
/** \name Transform Animation Time Slide
* \{ */
static void headerTimeSlide(TransInfo *t, const float sval, char str[UI_MAX_DRAW_STR])
{
char tvec[NUM_STR_REP_LEN * 3];
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec, &t->scene->unit);
}
else {
const float *range = t->custom.mode.data;
float minx = range[0];
float maxx = range[1];
float cval = t->values_final[0];
float val;
val = 2.0f * (cval - sval) / (maxx - minx);
CLAMP(val, -1.0f, 1.0f);
BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", val);
}
BLI_snprintf(str, UI_MAX_DRAW_STR, TIP_("TimeSlide: %s"), &tvec[0]);
}
static void applyTimeSlideValue(TransInfo *t, float sval, float cval)
{
int i;
const float *range = t->custom.mode.data;
float minx = range[0];
float maxx = range[1];
/* set value for drawing black line */
if (t->spacetype == SPACE_ACTION) {
SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first;
saction->timeslide = cval;
}
/* It doesn't matter whether we apply to t->data or
* t->data2d, but t->data2d is more convenient. */
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
/* it is assumed that td->extra is a pointer to the AnimData,
* whose active action is where this keyframe comes from
* (this is only valid when not in NLA)
*/
AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
/* only apply to data if in range */
if ((sval > minx) && (sval < maxx)) {
float cvalc = CLAMPIS(cval, minx, maxx);
float ival = td->ival;
float timefac;
/* NLA mapping magic here works as follows:
* - "ival" goes from strip time to global time
* - calculation is performed into td->val in global time
* (since sval and min/max are all in global time)
* - "td->val" then gets put back into strip time
*/
if (adt) {
/* strip to global */
ival = BKE_nla_tweakedit_remap(adt, ival, NLATIME_CONVERT_MAP);
}
/* left half? */
if (ival < sval) {
timefac = (sval - ival) / (sval - minx);
*(td->val) = cvalc - timefac * (cvalc - minx);
}
else {
timefac = (ival - sval) / (maxx - sval);
*(td->val) = cvalc + timefac * (maxx - cvalc);
}
if (adt) {
/* global to strip */
*(td->val) = BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_UNMAP);
}
}
}
}
}
static void applyTimeSlide(TransInfo *t, const int mval[2])
{
View2D *v2d = (View2D *)t->view;
float cval[2], sval[2];
const float *range = t->custom.mode.data;
float minx = range[0];
float maxx = range[1];
char str[UI_MAX_DRAW_STR];
/* calculate mouse co-ordinates */
UI_view2d_region_to_view(v2d, mval[0], mval[1], &cval[0], &cval[1]);
UI_view2d_region_to_view(v2d, t->mouse.imval[0], t->mouse.imval[1], &sval[0], &sval[1]);
/* t->values_final[0] stores cval[0], which is the current mouse-pointer location (in frames) */
// XXX Need to be able to repeat this
/* t->values_final[0] = cval[0]; */ /* UNUSED (reset again later). */
/* handle numeric-input stuff */
t->vec[0] = 2.0f * (cval[0] - sval[0]) / (maxx - minx);
applyNumInput(&t->num, &t->vec[0]);
t->values_final[0] = (maxx - minx) * t->vec[0] / 2.0f + sval[0];
headerTimeSlide(t, sval[0], str);
applyTimeSlideValue(t, sval[0], t->values_final[0]);
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initTimeSlide(TransInfo *t)
{
/* this tool is only really available in the Action Editor... */
if (t->spacetype == SPACE_ACTION) {
SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first;
/* set flag for drawing stuff */
saction->flag |= SACTION_MOVING;
}
else {
t->state = TRANS_CANCEL;
}
t->mode = TFM_TIME_SLIDE;
t->transform = applyTimeSlide;
initMouseInputMode(t, &t->mouse, INPUT_NONE);
{
Scene *scene = t->scene;
float *range;
t->custom.mode.data = range = MEM_mallocN(sizeof(float[2]), "TimeSlide Min/Max");
t->custom.mode.use_free = true;
float min = 999999999.0f, max = -999999999.0f;
int i;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
float val = *(td->val);
/* strip/action time to global (mapped) time */
if (adt) {
val = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_MAP);
}
if (min > val) {
min = val;
}
if (max < val) {
max = val;
}
}
}
if (min == max) {
/* just use the current frame ranges */
min = (float)PSFRA;
max = (float)PEFRA;
}
range[0] = min;
range[1] = max;
}
/* num-input has max of (n-1) */
t->idx_max = 0;
t->num.flag = 0;
t->num.idx_max = t->idx_max;
/* initialize snap like for everything else */
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
/* No time unit supporting frames currently... */
t->num.unit_type[0] = B_UNIT_NONE;
}
/** \} */

View File

@@ -0,0 +1,203 @@
/*
* 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 "DNA_anim_types.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_nla.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "UI_view2d.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Animation Translation) */
/** \name Transform Animation Translation
* \{ */
static void headerTimeTranslate(TransInfo *t, char str[UI_MAX_DRAW_STR])
{
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)) {
outputNumInput(&(t->num), tvec, &t->scene->unit);
}
else {
const short autosnap = getAnimEdit_SnapMode(t);
float val = t->values_final[0];
float snap_val;
snapFrameTransform(t, autosnap, false, val, &snap_val);
if (autosnap == SACTSNAP_FRAME) {
BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.2f (%.4f)", snap_val, val);
}
else if (autosnap == SACTSNAP_SECOND) {
BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.2f sec (%.4f)", snap_val, val);
}
else if (autosnap == SACTSNAP_TSTEP) {
BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f sec", snap_val);
}
else {
BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", snap_val);
}
}
ofs += BLI_snprintf(str, UI_MAX_DRAW_STR, TIP_("DeltaX: %s"), &tvec[0]);
if (t->flag & T_PROP_EDIT_ALL) {
ofs += BLI_snprintf(
str + ofs, UI_MAX_DRAW_STR - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
}
}
static void applyTimeTranslateValue(TransInfo *t, float value)
{
Scene *scene = t->scene;
int i;
const short autosnap = getAnimEdit_SnapMode(t);
const double secf = FPS;
float deltax, val /* , valprev */;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
TransData2D *td2d = tc->data_2d;
/* It doesn't matter whether we apply to t->data or
* t->data2d, but t->data2d is more convenient. */
for (i = 0; i < tc->data_len; i++, td++, td2d++) {
/* It is assumed that td->extra is a pointer to the AnimData,
* whose active action is where this keyframe comes from.
* (this is only valid when not in NLA)
* (also: masks and gpencil dont have animadata)
*/
AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
/* valprev = *td->val; */ /* UNUSED */
/* check if any need to apply nla-mapping */
if (adt && (t->spacetype != SPACE_SEQ)) {
deltax = value;
if (autosnap == SACTSNAP_TSTEP) {
deltax = (float)(floor(((double)deltax / secf) + 0.5) * secf);
}
else if (autosnap == SACTSNAP_STEP) {
deltax = floorf(deltax + 0.5f);
}
val = BKE_nla_tweakedit_remap(adt, td->ival, NLATIME_CONVERT_MAP);
val += deltax * td->factor;
*(td->val) = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP);
}
else {
deltax = val = t->values_final[0];
if (autosnap == SACTSNAP_TSTEP) {
val = (float)(floor(((double)deltax / secf) + 0.5) * secf);
}
else if (autosnap == SACTSNAP_STEP) {
val = floorf(val + 0.5f);
}
*(td->val) = td->ival + val * td->factor;
}
/* apply nearest snapping */
doAnimEdit_SnapFrame(t, td, td2d, adt, autosnap);
}
}
}
static void applyTimeTranslate(TransInfo *t, const int mval[2])
{
View2D *v2d = (View2D *)t->view;
char str[UI_MAX_DRAW_STR];
/* calculate translation amount from mouse movement - in 'time-grid space' */
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->mouse.imval[0], t->mouse.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];
}
/* handle numeric-input stuff */
t->vec[0] = t->values[0];
applyNumInput(&t->num, &t->vec[0]);
t->values_final[0] = t->vec[0];
headerTimeTranslate(t, str);
applyTimeTranslateValue(t, t->values_final[0]);
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initTimeTranslate(TransInfo *t)
{
/* this tool is only really available in the Action Editor... */
if (!ELEM(t->spacetype, SPACE_ACTION, SPACE_SEQ)) {
t->state = TRANS_CANCEL;
}
t->mode = TFM_TIME_TRANSLATE;
t->transform = applyTimeTranslate;
initMouseInputMode(t, &t->mouse, INPUT_NONE);
/* num-input has max of (n-1) */
t->idx_max = 0;
t->num.flag = 0;
t->num.idx_max = t->idx_max;
/* initialize snap like for everything else */
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
/* No time unit supporting frames currently... */
t->num.unit_type[0] = B_UNIT_NONE;
}
/** \} */

View File

@@ -0,0 +1,139 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (ToSphere) */
/** \name Transform ToSphere
* \{ */
static void applyToSphere(TransInfo *t, const int UNUSED(mval[2]))
{
float vec[3];
float ratio, radius;
int i;
char str[UI_MAX_DRAW_STR];
ratio = t->values[0];
snapGridIncrement(t, &ratio);
applyNumInput(&t->num, &ratio);
CLAMP(ratio, 0.0f, 1.0f);
t->values_final[0] = ratio;
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, &t->scene->unit);
BLI_snprintf(str, sizeof(str), TIP_("To Sphere: %s %s"), c, t->proptext);
}
else {
/* default header print */
BLI_snprintf(str, sizeof(str), TIP_("To Sphere: %.4f %s"), ratio, t->proptext);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
float tratio;
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
sub_v3_v3v3(vec, td->iloc, tc->center_local);
radius = normalize_v3(vec);
tratio = ratio * td->factor;
mul_v3_fl(vec, radius * (1.0f - tratio) + t->val * tratio);
add_v3_v3v3(td->loc, tc->center_local, vec);
}
}
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initToSphere(TransInfo *t)
{
int i;
t->mode = TFM_TOSPHERE;
t->transform = applyToSphere;
initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE;
t->num.val_flag[0] |= NUM_NULL_ONE | NUM_NO_NEGATIVE;
t->flag |= T_NO_CONSTRAINT;
// Calculate average radius
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
t->val += len_v3v3(tc->center_local, td->iloc);
}
}
t->val /= (float)t->data_len_all;
}
/** \} */

View File

@@ -0,0 +1,170 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_unit.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Rotation - Trackball) */
/** \name Transform Rotation - Trackball
* \{ */
static void applyTrackballValue(TransInfo *t,
const float axis1[3],
const float axis2[3],
const float angles[2])
{
float mat[3][3];
float axis[3];
float angle;
int i;
mul_v3_v3fl(axis, axis1, angles[0]);
madd_v3_v3fl(axis, axis2, angles[1]);
angle = normalize_v3(axis);
axis_angle_normalized_to_mat3(mat, axis, angle);
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_NOACTION) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
if (t->flag & T_PROP_EDIT) {
axis_angle_normalized_to_mat3(mat, axis, td->factor * angle);
}
ElementRotation(t, tc, td, mat, t->around);
}
}
}
static void applyTrackball(TransInfo *t, const int UNUSED(mval[2]))
{
char str[UI_MAX_DRAW_STR];
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]);
copy_v3_v3(axis2, t->persinv[1]);
normalize_v3(axis1);
normalize_v3(axis2);
copy_v2_v2(phi, t->values);
snapGridIncrement(t, phi);
applyNumInput(&t->num, phi);
copy_v2_v2(t->values_final, phi);
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN * 2];
outputNumInput(&(t->num), c, &t->scene->unit);
ofs += BLI_snprintf(str + ofs,
sizeof(str) - ofs,
TIP_("Trackball: %s %s %s"),
&c[0],
&c[NUM_STR_REP_LEN],
t->proptext);
}
else {
ofs += BLI_snprintf(str + ofs,
sizeof(str) - ofs,
TIP_("Trackball: %.2f %.2f %s"),
RAD2DEGF(phi[0]),
RAD2DEGF(phi[1]),
t->proptext);
}
if (t->flag & T_PROP_EDIT_ALL) {
ofs += BLI_snprintf(
str + ofs, sizeof(str) - ofs, TIP_(" 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]);
mul_m3_m3m3(mat, smat, totmat);
// TRANSFORM_FIX_ME
//copy_m3_m3(t->mat, mat); // used in gizmo
#endif
applyTrackballValue(t, axis1, axis2, phi);
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initTrackball(TransInfo *t)
{
t->mode = TFM_TRACKBALL;
t->transform = applyTrackball;
initMouseInputMode(t, &t->mouse, INPUT_TRACKBALL);
t->idx_max = 1;
t->num.idx_max = 1;
t->snap[0] = 0.0f;
t->snap[1] = DEG2RAD(5.0);
t->snap[2] = DEG2RAD(1.0);
copy_v3_fl(t->num.val_inc, t->snap[2]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_use_radians = (t->scene->unit.system_rotation == USER_UNIT_ROT_RADIANS);
t->num.unit_type[0] = B_UNIT_ROTATION;
t->num.unit_type[1] = B_UNIT_ROTATION;
t->flag |= T_NO_CONSTRAINT;
}
/** \} */

View File

@@ -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;
}
}
/** \} */

View File

@@ -0,0 +1,638 @@
/*
* 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 "BLI_math.h"
#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_editmesh.h"
#include "BKE_unit.h"
#include "GPU_immediate.h"
#include "GPU_matrix.h"
#include "GPU_state.h"
#include "ED_screen.h"
#include "WM_api.h"
#include "WM_types.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "BLT_translation.h"
#include "transform.h"
#include "transform_convert.h"
#include "transform_snap.h"
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
/* Transform (Vert Slide) */
/** \name Transform Vert Slide
* \{ */
static void calcVertSlideCustomPoints(struct TransInfo *t)
{
VertSlideParams *slp = t->custom.mode.data;
VertSlideData *sld = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data;
TransDataVertSlideVert *sv = &sld->sv[sld->curr_sv_index];
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->mouse.imval[0] - co_orig_2d[0], t->mouse.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 (slp->flipped && slp->use_even) {
setCustomPoints(t, &t->mouse, mval_start, mval_end);
}
else {
setCustomPoints(t, &t->mouse, mval_end, mval_start);
}
/* setCustomPoints isn't normally changing as the mouse moves,
* in this case apply mouse input immediately so we don't refresh
* with the value from the previous points */
applyMouseInput(t, &t->mouse, t->mval, t->values);
}
/**
* Run once when initializing vert slide to find the reference edge
*/
static void calcVertSlideMouseActiveVert(struct TransInfo *t, const int mval[2])
{
/* Active object may have no selected vertices. */
VertSlideData *sld = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data;
float mval_fl[2] = {UNPACK2(mval)};
TransDataVertSlideVert *sv;
/* set the vertex to use as a reference for the mouse direction 'curr_sv_index' */
float dist_sq = 0.0f;
float dist_min_sq = FLT_MAX;
int i;
for (i = 0, sv = sld->sv; i < sld->totsv; i++, sv++) {
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 = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data;
float imval_fl[2] = {UNPACK2(t->mouse.imval)};
float mval_fl[2] = {UNPACK2(mval)};
float dir[3];
TransDataVertSlideVert *sv;
int i;
/* note: we could save a matrix-multiply for each vertex
* by finding the closest edge in local-space.
* However this skews the outcome with non-uniform-scale. */
/* 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);
normalize_v3(dir);
for (i = 0, sv = sld->sv; i < sld->totsv; i++, sv++) {
if (sv->co_link_tot > 1) {
float dir_dot_best = -FLT_MAX;
int co_link_curr_best = -1;
int j;
for (j = 0; j < sv->co_link_tot; j++) {
float tdir[3];
float dir_dot;
sub_v3_v3v3(tdir, sv->co_orig_3d, sv->co_link_orig_3d[j]);
mul_mat3_m4_v3(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat, tdir);
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;
}
}
if (co_link_curr_best != -1) {
sv->co_link_curr = co_link_curr_best;
}
}
}
}
static bool createVertSlideVerts(TransInfo *t, TransDataContainer *tc)
{
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
BMesh *bm = em->bm;
BMIter iter;
BMIter eiter;
BMEdge *e;
BMVert *v;
TransDataVertSlideVert *sv_array;
VertSlideData *sld = MEM_callocN(sizeof(*sld), "sld");
int j;
sld->curr_sv_index = 0;
j = 0;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
bool ok = false;
if (BM_elem_flag_test(v, BM_ELEM_SELECT) && v->e) {
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
ok = true;
break;
}
}
}
if (ok) {
BM_elem_flag_enable(v, BM_ELEM_TAG);
j += 1;
}
else {
BM_elem_flag_disable(v, BM_ELEM_TAG);
}
}
if (!j) {
MEM_freeN(sld);
return false;
}
sv_array = MEM_callocN(sizeof(TransDataVertSlideVert) * j, "sv_array");
j = 0;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
int k;
sv_array[j].v = v;
copy_v3_v3(sv_array[j].co_orig_3d, v->co);
k = 0;
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
k++;
}
}
sv_array[j].co_link_orig_3d = MEM_mallocN(sizeof(*sv_array[j].co_link_orig_3d) * k,
__func__);
sv_array[j].co_link_tot = k;
k = 0;
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
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);
k++;
}
}
j++;
}
}
sld->sv = sv_array;
sld->totsv = j;
tc->custom.mode.data = sld;
/* 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, tc->obedit, sld->proj_mat);
}
}
/* XXX, calc vert slide across all objects */
if (tc == t->data_container) {
calcVertSlideMouseActiveVert(t, t->mval);
calcVertSlideMouseActiveEdges(t, t->mval);
}
return true;
}
static void freeVertSlideVerts(TransInfo *UNUSED(t),
TransDataContainer *UNUSED(tc),
TransCustomData *custom_data)
{
VertSlideData *sld = custom_data->data;
if (!sld) {
return;
}
if (sld->totsv > 0) {
TransDataVertSlideVert *sv = sld->sv;
int i = 0;
for (i = 0; i < sld->totsv; i++, sv++) {
MEM_freeN(sv->co_link_orig_3d);
}
}
MEM_freeN(sld->sv);
MEM_freeN(sld);
custom_data->data = NULL;
}
static eRedrawFlag handleEventVertSlide(struct TransInfo *t, const struct wmEvent *event)
{
if (t->mode == TFM_VERT_SLIDE) {
VertSlideParams *slp = t->custom.mode.data;
if (slp) {
switch (event->type) {
case EKEY:
if (event->val == KM_PRESS) {
slp->use_even = !slp->use_even;
if (slp->flipped) {
calcVertSlideCustomPoints(t);
}
return TREDRAW_HARD;
}
break;
case FKEY:
if (event->val == KM_PRESS) {
slp->flipped = !slp->flipped;
calcVertSlideCustomPoints(t);
return TREDRAW_HARD;
}
break;
case CKEY:
/* use like a modifier key */
if (event->val == KM_PRESS) {
t->flag ^= T_ALT_TRANSFORM;
calcVertSlideCustomPoints(t);
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: {
/* don't recalculate the best edge */
const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
if (is_clamp) {
calcVertSlideMouseActiveEdges(t, event->mval);
}
calcVertSlideCustomPoints(t);
break;
}
default:
break;
}
}
}
return TREDRAW_NOTHING;
}
void projectVertSlideData(TransInfo *t, bool is_final)
{
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
trans_mesh_customdata_correction_apply(tc, is_final);
}
}
void drawVertSlide(TransInfo *t)
{
if ((t->mode == TFM_VERT_SLIDE) && TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data) {
const VertSlideParams *slp = t->custom.mode.data;
VertSlideData *sld = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data;
const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
/* Non-Prop mode */
{
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;
int i;
GPU_depth_test(false);
GPU_blend(true);
GPU_blend_set_func_separate(
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
GPU_matrix_push();
GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat);
GPU_line_width(line_size);
const uint shdr_pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
immBegin(GPU_PRIM_LINES, sld->totsv * 2);
if (is_clamp) {
sv = sld->sv;
for (i = 0; i < sld->totsv; i++, sv++) {
immVertex3fv(shdr_pos, sv->co_orig_3d);
immVertex3fv(shdr_pos, sv->co_link_orig_3d[sv->co_link_curr]);
}
}
else {
sv = sld->sv;
for (i = 0; i < sld->totsv; i++, sv++) {
float a[3], b[3];
sub_v3_v3v3(a, sv->co_link_orig_3d[sv->co_link_curr], sv->co_orig_3d);
mul_v3_fl(a, 100.0f);
negate_v3_v3(b, a);
add_v3_v3(a, sv->co_orig_3d);
add_v3_v3(b, sv->co_orig_3d);
immVertex3fv(shdr_pos, a);
immVertex3fv(shdr_pos, b);
}
}
immEnd();
GPU_point_size(ctrl_size);
immBegin(GPU_PRIM_POINTS, 1);
immVertex3fv(shdr_pos,
(slp->flipped && slp->use_even) ?
curr_sv->co_link_orig_3d[curr_sv->co_link_curr] :
curr_sv->co_orig_3d);
immEnd();
immUnbindProgram();
/* direction from active vertex! */
if ((t->mval[0] != t->mouse.imval[0]) || (t->mval[1] != t->mouse.imval[1])) {
float zfac;
float mval_ofs[2];
float co_orig_3d[3];
float co_dest_3d[3];
mval_ofs[0] = t->mval[0] - t->mouse.imval[0];
mval_ofs[1] = t->mval[1] - t->mouse.imval[1];
mul_v3_m4v3(
co_orig_3d, TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat, curr_sv->co_orig_3d);
zfac = ED_view3d_calc_zfac(t->ar->regiondata, co_orig_3d, NULL);
ED_view3d_win_to_delta(t->ar, mval_ofs, co_dest_3d, zfac);
invert_m4_m4(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->imat,
TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat);
mul_mat3_m4_v3(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->imat, co_dest_3d);
add_v3_v3(co_dest_3d, curr_sv->co_orig_3d);
GPU_line_width(1.0f);
immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR);
float viewport_size[4];
GPU_viewport_size_get_f(viewport_size);
immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
immUniform1i("colors_len", 0); /* "simple" mode */
immUniformColor4f(1.0f, 1.0f, 1.0f, 1.0f);
immUniform1f("dash_width", 6.0f);
immUniform1f("dash_factor", 0.5f);
immBegin(GPU_PRIM_LINES, 2);
immVertex3fv(shdr_pos, curr_sv->co_orig_3d);
immVertex3fv(shdr_pos, co_dest_3d);
immEnd();
immUnbindProgram();
}
GPU_matrix_pop();
GPU_depth_test(true);
}
}
}
void doVertSlide(TransInfo *t, float perc)
{
VertSlideParams *slp = t->custom.mode.data;
slp->perc = perc;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
VertSlideData *sld = tc->custom.mode.data;
TransDataVertSlideVert *svlist = sld->sv, *sv;
int i;
sv = svlist;
if (slp->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);
}
}
else {
TransDataVertSlideVert *sv_curr = &sld->sv[sld->curr_sv_index];
const float edge_len_curr = len_v3v3(sv_curr->co_orig_3d,
sv_curr->co_link_orig_3d[sv_curr->co_link_curr]);
const float tperc = perc * edge_len_curr;
for (i = 0; i < sld->totsv; i++, sv++) {
float edge_len;
float dir[3];
sub_v3_v3v3(dir, sv->co_link_orig_3d[sv->co_link_curr], sv->co_orig_3d);
edge_len = normalize_v3(dir);
if (edge_len > FLT_EPSILON) {
if (slp->flipped) {
madd_v3_v3v3fl(sv->v->co, sv->co_link_orig_3d[sv->co_link_curr], dir, -tperc);
}
else {
madd_v3_v3v3fl(sv->v->co, sv->co_orig_3d, dir, tperc);
}
}
else {
copy_v3_v3(sv->v->co, sv->co_orig_3d);
}
}
}
}
}
void applyVertSlide(TransInfo *t, const int UNUSED(mval[2]))
{
char str[UI_MAX_DRAW_STR];
size_t ofs = 0;
float final;
VertSlideParams *slp = t->custom.mode.data;
const bool flipped = slp->flipped;
const bool use_even = slp->use_even;
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 */
if (is_constrained) {
CLAMP(final, 0.0f, 1.0f);
}
applyNumInput(&t->num, &final);
t->values_final[0] = final;
/* header string */
ofs += BLI_strncpy_rlen(str + ofs, TIP_("Vert Slide: "), sizeof(str) - ofs);
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, &t->scene->unit);
ofs += BLI_strncpy_rlen(str + ofs, &c[0], sizeof(str) - ofs);
}
else {
ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, "%.4f ", final);
}
ofs += BLI_snprintf(
str + ofs, sizeof(str) - ofs, TIP_("(E)ven: %s, "), WM_bool_as_string(use_even));
if (use_even) {
ofs += BLI_snprintf(
str + ofs, sizeof(str) - ofs, TIP_("(F)lipped: %s, "), WM_bool_as_string(flipped));
}
ofs += BLI_snprintf(
str + ofs, sizeof(str) - ofs, TIP_("Alt or (C)lamp: %s"), WM_bool_as_string(is_clamp));
/* done with header string */
/* do stuff here */
doVertSlide(t, final);
recalcData(t);
ED_area_status_text(t->sa, str);
}
void initVertSlide_ex(TransInfo *t, bool use_even, bool flipped, bool use_clamp)
{
t->mode = TFM_VERT_SLIDE;
t->transform = applyVertSlide;
t->handleEvent = handleEventVertSlide;
{
VertSlideParams *slp = MEM_callocN(sizeof(*slp), __func__);
slp->use_even = use_even;
slp->flipped = flipped;
slp->perc = 0.0f;
if (!use_clamp) {
t->flag |= T_ALT_TRANSFORM;
}
t->custom.mode.data = slp;
t->custom.mode.use_free = true;
}
bool ok = false;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
ok |= createVertSlideVerts(t, tc);
VertSlideData *sld = tc->custom.mode.data;
if (sld) {
tc->custom.mode.free_cb = freeVertSlideVerts;
}
}
if (ok == false) {
t->state = TRANS_CANCEL;
return;
}
trans_mesh_customdata_correction_init(t);
/* set custom point first if you want value to be initialized by init */
calcVertSlideCustomPoints(t);
initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE;
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
void initVertSlide(TransInfo *t)
{
initVertSlide_ex(t, false, false, true);
}
/** \} */