Blender  V3.3
transform_mode_shear.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include <stdlib.h>
9 
10 #include "DNA_gpencil_types.h"
11 
12 #include "BLI_math.h"
13 #include "BLI_string.h"
14 #include "BLI_task.h"
15 
16 #include "BKE_context.h"
17 #include "BKE_unit.h"
18 
19 #include "ED_screen.h"
20 
21 #include "WM_types.h"
22 
23 #include "UI_interface.h"
24 
25 #include "BLT_translation.h"
26 
27 #include "transform.h"
28 #include "transform_convert.h"
29 #include "transform_snap.h"
30 
31 #include "transform_mode.h"
32 
33 /* -------------------------------------------------------------------- */
41  const TransInfo *t;
43  float mat_final[3][3];
45 };
46 
47 static void transdata_elem_shear(const TransInfo *t,
48  const TransDataContainer *tc,
49  TransData *td,
50  const float mat_final[3][3],
51  const bool is_local_center)
52 {
53  float tmat[3][3];
54  const float *center;
55  if (t->flag & T_EDIT) {
56  mul_m3_series(tmat, td->smtx, mat_final, td->mtx);
57  }
58  else {
59  copy_m3_m3(tmat, mat_final);
60  }
61 
62  if (is_local_center) {
63  center = td->center;
64  }
65  else {
66  center = tc->center_local;
67  }
68 
69  float vec[3];
70  sub_v3_v3v3(vec, td->iloc, center);
71  mul_m3_v3(tmat, vec);
72  add_v3_v3(vec, center);
73  sub_v3_v3(vec, td->iloc);
74 
75  if (t->options & CTX_GPENCIL_STROKES) {
76  /* Grease pencil multi-frame falloff. */
77  bGPDstroke *gps = (bGPDstroke *)td->extra;
78  if (gps != NULL) {
80  }
81  else {
82  mul_v3_fl(vec, td->factor);
83  }
84  }
85  else {
86  mul_v3_fl(vec, td->factor);
87  }
88 
89  add_v3_v3v3(td->loc, td->iloc, vec);
90 }
91 
92 static void transdata_elem_shear_fn(void *__restrict iter_data_v,
93  const int iter,
94  const TaskParallelTLS *__restrict UNUSED(tls))
95 {
96  struct TransDataArgs_Shear *data = iter_data_v;
97  TransData *td = &data->tc->data[iter];
98  if (td->flag & TD_SKIP) {
99  return;
100  }
101  transdata_elem_shear(data->t, data->tc, td, data->mat_final, data->is_local_center);
102 }
103 
106 /* -------------------------------------------------------------------- */
111 {
112  float dir[3];
113  bool dir_flip = false;
114  copy_v3_v3(dir, t->spacemtx[t->orient_axis_ortho]);
115 
116  /* Needed for axis aligned view gizmo. */
117  if (t->orient[t->orient_curr].type == V3D_ORIENT_VIEW) {
118  if (t->orient_axis_ortho == 0) {
119  if (t->center2d[1] > t->mouse.imval[1]) {
120  dir_flip = !dir_flip;
121  }
122  }
123  else if (t->orient_axis_ortho == 1) {
124  if (t->center2d[0] > t->mouse.imval[0]) {
125  dir_flip = !dir_flip;
126  }
127  }
128  }
129 
130  /* Without this, half the gizmo handles move in the opposite direction. */
131  if ((t->orient_axis_ortho + 1) % 3 != t->orient_axis) {
132  dir_flip = !dir_flip;
133  }
134 
135  if (dir_flip) {
136  negate_v3(dir);
137  }
138 
139  mul_mat3_m4_v3(t->viewmat, dir);
140  if (normalize_v2(dir) == 0.0f) {
141  dir[0] = 1.0f;
142  }
143  setCustomPointsFromDirection(t, &t->mouse, dir);
144 
146 }
147 
149 {
150  eRedrawFlag status = TREDRAW_NOTHING;
151 
152  if (event->type == MIDDLEMOUSE && event->val == KM_PRESS) {
153  /* Use custom.mode.data pointer to signal Shear direction */
154  do {
155  t->orient_axis_ortho = (t->orient_axis_ortho + 1) % 3;
156  } while (t->orient_axis_ortho == t->orient_axis);
157 
159 
160  status = TREDRAW_HARD;
161  }
162  else if (event->type == EVT_XKEY && event->val == KM_PRESS) {
163  t->orient_axis_ortho = (t->orient_axis + 1) % 3;
165 
166  status = TREDRAW_HARD;
167  }
168  else if (event->type == EVT_YKEY && event->val == KM_PRESS) {
169  t->orient_axis_ortho = (t->orient_axis + 2) % 3;
171 
172  status = TREDRAW_HARD;
173  }
174 
175  return status;
176 }
177 
178 static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
179 {
180  float smat[3][3], axismat[3][3], axismat_inv[3][3], mat_final[3][3];
181  float value;
182  int i;
183  char str[UI_MAX_DRAW_STR];
184  const bool is_local_center = transdata_check_local_center(t, t->around);
185 
186  value = t->values[0] + t->values_modal_offset[0];
187 
188  transform_snap_increment(t, &value);
189 
190  applyNumInput(&t->num, &value);
191 
192  t->values_final[0] = value;
193 
194  /* header print for NumInput */
195  if (hasNumInput(&t->num)) {
196  char c[NUM_STR_REP_LEN];
197 
198  outputNumInput(&(t->num), c, &t->scene->unit);
199 
200  BLI_snprintf(str, sizeof(str), TIP_("Shear: %s %s"), c, t->proptext);
201  }
202  else {
203  /* default header print */
205  sizeof(str),
206  TIP_("Shear: %.3f %s (Press X or Y to set shear axis)"),
207  value,
208  t->proptext);
209  }
210 
211  unit_m3(smat);
212  smat[1][0] = value;
213 
214  copy_v3_v3(axismat_inv[0], t->spacemtx[t->orient_axis_ortho]);
215  copy_v3_v3(axismat_inv[2], t->spacemtx[t->orient_axis]);
216  cross_v3_v3v3(axismat_inv[1], axismat_inv[0], axismat_inv[2]);
217  invert_m3_m3(axismat, axismat_inv);
218 
219  mul_m3_series(mat_final, axismat_inv, smat, axismat);
220 
223  TransData *td = tc->data;
224  for (i = 0; i < tc->data_len; i++, td++) {
225  if (td->flag & TD_SKIP) {
226  continue;
227  }
229  }
230  }
231  else {
232  struct TransDataArgs_Shear data = {
233  .t = t,
234  .tc = tc,
235  .is_local_center = is_local_center,
236  };
237  copy_m3_m3(data.mat_final, mat_final);
238 
239  TaskParallelSettings settings;
242  }
243  }
244 
245  recalcData(t);
246 
247  ED_area_status_text(t->area, str);
248 }
249 
251 {
252  t->mode = TFM_SHEAR;
253  t->transform = applyShear;
254  t->handleEvent = handleEventShear;
255 
256  if (t->orient_axis == t->orient_axis_ortho) {
257  t->orient_axis = 2;
258  t->orient_axis_ortho = 1;
259  }
260 
262 
263  t->idx_max = 0;
264  t->num.idx_max = 0;
265  t->snap[0] = 0.1f;
266  t->snap[1] = t->snap[0] * 0.1f;
267 
268  copy_v3_fl(t->num.val_inc, t->snap[0]);
269  t->num.unit_sys = t->scene->unit.system;
270  t->num.unit_type[0] = B_UNIT_NONE; /* Don't think we have any unit here? */
271 
272  t->flag |= T_NO_CONSTRAINT;
273 
275 }
276 
@ B_UNIT_NONE
Definition: BKE_unit.h:100
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:926
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:71
void unit_m3(float m[3][3])
Definition: math_matrix.c:40
void mul_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:790
bool invert_m3_m3(float R[3][3], const float A[3][3])
Definition: math_matrix.c:1180
#define mul_m3_series(...)
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void negate_v3(float r[3])
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE float normalize_v2(float r[2])
MINLINE void add_v3_v3(float r[3], const float a[3])
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:94
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition: BLI_task.h:293
#define UNUSED(x)
#define TIP_(msgid)
@ V3D_ORIENT_VIEW
void outputNumInput(NumInput *n, char *str, struct UnitSettings *unit_settings)
Definition: numinput.c:87
#define NUM_STR_REP_LEN
Definition: ED_numinput.h:13
bool applyNumInput(NumInput *n, float *vec)
Definition: numinput.c:189
bool hasNumInput(const NumInput *n)
Definition: numinput.c:170
void ED_area_status_text(ScrArea *area, const char *str)
Definition: area.c:792
@ TFM_SHEAR
Definition: ED_transform.h:35
NSNotificationCenter * center
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
#define UI_MAX_DRAW_STR
Definition: UI_interface.h:91
@ KM_PRESS
Definition: WM_types.h:267
#define str(s)
static unsigned c
Definition: RandGen.cpp:83
void setCustomPointsFromDirection(TransInfo *t, MouseInput *mi, const float dir[2])
void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
#define FOREACH_TRANS_DATA_CONTAINER(t, th)
const TransDataContainer * tc
float smtx[3][3]
float mtx[3][3]
bGPDstroke_Runtime runtime
short val
Definition: WM_types.h:680
short type
Definition: WM_types.h:678
void recalcData(TransInfo *t)
conversion and adaptation of different datablocks to a common struct.
@ TD_SKIP
#define TRANSDATA_THREAD_LIMIT
bool transdata_check_local_center(const TransInfo *t, short around)
void transform_mode_default_modal_orientation_set(TransInfo *t, int type)
transform modes used by different operators.
static void transdata_elem_shear_fn(void *__restrict iter_data_v, const int iter, const TaskParallelTLS *__restrict UNUSED(tls))
void initShear(TransInfo *t)
static eRedrawFlag handleEventShear(TransInfo *t, const wmEvent *event)
static void initShear_mouseInputMode(TransInfo *t)
static void transdata_elem_shear(const TransInfo *t, const TransDataContainer *tc, TransData *td, const float mat_final[3][3], const bool is_local_center)
static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
bool transform_snap_increment(const TransInfo *t, float *r_val)
@ EVT_YKEY
@ EVT_XKEY
@ MIDDLEMOUSE