Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/transform/transform.c')
-rw-r--r--source/blender/editors/transform/transform.c15383
1 files changed, 7794 insertions, 7589 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 1358b526bca..944c6436dfb 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -35,7 +35,7 @@
#include "DNA_mask_types.h"
#include "DNA_mesh_types.h"
#include "DNA_movieclip_types.h"
-#include "DNA_scene_types.h" /* PET modes */
+#include "DNA_scene_types.h" /* PET modes */
#include "DNA_workspace_types.h"
#include "DNA_gpencil_types.h"
@@ -107,7 +107,8 @@ static void drawEdgeSlide(TransInfo *t);
static void drawVertSlide(TransInfo *t);
static void postInputRotation(TransInfo *t, float values[3]);
-static void ElementRotation(TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3], const short around);
+static void ElementRotation(
+ TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3], const short around);
static void initSnapSpatial(TransInfo *t, float r_snap[3]);
static void storeCustomLNorValue(TransDataContainer *t, BMesh *bm);
@@ -175,7 +176,8 @@ static void applyBoneEnvelope(TransInfo *t, const int mval[2]);
static void initBoneRoll(TransInfo *t);
static void applyBoneRoll(TransInfo *t, const int mval[2]);
-static void initEdgeSlide_ex(TransInfo *t, bool use_double_side, bool use_even, bool flipped, bool use_clamp);
+static void initEdgeSlide_ex(
+ TransInfo *t, bool use_double_side, bool use_even, bool flipped, bool use_clamp);
static void initEdgeSlide(TransInfo *t);
static eRedrawFlag handleEventEdgeSlide(TransInfo *t, const struct wmEvent *event);
static void applyEdgeSlide(TransInfo *t, const int mval[2]);
@@ -210,496 +212,489 @@ static void initGPOpacity(TransInfo *t);
static void applyGPOpacity(TransInfo *t, const int mval[2]);
/* end transform callbacks */
-
static bool transdata_check_local_center(TransInfo *t, short around)
{
- return ((around == V3D_AROUND_LOCAL_ORIGINS) && (
- (t->flag & (T_OBJECT | T_POSE)) ||
- /* implicit: (t->flag & T_EDIT) */
- (ELEM(t->obedit_type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE, OB_GPENCIL)) ||
- (t->spacetype == SPACE_GRAPH) ||
- (t->options & (CTX_MOVIECLIP | CTX_MASK | CTX_PAINT_CURVE)))
- );
+ return ((around == V3D_AROUND_LOCAL_ORIGINS) &&
+ ((t->flag & (T_OBJECT | T_POSE)) ||
+ /* implicit: (t->flag & T_EDIT) */
+ (ELEM(t->obedit_type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE, OB_GPENCIL)) ||
+ (t->spacetype == SPACE_GRAPH) ||
+ (t->options & (CTX_MOVIECLIP | CTX_MASK | CTX_PAINT_CURVE))));
}
bool transdata_check_local_islands(TransInfo *t, short around)
{
- return ((around == V3D_AROUND_LOCAL_ORIGINS) && (
- (ELEM(t->obedit_type, OB_MESH))));
+ return ((around == V3D_AROUND_LOCAL_ORIGINS) && ((ELEM(t->obedit_type, OB_MESH))));
}
/* ************************** SPACE DEPENDENT CODE **************************** */
void setTransformViewMatrices(TransInfo *t)
{
- if (t->spacetype == SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) {
- RegionView3D *rv3d = t->ar->regiondata;
+ if (t->spacetype == SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3d = t->ar->regiondata;
- copy_m4_m4(t->viewmat, rv3d->viewmat);
- copy_m4_m4(t->viewinv, rv3d->viewinv);
- copy_m4_m4(t->persmat, rv3d->persmat);
- copy_m4_m4(t->persinv, rv3d->persinv);
- t->persp = rv3d->persp;
- }
- else {
- unit_m4(t->viewmat);
- unit_m4(t->viewinv);
- unit_m4(t->persmat);
- unit_m4(t->persinv);
- t->persp = RV3D_ORTHO;
- }
+ copy_m4_m4(t->viewmat, rv3d->viewmat);
+ copy_m4_m4(t->viewinv, rv3d->viewinv);
+ copy_m4_m4(t->persmat, rv3d->persmat);
+ copy_m4_m4(t->persinv, rv3d->persinv);
+ t->persp = rv3d->persp;
+ }
+ else {
+ unit_m4(t->viewmat);
+ unit_m4(t->viewinv);
+ unit_m4(t->persmat);
+ unit_m4(t->persinv);
+ t->persp = RV3D_ORTHO;
+ }
- calculateCenter2D(t);
- calculateCenterLocal(t, t->center_global);
+ calculateCenter2D(t);
+ calculateCenterLocal(t, t->center_global);
}
void setTransformViewAspect(TransInfo *t, float r_aspect[3])
{
- copy_v3_fl(r_aspect, 1.0f);
-
- if (t->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = t->sa->spacedata.first;
-
- if (t->options & CTX_MASK) {
- ED_space_image_get_aspect(sima, &r_aspect[0], &r_aspect[1]);
- }
- else if (t->options & CTX_PAINT_CURVE) {
- /* pass */
- }
- else {
- ED_space_image_get_uv_aspect(sima, &r_aspect[0], &r_aspect[1]);
- }
- }
- else if (t->spacetype == SPACE_CLIP) {
- SpaceClip *sclip = t->sa->spacedata.first;
-
- if (t->options & CTX_MOVIECLIP) {
- ED_space_clip_get_aspect_dimension_aware(sclip, &r_aspect[0], &r_aspect[1]);
- }
- else {
- ED_space_clip_get_aspect(sclip, &r_aspect[0], &r_aspect[1]);
- }
- }
- else if (t->spacetype == SPACE_GRAPH) {
- /* depemds on context of usage */
- }
+ copy_v3_fl(r_aspect, 1.0f);
+
+ if (t->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = t->sa->spacedata.first;
+
+ if (t->options & CTX_MASK) {
+ ED_space_image_get_aspect(sima, &r_aspect[0], &r_aspect[1]);
+ }
+ else if (t->options & CTX_PAINT_CURVE) {
+ /* pass */
+ }
+ else {
+ ED_space_image_get_uv_aspect(sima, &r_aspect[0], &r_aspect[1]);
+ }
+ }
+ else if (t->spacetype == SPACE_CLIP) {
+ SpaceClip *sclip = t->sa->spacedata.first;
+
+ if (t->options & CTX_MOVIECLIP) {
+ ED_space_clip_get_aspect_dimension_aware(sclip, &r_aspect[0], &r_aspect[1]);
+ }
+ else {
+ ED_space_clip_get_aspect(sclip, &r_aspect[0], &r_aspect[1]);
+ }
+ }
+ else if (t->spacetype == SPACE_GRAPH) {
+ /* depemds on context of usage */
+ }
}
static void convertViewVec2D(View2D *v2d, float r_vec[3], int dx, int dy)
{
- float divx = BLI_rcti_size_x(&v2d->mask);
- float divy = BLI_rcti_size_y(&v2d->mask);
+ float divx = BLI_rcti_size_x(&v2d->mask);
+ float divy = BLI_rcti_size_y(&v2d->mask);
- r_vec[0] = BLI_rctf_size_x(&v2d->cur) * dx / divx;
- r_vec[1] = BLI_rctf_size_y(&v2d->cur) * dy / divy;
- r_vec[2] = 0.0f;
+ r_vec[0] = BLI_rctf_size_x(&v2d->cur) * dx / divx;
+ r_vec[1] = BLI_rctf_size_y(&v2d->cur) * dy / divy;
+ r_vec[2] = 0.0f;
}
static void convertViewVec2D_mask(View2D *v2d, float r_vec[3], int dx, int dy)
{
- float divx = BLI_rcti_size_x(&v2d->mask);
- float divy = BLI_rcti_size_y(&v2d->mask);
+ float divx = BLI_rcti_size_x(&v2d->mask);
+ float divy = BLI_rcti_size_y(&v2d->mask);
- float mulx = BLI_rctf_size_x(&v2d->cur);
- float muly = BLI_rctf_size_y(&v2d->cur);
+ float mulx = BLI_rctf_size_x(&v2d->cur);
+ float muly = BLI_rctf_size_y(&v2d->cur);
- /* difference with convertViewVec2D */
- /* clamp w/h, mask only */
- if (mulx / divx < muly / divy) {
- divy = divx;
- muly = mulx;
- }
- else {
- divx = divy;
- mulx = muly;
- }
- /* end difference */
+ /* difference with convertViewVec2D */
+ /* clamp w/h, mask only */
+ if (mulx / divx < muly / divy) {
+ divy = divx;
+ muly = mulx;
+ }
+ else {
+ divx = divy;
+ mulx = muly;
+ }
+ /* end difference */
- r_vec[0] = mulx * dx / divx;
- r_vec[1] = muly * dy / divy;
- r_vec[2] = 0.0f;
+ r_vec[0] = mulx * dx / divx;
+ r_vec[1] = muly * dy / divy;
+ r_vec[2] = 0.0f;
}
void convertViewVec(TransInfo *t, float r_vec[3], double dx, double dy)
{
- if ((t->spacetype == SPACE_VIEW3D) && (t->ar->regiontype == RGN_TYPE_WINDOW)) {
- if (t->options & CTX_PAINT_CURVE) {
- r_vec[0] = dx;
- r_vec[1] = dy;
- }
- else {
- const float mval_f[2] = {(float)dx, (float)dy};
- ED_view3d_win_to_delta(t->ar, mval_f, r_vec, t->zfac);
- }
- }
- else if (t->spacetype == SPACE_IMAGE) {
- if (t->options & CTX_MASK) {
- convertViewVec2D_mask(t->view, r_vec, dx, dy);
- }
- else if (t->options & CTX_PAINT_CURVE) {
- r_vec[0] = dx;
- r_vec[1] = dy;
- }
- else {
- convertViewVec2D(t->view, r_vec, dx, dy);
- }
-
- r_vec[0] *= t->aspect[0];
- r_vec[1] *= t->aspect[1];
- }
- else if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA)) {
- convertViewVec2D(t->view, r_vec, dx, dy);
- }
- else if (ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) {
- convertViewVec2D(&t->ar->v2d, r_vec, dx, dy);
- }
- else if (t->spacetype == SPACE_CLIP) {
- if (t->options & CTX_MASK) {
- convertViewVec2D_mask(t->view, r_vec, dx, dy);
- }
- else {
- convertViewVec2D(t->view, r_vec, dx, dy);
- }
-
- r_vec[0] *= t->aspect[0];
- r_vec[1] *= t->aspect[1];
- }
- else {
- printf("%s: called in an invalid context\n", __func__);
- zero_v3(r_vec);
- }
+ if ((t->spacetype == SPACE_VIEW3D) && (t->ar->regiontype == RGN_TYPE_WINDOW)) {
+ if (t->options & CTX_PAINT_CURVE) {
+ r_vec[0] = dx;
+ r_vec[1] = dy;
+ }
+ else {
+ const float mval_f[2] = {(float)dx, (float)dy};
+ ED_view3d_win_to_delta(t->ar, mval_f, r_vec, t->zfac);
+ }
+ }
+ else if (t->spacetype == SPACE_IMAGE) {
+ if (t->options & CTX_MASK) {
+ convertViewVec2D_mask(t->view, r_vec, dx, dy);
+ }
+ else if (t->options & CTX_PAINT_CURVE) {
+ r_vec[0] = dx;
+ r_vec[1] = dy;
+ }
+ else {
+ convertViewVec2D(t->view, r_vec, dx, dy);
+ }
+
+ r_vec[0] *= t->aspect[0];
+ r_vec[1] *= t->aspect[1];
+ }
+ else if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA)) {
+ convertViewVec2D(t->view, r_vec, dx, dy);
+ }
+ else if (ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) {
+ convertViewVec2D(&t->ar->v2d, r_vec, dx, dy);
+ }
+ else if (t->spacetype == SPACE_CLIP) {
+ if (t->options & CTX_MASK) {
+ convertViewVec2D_mask(t->view, r_vec, dx, dy);
+ }
+ else {
+ convertViewVec2D(t->view, r_vec, dx, dy);
+ }
+
+ r_vec[0] *= t->aspect[0];
+ r_vec[1] *= t->aspect[1];
+ }
+ else {
+ printf("%s: called in an invalid context\n", __func__);
+ zero_v3(r_vec);
+ }
}
void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DProjTest flag)
{
- if (t->spacetype == SPACE_VIEW3D) {
- if (t->ar->regiontype == RGN_TYPE_WINDOW) {
- if (ED_view3d_project_int_global(t->ar, vec, adr, flag) != V3D_PROJ_RET_OK) {
- /* this is what was done in 2.64, perhaps we can be smarter? */
- adr[0] = (int)2140000000.0f;
- adr[1] = (int)2140000000.0f;
- }
- }
- }
- else if (t->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = t->sa->spacedata.first;
-
- if (t->options & CTX_MASK) {
- float v[2];
-
- v[0] = vec[0] / t->aspect[0];
- v[1] = vec[1] / t->aspect[1];
-
- BKE_mask_coord_to_image(sima->image, &sima->iuser, v, v);
-
- ED_image_point_pos__reverse(sima, t->ar, v, v);
-
- adr[0] = v[0];
- adr[1] = v[1];
- }
- else if (t->options & CTX_PAINT_CURVE) {
- adr[0] = vec[0];
- adr[1] = vec[1];
- }
- else {
- float v[2];
-
- v[0] = vec[0] / t->aspect[0];
- v[1] = vec[1] / t->aspect[1];
-
- UI_view2d_view_to_region(t->view, v[0], v[1], &adr[0], &adr[1]);
- }
- }
- else if (t->spacetype == SPACE_ACTION) {
- int out[2] = {0, 0};
+ if (t->spacetype == SPACE_VIEW3D) {
+ if (t->ar->regiontype == RGN_TYPE_WINDOW) {
+ if (ED_view3d_project_int_global(t->ar, vec, adr, flag) != V3D_PROJ_RET_OK) {
+ /* this is what was done in 2.64, perhaps we can be smarter? */
+ adr[0] = (int)2140000000.0f;
+ adr[1] = (int)2140000000.0f;
+ }
+ }
+ }
+ else if (t->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = t->sa->spacedata.first;
+
+ if (t->options & CTX_MASK) {
+ float v[2];
+
+ v[0] = vec[0] / t->aspect[0];
+ v[1] = vec[1] / t->aspect[1];
+
+ BKE_mask_coord_to_image(sima->image, &sima->iuser, v, v);
+
+ ED_image_point_pos__reverse(sima, t->ar, v, v);
+
+ adr[0] = v[0];
+ adr[1] = v[1];
+ }
+ else if (t->options & CTX_PAINT_CURVE) {
+ adr[0] = vec[0];
+ adr[1] = vec[1];
+ }
+ else {
+ float v[2];
+
+ v[0] = vec[0] / t->aspect[0];
+ v[1] = vec[1] / t->aspect[1];
+
+ UI_view2d_view_to_region(t->view, v[0], v[1], &adr[0], &adr[1]);
+ }
+ }
+ else if (t->spacetype == SPACE_ACTION) {
+ int out[2] = {0, 0};
#if 0
- SpaceAction *sact = t->sa->spacedata.first;
-
- if (sact->flag & SACTION_DRAWTIME) {
- //vec[0] = vec[0]/((t->scene->r.frs_sec / t->scene->r.frs_sec_base));
- /* same as below */
- UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &out[0], &out[1]);
- }
- else
+ SpaceAction *sact = t->sa->spacedata.first;
+
+ if (sact->flag & SACTION_DRAWTIME) {
+ //vec[0] = vec[0]/((t->scene->r.frs_sec / t->scene->r.frs_sec_base));
+ /* same as below */
+ UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &out[0], &out[1]);
+ }
+ else
#endif
- {
- UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &out[0], &out[1]);
- }
-
- adr[0] = out[0];
- adr[1] = out[1];
- }
- else if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA)) {
- int out[2] = {0, 0};
-
- UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &out[0], &out[1]);
- adr[0] = out[0];
- adr[1] = out[1];
- }
- else if (t->spacetype == SPACE_SEQ) { /* XXX not tested yet, but should work */
- int out[2] = {0, 0};
-
- UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &out[0], &out[1]);
- adr[0] = out[0];
- adr[1] = out[1];
- }
- else if (t->spacetype == SPACE_CLIP) {
- SpaceClip *sc = t->sa->spacedata.first;
-
- if (t->options & CTX_MASK) {
- MovieClip *clip = ED_space_clip_get_clip(sc);
-
- if (clip) {
- float v[2];
-
- v[0] = vec[0] / t->aspect[0];
- v[1] = vec[1] / t->aspect[1];
-
- BKE_mask_coord_to_movieclip(sc->clip, &sc->user, v, v);
-
- ED_clip_point_stable_pos__reverse(sc, t->ar, v, v);
-
- adr[0] = v[0];
- adr[1] = v[1];
- }
- else {
- adr[0] = 0;
- adr[1] = 0;
- }
- }
- else if (t->options & CTX_MOVIECLIP) {
- float v[2];
-
- v[0] = vec[0] / t->aspect[0];
- v[1] = vec[1] / t->aspect[1];
-
- UI_view2d_view_to_region(t->view, v[0], v[1], &adr[0], &adr[1]);
- }
- else {
- BLI_assert(0);
- }
- }
- else if (t->spacetype == SPACE_NODE) {
- UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &adr[0], &adr[1]);
- }
+ {
+ UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &out[0], &out[1]);
+ }
+
+ adr[0] = out[0];
+ adr[1] = out[1];
+ }
+ else if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA)) {
+ int out[2] = {0, 0};
+
+ UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &out[0], &out[1]);
+ adr[0] = out[0];
+ adr[1] = out[1];
+ }
+ else if (t->spacetype == SPACE_SEQ) { /* XXX not tested yet, but should work */
+ int out[2] = {0, 0};
+
+ UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &out[0], &out[1]);
+ adr[0] = out[0];
+ adr[1] = out[1];
+ }
+ else if (t->spacetype == SPACE_CLIP) {
+ SpaceClip *sc = t->sa->spacedata.first;
+
+ if (t->options & CTX_MASK) {
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+
+ if (clip) {
+ float v[2];
+
+ v[0] = vec[0] / t->aspect[0];
+ v[1] = vec[1] / t->aspect[1];
+
+ BKE_mask_coord_to_movieclip(sc->clip, &sc->user, v, v);
+
+ ED_clip_point_stable_pos__reverse(sc, t->ar, v, v);
+
+ adr[0] = v[0];
+ adr[1] = v[1];
+ }
+ else {
+ adr[0] = 0;
+ adr[1] = 0;
+ }
+ }
+ else if (t->options & CTX_MOVIECLIP) {
+ float v[2];
+
+ v[0] = vec[0] / t->aspect[0];
+ v[1] = vec[1] / t->aspect[1];
+
+ UI_view2d_view_to_region(t->view, v[0], v[1], &adr[0], &adr[1]);
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ else if (t->spacetype == SPACE_NODE) {
+ UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &adr[0], &adr[1]);
+ }
}
void projectIntView(TransInfo *t, const float vec[3], int adr[2])
{
- projectIntViewEx(t, vec, adr, V3D_PROJ_TEST_NOP);
+ projectIntViewEx(t, vec, adr, V3D_PROJ_TEST_NOP);
}
void projectFloatViewEx(TransInfo *t, const float vec[3], float adr[2], const eV3DProjTest flag)
{
- switch (t->spacetype) {
- case SPACE_VIEW3D:
- {
- if (t->options & CTX_PAINT_CURVE) {
- adr[0] = vec[0];
- adr[1] = vec[1];
- }
- else if (t->ar->regiontype == RGN_TYPE_WINDOW) {
- /* allow points behind the view [#33643] */
- if (ED_view3d_project_float_global(t->ar, vec, adr, flag) != V3D_PROJ_RET_OK) {
- /* XXX, 2.64 and prior did this, weak! */
- adr[0] = t->ar->winx / 2.0f;
- adr[1] = t->ar->winy / 2.0f;
- }
- return;
- }
- break;
- }
- default:
- {
- int a[2] = {0, 0};
- projectIntView(t, vec, a);
- adr[0] = a[0];
- adr[1] = a[1];
- break;
- }
- }
+ switch (t->spacetype) {
+ case SPACE_VIEW3D: {
+ if (t->options & CTX_PAINT_CURVE) {
+ adr[0] = vec[0];
+ adr[1] = vec[1];
+ }
+ else if (t->ar->regiontype == RGN_TYPE_WINDOW) {
+ /* allow points behind the view [#33643] */
+ if (ED_view3d_project_float_global(t->ar, vec, adr, flag) != V3D_PROJ_RET_OK) {
+ /* XXX, 2.64 and prior did this, weak! */
+ adr[0] = t->ar->winx / 2.0f;
+ adr[1] = t->ar->winy / 2.0f;
+ }
+ return;
+ }
+ break;
+ }
+ default: {
+ int a[2] = {0, 0};
+ projectIntView(t, vec, a);
+ adr[0] = a[0];
+ adr[1] = a[1];
+ break;
+ }
+ }
}
void projectFloatView(TransInfo *t, const float vec[3], float adr[2])
{
- projectFloatViewEx(t, vec, adr, V3D_PROJ_TEST_NOP);
+ projectFloatViewEx(t, vec, adr, V3D_PROJ_TEST_NOP);
}
void applyAspectRatio(TransInfo *t, float vec[2])
{
- if ((t->spacetype == SPACE_IMAGE) && (t->mode == TFM_TRANSLATION) && !(t->options & CTX_PAINT_CURVE)) {
- SpaceImage *sima = t->sa->spacedata.first;
+ if ((t->spacetype == SPACE_IMAGE) && (t->mode == TFM_TRANSLATION) &&
+ !(t->options & CTX_PAINT_CURVE)) {
+ SpaceImage *sima = t->sa->spacedata.first;
- if ((sima->flag & SI_COORDFLOATS) == 0) {
- int width, height;
- ED_space_image_get_size(sima, &width, &height);
+ if ((sima->flag & SI_COORDFLOATS) == 0) {
+ int width, height;
+ ED_space_image_get_size(sima, &width, &height);
- vec[0] *= width;
- vec[1] *= height;
- }
+ vec[0] *= width;
+ vec[1] *= height;
+ }
- vec[0] /= t->aspect[0];
- vec[1] /= t->aspect[1];
- }
- else if ((t->spacetype == SPACE_CLIP) && (t->mode == TFM_TRANSLATION)) {
- if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
- vec[0] /= t->aspect[0];
- vec[1] /= t->aspect[1];
- }
- }
+ vec[0] /= t->aspect[0];
+ vec[1] /= t->aspect[1];
+ }
+ else if ((t->spacetype == SPACE_CLIP) && (t->mode == TFM_TRANSLATION)) {
+ if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
+ vec[0] /= t->aspect[0];
+ vec[1] /= t->aspect[1];
+ }
+ }
}
void removeAspectRatio(TransInfo *t, float vec[2])
{
- if ((t->spacetype == SPACE_IMAGE) && (t->mode == TFM_TRANSLATION)) {
- SpaceImage *sima = t->sa->spacedata.first;
+ if ((t->spacetype == SPACE_IMAGE) && (t->mode == TFM_TRANSLATION)) {
+ SpaceImage *sima = t->sa->spacedata.first;
- if ((sima->flag & SI_COORDFLOATS) == 0) {
- int width, height;
- ED_space_image_get_size(sima, &width, &height);
+ if ((sima->flag & SI_COORDFLOATS) == 0) {
+ int width, height;
+ ED_space_image_get_size(sima, &width, &height);
- vec[0] /= width;
- vec[1] /= height;
- }
+ vec[0] /= width;
+ vec[1] /= height;
+ }
- vec[0] *= t->aspect[0];
- vec[1] *= t->aspect[1];
- }
- else if ((t->spacetype == SPACE_CLIP) && (t->mode == TFM_TRANSLATION)) {
- if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
- vec[0] *= t->aspect[0];
- vec[1] *= t->aspect[1];
- }
- }
+ vec[0] *= t->aspect[0];
+ vec[1] *= t->aspect[1];
+ }
+ else if ((t->spacetype == SPACE_CLIP) && (t->mode == TFM_TRANSLATION)) {
+ if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
+ vec[0] *= t->aspect[0];
+ vec[1] *= t->aspect[1];
+ }
+ }
}
static void viewRedrawForce(const bContext *C, TransInfo *t)
{
- if (t->options & CTX_GPENCIL_STROKES) {
- bGPdata *gpd = ED_gpencil_data_get_active(C);
- if (gpd) {
- DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY);
- }
- WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
- }
- else if (t->spacetype == SPACE_VIEW3D) {
- if (t->options & CTX_PAINT_CURVE) {
- wmWindow *window = CTX_wm_window(C);
- WM_paint_cursor_tag_redraw(window, t->ar);
- }
- else {
- /* Do we need more refined tags? */
- if (t->flag & T_POSE)
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
- else
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
-
- /* For real-time animation record - send notifiers recognized by animation editors */
- // XXX: is this notifier a lame duck?
- if ((t->animtimer) && IS_AUTOKEY_ON(t->scene))
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL);
-
- }
- }
- else if (t->spacetype == SPACE_ACTION) {
- //SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first;
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- }
- else if (t->spacetype == SPACE_GRAPH) {
- //SpaceGraph *sipo = (SpaceGraph *)t->sa->spacedata.first;
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- }
- else if (t->spacetype == SPACE_NLA) {
- WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
- }
- else if (t->spacetype == SPACE_NODE) {
- //ED_area_tag_redraw(t->sa);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
- }
- else if (t->spacetype == SPACE_SEQ) {
- WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, NULL);
- }
- else if (t->spacetype == SPACE_IMAGE) {
- if (t->options & CTX_MASK) {
- Mask *mask = CTX_data_edit_mask(C);
-
- WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
- }
- else if (t->options & CTX_PAINT_CURVE) {
- wmWindow *window = CTX_wm_window(C);
- WM_paint_cursor_tag_redraw(window, t->ar);
- }
- else if (t->flag & T_CURSOR) {
- ED_area_tag_redraw(t->sa);
- }
- else {
- // XXX how to deal with lock?
- SpaceImage *sima = (SpaceImage *)t->sa->spacedata.first;
- if (sima->lock) {
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, OBEDIT_FROM_VIEW_LAYER(t->view_layer)->data);
- }
- else {
- ED_area_tag_redraw(t->sa);
- }
- }
- }
- else if (t->spacetype == SPACE_CLIP) {
- SpaceClip *sc = (SpaceClip *)t->sa->spacedata.first;
-
- if (ED_space_clip_check_show_trackedit(sc)) {
- MovieClip *clip = ED_space_clip_get_clip(sc);
-
- /* objects could be parented to tracking data, so send this for viewport refresh */
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
-
- WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
- }
- else if (ED_space_clip_check_show_maskedit(sc)) {
- Mask *mask = CTX_data_edit_mask(C);
-
- WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
- }
- }
+ if (t->options & CTX_GPENCIL_STROKES) {
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ if (gpd) {
+ DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY);
+ }
+ WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
+ }
+ else if (t->spacetype == SPACE_VIEW3D) {
+ if (t->options & CTX_PAINT_CURVE) {
+ wmWindow *window = CTX_wm_window(C);
+ WM_paint_cursor_tag_redraw(window, t->ar);
+ }
+ else {
+ /* Do we need more refined tags? */
+ if (t->flag & T_POSE)
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+ else
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
+
+ /* For real-time animation record - send notifiers recognized by animation editors */
+ // XXX: is this notifier a lame duck?
+ if ((t->animtimer) && IS_AUTOKEY_ON(t->scene))
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL);
+ }
+ }
+ else if (t->spacetype == SPACE_ACTION) {
+ //SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first;
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ }
+ else if (t->spacetype == SPACE_GRAPH) {
+ //SpaceGraph *sipo = (SpaceGraph *)t->sa->spacedata.first;
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ }
+ else if (t->spacetype == SPACE_NLA) {
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
+ }
+ else if (t->spacetype == SPACE_NODE) {
+ //ED_area_tag_redraw(t->sa);
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
+ }
+ else if (t->spacetype == SPACE_SEQ) {
+ WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, NULL);
+ }
+ else if (t->spacetype == SPACE_IMAGE) {
+ if (t->options & CTX_MASK) {
+ Mask *mask = CTX_data_edit_mask(C);
+
+ WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
+ }
+ else if (t->options & CTX_PAINT_CURVE) {
+ wmWindow *window = CTX_wm_window(C);
+ WM_paint_cursor_tag_redraw(window, t->ar);
+ }
+ else if (t->flag & T_CURSOR) {
+ ED_area_tag_redraw(t->sa);
+ }
+ else {
+ // XXX how to deal with lock?
+ SpaceImage *sima = (SpaceImage *)t->sa->spacedata.first;
+ if (sima->lock) {
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, OBEDIT_FROM_VIEW_LAYER(t->view_layer)->data);
+ }
+ else {
+ ED_area_tag_redraw(t->sa);
+ }
+ }
+ }
+ else if (t->spacetype == SPACE_CLIP) {
+ SpaceClip *sc = (SpaceClip *)t->sa->spacedata.first;
+
+ if (ED_space_clip_check_show_trackedit(sc)) {
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+
+ /* objects could be parented to tracking data, so send this for viewport refresh */
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
+
+ WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
+ }
+ else if (ED_space_clip_check_show_maskedit(sc)) {
+ Mask *mask = CTX_data_edit_mask(C);
+
+ WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
+ }
+ }
}
static void viewRedrawPost(bContext *C, TransInfo *t)
{
- ED_area_status_text(t->sa, NULL);
-
- if (t->spacetype == SPACE_VIEW3D) {
- /* if autokeying is enabled, send notifiers that keyframes were added */
- if (IS_AUTOKEY_ON(t->scene))
- WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
- /* redraw UV editor */
- if (ELEM(t->mode, TFM_VERT_SLIDE, TFM_EDGE_SLIDE) &&
- (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT))
- {
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
- }
-
- /* XXX temp, first hack to get auto-render in compositor work (ton) */
- WM_event_add_notifier(C, NC_SCENE | ND_TRANSFORM_DONE, CTX_data_scene(C));
-
- }
-
-#if 0 // TRANSFORM_FIX_ME
- if (t->spacetype == SPACE_VIEW3D) {
- allqueue(REDRAWBUTSOBJECT, 0);
- allqueue(REDRAWVIEW3D, 0);
- }
- else if (t->spacetype == SPACE_IMAGE) {
- allqueue(REDRAWIMAGE, 0);
- allqueue(REDRAWVIEW3D, 0);
- }
- else if (ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA, SPACE_GRAPH)) {
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWBUTSOBJECT, 0);
- }
-
- scrarea_queue_headredraw(curarea);
+ ED_area_status_text(t->sa, NULL);
+
+ if (t->spacetype == SPACE_VIEW3D) {
+ /* if autokeying is enabled, send notifiers that keyframes were added */
+ if (IS_AUTOKEY_ON(t->scene))
+ WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+
+ /* redraw UV editor */
+ if (ELEM(t->mode, TFM_VERT_SLIDE, TFM_EDGE_SLIDE) &&
+ (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) {
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
+ }
+
+ /* XXX temp, first hack to get auto-render in compositor work (ton) */
+ WM_event_add_notifier(C, NC_SCENE | ND_TRANSFORM_DONE, CTX_data_scene(C));
+ }
+
+#if 0 // TRANSFORM_FIX_ME
+ if (t->spacetype == SPACE_VIEW3D) {
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ else if (t->spacetype == SPACE_IMAGE) {
+ allqueue(REDRAWIMAGE, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ else if (ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA, SPACE_GRAPH)) {
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWTIME, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ }
+
+ scrarea_queue_headredraw(curarea);
#endif
}
@@ -707,81 +702,81 @@ static void viewRedrawPost(bContext *C, TransInfo *t)
static void view_editmove(unsigned short UNUSED(event))
{
-#if 0 // TRANSFORM_FIX_ME
- int refresh = 0;
- /* Regular: Zoom in */
- /* Shift: Scroll up */
- /* Ctrl: Scroll right */
- /* Alt-Shift: Rotate up */
- /* Alt-Ctrl: Rotate right */
-
- /* only work in 3D window for now
- * In the end, will have to send to event to a 2D window handler instead
- */
- if (Trans.flag & T_2D_EDIT)
- return;
-
- switch (event) {
- case WHEELUPMOUSE:
- if (G.qual & LR_SHIFTKEY) {
- if (G.qual & LR_ALTKEY) {
- G.qual &= ~LR_SHIFTKEY;
- persptoetsen(PAD2);
- G.qual |= LR_SHIFTKEY;
- }
- else {
- persptoetsen(PAD2);
- }
- }
- else if (G.qual & LR_CTRLKEY) {
- if (G.qual & LR_ALTKEY) {
- G.qual &= ~LR_CTRLKEY;
- persptoetsen(PAD4);
- G.qual |= LR_CTRLKEY;
- }
- else {
- persptoetsen(PAD4);
- }
- }
- else if (U.uiflag & USER_WHEELZOOMDIR)
- persptoetsen(PADMINUS);
- else
- persptoetsen(PADPLUSKEY);
-
- refresh = 1;
- break;
- case WHEELDOWNMOUSE:
- if (G.qual & LR_SHIFTKEY) {
- if (G.qual & LR_ALTKEY) {
- G.qual &= ~LR_SHIFTKEY;
- persptoetsen(PAD8);
- G.qual |= LR_SHIFTKEY;
- }
- else {
- persptoetsen(PAD8);
- }
- }
- else if (G.qual & LR_CTRLKEY) {
- if (G.qual & LR_ALTKEY) {
- G.qual &= ~LR_CTRLKEY;
- persptoetsen(PAD6);
- G.qual |= LR_CTRLKEY;
- }
- else {
- persptoetsen(PAD6);
- }
- }
- else if (U.uiflag & USER_WHEELZOOMDIR)
- persptoetsen(PADPLUSKEY);
- else
- persptoetsen(PADMINUS);
-
- refresh = 1;
- break;
- }
-
- if (refresh)
- setTransformViewMatrices(&Trans);
+#if 0 // TRANSFORM_FIX_ME
+ int refresh = 0;
+ /* Regular: Zoom in */
+ /* Shift: Scroll up */
+ /* Ctrl: Scroll right */
+ /* Alt-Shift: Rotate up */
+ /* Alt-Ctrl: Rotate right */
+
+ /* only work in 3D window for now
+ * In the end, will have to send to event to a 2D window handler instead
+ */
+ if (Trans.flag & T_2D_EDIT)
+ return;
+
+ switch (event) {
+ case WHEELUPMOUSE:
+ if (G.qual & LR_SHIFTKEY) {
+ if (G.qual & LR_ALTKEY) {
+ G.qual &= ~LR_SHIFTKEY;
+ persptoetsen(PAD2);
+ G.qual |= LR_SHIFTKEY;
+ }
+ else {
+ persptoetsen(PAD2);
+ }
+ }
+ else if (G.qual & LR_CTRLKEY) {
+ if (G.qual & LR_ALTKEY) {
+ G.qual &= ~LR_CTRLKEY;
+ persptoetsen(PAD4);
+ G.qual |= LR_CTRLKEY;
+ }
+ else {
+ persptoetsen(PAD4);
+ }
+ }
+ else if (U.uiflag & USER_WHEELZOOMDIR)
+ persptoetsen(PADMINUS);
+ else
+ persptoetsen(PADPLUSKEY);
+
+ refresh = 1;
+ break;
+ case WHEELDOWNMOUSE:
+ if (G.qual & LR_SHIFTKEY) {
+ if (G.qual & LR_ALTKEY) {
+ G.qual &= ~LR_SHIFTKEY;
+ persptoetsen(PAD8);
+ G.qual |= LR_SHIFTKEY;
+ }
+ else {
+ persptoetsen(PAD8);
+ }
+ }
+ else if (G.qual & LR_CTRLKEY) {
+ if (G.qual & LR_ALTKEY) {
+ G.qual &= ~LR_CTRLKEY;
+ persptoetsen(PAD6);
+ G.qual |= LR_CTRLKEY;
+ }
+ else {
+ persptoetsen(PAD6);
+ }
+ }
+ else if (U.uiflag & USER_WHEELZOOMDIR)
+ persptoetsen(PADPLUSKEY);
+ else
+ persptoetsen(PADMINUS);
+
+ refresh = 1;
+ break;
+ }
+
+ if (refresh)
+ setTransformViewMatrices(&Trans);
#endif
}
@@ -789,885 +784,898 @@ static void view_editmove(unsigned short UNUSED(event))
/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
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,
+ 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,
};
static bool transform_modal_item_poll(const wmOperator *op, int value)
{
- const TransInfo *t = op->customdata;
- switch (value) {
- case TFM_MODAL_CANCEL:
- {
- if ((t->flag & T_RELEASE_CONFIRM) && ISMOUSE(t->launch_event)) {
- return false;
- }
- break;
- }
- case TFM_MODAL_PROPSIZE:
- case TFM_MODAL_PROPSIZE_UP:
- case TFM_MODAL_PROPSIZE_DOWN:
- {
- if ((t->flag & T_PROP_EDIT) == 0) {
- return false;
- }
- break;
- }
- case TFM_MODAL_ADD_SNAP:
- case TFM_MODAL_REMOVE_SNAP:
- {
- if (t->spacetype != SPACE_VIEW3D) {
- return false;
- }
- else if (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) {
- return false;
- }
- else if (!validSnap(t)) {
- return false;
- }
- break;
- }
- case TFM_MODAL_AXIS_X:
- case TFM_MODAL_AXIS_Y:
- case TFM_MODAL_AXIS_Z:
- case TFM_MODAL_PLANE_X:
- case TFM_MODAL_PLANE_Y:
- case TFM_MODAL_PLANE_Z:
- {
- if (t->flag & T_NO_CONSTRAINT) {
- return false;
- }
- if (!ELEM(value, TFM_MODAL_AXIS_X, TFM_MODAL_AXIS_Y)) {
- if (t->flag & T_2D_EDIT) {
- return false;
- }
- }
- break;
- }
- case TFM_MODAL_CONS_OFF:
- {
- if ((t->con.mode & CON_APPLY) == 0) {
- return false;
- }
- break;
- }
- case TFM_MODAL_EDGESLIDE_UP:
- case TFM_MODAL_EDGESLIDE_DOWN:
- {
- if (t->mode != TFM_EDGE_SLIDE) {
- return false;
- }
- break;
- }
- case TFM_MODAL_INSERTOFS_TOGGLE_DIR:
- {
- if (t->spacetype != SPACE_NODE) {
- return false;
- }
- break;
- }
- case TFM_MODAL_AUTOIK_LEN_INC:
- case TFM_MODAL_AUTOIK_LEN_DEC:
- {
- if ((t->flag & T_AUTOIK) == 0) {
- return false;
- }
- break;
- }
- }
- return true;
+ const TransInfo *t = op->customdata;
+ switch (value) {
+ case TFM_MODAL_CANCEL: {
+ if ((t->flag & T_RELEASE_CONFIRM) && ISMOUSE(t->launch_event)) {
+ return false;
+ }
+ break;
+ }
+ case TFM_MODAL_PROPSIZE:
+ case TFM_MODAL_PROPSIZE_UP:
+ case TFM_MODAL_PROPSIZE_DOWN: {
+ if ((t->flag & T_PROP_EDIT) == 0) {
+ return false;
+ }
+ break;
+ }
+ case TFM_MODAL_ADD_SNAP:
+ case TFM_MODAL_REMOVE_SNAP: {
+ if (t->spacetype != SPACE_VIEW3D) {
+ return false;
+ }
+ else if (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) {
+ return false;
+ }
+ else if (!validSnap(t)) {
+ return false;
+ }
+ break;
+ }
+ case TFM_MODAL_AXIS_X:
+ case TFM_MODAL_AXIS_Y:
+ case TFM_MODAL_AXIS_Z:
+ case TFM_MODAL_PLANE_X:
+ case TFM_MODAL_PLANE_Y:
+ case TFM_MODAL_PLANE_Z: {
+ if (t->flag & T_NO_CONSTRAINT) {
+ return false;
+ }
+ if (!ELEM(value, TFM_MODAL_AXIS_X, TFM_MODAL_AXIS_Y)) {
+ if (t->flag & T_2D_EDIT) {
+ return false;
+ }
+ }
+ break;
+ }
+ case TFM_MODAL_CONS_OFF: {
+ if ((t->con.mode & CON_APPLY) == 0) {
+ return false;
+ }
+ break;
+ }
+ case TFM_MODAL_EDGESLIDE_UP:
+ case TFM_MODAL_EDGESLIDE_DOWN: {
+ if (t->mode != TFM_EDGE_SLIDE) {
+ return false;
+ }
+ break;
+ }
+ case TFM_MODAL_INSERTOFS_TOGGLE_DIR: {
+ if (t->spacetype != SPACE_NODE) {
+ return false;
+ }
+ break;
+ }
+ case TFM_MODAL_AUTOIK_LEN_INC:
+ case TFM_MODAL_AUTOIK_LEN_DEC: {
+ if ((t->flag & T_AUTOIK) == 0) {
+ return false;
+ }
+ break;
+ }
+ }
+ return true;
}
/* called in transform_ops.c, on each regeneration of keymaps */
wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
{
- static const EnumPropertyItem modal_items[] = {
- {TFM_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
- {TFM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
- {TFM_MODAL_AXIS_X, "AXIS_X", 0, "X axis", ""},
- {TFM_MODAL_AXIS_Y, "AXIS_Y", 0, "Y axis", ""},
- {TFM_MODAL_AXIS_Z, "AXIS_Z", 0, "Z axis", ""},
- {TFM_MODAL_PLANE_X, "PLANE_X", 0, "X plane", ""},
- {TFM_MODAL_PLANE_Y, "PLANE_Y", 0, "Y plane", ""},
- {TFM_MODAL_PLANE_Z, "PLANE_Z", 0, "Z plane", ""},
- {TFM_MODAL_CONS_OFF, "CONS_OFF", 0, "Clear Constraints", ""},
- {TFM_MODAL_SNAP_INV_ON, "SNAP_INV_ON", 0, "Snap Invert", ""},
- {TFM_MODAL_SNAP_INV_OFF, "SNAP_INV_OFF", 0, "Snap Invert (Off)", ""},
- {TFM_MODAL_SNAP_TOGGLE, "SNAP_TOGGLE", 0, "Snap Toggle", ""},
- {TFM_MODAL_ADD_SNAP, "ADD_SNAP", 0, "Add Snap Point", ""},
- {TFM_MODAL_REMOVE_SNAP, "REMOVE_SNAP", 0, "Remove Last Snap Point", ""},
- {NUM_MODAL_INCREMENT_UP, "INCREMENT_UP", 0, "Numinput Increment Up", ""},
- {NUM_MODAL_INCREMENT_DOWN, "INCREMENT_DOWN", 0, "Numinput Increment Down", ""},
- {TFM_MODAL_PROPSIZE_UP, "PROPORTIONAL_SIZE_UP", 0, "Increase Proportional Influence", ""},
- {TFM_MODAL_PROPSIZE_DOWN, "PROPORTIONAL_SIZE_DOWN", 0, "Decrease Proportional Influence", ""},
- {TFM_MODAL_AUTOIK_LEN_INC, "AUTOIK_CHAIN_LEN_UP", 0, "Increase Max AutoIK Chain Length", ""},
- {TFM_MODAL_AUTOIK_LEN_DEC, "AUTOIK_CHAIN_LEN_DOWN", 0, "Decrease Max AutoIK Chain Length", ""},
- {TFM_MODAL_EDGESLIDE_UP, "EDGESLIDE_EDGE_NEXT", 0, "Select next Edge Slide Edge", ""},
- {TFM_MODAL_EDGESLIDE_DOWN, "EDGESLIDE_PREV_NEXT", 0, "Select previous Edge Slide Edge", ""},
- {TFM_MODAL_PROPSIZE, "PROPORTIONAL_SIZE", 0, "Adjust Proportional Influence", ""},
- {TFM_MODAL_INSERTOFS_TOGGLE_DIR, "INSERTOFS_TOGGLE_DIR", 0, "Toggle Direction for Node Auto-offset", ""},
- {TFM_MODAL_TRANSLATE, "TRANSLATE", 0, "Move", ""},
- {TFM_MODAL_ROTATE, "ROTATE", 0, "Rotate", ""},
- {TFM_MODAL_RESIZE, "RESIZE", 0, "Resize", ""},
- {0, NULL, 0, NULL, NULL},
- };
-
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Transform Modal Map");
-
- keymap = WM_modalkeymap_add(keyconf, "Transform Modal Map", modal_items);
- keymap->poll_modal_item = transform_modal_item_poll;
-
- return keymap;
+ static const EnumPropertyItem modal_items[] = {
+ {TFM_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+ {TFM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
+ {TFM_MODAL_AXIS_X, "AXIS_X", 0, "X axis", ""},
+ {TFM_MODAL_AXIS_Y, "AXIS_Y", 0, "Y axis", ""},
+ {TFM_MODAL_AXIS_Z, "AXIS_Z", 0, "Z axis", ""},
+ {TFM_MODAL_PLANE_X, "PLANE_X", 0, "X plane", ""},
+ {TFM_MODAL_PLANE_Y, "PLANE_Y", 0, "Y plane", ""},
+ {TFM_MODAL_PLANE_Z, "PLANE_Z", 0, "Z plane", ""},
+ {TFM_MODAL_CONS_OFF, "CONS_OFF", 0, "Clear Constraints", ""},
+ {TFM_MODAL_SNAP_INV_ON, "SNAP_INV_ON", 0, "Snap Invert", ""},
+ {TFM_MODAL_SNAP_INV_OFF, "SNAP_INV_OFF", 0, "Snap Invert (Off)", ""},
+ {TFM_MODAL_SNAP_TOGGLE, "SNAP_TOGGLE", 0, "Snap Toggle", ""},
+ {TFM_MODAL_ADD_SNAP, "ADD_SNAP", 0, "Add Snap Point", ""},
+ {TFM_MODAL_REMOVE_SNAP, "REMOVE_SNAP", 0, "Remove Last Snap Point", ""},
+ {NUM_MODAL_INCREMENT_UP, "INCREMENT_UP", 0, "Numinput Increment Up", ""},
+ {NUM_MODAL_INCREMENT_DOWN, "INCREMENT_DOWN", 0, "Numinput Increment Down", ""},
+ {TFM_MODAL_PROPSIZE_UP, "PROPORTIONAL_SIZE_UP", 0, "Increase Proportional Influence", ""},
+ {TFM_MODAL_PROPSIZE_DOWN,
+ "PROPORTIONAL_SIZE_DOWN",
+ 0,
+ "Decrease Proportional Influence",
+ ""},
+ {TFM_MODAL_AUTOIK_LEN_INC, "AUTOIK_CHAIN_LEN_UP", 0, "Increase Max AutoIK Chain Length", ""},
+ {TFM_MODAL_AUTOIK_LEN_DEC,
+ "AUTOIK_CHAIN_LEN_DOWN",
+ 0,
+ "Decrease Max AutoIK Chain Length",
+ ""},
+ {TFM_MODAL_EDGESLIDE_UP, "EDGESLIDE_EDGE_NEXT", 0, "Select next Edge Slide Edge", ""},
+ {TFM_MODAL_EDGESLIDE_DOWN, "EDGESLIDE_PREV_NEXT", 0, "Select previous Edge Slide Edge", ""},
+ {TFM_MODAL_PROPSIZE, "PROPORTIONAL_SIZE", 0, "Adjust Proportional Influence", ""},
+ {TFM_MODAL_INSERTOFS_TOGGLE_DIR,
+ "INSERTOFS_TOGGLE_DIR",
+ 0,
+ "Toggle Direction for Node Auto-offset",
+ ""},
+ {TFM_MODAL_TRANSLATE, "TRANSLATE", 0, "Move", ""},
+ {TFM_MODAL_ROTATE, "ROTATE", 0, "Rotate", ""},
+ {TFM_MODAL_RESIZE, "RESIZE", 0, "Resize", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Transform Modal Map");
+
+ keymap = WM_modalkeymap_add(keyconf, "Transform Modal Map", modal_items);
+ keymap->poll_modal_item = transform_modal_item_poll;
+
+ return keymap;
}
static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cmode, bool is_plane)
{
- if (!(t->flag & T_NO_CONSTRAINT)) {
- int constraint_axis, constraint_plane;
- const bool edit_2d = (t->flag & T_2D_EDIT) != 0;
- const char *msg1 = "", *msg2 = "", *msg3 = "";
- char axis;
-
- /* Initialize */
- switch (key_type) {
- case XKEY:
- msg1 = IFACE_("along X");
- msg2 = IFACE_("along %s X");
- msg3 = IFACE_("locking %s X");
- axis = 'X';
- constraint_axis = CON_AXIS0;
- break;
- case YKEY:
- msg1 = IFACE_("along Y");
- msg2 = IFACE_("along %s Y");
- msg3 = IFACE_("locking %s Y");
- axis = 'Y';
- constraint_axis = CON_AXIS1;
- break;
- case ZKEY:
- msg1 = IFACE_("along Z");
- msg2 = IFACE_("along %s Z");
- msg3 = IFACE_("locking %s Z");
- axis = 'Z';
- constraint_axis = CON_AXIS2;
- break;
- default:
- /* Invalid key */
- return;
- }
- constraint_plane = ((CON_AXIS0 | CON_AXIS1 | CON_AXIS2) & (~constraint_axis));
-
- if (edit_2d && (key_type != ZKEY)) {
- if (cmode == axis) {
- stopConstraint(t);
- }
- else {
- setUserConstraint(t, V3D_ORIENT_GLOBAL, constraint_axis, msg1);
- }
- }
- else if (!edit_2d) {
- if (cmode != axis) {
- /* First press, constraint to an axis. */
- t->orientation.index = 0;
- const short *orientation_ptr = t->orientation.types[t->orientation.index];
- const short orientation = orientation_ptr ? *orientation_ptr : V3D_ORIENT_GLOBAL;
- if (is_plane == false) {
- setUserConstraint(t, orientation, constraint_axis, msg2);
- }
- else {
- setUserConstraint(t, orientation, constraint_plane, msg3);
- }
- }
- else {
- /* Successive presses on existing axis, cycle orientation modes. */
- t->orientation.index = (t->orientation.index + 1) % ARRAY_SIZE(t->orientation.types);
-
- if (t->orientation.index == 0) {
- stopConstraint(t);
- }
- else {
- const short *orientation_ptr = t->orientation.types[t->orientation.index];
- const short orientation = orientation_ptr ? *orientation_ptr : V3D_ORIENT_GLOBAL;
- if (is_plane == false) {
- setUserConstraint(t, orientation, constraint_axis, msg2);
- }
- else {
- setUserConstraint(t, orientation, constraint_plane, msg3);
- }
- }
- }
- }
- t->redraw |= TREDRAW_HARD;
- }
+ if (!(t->flag & T_NO_CONSTRAINT)) {
+ int constraint_axis, constraint_plane;
+ const bool edit_2d = (t->flag & T_2D_EDIT) != 0;
+ const char *msg1 = "", *msg2 = "", *msg3 = "";
+ char axis;
+
+ /* Initialize */
+ switch (key_type) {
+ case XKEY:
+ msg1 = IFACE_("along X");
+ msg2 = IFACE_("along %s X");
+ msg3 = IFACE_("locking %s X");
+ axis = 'X';
+ constraint_axis = CON_AXIS0;
+ break;
+ case YKEY:
+ msg1 = IFACE_("along Y");
+ msg2 = IFACE_("along %s Y");
+ msg3 = IFACE_("locking %s Y");
+ axis = 'Y';
+ constraint_axis = CON_AXIS1;
+ break;
+ case ZKEY:
+ msg1 = IFACE_("along Z");
+ msg2 = IFACE_("along %s Z");
+ msg3 = IFACE_("locking %s Z");
+ axis = 'Z';
+ constraint_axis = CON_AXIS2;
+ break;
+ default:
+ /* Invalid key */
+ return;
+ }
+ constraint_plane = ((CON_AXIS0 | CON_AXIS1 | CON_AXIS2) & (~constraint_axis));
+
+ if (edit_2d && (key_type != ZKEY)) {
+ if (cmode == axis) {
+ stopConstraint(t);
+ }
+ else {
+ setUserConstraint(t, V3D_ORIENT_GLOBAL, constraint_axis, msg1);
+ }
+ }
+ else if (!edit_2d) {
+ if (cmode != axis) {
+ /* First press, constraint to an axis. */
+ t->orientation.index = 0;
+ const short *orientation_ptr = t->orientation.types[t->orientation.index];
+ const short orientation = orientation_ptr ? *orientation_ptr : V3D_ORIENT_GLOBAL;
+ if (is_plane == false) {
+ setUserConstraint(t, orientation, constraint_axis, msg2);
+ }
+ else {
+ setUserConstraint(t, orientation, constraint_plane, msg3);
+ }
+ }
+ else {
+ /* Successive presses on existing axis, cycle orientation modes. */
+ t->orientation.index = (t->orientation.index + 1) % ARRAY_SIZE(t->orientation.types);
+
+ if (t->orientation.index == 0) {
+ stopConstraint(t);
+ }
+ else {
+ const short *orientation_ptr = t->orientation.types[t->orientation.index];
+ const short orientation = orientation_ptr ? *orientation_ptr : V3D_ORIENT_GLOBAL;
+ if (is_plane == false) {
+ setUserConstraint(t, orientation, constraint_axis, msg2);
+ }
+ else {
+ setUserConstraint(t, orientation, constraint_plane, msg3);
+ }
+ }
+ }
+ }
+ t->redraw |= TREDRAW_HARD;
+ }
}
int transformEvent(TransInfo *t, const wmEvent *event)
{
- char cmode = constraintModeToChar(t);
- bool handled = false;
- const int modifiers_prev = t->modifiers;
-
- t->redraw |= handleMouseInput(t, &t->mouse, event);
-
- /* Handle modal numinput events first, if already activated. */
- if (((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) &&
- hasNumInput(&t->num) && handleNumInput(t->context, &(t->num), event))
- {
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- else if (event->type == MOUSEMOVE) {
- if (t->modifiers & MOD_CONSTRAINT_SELECT)
- t->con.mode |= CON_SELECT;
-
- copy_v2_v2_int(t->mval, event->mval);
-
- /* Use this for soft redraw. Might cause flicker in object mode */
- // t->redraw |= TREDRAW_SOFT;
- t->redraw |= TREDRAW_HARD;
-
- if (t->state == TRANS_STARTING) {
- t->state = TRANS_RUNNING;
- }
-
- applyMouseInput(t, &t->mouse, t->mval, t->values);
-
- // Snapping mouse move events
- t->redraw |= handleSnapping(t, event);
- handled = true;
- }
- /* handle modal keymap first */
- else if (event->type == EVT_MODAL_MAP) {
- switch (event->val) {
- case TFM_MODAL_CANCEL:
- t->state = TRANS_CANCEL;
- handled = true;
- break;
- case TFM_MODAL_CONFIRM:
- t->state = TRANS_CONFIRM;
- handled = true;
- break;
- case TFM_MODAL_TRANSLATE:
- /* only switch when... */
- if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
- restoreTransObjects(t);
- resetTransModal(t);
- resetTransRestrictions(t);
- initTranslation(t);
- initSnapping(t, NULL); // need to reinit after mode change
- t->redraw |= TREDRAW_HARD;
- WM_event_add_mousemove(t->context);
- handled = true;
- }
- else if (t->mode == TFM_SEQ_SLIDE) {
- t->flag ^= T_ALT_TRANSFORM;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- else {
- if (t->obedit_type == OB_MESH) {
- if ((t->mode == TFM_TRANSLATION) && (t->spacetype == SPACE_VIEW3D)) {
- restoreTransObjects(t);
- resetTransModal(t);
- resetTransRestrictions(t);
-
- /* first try edge slide */
- initEdgeSlide(t);
- /* if that fails, do vertex slide */
- if (t->state == TRANS_CANCEL) {
- resetTransModal(t);
- t->state = TRANS_STARTING;
- initVertSlide(t);
- }
- /* vert slide can fail on unconnected vertices (rare but possible) */
- if (t->state == TRANS_CANCEL) {
- resetTransModal(t);
- t->mode = TFM_TRANSLATION;
- t->state = TRANS_STARTING;
- restoreTransObjects(t);
- resetTransRestrictions(t);
- initTranslation(t);
- }
- initSnapping(t, NULL); // need to reinit after mode change
- t->redraw |= TREDRAW_HARD;
- handled = true;
- WM_event_add_mousemove(t->context);
- }
- }
- else if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
- if (t->mode == TFM_TRANSLATION) {
- restoreTransObjects(t);
-
- t->flag ^= T_ALT_TRANSFORM;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- }
- }
- break;
- case TFM_MODAL_ROTATE:
- /* only switch when... */
- if (!(t->options & CTX_TEXTURE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) {
- if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
- restoreTransObjects(t);
- resetTransModal(t);
- resetTransRestrictions(t);
-
- if (t->mode == TFM_ROTATION) {
- initTrackball(t);
- }
- else {
- initRotation(t);
- }
- initSnapping(t, NULL); // need to reinit after mode change
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- }
- break;
- case TFM_MODAL_RESIZE:
- /* only switch when... */
- if (ELEM(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
-
- /* Scale isn't normally very useful after extrude along normals, see T39756 */
- if ((t->con.mode & CON_APPLY) && (t->con.orientation == V3D_ORIENT_NORMAL)) {
- stopConstraint(t);
- }
-
- restoreTransObjects(t);
- resetTransModal(t);
- resetTransRestrictions(t);
- initResize(t);
- initSnapping(t, NULL); // need to reinit after mode change
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- else if (t->mode == TFM_SHRINKFATTEN) {
- t->flag ^= T_ALT_TRANSFORM;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- else if (t->mode == TFM_RESIZE) {
- if (t->options & CTX_MOVIECLIP) {
- restoreTransObjects(t);
-
- t->flag ^= T_ALT_TRANSFORM;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- }
- break;
-
- case TFM_MODAL_SNAP_INV_ON:
- t->modifiers |= MOD_SNAP_INVERT;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- break;
- case TFM_MODAL_SNAP_INV_OFF:
- t->modifiers &= ~MOD_SNAP_INVERT;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- break;
- case TFM_MODAL_SNAP_TOGGLE:
- t->modifiers ^= MOD_SNAP;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- break;
- case TFM_MODAL_AXIS_X:
- if (!(t->flag & T_NO_CONSTRAINT)) {
- transform_event_xyz_constraint(t, XKEY, cmode, false);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case TFM_MODAL_AXIS_Y:
- if ((t->flag & T_NO_CONSTRAINT) == 0) {
- transform_event_xyz_constraint(t, YKEY, cmode, false);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case TFM_MODAL_AXIS_Z:
- if ((t->flag & (T_NO_CONSTRAINT)) == 0) {
- transform_event_xyz_constraint(t, ZKEY, cmode, false);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case TFM_MODAL_PLANE_X:
- if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
- transform_event_xyz_constraint(t, XKEY, cmode, true);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case TFM_MODAL_PLANE_Y:
- if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
- transform_event_xyz_constraint(t, YKEY, cmode, true);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case TFM_MODAL_PLANE_Z:
- if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
- transform_event_xyz_constraint(t, ZKEY, cmode, true);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case TFM_MODAL_CONS_OFF:
- if ((t->flag & T_NO_CONSTRAINT) == 0) {
- stopConstraint(t);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case TFM_MODAL_ADD_SNAP:
- addSnapPoint(t);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- break;
- case TFM_MODAL_REMOVE_SNAP:
- removeSnapPoint(t);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- break;
- case TFM_MODAL_PROPSIZE:
- /* MOUSEPAN usage... */
- if (t->flag & T_PROP_EDIT) {
- float fac = 1.0f + 0.005f *(event->y - event->prevy);
- t->prop_size *= fac;
- if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO) {
- t->prop_size = max_ff(min_ff(t->prop_size, ((View3D *)t->view)->clip_end), T_PROP_SIZE_MIN);
- }
- else {
- t->prop_size = max_ff(min_ff(t->prop_size, T_PROP_SIZE_MAX), T_PROP_SIZE_MIN);
- }
- calculatePropRatio(t);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case TFM_MODAL_PROPSIZE_UP:
- if (t->flag & T_PROP_EDIT) {
- t->prop_size *= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
- if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO) {
- t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->clip_end);
- }
- else {
- t->prop_size = min_ff(t->prop_size, T_PROP_SIZE_MAX);
- }
- calculatePropRatio(t);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case TFM_MODAL_PROPSIZE_DOWN:
- if (t->flag & T_PROP_EDIT) {
- t->prop_size /= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
- t->prop_size = max_ff(t->prop_size, T_PROP_SIZE_MIN);
- calculatePropRatio(t);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case TFM_MODAL_AUTOIK_LEN_INC:
- if (t->flag & T_AUTOIK) {
- transform_autoik_update(t, 1);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case TFM_MODAL_AUTOIK_LEN_DEC:
- if (t->flag & T_AUTOIK) {
- transform_autoik_update(t, -1);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case TFM_MODAL_INSERTOFS_TOGGLE_DIR:
- if (t->spacetype == SPACE_NODE) {
- SpaceNode *snode = (SpaceNode *)t->sa->spacedata.first;
-
- BLI_assert(t->sa->spacetype == t->spacetype);
-
- if (snode->insert_ofs_dir == SNODE_INSERTOFS_DIR_RIGHT) {
- snode->insert_ofs_dir = SNODE_INSERTOFS_DIR_LEFT;
- }
- else if (snode->insert_ofs_dir == SNODE_INSERTOFS_DIR_LEFT) {
- snode->insert_ofs_dir = SNODE_INSERTOFS_DIR_RIGHT;
- }
- else {
- BLI_assert(0);
- }
-
- t->redraw |= TREDRAW_SOFT;
- }
- break;
- /* Those two are only handled in transform's own handler, see T44634! */
- case TFM_MODAL_EDGESLIDE_UP:
- case TFM_MODAL_EDGESLIDE_DOWN:
- default:
- break;
- }
- }
- /* else do non-mapped events */
- else if (event->val == KM_PRESS) {
- switch (event->type) {
- case RIGHTMOUSE:
- t->state = TRANS_CANCEL;
- handled = true;
- break;
- /* enforce redraw of transform when modifiers are used */
- case LEFTSHIFTKEY:
- case RIGHTSHIFTKEY:
- t->modifiers |= MOD_CONSTRAINT_PLANE;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- break;
-
- case SPACEKEY:
- t->state = TRANS_CONFIRM;
- handled = true;
- break;
-
- case MIDDLEMOUSE:
- if ((t->flag & T_NO_CONSTRAINT) == 0) {
- /* exception for switching to dolly, or trackball, in camera view */
- if (t->flag & T_CAMERA) {
- if (t->mode == TFM_TRANSLATION)
- setLocalConstraint(t, (CON_AXIS2), IFACE_("along local Z"));
- else if (t->mode == TFM_ROTATION) {
- restoreTransObjects(t);
- initTrackball(t);
- }
- }
- else {
- t->modifiers |= MOD_CONSTRAINT_SELECT;
- if (t->con.mode & CON_APPLY) {
- stopConstraint(t);
- }
- else {
- if (event->shift) {
- /* bit hackish... but it prevents mmb select to print the
- * orientation from menu */
- float mati[3][3];
- strcpy(t->spacename, "global");
- unit_m3(mati);
- initSelectConstraint(t, mati);
- }
- else {
- initSelectConstraint(t, t->spacemtx);
- }
- postSelectConstraint(t);
- }
- }
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case ESCKEY:
- t->state = TRANS_CANCEL;
- handled = true;
- break;
- case PADENTER:
- case RETKEY:
- t->state = TRANS_CONFIRM;
- handled = true;
- break;
- case GKEY:
- /* only switch when... */
- if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL)) {
- restoreTransObjects(t);
- resetTransModal(t);
- resetTransRestrictions(t);
- initTranslation(t);
- initSnapping(t, NULL); // need to reinit after mode change
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case SKEY:
- /* only switch when... */
- if (ELEM(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL)) {
- restoreTransObjects(t);
- resetTransModal(t);
- resetTransRestrictions(t);
- initResize(t);
- initSnapping(t, NULL); // need to reinit after mode change
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case RKEY:
- /* only switch when... */
- if (!(t->options & CTX_TEXTURE)) {
- if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION)) {
- restoreTransObjects(t);
- resetTransModal(t);
- resetTransRestrictions(t);
-
- if (t->mode == TFM_ROTATION) {
- initTrackball(t);
- }
- else {
- initRotation(t);
- }
- initSnapping(t, NULL); // need to reinit after mode change
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- }
- break;
- case CKEY:
- if (event->alt) {
- if (!(t->options & CTX_NO_PET)) {
- t->flag ^= T_PROP_CONNECTED;
- sort_trans_data_dist(t);
- calculatePropRatio(t);
- t->redraw = TREDRAW_HARD;
- handled = true;
- }
- }
- break;
- case OKEY:
- if (t->flag & T_PROP_EDIT && event->shift) {
- t->prop_mode = (t->prop_mode + 1) % PROP_MODE_MAX;
- calculatePropRatio(t);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case PADPLUSKEY:
- if (event->alt && t->flag & T_PROP_EDIT) {
- t->prop_size *= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
- if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO)
- t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->clip_end);
- calculatePropRatio(t);
- t->redraw = TREDRAW_HARD;
- handled = true;
- }
- break;
- case PAGEUPKEY:
- case WHEELDOWNMOUSE:
- if (t->flag & T_AUTOIK) {
- transform_autoik_update(t, 1);
- }
- else {
- view_editmove(event->type);
- }
- t->redraw = TREDRAW_HARD;
- handled = true;
- break;
- case PADMINUS:
- if (event->alt && t->flag & T_PROP_EDIT) {
- t->prop_size /= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
- calculatePropRatio(t);
- t->redraw = TREDRAW_HARD;
- handled = true;
- }
- break;
- case PAGEDOWNKEY:
- case WHEELUPMOUSE:
- if (t->flag & T_AUTOIK) {
- transform_autoik_update(t, -1);
- }
- else {
- view_editmove(event->type);
- }
- t->redraw = TREDRAW_HARD;
- handled = true;
- break;
- case LEFTALTKEY:
- case RIGHTALTKEY:
- if (ELEM(t->spacetype, SPACE_SEQ, SPACE_VIEW3D)) {
- t->flag |= T_ALT_TRANSFORM;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case NKEY:
- if (ELEM(t->mode, TFM_ROTATION)) {
- if ((t->flag & T_EDIT) && t->obedit_type == OB_MESH) {
- restoreTransObjects(t);
- resetTransModal(t);
- resetTransRestrictions(t);
- initNormalRotation(t);
- t->redraw = TREDRAW_HARD;
- handled = true;
- }
- }
- break;
- default:
- break;
- }
-
- /* Snapping key events */
- t->redraw |= handleSnapping(t, event);
- }
- else if (event->val == KM_RELEASE) {
- switch (event->type) {
- case LEFTSHIFTKEY:
- case RIGHTSHIFTKEY:
- t->modifiers &= ~MOD_CONSTRAINT_PLANE;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- break;
-
- case MIDDLEMOUSE:
- if ((t->flag & T_NO_CONSTRAINT) == 0) {
- t->modifiers &= ~MOD_CONSTRAINT_SELECT;
- postSelectConstraint(t);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- case LEFTALTKEY:
- case RIGHTALTKEY:
- if (ELEM(t->spacetype, SPACE_SEQ, SPACE_VIEW3D)) {
- t->flag &= ~T_ALT_TRANSFORM;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
- default:
- break;
- }
-
- /* confirm transform if launch key is released after mouse move */
- if (t->flag & T_RELEASE_CONFIRM) {
- /* XXX Keyrepeat bug in Xorg messes this up, will test when fixed */
- if ((event->type == t->launch_event) && ISMOUSE(t->launch_event)) {
- t->state = TRANS_CONFIRM;
- }
- }
- }
-
- /* if we change snap options, get the unsnapped values back */
- if ((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) !=
- (modifiers_prev & (MOD_SNAP | MOD_SNAP_INVERT)))
- {
- applyMouseInput(t, &t->mouse, t->mval, t->values);
- }
-
- /* Per transform event, if present */
- if (t->handleEvent &&
- (!handled ||
- /* Needed for vertex slide, see [#38756] */
- (event->type == MOUSEMOVE)))
- {
- t->redraw |= t->handleEvent(t, event);
- }
-
- /* Try to init modal numinput now, if possible. */
- if (!(handled || t->redraw) && ((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) &&
- handleNumInput(t->context, &(t->num), event))
- {
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
-
- if (t->redraw &&
- !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE))
- {
- WM_window_status_area_tag_redraw(CTX_wm_window(t->context));
- }
-
- if (handled || t->redraw) {
- return 0;
- }
- else {
- return OPERATOR_PASS_THROUGH;
- }
+ char cmode = constraintModeToChar(t);
+ bool handled = false;
+ const int modifiers_prev = t->modifiers;
+
+ t->redraw |= handleMouseInput(t, &t->mouse, event);
+
+ /* Handle modal numinput events first, if already activated. */
+ if (((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) && hasNumInput(&t->num) &&
+ handleNumInput(t->context, &(t->num), event)) {
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ else if (event->type == MOUSEMOVE) {
+ if (t->modifiers & MOD_CONSTRAINT_SELECT)
+ t->con.mode |= CON_SELECT;
+
+ copy_v2_v2_int(t->mval, event->mval);
+
+ /* Use this for soft redraw. Might cause flicker in object mode */
+ // t->redraw |= TREDRAW_SOFT;
+ t->redraw |= TREDRAW_HARD;
+
+ if (t->state == TRANS_STARTING) {
+ t->state = TRANS_RUNNING;
+ }
+
+ applyMouseInput(t, &t->mouse, t->mval, t->values);
+
+ // Snapping mouse move events
+ t->redraw |= handleSnapping(t, event);
+ handled = true;
+ }
+ /* handle modal keymap first */
+ else if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case TFM_MODAL_CANCEL:
+ t->state = TRANS_CANCEL;
+ handled = true;
+ break;
+ case TFM_MODAL_CONFIRM:
+ t->state = TRANS_CONFIRM;
+ handled = true;
+ break;
+ case TFM_MODAL_TRANSLATE:
+ /* only switch when... */
+ if (ELEM(t->mode,
+ TFM_ROTATION,
+ TFM_RESIZE,
+ TFM_TRACKBALL,
+ TFM_EDGE_SLIDE,
+ TFM_VERT_SLIDE)) {
+ restoreTransObjects(t);
+ resetTransModal(t);
+ resetTransRestrictions(t);
+ initTranslation(t);
+ initSnapping(t, NULL); // need to reinit after mode change
+ t->redraw |= TREDRAW_HARD;
+ WM_event_add_mousemove(t->context);
+ handled = true;
+ }
+ else if (t->mode == TFM_SEQ_SLIDE) {
+ t->flag ^= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ else {
+ if (t->obedit_type == OB_MESH) {
+ if ((t->mode == TFM_TRANSLATION) && (t->spacetype == SPACE_VIEW3D)) {
+ restoreTransObjects(t);
+ resetTransModal(t);
+ resetTransRestrictions(t);
+
+ /* first try edge slide */
+ initEdgeSlide(t);
+ /* if that fails, do vertex slide */
+ if (t->state == TRANS_CANCEL) {
+ resetTransModal(t);
+ t->state = TRANS_STARTING;
+ initVertSlide(t);
+ }
+ /* vert slide can fail on unconnected vertices (rare but possible) */
+ if (t->state == TRANS_CANCEL) {
+ resetTransModal(t);
+ t->mode = TFM_TRANSLATION;
+ t->state = TRANS_STARTING;
+ restoreTransObjects(t);
+ resetTransRestrictions(t);
+ initTranslation(t);
+ }
+ initSnapping(t, NULL); // need to reinit after mode change
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ WM_event_add_mousemove(t->context);
+ }
+ }
+ else if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
+ if (t->mode == TFM_TRANSLATION) {
+ restoreTransObjects(t);
+
+ t->flag ^= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ }
+ }
+ break;
+ case TFM_MODAL_ROTATE:
+ /* only switch when... */
+ if (!(t->options & CTX_TEXTURE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) {
+ if (ELEM(t->mode,
+ TFM_ROTATION,
+ TFM_RESIZE,
+ TFM_TRACKBALL,
+ TFM_TRANSLATION,
+ TFM_EDGE_SLIDE,
+ TFM_VERT_SLIDE)) {
+ restoreTransObjects(t);
+ resetTransModal(t);
+ resetTransRestrictions(t);
+
+ if (t->mode == TFM_ROTATION) {
+ initTrackball(t);
+ }
+ else {
+ initRotation(t);
+ }
+ initSnapping(t, NULL); // need to reinit after mode change
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ }
+ break;
+ case TFM_MODAL_RESIZE:
+ /* only switch when... */
+ if (ELEM(t->mode,
+ TFM_ROTATION,
+ TFM_TRANSLATION,
+ TFM_TRACKBALL,
+ TFM_EDGE_SLIDE,
+ TFM_VERT_SLIDE)) {
+
+ /* Scale isn't normally very useful after extrude along normals, see T39756 */
+ if ((t->con.mode & CON_APPLY) && (t->con.orientation == V3D_ORIENT_NORMAL)) {
+ stopConstraint(t);
+ }
+
+ restoreTransObjects(t);
+ resetTransModal(t);
+ resetTransRestrictions(t);
+ initResize(t);
+ initSnapping(t, NULL); // need to reinit after mode change
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ else if (t->mode == TFM_SHRINKFATTEN) {
+ t->flag ^= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ else if (t->mode == TFM_RESIZE) {
+ if (t->options & CTX_MOVIECLIP) {
+ restoreTransObjects(t);
+
+ t->flag ^= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ }
+ break;
+
+ case TFM_MODAL_SNAP_INV_ON:
+ t->modifiers |= MOD_SNAP_INVERT;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ break;
+ case TFM_MODAL_SNAP_INV_OFF:
+ t->modifiers &= ~MOD_SNAP_INVERT;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ break;
+ case TFM_MODAL_SNAP_TOGGLE:
+ t->modifiers ^= MOD_SNAP;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ break;
+ case TFM_MODAL_AXIS_X:
+ if (!(t->flag & T_NO_CONSTRAINT)) {
+ transform_event_xyz_constraint(t, XKEY, cmode, false);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case TFM_MODAL_AXIS_Y:
+ if ((t->flag & T_NO_CONSTRAINT) == 0) {
+ transform_event_xyz_constraint(t, YKEY, cmode, false);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case TFM_MODAL_AXIS_Z:
+ if ((t->flag & (T_NO_CONSTRAINT)) == 0) {
+ transform_event_xyz_constraint(t, ZKEY, cmode, false);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case TFM_MODAL_PLANE_X:
+ if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
+ transform_event_xyz_constraint(t, XKEY, cmode, true);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case TFM_MODAL_PLANE_Y:
+ if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
+ transform_event_xyz_constraint(t, YKEY, cmode, true);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case TFM_MODAL_PLANE_Z:
+ if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
+ transform_event_xyz_constraint(t, ZKEY, cmode, true);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case TFM_MODAL_CONS_OFF:
+ if ((t->flag & T_NO_CONSTRAINT) == 0) {
+ stopConstraint(t);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case TFM_MODAL_ADD_SNAP:
+ addSnapPoint(t);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ break;
+ case TFM_MODAL_REMOVE_SNAP:
+ removeSnapPoint(t);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ break;
+ case TFM_MODAL_PROPSIZE:
+ /* MOUSEPAN usage... */
+ if (t->flag & T_PROP_EDIT) {
+ float fac = 1.0f + 0.005f * (event->y - event->prevy);
+ t->prop_size *= fac;
+ if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO) {
+ t->prop_size = max_ff(min_ff(t->prop_size, ((View3D *)t->view)->clip_end),
+ T_PROP_SIZE_MIN);
+ }
+ else {
+ t->prop_size = max_ff(min_ff(t->prop_size, T_PROP_SIZE_MAX), T_PROP_SIZE_MIN);
+ }
+ calculatePropRatio(t);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case TFM_MODAL_PROPSIZE_UP:
+ if (t->flag & T_PROP_EDIT) {
+ t->prop_size *= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
+ if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO) {
+ t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->clip_end);
+ }
+ else {
+ t->prop_size = min_ff(t->prop_size, T_PROP_SIZE_MAX);
+ }
+ calculatePropRatio(t);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case TFM_MODAL_PROPSIZE_DOWN:
+ if (t->flag & T_PROP_EDIT) {
+ t->prop_size /= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
+ t->prop_size = max_ff(t->prop_size, T_PROP_SIZE_MIN);
+ calculatePropRatio(t);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case TFM_MODAL_AUTOIK_LEN_INC:
+ if (t->flag & T_AUTOIK) {
+ transform_autoik_update(t, 1);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case TFM_MODAL_AUTOIK_LEN_DEC:
+ if (t->flag & T_AUTOIK) {
+ transform_autoik_update(t, -1);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case TFM_MODAL_INSERTOFS_TOGGLE_DIR:
+ if (t->spacetype == SPACE_NODE) {
+ SpaceNode *snode = (SpaceNode *)t->sa->spacedata.first;
+
+ BLI_assert(t->sa->spacetype == t->spacetype);
+
+ if (snode->insert_ofs_dir == SNODE_INSERTOFS_DIR_RIGHT) {
+ snode->insert_ofs_dir = SNODE_INSERTOFS_DIR_LEFT;
+ }
+ else if (snode->insert_ofs_dir == SNODE_INSERTOFS_DIR_LEFT) {
+ snode->insert_ofs_dir = SNODE_INSERTOFS_DIR_RIGHT;
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ t->redraw |= TREDRAW_SOFT;
+ }
+ break;
+ /* Those two are only handled in transform's own handler, see T44634! */
+ case TFM_MODAL_EDGESLIDE_UP:
+ case TFM_MODAL_EDGESLIDE_DOWN:
+ default:
+ break;
+ }
+ }
+ /* else do non-mapped events */
+ else if (event->val == KM_PRESS) {
+ switch (event->type) {
+ case RIGHTMOUSE:
+ t->state = TRANS_CANCEL;
+ handled = true;
+ break;
+ /* enforce redraw of transform when modifiers are used */
+ case LEFTSHIFTKEY:
+ case RIGHTSHIFTKEY:
+ t->modifiers |= MOD_CONSTRAINT_PLANE;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ break;
+
+ case SPACEKEY:
+ t->state = TRANS_CONFIRM;
+ handled = true;
+ break;
+
+ case MIDDLEMOUSE:
+ if ((t->flag & T_NO_CONSTRAINT) == 0) {
+ /* exception for switching to dolly, or trackball, in camera view */
+ if (t->flag & T_CAMERA) {
+ if (t->mode == TFM_TRANSLATION)
+ setLocalConstraint(t, (CON_AXIS2), IFACE_("along local Z"));
+ else if (t->mode == TFM_ROTATION) {
+ restoreTransObjects(t);
+ initTrackball(t);
+ }
+ }
+ else {
+ t->modifiers |= MOD_CONSTRAINT_SELECT;
+ if (t->con.mode & CON_APPLY) {
+ stopConstraint(t);
+ }
+ else {
+ if (event->shift) {
+ /* bit hackish... but it prevents mmb select to print the
+ * orientation from menu */
+ float mati[3][3];
+ strcpy(t->spacename, "global");
+ unit_m3(mati);
+ initSelectConstraint(t, mati);
+ }
+ else {
+ initSelectConstraint(t, t->spacemtx);
+ }
+ postSelectConstraint(t);
+ }
+ }
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case ESCKEY:
+ t->state = TRANS_CANCEL;
+ handled = true;
+ break;
+ case PADENTER:
+ case RETKEY:
+ t->state = TRANS_CONFIRM;
+ handled = true;
+ break;
+ case GKEY:
+ /* only switch when... */
+ if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL)) {
+ restoreTransObjects(t);
+ resetTransModal(t);
+ resetTransRestrictions(t);
+ initTranslation(t);
+ initSnapping(t, NULL); // need to reinit after mode change
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case SKEY:
+ /* only switch when... */
+ if (ELEM(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL)) {
+ restoreTransObjects(t);
+ resetTransModal(t);
+ resetTransRestrictions(t);
+ initResize(t);
+ initSnapping(t, NULL); // need to reinit after mode change
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case RKEY:
+ /* only switch when... */
+ if (!(t->options & CTX_TEXTURE)) {
+ if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION)) {
+ restoreTransObjects(t);
+ resetTransModal(t);
+ resetTransRestrictions(t);
+
+ if (t->mode == TFM_ROTATION) {
+ initTrackball(t);
+ }
+ else {
+ initRotation(t);
+ }
+ initSnapping(t, NULL); // need to reinit after mode change
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ }
+ break;
+ case CKEY:
+ if (event->alt) {
+ if (!(t->options & CTX_NO_PET)) {
+ t->flag ^= T_PROP_CONNECTED;
+ sort_trans_data_dist(t);
+ calculatePropRatio(t);
+ t->redraw = TREDRAW_HARD;
+ handled = true;
+ }
+ }
+ break;
+ case OKEY:
+ if (t->flag & T_PROP_EDIT && event->shift) {
+ t->prop_mode = (t->prop_mode + 1) % PROP_MODE_MAX;
+ calculatePropRatio(t);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case PADPLUSKEY:
+ if (event->alt && t->flag & T_PROP_EDIT) {
+ t->prop_size *= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
+ if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO)
+ t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->clip_end);
+ calculatePropRatio(t);
+ t->redraw = TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case PAGEUPKEY:
+ case WHEELDOWNMOUSE:
+ if (t->flag & T_AUTOIK) {
+ transform_autoik_update(t, 1);
+ }
+ else {
+ view_editmove(event->type);
+ }
+ t->redraw = TREDRAW_HARD;
+ handled = true;
+ break;
+ case PADMINUS:
+ if (event->alt && t->flag & T_PROP_EDIT) {
+ t->prop_size /= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
+ calculatePropRatio(t);
+ t->redraw = TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case PAGEDOWNKEY:
+ case WHEELUPMOUSE:
+ if (t->flag & T_AUTOIK) {
+ transform_autoik_update(t, -1);
+ }
+ else {
+ view_editmove(event->type);
+ }
+ t->redraw = TREDRAW_HARD;
+ handled = true;
+ break;
+ case LEFTALTKEY:
+ case RIGHTALTKEY:
+ if (ELEM(t->spacetype, SPACE_SEQ, SPACE_VIEW3D)) {
+ t->flag |= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case NKEY:
+ if (ELEM(t->mode, TFM_ROTATION)) {
+ if ((t->flag & T_EDIT) && t->obedit_type == OB_MESH) {
+ restoreTransObjects(t);
+ resetTransModal(t);
+ resetTransRestrictions(t);
+ initNormalRotation(t);
+ t->redraw = TREDRAW_HARD;
+ handled = true;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* Snapping key events */
+ t->redraw |= handleSnapping(t, event);
+ }
+ else if (event->val == KM_RELEASE) {
+ switch (event->type) {
+ case LEFTSHIFTKEY:
+ case RIGHTSHIFTKEY:
+ t->modifiers &= ~MOD_CONSTRAINT_PLANE;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ break;
+
+ case MIDDLEMOUSE:
+ if ((t->flag & T_NO_CONSTRAINT) == 0) {
+ t->modifiers &= ~MOD_CONSTRAINT_SELECT;
+ postSelectConstraint(t);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case LEFTALTKEY:
+ case RIGHTALTKEY:
+ if (ELEM(t->spacetype, SPACE_SEQ, SPACE_VIEW3D)) {
+ t->flag &= ~T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* confirm transform if launch key is released after mouse move */
+ if (t->flag & T_RELEASE_CONFIRM) {
+ /* XXX Keyrepeat bug in Xorg messes this up, will test when fixed */
+ if ((event->type == t->launch_event) && ISMOUSE(t->launch_event)) {
+ t->state = TRANS_CONFIRM;
+ }
+ }
+ }
+
+ /* if we change snap options, get the unsnapped values back */
+ if ((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) !=
+ (modifiers_prev & (MOD_SNAP | MOD_SNAP_INVERT))) {
+ applyMouseInput(t, &t->mouse, t->mval, t->values);
+ }
+
+ /* Per transform event, if present */
+ if (t->handleEvent && (!handled ||
+ /* Needed for vertex slide, see [#38756] */
+ (event->type == MOUSEMOVE))) {
+ t->redraw |= t->handleEvent(t, event);
+ }
+
+ /* Try to init modal numinput now, if possible. */
+ if (!(handled || t->redraw) && ((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) &&
+ handleNumInput(t->context, &(t->num), event)) {
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+
+ if (t->redraw && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
+ WM_window_status_area_tag_redraw(CTX_wm_window(t->context));
+ }
+
+ if (handled || t->redraw) {
+ return 0;
+ }
+ else {
+ return OPERATOR_PASS_THROUGH;
+ }
}
bool calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], float cent2d[2])
{
- TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data");
- bool success;
-
- t->context = C;
+ TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data");
+ bool success;
- t->state = TRANS_RUNNING;
+ t->context = C;
- /* avoid calculating PET */
- t->options = CTX_NO_PET;
+ t->state = TRANS_RUNNING;
- t->mode = TFM_DUMMY;
+ /* avoid calculating PET */
+ t->options = CTX_NO_PET;
- initTransInfo(C, t, NULL, NULL);
+ t->mode = TFM_DUMMY;
- /* avoid doing connectivity lookups (when V3D_AROUND_LOCAL_ORIGINS is set) */
- t->around = V3D_AROUND_CENTER_BOUNDS;
+ initTransInfo(C, t, NULL, NULL);
- createTransData(C, t); // make TransData structs from selection
+ /* avoid doing connectivity lookups (when V3D_AROUND_LOCAL_ORIGINS is set) */
+ t->around = V3D_AROUND_CENTER_BOUNDS;
- t->around = centerMode; // override userdefined mode
+ createTransData(C, t); // make TransData structs from selection
- if (t->data_len_all == 0) {
- success = false;
- }
- else {
- success = true;
+ t->around = centerMode; // override userdefined mode
- calculateCenter(t);
+ if (t->data_len_all == 0) {
+ success = false;
+ }
+ else {
+ success = true;
- if (cent2d) {
- copy_v2_v2(cent2d, t->center2d);
- }
+ calculateCenter(t);
- if (cent3d) {
- // Copy center from constraint center. Transform center can be local
- copy_v3_v3(cent3d, t->center_global);
- }
- }
+ if (cent2d) {
+ copy_v2_v2(cent2d, t->center2d);
+ }
+ if (cent3d) {
+ // Copy center from constraint center. Transform center can be local
+ copy_v3_v3(cent3d, t->center_global);
+ }
+ }
- /* aftertrans does insert keyframes, and clears base flags; doesn't read transdata */
- special_aftertrans_update(C, t);
+ /* aftertrans does insert keyframes, and clears base flags; doesn't read transdata */
+ special_aftertrans_update(C, t);
- postTrans(C, t);
+ postTrans(C, t);
- MEM_freeN(t);
+ MEM_freeN(t);
- return success;
+ return success;
}
typedef enum {
- UP,
- DOWN,
- LEFT,
- RIGHT,
+ UP,
+ DOWN,
+ LEFT,
+ RIGHT,
} ArrowDirection;
#define POS_INDEX 0
@@ -1677,382 +1685,384 @@ typedef enum {
static void drawArrow(ArrowDirection d, short offset, short length, short size)
{
- immBegin(GPU_PRIM_LINES, 6);
-
- switch (d) {
- case LEFT:
- offset = -offset;
- length = -length;
- size = -size;
- ATTR_FALLTHROUGH;
- case RIGHT:
- immVertex2f(POS_INDEX, offset, 0);
- immVertex2f(POS_INDEX, offset + length, 0);
- immVertex2f(POS_INDEX, offset + length, 0);
- immVertex2f(POS_INDEX, offset + length - size, -size);
- immVertex2f(POS_INDEX, offset + length, 0);
- immVertex2f(POS_INDEX, offset + length - size, size);
- break;
-
- case DOWN:
- offset = -offset;
- length = -length;
- size = -size;
- ATTR_FALLTHROUGH;
- case UP:
- immVertex2f(POS_INDEX, 0, offset);
- immVertex2f(POS_INDEX, 0, offset + length);
- immVertex2f(POS_INDEX, 0, offset + length);
- immVertex2f(POS_INDEX, -size, offset + length - size);
- immVertex2f(POS_INDEX, 0, offset + length);
- immVertex2f(POS_INDEX, size, offset + length - size);
- break;
- }
-
- immEnd();
+ immBegin(GPU_PRIM_LINES, 6);
+
+ switch (d) {
+ case LEFT:
+ offset = -offset;
+ length = -length;
+ size = -size;
+ ATTR_FALLTHROUGH;
+ case RIGHT:
+ immVertex2f(POS_INDEX, offset, 0);
+ immVertex2f(POS_INDEX, offset + length, 0);
+ immVertex2f(POS_INDEX, offset + length, 0);
+ immVertex2f(POS_INDEX, offset + length - size, -size);
+ immVertex2f(POS_INDEX, offset + length, 0);
+ immVertex2f(POS_INDEX, offset + length - size, size);
+ break;
+
+ case DOWN:
+ offset = -offset;
+ length = -length;
+ size = -size;
+ ATTR_FALLTHROUGH;
+ case UP:
+ immVertex2f(POS_INDEX, 0, offset);
+ immVertex2f(POS_INDEX, 0, offset + length);
+ immVertex2f(POS_INDEX, 0, offset + length);
+ immVertex2f(POS_INDEX, -size, offset + length - size);
+ immVertex2f(POS_INDEX, 0, offset + length);
+ immVertex2f(POS_INDEX, size, offset + length - size);
+ break;
+ }
+
+ immEnd();
}
static void drawArrowHead(ArrowDirection d, short size)
{
- immBegin(GPU_PRIM_LINES, 4);
-
- switch (d) {
- case LEFT:
- size = -size;
- ATTR_FALLTHROUGH;
- case RIGHT:
- immVertex2f(POS_INDEX, 0, 0);
- immVertex2f(POS_INDEX, -size, -size);
- immVertex2f(POS_INDEX, 0, 0);
- immVertex2f(POS_INDEX, -size, size);
- break;
-
- case DOWN:
- size = -size;
- ATTR_FALLTHROUGH;
- case UP:
- immVertex2f(POS_INDEX, 0, 0);
- immVertex2f(POS_INDEX, -size, -size);
- immVertex2f(POS_INDEX, 0, 0);
- immVertex2f(POS_INDEX, size, -size);
- break;
- }
-
- immEnd();
+ immBegin(GPU_PRIM_LINES, 4);
+
+ switch (d) {
+ case LEFT:
+ size = -size;
+ ATTR_FALLTHROUGH;
+ case RIGHT:
+ immVertex2f(POS_INDEX, 0, 0);
+ immVertex2f(POS_INDEX, -size, -size);
+ immVertex2f(POS_INDEX, 0, 0);
+ immVertex2f(POS_INDEX, -size, size);
+ break;
+
+ case DOWN:
+ size = -size;
+ ATTR_FALLTHROUGH;
+ case UP:
+ immVertex2f(POS_INDEX, 0, 0);
+ immVertex2f(POS_INDEX, -size, -size);
+ immVertex2f(POS_INDEX, 0, 0);
+ immVertex2f(POS_INDEX, size, -size);
+ break;
+ }
+
+ immEnd();
}
static void drawArc(float size, float angle_start, float angle_end, int segments)
{
- float delta = (angle_end - angle_start) / segments;
- float angle;
- int a;
+ float delta = (angle_end - angle_start) / segments;
+ float angle;
+ int a;
- immBegin(GPU_PRIM_LINE_STRIP, segments + 1);
+ immBegin(GPU_PRIM_LINE_STRIP, segments + 1);
- for (angle = angle_start, a = 0; a < segments; angle += delta, a++) {
- immVertex2f(POS_INDEX, cosf(angle) * size, sinf(angle) * size);
- }
- immVertex2f(POS_INDEX, cosf(angle_end) * size, sinf(angle_end) * size);
+ for (angle = angle_start, a = 0; a < segments; angle += delta, a++) {
+ immVertex2f(POS_INDEX, cosf(angle) * size, sinf(angle) * size);
+ }
+ immVertex2f(POS_INDEX, cosf(angle_end) * size, sinf(angle_end) * size);
- immEnd();
+ immEnd();
}
static bool helpline_poll(bContext *C)
{
- ARegion *ar = CTX_wm_region(C);
+ ARegion *ar = CTX_wm_region(C);
- if (ar && ar->regiontype == RGN_TYPE_WINDOW)
- return 1;
- return 0;
+ if (ar && ar->regiontype == RGN_TYPE_WINDOW)
+ return 1;
+ return 0;
}
static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
{
- TransInfo *t = (TransInfo *)customdata;
-
- if (t->helpline != HLP_NONE) {
- float cent[2];
- float mval[3] = {
- x,
- y,
- 0.0f,
- };
- float tmval[2] = {
- (float)t->mval[0],
- (float)t->mval[1],
- };
-
- projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO);
- /* Offset the values for the area region. */
- const float offset[2] = {
- t->ar->winrct.xmin,
- t->ar->winrct.ymin,
- };
-
- for (int i = 0; i < 2; i++) {
- cent[i] += offset[i];
- tmval[i] += offset[i];
- }
-
- GPU_matrix_push();
-
- /* Dashed lines first. */
- if (ELEM(t->helpline, HLP_SPRING, HLP_ANGLE)) {
- const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- UNUSED_VARS_NDEBUG(shdr_pos); /* silence warning */
- BLI_assert(shdr_pos == POS_INDEX);
-
- GPU_line_width(1.0f);
+ TransInfo *t = (TransInfo *)customdata;
+
+ if (t->helpline != HLP_NONE) {
+ float cent[2];
+ float mval[3] = {
+ x,
+ y,
+ 0.0f,
+ };
+ float tmval[2] = {
+ (float)t->mval[0],
+ (float)t->mval[1],
+ };
+
+ projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO);
+ /* Offset the values for the area region. */
+ const float offset[2] = {
+ t->ar->winrct.xmin,
+ t->ar->winrct.ymin,
+ };
+
+ for (int i = 0; i < 2; i++) {
+ cent[i] += offset[i];
+ tmval[i] += offset[i];
+ }
+
+ GPU_matrix_push();
+
+ /* Dashed lines first. */
+ if (ELEM(t->helpline, HLP_SPRING, HLP_ANGLE)) {
+ const uint shdr_pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ UNUSED_VARS_NDEBUG(shdr_pos); /* silence warning */
+ BLI_assert(shdr_pos == POS_INDEX);
+
+ GPU_line_width(1.0f);
- immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
- immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+ 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 */
- immUniformThemeColor(TH_VIEW_OVERLAY);
- immUniform1f("dash_width", 6.0f);
- immUniform1f("dash_factor", 0.5f);
-
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2fv(POS_INDEX, cent);
- immVertex2f(POS_INDEX, tmval[0], tmval[1]);
- immEnd();
+ immUniform1i("colors_len", 0); /* "simple" mode */
+ immUniformThemeColor(TH_VIEW_OVERLAY);
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
- immUnbindProgram();
- }
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2fv(POS_INDEX, cent);
+ immVertex2f(POS_INDEX, tmval[0], tmval[1]);
+ immEnd();
- /* And now, solid lines. */
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- UNUSED_VARS_NDEBUG(pos); /* silence warning */
- BLI_assert(pos == POS_INDEX);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUnbindProgram();
+ }
- switch (t->helpline) {
- case HLP_SPRING:
- immUniformThemeColor(TH_VIEW_OVERLAY);
+ /* And now, solid lines. */
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ UNUSED_VARS_NDEBUG(pos); /* silence warning */
+ BLI_assert(pos == POS_INDEX);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- GPU_matrix_translate_3fv(mval);
- GPU_matrix_rotate_axis(-RAD2DEGF(atan2f(cent[0] - tmval[0], cent[1] - tmval[1])), 'Z');
+ switch (t->helpline) {
+ case HLP_SPRING:
+ immUniformThemeColor(TH_VIEW_OVERLAY);
- GPU_line_width(3.0f);
- drawArrow(UP, 5, 10, 5);
- drawArrow(DOWN, 5, 10, 5);
- break;
- case HLP_HARROW:
- immUniformThemeColor(TH_VIEW_OVERLAY);
- GPU_matrix_translate_3fv(mval);
+ GPU_matrix_translate_3fv(mval);
+ GPU_matrix_rotate_axis(-RAD2DEGF(atan2f(cent[0] - tmval[0], cent[1] - tmval[1])), 'Z');
- GPU_line_width(3.0f);
- drawArrow(RIGHT, 5, 10, 5);
- drawArrow(LEFT, 5, 10, 5);
- break;
- case HLP_VARROW:
- immUniformThemeColor(TH_VIEW_OVERLAY);
+ GPU_line_width(3.0f);
+ drawArrow(UP, 5, 10, 5);
+ drawArrow(DOWN, 5, 10, 5);
+ break;
+ case HLP_HARROW:
+ immUniformThemeColor(TH_VIEW_OVERLAY);
+ GPU_matrix_translate_3fv(mval);
- GPU_matrix_translate_3fv(mval);
+ GPU_line_width(3.0f);
+ drawArrow(RIGHT, 5, 10, 5);
+ drawArrow(LEFT, 5, 10, 5);
+ break;
+ case HLP_VARROW:
+ immUniformThemeColor(TH_VIEW_OVERLAY);
- GPU_line_width(3.0f);
- drawArrow(UP, 5, 10, 5);
- drawArrow(DOWN, 5, 10, 5);
- break;
- case HLP_CARROW:
- {
- /* Draw arrow based on direction defined by custom-points. */
- immUniformThemeColor(TH_VIEW_OVERLAY);
+ GPU_matrix_translate_3fv(mval);
- GPU_matrix_translate_3fv(mval);
+ GPU_line_width(3.0f);
+ drawArrow(UP, 5, 10, 5);
+ drawArrow(DOWN, 5, 10, 5);
+ break;
+ case HLP_CARROW: {
+ /* Draw arrow based on direction defined by custom-points. */
+ immUniformThemeColor(TH_VIEW_OVERLAY);
- GPU_line_width(3.0f);
+ GPU_matrix_translate_3fv(mval);
- const int *data = t->mouse.data;
- const float dx = data[2] - data[0], dy = data[3] - data[1];
- const float angle = -atan2f(dx, dy);
+ GPU_line_width(3.0f);
- GPU_matrix_push();
+ const int *data = t->mouse.data;
+ const float dx = data[2] - data[0], dy = data[3] - data[1];
+ const float angle = -atan2f(dx, dy);
- GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
+ GPU_matrix_push();
- drawArrow(UP, 5, 10, 5);
- drawArrow(DOWN, 5, 10, 5);
+ GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
- GPU_matrix_pop();
- break;
- }
- case HLP_ANGLE:
- {
- float dx = tmval[0] - cent[0], dy = tmval[1] - cent[1];
- float angle = atan2f(dy, dx);
- float dist = hypotf(dx, dy);
- float delta_angle = min_ff(15.0f / dist, (float)M_PI / 4.0f);
- float spacing_angle = min_ff(5.0f / dist, (float)M_PI / 12.0f);
+ drawArrow(UP, 5, 10, 5);
+ drawArrow(DOWN, 5, 10, 5);
- immUniformThemeColor(TH_VIEW_OVERLAY);
+ GPU_matrix_pop();
+ break;
+ }
+ case HLP_ANGLE: {
+ float dx = tmval[0] - cent[0], dy = tmval[1] - cent[1];
+ float angle = atan2f(dy, dx);
+ float dist = hypotf(dx, dy);
+ float delta_angle = min_ff(15.0f / dist, (float)M_PI / 4.0f);
+ float spacing_angle = min_ff(5.0f / dist, (float)M_PI / 12.0f);
- GPU_matrix_translate_3f(cent[0] - tmval[0] + mval[0], cent[1] - tmval[1] + mval[1], 0);
+ immUniformThemeColor(TH_VIEW_OVERLAY);
- GPU_line_width(3.0f);
- drawArc(dist, angle - delta_angle, angle - spacing_angle, 10);
- drawArc(dist, angle + spacing_angle, angle + delta_angle, 10);
+ GPU_matrix_translate_3f(cent[0] - tmval[0] + mval[0], cent[1] - tmval[1] + mval[1], 0);
- GPU_matrix_push();
+ GPU_line_width(3.0f);
+ drawArc(dist, angle - delta_angle, angle - spacing_angle, 10);
+ drawArc(dist, angle + spacing_angle, angle + delta_angle, 10);
- GPU_matrix_translate_3f(cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0);
- GPU_matrix_rotate_axis(RAD2DEGF(angle - delta_angle), 'Z');
+ GPU_matrix_push();
- drawArrowHead(DOWN, 5);
+ GPU_matrix_translate_3f(
+ cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0);
+ GPU_matrix_rotate_axis(RAD2DEGF(angle - delta_angle), 'Z');
- GPU_matrix_pop();
+ drawArrowHead(DOWN, 5);
- GPU_matrix_translate_3f(cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0);
- GPU_matrix_rotate_axis(RAD2DEGF(angle + delta_angle), 'Z');
+ GPU_matrix_pop();
- drawArrowHead(UP, 5);
- break;
- }
- case HLP_TRACKBALL:
- {
- unsigned char col[3], col2[3];
- UI_GetThemeColor3ubv(TH_GRID, col);
+ GPU_matrix_translate_3f(
+ cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0);
+ GPU_matrix_rotate_axis(RAD2DEGF(angle + delta_angle), 'Z');
- GPU_matrix_translate_3fv(mval);
+ drawArrowHead(UP, 5);
+ break;
+ }
+ case HLP_TRACKBALL: {
+ unsigned char col[3], col2[3];
+ UI_GetThemeColor3ubv(TH_GRID, col);
- GPU_line_width(3.0f);
+ GPU_matrix_translate_3fv(mval);
- UI_make_axis_color(col, col2, 'X');
- immUniformColor3ubv(col2);
+ GPU_line_width(3.0f);
- drawArrow(RIGHT, 5, 10, 5);
- drawArrow(LEFT, 5, 10, 5);
+ UI_make_axis_color(col, col2, 'X');
+ immUniformColor3ubv(col2);
- UI_make_axis_color(col, col2, 'Y');
- immUniformColor3ubv(col2);
+ drawArrow(RIGHT, 5, 10, 5);
+ drawArrow(LEFT, 5, 10, 5);
- drawArrow(UP, 5, 10, 5);
- drawArrow(DOWN, 5, 10, 5);
- break;
- }
- }
+ UI_make_axis_color(col, col2, 'Y');
+ immUniformColor3ubv(col2);
- immUnbindProgram();
- GPU_matrix_pop();
- }
+ drawArrow(UP, 5, 10, 5);
+ drawArrow(DOWN, 5, 10, 5);
+ break;
+ }
+ }
+
+ immUnbindProgram();
+ GPU_matrix_pop();
+ }
}
static bool transinfo_show_overlay(const struct bContext *C, TransInfo *t, ARegion *ar)
{
- /* Don't show overlays when not the active view and when overlay is disabled: T57139 */
- bool ok = false;
- if (ar == t->ar) {
- ok = true;
- }
- else {
- ScrArea *sa = CTX_wm_area(C);
- if (sa->spacetype == SPACE_VIEW3D) {
- View3D *v3d = sa->spacedata.first;
- if ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) {
- ok = true;
- }
- }
- }
- return ok;
+ /* Don't show overlays when not the active view and when overlay is disabled: T57139 */
+ bool ok = false;
+ if (ar == t->ar) {
+ ok = true;
+ }
+ else {
+ ScrArea *sa = CTX_wm_area(C);
+ if (sa->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = sa->spacedata.first;
+ if ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) {
+ ok = true;
+ }
+ }
+ }
+ return ok;
}
static void drawTransformView(const struct bContext *C, ARegion *ar, void *arg)
{
- TransInfo *t = arg;
+ TransInfo *t = arg;
- if (!transinfo_show_overlay(C, t, ar)) {
- return;
- }
+ if (!transinfo_show_overlay(C, t, ar)) {
+ return;
+ }
- GPU_line_width(1.0f);
+ GPU_line_width(1.0f);
- drawConstraint(t);
- drawPropCircle(C, t);
- drawSnapping(C, t);
+ drawConstraint(t);
+ drawPropCircle(C, t);
+ drawSnapping(C, t);
- if (ar == t->ar) {
- /* edge slide, vert slide */
- drawEdgeSlide(t);
- drawVertSlide(t);
+ if (ar == t->ar) {
+ /* edge slide, vert slide */
+ drawEdgeSlide(t);
+ drawVertSlide(t);
- /* Rotation */
- drawDial3d(t);
- }
+ /* Rotation */
+ drawDial3d(t);
+ }
}
/* just draw a little warning message in the top-right corner of the viewport
* to warn that autokeying is enabled */
static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar)
{
- rcti rect;
- const char *printable = IFACE_("Auto Keying On");
- float printable_size[2];
- int xco, yco;
+ rcti rect;
+ const char *printable = IFACE_("Auto Keying On");
+ float printable_size[2];
+ int xco, yco;
- ED_region_visible_rect(ar, &rect);
+ ED_region_visible_rect(ar, &rect);
- const int font_id = BLF_default();
- BLF_width_and_height(font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]);
+ const int font_id = BLF_default();
+ BLF_width_and_height(
+ font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]);
- xco = (rect.xmax - U.widget_unit) - (int)printable_size[0];
- yco = (rect.ymax - U.widget_unit);
+ xco = (rect.xmax - U.widget_unit) - (int)printable_size[0];
+ yco = (rect.ymax - U.widget_unit);
- /* warning text (to clarify meaning of overlays)
- * - original color was red to match the icon, but that clashes badly with a less nasty border
- */
- unsigned char color[3];
- UI_GetThemeColorShade3ubv(TH_TEXT_HI, -50, color);
- BLF_color3ubv(font_id, color);
+ /* warning text (to clarify meaning of overlays)
+ * - original color was red to match the icon, but that clashes badly with a less nasty border
+ */
+ unsigned char color[3];
+ UI_GetThemeColorShade3ubv(TH_TEXT_HI, -50, color);
+ BLF_color3ubv(font_id, color);
#ifdef WITH_INTERNATIONAL
- BLF_draw_default(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX);
+ BLF_draw_default(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX);
#else
- BLF_draw_default_ascii(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX);
+ BLF_draw_default_ascii(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX);
#endif
- /* autokey recording icon... */
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ /* autokey recording icon... */
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(true);
- xco -= U.widget_unit;
- yco -= (int)printable_size[1] / 2;
+ xco -= U.widget_unit;
+ yco -= (int)printable_size[1] / 2;
- UI_icon_draw(xco, yco, ICON_REC);
+ UI_icon_draw(xco, yco, ICON_REC);
- GPU_blend(false);
+ GPU_blend(false);
}
static void drawTransformPixel(const struct bContext *C, ARegion *ar, void *arg)
{
- TransInfo *t = arg;
-
- if (!transinfo_show_overlay(C, t, ar)) {
- return;
- }
-
- if (ar == t->ar) {
- Scene *scene = t->scene;
- ViewLayer *view_layer = t->view_layer;
- Object *ob = OBACT(view_layer);
-
- /* draw auto-key-framing hint in the corner
- * - only draw if enabled (advanced users may be distracted/annoyed),
- * for objects that will be autokeyframed (no point otherwise),
- * AND only for the active region (as showing all is too overwhelming)
- */
- if ((U.autokey_flag & AUTOKEY_FLAG_NOWARNING) == 0) {
- if (ar == t->ar) {
- if (t->flag & (T_OBJECT | T_POSE)) {
- if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) {
- drawAutoKeyWarning(t, ar);
- }
- }
- }
- }
- }
+ TransInfo *t = arg;
+
+ if (!transinfo_show_overlay(C, t, ar)) {
+ return;
+ }
+
+ if (ar == t->ar) {
+ Scene *scene = t->scene;
+ ViewLayer *view_layer = t->view_layer;
+ Object *ob = OBACT(view_layer);
+
+ /* draw auto-key-framing hint in the corner
+ * - only draw if enabled (advanced users may be distracted/annoyed),
+ * for objects that will be autokeyframed (no point otherwise),
+ * AND only for the active region (as showing all is too overwhelming)
+ */
+ if ((U.autokey_flag & AUTOKEY_FLAG_NOWARNING) == 0) {
+ if (ar == t->ar) {
+ if (t->flag & (T_OBJECT | T_POSE)) {
+ if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) {
+ drawAutoKeyWarning(t, ar);
+ }
+ }
+ }
+ }
+ }
}
/**
@@ -2060,235 +2070,231 @@ static void drawTransformPixel(const struct bContext *C, ARegion *ar, void *arg)
*/
void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
{
- ToolSettings *ts = CTX_data_tool_settings(C);
- int proportional = 0;
- PropertyRNA *prop;
-
- // Save back mode in case we're in the generic operator
- if ((prop = RNA_struct_find_property(op->ptr, "mode"))) {
- RNA_property_enum_set(op->ptr, prop, t->mode);
- }
-
- if ((prop = RNA_struct_find_property(op->ptr, "value"))) {
- float values[4];
-
- copy_v4_v4(values, (t->flag & T_AUTOVALUES) ? t->auto_values : t->values);
-
- if (RNA_property_array_check(prop)) {
- RNA_property_float_set_array(op->ptr, prop, values);
- }
- else {
- RNA_property_float_set(op->ptr, prop, values[0]);
- }
- }
-
- /* convert flag to enum */
- switch (t->flag & T_PROP_EDIT_ALL) {
- case T_PROP_EDIT:
- proportional = PROP_EDIT_ON;
- break;
- case (T_PROP_EDIT | T_PROP_CONNECTED):
- proportional = PROP_EDIT_CONNECTED;
- break;
- case (T_PROP_EDIT | T_PROP_PROJECTED):
- proportional = PROP_EDIT_PROJECTED;
- break;
- default:
- proportional = PROP_EDIT_OFF;
- break;
- }
-
- // If modal, save settings back in scene if not set as operator argument
- if ((t->flag & T_MODAL) || (op->flag & OP_IS_REPEAT)) {
- /* save settings if not set in operator */
-
- /* skip saving proportional edit if it was not actually used */
- if (!(t->options & CTX_NO_PET)) {
- if ((prop = RNA_struct_find_property(op->ptr, "proportional")) &&
- !RNA_property_is_set(op->ptr, prop))
- {
- if (t->spacetype == SPACE_GRAPH)
- ts->proportional_fcurve = proportional;
- else if (t->spacetype == SPACE_ACTION)
- ts->proportional_action = proportional;
- else if (t->obedit_type != -1)
- ts->proportional = proportional;
- else if (t->options & CTX_MASK)
- ts->proportional_mask = (proportional != PROP_EDIT_OFF);
- else
- ts->proportional_objects = (proportional != PROP_EDIT_OFF);
- }
-
- if ((prop = RNA_struct_find_property(op->ptr, "proportional_size"))) {
- ts->proportional_size =
- RNA_property_is_set(op->ptr, prop) ? RNA_property_float_get(op->ptr, prop) : t->prop_size;
- }
-
- if ((prop = RNA_struct_find_property(op->ptr, "proportional_edit_falloff")) &&
- !RNA_property_is_set(op->ptr, prop))
- {
- ts->prop_mode = t->prop_mode;
- }
- }
-
- /* do we check for parameter? */
- if (transformModeUseSnap(t)) {
- if (t->modifiers & MOD_SNAP) {
- ts->snap_flag |= SCE_SNAP;
- }
- else {
- ts->snap_flag &= ~SCE_SNAP;
- }
- }
-
- if (t->spacetype == SPACE_VIEW3D) {
- if ((prop = RNA_struct_find_property(op->ptr, "orient_type")) &&
- !RNA_property_is_set(op->ptr, prop) &&
- (t->orientation.user != V3D_ORIENT_CUSTOM_MATRIX))
- {
- TransformOrientationSlot *orient_slot = &t->scene->orientation_slots[SCE_ORIENT_DEFAULT];
- orient_slot->type = t->orientation.user;
- BLI_assert(((orient_slot->index_custom == -1) && (t->orientation.custom == NULL)) ||
- (BKE_scene_transform_orientation_get_index(
- t->scene, t->orientation.custom) == orient_slot->index_custom));
- }
- }
- }
-
- if ((prop = RNA_struct_find_property(op->ptr, "proportional"))) {
- RNA_property_enum_set(op->ptr, prop, proportional);
- RNA_enum_set(op->ptr, "proportional_edit_falloff", t->prop_mode);
- RNA_float_set(op->ptr, "proportional_size", t->prop_size);
- }
-
- if ((prop = RNA_struct_find_property(op->ptr, "mirror"))) {
- RNA_property_boolean_set(op->ptr, prop, (t->flag & T_NO_MIRROR) == 0);
- }
-
- /* Orientation used for redo. */
- const bool use_orient_axis = (
- t->orient_matrix_is_set &&
- (RNA_struct_find_property(op->ptr, "orient_axis") != NULL));
- short orientation;
- if (t->con.mode & CON_APPLY) {
- orientation = t->con.orientation;
- if (orientation == V3D_ORIENT_CUSTOM) {
- const int orientation_index_custom = BKE_scene_transform_orientation_get_index(
- t->scene, t->orientation.custom);
- /* Maybe we need a t->con.custom_orientation?
- * Seems like it would always match t->orientation.custom. */
- orientation = V3D_ORIENT_CUSTOM + orientation_index_custom;
- BLI_assert(orientation >= V3D_ORIENT_CUSTOM);
- }
- }
- else if ((t->orientation.user == V3D_ORIENT_CUSTOM_MATRIX) &&
- (prop = RNA_struct_find_property(op->ptr, "orient_matrix_type")))
- {
- orientation = RNA_property_enum_get(op->ptr, prop);
- }
- else if (use_orient_axis) {
- /* We're not using an orientation, use the fallback. */
- orientation = t->orientation.unset;
- }
- else {
- orientation = V3D_ORIENT_GLOBAL;
- }
-
-
- if ((prop = RNA_struct_find_property(op->ptr, "orient_axis"))) {
- if (t->flag & T_MODAL) {
- if (t->con.mode & CON_APPLY) {
- int orient_axis = constraintModeToIndex(t);
- if (orient_axis != -1) {
- RNA_property_enum_set(op->ptr, prop, orient_axis);
- }
- }
- else {
- RNA_property_enum_set(op->ptr, prop, t->orient_axis);
- }
- }
- }
- if ((prop = RNA_struct_find_property(op->ptr, "orient_axis_ortho"))) {
- if (t->flag & T_MODAL) {
- RNA_property_enum_set(op->ptr, prop, t->orient_axis_ortho);
- }
- }
-
- if ((prop = RNA_struct_find_property(op->ptr, "orient_matrix"))) {
- if (t->flag & T_MODAL) {
- if (orientation != V3D_ORIENT_CUSTOM_MATRIX) {
- if (t->flag & T_MODAL) {
- RNA_enum_set(op->ptr, "orient_matrix_type", orientation);
- }
- }
- if (t->con.mode & CON_APPLY) {
- RNA_float_set_array(op->ptr, "orient_matrix", &t->con.mtx[0][0]);
- }
- else if (use_orient_axis) {
- RNA_float_set_array(op->ptr, "orient_matrix", &t->orient_matrix[0][0]);
- }
- else {
- RNA_float_set_array(op->ptr, "orient_matrix", &t->spacemtx[0][0]);
- }
- }
- }
-
- if ((prop = RNA_struct_find_property(op->ptr, "orient_type"))) {
- /* constraint orientation can be global, even if user selects something else
- * so use the orientation in the constraint if set */
-
- /* Use 'orient_matrix' instead. */
- if (t->flag & T_MODAL) {
- if (orientation != V3D_ORIENT_CUSTOM_MATRIX) {
- RNA_property_enum_set(op->ptr, prop, orientation);
- }
- }
- }
-
- if ((prop = RNA_struct_find_property(op->ptr, "constraint_axis"))) {
- bool constraint_axis[3] = {false, false, false};
- if (t->flag & T_MODAL) {
- /* Only set if needed, so we can hide in the UI when nothing is set.
- * See 'transform_poll_property'. */
- if (t->con.mode & CON_APPLY) {
- if (t->con.mode & CON_AXIS0) {
- constraint_axis[0] = true;
- }
- if (t->con.mode & CON_AXIS1) {
- constraint_axis[1] = true;
- }
- if (t->con.mode & CON_AXIS2) {
- constraint_axis[2] = true;
- }
- }
- if (ELEM(true, UNPACK3(constraint_axis))) {
- RNA_property_boolean_set_array(op->ptr, prop, constraint_axis);
- }
- }
- }
-
- {
- const char *prop_id = NULL;
- bool prop_state = true;
- if (t->mode == TFM_SHRINKFATTEN) {
- prop_id = "use_even_offset";
- prop_state = false;
- }
-
- if (prop_id && (prop = RNA_struct_find_property(op->ptr, prop_id))) {
- RNA_property_boolean_set(op->ptr, prop, ((t->flag & T_ALT_TRANSFORM) == 0) == prop_state);
- }
- }
-
- if ((prop = RNA_struct_find_property(op->ptr, "correct_uv"))) {
- RNA_property_boolean_set(op->ptr, prop, (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) != 0);
- }
-
- if (t->mode == TFM_SHEAR) {
- prop = RNA_struct_find_property(op->ptr, "shear_axis");
- t->custom.mode.data = POINTER_FROM_INT(RNA_property_enum_get(op->ptr, prop));
- RNA_property_enum_set(op->ptr, prop, POINTER_AS_INT(t->custom.mode.data));
- }
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ int proportional = 0;
+ PropertyRNA *prop;
+
+ // Save back mode in case we're in the generic operator
+ if ((prop = RNA_struct_find_property(op->ptr, "mode"))) {
+ RNA_property_enum_set(op->ptr, prop, t->mode);
+ }
+
+ if ((prop = RNA_struct_find_property(op->ptr, "value"))) {
+ float values[4];
+
+ copy_v4_v4(values, (t->flag & T_AUTOVALUES) ? t->auto_values : t->values);
+
+ if (RNA_property_array_check(prop)) {
+ RNA_property_float_set_array(op->ptr, prop, values);
+ }
+ else {
+ RNA_property_float_set(op->ptr, prop, values[0]);
+ }
+ }
+
+ /* convert flag to enum */
+ switch (t->flag & T_PROP_EDIT_ALL) {
+ case T_PROP_EDIT:
+ proportional = PROP_EDIT_ON;
+ break;
+ case (T_PROP_EDIT | T_PROP_CONNECTED):
+ proportional = PROP_EDIT_CONNECTED;
+ break;
+ case (T_PROP_EDIT | T_PROP_PROJECTED):
+ proportional = PROP_EDIT_PROJECTED;
+ break;
+ default:
+ proportional = PROP_EDIT_OFF;
+ break;
+ }
+
+ // If modal, save settings back in scene if not set as operator argument
+ if ((t->flag & T_MODAL) || (op->flag & OP_IS_REPEAT)) {
+ /* save settings if not set in operator */
+
+ /* skip saving proportional edit if it was not actually used */
+ if (!(t->options & CTX_NO_PET)) {
+ if ((prop = RNA_struct_find_property(op->ptr, "proportional")) &&
+ !RNA_property_is_set(op->ptr, prop)) {
+ if (t->spacetype == SPACE_GRAPH)
+ ts->proportional_fcurve = proportional;
+ else if (t->spacetype == SPACE_ACTION)
+ ts->proportional_action = proportional;
+ else if (t->obedit_type != -1)
+ ts->proportional = proportional;
+ else if (t->options & CTX_MASK)
+ ts->proportional_mask = (proportional != PROP_EDIT_OFF);
+ else
+ ts->proportional_objects = (proportional != PROP_EDIT_OFF);
+ }
+
+ if ((prop = RNA_struct_find_property(op->ptr, "proportional_size"))) {
+ ts->proportional_size = RNA_property_is_set(op->ptr, prop) ?
+ RNA_property_float_get(op->ptr, prop) :
+ t->prop_size;
+ }
+
+ if ((prop = RNA_struct_find_property(op->ptr, "proportional_edit_falloff")) &&
+ !RNA_property_is_set(op->ptr, prop)) {
+ ts->prop_mode = t->prop_mode;
+ }
+ }
+
+ /* do we check for parameter? */
+ if (transformModeUseSnap(t)) {
+ if (t->modifiers & MOD_SNAP) {
+ ts->snap_flag |= SCE_SNAP;
+ }
+ else {
+ ts->snap_flag &= ~SCE_SNAP;
+ }
+ }
+
+ if (t->spacetype == SPACE_VIEW3D) {
+ if ((prop = RNA_struct_find_property(op->ptr, "orient_type")) &&
+ !RNA_property_is_set(op->ptr, prop) &&
+ (t->orientation.user != V3D_ORIENT_CUSTOM_MATRIX)) {
+ TransformOrientationSlot *orient_slot = &t->scene->orientation_slots[SCE_ORIENT_DEFAULT];
+ orient_slot->type = t->orientation.user;
+ BLI_assert(((orient_slot->index_custom == -1) && (t->orientation.custom == NULL)) ||
+ (BKE_scene_transform_orientation_get_index(t->scene, t->orientation.custom) ==
+ orient_slot->index_custom));
+ }
+ }
+ }
+
+ if ((prop = RNA_struct_find_property(op->ptr, "proportional"))) {
+ RNA_property_enum_set(op->ptr, prop, proportional);
+ RNA_enum_set(op->ptr, "proportional_edit_falloff", t->prop_mode);
+ RNA_float_set(op->ptr, "proportional_size", t->prop_size);
+ }
+
+ if ((prop = RNA_struct_find_property(op->ptr, "mirror"))) {
+ RNA_property_boolean_set(op->ptr, prop, (t->flag & T_NO_MIRROR) == 0);
+ }
+
+ /* Orientation used for redo. */
+ const bool use_orient_axis = (t->orient_matrix_is_set &&
+ (RNA_struct_find_property(op->ptr, "orient_axis") != NULL));
+ short orientation;
+ if (t->con.mode & CON_APPLY) {
+ orientation = t->con.orientation;
+ if (orientation == V3D_ORIENT_CUSTOM) {
+ const int orientation_index_custom = BKE_scene_transform_orientation_get_index(
+ t->scene, t->orientation.custom);
+ /* Maybe we need a t->con.custom_orientation?
+ * Seems like it would always match t->orientation.custom. */
+ orientation = V3D_ORIENT_CUSTOM + orientation_index_custom;
+ BLI_assert(orientation >= V3D_ORIENT_CUSTOM);
+ }
+ }
+ else if ((t->orientation.user == V3D_ORIENT_CUSTOM_MATRIX) &&
+ (prop = RNA_struct_find_property(op->ptr, "orient_matrix_type"))) {
+ orientation = RNA_property_enum_get(op->ptr, prop);
+ }
+ else if (use_orient_axis) {
+ /* We're not using an orientation, use the fallback. */
+ orientation = t->orientation.unset;
+ }
+ else {
+ orientation = V3D_ORIENT_GLOBAL;
+ }
+
+ if ((prop = RNA_struct_find_property(op->ptr, "orient_axis"))) {
+ if (t->flag & T_MODAL) {
+ if (t->con.mode & CON_APPLY) {
+ int orient_axis = constraintModeToIndex(t);
+ if (orient_axis != -1) {
+ RNA_property_enum_set(op->ptr, prop, orient_axis);
+ }
+ }
+ else {
+ RNA_property_enum_set(op->ptr, prop, t->orient_axis);
+ }
+ }
+ }
+ if ((prop = RNA_struct_find_property(op->ptr, "orient_axis_ortho"))) {
+ if (t->flag & T_MODAL) {
+ RNA_property_enum_set(op->ptr, prop, t->orient_axis_ortho);
+ }
+ }
+
+ if ((prop = RNA_struct_find_property(op->ptr, "orient_matrix"))) {
+ if (t->flag & T_MODAL) {
+ if (orientation != V3D_ORIENT_CUSTOM_MATRIX) {
+ if (t->flag & T_MODAL) {
+ RNA_enum_set(op->ptr, "orient_matrix_type", orientation);
+ }
+ }
+ if (t->con.mode & CON_APPLY) {
+ RNA_float_set_array(op->ptr, "orient_matrix", &t->con.mtx[0][0]);
+ }
+ else if (use_orient_axis) {
+ RNA_float_set_array(op->ptr, "orient_matrix", &t->orient_matrix[0][0]);
+ }
+ else {
+ RNA_float_set_array(op->ptr, "orient_matrix", &t->spacemtx[0][0]);
+ }
+ }
+ }
+
+ if ((prop = RNA_struct_find_property(op->ptr, "orient_type"))) {
+ /* constraint orientation can be global, even if user selects something else
+ * so use the orientation in the constraint if set */
+
+ /* Use 'orient_matrix' instead. */
+ if (t->flag & T_MODAL) {
+ if (orientation != V3D_ORIENT_CUSTOM_MATRIX) {
+ RNA_property_enum_set(op->ptr, prop, orientation);
+ }
+ }
+ }
+
+ if ((prop = RNA_struct_find_property(op->ptr, "constraint_axis"))) {
+ bool constraint_axis[3] = {false, false, false};
+ if (t->flag & T_MODAL) {
+ /* Only set if needed, so we can hide in the UI when nothing is set.
+ * See 'transform_poll_property'. */
+ if (t->con.mode & CON_APPLY) {
+ if (t->con.mode & CON_AXIS0) {
+ constraint_axis[0] = true;
+ }
+ if (t->con.mode & CON_AXIS1) {
+ constraint_axis[1] = true;
+ }
+ if (t->con.mode & CON_AXIS2) {
+ constraint_axis[2] = true;
+ }
+ }
+ if (ELEM(true, UNPACK3(constraint_axis))) {
+ RNA_property_boolean_set_array(op->ptr, prop, constraint_axis);
+ }
+ }
+ }
+
+ {
+ const char *prop_id = NULL;
+ bool prop_state = true;
+ if (t->mode == TFM_SHRINKFATTEN) {
+ prop_id = "use_even_offset";
+ prop_state = false;
+ }
+
+ if (prop_id && (prop = RNA_struct_find_property(op->ptr, prop_id))) {
+ RNA_property_boolean_set(op->ptr, prop, ((t->flag & T_ALT_TRANSFORM) == 0) == prop_state);
+ }
+ }
+
+ if ((prop = RNA_struct_find_property(op->ptr, "correct_uv"))) {
+ RNA_property_boolean_set(
+ op->ptr, prop, (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) != 0);
+ }
+
+ if (t->mode == TFM_SHEAR) {
+ prop = RNA_struct_find_property(op->ptr, "shear_axis");
+ t->custom.mode.data = POINTER_FROM_INT(RNA_property_enum_get(op->ptr, prop));
+ RNA_property_enum_set(op->ptr, prop, POINTER_AS_INT(t->custom.mode.data));
+ }
}
/**
@@ -2298,896 +2304,896 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
*/
bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event, int mode)
{
- int options = 0;
- PropertyRNA *prop;
-
- t->context = C;
-
- /* added initialize, for external calls to set stuff in TransInfo, like undo string */
-
- t->state = TRANS_STARTING;
-
- if ((prop = RNA_struct_find_property(op->ptr, "cursor_transform")) && RNA_property_is_set(op->ptr, prop)) {
- if (RNA_property_boolean_get(op->ptr, prop)) {
- options |= CTX_CURSOR;
- }
- }
-
- if ((prop = RNA_struct_find_property(op->ptr, "texture_space")) && RNA_property_is_set(op->ptr, prop)) {
- if (RNA_property_boolean_get(op->ptr, prop)) {
- options |= CTX_TEXTURE;
- }
- }
-
- if ((prop = RNA_struct_find_property(op->ptr, "gpencil_strokes")) && RNA_property_is_set(op->ptr, prop)) {
- if (RNA_property_boolean_get(op->ptr, prop)) {
- options |= CTX_GPENCIL_STROKES;
- }
- }
-
- t->options = options;
-
- t->mode = mode;
-
- /* Needed to translate tweak events to mouse buttons. */
- t->launch_event = event ? WM_userdef_event_type_from_keymap_type(event->type) : -1;
-
- // XXX Remove this when wm_operator_call_internal doesn't use window->eventstate (which can have type = 0)
- // For gizmo only, so assume LEFTMOUSE
- if (t->launch_event == 0) {
- t->launch_event = LEFTMOUSE;
- }
-
- unit_m3(t->spacemtx);
-
- initTransInfo(C, t, op, event);
- initTransformOrientation(C, t);
-
- if (t->spacetype == SPACE_VIEW3D) {
- t->draw_handle_apply = ED_region_draw_cb_activate(t->ar->type, drawTransformApply, t, REGION_DRAW_PRE_VIEW);
- t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
- t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
- t->draw_handle_cursor = WM_paint_cursor_activate(
- CTX_wm_manager(C),
- SPACE_TYPE_ANY, RGN_TYPE_ANY,
- helpline_poll, drawHelpline, t);
- }
- else if (t->spacetype == SPACE_IMAGE) {
- t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
- //t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
- t->draw_handle_cursor = WM_paint_cursor_activate(
- CTX_wm_manager(C),
- SPACE_TYPE_ANY, RGN_TYPE_ANY,
- helpline_poll, drawHelpline, t);
- }
- else if (t->spacetype == SPACE_CLIP) {
- t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
- t->draw_handle_cursor = WM_paint_cursor_activate(
- CTX_wm_manager(C),
- SPACE_TYPE_ANY, RGN_TYPE_ANY,
- helpline_poll, drawHelpline, t);
- }
- else if (t->spacetype == SPACE_NODE) {
- /*t->draw_handle_apply = ED_region_draw_cb_activate(t->ar->type, drawTransformApply, t, REGION_DRAW_PRE_VIEW);*/
- t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
- t->draw_handle_cursor = WM_paint_cursor_activate(
- CTX_wm_manager(C),
- SPACE_TYPE_ANY, RGN_TYPE_ANY,
- helpline_poll, drawHelpline, t);
- }
- else if (t->spacetype == SPACE_GRAPH) {
- t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
- //t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
- t->draw_handle_cursor = WM_paint_cursor_activate(
- CTX_wm_manager(C),
- SPACE_TYPE_ANY, RGN_TYPE_ANY,
- helpline_poll, drawHelpline, t);
- }
- else if (t->spacetype == SPACE_ACTION) {
- t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
- //t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
- t->draw_handle_cursor = WM_paint_cursor_activate(
- CTX_wm_manager(C),
- SPACE_TYPE_ANY, RGN_TYPE_ANY,
- helpline_poll, drawHelpline, t);
- }
-
- createTransData(C, t); // make TransData structs from selection
-
- if (t->data_len_all == 0) {
- postTrans(C, t);
- return 0;
- }
-
- if (event) {
- /* keymap for shortcut header prints */
- t->keymap = WM_keymap_active(CTX_wm_manager(C), op->type->modalkeymap);
-
- /* Stupid code to have Ctrl-Click on gizmo work ok.
- *
- * Do this only for translation/rotation/resize because only these
- * modes are available from gizmo and doing such check could
- * lead to keymap conflicts for other modes (see #31584)
- */
- if (ELEM(mode, TFM_TRANSLATION, TFM_ROTATION, TFM_RESIZE)) {
- wmKeyMapItem *kmi;
-
- for (kmi = t->keymap->items.first; kmi; kmi = kmi->next) {
- if (kmi->flag & KMI_INACTIVE) {
- continue;
- }
-
- if (kmi->propvalue == TFM_MODAL_SNAP_INV_ON && kmi->val == KM_PRESS) {
- if ((ELEM(kmi->type, LEFTCTRLKEY, RIGHTCTRLKEY) && event->ctrl) ||
- (ELEM(kmi->type, LEFTSHIFTKEY, RIGHTSHIFTKEY) && event->shift) ||
- (ELEM(kmi->type, LEFTALTKEY, RIGHTALTKEY) && event->alt) ||
- ((kmi->type == OSKEY) && event->oskey) )
- {
- t->modifiers |= MOD_SNAP_INVERT;
- }
- break;
- }
- }
- }
- }
-
- initSnapping(t, op); // Initialize snapping data AFTER mode flags
-
- initSnapSpatial(t, t->snap_spatial);
-
- /* EVIL! posemode code can switch translation to rotate when 1 bone is selected.
- * will be removed (ton) */
-
- /* EVIL2: we gave as argument also texture space context bit... was cleared */
-
- /* EVIL3: extend mode for animation editors also switches modes...
- * but is best way to avoid duplicate code */
- mode = t->mode;
-
- calculatePropRatio(t);
- calculateCenter(t);
-
- /* Overwrite initial values if operator supplied a non-null vector.
- *
- * Run before init functions so 'values_modal_offset' can be applied on mouse input.
- */
- BLI_assert(is_zero_v4(t->values_modal_offset));
- if ((prop = RNA_struct_find_property(op->ptr, "value")) && RNA_property_is_set(op->ptr, prop)) {
- float values[4] = {0}; /* in case value isn't length 4, avoid uninitialized memory */
-
- if (RNA_property_array_check(prop)) {
- RNA_float_get_array(op->ptr, "value", values);
- }
- else {
- values[0] = RNA_float_get(op->ptr, "value");
- }
-
- copy_v4_v4(t->values, values);
-
- if (t->flag & T_MODAL) {
- copy_v4_v4(t->values_modal_offset, values);
- t->redraw = TREDRAW_HARD;
- }
- else {
- copy_v4_v4(t->auto_values, values);
- t->flag |= T_AUTOVALUES;
- }
- }
-
- if (event) {
- /* Initialize accurate transform to settings requested by keymap. */
- bool use_accurate = false;
- if ((prop = RNA_struct_find_property(op->ptr, "use_accurate")) && RNA_property_is_set(op->ptr, prop)) {
- if (RNA_property_boolean_get(op->ptr, prop)) {
- use_accurate = true;
- }
- }
- initMouseInput(t, &t->mouse, t->center2d, event->mval, use_accurate);
- }
-
- switch (mode) {
- case TFM_TRANSLATION:
- initTranslation(t);
- break;
- case TFM_ROTATION:
- initRotation(t);
- break;
- case TFM_RESIZE:
- initResize(t);
- break;
- case TFM_SKIN_RESIZE:
- initSkinResize(t);
- break;
- case TFM_TOSPHERE:
- initToSphere(t);
- break;
- case TFM_SHEAR:
- prop = RNA_struct_find_property(op->ptr, "shear_axis");
- t->custom.mode.data = POINTER_FROM_INT(RNA_property_enum_get(op->ptr, prop));
- initShear(t);
- break;
- case TFM_BEND:
- initBend(t);
- break;
- case TFM_SHRINKFATTEN:
- initShrinkFatten(t);
- break;
- case TFM_TILT:
- initTilt(t);
- break;
- case TFM_CURVE_SHRINKFATTEN:
- initCurveShrinkFatten(t);
- break;
- case TFM_MASK_SHRINKFATTEN:
- initMaskShrinkFatten(t);
- break;
- case TFM_GPENCIL_SHRINKFATTEN:
- initGPShrinkFatten(t);
- break;
- case TFM_TRACKBALL:
- initTrackball(t);
- break;
- case TFM_PUSHPULL:
- initPushPull(t);
- break;
- case TFM_CREASE:
- initCrease(t);
- break;
- case TFM_BONESIZE:
- { /* used for both B-Bone width (bonesize) as for deform-dist (envelope) */
- /* Note: we have to pick one, use the active object. */
- TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_OK(t);
- bArmature *arm = tc->poseobj->data;
- if (arm->drawtype == ARM_ENVELOPE) {
- initBoneEnvelope(t);
- t->mode = TFM_BONE_ENVELOPE_DIST;
- }
- else {
- initBoneSize(t);
- }
- break;
- }
- case TFM_BONE_ENVELOPE:
- initBoneEnvelope(t);
- break;
- case TFM_BONE_ENVELOPE_DIST:
- initBoneEnvelope(t);
- t->mode = TFM_BONE_ENVELOPE_DIST;
- break;
- case TFM_EDGE_SLIDE:
- case TFM_VERT_SLIDE:
- {
- const bool use_even = (op ? RNA_boolean_get(op->ptr, "use_even") : false);
- const bool flipped = (op ? RNA_boolean_get(op->ptr, "flipped") : false);
- const bool use_clamp = (op ? RNA_boolean_get(op->ptr, "use_clamp") : true);
- if (mode == TFM_EDGE_SLIDE) {
- const bool use_double_side = (op ? !RNA_boolean_get(op->ptr, "single_side") : true);
- initEdgeSlide_ex(t, use_double_side, use_even, flipped, use_clamp);
- }
- else {
- initVertSlide_ex(t, use_even, flipped, use_clamp);
- }
- break;
- }
- case TFM_BONE_ROLL:
- initBoneRoll(t);
- break;
- case TFM_TIME_TRANSLATE:
- initTimeTranslate(t);
- break;
- case TFM_TIME_SLIDE:
- initTimeSlide(t);
- break;
- case TFM_TIME_SCALE:
- initTimeScale(t);
- break;
- case TFM_TIME_DUPLICATE:
- /* same as TFM_TIME_EXTEND, but we need the mode info for later
- * so that duplicate-culling will work properly
- */
- if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA))
- initTranslation(t);
- else
- initTimeTranslate(t);
- t->mode = mode;
- break;
- case TFM_TIME_EXTEND:
- /* now that transdata has been made, do like for TFM_TIME_TRANSLATE (for most Animation
- * Editors because they have only 1D transforms for time values) or TFM_TRANSLATION
- * (for Graph/NLA Editors only since they uses 'standard' transforms to get 2D movement)
- * depending on which editor this was called from
- */
- if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA))
- initTranslation(t);
- else
- initTimeTranslate(t);
- break;
- case TFM_BAKE_TIME:
- initBakeTime(t);
- break;
- case TFM_MIRROR:
- initMirror(t);
- break;
- case TFM_BWEIGHT:
- initBevelWeight(t);
- break;
- case TFM_ALIGN:
- initAlign(t);
- break;
- case TFM_SEQ_SLIDE:
- initSeqSlide(t);
- break;
- case TFM_NORMAL_ROTATION:
- initNormalRotation(t);
- break;
- case TFM_GPENCIL_OPACITY:
- initGPOpacity(t);
- break;
- }
-
- if (t->state == TRANS_CANCEL) {
- postTrans(C, t);
- return 0;
- }
-
- /* Transformation axis from operator */
- if ((prop = RNA_struct_find_property(op->ptr, "orient_axis")) &&
- RNA_property_is_set(op->ptr, prop))
- {
- t->orient_axis = RNA_property_enum_get(op->ptr, prop);
- }
- if ((prop = RNA_struct_find_property(op->ptr, "orient_axis_ortho")) &&
- RNA_property_is_set(op->ptr, prop))
- {
- t->orient_axis_ortho = RNA_property_enum_get(op->ptr, prop);
- }
-
- /* Constraint init from operator */
- if ((t->flag & T_MODAL) ||
- /* For mirror operator the constraint axes are effectively the values. */
- (RNA_struct_find_property(op->ptr, "values") == NULL))
- {
- if ((prop = RNA_struct_find_property(op->ptr, "constraint_axis")) &&
- RNA_property_is_set(op->ptr, prop))
- {
- bool constraint_axis[3];
-
- RNA_property_boolean_get_array(op->ptr, prop, constraint_axis);
-
- if (constraint_axis[0] || constraint_axis[1] || constraint_axis[2]) {
- t->con.mode |= CON_APPLY;
-
- if (constraint_axis[0]) {
- t->con.mode |= CON_AXIS0;
- }
- if (constraint_axis[1]) {
- t->con.mode |= CON_AXIS1;
- }
- if (constraint_axis[2]) {
- t->con.mode |= CON_AXIS2;
- }
-
- setUserConstraint(t, t->orientation.user, t->con.mode, "%s");
- }
- }
- }
- else {
- /* So we can adjust in non global orientation. */
- if (t->orientation.user != V3D_ORIENT_GLOBAL) {
- t->con.mode |= CON_APPLY | CON_AXIS0 | CON_AXIS1 | CON_AXIS2;
- setUserConstraint(t, t->orientation.user, t->con.mode, "%s");
- }
- }
-
- /* Don't write into the values when non-modal because they are already set from operator redo values. */
- if (t->flag & T_MODAL) {
- /* Setup the mouse input with initial values. */
- applyMouseInput(t, &t->mouse, t->mouse.imval, t->values);
- }
-
- if ((prop = RNA_struct_find_property(op->ptr, "preserve_clnor"))) {
- if ((t->flag & T_EDIT) && t->obedit_type == OB_MESH) {
-
- FOREACH_TRANS_DATA_CONTAINER(t, tc) {
- if ((((Mesh *)(tc->obedit->data))->flag & ME_AUTOSMOOTH)) {
- BMEditMesh *em = NULL;// BKE_editmesh_from_object(t->obedit);
- bool do_skip = false;
-
- /* Currently only used for two of three most frequent transform ops,
- * can include more ops.
- * Note that scaling cannot be included here,
- * non-uniform scaling will affect normals. */
- if (ELEM(t->mode, TFM_TRANSLATION, TFM_ROTATION)) {
- if (em->bm->totvertsel == em->bm->totvert) {
- /* No need to invalidate if whole mesh is selected. */
- do_skip = true;
- }
- }
-
- if (t->flag & T_MODAL) {
- RNA_property_boolean_set(op->ptr, prop, false);
- }
- else if (!do_skip) {
- const bool preserve_clnor = RNA_property_boolean_get(op->ptr, prop);
- if (preserve_clnor) {
- BKE_editmesh_lnorspace_update(em);
- t->flag |= T_CLNOR_REBUILD;
- }
- BM_lnorspace_invalidate(em->bm, true);
- }
- }
- }
- }
- }
-
- t->context = NULL;
-
- return 1;
+ int options = 0;
+ PropertyRNA *prop;
+
+ t->context = C;
+
+ /* added initialize, for external calls to set stuff in TransInfo, like undo string */
+
+ t->state = TRANS_STARTING;
+
+ if ((prop = RNA_struct_find_property(op->ptr, "cursor_transform")) &&
+ RNA_property_is_set(op->ptr, prop)) {
+ if (RNA_property_boolean_get(op->ptr, prop)) {
+ options |= CTX_CURSOR;
+ }
+ }
+
+ if ((prop = RNA_struct_find_property(op->ptr, "texture_space")) &&
+ RNA_property_is_set(op->ptr, prop)) {
+ if (RNA_property_boolean_get(op->ptr, prop)) {
+ options |= CTX_TEXTURE;
+ }
+ }
+
+ if ((prop = RNA_struct_find_property(op->ptr, "gpencil_strokes")) &&
+ RNA_property_is_set(op->ptr, prop)) {
+ if (RNA_property_boolean_get(op->ptr, prop)) {
+ options |= CTX_GPENCIL_STROKES;
+ }
+ }
+
+ t->options = options;
+
+ t->mode = mode;
+
+ /* Needed to translate tweak events to mouse buttons. */
+ t->launch_event = event ? WM_userdef_event_type_from_keymap_type(event->type) : -1;
+
+ // XXX Remove this when wm_operator_call_internal doesn't use window->eventstate (which can have type = 0)
+ // For gizmo only, so assume LEFTMOUSE
+ if (t->launch_event == 0) {
+ t->launch_event = LEFTMOUSE;
+ }
+
+ unit_m3(t->spacemtx);
+
+ initTransInfo(C, t, op, event);
+ initTransformOrientation(C, t);
+
+ if (t->spacetype == SPACE_VIEW3D) {
+ t->draw_handle_apply = ED_region_draw_cb_activate(
+ t->ar->type, drawTransformApply, t, REGION_DRAW_PRE_VIEW);
+ t->draw_handle_view = ED_region_draw_cb_activate(
+ t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
+ t->draw_handle_pixel = ED_region_draw_cb_activate(
+ t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
+ t->draw_handle_cursor = WM_paint_cursor_activate(
+ CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t);
+ }
+ else if (t->spacetype == SPACE_IMAGE) {
+ t->draw_handle_view = ED_region_draw_cb_activate(
+ t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
+ //t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
+ t->draw_handle_cursor = WM_paint_cursor_activate(
+ CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t);
+ }
+ else if (t->spacetype == SPACE_CLIP) {
+ t->draw_handle_view = ED_region_draw_cb_activate(
+ t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
+ t->draw_handle_cursor = WM_paint_cursor_activate(
+ CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t);
+ }
+ else if (t->spacetype == SPACE_NODE) {
+ /*t->draw_handle_apply = ED_region_draw_cb_activate(t->ar->type, drawTransformApply, t, REGION_DRAW_PRE_VIEW);*/
+ t->draw_handle_view = ED_region_draw_cb_activate(
+ t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
+ t->draw_handle_cursor = WM_paint_cursor_activate(
+ CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t);
+ }
+ else if (t->spacetype == SPACE_GRAPH) {
+ t->draw_handle_view = ED_region_draw_cb_activate(
+ t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
+ //t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
+ t->draw_handle_cursor = WM_paint_cursor_activate(
+ CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t);
+ }
+ else if (t->spacetype == SPACE_ACTION) {
+ t->draw_handle_view = ED_region_draw_cb_activate(
+ t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
+ //t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
+ t->draw_handle_cursor = WM_paint_cursor_activate(
+ CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t);
+ }
+
+ createTransData(C, t); // make TransData structs from selection
+
+ if (t->data_len_all == 0) {
+ postTrans(C, t);
+ return 0;
+ }
+
+ if (event) {
+ /* keymap for shortcut header prints */
+ t->keymap = WM_keymap_active(CTX_wm_manager(C), op->type->modalkeymap);
+
+ /* Stupid code to have Ctrl-Click on gizmo work ok.
+ *
+ * Do this only for translation/rotation/resize because only these
+ * modes are available from gizmo and doing such check could
+ * lead to keymap conflicts for other modes (see #31584)
+ */
+ if (ELEM(mode, TFM_TRANSLATION, TFM_ROTATION, TFM_RESIZE)) {
+ wmKeyMapItem *kmi;
+
+ for (kmi = t->keymap->items.first; kmi; kmi = kmi->next) {
+ if (kmi->flag & KMI_INACTIVE) {
+ continue;
+ }
+
+ if (kmi->propvalue == TFM_MODAL_SNAP_INV_ON && kmi->val == KM_PRESS) {
+ if ((ELEM(kmi->type, LEFTCTRLKEY, RIGHTCTRLKEY) && event->ctrl) ||
+ (ELEM(kmi->type, LEFTSHIFTKEY, RIGHTSHIFTKEY) && event->shift) ||
+ (ELEM(kmi->type, LEFTALTKEY, RIGHTALTKEY) && event->alt) ||
+ ((kmi->type == OSKEY) && event->oskey)) {
+ t->modifiers |= MOD_SNAP_INVERT;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ initSnapping(t, op); // Initialize snapping data AFTER mode flags
+
+ initSnapSpatial(t, t->snap_spatial);
+
+ /* EVIL! posemode code can switch translation to rotate when 1 bone is selected.
+ * will be removed (ton) */
+
+ /* EVIL2: we gave as argument also texture space context bit... was cleared */
+
+ /* EVIL3: extend mode for animation editors also switches modes...
+ * but is best way to avoid duplicate code */
+ mode = t->mode;
+
+ calculatePropRatio(t);
+ calculateCenter(t);
+
+ /* Overwrite initial values if operator supplied a non-null vector.
+ *
+ * Run before init functions so 'values_modal_offset' can be applied on mouse input.
+ */
+ BLI_assert(is_zero_v4(t->values_modal_offset));
+ if ((prop = RNA_struct_find_property(op->ptr, "value")) && RNA_property_is_set(op->ptr, prop)) {
+ float values[4] = {0}; /* in case value isn't length 4, avoid uninitialized memory */
+
+ if (RNA_property_array_check(prop)) {
+ RNA_float_get_array(op->ptr, "value", values);
+ }
+ else {
+ values[0] = RNA_float_get(op->ptr, "value");
+ }
+
+ copy_v4_v4(t->values, values);
+
+ if (t->flag & T_MODAL) {
+ copy_v4_v4(t->values_modal_offset, values);
+ t->redraw = TREDRAW_HARD;
+ }
+ else {
+ copy_v4_v4(t->auto_values, values);
+ t->flag |= T_AUTOVALUES;
+ }
+ }
+
+ if (event) {
+ /* Initialize accurate transform to settings requested by keymap. */
+ bool use_accurate = false;
+ if ((prop = RNA_struct_find_property(op->ptr, "use_accurate")) &&
+ RNA_property_is_set(op->ptr, prop)) {
+ if (RNA_property_boolean_get(op->ptr, prop)) {
+ use_accurate = true;
+ }
+ }
+ initMouseInput(t, &t->mouse, t->center2d, event->mval, use_accurate);
+ }
+
+ switch (mode) {
+ case TFM_TRANSLATION:
+ initTranslation(t);
+ break;
+ case TFM_ROTATION:
+ initRotation(t);
+ break;
+ case TFM_RESIZE:
+ initResize(t);
+ break;
+ case TFM_SKIN_RESIZE:
+ initSkinResize(t);
+ break;
+ case TFM_TOSPHERE:
+ initToSphere(t);
+ break;
+ case TFM_SHEAR:
+ prop = RNA_struct_find_property(op->ptr, "shear_axis");
+ t->custom.mode.data = POINTER_FROM_INT(RNA_property_enum_get(op->ptr, prop));
+ initShear(t);
+ break;
+ case TFM_BEND:
+ initBend(t);
+ break;
+ case TFM_SHRINKFATTEN:
+ initShrinkFatten(t);
+ break;
+ case TFM_TILT:
+ initTilt(t);
+ break;
+ case TFM_CURVE_SHRINKFATTEN:
+ initCurveShrinkFatten(t);
+ break;
+ case TFM_MASK_SHRINKFATTEN:
+ initMaskShrinkFatten(t);
+ break;
+ case TFM_GPENCIL_SHRINKFATTEN:
+ initGPShrinkFatten(t);
+ break;
+ case TFM_TRACKBALL:
+ initTrackball(t);
+ break;
+ case TFM_PUSHPULL:
+ initPushPull(t);
+ break;
+ case TFM_CREASE:
+ initCrease(t);
+ break;
+ case TFM_BONESIZE: { /* used for both B-Bone width (bonesize) as for deform-dist (envelope) */
+ /* Note: we have to pick one, use the active object. */
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_OK(t);
+ bArmature *arm = tc->poseobj->data;
+ if (arm->drawtype == ARM_ENVELOPE) {
+ initBoneEnvelope(t);
+ t->mode = TFM_BONE_ENVELOPE_DIST;
+ }
+ else {
+ initBoneSize(t);
+ }
+ break;
+ }
+ case TFM_BONE_ENVELOPE:
+ initBoneEnvelope(t);
+ break;
+ case TFM_BONE_ENVELOPE_DIST:
+ initBoneEnvelope(t);
+ t->mode = TFM_BONE_ENVELOPE_DIST;
+ break;
+ case TFM_EDGE_SLIDE:
+ case TFM_VERT_SLIDE: {
+ const bool use_even = (op ? RNA_boolean_get(op->ptr, "use_even") : false);
+ const bool flipped = (op ? RNA_boolean_get(op->ptr, "flipped") : false);
+ const bool use_clamp = (op ? RNA_boolean_get(op->ptr, "use_clamp") : true);
+ if (mode == TFM_EDGE_SLIDE) {
+ const bool use_double_side = (op ? !RNA_boolean_get(op->ptr, "single_side") : true);
+ initEdgeSlide_ex(t, use_double_side, use_even, flipped, use_clamp);
+ }
+ else {
+ initVertSlide_ex(t, use_even, flipped, use_clamp);
+ }
+ break;
+ }
+ case TFM_BONE_ROLL:
+ initBoneRoll(t);
+ break;
+ case TFM_TIME_TRANSLATE:
+ initTimeTranslate(t);
+ break;
+ case TFM_TIME_SLIDE:
+ initTimeSlide(t);
+ break;
+ case TFM_TIME_SCALE:
+ initTimeScale(t);
+ break;
+ case TFM_TIME_DUPLICATE:
+ /* same as TFM_TIME_EXTEND, but we need the mode info for later
+ * so that duplicate-culling will work properly
+ */
+ if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA))
+ initTranslation(t);
+ else
+ initTimeTranslate(t);
+ t->mode = mode;
+ break;
+ case TFM_TIME_EXTEND:
+ /* now that transdata has been made, do like for TFM_TIME_TRANSLATE (for most Animation
+ * Editors because they have only 1D transforms for time values) or TFM_TRANSLATION
+ * (for Graph/NLA Editors only since they uses 'standard' transforms to get 2D movement)
+ * depending on which editor this was called from
+ */
+ if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA))
+ initTranslation(t);
+ else
+ initTimeTranslate(t);
+ break;
+ case TFM_BAKE_TIME:
+ initBakeTime(t);
+ break;
+ case TFM_MIRROR:
+ initMirror(t);
+ break;
+ case TFM_BWEIGHT:
+ initBevelWeight(t);
+ break;
+ case TFM_ALIGN:
+ initAlign(t);
+ break;
+ case TFM_SEQ_SLIDE:
+ initSeqSlide(t);
+ break;
+ case TFM_NORMAL_ROTATION:
+ initNormalRotation(t);
+ break;
+ case TFM_GPENCIL_OPACITY:
+ initGPOpacity(t);
+ break;
+ }
+
+ if (t->state == TRANS_CANCEL) {
+ postTrans(C, t);
+ return 0;
+ }
+
+ /* Transformation axis from operator */
+ if ((prop = RNA_struct_find_property(op->ptr, "orient_axis")) &&
+ RNA_property_is_set(op->ptr, prop)) {
+ t->orient_axis = RNA_property_enum_get(op->ptr, prop);
+ }
+ if ((prop = RNA_struct_find_property(op->ptr, "orient_axis_ortho")) &&
+ RNA_property_is_set(op->ptr, prop)) {
+ t->orient_axis_ortho = RNA_property_enum_get(op->ptr, prop);
+ }
+
+ /* Constraint init from operator */
+ if ((t->flag & T_MODAL) ||
+ /* For mirror operator the constraint axes are effectively the values. */
+ (RNA_struct_find_property(op->ptr, "values") == NULL)) {
+ if ((prop = RNA_struct_find_property(op->ptr, "constraint_axis")) &&
+ RNA_property_is_set(op->ptr, prop)) {
+ bool constraint_axis[3];
+
+ RNA_property_boolean_get_array(op->ptr, prop, constraint_axis);
+
+ if (constraint_axis[0] || constraint_axis[1] || constraint_axis[2]) {
+ t->con.mode |= CON_APPLY;
+
+ if (constraint_axis[0]) {
+ t->con.mode |= CON_AXIS0;
+ }
+ if (constraint_axis[1]) {
+ t->con.mode |= CON_AXIS1;
+ }
+ if (constraint_axis[2]) {
+ t->con.mode |= CON_AXIS2;
+ }
+
+ setUserConstraint(t, t->orientation.user, t->con.mode, "%s");
+ }
+ }
+ }
+ else {
+ /* So we can adjust in non global orientation. */
+ if (t->orientation.user != V3D_ORIENT_GLOBAL) {
+ t->con.mode |= CON_APPLY | CON_AXIS0 | CON_AXIS1 | CON_AXIS2;
+ setUserConstraint(t, t->orientation.user, t->con.mode, "%s");
+ }
+ }
+
+ /* Don't write into the values when non-modal because they are already set from operator redo values. */
+ if (t->flag & T_MODAL) {
+ /* Setup the mouse input with initial values. */
+ applyMouseInput(t, &t->mouse, t->mouse.imval, t->values);
+ }
+
+ if ((prop = RNA_struct_find_property(op->ptr, "preserve_clnor"))) {
+ if ((t->flag & T_EDIT) && t->obedit_type == OB_MESH) {
+
+ FOREACH_TRANS_DATA_CONTAINER(t, tc)
+ {
+ if ((((Mesh *)(tc->obedit->data))->flag & ME_AUTOSMOOTH)) {
+ BMEditMesh *em = NULL; // BKE_editmesh_from_object(t->obedit);
+ bool do_skip = false;
+
+ /* Currently only used for two of three most frequent transform ops,
+ * can include more ops.
+ * Note that scaling cannot be included here,
+ * non-uniform scaling will affect normals. */
+ if (ELEM(t->mode, TFM_TRANSLATION, TFM_ROTATION)) {
+ if (em->bm->totvertsel == em->bm->totvert) {
+ /* No need to invalidate if whole mesh is selected. */
+ do_skip = true;
+ }
+ }
+
+ if (t->flag & T_MODAL) {
+ RNA_property_boolean_set(op->ptr, prop, false);
+ }
+ else if (!do_skip) {
+ const bool preserve_clnor = RNA_property_boolean_get(op->ptr, prop);
+ if (preserve_clnor) {
+ BKE_editmesh_lnorspace_update(em);
+ t->flag |= T_CLNOR_REBUILD;
+ }
+ BM_lnorspace_invalidate(em->bm, true);
+ }
+ }
+ }
+ }
+ }
+
+ t->context = NULL;
+
+ return 1;
}
void transformApply(bContext *C, TransInfo *t)
{
- t->context = C;
+ t->context = C;
- if ((t->redraw & TREDRAW_HARD) || (t->draw_handle_apply == NULL && (t->redraw & TREDRAW_SOFT))) {
- selectConstraint(t);
- if (t->transform) {
- t->transform(t, t->mval); // calls recalcData()
- viewRedrawForce(C, t);
- }
- t->redraw = TREDRAW_NOTHING;
- }
- else if (t->redraw & TREDRAW_SOFT) {
- viewRedrawForce(C, t);
- }
+ if ((t->redraw & TREDRAW_HARD) || (t->draw_handle_apply == NULL && (t->redraw & TREDRAW_SOFT))) {
+ selectConstraint(t);
+ if (t->transform) {
+ t->transform(t, t->mval); // calls recalcData()
+ viewRedrawForce(C, t);
+ }
+ t->redraw = TREDRAW_NOTHING;
+ }
+ else if (t->redraw & TREDRAW_SOFT) {
+ viewRedrawForce(C, t);
+ }
- /* If auto confirm is on, break after one pass */
- if (t->options & CTX_AUTOCONFIRM) {
- t->state = TRANS_CONFIRM;
- }
+ /* If auto confirm is on, break after one pass */
+ if (t->options & CTX_AUTOCONFIRM) {
+ t->state = TRANS_CONFIRM;
+ }
- t->context = NULL;
+ t->context = NULL;
}
static void drawTransformApply(const bContext *C, ARegion *UNUSED(ar), void *arg)
{
- TransInfo *t = arg;
+ TransInfo *t = arg;
- if (t->redraw & TREDRAW_SOFT) {
- t->redraw |= TREDRAW_HARD;
- transformApply((bContext *)C, t);
- }
+ if (t->redraw & TREDRAW_SOFT) {
+ t->redraw |= TREDRAW_HARD;
+ transformApply((bContext *)C, t);
+ }
}
int transformEnd(bContext *C, TransInfo *t)
{
- int exit_code = OPERATOR_RUNNING_MODAL;
+ int exit_code = OPERATOR_RUNNING_MODAL;
- t->context = C;
+ t->context = C;
- if (t->state != TRANS_STARTING && t->state != TRANS_RUNNING) {
- /* handle restoring objects */
- if (t->state == TRANS_CANCEL) {
- /* exception, edge slide transformed UVs too */
- if (t->mode == TFM_EDGE_SLIDE) {
- doEdgeSlide(t, 0.0f);
- }
- else if (t->mode == TFM_VERT_SLIDE) {
- doVertSlide(t, 0.0f);
- }
+ if (t->state != TRANS_STARTING && t->state != TRANS_RUNNING) {
+ /* handle restoring objects */
+ if (t->state == TRANS_CANCEL) {
+ /* exception, edge slide transformed UVs too */
+ if (t->mode == TFM_EDGE_SLIDE) {
+ doEdgeSlide(t, 0.0f);
+ }
+ else if (t->mode == TFM_VERT_SLIDE) {
+ doVertSlide(t, 0.0f);
+ }
- exit_code = OPERATOR_CANCELLED;
- restoreTransObjects(t); // calls recalcData()
- }
- else {
- if (t->flag & T_CLNOR_REBUILD) {
- FOREACH_TRANS_DATA_CONTAINER(t, tc) {
- BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
- BM_lnorspace_rebuild(em->bm, true);
- }
- }
- exit_code = OPERATOR_FINISHED;
- }
+ exit_code = OPERATOR_CANCELLED;
+ restoreTransObjects(t); // calls recalcData()
+ }
+ else {
+ if (t->flag & T_CLNOR_REBUILD) {
+ FOREACH_TRANS_DATA_CONTAINER(t, tc)
+ {
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+ BM_lnorspace_rebuild(em->bm, true);
+ }
+ }
+ exit_code = OPERATOR_FINISHED;
+ }
- /* aftertrans does insert keyframes, and clears base flags; doesn't read transdata */
- special_aftertrans_update(C, t);
+ /* aftertrans does insert keyframes, and clears base flags; doesn't read transdata */
+ special_aftertrans_update(C, t);
- /* free data */
- postTrans(C, t);
+ /* free data */
+ postTrans(C, t);
- /* send events out for redraws */
- viewRedrawPost(C, t);
+ /* send events out for redraws */
+ viewRedrawPost(C, t);
- viewRedrawForce(C, t);
- }
+ viewRedrawForce(C, t);
+ }
- t->context = NULL;
+ t->context = NULL;
- return exit_code;
+ return exit_code;
}
/* ************************** TRANSFORM LOCKS **************************** */
static void protectedTransBits(short protectflag, float vec[3])
{
- if (protectflag & OB_LOCK_LOCX)
- vec[0] = 0.0f;
- if (protectflag & OB_LOCK_LOCY)
- vec[1] = 0.0f;
- if (protectflag & OB_LOCK_LOCZ)
- vec[2] = 0.0f;
+ if (protectflag & OB_LOCK_LOCX)
+ vec[0] = 0.0f;
+ if (protectflag & OB_LOCK_LOCY)
+ vec[1] = 0.0f;
+ if (protectflag & OB_LOCK_LOCZ)
+ vec[2] = 0.0f;
}
static void protectedSizeBits(short protectflag, float size[3])
{
- if (protectflag & OB_LOCK_SCALEX)
- size[0] = 1.0f;
- if (protectflag & OB_LOCK_SCALEY)
- size[1] = 1.0f;
- if (protectflag & OB_LOCK_SCALEZ)
- size[2] = 1.0f;
+ if (protectflag & OB_LOCK_SCALEX)
+ size[0] = 1.0f;
+ if (protectflag & OB_LOCK_SCALEY)
+ size[1] = 1.0f;
+ if (protectflag & OB_LOCK_SCALEZ)
+ size[2] = 1.0f;
}
static void protectedRotateBits(short protectflag, float eul[3], const float oldeul[3])
{
- if (protectflag & OB_LOCK_ROTX)
- eul[0] = oldeul[0];
- if (protectflag & OB_LOCK_ROTY)
- eul[1] = oldeul[1];
- if (protectflag & OB_LOCK_ROTZ)
- eul[2] = oldeul[2];
+ if (protectflag & OB_LOCK_ROTX)
+ eul[0] = oldeul[0];
+ if (protectflag & OB_LOCK_ROTY)
+ eul[1] = oldeul[1];
+ if (protectflag & OB_LOCK_ROTZ)
+ eul[2] = oldeul[2];
}
-
/* this function only does the delta rotation */
/* axis-angle is usually internally stored as quats... */
-static void protectedAxisAngleBits(short protectflag, float axis[3], float *angle, float oldAxis[3], float oldAngle)
-{
- /* check that protection flags are set */
- if ((protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) == 0)
- return;
-
- if (protectflag & OB_LOCK_ROT4D) {
- /* axis-angle getting limited as 4D entities that they are... */
- if (protectflag & OB_LOCK_ROTW)
- *angle = oldAngle;
- if (protectflag & OB_LOCK_ROTX)
- axis[0] = oldAxis[0];
- if (protectflag & OB_LOCK_ROTY)
- axis[1] = oldAxis[1];
- if (protectflag & OB_LOCK_ROTZ)
- axis[2] = oldAxis[2];
- }
- else {
- /* axis-angle get limited with euler... */
- float eul[3], oldeul[3];
-
- axis_angle_to_eulO(eul, EULER_ORDER_DEFAULT, axis, *angle);
- axis_angle_to_eulO(oldeul, EULER_ORDER_DEFAULT, oldAxis, oldAngle);
-
- if (protectflag & OB_LOCK_ROTX)
- eul[0] = oldeul[0];
- if (protectflag & OB_LOCK_ROTY)
- eul[1] = oldeul[1];
- if (protectflag & OB_LOCK_ROTZ)
- eul[2] = oldeul[2];
-
- eulO_to_axis_angle(axis, angle, eul, EULER_ORDER_DEFAULT);
-
- /* when converting to axis-angle, we need a special exception for the case when there is no axis */
- if (IS_EQF(axis[0], axis[1]) && IS_EQF(axis[1], axis[2])) {
- /* for now, rotate around y-axis then (so that it simply becomes the roll) */
- axis[1] = 1.0f;
- }
- }
+static void protectedAxisAngleBits(
+ short protectflag, float axis[3], float *angle, float oldAxis[3], float oldAngle)
+{
+ /* check that protection flags are set */
+ if ((protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) == 0)
+ return;
+
+ if (protectflag & OB_LOCK_ROT4D) {
+ /* axis-angle getting limited as 4D entities that they are... */
+ if (protectflag & OB_LOCK_ROTW)
+ *angle = oldAngle;
+ if (protectflag & OB_LOCK_ROTX)
+ axis[0] = oldAxis[0];
+ if (protectflag & OB_LOCK_ROTY)
+ axis[1] = oldAxis[1];
+ if (protectflag & OB_LOCK_ROTZ)
+ axis[2] = oldAxis[2];
+ }
+ else {
+ /* axis-angle get limited with euler... */
+ float eul[3], oldeul[3];
+
+ axis_angle_to_eulO(eul, EULER_ORDER_DEFAULT, axis, *angle);
+ axis_angle_to_eulO(oldeul, EULER_ORDER_DEFAULT, oldAxis, oldAngle);
+
+ if (protectflag & OB_LOCK_ROTX)
+ eul[0] = oldeul[0];
+ if (protectflag & OB_LOCK_ROTY)
+ eul[1] = oldeul[1];
+ if (protectflag & OB_LOCK_ROTZ)
+ eul[2] = oldeul[2];
+
+ eulO_to_axis_angle(axis, angle, eul, EULER_ORDER_DEFAULT);
+
+ /* when converting to axis-angle, we need a special exception for the case when there is no axis */
+ if (IS_EQF(axis[0], axis[1]) && IS_EQF(axis[1], axis[2])) {
+ /* for now, rotate around y-axis then (so that it simply becomes the roll) */
+ axis[1] = 1.0f;
+ }
+ }
}
/* this function only does the delta rotation */
static void protectedQuaternionBits(short protectflag, float quat[4], const float oldquat[4])
{
- /* check that protection flags are set */
- if ((protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) == 0)
- return;
-
- if (protectflag & OB_LOCK_ROT4D) {
- /* quaternions getting limited as 4D entities that they are... */
- if (protectflag & OB_LOCK_ROTW)
- quat[0] = oldquat[0];
- if (protectflag & OB_LOCK_ROTX)
- quat[1] = oldquat[1];
- if (protectflag & OB_LOCK_ROTY)
- quat[2] = oldquat[2];
- if (protectflag & OB_LOCK_ROTZ)
- quat[3] = oldquat[3];
- }
- else {
- /* quaternions get limited with euler... (compatibility mode) */
- float eul[3], oldeul[3], nquat[4], noldquat[4];
- float qlen;
-
- qlen = normalize_qt_qt(nquat, quat);
- normalize_qt_qt(noldquat, oldquat);
-
- quat_to_eul(eul, nquat);
- quat_to_eul(oldeul, noldquat);
-
- if (protectflag & OB_LOCK_ROTX)
- eul[0] = oldeul[0];
- if (protectflag & OB_LOCK_ROTY)
- eul[1] = oldeul[1];
- if (protectflag & OB_LOCK_ROTZ)
- eul[2] = oldeul[2];
-
- eul_to_quat(quat, eul);
-
- /* restore original quat size */
- mul_qt_fl(quat, qlen);
-
- /* quaternions flip w sign to accumulate rotations correctly */
- if ((nquat[0] < 0.0f && quat[0] > 0.0f) ||
- (nquat[0] > 0.0f && quat[0] < 0.0f))
- {
- mul_qt_fl(quat, -1.0f);
- }
- }
+ /* check that protection flags are set */
+ if ((protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) == 0)
+ return;
+
+ if (protectflag & OB_LOCK_ROT4D) {
+ /* quaternions getting limited as 4D entities that they are... */
+ if (protectflag & OB_LOCK_ROTW)
+ quat[0] = oldquat[0];
+ if (protectflag & OB_LOCK_ROTX)
+ quat[1] = oldquat[1];
+ if (protectflag & OB_LOCK_ROTY)
+ quat[2] = oldquat[2];
+ if (protectflag & OB_LOCK_ROTZ)
+ quat[3] = oldquat[3];
+ }
+ else {
+ /* quaternions get limited with euler... (compatibility mode) */
+ float eul[3], oldeul[3], nquat[4], noldquat[4];
+ float qlen;
+
+ qlen = normalize_qt_qt(nquat, quat);
+ normalize_qt_qt(noldquat, oldquat);
+
+ quat_to_eul(eul, nquat);
+ quat_to_eul(oldeul, noldquat);
+
+ if (protectflag & OB_LOCK_ROTX)
+ eul[0] = oldeul[0];
+ if (protectflag & OB_LOCK_ROTY)
+ eul[1] = oldeul[1];
+ if (protectflag & OB_LOCK_ROTZ)
+ eul[2] = oldeul[2];
+
+ eul_to_quat(quat, eul);
+
+ /* restore original quat size */
+ mul_qt_fl(quat, qlen);
+
+ /* quaternions flip w sign to accumulate rotations correctly */
+ if ((nquat[0] < 0.0f && quat[0] > 0.0f) || (nquat[0] > 0.0f && quat[0] < 0.0f)) {
+ mul_qt_fl(quat, -1.0f);
+ }
+ }
}
/* ******************* TRANSFORM LIMITS ********************** */
static void constraintTransLim(TransInfo *t, TransData *td)
{
- if (td->con) {
- const bConstraintTypeInfo *ctiLoc = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_LOCLIMIT);
- const bConstraintTypeInfo *ctiDist = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_DISTLIMIT);
-
- bConstraintOb cob = {NULL};
- bConstraint *con;
- float ctime = (float)(t->scene->r.cfra);
-
- /* Make a temporary bConstraintOb for using these limit constraints
- * - they only care that cob->matrix is correctly set ;-)
- * - current space should be local
- */
- unit_m4(cob.matrix);
- copy_v3_v3(cob.matrix[3], td->loc);
-
- /* Evaluate valid constraints */
- for (con = td->con; con; con = con->next) {
- const bConstraintTypeInfo *cti = NULL;
- ListBase targets = {NULL, NULL};
-
- /* only consider constraint if enabled */
- if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) continue;
- if (con->enforce == 0.0f) continue;
-
- /* only use it if it's tagged for this purpose (and the right type) */
- if (con->type == CONSTRAINT_TYPE_LOCLIMIT) {
- bLocLimitConstraint *data = con->data;
-
- if ((data->flag2 & LIMIT_TRANSFORM) == 0)
- continue;
- cti = ctiLoc;
- }
- else if (con->type == CONSTRAINT_TYPE_DISTLIMIT) {
- bDistLimitConstraint *data = con->data;
-
- if ((data->flag & LIMITDIST_TRANSFORM) == 0)
- continue;
- cti = ctiDist;
- }
-
- if (cti) {
- /* do space conversions */
- if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
- /* just multiply by td->mtx (this should be ok) */
- mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
- }
- else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
- /* skip... incompatible spacetype */
- continue;
- }
-
- /* get constraint targets if needed */
- BKE_constraint_targets_for_solving_get(t->depsgraph, con, &cob, &targets, ctime);
-
- /* do constraint */
- cti->evaluate_constraint(con, &cob, &targets);
-
- /* convert spaces again */
- if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
- /* just multiply by td->smtx (this should be ok) */
- mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
- }
-
- /* free targets list */
- BLI_freelistN(&targets);
- }
- }
-
- /* copy results from cob->matrix */
- copy_v3_v3(td->loc, cob.matrix[3]);
- }
+ if (td->con) {
+ const bConstraintTypeInfo *ctiLoc = BKE_constraint_typeinfo_from_type(
+ CONSTRAINT_TYPE_LOCLIMIT);
+ const bConstraintTypeInfo *ctiDist = BKE_constraint_typeinfo_from_type(
+ CONSTRAINT_TYPE_DISTLIMIT);
+
+ bConstraintOb cob = {NULL};
+ bConstraint *con;
+ float ctime = (float)(t->scene->r.cfra);
+
+ /* Make a temporary bConstraintOb for using these limit constraints
+ * - they only care that cob->matrix is correctly set ;-)
+ * - current space should be local
+ */
+ unit_m4(cob.matrix);
+ copy_v3_v3(cob.matrix[3], td->loc);
+
+ /* Evaluate valid constraints */
+ for (con = td->con; con; con = con->next) {
+ const bConstraintTypeInfo *cti = NULL;
+ ListBase targets = {NULL, NULL};
+
+ /* only consider constraint if enabled */
+ if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF))
+ continue;
+ if (con->enforce == 0.0f)
+ continue;
+
+ /* only use it if it's tagged for this purpose (and the right type) */
+ if (con->type == CONSTRAINT_TYPE_LOCLIMIT) {
+ bLocLimitConstraint *data = con->data;
+
+ if ((data->flag2 & LIMIT_TRANSFORM) == 0)
+ continue;
+ cti = ctiLoc;
+ }
+ else if (con->type == CONSTRAINT_TYPE_DISTLIMIT) {
+ bDistLimitConstraint *data = con->data;
+
+ if ((data->flag & LIMITDIST_TRANSFORM) == 0)
+ continue;
+ cti = ctiDist;
+ }
+
+ if (cti) {
+ /* do space conversions */
+ if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
+ /* just multiply by td->mtx (this should be ok) */
+ mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
+ }
+ else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
+ /* skip... incompatible spacetype */
+ continue;
+ }
+
+ /* get constraint targets if needed */
+ BKE_constraint_targets_for_solving_get(t->depsgraph, con, &cob, &targets, ctime);
+
+ /* do constraint */
+ cti->evaluate_constraint(con, &cob, &targets);
+
+ /* convert spaces again */
+ if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
+ /* just multiply by td->smtx (this should be ok) */
+ mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
+ }
+
+ /* free targets list */
+ BLI_freelistN(&targets);
+ }
+ }
+
+ /* copy results from cob->matrix */
+ copy_v3_v3(td->loc, cob.matrix[3]);
+ }
}
static void constraintob_from_transdata(bConstraintOb *cob, TransData *td)
{
- /* Make a temporary bConstraintOb for use by limit constraints
- * - they only care that cob->matrix is correctly set ;-)
- * - current space should be local
- */
- memset(cob, 0, sizeof(bConstraintOb));
- if (td->ext) {
- if (td->ext->rotOrder == ROT_MODE_QUAT) {
- /* quats */
- /* objects and bones do normalization first too, otherwise
- * we don't necessarily end up with a rotation matrix, and
- * then conversion back to quat gives a different result */
- float quat[4];
- normalize_qt_qt(quat, td->ext->quat);
- quat_to_mat4(cob->matrix, quat);
- }
- else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
- /* axis angle */
- axis_angle_to_mat4(cob->matrix, td->ext->rotAxis, *td->ext->rotAngle);
- }
- else {
- /* eulers */
- eulO_to_mat4(cob->matrix, td->ext->rot, td->ext->rotOrder);
- }
- }
+ /* Make a temporary bConstraintOb for use by limit constraints
+ * - they only care that cob->matrix is correctly set ;-)
+ * - current space should be local
+ */
+ memset(cob, 0, sizeof(bConstraintOb));
+ if (td->ext) {
+ if (td->ext->rotOrder == ROT_MODE_QUAT) {
+ /* quats */
+ /* objects and bones do normalization first too, otherwise
+ * we don't necessarily end up with a rotation matrix, and
+ * then conversion back to quat gives a different result */
+ float quat[4];
+ normalize_qt_qt(quat, td->ext->quat);
+ quat_to_mat4(cob->matrix, quat);
+ }
+ else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
+ /* axis angle */
+ axis_angle_to_mat4(cob->matrix, td->ext->rotAxis, *td->ext->rotAngle);
+ }
+ else {
+ /* eulers */
+ eulO_to_mat4(cob->matrix, td->ext->rot, td->ext->rotOrder);
+ }
+ }
}
static void constraintRotLim(TransInfo *UNUSED(t), TransData *td)
{
- if (td->con) {
- const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_ROTLIMIT);
- bConstraintOb cob;
- bConstraint *con;
- bool do_limit = false;
-
- /* Evaluate valid constraints */
- for (con = td->con; con; con = con->next) {
- /* only consider constraint if enabled */
- if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) continue;
- if (con->enforce == 0.0f) continue;
-
- /* we're only interested in Limit-Rotation constraints */
- if (con->type == CONSTRAINT_TYPE_ROTLIMIT) {
- bRotLimitConstraint *data = con->data;
-
- /* only use it if it's tagged for this purpose */
- if ((data->flag2 & LIMIT_TRANSFORM) == 0)
- continue;
-
- /* skip incompatible spacetypes */
- if (!ELEM(con->ownspace, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL))
- continue;
-
- /* only do conversion if necessary, to preserve quats and eulers */
- if (do_limit == false) {
- constraintob_from_transdata(&cob, td);
- do_limit = true;
- }
-
- /* do space conversions */
- if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
- /* just multiply by td->mtx (this should be ok) */
- mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
- }
-
- /* do constraint */
- cti->evaluate_constraint(con, &cob, NULL);
-
- /* convert spaces again */
- if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
- /* just multiply by td->smtx (this should be ok) */
- mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
- }
- }
- }
-
- if (do_limit) {
- /* copy results from cob->matrix */
- if (td->ext->rotOrder == ROT_MODE_QUAT) {
- /* quats */
- mat4_to_quat(td->ext->quat, cob.matrix);
- }
- else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
- /* axis angle */
- mat4_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, cob.matrix);
- }
- else {
- /* eulers */
- mat4_to_eulO(td->ext->rot, td->ext->rotOrder, cob.matrix);
- }
- }
- }
+ if (td->con) {
+ const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_ROTLIMIT);
+ bConstraintOb cob;
+ bConstraint *con;
+ bool do_limit = false;
+
+ /* Evaluate valid constraints */
+ for (con = td->con; con; con = con->next) {
+ /* only consider constraint if enabled */
+ if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF))
+ continue;
+ if (con->enforce == 0.0f)
+ continue;
+
+ /* we're only interested in Limit-Rotation constraints */
+ if (con->type == CONSTRAINT_TYPE_ROTLIMIT) {
+ bRotLimitConstraint *data = con->data;
+
+ /* only use it if it's tagged for this purpose */
+ if ((data->flag2 & LIMIT_TRANSFORM) == 0)
+ continue;
+
+ /* skip incompatible spacetypes */
+ if (!ELEM(con->ownspace, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL))
+ continue;
+
+ /* only do conversion if necessary, to preserve quats and eulers */
+ if (do_limit == false) {
+ constraintob_from_transdata(&cob, td);
+ do_limit = true;
+ }
+
+ /* do space conversions */
+ if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
+ /* just multiply by td->mtx (this should be ok) */
+ mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
+ }
+
+ /* do constraint */
+ cti->evaluate_constraint(con, &cob, NULL);
+
+ /* convert spaces again */
+ if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
+ /* just multiply by td->smtx (this should be ok) */
+ mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
+ }
+ }
+ }
+
+ if (do_limit) {
+ /* copy results from cob->matrix */
+ if (td->ext->rotOrder == ROT_MODE_QUAT) {
+ /* quats */
+ mat4_to_quat(td->ext->quat, cob.matrix);
+ }
+ else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
+ /* axis angle */
+ mat4_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, cob.matrix);
+ }
+ else {
+ /* eulers */
+ mat4_to_eulO(td->ext->rot, td->ext->rotOrder, cob.matrix);
+ }
+ }
+ }
}
static void constraintSizeLim(TransInfo *t, TransData *td)
{
- if (td->con && td->ext) {
- const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_SIZELIMIT);
- bConstraintOb cob = {NULL};
- bConstraint *con;
- float size_sign[3], size_abs[3];
- int i;
-
- /* Make a temporary bConstraintOb for using these limit constraints
- * - they only care that cob->matrix is correctly set ;-)
- * - current space should be local
- */
- if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
- /* scale val and reset size */
- return; // TODO: fix this case
- }
- else {
- /* Reset val if SINGLESIZE but using a constraint */
- if (td->flag & TD_SINGLESIZE)
- return;
-
- /* separate out sign to apply back later */
- for (i = 0; i < 3; i++) {
- size_sign[i] = signf(td->ext->size[i]);
- size_abs[i] = fabsf(td->ext->size[i]);
- }
-
- size_to_mat4(cob.matrix, size_abs);
- }
-
- /* Evaluate valid constraints */
- for (con = td->con; con; con = con->next) {
- /* only consider constraint if enabled */
- if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) continue;
- if (con->enforce == 0.0f) continue;
-
- /* we're only interested in Limit-Scale constraints */
- if (con->type == CONSTRAINT_TYPE_SIZELIMIT) {
- bSizeLimitConstraint *data = con->data;
-
- /* only use it if it's tagged for this purpose */
- if ((data->flag2 & LIMIT_TRANSFORM) == 0)
- continue;
-
- /* do space conversions */
- if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
- /* just multiply by td->mtx (this should be ok) */
- mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
- }
- else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
- /* skip... incompatible spacetype */
- continue;
- }
-
- /* do constraint */
- cti->evaluate_constraint(con, &cob, NULL);
-
- /* convert spaces again */
- if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
- /* just multiply by td->smtx (this should be ok) */
- mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
- }
- }
- }
-
- /* copy results from cob->matrix */
- if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
- /* scale val and reset size */
- return; // TODO: fix this case
- }
- else {
- /* Reset val if SINGLESIZE but using a constraint */
- if (td->flag & TD_SINGLESIZE)
- return;
-
- /* extrace scale from matrix and apply back sign */
- mat4_to_size(td->ext->size, cob.matrix);
- mul_v3_v3(td->ext->size, size_sign);
- }
- }
+ if (td->con && td->ext) {
+ const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_SIZELIMIT);
+ bConstraintOb cob = {NULL};
+ bConstraint *con;
+ float size_sign[3], size_abs[3];
+ int i;
+
+ /* Make a temporary bConstraintOb for using these limit constraints
+ * - they only care that cob->matrix is correctly set ;-)
+ * - current space should be local
+ */
+ if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
+ /* scale val and reset size */
+ return; // TODO: fix this case
+ }
+ else {
+ /* Reset val if SINGLESIZE but using a constraint */
+ if (td->flag & TD_SINGLESIZE)
+ return;
+
+ /* separate out sign to apply back later */
+ for (i = 0; i < 3; i++) {
+ size_sign[i] = signf(td->ext->size[i]);
+ size_abs[i] = fabsf(td->ext->size[i]);
+ }
+
+ size_to_mat4(cob.matrix, size_abs);
+ }
+
+ /* Evaluate valid constraints */
+ for (con = td->con; con; con = con->next) {
+ /* only consider constraint if enabled */
+ if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF))
+ continue;
+ if (con->enforce == 0.0f)
+ continue;
+
+ /* we're only interested in Limit-Scale constraints */
+ if (con->type == CONSTRAINT_TYPE_SIZELIMIT) {
+ bSizeLimitConstraint *data = con->data;
+
+ /* only use it if it's tagged for this purpose */
+ if ((data->flag2 & LIMIT_TRANSFORM) == 0)
+ continue;
+
+ /* do space conversions */
+ if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
+ /* just multiply by td->mtx (this should be ok) */
+ mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
+ }
+ else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
+ /* skip... incompatible spacetype */
+ continue;
+ }
+
+ /* do constraint */
+ cti->evaluate_constraint(con, &cob, NULL);
+
+ /* convert spaces again */
+ if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
+ /* just multiply by td->smtx (this should be ok) */
+ mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
+ }
+ }
+ }
+
+ /* copy results from cob->matrix */
+ if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
+ /* scale val and reset size */
+ return; // TODO: fix this case
+ }
+ else {
+ /* Reset val if SINGLESIZE but using a constraint */
+ if (td->flag & TD_SINGLESIZE)
+ return;
+
+ /* extrace scale from matrix and apply back sign */
+ mat4_to_size(td->ext->size, cob.matrix);
+ mul_v3_v3(td->ext->size, size_sign);
+ }
+ }
}
-
/* -------------------------------------------------------------------- */
/* Transform (Bend) */
@@ -3195,246 +3201,258 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
* \{ */
struct BendCustomData {
- /* All values are in global space. */
- float warp_sta[3];
- float warp_end[3];
+ /* All values are in global space. */
+ float warp_sta[3];
+ float warp_end[3];
- float warp_nor[3];
- float warp_tan[3];
+ float warp_nor[3];
+ float warp_tan[3];
- /* for applying the mouse distance */
- float warp_init_dist;
+ /* for applying the mouse distance */
+ float warp_init_dist;
};
static void initBend(TransInfo *t)
{
- const float mval_fl[2] = {UNPACK2(t->mval)};
- const float *curs;
- float tvec[3];
- struct BendCustomData *data;
+ 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;
+ t->mode = TFM_BEND;
+ t->transform = Bend;
+ t->handleEvent = handleEventBend;
- setInputPostFct(&t->mouse, postInputRotation);
- initMouseInputMode(t, &t->mouse, INPUT_ANGLE_SPRING);
+ 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;
+ 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;
+ 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;
+ 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);
+ //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;
+ t->val = 0.0f;
- data = MEM_callocN(sizeof(*data), __func__);
+ data = MEM_callocN(sizeof(*data), __func__);
- curs = t->scene->cursor.location;
- copy_v3_v3(data->warp_sta, curs);
- ED_view3d_win_to_3d(t->sa->spacedata.first, t->ar, curs, mval_fl, data->warp_end);
+ curs = t->scene->cursor.location;
+ copy_v3_v3(data->warp_sta, curs);
+ ED_view3d_win_to_3d(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);
+ 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);
+ /* 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);
+ data->warp_init_dist = len_v3v3(data->warp_end, data->warp_sta);
- t->custom.mode.data = data;
- t->custom.mode.use_free = true;
+ t->custom.mode.data = data;
+ t->custom.mode.use_free = true;
}
static eRedrawFlag handleEventBend(TransInfo *UNUSED(t), const wmEvent *event)
{
- eRedrawFlag status = TREDRAW_NOTHING;
+ eRedrawFlag status = TREDRAW_NOTHING;
- if (event->type == MIDDLEMOUSE && event->val == KM_PRESS) {
- status = TREDRAW_HARD;
- }
+ if (event->type == MIDDLEMOUSE && event->val == KM_PRESS) {
+ status = TREDRAW_HARD;
+ }
- return status;
+ 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;
+ 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;
+ union {
+ struct {
+ float angle, scale;
+ };
+ float vector[2];
+ } values;
- /* amount of radians for bend */
- copy_v2_v2(values.vector, t->values);
+ /* amount of radians for bend */
+ copy_v2_v2(values.vector, t->values);
#if 0
- snapGrid(t, angle_rad);
+ 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;
- }
+ /* 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, 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), IFACE_("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), IFACE_("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);
+ if (applyNumInput(&t->num, values.vector)) {
+ values.scale = values.scale / data->warp_init_dist;
+ }
+
+ copy_v2_v2(t->values, values.vector);
+
+ /* header print for NumInput */
+ if (hasNumInput(&t->num)) {
+ char c[NUM_STR_REP_LEN * 2];
+
+ outputNumInput(&(t->num), c, &t->scene->unit);
+
+ BLI_snprintf(str,
+ sizeof(str),
+ IFACE_("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),
+ IFACE_("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);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Shear) */
@@ -3443,192 +3461,195 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
static void initShear_mouseInputMode(TransInfo *t)
{
- float dir[3];
+ float dir[3];
- if (t->custom.mode.data == NULL) {
- copy_v3_v3(dir, t->orient_matrix[t->orient_axis_ortho]);
- }
- else {
- cross_v3_v3v3(dir, t->orient_matrix[t->orient_axis_ortho], t->orient_matrix[t->orient_axis]);
- }
+ if (t->custom.mode.data == NULL) {
+ copy_v3_v3(dir, t->orient_matrix[t->orient_axis_ortho]);
+ }
+ else {
+ cross_v3_v3v3(dir, t->orient_matrix[t->orient_axis_ortho], t->orient_matrix[t->orient_axis]);
+ }
- /* Without this, half the gizmo handles move in the opposite direction. */
- if ((t->orient_axis_ortho + 1) % 3 != t->orient_axis) {
- negate_v3(dir);
- }
+ /* Without this, half the gizmo handles move in the opposite direction. */
+ if ((t->orient_axis_ortho + 1) % 3 != t->orient_axis) {
+ 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);
+ 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);
+ initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO);
}
static void initShear(TransInfo *t)
{
- t->mode = TFM_SHEAR;
- t->transform = applyShear;
- t->handleEvent = handleEventShear;
+ 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;
- }
+ if (t->orient_axis == t->orient_axis_ortho) {
+ t->orient_axis = 2;
+ t->orient_axis_ortho = 1;
+ }
- initShear_mouseInputMode(t);
+ 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;
+ 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? */
+ 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;
+ t->flag |= T_NO_CONSTRAINT;
}
static eRedrawFlag handleEventShear(TransInfo *t, const wmEvent *event)
{
- eRedrawFlag status = TREDRAW_NOTHING;
+ eRedrawFlag status = TREDRAW_NOTHING;
- if (event->type == MIDDLEMOUSE && event->val == KM_PRESS) {
- /* Use custom.mode.data pointer to signal Shear direction */
- if (t->custom.mode.data == NULL) {
- t->custom.mode.data = (void *)1;
- }
- else {
- t->custom.mode.data = NULL;
- }
- initShear_mouseInputMode(t);
+ if (event->type == MIDDLEMOUSE && event->val == KM_PRESS) {
+ /* Use custom.mode.data pointer to signal Shear direction */
+ if (t->custom.mode.data == NULL) {
+ t->custom.mode.data = (void *)1;
+ }
+ else {
+ t->custom.mode.data = NULL;
+ }
+ initShear_mouseInputMode(t);
- status = TREDRAW_HARD;
- }
- else if (event->type == XKEY && event->val == KM_PRESS) {
- t->custom.mode.data = NULL;
- initShear_mouseInputMode(t);
+ status = TREDRAW_HARD;
+ }
+ else if (event->type == XKEY && event->val == KM_PRESS) {
+ t->custom.mode.data = NULL;
+ initShear_mouseInputMode(t);
- status = TREDRAW_HARD;
- }
- else if (event->type == YKEY && event->val == KM_PRESS) {
- t->custom.mode.data = (void *)1;
- initShear_mouseInputMode(t);
+ status = TREDRAW_HARD;
+ }
+ else if (event->type == YKEY && event->val == KM_PRESS) {
+ t->custom.mode.data = (void *)1;
+ initShear_mouseInputMode(t);
- status = TREDRAW_HARD;
- }
+ status = TREDRAW_HARD;
+ }
- return status;
+ 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[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), IFACE_("Shear: %s %s"), c, t->proptext);
- }
- else {
- /* default header print */
- BLI_snprintf(str, sizeof(str), IFACE_("Shear: %.3f %s (Press X or Y to set shear axis)"), value, t->proptext);
- }
-
- unit_m3(smat);
-
- // Custom data signals shear direction
- if (t->custom.mode.data == NULL)
- smat[1][0] = value;
- else
- smat[0][1] = 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);
+ 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[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), IFACE_("Shear: %s %s"), c, t->proptext);
+ }
+ else {
+ /* default header print */
+ BLI_snprintf(str,
+ sizeof(str),
+ IFACE_("Shear: %.3f %s (Press X or Y to set shear axis)"),
+ value,
+ t->proptext);
+ }
+
+ unit_m3(smat);
+
+ // Custom data signals shear direction
+ if (t->custom.mode.data == NULL)
+ smat[1][0] = value;
+ else
+ smat[0][1] = 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);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Resize) */
@@ -3637,81 +3658,108 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
static void initResize(TransInfo *t)
{
- t->mode = TFM_RESIZE;
- t->transform = applyResize;
+ t->mode = TFM_RESIZE;
+ t->transform = applyResize;
- initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
}
static void headerResize(TransInfo *t, const float vec[3], 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, "%.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]);
- }
-
- if (t->con.mode & CON_APPLY) {
- switch (t->num.idx_max) {
- case 0:
- ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_("Scale: %s%s %s"),
- &tvec[0], t->con.text, t->proptext);
- break;
- case 1:
- ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_("Scale: %s : %s%s %s"),
- &tvec[0], &tvec[NUM_STR_REP_LEN], t->con.text, t->proptext);
- break;
- case 2:
- ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_("Scale: %s : %s : %s%s %s"), &tvec[0],
- &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
- break;
- }
- }
- else {
- if (t->flag & T_2D_EDIT) {
- ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_("Scale X: %s Y: %s%s %s"),
- &tvec[0], &tvec[NUM_STR_REP_LEN], t->con.text, t->proptext);
- }
- else {
- ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_("Scale 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);
- }
- }
-
- if (t->flag & T_PROP_EDIT_ALL) {
- ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
- }
+ 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, "%.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]);
+ }
+
+ if (t->con.mode & CON_APPLY) {
+ switch (t->num.idx_max) {
+ case 0:
+ ofs += BLI_snprintf(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ IFACE_("Scale: %s%s %s"),
+ &tvec[0],
+ t->con.text,
+ t->proptext);
+ break;
+ case 1:
+ ofs += BLI_snprintf(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ IFACE_("Scale: %s : %s%s %s"),
+ &tvec[0],
+ &tvec[NUM_STR_REP_LEN],
+ t->con.text,
+ t->proptext);
+ break;
+ case 2:
+ ofs += BLI_snprintf(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ IFACE_("Scale: %s : %s : %s%s %s"),
+ &tvec[0],
+ &tvec[NUM_STR_REP_LEN],
+ &tvec[NUM_STR_REP_LEN * 2],
+ t->con.text,
+ t->proptext);
+ break;
+ }
+ }
+ else {
+ if (t->flag & T_2D_EDIT) {
+ ofs += BLI_snprintf(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ IFACE_("Scale X: %s Y: %s%s %s"),
+ &tvec[0],
+ &tvec[NUM_STR_REP_LEN],
+ t->con.text,
+ t->proptext);
+ }
+ else {
+ ofs += BLI_snprintf(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ IFACE_("Scale 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);
+ }
+ }
+
+ if (t->flag & T_PROP_EDIT_ALL) {
+ ofs += BLI_snprintf(
+ str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
+ }
}
/**
@@ -3721,227 +3769,228 @@ static void headerResize(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_
*/
static void TransMat3ToSize(float mat[3][3], float smat[3][3], float size[3])
{
- float rmat[3][3];
+ float rmat[3][3];
- mat3_to_rot_size(rmat, size, mat);
+ mat3_to_rot_size(rmat, size, mat);
- /* first tried with dotproduct... but the sign flip is crucial */
- if (dot_v3v3(rmat[0], smat[0]) < 0.0f) size[0] = -size[0];
- if (dot_v3v3(rmat[1], smat[1]) < 0.0f) size[1] = -size[1];
- if (dot_v3v3(rmat[2], smat[2]) < 0.0f) size[2] = -size[2];
+ /* first tried with dotproduct... but the sign flip is crucial */
+ if (dot_v3v3(rmat[0], smat[0]) < 0.0f)
+ size[0] = -size[0];
+ if (dot_v3v3(rmat[1], smat[1]) < 0.0f)
+ size[1] = -size[1];
+ if (dot_v3v3(rmat[2], smat[2]) < 0.0f)
+ size[2] = -size[2];
}
static void ElementResize(TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3])
{
- float tmat[3][3], smat[3][3], center[3];
- float vec[3];
-
- 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, tc, td, tmat);
- }
-
- /* local constraint shouldn't alter center */
- if (transdata_check_local_center(t, t->around)) {
- copy_v3_v3(center, td->center);
- }
- else if (t->options & CTX_MOVIECLIP) {
- if (td->flag & TD_INDIVIDUAL_SCALE) {
- copy_v3_v3(center, td->center);
- }
- else {
- copy_v3_v3(center, tc->center_local);
- }
- }
- else {
- copy_v3_v3(center, tc->center_local);
- }
-
- /* Size checked needed since the 3D cursor only uses rotation fields. */
- if (td->ext && td->ext->size) {
- float fsize[3];
-
- if (t->flag & (T_OBJECT | T_TEXTURE | T_POSE)) {
- float obsizemat[3][3];
- /* Reorient the size mat to fit the oriented object. */
- mul_m3_m3m3(obsizemat, tmat, td->axismtx);
- /* print_m3("obsizemat", obsizemat); */
- TransMat3ToSize(obsizemat, td->axismtx, fsize);
- /* print_v3("fsize", fsize); */
- }
- else {
- mat3_to_size(fsize, tmat);
- }
-
- protectedSizeBits(td->protectflag, fsize);
-
- if ((t->flag & T_V3D_ALIGN) == 0) { /* align mode doesn't resize objects itself */
- if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
- /* scale val and reset size */
- *td->val = td->ival * (1 + (fsize[0] - 1) * td->factor);
-
- td->ext->size[0] = td->ext->isize[0];
- td->ext->size[1] = td->ext->isize[1];
- td->ext->size[2] = td->ext->isize[2];
- }
- else {
- /* Reset val if SINGLESIZE but using a constraint */
- if (td->flag & TD_SINGLESIZE)
- *td->val = td->ival;
-
- td->ext->size[0] = td->ext->isize[0] * (1 + (fsize[0] - 1) * td->factor);
- td->ext->size[1] = td->ext->isize[1] * (1 + (fsize[1] - 1) * td->factor);
- td->ext->size[2] = td->ext->isize[2] * (1 + (fsize[2] - 1) * td->factor);
- }
- }
-
- constraintSizeLim(t, td);
- }
-
- /* For individual element center, Editmode need to use iloc */
- if (t->flag & T_POINTS)
- sub_v3_v3v3(vec, td->iloc, center);
- else
- sub_v3_v3v3(vec, td->center, center);
-
- mul_m3_v3(tmat, vec);
-
- add_v3_v3(vec, center);
- if (t->flag & T_POINTS)
- sub_v3_v3(vec, td->iloc);
- else
- sub_v3_v3(vec, td->center);
-
- /* grease pencil falloff */
- if (t->options & CTX_GPENCIL_STROKES) {
- bGPDstroke *gps = (bGPDstroke *)td->extra;
- mul_v3_fl(vec, td->factor * gps->runtime.multi_frame_falloff);
-
- /* scale stroke thickness */
- if (td->val) {
- snapGridIncrement(t, t->values);
- applyNumInput(&t->num, t->values);
-
- float ratio = t->values[0];
- *td->val = td->ival * ratio * gps->runtime.multi_frame_falloff;
- CLAMP_MIN(*td->val, 0.001f);
- }
-
- }
- else {
- mul_v3_fl(vec, td->factor);
- }
-
- if (t->flag & (T_OBJECT | T_POSE)) {
- mul_m3_v3(td->smtx, vec);
- }
-
- protectedTransBits(td->protectflag, vec);
- if (td->loc) {
- add_v3_v3v3(td->loc, td->iloc, vec);
- }
-
- constraintTransLim(t, td);
+ float tmat[3][3], smat[3][3], center[3];
+ float vec[3];
+
+ 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, tc, td, tmat);
+ }
+
+ /* local constraint shouldn't alter center */
+ if (transdata_check_local_center(t, t->around)) {
+ copy_v3_v3(center, td->center);
+ }
+ else if (t->options & CTX_MOVIECLIP) {
+ if (td->flag & TD_INDIVIDUAL_SCALE) {
+ copy_v3_v3(center, td->center);
+ }
+ else {
+ copy_v3_v3(center, tc->center_local);
+ }
+ }
+ else {
+ copy_v3_v3(center, tc->center_local);
+ }
+
+ /* Size checked needed since the 3D cursor only uses rotation fields. */
+ if (td->ext && td->ext->size) {
+ float fsize[3];
+
+ if (t->flag & (T_OBJECT | T_TEXTURE | T_POSE)) {
+ float obsizemat[3][3];
+ /* Reorient the size mat to fit the oriented object. */
+ mul_m3_m3m3(obsizemat, tmat, td->axismtx);
+ /* print_m3("obsizemat", obsizemat); */
+ TransMat3ToSize(obsizemat, td->axismtx, fsize);
+ /* print_v3("fsize", fsize); */
+ }
+ else {
+ mat3_to_size(fsize, tmat);
+ }
+
+ protectedSizeBits(td->protectflag, fsize);
+
+ if ((t->flag & T_V3D_ALIGN) == 0) { /* align mode doesn't resize objects itself */
+ if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
+ /* scale val and reset size */
+ *td->val = td->ival * (1 + (fsize[0] - 1) * td->factor);
+
+ td->ext->size[0] = td->ext->isize[0];
+ td->ext->size[1] = td->ext->isize[1];
+ td->ext->size[2] = td->ext->isize[2];
+ }
+ else {
+ /* Reset val if SINGLESIZE but using a constraint */
+ if (td->flag & TD_SINGLESIZE)
+ *td->val = td->ival;
+
+ td->ext->size[0] = td->ext->isize[0] * (1 + (fsize[0] - 1) * td->factor);
+ td->ext->size[1] = td->ext->isize[1] * (1 + (fsize[1] - 1) * td->factor);
+ td->ext->size[2] = td->ext->isize[2] * (1 + (fsize[2] - 1) * td->factor);
+ }
+ }
+
+ constraintSizeLim(t, td);
+ }
+
+ /* For individual element center, Editmode need to use iloc */
+ if (t->flag & T_POINTS)
+ sub_v3_v3v3(vec, td->iloc, center);
+ else
+ sub_v3_v3v3(vec, td->center, center);
+
+ mul_m3_v3(tmat, vec);
+
+ add_v3_v3(vec, center);
+ if (t->flag & T_POINTS)
+ sub_v3_v3(vec, td->iloc);
+ else
+ sub_v3_v3(vec, td->center);
+
+ /* grease pencil falloff */
+ if (t->options & CTX_GPENCIL_STROKES) {
+ bGPDstroke *gps = (bGPDstroke *)td->extra;
+ mul_v3_fl(vec, td->factor * gps->runtime.multi_frame_falloff);
+
+ /* scale stroke thickness */
+ if (td->val) {
+ snapGridIncrement(t, t->values);
+ applyNumInput(&t->num, t->values);
+
+ float ratio = t->values[0];
+ *td->val = td->ival * ratio * gps->runtime.multi_frame_falloff;
+ CLAMP_MIN(*td->val, 0.001f);
+ }
+ }
+ else {
+ mul_v3_fl(vec, td->factor);
+ }
+
+ if (t->flag & (T_OBJECT | T_POSE)) {
+ mul_m3_v3(td->smtx, vec);
+ }
+
+ protectedTransBits(td->protectflag, vec);
+ if (td->loc) {
+ add_v3_v3v3(td->loc, td->iloc, vec);
+ }
+
+ constraintTransLim(t, td);
}
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_AUTOVALUES) {
- copy_v3_v3(t->values, t->auto_values);
- }
- else {
- float ratio = t->values[0];
-
- copy_v3_fl(t->values, ratio);
-
- snapGridIncrement(t, t->values);
-
- if (applyNumInput(&t->num, t->values)) {
- constraintNumInput(t, t->values);
- }
-
- applySnapping(t, t->values);
- }
-
- size_to_mat3(mat, t->values);
- 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[i] = 1.0f;
- }
- else {
- pvec[j++] = t->values[i];
- }
- }
- headerResize(t, pvec, str);
- }
- else {
- headerResize(t, t->values, 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, 1)) {
- size_to_mat3(mat, t->values);
-
- 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);
+ float mat[3][3];
+ int i;
+ char str[UI_MAX_DRAW_STR];
+
+ if (t->flag & T_AUTOVALUES) {
+ copy_v3_v3(t->values, t->auto_values);
+ }
+ else {
+ float ratio = t->values[0];
+
+ copy_v3_fl(t->values, ratio);
+
+ snapGridIncrement(t, t->values);
+
+ if (applyNumInput(&t->num, t->values)) {
+ constraintNumInput(t, t->values);
+ }
+
+ applySnapping(t, t->values);
+ }
+
+ size_to_mat3(mat, t->values);
+ 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[i] = 1.0f;
+ }
+ else {
+ pvec[j++] = t->values[i];
+ }
+ }
+ headerResize(t, pvec, str);
+ }
+ else {
+ headerResize(t, t->values, 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, 1)) {
+ size_to_mat3(mat, t->values);
+
+ 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);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Skin) */
@@ -3950,101 +3999,101 @@ static void applyResize(TransInfo *t, const int UNUSED(mval[2]))
static void initSkinResize(TransInfo *t)
{
- t->mode = TFM_SKIN_RESIZE;
- t->transform = applySkinResize;
+ t->mode = TFM_SKIN_RESIZE;
+ t->transform = applySkinResize;
- initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
}
static void applySkinResize(TransInfo *t, const int UNUSED(mval[2]))
{
- float size[3], mat[3][3];
- int i;
- char str[UI_MAX_DRAW_STR];
+ float size[3], mat[3][3];
+ int i;
+ char str[UI_MAX_DRAW_STR];
- copy_v3_fl(size, t->values[0]);
+ copy_v3_fl(size, t->values[0]);
- snapGridIncrement(t, size);
+ snapGridIncrement(t, size);
- if (applyNumInput(&t->num, size)) {
- constraintNumInput(t, size);
- }
+ if (applyNumInput(&t->num, size)) {
+ constraintNumInput(t, size);
+ }
- applySnapping(t, size);
+ applySnapping(t, size);
- if (t->flag & T_AUTOVALUES) {
- copy_v3_v3(size, t->auto_values);
- }
+ if (t->flag & T_AUTOVALUES) {
+ copy_v3_v3(size, t->auto_values);
+ }
- copy_v3_v3(t->values, size);
+ copy_v3_v3(t->values, size);
- size_to_mat3(mat, size);
+ size_to_mat3(mat, size);
- headerResize(t, size, str);
+ headerResize(t, size, 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];
+ 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_NOACTION)
+ break;
- if (td->flag & TD_SKIP)
- continue;
+ 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->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);
- }
+ 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);
- }
- }
+ 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);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (ToSphere) */
@@ -4053,96 +4102,97 @@ static void applySkinResize(TransInfo *t, const int UNUSED(mval[2]))
static void initToSphere(TransInfo *t)
{
- int i;
+ int i;
- t->mode = TFM_TOSPHERE;
- t->transform = applyToSphere;
+ t->mode = TFM_TOSPHERE;
+ t->transform = applyToSphere;
- initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
+ 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;
+ 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;
+ 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;
+ 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);
- }
- }
+ // 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;
+ t->val /= (float)t->data_len_all;
}
static void applyToSphere(TransInfo *t, const int UNUSED(mval[2]))
{
- float vec[3];
- float ratio, radius;
- int i;
- char str[UI_MAX_DRAW_STR];
+ float vec[3];
+ float ratio, radius;
+ int i;
+ char str[UI_MAX_DRAW_STR];
- ratio = t->values[0];
+ ratio = t->values[0];
- snapGridIncrement(t, &ratio);
+ snapGridIncrement(t, &ratio);
- applyNumInput(&t->num, &ratio);
+ applyNumInput(&t->num, &ratio);
- CLAMP(ratio, 0.0f, 1.0f);
+ CLAMP(ratio, 0.0f, 1.0f);
- t->values[0] = ratio;
+ t->values[0] = ratio;
- /* header print for NumInput */
- if (hasNumInput(&t->num)) {
- char c[NUM_STR_REP_LEN];
+ /* header print for NumInput */
+ if (hasNumInput(&t->num)) {
+ char c[NUM_STR_REP_LEN];
- outputNumInput(&(t->num), c, &t->scene->unit);
+ outputNumInput(&(t->num), c, &t->scene->unit);
- BLI_snprintf(str, sizeof(str), IFACE_("To Sphere: %s %s"), c, t->proptext);
- }
- else {
- /* default header print */
- BLI_snprintf(str, sizeof(str), IFACE_("To Sphere: %.4f %s"), ratio, t->proptext);
- }
+ BLI_snprintf(str, sizeof(str), IFACE_("To Sphere: %s %s"), c, t->proptext);
+ }
+ else {
+ /* default header print */
+ BLI_snprintf(str, sizeof(str), IFACE_("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;
+ 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;
+ if (td->flag & TD_SKIP)
+ continue;
- sub_v3_v3v3(vec, td->iloc, tc->center_local);
+ sub_v3_v3v3(vec, td->iloc, tc->center_local);
- radius = normalize_v3(vec);
+ radius = normalize_v3(vec);
- tratio = ratio * td->factor;
+ tratio = ratio * td->factor;
- mul_v3_fl(vec, radius * (1.0f - tratio) + t->val * tratio);
+ mul_v3_fl(vec, radius * (1.0f - tratio) + t->val * tratio);
- add_v3_v3v3(td->loc, tc->center_local, vec);
- }
- }
+ add_v3_v3v3(td->loc, tc->center_local, vec);
+ }
+ }
- recalcData(t);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Rotation) */
@@ -4151,56 +4201,66 @@ static void applyToSphere(TransInfo *t, const int UNUSED(mval[2]))
static void postInputRotation(TransInfo *t, float values[3])
{
- 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, values);
- }
+ 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, values);
+ }
}
static void initRotation(TransInfo *t)
{
- t->mode = TFM_ROTATION;
- t->transform = applyRotation;
+ t->mode = TFM_ROTATION;
+ t->transform = applyRotation;
- setInputPostFct(&t->mouse, postInputRotation);
- initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
+ 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);
+ 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;
+ 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;
+ if (t->flag & T_2D_EDIT)
+ t->flag |= T_NO_CONSTRAINT;
}
/* Used by Transform Rotation and Transform Normal Rotation */
static void headerRotation(TransInfo *t, char str[UI_MAX_DRAW_STR], float final)
{
- size_t ofs = 0;
+ size_t ofs = 0;
- if (hasNumInput(&t->num)) {
- char c[NUM_STR_REP_LEN];
+ if (hasNumInput(&t->num)) {
+ char c[NUM_STR_REP_LEN];
- outputNumInput(&(t->num), c, &t->scene->unit);
+ outputNumInput(&(t->num), c, &t->scene->unit);
- ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_("Rot: %s %s %s"), &c[0], t->con.text, t->proptext);
- }
- else {
- ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_("Rot: %.2f%s %s"),
- RAD2DEGF(final), t->con.text, t->proptext);
- }
+ ofs += BLI_snprintf(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ IFACE_("Rot: %s %s %s"),
+ &c[0],
+ t->con.text,
+ t->proptext);
+ }
+ else {
+ ofs += BLI_snprintf(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ IFACE_("Rot: %.2f%s %s"),
+ RAD2DEGF(final),
+ t->con.text,
+ t->proptext);
+ }
- if (t->flag & T_PROP_EDIT_ALL) {
- ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
- }
+ if (t->flag & T_PROP_EDIT_ALL) {
+ ofs += BLI_snprintf(
+ str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
+ }
}
/**
@@ -4209,309 +4269,314 @@ static void headerRotation(TransInfo *t, char str[UI_MAX_DRAW_STR], float final)
*
* Protected axis and other transform settings are taken into account.
*/
-static void ElementRotation_ex(TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3], const float *center)
-{
- float vec[3], totmat[3][3], smat[3][3];
- float eul[3], fmat[3][3], quat[4];
-
- if (t->flag & T_POINTS) {
- mul_m3_m3m3(totmat, mat, td->mtx);
- mul_m3_m3m3(smat, td->smtx, totmat);
-
- /* apply gpencil falloff */
- if (t->options & CTX_GPENCIL_STROKES) {
- bGPDstroke *gps = (bGPDstroke *)td->extra;
- float sx = smat[0][0];
- float sy = smat[1][1];
- float sz = smat[2][2];
-
- mul_m3_fl(smat, gps->runtime.multi_frame_falloff);
- /* fix scale */
- smat[0][0] = sx;
- smat[1][1] = sy;
- smat[2][2] = sz;
- }
-
- sub_v3_v3v3(vec, td->iloc, center);
- mul_m3_v3(smat, vec);
-
- add_v3_v3v3(td->loc, vec, center);
-
- sub_v3_v3v3(vec, td->loc, td->iloc);
- protectedTransBits(td->protectflag, vec);
- add_v3_v3v3(td->loc, td->iloc, vec);
-
-
- if (td->flag & TD_USEQUAT) {
- mul_m3_series(fmat, td->smtx, mat, td->mtx);
- mat3_to_quat(quat, fmat); // Actual transform
-
- if (td->ext->quat) {
- mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
-
- /* is there a reason not to have this here? -jahka */
- protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
- }
- }
- }
- /**
- * HACK WARNING
- *
- * This is some VERY ugly special case to deal with pose mode.
- *
- * The problem is that mtx and smtx include each bone orientation.
- *
- * That is needed to rotate each bone properly, HOWEVER, to calculate
- * the translation component, we only need the actual armature object's
- * matrix (and inverse). That is not all though. Once the proper translation
- * has been computed, it has to be converted back into the bone's space.
- */
- else if (t->flag & T_POSE) {
- // Extract and invert armature object matrix
-
- if ((td->flag & TD_NO_LOC) == 0) {
- sub_v3_v3v3(vec, td->center, center);
-
- mul_m3_v3(tc->mat3, vec); // To Global space
- mul_m3_v3(mat, vec); // Applying rotation
- mul_m3_v3(tc->imat3, vec); // To Local space
-
- add_v3_v3(vec, center);
- /* vec now is the location where the object has to be */
-
- sub_v3_v3v3(vec, vec, td->center); // Translation needed from the initial location
-
- /* special exception, see TD_PBONE_LOCAL_MTX definition comments */
- if (td->flag & TD_PBONE_LOCAL_MTX_P) {
- /* do nothing */
- }
- else if (td->flag & TD_PBONE_LOCAL_MTX_C) {
- mul_m3_v3(tc->mat3, vec); // To Global space
- mul_m3_v3(td->ext->l_smtx, vec); // To Pose space (Local Location)
- }
- else {
- mul_m3_v3(tc->mat3, vec); // To Global space
- mul_m3_v3(td->smtx, vec); // To Pose space
- }
-
- protectedTransBits(td->protectflag, vec);
-
- add_v3_v3v3(td->loc, td->iloc, vec);
-
- constraintTransLim(t, td);
- }
-
- /* rotation */
- /* MORE HACK: as in some cases the matrix to apply location and rot/scale is not the same,
- * and ElementRotation() might be called in Translation context (with align snapping),
- * we need to be sure to actually use the *rotation* matrix here...
- * So no other way than storing it in some dedicated members of td->ext! */
- if ((t->flag & T_V3D_ALIGN) == 0) { /* align mode doesn't rotate objects itself */
- /* euler or quaternion/axis-angle? */
- if (td->ext->rotOrder == ROT_MODE_QUAT) {
- mul_m3_series(fmat, td->ext->r_smtx, mat, td->ext->r_mtx);
-
- mat3_to_quat(quat, fmat); /* Actual transform */
-
- mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
- /* this function works on end result */
- protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
-
- }
- else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
- /* calculate effect based on quats */
- float iquat[4], tquat[4];
-
- axis_angle_to_quat(iquat, td->ext->irotAxis, td->ext->irotAngle);
-
- mul_m3_series(fmat, td->ext->r_smtx, mat, td->ext->r_mtx);
- mat3_to_quat(quat, fmat); /* Actual transform */
- mul_qt_qtqt(tquat, quat, iquat);
-
- quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat);
-
- /* this function works on end result */
- protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis,
- td->ext->irotAngle);
- }
- else {
- float eulmat[3][3];
-
- mul_m3_m3m3(totmat, mat, td->ext->r_mtx);
- mul_m3_m3m3(smat, td->ext->r_smtx, totmat);
-
- /* calculate the total rotatation in eulers */
- copy_v3_v3(eul, td->ext->irot);
- eulO_to_mat3(eulmat, eul, td->ext->rotOrder);
-
- /* mat = transform, obmat = bone rotation */
- mul_m3_m3m3(fmat, smat, eulmat);
-
- mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
-
- /* and apply (to end result only) */
- protectedRotateBits(td->protectflag, eul, td->ext->irot);
- copy_v3_v3(td->ext->rot, eul);
- }
-
- constraintRotLim(t, td);
- }
- }
- else {
- if ((td->flag & TD_NO_LOC) == 0) {
- /* translation */
- sub_v3_v3v3(vec, td->center, center);
- mul_m3_v3(mat, vec);
- add_v3_v3(vec, center);
- /* vec now is the location where the object has to be */
- sub_v3_v3(vec, td->center);
- mul_m3_v3(td->smtx, vec);
-
- protectedTransBits(td->protectflag, vec);
-
- add_v3_v3v3(td->loc, td->iloc, vec);
- }
-
-
- constraintTransLim(t, td);
-
- /* rotation */
- if ((t->flag & T_V3D_ALIGN) == 0) { // align mode doesn't rotate objects itself
- /* euler or quaternion? */
- if ((td->ext->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) {
- /* can be called for texture space translate for example, then opt out */
- if (td->ext->quat) {
- mul_m3_series(fmat, td->smtx, mat, td->mtx);
- mat3_to_quat(quat, fmat); // Actual transform
-
- mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
- /* this function works on end result */
- protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
- }
- }
- else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
- /* calculate effect based on quats */
- float iquat[4], tquat[4];
-
- axis_angle_to_quat(iquat, td->ext->irotAxis, td->ext->irotAngle);
-
- mul_m3_series(fmat, td->smtx, mat, td->mtx);
- mat3_to_quat(quat, fmat); // Actual transform
- mul_qt_qtqt(tquat, quat, iquat);
-
- quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat);
-
- /* this function works on end result */
- protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis,
- td->ext->irotAngle);
- }
- else {
- float obmat[3][3];
-
- mul_m3_m3m3(totmat, mat, td->mtx);
- mul_m3_m3m3(smat, td->smtx, totmat);
-
- /* calculate the total rotatation in eulers */
- add_v3_v3v3(eul, td->ext->irot, td->ext->drot); /* correct for delta rot */
- eulO_to_mat3(obmat, eul, td->ext->rotOrder);
- /* mat = transform, obmat = object rotation */
- mul_m3_m3m3(fmat, smat, obmat);
-
- mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
-
- /* correct back for delta rot */
- sub_v3_v3v3(eul, eul, td->ext->drot);
-
- /* and apply */
- protectedRotateBits(td->protectflag, eul, td->ext->irot);
- copy_v3_v3(td->ext->rot, eul);
- }
-
- constraintRotLim(t, td);
- }
- }
-}
-
-static void ElementRotation(TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3], const short around)
+static void ElementRotation_ex(
+ TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3], const float *center)
+{
+ float vec[3], totmat[3][3], smat[3][3];
+ float eul[3], fmat[3][3], quat[4];
+
+ if (t->flag & T_POINTS) {
+ mul_m3_m3m3(totmat, mat, td->mtx);
+ mul_m3_m3m3(smat, td->smtx, totmat);
+
+ /* apply gpencil falloff */
+ if (t->options & CTX_GPENCIL_STROKES) {
+ bGPDstroke *gps = (bGPDstroke *)td->extra;
+ float sx = smat[0][0];
+ float sy = smat[1][1];
+ float sz = smat[2][2];
+
+ mul_m3_fl(smat, gps->runtime.multi_frame_falloff);
+ /* fix scale */
+ smat[0][0] = sx;
+ smat[1][1] = sy;
+ smat[2][2] = sz;
+ }
+
+ sub_v3_v3v3(vec, td->iloc, center);
+ mul_m3_v3(smat, vec);
+
+ add_v3_v3v3(td->loc, vec, center);
+
+ sub_v3_v3v3(vec, td->loc, td->iloc);
+ protectedTransBits(td->protectflag, vec);
+ add_v3_v3v3(td->loc, td->iloc, vec);
+
+ if (td->flag & TD_USEQUAT) {
+ mul_m3_series(fmat, td->smtx, mat, td->mtx);
+ mat3_to_quat(quat, fmat); // Actual transform
+
+ if (td->ext->quat) {
+ mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
+
+ /* is there a reason not to have this here? -jahka */
+ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
+ }
+ }
+ }
+ /**
+ * HACK WARNING
+ *
+ * This is some VERY ugly special case to deal with pose mode.
+ *
+ * The problem is that mtx and smtx include each bone orientation.
+ *
+ * That is needed to rotate each bone properly, HOWEVER, to calculate
+ * the translation component, we only need the actual armature object's
+ * matrix (and inverse). That is not all though. Once the proper translation
+ * has been computed, it has to be converted back into the bone's space.
+ */
+ else if (t->flag & T_POSE) {
+ // Extract and invert armature object matrix
+
+ if ((td->flag & TD_NO_LOC) == 0) {
+ sub_v3_v3v3(vec, td->center, center);
+
+ mul_m3_v3(tc->mat3, vec); // To Global space
+ mul_m3_v3(mat, vec); // Applying rotation
+ mul_m3_v3(tc->imat3, vec); // To Local space
+
+ add_v3_v3(vec, center);
+ /* vec now is the location where the object has to be */
+
+ sub_v3_v3v3(vec, vec, td->center); // Translation needed from the initial location
+
+ /* special exception, see TD_PBONE_LOCAL_MTX definition comments */
+ if (td->flag & TD_PBONE_LOCAL_MTX_P) {
+ /* do nothing */
+ }
+ else if (td->flag & TD_PBONE_LOCAL_MTX_C) {
+ mul_m3_v3(tc->mat3, vec); // To Global space
+ mul_m3_v3(td->ext->l_smtx, vec); // To Pose space (Local Location)
+ }
+ else {
+ mul_m3_v3(tc->mat3, vec); // To Global space
+ mul_m3_v3(td->smtx, vec); // To Pose space
+ }
+
+ protectedTransBits(td->protectflag, vec);
+
+ add_v3_v3v3(td->loc, td->iloc, vec);
+
+ constraintTransLim(t, td);
+ }
+
+ /* rotation */
+ /* MORE HACK: as in some cases the matrix to apply location and rot/scale is not the same,
+ * and ElementRotation() might be called in Translation context (with align snapping),
+ * we need to be sure to actually use the *rotation* matrix here...
+ * So no other way than storing it in some dedicated members of td->ext! */
+ if ((t->flag & T_V3D_ALIGN) == 0) { /* align mode doesn't rotate objects itself */
+ /* euler or quaternion/axis-angle? */
+ if (td->ext->rotOrder == ROT_MODE_QUAT) {
+ mul_m3_series(fmat, td->ext->r_smtx, mat, td->ext->r_mtx);
+
+ mat3_to_quat(quat, fmat); /* Actual transform */
+
+ mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
+ /* this function works on end result */
+ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
+ }
+ else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
+ /* calculate effect based on quats */
+ float iquat[4], tquat[4];
+
+ axis_angle_to_quat(iquat, td->ext->irotAxis, td->ext->irotAngle);
+
+ mul_m3_series(fmat, td->ext->r_smtx, mat, td->ext->r_mtx);
+ mat3_to_quat(quat, fmat); /* Actual transform */
+ mul_qt_qtqt(tquat, quat, iquat);
+
+ quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat);
+
+ /* this function works on end result */
+ protectedAxisAngleBits(td->protectflag,
+ td->ext->rotAxis,
+ td->ext->rotAngle,
+ td->ext->irotAxis,
+ td->ext->irotAngle);
+ }
+ else {
+ float eulmat[3][3];
+
+ mul_m3_m3m3(totmat, mat, td->ext->r_mtx);
+ mul_m3_m3m3(smat, td->ext->r_smtx, totmat);
+
+ /* calculate the total rotatation in eulers */
+ copy_v3_v3(eul, td->ext->irot);
+ eulO_to_mat3(eulmat, eul, td->ext->rotOrder);
+
+ /* mat = transform, obmat = bone rotation */
+ mul_m3_m3m3(fmat, smat, eulmat);
+
+ mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
+
+ /* and apply (to end result only) */
+ protectedRotateBits(td->protectflag, eul, td->ext->irot);
+ copy_v3_v3(td->ext->rot, eul);
+ }
+
+ constraintRotLim(t, td);
+ }
+ }
+ else {
+ if ((td->flag & TD_NO_LOC) == 0) {
+ /* translation */
+ sub_v3_v3v3(vec, td->center, center);
+ mul_m3_v3(mat, vec);
+ add_v3_v3(vec, center);
+ /* vec now is the location where the object has to be */
+ sub_v3_v3(vec, td->center);
+ mul_m3_v3(td->smtx, vec);
+
+ protectedTransBits(td->protectflag, vec);
+
+ add_v3_v3v3(td->loc, td->iloc, vec);
+ }
+
+ constraintTransLim(t, td);
+
+ /* rotation */
+ if ((t->flag & T_V3D_ALIGN) == 0) { // align mode doesn't rotate objects itself
+ /* euler or quaternion? */
+ if ((td->ext->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) {
+ /* can be called for texture space translate for example, then opt out */
+ if (td->ext->quat) {
+ mul_m3_series(fmat, td->smtx, mat, td->mtx);
+ mat3_to_quat(quat, fmat); // Actual transform
+
+ mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
+ /* this function works on end result */
+ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
+ }
+ }
+ else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
+ /* calculate effect based on quats */
+ float iquat[4], tquat[4];
+
+ axis_angle_to_quat(iquat, td->ext->irotAxis, td->ext->irotAngle);
+
+ mul_m3_series(fmat, td->smtx, mat, td->mtx);
+ mat3_to_quat(quat, fmat); // Actual transform
+ mul_qt_qtqt(tquat, quat, iquat);
+
+ quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat);
+
+ /* this function works on end result */
+ protectedAxisAngleBits(td->protectflag,
+ td->ext->rotAxis,
+ td->ext->rotAngle,
+ td->ext->irotAxis,
+ td->ext->irotAngle);
+ }
+ else {
+ float obmat[3][3];
+
+ mul_m3_m3m3(totmat, mat, td->mtx);
+ mul_m3_m3m3(smat, td->smtx, totmat);
+
+ /* calculate the total rotatation in eulers */
+ add_v3_v3v3(eul, td->ext->irot, td->ext->drot); /* correct for delta rot */
+ eulO_to_mat3(obmat, eul, td->ext->rotOrder);
+ /* mat = transform, obmat = object rotation */
+ mul_m3_m3m3(fmat, smat, obmat);
+
+ mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
+
+ /* correct back for delta rot */
+ sub_v3_v3v3(eul, eul, td->ext->drot);
+
+ /* and apply */
+ protectedRotateBits(td->protectflag, eul, td->ext->irot);
+ copy_v3_v3(td->ext->rot, eul);
+ }
+
+ constraintRotLim(t, td);
+ }
+ }
+}
+
+static void ElementRotation(
+ TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3], const short around)
{
- const float *center;
-
- /* local constraint shouldn't alter center */
- if (transdata_check_local_center(t, around)) {
- center = td->center;
- }
- else {
- center = tc->center_local;
- }
-
- ElementRotation_ex(t, tc, td, mat, center);
+ const float *center;
+
+ /* local constraint shouldn't alter center */
+ if (transdata_check_local_center(t, around)) {
+ center = td->center;
+ }
+ else {
+ center = tc->center_local;
+ }
+
+ ElementRotation_ex(t, tc, td, mat, center);
}
static void applyRotationValue(TransInfo *t, float angle, float axis[3])
{
- float mat[3][3];
- int i;
+ float mat[3][3];
+ int i;
- axis_angle_normalized_to_mat3(mat, axis, angle);
+ 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++) {
+ 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_NOACTION)
+ break;
- if (td->flag & TD_SKIP)
- continue;
+ if (td->flag & TD_SKIP)
+ continue;
- if (t->con.applyRot) {
- t->con.applyRot(t, tc, td, axis, NULL);
- axis_angle_normalized_to_mat3(mat, axis, angle * td->factor);
- }
- else if (t->flag & T_PROP_EDIT) {
- axis_angle_normalized_to_mat3(mat, axis, angle * td->factor);
- }
+ if (t->con.applyRot) {
+ t->con.applyRot(t, tc, td, axis, NULL);
+ axis_angle_normalized_to_mat3(mat, axis, angle * td->factor);
+ }
+ else if (t->flag & T_PROP_EDIT) {
+ axis_angle_normalized_to_mat3(mat, axis, angle * td->factor);
+ }
- ElementRotation(t, tc, td, mat, t->around);
- }
- }
+ ElementRotation(t, tc, td, mat, t->around);
+ }
+ }
}
static void applyRotation(TransInfo *t, const int UNUSED(mval[2]))
{
- char str[UI_MAX_DRAW_STR];
+ char str[UI_MAX_DRAW_STR];
- float final;
+ float final;
- final = t->values[0];
+ final = t->values[0];
- snapGridIncrement(t, &final);
+ snapGridIncrement(t, &final);
- float axis_final[3];
- copy_v3_v3(axis_final, t->orient_matrix[t->orient_axis]);
+ 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);
- }
+ if ((t->con.mode & CON_APPLY) && t->con.applyRot) {
+ t->con.applyRot(t, NULL, NULL, axis_final, NULL);
+ }
- applySnapping(t, &final);
+ applySnapping(t, &final);
- /* Used to clamp final result in [-PI, PI[ range, no idea why, inheritance from 2.4x area, see T48998. */
- applyNumInput(&t->num, &final);
+ /* Used to clamp final result in [-PI, PI[ range, no idea why, inheritance from 2.4x area, see T48998. */
+ applyNumInput(&t->num, &final);
- t->values[0] = final;
+ t->values[0] = final;
- headerRotation(t, str, final);
+ headerRotation(t, str, final);
- applyRotationValue(t, final, axis_final);
+ applyRotationValue(t, final, axis_final);
- recalcData(t);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Rotation - Trackball) */
@@ -4520,115 +4585,127 @@ static void applyRotation(TransInfo *t, const int UNUSED(mval[2]))
static void initTrackball(TransInfo *t)
{
- t->mode = TFM_TRACKBALL;
- t->transform = applyTrackball;
+ t->mode = TFM_TRACKBALL;
+ t->transform = applyTrackball;
- initMouseInputMode(t, &t->mouse, INPUT_TRACKBALL);
+ 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);
+ 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;
+ 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;
+ t->flag |= T_NO_CONSTRAINT;
}
-static void applyTrackballValue(TransInfo *t, const float axis1[3], const float axis2[3], float angles[2])
+static void applyTrackballValue(TransInfo *t,
+ const float axis1[3],
+ const float axis2[3],
+ float angles[2])
{
- float mat[3][3];
- float axis[3];
- float angle;
- int i;
+ 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);
+ 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;
+ 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->flag & TD_SKIP)
+ continue;
- if (t->flag & T_PROP_EDIT) {
- axis_angle_normalized_to_mat3(mat, axis, td->factor * angle);
- }
+ if (t->flag & T_PROP_EDIT) {
+ axis_angle_normalized_to_mat3(mat, axis, td->factor * angle);
+ }
- ElementRotation(t, tc, td, mat, t->around);
- }
- }
+ 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];
+ 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];
+ float phi[2];
- copy_v3_v3(axis1, t->persinv[0]);
- copy_v3_v3(axis2, t->persinv[1]);
- normalize_v3(axis1);
- normalize_v3(axis2);
+ 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);
+ copy_v2_v2(phi, t->values);
- snapGridIncrement(t, phi);
+ snapGridIncrement(t, phi);
- applyNumInput(&t->num, phi);
+ applyNumInput(&t->num, phi);
- copy_v2_v2(t->values, phi);
+ copy_v2_v2(t->values, phi);
- if (hasNumInput(&t->num)) {
- char c[NUM_STR_REP_LEN * 2];
+ if (hasNumInput(&t->num)) {
+ char c[NUM_STR_REP_LEN * 2];
- outputNumInput(&(t->num), c, &t->scene->unit);
+ outputNumInput(&(t->num), c, &t->scene->unit);
- ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("Trackball: %s %s %s"),
- &c[0], &c[NUM_STR_REP_LEN], t->proptext);
- }
- else {
- ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("Trackball: %.2f %.2f %s"),
- RAD2DEGF(phi[0]), RAD2DEGF(phi[1]), t->proptext);
- }
+ ofs += BLI_snprintf(str + ofs,
+ sizeof(str) - ofs,
+ IFACE_("Trackball: %s %s %s"),
+ &c[0],
+ &c[NUM_STR_REP_LEN],
+ t->proptext);
+ }
+ else {
+ ofs += BLI_snprintf(str + ofs,
+ sizeof(str) - ofs,
+ IFACE_("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, IFACE_(" Proportional size: %.2f"), t->prop_size);
- }
+ if (t->flag & T_PROP_EDIT_ALL) {
+ ofs += BLI_snprintf(
+ str + ofs, sizeof(str) - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
+ }
-#if 0 /* UNUSED */
- axis_angle_normalized_to_mat3(smat, axis1, phi[0]);
- axis_angle_normalized_to_mat3(totmat, axis2, phi[1]);
+#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);
+ mul_m3_m3m3(mat, smat, totmat);
- // TRANSFORM_FIX_ME
- //copy_m3_m3(t->mat, mat); // used in gizmo
+ // TRANSFORM_FIX_ME
+ //copy_m3_m3(t->mat, mat); // used in gizmo
#endif
- applyTrackballValue(t, axis1, axis2, phi);
+ applyTrackballValue(t, axis1, axis2, phi);
- recalcData(t);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Normal Rotation) */
@@ -4637,153 +4714,154 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2]))
static void storeCustomLNorValue(TransDataContainer *tc, BMesh *bm)
{
- BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm);
- // BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
+ BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm);
+ // BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
- tc->custom.mode.data = lnors_ed_arr;
- tc->custom.mode.free_cb = freeCustomNormalArray;
+ 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;
+ 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;
+ 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);
- }
- }
+ /* 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);
+ BM_loop_normal_editdata_array_free(lnors_ed_arr);
- tc->custom.mode.data = NULL;
- tc->custom.mode.free_cb = NULL;
+ tc->custom.mode.data = NULL;
+ tc->custom.mode.free_cb = NULL;
}
static void initNormalRotation(TransInfo *t)
{
- t->mode = TFM_NORMAL_ROTATION;
- t->transform = applyNormalRotation;
+ t->mode = TFM_NORMAL_ROTATION;
+ t->transform = applyNormalRotation;
- setInputPostFct(&t->mouse, postInputRotation);
- initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
+ 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);
+ 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;
+ 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;
+ FOREACH_TRANS_DATA_CONTAINER(t, tc)
+ {
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+ BMesh *bm = em->bm;
- BKE_editmesh_lnorspace_update(em);
+ BKE_editmesh_lnorspace_update(em);
- storeCustomLNorValue(tc, bm);
- }
+ storeCustomLNorValue(tc, bm);
+ }
}
/* 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];
+ char str[UI_MAX_DRAW_STR];
- float axis_final[3];
- copy_v3_v3(axis_final, t->orient_matrix[t->orient_axis]);
+ 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);
- }
+ 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;
+ 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;
+ 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);
+ float axis[3];
+ float mat[3][3];
+ float angle = t->values[0];
+ copy_v3_v3(axis, axis_final);
- snapGridIncrement(t, &angle);
+ snapGridIncrement(t, &angle);
- applySnapping(t, &angle);
+ applySnapping(t, &angle);
- applyNumInput(&t->num, &angle);
+ applyNumInput(&t->num, &angle);
- headerRotation(t, str, angle);
+ headerRotation(t, str, angle);
- axis_angle_normalized_to_mat3(mat, axis, 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);
+ 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);
- }
- }
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->nloc, lnor_ed->clnors_data);
+ }
+ }
- recalcData(t);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Translation) */
static void initSnapSpatial(TransInfo *t, float r_snap[3])
{
- if (t->spacetype == SPACE_VIEW3D) {
- RegionView3D *rv3d = t->ar->regiondata;
-
- if (rv3d) {
- View3D *v3d = t->sa->spacedata.first;
- r_snap[0] = 0.0f;
- r_snap[1] = ED_view3d_grid_view_scale(t->scene, v3d, rv3d, NULL) * 1.0f;
- r_snap[2] = r_snap[1] * 0.1f;
- }
- }
- else if (t->spacetype == SPACE_IMAGE) {
- r_snap[0] = 0.0f;
- r_snap[1] = 0.0625f;
- r_snap[2] = 0.03125f;
- }
- else if (t->spacetype == SPACE_CLIP) {
- r_snap[0] = 0.0f;
- r_snap[1] = 0.125f;
- r_snap[2] = 0.0625f;
- }
- else if (t->spacetype == SPACE_NODE) {
- r_snap[0] = 0.0f;
- r_snap[1] = ED_node_grid_size();
- r_snap[2] = ED_node_grid_size();
- }
- else if (t->spacetype == SPACE_GRAPH) {
- r_snap[0] = 0.0f;
- r_snap[1] = 1.0;
- r_snap[2] = 0.1f;
- }
- else {
- r_snap[0] = 0.0f;
- r_snap[1] = r_snap[2] = 1.0f;
- }
+ if (t->spacetype == SPACE_VIEW3D) {
+ RegionView3D *rv3d = t->ar->regiondata;
+
+ if (rv3d) {
+ View3D *v3d = t->sa->spacedata.first;
+ r_snap[0] = 0.0f;
+ r_snap[1] = ED_view3d_grid_view_scale(t->scene, v3d, rv3d, NULL) * 1.0f;
+ r_snap[2] = r_snap[1] * 0.1f;
+ }
+ }
+ else if (t->spacetype == SPACE_IMAGE) {
+ r_snap[0] = 0.0f;
+ r_snap[1] = 0.0625f;
+ r_snap[2] = 0.03125f;
+ }
+ else if (t->spacetype == SPACE_CLIP) {
+ r_snap[0] = 0.0f;
+ r_snap[1] = 0.125f;
+ r_snap[2] = 0.0625f;
+ }
+ else if (t->spacetype == SPACE_NODE) {
+ r_snap[0] = 0.0f;
+ r_snap[1] = ED_node_grid_size();
+ r_snap[2] = ED_node_grid_size();
+ }
+ else if (t->spacetype == SPACE_GRAPH) {
+ r_snap[0] = 0.0f;
+ r_snap[1] = 1.0;
+ r_snap[2] = 0.1f;
+ }
+ else {
+ r_snap[0] = 0.0f;
+ r_snap[1] = r_snap[2] = 1.0f;
+ }
}
/** \name Transform Translation
@@ -4791,304 +4869,355 @@ static void initSnapSpatial(TransInfo *t, float r_snap[3])
static 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;
- }
+ 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;
+ }
}
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, IFACE_("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, IFACE_(" 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) ? IFACE_("right") : IFACE_("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, IFACE_("Auto-offset set to %s - press %s to toggle direction | %s"),
- str_dir, str_km, str_old);
-
- MEM_freeN((void *)str_old);
- }
- }
+ 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, IFACE_("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, IFACE_(" 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) ?
+ IFACE_("right") :
+ IFACE_("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,
+ IFACE_("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);
- }
-
- if (use_rotate_offset) {
- add_v3_v3(tvec, rotate_offset);
- }
-
- mul_m3_v3(td->smtx, tvec);
-
- 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);
- }
- }
+ 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);
+ }
+
+ if (use_rotate_offset) {
+ add_v3_v3(tvec, rotate_offset);
+ }
+
+ mul_m3_v3(td->smtx, tvec);
+
+ 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 value_final[3];
+ char str[UI_MAX_DRAW_STR];
+ float value_final[3];
- if (t->flag & T_AUTOVALUES) {
- copy_v3_v3(t->values, t->auto_values);
- }
- else {
- if ((t->con.mode & CON_APPLY) == 0) {
- snapGridIncrement(t, t->values);
- }
+ if (t->flag & T_AUTOVALUES) {
+ copy_v3_v3(t->values, t->auto_values);
+ }
+ else {
+ if ((t->con.mode & CON_APPLY) == 0) {
+ snapGridIncrement(t, t->values);
+ }
- if (applyNumInput(&t->num, t->values)) {
- removeAspectRatio(t, t->values);
- }
+ if (applyNumInput(&t->num, t->values)) {
+ removeAspectRatio(t, t->values);
+ }
- applySnapping(t, t->values);
- }
+ applySnapping(t, t->values);
+ }
- if (t->con.mode & CON_APPLY) {
- float pvec[3] = {0.0f, 0.0f, 0.0f};
- t->con.applyVec(t, NULL, NULL, t->values, value_final, pvec);
- headerTranslation(t, pvec, str);
+ if (t->con.mode & CON_APPLY) {
+ float pvec[3] = {0.0f, 0.0f, 0.0f};
+ t->con.applyVec(t, NULL, NULL, t->values, value_final, pvec);
+ headerTranslation(t, pvec, str);
- /* only so we have re-usable value with redo, see T46741. */
- mul_v3_m3v3(t->values, t->con.imtx, value_final);
- }
- else {
- headerTranslation(t, t->values, str);
- copy_v3_v3(value_final, t->values);
- }
+ /* only so we have re-usable value with redo, see T46741. */
+ mul_v3_m3v3(t->values, t->con.imtx, value_final);
+ }
+ else {
+ headerTranslation(t, t->values, str);
+ copy_v3_v3(value_final, t->values);
+ }
- /* don't use 't->values' now on */
+ /* don't use 't->values' now on */
- applyTranslationValue(t, value_final);
+ applyTranslationValue(t, value_final);
- /* evil hack - redo translation if clipping needed */
- if (t->flag & T_CLIP_UV && clipUVTransform(t, value_final, 0)) {
- applyTranslationValue(t, value_final);
+ /* evil hack - redo translation if clipping needed */
+ if (t->flag & T_CLIP_UV && clipUVTransform(t, value_final, 0)) {
+ applyTranslationValue(t, value_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);
- }
- }
+ /* 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);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Shrink-Fatten) */
@@ -5097,100 +5226,101 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2]))
static 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;
+ // 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);
+ 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;
+ 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;
+ 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;
- }
+ t->flag |= T_NO_CONSTRAINT;
+ }
}
-
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[0] = -distance;
-
- /* header print for NumInput */
- ofs += BLI_strncpy_rlen(str + ofs, IFACE_("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, IFACE_(" 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);
+ 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[0] = -distance;
+
+ /* header print for NumInput */
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_("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,
+ IFACE_(" 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);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Tilt) */
@@ -5199,77 +5329,76 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
static void initTilt(TransInfo *t)
{
- t->mode = TFM_TILT;
- t->transform = applyTilt;
+ t->mode = TFM_TILT;
+ t->transform = applyTilt;
- initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
+ 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);
+ 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;
+ 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;
+ t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
-
static void applyTilt(TransInfo *t, const int UNUSED(mval[2]))
{
- int i;
- char str[UI_MAX_DRAW_STR];
+ int i;
+ char str[UI_MAX_DRAW_STR];
- float final;
+ float final;
- final = t->values[0];
+ final = t->values[0];
- snapGridIncrement(t, &final);
+ snapGridIncrement(t, &final);
- applyNumInput(&t->num, &final);
+ applyNumInput(&t->num, &final);
- t->values[0] = final;
+ t->values[0] = final;
- if (hasNumInput(&t->num)) {
- char c[NUM_STR_REP_LEN];
+ if (hasNumInput(&t->num)) {
+ char c[NUM_STR_REP_LEN];
- outputNumInput(&(t->num), c, &t->scene->unit);
+ outputNumInput(&(t->num), c, &t->scene->unit);
- BLI_snprintf(str, sizeof(str), IFACE_("Tilt: %s° %s"), &c[0], t->proptext);
+ BLI_snprintf(str, sizeof(str), IFACE_("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[0] = final;
- }
- else {
- BLI_snprintf(str, sizeof(str), IFACE_("Tilt: %.2f° %s"), RAD2DEGF(final), t->proptext);
- }
+ /* XXX For some reason, this seems needed for this op, else RNA prop is not updated... :/ */
+ t->values[0] = final;
+ }
+ else {
+ BLI_snprintf(str, sizeof(str), IFACE_("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;
+ 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->flag & TD_SKIP)
+ continue;
- if (td->val) {
- *td->val = td->ival + final * td->factor;
- }
- }
- }
+ if (td->val) {
+ *td->val = td->ival + final * td->factor;
+ }
+ }
+ }
- recalcData(t);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Curve Shrink/Fatten) */
@@ -5278,79 +5407,80 @@ static void applyTilt(TransInfo *t, const int UNUSED(mval[2]))
static void initCurveShrinkFatten(TransInfo *t)
{
- t->mode = TFM_CURVE_SHRINKFATTEN;
- t->transform = applyCurveShrinkFatten;
+ t->mode = TFM_CURVE_SHRINKFATTEN;
+ t->transform = applyCurveShrinkFatten;
- initMouseInputMode(t, &t->mouse, INPUT_SPRING);
+ 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;
+ 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;
+ 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;
+ t->flag |= T_NO_ZERO;
#ifdef USE_NUM_NO_ZERO
- t->num.val_flag[0] |= NUM_NO_ZERO;
+ t->num.val_flag[0] |= NUM_NO_ZERO;
#endif
- t->flag |= T_NO_CONSTRAINT;
+ t->flag |= T_NO_CONSTRAINT;
}
static void applyCurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
{
- float ratio;
- int i;
- char str[UI_MAX_DRAW_STR];
+ float ratio;
+ int i;
+ char str[UI_MAX_DRAW_STR];
- ratio = t->values[0];
+ ratio = t->values[0];
- snapGridIncrement(t, &ratio);
+ snapGridIncrement(t, &ratio);
- applyNumInput(&t->num, &ratio);
+ applyNumInput(&t->num, &ratio);
- t->values[0] = ratio;
+ t->values[0] = ratio;
- /* header print for NumInput */
- if (hasNumInput(&t->num)) {
- char c[NUM_STR_REP_LEN];
+ /* 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), IFACE_("Shrink/Fatten: %s"), c);
- }
- else {
- BLI_snprintf(str, sizeof(str), IFACE_("Shrink/Fatten: %3f"), ratio);
- }
+ outputNumInput(&(t->num), c, &t->scene->unit);
+ BLI_snprintf(str, sizeof(str), IFACE_("Shrink/Fatten: %s"), c);
+ }
+ else {
+ BLI_snprintf(str, sizeof(str), IFACE_("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;
+ 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->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;
- }
- }
- }
+ 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);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Mask Shrink/Fatten) */
@@ -5359,104 +5489,106 @@ static void applyCurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
static void initMaskShrinkFatten(TransInfo *t)
{
- t->mode = TFM_MASK_SHRINKFATTEN;
- t->transform = applyMaskShrinkFatten;
+ t->mode = TFM_MASK_SHRINKFATTEN;
+ t->transform = applyMaskShrinkFatten;
- initMouseInputMode(t, &t->mouse, INPUT_SPRING);
+ 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;
+ 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;
+ 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;
+ t->flag |= T_NO_ZERO;
#ifdef USE_NUM_NO_ZERO
- t->num.val_flag[0] |= NUM_NO_ZERO;
+ t->num.val_flag[0] |= NUM_NO_ZERO;
#endif
- t->flag |= T_NO_CONSTRAINT;
+ t->flag |= T_NO_CONSTRAINT;
}
static void applyMaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
{
- float ratio;
- int i;
- bool initial_feather = false;
- char str[UI_MAX_DRAW_STR];
+ float ratio;
+ int i;
+ bool initial_feather = false;
+ char str[UI_MAX_DRAW_STR];
- ratio = t->values[0];
+ ratio = t->values[0];
- snapGridIncrement(t, &ratio);
+ snapGridIncrement(t, &ratio);
- applyNumInput(&t->num, &ratio);
+ applyNumInput(&t->num, &ratio);
- t->values[0] = ratio;
+ t->values[0] = ratio;
- /* header print for NumInput */
- if (hasNumInput(&t->num)) {
- char c[NUM_STR_REP_LEN];
+ /* 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), IFACE_("Feather Shrink/Fatten: %s"), c);
- }
- else {
- BLI_snprintf(str, sizeof(str), IFACE_("Feather Shrink/Fatten: %3f"), ratio);
- }
+ outputNumInput(&(t->num), c, &t->scene->unit);
+ BLI_snprintf(str, sizeof(str), IFACE_("Feather Shrink/Fatten: %s"), c);
+ }
+ else {
+ BLI_snprintf(str, sizeof(str), IFACE_("Feather Shrink/Fatten: %3f"), ratio);
+ }
- /* detect if no points have feather yet */
- if (ratio > 1.0f) {
- initial_feather = true;
+ /* 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;
+ 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->flag & TD_SKIP)
+ continue;
- if (td->ival >= 0.001f)
- initial_feather = false;
- }
- }
- }
+ 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;
+ /* 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->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;
+ 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;
- }
- }
- }
+ /* 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);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (GPencil Shrink/Fatten) */
@@ -5465,73 +5597,75 @@ static void applyMaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
static void initGPShrinkFatten(TransInfo *t)
{
- t->mode = TFM_GPENCIL_SHRINKFATTEN;
- t->transform = applyGPShrinkFatten;
+ t->mode = TFM_GPENCIL_SHRINKFATTEN;
+ t->transform = applyGPShrinkFatten;
- initMouseInputMode(t, &t->mouse, INPUT_SPRING);
+ 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;
+ 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;
+ 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;
+ t->flag |= T_NO_ZERO;
#ifdef USE_NUM_NO_ZERO
- t->num.val_flag[0] |= NUM_NO_ZERO;
+ t->num.val_flag[0] |= NUM_NO_ZERO;
#endif
- t->flag |= T_NO_CONSTRAINT;
+ t->flag |= T_NO_CONSTRAINT;
}
static void applyGPShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
{
- float ratio;
- int i;
- char str[UI_MAX_DRAW_STR];
+ float ratio;
+ int i;
+ char str[UI_MAX_DRAW_STR];
- ratio = t->values[0];
+ ratio = t->values[0];
- snapGridIncrement(t, &ratio);
+ snapGridIncrement(t, &ratio);
- applyNumInput(&t->num, &ratio);
+ applyNumInput(&t->num, &ratio);
- t->values[0] = ratio;
+ t->values[0] = ratio;
- /* header print for NumInput */
- if (hasNumInput(&t->num)) {
- char c[NUM_STR_REP_LEN];
+ /* 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), IFACE_("Shrink/Fatten: %s"), c);
- }
- else {
- BLI_snprintf(str, sizeof(str), IFACE_("Shrink/Fatten: %3f"), ratio);
- }
+ outputNumInput(&(t->num), c, &t->scene->unit);
+ BLI_snprintf(str, sizeof(str), IFACE_("Shrink/Fatten: %s"), c);
+ }
+ else {
+ BLI_snprintf(str, sizeof(str), IFACE_("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;
+ 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->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;
- }
- }
- }
+ 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);
+ ED_area_status_text(t->sa, str);
}
/** \} */
@@ -5543,77 +5677,77 @@ static void applyGPShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
static void initGPOpacity(TransInfo *t)
{
- t->mode = TFM_GPENCIL_OPACITY;
- t->transform = applyGPOpacity;
+ t->mode = TFM_GPENCIL_OPACITY;
+ t->transform = applyGPOpacity;
- initMouseInputMode(t, &t->mouse, INPUT_SPRING);
+ 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;
+ 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;
+ 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;
+ t->flag |= T_NO_ZERO;
#ifdef USE_NUM_NO_ZERO
- t->num.val_flag[0] |= NUM_NO_ZERO;
+ t->num.val_flag[0] |= NUM_NO_ZERO;
#endif
- t->flag |= T_NO_CONSTRAINT;
+ t->flag |= T_NO_CONSTRAINT;
}
static void applyGPOpacity(TransInfo *t, const int UNUSED(mval[2]))
{
- float ratio;
- int i;
- char str[UI_MAX_DRAW_STR];
+ float ratio;
+ int i;
+ char str[UI_MAX_DRAW_STR];
- ratio = t->values[0];
+ ratio = t->values[0];
- snapGridIncrement(t, &ratio);
+ snapGridIncrement(t, &ratio);
- applyNumInput(&t->num, &ratio);
+ applyNumInput(&t->num, &ratio);
- t->values[0] = ratio;
+ t->values[0] = ratio;
- /* header print for NumInput */
- if (hasNumInput(&t->num)) {
- char c[NUM_STR_REP_LEN];
+ /* 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), IFACE_("Opacity: %s"), c);
- }
- else {
- BLI_snprintf(str, sizeof(str), IFACE_("Opacity: %3f"), ratio);
- }
+ outputNumInput(&(t->num), c, &t->scene->unit);
+ BLI_snprintf(str, sizeof(str), IFACE_("Opacity: %s"), c);
+ }
+ else {
+ BLI_snprintf(str, sizeof(str), IFACE_("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;
+ 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->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);
- }
- }
- }
+ 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);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Push/Pull) */
@@ -5622,93 +5756,93 @@ static void applyGPOpacity(TransInfo *t, const int UNUSED(mval[2]))
static void initPushPull(TransInfo *t)
{
- t->mode = TFM_PUSHPULL;
- t->transform = applyPushPull;
+ t->mode = TFM_PUSHPULL;
+ t->transform = applyPushPull;
- initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
+ 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;
+ 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;
+ 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;
}
-
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];
+ float vec[3], axis_global[3];
+ float distance;
+ int i;
+ char str[UI_MAX_DRAW_STR];
- distance = t->values[0];
+ distance = t->values[0];
- snapGridIncrement(t, &distance);
+ snapGridIncrement(t, &distance);
- applyNumInput(&t->num, &distance);
+ applyNumInput(&t->num, &distance);
- t->values[0] = distance;
+ t->values[0] = distance;
- /* header print for NumInput */
- if (hasNumInput(&t->num)) {
- char c[NUM_STR_REP_LEN];
+ /* header print for NumInput */
+ if (hasNumInput(&t->num)) {
+ char c[NUM_STR_REP_LEN];
- outputNumInput(&(t->num), c, &t->scene->unit);
+ outputNumInput(&(t->num), c, &t->scene->unit);
- BLI_snprintf(str, sizeof(str), IFACE_("Push/Pull: %s%s %s"), c, t->con.text, t->proptext);
- }
- else {
- /* default header print */
- BLI_snprintf(str, sizeof(str), IFACE_("Push/Pull: %.4f%s %s"), distance, t->con.text, t->proptext);
- }
+ BLI_snprintf(str, sizeof(str), IFACE_("Push/Pull: %s%s %s"), c, t->con.text, t->proptext);
+ }
+ else {
+ /* default header print */
+ BLI_snprintf(
+ str, sizeof(str), IFACE_("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);
- }
+ 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;
+ 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->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);
+ 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);
+ 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);
- }
- }
+ add_v3_v3v3(td->loc, td->iloc, vec);
+ }
+ }
- recalcData(t);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Bevel Weight) */
@@ -5717,80 +5851,82 @@ static void applyPushPull(TransInfo *t, const int UNUSED(mval[2]))
static void initBevelWeight(TransInfo *t)
{
- t->mode = TFM_BWEIGHT;
- t->transform = applyBevelWeight;
+ t->mode = TFM_BWEIGHT;
+ t->transform = applyBevelWeight;
- initMouseInputMode(t, &t->mouse, INPUT_SPRING_DELTA);
+ 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;
+ 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;
+ 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;
+ t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
static void applyBevelWeight(TransInfo *t, const int UNUSED(mval[2]))
{
- float weight;
- int i;
- char str[UI_MAX_DRAW_STR];
+ float weight;
+ int i;
+ char str[UI_MAX_DRAW_STR];
- weight = t->values[0];
+ weight = t->values[0];
- CLAMP_MAX(weight, 1.0f);
+ CLAMP_MAX(weight, 1.0f);
- snapGridIncrement(t, &weight);
+ snapGridIncrement(t, &weight);
- applyNumInput(&t->num, &weight);
+ applyNumInput(&t->num, &weight);
- t->values[0] = weight;
+ t->values[0] = weight;
- /* header print for NumInput */
- if (hasNumInput(&t->num)) {
- char c[NUM_STR_REP_LEN];
+ /* header print for NumInput */
+ if (hasNumInput(&t->num)) {
+ char c[NUM_STR_REP_LEN];
- outputNumInput(&(t->num), c, &t->scene->unit);
+ outputNumInput(&(t->num), c, &t->scene->unit);
- if (weight >= 0.0f)
- BLI_snprintf(str, sizeof(str), IFACE_("Bevel Weight: +%s %s"), c, t->proptext);
- else
- BLI_snprintf(str, sizeof(str), IFACE_("Bevel Weight: %s %s"), c, t->proptext);
- }
- else {
- /* default header print */
- if (weight >= 0.0f)
- BLI_snprintf(str, sizeof(str), IFACE_("Bevel Weight: +%.3f %s"), weight, t->proptext);
- else
- BLI_snprintf(str, sizeof(str), IFACE_("Bevel Weight: %.3f %s"), weight, t->proptext);
- }
+ if (weight >= 0.0f)
+ BLI_snprintf(str, sizeof(str), IFACE_("Bevel Weight: +%s %s"), c, t->proptext);
+ else
+ BLI_snprintf(str, sizeof(str), IFACE_("Bevel Weight: %s %s"), c, t->proptext);
+ }
+ else {
+ /* default header print */
+ if (weight >= 0.0f)
+ BLI_snprintf(str, sizeof(str), IFACE_("Bevel Weight: +%.3f %s"), weight, t->proptext);
+ else
+ BLI_snprintf(str, sizeof(str), IFACE_("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;
+ 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;
- }
- }
- }
+ 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);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Crease) */
@@ -5799,83 +5935,85 @@ static void applyBevelWeight(TransInfo *t, const int UNUSED(mval[2]))
static void initCrease(TransInfo *t)
{
- t->mode = TFM_CREASE;
- t->transform = applyCrease;
+ t->mode = TFM_CREASE;
+ t->transform = applyCrease;
- initMouseInputMode(t, &t->mouse, INPUT_SPRING_DELTA);
+ 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;
+ 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;
+ 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;
+ t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
static void applyCrease(TransInfo *t, const int UNUSED(mval[2]))
{
- float crease;
- int i;
- char str[UI_MAX_DRAW_STR];
+ float crease;
+ int i;
+ char str[UI_MAX_DRAW_STR];
- crease = t->values[0];
+ crease = t->values[0];
- CLAMP_MAX(crease, 1.0f);
+ CLAMP_MAX(crease, 1.0f);
- snapGridIncrement(t, &crease);
+ snapGridIncrement(t, &crease);
- applyNumInput(&t->num, &crease);
+ applyNumInput(&t->num, &crease);
- t->values[0] = crease;
+ t->values[0] = crease;
- /* header print for NumInput */
- if (hasNumInput(&t->num)) {
- char c[NUM_STR_REP_LEN];
+ /* header print for NumInput */
+ if (hasNumInput(&t->num)) {
+ char c[NUM_STR_REP_LEN];
- outputNumInput(&(t->num), c, &t->scene->unit);
+ outputNumInput(&(t->num), c, &t->scene->unit);
- if (crease >= 0.0f)
- BLI_snprintf(str, sizeof(str), IFACE_("Crease: +%s %s"), c, t->proptext);
- else
- BLI_snprintf(str, sizeof(str), IFACE_("Crease: %s %s"), c, t->proptext);
- }
- else {
- /* default header print */
- if (crease >= 0.0f)
- BLI_snprintf(str, sizeof(str), IFACE_("Crease: +%.3f %s"), crease, t->proptext);
- else
- BLI_snprintf(str, sizeof(str), IFACE_("Crease: %.3f %s"), crease, t->proptext);
- }
+ if (crease >= 0.0f)
+ BLI_snprintf(str, sizeof(str), IFACE_("Crease: +%s %s"), c, t->proptext);
+ else
+ BLI_snprintf(str, sizeof(str), IFACE_("Crease: %s %s"), c, t->proptext);
+ }
+ else {
+ /* default header print */
+ if (crease >= 0.0f)
+ BLI_snprintf(str, sizeof(str), IFACE_("Crease: +%.3f %s"), crease, t->proptext);
+ else
+ BLI_snprintf(str, sizeof(str), IFACE_("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;
+ 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->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;
- }
- }
- }
+ 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);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (EditBone (B-bone) width scaling) */
@@ -5884,121 +6022,134 @@ static void applyCrease(TransInfo *t, const int UNUSED(mval[2]))
static void initBoneSize(TransInfo *t)
{
- t->mode = TFM_BONESIZE;
- t->transform = applyBoneSize;
+ t->mode = TFM_BONESIZE;
+ t->transform = applyBoneSize;
- initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
+ 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;
+ 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;
+ 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;
}
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, IFACE_("ScaleB: %s%s %s"), &tvec[0], t->con.text, t->proptext);
- else
- BLI_snprintf(str, UI_MAX_DRAW_STR, IFACE_("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, IFACE_("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);
- }
+ 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, IFACE_("ScaleB: %s%s %s"), &tvec[0], t->con.text, t->proptext);
+ else
+ BLI_snprintf(str,
+ UI_MAX_DRAW_STR,
+ IFACE_("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,
+ IFACE_("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];
+ 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);
+ 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);
- }
+ 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;
+ /* 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];
+ float size[3], mat[3][3];
+ float ratio = t->values[0];
+ int i;
+ char str[UI_MAX_DRAW_STR];
- copy_v3_fl(size, ratio);
+ copy_v3_fl(size, ratio);
- snapGridIncrement(t, size);
+ snapGridIncrement(t, size);
- if (applyNumInput(&t->num, size)) {
- constraintNumInput(t, size);
- }
+ if (applyNumInput(&t->num, size)) {
+ constraintNumInput(t, size);
+ }
- copy_v3_v3(t->values, size);
+ copy_v3_v3(t->values, size);
- size_to_mat3(mat, size);
+ size_to_mat3(mat, size);
- if (t->con.applySize) {
- t->con.applySize(t, NULL, NULL, mat);
- }
+ if (t->con.applySize) {
+ t->con.applySize(t, NULL, NULL, mat);
+ }
- copy_m3_m3(t->mat, mat); // used in gizmo
+ copy_m3_m3(t->mat, mat); // used in gizmo
- headerBoneSize(t, size, str);
+ 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;
+ 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->flag & TD_SKIP)
+ continue;
- ElementBoneSize(t, tc, td, mat);
- }
- }
+ ElementBoneSize(t, tc, td, mat);
+ }
+ }
- recalcData(t);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Bone Envelope) */
@@ -6007,71 +6158,72 @@ static void applyBoneSize(TransInfo *t, const int UNUSED(mval[2]))
static void initBoneEnvelope(TransInfo *t)
{
- t->mode = TFM_BONE_ENVELOPE;
- t->transform = applyBoneEnvelope;
+ t->mode = TFM_BONE_ENVELOPE;
+ t->transform = applyBoneEnvelope;
- initMouseInputMode(t, &t->mouse, INPUT_SPRING);
+ 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;
+ 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;
+ 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;
+ t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
static void applyBoneEnvelope(TransInfo *t, const int UNUSED(mval[2]))
{
- float ratio;
- int i;
- char str[UI_MAX_DRAW_STR];
+ float ratio;
+ int i;
+ char str[UI_MAX_DRAW_STR];
- ratio = t->values[0];
+ ratio = t->values[0];
- snapGridIncrement(t, &ratio);
+ snapGridIncrement(t, &ratio);
- applyNumInput(&t->num, &ratio);
+ applyNumInput(&t->num, &ratio);
- t->values[0] = ratio;
+ t->values[0] = ratio;
- /* header print for NumInput */
- if (hasNumInput(&t->num)) {
- char c[NUM_STR_REP_LEN];
+ /* 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), IFACE_("Envelope: %s"), c);
- }
- else {
- BLI_snprintf(str, sizeof(str), IFACE_("Envelope: %3f"), ratio);
- }
+ outputNumInput(&(t->num), c, &t->scene->unit);
+ BLI_snprintf(str, sizeof(str), IFACE_("Envelope: %s"), c);
+ }
+ else {
+ BLI_snprintf(str, sizeof(str), IFACE_("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;
+ 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->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;
- }
- }
- }
+ 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);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
@@ -6081,159 +6233,157 @@ static void applyBoneEnvelope(TransInfo *t, const int UNUSED(mval[2]))
/** \name Orig-Data Store Utility Functions
* \{ */
-static void slide_origdata_init_flag(
- TransInfo *t, TransDataContainer *tc, SlideOrigData *sod)
-{
- BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
- BMesh *bm = em->bm;
- const bool has_layer_math = CustomData_has_math(&bm->ldata);
- const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
-
- if ((t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) &&
- /* don't do this at all for non-basis shape keys, too easy to
- * accidentally break uv maps or vertex colors then */
- (bm->shapenr <= 1) &&
- (has_layer_math || (cd_loop_mdisp_offset != -1)))
- {
- sod->use_origfaces = true;
- sod->cd_loop_mdisp_offset = cd_loop_mdisp_offset;
- }
- else {
- sod->use_origfaces = false;
- sod->cd_loop_mdisp_offset = -1;
- }
-}
-
-static void slide_origdata_init_data(
- TransDataContainer *tc, SlideOrigData *sod)
-{
- if (sod->use_origfaces) {
- BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
- BMesh *bm = em->bm;
-
- sod->origfaces = BLI_ghash_ptr_new(__func__);
- sod->bm_origfaces = BM_mesh_create(
- &bm_mesh_allocsize_default,
- &((struct BMeshCreateParams){.use_toolflags = false,}));
- /* we need to have matching customdata */
- BM_mesh_copy_init_customdata(sod->bm_origfaces, bm, NULL);
- }
-}
-
-static void slide_origdata_create_data_vert(
- BMesh *bm, SlideOrigData *sod,
- TransDataGenericSlideVert *sv)
-{
- BMIter liter;
- int j, l_num;
- float *loop_weights;
-
- /* copy face data */
- // BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) {
- BM_iter_init(&liter, bm, BM_LOOPS_OF_VERT, sv->v);
- l_num = liter.count;
- loop_weights = BLI_array_alloca(loop_weights, l_num);
- for (j = 0; j < l_num; j++) {
- BMLoop *l = BM_iter_step(&liter);
- BMLoop *l_prev, *l_next;
- void **val_p;
- if (!BLI_ghash_ensure_p(sod->origfaces, l->f, &val_p)) {
- BMFace *f_copy = BM_face_copy(sod->bm_origfaces, bm, l->f, true, true);
- *val_p = f_copy;
- }
-
- if ((l_prev = BM_loop_find_prev_nodouble(l, l->next, FLT_EPSILON)) &&
- (l_next = BM_loop_find_next_nodouble(l, l_prev, FLT_EPSILON)))
- {
- loop_weights[j] = angle_v3v3v3(l_prev->v->co, l->v->co, l_next->v->co);
- }
- else {
- loop_weights[j] = 0.0f;
- }
-
- }
-
- /* store cd_loop_groups */
- if (sod->layer_math_map_num && (l_num != 0)) {
- sv->cd_loop_groups = BLI_memarena_alloc(sod->arena, sod->layer_math_map_num * sizeof(void *));
- for (j = 0; j < sod->layer_math_map_num; j++) {
- const int layer_nr = sod->layer_math_map[j];
- sv->cd_loop_groups[j] = BM_vert_loop_groups_data_layer_create(bm, sv->v, layer_nr, loop_weights, sod->arena);
- }
- }
- else {
- sv->cd_loop_groups = NULL;
- }
-
- BLI_ghash_insert(sod->origverts, sv->v, sv);
-}
-
-static void slide_origdata_create_data(
- TransDataContainer *tc, SlideOrigData *sod,
- TransDataGenericSlideVert *sv_array, unsigned int v_stride, unsigned int v_num)
-{
- if (sod->use_origfaces) {
- BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
- BMesh *bm = em->bm;
- unsigned int i;
- TransDataGenericSlideVert *sv;
-
- int layer_index_dst;
- int j;
-
- layer_index_dst = 0;
-
- if (CustomData_has_math(&bm->ldata)) {
- /* over alloc, only 'math' layers are indexed */
- sod->layer_math_map = MEM_mallocN(bm->ldata.totlayer * sizeof(int), __func__);
- for (j = 0; j < bm->ldata.totlayer; j++) {
- if (CustomData_layer_has_math(&bm->ldata, j)) {
- sod->layer_math_map[layer_index_dst++] = j;
- }
- }
- BLI_assert(layer_index_dst != 0);
- }
-
- sod->layer_math_map_num = layer_index_dst;
-
- sod->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
-
- sod->origverts = BLI_ghash_ptr_new_ex(__func__, v_num);
-
- for (i = 0, sv = sv_array; i < v_num; i++, sv = POINTER_OFFSET(sv, v_stride)) {
- slide_origdata_create_data_vert(bm, sod, sv);
- }
-
- if (tc->mirror.axis_flag) {
- TransData *td = tc->data;
- TransDataGenericSlideVert *sv_mirror;
-
- sod->sv_mirror = MEM_callocN(sizeof(*sv_mirror) * tc->data_len, __func__);
- sod->totsv_mirror = tc->data_len;
-
- sv_mirror = sod->sv_mirror;
-
- for (i = 0; i < tc->data_len; i++, td++) {
- BMVert *eve = td->extra;
- /* Check the vertex has been used since both sides of the mirror may be selected & sliding. */
- if (eve && !BLI_ghash_haskey(sod->origverts, eve)) {
- sv_mirror->v = eve;
- copy_v3_v3(sv_mirror->co_orig_3d, eve->co);
-
- slide_origdata_create_data_vert(bm, sod, sv_mirror);
- sv_mirror++;
- }
- else {
- sod->totsv_mirror--;
- }
- }
-
- if (sod->totsv_mirror == 0) {
- MEM_freeN(sod->sv_mirror);
- sod->sv_mirror = NULL;
- }
- }
- }
+static void slide_origdata_init_flag(TransInfo *t, TransDataContainer *tc, SlideOrigData *sod)
+{
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+ BMesh *bm = em->bm;
+ const bool has_layer_math = CustomData_has_math(&bm->ldata);
+ const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
+
+ if ((t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) &&
+ /* don't do this at all for non-basis shape keys, too easy to
+ * accidentally break uv maps or vertex colors then */
+ (bm->shapenr <= 1) && (has_layer_math || (cd_loop_mdisp_offset != -1))) {
+ sod->use_origfaces = true;
+ sod->cd_loop_mdisp_offset = cd_loop_mdisp_offset;
+ }
+ else {
+ sod->use_origfaces = false;
+ sod->cd_loop_mdisp_offset = -1;
+ }
+}
+
+static void slide_origdata_init_data(TransDataContainer *tc, SlideOrigData *sod)
+{
+ if (sod->use_origfaces) {
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+ BMesh *bm = em->bm;
+
+ sod->origfaces = BLI_ghash_ptr_new(__func__);
+ sod->bm_origfaces = BM_mesh_create(&bm_mesh_allocsize_default,
+ &((struct BMeshCreateParams){
+ .use_toolflags = false,
+ }));
+ /* we need to have matching customdata */
+ BM_mesh_copy_init_customdata(sod->bm_origfaces, bm, NULL);
+ }
+}
+
+static void slide_origdata_create_data_vert(BMesh *bm,
+ SlideOrigData *sod,
+ TransDataGenericSlideVert *sv)
+{
+ BMIter liter;
+ int j, l_num;
+ float *loop_weights;
+
+ /* copy face data */
+ // BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) {
+ BM_iter_init(&liter, bm, BM_LOOPS_OF_VERT, sv->v);
+ l_num = liter.count;
+ loop_weights = BLI_array_alloca(loop_weights, l_num);
+ for (j = 0; j < l_num; j++) {
+ BMLoop *l = BM_iter_step(&liter);
+ BMLoop *l_prev, *l_next;
+ void **val_p;
+ if (!BLI_ghash_ensure_p(sod->origfaces, l->f, &val_p)) {
+ BMFace *f_copy = BM_face_copy(sod->bm_origfaces, bm, l->f, true, true);
+ *val_p = f_copy;
+ }
+
+ if ((l_prev = BM_loop_find_prev_nodouble(l, l->next, FLT_EPSILON)) &&
+ (l_next = BM_loop_find_next_nodouble(l, l_prev, FLT_EPSILON))) {
+ loop_weights[j] = angle_v3v3v3(l_prev->v->co, l->v->co, l_next->v->co);
+ }
+ else {
+ loop_weights[j] = 0.0f;
+ }
+ }
+
+ /* store cd_loop_groups */
+ if (sod->layer_math_map_num && (l_num != 0)) {
+ sv->cd_loop_groups = BLI_memarena_alloc(sod->arena, sod->layer_math_map_num * sizeof(void *));
+ for (j = 0; j < sod->layer_math_map_num; j++) {
+ const int layer_nr = sod->layer_math_map[j];
+ sv->cd_loop_groups[j] = BM_vert_loop_groups_data_layer_create(
+ bm, sv->v, layer_nr, loop_weights, sod->arena);
+ }
+ }
+ else {
+ sv->cd_loop_groups = NULL;
+ }
+
+ BLI_ghash_insert(sod->origverts, sv->v, sv);
+}
+
+static void slide_origdata_create_data(TransDataContainer *tc,
+ SlideOrigData *sod,
+ TransDataGenericSlideVert *sv_array,
+ unsigned int v_stride,
+ unsigned int v_num)
+{
+ if (sod->use_origfaces) {
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+ BMesh *bm = em->bm;
+ unsigned int i;
+ TransDataGenericSlideVert *sv;
+
+ int layer_index_dst;
+ int j;
+
+ layer_index_dst = 0;
+
+ if (CustomData_has_math(&bm->ldata)) {
+ /* over alloc, only 'math' layers are indexed */
+ sod->layer_math_map = MEM_mallocN(bm->ldata.totlayer * sizeof(int), __func__);
+ for (j = 0; j < bm->ldata.totlayer; j++) {
+ if (CustomData_layer_has_math(&bm->ldata, j)) {
+ sod->layer_math_map[layer_index_dst++] = j;
+ }
+ }
+ BLI_assert(layer_index_dst != 0);
+ }
+
+ sod->layer_math_map_num = layer_index_dst;
+
+ sod->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+
+ sod->origverts = BLI_ghash_ptr_new_ex(__func__, v_num);
+
+ for (i = 0, sv = sv_array; i < v_num; i++, sv = POINTER_OFFSET(sv, v_stride)) {
+ slide_origdata_create_data_vert(bm, sod, sv);
+ }
+
+ if (tc->mirror.axis_flag) {
+ TransData *td = tc->data;
+ TransDataGenericSlideVert *sv_mirror;
+
+ sod->sv_mirror = MEM_callocN(sizeof(*sv_mirror) * tc->data_len, __func__);
+ sod->totsv_mirror = tc->data_len;
+
+ sv_mirror = sod->sv_mirror;
+
+ for (i = 0; i < tc->data_len; i++, td++) {
+ BMVert *eve = td->extra;
+ /* Check the vertex has been used since both sides of the mirror may be selected & sliding. */
+ if (eve && !BLI_ghash_haskey(sod->origverts, eve)) {
+ sv_mirror->v = eve;
+ copy_v3_v3(sv_mirror->co_orig_3d, eve->co);
+
+ slide_origdata_create_data_vert(bm, sod, sv_mirror);
+ sv_mirror++;
+ }
+ else {
+ sod->totsv_mirror--;
+ }
+ }
+
+ if (sod->totsv_mirror == 0) {
+ MEM_freeN(sod->sv_mirror);
+ sod->sv_mirror = NULL;
+ }
+ }
+ }
}
/**
@@ -6241,192 +6391,199 @@ static void slide_origdata_create_data(
*/
static const float *slide_origdata_orig_vert_co(SlideOrigData *sod, BMVert *v)
{
- TransDataGenericSlideVert *sv = BLI_ghash_lookup(sod->origverts, v);
- return sv ? sv->co_orig_3d : v->co;
-}
-
-static void slide_origdata_interp_data_vert(
- SlideOrigData *sod, BMesh *bm, bool is_final,
- TransDataGenericSlideVert *sv)
-{
- BMIter liter;
- int j, l_num;
- float *loop_weights;
- const bool is_moved = (len_squared_v3v3(sv->v->co, sv->co_orig_3d) > FLT_EPSILON);
- const bool do_loop_weight = sod->layer_math_map_num && is_moved;
- const bool do_loop_mdisps = is_final && is_moved && (sod->cd_loop_mdisp_offset != -1);
- const float *v_proj_axis = sv->v->no;
- /* original (l->prev, l, l->next) projections for each loop ('l' remains unchanged) */
- float v_proj[3][3];
-
- if (do_loop_weight || do_loop_mdisps) {
- project_plane_normalized_v3_v3v3(v_proj[1], sv->co_orig_3d, v_proj_axis);
- }
-
- // BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT)
- BM_iter_init(&liter, bm, BM_LOOPS_OF_VERT, sv->v);
- l_num = liter.count;
- loop_weights = do_loop_weight ? BLI_array_alloca(loop_weights, l_num) : NULL;
- for (j = 0; j < l_num; j++) {
- BMFace *f_copy; /* the copy of 'f' */
- BMLoop *l = BM_iter_step(&liter);
-
- f_copy = BLI_ghash_lookup(sod->origfaces, l->f);
-
- /* only loop data, no vertex data since that contains shape keys,
- * and we do not want to mess up other shape keys */
- BM_loop_interp_from_face(bm, l, f_copy, false, false);
-
- /* make sure face-attributes are correct (e.g. MTexPoly) */
- BM_elem_attrs_copy_ex(sod->bm_origfaces, bm, f_copy, l->f, 0x0, CD_MASK_NORMAL);
-
- /* weight the loop */
- if (do_loop_weight) {
- const float eps = 1.0e-8f;
- const BMLoop *l_prev = l->prev;
- const BMLoop *l_next = l->next;
- const float *co_prev = slide_origdata_orig_vert_co(sod, l_prev->v);
- const float *co_next = slide_origdata_orig_vert_co(sod, l_next->v);
- bool co_prev_ok;
- bool co_next_ok;
-
-
- /* In the unlikely case that we're next to a zero length edge -
- * walk around the to the next.
- *
- * Since we only need to check if the vertex is in this corner,
- * its not important _which_ loop - as long as its not overlapping
- * 'sv->co_orig_3d', see: T45096. */
- project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
- while (UNLIKELY(((co_prev_ok = (len_squared_v3v3(v_proj[1], v_proj[0]) > eps)) == false) &&
- ((l_prev = l_prev->prev) != l->next)))
- {
- co_prev = slide_origdata_orig_vert_co(sod, l_prev->v);
- project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
- }
- project_plane_normalized_v3_v3v3(v_proj[2], co_next, v_proj_axis);
- while (UNLIKELY(((co_next_ok = (len_squared_v3v3(v_proj[1], v_proj[2]) > eps)) == false) &&
- ((l_next = l_next->next) != l->prev)))
- {
- co_next = slide_origdata_orig_vert_co(sod, l_next->v);
- project_plane_normalized_v3_v3v3(v_proj[2], co_next, v_proj_axis);
- }
-
- if (co_prev_ok && co_next_ok) {
- const float dist = dist_signed_squared_to_corner_v3v3v3(sv->v->co, UNPACK3(v_proj), v_proj_axis);
-
- loop_weights[j] = (dist >= 0.0f) ? 1.0f : ((dist <= -eps) ? 0.0f : (1.0f + (dist / eps)));
- if (UNLIKELY(!isfinite(loop_weights[j]))) {
- loop_weights[j] = 0.0f;
- }
- }
- else {
- loop_weights[j] = 0.0f;
- }
- }
- }
-
- if (sod->layer_math_map_num) {
- if (do_loop_weight) {
- for (j = 0; j < sod->layer_math_map_num; j++) {
- BM_vert_loop_groups_data_layer_merge_weights(bm, sv->cd_loop_groups[j], sod->layer_math_map[j], loop_weights);
- }
- }
- else {
- for (j = 0; j < sod->layer_math_map_num; j++) {
- BM_vert_loop_groups_data_layer_merge(bm, sv->cd_loop_groups[j], sod->layer_math_map[j]);
- }
- }
- }
-
- /* Special handling for multires
- *
- * Interpolate from every other loop (not ideal)
- * However values will only be taken from loops which overlap other mdisps.
- * */
- if (do_loop_mdisps) {
- float (*faces_center)[3] = BLI_array_alloca(faces_center, l_num);
- BMLoop *l;
-
- BM_ITER_ELEM_INDEX (l, &liter, sv->v, BM_LOOPS_OF_VERT, j) {
- BM_face_calc_center_median(l->f, faces_center[j]);
- }
-
- BM_ITER_ELEM_INDEX (l, &liter, sv->v, BM_LOOPS_OF_VERT, j) {
- BMFace *f_copy = BLI_ghash_lookup(sod->origfaces, l->f);
- float f_copy_center[3];
- BMIter liter_other;
- BMLoop *l_other;
- int j_other;
-
- BM_face_calc_center_median(f_copy, f_copy_center);
-
- BM_ITER_ELEM_INDEX (l_other, &liter_other, sv->v, BM_LOOPS_OF_VERT, j_other) {
- BM_face_interp_multires_ex(
- bm, l_other->f, f_copy,
- faces_center[j_other], f_copy_center, sod->cd_loop_mdisp_offset);
- }
- }
- }
-}
-
-static void slide_origdata_interp_data(
- Object *obedit, SlideOrigData *sod,
- TransDataGenericSlideVert *sv, unsigned int v_stride, unsigned int v_num,
- bool is_final)
-{
- if (sod->use_origfaces) {
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- BMesh *bm = em->bm;
- unsigned int i;
- const bool has_mdisps = (sod->cd_loop_mdisp_offset != -1);
-
- for (i = 0; i < v_num; i++, sv = POINTER_OFFSET(sv, v_stride)) {
-
- if (sv->cd_loop_groups || has_mdisps) {
- slide_origdata_interp_data_vert(sod, bm, is_final, sv);
- }
- }
-
- if (sod->sv_mirror) {
- sv = sod->sv_mirror;
- for (i = 0; i < v_num; i++, sv++) {
- if (sv->cd_loop_groups || has_mdisps) {
- slide_origdata_interp_data_vert(sod, bm, is_final, sv);
- }
- }
- }
- }
-}
-
-static void slide_origdata_free_date(
- SlideOrigData *sod)
-{
- if (sod->use_origfaces) {
- if (sod->bm_origfaces) {
- BM_mesh_free(sod->bm_origfaces);
- sod->bm_origfaces = NULL;
- }
-
- if (sod->origfaces) {
- BLI_ghash_free(sod->origfaces, NULL, NULL);
- sod->origfaces = NULL;
- }
-
- if (sod->origverts) {
- BLI_ghash_free(sod->origverts, NULL, NULL);
- sod->origverts = NULL;
- }
-
- if (sod->arena) {
- BLI_memarena_free(sod->arena);
- sod->arena = NULL;
- }
-
- MEM_SAFE_FREE(sod->layer_math_map);
-
- MEM_SAFE_FREE(sod->sv_mirror);
- }
+ TransDataGenericSlideVert *sv = BLI_ghash_lookup(sod->origverts, v);
+ return sv ? sv->co_orig_3d : v->co;
+}
+
+static void slide_origdata_interp_data_vert(SlideOrigData *sod,
+ BMesh *bm,
+ bool is_final,
+ TransDataGenericSlideVert *sv)
+{
+ BMIter liter;
+ int j, l_num;
+ float *loop_weights;
+ const bool is_moved = (len_squared_v3v3(sv->v->co, sv->co_orig_3d) > FLT_EPSILON);
+ const bool do_loop_weight = sod->layer_math_map_num && is_moved;
+ const bool do_loop_mdisps = is_final && is_moved && (sod->cd_loop_mdisp_offset != -1);
+ const float *v_proj_axis = sv->v->no;
+ /* original (l->prev, l, l->next) projections for each loop ('l' remains unchanged) */
+ float v_proj[3][3];
+
+ if (do_loop_weight || do_loop_mdisps) {
+ project_plane_normalized_v3_v3v3(v_proj[1], sv->co_orig_3d, v_proj_axis);
+ }
+
+ // BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT)
+ BM_iter_init(&liter, bm, BM_LOOPS_OF_VERT, sv->v);
+ l_num = liter.count;
+ loop_weights = do_loop_weight ? BLI_array_alloca(loop_weights, l_num) : NULL;
+ for (j = 0; j < l_num; j++) {
+ BMFace *f_copy; /* the copy of 'f' */
+ BMLoop *l = BM_iter_step(&liter);
+
+ f_copy = BLI_ghash_lookup(sod->origfaces, l->f);
+
+ /* only loop data, no vertex data since that contains shape keys,
+ * and we do not want to mess up other shape keys */
+ BM_loop_interp_from_face(bm, l, f_copy, false, false);
+
+ /* make sure face-attributes are correct (e.g. MTexPoly) */
+ BM_elem_attrs_copy_ex(sod->bm_origfaces, bm, f_copy, l->f, 0x0, CD_MASK_NORMAL);
+
+ /* weight the loop */
+ if (do_loop_weight) {
+ const float eps = 1.0e-8f;
+ const BMLoop *l_prev = l->prev;
+ const BMLoop *l_next = l->next;
+ const float *co_prev = slide_origdata_orig_vert_co(sod, l_prev->v);
+ const float *co_next = slide_origdata_orig_vert_co(sod, l_next->v);
+ bool co_prev_ok;
+ bool co_next_ok;
+
+ /* In the unlikely case that we're next to a zero length edge -
+ * walk around the to the next.
+ *
+ * Since we only need to check if the vertex is in this corner,
+ * its not important _which_ loop - as long as its not overlapping
+ * 'sv->co_orig_3d', see: T45096. */
+ project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
+ while (UNLIKELY(((co_prev_ok = (len_squared_v3v3(v_proj[1], v_proj[0]) > eps)) == false) &&
+ ((l_prev = l_prev->prev) != l->next))) {
+ co_prev = slide_origdata_orig_vert_co(sod, l_prev->v);
+ project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
+ }
+ project_plane_normalized_v3_v3v3(v_proj[2], co_next, v_proj_axis);
+ while (UNLIKELY(((co_next_ok = (len_squared_v3v3(v_proj[1], v_proj[2]) > eps)) == false) &&
+ ((l_next = l_next->next) != l->prev))) {
+ co_next = slide_origdata_orig_vert_co(sod, l_next->v);
+ project_plane_normalized_v3_v3v3(v_proj[2], co_next, v_proj_axis);
+ }
+
+ if (co_prev_ok && co_next_ok) {
+ const float dist = dist_signed_squared_to_corner_v3v3v3(
+ sv->v->co, UNPACK3(v_proj), v_proj_axis);
+
+ loop_weights[j] = (dist >= 0.0f) ? 1.0f : ((dist <= -eps) ? 0.0f : (1.0f + (dist / eps)));
+ if (UNLIKELY(!isfinite(loop_weights[j]))) {
+ loop_weights[j] = 0.0f;
+ }
+ }
+ else {
+ loop_weights[j] = 0.0f;
+ }
+ }
+ }
+
+ if (sod->layer_math_map_num) {
+ if (do_loop_weight) {
+ for (j = 0; j < sod->layer_math_map_num; j++) {
+ BM_vert_loop_groups_data_layer_merge_weights(
+ bm, sv->cd_loop_groups[j], sod->layer_math_map[j], loop_weights);
+ }
+ }
+ else {
+ for (j = 0; j < sod->layer_math_map_num; j++) {
+ BM_vert_loop_groups_data_layer_merge(bm, sv->cd_loop_groups[j], sod->layer_math_map[j]);
+ }
+ }
+ }
+
+ /* Special handling for multires
+ *
+ * Interpolate from every other loop (not ideal)
+ * However values will only be taken from loops which overlap other mdisps.
+ * */
+ if (do_loop_mdisps) {
+ float(*faces_center)[3] = BLI_array_alloca(faces_center, l_num);
+ BMLoop *l;
+
+ BM_ITER_ELEM_INDEX(l, &liter, sv->v, BM_LOOPS_OF_VERT, j)
+ {
+ BM_face_calc_center_median(l->f, faces_center[j]);
+ }
+
+ BM_ITER_ELEM_INDEX(l, &liter, sv->v, BM_LOOPS_OF_VERT, j)
+ {
+ BMFace *f_copy = BLI_ghash_lookup(sod->origfaces, l->f);
+ float f_copy_center[3];
+ BMIter liter_other;
+ BMLoop *l_other;
+ int j_other;
+
+ BM_face_calc_center_median(f_copy, f_copy_center);
+
+ BM_ITER_ELEM_INDEX(l_other, &liter_other, sv->v, BM_LOOPS_OF_VERT, j_other)
+ {
+ BM_face_interp_multires_ex(bm,
+ l_other->f,
+ f_copy,
+ faces_center[j_other],
+ f_copy_center,
+ sod->cd_loop_mdisp_offset);
+ }
+ }
+ }
+}
+
+static void slide_origdata_interp_data(Object *obedit,
+ SlideOrigData *sod,
+ TransDataGenericSlideVert *sv,
+ unsigned int v_stride,
+ unsigned int v_num,
+ bool is_final)
+{
+ if (sod->use_origfaces) {
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ unsigned int i;
+ const bool has_mdisps = (sod->cd_loop_mdisp_offset != -1);
+
+ for (i = 0; i < v_num; i++, sv = POINTER_OFFSET(sv, v_stride)) {
+
+ if (sv->cd_loop_groups || has_mdisps) {
+ slide_origdata_interp_data_vert(sod, bm, is_final, sv);
+ }
+ }
+
+ if (sod->sv_mirror) {
+ sv = sod->sv_mirror;
+ for (i = 0; i < v_num; i++, sv++) {
+ if (sv->cd_loop_groups || has_mdisps) {
+ slide_origdata_interp_data_vert(sod, bm, is_final, sv);
+ }
+ }
+ }
+ }
+}
+
+static void slide_origdata_free_date(SlideOrigData *sod)
+{
+ if (sod->use_origfaces) {
+ if (sod->bm_origfaces) {
+ BM_mesh_free(sod->bm_origfaces);
+ sod->bm_origfaces = NULL;
+ }
+
+ if (sod->origfaces) {
+ BLI_ghash_free(sod->origfaces, NULL, NULL);
+ sod->origfaces = NULL;
+ }
+
+ if (sod->origverts) {
+ BLI_ghash_free(sod->origverts, NULL, NULL);
+ sod->origverts = NULL;
+ }
+
+ if (sod->arena) {
+ BLI_memarena_free(sod->arena);
+ sod->arena = NULL;
+ }
+
+ MEM_SAFE_FREE(sod->layer_math_map);
+
+ MEM_SAFE_FREE(sod->sv_mirror);
+ }
}
/** \} */
@@ -6439,100 +6596,95 @@ static void slide_origdata_free_date(
static void calcEdgeSlideCustomPoints(struct TransInfo *t)
{
- EdgeSlideData *sld = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data;
+ EdgeSlideData *sld = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data;
- setCustomPoints(t, &t->mouse, sld->mval_end, sld->mval_start);
+ setCustomPoints(t, &t->mouse, sld->mval_end, sld->mval_start);
- /* setCustomPoints isn't normally changing as the mouse moves,
- * in this case apply mouse input immediately so we don't refresh
- * with the value from the previous points */
- applyMouseInput(t, &t->mouse, t->mval, t->values);
+ /* 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);
}
-
static BMEdge *get_other_edge(BMVert *v, BMEdge *e)
{
- BMIter iter;
- BMEdge *e_iter;
+ BMIter iter;
+ BMEdge *e_iter;
- BM_ITER_ELEM (e_iter, &iter, v, BM_EDGES_OF_VERT) {
- if (BM_elem_flag_test(e_iter, BM_ELEM_SELECT) && e_iter != e) {
- return e_iter;
- }
- }
+ BM_ITER_ELEM (e_iter, &iter, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(e_iter, BM_ELEM_SELECT) && e_iter != e) {
+ return e_iter;
+ }
+ }
- return NULL;
+ return NULL;
}
/* interpoaltes along a line made up of 2 segments (used for edge slide) */
-static void interp_line_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], float t)
-{
- float t_mid, t_delta;
-
- /* could be pre-calculated */
- t_mid = line_point_factor_v3(v2, v1, v3);
-
- t_delta = t - t_mid;
- if (t_delta < 0.0f) {
- if (UNLIKELY(fabsf(t_mid) < FLT_EPSILON)) {
- copy_v3_v3(p, v2);
- }
- else {
- interp_v3_v3v3(p, v1, v2, t / t_mid);
- }
- }
- else {
- t = t - t_mid;
- t_mid = 1.0f - t_mid;
-
- if (UNLIKELY(fabsf(t_mid) < FLT_EPSILON)) {
- copy_v3_v3(p, v3);
- }
- else {
- interp_v3_v3v3(p, v2, v3, t / t_mid);
- }
- }
+static void interp_line_v3_v3v3v3(
+ float p[3], const float v1[3], const float v2[3], const float v3[3], float t)
+{
+ float t_mid, t_delta;
+
+ /* could be pre-calculated */
+ t_mid = line_point_factor_v3(v2, v1, v3);
+
+ t_delta = t - t_mid;
+ if (t_delta < 0.0f) {
+ if (UNLIKELY(fabsf(t_mid) < FLT_EPSILON)) {
+ copy_v3_v3(p, v2);
+ }
+ else {
+ interp_v3_v3v3(p, v1, v2, t / t_mid);
+ }
+ }
+ else {
+ t = t - t_mid;
+ t_mid = 1.0f - t_mid;
+
+ if (UNLIKELY(fabsf(t_mid) < FLT_EPSILON)) {
+ copy_v3_v3(p, v3);
+ }
+ else {
+ interp_v3_v3v3(p, v2, v3, t / t_mid);
+ }
+ }
}
/**
* Find the closest point on the ngon on the opposite side.
* used to set the edge slide distance for ngons.
*/
-static bool bm_loop_calc_opposite_co(BMLoop *l_tmp,
- const float plane_no[3],
- float r_co[3])
-{
- /* skip adjacent edges */
- BMLoop *l_first = l_tmp->next;
- BMLoop *l_last = l_tmp->prev;
- BMLoop *l_iter;
- float dist = FLT_MAX;
- bool found = false;
-
- l_iter = l_first;
- do {
- float tvec[3];
- if (isect_line_plane_v3(tvec,
- l_iter->v->co, l_iter->next->v->co,
- l_tmp->v->co, plane_no))
- {
- const float fac = line_point_factor_v3(tvec, l_iter->v->co, l_iter->next->v->co);
- /* allow some overlap to avoid missing the intersection because of float precision */
- if ((fac > -FLT_EPSILON) && (fac < 1.0f + FLT_EPSILON)) {
- /* likelihood of multiple intersections per ngon is quite low,
- * it would have to loop back on its self, but better support it
- * so check for the closest opposite edge */
- const float tdist = len_v3v3(l_tmp->v->co, tvec);
- if (tdist < dist) {
- copy_v3_v3(r_co, tvec);
- dist = tdist;
- found = true;
- }
- }
- }
- } while ((l_iter = l_iter->next) != l_last);
-
- return found;
+static bool bm_loop_calc_opposite_co(BMLoop *l_tmp, const float plane_no[3], float r_co[3])
+{
+ /* skip adjacent edges */
+ BMLoop *l_first = l_tmp->next;
+ BMLoop *l_last = l_tmp->prev;
+ BMLoop *l_iter;
+ float dist = FLT_MAX;
+ bool found = false;
+
+ l_iter = l_first;
+ do {
+ float tvec[3];
+ if (isect_line_plane_v3(tvec, l_iter->v->co, l_iter->next->v->co, l_tmp->v->co, plane_no)) {
+ const float fac = line_point_factor_v3(tvec, l_iter->v->co, l_iter->next->v->co);
+ /* allow some overlap to avoid missing the intersection because of float precision */
+ if ((fac > -FLT_EPSILON) && (fac < 1.0f + FLT_EPSILON)) {
+ /* likelihood of multiple intersections per ngon is quite low,
+ * it would have to loop back on its self, but better support it
+ * so check for the closest opposite edge */
+ const float tdist = len_v3v3(l_tmp->v->co, tvec);
+ if (tdist < dist) {
+ copy_v3_v3(r_co, tvec);
+ dist = tdist;
+ found = true;
+ }
+ }
+ }
+ } while ((l_iter = l_iter->next) != l_last);
+
+ return found;
}
/**
@@ -6542,667 +6694,673 @@ static bool bm_loop_calc_opposite_co(BMLoop *l_tmp,
* \param r_slide_vec: the direction to slide,
* the length of the vector defines the slide distance.
*/
-static BMLoop *get_next_loop(BMVert *v, BMLoop *l,
- BMEdge *e_prev, BMEdge *e_next, float r_slide_vec[3])
-{
- BMLoop *l_first;
- float vec_accum[3] = {0.0f, 0.0f, 0.0f};
- float vec_accum_len = 0.0f;
- int i = 0;
-
- BLI_assert(BM_edge_share_vert(e_prev, e_next) == v);
- BLI_assert(BM_vert_in_edge(l->e, v));
-
- l_first = l;
- do {
- l = BM_loop_other_edge_loop(l, v);
-
- if (l->e == e_next) {
- if (i) {
- normalize_v3_length(vec_accum, vec_accum_len / (float)i);
- }
- else {
- /* When there is no edge to slide along,
- * we must slide along the vector defined by the face we're attach to */
- BMLoop *l_tmp = BM_face_vert_share_loop(l_first->f, v);
-
- BLI_assert(ELEM(l_tmp->e, e_prev, e_next) && ELEM(l_tmp->prev->e, e_prev, e_next));
-
- if (l_tmp->f->len == 4) {
- /* we could use code below, but in this case
- * sliding diagonally across the quad works well */
- sub_v3_v3v3(vec_accum, l_tmp->next->next->v->co, v->co);
- }
- else {
- float tdir[3];
- BM_loop_calc_face_direction(l_tmp, tdir);
- cross_v3_v3v3(vec_accum, l_tmp->f->no, tdir);
+static BMLoop *get_next_loop(
+ BMVert *v, BMLoop *l, BMEdge *e_prev, BMEdge *e_next, float r_slide_vec[3])
+{
+ BMLoop *l_first;
+ float vec_accum[3] = {0.0f, 0.0f, 0.0f};
+ float vec_accum_len = 0.0f;
+ int i = 0;
+
+ BLI_assert(BM_edge_share_vert(e_prev, e_next) == v);
+ BLI_assert(BM_vert_in_edge(l->e, v));
+
+ l_first = l;
+ do {
+ l = BM_loop_other_edge_loop(l, v);
+
+ if (l->e == e_next) {
+ if (i) {
+ normalize_v3_length(vec_accum, vec_accum_len / (float)i);
+ }
+ else {
+ /* When there is no edge to slide along,
+ * we must slide along the vector defined by the face we're attach to */
+ BMLoop *l_tmp = BM_face_vert_share_loop(l_first->f, v);
+
+ BLI_assert(ELEM(l_tmp->e, e_prev, e_next) && ELEM(l_tmp->prev->e, e_prev, e_next));
+
+ if (l_tmp->f->len == 4) {
+ /* we could use code below, but in this case
+ * sliding diagonally across the quad works well */
+ sub_v3_v3v3(vec_accum, l_tmp->next->next->v->co, v->co);
+ }
+ else {
+ float tdir[3];
+ BM_loop_calc_face_direction(l_tmp, tdir);
+ cross_v3_v3v3(vec_accum, l_tmp->f->no, tdir);
#if 0
- /* rough guess, we can do better! */
- normalize_v3_length(vec_accum, (BM_edge_calc_length(e_prev) + BM_edge_calc_length(e_next)) / 2.0f);
+ /* rough guess, we can do better! */
+ normalize_v3_length(vec_accum, (BM_edge_calc_length(e_prev) + BM_edge_calc_length(e_next)) / 2.0f);
#else
- /* be clever, check the opposite ngon edge to slide into.
- * this gives best results */
- {
- float tvec[3];
- float dist;
-
- if (bm_loop_calc_opposite_co(l_tmp, tdir, tvec)) {
- dist = len_v3v3(l_tmp->v->co, tvec);
- }
- else {
- dist = (BM_edge_calc_length(e_prev) + BM_edge_calc_length(e_next)) / 2.0f;
- }
-
- normalize_v3_length(vec_accum, dist);
- }
+ /* be clever, check the opposite ngon edge to slide into.
+ * this gives best results */
+ {
+ float tvec[3];
+ float dist;
+
+ if (bm_loop_calc_opposite_co(l_tmp, tdir, tvec)) {
+ dist = len_v3v3(l_tmp->v->co, tvec);
+ }
+ else {
+ dist = (BM_edge_calc_length(e_prev) + BM_edge_calc_length(e_next)) / 2.0f;
+ }
+
+ normalize_v3_length(vec_accum, dist);
+ }
#endif
- }
- }
+ }
+ }
- copy_v3_v3(r_slide_vec, vec_accum);
- return l;
- }
- else {
- /* accumulate the normalized edge vector,
- * normalize so some edges don't skew the result */
- float tvec[3];
- sub_v3_v3v3(tvec, BM_edge_other_vert(l->e, v)->co, v->co);
- vec_accum_len += normalize_v3(tvec);
- add_v3_v3(vec_accum, tvec);
- i += 1;
- }
+ copy_v3_v3(r_slide_vec, vec_accum);
+ return l;
+ }
+ else {
+ /* accumulate the normalized edge vector,
+ * normalize so some edges don't skew the result */
+ float tvec[3];
+ sub_v3_v3v3(tvec, BM_edge_other_vert(l->e, v)->co, v->co);
+ vec_accum_len += normalize_v3(tvec);
+ add_v3_v3(vec_accum, tvec);
+ i += 1;
+ }
- if (BM_loop_other_edge_loop(l, v)->e == e_next) {
- if (i) {
- normalize_v3_length(vec_accum, vec_accum_len / (float)i);
- }
+ if (BM_loop_other_edge_loop(l, v)->e == e_next) {
+ if (i) {
+ normalize_v3_length(vec_accum, vec_accum_len / (float)i);
+ }
- copy_v3_v3(r_slide_vec, vec_accum);
- return BM_loop_other_edge_loop(l, v);
- }
+ copy_v3_v3(r_slide_vec, vec_accum);
+ return BM_loop_other_edge_loop(l, v);
+ }
- } while ((l != l->radial_next) &&
- ((l = l->radial_next) != l_first));
+ } while ((l != l->radial_next) && ((l = l->radial_next) != l_first));
- if (i) {
- normalize_v3_length(vec_accum, vec_accum_len / (float)i);
- }
+ if (i) {
+ normalize_v3_length(vec_accum, vec_accum_len / (float)i);
+ }
- copy_v3_v3(r_slide_vec, vec_accum);
+ copy_v3_v3(r_slide_vec, vec_accum);
- return NULL;
+ return NULL;
}
/**
* Calculate screenspace `mval_start` / `mval_end`, optionally slide direction.
*/
-static void calcEdgeSlide_mval_range(
- TransInfo *t, TransDataContainer *tc, EdgeSlideData *sld, const int *sv_table, const int loop_nr,
- const float mval[2], const bool use_occlude_geometry, const bool use_calc_direction)
-{
- TransDataEdgeSlideVert *sv_array = sld->sv;
- BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
- BMesh *bm = em->bm;
- ARegion *ar = t->ar;
- View3D *v3d = NULL;
- RegionView3D *rv3d = NULL;
- float projectMat[4][4];
- BMBVHTree *bmbvh;
-
- /* only for use_calc_direction */
- float (*loop_dir)[3] = NULL, *loop_maxdist = NULL;
-
- float mval_start[2], mval_end[2];
- float mval_dir[3], dist_best_sq;
- BMIter iter;
- BMEdge *e;
-
- if (t->spacetype == SPACE_VIEW3D) {
- /* background mode support */
- v3d = t->sa ? t->sa->spacedata.first : NULL;
- rv3d = t->ar ? t->ar->regiondata : NULL;
- }
-
- if (!rv3d) {
- /* ok, let's try to survive this */
- unit_m4(projectMat);
- }
- else {
- ED_view3d_ob_project_mat_get(rv3d, tc->obedit, projectMat);
- }
-
- if (use_occlude_geometry) {
- bmbvh = BKE_bmbvh_new_from_editmesh(em, BMBVH_RESPECT_HIDDEN, NULL, false);
- }
- else {
- bmbvh = NULL;
- }
-
- /* find mouse vectors, the global one, and one per loop in case we have
- * multiple loops selected, in case they are oriented different */
- zero_v3(mval_dir);
- dist_best_sq = -1.0f;
-
- if (use_calc_direction) {
- loop_dir = MEM_callocN(sizeof(float[3]) * loop_nr, "sv loop_dir");
- loop_maxdist = MEM_mallocN(sizeof(float) * loop_nr, "sv loop_maxdist");
- copy_vn_fl(loop_maxdist, loop_nr, -1.0f);
- }
-
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- int i;
-
- /* search cross edges for visible edge to the mouse cursor,
- * then use the shared vertex to calculate screen vector*/
- for (i = 0; i < 2; i++) {
- BMIter iter_other;
- BMEdge *e_other;
-
- BMVert *v = i ? e->v1 : e->v2;
- BM_ITER_ELEM (e_other, &iter_other, v, BM_EDGES_OF_VERT) {
- /* screen-space coords */
- float sco_a[3], sco_b[3];
- float dist_sq;
- int j, l_nr;
-
- if (BM_elem_flag_test(e_other, BM_ELEM_SELECT))
- continue;
-
- /* This test is only relevant if object is not wire-drawn! See [#32068]. */
- if (use_occlude_geometry &&
- !BMBVH_EdgeVisible(bmbvh, e_other, t->depsgraph, ar, v3d, tc->obedit))
- {
- continue;
- }
-
- BLI_assert(sv_table[BM_elem_index_get(v)] != -1);
- j = sv_table[BM_elem_index_get(v)];
-
- if (sv_array[j].v_side[1]) {
- ED_view3d_project_float_v3_m4(ar, sv_array[j].v_side[1]->co, sco_b, projectMat);
- }
- else {
- add_v3_v3v3(sco_b, v->co, sv_array[j].dir_side[1]);
- ED_view3d_project_float_v3_m4(ar, sco_b, sco_b, projectMat);
- }
-
- if (sv_array[j].v_side[0]) {
- ED_view3d_project_float_v3_m4(ar, sv_array[j].v_side[0]->co, sco_a, projectMat);
- }
- else {
- add_v3_v3v3(sco_a, v->co, sv_array[j].dir_side[0]);
- ED_view3d_project_float_v3_m4(ar, sco_a, sco_a, projectMat);
- }
-
- /* global direction */
- dist_sq = dist_squared_to_line_segment_v2(mval, sco_b, sco_a);
- if ((dist_best_sq == -1.0f) ||
- /* intentionally use 2d size on 3d vector */
- (dist_sq < dist_best_sq && (len_squared_v2v2(sco_b, sco_a) > 0.1f)))
- {
- dist_best_sq = dist_sq;
- sub_v3_v3v3(mval_dir, sco_b, sco_a);
- }
-
- if (use_calc_direction) {
- /* per loop direction */
- l_nr = sv_array[j].loop_nr;
- if (loop_maxdist[l_nr] == -1.0f || dist_sq < loop_maxdist[l_nr]) {
- loop_maxdist[l_nr] = dist_sq;
- sub_v3_v3v3(loop_dir[l_nr], sco_b, sco_a);
- }
- }
- }
- }
- }
- }
-
- if (use_calc_direction) {
- int i;
- sv_array = sld->sv;
- for (i = 0; i < sld->totsv; i++, sv_array++) {
- /* switch a/b if loop direction is different from global direction */
- int l_nr = sv_array->loop_nr;
- if (dot_v3v3(loop_dir[l_nr], mval_dir) < 0.0f) {
- swap_v3_v3(sv_array->dir_side[0], sv_array->dir_side[1]);
- SWAP(BMVert *, sv_array->v_side[0], sv_array->v_side[1]);
- }
- }
-
- MEM_freeN(loop_dir);
- MEM_freeN(loop_maxdist);
- }
-
- /* possible all of the edge loops are pointing directly at the view */
- if (UNLIKELY(len_squared_v2(mval_dir) < 0.1f)) {
- mval_dir[0] = 0.0f;
- mval_dir[1] = 100.0f;
- }
-
- /* zero out start */
- zero_v2(mval_start);
-
- /* dir holds a vector along edge loop */
- copy_v2_v2(mval_end, mval_dir);
- mul_v2_fl(mval_end, 0.5f);
-
- sld->mval_start[0] = t->mval[0] + mval_start[0];
- sld->mval_start[1] = t->mval[1] + mval_start[1];
-
- sld->mval_end[0] = t->mval[0] + mval_end[0];
- sld->mval_end[1] = t->mval[1] + mval_end[1];
-
- if (bmbvh) {
- BKE_bmbvh_free(bmbvh);
- }
-}
-
-static void calcEdgeSlide_even(
- TransInfo *t, TransDataContainer *tc, EdgeSlideData *sld, const float mval[2])
-{
- TransDataEdgeSlideVert *sv = sld->sv;
-
- if (sld->totsv > 0) {
- ARegion *ar = t->ar;
- RegionView3D *rv3d = NULL;
- float projectMat[4][4];
-
- int i = 0;
-
- float v_proj[2];
- float dist_sq = 0;
- float dist_min_sq = FLT_MAX;
-
- if (t->spacetype == SPACE_VIEW3D) {
- /* background mode support */
- rv3d = t->ar ? t->ar->regiondata : NULL;
- }
-
- if (!rv3d) {
- /* ok, let's try to survive this */
- unit_m4(projectMat);
- }
- else {
- ED_view3d_ob_project_mat_get(rv3d, tc->obedit, projectMat);
- }
-
- for (i = 0; i < sld->totsv; i++, sv++) {
- /* Set length */
- sv->edge_len = len_v3v3(sv->dir_side[0], sv->dir_side[1]);
-
- ED_view3d_project_float_v2_m4(ar, sv->v->co, v_proj, projectMat);
- dist_sq = len_squared_v2v2(mval, v_proj);
- if (dist_sq < dist_min_sq) {
- dist_min_sq = dist_sq;
- sld->curr_sv_index = i;
- }
- }
- }
- else {
- sld->curr_sv_index = 0;
- }
+static void calcEdgeSlide_mval_range(TransInfo *t,
+ TransDataContainer *tc,
+ EdgeSlideData *sld,
+ const int *sv_table,
+ const int loop_nr,
+ const float mval[2],
+ const bool use_occlude_geometry,
+ const bool use_calc_direction)
+{
+ TransDataEdgeSlideVert *sv_array = sld->sv;
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+ BMesh *bm = em->bm;
+ ARegion *ar = t->ar;
+ View3D *v3d = NULL;
+ RegionView3D *rv3d = NULL;
+ float projectMat[4][4];
+ BMBVHTree *bmbvh;
+
+ /* only for use_calc_direction */
+ float(*loop_dir)[3] = NULL, *loop_maxdist = NULL;
+
+ float mval_start[2], mval_end[2];
+ float mval_dir[3], dist_best_sq;
+ BMIter iter;
+ BMEdge *e;
+
+ if (t->spacetype == SPACE_VIEW3D) {
+ /* background mode support */
+ v3d = t->sa ? t->sa->spacedata.first : NULL;
+ rv3d = t->ar ? t->ar->regiondata : NULL;
+ }
+
+ if (!rv3d) {
+ /* ok, let's try to survive this */
+ unit_m4(projectMat);
+ }
+ else {
+ ED_view3d_ob_project_mat_get(rv3d, tc->obedit, projectMat);
+ }
+
+ if (use_occlude_geometry) {
+ bmbvh = BKE_bmbvh_new_from_editmesh(em, BMBVH_RESPECT_HIDDEN, NULL, false);
+ }
+ else {
+ bmbvh = NULL;
+ }
+
+ /* find mouse vectors, the global one, and one per loop in case we have
+ * multiple loops selected, in case they are oriented different */
+ zero_v3(mval_dir);
+ dist_best_sq = -1.0f;
+
+ if (use_calc_direction) {
+ loop_dir = MEM_callocN(sizeof(float[3]) * loop_nr, "sv loop_dir");
+ loop_maxdist = MEM_mallocN(sizeof(float) * loop_nr, "sv loop_maxdist");
+ copy_vn_fl(loop_maxdist, loop_nr, -1.0f);
+ }
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ int i;
+
+ /* search cross edges for visible edge to the mouse cursor,
+ * then use the shared vertex to calculate screen vector*/
+ for (i = 0; i < 2; i++) {
+ BMIter iter_other;
+ BMEdge *e_other;
+
+ BMVert *v = i ? e->v1 : e->v2;
+ BM_ITER_ELEM (e_other, &iter_other, v, BM_EDGES_OF_VERT) {
+ /* screen-space coords */
+ float sco_a[3], sco_b[3];
+ float dist_sq;
+ int j, l_nr;
+
+ if (BM_elem_flag_test(e_other, BM_ELEM_SELECT))
+ continue;
+
+ /* This test is only relevant if object is not wire-drawn! See [#32068]. */
+ if (use_occlude_geometry &&
+ !BMBVH_EdgeVisible(bmbvh, e_other, t->depsgraph, ar, v3d, tc->obedit)) {
+ continue;
+ }
+
+ BLI_assert(sv_table[BM_elem_index_get(v)] != -1);
+ j = sv_table[BM_elem_index_get(v)];
+
+ if (sv_array[j].v_side[1]) {
+ ED_view3d_project_float_v3_m4(ar, sv_array[j].v_side[1]->co, sco_b, projectMat);
+ }
+ else {
+ add_v3_v3v3(sco_b, v->co, sv_array[j].dir_side[1]);
+ ED_view3d_project_float_v3_m4(ar, sco_b, sco_b, projectMat);
+ }
+
+ if (sv_array[j].v_side[0]) {
+ ED_view3d_project_float_v3_m4(ar, sv_array[j].v_side[0]->co, sco_a, projectMat);
+ }
+ else {
+ add_v3_v3v3(sco_a, v->co, sv_array[j].dir_side[0]);
+ ED_view3d_project_float_v3_m4(ar, sco_a, sco_a, projectMat);
+ }
+
+ /* global direction */
+ dist_sq = dist_squared_to_line_segment_v2(mval, sco_b, sco_a);
+ if ((dist_best_sq == -1.0f) ||
+ /* intentionally use 2d size on 3d vector */
+ (dist_sq < dist_best_sq && (len_squared_v2v2(sco_b, sco_a) > 0.1f))) {
+ dist_best_sq = dist_sq;
+ sub_v3_v3v3(mval_dir, sco_b, sco_a);
+ }
+
+ if (use_calc_direction) {
+ /* per loop direction */
+ l_nr = sv_array[j].loop_nr;
+ if (loop_maxdist[l_nr] == -1.0f || dist_sq < loop_maxdist[l_nr]) {
+ loop_maxdist[l_nr] = dist_sq;
+ sub_v3_v3v3(loop_dir[l_nr], sco_b, sco_a);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (use_calc_direction) {
+ int i;
+ sv_array = sld->sv;
+ for (i = 0; i < sld->totsv; i++, sv_array++) {
+ /* switch a/b if loop direction is different from global direction */
+ int l_nr = sv_array->loop_nr;
+ if (dot_v3v3(loop_dir[l_nr], mval_dir) < 0.0f) {
+ swap_v3_v3(sv_array->dir_side[0], sv_array->dir_side[1]);
+ SWAP(BMVert *, sv_array->v_side[0], sv_array->v_side[1]);
+ }
+ }
+
+ MEM_freeN(loop_dir);
+ MEM_freeN(loop_maxdist);
+ }
+
+ /* possible all of the edge loops are pointing directly at the view */
+ if (UNLIKELY(len_squared_v2(mval_dir) < 0.1f)) {
+ mval_dir[0] = 0.0f;
+ mval_dir[1] = 100.0f;
+ }
+
+ /* zero out start */
+ zero_v2(mval_start);
+
+ /* dir holds a vector along edge loop */
+ copy_v2_v2(mval_end, mval_dir);
+ mul_v2_fl(mval_end, 0.5f);
+
+ sld->mval_start[0] = t->mval[0] + mval_start[0];
+ sld->mval_start[1] = t->mval[1] + mval_start[1];
+
+ sld->mval_end[0] = t->mval[0] + mval_end[0];
+ sld->mval_end[1] = t->mval[1] + mval_end[1];
+
+ if (bmbvh) {
+ BKE_bmbvh_free(bmbvh);
+ }
+}
+
+static void calcEdgeSlide_even(TransInfo *t,
+ TransDataContainer *tc,
+ EdgeSlideData *sld,
+ const float mval[2])
+{
+ TransDataEdgeSlideVert *sv = sld->sv;
+
+ if (sld->totsv > 0) {
+ ARegion *ar = t->ar;
+ RegionView3D *rv3d = NULL;
+ float projectMat[4][4];
+
+ int i = 0;
+
+ float v_proj[2];
+ float dist_sq = 0;
+ float dist_min_sq = FLT_MAX;
+
+ if (t->spacetype == SPACE_VIEW3D) {
+ /* background mode support */
+ rv3d = t->ar ? t->ar->regiondata : NULL;
+ }
+
+ if (!rv3d) {
+ /* ok, let's try to survive this */
+ unit_m4(projectMat);
+ }
+ else {
+ ED_view3d_ob_project_mat_get(rv3d, tc->obedit, projectMat);
+ }
+
+ for (i = 0; i < sld->totsv; i++, sv++) {
+ /* Set length */
+ sv->edge_len = len_v3v3(sv->dir_side[0], sv->dir_side[1]);
+
+ ED_view3d_project_float_v2_m4(ar, sv->v->co, v_proj, projectMat);
+ dist_sq = len_squared_v2v2(mval, v_proj);
+ if (dist_sq < dist_min_sq) {
+ dist_min_sq = dist_sq;
+ sld->curr_sv_index = i;
+ }
+ }
+ }
+ else {
+ sld->curr_sv_index = 0;
+ }
}
static bool createEdgeSlideVerts_double_side(TransInfo *t, TransDataContainer *tc)
{
- BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
- BMesh *bm = em->bm;
- BMIter iter;
- BMEdge *e;
- BMVert *v;
- TransDataEdgeSlideVert *sv_array;
- int sv_tot;
- int *sv_table; /* BMVert -> sv_array index */
- EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld");
- float mval[2] = {(float)t->mval[0], (float)t->mval[1]};
- int numsel, i, loop_nr;
- bool use_occlude_geometry = false;
- View3D *v3d = NULL;
- RegionView3D *rv3d = NULL;
-
- slide_origdata_init_flag(t, tc, &sld->orig_data);
-
- sld->curr_sv_index = 0;
-
- /*ensure valid selection*/
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
- BMIter iter2;
- numsel = 0;
- BM_ITER_ELEM (e, &iter2, v, BM_EDGES_OF_VERT) {
- if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- /* BMESH_TODO: this is probably very evil,
- * set v->e to a selected edge*/
- v->e = e;
-
- numsel++;
- }
- }
-
- if (numsel == 0 || numsel > 2) {
- MEM_freeN(sld);
- return false; /* invalid edge selection */
- }
- }
- }
-
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- /* note, any edge with loops can work, but we won't get predictable results, so bail out */
- if (!BM_edge_is_manifold(e) && !BM_edge_is_boundary(e)) {
- /* can edges with at least once face user */
- MEM_freeN(sld);
- return false;
- }
- }
- }
-
- sv_table = MEM_mallocN(sizeof(*sv_table) * bm->totvert, __func__);
-
-#define INDEX_UNSET -1
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+ BMesh *bm = em->bm;
+ BMIter iter;
+ BMEdge *e;
+ BMVert *v;
+ TransDataEdgeSlideVert *sv_array;
+ int sv_tot;
+ int *sv_table; /* BMVert -> sv_array index */
+ EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld");
+ float mval[2] = {(float)t->mval[0], (float)t->mval[1]};
+ int numsel, i, loop_nr;
+ bool use_occlude_geometry = false;
+ View3D *v3d = NULL;
+ RegionView3D *rv3d = NULL;
+
+ slide_origdata_init_flag(t, tc, &sld->orig_data);
+
+ sld->curr_sv_index = 0;
+
+ /*ensure valid selection*/
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ BMIter iter2;
+ numsel = 0;
+ BM_ITER_ELEM (e, &iter2, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ /* BMESH_TODO: this is probably very evil,
+ * set v->e to a selected edge*/
+ v->e = e;
+
+ numsel++;
+ }
+ }
+
+ if (numsel == 0 || numsel > 2) {
+ MEM_freeN(sld);
+ return false; /* invalid edge selection */
+ }
+ }
+ }
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ /* note, any edge with loops can work, but we won't get predictable results, so bail out */
+ if (!BM_edge_is_manifold(e) && !BM_edge_is_boundary(e)) {
+ /* can edges with at least once face user */
+ MEM_freeN(sld);
+ return false;
+ }
+ }
+ }
+
+ sv_table = MEM_mallocN(sizeof(*sv_table) * bm->totvert, __func__);
+
+#define INDEX_UNSET -1
#define INDEX_INVALID -2
- {
- int j = 0;
- BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
- if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
- BM_elem_flag_enable(v, BM_ELEM_TAG);
- sv_table[i] = INDEX_UNSET;
- j += 1;
- }
- else {
- BM_elem_flag_disable(v, BM_ELEM_TAG);
- sv_table[i] = INDEX_INVALID;
- }
- BM_elem_index_set(v, i); /* set_inline */
- }
- bm->elem_index_dirty &= ~BM_VERT;
-
- if (!j) {
- MEM_freeN(sld);
- MEM_freeN(sv_table);
- return false;
- }
- sv_tot = j;
- }
-
- sv_array = MEM_callocN(sizeof(TransDataEdgeSlideVert) * sv_tot, "sv_array");
- loop_nr = 0;
-
- STACK_DECLARE(sv_array);
- STACK_INIT(sv_array, sv_tot);
-
- while (1) {
- float vec_a[3], vec_b[3];
- BMLoop *l_a, *l_b;
- BMLoop *l_a_prev, *l_b_prev;
- BMVert *v_first;
- /* If this succeeds call get_next_loop()
- * which calculates the direction to slide based on clever checks.
- *
- * otherwise we simply use 'e_dir' as an edge-rail.
- * (which is better when the attached edge is a boundary, see: T40422)
- */
+ {
+ int j = 0;
+ BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ BM_elem_flag_enable(v, BM_ELEM_TAG);
+ sv_table[i] = INDEX_UNSET;
+ j += 1;
+ }
+ else {
+ BM_elem_flag_disable(v, BM_ELEM_TAG);
+ sv_table[i] = INDEX_INVALID;
+ }
+ BM_elem_index_set(v, i); /* set_inline */
+ }
+ bm->elem_index_dirty &= ~BM_VERT;
+
+ if (!j) {
+ MEM_freeN(sld);
+ MEM_freeN(sv_table);
+ return false;
+ }
+ sv_tot = j;
+ }
+
+ sv_array = MEM_callocN(sizeof(TransDataEdgeSlideVert) * sv_tot, "sv_array");
+ loop_nr = 0;
+
+ STACK_DECLARE(sv_array);
+ STACK_INIT(sv_array, sv_tot);
+
+ while (1) {
+ float vec_a[3], vec_b[3];
+ BMLoop *l_a, *l_b;
+ BMLoop *l_a_prev, *l_b_prev;
+ BMVert *v_first;
+ /* If this succeeds call get_next_loop()
+ * which calculates the direction to slide based on clever checks.
+ *
+ * otherwise we simply use 'e_dir' as an edge-rail.
+ * (which is better when the attached edge is a boundary, see: T40422)
+ */
#define EDGESLIDE_VERT_IS_INNER(v, e_dir) \
- ((BM_edge_is_boundary(e_dir) == false) && \
- (BM_vert_edge_count_nonwire(v) == 2))
-
- v = NULL;
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(v, BM_ELEM_TAG))
- break;
-
- }
-
- if (!v)
- break;
-
- if (!v->e)
- continue;
-
- v_first = v;
-
- /*walk along the edge loop*/
- e = v->e;
-
- /*first, rewind*/
- do {
- e = get_other_edge(v, e);
- if (!e) {
- e = v->e;
- break;
- }
-
- if (!BM_elem_flag_test(BM_edge_other_vert(e, v), BM_ELEM_TAG))
- break;
-
- v = BM_edge_other_vert(e, v);
- } while (e != v_first->e);
-
- BM_elem_flag_disable(v, BM_ELEM_TAG);
-
- l_a = e->l;
- l_b = e->l->radial_next;
-
- /* regarding e_next, use get_next_loop()'s improved interpolation where possible */
- {
- BMEdge *e_next = get_other_edge(v, e);
- if (e_next) {
- get_next_loop(v, l_a, e, e_next, vec_a);
- }
- else {
- BMLoop *l_tmp = BM_loop_other_edge_loop(l_a, v);
- if (EDGESLIDE_VERT_IS_INNER(v, l_tmp->e)) {
- get_next_loop(v, l_a, e, l_tmp->e, vec_a);
- }
- else {
- sub_v3_v3v3(vec_a, BM_edge_other_vert(l_tmp->e, v)->co, v->co);
- }
- }
- }
-
- /* !BM_edge_is_boundary(e); */
- if (l_b != l_a) {
- BMEdge *e_next = get_other_edge(v, e);
- if (e_next) {
- get_next_loop(v, l_b, e, e_next, vec_b);
- }
- else {
- BMLoop *l_tmp = BM_loop_other_edge_loop(l_b, v);
- if (EDGESLIDE_VERT_IS_INNER(v, l_tmp->e)) {
- get_next_loop(v, l_b, e, l_tmp->e, vec_b);
- }
- else {
- sub_v3_v3v3(vec_b, BM_edge_other_vert(l_tmp->e, v)->co, v->co);
- }
- }
- }
- else {
- l_b = NULL;
- }
-
- l_a_prev = NULL;
- l_b_prev = NULL;
-
-#define SV_FROM_VERT(v) ( \
- (sv_table[BM_elem_index_get(v)] == INDEX_UNSET) ? \
- ((void)(sv_table[BM_elem_index_get(v)] = STACK_SIZE(sv_array)), STACK_PUSH_RET_PTR(sv_array)) : \
- (&sv_array[sv_table[BM_elem_index_get(v)]]))
-
- /*iterate over the loop*/
- v_first = v;
- do {
- bool l_a_ok_prev;
- bool l_b_ok_prev;
- TransDataEdgeSlideVert *sv;
- BMVert *v_prev;
- BMEdge *e_prev;
-
- /* XXX, 'sv' will initialize multiple times, this is suspicious. see [#34024] */
- BLI_assert(v != NULL);
- BLI_assert(sv_table[BM_elem_index_get(v)] != INDEX_INVALID);
- sv = SV_FROM_VERT(v);
- sv->v = v;
- copy_v3_v3(sv->v_co_orig, v->co);
- sv->loop_nr = loop_nr;
-
- if (l_a || l_a_prev) {
- BMLoop *l_tmp = BM_loop_other_edge_loop(l_a ? l_a : l_a_prev, v);
- sv->v_side[0] = BM_edge_other_vert(l_tmp->e, v);
- copy_v3_v3(sv->dir_side[0], vec_a);
- }
-
- if (l_b || l_b_prev) {
- BMLoop *l_tmp = BM_loop_other_edge_loop(l_b ? l_b : l_b_prev, v);
- sv->v_side[1] = BM_edge_other_vert(l_tmp->e, v);
- copy_v3_v3(sv->dir_side[1], vec_b);
- }
-
- v_prev = v;
- v = BM_edge_other_vert(e, v);
-
- e_prev = e;
- e = get_other_edge(v, e);
-
- if (!e) {
- BLI_assert(v != NULL);
-
- BLI_assert(sv_table[BM_elem_index_get(v)] != INDEX_INVALID);
- sv = SV_FROM_VERT(v);
-
- sv->v = v;
- copy_v3_v3(sv->v_co_orig, v->co);
- sv->loop_nr = loop_nr;
-
- if (l_a) {
- BMLoop *l_tmp = BM_loop_other_edge_loop(l_a, v);
- sv->v_side[0] = BM_edge_other_vert(l_tmp->e, v);
- if (EDGESLIDE_VERT_IS_INNER(v, l_tmp->e)) {
- get_next_loop(v, l_a, e_prev, l_tmp->e, sv->dir_side[0]);
- }
- else {
- sub_v3_v3v3(sv->dir_side[0], sv->v_side[0]->co, v->co);
- }
- }
-
- if (l_b) {
- BMLoop *l_tmp = BM_loop_other_edge_loop(l_b, v);
- sv->v_side[1] = BM_edge_other_vert(l_tmp->e, v);
- if (EDGESLIDE_VERT_IS_INNER(v, l_tmp->e)) {
- get_next_loop(v, l_b, e_prev, l_tmp->e, sv->dir_side[1]);
- }
- else {
- sub_v3_v3v3(sv->dir_side[1], sv->v_side[1]->co, v->co);
- }
- }
-
- BM_elem_flag_disable(v, BM_ELEM_TAG);
- BM_elem_flag_disable(v_prev, BM_ELEM_TAG);
-
- break;
- }
- l_a_ok_prev = (l_a != NULL);
- l_b_ok_prev = (l_b != NULL);
-
- l_a_prev = l_a;
- l_b_prev = l_b;
-
- if (l_a) {
- l_a = get_next_loop(v, l_a, e_prev, e, vec_a);
- }
- else {
- zero_v3(vec_a);
- }
-
- if (l_b) {
- l_b = get_next_loop(v, l_b, e_prev, e, vec_b);
- }
- else {
- zero_v3(vec_b);
- }
-
-
- if (l_a && l_b) {
- /* pass */
- }
- else {
- if (l_a || l_b) {
- /* find the opposite loop if it was missing previously */
- if (l_a == NULL && l_b && (l_b->radial_next != l_b)) l_a = l_b->radial_next;
- else if (l_b == NULL && l_a && (l_a->radial_next != l_a)) l_b = l_a->radial_next;
- }
- else if (e->l != NULL) {
- /* if there are non-contiguous faces, we can still recover
- * the loops of the new edges faces */
-
- /* note!, the behavior in this case means edges may move in opposite directions,
- * this could be made to work more usefully. */
-
- if (l_a_ok_prev) {
- l_a = e->l;
- l_b = (l_a->radial_next != l_a) ? l_a->radial_next : NULL;
- }
- else if (l_b_ok_prev) {
- l_b = e->l;
- l_a = (l_b->radial_next != l_b) ? l_b->radial_next : NULL;
- }
- }
-
- if (!l_a_ok_prev && l_a) {
- get_next_loop(v, l_a, e, e_prev, vec_a);
- }
- if (!l_b_ok_prev && l_b) {
- get_next_loop(v, l_b, e, e_prev, vec_b);
- }
- }
-
- BM_elem_flag_disable(v, BM_ELEM_TAG);
- BM_elem_flag_disable(v_prev, BM_ELEM_TAG);
- } while ((e != v_first->e) && (l_a || l_b));
+ ((BM_edge_is_boundary(e_dir) == false) && (BM_vert_edge_count_nonwire(v) == 2))
+
+ v = NULL;
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_TAG))
+ break;
+ }
+
+ if (!v)
+ break;
+
+ if (!v->e)
+ continue;
+
+ v_first = v;
+
+ /*walk along the edge loop*/
+ e = v->e;
+
+ /*first, rewind*/
+ do {
+ e = get_other_edge(v, e);
+ if (!e) {
+ e = v->e;
+ break;
+ }
+
+ if (!BM_elem_flag_test(BM_edge_other_vert(e, v), BM_ELEM_TAG))
+ break;
+
+ v = BM_edge_other_vert(e, v);
+ } while (e != v_first->e);
+
+ BM_elem_flag_disable(v, BM_ELEM_TAG);
+
+ l_a = e->l;
+ l_b = e->l->radial_next;
+
+ /* regarding e_next, use get_next_loop()'s improved interpolation where possible */
+ {
+ BMEdge *e_next = get_other_edge(v, e);
+ if (e_next) {
+ get_next_loop(v, l_a, e, e_next, vec_a);
+ }
+ else {
+ BMLoop *l_tmp = BM_loop_other_edge_loop(l_a, v);
+ if (EDGESLIDE_VERT_IS_INNER(v, l_tmp->e)) {
+ get_next_loop(v, l_a, e, l_tmp->e, vec_a);
+ }
+ else {
+ sub_v3_v3v3(vec_a, BM_edge_other_vert(l_tmp->e, v)->co, v->co);
+ }
+ }
+ }
+
+ /* !BM_edge_is_boundary(e); */
+ if (l_b != l_a) {
+ BMEdge *e_next = get_other_edge(v, e);
+ if (e_next) {
+ get_next_loop(v, l_b, e, e_next, vec_b);
+ }
+ else {
+ BMLoop *l_tmp = BM_loop_other_edge_loop(l_b, v);
+ if (EDGESLIDE_VERT_IS_INNER(v, l_tmp->e)) {
+ get_next_loop(v, l_b, e, l_tmp->e, vec_b);
+ }
+ else {
+ sub_v3_v3v3(vec_b, BM_edge_other_vert(l_tmp->e, v)->co, v->co);
+ }
+ }
+ }
+ else {
+ l_b = NULL;
+ }
+
+ l_a_prev = NULL;
+ l_b_prev = NULL;
+
+#define SV_FROM_VERT(v) \
+ ((sv_table[BM_elem_index_get(v)] == INDEX_UNSET) ? \
+ ((void)(sv_table[BM_elem_index_get(v)] = STACK_SIZE(sv_array)), \
+ STACK_PUSH_RET_PTR(sv_array)) : \
+ (&sv_array[sv_table[BM_elem_index_get(v)]]))
+
+ /*iterate over the loop*/
+ v_first = v;
+ do {
+ bool l_a_ok_prev;
+ bool l_b_ok_prev;
+ TransDataEdgeSlideVert *sv;
+ BMVert *v_prev;
+ BMEdge *e_prev;
+
+ /* XXX, 'sv' will initialize multiple times, this is suspicious. see [#34024] */
+ BLI_assert(v != NULL);
+ BLI_assert(sv_table[BM_elem_index_get(v)] != INDEX_INVALID);
+ sv = SV_FROM_VERT(v);
+ sv->v = v;
+ copy_v3_v3(sv->v_co_orig, v->co);
+ sv->loop_nr = loop_nr;
+
+ if (l_a || l_a_prev) {
+ BMLoop *l_tmp = BM_loop_other_edge_loop(l_a ? l_a : l_a_prev, v);
+ sv->v_side[0] = BM_edge_other_vert(l_tmp->e, v);
+ copy_v3_v3(sv->dir_side[0], vec_a);
+ }
+
+ if (l_b || l_b_prev) {
+ BMLoop *l_tmp = BM_loop_other_edge_loop(l_b ? l_b : l_b_prev, v);
+ sv->v_side[1] = BM_edge_other_vert(l_tmp->e, v);
+ copy_v3_v3(sv->dir_side[1], vec_b);
+ }
+
+ v_prev = v;
+ v = BM_edge_other_vert(e, v);
+
+ e_prev = e;
+ e = get_other_edge(v, e);
+
+ if (!e) {
+ BLI_assert(v != NULL);
+
+ BLI_assert(sv_table[BM_elem_index_get(v)] != INDEX_INVALID);
+ sv = SV_FROM_VERT(v);
+
+ sv->v = v;
+ copy_v3_v3(sv->v_co_orig, v->co);
+ sv->loop_nr = loop_nr;
+
+ if (l_a) {
+ BMLoop *l_tmp = BM_loop_other_edge_loop(l_a, v);
+ sv->v_side[0] = BM_edge_other_vert(l_tmp->e, v);
+ if (EDGESLIDE_VERT_IS_INNER(v, l_tmp->e)) {
+ get_next_loop(v, l_a, e_prev, l_tmp->e, sv->dir_side[0]);
+ }
+ else {
+ sub_v3_v3v3(sv->dir_side[0], sv->v_side[0]->co, v->co);
+ }
+ }
+
+ if (l_b) {
+ BMLoop *l_tmp = BM_loop_other_edge_loop(l_b, v);
+ sv->v_side[1] = BM_edge_other_vert(l_tmp->e, v);
+ if (EDGESLIDE_VERT_IS_INNER(v, l_tmp->e)) {
+ get_next_loop(v, l_b, e_prev, l_tmp->e, sv->dir_side[1]);
+ }
+ else {
+ sub_v3_v3v3(sv->dir_side[1], sv->v_side[1]->co, v->co);
+ }
+ }
+
+ BM_elem_flag_disable(v, BM_ELEM_TAG);
+ BM_elem_flag_disable(v_prev, BM_ELEM_TAG);
+
+ break;
+ }
+ l_a_ok_prev = (l_a != NULL);
+ l_b_ok_prev = (l_b != NULL);
+
+ l_a_prev = l_a;
+ l_b_prev = l_b;
+
+ if (l_a) {
+ l_a = get_next_loop(v, l_a, e_prev, e, vec_a);
+ }
+ else {
+ zero_v3(vec_a);
+ }
+
+ if (l_b) {
+ l_b = get_next_loop(v, l_b, e_prev, e, vec_b);
+ }
+ else {
+ zero_v3(vec_b);
+ }
+
+ if (l_a && l_b) {
+ /* pass */
+ }
+ else {
+ if (l_a || l_b) {
+ /* find the opposite loop if it was missing previously */
+ if (l_a == NULL && l_b && (l_b->radial_next != l_b))
+ l_a = l_b->radial_next;
+ else if (l_b == NULL && l_a && (l_a->radial_next != l_a))
+ l_b = l_a->radial_next;
+ }
+ else if (e->l != NULL) {
+ /* if there are non-contiguous faces, we can still recover
+ * the loops of the new edges faces */
+
+ /* note!, the behavior in this case means edges may move in opposite directions,
+ * this could be made to work more usefully. */
+
+ if (l_a_ok_prev) {
+ l_a = e->l;
+ l_b = (l_a->radial_next != l_a) ? l_a->radial_next : NULL;
+ }
+ else if (l_b_ok_prev) {
+ l_b = e->l;
+ l_a = (l_b->radial_next != l_b) ? l_b->radial_next : NULL;
+ }
+ }
+
+ if (!l_a_ok_prev && l_a) {
+ get_next_loop(v, l_a, e, e_prev, vec_a);
+ }
+ if (!l_b_ok_prev && l_b) {
+ get_next_loop(v, l_b, e, e_prev, vec_b);
+ }
+ }
+
+ BM_elem_flag_disable(v, BM_ELEM_TAG);
+ BM_elem_flag_disable(v_prev, BM_ELEM_TAG);
+ } while ((e != v_first->e) && (l_a || l_b));
#undef SV_FROM_VERT
#undef INDEX_UNSET
#undef INDEX_INVALID
- loop_nr++;
+ loop_nr++;
#undef EDGESLIDE_VERT_IS_INNER
- }
+ }
- /* EDBM_flag_disable_all(em, BM_ELEM_SELECT); */
+ /* EDBM_flag_disable_all(em, BM_ELEM_SELECT); */
- BLI_assert(STACK_SIZE(sv_array) == sv_tot);
+ BLI_assert(STACK_SIZE(sv_array) == sv_tot);
- sld->sv = sv_array;
- sld->totsv = sv_tot;
+ sld->sv = sv_array;
+ sld->totsv = sv_tot;
- /* use for visibility checks */
- if (t->spacetype == SPACE_VIEW3D) {
- v3d = t->sa ? t->sa->spacedata.first : NULL;
- rv3d = t->ar ? t->ar->regiondata : NULL;
- use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE && !XRAY_ENABLED(v3d));
- }
+ /* use for visibility checks */
+ if (t->spacetype == SPACE_VIEW3D) {
+ v3d = t->sa ? t->sa->spacedata.first : NULL;
+ rv3d = t->ar ? t->ar->regiondata : NULL;
+ use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE &&
+ !XRAY_ENABLED(v3d));
+ }
- calcEdgeSlide_mval_range(t, tc, sld, sv_table, loop_nr, mval, use_occlude_geometry, true);
+ calcEdgeSlide_mval_range(t, tc, sld, sv_table, loop_nr, mval, use_occlude_geometry, true);
- /* create copies of faces for customdata projection */
- bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
- slide_origdata_init_data(tc, &sld->orig_data);
- slide_origdata_create_data(tc, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
+ /* create copies of faces for customdata projection */
+ bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
+ slide_origdata_init_data(tc, &sld->orig_data);
+ slide_origdata_create_data(
+ tc, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
- if (rv3d) {
- calcEdgeSlide_even(t, tc, sld, mval);
- }
+ if (rv3d) {
+ calcEdgeSlide_even(t, tc, sld, mval);
+ }
- sld->em = em;
+ sld->em = em;
- tc->custom.mode.data = sld;
+ tc->custom.mode.data = sld;
- MEM_freeN(sv_table);
+ MEM_freeN(sv_table);
- return true;
+ return true;
}
/**
@@ -7211,600 +7369,623 @@ static bool createEdgeSlideVerts_double_side(TransInfo *t, TransDataContainer *t
*/
static bool createEdgeSlideVerts_single_side(TransInfo *t, TransDataContainer *tc)
{
- BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
- BMesh *bm = em->bm;
- BMIter iter;
- BMEdge *e;
- TransDataEdgeSlideVert *sv_array;
- int sv_tot;
- int *sv_table; /* BMVert -> sv_array index */
- EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld");
- float mval[2] = {(float)t->mval[0], (float)t->mval[1]};
- int loop_nr;
- bool use_occlude_geometry = false;
- View3D *v3d = NULL;
- RegionView3D *rv3d = NULL;
-
- if (t->spacetype == SPACE_VIEW3D) {
- /* background mode support */
- v3d = t->sa ? t->sa->spacedata.first : NULL;
- rv3d = t->ar ? t->ar->regiondata : NULL;
- }
-
- slide_origdata_init_flag(t, tc, &sld->orig_data);
-
- sld->curr_sv_index = 0;
- /* ensure valid selection */
- {
- int i = 0, j = 0;
- BMVert *v;
-
- BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
- if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
- float len_sq_max = -1.0f;
- BMIter iter2;
- BM_ITER_ELEM (e, &iter2, v, BM_EDGES_OF_VERT) {
- if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- float len_sq = BM_edge_calc_length_squared(e);
- if (len_sq > len_sq_max) {
- len_sq_max = len_sq;
- v->e = e;
- }
- }
- }
-
- if (len_sq_max != -1.0f) {
- j++;
- }
- }
- BM_elem_index_set(v, i); /* set_inline */
- }
- bm->elem_index_dirty &= ~BM_VERT;
-
- if (!j) {
- MEM_freeN(sld);
- return false;
- }
-
- sv_tot = j;
- }
-
- BLI_assert(sv_tot != 0);
- /* over alloc */
- sv_array = MEM_callocN(sizeof(TransDataEdgeSlideVert) * bm->totvertsel, "sv_array");
-
- /* same loop for all loops, weak but we dont connect loops in this case */
- loop_nr = 1;
-
- sv_table = MEM_mallocN(sizeof(*sv_table) * bm->totvert, __func__);
-
- {
- int i = 0, j = 0;
- BMVert *v;
-
- BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
- sv_table[i] = -1;
- if ((v->e != NULL) && (BM_elem_flag_test(v, BM_ELEM_SELECT))) {
- if (BM_elem_flag_test(v->e, BM_ELEM_SELECT) == 0) {
- TransDataEdgeSlideVert *sv;
- sv = &sv_array[j];
- sv->v = v;
- copy_v3_v3(sv->v_co_orig, v->co);
- sv->v_side[0] = BM_edge_other_vert(v->e, v);
- sub_v3_v3v3(sv->dir_side[0], sv->v_side[0]->co, v->co);
- sv->loop_nr = 0;
- sv_table[i] = j;
- j += 1;
- }
- }
- }
- }
-
- /* check for wire vertices,
- * interpolate the directions of wire verts between non-wire verts */
- if (sv_tot != bm->totvert) {
- const int sv_tot_nowire = sv_tot;
- TransDataEdgeSlideVert *sv_iter = sv_array;
-
- for (int i = 0; i < sv_tot_nowire; i++, sv_iter++) {
- BMIter eiter;
- BM_ITER_ELEM (e, &eiter, sv_iter->v, BM_EDGES_OF_VERT) {
- /* walk over wire */
- TransDataEdgeSlideVert *sv_end = NULL;
- BMEdge *e_step = e;
- BMVert *v = sv_iter->v;
- int j;
-
- j = sv_tot;
-
- while (1) {
- BMVert *v_other = BM_edge_other_vert(e_step, v);
- int endpoint = (
- (sv_table[BM_elem_index_get(v_other)] != -1) +
- (BM_vert_is_edge_pair(v_other) == false));
-
- if ((BM_elem_flag_test(e_step, BM_ELEM_SELECT) &&
- BM_elem_flag_test(v_other, BM_ELEM_SELECT)) &&
- (endpoint == 0))
- {
- /* scan down the list */
- TransDataEdgeSlideVert *sv;
- BLI_assert(sv_table[BM_elem_index_get(v_other)] == -1);
- sv_table[BM_elem_index_get(v_other)] = j;
- sv = &sv_array[j];
- sv->v = v_other;
- copy_v3_v3(sv->v_co_orig, v_other->co);
- copy_v3_v3(sv->dir_side[0], sv_iter->dir_side[0]);
- j++;
-
- /* advance! */
- v = v_other;
- e_step = BM_DISK_EDGE_NEXT(e_step, v_other);
- }
- else {
- if ((endpoint == 2) && (sv_tot != j)) {
- BLI_assert(BM_elem_index_get(v_other) != -1);
- sv_end = &sv_array[sv_table[BM_elem_index_get(v_other)]];
- }
- break;
- }
- }
-
- if (sv_end) {
- int sv_tot_prev = sv_tot;
- const float *co_src = sv_iter->v->co;
- const float *co_dst = sv_end->v->co;
- const float *dir_src = sv_iter->dir_side[0];
- const float *dir_dst = sv_end->dir_side[0];
- sv_tot = j;
-
- while (j-- != sv_tot_prev) {
- float factor;
- factor = line_point_factor_v3(sv_array[j].v->co, co_src, co_dst);
- interp_v3_v3v3(sv_array[j].dir_side[0], dir_src, dir_dst, factor);
- }
- }
- }
- }
- }
-
- /* EDBM_flag_disable_all(em, BM_ELEM_SELECT); */
-
- sld->sv = sv_array;
- sld->totsv = sv_tot;
-
- /* use for visibility checks */
- if (t->spacetype == SPACE_VIEW3D) {
- v3d = t->sa ? t->sa->spacedata.first : NULL;
- rv3d = t->ar ? t->ar->regiondata : NULL;
- use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE && !XRAY_ENABLED(v3d));
- }
-
- calcEdgeSlide_mval_range(t, tc, sld, sv_table, loop_nr, mval, use_occlude_geometry, false);
-
- /* create copies of faces for customdata projection */
- bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
- slide_origdata_init_data(tc, &sld->orig_data);
- slide_origdata_create_data(tc, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
-
- if (rv3d) {
- calcEdgeSlide_even(t, tc, sld, mval);
- }
-
- sld->em = em;
-
- tc->custom.mode.data = sld;
-
- MEM_freeN(sv_table);
-
- return true;
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+ BMesh *bm = em->bm;
+ BMIter iter;
+ BMEdge *e;
+ TransDataEdgeSlideVert *sv_array;
+ int sv_tot;
+ int *sv_table; /* BMVert -> sv_array index */
+ EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld");
+ float mval[2] = {(float)t->mval[0], (float)t->mval[1]};
+ int loop_nr;
+ bool use_occlude_geometry = false;
+ View3D *v3d = NULL;
+ RegionView3D *rv3d = NULL;
+
+ if (t->spacetype == SPACE_VIEW3D) {
+ /* background mode support */
+ v3d = t->sa ? t->sa->spacedata.first : NULL;
+ rv3d = t->ar ? t->ar->regiondata : NULL;
+ }
+
+ slide_origdata_init_flag(t, tc, &sld->orig_data);
+
+ sld->curr_sv_index = 0;
+ /* ensure valid selection */
+ {
+ int i = 0, j = 0;
+ BMVert *v;
+
+ BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ float len_sq_max = -1.0f;
+ BMIter iter2;
+ BM_ITER_ELEM (e, &iter2, v, BM_EDGES_OF_VERT) {
+ if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ float len_sq = BM_edge_calc_length_squared(e);
+ if (len_sq > len_sq_max) {
+ len_sq_max = len_sq;
+ v->e = e;
+ }
+ }
+ }
+
+ if (len_sq_max != -1.0f) {
+ j++;
+ }
+ }
+ BM_elem_index_set(v, i); /* set_inline */
+ }
+ bm->elem_index_dirty &= ~BM_VERT;
+
+ if (!j) {
+ MEM_freeN(sld);
+ return false;
+ }
+
+ sv_tot = j;
+ }
+
+ BLI_assert(sv_tot != 0);
+ /* over alloc */
+ sv_array = MEM_callocN(sizeof(TransDataEdgeSlideVert) * bm->totvertsel, "sv_array");
+
+ /* same loop for all loops, weak but we dont connect loops in this case */
+ loop_nr = 1;
+
+ sv_table = MEM_mallocN(sizeof(*sv_table) * bm->totvert, __func__);
+
+ {
+ int i = 0, j = 0;
+ BMVert *v;
+
+ BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
+ sv_table[i] = -1;
+ if ((v->e != NULL) && (BM_elem_flag_test(v, BM_ELEM_SELECT))) {
+ if (BM_elem_flag_test(v->e, BM_ELEM_SELECT) == 0) {
+ TransDataEdgeSlideVert *sv;
+ sv = &sv_array[j];
+ sv->v = v;
+ copy_v3_v3(sv->v_co_orig, v->co);
+ sv->v_side[0] = BM_edge_other_vert(v->e, v);
+ sub_v3_v3v3(sv->dir_side[0], sv->v_side[0]->co, v->co);
+ sv->loop_nr = 0;
+ sv_table[i] = j;
+ j += 1;
+ }
+ }
+ }
+ }
+
+ /* check for wire vertices,
+ * interpolate the directions of wire verts between non-wire verts */
+ if (sv_tot != bm->totvert) {
+ const int sv_tot_nowire = sv_tot;
+ TransDataEdgeSlideVert *sv_iter = sv_array;
+
+ for (int i = 0; i < sv_tot_nowire; i++, sv_iter++) {
+ BMIter eiter;
+ BM_ITER_ELEM (e, &eiter, sv_iter->v, BM_EDGES_OF_VERT) {
+ /* walk over wire */
+ TransDataEdgeSlideVert *sv_end = NULL;
+ BMEdge *e_step = e;
+ BMVert *v = sv_iter->v;
+ int j;
+
+ j = sv_tot;
+
+ while (1) {
+ BMVert *v_other = BM_edge_other_vert(e_step, v);
+ int endpoint = ((sv_table[BM_elem_index_get(v_other)] != -1) +
+ (BM_vert_is_edge_pair(v_other) == false));
+
+ if ((BM_elem_flag_test(e_step, BM_ELEM_SELECT) &&
+ BM_elem_flag_test(v_other, BM_ELEM_SELECT)) &&
+ (endpoint == 0)) {
+ /* scan down the list */
+ TransDataEdgeSlideVert *sv;
+ BLI_assert(sv_table[BM_elem_index_get(v_other)] == -1);
+ sv_table[BM_elem_index_get(v_other)] = j;
+ sv = &sv_array[j];
+ sv->v = v_other;
+ copy_v3_v3(sv->v_co_orig, v_other->co);
+ copy_v3_v3(sv->dir_side[0], sv_iter->dir_side[0]);
+ j++;
+
+ /* advance! */
+ v = v_other;
+ e_step = BM_DISK_EDGE_NEXT(e_step, v_other);
+ }
+ else {
+ if ((endpoint == 2) && (sv_tot != j)) {
+ BLI_assert(BM_elem_index_get(v_other) != -1);
+ sv_end = &sv_array[sv_table[BM_elem_index_get(v_other)]];
+ }
+ break;
+ }
+ }
+
+ if (sv_end) {
+ int sv_tot_prev = sv_tot;
+ const float *co_src = sv_iter->v->co;
+ const float *co_dst = sv_end->v->co;
+ const float *dir_src = sv_iter->dir_side[0];
+ const float *dir_dst = sv_end->dir_side[0];
+ sv_tot = j;
+
+ while (j-- != sv_tot_prev) {
+ float factor;
+ factor = line_point_factor_v3(sv_array[j].v->co, co_src, co_dst);
+ interp_v3_v3v3(sv_array[j].dir_side[0], dir_src, dir_dst, factor);
+ }
+ }
+ }
+ }
+ }
+
+ /* EDBM_flag_disable_all(em, BM_ELEM_SELECT); */
+
+ sld->sv = sv_array;
+ sld->totsv = sv_tot;
+
+ /* use for visibility checks */
+ if (t->spacetype == SPACE_VIEW3D) {
+ v3d = t->sa ? t->sa->spacedata.first : NULL;
+ rv3d = t->ar ? t->ar->regiondata : NULL;
+ use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE &&
+ !XRAY_ENABLED(v3d));
+ }
+
+ calcEdgeSlide_mval_range(t, tc, sld, sv_table, loop_nr, mval, use_occlude_geometry, false);
+
+ /* create copies of faces for customdata projection */
+ bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
+ slide_origdata_init_data(tc, &sld->orig_data);
+ slide_origdata_create_data(
+ tc, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
+
+ if (rv3d) {
+ calcEdgeSlide_even(t, tc, sld, mval);
+ }
+
+ sld->em = em;
+
+ tc->custom.mode.data = sld;
+
+ MEM_freeN(sv_table);
+
+ return true;
}
void projectEdgeSlideData(TransInfo *t, bool is_final)
{
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- EdgeSlideData *sld = tc->custom.mode.data;
- SlideOrigData *sod = &sld->orig_data;
+ FOREACH_TRANS_DATA_CONTAINER(t, tc)
+ {
+ EdgeSlideData *sld = tc->custom.mode.data;
+ SlideOrigData *sod = &sld->orig_data;
- if (sod->use_origfaces == false) {
- return;
- }
+ if (sod->use_origfaces == false) {
+ return;
+ }
- slide_origdata_interp_data(tc->obedit, sod, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv, is_final);
- }
+ slide_origdata_interp_data(tc->obedit,
+ sod,
+ (TransDataGenericSlideVert *)sld->sv,
+ sizeof(*sld->sv),
+ sld->totsv,
+ is_final);
+ }
}
void freeEdgeSlideTempFaces(EdgeSlideData *sld)
{
- slide_origdata_free_date(&sld->orig_data);
+ slide_origdata_free_date(&sld->orig_data);
}
-void freeEdgeSlideVerts(TransInfo *UNUSED(t), TransDataContainer *UNUSED(tc), TransCustomData *custom_data)
+void freeEdgeSlideVerts(TransInfo *UNUSED(t),
+ TransDataContainer *UNUSED(tc),
+ TransCustomData *custom_data)
{
- EdgeSlideData *sld = custom_data->data;
+ EdgeSlideData *sld = custom_data->data;
- if (!sld)
- return;
+ if (!sld)
+ return;
- freeEdgeSlideTempFaces(sld);
+ freeEdgeSlideTempFaces(sld);
- bmesh_edit_end(sld->em->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
+ bmesh_edit_end(sld->em->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
- MEM_freeN(sld->sv);
- MEM_freeN(sld);
+ MEM_freeN(sld->sv);
+ MEM_freeN(sld);
- custom_data->data = NULL;
+ custom_data->data = NULL;
}
-static void initEdgeSlide_ex(TransInfo *t, bool use_double_side, bool use_even, bool flipped, bool use_clamp)
+static void initEdgeSlide_ex(
+ TransInfo *t, bool use_double_side, bool use_even, bool flipped, bool use_clamp)
{
- EdgeSlideData *sld;
- bool ok = false;
+ EdgeSlideData *sld;
+ bool ok = false;
- t->mode = TFM_EDGE_SLIDE;
- t->transform = applyEdgeSlide;
- t->handleEvent = handleEventEdgeSlide;
+ t->mode = TFM_EDGE_SLIDE;
+ t->transform = applyEdgeSlide;
+ t->handleEvent = handleEventEdgeSlide;
- {
- EdgeSlideParams *slp = MEM_callocN(sizeof(*slp), __func__);
- slp->use_even = use_even;
- slp->flipped = flipped;
- /* happens to be best for single-sided */
- if (use_double_side == false) {
- slp->flipped = !flipped;
- }
- slp->perc = 0.0f;
+ {
+ EdgeSlideParams *slp = MEM_callocN(sizeof(*slp), __func__);
+ slp->use_even = use_even;
+ slp->flipped = flipped;
+ /* happens to be best for single-sided */
+ if (use_double_side == false) {
+ slp->flipped = !flipped;
+ }
+ slp->perc = 0.0f;
- if (!use_clamp) {
- t->flag |= T_ALT_TRANSFORM;
- }
+ if (!use_clamp) {
+ t->flag |= T_ALT_TRANSFORM;
+ }
- t->custom.mode.data = slp;
- t->custom.mode.use_free = true;
- }
+ t->custom.mode.data = slp;
+ t->custom.mode.use_free = true;
+ }
- if (use_double_side) {
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- ok |= createEdgeSlideVerts_double_side(t, tc);
- }
- }
- else {
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- ok |= createEdgeSlideVerts_single_side(t, tc);
- }
- }
+ if (use_double_side) {
+ FOREACH_TRANS_DATA_CONTAINER(t, tc)
+ {
+ ok |= createEdgeSlideVerts_double_side(t, tc);
+ }
+ }
+ else {
+ FOREACH_TRANS_DATA_CONTAINER(t, tc)
+ {
+ ok |= createEdgeSlideVerts_single_side(t, tc);
+ }
+ }
- if (!ok) {
- t->state = TRANS_CANCEL;
- return;
- }
+ if (!ok) {
+ t->state = TRANS_CANCEL;
+ return;
+ }
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- sld = tc->custom.mode.data;
- if (!sld) {
- continue;
- }
- tc->custom.mode.free_cb = freeEdgeSlideVerts;
- }
+ FOREACH_TRANS_DATA_CONTAINER(t, tc)
+ {
+ sld = tc->custom.mode.data;
+ if (!sld) {
+ continue;
+ }
+ tc->custom.mode.free_cb = freeEdgeSlideVerts;
+ }
- /* set custom point first if you want value to be initialized by init */
- calcEdgeSlideCustomPoints(t);
- initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO_FLIP);
+ /* set custom point first if you want value to be initialized by init */
+ calcEdgeSlideCustomPoints(t);
+ initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO_FLIP);
- 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;
+ 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;
+ 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;
+ t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
static void initEdgeSlide(TransInfo *t)
{
- initEdgeSlide_ex(t, true, false, false, true);
+ initEdgeSlide_ex(t, true, false, false, true);
}
static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEvent *event)
{
- if (t->mode == TFM_EDGE_SLIDE) {
- EdgeSlideParams *slp = t->custom.mode.data;
-
- if (slp) {
- switch (event->type) {
- case EKEY:
- if (event->val == KM_PRESS) {
- slp->use_even = !slp->use_even;
- calcEdgeSlideCustomPoints(t);
- return TREDRAW_HARD;
- }
- break;
- case FKEY:
- if (event->val == KM_PRESS) {
- slp->flipped = !slp->flipped;
- calcEdgeSlideCustomPoints(t);
- return TREDRAW_HARD;
- }
- break;
- case CKEY:
- /* use like a modifier key */
- if (event->val == KM_PRESS) {
- t->flag ^= T_ALT_TRANSFORM;
- calcEdgeSlideCustomPoints(t);
- return TREDRAW_HARD;
- }
- break;
- case EVT_MODAL_MAP:
+ if (t->mode == TFM_EDGE_SLIDE) {
+ EdgeSlideParams *slp = t->custom.mode.data;
+
+ if (slp) {
+ switch (event->type) {
+ case EKEY:
+ if (event->val == KM_PRESS) {
+ slp->use_even = !slp->use_even;
+ calcEdgeSlideCustomPoints(t);
+ return TREDRAW_HARD;
+ }
+ break;
+ case FKEY:
+ if (event->val == KM_PRESS) {
+ slp->flipped = !slp->flipped;
+ calcEdgeSlideCustomPoints(t);
+ return TREDRAW_HARD;
+ }
+ break;
+ case CKEY:
+ /* use like a modifier key */
+ if (event->val == KM_PRESS) {
+ t->flag ^= T_ALT_TRANSFORM;
+ calcEdgeSlideCustomPoints(t);
+ return TREDRAW_HARD;
+ }
+ break;
+ case EVT_MODAL_MAP:
#if 0
- switch (event->val) {
- case TFM_MODAL_EDGESLIDE_DOWN:
- sld->curr_sv_index = ((sld->curr_sv_index - 1) + sld->totsv) % sld->totsv;
- return TREDRAW_HARD;
- case TFM_MODAL_EDGESLIDE_UP:
- sld->curr_sv_index = (sld->curr_sv_index + 1) % sld->totsv;
- return TREDRAW_HARD;
- }
+ switch (event->val) {
+ case TFM_MODAL_EDGESLIDE_DOWN:
+ sld->curr_sv_index = ((sld->curr_sv_index - 1) + sld->totsv) % sld->totsv;
+ return TREDRAW_HARD;
+ case TFM_MODAL_EDGESLIDE_UP:
+ sld->curr_sv_index = (sld->curr_sv_index + 1) % sld->totsv;
+ return TREDRAW_HARD;
+ }
#endif
- break;
- case MOUSEMOVE:
- calcEdgeSlideCustomPoints(t);
- break;
- default:
- break;
- }
- }
- }
- return TREDRAW_NOTHING;
+ break;
+ case MOUSEMOVE:
+ calcEdgeSlideCustomPoints(t);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return TREDRAW_NOTHING;
}
static void drawEdgeSlide(TransInfo *t)
{
- if ((t->mode == TFM_EDGE_SLIDE) && TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data) {
- const EdgeSlideParams *slp = t->custom.mode.data;
- EdgeSlideData *sld = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data;
- const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
-
- /* Even mode */
- if ((slp->use_even == true) || (is_clamp == false)) {
- const float line_size = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.5f;
-
- 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);
-
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
-
- if (slp->use_even == true) {
- float co_a[3], co_b[3], co_mark[3];
- TransDataEdgeSlideVert *curr_sv = &sld->sv[sld->curr_sv_index];
- const float fac = (slp->perc + 1.0f) / 2.0f;
- const float ctrl_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 1.5f;
- const float guide_size = ctrl_size - 0.5f;
- const int alpha_shade = -30;
-
- add_v3_v3v3(co_a, curr_sv->v_co_orig, curr_sv->dir_side[0]);
- add_v3_v3v3(co_b, curr_sv->v_co_orig, curr_sv->dir_side[1]);
-
- GPU_line_width(line_size);
- immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
- immBeginAtMost(GPU_PRIM_LINES, 4);
- if (curr_sv->v_side[0]) {
- immVertex3fv(pos, curr_sv->v_side[0]->co);
- immVertex3fv(pos, curr_sv->v_co_orig);
- }
- if (curr_sv->v_side[1]) {
- immVertex3fv(pos, curr_sv->v_side[1]->co);
- immVertex3fv(pos, curr_sv->v_co_orig);
- }
- immEnd();
-
- immUniformThemeColorShadeAlpha(TH_SELECT, -30, alpha_shade);
- GPU_point_size(ctrl_size);
- immBegin(GPU_PRIM_POINTS, 1);
- if (slp->flipped) {
- if (curr_sv->v_side[1]) immVertex3fv(pos, curr_sv->v_side[1]->co);
- }
- else {
- if (curr_sv->v_side[0]) immVertex3fv(pos, curr_sv->v_side[0]->co);
- }
- immEnd();
-
- immUniformThemeColorShadeAlpha(TH_SELECT, 255, alpha_shade);
- GPU_point_size(guide_size);
- immBegin(GPU_PRIM_POINTS, 1);
- interp_line_v3_v3v3v3(co_mark, co_b, curr_sv->v_co_orig, co_a, fac);
- immVertex3fv(pos, co_mark);
- immEnd();
- }
- else {
- if (is_clamp == false) {
- const int side_index = sld->curr_side_unclamp;
- TransDataEdgeSlideVert *sv;
- int i;
- const int alpha_shade = -160;
-
- GPU_line_width(line_size);
- immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
- immBegin(GPU_PRIM_LINES, sld->totsv * 2);
-
- /* TODO(campbell): Loop over all verts */
- sv = sld->sv;
- for (i = 0; i < sld->totsv; i++, sv++) {
- float a[3], b[3];
-
- if (!is_zero_v3(sv->dir_side[side_index])) {
- copy_v3_v3(a, sv->dir_side[side_index]);
- }
- else {
- copy_v3_v3(a, sv->dir_side[!side_index]);
- }
-
- mul_v3_fl(a, 100.0f);
- negate_v3_v3(b, a);
- add_v3_v3(a, sv->v_co_orig);
- add_v3_v3(b, sv->v_co_orig);
-
- immVertex3fv(pos, a);
- immVertex3fv(pos, b);
- }
- immEnd();
- }
- else {
- BLI_assert(0);
- }
- }
-
- immUnbindProgram();
-
- GPU_matrix_pop();
-
- GPU_blend(false);
-
- GPU_depth_test(true);
- }
- }
+ if ((t->mode == TFM_EDGE_SLIDE) && TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data) {
+ const EdgeSlideParams *slp = t->custom.mode.data;
+ EdgeSlideData *sld = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data;
+ const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
+
+ /* Even mode */
+ if ((slp->use_even == true) || (is_clamp == false)) {
+ const float line_size = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.5f;
+
+ 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);
+
+ uint pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ if (slp->use_even == true) {
+ float co_a[3], co_b[3], co_mark[3];
+ TransDataEdgeSlideVert *curr_sv = &sld->sv[sld->curr_sv_index];
+ const float fac = (slp->perc + 1.0f) / 2.0f;
+ const float ctrl_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 1.5f;
+ const float guide_size = ctrl_size - 0.5f;
+ const int alpha_shade = -30;
+
+ add_v3_v3v3(co_a, curr_sv->v_co_orig, curr_sv->dir_side[0]);
+ add_v3_v3v3(co_b, curr_sv->v_co_orig, curr_sv->dir_side[1]);
+
+ GPU_line_width(line_size);
+ immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
+ immBeginAtMost(GPU_PRIM_LINES, 4);
+ if (curr_sv->v_side[0]) {
+ immVertex3fv(pos, curr_sv->v_side[0]->co);
+ immVertex3fv(pos, curr_sv->v_co_orig);
+ }
+ if (curr_sv->v_side[1]) {
+ immVertex3fv(pos, curr_sv->v_side[1]->co);
+ immVertex3fv(pos, curr_sv->v_co_orig);
+ }
+ immEnd();
+
+ immUniformThemeColorShadeAlpha(TH_SELECT, -30, alpha_shade);
+ GPU_point_size(ctrl_size);
+ immBegin(GPU_PRIM_POINTS, 1);
+ if (slp->flipped) {
+ if (curr_sv->v_side[1])
+ immVertex3fv(pos, curr_sv->v_side[1]->co);
+ }
+ else {
+ if (curr_sv->v_side[0])
+ immVertex3fv(pos, curr_sv->v_side[0]->co);
+ }
+ immEnd();
+
+ immUniformThemeColorShadeAlpha(TH_SELECT, 255, alpha_shade);
+ GPU_point_size(guide_size);
+ immBegin(GPU_PRIM_POINTS, 1);
+ interp_line_v3_v3v3v3(co_mark, co_b, curr_sv->v_co_orig, co_a, fac);
+ immVertex3fv(pos, co_mark);
+ immEnd();
+ }
+ else {
+ if (is_clamp == false) {
+ const int side_index = sld->curr_side_unclamp;
+ TransDataEdgeSlideVert *sv;
+ int i;
+ const int alpha_shade = -160;
+
+ GPU_line_width(line_size);
+ immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
+ immBegin(GPU_PRIM_LINES, sld->totsv * 2);
+
+ /* TODO(campbell): Loop over all verts */
+ sv = sld->sv;
+ for (i = 0; i < sld->totsv; i++, sv++) {
+ float a[3], b[3];
+
+ if (!is_zero_v3(sv->dir_side[side_index])) {
+ copy_v3_v3(a, sv->dir_side[side_index]);
+ }
+ else {
+ copy_v3_v3(a, sv->dir_side[!side_index]);
+ }
+
+ mul_v3_fl(a, 100.0f);
+ negate_v3_v3(b, a);
+ add_v3_v3(a, sv->v_co_orig);
+ add_v3_v3(b, sv->v_co_orig);
+
+ immVertex3fv(pos, a);
+ immVertex3fv(pos, b);
+ }
+ immEnd();
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+
+ immUnbindProgram();
+
+ GPU_matrix_pop();
+
+ GPU_blend(false);
+
+ GPU_depth_test(true);
+ }
+ }
}
static void doEdgeSlide(TransInfo *t, float perc)
{
- EdgeSlideParams *slp = t->custom.mode.data;
- EdgeSlideData *sld_active = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data;
-
- slp->perc = perc;
-
- if (slp->use_even == false) {
- const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
- if (is_clamp) {
- const int side_index = (perc < 0.0f);
- const float perc_final = fabsf(perc);
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- EdgeSlideData *sld = tc->custom.mode.data;
- TransDataEdgeSlideVert *sv = sld->sv;
- for (int i = 0; i < sld->totsv; i++, sv++) {
- madd_v3_v3v3fl(sv->v->co, sv->v_co_orig, sv->dir_side[side_index], perc_final);
- }
- sld->curr_side_unclamp = side_index;
- }
- }
- else {
- const float perc_init = fabsf(perc) * ((sld_active->curr_side_unclamp == (perc < 0.0f)) ? 1 : -1);
- const int side_index = sld_active->curr_side_unclamp;
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- EdgeSlideData *sld = tc->custom.mode.data;
- TransDataEdgeSlideVert *sv = sld->sv;
- for (int i = 0; i < sld->totsv; i++, sv++) {
- float dir_flip[3];
- float perc_final = perc_init;
- if (!is_zero_v3(sv->dir_side[side_index])) {
- copy_v3_v3(dir_flip, sv->dir_side[side_index]);
- }
- else {
- copy_v3_v3(dir_flip, sv->dir_side[!side_index]);
- perc_final *= -1;
- }
- madd_v3_v3v3fl(sv->v->co, sv->v_co_orig, dir_flip, perc_final);
- }
- }
- }
- }
- else {
- /**
- * Implementation note, even mode ignores the starting positions and uses only the
- * a/b verts, this could be changed/improved so the distance is still met but the verts are moved along
- * their original path (which may not be straight), however how it works now is OK and matches 2.4x - Campbell
- *
- * \note len_v3v3(curr_sv->dir_side[0], curr_sv->dir_side[1])
- * is the same as the distance between the original vert locations, same goes for the lines below.
- */
- TransDataEdgeSlideVert *curr_sv = &sld_active->sv[sld_active->curr_sv_index];
- const float curr_length_perc = curr_sv->edge_len * (((slp->flipped ? perc : -perc) + 1.0f) / 2.0f);
-
- float co_a[3];
- float co_b[3];
-
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- EdgeSlideData *sld = tc->custom.mode.data;
- TransDataEdgeSlideVert *sv = sld->sv;
- for (int i = 0; i < sld->totsv; i++, sv++) {
- if (sv->edge_len > FLT_EPSILON) {
- const float fac = min_ff(sv->edge_len, curr_length_perc) / sv->edge_len;
-
- add_v3_v3v3(co_a, sv->v_co_orig, sv->dir_side[0]);
- add_v3_v3v3(co_b, sv->v_co_orig, sv->dir_side[1]);
-
- if (slp->flipped) {
- interp_line_v3_v3v3v3(sv->v->co, co_b, sv->v_co_orig, co_a, fac);
- }
- else {
- interp_line_v3_v3v3v3(sv->v->co, co_a, sv->v_co_orig, co_b, fac);
- }
- }
- }
- }
- }
+ EdgeSlideParams *slp = t->custom.mode.data;
+ EdgeSlideData *sld_active = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data;
+
+ slp->perc = perc;
+
+ if (slp->use_even == false) {
+ const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
+ if (is_clamp) {
+ const int side_index = (perc < 0.0f);
+ const float perc_final = fabsf(perc);
+ FOREACH_TRANS_DATA_CONTAINER(t, tc)
+ {
+ EdgeSlideData *sld = tc->custom.mode.data;
+ TransDataEdgeSlideVert *sv = sld->sv;
+ for (int i = 0; i < sld->totsv; i++, sv++) {
+ madd_v3_v3v3fl(sv->v->co, sv->v_co_orig, sv->dir_side[side_index], perc_final);
+ }
+ sld->curr_side_unclamp = side_index;
+ }
+ }
+ else {
+ const float perc_init = fabsf(perc) *
+ ((sld_active->curr_side_unclamp == (perc < 0.0f)) ? 1 : -1);
+ const int side_index = sld_active->curr_side_unclamp;
+ FOREACH_TRANS_DATA_CONTAINER(t, tc)
+ {
+ EdgeSlideData *sld = tc->custom.mode.data;
+ TransDataEdgeSlideVert *sv = sld->sv;
+ for (int i = 0; i < sld->totsv; i++, sv++) {
+ float dir_flip[3];
+ float perc_final = perc_init;
+ if (!is_zero_v3(sv->dir_side[side_index])) {
+ copy_v3_v3(dir_flip, sv->dir_side[side_index]);
+ }
+ else {
+ copy_v3_v3(dir_flip, sv->dir_side[!side_index]);
+ perc_final *= -1;
+ }
+ madd_v3_v3v3fl(sv->v->co, sv->v_co_orig, dir_flip, perc_final);
+ }
+ }
+ }
+ }
+ else {
+ /**
+ * Implementation note, even mode ignores the starting positions and uses only the
+ * a/b verts, this could be changed/improved so the distance is still met but the verts are moved along
+ * their original path (which may not be straight), however how it works now is OK and matches 2.4x - Campbell
+ *
+ * \note len_v3v3(curr_sv->dir_side[0], curr_sv->dir_side[1])
+ * is the same as the distance between the original vert locations, same goes for the lines below.
+ */
+ TransDataEdgeSlideVert *curr_sv = &sld_active->sv[sld_active->curr_sv_index];
+ const float curr_length_perc = curr_sv->edge_len *
+ (((slp->flipped ? perc : -perc) + 1.0f) / 2.0f);
+
+ float co_a[3];
+ float co_b[3];
+
+ FOREACH_TRANS_DATA_CONTAINER(t, tc)
+ {
+ EdgeSlideData *sld = tc->custom.mode.data;
+ TransDataEdgeSlideVert *sv = sld->sv;
+ for (int i = 0; i < sld->totsv; i++, sv++) {
+ if (sv->edge_len > FLT_EPSILON) {
+ const float fac = min_ff(sv->edge_len, curr_length_perc) / sv->edge_len;
+
+ add_v3_v3v3(co_a, sv->v_co_orig, sv->dir_side[0]);
+ add_v3_v3v3(co_b, sv->v_co_orig, sv->dir_side[1]);
+
+ if (slp->flipped) {
+ interp_line_v3_v3v3v3(sv->v->co, co_b, sv->v_co_orig, co_a, fac);
+ }
+ else {
+ interp_line_v3_v3v3v3(sv->v->co, co_a, sv->v_co_orig, co_b, fac);
+ }
+ }
+ }
+ }
+ }
}
static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
{
- char str[UI_MAX_DRAW_STR];
- size_t ofs = 0;
- float final;
- EdgeSlideParams *slp = t->custom.mode.data;
- bool flipped = slp->flipped;
- 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, -1.0f, 1.0f);
- }
-
- applyNumInput(&t->num, &final);
-
- t->values[0] = final;
-
- /* header string */
- ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Edge 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, IFACE_("(E)ven: %s, "), WM_bool_as_string(use_even));
- if (use_even) {
- ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("(F)lipped: %s, "), WM_bool_as_string(flipped));
- }
- ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("Alt or (C)lamp: %s"), WM_bool_as_string(is_clamp));
- /* done with header string */
-
- /* do stuff here */
- doEdgeSlide(t, final);
-
- recalcData(t);
-
- ED_area_status_text(t->sa, str);
+ char str[UI_MAX_DRAW_STR];
+ size_t ofs = 0;
+ float final;
+ EdgeSlideParams *slp = t->custom.mode.data;
+ bool flipped = slp->flipped;
+ 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, -1.0f, 1.0f);
+ }
+
+ applyNumInput(&t->num, &final);
+
+ t->values[0] = final;
+
+ /* header string */
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Edge 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, IFACE_("(E)ven: %s, "), WM_bool_as_string(use_even));
+ if (use_even) {
+ ofs += BLI_snprintf(
+ str + ofs, sizeof(str) - ofs, IFACE_("(F)lipped: %s, "), WM_bool_as_string(flipped));
+ }
+ ofs += BLI_snprintf(
+ str + ofs, sizeof(str) - ofs, IFACE_("Alt or (C)lamp: %s"), WM_bool_as_string(is_clamp));
+ /* done with header string */
+
+ /* do stuff here */
+ doEdgeSlide(t, final);
+
+ recalcData(t);
+
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Vert Slide) */
@@ -7813,35 +7994,35 @@ static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
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];
+ 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];
+ 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];
+ float co_curr_2d[2], co_orig_2d[2];
- int mval_ofs[2], mval_start[2], mval_end[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);
+ 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]);
+ 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);
- }
+ 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);
+ /* 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);
}
/**
@@ -7849,27 +8030,27 @@ static void calcVertSlideCustomPoints(struct TransInfo *t)
*/
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;
+ /* 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;
+ /* 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];
+ 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);
+ 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;
- }
- }
+ 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;
+ }
+ }
}
/**
@@ -7877,530 +8058,547 @@ static void calcVertSlideMouseActiveVert(struct TransInfo *t, const int mval[2])
*/
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)};
+ 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;
+ 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. */
+ /* 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);
+ /* 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 (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;
+ 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]);
+ 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;
- }
- }
+ 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;
- }
- }
- }
+ 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;
-
- slide_origdata_init_flag(t, tc, &sld->orig_data);
-
- 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;
-
- bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
- slide_origdata_init_data(tc, &sld->orig_data);
- slide_origdata_create_data(tc, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
-
- sld->em = em;
-
- 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;
+ 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;
+
+ slide_origdata_init_flag(t, tc, &sld->orig_data);
+
+ 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;
+
+ bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
+ slide_origdata_init_data(tc, &sld->orig_data);
+ slide_origdata_create_data(
+ tc, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
+
+ sld->em = em;
+
+ 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;
}
void projectVertSlideData(TransInfo *t, bool is_final)
{
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- VertSlideData *sld = tc->custom.mode.data;
- SlideOrigData *sod = &sld->orig_data;
- if (sod->use_origfaces == true) {
- slide_origdata_interp_data(tc->obedit, sod, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv, is_final);
- }
- }
+ FOREACH_TRANS_DATA_CONTAINER(t, tc)
+ {
+ VertSlideData *sld = tc->custom.mode.data;
+ SlideOrigData *sod = &sld->orig_data;
+ if (sod->use_origfaces == true) {
+ slide_origdata_interp_data(tc->obedit,
+ sod,
+ (TransDataGenericSlideVert *)sld->sv,
+ sizeof(*sld->sv),
+ sld->totsv,
+ is_final);
+ }
+ }
}
void freeVertSlideTempFaces(VertSlideData *sld)
{
- slide_origdata_free_date(&sld->orig_data);
+ slide_origdata_free_date(&sld->orig_data);
}
-void freeVertSlideVerts(TransInfo *UNUSED(t), TransDataContainer *UNUSED(tc), TransCustomData *custom_data)
+void freeVertSlideVerts(TransInfo *UNUSED(t),
+ TransDataContainer *UNUSED(tc),
+ TransCustomData *custom_data)
{
- VertSlideData *sld = custom_data->data;
+ VertSlideData *sld = custom_data->data;
- if (!sld)
- return;
+ if (!sld)
+ return;
- freeVertSlideTempFaces(sld);
+ freeVertSlideTempFaces(sld);
- bmesh_edit_end(sld->em->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
+ bmesh_edit_end(sld->em->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
- 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);
- }
- }
+ 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);
+ MEM_freeN(sld->sv);
+ MEM_freeN(sld);
- custom_data->data = NULL;
+ custom_data->data = NULL;
}
static void initVertSlide_ex(TransInfo *t, bool use_even, bool flipped, bool use_clamp)
{
- t->mode = TFM_VERT_SLIDE;
- t->transform = applyVertSlide;
- t->handleEvent = handleEventVertSlide;
+ 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;
+ {
+ 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;
- }
+ if (!use_clamp) {
+ t->flag |= T_ALT_TRANSFORM;
+ }
- t->custom.mode.data = slp;
- t->custom.mode.use_free = true;
- }
+ 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;
- }
- }
+ 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;
- }
+ if (ok == false) {
+ t->state = TRANS_CANCEL;
+ return;
+ }
- /* set custom point first if you want value to be initialized by init */
- calcVertSlideCustomPoints(t);
- initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO);
+ /* 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;
+ 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;
+ 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;
+ t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
static void initVertSlide(TransInfo *t)
{
- initVertSlide_ex(t, false, false, true);
+ initVertSlide_ex(t, false, false, true);
}
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 (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;
+ 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;
+ 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;
}
static 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);
+ 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_matrix_push();
- GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat);
+ GPU_blend(true);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_line_width(line_size);
+ GPU_matrix_push();
+ GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat);
- const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ GPU_line_width(line_size);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
+ const uint shdr_pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- 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);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
- immVertex3fv(shdr_pos, a);
- immVertex3fv(shdr_pos, b);
- }
- }
- immEnd();
+ 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);
- GPU_point_size(ctrl_size);
+ immVertex3fv(shdr_pos, a);
+ immVertex3fv(shdr_pos, b);
+ }
+ }
+ immEnd();
- 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();
+ GPU_point_size(ctrl_size);
- immUnbindProgram();
+ 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();
- /* 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];
+ immUnbindProgram();
- mval_ofs[0] = t->mval[0] - t->mouse.imval[0];
- mval_ofs[1] = t->mval[1] - t->mouse.imval[1];
+ /* 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];
- 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);
+ mval_ofs[0] = t->mval[0] - t->mouse.imval[0];
+ mval_ofs[1] = t->mval[1] - t->mouse.imval[1];
- ED_view3d_win_to_delta(t->ar, mval_ofs, co_dest_3d, zfac);
+ 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);
- 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);
+ ED_view3d_win_to_delta(t->ar, mval_ofs, co_dest_3d, zfac);
- add_v3_v3(co_dest_3d, curr_sv->co_orig_3d);
+ 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);
- GPU_line_width(1.0f);
+ add_v3_v3(co_dest_3d, curr_sv->co_orig_3d);
- immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR);
+ GPU_line_width(1.0f);
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
- immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+ immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR);
- 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);
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
- immBegin(GPU_PRIM_LINES, 2);
- immVertex3fv(shdr_pos, curr_sv->co_orig_3d);
- immVertex3fv(shdr_pos, co_dest_3d);
- immEnd();
+ 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();
- }
+ immUnbindProgram();
+ }
- GPU_matrix_pop();
+ GPU_matrix_pop();
- GPU_depth_test(true);
- }
- }
+ GPU_depth_test(true);
+ }
+ }
}
static 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);
- }
- }
- }
- }
+ 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);
+ }
+ }
+ }
+ }
}
static 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[0] = final;
-
- /* header string */
- ofs += BLI_strncpy_rlen(str + ofs, IFACE_("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, IFACE_("(E)ven: %s, "), WM_bool_as_string(use_even));
- if (use_even) {
- ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("(F)lipped: %s, "), WM_bool_as_string(flipped));
- }
- ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("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);
+ 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[0] = final;
+
+ /* header string */
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_("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, IFACE_("(E)ven: %s, "), WM_bool_as_string(use_even));
+ if (use_even) {
+ ofs += BLI_snprintf(
+ str + ofs, sizeof(str) - ofs, IFACE_("(F)lipped: %s, "), WM_bool_as_string(flipped));
+ }
+ ofs += BLI_snprintf(
+ str + ofs, sizeof(str) - ofs, IFACE_("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);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (EditBone Roll) */
@@ -8409,72 +8607,72 @@ static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2]))
static void initBoneRoll(TransInfo *t)
{
- t->mode = TFM_BONE_ROLL;
- t->transform = applyBoneRoll;
+ t->mode = TFM_BONE_ROLL;
+ t->transform = applyBoneRoll;
- initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
+ 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);
+ 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;
+ 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;
+ t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
static void applyBoneRoll(TransInfo *t, const int UNUSED(mval[2]))
{
- int i;
- char str[UI_MAX_DRAW_STR];
+ int i;
+ char str[UI_MAX_DRAW_STR];
- float final;
+ float final;
- final = t->values[0];
+ final = t->values[0];
- snapGridIncrement(t, &final);
+ snapGridIncrement(t, &final);
- applyNumInput(&t->num, &final);
+ applyNumInput(&t->num, &final);
- t->values[0] = final;
+ t->values[0] = final;
- if (hasNumInput(&t->num)) {
- char c[NUM_STR_REP_LEN];
+ if (hasNumInput(&t->num)) {
+ char c[NUM_STR_REP_LEN];
- outputNumInput(&(t->num), c, &t->scene->unit);
+ outputNumInput(&(t->num), c, &t->scene->unit);
- BLI_snprintf(str, sizeof(str), IFACE_("Roll: %s"), &c[0]);
- }
- else {
- BLI_snprintf(str, sizeof(str), IFACE_("Roll: %.2f"), RAD2DEGF(final));
- }
+ BLI_snprintf(str, sizeof(str), IFACE_("Roll: %s"), &c[0]);
+ }
+ else {
+ BLI_snprintf(str, sizeof(str), IFACE_("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;
+ /* 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;
+ if (td->flag & TD_SKIP)
+ continue;
- *(td->val) = td->ival - final;
- }
- }
+ *(td->val) = td->ival - final;
+ }
+ }
- recalcData(t);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Bake-Time) */
@@ -8483,89 +8681,91 @@ static void applyBoneRoll(TransInfo *t, const int UNUSED(mval[2]))
static void initBakeTime(TransInfo *t)
{
- t->transform = applyBakeTime;
- initMouseInputMode(t, &t->mouse, INPUT_NONE);
+ 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;
+ 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? */
+ 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? */
}
static void applyBakeTime(TransInfo *t, const int mval[2])
{
- float time;
- int i;
- char str[UI_MAX_DRAW_STR];
+ float time;
+ int i;
+ char str[UI_MAX_DRAW_STR];
- float fac = 0.1f;
+ float fac = 0.1f;
- /* XXX, disable precision for now,
- * this isn't even accessible by the user */
+ /* 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
+ 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), IFACE_("Time: +%s %s"), c, t->proptext);
- else
- BLI_snprintf(str, sizeof(str), IFACE_("Time: %s %s"), c, t->proptext);
- }
- else {
- /* default header print */
- if (time >= 0.0f)
- BLI_snprintf(str, sizeof(str), IFACE_("Time: +%.3f %s"), time, t->proptext);
- else
- BLI_snprintf(str, sizeof(str), IFACE_("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);
+ {
+ 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), IFACE_("Time: +%s %s"), c, t->proptext);
+ else
+ BLI_snprintf(str, sizeof(str), IFACE_("Time: %s %s"), c, t->proptext);
+ }
+ else {
+ /* default header print */
+ if (time >= 0.0f)
+ BLI_snprintf(str, sizeof(str), IFACE_("Time: +%.3f %s"), time, t->proptext);
+ else
+ BLI_snprintf(str, sizeof(str), IFACE_("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);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Mirror) */
@@ -8574,85 +8774,86 @@ static void applyBakeTime(TransInfo *t, const int mval[2])
static void initMirror(TransInfo *t)
{
- t->transform = applyMirror;
- initMouseInputMode(t, &t->mouse, INPUT_NONE);
+ 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;
- }
+ t->flag |= T_NULL_ONE;
+ if ((t->flag & T_EDIT) == 0) {
+ t->flag |= T_NO_ZERO;
+ }
}
static void applyMirror(TransInfo *t, const int UNUSED(mval[2]))
{
- float size[3], mat[3][3];
- int i;
- char str[UI_MAX_DRAW_STR];
+ float size[3], mat[3][3];
+ int i;
+ char str[UI_MAX_DRAW_STR];
- /*
- * OPTIMIZATION:
- * This still recalcs transformation on mouse move
- * while it should only recalc on constraint change
- * */
+ /*
+ * 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;
+ /* if an axis has been selected */
+ if (t->con.mode & CON_APPLY) {
+ size[0] = size[1] = size[2] = -1;
- size_to_mat3(mat, size);
+ size_to_mat3(mat, size);
- if (t->con.applySize) {
- t->con.applySize(t, NULL, NULL, mat);
- }
+ if (t->con.applySize) {
+ t->con.applySize(t, NULL, NULL, mat);
+ }
- BLI_snprintf(str, sizeof(str), IFACE_("Mirror%s"), t->con.text);
+ BLI_snprintf(str, sizeof(str), IFACE_("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;
+ 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->flag & TD_SKIP)
+ continue;
- ElementResize(t, tc, td, mat);
- }
- }
+ ElementResize(t, tc, td, mat);
+ }
+ }
- recalcData(t);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
- }
- else {
- size[0] = size[1] = size[2] = 1;
+ ED_area_status_text(t->sa, str);
+ }
+ else {
+ size[0] = size[1] = size[2] = 1;
- size_to_mat3(mat, size);
+ 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;
+ 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->flag & TD_SKIP)
+ continue;
- ElementResize(t, tc, td, mat);
- }
- }
+ ElementResize(t, tc, td, mat);
+ }
+ }
- recalcData(t);
+ recalcData(t);
- if (t->flag & T_2D_EDIT)
- ED_area_status_text(t->sa, IFACE_("Select a mirror axis (X, Y)"));
- else
- ED_area_status_text(t->sa, IFACE_("Select a mirror axis (X, Y, Z)"));
- }
+ if (t->flag & T_2D_EDIT)
+ ED_area_status_text(t->sa, IFACE_("Select a mirror axis (X, Y)"));
+ else
+ ED_area_status_text(t->sa, IFACE_("Select a mirror axis (X, Y, Z)"));
+ }
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Align) */
@@ -8661,59 +8862,58 @@ static void applyMirror(TransInfo *t, const int UNUSED(mval[2]))
static void initAlign(TransInfo *t)
{
- t->flag |= T_NO_CONSTRAINT;
+ t->flag |= T_NO_CONSTRAINT;
- t->transform = applyAlign;
+ t->transform = applyAlign;
- initMouseInputMode(t, &t->mouse, INPUT_NONE);
+ initMouseInputMode(t, &t->mouse, INPUT_NONE);
}
static void applyAlign(TransInfo *t, const int UNUSED(mval[2]))
{
- float center[3];
- int i;
+ 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];
- 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_NOACTION)
- break;
+ if (td->flag & TD_SKIP)
+ continue;
- 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);
+ }
+ }
- /* 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);
- invert_m3_m3(invmat, td->axismtx);
+ mul_m3_m3m3(mat, t->spacemtx, invmat);
- mul_m3_m3m3(mat, t->spacemtx, invmat);
+ ElementRotation(t, tc, td, mat, t->around);
+ }
+ /* restoring original center */
+ copy_v3_v3(tc->center_local, center);
+ }
- ElementRotation(t, tc, td, mat, t->around);
- }
- /* restoring original center */
- copy_v3_v3(tc->center_local, center);
- }
+ recalcData(t);
- recalcData(t);
-
- ED_area_status_text(t->sa, IFACE_("Align"));
+ ED_area_status_text(t->sa, IFACE_("Align"));
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Sequencer Slide) */
@@ -8722,98 +8922,101 @@ static void applyAlign(TransInfo *t, const int UNUSED(mval[2]))
static void initSeqSlide(TransInfo *t)
{
- t->transform = applySeqSlide;
+ t->transform = applySeqSlide;
- initMouseInputMode(t, &t->mouse, INPUT_VECTOR);
+ initMouseInputMode(t, &t->mouse, INPUT_VECTOR);
- t->idx_max = 1;
- t->num.flag = 0;
- t->num.idx_max = t->idx_max;
+ 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;
+ 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;
+ 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;
}
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;
+ 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]);
- }
+ 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, IFACE_("Sequence Slide: %s%s, ("), &tvec[0], t->con.text);
+ ofs += BLI_snprintf(
+ str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_("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, IFACE_(" or Alt) Expand to fit %s"),
- WM_bool_as_string((t->flag & T_ALT_TRANSFORM) != 0));
+ 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,
+ IFACE_(" 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;
+ 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;
+ 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->flag & TD_SKIP)
+ continue;
- madd_v2_v2v2fl(td->loc, td->iloc, val, td->factor);
- }
- }
+ 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];
+ char str[UI_MAX_DRAW_STR];
- snapSequenceBounds(t, mval);
+ 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, tvec);
- }
- else {
- // snapGridIncrement(t, t->values);
- applyNumInput(&t->num, t->values);
- }
+ 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, tvec);
+ }
+ else {
+ // snapGridIncrement(t, t->values);
+ applyNumInput(&t->num, t->values);
+ }
- t->values[0] = floorf(t->values[0] + 0.5f);
- t->values[1] = floorf(t->values[1] + 0.5f);
+ t->values[0] = floorf(t->values[0] + 0.5f);
+ t->values[1] = floorf(t->values[1] + 0.5f);
- headerSeqSlide(t, t->values, str);
- applySeqSlideValue(t, t->values);
+ headerSeqSlide(t, t->values, str);
+ applySeqSlideValue(t, t->values);
- recalcData(t);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Animation Editors - Transform Utils
*
@@ -8829,109 +9032,109 @@ static void applySeqSlide(TransInfo *t, const int mval[2])
// XXX these modifier checks should be keymappable
static short getAnimEdit_SnapMode(TransInfo *t)
{
- short autosnap = SACTSNAP_OFF;
+ short autosnap = SACTSNAP_OFF;
- if (t->spacetype == SPACE_ACTION) {
- SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first;
+ if (t->spacetype == SPACE_ACTION) {
+ SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first;
- if (saction)
- autosnap = saction->autosnap;
- }
- else if (t->spacetype == SPACE_GRAPH) {
- SpaceGraph *sipo = (SpaceGraph *)t->sa->spacedata.first;
+ if (saction)
+ autosnap = saction->autosnap;
+ }
+ else if (t->spacetype == SPACE_GRAPH) {
+ SpaceGraph *sipo = (SpaceGraph *)t->sa->spacedata.first;
- if (sipo)
- autosnap = sipo->autosnap;
- }
- else if (t->spacetype == SPACE_NLA) {
- SpaceNla *snla = (SpaceNla *)t->sa->spacedata.first;
+ if (sipo)
+ autosnap = sipo->autosnap;
+ }
+ else if (t->spacetype == SPACE_NLA) {
+ SpaceNla *snla = (SpaceNla *)t->sa->spacedata.first;
- if (snla)
- autosnap = snla->autosnap;
- }
- else {
- autosnap = SACTSNAP_OFF;
- }
+ if (snla)
+ autosnap = snla->autosnap;
+ }
+ else {
+ autosnap = SACTSNAP_OFF;
+ }
- /* toggle autosnap on/off
- * - when toggling on, prefer nearest frame over 1.0 frame increments
- */
- if (t->modifiers & MOD_SNAP_INVERT) {
- if (autosnap)
- autosnap = SACTSNAP_OFF;
- else
- autosnap = SACTSNAP_FRAME;
- }
+ /* toggle autosnap on/off
+ * - when toggling on, prefer nearest frame over 1.0 frame increments
+ */
+ if (t->modifiers & MOD_SNAP_INVERT) {
+ if (autosnap)
+ autosnap = SACTSNAP_OFF;
+ else
+ autosnap = SACTSNAP_FRAME;
+ }
- return autosnap;
+ return autosnap;
}
/* This function is used by Animation Editor specific transform functions to do
* the Snap Keyframe to Nearest Frame/Marker
*/
-static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, TransData2D *td2d, AnimData *adt, short autosnap)
-{
- /* snap key to nearest frame or second? */
- if (ELEM(autosnap, SACTSNAP_FRAME, SACTSNAP_SECOND)) {
- const Scene *scene = t->scene;
- const double secf = FPS;
- double val;
-
- /* convert frame to nla-action time (if needed) */
- if (adt)
- val = BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_MAP);
- else
- val = *(td->val);
-
- /* do the snapping to nearest frame/second */
- if (autosnap == SACTSNAP_FRAME) {
- val = floorf(val + 0.5);
- }
- else if (autosnap == SACTSNAP_SECOND) {
- val = (float)(floor((val / secf) + 0.5) * secf);
- }
-
- /* convert frame out of nla-action time */
- if (adt)
- *(td->val) = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP);
- else
- *(td->val) = val;
- }
- /* snap key to nearest marker? */
- else if (autosnap == SACTSNAP_MARKER) {
- float val;
-
- /* convert frame to nla-action time (if needed) */
- if (adt)
- val = BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_MAP);
- else
- val = *(td->val);
-
- /* snap to nearest marker */
- // TODO: need some more careful checks for where data comes from
- val = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, val);
-
- /* convert frame out of nla-action time */
- if (adt)
- *(td->val) = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP);
- else
- *(td->val) = val;
- }
-
- /* if the handles are to be moved too (as side-effect of keyframes moving, to keep the general effect)
- * offset them by the same amount so that the general angles are maintained (i.e. won't change while
- * handles are free-to-roam and keyframes are snap-locked)
- */
- if ((td->flag & TD_MOVEHANDLE1) && td2d->h1) {
- td2d->h1[0] = td2d->ih1[0] + *td->val - td->ival;
- }
- if ((td->flag & TD_MOVEHANDLE2) && td2d->h2) {
- td2d->h2[0] = td2d->ih2[0] + *td->val - td->ival;
- }
+static void doAnimEdit_SnapFrame(
+ TransInfo *t, TransData *td, TransData2D *td2d, AnimData *adt, short autosnap)
+{
+ /* snap key to nearest frame or second? */
+ if (ELEM(autosnap, SACTSNAP_FRAME, SACTSNAP_SECOND)) {
+ const Scene *scene = t->scene;
+ const double secf = FPS;
+ double val;
+
+ /* convert frame to nla-action time (if needed) */
+ if (adt)
+ val = BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_MAP);
+ else
+ val = *(td->val);
+
+ /* do the snapping to nearest frame/second */
+ if (autosnap == SACTSNAP_FRAME) {
+ val = floorf(val + 0.5);
+ }
+ else if (autosnap == SACTSNAP_SECOND) {
+ val = (float)(floor((val / secf) + 0.5) * secf);
+ }
+
+ /* convert frame out of nla-action time */
+ if (adt)
+ *(td->val) = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP);
+ else
+ *(td->val) = val;
+ }
+ /* snap key to nearest marker? */
+ else if (autosnap == SACTSNAP_MARKER) {
+ float val;
+
+ /* convert frame to nla-action time (if needed) */
+ if (adt)
+ val = BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_MAP);
+ else
+ val = *(td->val);
+
+ /* snap to nearest marker */
+ // TODO: need some more careful checks for where data comes from
+ val = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, val);
+
+ /* convert frame out of nla-action time */
+ if (adt)
+ *(td->val) = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP);
+ else
+ *(td->val) = val;
+ }
+
+ /* if the handles are to be moved too (as side-effect of keyframes moving, to keep the general effect)
+ * offset them by the same amount so that the general angles are maintained (i.e. won't change while
+ * handles are free-to-roam and keyframes are snap-locked)
+ */
+ if ((td->flag & TD_MOVEHANDLE1) && td2d->h1) {
+ td2d->h1[0] = td2d->ih1[0] + *td->val - td->ival;
+ }
+ if ((td->flag & TD_MOVEHANDLE2) && td2d->h2) {
+ td2d->h2[0] = td2d->ih2[0] + *td->val - td->ival;
+ }
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Animation Translation) */
@@ -8940,164 +9143,165 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, TransData2D *td2d,
static 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;
- }
+ /* 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;
+ t->mode = TFM_TIME_TRANSLATE;
+ t->transform = applyTimeTranslate;
- initMouseInputMode(t, &t->mouse, INPUT_NONE);
+ 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;
+ /* 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;
+ /* 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;
+ 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;
}
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 Scene *scene = t->scene;
- const short autosnap = getAnimEdit_SnapMode(t);
- const double secf = FPS;
- float val = t->values[0];
-
- /* apply snapping + frame->seconds conversions */
- if (autosnap == SACTSNAP_STEP) {
- /* frame step */
- val = floorf(val + 0.5f);
- }
- else if (autosnap == SACTSNAP_TSTEP) {
- /* second step */
- val = floorf((double)val / secf + 0.5);
- }
- else if (autosnap == SACTSNAP_SECOND) {
- /* nearest second */
- val = (float)((double)val / secf);
- }
-
- if (autosnap == SACTSNAP_FRAME)
- BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%d.00 (%.4f)", (int)val, val);
- else if (autosnap == SACTSNAP_SECOND)
- BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%d.00 sec (%.4f)", (int)val, val);
- else if (autosnap == SACTSNAP_TSTEP)
- BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f sec", val);
- else
- BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", val);
- }
-
- ofs += BLI_snprintf(str, UI_MAX_DRAW_STR, IFACE_("DeltaX: %s"), &tvec[0]);
-
- if (t->flag & T_PROP_EDIT_ALL) {
- ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
- }
+ 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 Scene *scene = t->scene;
+ const short autosnap = getAnimEdit_SnapMode(t);
+ const double secf = FPS;
+ float val = t->values[0];
+
+ /* apply snapping + frame->seconds conversions */
+ if (autosnap == SACTSNAP_STEP) {
+ /* frame step */
+ val = floorf(val + 0.5f);
+ }
+ else if (autosnap == SACTSNAP_TSTEP) {
+ /* second step */
+ val = floorf((double)val / secf + 0.5);
+ }
+ else if (autosnap == SACTSNAP_SECOND) {
+ /* nearest second */
+ val = (float)((double)val / secf);
+ }
+
+ if (autosnap == SACTSNAP_FRAME)
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%d.00 (%.4f)", (int)val, val);
+ else if (autosnap == SACTSNAP_SECOND)
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%d.00 sec (%.4f)", (int)val, val);
+ else if (autosnap == SACTSNAP_TSTEP)
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f sec", val);
+ else
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", val);
+ }
+
+ ofs += BLI_snprintf(str, UI_MAX_DRAW_STR, IFACE_("DeltaX: %s"), &tvec[0]);
+
+ if (t->flag & T_PROP_EDIT_ALL) {
+ ofs += BLI_snprintf(
+ str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
+ }
}
static void applyTimeTranslateValue(TransInfo *t)
{
- 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)
- */
- 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 = t->values[0];
-
- 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[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;
- }
-
- /* apply nearest snapping */
- doAnimEdit_SnapFrame(t, td, td2d, adt, autosnap);
- }
- }
+ 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)
+ */
+ 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 = t->values[0];
+
+ 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[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;
+ }
+
+ /* 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];
+ 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]);
+ /* 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];
- }
+ /* 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[0] = t->vec[0];
- headerTimeTranslate(t, str);
+ /* handle numeric-input stuff */
+ t->vec[0] = t->values[0];
+ applyNumInput(&t->num, &t->vec[0]);
+ t->values[0] = t->vec[0];
+ headerTimeTranslate(t, str);
- applyTimeTranslateValue(t);
+ applyTimeTranslateValue(t);
- recalcData(t);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Animation Time Slide) */
@@ -9106,188 +9310,190 @@ static void applyTimeTranslate(TransInfo *t, const int mval[2])
static 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;
+ /* 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;
}
static void headerTimeSlide(TransInfo *t, const float sval, char str[UI_MAX_DRAW_STR])
{
- char tvec[NUM_STR_REP_LEN * 3];
+ 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[0];
- float val;
+ 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[0];
+ float val;
- val = 2.0f * (cval - sval) / (maxx - minx);
- CLAMP(val, -1.0f, 1.0f);
+ 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(&tvec[0], NUM_STR_REP_LEN, "%.4f", val);
+ }
- BLI_snprintf(str, UI_MAX_DRAW_STR, IFACE_("TimeSlide: %s"), &tvec[0]);
+ BLI_snprintf(str, UI_MAX_DRAW_STR, IFACE_("TimeSlide: %s"), &tvec[0]);
}
static void applyTimeSlideValue(TransInfo *t, float sval)
{
- 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;
- float cvalf = t->values[0];
-
- saction->timeslide = cvalf;
- }
-
- /* 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;
- float cval = t->values[0];
-
- /* 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);
- }
- }
- }
- }
+ 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;
+ float cvalf = t->values[0];
+
+ saction->timeslide = cvalf;
+ }
+
+ /* 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;
+ float cval = t->values[0];
+
+ /* 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];
+ 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]);
+ /* 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[0] stores cval[0], which is the current mouse-pointer location (in frames) */
- // XXX Need to be able to repeat this
- /* t->values[0] = cval[0]; */ /* UNUSED (reset again later). */
+ /* t->values[0] stores cval[0], which is the current mouse-pointer location (in frames) */
+ // XXX Need to be able to repeat this
+ /* t->values[0] = cval[0]; */ /* 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[0] = (maxx - minx) * t->vec[0] / 2.0f + sval[0];
+ /* handle numeric-input stuff */
+ t->vec[0] = 2.0f * (cval[0] - sval[0]) / (maxx - minx);
+ applyNumInput(&t->num, &t->vec[0]);
+ t->values[0] = (maxx - minx) * t->vec[0] / 2.0f + sval[0];
- headerTimeSlide(t, sval[0], str);
- applyTimeSlideValue(t, sval[0]);
+ headerTimeSlide(t, sval[0], str);
+ applyTimeSlideValue(t, sval[0]);
- recalcData(t);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Transform (Animation Time Scale) */
@@ -9296,134 +9502,133 @@ static void applyTimeSlide(TransInfo *t, const int mval[2])
static void initTimeScale(TransInfo *t)
{
- float center[2];
+ 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;
- }
+ /* 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;
+ 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];
- }
+ /* 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);
+ /* force a reinit with the center2d used here */
+ initMouseInput(t, &t->mouse, center, t->mouse.imval, false);
- initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
+ initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
- t->flag |= T_NULL_ONE;
- t->num.val_flag[0] |= NUM_NULL_ONE;
+ 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;
+ /* 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;
+ /* 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;
+ 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;
}
static void headerTimeScale(TransInfo *t, char str[UI_MAX_DRAW_STR])
{
- char tvec[NUM_STR_REP_LEN * 3];
+ 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[0]);
+ if (hasNumInput(&t->num))
+ outputNumInput(&(t->num), tvec, &t->scene->unit);
+ else
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", t->values[0]);
- BLI_snprintf(str, UI_MAX_DRAW_STR, IFACE_("ScaleX: %s"), &tvec[0]);
+ BLI_snprintf(str, UI_MAX_DRAW_STR, IFACE_("ScaleX: %s"), &tvec[0]);
}
static void applyTimeScaleValue(TransInfo *t)
{
- Scene *scene = t->scene;
- int i;
+ Scene *scene = t->scene;
+ int i;
- const short autosnap = getAnimEdit_SnapMode(t);
- const double secf = FPS;
+ 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 = t->values[0];
+ 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 = t->values[0];
- if (autosnap == SACTSNAP_TSTEP) {
- fac = (float)(floor((double)fac / secf + 0.5) * secf);
- }
- else if (autosnap == SACTSNAP_STEP) {
- fac = floorf(fac + 0.5f);
- }
+ 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;
+ /* 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);
+ /* 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;
+ /* now, calculate the new value */
+ *(td->val) = ((td->ival - startx) * fac) + startx;
- /* apply nearest snapping */
- doAnimEdit_SnapFrame(t, td, td2d, adt, autosnap);
- }
- }
+ /* 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];
+ char str[UI_MAX_DRAW_STR];
- /* handle numeric-input stuff */
- t->vec[0] = t->values[0];
- applyNumInput(&t->num, &t->vec[0]);
- t->values[0] = t->vec[0];
- headerTimeScale(t, str);
+ /* handle numeric-input stuff */
+ t->vec[0] = t->values[0];
+ applyNumInput(&t->num, &t->vec[0]);
+ t->values[0] = t->vec[0];
+ headerTimeScale(t, str);
- applyTimeScaleValue(t);
+ applyTimeScaleValue(t);
- recalcData(t);
+ recalcData(t);
- ED_area_status_text(t->sa, str);
+ ED_area_status_text(t->sa, str);
}
/** \} */
-
/* TODO, move to: transform_query.c */
bool checkUseAxisMatrix(TransInfo *t)
{
- /* currently only checks for editmode */
- if (t->flag & T_EDIT) {
- if ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
- (ELEM(t->obedit_type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE)))
- {
- /* not all editmode supports axis-matrix */
- return true;
- }
- }
-
- return false;
+ /* currently only checks for editmode */
+ if (t->flag & T_EDIT) {
+ if ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
+ (ELEM(t->obedit_type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE))) {
+ /* not all editmode supports axis-matrix */
+ return true;
+ }
+ }
+
+ return false;
}