Blender  V3.3
transform.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 "MEM_guardedalloc.h"
11 
12 #include "DNA_gpencil_types.h"
13 #include "DNA_mask_types.h"
14 #include "DNA_mesh_types.h"
15 #include "DNA_screen_types.h"
16 
17 #include "BLI_math.h"
18 #include "BLI_rect.h"
19 
20 #include "BKE_context.h"
21 #include "BKE_editmesh.h"
22 #include "BKE_mask.h"
23 #include "BKE_scene.h"
24 
25 #include "GPU_state.h"
26 
27 #include "ED_clip.h"
28 #include "ED_gpencil.h"
29 #include "ED_image.h"
30 #include "ED_keyframing.h"
31 #include "ED_node.h"
32 #include "ED_screen.h"
33 #include "ED_space_api.h"
34 
35 #include "SEQ_transform.h"
36 
37 #include "WM_api.h"
38 #include "WM_message.h"
39 #include "WM_types.h"
40 
41 #include "UI_interface_icons.h"
42 #include "UI_resources.h"
43 #include "UI_view2d.h"
44 
45 #include "RNA_access.h"
46 
47 #include "BLF_api.h"
48 #include "BLT_translation.h"
49 
50 #include "transform.h"
51 #include "transform_constraints.h"
52 #include "transform_convert.h"
53 #include "transform_draw_cursors.h"
54 #include "transform_mode.h"
55 #include "transform_orientations.h"
56 #include "transform_snap.h"
57 
58 /* Disabling, since when you type you know what you are doing,
59  * and being able to set it to zero is handy. */
60 /* #define USE_NUM_NO_ZERO */
61 
62 static void initSnapSpatial(TransInfo *t, float r_snap[2]);
63 
65 {
66  if (t->options & (CTX_CURSOR | CTX_TEXTURE_SPACE)) {
67  return false;
68  }
69  return ((around == V3D_AROUND_LOCAL_ORIGINS) && (ELEM(t->obedit_type, OB_MESH, OB_GPENCIL)));
70 }
71 
72 /* ************************** SPACE DEPENDENT CODE **************************** */
73 
75 {
76  if (!(t->options & CTX_PAINT_CURVE) && (t->spacetype == SPACE_VIEW3D) && t->region &&
77  (t->region->regiontype == RGN_TYPE_WINDOW)) {
78  RegionView3D *rv3d = t->region->regiondata;
79 
80  copy_m4_m4(t->viewmat, rv3d->viewmat);
81  copy_m4_m4(t->viewinv, rv3d->viewinv);
82  copy_m4_m4(t->persmat, rv3d->persmat);
83  copy_m4_m4(t->persinv, rv3d->persinv);
84  t->persp = rv3d->persp;
85  }
86  else {
87  unit_m4(t->viewmat);
88  unit_m4(t->viewinv);
89  unit_m4(t->persmat);
90  unit_m4(t->persinv);
91  t->persp = RV3D_ORTHO;
92  }
93 
95  calculateCenterLocal(t, t->center_global);
96 }
97 
98 void setTransformViewAspect(TransInfo *t, float r_aspect[3])
99 {
100  copy_v3_fl(r_aspect, 1.0f);
101 
102  if (t->spacetype == SPACE_IMAGE) {
103  SpaceImage *sima = t->area->spacedata.first;
104 
105  if (t->options & CTX_MASK) {
106  ED_space_image_get_aspect(sima, &r_aspect[0], &r_aspect[1]);
107  }
108  else if (t->options & CTX_PAINT_CURVE) {
109  /* pass */
110  }
111  else {
112  ED_space_image_get_uv_aspect(sima, &r_aspect[0], &r_aspect[1]);
113  }
114  }
115  else if (t->spacetype == SPACE_SEQ) {
116  if (t->options & CTX_CURSOR) {
117  SEQ_image_preview_unit_to_px(t->scene, r_aspect, r_aspect);
118  }
119  }
120  else if (t->spacetype == SPACE_CLIP) {
121  SpaceClip *sclip = t->area->spacedata.first;
122 
123  if (t->options & CTX_MOVIECLIP) {
124  ED_space_clip_get_aspect_dimension_aware(sclip, &r_aspect[0], &r_aspect[1]);
125  }
126  else {
127  ED_space_clip_get_aspect(sclip, &r_aspect[0], &r_aspect[1]);
128  }
129  }
130  else if (t->spacetype == SPACE_GRAPH) {
131  /* Depends on context of usage. */
132  }
133 }
134 
135 static void convertViewVec2D(View2D *v2d, float r_vec[3], int dx, int dy)
136 {
137  float divx = BLI_rcti_size_x(&v2d->mask);
138  float divy = BLI_rcti_size_y(&v2d->mask);
139 
140  r_vec[0] = BLI_rctf_size_x(&v2d->cur) * dx / divx;
141  r_vec[1] = BLI_rctf_size_y(&v2d->cur) * dy / divy;
142  r_vec[2] = 0.0f;
143 }
144 
145 static void convertViewVec2D_mask(View2D *v2d, float r_vec[3], int dx, int dy)
146 {
147  float divx = BLI_rcti_size_x(&v2d->mask);
148  float divy = BLI_rcti_size_y(&v2d->mask);
149 
150  float mulx = BLI_rctf_size_x(&v2d->cur);
151  float muly = BLI_rctf_size_y(&v2d->cur);
152 
153  /* difference with convertViewVec2D */
154  /* clamp w/h, mask only */
155  if (mulx / divx < muly / divy) {
156  divy = divx;
157  muly = mulx;
158  }
159  else {
160  divx = divy;
161  mulx = muly;
162  }
163  /* end difference */
164 
165  r_vec[0] = mulx * dx / divx;
166  r_vec[1] = muly * dy / divy;
167  r_vec[2] = 0.0f;
168 }
169 
170 void convertViewVec(TransInfo *t, float r_vec[3], double dx, double dy)
171 {
172  if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) {
173  if (t->options & CTX_PAINT_CURVE) {
174  r_vec[0] = dx;
175  r_vec[1] = dy;
176  }
177  else {
178  const float xy_delta[2] = {(float)dx, (float)dy};
179  ED_view3d_win_to_delta(t->region, xy_delta, t->zfac, r_vec);
180  }
181  }
182  else if (t->spacetype == SPACE_IMAGE) {
183  if (t->options & CTX_MASK) {
184  convertViewVec2D_mask(t->view, r_vec, dx, dy);
185  }
186  else if (t->options & CTX_PAINT_CURVE) {
187  r_vec[0] = dx;
188  r_vec[1] = dy;
189  }
190  else {
191  convertViewVec2D(t->view, r_vec, dx, dy);
192  }
193 
194  r_vec[0] *= t->aspect[0];
195  r_vec[1] *= t->aspect[1];
196  }
197  else if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA)) {
198  convertViewVec2D(t->view, r_vec, dx, dy);
199  }
200  else if (ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) {
201  convertViewVec2D(&t->region->v2d, r_vec, dx, dy);
202  }
203  else if (t->spacetype == SPACE_CLIP) {
204  if (t->options & CTX_MASK) {
205  convertViewVec2D_mask(t->view, r_vec, dx, dy);
206  }
207  else {
208  convertViewVec2D(t->view, r_vec, dx, dy);
209  }
210 
211  r_vec[0] *= t->aspect[0];
212  r_vec[1] *= t->aspect[1];
213  }
214  else {
215  printf("%s: called in an invalid context\n", __func__);
216  zero_v3(r_vec);
217  }
218 }
219 
220 void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DProjTest flag)
221 {
222  if (t->spacetype == SPACE_VIEW3D) {
223  if (t->region->regiontype == RGN_TYPE_WINDOW) {
224  if (ED_view3d_project_int_global(t->region, vec, adr, flag) != V3D_PROJ_RET_OK) {
225  /* this is what was done in 2.64, perhaps we can be smarter? */
226  adr[0] = (int)2140000000.0f;
227  adr[1] = (int)2140000000.0f;
228  }
229  }
230  }
231  else if (t->spacetype == SPACE_IMAGE) {
232  SpaceImage *sima = t->area->spacedata.first;
233 
234  if (t->options & CTX_MASK) {
235  float v[2];
236 
237  v[0] = vec[0] / t->aspect[0];
238  v[1] = vec[1] / t->aspect[1];
239 
240  BKE_mask_coord_to_image(sima->image, &sima->iuser, v, v);
241 
242  ED_image_point_pos__reverse(sima, t->region, v, v);
243 
244  adr[0] = v[0];
245  adr[1] = v[1];
246  }
247  else if (t->options & CTX_PAINT_CURVE) {
248  adr[0] = vec[0];
249  adr[1] = vec[1];
250  }
251  else {
252  float v[2];
253 
254  v[0] = vec[0] / t->aspect[0];
255  v[1] = vec[1] / t->aspect[1];
256 
257  UI_view2d_view_to_region(t->view, v[0], v[1], &adr[0], &adr[1]);
258  }
259  }
260  else if (t->spacetype == SPACE_ACTION) {
261  int out[2] = {0, 0};
262 #if 0
263  SpaceAction *sact = t->area->spacedata.first;
264 
265  if (sact->flag & SACTION_DRAWTIME) {
266  // vec[0] = vec[0] / ((t->scene->r.frs_sec / t->scene->r.frs_sec_base));
267  /* same as below */
268  UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &out[0], &out[1]);
269  }
270  else
271 #endif
272  {
273  UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &out[0], &out[1]);
274  }
275 
276  adr[0] = out[0];
277  adr[1] = out[1];
278  }
279  else if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA)) {
280  int out[2] = {0, 0};
281 
282  UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &out[0], &out[1]);
283  adr[0] = out[0];
284  adr[1] = out[1];
285  }
286  else if (t->spacetype == SPACE_SEQ) { /* XXX not tested yet, but should work */
287  int out[2] = {0, 0};
288 
289  UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &out[0], &out[1]);
290  adr[0] = out[0];
291  adr[1] = out[1];
292  }
293  else if (t->spacetype == SPACE_CLIP) {
294  SpaceClip *sc = t->area->spacedata.first;
295 
296  if (t->options & CTX_MASK) {
297  MovieClip *clip = ED_space_clip_get_clip(sc);
298 
299  if (clip) {
300  float v[2];
301 
302  v[0] = vec[0] / t->aspect[0];
303  v[1] = vec[1] / t->aspect[1];
304 
305  BKE_mask_coord_to_movieclip(sc->clip, &sc->user, v, v);
306 
307  ED_clip_point_stable_pos__reverse(sc, t->region, v, v);
308 
309  adr[0] = v[0];
310  adr[1] = v[1];
311  }
312  else {
313  adr[0] = 0;
314  adr[1] = 0;
315  }
316  }
317  else if (t->options & CTX_MOVIECLIP) {
318  float v[2];
319 
320  v[0] = vec[0] / t->aspect[0];
321  v[1] = vec[1] / t->aspect[1];
322 
323  UI_view2d_view_to_region(t->view, v[0], v[1], &adr[0], &adr[1]);
324  }
325  else {
326  BLI_assert(0);
327  }
328  }
329  else if (t->spacetype == SPACE_NODE) {
330  UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &adr[0], &adr[1]);
331  }
332 }
333 void projectIntView(TransInfo *t, const float vec[3], int adr[2])
334 {
336 }
337 
338 void projectFloatViewEx(TransInfo *t, const float vec[3], float adr[2], const eV3DProjTest flag)
339 {
340  switch (t->spacetype) {
341  case SPACE_VIEW3D: {
342  if (t->options & CTX_PAINT_CURVE) {
343  adr[0] = vec[0];
344  adr[1] = vec[1];
345  }
346  else if (t->region->regiontype == RGN_TYPE_WINDOW) {
347  /* allow points behind the view T33643. */
348  if (ED_view3d_project_float_global(t->region, vec, adr, flag) != V3D_PROJ_RET_OK) {
349  /* XXX, 2.64 and prior did this, weak! */
350  adr[0] = t->region->winx / 2.0f;
351  adr[1] = t->region->winy / 2.0f;
352  }
353  return;
354  }
355  break;
356  }
357  default: {
358  int a[2] = {0, 0};
359  projectIntView(t, vec, a);
360  adr[0] = a[0];
361  adr[1] = a[1];
362  break;
363  }
364  }
365 }
366 void projectFloatView(TransInfo *t, const float vec[3], float adr[2])
367 {
369 }
370 
371 void applyAspectRatio(TransInfo *t, float vec[2])
372 {
373  if ((t->spacetype == SPACE_IMAGE) && (t->mode == TFM_TRANSLATION) &&
374  !(t->options & CTX_PAINT_CURVE)) {
375  SpaceImage *sima = t->area->spacedata.first;
376 
377  if ((sima->flag & SI_COORDFLOATS) == 0) {
378  int width, height;
380 
381  vec[0] *= width;
382  vec[1] *= height;
383  }
384 
385  vec[0] /= t->aspect[0];
386  vec[1] /= t->aspect[1];
387  }
388  else if ((t->spacetype == SPACE_CLIP) && (t->mode == TFM_TRANSLATION)) {
389  if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
390  vec[0] /= t->aspect[0];
391  vec[1] /= t->aspect[1];
392  }
393  }
394 }
395 
396 void removeAspectRatio(TransInfo *t, float vec[2])
397 {
398  if ((t->spacetype == SPACE_IMAGE) && (t->mode == TFM_TRANSLATION)) {
399  SpaceImage *sima = t->area->spacedata.first;
400 
401  if ((sima->flag & SI_COORDFLOATS) == 0) {
402  int width, height;
404 
405  vec[0] /= width;
406  vec[1] /= height;
407  }
408 
409  vec[0] *= t->aspect[0];
410  vec[1] *= t->aspect[1];
411  }
412  else if ((t->spacetype == SPACE_CLIP) && (t->mode == TFM_TRANSLATION)) {
413  if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
414  vec[0] *= t->aspect[0];
415  vec[1] *= t->aspect[1];
416  }
417  }
418 }
419 
420 static void viewRedrawForce(const bContext *C, TransInfo *t)
421 {
422  if (t->options & CTX_GPENCIL_STROKES) {
424  if (gpd) {
426  }
428  }
429  else if (t->spacetype == SPACE_VIEW3D) {
430  if (t->options & CTX_PAINT_CURVE) {
431  wmWindow *window = CTX_wm_window(C);
432  WM_paint_cursor_tag_redraw(window, t->region);
433  }
434  else {
435  /* Do we need more refined tags? */
436  if (t->options & CTX_POSE_BONE) {
438  }
439  else {
441  }
442 
443  /* For real-time animation record - send notifiers recognized by animation editors */
444  /* XXX: is this notifier a lame duck? */
445  if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
447  }
448  }
449  }
450  else if (t->spacetype == SPACE_ACTION) {
451  // SpaceAction *saction = (SpaceAction *)t->area->spacedata.first;
453  }
454  else if (t->spacetype == SPACE_GRAPH) {
455  // SpaceGraph *sipo = (SpaceGraph *)t->area->spacedata.first;
457  }
458  else if (t->spacetype == SPACE_NLA) {
460  }
461  else if (t->spacetype == SPACE_NODE) {
462  // ED_area_tag_redraw(t->area);
464  }
465  else if (t->spacetype == SPACE_SEQ) {
467  /* Key-frames on strips has been moved, so make sure related editors are informed. */
469  }
470  else if (t->spacetype == SPACE_IMAGE) {
471  if (t->options & CTX_MASK) {
473 
475  }
476  else if (t->options & CTX_PAINT_CURVE) {
477  wmWindow *window = CTX_wm_window(C);
478  WM_paint_cursor_tag_redraw(window, t->region);
479  }
480  else if (t->options & CTX_CURSOR) {
481  ED_area_tag_redraw(t->area);
482  }
483  else {
484  /* XXX how to deal with lock? */
485  SpaceImage *sima = (SpaceImage *)t->area->spacedata.first;
486  if (sima->lock) {
488  }
489  else {
490  ED_area_tag_redraw(t->area);
491  }
492  }
493  }
494  else if (t->spacetype == SPACE_CLIP) {
495  SpaceClip *sc = (SpaceClip *)t->area->spacedata.first;
496 
498  MovieClip *clip = ED_space_clip_get_clip(sc);
499 
500  /* objects could be parented to tracking data, so send this for viewport refresh */
502 
504  }
505  else if (ED_space_clip_check_show_maskedit(sc)) {
507 
509  }
510  }
511 }
512 
514 {
515  ED_area_status_text(t->area, NULL);
516 
517  if (t->spacetype == SPACE_VIEW3D) {
518  /* if autokeying is enabled, send notifiers that keyframes were added */
519  if (IS_AUTOKEY_ON(t->scene)) {
521  }
522 
523  /* redraw UV editor */
524  const char uvcalc_correct_flag = ELEM(t->mode, TFM_VERT_SLIDE, TFM_EDGE_SLIDE) ?
527 
528  if ((t->data_type == &TransConvertType_Mesh) &&
529  (t->settings->uvcalc_flag & uvcalc_correct_flag)) {
531  }
532 
533  /* XXX(ton): temp, first hack to get auto-render in compositor work. */
535  }
536 
537 #if 0 /* TRANSFORM_FIX_ME */
538  if (t->spacetype == SPACE_VIEW3D) {
539  allqueue(REDRAWBUTSOBJECT, 0);
540  allqueue(REDRAWVIEW3D, 0);
541  }
542  else if (t->spacetype == SPACE_IMAGE) {
543  allqueue(REDRAWIMAGE, 0);
544  allqueue(REDRAWVIEW3D, 0);
545  }
546  else if (ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA, SPACE_GRAPH)) {
547  allqueue(REDRAWVIEW3D, 0);
548  allqueue(REDRAWACTION, 0);
549  allqueue(REDRAWNLA, 0);
550  allqueue(REDRAWIPO, 0);
551  allqueue(REDRAWTIME, 0);
552  allqueue(REDRAWBUTSOBJECT, 0);
553  }
554 
555  scrarea_queue_headredraw(curarea);
556 #endif
557 }
558 
559 /* ************************************************* */
560 
561 static bool transform_modal_item_poll(const wmOperator *op, int value)
562 {
563  const TransInfo *t = op->customdata;
564  switch (value) {
565  case TFM_MODAL_CANCEL: {
566  /* TODO: Canceling with LMB is not possible when the operator is activated
567  * through tweak and the LMB is pressed.
568  * Therefore, this item should not appear in the status bar. */
569  break;
570  }
571  case TFM_MODAL_PROPSIZE:
574  if ((t->flag & T_PROP_EDIT) == 0) {
575  return false;
576  }
577  break;
578  }
579  case TFM_MODAL_ADD_SNAP:
580  case TFM_MODAL_REMOVE_SNAP: {
581  if (t->spacetype != SPACE_VIEW3D) {
582  return false;
583  }
584  if ((t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) == 0) {
585  return false;
586  }
587  if (value == TFM_MODAL_ADD_SNAP) {
588  if (!validSnap(t)) {
589  return false;
590  }
591  }
592  else {
593  if (!t->tsnap.selectedPoint) {
594  return false;
595  }
596  }
597  break;
598  }
599  case TFM_MODAL_AXIS_X:
600  case TFM_MODAL_AXIS_Y:
601  case TFM_MODAL_AXIS_Z:
602  case TFM_MODAL_PLANE_X:
603  case TFM_MODAL_PLANE_Y:
604  case TFM_MODAL_PLANE_Z:
606  if (t->flag & T_NO_CONSTRAINT) {
607  return false;
608  }
609  if (!ELEM(value, TFM_MODAL_AXIS_X, TFM_MODAL_AXIS_Y)) {
610  if (t->flag & T_2D_EDIT) {
611  return false;
612  }
613  }
614  break;
615  }
616  case TFM_MODAL_CONS_OFF: {
617  if ((t->con.mode & CON_APPLY) == 0) {
618  return false;
619  }
620  break;
621  }
624  if (t->mode != TFM_EDGE_SLIDE) {
625  return false;
626  }
627  break;
628  }
630  if (t->spacetype != SPACE_NODE) {
631  return false;
632  }
633  break;
634  }
637  if ((t->flag & T_AUTOIK) == 0) {
638  return false;
639  }
640  break;
641  }
642  case TFM_MODAL_TRANSLATE:
643  case TFM_MODAL_ROTATE:
644  case TFM_MODAL_RESIZE: {
645  if (!transform_mode_is_changeable(t->mode)) {
646  return false;
647  }
648  break;
649  }
650  }
651  return true;
652 }
653 
655 {
656  static const EnumPropertyItem modal_items[] = {
657  {TFM_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
658  {TFM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
659  {TFM_MODAL_AXIS_X, "AXIS_X", 0, "X Axis", ""},
660  {TFM_MODAL_AXIS_Y, "AXIS_Y", 0, "Y Axis", ""},
661  {TFM_MODAL_AXIS_Z, "AXIS_Z", 0, "Z Axis", ""},
662  {TFM_MODAL_PLANE_X, "PLANE_X", 0, "X Plane", ""},
663  {TFM_MODAL_PLANE_Y, "PLANE_Y", 0, "Y Plane", ""},
664  {TFM_MODAL_PLANE_Z, "PLANE_Z", 0, "Z Plane", ""},
665  {TFM_MODAL_CONS_OFF, "CONS_OFF", 0, "Clear Constraints", ""},
666  {TFM_MODAL_SNAP_INV_ON, "SNAP_INV_ON", 0, "Snap Invert", ""},
667  {TFM_MODAL_SNAP_INV_OFF, "SNAP_INV_OFF", 0, "Snap Invert (Off)", ""},
668  {TFM_MODAL_SNAP_TOGGLE, "SNAP_TOGGLE", 0, "Snap Toggle", ""},
669  {TFM_MODAL_ADD_SNAP, "ADD_SNAP", 0, "Add Snap Point", ""},
670  {TFM_MODAL_REMOVE_SNAP, "REMOVE_SNAP", 0, "Remove Last Snap Point", ""},
671  {NUM_MODAL_INCREMENT_UP, "INCREMENT_UP", 0, "Numinput Increment Up", ""},
672  {NUM_MODAL_INCREMENT_DOWN, "INCREMENT_DOWN", 0, "Numinput Increment Down", ""},
673  {TFM_MODAL_PROPSIZE_UP, "PROPORTIONAL_SIZE_UP", 0, "Increase Proportional Influence", ""},
675  "PROPORTIONAL_SIZE_DOWN",
676  0,
677  "Decrease Proportional Influence",
678  ""},
679  {TFM_MODAL_AUTOIK_LEN_INC, "AUTOIK_CHAIN_LEN_UP", 0, "Increase Max AutoIK Chain Length", ""},
681  "AUTOIK_CHAIN_LEN_DOWN",
682  0,
683  "Decrease Max AutoIK Chain Length",
684  ""},
685  {TFM_MODAL_EDGESLIDE_UP, "EDGESLIDE_EDGE_NEXT", 0, "Select Next Edge Slide Edge", ""},
686  {TFM_MODAL_EDGESLIDE_DOWN, "EDGESLIDE_PREV_NEXT", 0, "Select Previous Edge Slide Edge", ""},
687  {TFM_MODAL_PROPSIZE, "PROPORTIONAL_SIZE", 0, "Adjust Proportional Influence", ""},
689  "INSERTOFS_TOGGLE_DIR",
690  0,
691  "Toggle Direction for Node Auto-Offset",
692  ""},
693  {TFM_MODAL_TRANSLATE, "TRANSLATE", 0, "Move", ""},
694  {TFM_MODAL_ROTATE, "ROTATE", 0, "Rotate", ""},
695  {TFM_MODAL_RESIZE, "RESIZE", 0, "Resize", ""},
696  {TFM_MODAL_AUTOCONSTRAINT, "AUTOCONSTRAIN", 0, "Automatic Constraint", ""},
697  {TFM_MODAL_AUTOCONSTRAINTPLANE, "AUTOCONSTRAINPLANE", 0, "Automatic Constraint Plane", ""},
698  {TFM_MODAL_PRECISION, "PRECISION", 0, "Precision Mode", ""},
699  {0, NULL, 0, NULL, NULL},
700  };
701 
702  wmKeyMap *keymap = WM_modalkeymap_ensure(keyconf, "Transform Modal Map", modal_items);
704 
705  /* Default modal map values:
706  *
707  * \code{.c}
708  * WM_modalkeymap_add_item(keymap,
709  * &(const KeyMapItem_Params){
710  * .type = EVT_RETKEY,
711  * .value = KM_PRESS,
712  * .modifier = KM_ANY,
713  * .direction = KM_ANY,
714  * },
715  * TFM_MODAL_CONFIRM);
716  * WM_modalkeymap_add_item(keymap,
717  * &(const KeyMapItem_Params){
718  * .type = EVT_ESCKEY,
719  * .value = KM_PRESS,
720  * .modifier = KM_ANY,
721  * .direction = KM_ANY,
722  * },
723  * TFM_MODAL_CANCEL);
724  * WM_modalkeymap_add_item(keymap,
725  * &(const KeyMapItem_Params){
726  * .type = EVT_PAGEUPKEY,
727  * .value = KM_PRESS,
728  * .modifier = KM_ANY,
729  * .direction = KM_ANY,
730  * },
731  * TFM_MODAL_AUTOIK_LEN_INC);
732  * WM_modalkeymap_add_item(keymap,
733  * &(const KeyMapItem_Params){
734  * .type = EVT_PAGEDOWNKEY,
735  * .value = KM_PRESS,
736  * .modifier = KM_ANY,
737  * .direction = KM_ANY,
738  * },
739  * TFM_MODAL_AUTOIK_LEN_DEC);
740  * WM_modalkeymap_add_item(keymap,
741  * &(const KeyMapItem_Params){
742  * .type = EVT_GKEY,
743  * .value = KM_PRESS,
744  * .modifier = KM_ANY,
745  * .direction = KM_ANY,
746  * },
747  * TFM_MODAL_TRANSLATE);
748  * WM_modalkeymap_add_item(keymap,
749  * &(const KeyMapItem_Params){
750  * .type = EVT_RKEY,
751  * .value = KM_PRESS,
752  * .modifier = KM_ANY,
753  * .direction = KM_ANY,
754  * },
755  * TFM_MODAL_ROTATE);
756  * WM_modalkeymap_add_item(keymap,
757  * &(const KeyMapItem_Params){
758  * .type = EVT_SKEY,
759  * .value = KM_PRESS,
760  * .modifier = KM_ANY,
761  * .direction = KM_ANY,
762  * },
763  * TFM_MODAL_RESIZE);
764  * WM_modalkeymap_add_item(keymap,
765  * &(const KeyMapItem_Params){
766  * .type = MIDDLEMOUSE,
767  * .value = KM_PRESS,
768  * .modifier = KM_ANY,
769  * .direction = KM_ANY,
770  * },
771  * TFM_MODAL_AUTOCONSTRAINT);
772  * WM_modalkeymap_add_item(keymap,
773  * &(const KeyMapItem_Params){
774  * .type = MIDDLEMOUSE,
775  * .value = KM_PRESS,
776  * .modifier = KM_SHIFT,
777  * .direction = KM_ANY,
778  * },
779  * TFM_MODAL_AUTOCONSTRAINTPLANE);
780  * \endcode
781  */
782 
783  return keymap;
784 }
785 
786 static bool transform_event_modal_constraint(TransInfo *t, short modal_type)
787 {
788  if (t->flag & T_NO_CONSTRAINT) {
789  return false;
790  }
791 
792  if (t->flag & T_2D_EDIT && ELEM(modal_type, TFM_MODAL_AXIS_Z, TFM_MODAL_PLANE_Z)) {
793  return false;
794  }
795 
796  int constraint_curr = -1;
797 
800 
801  /* Avoid changing orientation in this case. */
802  constraint_curr = -2;
803  }
804  else if (t->con.mode & CON_APPLY) {
805  constraint_curr = t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2);
806  }
807 
808  int constraint_new;
809  const char *msg_2d = "", *msg_3d = "";
810 
811  /* Initialize */
812  switch (modal_type) {
813  case TFM_MODAL_AXIS_X:
814  msg_2d = TIP_("along X");
815  msg_3d = TIP_("along %s X");
816  constraint_new = CON_AXIS0;
817  break;
818  case TFM_MODAL_AXIS_Y:
819  msg_2d = TIP_("along Y");
820  msg_3d = TIP_("along %s Y");
821  constraint_new = CON_AXIS1;
822  break;
823  case TFM_MODAL_AXIS_Z:
824  msg_2d = TIP_("along Z");
825  msg_3d = TIP_("along %s Z");
826  constraint_new = CON_AXIS2;
827  break;
828  case TFM_MODAL_PLANE_X:
829  msg_3d = TIP_("locking %s X");
830  constraint_new = CON_AXIS1 | CON_AXIS2;
831  break;
832  case TFM_MODAL_PLANE_Y:
833  msg_3d = TIP_("locking %s Y");
834  constraint_new = CON_AXIS0 | CON_AXIS2;
835  break;
836  case TFM_MODAL_PLANE_Z:
837  msg_3d = TIP_("locking %s Z");
838  constraint_new = CON_AXIS0 | CON_AXIS1;
839  break;
840  default:
841  /* Invalid key */
842  return false;
843  }
844 
845  if (t->flag & T_2D_EDIT) {
846  BLI_assert(modal_type < TFM_MODAL_PLANE_X);
847  if (constraint_new == CON_AXIS2) {
848  return false;
849  }
850 
851  if (t->data_type == &TransConvertType_SequencerImage) {
852  /* Setup the 2d msg string so it writes out the transform space. */
853  msg_2d = msg_3d;
854 
855  short orient_index = 1;
856  if (t->orient_curr == O_DEFAULT || ELEM(constraint_curr, -1, constraint_new)) {
857  /* Successive presses on existing axis, cycle orientation modes. */
858  orient_index = (short)((t->orient_curr + 1) % (int)ARRAY_SIZE(t->orient));
859  }
860 
861  transform_orientations_current_set(t, orient_index);
862  if (orient_index != 0) {
863  /* Make sure that we don't stop the constraint unless we are looped back around to
864  * "no constraint". */
865  constraint_curr = -1;
866  }
867  }
868 
869  if (constraint_curr == constraint_new) {
870  stopConstraint(t);
871  }
872  else {
873  setUserConstraint(t, constraint_new, msg_2d);
874  }
875  }
876  else {
877  short orient_index = 1;
878  if (t->orient_curr == O_DEFAULT || ELEM(constraint_curr, -1, constraint_new)) {
879  /* Successive presses on existing axis, cycle orientation modes. */
880  orient_index = (short)((t->orient_curr + 1) % (int)ARRAY_SIZE(t->orient));
881  }
882 
883  transform_orientations_current_set(t, orient_index);
884  if (orient_index == 0) {
885  stopConstraint(t);
886  }
887  else {
888  setUserConstraint(t, constraint_new, msg_3d);
889  }
890  }
891  t->redraw |= TREDRAW_HARD;
892  return true;
893 }
894 
895 int transformEvent(TransInfo *t, const wmEvent *event)
896 {
897  bool handled = false;
898  const int modifiers_prev = t->modifiers;
899  const int mode_prev = t->mode;
900 
901  /* Handle modal numinput events first, if already activated. */
902  if (((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) && hasNumInput(&t->num) &&
903  handleNumInput(t->context, &(t->num), event)) {
904  t->redraw |= TREDRAW_HARD;
905  handled = true;
906  }
907  else if (event->type == MOUSEMOVE) {
908  copy_v2_v2_int(t->mval, event->mval);
909 
910  /* Use this for soft redraw. Might cause flicker in object mode */
911  // t->redraw |= TREDRAW_SOFT;
912  t->redraw |= TREDRAW_HARD;
913 
914  if (t->state == TRANS_STARTING) {
915  t->state = TRANS_RUNNING;
916  }
917 
918  applyMouseInput(t, &t->mouse, t->mval, t->values);
919 
920  /* Snapping mouse move events. */
921  t->redraw |= handleSnapping(t, event);
922  handled = true;
923  }
924  /* handle modal keymap first */
925  /* enforce redraw of transform when modifiers are used */
926  else if (event->type == EVT_MODAL_MAP) {
927  switch (event->val) {
928  case TFM_MODAL_CANCEL:
929  t->state = TRANS_CANCEL;
930  handled = true;
931  break;
932  case TFM_MODAL_CONFIRM:
933  t->state = TRANS_CONFIRM;
934  handled = true;
935  break;
936  case TFM_MODAL_TRANSLATE:
937  /* only switch when... */
938  if (t->mode == TFM_TRANSLATION) {
939  if ((t->obedit_type == OB_MESH) && (t->spacetype == SPACE_VIEW3D)) {
943 
944  /* first try edge slide */
946  /* if that fails, do vertex slide */
947  if (t->state == TRANS_CANCEL) {
949  t->state = TRANS_STARTING;
951  }
952  /* vert slide can fail on unconnected vertices (rare but possible) */
953  if (t->state == TRANS_CANCEL) {
955  t->state = TRANS_STARTING;
959  }
960  initSnapping(t, NULL); /* need to reinit after mode change */
961  t->redraw |= TREDRAW_HARD;
962  handled = true;
963  }
964  else if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
966 
967  t->flag ^= T_ALT_TRANSFORM;
968  t->redraw |= TREDRAW_HARD;
969  handled = true;
970  }
971  }
972  else if (transform_mode_is_changeable(t->mode)) {
977  initSnapping(t, NULL); /* need to reinit after mode change */
978  t->redraw |= TREDRAW_HARD;
979  handled = true;
980  }
981  break;
982  case TFM_MODAL_ROTATE:
983  /* only switch when... */
984  if (!(t->options & CTX_TEXTURE_SPACE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) {
985  if (transform_mode_is_changeable(t->mode)) {
989 
990  if (t->mode == TFM_ROTATION) {
992  }
993  else {
995  }
996  initSnapping(t, NULL); /* need to reinit after mode change */
997  t->redraw |= TREDRAW_HARD;
998  handled = true;
999  }
1000  }
1001  break;
1002  case TFM_MODAL_RESIZE:
1003  /* only switch when... */
1004  if (t->mode == TFM_RESIZE) {
1005  if (t->options & CTX_MOVIECLIP) {
1007 
1008  t->flag ^= T_ALT_TRANSFORM;
1009  t->redraw |= TREDRAW_HARD;
1010  handled = true;
1011  }
1012  }
1013  else if (transform_mode_is_changeable(t->mode)) {
1014  /* Scale isn't normally very useful after extrude along normals, see T39756 */
1015  if ((t->con.mode & CON_APPLY) && (t->orient[t->orient_curr].type == V3D_ORIENT_NORMAL)) {
1016  stopConstraint(t);
1017  }
1018 
1020  resetTransModal(t);
1023  initSnapping(t, NULL); /* need to reinit after mode change */
1024  t->redraw |= TREDRAW_HARD;
1025  handled = true;
1026  }
1027  break;
1028 
1029  case TFM_MODAL_SNAP_INV_ON:
1030  t->modifiers |= MOD_SNAP_INVERT;
1031  t->redraw |= TREDRAW_HARD;
1032  handled = true;
1033  break;
1035  t->modifiers &= ~MOD_SNAP_INVERT;
1036  t->redraw |= TREDRAW_HARD;
1037  handled = true;
1038  break;
1039  case TFM_MODAL_SNAP_TOGGLE:
1040  t->modifiers ^= MOD_SNAP;
1041  t->redraw |= TREDRAW_HARD;
1042  handled = true;
1043  break;
1044  case TFM_MODAL_AXIS_X:
1045  case TFM_MODAL_AXIS_Y:
1046  case TFM_MODAL_AXIS_Z:
1047  case TFM_MODAL_PLANE_X:
1048  case TFM_MODAL_PLANE_Y:
1049  case TFM_MODAL_PLANE_Z:
1050  if (transform_event_modal_constraint(t, event->val)) {
1051  handled = true;
1052  }
1053  break;
1054  case TFM_MODAL_CONS_OFF:
1055  if ((t->flag & T_NO_CONSTRAINT) == 0) {
1056  stopConstraint(t);
1057  t->redraw |= TREDRAW_HARD;
1058  handled = true;
1059  }
1060  break;
1061  case TFM_MODAL_ADD_SNAP:
1062  addSnapPoint(t);
1063  t->redraw |= TREDRAW_HARD;
1064  handled = true;
1065  break;
1066  case TFM_MODAL_REMOVE_SNAP:
1067  removeSnapPoint(t);
1068  t->redraw |= TREDRAW_HARD;
1069  handled = true;
1070  break;
1071  case TFM_MODAL_PROPSIZE:
1072  /* MOUSEPAN usage... */
1073  if (t->flag & T_PROP_EDIT) {
1074  float fac = 1.0f + 0.005f * (event->xy[1] - event->prev_xy[1]);
1075  t->prop_size *= fac;
1076  if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO) {
1077  t->prop_size = max_ff(min_ff(t->prop_size, ((View3D *)t->view)->clip_end),
1078  T_PROP_SIZE_MIN);
1079  }
1080  else {
1081  t->prop_size = max_ff(min_ff(t->prop_size, T_PROP_SIZE_MAX), T_PROP_SIZE_MIN);
1082  }
1084  t->redraw |= TREDRAW_HARD;
1085  handled = true;
1086  }
1087  break;
1088  case TFM_MODAL_PROPSIZE_UP:
1089  if (t->flag & T_PROP_EDIT) {
1090  t->prop_size *= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
1091  if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO) {
1092  t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->clip_end);
1093  }
1094  else {
1095  t->prop_size = min_ff(t->prop_size, T_PROP_SIZE_MAX);
1096  }
1098  t->redraw |= TREDRAW_HARD;
1099  handled = true;
1100  }
1101  break;
1103  if (t->flag & T_PROP_EDIT) {
1104  t->prop_size /= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
1105  t->prop_size = max_ff(t->prop_size, T_PROP_SIZE_MIN);
1107  t->redraw |= TREDRAW_HARD;
1108  handled = true;
1109  }
1110  break;
1112  if (t->flag & T_AUTOIK) {
1114  t->redraw |= TREDRAW_HARD;
1115  handled = true;
1116  }
1117  break;
1119  if (t->flag & T_AUTOIK) {
1121  t->redraw |= TREDRAW_HARD;
1122  handled = true;
1123  }
1124  break;
1126  if (t->spacetype == SPACE_NODE) {
1127  SpaceNode *snode = (SpaceNode *)t->area->spacedata.first;
1128 
1129  BLI_assert(t->area->spacetype == t->spacetype);
1130 
1131  if (snode->insert_ofs_dir == SNODE_INSERTOFS_DIR_RIGHT) {
1133  }
1134  else if (snode->insert_ofs_dir == SNODE_INSERTOFS_DIR_LEFT) {
1136  }
1137  else {
1138  BLI_assert(0);
1139  }
1140 
1141  t->redraw |= TREDRAW_SOFT;
1142  }
1143  break;
1146  if ((t->flag & T_RELEASE_CONFIRM) && (event->prev_val == KM_RELEASE) &&
1147  event->prev_type == t->launch_event) {
1148  /* Confirm transform if launch key is released after mouse move. */
1149  t->state = TRANS_CONFIRM;
1150  }
1151  else if ((t->flag & T_NO_CONSTRAINT) == 0) {
1153  /* Confirm. */
1156  t->redraw = TREDRAW_HARD;
1157  }
1158  else {
1159  if (t->options & CTX_CAMERA) {
1160  /* Exception for switching to dolly, or trackball, in camera view. */
1161  if (t->mode == TFM_TRANSLATION) {
1162  setLocalConstraint(t, (CON_AXIS2), TIP_("along local Z"));
1163  }
1164  else if (t->mode == TFM_ROTATION) {
1167  }
1168  t->redraw = TREDRAW_HARD;
1169  }
1170  else {
1171  t->modifiers |= (event->val == TFM_MODAL_AUTOCONSTRAINT) ?
1174  if (t->con.mode & CON_APPLY) {
1175  stopConstraint(t);
1177 
1178  /* In this case we might just want to remove the constraint,
1179  * so set #TREDRAW_SOFT to only select the constraint on the next mouse move event.
1180  * This way we can kind of "cancel" due to confirmation without constraint. */
1181  t->redraw = TREDRAW_SOFT;
1182  }
1183  else {
1185 
1186  /* When first called, set #TREDRAW_HARD to select constraint immediately in
1187  * #selectConstraint. */
1188  BLI_assert(t->redraw == TREDRAW_HARD);
1189  }
1190  }
1191  }
1192  handled = true;
1193  }
1194  break;
1195  case TFM_MODAL_PRECISION:
1196  if (event->prev_val == KM_PRESS) {
1197  t->modifiers |= MOD_PRECISION;
1198  /* Shift is modifier for higher precision transform. */
1199  t->mouse.precision = 1;
1200  t->redraw |= TREDRAW_HARD;
1201  }
1202  else if (event->prev_val == KM_RELEASE) {
1203  t->modifiers &= ~MOD_PRECISION;
1204  t->mouse.precision = 0;
1205  t->redraw |= TREDRAW_HARD;
1206  }
1207  break;
1208  /* Those two are only handled in transform's own handler, see T44634! */
1211  default:
1212  break;
1213  }
1214  }
1215  /* Else do non-mapped events. */
1216  else if (event->val == KM_PRESS) {
1217  switch (event->type) {
1218  case EVT_CKEY:
1219  if (event->flag & WM_EVENT_IS_REPEAT) {
1220  break;
1221  }
1222  if (event->modifier & KM_ALT) {
1223  if (!(t->options & CTX_NO_PET)) {
1224  t->flag ^= T_PROP_CONNECTED;
1227  t->redraw = TREDRAW_HARD;
1228  handled = true;
1229  }
1230  }
1231  break;
1232  case EVT_OKEY:
1233  if (event->flag & WM_EVENT_IS_REPEAT) {
1234  break;
1235  }
1236  if ((t->flag & T_PROP_EDIT) && (event->modifier & KM_SHIFT)) {
1237  t->prop_mode = (t->prop_mode + 1) % PROP_MODE_MAX;
1239  t->redraw |= TREDRAW_HARD;
1240  handled = true;
1241  }
1242  break;
1243  case EVT_PADPLUSKEY:
1244  if ((event->modifier & KM_ALT) && (t->flag & T_PROP_EDIT)) {
1245  t->prop_size *= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
1246  if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO) {
1247  t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->clip_end);
1248  }
1250  t->redraw = TREDRAW_HARD;
1251  handled = true;
1252  }
1253  break;
1254  case EVT_PADMINUS:
1255  if ((event->modifier & KM_ALT) && (t->flag & T_PROP_EDIT)) {
1256  t->prop_size /= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
1258  t->redraw = TREDRAW_HARD;
1259  handled = true;
1260  }
1261  break;
1262  case EVT_LEFTALTKEY:
1263  case EVT_RIGHTALTKEY:
1264  if (ELEM(t->spacetype, SPACE_SEQ, SPACE_VIEW3D)) {
1265  t->flag |= T_ALT_TRANSFORM;
1266  t->redraw |= TREDRAW_HARD;
1267  handled = true;
1268  }
1269  break;
1270  case EVT_NKEY:
1271  if (event->flag & WM_EVENT_IS_REPEAT) {
1272  break;
1273  }
1274  if (ELEM(t->mode, TFM_ROTATION)) {
1275  if ((t->flag & T_EDIT) && t->obedit_type == OB_MESH) {
1277  resetTransModal(t);
1280  t->redraw = TREDRAW_HARD;
1281  handled = true;
1282  }
1283  }
1284  break;
1285  default:
1286  break;
1287  }
1288 
1289  /* Snapping key events */
1290  t->redraw |= handleSnapping(t, event);
1291  }
1292  else if (event->val == KM_RELEASE) {
1293  switch (event->type) {
1294  case EVT_LEFTALTKEY:
1295  case EVT_RIGHTALTKEY:
1296  /* TODO: Modal Map */
1297  if (ELEM(t->spacetype, SPACE_SEQ, SPACE_VIEW3D)) {
1298  t->flag &= ~T_ALT_TRANSFORM;
1299  t->redraw |= TREDRAW_HARD;
1300  handled = true;
1301  }
1302  break;
1303  }
1304 
1305  /* confirm transform if launch key is released after mouse move */
1306  if ((t->flag & T_RELEASE_CONFIRM) && event->type == t->launch_event) {
1307  t->state = TRANS_CONFIRM;
1308  }
1309  }
1310 
1311  /* if we change snap options, get the unsnapped values back */
1312  if ((mode_prev != t->mode) || ((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) !=
1313  (modifiers_prev & (MOD_SNAP | MOD_SNAP_INVERT)))) {
1314  applyMouseInput(t, &t->mouse, t->mval, t->values);
1315  }
1316 
1317  /* Per transform event, if present */
1318  if (t->handleEvent && (!handled ||
1319  /* Needed for vertex slide, see T38756. */
1320  (event->type == MOUSEMOVE))) {
1321  t->redraw |= t->handleEvent(t, event);
1322  }
1323 
1324  /* Try to init modal numinput now, if possible. */
1325  if (!(handled || t->redraw) && ((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) &&
1326  handleNumInput(t->context, &(t->num), event)) {
1327  t->redraw |= TREDRAW_HARD;
1328  handled = true;
1329  }
1330 
1331  if (t->redraw && !ISMOUSE_MOTION(event->type)) {
1333  }
1334 
1335  if (handled || t->redraw) {
1336  return 0;
1337  }
1338  return OPERATOR_PASS_THROUGH;
1339 }
1340 
1341 bool calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], float cent2d[2])
1342 {
1343  TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data");
1344  bool success;
1345 
1346  t->context = C;
1347 
1348  t->state = TRANS_RUNNING;
1349 
1350  /* avoid calculating PET */
1351  t->options = CTX_NO_PET;
1352 
1353  t->mode = TFM_DUMMY;
1354 
1355  initTransInfo(C, t, NULL, NULL);
1356 
1357  /* avoid doing connectivity lookups (when V3D_AROUND_LOCAL_ORIGINS is set) */
1358  t->around = V3D_AROUND_CENTER_BOUNDS;
1359 
1360  createTransData(C, t); /* make TransData structs from selection */
1361 
1362  t->around = centerMode; /* override user-defined mode. */
1363 
1364  if (t->data_len_all == 0) {
1365  success = false;
1366  }
1367  else {
1368  success = true;
1369 
1370  calculateCenter(t);
1371 
1372  if (cent2d) {
1373  copy_v2_v2(cent2d, t->center2d);
1374  }
1375 
1376  if (cent3d) {
1377  /* Copy center from constraint center. Transform center can be local */
1378  copy_v3_v3(cent3d, t->center_global);
1379  }
1380  }
1381 
1382  /* aftertrans does insert keyframes, and clears base flags; doesn't read transdata */
1384 
1385  postTrans(C, t);
1386 
1387  MEM_freeN(t);
1388 
1389  return success;
1390 }
1391 
1392 static bool transinfo_show_overlay(const struct bContext *C, TransInfo *t, ARegion *region)
1393 {
1394  /* Don't show overlays when not the active view and when overlay is disabled: T57139 */
1395  bool ok = false;
1396  if (region == t->region) {
1397  ok = true;
1398  }
1399  else {
1400  ScrArea *area = CTX_wm_area(C);
1401  if (area->spacetype == SPACE_VIEW3D) {
1402  View3D *v3d = area->spacedata.first;
1403  if ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) {
1404  ok = true;
1405  }
1406  }
1407  }
1408  return ok;
1409 }
1410 
1411 static void drawTransformView(const struct bContext *C, ARegion *region, void *arg)
1412 {
1413  TransInfo *t = arg;
1414 
1415  if (!transinfo_show_overlay(C, t, region)) {
1416  return;
1417  }
1418 
1419  GPU_line_width(1.0f);
1420 
1421  drawConstraint(t);
1422  drawPropCircle(C, t);
1423  drawSnapping(C, t);
1424 
1425  if (region == t->region) {
1426  /* edge slide, vert slide */
1427  drawEdgeSlide(t);
1428  drawVertSlide(t);
1429  }
1430 }
1431 
1432 /* just draw a little warning message in the top-right corner of the viewport
1433  * to warn that autokeying is enabled */
1435 {
1436  const char *printable = IFACE_("Auto Keying On");
1437  float printable_size[2];
1438  int xco, yco;
1439 
1440  const rcti *rect = ED_region_visible_rect(region);
1441 
1442  const int font_id = BLF_default();
1444  font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]);
1445 
1446  xco = (rect->xmax - U.widget_unit) - (int)printable_size[0];
1447  yco = (rect->ymax - U.widget_unit);
1448 
1449  /* warning text (to clarify meaning of overlays)
1450  * - original color was red to match the icon, but that clashes badly with a less nasty border
1451  */
1452  uchar color[3];
1454  BLF_color3ubv(font_id, color);
1455  BLF_draw_default(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX);
1456 
1457  /* autokey recording icon... */
1459 
1460  xco -= U.widget_unit;
1461  yco -= (int)printable_size[1] / 2;
1462 
1463  UI_icon_draw(xco, yco, ICON_REC);
1464 
1466 }
1467 
1468 static void drawTransformPixel(const struct bContext *C, ARegion *region, void *arg)
1469 {
1470  TransInfo *t = arg;
1471 
1472  if (!transinfo_show_overlay(C, t, region)) {
1473  return;
1474  }
1475 
1476  if (region == t->region) {
1477  Scene *scene = t->scene;
1478  ViewLayer *view_layer = t->view_layer;
1479  Object *ob = OBACT(view_layer);
1480 
1481  /* draw auto-key-framing hint in the corner
1482  * - only draw if enabled (advanced users may be distracted/annoyed),
1483  * for objects that will be auto-keyframed (no point otherwise),
1484  * AND only for the active region (as showing all is too overwhelming)
1485  */
1486  if ((U.autokey_flag & AUTOKEY_FLAG_NOWARNING) == 0) {
1487  if (region == t->region) {
1488  if (t->options & (CTX_OBJECT | CTX_POSE_BONE)) {
1489  if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) {
1490  drawAutoKeyWarning(t, region);
1491  }
1492  }
1493  }
1494  }
1495  }
1496 }
1497 
1499 {
1501  PropertyRNA *prop;
1502 
1503  /* Save back mode in case we're in the generic operator */
1504  if ((prop = RNA_struct_find_property(op->ptr, "mode"))) {
1505  RNA_property_enum_set(op->ptr, prop, t->mode);
1506  }
1507 
1508  if ((prop = RNA_struct_find_property(op->ptr, "value"))) {
1509  if (RNA_property_array_check(prop)) {
1510  RNA_property_float_set_array(op->ptr, prop, t->values_final);
1511  }
1512  else {
1513  RNA_property_float_set(op->ptr, prop, t->values_final[0]);
1514  }
1515  }
1516 
1517  /* Save proportional edit settings.
1518  * Skip saving proportional edit if it was not actually used. */
1519  if (!(t->options & CTX_NO_PET)) {
1520  bool use_prop_edit = false;
1521  int prop_edit_flag = 0;
1522  if (t->flag & T_PROP_EDIT_ALL) {
1523  if (t->flag & T_PROP_EDIT) {
1524  use_prop_edit = true;
1525  }
1526  if (t->flag & T_PROP_CONNECTED) {
1527  prop_edit_flag |= PROP_EDIT_CONNECTED;
1528  }
1529  if (t->flag & T_PROP_PROJECTED) {
1530  prop_edit_flag |= PROP_EDIT_PROJECTED;
1531  }
1532  }
1533 
1534  /* If modal, save settings back in scene if not set as operator argument */
1535  if ((t->flag & T_MODAL) || (op->flag & OP_IS_REPEAT)) {
1536  /* save settings if not set in operator */
1537  if ((prop = RNA_struct_find_property(op->ptr, "use_proportional_edit")) &&
1538  !RNA_property_is_set(op->ptr, prop)) {
1539  const Object *obact = OBACT(t->view_layer);
1540 
1541  if (t->spacetype == SPACE_GRAPH) {
1542  ts->proportional_fcurve = use_prop_edit;
1543  }
1544  else if (t->spacetype == SPACE_ACTION) {
1545  ts->proportional_action = use_prop_edit;
1546  }
1547  else if (t->options & CTX_MASK) {
1548  ts->proportional_mask = use_prop_edit;
1549  }
1550  else if (obact && obact->mode == OB_MODE_OBJECT) {
1551  ts->proportional_objects = use_prop_edit;
1552  }
1553  else {
1554  if (use_prop_edit) {
1556  }
1557  else {
1559  }
1560  }
1561  }
1562 
1563  if ((prop = RNA_struct_find_property(op->ptr, "proportional_size"))) {
1564  ts->proportional_size = RNA_property_is_set(op->ptr, prop) ?
1565  RNA_property_float_get(op->ptr, prop) :
1566  t->prop_size;
1567  }
1568 
1569  if ((prop = RNA_struct_find_property(op->ptr, "proportional_edit_falloff")) &&
1570  !RNA_property_is_set(op->ptr, prop)) {
1571  ts->prop_mode = t->prop_mode;
1572  }
1573  }
1574 
1575  if ((prop = RNA_struct_find_property(op->ptr, "use_proportional_edit"))) {
1576  RNA_property_boolean_set(op->ptr, prop, use_prop_edit);
1577  RNA_boolean_set(op->ptr, "use_proportional_connected", prop_edit_flag & PROP_EDIT_CONNECTED);
1578  RNA_boolean_set(op->ptr, "use_proportional_projected", prop_edit_flag & PROP_EDIT_PROJECTED);
1579  RNA_enum_set(op->ptr, "proportional_edit_falloff", t->prop_mode);
1580  RNA_float_set(op->ptr, "proportional_size", t->prop_size);
1581  }
1582  }
1583 
1584  /* Save snapping settings. */
1585  if ((prop = RNA_struct_find_property(op->ptr, "snap"))) {
1586  RNA_property_boolean_set(op->ptr, prop, (t->modifiers & MOD_SNAP) != 0);
1587 
1588  if ((prop = RNA_struct_find_property(op->ptr, "snap_elements"))) {
1589  RNA_property_enum_set(op->ptr, prop, t->tsnap.mode);
1590  RNA_boolean_set(op->ptr, "use_snap_project", t->tsnap.project);
1591  RNA_enum_set(op->ptr, "snap_target", t->tsnap.source_select);
1592 
1593  eSnapTargetSelect target = t->tsnap.target_select;
1594  RNA_boolean_set(op->ptr, "use_snap_self", (target & SCE_SNAP_TARGET_NOT_ACTIVE) == 0);
1595  RNA_boolean_set(op->ptr, "use_snap_edit", (target & SCE_SNAP_TARGET_NOT_EDITED) == 0);
1596  RNA_boolean_set(op->ptr, "use_snap_nonedit", (target & SCE_SNAP_TARGET_NOT_NONEDITED) == 0);
1598  op->ptr, "use_snap_selectable", (target & SCE_SNAP_TARGET_ONLY_SELECTABLE) != 0);
1599  }
1600 
1601  /* Update `ToolSettings` for properties that change during modal. */
1602  if (t->flag & T_MODAL) {
1603  /* Do we check for parameter? */
1604  if (transformModeUseSnap(t)) {
1605  if (!(t->modifiers & MOD_SNAP) != !(t->tsnap.flag & SCE_SNAP)) {
1606  /* Type is #eSnapFlag, but type must match various snap attributes in #ToolSettings. */
1607  short *snap_flag_ptr;
1608 
1609  wmMsgParams_RNA msg_key_params = {{0}};
1610  RNA_pointer_create(&t->scene->id, &RNA_ToolSettings, ts, &msg_key_params.ptr);
1611 
1612  if (t->spacetype == SPACE_NODE) {
1613  snap_flag_ptr = &ts->snap_flag_node;
1614  msg_key_params.prop = &rna_ToolSettings_use_snap_node;
1615  }
1616  else if (t->spacetype == SPACE_IMAGE) {
1617  snap_flag_ptr = &ts->snap_uv_flag;
1618  msg_key_params.prop = &rna_ToolSettings_use_snap_uv;
1619  }
1620  else if (t->spacetype == SPACE_SEQ) {
1621  snap_flag_ptr = &ts->snap_flag_seq;
1622  msg_key_params.prop = &rna_ToolSettings_use_snap_sequencer;
1623  }
1624  else {
1625  snap_flag_ptr = &ts->snap_flag;
1626  msg_key_params.prop = &rna_ToolSettings_use_snap;
1627  }
1628 
1629  if (t->modifiers & MOD_SNAP) {
1630  *snap_flag_ptr |= SCE_SNAP;
1631  }
1632  else {
1633  *snap_flag_ptr &= ~SCE_SNAP;
1634  }
1635  WM_msg_publish_rna_params(t->mbus, &msg_key_params);
1636  }
1637  }
1638  }
1639  }
1640 
1641  if ((prop = RNA_struct_find_property(op->ptr, "mirror"))) {
1642  RNA_property_boolean_set(op->ptr, prop, (t->flag & T_NO_MIRROR) == 0);
1643  }
1644 
1645  if ((prop = RNA_struct_find_property(op->ptr, "orient_axis"))) {
1646  if (t->flag & T_MODAL) {
1647  if (t->con.mode & CON_APPLY) {
1648  int orient_axis = constraintModeToIndex(t);
1649  if (orient_axis != -1) {
1650  RNA_property_enum_set(op->ptr, prop, orient_axis);
1651  }
1652  }
1653  else {
1654  RNA_property_enum_set(op->ptr, prop, t->orient_axis);
1655  }
1656  }
1657  }
1658  if ((prop = RNA_struct_find_property(op->ptr, "orient_axis_ortho"))) {
1659  if (t->flag & T_MODAL) {
1660  RNA_property_enum_set(op->ptr, prop, t->orient_axis_ortho);
1661  }
1662  }
1663 
1664  if ((prop = RNA_struct_find_property(op->ptr, "orient_type"))) {
1665  short orient_type_set, orient_type_curr;
1666  orient_type_set = RNA_property_is_set(op->ptr, prop) ? RNA_property_enum_get(op->ptr, prop) :
1667  -1;
1668  orient_type_curr = t->orient[t->orient_curr].type;
1669 
1670  if (!ELEM(orient_type_curr, orient_type_set, V3D_ORIENT_CUSTOM_MATRIX)) {
1671  RNA_property_enum_set(op->ptr, prop, orient_type_curr);
1672  orient_type_set = orient_type_curr;
1673  }
1674 
1675  if (((prop = RNA_struct_find_property(op->ptr, "orient_matrix_type")) &&
1676  !RNA_property_is_set(op->ptr, prop))) {
1677  /* Set the first time to register on redo. */
1678  RNA_property_enum_set(op->ptr, prop, orient_type_set);
1679  RNA_float_set_array(op->ptr, "orient_matrix", &t->spacemtx[0][0]);
1680  }
1681  }
1682 
1683  if ((prop = RNA_struct_find_property(op->ptr, "constraint_axis"))) {
1684  bool constraint_axis[3] = {false, false, false};
1685  if (t->con.mode & CON_APPLY) {
1686  if (t->con.mode & CON_AXIS0) {
1687  constraint_axis[0] = true;
1688  }
1689  if (t->con.mode & CON_AXIS1) {
1690  constraint_axis[1] = true;
1691  }
1692  if (t->con.mode & CON_AXIS2) {
1693  constraint_axis[2] = true;
1694  }
1695  RNA_property_boolean_set_array(op->ptr, prop, constraint_axis);
1696  }
1697  else {
1698  RNA_property_unset(op->ptr, prop);
1699  }
1700  }
1701 
1702  {
1703  const char *prop_id = NULL;
1704  bool prop_state = true;
1705  if (t->mode == TFM_SHRINKFATTEN) {
1706  prop_id = "use_even_offset";
1707  prop_state = false;
1708  }
1709 
1710  if (prop_id && (prop = RNA_struct_find_property(op->ptr, prop_id))) {
1711  RNA_property_boolean_set(op->ptr, prop, ((t->flag & T_ALT_TRANSFORM) == 0) == prop_state);
1712  }
1713  }
1714 
1715  if ((prop = RNA_struct_find_property(op->ptr, "correct_uv"))) {
1717  op->ptr, prop, (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT_SLIDE) != 0);
1718  }
1719 }
1720 
1721 static void initSnapSpatial(TransInfo *t, float r_snap[2])
1722 {
1723  if (t->spacetype == SPACE_VIEW3D) {
1724  if (t->region->regiondata) {
1725  View3D *v3d = t->area->spacedata.first;
1726  r_snap[0] = ED_view3d_grid_view_scale(t->scene, v3d, t->region, NULL) * 1.0f;
1727  r_snap[1] = r_snap[0] * 0.1f;
1728  }
1729  }
1730  else if (t->spacetype == SPACE_IMAGE) {
1731  SpaceImage *sima = t->area->spacedata.first;
1732  View2D *v2d = &t->region->v2d;
1733  int grid_size = SI_GRID_STEPS_LEN;
1734  float zoom_factor = ED_space_image_zoom_level(v2d, grid_size);
1735  float grid_steps[SI_GRID_STEPS_LEN];
1736 
1737  ED_space_image_grid_steps(sima, grid_steps, grid_size);
1738  /* Snapping value based on what type of grid is used (adaptive-subdividing or custom-grid). */
1739  r_snap[0] = ED_space_image_increment_snap_value(grid_size, grid_steps, zoom_factor);
1740  r_snap[1] = r_snap[0] / 2.0f;
1741  }
1742  else if (t->spacetype == SPACE_CLIP) {
1743  r_snap[0] = 0.125f;
1744  r_snap[1] = 0.0625f;
1745  }
1746  else if (t->spacetype == SPACE_NODE) {
1747  r_snap[0] = r_snap[1] = ED_node_grid_size();
1748  }
1749  else if (t->spacetype == SPACE_GRAPH) {
1750  r_snap[0] = 1.0;
1751  r_snap[1] = 0.1f;
1752  }
1753  else {
1754  r_snap[0] = r_snap[1] = 1.0f;
1755  }
1756 }
1757 
1758 bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event, int mode)
1759 {
1760  int options = 0;
1761  PropertyRNA *prop;
1762 
1763  mode = transform_mode_really_used(C, mode);
1764 
1765  t->context = C;
1766 
1767  /* added initialize, for external calls to set stuff in TransInfo, like undo string */
1768 
1769  t->state = TRANS_STARTING;
1770 
1771  if ((prop = RNA_struct_find_property(op->ptr, "cursor_transform")) &&
1772  RNA_property_is_set(op->ptr, prop)) {
1773  if (RNA_property_boolean_get(op->ptr, prop)) {
1774  options |= CTX_CURSOR;
1775  }
1776  }
1777 
1778  if ((prop = RNA_struct_find_property(op->ptr, "texture_space")) &&
1779  RNA_property_is_set(op->ptr, prop)) {
1780  if (RNA_property_boolean_get(op->ptr, prop)) {
1782  }
1783  }
1784 
1785  if ((prop = RNA_struct_find_property(op->ptr, "gpencil_strokes")) &&
1786  RNA_property_is_set(op->ptr, prop)) {
1787  if (RNA_property_boolean_get(op->ptr, prop)) {
1789  }
1790  }
1791 
1792  if ((prop = RNA_struct_find_property(op->ptr, "view2d_edge_pan")) &&
1793  RNA_property_is_set(op->ptr, prop)) {
1794  if (RNA_property_boolean_get(op->ptr, prop)) {
1796  }
1797  }
1798 
1799  t->options = options;
1800 
1801  t->mode = mode;
1802 
1803  /* Needed to translate tweak events to mouse buttons. */
1804  t->launch_event = event ? WM_userdef_event_type_from_keymap_type(event->type) : -1;
1805  t->is_launch_event_drag = event ? (event->val == KM_CLICK_DRAG) : false;
1806 
1807  unit_m3(t->spacemtx);
1808 
1809  initTransInfo(C, t, op, event);
1810 
1811  if (t->spacetype == SPACE_VIEW3D) {
1812  t->draw_handle_view = ED_region_draw_cb_activate(
1813  t->region->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
1814  t->draw_handle_pixel = ED_region_draw_cb_activate(
1815  t->region->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
1816  t->draw_handle_cursor = WM_paint_cursor_activate(
1818  }
1819  else if (ELEM(t->spacetype,
1820  SPACE_IMAGE,
1821  SPACE_CLIP,
1822  SPACE_NODE,
1823  SPACE_GRAPH,
1824  SPACE_ACTION,
1825  SPACE_SEQ)) {
1826  t->draw_handle_view = ED_region_draw_cb_activate(
1827  t->region->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
1828  t->draw_handle_cursor = WM_paint_cursor_activate(
1830  }
1831 
1832  createTransData(C, t); /* Make #TransData structs from selection. */
1833 
1834  if (t->data_len_all == 0) {
1835  postTrans(C, t);
1836  return 0;
1837  }
1838 
1839  /* When proportional editing is enabled, data_len_all can be non zero when
1840  * nothing is selected, if this is the case we can end the transform early.
1841  *
1842  * By definition transform-data has selected items in beginning,
1843  * so only the first item in each container needs to be checked
1844  * when looking for the presence of selected data. */
1845  if (t->flag & T_PROP_EDIT) {
1846  bool has_selected_any = false;
1848  if (tc->data->flag & TD_SELECTED) {
1849  has_selected_any = true;
1850  break;
1851  }
1852  }
1853 
1854  if (!has_selected_any) {
1855  postTrans(C, t);
1856  return 0;
1857  }
1858  }
1859 
1860  if (event) {
1861  /* keymap for shortcut header prints */
1862  t->keymap = WM_keymap_active(CTX_wm_manager(C), op->type->modalkeymap);
1863 
1864  /* Stupid code to have Ctrl-Click on gizmo work ok.
1865  *
1866  * Do this only for translation/rotation/resize because only these
1867  * modes are available from gizmo and doing such check could
1868  * lead to keymap conflicts for other modes (see T31584)
1869  */
1871  wmKeyMapItem *kmi;
1872 
1873  for (kmi = t->keymap->items.first; kmi; kmi = kmi->next) {
1874  if (kmi->flag & KMI_INACTIVE) {
1875  continue;
1876  }
1877 
1878  if (kmi->propvalue == TFM_MODAL_SNAP_INV_ON && kmi->val == KM_PRESS) {
1879  if ((ELEM(kmi->type, EVT_LEFTCTRLKEY, EVT_RIGHTCTRLKEY) &&
1880  (event->modifier & KM_CTRL)) ||
1882  (event->modifier & KM_SHIFT)) ||
1883  (ELEM(kmi->type, EVT_LEFTALTKEY, EVT_RIGHTALTKEY) && (event->modifier & KM_ALT)) ||
1884  ((kmi->type == EVT_OSKEY) && (event->modifier & KM_OSKEY))) {
1885  t->modifiers |= MOD_SNAP_INVERT;
1886  }
1887  break;
1888  }
1889  }
1890  }
1891  }
1892 
1893  initSnapping(t, op); /* Initialize snapping data AFTER mode flags */
1894 
1895  initSnapSpatial(t, t->snap_spatial);
1896 
1897  /* EVIL! posemode code can switch translation to rotate when 1 bone is selected.
1898  * will be removed (ton) */
1899 
1900  /* EVIL2: we gave as argument also texture space context bit... was cleared */
1901 
1902  /* EVIL3: extend mode for animation editors also switches modes...
1903  * but is best way to avoid duplicate code */
1904  mode = t->mode;
1905 
1907  calculateCenter(t);
1908 
1909  if (event) {
1910  /* Initialize accurate transform to settings requested by keymap. */
1911  bool use_accurate = false;
1912  if ((prop = RNA_struct_find_property(op->ptr, "use_accurate")) &&
1913  RNA_property_is_set(op->ptr, prop)) {
1914  if (RNA_property_boolean_get(op->ptr, prop)) {
1915  use_accurate = true;
1916  }
1917  }
1918 
1919  int mval[2];
1920  if (t->flag & T_EVENT_DRAG_START) {
1921  WM_event_drag_start_mval(event, t->region, mval);
1922  }
1923  else {
1924  copy_v2_v2_int(mval, event->mval);
1925  }
1926  initMouseInput(t, &t->mouse, t->center2d, mval, use_accurate);
1927  }
1928 
1929  transform_mode_init(t, op, mode);
1930 
1931  if (t->state == TRANS_CANCEL) {
1932  postTrans(C, t);
1933  return 0;
1934  }
1935 
1936  /* Transformation axis from operator */
1937  if ((prop = RNA_struct_find_property(op->ptr, "orient_axis")) &&
1938  RNA_property_is_set(op->ptr, prop)) {
1939  t->orient_axis = RNA_property_enum_get(op->ptr, prop);
1940  }
1941  if ((prop = RNA_struct_find_property(op->ptr, "orient_axis_ortho")) &&
1942  RNA_property_is_set(op->ptr, prop)) {
1943  t->orient_axis_ortho = RNA_property_enum_get(op->ptr, prop);
1944  }
1945 
1946  /* Constraint init from operator */
1947  if (t->con.mode & CON_APPLY) {
1948  setUserConstraint(t, t->con.mode, "%s");
1949  }
1950 
1951  /* Don't write into the values when non-modal because they are already set from operator redo
1952  * values. */
1953  if (t->flag & T_MODAL) {
1954  /* Setup the mouse input with initial values. */
1955  applyMouseInput(t, &t->mouse, t->mouse.imval, t->values);
1956  }
1957 
1958  if ((prop = RNA_struct_find_property(op->ptr, "preserve_clnor"))) {
1959  if ((t->flag & T_EDIT) && t->obedit_type == OB_MESH) {
1960 
1962  if (((Mesh *)(tc->obedit->data))->flag & ME_AUTOSMOOTH) {
1963  BMEditMesh *em = NULL; /* BKE_editmesh_from_object(t->obedit); */
1964  bool do_skip = false;
1965 
1966  /* Currently only used for two of three most frequent transform ops,
1967  * can include more ops.
1968  * Note that scaling cannot be included here,
1969  * non-uniform scaling will affect normals. */
1970  if (ELEM(t->mode, TFM_TRANSLATION, TFM_ROTATION)) {
1971  if (em->bm->totvertsel == em->bm->totvert) {
1972  /* No need to invalidate if whole mesh is selected. */
1973  do_skip = true;
1974  }
1975  }
1976 
1977  if (t->flag & T_MODAL) {
1978  RNA_property_boolean_set(op->ptr, prop, false);
1979  }
1980  else if (!do_skip) {
1981  const bool preserve_clnor = RNA_property_boolean_get(op->ptr, prop);
1982  if (preserve_clnor) {
1983  BKE_editmesh_lnorspace_update(em, tc->obedit->data);
1984  t->flag |= T_CLNOR_REBUILD;
1985  }
1986  BM_lnorspace_invalidate(em->bm, true);
1987  }
1988  }
1989  }
1990  }
1991  }
1992 
1993  t->context = NULL;
1994 
1995  return 1;
1996 }
1997 
1999 {
2000  t->context = C;
2001 
2002  if (t->redraw == TREDRAW_HARD) {
2004  if (t->transform) {
2005  t->transform(t, t->mval); /* calls recalcData() */
2006  }
2007  }
2008 
2009  if (t->redraw & TREDRAW_SOFT) {
2010  viewRedrawForce(C, t);
2011  }
2012 
2013  t->redraw = TREDRAW_NOTHING;
2014 
2015  /* If auto confirm is on, break after one pass */
2016  if (t->options & CTX_AUTOCONFIRM) {
2017  t->state = TRANS_CONFIRM;
2018  }
2019 
2020  t->context = NULL;
2021 }
2022 
2024 {
2025  int exit_code = OPERATOR_RUNNING_MODAL;
2026 
2027  t->context = C;
2028 
2029  if (!ELEM(t->state, TRANS_STARTING, TRANS_RUNNING)) {
2030  /* handle restoring objects */
2031  if (t->state == TRANS_CANCEL) {
2032  exit_code = OPERATOR_CANCELLED;
2033  restoreTransObjects(t); /* calls recalcData() */
2034  }
2035  else {
2036  if (t->flag & T_CLNOR_REBUILD) {
2038  BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
2039  BM_lnorspace_rebuild(em->bm, true);
2040  }
2041  }
2042  exit_code = OPERATOR_FINISHED;
2043  }
2044 
2045  /* aftertrans does insert keyframes, and clears base flags; doesn't read transdata */
2047 
2048  /* Free data, also handles overlap [in freeTransCustomData()]. */
2049  postTrans(C, t);
2050 
2051  /* send events out for redraws */
2052  viewRedrawPost(C, t);
2053 
2054  viewRedrawForce(C, t);
2055  }
2056 
2057  t->context = NULL;
2058 
2059  return exit_code;
2060 }
2061 
2063 {
2064  /* currently only checks for editmode */
2065  if (t->flag & T_EDIT) {
2066  if ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
2067  (ELEM(t->obedit_type, OB_MESH, OB_CURVES_LEGACY, OB_MBALL, OB_ARMATURE))) {
2068  /* not all editmode supports axis-matrix */
2069  return true;
2070  }
2071  }
2072 
2073  return false;
2074 }
2075 
2076 bool transform_apply_matrix(TransInfo *t, float mat[4][4])
2077 {
2078  if (t->transform_matrix != NULL) {
2079  t->transform_matrix(t, mat);
2080  return true;
2081  }
2082  return false;
2083 }
2084 
2085 void transform_final_value_get(const TransInfo *t, float *value, const int value_num)
2086 {
2087  memcpy(value, t->values_final, sizeof(float) * value_num);
2088 }
typedef float(TangentPoint)[2]
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:738
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:713
struct Mask * CTX_data_edit_mask(const bContext *C)
Definition: context.c:1390
struct ToolSettings * CTX_data_tool_settings(const bContext *C)
Definition: context.c:1282
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
void BKE_editmesh_lnorspace_update(BMEditMesh *em, struct Mesh *me)
Definition: editmesh.c:276
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
Definition: editmesh.c:58
void BKE_mask_coord_to_image(struct Image *image, struct ImageUser *iuser, float r_co[2], const float co[2])
Definition: mask.c:1263
void BKE_mask_coord_to_movieclip(struct MovieClip *clip, struct MovieClipUser *user, float r_co[2], const float co[2])
Definition: mask.c:1246
void BLF_color3ubv(int fontid, const unsigned char rgb[3])
Definition: blf.c:407
int BLF_default(void)
Definition: blf_default.c:44
void BLF_width_and_height(int fontid, const char *str, size_t str_len, float *r_width, float *r_height) ATTR_NONNULL()
Definition: blf.c:662
#define BLF_DRAW_STR_DUMMY_MAX
Definition: BLF_api.h:356
void BLF_draw_default(float x, float y, float z, const char *str, size_t str_len) ATTR_NONNULL()
Definition: blf_default.c:59
#define BLI_assert(a)
Definition: BLI_assert.h:46
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
void unit_m3(float m[3][3])
Definition: math_matrix.c:40
void unit_m4(float m[4][4])
Definition: rct.c:1090
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v2_v2_int(int r[2], const int a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void zero_v3(float r[3])
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:190
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:186
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:194
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition: BLI_rect.h:198
unsigned char uchar
Definition: BLI_sys_types.h:70
#define ARRAY_SIZE(arr)
#define UNUSED(x)
#define ELEM(...)
#define TIP_(msgid)
#define IFACE_(msgid)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:791
@ SACTION_DRAWTIME
@ ME_AUTOSMOOTH
@ OB_MODE_OBJECT
@ OB_MBALL
@ OB_ARMATURE
@ OB_MESH
@ OB_CURVES_LEGACY
@ OB_GPENCIL
#define OBEDIT_FROM_VIEW_LAYER(view_layer)
eSnapTargetSelect
@ SCE_SNAP_TARGET_NOT_ACTIVE
@ SCE_SNAP_TARGET_NOT_NONEDITED
@ SCE_SNAP_TARGET_ONLY_SELECTABLE
@ SCE_SNAP_TARGET_NOT_EDITED
#define UVCALC_TRANSFORM_CORRECT_SLIDE
#define OBACT(_view_layer)
@ PROP_EDIT_PROJECTED
@ PROP_EDIT_USE
@ PROP_EDIT_CONNECTED
@ SCE_SNAP
#define UVCALC_TRANSFORM_CORRECT
#define PROP_MODE_MAX
@ SCE_SNAP_MODE_INCREMENT
@ SCE_SNAP_MODE_GRID
@ RGN_TYPE_WINDOW
#define RGN_TYPE_ANY
@ SI_COORDFLOATS
@ SNODE_INSERTOFS_DIR_RIGHT
@ SNODE_INSERTOFS_DIR_LEFT
@ SPACE_CLIP
@ SPACE_ACTION
@ SPACE_NODE
@ SPACE_NLA
@ SPACE_SEQ
@ SPACE_IMAGE
@ SPACE_GRAPH
@ SPACE_VIEW3D
#define SI_GRID_STEPS_LEN
#define SPACE_TYPE_ANY
@ AUTOKEY_FLAG_NOWARNING
@ V3D_AROUND_CENTER_BOUNDS
@ V3D_AROUND_LOCAL_ORIGINS
@ V3D_ORIENT_NORMAL
@ V3D_ORIENT_CUSTOM_MATRIX
#define V3D_HIDE_OVERLAYS
#define RV3D_ORTHO
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
void ED_clip_point_stable_pos__reverse(struct SpaceClip *sc, struct ARegion *region, const float co[2], float r_co[2])
the reverse of ED_clip_point_stable_pos(), gets the marker region coords. better name here?...
Definition: clip_editor.c:517
void ED_space_clip_get_aspect(struct SpaceClip *sc, float *aspx, float *aspy)
Definition: clip_editor.c:176
bool ED_space_clip_check_show_trackedit(struct SpaceClip *sc)
Definition: clip_editor.c:546
void ED_space_clip_get_aspect_dimension_aware(struct SpaceClip *sc, float *aspx, float *aspy)
Definition: clip_editor.c:197
bool ED_space_clip_check_show_maskedit(struct SpaceClip *sc)
Definition: clip_editor.c:555
struct MovieClip * ED_space_clip_get_clip(struct SpaceClip *sc)
Definition: clip_editor.c:570
float ED_space_image_increment_snap_value(int grid_dimesnions, const float grid_steps[SI_GRID_STEPS_LEN], float zoom_factor)
Definition: image_draw.c:604
void ED_space_image_grid_steps(struct SpaceImage *sima, float grid_steps[SI_GRID_STEPS_LEN], int grid_dimension)
Definition: image_draw.c:587
float ED_space_image_zoom_level(const struct View2D *v2d, int grid_dimension)
void ED_space_image_get_uv_aspect(struct SpaceImage *sima, float *r_aspx, float *r_aspy)
Definition: image_edit.c:262
void ED_image_point_pos__reverse(struct SpaceImage *sima, const struct ARegion *region, const float co[2], float r_co[2])
void ED_space_image_get_size(struct SpaceImage *sima, int *r_width, int *r_height)
Definition: image_edit.c:201
void ED_space_image_get_aspect(struct SpaceImage *sima, float *r_aspx, float *r_aspy)
Definition: image_edit.c:236
#define IS_AUTOKEY_ON(scene)
float ED_node_grid_size(void)
Definition: node_draw.cc:87
#define NUM_MODAL_INCREMENT_DOWN
Definition: ED_numinput.h:96
#define NUM_MODAL_INCREMENT_UP
Definition: ED_numinput.h:95
bool hasNumInput(const NumInput *n)
Definition: numinput.c:170
bool handleNumInput(struct bContext *C, NumInput *n, const struct wmEvent *event)
void ED_area_tag_redraw(ScrArea *area)
Definition: area.c:729
void ED_area_status_text(ScrArea *area, const char *str)
Definition: area.c:792
const rcti * ED_region_visible_rect(ARegion *region)
Definition: area.c:3763
#define REGION_DRAW_POST_VIEW
Definition: ED_space_api.h:62
void * ED_region_draw_cb_activate(struct ARegionType *art, void(*draw)(const struct bContext *, struct ARegion *, void *), void *customdata, int type)
Definition: spacetypes.c:226
#define REGION_DRAW_POST_PIXEL
Definition: ED_space_api.h:63
@ TFM_RESIZE
Definition: ED_transform.h:32
@ TFM_EDGE_SLIDE
Definition: ED_transform.h:59
@ TFM_SHRINKFATTEN
Definition: ED_transform.h:37
@ TFM_VERT_SLIDE
Definition: ED_transform.h:60
@ TFM_ROTATION
Definition: ED_transform.h:31
@ TFM_TRANSLATION
Definition: ED_transform.h:30
@ TFM_NORMAL_ROTATION
Definition: ED_transform.h:63
@ TFM_DUMMY
Definition: ED_transform.h:29
@ TFM_TRACKBALL
Definition: ED_transform.h:39
eV3DProjTest
Definition: ED_view3d.h:233
@ V3D_PROJ_TEST_NOP
Definition: ED_view3d.h:234
void ED_view3d_win_to_delta(const struct ARegion *region, const float xy_delta[2], float zfac, float r_out[3])
eV3DProjStatus ED_view3d_project_float_global(const struct ARegion *region, const float co[3], float r_co[2], eV3DProjTest flag)
@ V3D_PROJ_RET_OK
Definition: ED_view3d.h:217
eV3DProjStatus ED_view3d_project_int_global(const struct ARegion *region, const float co[3], int r_co[2], eV3DProjTest flag)
float ED_view3d_grid_view_scale(struct Scene *scene, struct View3D *v3d, struct ARegion *region, const char **r_grid_unit)
Definition: view3d_draw.c:901
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_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 width
_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
@ GPU_BLEND_NONE
Definition: GPU_state.h:60
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:62
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:39
void GPU_line_width(float width)
Definition: gpu_state.cc:158
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
#define C
Definition: RandGen.cpp:25
void UI_icon_draw(float x, float y, int icon_id)
@ TH_TEXT_HI
Definition: UI_resources.h:43
void UI_GetThemeColorShade3ubv(int colorid, int offset, unsigned char col[3])
Definition: resources.c:1208
void UI_view2d_view_to_region(const struct View2D *v2d, float x, float y, int *r_region_x, int *r_region_y) ATTR_NONNULL()
#define ND_SEQUENCER
Definition: WM_types.h:385
@ KM_PRESS
Definition: WM_types.h:267
@ KM_CLICK_DRAG
Definition: WM_types.h:275
@ KM_RELEASE
Definition: WM_types.h:268
#define ND_TRANSFORM_DONE
Definition: WM_types.h:400
#define NC_GEOM
Definition: WM_types.h:343
@ WM_EVENT_IS_REPEAT
Definition: WM_types.h:613
#define ND_DATA
Definition: WM_types.h:456
#define NC_ANIMATION
Definition: WM_types.h:338
#define NC_MOVIECLIP
Definition: WM_types.h:347
#define NC_SCENE
Definition: WM_types.h:328
#define ND_SPACE_NODE_VIEW
Definition: WM_types.h:479
#define ND_POSE
Definition: WM_types.h:407
#define NA_EDITED
Definition: WM_types.h:523
#define NC_GPENCIL
Definition: WM_types.h:349
#define ND_NLA
Definition: WM_types.h:445
#define ND_TRANSFORM
Definition: WM_types.h:405
@ KM_CTRL
Definition: WM_types.h:239
@ KM_ALT
Definition: WM_types.h:240
@ KM_OSKEY
Definition: WM_types.h:242
@ KM_SHIFT
Definition: WM_types.h:238
#define NC_MASK
Definition: WM_types.h:348
#define ND_KEYS
Definition: WM_types.h:412
#define ND_KEYFRAME
Definition: WM_types.h:442
#define NC_OBJECT
Definition: WM_types.h:329
#define NC_SPACE
Definition: WM_types.h:342
void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all)
void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor)
ATTR_WARN_UNUSED_RESULT const BMVert * v
unsigned int U
Definition: btGjkEpa3.h:78
CCL_NAMESPACE_BEGIN struct Options options
Scene scene
bGPdata * ED_gpencil_data_get_active(const bContext *C)
bool autokeyframe_cfra_can_key(const Scene *scene, ID *id)
Definition: keyframing.c:2850
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
static unsigned a[3]
Definition: RandGen.cpp:78
static void area(int d1, int d2, int e1, int e2, float weights[2])
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2767
bool RNA_property_array_check(PropertyRNA *prop)
Definition: rna_access.c:1080
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:136
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:4874
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:5271
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:3421
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2153
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
Definition: rna_access.c:2180
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
Definition: rna_access.c:4968
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
Definition: rna_access.c:2978
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3402
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
Definition: rna_access.c:2790
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:5015
void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
Definition: rna_access.c:4992
void RNA_property_unset(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:5281
void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const bool *values)
Definition: rna_access.c:2304
void initMouseInput(TransInfo *t, MouseInput *mi, const float center[2], const int mval[2], bool precision)
void calculateCenter(TransInfo *t)
void resetTransRestrictions(TransInfo *t)
void postTrans(struct bContext *C, TransInfo *t)
void calculateCenter2D(TransInfo *t)
void applyMouseInput(struct TransInfo *t, struct MouseInput *mi, const int mval[2], float output[3])
void resetTransModal(TransInfo *t)
void restoreTransObjects(TransInfo *t)
void calculatePropRatio(TransInfo *t)
void initTransInfo(struct bContext *C, TransInfo *t, struct wmOperator *op, const struct wmEvent *event)
void calculateCenterLocal(TransInfo *t, const float center_global[3])
#define FOREACH_TRANS_DATA_CONTAINER(t, th)
void SEQ_image_preview_unit_to_px(const Scene *scene, const float co_src[2], float co_dst[2])
struct BMesh * bm
Definition: BKE_editmesh.h:40
int totvert
Definition: bmesh_class.h:297
int totvertsel
Definition: bmesh_class.h:298
float persmat[4][4]
float persinv[4][4]
float viewmat[4][4]
float viewinv[4][4]
struct MovieClipUser user
struct MovieClip * clip
struct ImageUser iuser
struct Image * image
int ymax
Definition: DNA_vec_types.h:64
int xmax
Definition: DNA_vec_types.h:63
short val
Definition: WM_types.h:680
short prev_type
Definition: WM_types.h:720
int mval[2]
Definition: WM_types.h:684
uint8_t modifier
Definition: WM_types.h:693
eWM_EventFlag flag
Definition: WM_types.h:707
short prev_val
Definition: WM_types.h:722
short type
Definition: WM_types.h:678
struct wmKeyMapItem * next
bool(* poll_modal_item)(const struct wmOperator *op, int value)
const PropertyRNA * prop
struct wmKeyMap * modalkeymap
Definition: WM_types.h:987
struct wmOperatorType * type
struct PointerRNA * ptr
wmKeyMap * transform_modal_keymap(wmKeyConfig *keyconf)
Definition: transform.c:654
void projectFloatViewEx(TransInfo *t, const float vec[3], float adr[2], const eV3DProjTest flag)
Definition: transform.c:338
bool checkUseAxisMatrix(TransInfo *t)
Definition: transform.c:2062
static bool transform_modal_item_poll(const wmOperator *op, int value)
Definition: transform.c:561
void transformApply(bContext *C, TransInfo *t)
Definition: transform.c:1998
static void convertViewVec2D(View2D *v2d, float r_vec[3], int dx, int dy)
Definition: transform.c:135
static void drawTransformView(const struct bContext *C, ARegion *region, void *arg)
Definition: transform.c:1411
static void initSnapSpatial(TransInfo *t, float r_snap[2])
Definition: transform.c:1721
void setTransformViewAspect(TransInfo *t, float r_aspect[3])
Definition: transform.c:98
static void drawTransformPixel(const struct bContext *C, ARegion *region, void *arg)
Definition: transform.c:1468
bool transdata_check_local_islands(TransInfo *t, short around)
Definition: transform.c:64
void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
Definition: transform.c:1498
static bool transform_event_modal_constraint(TransInfo *t, short modal_type)
Definition: transform.c:786
bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event, int mode)
Definition: transform.c:1758
void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DProjTest flag)
Definition: transform.c:220
void convertViewVec(TransInfo *t, float r_vec[3], double dx, double dy)
Definition: transform.c:170
int transformEvent(TransInfo *t, const wmEvent *event)
Definition: transform.c:895
void removeAspectRatio(TransInfo *t, float vec[2])
Definition: transform.c:396
void transform_final_value_get(const TransInfo *t, float *value, const int value_num)
Definition: transform.c:2085
bool transform_apply_matrix(TransInfo *t, float mat[4][4])
Definition: transform.c:2076
static void viewRedrawPost(bContext *C, TransInfo *t)
Definition: transform.c:513
static void viewRedrawForce(const bContext *C, TransInfo *t)
Definition: transform.c:420
void setTransformViewMatrices(TransInfo *t)
Definition: transform.c:74
bool calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], float cent2d[2])
Definition: transform.c:1341
static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *region)
Definition: transform.c:1434
void projectFloatView(TransInfo *t, const float vec[3], float adr[2])
Definition: transform.c:366
static void convertViewVec2D_mask(View2D *v2d, float r_vec[3], int dx, int dy)
Definition: transform.c:145
void projectIntView(TransInfo *t, const float vec[3], int adr[2])
Definition: transform.c:333
void applyAspectRatio(TransInfo *t, float vec[2])
Definition: transform.c:371
static bool transinfo_show_overlay(const struct bContext *C, TransInfo *t, ARegion *region)
Definition: transform.c:1392
int transformEnd(bContext *C, TransInfo *t)
Definition: transform.c:2023
void drawConstraint(TransInfo *t)
void drawPropCircle(const struct bContext *C, TransInfo *t)
int constraintModeToIndex(const TransInfo *t)
void postSelectConstraint(TransInfo *t)
void setUserConstraint(TransInfo *t, int mode, const char ftext[])
void stopConstraint(TransInfo *t)
void setLocalConstraint(TransInfo *t, int mode, const char text[])
void initSelectConstraint(TransInfo *t)
void selectConstraint(TransInfo *t)
void transform_autoik_update(TransInfo *t, short mode)
void special_aftertrans_update(bContext *C, TransInfo *t)
void sort_trans_data_dist(TransInfo *t)
void createTransData(bContext *C, TransInfo *t)
conversion and adaptation of different datablocks to a common struct.
TransConvertTypeInfo TransConvertType_SequencerImage
TransConvertTypeInfo TransConvertType_Mesh
@ TD_SELECTED
#define T_PROP_SIZE_MIN
#define T_PROP_SIZE_MAX
bool transform_draw_cursor_poll(bContext *C)
void transform_draw_cursor_draw(bContext *UNUSED(C), int x, int y, void *customdata)
void transform_mode_init(TransInfo *t, wmOperator *op, const int mode)
bool transform_mode_is_changeable(const int mode)
eTfmMode transform_mode_really_used(bContext *C, eTfmMode mode)
transform modes used by different operators.
void drawEdgeSlide(TransInfo *t)
void drawVertSlide(TransInfo *t)
void transform_orientations_current_set(TransInfo *t, const short orient_index)
bool transformModeUseSnap(const TransInfo *t)
void addSnapPoint(TransInfo *t)
bool validSnap(const TransInfo *t)
eRedrawFlag handleSnapping(TransInfo *t, const wmEvent *event)
void removeSnapPoint(TransInfo *t)
void drawSnapping(const struct bContext *C, TransInfo *t)
void initSnapping(TransInfo *t, wmOperator *op)
void WM_paint_cursor_tag_redraw(wmWindow *win, ARegion *UNUSED(region))
Definition: wm_draw.c:1294
void WM_event_drag_start_mval(const wmEvent *event, const ARegion *region, int r_mval[2])
int WM_userdef_event_type_from_keymap_type(int kmitype)
void WM_window_status_area_tag_redraw(wmWindow *win)
void WM_main_add_notifier(unsigned int type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
#define ISMOUSE_MOTION(event_type)
@ EVT_OKEY
@ EVT_MODAL_MAP
@ EVT_RIGHTCTRLKEY
@ EVT_CKEY
@ EVT_OSKEY
@ EVT_LEFTCTRLKEY
@ MOUSEMOVE
@ EVT_RIGHTALTKEY
@ EVT_PADMINUS
@ EVT_NKEY
@ EVT_LEFTALTKEY
@ EVT_RIGHTSHIFTKEY
@ EVT_LEFTSHIFTKEY
@ EVT_PADPLUSKEY
wmKeyMap * WM_keymap_active(const wmWindowManager *wm, wmKeyMap *keymap)
Definition: wm_keymap.c:1943
wmKeyMap * WM_modalkeymap_ensure(wmKeyConfig *keyconf, const char *idname, const EnumPropertyItem *items)
Definition: wm_keymap.c:888
void WM_msg_publish_rna_params(struct wmMsgBus *mbus, const wmMsgParams_RNA *msg_key_params)
wmPaintCursor * WM_paint_cursor_activate(short space_type, short region_type, bool(*poll)(bContext *C), wmPaintCursorDraw draw, void *customdata)