Blender  V2.93
editmesh_extrude_spin_gizmo.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 
21 #include "BLI_listbase.h"
22 #include "BLI_math.h"
23 
24 #include "BKE_context.h"
25 #include "BKE_scene.h"
26 
27 #include "RNA_access.h"
28 #include "RNA_define.h"
29 #include "RNA_enum_types.h"
30 
31 #include "WM_api.h"
32 #include "WM_message.h"
33 #include "WM_toolsystem.h"
34 #include "WM_types.h"
35 
36 #include "ED_gizmo_utils.h"
37 #include "ED_screen.h"
38 #include "ED_view3d.h"
39 
40 #include "UI_resources.h"
41 
42 #include "MEM_guardedalloc.h"
43 
44 #include "mesh_intern.h" /* own include */
45 
46 #include "ED_transform.h"
47 
48 #include "ED_gizmo_library.h"
49 #include "ED_undo.h"
50 
54 // Disable for now, issues w/ refresh and '+' icons overlap.
55 // #define USE_SELECT_CENTER
56 
57 #ifdef USE_SELECT_CENTER
58 # include "BKE_editmesh.h"
59 #endif
60 
61 static const float dial_angle_partial = M_PI / 2;
62 static const float dial_angle_partial_margin = 0.92f;
63 
64 #define ORTHO_AXIS_OFFSET 2
65 
66 /* -------------------------------------------------------------------- */
70 typedef struct GizmoGroupData_SpinInit {
71  struct {
74  } gizmos;
75 
76  /* Only for view orientation. */
77  struct {
78  float viewinv_m3[3][3];
79  } prev;
80 
81  /* We could store more vars here! */
82  struct {
85  float orient_mat[3][3];
86 #ifdef USE_SELECT_CENTER
87  float select_center[3];
88  float select_center_ortho_axis[3][3];
89  bool use_select_center;
90 #endif
91  } data;
92 
93  /* Store data for invoke. */
94  struct {
96  } invoke;
97 
99 
100 /* Use dials only as a visualization when hovering over the icons. */
101 #define USE_DIAL_HOVER
102 
103 #define INIT_SCALE_BASE 2.3f
104 #define INIT_SCALE_BUTTON 0.15f
105 
106 static const uchar shape_plus[] = {
107  0x73, 0x73, 0x73, 0x36, 0x8c, 0x36, 0x8c, 0x73, 0xc9, 0x73, 0xc9, 0x8c, 0x8c,
108  0x8c, 0x8c, 0xc9, 0x73, 0xc9, 0x73, 0x8c, 0x36, 0x8c, 0x36, 0x73, 0x36, 0x73,
109 };
110 
112 {
113  /* alpha values for normal/highlighted states */
114  const float alpha = 0.6f;
115  const float alpha_hi = 1.0f;
116  const float scale_base = INIT_SCALE_BASE;
117  const float scale_button = INIT_SCALE_BUTTON;
118 
119  GizmoGroupData_SpinInit *ggd = MEM_callocN(sizeof(*ggd), __func__);
120  gzgroup->customdata = ggd;
121  const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
122  const wmGizmoType *gzt_button = WM_gizmotype_find("GIZMO_GT_button_2d", true);
123 
124  for (int i = 0; i < 3; i++) {
125  for (int j = 0; j < 2; j++) {
126  wmGizmo *gz = WM_gizmo_new_ptr(gzt_button, gzgroup, NULL);
127  PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "shape");
129  gz->ptr, prop, (const char *)shape_plus, ARRAY_SIZE(shape_plus));
130 
131  RNA_enum_set(gz->ptr, "draw_options", ED_GIZMO_BUTTON_SHOW_BACKDROP);
132 
133  float color[4];
134  UI_GetThemeColor3fv(TH_AXIS_X + i, color);
135  color[3] = alpha;
136  WM_gizmo_set_color(gz, color);
137 
138  WM_gizmo_set_scale(gz, scale_button);
139  gz->color[3] = 0.6f;
140 
142 
143  ggd->gizmos.icon_button[i][j] = gz;
144  }
145  }
146 
147  for (int i = 0; i < ARRAY_SIZE(ggd->gizmos.xyz_view); i++) {
148  wmGizmo *gz = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
151  ggd->gizmos.xyz_view[i] = gz;
152  }
153 
154  for (int i = 0; i < 3; i++) {
155  wmGizmo *gz = ggd->gizmos.xyz_view[i];
156 #ifndef USE_DIAL_HOVER
157  RNA_enum_set(gz->ptr, "draw_options", ED_GIZMO_DIAL_DRAW_FLAG_CLIP);
158 #endif
159  WM_gizmo_set_line_width(gz, 2.0f);
160  float color[4];
161  UI_GetThemeColor3fv(TH_AXIS_X + i, color);
162  color[3] = alpha;
163  WM_gizmo_set_color(gz, color);
164  color[3] = alpha_hi;
165  WM_gizmo_set_color_highlight(gz, color);
167  RNA_float_set(gz->ptr,
168  "arc_partial_angle",
170  }
171 
172  {
173  wmGizmo *gz = ggd->gizmos.xyz_view[3];
174  WM_gizmo_set_line_width(gz, 2.0f);
175  float color[4];
176  copy_v3_fl(color, 1.0f);
177  color[3] = alpha;
178  WM_gizmo_set_color(gz, color);
179  color[3] = alpha_hi;
180  WM_gizmo_set_color_highlight(gz, color);
181  WM_gizmo_set_scale(gz, scale_base);
182  }
183 
184 #ifdef USE_DIAL_HOVER
185  for (int i = 0; i < 4; i++) {
186  wmGizmo *gz = ggd->gizmos.xyz_view[i];
188  }
189 #endif
190 
191  ggd->data.ot_spin = WM_operatortype_find("MESH_OT_spin", true);
192  ggd->data.gzgt_axis_prop = RNA_struct_type_find_property(gzgroup->type->srna, "axis");
193 }
194 
195 static void gizmo_mesh_spin_init_refresh(const bContext *C, wmGizmoGroup *gzgroup);
196 
198  int axis_index,
199  const float axis_vec[3],
200  const float axis_tan[3])
201 {
202  GizmoGroupData_SpinInit *ggd = gzgroup->customdata;
203  wmGizmo *gz = ggd->gizmos.xyz_view[axis_index];
204  if (axis_tan != NULL) {
205  WM_gizmo_set_matrix_rotation_from_yz_axis(gz, axis_tan, axis_vec);
206  }
207  else {
209  }
210 
211  /* Only for display, use icons to access. */
212 #ifndef USE_DIAL_HOVER
213  {
215  RNA_float_set_array(ptr, "axis", axis_vec);
216  }
217 #endif
218  if (axis_index < 3) {
219  for (int j = 0; j < 2; j++) {
220  gz = ggd->gizmos.icon_button[axis_index][j];
222  float axis_vec_flip[3];
223  if (0 == j) {
224  negate_v3_v3(axis_vec_flip, axis_vec);
225  }
226  else {
227  copy_v3_v3(axis_vec_flip, axis_vec);
228  }
229  RNA_float_set_array(ptr, "axis", axis_vec_flip);
230  }
231  }
232 }
233 
235 {
236  GizmoGroupData_SpinInit *ggd = gzgroup->customdata;
238  float viewinv_m3[3][3];
239  copy_m3_m4(viewinv_m3, rv3d->viewinv);
240 
241  {
245  switch (orient_slot->type) {
246  case V3D_ORIENT_VIEW: {
247  if (!equals_m3m3(viewinv_m3, ggd->prev.viewinv_m3)) {
248  /* Take care calling refresh from draw_prepare,
249  * this should be OK because it's only adjusting the cage orientation. */
251  }
252  break;
253  }
254  }
255  }
256 
257  /* Refresh handled above when using view orientation. */
258  if (!equals_m3m3(viewinv_m3, ggd->prev.viewinv_m3)) {
260  copy_m3_m4(ggd->prev.viewinv_m3, rv3d->viewinv);
261  }
262 
263  /* Hack! highlight XYZ dials based on buttons */
264 #ifdef USE_DIAL_HOVER
265  {
266  PointerRNA ptr;
269  const int axis_flag = RNA_property_enum_get(&ptr, ggd->data.gzgt_axis_prop);
270  for (int i = 0; i < 4; i++) {
271  bool hide = (axis_flag & (1 << i)) == 0;
272  wmGizmo *gz = ggd->gizmos.xyz_view[i];
274  if (!hide) {
275  RNA_float_set(gz->ptr,
276  "arc_partial_angle",
278  }
279  }
280 
281  for (int i = 0; i < 3; i++) {
282  for (int j = 0; j < 2; j++) {
283  wmGizmo *gz = ggd->gizmos.icon_button[i][j];
284  if (gz->state & WM_GIZMO_STATE_HIGHLIGHT) {
286  RNA_float_set(ggd->gizmos.xyz_view[i]->ptr, "arc_partial_angle", 0.0f);
287  i = 3;
288  break;
289  }
290  }
291  }
292  }
293 #endif
294 }
295 
297  wmGizmoGroup *gzgroup,
298  wmGizmo *gz,
299  const wmEvent *UNUSED(event))
300 {
301  /* Set the initial ortho axis. */
302  GizmoGroupData_SpinInit *ggd = gzgroup->customdata;
303  ggd->invoke.ortho_axis_active = -1;
304  for (int i = 0; i < 3; i++) {
305  if (ELEM(gz, UNPACK2(ggd->gizmos.icon_button[i]))) {
306  ggd->invoke.ortho_axis_active = i;
307  break;
308  }
309  }
310 }
311 
313 {
314  GizmoGroupData_SpinInit *ggd = gzgroup->customdata;
316  const float *gizmo_center = NULL;
317  {
319  const View3DCursor *cursor = &scene->cursor;
320  gizmo_center = cursor->location;
321  }
322 
323  for (int i = 0; i < ARRAY_SIZE(ggd->gizmos.xyz_view); i++) {
324  wmGizmo *gz = ggd->gizmos.xyz_view[i];
325  WM_gizmo_set_matrix_location(gz, gizmo_center);
326  }
327 
328  for (int i = 0; i < ARRAY_SIZE(ggd->gizmos.icon_button); i++) {
329  for (int j = 0; j < 2; j++) {
330  wmGizmo *gz = ggd->gizmos.icon_button[i][j];
331  WM_gizmo_set_matrix_location(gz, gizmo_center);
332  }
333  }
334 
336  for (int i = 0; i < 3; i++) {
337  const int axis_ortho = (i + ORTHO_AXIS_OFFSET) % 3;
338  const float *axis_ortho_vec = ggd->data.orient_mat[axis_ortho];
339 #ifdef USE_SELECT_CENTER
340  if (ggd->data.use_select_center) {
341  float delta[3];
342  sub_v3_v3v3(delta, ggd->data.select_center, gizmo_center);
344  ggd->data.select_center_ortho_axis[i], delta, ggd->data.orient_mat[i]);
345  if (normalize_v3(ggd->data.select_center_ortho_axis[i]) != 0.0f) {
346  axis_ortho_vec = ggd->data.select_center_ortho_axis[i];
347  }
348  }
349 #endif
351  gzgroup, i, ggd->data.orient_mat[i], axis_ortho_vec);
352  }
353 
354  {
356  }
357 
358 #ifdef USE_SELECT_CENTER
359  {
360  Object *obedit = CTX_data_edit_object(C);
361  BMEditMesh *em = BKE_editmesh_from_object(obedit);
362  float select_center[3] = {0};
363  int totsel = 0;
364 
365  BMesh *bm = em->bm;
366  BMVert *eve;
367  BMIter iter;
368 
369  BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
370  if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
371  if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
372  totsel++;
373  add_v3_v3(select_center, eve->co);
374  }
375  }
376  }
377  if (totsel) {
378  mul_v3_fl(select_center, 1.0f / totsel);
379  mul_m4_v3(obedit->obmat, select_center);
380  copy_v3_v3(ggd->data.select_center, select_center);
381  ggd->data.use_select_center = true;
382  }
383  else {
384  ggd->data.use_select_center = false;
385  }
386  }
387 #endif
388 
389  for (int i = 0; i < ARRAY_SIZE(ggd->gizmos.icon_button); i++) {
390  const int axis_ortho = (i + ORTHO_AXIS_OFFSET) % 3;
391  const float *axis_ortho_vec = ggd->data.orient_mat[axis_ortho];
392  float offset = INIT_SCALE_BASE / INIT_SCALE_BUTTON;
393  float offset_vec[3];
394 
395 #ifdef USE_SELECT_CENTER
396  if (ggd->data.use_select_center && !is_zero_v3(ggd->data.select_center_ortho_axis[i])) {
397  axis_ortho_vec = ggd->data.select_center_ortho_axis[i];
398  }
399 #endif
400 
401  mul_v3_v3fl(offset_vec, axis_ortho_vec, offset);
402  for (int j = 0; j < 2; j++) {
403  wmGizmo *gz = ggd->gizmos.icon_button[i][j];
404  float mat3[3][3];
405  axis_angle_to_mat3(mat3, ggd->data.orient_mat[i], dial_angle_partial * (j ? -0.5f : 0.5f));
406  mul_v3_m3v3(gz->matrix_offset[3], mat3, offset_vec);
407  }
408  }
409 
410  {
411  PointerRNA ptr;
414  const int axis_flag = RNA_property_enum_get(&ptr, ggd->data.gzgt_axis_prop);
415  for (int i = 0; i < ARRAY_SIZE(ggd->gizmos.icon_button); i++) {
416  for (int j = 0; j < 2; j++) {
417  wmGizmo *gz = ggd->gizmos.icon_button[i][j];
418  WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, (axis_flag & (1 << i)) == 0);
419  }
420  }
421  }
422 
423  /* Needed to test view orientation changes. */
424  copy_m3_m4(ggd->prev.viewinv_m3, rv3d->viewinv);
425 }
426 
428  wmGizmoGroup *gzgroup,
429  struct wmMsgBus *mbus)
430 {
431  GizmoGroupData_SpinInit *ggd = gzgroup->customdata;
433  ARegion *region = CTX_wm_region(C);
434 
435  /* Subscribe to view properties */
436  wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = {
437  .owner = region,
438  .user_data = gzgroup->parent_gzmap,
440  };
441 
442  PointerRNA cursor_ptr;
444  /* All cursor properties. */
445  WM_msg_subscribe_rna(mbus, &cursor_ptr, NULL, &msg_sub_value_gz_tag_refresh, __func__);
446 
448  &(const wmMsgParams_RNA){
449  .ptr =
450  (PointerRNA){
451  .type = gzgroup->type->srna,
452  },
453  .prop = ggd->data.gzgt_axis_prop,
454  },
455  &msg_sub_value_gz_tag_refresh,
456  __func__);
457 }
458 
459 void MESH_GGT_spin(struct wmGizmoGroupType *gzgt)
460 {
461  gzgt->name = "Mesh Spin Init";
462  gzgt->idname = "MESH_GGT_spin";
463 
464  gzgt->flag = WM_GIZMOGROUPTYPE_3D;
465 
468 
471  /* This works well with right click selection but overrides left-mouse selection
472  * when clicking which is needed to create a full 360 degree revolution, see: T86030. */
473  // gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
478 
479  RNA_def_enum_flag(gzgt->srna, "axis", rna_enum_axis_flag_xyz_items, (1 << 2), "Axis", "");
480 }
481 
482 #undef INIT_SCALE_BASE
483 #undef INIT_SCALE_BUTTON
484 
487 /* -------------------------------------------------------------------- */
496 #define USE_ANGLE_Z_ORIENT
497 
498 typedef struct GizmoGroupData_SpinRedo {
499  /* Translate XYZ. */
501  /* Spin angle */
502  struct wmGizmo *angle_z;
503 
504  /* Translate XY constrained ('orient_mat'). */
505  struct wmGizmo *translate_xy[2];
506  /* Rotate XY constrained ('orient_mat'). */
507  struct wmGizmo *rotate_xy[2];
508 
509  /* Rotate on view axis. */
511 
512  struct {
513  float plane_co[3];
514  float plane_no[3];
515  } prev;
516 
517  bool is_init;
518 
519  /* We could store more vars here! */
520  struct {
527 
528 #ifdef USE_ANGLE_Z_ORIENT
529  /* Apply 'orient_mat' for the final value. */
531 #endif
532  /* The orientation, since the operator doesn't store this, we store our own.
533  * this is kept in sync with the operator,
534  * rotating the orientation when it doesn't match.
535  *
536  * Initialize to a sensible value where possible.
537  */
538  float orient_mat[3][3];
539 
540  } data;
542 
549 {
550  if (ggd->is_init) {
551  wmGizmo *gz = ggd->angle_z;
552  PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "click_value");
553  RNA_property_unset(gz->ptr, prop);
554  ggd->is_init = false;
555  }
556 
557  wmOperator *op = ggd->data.op;
558  if (op == WM_operator_last_redo((bContext *)ggd->data.context)) {
560  }
561 }
562 
564  const float plane_no[3])
565 {
566  float mat[3][3];
567  rotation_between_vecs_to_mat3(mat, ggd->data.orient_mat[2], plane_no);
568  mul_m3_m3m3(ggd->data.orient_mat, mat, ggd->data.orient_mat);
569  /* Not needed, just set for numeric stability. */
570  copy_v3_v3(ggd->data.orient_mat[2], plane_no);
571 }
572 
574 {
575  wmOperator *op = ggd->data.op;
576  float plane_co[3], plane_no[3];
577  RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_co, plane_co);
578  RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_no, plane_no);
579  if (UNLIKELY(normalize_v3(plane_no) == 0.0f)) {
580  return;
581  }
582  const bool is_plane_co_eq = equals_v3v3(plane_co, ggd->prev.plane_co);
583  const bool is_plane_no_eq = equals_v3v3(plane_no, ggd->prev.plane_no);
584  if (is_plane_co_eq && is_plane_no_eq) {
585  return;
586  }
587  copy_v3_v3(ggd->prev.plane_co, plane_co);
588  copy_v3_v3(ggd->prev.plane_no, plane_no);
589 
590  if (is_plane_no_eq == false) {
592  }
593 
594  for (int i = 0; i < 2; i++) {
595  WM_gizmo_set_matrix_location(ggd->rotate_xy[i], plane_co);
596  WM_gizmo_set_matrix_location(ggd->translate_xy[i], plane_co);
597  }
598  WM_gizmo_set_matrix_location(ggd->angle_z, plane_co);
600  /* translate_c location comes from the property. */
601 
602  for (int i = 0; i < 2; i++) {
605  }
606 #ifdef USE_ANGLE_Z_ORIENT
607  {
608  float plane_tan[3];
609  float orient_axis[3];
610  mul_v3_m3v3(orient_axis, ggd->data.orient_mat, ggd->data.orient_axis_relative);
611  project_plane_normalized_v3_v3v3(plane_tan, orient_axis, plane_no);
612  if (normalize_v3(plane_tan) != 0.0f) {
613  WM_gizmo_set_matrix_rotation_from_yz_axis(ggd->angle_z, plane_tan, plane_no);
614  }
615  else {
617  }
618  }
619 #else
621 #endif
622 }
623 
624 /* depth callbacks */
625 static void gizmo_spin_prop_depth_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
626 {
628  wmOperator *op = ggd->data.op;
629  float *value = value_p;
630 
631  BLI_assert(gz_prop->type->array_length == 1);
632  UNUSED_VARS_NDEBUG(gz_prop);
633 
634  const float *plane_no = gz->matrix_basis[2];
635  float plane_co[3];
636  RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_co, plane_co);
637 
638  value[0] = dot_v3v3(plane_no, plane_co) - dot_v3v3(plane_no, gz->matrix_basis[3]);
639 }
640 
641 static void gizmo_spin_prop_depth_set(const wmGizmo *gz,
642  wmGizmoProperty *gz_prop,
643  const void *value_p)
644 {
646  wmOperator *op = ggd->data.op;
647  const float *value = value_p;
648 
649  BLI_assert(gz_prop->type->array_length == 1);
650  UNUSED_VARS_NDEBUG(gz_prop);
651 
652  float plane_co[3], plane[4];
653  RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_co, plane_co);
654  normalize_v3_v3(plane, gz->matrix_basis[2]);
655 
656  plane[3] = -value[0] - dot_v3v3(plane, gz->matrix_basis[3]);
657 
658  /* Keep our location, may be offset simply to be inside the viewport. */
659  closest_to_plane_normalized_v3(plane_co, plane, plane_co);
660 
661  RNA_property_float_set_array(op->ptr, ggd->data.prop_axis_co, plane_co);
662 
663  gizmo_spin_exec(ggd);
664 }
665 
666 /* translate callbacks */
668  wmGizmoProperty *gz_prop,
669  void *value_p)
670 {
672  wmOperator *op = ggd->data.op;
673  float *value = value_p;
674 
675  BLI_assert(gz_prop->type->array_length == 3);
676  UNUSED_VARS_NDEBUG(gz_prop);
677 
679 }
680 
682  wmGizmoProperty *gz_prop,
683  const void *value)
684 {
686  wmOperator *op = ggd->data.op;
687 
688  BLI_assert(gz_prop->type->array_length == 3);
689  UNUSED_VARS_NDEBUG(gz_prop);
690 
692 
693  gizmo_spin_exec(ggd);
694 }
695 
696 /* angle callbacks */
698  wmGizmoProperty *gz_prop,
699  void *value_p)
700 {
702  wmOperator *op = ggd->data.op;
703  float *value = value_p;
704 
705  BLI_assert(gz_prop->type->array_length == 1);
706  UNUSED_VARS_NDEBUG(gz_prop);
707 
708  float plane_no[4];
709  RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_no, plane_no);
710  normalize_v3(plane_no);
711 
712  const float *rotate_axis = gz->matrix_basis[2];
713  float rotate_up[3];
714  ortho_v3_v3(rotate_up, rotate_axis);
715 
716  float plane_no_proj[3];
717  project_plane_normalized_v3_v3v3(plane_no_proj, plane_no, rotate_axis);
718 
719  if (!is_zero_v3(plane_no_proj)) {
720  const float angle = -angle_signed_on_axis_v3v3_v3(plane_no_proj, rotate_up, rotate_axis);
721  value[0] = angle;
722  }
723  else {
724  value[0] = 0.0f;
725  }
726 }
727 
729  wmGizmoProperty *gz_prop,
730  const void *value_p)
731 {
733  wmOperator *op = ggd->data.op;
734  const float *value = value_p;
735 
736  BLI_assert(gz_prop->type->array_length == 1);
737  UNUSED_VARS_NDEBUG(gz_prop);
738 
739  float plane_no[4];
740  RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_no, plane_no);
741  normalize_v3(plane_no);
742 
743  const float *rotate_axis = gz->matrix_basis[2];
744  float rotate_up[3];
745  ortho_v3_v3(rotate_up, rotate_axis);
746 
747  float plane_no_proj[3];
748  project_plane_normalized_v3_v3v3(plane_no_proj, plane_no, rotate_axis);
749 
750  if (!is_zero_v3(plane_no_proj)) {
751  const float angle = -angle_signed_on_axis_v3v3_v3(plane_no_proj, rotate_up, rotate_axis);
752  const float angle_delta = angle - angle_compat_rad(value[0], angle);
753  if (angle_delta != 0.0f) {
754  float mat[3][3];
755  axis_angle_normalized_to_mat3(mat, rotate_axis, angle_delta);
756  mul_m3_v3(mat, plane_no);
757 
758  /* re-normalize - seems acceptable */
759  RNA_property_float_set_array(op->ptr, ggd->data.prop_axis_no, plane_no);
760 
761  gizmo_spin_exec(ggd);
762  }
763  }
764 }
765 
766 /* angle callbacks */
767 static void gizmo_spin_prop_angle_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
768 {
770  wmOperator *op = ggd->data.op;
771  float *value = value_p;
772 
773  BLI_assert(gz_prop->type->array_length == 1);
774  UNUSED_VARS_NDEBUG(gz_prop);
775  value[0] = RNA_property_float_get(op->ptr, ggd->data.prop_angle);
776 }
777 
778 static void gizmo_spin_prop_angle_set(const wmGizmo *gz,
779  wmGizmoProperty *gz_prop,
780  const void *value_p)
781 {
783  wmOperator *op = ggd->data.op;
784  BLI_assert(gz_prop->type->array_length == 1);
785  UNUSED_VARS_NDEBUG(gz_prop);
786  const float *value = value_p;
787  RNA_property_float_set(op->ptr, ggd->data.prop_angle, value[0]);
788 
789  gizmo_spin_exec(ggd);
790 }
791 
793 {
794  if (ED_gizmo_poll_or_unlink_delayed_from_operator(C, gzgt, "MESH_OT_spin")) {
795  if (ED_gizmo_poll_or_unlink_delayed_from_tool_ex(C, gzgt, "MESH_GGT_spin")) {
796  return true;
797  }
798  }
799  return false;
800 }
801 
803 {
804  /* Start off dragging. */
805  GizmoGroupData_SpinRedo *ggd = gzgroup->customdata;
806  wmWindow *win = CTX_wm_window(C);
807  wmGizmo *gz = ggd->angle_z;
808  wmGizmoMap *gzmap = gzgroup->parent_gzmap;
809 
810  ggd->is_init = true;
811 
812  WM_gizmo_modal_set_from_setup(gzmap, (bContext *)C, gz, 0, win->eventstate);
813 }
814 
815 static void gizmo_mesh_spin_redo_setup(const bContext *C, wmGizmoGroup *gzgroup)
816 {
817  wmOperatorType *ot = WM_operatortype_find("MESH_OT_spin", true);
819 
820  if ((op == NULL) || (op->type != ot)) {
821  return;
822  }
823 
824  GizmoGroupData_SpinRedo *ggd = MEM_callocN(sizeof(*ggd), __func__);
825  gzgroup->customdata = ggd;
826 
827  const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
828  const wmGizmoType *gzt_move = WM_gizmotype_find("GIZMO_GT_move_3d", true);
829  const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
830 
831  /* Rotate View Axis (rotate_view) */
832  {
833  wmGizmo *gz = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
835  zero_v4(gz->color);
836  copy_v3_fl(gz->color_hi, 1.0f);
837  gz->color_hi[3] = 0.1f;
839  RNA_enum_set(gz->ptr,
840  "draw_options",
843  ggd->rotate_view = gz;
844  }
845 
846  /* Translate Center (translate_c) */
847  {
848  wmGizmo *gz = WM_gizmo_new_ptr(gzt_move, gzgroup, NULL);
850  gz->color[3] = 0.6f;
851  RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_MOVE_STYLE_RING_2D);
853  WM_gizmo_set_scale(gz, 0.15);
854  WM_gizmo_set_line_width(gz, 2.0f);
855  ggd->translate_c = gz;
856  }
857 
858  /* Spin Angle (angle_z) */
859  {
860  wmGizmo *gz = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
861  copy_v3_v3(gz->color, gz->color_hi);
862  gz->color[3] = 0.5f;
863  RNA_boolean_set(gz->ptr, "wrap_angle", false);
865  RNA_float_set(gz->ptr, "arc_inner_factor", 0.9f);
866  RNA_float_set(gz->ptr, "click_value", M_PI * 2);
868  WM_gizmo_set_scale(gz, 2.0f);
869  WM_gizmo_set_line_width(gz, 1.0f);
870  ggd->angle_z = gz;
871  }
872 
873  /* Translate X/Y Tangents (translate_xy) */
874  for (int i = 0; i < 2; i++) {
875  wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
877  RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_NORMAL);
878  RNA_enum_set(gz->ptr, "draw_options", 0);
879  WM_gizmo_set_scale(gz, 1.2f);
880  ggd->translate_xy[i] = gz;
881  }
882 
883  /* Rotate X/Y Tangents (rotate_xy) */
884  for (int i = 0; i < 2; i++) {
885  wmGizmo *gz = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
887  gz->color[3] = 0.6f;
889  WM_gizmo_set_line_width(gz, 3.0f);
890  /* show the axis instead of mouse cursor */
891  RNA_enum_set(gz->ptr,
892  "draw_options",
895  ggd->rotate_xy[i] = gz;
896  }
897 
898  {
899  ggd->data.context = (bContext *)C;
900  ggd->data.ot = ot;
901  ggd->data.op = op;
905  }
906 
907  /* The spin operator only knows about an axis,
908  * while the manipulator has X/Y orientation for the gizmos.
909  * Initialize the orientation from the spin gizmo if possible.
910  */
911  {
912  ARegion *region = CTX_wm_region(C);
913  wmGizmoMap *gzmap = region->gizmo_map;
914  wmGizmoGroup *gzgroup_init = WM_gizmomap_group_find(gzmap, "MESH_GGT_spin");
915  if (gzgroup_init) {
916  GizmoGroupData_SpinInit *ggd_init = gzgroup_init->customdata;
917  copy_m3_m3(ggd->data.orient_mat, ggd_init->data.orient_mat);
918  if (ggd_init->invoke.ortho_axis_active != -1) {
920  ggd_init->gizmos.xyz_view[ggd_init->invoke.ortho_axis_active]->matrix_basis[1]);
921  ggd_init->invoke.ortho_axis_active = -1;
922  }
923  }
924  else {
925  unit_m3(ggd->data.orient_mat);
926  }
927  }
928 
929 #ifdef USE_ANGLE_Z_ORIENT
930  {
931  wmWindow *win = CTX_wm_window(C);
932  View3D *v3d = CTX_wm_view3d(C);
933  ARegion *region = CTX_wm_region(C);
934  const wmEvent *event = win->eventstate;
935  float plane_co[3], plane_no[3];
936  RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_co, plane_co);
937  RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_no, plane_no);
938 
940 
941  /* Use cursor as fallback if it's not set by the 'ortho_axis_active'. */
943  float cursor_co[3];
944  const int mval[2] = {event->x - region->winrct.xmin, event->y - region->winrct.ymin};
945  float plane[4];
946  plane_from_point_normal_v3(plane, plane_co, plane_no);
947  if (UNLIKELY(!ED_view3d_win_to_3d_on_plane_int(region, plane, mval, false, cursor_co))) {
948  ED_view3d_win_to_3d_int(v3d, region, plane, mval, cursor_co);
949  }
950  sub_v3_v3v3(ggd->data.orient_axis_relative, cursor_co, plane_co);
951  }
952 
953  if (!is_zero_v3(ggd->data.orient_axis_relative)) {
955  float imat3[3][3];
956  invert_m3_m3(imat3, ggd->data.orient_mat);
957  mul_m3_v3(imat3, ggd->data.orient_axis_relative);
958  }
959  }
960 #endif
961 
963 
964  /* Setup property callbacks */
965  {
967  "offset",
968  &(const struct wmGizmoPropertyFnParams){
969  .value_get_fn = gizmo_spin_prop_translate_get,
970  .value_set_fn = gizmo_spin_prop_translate_set,
971  .range_get_fn = NULL,
972  .user_data = NULL,
973  });
974 
976  "offset",
977  &(const struct wmGizmoPropertyFnParams){
978  .value_get_fn = gizmo_spin_prop_axis_angle_get,
979  .value_set_fn = gizmo_spin_prop_axis_angle_set,
980  .range_get_fn = NULL,
981  .user_data = NULL,
982  });
983 
984  for (int i = 0; i < 2; i++) {
986  "offset",
987  &(const struct wmGizmoPropertyFnParams){
988  .value_get_fn = gizmo_spin_prop_axis_angle_get,
989  .value_set_fn = gizmo_spin_prop_axis_angle_set,
990  .range_get_fn = NULL,
991  .user_data = NULL,
992  });
994  "offset",
995  &(const struct wmGizmoPropertyFnParams){
996  .value_get_fn = gizmo_spin_prop_depth_get,
997  .value_set_fn = gizmo_spin_prop_depth_set,
998  .range_get_fn = NULL,
999  .user_data = NULL,
1000  });
1001  }
1002 
1004  "offset",
1005  &(const struct wmGizmoPropertyFnParams){
1006  .value_get_fn = gizmo_spin_prop_angle_get,
1007  .value_set_fn = gizmo_spin_prop_angle_set,
1008  .range_get_fn = NULL,
1009  .user_data = NULL,
1010  });
1011  }
1012 
1013  wmWindow *win = CTX_wm_window(C);
1014  if (win && win->active) {
1015  bScreen *screen = WM_window_get_active_screen(win);
1016  if (screen->active_region) {
1017  ARegion *region = CTX_wm_region(C);
1018  if (screen->active_region == region) {
1019  /* Become modal as soon as it's started. */
1021  }
1022  }
1023  }
1024 }
1025 
1027 {
1028  GizmoGroupData_SpinRedo *ggd = gzgroup->customdata;
1029  if (ggd->data.op->next) {
1031  }
1032 
1033  /* Not essential, just avoids feedback loop where matrices
1034  * could shift because of float precision.
1035  * Updates in this case are also redundant. */
1036  bool is_modal = false;
1037  LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
1038  if (gz->state & WM_GIZMO_STATE_MODAL) {
1039  is_modal = true;
1040  break;
1041  }
1042  }
1043  if (!is_modal) {
1045  }
1046 
1049  {
1050  float view_up[3];
1051  project_plane_normalized_v3_v3v3(view_up, ggd->data.orient_mat[2], rv3d->viewinv[2]);
1052  if (normalize_v3(view_up) != 0.0f) {
1054  }
1055  else {
1057  }
1058  }
1059 }
1060 
1062 {
1063  gzgt->name = "Mesh Spin Redo";
1064  gzgt->idname = "MESH_GGT_spin_redo";
1065 
1066  gzgt->flag = WM_GIZMOGROUPTYPE_3D;
1067 
1070 
1074 }
1075 
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 View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:760
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
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
Definition: editmesh.c:85
struct TransformOrientationSlot * BKE_scene_orientation_slot_get(struct Scene *scene, int slot_index)
Definition: scene.c:2486
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
#define M_PI
Definition: BLI_math_base.h:38
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition: math_geom.c:243
void closest_to_plane_normalized_v3(float r_close[3], const float plane[4], const float pt[3])
Definition: math_geom.c:412
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:930
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
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
bool invert_m3_m3(float R[3][3], const float A[3][3])
Definition: math_matrix.c:1161
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
Definition: math_matrix.c:901
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:391
float angle_compat_rad(float angle, float angle_compat)
void axis_angle_normalized_to_mat3(float R[3][3], const float axis[3], const 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], const 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:757
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:551
void ortho_v3_v3(float out[3], const float v[3])
Definition: math_vector.c:875
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:86
#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_MOVE_STYLE_RING_2D
@ ED_GIZMO_ARROW_STYLE_NORMAL
@ 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_BUTTON_SHOW_BACKDROP
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:678
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], const bool do_clip, float r_out[3])
struct RegionView3D * ED_view3d_context_rv3d(struct bContext *C)
Definition: space_view3d.c:89
Read Guarded memory(de)allocation.
StructRNA RNA_View3DCursor
struct PointerRNA PointerRNA
#define C
Definition: RandGen.cpp:39
void UI_GetThemeColor3fv(int colorid, float col[3])
Definition: resources.c:1191
@ TH_AXIS_X
Definition: UI_resources.h:316
@ TH_GIZMO_PRIMARY
Definition: UI_resources.h:321
@ WM_GIZMO_HIDDEN
@ WM_GIZMO_OPERATOR_TOOL_INIT
@ WM_GIZMO_DRAW_VALUE
@ WM_GIZMO_DRAW_OFFSET_SCALE
@ WM_GIZMO_HIDDEN_SELECT
@ 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:26
#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 CCL_NAMESPACE_BEGIN const double alpha
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)
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2941
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
Definition: rna_access.c:3033
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:6272
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
PropertyRNA * RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
Definition: rna_access.c:953
void RNA_property_string_set_bytes(PointerRNA *ptr, PropertyRNA *prop, const char *value, int len)
Definition: rna_access.c:3430
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
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3543
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
Definition: rna_access.c:2964
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
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:3795
const EnumPropertyItem rna_enum_axis_flag_xyz_items[]
Definition: rna_modifier.c:591
struct wmGizmoMap * gizmo_map
struct BMesh * bm
Definition: BKE_editmesh.h:52
float co[3]
Definition: bmesh_class.h:99
struct GizmoGroupData_SpinInit::@434 data
struct GizmoGroupData_SpinInit::@433 prev
struct GizmoGroupData_SpinInit::@435 invoke
struct GizmoGroupData_SpinInit::@432 gizmos
struct GizmoGroupData_SpinRedo::@437 data
struct GizmoGroupData_SpinRedo::@436 prev
float obmat[4][4]
float viewinv[4][4]
View3DCursor cursor
struct ARegion * active_region
int ymin
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
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:802
struct wmOperator * next
struct wmOperatorType * type
struct PointerRNA * ptr
struct wmEvent * eventstate
PointerRNA * ptr
Definition: wm_files.c:3157
wmOperatorType * ot
Definition: wm_files.c:3156
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_modal_set_from_setup(struct wmGizmoMap *gzmap, struct bContext *C, struct wmGizmo *gz, int part_index, const wmEvent *event)
Definition: wm_gizmo.c:463
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
void WM_gizmo_set_color(wmGizmo *gz, const float color[4])
Definition: wm_gizmo.c:363
wmGizmoGroup * WM_gizmomap_group_find(struct wmGizmoMap *gzmap, const char *idname)
Definition: wm_gizmo_map.c:219
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:58
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:71
bScreen * WM_window_get_active_screen(const wmWindow *win)
Definition: wm_window.c:2372