Blender  V3.3
editmesh_extrude_spin_gizmo.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include "BLI_listbase.h"
8 #include "BLI_math.h"
9 
10 #include "BKE_context.h"
11 #include "BKE_scene.h"
12 
13 #include "RNA_access.h"
14 #include "RNA_define.h"
15 #include "RNA_enum_types.h"
16 
17 #include "WM_api.h"
18 #include "WM_message.h"
19 #include "WM_toolsystem.h"
20 #include "WM_types.h"
21 
22 #include "ED_gizmo_utils.h"
23 #include "ED_screen.h"
24 #include "ED_view3d.h"
25 
26 #include "UI_resources.h"
27 
28 #include "MEM_guardedalloc.h"
29 
30 #include "mesh_intern.h" /* own include */
31 
32 #include "ED_transform.h"
33 
34 #include "ED_gizmo_library.h"
35 #include "ED_undo.h"
36 
40 /* Disable for now, issues w/ refresh and '+' icons overlap. */
41 // #define USE_SELECT_CENTER
42 
43 #ifdef USE_SELECT_CENTER
44 # include "BKE_editmesh.h"
45 #endif
46 
47 static const float dial_angle_partial = M_PI_2;
48 static const float dial_angle_partial_margin = 0.92f;
49 
50 #define ORTHO_AXIS_OFFSET 2
51 
52 /* -------------------------------------------------------------------- */
56 typedef struct GizmoGroupData_SpinInit {
57  struct {
60  } gizmos;
61 
62  /* Only for view orientation. */
63  struct {
64  float viewinv_m3[3][3];
65  } prev;
66 
67  /* We could store more vars here! */
68  struct {
71  float orient_mat[3][3];
72 #ifdef USE_SELECT_CENTER
73  float select_center[3];
74  float select_center_ortho_axis[3][3];
75  bool use_select_center;
76 #endif
77  } data;
78 
79  /* Store data for invoke. */
80  struct {
82  } invoke;
83 
85 
86 /* Use dials only as a visualization when hovering over the icons. */
87 #define USE_DIAL_HOVER
88 
89 #define INIT_SCALE_BASE 2.3f
90 #define INIT_SCALE_BUTTON 0.15f
91 
92 static const uchar shape_plus[] = {
93  0x73, 0x73, 0x73, 0x36, 0x8c, 0x36, 0x8c, 0x73, 0xc9, 0x73, 0xc9, 0x8c, 0x8c,
94  0x8c, 0x8c, 0xc9, 0x73, 0xc9, 0x73, 0x8c, 0x36, 0x8c, 0x36, 0x73, 0x36, 0x73,
95 };
96 
98 {
99  /* alpha values for normal/highlighted states */
100  const float alpha = 0.6f;
101  const float alpha_hi = 1.0f;
102  const float scale_base = INIT_SCALE_BASE;
103  const float scale_button = INIT_SCALE_BUTTON;
104 
105  GizmoGroupData_SpinInit *ggd = MEM_callocN(sizeof(*ggd), __func__);
106  gzgroup->customdata = ggd;
107  const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
108  const wmGizmoType *gzt_button = WM_gizmotype_find("GIZMO_GT_button_2d", true);
109 
110  for (int i = 0; i < 3; i++) {
111  for (int j = 0; j < 2; j++) {
112  wmGizmo *gz = WM_gizmo_new_ptr(gzt_button, gzgroup, NULL);
113  PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "shape");
115  gz->ptr, prop, (const char *)shape_plus, ARRAY_SIZE(shape_plus));
116 
117  RNA_enum_set(gz->ptr, "draw_options", ED_GIZMO_BUTTON_SHOW_BACKDROP);
118 
119  float color[4];
121  color[3] = alpha;
123 
124  WM_gizmo_set_scale(gz, scale_button);
125  gz->color[3] = 0.6f;
126 
128 
129  ggd->gizmos.icon_button[i][j] = gz;
130  }
131  }
132 
133  for (int i = 0; i < ARRAY_SIZE(ggd->gizmos.xyz_view); i++) {
134  wmGizmo *gz = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
137  ggd->gizmos.xyz_view[i] = gz;
138  }
139 
140  for (int i = 0; i < 3; i++) {
141  wmGizmo *gz = ggd->gizmos.xyz_view[i];
142 #ifndef USE_DIAL_HOVER
143  RNA_enum_set(gz->ptr, "draw_options", ED_GIZMO_DIAL_DRAW_FLAG_CLIP);
144 #endif
145  WM_gizmo_set_line_width(gz, 2.0f);
146  float color[4];
148  color[3] = alpha;
150  color[3] = alpha_hi;
153  RNA_float_set(gz->ptr,
154  "arc_partial_angle",
156  }
157 
158  {
159  wmGizmo *gz = ggd->gizmos.xyz_view[3];
160  WM_gizmo_set_line_width(gz, 2.0f);
161  float color[4];
162  copy_v3_fl(color, 1.0f);
163  color[3] = alpha;
165  color[3] = alpha_hi;
167  WM_gizmo_set_scale(gz, scale_base);
168  }
169 
170 #ifdef USE_DIAL_HOVER
171  for (int i = 0; i < 4; i++) {
172  wmGizmo *gz = ggd->gizmos.xyz_view[i];
174  }
175 #endif
176 
177  ggd->data.ot_spin = WM_operatortype_find("MESH_OT_spin", true);
178  ggd->data.gzgt_axis_prop = RNA_struct_type_find_property(gzgroup->type->srna, "axis");
179 }
180 
181 static void gizmo_mesh_spin_init_refresh(const bContext *C, wmGizmoGroup *gzgroup);
182 
184  int axis_index,
185  const float axis_vec[3],
186  const float axis_tan[3])
187 {
188  GizmoGroupData_SpinInit *ggd = gzgroup->customdata;
189  wmGizmo *gz = ggd->gizmos.xyz_view[axis_index];
190  if (axis_tan != NULL) {
191  WM_gizmo_set_matrix_rotation_from_yz_axis(gz, axis_tan, axis_vec);
192  }
193  else {
195  }
196 
197  /* Only for display, use icons to access. */
198 #ifndef USE_DIAL_HOVER
199  {
201  RNA_float_set_array(ptr, "axis", axis_vec);
202  }
203 #endif
204  if (axis_index < 3) {
205  for (int j = 0; j < 2; j++) {
206  gz = ggd->gizmos.icon_button[axis_index][j];
208  float axis_vec_flip[3];
209  if (0 == j) {
210  negate_v3_v3(axis_vec_flip, axis_vec);
211  }
212  else {
213  copy_v3_v3(axis_vec_flip, axis_vec);
214  }
215  RNA_float_set_array(ptr, "axis", axis_vec_flip);
216  }
217  }
218 }
219 
221 {
222  GizmoGroupData_SpinInit *ggd = gzgroup->customdata;
224  float viewinv_m3[3][3];
225  copy_m3_m4(viewinv_m3, rv3d->viewinv);
226 
227  {
231  switch (orient_slot->type) {
232  case V3D_ORIENT_VIEW: {
233  if (!equals_m3m3(viewinv_m3, ggd->prev.viewinv_m3)) {
234  /* Take care calling refresh from draw_prepare,
235  * this should be OK because it's only adjusting the cage orientation. */
237  }
238  break;
239  }
240  }
241  }
242 
243  /* Refresh handled above when using view orientation. */
244  if (!equals_m3m3(viewinv_m3, ggd->prev.viewinv_m3)) {
246  copy_m3_m4(ggd->prev.viewinv_m3, rv3d->viewinv);
247  }
248 
249  /* Hack! highlight XYZ dials based on buttons */
250 #ifdef USE_DIAL_HOVER
251  {
252  PointerRNA ptr;
255  const int axis_flag = RNA_property_enum_get(&ptr, ggd->data.gzgt_axis_prop);
256  for (int i = 0; i < 4; i++) {
257  bool hide = (axis_flag & (1 << i)) == 0;
258  wmGizmo *gz = ggd->gizmos.xyz_view[i];
260  if (!hide) {
261  RNA_float_set(gz->ptr,
262  "arc_partial_angle",
264  }
265  }
266 
267  for (int i = 0; i < 3; i++) {
268  for (int j = 0; j < 2; j++) {
269  wmGizmo *gz = ggd->gizmos.icon_button[i][j];
270  if (gz->state & WM_GIZMO_STATE_HIGHLIGHT) {
272  RNA_float_set(ggd->gizmos.xyz_view[i]->ptr, "arc_partial_angle", 0.0f);
273  i = 3;
274  break;
275  }
276  }
277  }
278  }
279 #endif
280 }
281 
283  wmGizmoGroup *gzgroup,
284  wmGizmo *gz,
285  const wmEvent *UNUSED(event))
286 {
287  /* Set the initial ortho axis. */
288  GizmoGroupData_SpinInit *ggd = gzgroup->customdata;
289  ggd->invoke.ortho_axis_active = -1;
290  for (int i = 0; i < 3; i++) {
291  if (ELEM(gz, UNPACK2(ggd->gizmos.icon_button[i]))) {
292  ggd->invoke.ortho_axis_active = i;
293  break;
294  }
295  }
296 }
297 
299 {
300  GizmoGroupData_SpinInit *ggd = gzgroup->customdata;
302  const float *gizmo_center = NULL;
303  {
305  const View3DCursor *cursor = &scene->cursor;
306  gizmo_center = cursor->location;
307  }
308 
309  for (int i = 0; i < ARRAY_SIZE(ggd->gizmos.xyz_view); i++) {
310  wmGizmo *gz = ggd->gizmos.xyz_view[i];
311  WM_gizmo_set_matrix_location(gz, gizmo_center);
312  }
313 
314  for (int i = 0; i < ARRAY_SIZE(ggd->gizmos.icon_button); i++) {
315  for (int j = 0; j < 2; j++) {
316  wmGizmo *gz = ggd->gizmos.icon_button[i][j];
317  WM_gizmo_set_matrix_location(gz, gizmo_center);
318  }
319  }
320 
322  for (int i = 0; i < 3; i++) {
323  const int axis_ortho = (i + ORTHO_AXIS_OFFSET) % 3;
324  const float *axis_ortho_vec = ggd->data.orient_mat[axis_ortho];
325 #ifdef USE_SELECT_CENTER
326  if (ggd->data.use_select_center) {
327  float delta[3];
328  sub_v3_v3v3(delta, ggd->data.select_center, gizmo_center);
330  ggd->data.select_center_ortho_axis[i], delta, ggd->data.orient_mat[i]);
331  if (normalize_v3(ggd->data.select_center_ortho_axis[i]) != 0.0f) {
332  axis_ortho_vec = ggd->data.select_center_ortho_axis[i];
333  }
334  }
335 #endif
337  gzgroup, i, ggd->data.orient_mat[i], axis_ortho_vec);
338  }
339 
340  {
342  }
343 
344 #ifdef USE_SELECT_CENTER
345  {
346  Object *obedit = CTX_data_edit_object(C);
347  BMEditMesh *em = BKE_editmesh_from_object(obedit);
348  float select_center[3] = {0};
349  int totsel = 0;
350 
351  BMesh *bm = em->bm;
352  BMVert *eve;
353  BMIter iter;
354 
355  BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
356  if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
357  if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
358  totsel++;
359  add_v3_v3(select_center, eve->co);
360  }
361  }
362  }
363  if (totsel) {
364  mul_v3_fl(select_center, 1.0f / totsel);
365  mul_m4_v3(obedit->obmat, select_center);
366  copy_v3_v3(ggd->data.select_center, select_center);
367  ggd->data.use_select_center = true;
368  }
369  else {
370  ggd->data.use_select_center = false;
371  }
372  }
373 #endif
374 
375  for (int i = 0; i < ARRAY_SIZE(ggd->gizmos.icon_button); i++) {
376  const int axis_ortho = (i + ORTHO_AXIS_OFFSET) % 3;
377  const float *axis_ortho_vec = ggd->data.orient_mat[axis_ortho];
379  float offset_vec[3];
380 
381 #ifdef USE_SELECT_CENTER
382  if (ggd->data.use_select_center && !is_zero_v3(ggd->data.select_center_ortho_axis[i])) {
383  axis_ortho_vec = ggd->data.select_center_ortho_axis[i];
384  }
385 #endif
386 
387  mul_v3_v3fl(offset_vec, axis_ortho_vec, offset);
388  for (int j = 0; j < 2; j++) {
389  wmGizmo *gz = ggd->gizmos.icon_button[i][j];
390  float mat3[3][3];
391  axis_angle_to_mat3(mat3, ggd->data.orient_mat[i], dial_angle_partial * (j ? -0.5f : 0.5f));
392  mul_v3_m3v3(gz->matrix_offset[3], mat3, offset_vec);
393  }
394  }
395 
396  {
397  PointerRNA ptr;
400  const int axis_flag = RNA_property_enum_get(&ptr, ggd->data.gzgt_axis_prop);
401  for (int i = 0; i < ARRAY_SIZE(ggd->gizmos.icon_button); i++) {
402  for (int j = 0; j < 2; j++) {
403  wmGizmo *gz = ggd->gizmos.icon_button[i][j];
404  WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, (axis_flag & (1 << i)) == 0);
405  }
406  }
407  }
408 
409  /* Needed to test view orientation changes. */
410  copy_m3_m4(ggd->prev.viewinv_m3, rv3d->viewinv);
411 }
412 
414  wmGizmoGroup *gzgroup,
415  struct wmMsgBus *mbus)
416 {
417  GizmoGroupData_SpinInit *ggd = gzgroup->customdata;
419  ARegion *region = CTX_wm_region(C);
420 
421  /* Subscribe to view properties */
422  wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = {
423  .owner = region,
424  .user_data = gzgroup->parent_gzmap,
426  };
427 
428  PointerRNA cursor_ptr;
429  RNA_pointer_create(&scene->id, &RNA_View3DCursor, &scene->cursor, &cursor_ptr);
430  /* All cursor properties. */
431  WM_msg_subscribe_rna(mbus, &cursor_ptr, NULL, &msg_sub_value_gz_tag_refresh, __func__);
432 
434  &(const wmMsgParams_RNA){
435  .ptr =
436  (PointerRNA){
437  .type = gzgroup->type->srna,
438  },
439  .prop = ggd->data.gzgt_axis_prop,
440  },
441  &msg_sub_value_gz_tag_refresh,
442  __func__);
443 }
444 
445 void MESH_GGT_spin(struct wmGizmoGroupType *gzgt)
446 {
447  gzgt->name = "Mesh Spin Init";
448  gzgt->idname = "MESH_GGT_spin";
449 
451 
454 
457  /* This works well with right click selection but overrides left-mouse selection
458  * when clicking which is needed to create a full 360 degree revolution, see: T89912. */
459  // gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
464 
465  RNA_def_enum_flag(gzgt->srna, "axis", rna_enum_axis_flag_xyz_items, (1 << 2), "Axis", "");
466 }
467 
468 #undef INIT_SCALE_BASE
469 #undef INIT_SCALE_BUTTON
470 
473 /* -------------------------------------------------------------------- */
482 #define USE_ANGLE_Z_ORIENT
483 
484 typedef struct GizmoGroupData_SpinRedo {
485  /* Translate XYZ. */
487  /* Spin angle */
488  struct wmGizmo *angle_z;
489 
490  /* Translate XY constrained ('orient_mat'). */
491  struct wmGizmo *translate_xy[2];
492  /* Rotate XY constrained ('orient_mat'). */
493  struct wmGizmo *rotate_xy[2];
494 
495  /* Rotate on view axis. */
497 
498  struct {
499  float plane_co[3];
500  float plane_no[3];
501  } prev;
502 
503  bool is_init;
504 
505  /* We could store more vars here! */
506  struct {
513 
514 #ifdef USE_ANGLE_Z_ORIENT
515  /* Apply 'orient_mat' for the final value. */
517 #endif
518  /* The orientation, since the operator doesn't store this, we store our own.
519  * this is kept in sync with the operator,
520  * rotating the orientation when it doesn't match.
521  *
522  * Initialize to a sensible value where possible.
523  */
524  float orient_mat[3][3];
525 
526  } data;
528 
535 {
536  if (ggd->is_init) {
537  wmGizmo *gz = ggd->angle_z;
538  PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "click_value");
539  RNA_property_unset(gz->ptr, prop);
540  ggd->is_init = false;
541  }
542 
543  wmOperator *op = ggd->data.op;
544  if (op == WM_operator_last_redo((bContext *)ggd->data.context)) {
546  }
547 }
548 
550  const float plane_no[3])
551 {
552  float mat[3][3];
553  rotation_between_vecs_to_mat3(mat, ggd->data.orient_mat[2], plane_no);
554  mul_m3_m3m3(ggd->data.orient_mat, mat, ggd->data.orient_mat);
555  /* Not needed, just set for numeric stability. */
556  copy_v3_v3(ggd->data.orient_mat[2], plane_no);
557 }
558 
560 {
561  wmOperator *op = ggd->data.op;
562  float plane_co[3], plane_no[3];
563  RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_co, plane_co);
564  RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_no, plane_no);
565  if (UNLIKELY(normalize_v3(plane_no) == 0.0f)) {
566  return;
567  }
568  const bool is_plane_co_eq = equals_v3v3(plane_co, ggd->prev.plane_co);
569  const bool is_plane_no_eq = equals_v3v3(plane_no, ggd->prev.plane_no);
570  if (is_plane_co_eq && is_plane_no_eq) {
571  return;
572  }
573  copy_v3_v3(ggd->prev.plane_co, plane_co);
574  copy_v3_v3(ggd->prev.plane_no, plane_no);
575 
576  if (is_plane_no_eq == false) {
578  }
579 
580  for (int i = 0; i < 2; i++) {
581  WM_gizmo_set_matrix_location(ggd->rotate_xy[i], plane_co);
582  WM_gizmo_set_matrix_location(ggd->translate_xy[i], plane_co);
583  }
584  WM_gizmo_set_matrix_location(ggd->angle_z, plane_co);
586  /* translate_c location comes from the property. */
587 
588  for (int i = 0; i < 2; i++) {
591  }
592 #ifdef USE_ANGLE_Z_ORIENT
593  {
594  float plane_tan[3];
595  float orient_axis[3];
596  mul_v3_m3v3(orient_axis, ggd->data.orient_mat, ggd->data.orient_axis_relative);
597  project_plane_normalized_v3_v3v3(plane_tan, orient_axis, plane_no);
598  if (normalize_v3(plane_tan) != 0.0f) {
599  WM_gizmo_set_matrix_rotation_from_yz_axis(ggd->angle_z, plane_tan, plane_no);
600  }
601  else {
603  }
604  }
605 #else
607 #endif
608 }
609 
610 /* depth callbacks */
611 static void gizmo_spin_prop_depth_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
612 {
614  wmOperator *op = ggd->data.op;
615  float *value = value_p;
616 
617  BLI_assert(gz_prop->type->array_length == 1);
618  UNUSED_VARS_NDEBUG(gz_prop);
619 
620  const float *plane_no = gz->matrix_basis[2];
621  float plane_co[3];
622  RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_co, plane_co);
623 
624  value[0] = dot_v3v3(plane_no, plane_co) - dot_v3v3(plane_no, gz->matrix_basis[3]);
625 }
626 
627 static void gizmo_spin_prop_depth_set(const wmGizmo *gz,
628  wmGizmoProperty *gz_prop,
629  const void *value_p)
630 {
632  wmOperator *op = ggd->data.op;
633  const float *value = value_p;
634 
635  BLI_assert(gz_prop->type->array_length == 1);
636  UNUSED_VARS_NDEBUG(gz_prop);
637 
638  float plane_co[3], plane[4];
639  RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_co, plane_co);
640  normalize_v3_v3(plane, gz->matrix_basis[2]);
641 
642  plane[3] = -value[0] - dot_v3v3(plane, gz->matrix_basis[3]);
643 
644  /* Keep our location, may be offset simply to be inside the viewport. */
645  closest_to_plane_normalized_v3(plane_co, plane, plane_co);
646 
647  RNA_property_float_set_array(op->ptr, ggd->data.prop_axis_co, plane_co);
648 
649  gizmo_spin_exec(ggd);
650 }
651 
652 /* translate callbacks */
654  wmGizmoProperty *gz_prop,
655  void *value_p)
656 {
658  wmOperator *op = ggd->data.op;
659  float *value = value_p;
660 
661  BLI_assert(gz_prop->type->array_length == 3);
662  UNUSED_VARS_NDEBUG(gz_prop);
663 
665 }
666 
668  wmGizmoProperty *gz_prop,
669  const void *value)
670 {
672  wmOperator *op = ggd->data.op;
673 
674  BLI_assert(gz_prop->type->array_length == 3);
675  UNUSED_VARS_NDEBUG(gz_prop);
676 
678 
679  gizmo_spin_exec(ggd);
680 }
681 
682 /* angle callbacks */
684  wmGizmoProperty *gz_prop,
685  void *value_p)
686 {
688  wmOperator *op = ggd->data.op;
689  float *value = value_p;
690 
691  BLI_assert(gz_prop->type->array_length == 1);
692  UNUSED_VARS_NDEBUG(gz_prop);
693 
694  float plane_no[4];
695  RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_no, plane_no);
696  normalize_v3(plane_no);
697 
698  const float *rotate_axis = gz->matrix_basis[2];
699  float rotate_up[3];
700  ortho_v3_v3(rotate_up, rotate_axis);
701 
702  float plane_no_proj[3];
703  project_plane_normalized_v3_v3v3(plane_no_proj, plane_no, rotate_axis);
704 
705  if (!is_zero_v3(plane_no_proj)) {
706  const float angle = -angle_signed_on_axis_v3v3_v3(plane_no_proj, rotate_up, rotate_axis);
707  value[0] = angle;
708  }
709  else {
710  value[0] = 0.0f;
711  }
712 }
713 
715  wmGizmoProperty *gz_prop,
716  const void *value_p)
717 {
719  wmOperator *op = ggd->data.op;
720  const float *value = value_p;
721 
722  BLI_assert(gz_prop->type->array_length == 1);
723  UNUSED_VARS_NDEBUG(gz_prop);
724 
725  float plane_no[4];
726  RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_no, plane_no);
727  normalize_v3(plane_no);
728 
729  const float *rotate_axis = gz->matrix_basis[2];
730  float rotate_up[3];
731  ortho_v3_v3(rotate_up, rotate_axis);
732 
733  float plane_no_proj[3];
734  project_plane_normalized_v3_v3v3(plane_no_proj, plane_no, rotate_axis);
735 
736  if (!is_zero_v3(plane_no_proj)) {
737  const float angle = -angle_signed_on_axis_v3v3_v3(plane_no_proj, rotate_up, rotate_axis);
738  const float angle_delta = angle - angle_compat_rad(value[0], angle);
739  if (angle_delta != 0.0f) {
740  float mat[3][3];
741  axis_angle_normalized_to_mat3(mat, rotate_axis, angle_delta);
742  mul_m3_v3(mat, plane_no);
743 
744  /* re-normalize - seems acceptable */
745  RNA_property_float_set_array(op->ptr, ggd->data.prop_axis_no, plane_no);
746 
747  gizmo_spin_exec(ggd);
748  }
749  }
750 }
751 
752 /* angle callbacks */
753 static void gizmo_spin_prop_angle_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
754 {
756  wmOperator *op = ggd->data.op;
757  float *value = value_p;
758 
759  BLI_assert(gz_prop->type->array_length == 1);
760  UNUSED_VARS_NDEBUG(gz_prop);
761  value[0] = RNA_property_float_get(op->ptr, ggd->data.prop_angle);
762 }
763 
764 static void gizmo_spin_prop_angle_set(const wmGizmo *gz,
765  wmGizmoProperty *gz_prop,
766  const void *value_p)
767 {
769  wmOperator *op = ggd->data.op;
770  BLI_assert(gz_prop->type->array_length == 1);
771  UNUSED_VARS_NDEBUG(gz_prop);
772  const float *value = value_p;
773  RNA_property_float_set(op->ptr, ggd->data.prop_angle, value[0]);
774 
775  gizmo_spin_exec(ggd);
776 }
777 
779 {
780  if (ED_gizmo_poll_or_unlink_delayed_from_operator(C, gzgt, "MESH_OT_spin")) {
781  if (ED_gizmo_poll_or_unlink_delayed_from_tool_ex(C, gzgt, "MESH_GGT_spin")) {
782  return true;
783  }
784  }
785  return false;
786 }
787 
789 {
790  /* Start off dragging. */
791  GizmoGroupData_SpinRedo *ggd = gzgroup->customdata;
792  wmWindow *win = CTX_wm_window(C);
793  wmGizmo *gz = ggd->angle_z;
794  wmGizmoMap *gzmap = gzgroup->parent_gzmap;
795 
796  ggd->is_init = true;
797 
798  WM_gizmo_modal_set_from_setup(gzmap, (bContext *)C, gz, 0, win->eventstate);
799 }
800 
801 static void gizmo_mesh_spin_redo_setup(const bContext *C, wmGizmoGroup *gzgroup)
802 {
803  wmOperatorType *ot = WM_operatortype_find("MESH_OT_spin", true);
805 
806  if ((op == NULL) || (op->type != ot)) {
807  return;
808  }
809 
810  GizmoGroupData_SpinRedo *ggd = MEM_callocN(sizeof(*ggd), __func__);
811  gzgroup->customdata = ggd;
812 
813  const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
814  const wmGizmoType *gzt_move = WM_gizmotype_find("GIZMO_GT_move_3d", true);
815  const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
816 
817  /* Rotate View Axis (rotate_view) */
818  {
819  wmGizmo *gz = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
821  zero_v4(gz->color);
822  copy_v3_fl(gz->color_hi, 1.0f);
823  gz->color_hi[3] = 0.1f;
825  RNA_enum_set(gz->ptr,
826  "draw_options",
829  ggd->rotate_view = gz;
830  }
831 
832  /* Translate Center (translate_c) */
833  {
834  wmGizmo *gz = WM_gizmo_new_ptr(gzt_move, gzgroup, NULL);
836  gz->color[3] = 0.6f;
837  RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_MOVE_STYLE_RING_2D);
839  WM_gizmo_set_scale(gz, 0.15);
840  WM_gizmo_set_line_width(gz, 2.0f);
841  ggd->translate_c = gz;
842  }
843 
844  /* Spin Angle (angle_z) */
845  {
846  wmGizmo *gz = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
847  copy_v3_v3(gz->color, gz->color_hi);
848  gz->color[3] = 0.5f;
849  RNA_boolean_set(gz->ptr, "wrap_angle", false);
851  RNA_float_set(gz->ptr, "arc_inner_factor", 0.9f);
852  RNA_float_set(gz->ptr, "click_value", M_PI * 2);
854  WM_gizmo_set_scale(gz, 2.0f);
855  WM_gizmo_set_line_width(gz, 1.0f);
856  ggd->angle_z = gz;
857  }
858 
859  /* Translate X/Y Tangents (translate_xy) */
860  for (int i = 0; i < 2; i++) {
861  wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
863  RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_NORMAL);
864  RNA_enum_set(gz->ptr, "draw_options", 0);
865  WM_gizmo_set_scale(gz, 1.2f);
866  ggd->translate_xy[i] = gz;
867  }
868 
869  /* Rotate X/Y Tangents (rotate_xy) */
870  for (int i = 0; i < 2; i++) {
871  wmGizmo *gz = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
873  gz->color[3] = 0.6f;
875  WM_gizmo_set_line_width(gz, 3.0f);
876  /* show the axis instead of mouse cursor */
877  RNA_enum_set(gz->ptr,
878  "draw_options",
881  ggd->rotate_xy[i] = gz;
882  }
883 
884  {
885  ggd->data.context = (bContext *)C;
886  ggd->data.ot = ot;
887  ggd->data.op = op;
891  }
892 
893  /* The spin operator only knows about an axis,
894  * while the manipulator has X/Y orientation for the gizmos.
895  * Initialize the orientation from the spin gizmo if possible.
896  */
897  {
898  ARegion *region = CTX_wm_region(C);
899  wmGizmoMap *gzmap = region->gizmo_map;
900  wmGizmoGroup *gzgroup_init = WM_gizmomap_group_find(gzmap, "MESH_GGT_spin");
901  if (gzgroup_init) {
902  GizmoGroupData_SpinInit *ggd_init = gzgroup_init->customdata;
903  copy_m3_m3(ggd->data.orient_mat, ggd_init->data.orient_mat);
904  if (ggd_init->invoke.ortho_axis_active != -1) {
906  ggd_init->gizmos.xyz_view[ggd_init->invoke.ortho_axis_active]->matrix_basis[1]);
907  ggd_init->invoke.ortho_axis_active = -1;
908  }
909  }
910  else {
911  unit_m3(ggd->data.orient_mat);
912  }
913  }
914 
915 #ifdef USE_ANGLE_Z_ORIENT
916  {
917  wmWindow *win = CTX_wm_window(C);
918  View3D *v3d = CTX_wm_view3d(C);
919  ARegion *region = CTX_wm_region(C);
920  const wmEvent *event = win->eventstate;
921  float plane_co[3], plane_no[3];
922  RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_co, plane_co);
923  RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_no, plane_no);
924 
926 
927  /* Use cursor as fallback if it's not set by the 'ortho_axis_active'. */
929  float cursor_co[3];
930  const int mval[2] = {event->xy[0] - region->winrct.xmin, event->xy[1] - region->winrct.ymin};
931  float plane[4];
932  plane_from_point_normal_v3(plane, plane_co, plane_no);
933  if (UNLIKELY(!ED_view3d_win_to_3d_on_plane_int(region, plane, mval, false, cursor_co))) {
934  ED_view3d_win_to_3d_int(v3d, region, plane, mval, cursor_co);
935  }
936  sub_v3_v3v3(ggd->data.orient_axis_relative, cursor_co, plane_co);
937  }
938 
939  if (!is_zero_v3(ggd->data.orient_axis_relative)) {
941  float imat3[3][3];
942  invert_m3_m3(imat3, ggd->data.orient_mat);
943  mul_m3_v3(imat3, ggd->data.orient_axis_relative);
944  }
945  }
946 #endif
947 
949 
950  /* Setup property callbacks */
951  {
953  "offset",
954  &(const struct wmGizmoPropertyFnParams){
955  .value_get_fn = gizmo_spin_prop_translate_get,
956  .value_set_fn = gizmo_spin_prop_translate_set,
957  .range_get_fn = NULL,
958  .user_data = NULL,
959  });
960 
962  "offset",
963  &(const struct wmGizmoPropertyFnParams){
964  .value_get_fn = gizmo_spin_prop_axis_angle_get,
965  .value_set_fn = gizmo_spin_prop_axis_angle_set,
966  .range_get_fn = NULL,
967  .user_data = NULL,
968  });
969 
970  for (int i = 0; i < 2; i++) {
972  "offset",
973  &(const struct wmGizmoPropertyFnParams){
974  .value_get_fn = gizmo_spin_prop_axis_angle_get,
975  .value_set_fn = gizmo_spin_prop_axis_angle_set,
976  .range_get_fn = NULL,
977  .user_data = NULL,
978  });
980  "offset",
981  &(const struct wmGizmoPropertyFnParams){
982  .value_get_fn = gizmo_spin_prop_depth_get,
983  .value_set_fn = gizmo_spin_prop_depth_set,
984  .range_get_fn = NULL,
985  .user_data = NULL,
986  });
987  }
988 
990  "offset",
991  &(const struct wmGizmoPropertyFnParams){
992  .value_get_fn = gizmo_spin_prop_angle_get,
993  .value_set_fn = gizmo_spin_prop_angle_set,
994  .range_get_fn = NULL,
995  .user_data = NULL,
996  });
997  }
998 
999  wmWindow *win = CTX_wm_window(C);
1000  if (win && win->active) {
1001  bScreen *screen = WM_window_get_active_screen(win);
1002  if (screen->active_region) {
1003  ARegion *region = CTX_wm_region(C);
1004  if (screen->active_region == region) {
1005  /* Become modal as soon as it's started. */
1007  }
1008  }
1009  }
1010 }
1011 
1013 {
1014  GizmoGroupData_SpinRedo *ggd = gzgroup->customdata;
1015  if (ggd->data.op->next) {
1017  }
1018 
1019  /* Not essential, just avoids feedback loop where matrices
1020  * could shift because of float precision.
1021  * Updates in this case are also redundant. */
1022  bool is_modal = false;
1023  LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
1024  if (gz->state & WM_GIZMO_STATE_MODAL) {
1025  is_modal = true;
1026  break;
1027  }
1028  }
1029  if (!is_modal) {
1031  }
1032 
1035  {
1036  float view_up[3];
1037  project_plane_normalized_v3_v3v3(view_up, ggd->data.orient_mat[2], rv3d->viewinv[2]);
1038  if (normalize_v3(view_up) != 0.0f) {
1040  }
1041  else {
1043  }
1044  }
1045 }
1046 
1048 {
1049  gzgt->name = "Mesh Spin Redo";
1050  gzgt->idname = "MESH_GGT_spin_redo";
1051 
1053 
1056 
1060 }
1061 
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct Object * CTX_data_edit_object(const bContext *C)
Definition: context.c:1370
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:784
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:793
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
Definition: editmesh.c:58
struct TransformOrientationSlot * BKE_scene_orientation_slot_get(struct Scene *scene, int slot_index)
Definition: scene.cc:2431
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
#define M_PI_2
Definition: BLI_math_base.h:23
#define M_PI
Definition: BLI_math_base.h:20
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition: math_geom.c:209
void closest_to_plane_normalized_v3(float r_close[3], const float plane[4], const float pt[3])
Definition: math_geom.c:408
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:926
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:71
void unit_m3(float m[3][3])
Definition: math_matrix.c:40
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:87
bool equals_m3m3(const float mat1[3][3], const float mat2[3][3])
Definition: math_matrix.c:2525
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
bool invert_m3_m3(float R[3][3], const float A[3][3])
Definition: math_matrix.c:1180
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
Definition: math_matrix.c:897
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:388
float angle_compat_rad(float angle, float angle_compat)
void axis_angle_normalized_to_mat3(float R[3][3], const float axis[3], float angle)
void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float v2[3])
void axis_angle_to_mat3(float R[3][3], const float axis[3], float angle)
MINLINE float normalize_v3(float r[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 bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
Definition: math_vector.c:652
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:488
void ortho_v3_v3(float out[3], const float v[3])
Definition: math_vector.c:732
MINLINE void zero_v4(float r[4])
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
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
unsigned char uchar
Definition: BLI_sys_types.h:70
#define UNPACK2(a)
#define ARRAY_SIZE(arr)
#define UNUSED_VARS_NDEBUG(...)
#define UNUSED(x)
#define UNLIKELY(x)
#define ELEM(...)
@ SCE_ORIENT_ROTATE
@ RGN_TYPE_WINDOW
@ SPACE_VIEW3D
@ V3D_ORIENT_VIEW
@ ED_GIZMO_BUTTON_SHOW_BACKDROP
@ ED_GIZMO_MOVE_STYLE_RING_2D
@ ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_MIRROR
@ ED_GIZMO_DIAL_DRAW_FLAG_FILL
@ ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_START_Y
@ ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE
@ ED_GIZMO_DIAL_DRAW_FLAG_CLIP
@ ED_GIZMO_ARROW_STYLE_NORMAL
bool ED_gizmo_poll_or_unlink_delayed_from_tool(const struct bContext *C, struct wmGizmoGroupType *gzgt)
bool ED_gizmo_poll_or_unlink_delayed_from_operator(const struct bContext *C, struct wmGizmoGroupType *gzgt, const char *idname)
bool ED_gizmo_poll_or_unlink_delayed_from_tool_ex(const struct bContext *C, struct wmGizmoGroupType *gzgt, const char *gzgt_idname)
void ED_transform_calc_orientation_from_type(const struct bContext *C, float r_mat[3][3])
int ED_undo_operator_repeat(struct bContext *C, struct wmOperator *op)
Definition: ed_undo.c:662
void ED_view3d_win_to_3d_int(const struct View3D *v3d, const struct ARegion *region, const float depth_pt[3], const int mval[2], float r_out[3])
bool ED_view3d_win_to_3d_on_plane_int(const struct ARegion *region, const float plane[4], const int mval[2], bool do_clip, float r_out[3])
struct RegionView3D * ED_view3d_context_rv3d(struct bContext *C)
Definition: space_view3d.c:82
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
struct PointerRNA PointerRNA
#define C
Definition: RandGen.cpp:25
void UI_GetThemeColor3fv(int colorid, float col[3])
Definition: resources.c:1165
@ TH_AXIS_X
Definition: UI_resources.h:300
@ TH_GIZMO_PRIMARY
Definition: UI_resources.h:305
@ WM_GIZMO_HIDDEN
@ WM_GIZMO_OPERATOR_TOOL_INIT
@ WM_GIZMO_DRAW_VALUE
@ WM_GIZMO_DRAW_OFFSET_SCALE
@ WM_GIZMO_HIDDEN_SELECT
@ WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP
@ WM_GIZMOGROUPTYPE_3D
@ WM_GIZMO_STATE_HIGHLIGHT
@ WM_GIZMO_STATE_MODAL
#define WM_toolsystem_ref_properties_ensure_from_gizmo_group(tref, gzgroup, r_ptr)
@ 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:12
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_VERTS_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
Scene scene
static void gizmo_spin_prop_depth_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
static void gizmo_mesh_spin_redo_setup(const bContext *C, wmGizmoGroup *gzgroup)
static bool gizmo_mesh_spin_redo_poll(const bContext *C, wmGizmoGroupType *gzgt)
static void gizmo_mesh_spin_redo_update_orient_axis(GizmoGroupData_SpinRedo *ggd, const float plane_no[3])
static void gizmo_spin_prop_axis_angle_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
static void gizmo_spin_exec(GizmoGroupData_SpinRedo *ggd)
#define INIT_SCALE_BASE
static void gizmo_spin_prop_angle_set(const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value_p)
static void gizmo_mesh_spin_redo_draw_prepare(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
static void gizmo_spin_prop_depth_set(const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value_p)
struct GizmoGroupData_SpinRedo GizmoGroupData_SpinRedo
struct GizmoGroupData_SpinInit GizmoGroupData_SpinInit
static void gizmo_mesh_spin_init_invoke_prepare(const bContext *UNUSED(C), wmGizmoGroup *gzgroup, wmGizmo *gz, const wmEvent *UNUSED(event))
static void gizmo_spin_prop_axis_angle_set(const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value_p)
static void gizmo_spin_prop_angle_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
void MESH_GGT_spin(struct wmGizmoGroupType *gzgt)
static const uchar shape_plus[]
static void gizmo_mesh_spin_init_message_subscribe(const bContext *C, wmGizmoGroup *gzgroup, struct wmMsgBus *mbus)
#define ORTHO_AXIS_OFFSET
void MESH_GGT_spin_redo(struct wmGizmoGroupType *gzgt)
static void gizmo_mesh_spin_init_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
#define INIT_SCALE_BUTTON
static void gizmo_spin_prop_translate_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
static void gizmo_mesh_spin_init_refresh_axis_orientation(wmGizmoGroup *gzgroup, int axis_index, const float axis_vec[3], const float axis_tan[3])
static void gizmo_mesh_spin_redo_update_from_op(GizmoGroupData_SpinRedo *ggd)
static const float dial_angle_partial_margin
static void gizmo_mesh_spin_init_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
static const float dial_angle_partial
static void gizmo_spin_prop_translate_set(const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value)
static void gizmo_mesh_spin_redo_modal_from_setup(const bContext *C, wmGizmoGroup *gzgroup)
static void gizmo_mesh_spin_init_refresh(const bContext *C, wmGizmoGroup *gzgroup)
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2767
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
Definition: rna_access.c:2879
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:136
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:4874
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
PropertyRNA * RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
Definition: rna_access.c:806
void RNA_property_string_set_bytes(PointerRNA *ptr, PropertyRNA *prop, const char *value, int len)
Definition: rna_access.c:3268
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
Definition: rna_access.c:4968
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
Definition: rna_access.c:2978
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3402
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
Definition: rna_access.c:2790
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:5015
void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
Definition: rna_access.c:4992
void RNA_property_unset(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:5281
PropertyRNA * RNA_def_enum_flag(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3806
const EnumPropertyItem rna_enum_axis_flag_xyz_items[]
Definition: rna_modifier.c:622
struct wmGizmoMap * gizmo_map
struct BMesh * bm
Definition: BKE_editmesh.h:40
float co[3]
Definition: bmesh_class.h:87
struct GizmoGroupData_SpinInit::@455 invoke
struct GizmoGroupData_SpinInit::@452 gizmos
struct GizmoGroupData_SpinInit::@453 prev
struct GizmoGroupData_SpinInit::@454 data
struct GizmoGroupData_SpinRedo::@456 prev
struct GizmoGroupData_SpinRedo::@457 data
float obmat[4][4]
float viewinv[4][4]
View3DCursor cursor
struct ARegion * active_region
int ymin
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
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 wmGizmoGroupType * type
struct wmGizmoMap * parent_gzmap
const struct wmGizmoPropertyType * type
eWM_GizmoFlagState state
struct wmGizmoGroup * parent_gzgroup
float matrix_basis[4][4]
float matrix_offset[4][4]
float color_hi[4]
float color[4]
struct PointerRNA * ptr
eWM_GizmoFlag flag
struct StructRNA * srna
Definition: WM_types.h:969
struct wmOperator * next
struct wmOperatorType * type
struct PointerRNA * ptr
struct wmEvent * eventstate
PointerRNA * ptr
Definition: wm_files.c:3480
wmOperatorType * ot
Definition: wm_files.c:3479
PointerRNA * WM_gizmo_operator_set(wmGizmo *gz, int part_index, wmOperatorType *ot, IDProperty *properties)
Definition: wm_gizmo.c:203
void WM_gizmo_set_color_highlight(wmGizmo *gz, const float color_hi[4])
Definition: wm_gizmo.c:337
void WM_gizmo_set_line_width(wmGizmo *gz, const float line_width)
Definition: wm_gizmo.c:319
void WM_gizmo_modal_set_from_setup(struct wmGizmoMap *gzmap, struct bContext *C, struct wmGizmo *gz, int part_index, const wmEvent *event)
Definition: wm_gizmo.c:416
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:278
wmGizmo * WM_gizmo_new_ptr(const wmGizmoType *gzt, wmGizmoGroup *gzgroup, PointerRNA *properties)
Definition: wm_gizmo.c:81
void WM_gizmo_set_scale(wmGizmo *gz, const float scale)
Definition: wm_gizmo.c:314
void WM_gizmo_set_matrix_location(wmGizmo *gz, const float origin[3])
Definition: wm_gizmo.c:284
void WM_gizmo_set_flag(wmGizmo *gz, const int flag, const bool enable)
Definition: wm_gizmo.c:304
void WM_gizmo_set_matrix_rotation_from_z_axis(wmGizmo *gz, const float z_axis[3])
Definition: wm_gizmo.c:274
void WM_gizmo_set_color(wmGizmo *gz, const float color[4])
Definition: wm_gizmo.c:328
wmGizmoGroup * WM_gizmomap_group_find(struct wmGizmoMap *gzmap, const char *idname)
Definition: wm_gizmo_map.c:202
void WM_gizmo_do_msg_notify_tag_refresh(bContext *UNUSED(C), wmMsgSubscribeKey *UNUSED(msg_key), wmMsgSubscribeValue *msg_val)
void WM_gizmo_target_property_def_func(wmGizmo *gz, const char *idname, const wmGizmoPropertyFnParams *params)
const wmGizmoType * WM_gizmotype_find(const char *idname, bool quiet)
Definition: wm_gizmo_type.c:45
void WM_msg_subscribe_rna_params(struct wmMsgBus *mbus, const wmMsgParams_RNA *msg_key_params, const wmMsgSubscribeValue *msg_val_params, const char *id_repr)
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)
wmOperator * WM_operator_last_redo(const bContext *C)
struct bToolRef * WM_toolsystem_ref_from_context(struct bContext *C)
Definition: wm_toolsystem.c:57
bScreen * WM_window_get_active_screen(const wmWindow *win)
Definition: wm_window.c:2300