Blender  V2.93
transform_gizmo_3d.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
25 #include <float.h>
26 #include <math.h>
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #include "DNA_armature_types.h"
31 #include "DNA_curve_types.h"
32 #include "DNA_gpencil_types.h"
33 #include "DNA_lattice_types.h"
34 #include "DNA_meta_types.h"
35 #include "DNA_scene_types.h"
36 #include "DNA_screen_types.h"
37 #include "DNA_view3d_types.h"
38 
39 #include "BLI_array_utils.h"
40 #include "BLI_listbase.h"
41 #include "BLI_math.h"
42 #include "BLI_utildefines.h"
43 
44 #include "BKE_action.h"
45 #include "BKE_armature.h"
46 #include "BKE_context.h"
47 #include "BKE_curve.h"
48 #include "BKE_editmesh.h"
49 #include "BKE_global.h"
50 #include "BKE_gpencil.h"
51 #include "BKE_layer.h"
52 #include "BKE_object.h"
53 #include "BKE_paint.h"
54 #include "BKE_pointcache.h"
55 #include "BKE_scene.h"
56 
57 #include "DEG_depsgraph.h"
58 
59 #include "WM_api.h"
60 #include "WM_message.h"
61 #include "WM_types.h"
62 #include "wm.h"
63 
64 #include "ED_armature.h"
65 #include "ED_gizmo_library.h"
66 #include "ED_gizmo_utils.h"
67 #include "ED_gpencil.h"
68 #include "ED_object.h"
69 #include "ED_particle.h"
70 #include "ED_screen.h"
71 #include "ED_view3d.h"
72 
73 #include "UI_interface.h"
74 #include "UI_resources.h"
75 
76 #include "RNA_access.h"
77 #include "RNA_define.h"
78 
79 /* local module include */
80 #include "transform.h"
81 #include "transform_convert.h"
82 #include "transform_snap.h"
83 
84 #include "MEM_guardedalloc.h"
85 
86 #include "GPU_state.h"
87 
88 /* return codes for select, and drawing flags */
89 
90 #define MAN_TRANS_X (1 << 0)
91 #define MAN_TRANS_Y (1 << 1)
92 #define MAN_TRANS_Z (1 << 2)
93 #define MAN_TRANS_C (MAN_TRANS_X | MAN_TRANS_Y | MAN_TRANS_Z)
94 
95 #define MAN_ROT_X (1 << 3)
96 #define MAN_ROT_Y (1 << 4)
97 #define MAN_ROT_Z (1 << 5)
98 #define MAN_ROT_C (MAN_ROT_X | MAN_ROT_Y | MAN_ROT_Z)
99 
100 #define MAN_SCALE_X (1 << 8)
101 #define MAN_SCALE_Y (1 << 9)
102 #define MAN_SCALE_Z (1 << 10)
103 #define MAN_SCALE_C (MAN_SCALE_X | MAN_SCALE_Y | MAN_SCALE_Z)
104 
105 /* threshold for testing view aligned gizmo axis */
106 static struct {
107  float min, max;
108 } g_tw_axis_range[2] = {
109  /* Regular range */
110  {0.02f, 0.1f},
111  /* Use a different range because we flip the dot product,
112  * also the view aligned planes are harder to see so hiding early is preferred. */
113  {0.175f, 0.25f},
114 };
115 
116 /* axes as index */
117 enum {
122 
126 #define MAN_AXIS_RANGE_TRANS_START MAN_AXIS_TRANS_X
127 #define MAN_AXIS_RANGE_TRANS_END (MAN_AXIS_TRANS_ZX + 1)
128 
133  MAN_AXIS_ROT_T, /* trackball rotation */
134 #define MAN_AXIS_RANGE_ROT_START MAN_AXIS_ROT_X
135 #define MAN_AXIS_RANGE_ROT_END (MAN_AXIS_ROT_T + 1)
136 
144 #define MAN_AXIS_RANGE_SCALE_START MAN_AXIS_SCALE_X
145 #define MAN_AXIS_RANGE_SCALE_END (MAN_AXIS_SCALE_ZX + 1)
146 
148 };
149 
150 /* axis types */
151 enum {
156 };
157 
158 typedef struct GizmoGroup {
160  int twtype;
161 
162  /* Users may change the twtype, detect changes to re-setup gizmo options. */
166 
167  /* Only for view orientation. */
168  struct {
169  float viewinv_m3[3][3];
170  } prev;
171 
174 
175 /* -------------------------------------------------------------------- */
179 /* loop over axes */
180 #define MAN_ITER_AXES_BEGIN(axis, axis_idx) \
181  { \
182  wmGizmo *axis; \
183  int axis_idx; \
184  for (axis_idx = 0; axis_idx < MAN_AXIS_LAST; axis_idx++) { \
185  axis = gizmo_get_axis_from_index(ggd, axis_idx);
186 
187 #define MAN_ITER_AXES_END \
188  } \
189  } \
190  ((void)0)
191 
192 static wmGizmo *gizmo_get_axis_from_index(const GizmoGroup *ggd, const short axis_idx)
193 {
194  BLI_assert(IN_RANGE_INCL(axis_idx, (float)MAN_AXIS_TRANS_X, (float)MAN_AXIS_LAST));
195  return ggd->gizmos[axis_idx];
196 }
197 
198 static short gizmo_get_axis_type(const int axis_idx)
199 {
200  if (axis_idx >= MAN_AXIS_RANGE_TRANS_START && axis_idx < MAN_AXIS_RANGE_TRANS_END) {
201  return MAN_AXES_TRANSLATE;
202  }
203  if (axis_idx >= MAN_AXIS_RANGE_ROT_START && axis_idx < MAN_AXIS_RANGE_ROT_END) {
204  return MAN_AXES_ROTATE;
205  }
206  if (axis_idx >= MAN_AXIS_RANGE_SCALE_START && axis_idx < MAN_AXIS_RANGE_SCALE_END) {
207  return MAN_AXES_SCALE;
208  }
209  BLI_assert(0);
210  return -1;
211 }
212 
213 static uint gizmo_orientation_axis(const int axis_idx, bool *r_is_plane)
214 {
215  switch (axis_idx) {
216  case MAN_AXIS_TRANS_YZ:
217  case MAN_AXIS_SCALE_YZ:
218  if (r_is_plane) {
219  *r_is_plane = true;
220  }
222  case MAN_AXIS_TRANS_X:
223  case MAN_AXIS_ROT_X:
224  case MAN_AXIS_SCALE_X:
225  return 0;
226 
227  case MAN_AXIS_TRANS_ZX:
228  case MAN_AXIS_SCALE_ZX:
229  if (r_is_plane) {
230  *r_is_plane = true;
231  }
233  case MAN_AXIS_TRANS_Y:
234  case MAN_AXIS_ROT_Y:
235  case MAN_AXIS_SCALE_Y:
236  return 1;
237 
238  case MAN_AXIS_TRANS_XY:
239  case MAN_AXIS_SCALE_XY:
240  if (r_is_plane) {
241  *r_is_plane = true;
242  }
244  case MAN_AXIS_TRANS_Z:
245  case MAN_AXIS_ROT_Z:
246  case MAN_AXIS_SCALE_Z:
247  return 2;
248  }
249  return 3;
250 }
251 
252 static bool gizmo_is_axis_visible(const RegionView3D *rv3d,
253  const int twtype,
254  const float idot[3],
255  const int axis_type,
256  const int axis_idx)
257 {
258  if ((axis_idx >= MAN_AXIS_RANGE_ROT_START && axis_idx < MAN_AXIS_RANGE_ROT_END) == 0) {
259  bool is_plane = false;
260  const uint aidx_norm = gizmo_orientation_axis(axis_idx, &is_plane);
261  /* don't draw axis perpendicular to the view */
262  if (aidx_norm < 3) {
263  float idot_axis = idot[aidx_norm];
264  if (is_plane) {
265  idot_axis = 1.0f - idot_axis;
266  }
267  if (idot_axis < g_tw_axis_range[is_plane].min) {
268  return false;
269  }
270  }
271  }
272 
273  if ((axis_type == MAN_AXES_TRANSLATE && !(twtype & V3D_GIZMO_SHOW_OBJECT_TRANSLATE)) ||
274  (axis_type == MAN_AXES_ROTATE && !(twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE)) ||
275  (axis_type == MAN_AXES_SCALE && !(twtype & V3D_GIZMO_SHOW_OBJECT_SCALE))) {
276  return false;
277  }
278 
279  switch (axis_idx) {
280  case MAN_AXIS_TRANS_X:
281  return (rv3d->twdrawflag & MAN_TRANS_X);
282  case MAN_AXIS_TRANS_Y:
283  return (rv3d->twdrawflag & MAN_TRANS_Y);
284  case MAN_AXIS_TRANS_Z:
285  return (rv3d->twdrawflag & MAN_TRANS_Z);
286  case MAN_AXIS_TRANS_C:
287  return (rv3d->twdrawflag & MAN_TRANS_C);
288  case MAN_AXIS_ROT_X:
289  return (rv3d->twdrawflag & MAN_ROT_X);
290  case MAN_AXIS_ROT_Y:
291  return (rv3d->twdrawflag & MAN_ROT_Y);
292  case MAN_AXIS_ROT_Z:
293  return (rv3d->twdrawflag & MAN_ROT_Z);
294  case MAN_AXIS_ROT_C:
295  case MAN_AXIS_ROT_T:
296  return (rv3d->twdrawflag & MAN_ROT_C);
297  case MAN_AXIS_SCALE_X:
298  return (rv3d->twdrawflag & MAN_SCALE_X);
299  case MAN_AXIS_SCALE_Y:
300  return (rv3d->twdrawflag & MAN_SCALE_Y);
301  case MAN_AXIS_SCALE_Z:
302  return (rv3d->twdrawflag & MAN_SCALE_Z);
303  case MAN_AXIS_SCALE_C:
304  return (rv3d->twdrawflag & MAN_SCALE_C && (twtype & V3D_GIZMO_SHOW_OBJECT_TRANSLATE) == 0);
305  case MAN_AXIS_TRANS_XY:
306  return (rv3d->twdrawflag & MAN_TRANS_X && rv3d->twdrawflag & MAN_TRANS_Y &&
307  (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
308  case MAN_AXIS_TRANS_YZ:
309  return (rv3d->twdrawflag & MAN_TRANS_Y && rv3d->twdrawflag & MAN_TRANS_Z &&
310  (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
311  case MAN_AXIS_TRANS_ZX:
312  return (rv3d->twdrawflag & MAN_TRANS_Z && rv3d->twdrawflag & MAN_TRANS_X &&
313  (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
314  case MAN_AXIS_SCALE_XY:
315  return (rv3d->twdrawflag & MAN_SCALE_X && rv3d->twdrawflag & MAN_SCALE_Y &&
316  (twtype & V3D_GIZMO_SHOW_OBJECT_TRANSLATE) == 0 &&
317  (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
318  case MAN_AXIS_SCALE_YZ:
319  return (rv3d->twdrawflag & MAN_SCALE_Y && rv3d->twdrawflag & MAN_SCALE_Z &&
320  (twtype & V3D_GIZMO_SHOW_OBJECT_TRANSLATE) == 0 &&
321  (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
322  case MAN_AXIS_SCALE_ZX:
323  return (rv3d->twdrawflag & MAN_SCALE_Z && rv3d->twdrawflag & MAN_SCALE_X &&
324  (twtype & V3D_GIZMO_SHOW_OBJECT_TRANSLATE) == 0 &&
325  (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
326  }
327  return false;
328 }
329 
330 static void gizmo_get_axis_color(const int axis_idx,
331  const float idot[3],
332  float r_col[4],
333  float r_col_hi[4])
334 {
335  /* alpha values for normal/highlighted states */
336  const float alpha = 0.6f;
337  const float alpha_hi = 1.0f;
338  float alpha_fac;
339 
340  if (axis_idx >= MAN_AXIS_RANGE_ROT_START && axis_idx < MAN_AXIS_RANGE_ROT_END) {
341  /* Never fade rotation rings. */
342  /* trackball rotation axis is a special case, we only draw a slight overlay */
343  alpha_fac = (axis_idx == MAN_AXIS_ROT_T) ? 0.05f : 1.0f;
344  }
345  else {
346  bool is_plane = false;
347  const int axis_idx_norm = gizmo_orientation_axis(axis_idx, &is_plane);
348  /* Get alpha fac based on axis angle,
349  * to fade axis out when hiding it because it points towards view. */
350  if (axis_idx_norm < 3) {
351  const float idot_min = g_tw_axis_range[is_plane].min;
352  const float idot_max = g_tw_axis_range[is_plane].max;
353  float idot_axis = idot[axis_idx_norm];
354  if (is_plane) {
355  idot_axis = 1.0f - idot_axis;
356  }
357  alpha_fac = ((idot_axis > idot_max) ?
358  1.0f :
359  (idot_axis < idot_min) ? 0.0f :
360  ((idot_axis - idot_min) / (idot_max - idot_min)));
361  }
362  else {
363  alpha_fac = 1.0f;
364  }
365  }
366 
367  switch (axis_idx) {
368  case MAN_AXIS_TRANS_X:
369  case MAN_AXIS_ROT_X:
370  case MAN_AXIS_SCALE_X:
371  case MAN_AXIS_TRANS_YZ:
372  case MAN_AXIS_SCALE_YZ:
374  break;
375  case MAN_AXIS_TRANS_Y:
376  case MAN_AXIS_ROT_Y:
377  case MAN_AXIS_SCALE_Y:
378  case MAN_AXIS_TRANS_ZX:
379  case MAN_AXIS_SCALE_ZX:
381  break;
382  case MAN_AXIS_TRANS_Z:
383  case MAN_AXIS_ROT_Z:
384  case MAN_AXIS_SCALE_Z:
385  case MAN_AXIS_TRANS_XY:
386  case MAN_AXIS_SCALE_XY:
388  break;
389  case MAN_AXIS_TRANS_C:
390  case MAN_AXIS_ROT_C:
391  case MAN_AXIS_SCALE_C:
392  case MAN_AXIS_ROT_T:
394  break;
395  }
396 
397  copy_v4_v4(r_col_hi, r_col);
398 
399  r_col[3] = alpha * alpha_fac;
400  r_col_hi[3] = alpha_hi * alpha_fac;
401 }
402 
403 static void gizmo_get_axis_constraint(const int axis_idx, bool r_axis[3])
404 {
405  ARRAY_SET_ITEMS(r_axis, 0, 0, 0);
406 
407  switch (axis_idx) {
408  case MAN_AXIS_TRANS_X:
409  case MAN_AXIS_ROT_X:
410  case MAN_AXIS_SCALE_X:
411  r_axis[0] = 1;
412  break;
413  case MAN_AXIS_TRANS_Y:
414  case MAN_AXIS_ROT_Y:
415  case MAN_AXIS_SCALE_Y:
416  r_axis[1] = 1;
417  break;
418  case MAN_AXIS_TRANS_Z:
419  case MAN_AXIS_ROT_Z:
420  case MAN_AXIS_SCALE_Z:
421  r_axis[2] = 1;
422  break;
423  case MAN_AXIS_TRANS_XY:
424  case MAN_AXIS_SCALE_XY:
425  r_axis[0] = r_axis[1] = 1;
426  break;
427  case MAN_AXIS_TRANS_YZ:
428  case MAN_AXIS_SCALE_YZ:
429  r_axis[1] = r_axis[2] = 1;
430  break;
431  case MAN_AXIS_TRANS_ZX:
432  case MAN_AXIS_SCALE_ZX:
433  r_axis[2] = r_axis[0] = 1;
434  break;
435  default:
436  break;
437  }
438 }
439 
440 /* **************** Preparation Stuff **************** */
441 
442 static void reset_tw_center(struct TransformBounds *tbounds)
443 {
444  INIT_MINMAX(tbounds->min, tbounds->max);
445  zero_v3(tbounds->center);
446 
447  for (int i = 0; i < 3; i++) {
448  tbounds->axis_min[i] = +FLT_MAX;
449  tbounds->axis_max[i] = -FLT_MAX;
450  }
451 }
452 
453 /* transform widget center calc helper for below */
454 static void calc_tw_center(struct TransformBounds *tbounds, const float co[3])
455 {
456  minmax_v3v3_v3(tbounds->min, tbounds->max, co);
457  add_v3_v3(tbounds->center, co);
458 
459  for (int i = 0; i < 3; i++) {
460  const float d = dot_v3v3(tbounds->axis[i], co);
461  tbounds->axis_min[i] = min_ff(d, tbounds->axis_min[i]);
462  tbounds->axis_max[i] = max_ff(d, tbounds->axis_max[i]);
463  }
464 }
465 
466 static void calc_tw_center_with_matrix(struct TransformBounds *tbounds,
467  const float co[3],
468  const bool use_matrix,
469  const float matrix[4][4])
470 {
471  float co_world[3];
472  if (use_matrix) {
473  mul_v3_m4v3(co_world, matrix, co);
474  co = co_world;
475  }
476  calc_tw_center(tbounds, co);
477 }
478 
479 static void protectflag_to_drawflags(short protectflag, short *drawflags)
480 {
481  if (protectflag & OB_LOCK_LOCX) {
482  *drawflags &= ~MAN_TRANS_X;
483  }
484  if (protectflag & OB_LOCK_LOCY) {
485  *drawflags &= ~MAN_TRANS_Y;
486  }
487  if (protectflag & OB_LOCK_LOCZ) {
488  *drawflags &= ~MAN_TRANS_Z;
489  }
490 
491  if (protectflag & OB_LOCK_ROTX) {
492  *drawflags &= ~MAN_ROT_X;
493  }
494  if (protectflag & OB_LOCK_ROTY) {
495  *drawflags &= ~MAN_ROT_Y;
496  }
497  if (protectflag & OB_LOCK_ROTZ) {
498  *drawflags &= ~MAN_ROT_Z;
499  }
500 
501  if (protectflag & OB_LOCK_SCALEX) {
502  *drawflags &= ~MAN_SCALE_X;
503  }
504  if (protectflag & OB_LOCK_SCALEY) {
505  *drawflags &= ~MAN_SCALE_Y;
506  }
507  if (protectflag & OB_LOCK_SCALEZ) {
508  *drawflags &= ~MAN_SCALE_Z;
509  }
510 }
511 
512 /* for pose mode */
514  const bPoseChannel *pchan,
515  short orientation_index)
516 {
517  /* Protect-flags apply to local space in pose mode, so only let them influence axis
518  * visibility if we show the global orientation, otherwise it's confusing. */
519  if (orientation_index == V3D_ORIENT_LOCAL) {
521  }
522 }
523 
524 /* for editmode*/
526 {
527  if (ebo->flag & BONE_EDITMODE_LOCKED) {
529  }
530 }
531 
532 /* could move into BLI_math however this is only useful for display/editing purposes */
533 static void axis_angle_to_gimbal_axis(float gmat[3][3], const float axis[3], const float angle)
534 {
535  /* X/Y are arbitrary axes, most importantly Z is the axis of rotation. */
536 
537  float cross_vec[3];
538  float quat[4];
539 
540  /* this is an un-scientific method to get a vector to cross with
541  * XYZ intentionally YZX */
542  cross_vec[0] = axis[1];
543  cross_vec[1] = axis[2];
544  cross_vec[2] = axis[0];
545 
546  /* X-axis */
547  cross_v3_v3v3(gmat[0], cross_vec, axis);
548  normalize_v3(gmat[0]);
549  axis_angle_to_quat(quat, axis, angle);
550  mul_qt_v3(quat, gmat[0]);
551 
552  /* Y-axis */
553  axis_angle_to_quat(quat, axis, M_PI_2);
554  copy_v3_v3(gmat[1], gmat[0]);
555  mul_qt_v3(quat, gmat[1]);
556 
557  /* Z-axis */
558  copy_v3_v3(gmat[2], axis);
559 
560  normalize_m3(gmat);
561 }
562 
563 static bool test_rotmode_euler(short rotmode)
564 {
565  return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1;
566 }
567 
571 bool gimbal_axis(Object *ob, float gmat[3][3])
572 {
573  if (ob->mode & OB_MODE_POSE) {
575 
576  if (pchan) {
577  float mat[3][3], tmat[3][3], obmat[3][3];
578  if (test_rotmode_euler(pchan->rotmode)) {
579  eulO_to_gimbal_axis(mat, pchan->eul, pchan->rotmode);
580  }
581  else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
582  axis_angle_to_gimbal_axis(mat, pchan->rotAxis, pchan->rotAngle);
583  }
584  else { /* quat */
585  return 0;
586  }
587 
588  /* apply bone transformation */
589  mul_m3_m3m3(tmat, pchan->bone->bone_mat, mat);
590 
591  if (pchan->parent) {
592  float parent_mat[3][3];
593 
594  copy_m3_m4(parent_mat,
595  (pchan->bone->flag & BONE_HINGE) ? pchan->parent->bone->arm_mat :
596  pchan->parent->pose_mat);
597  mul_m3_m3m3(mat, parent_mat, tmat);
598 
599  /* needed if object transformation isn't identity */
600  copy_m3_m4(obmat, ob->obmat);
601  mul_m3_m3m3(gmat, obmat, mat);
602  }
603  else {
604  /* needed if object transformation isn't identity */
605  copy_m3_m4(obmat, ob->obmat);
606  mul_m3_m3m3(gmat, obmat, tmat);
607  }
608 
609  normalize_m3(gmat);
610  return 1;
611  }
612  }
613  else {
614  if (test_rotmode_euler(ob->rotmode)) {
615  eulO_to_gimbal_axis(gmat, ob->rot, ob->rotmode);
616  }
617  else if (ob->rotmode == ROT_MODE_AXISANGLE) {
619  }
620  else { /* quat */
621  return 0;
622  }
623 
624  if (ob->parent) {
625  float parent_mat[3][3];
626  copy_m3_m4(parent_mat, ob->parent->obmat);
627  normalize_m3(parent_mat);
628  mul_m3_m3m3(gmat, parent_mat, gmat);
629  }
630  return 1;
631  }
632 
633  return 0;
634 }
635 
636 /* centroid, boundbox, of selection */
637 /* returns total items selected */
639  const struct TransformCalcParams *params,
640  struct TransformBounds *tbounds)
641 {
643  ARegion *region = CTX_wm_region(C);
645  /* TODO(sergey): This function is used from operator's modal() and from gizmo's refresh().
646  * Is it fine to possibly evaluate dependency graph here? */
648  ViewLayer *view_layer = CTX_data_view_layer(C);
649  View3D *v3d = area->spacedata.first;
650  Object *obedit = CTX_data_edit_object(C);
651  RegionView3D *rv3d = region->regiondata;
652  Base *base;
653  Object *ob = OBACT(view_layer);
655  const bool is_gp_edit = GPENCIL_ANY_MODE(gpd);
656  const bool is_curve_edit = GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd);
657  int a, totsel = 0;
658 
659  const int pivot_point = scene->toolsettings->transform_pivot_point;
660  const short orient_index = params->orientation_index ?
661  (params->orientation_index - 1) :
663 
664  /* transform widget matrix */
665  unit_m4(rv3d->twmat);
666 
667  unit_m3(rv3d->tw_axis_matrix);
668  zero_v3(rv3d->tw_axis_min);
669  zero_v3(rv3d->tw_axis_max);
670 
671  rv3d->twdrawflag = 0xFFFF;
672 
673  /* global, local or normal orientation?
674  * if we could check 'totsel' now, this should be skipped with no selection. */
675  if (ob) {
676  float mat[3][3];
678  C, mat, scene, rv3d, ob, obedit, orient_index, pivot_point);
679  copy_m4_m3(rv3d->twmat, mat);
680  }
681 
682  /* transform widget centroid/center */
683  reset_tw_center(tbounds);
684 
685  copy_m3_m4(tbounds->axis, rv3d->twmat);
686  if (params->use_local_axis && (ob && ob->mode & OB_MODE_EDIT)) {
687  float diff_mat[3][3];
688  copy_m3_m4(diff_mat, ob->obmat);
689  normalize_m3(diff_mat);
690  invert_m3(diff_mat);
691  mul_m3_m3m3(tbounds->axis, tbounds->axis, diff_mat);
692  normalize_m3(tbounds->axis);
693  }
694 
695  if (is_gp_edit) {
696  float diff_mat[4][4];
697  const bool use_mat_local = true;
698  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
699  /* only editable and visible layers are considered */
700 
701  if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
702 
703  /* calculate difference matrix */
705 
706  LISTBASE_FOREACH (bGPDstroke *, gps, &gpl->actframe->strokes) {
707  /* skip strokes that are invalid for current view */
708  if (ED_gpencil_stroke_can_use(C, gps) == false) {
709  continue;
710  }
711 
712  if (is_curve_edit) {
713  if (gps->editcurve == NULL) {
714  continue;
715  }
716 
717  bGPDcurve *gpc = gps->editcurve;
718  if (gpc->flag & GP_CURVE_SELECT) {
719  for (uint32_t i = 0; i < gpc->tot_curve_points; i++) {
720  bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
721  BezTriple *bezt = &gpc_pt->bezt;
722  if (gpc_pt->flag & GP_CURVE_POINT_SELECT) {
723  for (uint32_t j = 0; j < 3; j++) {
724  if (BEZT_ISSEL_IDX(bezt, j)) {
725  calc_tw_center_with_matrix(tbounds, bezt->vec[j], use_mat_local, diff_mat);
726  totsel++;
727  }
728  }
729  }
730  }
731  }
732  }
733  else {
734  /* we're only interested in selected points here... */
735  if (gps->flag & GP_STROKE_SELECT) {
736  bGPDspoint *pt;
737  int i;
738 
739  /* Change selection status of all points, then make the stroke match */
740  for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
741  if (pt->flag & GP_SPOINT_SELECT) {
742  calc_tw_center_with_matrix(tbounds, &pt->x, use_mat_local, diff_mat);
743  totsel++;
744  }
745  }
746  }
747  }
748  }
749  }
750  }
751 
752  /* selection center */
753  if (totsel) {
754  mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */
755  }
756  }
757  else if (obedit) {
758 
759 #define FOREACH_EDIT_OBJECT_BEGIN(ob_iter, use_mat_local) \
760  { \
761  invert_m4_m4(obedit->imat, obedit->obmat); \
762  uint objects_len = 0; \
763  Object **objects = BKE_view_layer_array_from_objects_in_edit_mode( \
764  view_layer, CTX_wm_view3d(C), &objects_len); \
765  for (uint ob_index = 0; ob_index < objects_len; ob_index++) { \
766  Object *ob_iter = objects[ob_index]; \
767  const bool use_mat_local = (ob_iter != obedit);
768 
769 #define FOREACH_EDIT_OBJECT_END() \
770  } \
771  MEM_freeN(objects); \
772  } \
773  ((void)0)
774 
775  ob = obedit;
776  if (obedit->type == OB_MESH) {
777  FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) {
778  BMEditMesh *em_iter = BKE_editmesh_from_object(ob_iter);
779  BMesh *bm = em_iter->bm;
780 
781  if (bm->totvertsel == 0) {
782  continue;
783  }
784 
785  BMVert *eve;
786  BMIter iter;
787 
788  float mat_local[4][4];
789  if (use_mat_local) {
790  mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
791  }
792 
793  BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
794  if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
795  if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
796  calc_tw_center_with_matrix(tbounds, eve->co, use_mat_local, mat_local);
797  totsel++;
798  }
799  }
800  }
801  }
803  } /* end editmesh */
804  else if (obedit->type == OB_ARMATURE) {
805  FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) {
806  bArmature *arm = ob_iter->data;
807 
808  float mat_local[4][4];
809  if (use_mat_local) {
810  mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
811  }
812  LISTBASE_FOREACH (EditBone *, ebo, arm->edbo) {
813  if (EBONE_VISIBLE(arm, ebo)) {
814  if (ebo->flag & BONE_TIPSEL) {
815  calc_tw_center_with_matrix(tbounds, ebo->tail, use_mat_local, mat_local);
816  totsel++;
817  }
818  if ((ebo->flag & BONE_ROOTSEL) &&
819  /* don't include same point multiple times */
820  ((ebo->flag & BONE_CONNECTED) && (ebo->parent != NULL) &&
821  (ebo->parent->flag & BONE_TIPSEL) && EBONE_VISIBLE(arm, ebo->parent)) == 0) {
822  calc_tw_center_with_matrix(tbounds, ebo->head, use_mat_local, mat_local);
823  totsel++;
824  }
825  if (ebo->flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)) {
827  }
828  }
829  }
830  }
832  }
833  else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
834  FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) {
835  Curve *cu = ob_iter->data;
836  Nurb *nu;
837  BezTriple *bezt;
838  BPoint *bp;
839  ListBase *nurbs = BKE_curve_editNurbs_get(cu);
840 
841  float mat_local[4][4];
842  if (use_mat_local) {
843  mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
844  }
845 
846  nu = nurbs->first;
847  while (nu) {
848  if (nu->type == CU_BEZIER) {
849  bezt = nu->bezt;
850  a = nu->pntsu;
851  while (a--) {
852  /* exceptions
853  * if handles are hidden then only check the center points.
854  * If the center knot is selected then only use this as the center point.
855  */
857  if (bezt->f2 & SELECT) {
858  calc_tw_center_with_matrix(tbounds, bezt->vec[1], use_mat_local, mat_local);
859  totsel++;
860  }
861  }
862  else if (bezt->f2 & SELECT) {
863  calc_tw_center_with_matrix(tbounds, bezt->vec[1], use_mat_local, mat_local);
864  totsel++;
865  }
866  else {
867  if (bezt->f1 & SELECT) {
868  const float *co = bezt->vec[(pivot_point == V3D_AROUND_LOCAL_ORIGINS) ? 1 : 0];
869  calc_tw_center_with_matrix(tbounds, co, use_mat_local, mat_local);
870  totsel++;
871  }
872  if (bezt->f3 & SELECT) {
873  const float *co = bezt->vec[(pivot_point == V3D_AROUND_LOCAL_ORIGINS) ? 1 : 2];
874  calc_tw_center_with_matrix(tbounds, co, use_mat_local, mat_local);
875  totsel++;
876  }
877  }
878  bezt++;
879  }
880  }
881  else {
882  bp = nu->bp;
883  a = nu->pntsu * nu->pntsv;
884  while (a--) {
885  if (bp->f1 & SELECT) {
886  calc_tw_center_with_matrix(tbounds, bp->vec, use_mat_local, mat_local);
887  totsel++;
888  }
889  bp++;
890  }
891  }
892  nu = nu->next;
893  }
894  }
896  }
897  else if (obedit->type == OB_MBALL) {
898  FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) {
899  MetaBall *mb = (MetaBall *)ob_iter->data;
900 
901  float mat_local[4][4];
902  if (use_mat_local) {
903  mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
904  }
905 
906  LISTBASE_FOREACH (MetaElem *, ml, mb->editelems) {
907  if (ml->flag & SELECT) {
908  calc_tw_center_with_matrix(tbounds, &ml->x, use_mat_local, mat_local);
909  totsel++;
910  }
911  }
912  }
914  }
915  else if (obedit->type == OB_LATTICE) {
916  FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) {
917  Lattice *lt = ((Lattice *)ob_iter->data)->editlatt->latt;
918  BPoint *bp = lt->def;
919  a = lt->pntsu * lt->pntsv * lt->pntsw;
920 
921  float mat_local[4][4];
922  if (use_mat_local) {
923  mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
924  }
925 
926  while (a--) {
927  if (bp->f1 & SELECT) {
928  calc_tw_center_with_matrix(tbounds, bp->vec, use_mat_local, mat_local);
929  totsel++;
930  }
931  bp++;
932  }
933  }
935  }
936 
937 #undef FOREACH_EDIT_OBJECT_BEGIN
938 #undef FOREACH_EDIT_OBJECT_END
939 
940  /* selection center */
941  if (totsel) {
942  mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */
943  mul_m4_v3(obedit->obmat, tbounds->center);
944  mul_m4_v3(obedit->obmat, tbounds->min);
945  mul_m4_v3(obedit->obmat, tbounds->max);
946  }
947  }
948  else if (ob && (ob->mode & OB_MODE_POSE)) {
949  invert_m4_m4(ob->imat, ob->obmat);
950 
951  uint objects_len = 0;
952  Object **objects = BKE_object_pose_array_get(view_layer, v3d, &objects_len);
953 
954  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
955  Object *ob_iter = objects[ob_index];
956  const bool use_mat_local = (ob_iter != ob);
957  bPoseChannel *pchan;
958 
959  /* mislead counting bones... bah. We don't know the gizmo mode, could be mixed */
960  const int mode = TFM_ROTATION;
961 
962  const int totsel_iter = transform_convert_pose_transflags_update(
963  ob_iter, mode, V3D_AROUND_CENTER_BOUNDS, NULL);
964 
965  if (totsel_iter) {
966  float mat_local[4][4];
967  if (use_mat_local) {
968  mul_m4_m4m4(mat_local, ob->imat, ob_iter->obmat);
969  }
970 
971  /* use channels to get stats */
972  for (pchan = ob_iter->pose->chanbase.first; pchan; pchan = pchan->next) {
973  Bone *bone = pchan->bone;
974  if (bone && (bone->flag & BONE_TRANSFORM)) {
975  calc_tw_center_with_matrix(tbounds, pchan->pose_head, use_mat_local, mat_local);
976  protectflag_to_drawflags_pchan(rv3d, pchan, orient_index);
977  }
978  }
979  totsel += totsel_iter;
980  }
981  }
982  MEM_freeN(objects);
983 
984  if (totsel) {
985  mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */
986  mul_m4_v3(ob->obmat, tbounds->center);
987  mul_m4_v3(ob->obmat, tbounds->min);
988  mul_m4_v3(ob->obmat, tbounds->max);
989  }
990  }
991  else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) {
992  if (ob->mode & OB_MODE_SCULPT) {
993  totsel = 1;
994  calc_tw_center_with_matrix(tbounds, ob->sculpt->pivot_pos, false, ob->obmat);
995  mul_m4_v3(ob->obmat, tbounds->center);
996  mul_m4_v3(ob->obmat, tbounds->min);
997  mul_m4_v3(ob->obmat, tbounds->max);
998  }
999  }
1000  else if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) {
1001  PTCacheEdit *edit = PE_get_current(depsgraph, scene, ob);
1002  PTCacheEditPoint *point;
1003  PTCacheEditKey *ek;
1004  int k;
1005 
1006  if (edit) {
1007  point = edit->points;
1008  for (a = 0; a < edit->totpoint; a++, point++) {
1009  if (point->flag & PEP_HIDE) {
1010  continue;
1011  }
1012 
1013  for (k = 0, ek = point->keys; k < point->totkey; k++, ek++) {
1014  if (ek->flag & PEK_SELECT) {
1015  calc_tw_center(tbounds, (ek->flag & PEK_USE_WCO) ? ek->world_co : ek->co);
1016  totsel++;
1017  }
1018  }
1019  }
1020 
1021  /* selection center */
1022  if (totsel) {
1023  mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */
1024  }
1025  }
1026  }
1027  else {
1028 
1029  /* we need the one selected object, if its not active */
1030  base = BASACT(view_layer);
1031  ob = OBACT(view_layer);
1032  if (base && ((base->flag & BASE_SELECTED) == 0)) {
1033  ob = NULL;
1034  }
1035 
1036  for (base = view_layer->object_bases.first; base; base = base->next) {
1037  if (!BASE_SELECTED_EDITABLE(v3d, base)) {
1038  continue;
1039  }
1040  if (ob == NULL) {
1041  ob = base->object;
1042  }
1043 
1044  /* Get the boundbox out of the evaluated object. */
1045  const BoundBox *bb = NULL;
1046  if (params->use_only_center == false) {
1047  bb = BKE_object_boundbox_get(base->object);
1048  }
1049 
1050  if (params->use_only_center || (bb == NULL)) {
1051  calc_tw_center(tbounds, base->object->obmat[3]);
1052  }
1053  else {
1054  for (uint j = 0; j < 8; j++) {
1055  float co[3];
1056  mul_v3_m4v3(co, base->object->obmat, bb->vec[j]);
1057  calc_tw_center(tbounds, co);
1058  }
1059  }
1060 
1061  /* Protect-flags apply to world space in object mode, so only let them influence axis
1062  * visibility if we show the global orientation, otherwise it's confusing. */
1063  if (orient_index == V3D_ORIENT_GLOBAL) {
1065  }
1066  totsel++;
1067  }
1068 
1069  /* selection center */
1070  if (totsel) {
1071  mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */
1072  }
1073  }
1074 
1075  if (totsel == 0) {
1076  unit_m4(rv3d->twmat);
1077  }
1078  else {
1079  copy_v3_v3(rv3d->tw_axis_min, tbounds->axis_min);
1080  copy_v3_v3(rv3d->tw_axis_max, tbounds->axis_max);
1081  copy_m3_m3(rv3d->tw_axis_matrix, tbounds->axis);
1082  }
1083 
1084  return totsel;
1085 }
1086 
1087 static void gizmo_get_idot(RegionView3D *rv3d, float r_idot[3])
1088 {
1089  float view_vec[3], axis_vec[3];
1090  ED_view3d_global_to_vector(rv3d, rv3d->twmat[3], view_vec);
1091  for (int i = 0; i < 3; i++) {
1092  normalize_v3_v3(axis_vec, rv3d->twmat[i]);
1093  r_idot[i] = 1.0f - fabsf(dot_v3v3(view_vec, axis_vec));
1094  }
1095 }
1096 
1097 static void gizmo_prepare_mat(const bContext *C,
1098  RegionView3D *rv3d,
1099  const struct TransformBounds *tbounds)
1100 {
1102  ViewLayer *view_layer = CTX_data_view_layer(C);
1103 
1106  case V3D_AROUND_ACTIVE: {
1107  mid_v3_v3v3(rv3d->twmat[3], tbounds->min, tbounds->max);
1108 
1111  if (gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) {
1112  /* pass */
1113  }
1114  else {
1115  Object *ob = OBACT(view_layer);
1116  if (ob != NULL) {
1117  if ((ob->mode & OB_MODE_ALL_SCULPT) && ob->sculpt) {
1118  SculptSession *ss = ob->sculpt;
1119  copy_v3_v3(rv3d->twmat[3], ss->pivot_pos);
1120  }
1121  else {
1122  ED_object_calc_active_center(ob, false, rv3d->twmat[3]);
1123  }
1124  }
1125  }
1126  }
1127  break;
1128  }
1131  copy_v3_v3(rv3d->twmat[3], tbounds->center);
1132  break;
1133  case V3D_AROUND_CURSOR:
1134  copy_v3_v3(rv3d->twmat[3], scene->cursor.location);
1135  break;
1136  }
1137 }
1138 
1143 static void gizmo_line_range(const int twtype, const short axis_type, float *r_start, float *r_len)
1144 {
1145  const float ofs = 0.2f;
1146 
1147  *r_start = 0.2f;
1148  *r_len = 1.0f;
1149 
1150  switch (axis_type) {
1151  case MAN_AXES_TRANSLATE:
1152  if (twtype & V3D_GIZMO_SHOW_OBJECT_SCALE) {
1153  *r_start = *r_len - ofs + 0.075f;
1154  }
1155  if (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) {
1156  *r_len += ofs;
1157  }
1158  break;
1159  case MAN_AXES_SCALE:
1161  *r_len -= ofs + 0.025f;
1162  }
1163  break;
1164  }
1165 
1166  *r_len -= *r_start;
1167 }
1168 
1170  struct wmMsgBus *mbus,
1171  Scene *scene,
1172  bScreen *screen,
1173  ScrArea *area,
1174  ARegion *region,
1175  const void *type_fn)
1176 {
1177  /* Subscribe to view properties */
1178  wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = {
1179  .owner = region,
1180  .user_data = gzgroup->parent_gzmap,
1182  };
1183 
1184  int orient_flag = 0;
1185  if (type_fn == VIEW3D_GGT_xform_gizmo) {
1186  GizmoGroup *ggd = gzgroup->customdata;
1187  orient_flag = ggd->twtype_init;
1188  }
1189  else if (type_fn == VIEW3D_GGT_xform_cage) {
1190  orient_flag = V3D_GIZMO_SHOW_OBJECT_SCALE;
1191  /* pass */
1192  }
1193  else if (type_fn == VIEW3D_GGT_xform_shear) {
1194  orient_flag = V3D_GIZMO_SHOW_OBJECT_ROTATE;
1195  }
1197  orient_flag);
1198  PointerRNA orient_ref_ptr;
1199  RNA_pointer_create(&scene->id, &RNA_TransformOrientationSlot, orient_slot, &orient_ref_ptr);
1200  const ToolSettings *ts = scene->toolsettings;
1201 
1202  PointerRNA scene_ptr;
1203  RNA_id_pointer_create(&scene->id, &scene_ptr);
1204  {
1205  extern PropertyRNA rna_Scene_transform_orientation_slots;
1206  const PropertyRNA *props[] = {
1207  &rna_Scene_transform_orientation_slots,
1208  };
1209  for (int i = 0; i < ARRAY_SIZE(props); i++) {
1210  WM_msg_subscribe_rna(mbus, &scene_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
1211  }
1212  }
1213 
1215  (orient_slot->type == V3D_ORIENT_CURSOR)) {
1216  /* We could be more specific here, for now subscribe to any cursor change. */
1217  PointerRNA cursor_ptr;
1218  RNA_pointer_create(&scene->id, &RNA_View3DCursor, &scene->cursor, &cursor_ptr);
1219  WM_msg_subscribe_rna(mbus, &cursor_ptr, NULL, &msg_sub_value_gz_tag_refresh, __func__);
1220  }
1221 
1222  {
1223  extern PropertyRNA rna_TransformOrientationSlot_type;
1224  extern PropertyRNA rna_TransformOrientationSlot_use;
1225  const PropertyRNA *props[] = {
1226  &rna_TransformOrientationSlot_type,
1227  &rna_TransformOrientationSlot_use,
1228  };
1229  for (int i = 0; i < ARRAY_SIZE(props); i++) {
1230  if (props[i]) {
1232  mbus, &orient_ref_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
1233  }
1234  }
1235  }
1236 
1237  PointerRNA toolsettings_ptr;
1238  RNA_pointer_create(&scene->id, &RNA_ToolSettings, scene->toolsettings, &toolsettings_ptr);
1239 
1241  extern PropertyRNA rna_ToolSettings_transform_pivot_point;
1242  const PropertyRNA *props[] = {
1243  &rna_ToolSettings_transform_pivot_point,
1244  };
1245  for (int i = 0; i < ARRAY_SIZE(props); i++) {
1247  mbus, &toolsettings_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
1248  }
1249  }
1250 
1251  {
1252  extern PropertyRNA rna_ToolSettings_workspace_tool_type;
1253  const PropertyRNA *props[] = {
1254  &rna_ToolSettings_workspace_tool_type,
1255  };
1256  for (int i = 0; i < ARRAY_SIZE(props); i++) {
1258  mbus, &toolsettings_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
1259  }
1260  }
1261 
1262  PointerRNA view3d_ptr;
1263  RNA_pointer_create(&screen->id, &RNA_SpaceView3D, area->spacedata.first, &view3d_ptr);
1264 
1265  if (type_fn == VIEW3D_GGT_xform_gizmo) {
1266  GizmoGroup *ggd = gzgroup->customdata;
1267  if (ggd->use_twtype_refresh) {
1268  extern PropertyRNA rna_SpaceView3D_show_gizmo_object_translate;
1269  extern PropertyRNA rna_SpaceView3D_show_gizmo_object_rotate;
1270  extern PropertyRNA rna_SpaceView3D_show_gizmo_object_scale;
1271  const PropertyRNA *props[] = {
1272  &rna_SpaceView3D_show_gizmo_object_translate,
1273  &rna_SpaceView3D_show_gizmo_object_rotate,
1274  &rna_SpaceView3D_show_gizmo_object_scale,
1275  };
1276  for (int i = 0; i < ARRAY_SIZE(props); i++) {
1277  WM_msg_subscribe_rna(mbus, &view3d_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
1278  }
1279  }
1280  }
1281  else if (type_fn == VIEW3D_GGT_xform_cage) {
1282  /* pass */
1283  }
1284  else if (type_fn == VIEW3D_GGT_xform_shear) {
1285  /* pass */
1286  }
1287  else {
1288  BLI_assert(0);
1289  }
1290 
1291  WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_gz_tag_refresh);
1292  WM_msg_subscribe_rna_anon_prop(mbus, EditBone, lock, &msg_sub_value_gz_tag_refresh);
1293 }
1294 
1295 void drawDial3d(const TransInfo *t)
1296 {
1297  if (t->mode == TFM_ROTATION && t->spacetype == SPACE_VIEW3D) {
1298  if (t->options & CTX_PAINT_CURVE) {
1299  /* Matrices are in the screen space. Not supported. */
1300  return;
1301  }
1302 
1303  wmGizmo *gz = wm_gizmomap_modal_get(t->region->gizmo_map);
1304  if (gz == NULL) {
1305  /* We only draw Dial3d if the operator has been called by a gizmo. */
1306  return;
1307  }
1308 
1309  float mat_basis[4][4];
1310  float mat_final[4][4];
1311  float color[4];
1312  float increment = 0.0f;
1313  float line_with = GIZMO_AXIS_LINE_WIDTH + 1.0f;
1314  float scale = UI_DPI_FAC * U.gizmo_size;
1315 
1316  int axis_idx;
1317 
1318  const TransCon *tc = &(t->con);
1319  if (tc->mode & CON_APPLY) {
1320  if (tc->mode & CON_AXIS0) {
1321  axis_idx = MAN_AXIS_ROT_X;
1322  negate_v3_v3(mat_basis[2], t->spacemtx[0]);
1323  }
1324  else if (tc->mode & CON_AXIS1) {
1325  axis_idx = MAN_AXIS_ROT_Y;
1326  negate_v3_v3(mat_basis[2], t->spacemtx[1]);
1327  }
1328  else {
1329  BLI_assert((tc->mode & CON_AXIS2) != 0);
1330  axis_idx = MAN_AXIS_ROT_Z;
1331  negate_v3_v3(mat_basis[2], t->spacemtx[2]);
1332  }
1333  }
1334  else {
1335  axis_idx = MAN_AXIS_ROT_C;
1336  copy_v3_v3(mat_basis[2], t->spacemtx[t->orient_axis]);
1337  scale *= 1.2f;
1338  line_with -= 1.0f;
1339  }
1340 
1341  copy_v3_v3(mat_basis[3], t->center_global);
1342  mat_basis[2][3] = -dot_v3v3(mat_basis[2], mat_basis[3]);
1343 
1345  t->region, mat_basis[2], (float[2]){UNPACK2(t->mouse.imval)}, false, mat_basis[1])) {
1346  sub_v3_v3(mat_basis[1], mat_basis[3]);
1347  normalize_v3(mat_basis[1]);
1348  cross_v3_v3v3(mat_basis[0], mat_basis[1], mat_basis[2]);
1349  }
1350  else {
1351  /* The plane and the mouse direction are parallel.
1352  * Calculate a matrix orthogonal to the axis. */
1353  ortho_basis_v3v3_v3(mat_basis[0], mat_basis[1], mat_basis[2]);
1354  }
1355 
1356  mat_basis[0][3] = 0.0f;
1357  mat_basis[1][3] = 0.0f;
1358  mat_basis[2][3] = 0.0f;
1359  mat_basis[3][3] = 1.0f;
1360 
1361  copy_m4_m4(mat_final, mat_basis);
1362  scale *= ED_view3d_pixel_size_no_ui_scale(t->region->regiondata, mat_final[3]);
1363  mul_mat3_m4_fl(mat_final, scale);
1364 
1365  if (activeSnap(t) && (!transformModeUseSnap(t) ||
1366  (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) {
1367  increment = (t->modifiers & MOD_PRECISION) ? t->snap[1] : t->snap[0];
1368  }
1369 
1370  BLI_assert(axis_idx >= MAN_AXIS_RANGE_ROT_START && axis_idx < MAN_AXIS_RANGE_ROT_END);
1371  gizmo_get_axis_color(axis_idx, NULL, color, color);
1372 
1375  GPU_line_smooth(true);
1376 
1378  mat_final,
1379  line_with,
1380  color,
1381  false,
1382  &(struct Dial3dParams){
1383  .draw_options = ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE,
1384  .angle_delta = t->values_final[0],
1385  .angle_increment = increment,
1386  });
1387 
1388  GPU_line_smooth(false);
1391  }
1392 }
1393 
1396 /* -------------------------------------------------------------------- */
1401 {
1402  GizmoGroup *ggd;
1403 
1404  ggd = MEM_callocN(sizeof(GizmoGroup), "gizmo_data");
1405 
1406  const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
1407  const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
1408  const wmGizmoType *gzt_prim = WM_gizmotype_find("GIZMO_GT_primitive_3d", true);
1409 
1410 #define GIZMO_NEW_ARROW(v, draw_style) \
1411  { \
1412  ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); \
1413  RNA_enum_set(ggd->gizmos[v]->ptr, "draw_style", draw_style); \
1414  } \
1415  ((void)0)
1416 #define GIZMO_NEW_DIAL(v, draw_options) \
1417  { \
1418  ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL); \
1419  RNA_enum_set(ggd->gizmos[v]->ptr, "draw_options", draw_options); \
1420  } \
1421  ((void)0)
1422 #define GIZMO_NEW_PRIM(v, draw_style) \
1423  { \
1424  ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_prim, gzgroup, NULL); \
1425  RNA_enum_set(ggd->gizmos[v]->ptr, "draw_style", draw_style); \
1426  } \
1427  ((void)0)
1428 
1429  /* add/init widgets - order matters! */
1431 
1433 
1437 
1441 
1445 
1446  /* init screen aligned widget last here, looks better, behaves better */
1448 
1450 
1454 
1458 
1460 
1461  /* Prevent axis gizmos overlapping the center point, see: T63744. */
1462  ggd->gizmos[MAN_AXIS_TRANS_C]->select_bias = 2.0f;
1463 
1464  ggd->gizmos[MAN_AXIS_SCALE_C]->select_bias = -2.0f;
1465 
1466  /* Use 1/6 since this is '0.2' if the main scale is 1.2. */
1467  RNA_float_set(ggd->gizmos[MAN_AXIS_SCALE_C]->ptr, "arc_inner_factor", 1.0 / 6.0);
1468 
1469  return ggd;
1470 }
1471 
1475 static int gizmo_modal(bContext *C,
1476  wmGizmo *widget,
1477  const wmEvent *event,
1478  eWM_GizmoFlagTweak UNUSED(tweak_flag))
1479 {
1480  /* Avoid unnecessary updates, partially address: T55458. */
1481  if (ELEM(event->type, TIMER, INBETWEEN_MOUSEMOVE)) {
1482  return OPERATOR_RUNNING_MODAL;
1483  }
1484 
1485  ARegion *region = CTX_wm_region(C);
1486  RegionView3D *rv3d = region->regiondata;
1487  struct TransformBounds tbounds;
1488 
1490  &(struct TransformCalcParams){
1491  .use_only_center = true,
1492  },
1493  &tbounds)) {
1494  gizmo_prepare_mat(C, rv3d, &tbounds);
1495  WM_gizmo_set_matrix_location(widget, rv3d->twmat[3]);
1496  }
1497 
1499 
1500  return OPERATOR_RUNNING_MODAL;
1501 }
1502 
1504 {
1505  struct {
1506  wmOperatorType *translate, *rotate, *trackball, *resize;
1507  } ot_store = {NULL};
1508  GizmoGroup *ggd = gzgroup->customdata;
1509 
1510  MAN_ITER_AXES_BEGIN (axis, axis_idx) {
1511  const short axis_type = gizmo_get_axis_type(axis_idx);
1512  bool constraint_axis[3] = {1, 0, 0};
1513  PointerRNA *ptr = NULL;
1514 
1515  gizmo_get_axis_constraint(axis_idx, constraint_axis);
1516 
1517  /* custom handler! */
1519 
1520  switch (axis_idx) {
1521  case MAN_AXIS_TRANS_X:
1522  case MAN_AXIS_TRANS_Y:
1523  case MAN_AXIS_TRANS_Z:
1524  case MAN_AXIS_SCALE_X:
1525  case MAN_AXIS_SCALE_Y:
1526  case MAN_AXIS_SCALE_Z:
1527  if (axis_idx >= MAN_AXIS_RANGE_TRANS_START && axis_idx < MAN_AXIS_RANGE_TRANS_END) {
1528  int draw_options = 0;
1530  draw_options |= ED_GIZMO_ARROW_DRAW_FLAG_STEM;
1531  }
1532  RNA_enum_set(axis->ptr, "draw_options", draw_options);
1533  }
1534 
1536  break;
1537  case MAN_AXIS_ROT_X:
1538  case MAN_AXIS_ROT_Y:
1539  case MAN_AXIS_ROT_Z:
1540  /* increased line width for better display */
1543  break;
1544  case MAN_AXIS_TRANS_XY:
1545  case MAN_AXIS_TRANS_YZ:
1546  case MAN_AXIS_TRANS_ZX:
1547  case MAN_AXIS_SCALE_XY:
1548  case MAN_AXIS_SCALE_YZ:
1549  case MAN_AXIS_SCALE_ZX: {
1550  const float ofs_ax = 7.0f;
1551  const float ofs[3] = {ofs_ax, ofs_ax, 0.0f};
1552  WM_gizmo_set_scale(axis, 0.07f);
1555  break;
1556  }
1557  case MAN_AXIS_TRANS_C:
1558  case MAN_AXIS_ROT_C:
1559  case MAN_AXIS_SCALE_C:
1560  case MAN_AXIS_ROT_T:
1562  if (axis_idx == MAN_AXIS_ROT_T) {
1564  }
1565  else if (axis_idx == MAN_AXIS_ROT_C) {
1567  WM_gizmo_set_scale(axis, 1.2f);
1568  }
1569  else if (axis_idx == MAN_AXIS_SCALE_C) {
1570  WM_gizmo_set_scale(axis, 1.2f);
1571  }
1572  else {
1573  WM_gizmo_set_scale(axis, 0.2f);
1574  }
1575  break;
1576  }
1577 
1578  switch (axis_type) {
1579  case MAN_AXES_TRANSLATE:
1580  if (ot_store.translate == NULL) {
1581  ot_store.translate = WM_operatortype_find("TRANSFORM_OT_translate", true);
1582  }
1583  ptr = WM_gizmo_operator_set(axis, 0, ot_store.translate, NULL);
1584  break;
1585  case MAN_AXES_ROTATE: {
1586  wmOperatorType *ot_rotate;
1587  if (axis_idx == MAN_AXIS_ROT_T) {
1588  if (ot_store.trackball == NULL) {
1589  ot_store.trackball = WM_operatortype_find("TRANSFORM_OT_trackball", true);
1590  }
1591  ot_rotate = ot_store.trackball;
1592  }
1593  else {
1594  if (ot_store.rotate == NULL) {
1595  ot_store.rotate = WM_operatortype_find("TRANSFORM_OT_rotate", true);
1596  }
1597  ot_rotate = ot_store.rotate;
1598  }
1599  ptr = WM_gizmo_operator_set(axis, 0, ot_rotate, NULL);
1600  break;
1601  }
1602  case MAN_AXES_SCALE: {
1603  if (ot_store.resize == NULL) {
1604  ot_store.resize = WM_operatortype_find("TRANSFORM_OT_resize", true);
1605  }
1606  ptr = WM_gizmo_operator_set(axis, 0, ot_store.resize, NULL);
1607  break;
1608  }
1609  }
1610 
1611  if (ptr) {
1612  PropertyRNA *prop;
1613  if (ELEM(true, UNPACK3(constraint_axis))) {
1614  if ((prop = RNA_struct_find_property(ptr, "constraint_axis"))) {
1615  RNA_property_boolean_set_array(ptr, prop, constraint_axis);
1616  }
1617  }
1618 
1619  RNA_boolean_set(ptr, "release_confirm", 1);
1620  }
1621  }
1623 }
1624 
1625 static void WIDGETGROUP_gizmo_setup(const bContext *C, wmGizmoGroup *gzgroup)
1626 {
1627  GizmoGroup *ggd = gizmogroup_init(gzgroup);
1628 
1629  gzgroup->customdata = ggd;
1630 
1631  {
1632  ScrArea *area = CTX_wm_area(C);
1633  const bToolRef *tref = area->runtime.tool;
1634 
1635  ggd->twtype = 0;
1636  if (tref && STREQ(tref->idname, "builtin.move")) {
1638  }
1639  else if (tref && STREQ(tref->idname, "builtin.rotate")) {
1641  }
1642  else if (tref && STREQ(tref->idname, "builtin.scale")) {
1644  }
1645  else if (tref && STREQ(tref->idname, "builtin.transform")) {
1648  }
1649  else {
1650  /* This is also correct logic for 'builtin.transform', no special check needed. */
1651  /* Setup all gizmos, they can be toggled via 'ToolSettings.gizmo_flag' */
1654  ggd->use_twtype_refresh = true;
1655  }
1656  BLI_assert(ggd->twtype != 0);
1657  ggd->twtype_init = ggd->twtype;
1658  }
1659 
1660  /* *** set properties for axes *** */
1662 }
1663 
1664 static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
1665 {
1666  GizmoGroup *ggd = gzgroup->customdata;
1668  ScrArea *area = CTX_wm_area(C);
1669  View3D *v3d = area->spacedata.first;
1670  ARegion *region = CTX_wm_region(C);
1671  RegionView3D *rv3d = region->regiondata;
1672  struct TransformBounds tbounds;
1673 
1675  gzgroup->use_fallback_keymap = true;
1676  }
1677  else {
1678  gzgroup->use_fallback_keymap = false;
1679  }
1680 
1681  if (ggd->use_twtype_refresh) {
1682  ggd->twtype = v3d->gizmo_show_object & ggd->twtype_init;
1683  if (ggd->twtype != ggd->twtype_prev) {
1684  ggd->twtype_prev = ggd->twtype;
1686  }
1687  }
1688 
1689  const int orient_index = BKE_scene_orientation_get_index_from_flag(scene, ggd->twtype_init);
1690 
1691  /* skip, we don't draw anything anyway */
1693  &(struct TransformCalcParams){
1694  .use_only_center = true,
1695  .orientation_index = orient_index + 1,
1696  },
1697  &tbounds) == 0))) {
1698  return;
1699  }
1700 
1701  gizmo_prepare_mat(C, rv3d, &tbounds);
1702 
1703  /* *** set properties for axes *** */
1704 
1705  MAN_ITER_AXES_BEGIN (axis, axis_idx) {
1706  const short axis_type = gizmo_get_axis_type(axis_idx);
1707  const int aidx_norm = gizmo_orientation_axis(axis_idx, NULL);
1708 
1710 
1711  switch (axis_idx) {
1712  case MAN_AXIS_TRANS_X:
1713  case MAN_AXIS_TRANS_Y:
1714  case MAN_AXIS_TRANS_Z:
1715  case MAN_AXIS_SCALE_X:
1716  case MAN_AXIS_SCALE_Y:
1717  case MAN_AXIS_SCALE_Z: {
1718  float start_co[3] = {0.0f, 0.0f, 0.0f};
1719  float len;
1720 
1721  gizmo_line_range(ggd->twtype, axis_type, &start_co[2], &len);
1722 
1724  RNA_float_set(axis->ptr, "length", len);
1725 
1726  if (axis_idx >= MAN_AXIS_RANGE_TRANS_START && axis_idx < MAN_AXIS_RANGE_TRANS_END) {
1727  if (ggd->twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) {
1728  /* Avoid rotate and translate arrows overlap. */
1729  start_co[2] += 0.215f;
1730  }
1731  }
1734  break;
1735  }
1736  case MAN_AXIS_ROT_X:
1737  case MAN_AXIS_ROT_Y:
1738  case MAN_AXIS_ROT_Z:
1740  break;
1741  case MAN_AXIS_TRANS_XY:
1742  case MAN_AXIS_TRANS_YZ:
1743  case MAN_AXIS_TRANS_ZX:
1744  case MAN_AXIS_SCALE_XY:
1745  case MAN_AXIS_SCALE_YZ:
1746  case MAN_AXIS_SCALE_ZX: {
1747  const float *y_axis = rv3d->twmat[aidx_norm - 1 < 0 ? 2 : aidx_norm - 1];
1748  const float *z_axis = rv3d->twmat[aidx_norm];
1750  break;
1751  }
1752  }
1753  }
1755 
1756  /* Ensure rotate disks don't overlap scale arrows, especially in ortho view. */
1757  float rotate_select_bias = 0.0f;
1759  rotate_select_bias = -2.0f;
1760  }
1761  for (int i = MAN_AXIS_RANGE_ROT_START; i < MAN_AXIS_RANGE_ROT_END; i++) {
1762  ggd->gizmos[i]->select_bias = rotate_select_bias;
1763  }
1764 }
1765 
1767  wmGizmoGroup *gzgroup,
1768  struct wmMsgBus *mbus)
1769 {
1771  bScreen *screen = CTX_wm_screen(C);
1772  ScrArea *area = CTX_wm_area(C);
1773  ARegion *region = CTX_wm_region(C);
1775  gzgroup, mbus, scene, screen, area, region, VIEW3D_GGT_xform_gizmo);
1776 }
1777 
1779 {
1780  GizmoGroup *ggd = gzgroup->customdata;
1781  // ScrArea *area = CTX_wm_area(C);
1782  ARegion *region = CTX_wm_region(C);
1783  // View3D *v3d = area->spacedata.first;
1784  RegionView3D *rv3d = region->regiondata;
1785  float viewinv_m3[3][3];
1786  copy_m3_m4(viewinv_m3, rv3d->viewinv);
1787  float idot[3];
1788 
1789  /* when looking through a selected camera, the gizmo can be at the
1790  * exact same position as the view, skip so we don't break selection */
1791  if (ggd->all_hidden || fabsf(ED_view3d_pixel_size(rv3d, rv3d->twmat[3])) < 5e-7f) {
1792  MAN_ITER_AXES_BEGIN (axis, axis_idx) {
1794  }
1796  return;
1797  }
1798  gizmo_get_idot(rv3d, idot);
1799 
1800  /* *** set properties for axes *** */
1801  MAN_ITER_AXES_BEGIN (axis, axis_idx) {
1802  const short axis_type = gizmo_get_axis_type(axis_idx);
1803  /* XXX maybe unset _HIDDEN flag on redraw? */
1804 
1805  if (gizmo_is_axis_visible(rv3d, ggd->twtype, idot, axis_type, axis_idx)) {
1807  }
1808  else {
1810  continue;
1811  }
1812 
1813  float color[4], color_hi[4];
1814  gizmo_get_axis_color(axis_idx, idot, color, color_hi);
1815  WM_gizmo_set_color(axis, color);
1817 
1818  switch (axis_idx) {
1819  case MAN_AXIS_TRANS_C:
1820  case MAN_AXIS_ROT_C:
1821  case MAN_AXIS_SCALE_C:
1822  case MAN_AXIS_ROT_T:
1824  break;
1825  }
1826  }
1828 
1829  /* Refresh handled above when using view orientation. */
1830  if (!equals_m3m3(viewinv_m3, ggd->prev.viewinv_m3)) {
1831  {
1834  scene, ggd->twtype_init);
1835  switch (orient_slot->type) {
1836  case V3D_ORIENT_VIEW: {
1837  WIDGETGROUP_gizmo_refresh(C, gzgroup);
1838  break;
1839  }
1840  }
1841  }
1842  copy_m3_m4(ggd->prev.viewinv_m3, rv3d->viewinv);
1843  }
1844 }
1845 
1847  wmGizmoGroup *gzgroup,
1848  wmGizmo *gz,
1849  const wmEvent *UNUSED(event))
1850 {
1851 
1852  GizmoGroup *ggd = gzgroup->customdata;
1853 
1854  /* Support gizmo specific orientation. */
1855  if (gz != ggd->gizmos[MAN_AXIS_ROT_T]) {
1857  wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
1858  PointerRNA *ptr = &gzop->ptr;
1859  PropertyRNA *prop_orient_type = RNA_struct_find_property(ptr, "orient_type");
1861  scene, ggd->twtype_init);
1862  if ((gz == ggd->gizmos[MAN_AXIS_ROT_C]) ||
1863  (orient_slot == &scene->orientation_slots[SCE_ORIENT_DEFAULT])) {
1864  /* #MAN_AXIS_ROT_C always uses the #V3D_ORIENT_VIEW orientation,
1865  * optionally we could set this orientation instead of unset the property. */
1866  RNA_property_unset(ptr, prop_orient_type);
1867  }
1868  else {
1869  /* TODO: APIfunction */
1870  int index = BKE_scene_orientation_slot_get_index(orient_slot);
1871  RNA_property_enum_set(ptr, prop_orient_type, index);
1872  }
1873  }
1874 
1875  /* Support shift click to constrain axis. */
1876  const int axis_idx = BLI_array_findindex(ggd->gizmos, ARRAY_SIZE(ggd->gizmos), &gz);
1877  int axis = -1;
1878  switch (axis_idx) {
1879  case MAN_AXIS_TRANS_X:
1880  case MAN_AXIS_TRANS_Y:
1881  case MAN_AXIS_TRANS_Z:
1882  axis = axis_idx - MAN_AXIS_TRANS_X;
1883  break;
1884  case MAN_AXIS_SCALE_X:
1885  case MAN_AXIS_SCALE_Y:
1886  case MAN_AXIS_SCALE_Z:
1887  axis = axis_idx - MAN_AXIS_SCALE_X;
1888  break;
1889  }
1890 
1891  if (axis != -1) {
1892  wmWindow *win = CTX_wm_window(C);
1893  /* Swap single axis for two-axis constraint. */
1894  bool flip = win->eventstate->shift;
1895  BLI_assert(axis_idx != -1);
1896  const short axis_type = gizmo_get_axis_type(axis_idx);
1897  if (axis_type != MAN_AXES_ROTATE) {
1898  wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
1899  PointerRNA *ptr = &gzop->ptr;
1900  PropertyRNA *prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis");
1901  if (prop_constraint_axis) {
1902  bool constraint[3] = {false};
1903  constraint[axis] = true;
1904  if (flip) {
1905  for (int i = 0; i < ARRAY_SIZE(constraint); i++) {
1906  constraint[i] = !constraint[i];
1907  }
1908  }
1909  RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint);
1910  }
1911  }
1912  }
1913 }
1914 
1916 {
1917  if (v3d->gizmo_flag & V3D_GIZMO_HIDE) {
1918  return false;
1919  }
1920  if (G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) {
1921  return false;
1922  }
1923  return true;
1924 }
1925 
1926 static bool WIDGETGROUP_gizmo_poll_context(const struct bContext *C,
1927  struct wmGizmoGroupType *UNUSED(gzgt))
1928 {
1929  ScrArea *area = CTX_wm_area(C);
1930  View3D *v3d = area->spacedata.first;
1931  if (!WIDGETGROUP_gizmo_poll_generic(v3d)) {
1932  return false;
1933  }
1934 
1935  const bToolRef *tref = area->runtime.tool;
1936  if (v3d->gizmo_flag & V3D_GIZMO_HIDE_CONTEXT) {
1937  return false;
1938  }
1940  V3D_GIZMO_SHOW_OBJECT_SCALE)) == 0) {
1941  return false;
1942  }
1943 
1944  /* Don't show if the tool has a gizmo. */
1945  if (tref && tref->runtime && tref->runtime->gizmo_group[0]) {
1946  return false;
1947  }
1948  return true;
1949 }
1950 
1951 static bool WIDGETGROUP_gizmo_poll_tool(const struct bContext *C, struct wmGizmoGroupType *gzgt)
1952 {
1954  return false;
1955  }
1956 
1957  ScrArea *area = CTX_wm_area(C);
1958  View3D *v3d = area->spacedata.first;
1959  if (!WIDGETGROUP_gizmo_poll_generic(v3d)) {
1960  return false;
1961  }
1962 
1963  if (v3d->gizmo_flag & V3D_GIZMO_HIDE_TOOL) {
1964  return false;
1965  }
1966 
1967  return true;
1968 }
1969 
1970 /* Expose as multiple gizmos so tools use one, persistent context another.
1971  * Needed because they use different options which isn't so simple to dynamically update. */
1972 
1974 {
1975  gzgt->name = "3D View: Transform Gizmo";
1976  gzgt->idname = "VIEW3D_GGT_xform_gizmo";
1977 
1980 
1983 
1991 
1992  static const EnumPropertyItem rna_enum_gizmo_items[] = {
1993  {V3D_GIZMO_SHOW_OBJECT_TRANSLATE, "TRANSLATE", 0, "Move", ""},
1994  {V3D_GIZMO_SHOW_OBJECT_ROTATE, "ROTATE", 0, "Rotate", ""},
1995  {V3D_GIZMO_SHOW_OBJECT_SCALE, "SCALE", 0, "Scale", ""},
1996  {0, "NONE", 0, "None", ""},
1997  {0, NULL, 0, NULL, NULL},
1998  };
1999  RNA_def_enum(gzgt->srna,
2000  "drag_action",
2001  rna_enum_gizmo_items,
2003  "Drag Action",
2004  "");
2005 }
2006 
2009 {
2010  gzgt->name = "3D View: Transform Gizmo Context";
2011  gzgt->idname = "VIEW3D_GGT_xform_gizmo_context";
2012 
2015 
2023 }
2024 
2027 /* -------------------------------------------------------------------- */
2033  /* Only for view orientation. */
2034  struct {
2035  float viewinv_m3[3][3];
2036  } prev;
2037 };
2038 
2040 {
2042  return false;
2043  }
2044  View3D *v3d = CTX_wm_view3d(C);
2046  return false;
2047  }
2048  if (G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) {
2049  return false;
2050  }
2051  return true;
2052 }
2053 
2055 {
2056  struct XFormCageWidgetGroup *xgzgroup = MEM_mallocN(sizeof(struct XFormCageWidgetGroup),
2057  __func__);
2058  const wmGizmoType *gzt_cage = WM_gizmotype_find("GIZMO_GT_cage_3d", true);
2059  xgzgroup->gizmo = WM_gizmo_new_ptr(gzt_cage, gzgroup, NULL);
2060  wmGizmo *gz = xgzgroup->gizmo;
2061 
2062  RNA_enum_set(gz->ptr,
2063  "transform",
2065 
2066  gz->color[0] = 1;
2067  gz->color_hi[0] = 1;
2068 
2069  gzgroup->customdata = xgzgroup;
2070 
2071  {
2072  wmOperatorType *ot_resize = WM_operatortype_find("TRANSFORM_OT_resize", true);
2073  PointerRNA *ptr;
2074 
2075  /* assign operator */
2076  PropertyRNA *prop_release_confirm = NULL;
2077  PropertyRNA *prop_constraint_axis = NULL;
2078 
2080  for (int x = 0; x < 3; x++) {
2081  for (int y = 0; y < 3; y++) {
2082  for (int z = 0; z < 3; z++) {
2083  const bool constraint[3] = {x != 1, y != 1, z != 1};
2084  ptr = WM_gizmo_operator_set(gz, i, ot_resize, NULL);
2085  if (prop_release_confirm == NULL) {
2086  prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm");
2087  prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis");
2088  }
2089  RNA_property_boolean_set(ptr, prop_release_confirm, true);
2090  RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint);
2091  i++;
2092  }
2093  }
2094  }
2095  }
2096 }
2097 
2099 {
2100  ARegion *region = CTX_wm_region(C);
2101  RegionView3D *rv3d = region->regiondata;
2103 
2104  struct XFormCageWidgetGroup *xgzgroup = gzgroup->customdata;
2105  wmGizmo *gz = xgzgroup->gizmo;
2106 
2107  struct TransformBounds tbounds;
2108 
2110  gzgroup->use_fallback_keymap = true;
2111  }
2112  else {
2113  gzgroup->use_fallback_keymap = false;
2114  }
2115 
2117 
2119  &(struct TransformCalcParams){
2120  .use_local_axis = true,
2121  .orientation_index = orient_index + 1,
2122  },
2123  &tbounds) == 0) ||
2124  equals_v3v3(rv3d->tw_axis_min, rv3d->tw_axis_max)) {
2126  }
2127  else {
2128  ViewLayer *view_layer = CTX_data_view_layer(C);
2129  Object *ob = OBACT(view_layer);
2130  if (ob && ob->mode & OB_MODE_EDIT) {
2131  copy_m4_m4(gz->matrix_space, ob->obmat);
2132  }
2133  else {
2134  unit_m4(gz->matrix_space);
2135  }
2136 
2137  gizmo_prepare_mat(C, rv3d, &tbounds);
2138 
2139  WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
2141 
2142  float dims[3];
2143  sub_v3_v3v3(dims, rv3d->tw_axis_max, rv3d->tw_axis_min);
2144  RNA_float_set_array(gz->ptr, "dimensions", dims);
2145  mul_v3_fl(dims, 0.5f);
2146 
2148  mid_v3_v3v3(gz->matrix_offset[3], rv3d->tw_axis_max, rv3d->tw_axis_min);
2149  mul_m3_v3(rv3d->tw_axis_matrix, gz->matrix_offset[3]);
2150 
2151  float matrix_offset_global[4][4];
2152  mul_m4_m4m4(matrix_offset_global, gz->matrix_space, gz->matrix_offset);
2153 
2154  PropertyRNA *prop_center_override = NULL;
2155  float center[3];
2156  float center_global[3];
2158  for (int x = 0; x < 3; x++) {
2159  center[0] = (float)(1 - x) * dims[0];
2160  for (int y = 0; y < 3; y++) {
2161  center[1] = (float)(1 - y) * dims[1];
2162  for (int z = 0; z < 3; z++) {
2163  center[2] = (float)(1 - z) * dims[2];
2164  struct wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, i);
2165  if (prop_center_override == NULL) {
2166  prop_center_override = RNA_struct_find_property(&gzop->ptr, "center_override");
2167  }
2168  mul_v3_m4v3(center_global, matrix_offset_global, center);
2169  RNA_property_float_set_array(&gzop->ptr, prop_center_override, center_global);
2170  i++;
2171  }
2172  }
2173  }
2174  }
2175 
2176  /* Needed to test view orientation changes. */
2177  copy_m3_m4(xgzgroup->prev.viewinv_m3, rv3d->viewinv);
2178 }
2179 
2181  wmGizmoGroup *gzgroup,
2182  struct wmMsgBus *mbus)
2183 {
2185  bScreen *screen = CTX_wm_screen(C);
2186  ScrArea *area = CTX_wm_area(C);
2187  ARegion *region = CTX_wm_region(C);
2188  gizmo_xform_message_subscribe(gzgroup, mbus, scene, screen, area, region, VIEW3D_GGT_xform_cage);
2189 }
2190 
2192 {
2193  struct XFormCageWidgetGroup *xgzgroup = gzgroup->customdata;
2194 
2196  {
2200  switch (orient_slot->type) {
2201  case V3D_ORIENT_VIEW: {
2202  float viewinv_m3[3][3];
2203  copy_m3_m4(viewinv_m3, rv3d->viewinv);
2204  if (!equals_m3m3(viewinv_m3, xgzgroup->prev.viewinv_m3)) {
2205  /* Take care calling refresh from draw_prepare,
2206  * this should be OK because it's only adjusting the cage orientation. */
2208  }
2209  break;
2210  }
2211  }
2212  }
2213 }
2214 
2216 {
2217  gzgt->name = "Transform Cage";
2218  gzgt->idname = "VIEW3D_GGT_xform_cage";
2219 
2222 
2225 
2232 }
2233 
2236 /* -------------------------------------------------------------------- */
2241  wmGizmo *gizmo[3][2];
2244 
2245  /* Only for view orientation. */
2246  struct {
2247  float viewinv_m3[3][3];
2248  } prev;
2249 };
2250 
2252 {
2254  return false;
2255  }
2256  View3D *v3d = CTX_wm_view3d(C);
2258  return false;
2259  }
2260  return true;
2261 }
2262 
2264 {
2265  struct XFormShearWidgetGroup *xgzgroup = MEM_mallocN(sizeof(struct XFormShearWidgetGroup),
2266  __func__);
2267  const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
2268  wmOperatorType *ot_shear = WM_operatortype_find("TRANSFORM_OT_shear", true);
2269 
2270  float axis_color[3][3];
2271  for (int i = 0; i < 3; i++) {
2272  UI_GetThemeColor3fv(TH_AXIS_X + i, axis_color[i]);
2273  }
2274 
2275  for (int i = 0; i < 3; i++) {
2276  for (int j = 0; j < 2; j++) {
2277  wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
2278  RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX);
2279  const int i_ortho_a = (i + j + 1) % 3;
2280  const int i_ortho_b = (i + (1 - j) + 1) % 3;
2281  interp_v3_v3v3(gz->color, axis_color[i_ortho_a], axis_color[i_ortho_b], 0.75f);
2282  gz->color[3] = 0.5f;
2283  PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_shear, NULL);
2284  RNA_boolean_set(ptr, "release_confirm", 1);
2285  xgzgroup->gizmo[i][j] = gz;
2286  }
2287  }
2288 
2289  for (int i = 0; i < 4; i++) {
2290  wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
2291  RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX);
2292  RNA_enum_set(gz->ptr, "draw_options", 0); /* No stem. */
2293  copy_v3_fl(gz->color, 1.0f);
2294  gz->color[3] = 0.5f;
2296  PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_shear, NULL);
2297  RNA_boolean_set(ptr, "release_confirm", 1);
2298  xgzgroup->gizmo_view[i] = gz;
2299 
2300  /* Unlike the other gizmos, this never changes so can be set on setup. */
2301  wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
2302  RNA_enum_set(&gzop->ptr, "orient_type", V3D_ORIENT_VIEW);
2303 
2304  RNA_enum_set(&gzop->ptr, "orient_axis", 2);
2305  RNA_enum_set(&gzop->ptr, "orient_axis_ortho", ((i % 2) ? 0 : 1));
2306  }
2307 
2308  gzgroup->customdata = xgzgroup;
2309 }
2310 
2312 {
2314  ARegion *region = CTX_wm_region(C);
2315  RegionView3D *rv3d = region->regiondata;
2316 
2317  struct XFormShearWidgetGroup *xgzgroup = gzgroup->customdata;
2318  struct TransformBounds tbounds;
2319 
2321  gzgroup->use_fallback_keymap = true;
2322  }
2323  else {
2324  gzgroup->use_fallback_keymap = false;
2325  }
2326 
2327  /* Needed to test view orientation changes. */
2328  copy_m3_m4(xgzgroup->prev.viewinv_m3, rv3d->viewinv);
2329 
2332  const int orient_index = BKE_scene_orientation_slot_get_index(orient_slot);
2333 
2335  &(struct TransformCalcParams){
2336  .use_local_axis = false,
2337  .orientation_index = orient_index + 1,
2338  },
2339  &tbounds) == 0) {
2340  for (int i = 0; i < 3; i++) {
2341  for (int j = 0; j < 2; j++) {
2342  wmGizmo *gz = xgzgroup->gizmo[i][j];
2344  }
2345  }
2346 
2347  for (int i = 0; i < 4; i++) {
2348  wmGizmo *gz = xgzgroup->gizmo_view[i];
2350  }
2351  }
2352  else {
2353  gizmo_prepare_mat(C, rv3d, &tbounds);
2354  for (int i = 0; i < 3; i++) {
2355  for (int j = 0; j < 2; j++) {
2356  wmGizmo *gz = xgzgroup->gizmo[i][j];
2357  WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
2359 
2360  wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
2361  const int i_ortho_a = (i + j + 1) % 3;
2362  const int i_ortho_b = (i + (1 - j) + 1) % 3;
2363  WM_gizmo_set_matrix_rotation_from_yz_axis(gz, rv3d->twmat[i_ortho_a], rv3d->twmat[i]);
2364  WM_gizmo_set_matrix_location(gz, rv3d->twmat[3]);
2365 
2366  RNA_float_set_array(&gzop->ptr, "orient_matrix", &tbounds.axis[0][0]);
2367  RNA_enum_set(&gzop->ptr, "orient_type", orient_slot->type);
2368 
2369  RNA_enum_set(&gzop->ptr, "orient_axis", i_ortho_b);
2370  RNA_enum_set(&gzop->ptr, "orient_axis_ortho", i_ortho_a);
2371 
2372  mul_v3_fl(gz->matrix_basis[0], 0.5f);
2373  mul_v3_fl(gz->matrix_basis[1], 6.0f);
2374  }
2375  }
2376 
2377  for (int i = 0; i < 4; i++) {
2378  wmGizmo *gz = xgzgroup->gizmo_view[i];
2379  WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
2380  }
2381  }
2382 }
2383 
2385  wmGizmoGroup *gzgroup,
2386  struct wmMsgBus *mbus)
2387 {
2389  bScreen *screen = CTX_wm_screen(C);
2390  ScrArea *area = CTX_wm_area(C);
2391  ARegion *region = CTX_wm_region(C);
2393  gzgroup, mbus, scene, screen, area, region, VIEW3D_GGT_xform_shear);
2394 }
2395 
2397 {
2398  struct XFormShearWidgetGroup *xgzgroup = gzgroup->customdata;
2400  {
2402  /* Shear is like rotate, use the rotate setting. */
2405  switch (orient_slot->type) {
2406  case V3D_ORIENT_VIEW: {
2407  float viewinv_m3[3][3];
2408  copy_m3_m4(viewinv_m3, rv3d->viewinv);
2409  if (!equals_m3m3(viewinv_m3, xgzgroup->prev.viewinv_m3)) {
2410  /* Take care calling refresh from draw_prepare,
2411  * this should be OK because it's only adjusting the cage orientation. */
2413  }
2414  break;
2415  }
2416  }
2417  }
2418 
2419  for (int i = 0; i < 4; i++) {
2420  const float outer_thin = 0.3f;
2421  const float outer_offset = 1.0f / 0.3f;
2422  wmGizmo *gz = xgzgroup->gizmo_view[i];
2424  gz, rv3d->viewinv[(i + 1) % 2], rv3d->viewinv[i % 2]);
2425  if (i >= 2) {
2426  negate_v3(gz->matrix_basis[1]);
2427  negate_v3(gz->matrix_basis[2]);
2428  }
2429 
2430  /* No need for depth with view aligned gizmos. */
2431  mul_v3_fl(gz->matrix_basis[0], 0.0f);
2432  mul_v3_fl(gz->matrix_basis[1], 20.0f + ((1.0f / outer_thin) * 1.8f));
2433  mul_v3_fl(gz->matrix_basis[2], outer_thin);
2434  WM_gizmo_set_matrix_location(gz, rv3d->twmat[3]);
2435  gz->matrix_offset[3][2] = outer_offset;
2436  }
2437 
2438  /* Basic ordering for drawing only. */
2439  {
2440  LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
2441  /* Since we have two pairs of each axis,
2442  * bias the values so gizmos that are orthogonal to the view get priority.
2443  * This means we never default to shearing along
2444  * the view axis in the case of an overlap. */
2445  float axis_order[3], axis_bias[3];
2446  copy_v3_v3(axis_order, gz->matrix_basis[2]);
2447  copy_v3_v3(axis_bias, gz->matrix_basis[1]);
2448  if (dot_v3v3(axis_bias, rv3d->viewinv[2]) < 0.0f) {
2449  negate_v3(axis_bias);
2450  }
2451  madd_v3_v3fl(axis_order, axis_bias, 0.01f);
2452  gz->temp.f = dot_v3v3(rv3d->viewinv[2], axis_order);
2453  }
2455  }
2456 }
2457 
2459 {
2460  gzgt->name = "Transform Shear";
2461  gzgt->idname = "VIEW3D_GGT_xform_shear";
2462 
2465 
2468 
2475 }
2476 
typedef float(TangentPoint)[2]
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_active(struct Object *ob)
Definition: action.c:708
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct Object * CTX_data_edit_object(const bContext *C)
Definition: context.c:1296
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct bGPdata * CTX_data_gpencil_data(const bContext *C)
Definition: context.c:1371
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:760
struct Depsgraph * CTX_data_expect_evaluated_depsgraph(const bContext *C)
Definition: context.c:1415
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:709
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:769
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
struct ListBase * BKE_curve_editNurbs_get(struct Curve *cu)
Definition: curve.c:437
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
Definition: editmesh.c:85
@ G_TRANSFORM_OBJ
Definition: BKE_global.h:218
@ G_TRANSFORM_EDIT
Definition: BKE_global.h:219
bool BKE_gpencil_layer_is_editable(const struct bGPDlayer *gpl)
void BKE_gpencil_layer_transform_matrix_get(const struct Depsgraph *depsgraph, struct Object *obact, struct bGPDlayer *gpl, float diff_mat[4][4])
General operations, lookup, etc. for blender objects.
struct Object ** BKE_object_pose_array_get(struct ViewLayer *view_layer, struct View3D *v3d, unsigned int *r_objects_len)
Definition: object.c:2556
struct BoundBox * BKE_object_boundbox_get(struct Object *ob)
Definition: object.c:3817
#define PEP_HIDE
#define PEK_SELECT
#define PEK_USE_WCO
int BKE_scene_orientation_slot_get_index(const struct TransformOrientationSlot *orient_slot)
int BKE_scene_orientation_get_index(struct Scene *scene, int slot_index)
Definition: scene.c:2531
struct TransformOrientationSlot * BKE_scene_orientation_slot_get(struct Scene *scene, int slot_index)
Definition: scene.c:2486
struct TransformOrientationSlot * BKE_scene_orientation_slot_get_from_flag(struct Scene *scene, int flag)
Definition: scene.c:2494
int BKE_scene_orientation_get_index_from_flag(struct Scene *scene, int flag)
Definition: scene.c:2537
Generic array manipulation API.
#define BLI_array_findindex(arr, arr_len, p)
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define ATTR_FALLTHROUGH
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void void BLI_listbase_sort(struct ListBase *listbase, int(*cmp)(const void *, const void *)) ATTR_NONNULL(1
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
#define M_PI_2
Definition: BLI_math_base.h:41
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:930
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
void mul_mat3_m4_fl(float R[4][4], float f)
Definition: math_matrix.c:982
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:89
void unit_m3(float m[3][3])
Definition: math_matrix.c:58
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:105
void unit_m4(float m[4][4])
Definition: rct.c:1140
void copy_m4_m3(float m1[4][4], const float m2[3][3])
Definition: math_matrix.c:120
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void normalize_m3(float R[3][3]) ATTR_NONNULL()
Definition: math_matrix.c:1919
bool equals_m3m3(const float mat1[3][3], const float mat2[3][3])
Definition: math_matrix.c:2606
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:742
bool invert_m3(float R[3][3])
Definition: math_matrix.c:1152
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:391
void axis_angle_to_quat(float r[4], const float axis[3], const float angle)
void mul_qt_v3(const float q[4], float r[3])
Definition: math_rotation.c:97
void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], const short order)
MINLINE void copy_v4_v4(float r[4], const float a[4])
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t)
Definition: math_vector.c:49
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
Definition: math_vector.c:1020
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float normalize_v3(float r[3])
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 negate_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void negate_v3(float r[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE bool equals_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
Definition: math_vector.c:270
void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3])
Definition: math_vector.c:845
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
unsigned int uint
Definition: BLI_sys_types.h:83
#define INIT_MINMAX(min, max)
#define ARRAY_SIZE(arr)
#define ARRAY_SET_ITEMS(...)
#define UNUSED(x)
#define UNPACK3(a)
#define ELEM(...)
#define IN_RANGE_INCL(a, b, c)
#define STREQ(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
@ ROT_MODE_QUAT
@ ROT_MODE_AXISANGLE
@ BONE_ROOTSEL
@ BONE_SELECTED
@ BONE_TRANSFORM
@ BONE_EDITMODE_LOCKED
@ BONE_TIPSEL
@ BONE_CONNECTED
@ BONE_HINGE
@ CU_BEZIER
#define BEZT_ISSEL_IDX(bezt, i)
@ GP_CURVE_SELECT
@ GP_STROKE_SELECT
@ GP_DATA_STROKE_EDITMODE
#define GPENCIL_ANY_MODE(gpd)
#define GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd)
@ GP_CURVE_POINT_SELECT
@ GP_SPOINT_SELECT
@ BASE_SELECTED
#define OB_MODE_ALL_PAINT
@ OB_MODE_PARTICLE_EDIT
@ OB_MODE_EDIT
@ OB_MODE_SCULPT
@ OB_MODE_POSE
#define OB_MODE_ALL_SCULPT
@ OB_LOCK_ROTZ
@ OB_LOCK_ROT
@ OB_LOCK_SCALEZ
@ OB_LOCK_ROTX
@ OB_LOCK_SCALEX
@ OB_LOCK_LOCY
@ OB_LOCK_LOCZ
@ OB_LOCK_ROTY
@ OB_LOCK_SCALEY
@ OB_LOCK_LOC
@ OB_LOCK_LOCX
@ OB_LOCK_SCALE
@ OB_LATTICE
@ OB_MBALL
@ OB_SURF
@ OB_ARMATURE
@ OB_MESH
@ OB_CURVE
#define BASE_SELECTED_EDITABLE(v3d, base)
@ SCE_WORKSPACE_TOOL_FALLBACK
#define BASACT(_view_layer)
#define OBACT(_view_layer)
@ SCE_ORIENT_DEFAULT
@ SCE_ORIENT_ROTATE
@ SCE_ORIENT_SCALE
#define SCE_SNAP_MODE_GRID
#define SCE_SNAP_MODE_INCREMENT
@ RGN_TYPE_WINDOW
@ SPACE_VIEW3D
@ V3D_ORIENT_GLOBAL
@ V3D_ORIENT_LOCAL
@ V3D_ORIENT_VIEW
@ V3D_ORIENT_CURSOR
@ V3D_AROUND_ACTIVE
@ V3D_AROUND_CENTER_BOUNDS
@ V3D_AROUND_CURSOR
@ V3D_AROUND_CENTER_MEDIAN
@ V3D_AROUND_LOCAL_ORIGINS
@ V3D_GIZMO_SHOW_OBJECT_ROTATE
@ V3D_GIZMO_SHOW_OBJECT_SCALE
@ V3D_GIZMO_SHOW_OBJECT_TRANSLATE
@ CURVE_HANDLE_NONE
@ V3D_GIZMO_HIDE_TOOL
@ V3D_GIZMO_HIDE
@ V3D_GIZMO_HIDE_CONTEXT
@ OPERATOR_RUNNING_MODAL
#define EBONE_VISIBLE(arm, ebone)
Definition: ED_armature.h:56
@ ED_GIZMO_PRIMITIVE_STYLE_PLANE
@ ED_GIZMO_ARROW_DRAW_FLAG_STEM
@ ED_GIZMO_ARROW_STYLE_BOX
@ ED_GIZMO_ARROW_STYLE_NORMAL
@ ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE
@ ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE
@ ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT
@ ED_GIZMO_DIAL_DRAW_FLAG_FILL
@ ED_GIZMO_DIAL_DRAW_FLAG_NOP
@ ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE
@ ED_GIZMO_DIAL_DRAW_FLAG_CLIP
@ ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z
bool ED_gizmo_poll_or_unlink_delayed_from_tool(const struct bContext *C, struct wmGizmoGroupType *gzgt)
bool ED_object_calc_active_center(struct Object *ob, const bool select_only, float r_center[3])
Definition: object_utils.c:125
struct PTCacheEdit * PE_get_current(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob)
void ED_region_tag_redraw_editor_overlays(struct ARegion *region)
Definition: area.c:706
@ TFM_ROTATION
Definition: ED_transform.h:47
short ED_transform_calc_orientation_from_type_ex(const struct bContext *C, float r_mat[3][3], struct Scene *scene, struct RegionView3D *rv3d, struct Object *ob, struct Object *obedit, const short orientation_index, const int pivot_point)
bool ED_view3d_win_to_3d_on_plane(const struct ARegion *region, const float plane[4], const float mval[2], const bool do_clip, float r_out[3])
float ED_view3d_pixel_size(const struct RegionView3D *rv3d, const float co[3])
float ED_view3d_pixel_size_no_ui_scale(const struct RegionView3D *rv3d, const float co[3])
void ED_view3d_global_to_vector(const struct RegionView3D *rv3d, const float coord[3], float vec[3])
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 z
_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 y
_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:55
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:57
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:55
void GPU_line_smooth(bool enable)
Definition: gpu_state.cc:85
@ GPU_DEPTH_LESS_EQUAL
Definition: GPU_state.h:81
@ GPU_DEPTH_NONE
Definition: GPU_state.h:78
void GPU_depth_test(eGPUDepthTest test)
Definition: gpu_state.cc:75
Read Guarded memory(de)allocation.
StructRNA RNA_SpaceView3D
StructRNA RNA_View3DCursor
StructRNA RNA_TransformOrientationSlot
StructRNA RNA_ToolSettings
#define C
Definition: RandGen.cpp:39
#define UI_DPI_FAC
Definition: UI_interface.h:309
void UI_GetThemeColor3fv(int colorid, float col[3])
Definition: resources.c:1191
@ TH_GIZMO_VIEW_ALIGN
Definition: UI_resources.h:323
@ TH_AXIS_Y
Definition: UI_resources.h:317
@ TH_AXIS_X
Definition: UI_resources.h:316
@ TH_AXIS_Z
Definition: UI_resources.h:318
void UI_GetThemeColor4fv(int colorid, float col[4])
Definition: resources.c:1199
eWM_GizmoFlagTweak
Gizmo tweak flag. Bitflag passed to gizmo while tweaking.
@ WM_GIZMO_HIDDEN
@ WM_GIZMO_DRAW_VALUE
@ WM_GIZMO_MOVE_CURSOR
@ WM_GIZMO_DRAW_HOVER
@ WM_GIZMO_DRAW_OFFSET_SCALE
@ WM_GIZMO_SELECT_BACKGROUND
@ WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP
@ WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK
@ WM_GIZMOGROUPTYPE_3D
@ WM_GIZMOGROUPTYPE_PERSISTENT
@ BM_ELEM_HIDDEN
Definition: bmesh_class.h:472
@ BM_ELEM_SELECT
Definition: bmesh_class.h:471
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:26
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_VERTS_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
unsigned int U
Definition: btGjkEpa3.h:78
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
SIMD_FORCE_INLINE btVector3 rotate(const btVector3 &wAxis, const btScalar angle) const
Return a rotated version of this vector.
#define SELECT
Scene scene
const Depsgraph * depsgraph
static CCL_NAMESPACE_BEGIN const double alpha
void ED_gizmotypes_dial_3d_draw_util(const float matrix_basis[4][4], const float matrix_final[4][4], const float line_width, const float color[4], const bool select, struct Dial3dParams *params)
Definition: dial3d_gizmo.c:600
bool ED_gpencil_stroke_can_use(const bContext *C, const bGPDstroke *gps)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define fabsf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static unsigned a[3]
Definition: RandGen.cpp:92
static void area(int d1, int d2, int e1, int e2, float weights[2])
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:122
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:6272
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:3562
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
Definition: rna_access.c:2358
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
Definition: rna_access.c:6366
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
Definition: rna_access.c:3132
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6413
void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
Definition: rna_access.c:6390
void RNA_property_unset(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:6665
void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const bool *values)
Definition: rna_access.c:2482
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
unsigned int uint32_t
Definition: stdint.h:83
void * regiondata
struct BMesh * bm
Definition: BKE_editmesh.h:52
float co[3]
Definition: bmesh_class.h:99
int totvertsel
Definition: bmesh_class.h:298
uint8_t f1
float vec[4]
struct Base * next
short flag
struct Object * object
float vec[3][3]
float arm_mat[4][4]
float bone_mat[3][3]
float vec[8][3]
struct Lattice * latt
struct wmGizmo * gizmos[MAN_AXIS_LAST]
float viewinv_m3[3][3]
struct GizmoGroup::@582 prev
struct EditLatt * editlatt
struct BPoint * def
void * first
Definition: DNA_listBase.h:47
ListBase * editelems
struct Nurb * next
short type
BezTriple * bezt
BPoint * bp
struct bPose * pose
float imat[4][4]
float rot[3]
float obmat[4][4]
short rotmode
float rotAngle
float rotAxis[3]
short protectflag
struct Object * parent
struct SculptSession * sculpt
struct PTCacheEditKey * keys
PTCacheEditPoint * points
float tw_axis_matrix[3][3]
float tw_axis_min[3]
float tw_axis_max[3]
float twmat[4][4]
float viewinv[4][4]
struct ToolSettings * toolsettings
View3DCursor cursor
TransformOrientationSlot orientation_slots[4]
float pivot_pos[3]
Definition: BKE_paint.h:567
char transform_pivot_point
eTConstraint mode
Definition: transform.h:348
float axis_min[3]
Definition: ED_transform.h:181
float axis[3][3]
Definition: ED_transform.h:180
float axis_max[3]
Definition: ED_transform.h:181
View3DOverlay overlay
char gizmo_flag
char gizmo_show_object
ListBase object_bases
struct XFormCageWidgetGroup::@583 prev
struct XFormShearWidgetGroup::@584 prev
ListBase * edbo
bGPDcurve_point * curve_points
ListBase layers
struct Bone * bone
struct bPoseChannel * parent
float pose_head[3]
struct bPoseChannel * next
float pose_mat[4][4]
ListBase chanbase
char idname[64]
bToolRef_Runtime * runtime
short shift
Definition: WM_types.h:618
short type
Definition: WM_types.h:577
wmGizmoGroupFnSetupKeymap setup_keymap
wmGizmoGroupFnMsgBusSubscribe message_subscribe
wmGizmoGroupFnRefresh refresh
wmGizmoGroupFnInit setup
const char * idname
wmGizmoGroupFnInvokePrepare invoke_prepare
eWM_GizmoFlagGroupTypeFlag flag
wmGizmoGroupFnPoll poll
struct StructRNA * srna
struct wmGizmoMapType_Params gzmap_params
const char * name
wmGizmoGroupFnDrawPrepare draw_prepare
ListBase gizmos
struct wmGizmoMap * parent_gzmap
bool use_fallback_keymap
PointerRNA ptr
float matrix_basis[4][4]
float select_bias
float matrix_offset[4][4]
float color_hi[4]
float color[4]
struct PointerRNA * ptr
float matrix_space[4][4]
eWM_GizmoFlag flag
union wmGizmo::@1148 temp
struct wmEvent * eventstate
@ CON_APPLY
Definition: transform.h:177
@ CON_AXIS1
Definition: transform.h:180
@ CON_AXIS0
Definition: transform.h:179
@ CON_AXIS2
Definition: transform.h:181
@ CTX_PAINT_CURVE
Definition: transform.h:86
@ MOD_PRECISION
Definition: transform.h:158
#define GIZMO_AXIS_LINE_WIDTH
Definition: transform.h:707
conversion and adaptation of different datablocks to a common struct.
int transform_convert_pose_transflags_update(Object *ob, const int mode, const short around, bool has_translate_rotate[2])
#define MAN_AXIS_RANGE_SCALE_START
#define MAN_AXIS_RANGE_ROT_END
static void WIDGETGROUP_xform_shear_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
static void WIDGETGROUP_gizmo_invoke_prepare(const bContext *C, wmGizmoGroup *gzgroup, wmGizmo *gz, const wmEvent *UNUSED(event))
static bool WIDGETGROUP_gizmo_poll_generic(View3D *v3d)
static bool test_rotmode_euler(short rotmode)
float max
@ MAN_AXES_ROTATE
@ MAN_AXES_SCALE
@ MAN_AXES_TRANSLATE
@ MAN_AXES_ALL
void VIEW3D_GGT_xform_gizmo_context(wmGizmoGroupType *gzgt)
static void protectflag_to_drawflags(short protectflag, short *drawflags)
static bool WIDGETGROUP_gizmo_poll_context(const struct bContext *C, struct wmGizmoGroupType *UNUSED(gzgt))
void VIEW3D_GGT_xform_shear(wmGizmoGroupType *gzgt)
#define MAN_TRANS_C
#define MAN_SCALE_Z
static void WIDGETGROUP_gizmo_setup(const bContext *C, wmGizmoGroup *gzgroup)
static void gizmo_get_axis_color(const int axis_idx, const float idot[3], float r_col[4], float r_col_hi[4])
#define MAN_ROT_X
static void calc_tw_center_with_matrix(struct TransformBounds *tbounds, const float co[3], const bool use_matrix, const float matrix[4][4])
float min
void VIEW3D_GGT_xform_gizmo(wmGizmoGroupType *gzgt)
#define MAN_SCALE_X
static void reset_tw_center(struct TransformBounds *tbounds)
static int gizmo_modal(bContext *C, wmGizmo *widget, const wmEvent *event, eWM_GizmoFlagTweak UNUSED(tweak_flag))
@ MAN_AXIS_LAST
@ MAN_AXIS_SCALE_X
@ MAN_AXIS_TRANS_ZX
@ MAN_AXIS_ROT_Z
@ MAN_AXIS_TRANS_Z
@ MAN_AXIS_SCALE_XY
@ MAN_AXIS_TRANS_XY
@ MAN_AXIS_ROT_T
@ MAN_AXIS_TRANS_YZ
@ MAN_AXIS_TRANS_C
@ MAN_AXIS_TRANS_Y
@ MAN_AXIS_SCALE_ZX
@ MAN_AXIS_ROT_X
@ MAN_AXIS_SCALE_C
@ MAN_AXIS_TRANS_X
@ MAN_AXIS_SCALE_Y
@ MAN_AXIS_SCALE_YZ
@ MAN_AXIS_ROT_C
@ MAN_AXIS_ROT_Y
@ MAN_AXIS_SCALE_Z
static void gizmo_get_idot(RegionView3D *rv3d, float r_idot[3])
static void WIDGETGROUP_xform_shear_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *gzgroup)
static void protectflag_to_drawflags_pchan(RegionView3D *rv3d, const bPoseChannel *pchan, short orientation_index)
static void protectflag_to_drawflags_ebone(RegionView3D *rv3d, const EditBone *ebo)
static void WIDGETGROUP_xform_shear_message_subscribe(const bContext *C, wmGizmoGroup *gzgroup, struct wmMsgBus *mbus)
struct GizmoGroup GizmoGroup
#define FOREACH_EDIT_OBJECT_BEGIN(ob_iter, use_mat_local)
#define GIZMO_NEW_PRIM(v, draw_style)
static bool WIDGETGROUP_xform_cage_poll(const bContext *C, wmGizmoGroupType *gzgt)
#define MAN_ROT_Y
static GizmoGroup * gizmogroup_init(wmGizmoGroup *gzgroup)
static void gizmo_prepare_mat(const bContext *C, RegionView3D *rv3d, const struct TransformBounds *tbounds)
#define MAN_ROT_C
static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *gzgroup)
#define MAN_ITER_AXES_END
static void WIDGETGROUP_xform_cage_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
#define MAN_AXIS_RANGE_TRANS_END
static void gizmo_line_range(const int twtype, const short axis_type, float *r_start, float *r_len)
int ED_transform_calc_gizmo_stats(const bContext *C, const struct TransformCalcParams *params, struct TransformBounds *tbounds)
#define MAN_TRANS_X
void drawDial3d(const TransInfo *t)
static void gizmo_get_axis_constraint(const int axis_idx, bool r_axis[3])
static bool gizmo_is_axis_visible(const RegionView3D *rv3d, const int twtype, const float idot[3], const int axis_type, const int axis_idx)
static void axis_angle_to_gimbal_axis(float gmat[3][3], const float axis[3], const float angle)
#define GIZMO_NEW_ARROW(v, draw_style)
static void WIDGETGROUP_xform_cage_message_subscribe(const bContext *C, wmGizmoGroup *gzgroup, struct wmMsgBus *mbus)
#define FOREACH_EDIT_OBJECT_END()
static void gizmo_xform_message_subscribe(wmGizmoGroup *gzgroup, struct wmMsgBus *mbus, Scene *scene, bScreen *screen, ScrArea *area, ARegion *region, const void *type_fn)
#define MAN_AXIS_RANGE_ROT_START
static bool WIDGETGROUP_xform_shear_poll(const bContext *C, wmGizmoGroupType *gzgt)
bool gimbal_axis(Object *ob, float gmat[3][3])
static void WIDGETGROUP_xform_shear_refresh(const bContext *C, wmGizmoGroup *gzgroup)
static uint gizmo_orientation_axis(const int axis_idx, bool *r_is_plane)
static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
#define MAN_AXIS_RANGE_SCALE_END
static void WIDGETGROUP_gizmo_message_subscribe(const bContext *C, wmGizmoGroup *gzgroup, struct wmMsgBus *mbus)
#define MAN_ROT_Z
static short gizmo_get_axis_type(const int axis_idx)
static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
static struct @579 g_tw_axis_range[2]
static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
#define MAN_TRANS_Z
#define GIZMO_NEW_DIAL(v, draw_options)
static void calc_tw_center(struct TransformBounds *tbounds, const float co[3])
static wmGizmo * gizmo_get_axis_from_index(const GizmoGroup *ggd, const short axis_idx)
#define MAN_ITER_AXES_BEGIN(axis, axis_idx)
void VIEW3D_GGT_xform_cage(wmGizmoGroupType *gzgt)
#define MAN_SCALE_C
#define MAN_SCALE_Y
static bool WIDGETGROUP_gizmo_poll_tool(const struct bContext *C, struct wmGizmoGroupType *gzgt)
#define MAN_TRANS_Y
#define MAN_AXIS_RANGE_TRANS_START
bool transformModeUseSnap(const TransInfo *t)
bool activeSnap(const TransInfo *t)
#define G(x, y, z)
uint len
@ TIMER
@ INBETWEEN_MOUSEMOVE
PointerRNA * ptr
Definition: wm_files.c:3157
void WM_gizmo_set_matrix_offset_location(wmGizmo *gz, const float offset[3])
Definition: wm_gizmo.c:334
void WM_gizmo_set_fn_custom_modal(struct wmGizmo *gz, wmGizmoFnModal fn)
Definition: wm_gizmo.c:383
PointerRNA * WM_gizmo_operator_set(wmGizmo *gz, int part_index, wmOperatorType *ot, IDProperty *properties)
Definition: wm_gizmo.c:232
void WM_gizmo_set_color_highlight(wmGizmo *gz, const float color_hi[4])
Definition: wm_gizmo.c:372
void WM_gizmo_set_line_width(wmGizmo *gz, const float line_width)
Definition: wm_gizmo.c:354
void WM_gizmo_set_matrix_rotation_from_yz_axis(wmGizmo *gz, const float y_axis[3], const float z_axis[3])
Definition: wm_gizmo.c:310
wmGizmo * WM_gizmo_new_ptr(const wmGizmoType *gzt, wmGizmoGroup *gzgroup, PointerRNA *properties)
Definition: wm_gizmo.c:96
void WM_gizmo_set_scale(wmGizmo *gz, const float scale)
Definition: wm_gizmo.c:349
void WM_gizmo_set_matrix_location(wmGizmo *gz, const float origin[3])
Definition: wm_gizmo.c:316
void WM_gizmo_set_flag(wmGizmo *gz, const int flag, const bool enable)
Definition: wm_gizmo.c:339
void WM_gizmo_set_matrix_rotation_from_z_axis(wmGizmo *gz, const float z_axis[3])
Definition: wm_gizmo.c:306
struct wmGizmoOpElem * WM_gizmo_operator_get(wmGizmo *gz, int part_index)
Definition: wm_gizmo.c:224
void WM_gizmo_set_color(wmGizmo *gz, const float color[4])
Definition: wm_gizmo.c:363
int WM_gizmo_cmp_temp_fl_reverse(const void *gz_a_ptr, const void *gz_b_ptr)
wmKeyMap * WM_gizmogroup_setup_keymap_generic_maybe_drag(const wmGizmoGroupType *UNUSED(gzgt), wmKeyConfig *kc)
wmGizmo * wm_gizmomap_modal_get(wmGizmoMap *gzmap)
void WM_gizmo_do_msg_notify_tag_refresh(bContext *UNUSED(C), wmMsgSubscribeKey *UNUSED(msg_key), wmMsgSubscribeValue *msg_val)
const wmGizmoType * WM_gizmotype_find(const char *idname, bool quiet)
Definition: wm_gizmo_type.c:58
#define WM_msg_subscribe_rna_anon_prop(mbus, type_, prop_, value)
void WM_msg_subscribe_rna(struct wmMsgBus *mbus, PointerRNA *ptr, const PropertyRNA *prop, const wmMsgSubscribeValue *msg_val_params, const char *id_repr)
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)