Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2018-09-21 03:50:55 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-09-21 06:34:29 +0300
commit3266ebf9e5df19460ce4960e6c7b7f3618611229 (patch)
treebb830a3ff40fab18199d7c003f9243d066c2fdfe /source/blender/editors/mesh
parent7deb38eec6988dce64a7179ad1b72daa35cb060d (diff)
Gizmo: enable spin tool redo gizmos again
- Add x,y rotate and translate controls. - Remove x-depth adjustment.
Diffstat (limited to 'source/blender/editors/mesh')
-rw-r--r--source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c265
1 files changed, 165 insertions, 100 deletions
diff --git a/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c b/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c
index e8f29d9a9b2..c179f5c18ae 100644
--- a/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c
+++ b/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c
@@ -65,6 +65,7 @@ typedef struct GizmoGroupData_SpinInit {
/* We could store more vars here! */
struct {
wmOperatorType *ot_spin;
+ float orient_mat[3][3];
} data;
} GizmoGroupData_SpinInit;
@@ -95,6 +96,7 @@ static void gizmo_mesh_spin_init_setup(const bContext *UNUSED(C), wmGizmoGroup *
WM_gizmo_set_color(gz, color);
color[3] = alpha_hi;
WM_gizmo_set_color_highlight(gz, color);
+ WM_gizmo_set_scale(gz, 3.0);
}
{
@@ -106,10 +108,9 @@ static void gizmo_mesh_spin_init_setup(const bContext *UNUSED(C), wmGizmoGroup *
WM_gizmo_set_color(gz, color);
color[3] = alpha_hi;
WM_gizmo_set_color_highlight(gz, color);
+ WM_gizmo_set_scale(gz, 3.2f);
}
- WM_gizmo_set_scale(ggd->gizmos.xyz_view[3], 1.2f);
-
ggd->data.ot_spin = WM_operatortype_find("MESH_OT_spin", true);
}
@@ -173,10 +174,9 @@ static void gizmo_mesh_spin_init_refresh(const bContext *C, wmGizmoGroup *gzgrou
}
}
- float mat[3][3];
- ED_transform_calc_orientation_from_type(C, mat);
+ ED_transform_calc_orientation_from_type(C, ggd->data.orient_mat);
for (int i = 0; i < 3; i++) {
- gizmo_mesh_spin_init_refresh_axis_orientation(gzgroup, i, mat[i]);
+ gizmo_mesh_spin_init_refresh_axis_orientation(gzgroup, i, ggd->data.orient_mat[i]);
}
{
@@ -241,11 +241,6 @@ void MESH_GGT_spin(struct wmGizmoGroupType *gzgt)
* \{ */
/**
- * Don't show these for now, because they overlay the tools #MESH_GGT_spin_redo gizmos.
- * this means we cant rotate the currently running gizmo.
- */
-// #define USE_EXTRA_CONTROLS
-/**
* Orient the dial so the 'arc' starts where the mouse cursor is,
* this is simply to keep the gizmo displaying where the cursor starts.
* It's not needed for practical functionality.
@@ -253,15 +248,21 @@ void MESH_GGT_spin(struct wmGizmoGroupType *gzgt)
#define USE_ANGLE_Z_ORIENT
typedef struct GizmoGroupData_SpinRedo {
- /* Arrow to change plane depth. */
- struct wmGizmo *translate_z;
- /* Translate XYZ */
+ /* Translate XYZ. */
struct wmGizmo *translate_c;
- /* For grabbing the gizmo and moving freely. */
- struct wmGizmo *rotate_c;
/* Spin angle */
struct wmGizmo *angle_z;
+ /* Translate XY constrained. */
+ struct wmGizmo *translate_xy[2];
+ /* For grabbing the gizmo and moving freely. */
+ struct wmGizmo *rotate_xy[2];
+
+ struct {
+ float plane_co[3];
+ float plane_no[3];
+ } prev;
+
/* We could store more vars here! */
struct {
bContext *context;
@@ -272,10 +273,17 @@ typedef struct GizmoGroupData_SpinRedo {
PropertyRNA *prop_angle;
float rotate_axis[3];
- float rotate_up[3];
#ifdef USE_ANGLE_Z_ORIENT
float orient_axis[3];
#endif
+ /* The orientation, since the operator doesn't store this, we store our own.
+ * this is kept in sync with the operator,
+ * rotating the orientation when it doesn't match.
+ *
+ * Initialize to a sensible value where possible.
+ */
+ float orient_mat[3][3];
+
} data;
} GizmoGroupData_SpinRedo;
@@ -295,18 +303,39 @@ static void gizmo_spin_exec(GizmoGroupData_SpinRedo *ggd)
static void gizmo_mesh_spin_redo_update_from_op(GizmoGroupData_SpinRedo *ggd)
{
wmOperator *op = ggd->data.op;
-
float plane_co[3], plane_no[3];
-
RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_co, plane_co);
RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_no, plane_no);
+ if (UNLIKELY(normalize_v3(plane_no) == 0.0f)) {
+ return;
+ }
+ const bool is_plane_co_eq = equals_v3v3(plane_co, ggd->prev.plane_co);
+ const bool is_plane_no_eq = equals_v3v3(plane_no, ggd->prev.plane_no);
+ if (is_plane_co_eq && is_plane_no_eq) {
+ return;
+ }
+ copy_v3_v3(ggd->prev.plane_co, plane_co);
+ copy_v3_v3(ggd->prev.plane_no, plane_no);
+
+ if (is_plane_no_eq == false) {
+ float mat[3][3];
+ rotation_between_vecs_to_mat3(mat, ggd->data.orient_mat[2], plane_no);
+ mul_m3_m3m3(ggd->data.orient_mat, mat, ggd->data.orient_mat);
+ /* Not needed, just set for numeric stability. */
+ copy_v3_v3(ggd->data.orient_mat[2], plane_no);
+ }
- WM_gizmo_set_matrix_location(ggd->translate_z, plane_co);
- WM_gizmo_set_matrix_location(ggd->rotate_c, plane_co);
+ for (int i = 0; i < 2; i++) {
+ WM_gizmo_set_matrix_location(ggd->rotate_xy[i], plane_co);
+ WM_gizmo_set_matrix_location(ggd->translate_xy[i], plane_co);
+ }
WM_gizmo_set_matrix_location(ggd->angle_z, plane_co);
/* translate_c location comes from the property. */
- WM_gizmo_set_matrix_rotation_from_z_axis(ggd->translate_z, plane_no);
+ for (int i = 0; i < 2; i++) {
+ WM_gizmo_set_matrix_rotation_from_z_axis(ggd->translate_xy[i], ggd->data.orient_mat[i]);
+ WM_gizmo_set_matrix_rotation_from_z_axis(ggd->rotate_xy[i], ggd->data.orient_mat[i]);
+ }
#ifdef USE_ANGLE_Z_ORIENT
{
float plane_tan[3];
@@ -321,30 +350,6 @@ static void gizmo_mesh_spin_redo_update_from_op(GizmoGroupData_SpinRedo *ggd)
#else
WM_gizmo_set_matrix_rotation_from_z_axis(ggd->angle_z, plane_no);
#endif
-
- WM_gizmo_set_scale(ggd->translate_c, 0.2);
-
- WM_gizmo_set_scale(ggd->angle_z, 2.0f);
- WM_gizmo_set_line_width(ggd->angle_z, 1.0f);
-
- RegionView3D *rv3d = ED_view3d_context_rv3d(ggd->data.context);
- if (rv3d) {
- normalize_v3_v3(ggd->data.rotate_axis, rv3d->viewinv[2]);
- normalize_v3_v3(ggd->data.rotate_up, rv3d->viewinv[1]);
-
- /* ensure its orthogonal */
- project_plane_normalized_v3_v3v3(ggd->data.rotate_up, ggd->data.rotate_up, ggd->data.rotate_axis);
- normalize_v3(ggd->data.rotate_up);
-
- WM_gizmo_set_matrix_rotation_from_z_axis(ggd->translate_c, plane_no);
- WM_gizmo_set_matrix_rotation_from_yz_axis(ggd->rotate_c, plane_no, ggd->data.rotate_axis);
-
- /* show the axis instead of mouse cursor */
- RNA_enum_set(ggd->rotate_c->ptr, "draw_options",
- ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_MIRROR |
- ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_START_Y);
-
- }
}
/* depth callbacks */
@@ -359,9 +364,9 @@ static void gizmo_spin_prop_depth_get(
BLI_assert(gz_prop->type->array_length == 1);
UNUSED_VARS_NDEBUG(gz_prop);
- float plane_co[3], plane_no[3];
+ const float *plane_no = gz->matrix_basis[2];
+ float plane_co[3];
RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_co, plane_co);
- RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_no, plane_no);
value[0] = dot_v3v3(plane_no, plane_co) - dot_v3v3(plane_no, gz->matrix_basis[3]);
}
@@ -379,8 +384,7 @@ static void gizmo_spin_prop_depth_set(
float plane_co[3], plane[4];
RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_co, plane_co);
- RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_no, plane);
- normalize_v3(plane);
+ normalize_v3_v3(plane, gz->matrix_basis[2]);
plane[3] = -value[0] - dot_v3v3(plane, gz->matrix_basis[3]);
@@ -438,11 +442,15 @@ static void gizmo_spin_prop_axis_angle_get(
RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_no, plane_no);
normalize_v3(plane_no);
+ const float *rotate_axis = gz->matrix_basis[2];
+ float rotate_up[3];
+ ortho_v3_v3(rotate_up, rotate_axis);
+
float plane_no_proj[3];
- project_plane_normalized_v3_v3v3(plane_no_proj, plane_no, ggd->data.rotate_axis);
+ project_plane_normalized_v3_v3v3(plane_no_proj, plane_no, rotate_axis);
if (!is_zero_v3(plane_no_proj)) {
- const float angle = -angle_signed_on_axis_v3v3_v3(plane_no_proj, ggd->data.rotate_up, ggd->data.rotate_axis);
+ const float angle = -angle_signed_on_axis_v3v3_v3(plane_no_proj, rotate_up, rotate_axis);
value[0] = angle;
}
else {
@@ -465,15 +473,19 @@ static void gizmo_spin_prop_axis_angle_set(
RNA_property_float_get_array(op->ptr, ggd->data.prop_axis_no, plane_no);
normalize_v3(plane_no);
+ const float *rotate_axis = gz->matrix_basis[2];
+ float rotate_up[3];
+ ortho_v3_v3(rotate_up, rotate_axis);
+
float plane_no_proj[3];
- project_plane_normalized_v3_v3v3(plane_no_proj, plane_no, ggd->data.rotate_axis);
+ project_plane_normalized_v3_v3v3(plane_no_proj, plane_no, rotate_axis);
if (!is_zero_v3(plane_no_proj)) {
- const float angle = -angle_signed_on_axis_v3v3_v3(plane_no_proj, ggd->data.rotate_up, ggd->data.rotate_axis);
+ const float angle = -angle_signed_on_axis_v3v3_v3(plane_no_proj, rotate_up, rotate_axis);
const float angle_delta = angle - angle_compat_rad(value[0], angle);
if (angle_delta != 0.0f) {
float mat[3][3];
- axis_angle_normalized_to_mat3(mat, ggd->data.rotate_axis, angle_delta);
+ axis_angle_normalized_to_mat3(mat, rotate_axis, angle_delta);
mul_m3_v3(mat, plane_no);
/* re-normalize - seems acceptable */
@@ -569,29 +581,57 @@ static void gizmo_mesh_spin_redo_setup(const bContext *C, wmGizmoGroup *gzgroup)
const wmGizmoType *gzt_move = WM_gizmotype_find("GIZMO_GT_move_3d", true);
const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
- ggd->translate_z = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
- ggd->translate_c = WM_gizmo_new_ptr(gzt_move, gzgroup, NULL);
- ggd->rotate_c = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
- ggd->angle_z = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
-
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, ggd->translate_z->color);
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, ggd->translate_c->color);
- UI_GetThemeColor3fv(TH_GIZMO_SECONDARY, ggd->rotate_c->color);
- copy_v3_v3(ggd->angle_z->color, ggd->angle_z->color_hi);
- ggd->angle_z->color[3] = 0.5f;
-
- RNA_enum_set(ggd->translate_z->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_NORMAL);
- RNA_enum_set(ggd->translate_c->ptr, "draw_style", ED_GIZMO_MOVE_STYLE_RING_2D);
+ /* Translate Center (translate_c) */
+ {
+ wmGizmo *gz = WM_gizmo_new_ptr(gzt_move, gzgroup, NULL);
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ gz->color[3] = 0.6f;
+ RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_MOVE_STYLE_RING_2D);
+ WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_VALUE, true);
+ WM_gizmo_set_scale(gz, 0.15);
+ WM_gizmo_set_line_width(gz, 2.0f);
+ ggd->translate_c = gz;
+ }
- RNA_boolean_set(ggd->angle_z->ptr, "wrap_angle", false);
- RNA_enum_set(ggd->angle_z->ptr, "draw_options", ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE);
- RNA_float_set(ggd->angle_z->ptr, "arc_inner_factor", 0.9f);
+ /* Spin Angle (angle_z) */
+ {
+ wmGizmo *gz = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
+ copy_v3_v3(gz->color, gz->color_hi);
+ gz->color[3] = 0.5f;
+ RNA_boolean_set(gz->ptr, "wrap_angle", false);
+ RNA_enum_set(gz->ptr, "draw_options", ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE);
+ RNA_float_set(gz->ptr, "arc_inner_factor", 0.9f);
+ WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_VALUE, true);
+ WM_gizmo_set_scale(gz, 2.0f);
+ WM_gizmo_set_line_width(gz, 1.0f);
+ ggd->angle_z = gz;
+ }
- WM_gizmo_set_flag(ggd->translate_c, WM_GIZMO_DRAW_VALUE, true);
- WM_gizmo_set_flag(ggd->rotate_c, WM_GIZMO_DRAW_VALUE, true);
- WM_gizmo_set_flag(ggd->angle_z, WM_GIZMO_DRAW_VALUE, true);
+ /* Translate X/Y Tangents (translate_xy) */
+ for (int i = 0; i < 2; i++) {
+ wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
+ UI_GetThemeColor3fv(TH_AXIS_X + i, gz->color);
+ RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_NORMAL);
+ RNA_enum_set(gz->ptr, "draw_options", 0);
+ WM_gizmo_set_scale(gz, 1.2f);
+ ggd->translate_xy[i] = gz;
+ }
- WM_gizmo_set_scale(ggd->rotate_c, 0.8f);
+ /* Rotate X/Y Tangents (rotate_xy) */
+ for (int i = 0; i < 2; i++) {
+ wmGizmo *gz = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
+ UI_GetThemeColor3fv(TH_AXIS_X + i, gz->color);
+ gz->color[3] = 0.6f;
+ WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_VALUE, true);
+ WM_gizmo_set_scale(gz, 1.0f);
+ WM_gizmo_set_line_width(gz, 3.0f);
+ /* show the axis instead of mouse cursor */
+ RNA_enum_set(gz->ptr, "draw_options",
+ ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_MIRROR |
+ ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_START_Y |
+ ED_GIZMO_DIAL_DRAW_FLAG_CLIP);
+ ggd->rotate_xy[i] = gz;
+ }
{
ggd->data.context = (bContext *)C;
@@ -602,20 +642,28 @@ static void gizmo_mesh_spin_redo_setup(const bContext *C, wmGizmoGroup *gzgroup)
ggd->data.prop_angle = RNA_struct_type_find_property(ot->srna, "angle");
}
+ /* The spin operator only knows about an axis,
+ * while the manipulator has X/Y orientation for the gizmos.
+ * Initialize the orientation from the spin gizmo if possible.
+ */
+ {
+ ARegion *ar = CTX_wm_region(C);
+ wmGizmoMap *gzmap = ar->gizmo_map;
+ wmGizmoGroup *gzgroup_init = WM_gizmomap_group_find(gzmap, "MESH_GGT_spin");
+ if (gzgroup_init) {
+ GizmoGroupData_SpinInit *ggd_init = gzgroup_init->customdata;
+ copy_m3_m3(ggd->data.orient_mat, ggd_init->data.orient_mat);
+ }
+ else {
+ unit_m3(ggd->data.orient_mat);
+ }
+ }
+
gizmo_mesh_spin_redo_update_from_op(ggd);
/* Setup property callbacks */
{
WM_gizmo_target_property_def_func(
- ggd->translate_z, "offset",
- &(const struct wmGizmoPropertyFnParams) {
- .value_get_fn = gizmo_spin_prop_depth_get,
- .value_set_fn = gizmo_spin_prop_depth_set,
- .range_get_fn = NULL,
- .user_data = NULL,
- });
-
- WM_gizmo_target_property_def_func(
ggd->translate_c, "offset",
&(const struct wmGizmoPropertyFnParams) {
.value_get_fn = gizmo_spin_prop_translate_get,
@@ -624,14 +672,24 @@ static void gizmo_mesh_spin_redo_setup(const bContext *C, wmGizmoGroup *gzgroup)
.user_data = NULL,
});
- WM_gizmo_target_property_def_func(
- ggd->rotate_c, "offset",
- &(const struct wmGizmoPropertyFnParams) {
- .value_get_fn = gizmo_spin_prop_axis_angle_get,
- .value_set_fn = gizmo_spin_prop_axis_angle_set,
- .range_get_fn = NULL,
- .user_data = NULL,
- });
+ for (int i = 0; i < 2; i++) {
+ WM_gizmo_target_property_def_func(
+ ggd->rotate_xy[i], "offset",
+ &(const struct wmGizmoPropertyFnParams) {
+ .value_get_fn = gizmo_spin_prop_axis_angle_get,
+ .value_set_fn = gizmo_spin_prop_axis_angle_set,
+ .range_get_fn = NULL,
+ .user_data = NULL,
+ });
+ WM_gizmo_target_property_def_func(
+ ggd->translate_xy[i], "offset",
+ &(const struct wmGizmoPropertyFnParams) {
+ .value_get_fn = gizmo_spin_prop_depth_get,
+ .value_set_fn = gizmo_spin_prop_depth_set,
+ .range_get_fn = NULL,
+ .user_data = NULL,
+ });
+ }
WM_gizmo_target_property_def_func(
ggd->angle_z, "offset",
@@ -641,16 +699,8 @@ static void gizmo_mesh_spin_redo_setup(const bContext *C, wmGizmoGroup *gzgroup)
.range_get_fn = NULL,
.user_data = NULL,
});
-
}
-#ifndef USE_EXTRA_CONTROLS
- /* Disable for now. */
- WM_gizmo_set_flag(ggd->translate_z, WM_GIZMO_HIDDEN, true);
- WM_gizmo_set_flag(ggd->translate_c, WM_GIZMO_HIDDEN, true);
- WM_gizmo_set_flag(ggd->rotate_c, WM_GIZMO_HIDDEN, true);
-#endif
-
/* Become modal as soon as it's started. */
gizmo_mesh_spin_redo_modal_from_setup(C, gzgroup);
}
@@ -662,7 +712,22 @@ static void gizmo_mesh_spin_redo_draw_prepare(
if (ggd->data.op->next) {
ggd->data.op = WM_operator_last_redo((bContext *)ggd->data.context);
}
- gizmo_mesh_spin_redo_update_from_op(ggd);
+
+ /* Not essentual, just avoids feedback loop where matrices could shift because of float precision.
+ * Updates in this case are also redundant. */
+ bool is_modal = false;
+ for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) {
+ if (gz->state & WM_GIZMO_STATE_MODAL) {
+ is_modal = true;
+ break;
+ }
+ }
+ if (!is_modal) {
+ gizmo_mesh_spin_redo_update_from_op(ggd);
+ }
+
+ RegionView3D *rv3d = ED_view3d_context_rv3d(ggd->data.context);
+ WM_gizmo_set_matrix_rotation_from_z_axis(ggd->translate_c, rv3d->viewinv[2]);
}
void MESH_GGT_spin_redo(struct wmGizmoGroupType *gzgt)