From 33eabb82207e165de45fb6a0ea74dec962de7265 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Sat, 23 Nov 2019 13:11:39 +0300 Subject: Action Constraint: introduce a mix mode setting. Currently the action channels are applied after the existing transformation, as if the action controlled a child of the bone. This is not very natural, but more importantly, the transform tools are not designed to work conveniently with an additional 'pseudo-child' transformation, resulting in effects like an unexpected pivot location. Implementing a Before mode that integrates the action channels as if applied to a parent allows using the special transform tool code intended for dealing with such constraints. Note that in either mode, Action constraints should be added in reverse order, putting a new constraint before the existing ones that the Action was keyframed to work together. In order to implement the option, extract a utility from the Copy Transform constraint code for combining transforms with special anti-shear scale handling that matches the Aligned Inherit Scale mode. The Before mode also requires switching the constraint to the Local owner space, while the After mode can still use the World space for efficiency as before. Since the constraint doesn't have an Owner space option in the UI, this has to be handled in an RNA setter. For full backward compatibility, the original simple matrix multiplication mode is preserved as the third option, but it is not recommended due to creating shear. Differential Revision: https://developer.blender.org/D6297 --- source/blender/editors/transform/transform_convert.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c index db8f36883f8..2001d42a5eb 100644 --- a/source/blender/editors/transform/transform_convert.c +++ b/source/blender/editors/transform/transform_convert.c @@ -1350,6 +1350,15 @@ bool constraints_list_needinv(TransInfo *t, ListBase *list) return true; } } + else if (con->type == CONSTRAINT_TYPE_ACTION) { + /* The Action constraint only does this in the Before mode. */ + bActionConstraint *data = (bActionConstraint *)con->data; + + if (ELEM(data->mix_mode, ACTCON_MIX_BEFORE) && + ELEM(t->mode, TFM_ROTATION, TFM_TRANSLATION)) { + return true; + } + } else if (con->type == CONSTRAINT_TYPE_TRANSFORM) { /* Transform constraint needs it for rotation at least (r.57309), * but doing so when translating may also mess things up [#36203] -- cgit v1.2.3 From 86a2ffc3ab321f00317aa05fb423c4df6f68aced Mon Sep 17 00:00:00 2001 From: mano-wii Date: Tue, 31 Dec 2019 12:56:27 -0300 Subject: Transform: Individual Origins: Create islands between only selected uvs. Currently the islands are created depending only on the visible UVs. This can be confusing because compared to Edit Meshes, islands are created based on the selected elements. T68284 shows a case where this confusion is observed. Differential Revision: https://developer.blender.org/D6502 --- source/blender/editors/transform/transform_convert_mesh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c index 8b7dcecf9e8..006f913f218 100644 --- a/source/blender/editors/transform/transform_convert_mesh.c +++ b/source/blender/editors/transform/transform_convert_mesh.c @@ -1451,7 +1451,7 @@ void createTransUVs(bContext *C, TransInfo *t) if (is_prop_connected || is_island_center) { /* create element map with island information */ const bool use_facesel = (ts->uv_flag & UV_SYNC_SELECTION) == 0; - elementmap = BM_uv_element_map_create(em->bm, use_facesel, false, true); + elementmap = BM_uv_element_map_create(em->bm, scene, use_facesel, true, false, true); if (elementmap == NULL) { continue; } -- cgit v1.2.3 From de530a95dc7b482dc22c933b9b8b2a98c79b5663 Mon Sep 17 00:00:00 2001 From: mano-wii Date: Thu, 2 Jan 2020 12:48:30 -0300 Subject: Transform: Pose: Partial support for Auto IK + X-Mirror Fix T69572 TODO: support `Relative-Mirror` as well. Maniphest Tasks: T69572 Differential Revision: https://developer.blender.org/D5862 --- .../blender/editors/transform/transform_convert.c | 7 +- .../editors/transform/transform_convert_armature.c | 65 ++++++++-------- .../blender/editors/transform/transform_generics.c | 88 ++++++++++++---------- .../editors/transform/transform_orientations.c | 2 +- 4 files changed, 87 insertions(+), 75 deletions(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c index 2001d42a5eb..a214eb1c80b 100644 --- a/source/blender/editors/transform/transform_convert.c +++ b/source/blender/editors/transform/transform_convert.c @@ -450,20 +450,15 @@ int count_set_pose_transflags(Object *ob, for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { bone = pchan->bone; + bone->flag &= ~(BONE_TRANSFORM | BONE_TRANSFORM_MIRROR); if (PBONE_VISIBLE(arm, bone)) { if ((bone->flag & BONE_SELECTED)) { bone->flag |= BONE_TRANSFORM; } - else { - bone->flag &= ~BONE_TRANSFORM; - } bone->flag &= ~BONE_HINGE_CHILD_TRANSFORM; bone->flag &= ~BONE_TRANSFORM_CHILD; } - else { - bone->flag &= ~BONE_TRANSFORM; - } } /* make sure no bone can be transformed when a parent is transformed */ diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c index cc023688c8e..0edf55ece7e 100644 --- a/source/blender/editors/transform/transform_convert_armature.c +++ b/source/blender/editors/transform/transform_convert_armature.c @@ -86,6 +86,7 @@ static void add_pose_transdata( td->flag |= TD_NO_LOC; } + td->extra = pchan; td->protectflag = pchan->protectflag; td->loc = pchan->loc; @@ -364,7 +365,7 @@ static short pose_grab_with_ik(Main *bmain, Object *ob) * (but they must be selected, and only one ik-solver per chain should get added) */ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { if (pchan->bone->layer & arm->layer) { - if (pchan->bone->flag & BONE_SELECTED) { + if (pchan->bone->flag & (BONE_SELECTED | BONE_TRANSFORM_MIRROR)) { /* Rule: no IK for solitatry (unconnected) bones */ for (bonec = pchan->bone->childbase.first; bonec; bonec = bonec->next) { if (bonec->flag & BONE_CONNECTED) { @@ -379,7 +380,7 @@ static short pose_grab_with_ik(Main *bmain, Object *ob) if (pchan->parent) { /* only adds if there's no IK yet (and no parent bone was selected) */ for (parent = pchan->parent; parent; parent = parent->parent) { - if (parent->bone->flag & BONE_SELECTED) { + if (parent->bone->flag & (BONE_SELECTED | BONE_TRANSFORM_MIRROR)) { break; } } @@ -513,14 +514,6 @@ void createTransPose(TransInfo *t) } } - /* do we need to add temporal IK chains? */ - if ((pose->flag & POSE_AUTO_IK) && t->mode == TFM_TRANSLATION) { - if (pose_grab_with_ik(bmain, ob)) { - t->flag |= T_AUTOIK; - has_translate_rotate[0] = true; - } - } - if (mirror) { int total_mirrored = 0; for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { @@ -541,16 +534,6 @@ void createTransPose(TransInfo *t) } } - /* if there are no translatable bones, do rotation */ - if ((t->mode == TFM_TRANSLATION) && !has_translate_rotate[0]) { - if (has_translate_rotate[1]) { - t->mode = TFM_ROTATION; - } - else { - t->mode = TFM_RESIZE; - } - } - FOREACH_TRANS_DATA_CONTAINER (t, tc) { if (tc->data_len == 0) { continue; @@ -582,20 +565,32 @@ void createTransPose(TransInfo *t) td->val = NULL; } - /* use pose channels to fill trans data */ - td = tc->data; - for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - if (pchan->bone->flag & BONE_TRANSFORM) { - add_pose_transdata(t, pchan, ob, tc, td); - - if (mirror) { + if (mirror) { + for (bPoseChannel *pchan = pose->chanbase.first; pchan; pchan = pchan->next) { + if (pchan->bone->flag & BONE_TRANSFORM) { bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name); if (pchan_mirror) { + pchan_mirror->bone->flag |= BONE_TRANSFORM_MIRROR; pose_mirror_info_init(&pid[pid_index], pchan_mirror, pchan, is_mirror_relative); pid_index++; } } + } + } + /* do we need to add temporal IK chains? */ + if ((pose->flag & POSE_AUTO_IK) && t->mode == TFM_TRANSLATION) { + if (pose_grab_with_ik(bmain, ob)) { + t->flag |= T_AUTOIK; + has_translate_rotate[0] = true; + } + } + + /* use pose channels to fill trans data */ + td = tc->data; + for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + if (pchan->bone->flag & BONE_TRANSFORM) { + add_pose_transdata(t, pchan, ob, tc, td); td++; } } @@ -603,10 +598,20 @@ void createTransPose(TransInfo *t) if (td != (tc->data + tc->data_len)) { BKE_report(t->reports, RPT_DEBUG, "Bone selection count error"); } + } - /* initialize initial auto=ik chainlen's? */ - if (t->flag & T_AUTOIK) { - transform_autoik_update(t, 0); + /* initialize initial auto=ik chainlen's? */ + if (t->flag & T_AUTOIK) { + transform_autoik_update(t, 0); + } + + /* if there are no translatable bones, do rotation */ + if ((t->mode == TFM_TRANSLATION) && !has_translate_rotate[0]) { + if (has_translate_rotate[1]) { + t->mode = TFM_ROTATION; + } + else { + t->mode = TFM_RESIZE; } } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 9031dc06e3f..5595c3a0e38 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -31,6 +31,7 @@ #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_brush_types.h" +#include "DNA_constraint_types.h" #include "DNA_gpencil_types.h" #include "DNA_lattice_types.h" #include "DNA_screen_types.h" @@ -785,50 +786,61 @@ static void recalcData_spaceclip(TransInfo *t) * if pose bone (partial) selected, copy data. * context; posemode armature, with mirror editing enabled. * - * \param pid: Optional, apply relative transform when set. + * \param pid: Optional, apply relative transform when set (has no effect on mirrored bones). */ -static void pose_transform_mirror_update(Object *ob, PoseInitData_Mirror *pid) +static void pose_transform_mirror_update(TransInfo *t, + TransDataContainer *tc, + Object *ob, + PoseInitData_Mirror *pid) { float flip_mtx[4][4]; unit_m4(flip_mtx); flip_mtx[0][0] = -1; - for (bPoseChannel *pchan_orig = ob->pose->chanbase.first; pchan_orig; - pchan_orig = pchan_orig->next) { - /* Clear the MIRROR flag from previous runs */ - pchan_orig->bone->flag &= ~BONE_TRANSFORM_MIRROR; - } - - for (bPoseChannel *pchan_orig = ob->pose->chanbase.first; pchan_orig; - pchan_orig = pchan_orig->next) { - /* no layer check, correct mirror is more important */ - if (pchan_orig->bone->flag & BONE_TRANSFORM) { - bPoseChannel *pchan = BKE_pose_channel_get_mirrored(ob->pose, pchan_orig->name); - - if (pchan) { - /* also do bbone scaling */ - pchan->bone->xwidth = pchan_orig->bone->xwidth; - pchan->bone->zwidth = pchan_orig->bone->zwidth; - - /* we assume X-axis flipping for now */ - pchan->curve_in_x = pchan_orig->curve_in_x * -1; - pchan->curve_out_x = pchan_orig->curve_out_x * -1; - pchan->roll1 = pchan_orig->roll1 * -1; // XXX? - pchan->roll2 = pchan_orig->roll2 * -1; // XXX? - - float pchan_mtx_final[4][4]; - BKE_pchan_to_mat4(pchan_orig, pchan_mtx_final); - mul_m4_m4m4(pchan_mtx_final, pchan_mtx_final, flip_mtx); - mul_m4_m4m4(pchan_mtx_final, flip_mtx, pchan_mtx_final); - if (pid) { - mul_m4_m4m4(pchan_mtx_final, pid->offset_mtx, pchan_mtx_final); - pid++; - } - BKE_pchan_apply_mat4(pchan, pchan_mtx_final, false); + TransData *td = tc->data; + for (int i = tc->data_len; i--; td++) { + bPoseChannel *pchan_orig = td->extra; + BLI_assert(pchan_orig->bone->flag & BONE_TRANSFORM); + /* No layer check, correct mirror is more important. */ + bPoseChannel *pchan = BKE_pose_channel_get_mirrored(ob->pose, pchan_orig->name); + if (pchan == NULL) { + continue; + } + + /* Also do bbone scaling. */ + pchan->bone->xwidth = pchan_orig->bone->xwidth; + pchan->bone->zwidth = pchan_orig->bone->zwidth; - /* set flag to let autokeyframe know to keyframe the mirrred bone */ - pchan->bone->flag |= BONE_TRANSFORM_MIRROR; + /* We assume X-axis flipping for now. */ + pchan->curve_in_x = pchan_orig->curve_in_x * -1; + pchan->curve_out_x = pchan_orig->curve_out_x * -1; + pchan->roll1 = pchan_orig->roll1 * -1; // XXX? + pchan->roll2 = pchan_orig->roll2 * -1; // XXX? + + float pchan_mtx_final[4][4]; + BKE_pchan_to_mat4(pchan_orig, pchan_mtx_final); + mul_m4_m4m4(pchan_mtx_final, pchan_mtx_final, flip_mtx); + mul_m4_m4m4(pchan_mtx_final, flip_mtx, pchan_mtx_final); + if (pid) { + mul_m4_m4m4(pchan_mtx_final, pid->offset_mtx, pchan_mtx_final); + } + BKE_pchan_apply_mat4(pchan, pchan_mtx_final, false); + + /* In this case we can do target-less IK grabbing. */ + if (t->mode == TFM_TRANSLATION) { + bKinematicConstraint *data = has_targetless_ik(pchan); + if (data == NULL) { + continue; } + mul_v3_m4v3(data->grabtarget, flip_mtx, td->loc); + if (pid) { + /* TODO(germano): Realitve Mirror support */ + } + data->flag |= CONSTRAINT_IK_AUTO; + } + + if (pid) { + pid++; } } } @@ -1045,7 +1057,7 @@ static void recalcData_objects(TransInfo *t) DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); bPose *pose = ob->pose; if (arm->flag & ARM_MIRROR_EDIT || pose->flag & POSE_MIRROR_EDIT) { - pose_transform_mirror_update(ob, NULL); + pose_transform_mirror_update(t, tc, ob, NULL); } } } @@ -1063,7 +1075,7 @@ static void recalcData_objects(TransInfo *t) if (pose->flag & POSE_MIRROR_RELATIVE) { pid = tc->custom.type.data; } - pose_transform_mirror_update(ob, pid); + pose_transform_mirror_update(t, tc, ob, pid); } else { restoreMirrorPoseBones(tc); diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 3159464072e..1952a2c862e 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -413,7 +413,7 @@ static int count_bone_select(bArmature *arm, ListBase *lb, const bool do_it) int total = 0; for (bone = lb->first; bone; bone = bone->next) { - bone->flag &= ~BONE_TRANSFORM; + bone->flag &= ~(BONE_TRANSFORM | BONE_TRANSFORM_MIRROR); do_next = do_it; if (do_it) { if (bone->layer & arm->layer) { -- cgit v1.2.3 From 98e4fbc7cc9e9bd6492e7bbb82e48dcf7b4d0bac Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 6 Jan 2020 22:42:21 +1100 Subject: Gizmo: use compatible scale values between 2D/3D gizmos Make the UV editor gizmos the same size as the 3D view. --- source/blender/editors/transform/transform_gizmo_2d.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c index 3f0032cc7cc..43deb768f52 100644 --- a/source/blender/editors/transform/transform_gizmo_2d.c +++ b/source/blender/editors/transform/transform_gizmo_2d.c @@ -208,7 +208,6 @@ void ED_widgetgroup_gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup /* custom handler! */ WM_gizmo_set_fn_custom_modal(gz, gizmo2d_modal); - WM_gizmo_set_scale(gz, U.gizmo_size); if (i < 2) { float color[4], color_hi[4]; @@ -221,6 +220,8 @@ void ED_widgetgroup_gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup WM_gizmo_set_line_width(gz, GIZMO_AXIS_LINE_WIDTH); WM_gizmo_set_color(gz, color); WM_gizmo_set_color_highlight(gz, color_hi); + + WM_gizmo_set_scale(gz, 1.0f); } else { PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "icon"); @@ -230,6 +231,8 @@ void ED_widgetgroup_gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup /* Make the center low alpha. */ WM_gizmo_set_line_width(gz, 2.0f); RNA_float_set(gz->ptr, "backdrop_fill_alpha", 0.0); + + WM_gizmo_set_scale(gz, 1.2f); } /* Assign operator. */ @@ -511,7 +514,6 @@ void ED_widgetgroup_gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup /* custom handler! */ WM_gizmo_set_fn_custom_modal(gz, gizmo2d_modal); - WM_gizmo_set_scale(gz, U.gizmo_size); if (i < 2) { const float offset[3] = {0.0f, 0.2f}; @@ -527,6 +529,8 @@ void ED_widgetgroup_gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup WM_gizmo_set_line_width(gz, GIZMO_AXIS_LINE_WIDTH); WM_gizmo_set_color(gz, color); WM_gizmo_set_color_highlight(gz, color_hi); + + WM_gizmo_set_scale(gz, 1.0f); } else { PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "icon"); @@ -536,6 +540,8 @@ void ED_widgetgroup_gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup /* Make the center low alpha. */ WM_gizmo_set_line_width(gz, 2.0f); RNA_float_set(gz->ptr, "backdrop_fill_alpha", 0.0); + + WM_gizmo_set_scale(gz, 1.2f); } /* Assign operator. */ @@ -629,7 +635,7 @@ void ED_widgetgroup_gizmo2d_rotate_setup(const bContext *UNUSED(C), wmGizmoGroup /* custom handler! */ WM_gizmo_set_fn_custom_modal(gz, gizmo2d_modal); - WM_gizmo_set_scale(gz, U.gizmo_size); + WM_gizmo_set_scale(gz, 1.0f); { PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "icon"); -- cgit v1.2.3 From 0d67eb277f9bcf01ab6781ae27816caf690eb671 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 6 Jan 2020 22:42:49 +1100 Subject: Gizmo: support 3D arrow gizmos in 2D spaces Allows 2D arrows to be removed, since they work slightly differently and don't support offset matrices. Use these in the UV editor. --- source/blender/editors/transform/transform_gizmo_2d.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c index 43deb768f52..131345f7285 100644 --- a/source/blender/editors/transform/transform_gizmo_2d.c +++ b/source/blender/editors/transform/transform_gizmo_2d.c @@ -115,7 +115,7 @@ static void gizmo2d_get_axis_color(const int axis_idx, float *r_col, float *r_co static GizmoGroup2D *gizmogroup2d_init(wmGizmoGroup *gzgroup) { - const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_2d", true); + const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true); const wmGizmoType *gzt_cage = WM_gizmotype_find("GIZMO_GT_cage_2d", true); const wmGizmoType *gzt_button = WM_gizmotype_find("GIZMO_GT_button_2d", true); @@ -214,8 +214,11 @@ void ED_widgetgroup_gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup gizmo2d_get_axis_color(i, color, color_hi); /* set up widget data */ - RNA_float_set(gz->ptr, "angle", -M_PI_2 * i); RNA_float_set(gz->ptr, "length", 0.8f); + float axis[3] = {0.0f}; + axis[(i + 1) % 2] = 1.0f; + WM_gizmo_set_matrix_rotation_from_z_axis(gz, axis); + WM_gizmo_set_matrix_offset_location(gz, offset); WM_gizmo_set_line_width(gz, GIZMO_AXIS_LINE_WIDTH); WM_gizmo_set_color(gz, color); @@ -453,7 +456,7 @@ typedef struct GizmoGroup_Resize2D { static GizmoGroup_Resize2D *gizmogroup2d_resize_init(wmGizmoGroup *gzgroup) { - const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_2d", true); + const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true); const wmGizmoType *gzt_button = WM_gizmotype_find("GIZMO_GT_button_2d", true); GizmoGroup_Resize2D *ggd = MEM_callocN(sizeof(GizmoGroup_Resize2D), __func__); @@ -521,8 +524,11 @@ void ED_widgetgroup_gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup gizmo2d_get_axis_color(i, color, color_hi); /* set up widget data */ - RNA_float_set(gz->ptr, "angle", -M_PI_2 * i); RNA_float_set(gz->ptr, "length", 0.8f); + float axis[3] = {0.0f}; + axis[(i + 1) % 2] = 1.0f; + WM_gizmo_set_matrix_rotation_from_z_axis(gz, axis); + RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX); WM_gizmo_set_matrix_offset_location(gz, offset); -- cgit v1.2.3 From 24d46bdbf745a4a319744f60a02f37a3d77654a5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 6 Jan 2020 23:04:31 +1100 Subject: Gizmo: match UV editor gizmos more closely to the 3D view --- source/blender/editors/transform/transform_gizmo_2d.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c index 131345f7285..e76ece987df 100644 --- a/source/blender/editors/transform/transform_gizmo_2d.c +++ b/source/blender/editors/transform/transform_gizmo_2d.c @@ -204,7 +204,6 @@ void ED_widgetgroup_gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup for (int i = 0; i < ARRAY_SIZE(ggd->translate_xy); i++) { wmGizmo *gz = ggd->translate_xy[i]; - const float offset[3] = {0.0f, 0.2f}; /* custom handler! */ WM_gizmo_set_fn_custom_modal(gz, gizmo2d_modal); @@ -219,7 +218,11 @@ void ED_widgetgroup_gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup axis[(i + 1) % 2] = 1.0f; WM_gizmo_set_matrix_rotation_from_z_axis(gz, axis); + float offset[3] = {0, 0, 0}; + offset[2] = 0.18f; WM_gizmo_set_matrix_offset_location(gz, offset); + gz->flag |= WM_GIZMO_DRAW_OFFSET_SCALE; + WM_gizmo_set_line_width(gz, GIZMO_AXIS_LINE_WIDTH); WM_gizmo_set_color(gz, color); WM_gizmo_set_color_highlight(gz, color_hi); @@ -234,8 +237,9 @@ void ED_widgetgroup_gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup /* Make the center low alpha. */ WM_gizmo_set_line_width(gz, 2.0f); RNA_float_set(gz->ptr, "backdrop_fill_alpha", 0.0); + WM_gizmo_set_color(gz, (const float[4]){1, 1, 1, 0.6}); - WM_gizmo_set_scale(gz, 1.2f); + WM_gizmo_set_scale(gz, 0.2f); } /* Assign operator. */ @@ -519,19 +523,17 @@ void ED_widgetgroup_gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup WM_gizmo_set_fn_custom_modal(gz, gizmo2d_modal); if (i < 2) { - const float offset[3] = {0.0f, 0.2f}; float color[4], color_hi[4]; gizmo2d_get_axis_color(i, color, color_hi); /* set up widget data */ - RNA_float_set(gz->ptr, "length", 0.8f); + RNA_float_set(gz->ptr, "length", 1.0f); float axis[3] = {0.0f}; axis[(i + 1) % 2] = 1.0f; WM_gizmo_set_matrix_rotation_from_z_axis(gz, axis); RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX); - WM_gizmo_set_matrix_offset_location(gz, offset); WM_gizmo_set_line_width(gz, GIZMO_AXIS_LINE_WIDTH); WM_gizmo_set_color(gz, color); WM_gizmo_set_color_highlight(gz, color_hi); @@ -546,6 +548,7 @@ void ED_widgetgroup_gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup /* Make the center low alpha. */ WM_gizmo_set_line_width(gz, 2.0f); RNA_float_set(gz->ptr, "backdrop_fill_alpha", 0.0); + WM_gizmo_set_color(gz, (const float[4]){1, 1, 1, 0.6}); WM_gizmo_set_scale(gz, 1.2f); } @@ -641,7 +644,7 @@ void ED_widgetgroup_gizmo2d_rotate_setup(const bContext *UNUSED(C), wmGizmoGroup /* custom handler! */ WM_gizmo_set_fn_custom_modal(gz, gizmo2d_modal); - WM_gizmo_set_scale(gz, 1.0f); + WM_gizmo_set_scale(gz, 1.2f); { PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "icon"); @@ -651,6 +654,7 @@ void ED_widgetgroup_gizmo2d_rotate_setup(const bContext *UNUSED(C), wmGizmoGroup /* Make the center low alpha. */ WM_gizmo_set_line_width(gz, 2.0f); RNA_float_set(gz->ptr, "backdrop_fill_alpha", 0.0); + WM_gizmo_set_color(gz, (const float[4]){1, 1, 1, 0.6}); } /* Assign operator. */ -- cgit v1.2.3 From e95c0fba095dfac38b33b5ad7db36316093e2acf Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Jan 2020 14:20:49 +1100 Subject: BMesh: remove BMEditMesh.ob use BKE_editmesh_lnorspace_* API Note that this is a bit clumsy having both edit-mesh and mesh, BKE_editmesh_ensure_autosmooth & BKE_editmesh_lnorspace_update are often called together, these could be made into a single functions. --- source/blender/editors/transform/transform.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 7112444655b..9a98a2b8a00 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2479,7 +2479,7 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve else if (!do_skip) { const bool preserve_clnor = RNA_property_boolean_get(op->ptr, prop); if (preserve_clnor) { - BKE_editmesh_lnorspace_update(em); + BKE_editmesh_lnorspace_update(em, tc->obedit->data); t->flag |= T_CLNOR_REBUILD; } BM_lnorspace_invalidate(em->bm, true); @@ -4657,8 +4657,8 @@ static void initNormalRotation(TransInfo *t) BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); BMesh *bm = em->bm; - BKE_editmesh_ensure_autosmooth(em); - BKE_editmesh_lnorspace_update(em); + BKE_editmesh_ensure_autosmooth(em, tc->obedit->data); + BKE_editmesh_lnorspace_update(em, tc->obedit->data); storeCustomLNorValue(tc, bm); } -- cgit v1.2.3 From 1ef59d0eb535c3d526a1a1f72e257b5aa5b15fb3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Jan 2020 17:02:50 +1100 Subject: BMesh: remove BMEditMesh.ob use for ED_transform_snap_object_* API --- .../editors/transform/transform_snap_object.c | 69 ++++++++++++++-------- 1 file changed, 46 insertions(+), 23 deletions(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 604ecb984a9..4fe2ae5321b 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -130,6 +130,8 @@ struct SnapObjectContext { /* Object -> SnapObjectData map */ struct { GHash *object_map; + /** Map object-data to objects so objects share edit mode data. */ + GHash *data_to_object_map; MemArena *mem_arena; } cache; @@ -164,6 +166,21 @@ static void bm_mesh_minmax(BMesh *bm, float r_min[3], float r_max[3]) } } +static SnapObjectData *snap_object_data_lookup(SnapObjectContext *sctx, Object *ob) +{ + SnapObjectData *sod = BLI_ghash_lookup(sctx->cache.object_map, ob); + if (sod == NULL) { + if (sctx->cache.data_to_object_map != NULL) { + ob = BLI_ghash_lookup(sctx->cache.data_to_object_map, ob->data); + /* Could be NULl when mixing edit-mode and non edit-mode objects. */ + if (ob != NULL) { + sod = BLI_ghash_lookup(sctx->cache.object_map, ob); + } + } + } + return sod; +} + static SnapObjectData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx, Object *ob) { void **sod_p; @@ -182,13 +199,28 @@ static SnapObjectData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx, O return *sod_p; } -/* Use `em->ob` as the key in ghash since the editmesh is used - * to create bvhtree and is the same for each linked object. */ static SnapObjectData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx, + Object *ob, BMEditMesh *em) { void **sod_p; - if (BLI_ghash_ensure_p(sctx->cache.object_map, em->ob, &sod_p)) { + + { + /* Use object-data as the key in ghash since the editmesh + * is used to create bvhtree and is the same for each linked object. */ + if (sctx->cache.data_to_object_map == NULL) { + sctx->cache.data_to_object_map = BLI_ghash_ptr_new(__func__); + } + void **ob_p; + if (BLI_ghash_ensure_p(sctx->cache.data_to_object_map, ob->data, &ob_p)) { + ob = *ob_p; + } + else { + *ob_p = ob; + } + } + + if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) { BLI_assert(((SnapObjectData *)*sod_p)->type == SNAP_EDIT_MESH); } else { @@ -617,8 +649,6 @@ static bool raycastEditMesh(SnapObjectContext *sctx, return retval; } - BLI_assert(BKE_object_get_pre_modified_mesh(em->ob) == BKE_object_get_pre_modified_mesh(ob)); - float imat[4][4]; float ray_start_local[3], ray_normal_local[3]; float local_scale, local_depth, len_diff = 0.0f; @@ -638,7 +668,7 @@ static bool raycastEditMesh(SnapObjectContext *sctx, local_depth *= local_scale; } - SnapObjectData_EditMesh *sod = snap_object_data_editmesh_get(sctx, em); + SnapObjectData_EditMesh *sod = snap_object_data_editmesh_get(sctx, ob, em); /* Test BoundBox */ @@ -666,7 +696,7 @@ static bool raycastEditMesh(SnapObjectContext *sctx, BVHTreeFromEditMesh *treedata = sod->bvh_trees[2]; - BVHCache **em_bvh_cache = &((Mesh *)em->ob->data)->runtime.bvh_cache; + BVHCache **em_bvh_cache = &((Mesh *)ob->data)->runtime.bvh_cache; if (sctx->callbacks.edit_mesh.test_face_fn == NULL) { /* The tree is owned by the Mesh and may have been freed since we last used! */ @@ -1365,13 +1395,7 @@ static short snap_mesh_polygon(SnapObjectContext *sctx, .dist_sq = SQUARE(*dist_px), }; - SnapObjectData *sod = BLI_ghash_lookup(sctx->cache.object_map, ob); - if (sod == NULL) { - /* The object is in edit mode, and the key used - * was the object referenced in BMEditMesh */ - BMEditMesh *em = BKE_editmesh_from_object(ob); - sod = BLI_ghash_lookup(sctx->cache.object_map, em->ob); - } + SnapObjectData *sod = snap_object_data_lookup(sctx, ob); BLI_assert(sod != NULL); @@ -1492,13 +1516,7 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, return elem; } - SnapObjectData *sod = BLI_ghash_lookup(sctx->cache.object_map, ob); - if (sod == NULL) { - /* The object is in edit mode, and the key used - * was the object referenced in BMEditMesh */ - BMEditMesh *em = BKE_editmesh_from_object(ob); - sod = BLI_ghash_lookup(sctx->cache.object_map, em->ob); - } + SnapObjectData *sod = snap_object_data_lookup(sctx, ob); BLI_assert(sod != NULL); @@ -2380,7 +2398,7 @@ static short snapEditMesh(SnapObjectContext *sctx, float dist_px_sq = SQUARE(*dist_px); - SnapObjectData_EditMesh *sod = snap_object_data_editmesh_get(sctx, em); + SnapObjectData_EditMesh *sod = snap_object_data_editmesh_get(sctx, ob, em); /* Test BoundBox */ @@ -2390,7 +2408,7 @@ static short snapEditMesh(SnapObjectContext *sctx, return 0; } - BVHCache **em_bvh_cache = &((Mesh *)em->ob->data)->runtime.bvh_cache; + BVHCache **em_bvh_cache = &((Mesh *)ob->data)->runtime.bvh_cache; if (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX) { if (sod->bvh_trees[0] == NULL) { @@ -2750,6 +2768,8 @@ SnapObjectContext *ED_transform_snap_object_context_create(Main *bmain, sctx->depsgraph = depsgraph; sctx->cache.object_map = BLI_ghash_ptr_new(__func__); + /* Initialize as needed (edit-mode only). */ + sctx->cache.data_to_object_map = NULL; sctx->cache.mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); return sctx; @@ -2797,6 +2817,9 @@ static void snap_object_data_free(void *sod_v) void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx) { BLI_ghash_free(sctx->cache.object_map, NULL, snap_object_data_free); + if (sctx->cache.data_to_object_map != NULL) { + BLI_ghash_free(sctx->cache.data_to_object_map, NULL, NULL); + } BLI_memarena_free(sctx->cache.mem_arena); MEM_freeN(sctx); -- cgit v1.2.3 From ac4057b95a5b20c4903308881193e291266f87db Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 9 Jan 2020 13:56:45 +1100 Subject: Gizmo: use pivot center for UV gizmos --- .../blender/editors/transform/transform_gizmo_2d.c | 184 +++++++++++++++++---- 1 file changed, 152 insertions(+), 32 deletions(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c index e76ece987df..dc8d820b075 100644 --- a/source/blender/editors/transform/transform_gizmo_2d.c +++ b/source/blender/editors/transform/transform_gizmo_2d.c @@ -44,6 +44,7 @@ #include "WM_api.h" #include "WM_types.h" #include "wm.h" /* XXX */ +#include "WM_message.h" #include "ED_image.h" #include "ED_screen.h" @@ -52,15 +53,56 @@ #include "transform.h" /* own include */ +/* -------------------------------------------------------------------- */ +/** \name Shared Callback's + */ + +static void gizmo2d_pivot_point_message_subscribe(struct wmGizmoGroup *gzgroup, + struct wmMsgBus *mbus, + /* Additional args. */ + bScreen *screen, + ScrArea *sa, + ARegion *ar) +{ + wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = { + .owner = ar, + .user_data = gzgroup->parent_gzmap, + .notify = WM_gizmo_do_msg_notify_tag_refresh, + }; + + switch (sa->spacetype) { + case SPACE_IMAGE: { + SpaceImage *sima = sa->spacedata.first; + PointerRNA ptr; + RNA_pointer_create(&screen->id, &RNA_SpaceImageEditor, sima, &ptr); + { + extern PropertyRNA rna_SpaceImageEditor_pivot_point; + extern PropertyRNA rna_SpaceImageEditor_cursor_location; + const PropertyRNA *props[] = { + &rna_SpaceImageEditor_pivot_point, + (sima->around == V3D_AROUND_CURSOR) ? &rna_SpaceImageEditor_cursor_location : NULL, + }; + for (int i = 0; i < ARRAY_SIZE(props); i++) { + if (props[i] == NULL) { + continue; + } + WM_msg_subscribe_rna(mbus, &ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__); + } + } + break; + } + } +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Arrow / Cage Gizmo Group * * Defines public functions, not the gizmo it's self: * - * - #ED_widgetgroup_gizmo2d_xform_setup - * - #ED_widgetgroup_gizmo2d_xform_refresh - * - #ED_widgetgroup_gizmo2d_xform_draw_prepare - * - #ED_widgetgroup_gizmo2d_xform_poll + * - #ED_widgetgroup_gizmo2d_xform_callbacks_set + * - #ED_widgetgroup_gizmo2d_xform_no_cage_callbacks_set * * \{ */ @@ -150,12 +192,13 @@ static void gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min ScrArea *sa = CTX_wm_area(C); if (sa->spacetype == SPACE_IMAGE) { SpaceImage *sima = sa->spacedata.first; + Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); Image *ima = ED_space_image(sima); uint objects_len = 0; Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs( view_layer, NULL, &objects_len); - if (!ED_uvedit_minmax_multi(CTX_data_scene(C), ima, objects, objects_len, r_min, r_max)) { + if (!ED_uvedit_minmax_multi(scene, ima, objects, objects_len, r_min, r_max)) { zero_v2(r_min); zero_v2(r_max); } @@ -168,6 +211,18 @@ static void gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min mid_v2_v2v2(r_center, r_min, r_max); } +static void gizmo2d_calc_center(const bContext *C, float r_center[2]) +{ + ScrArea *sa = CTX_wm_area(C); + zero_v2(r_center); + if (sa->spacetype == SPACE_IMAGE) { + SpaceImage *sima = sa->spacedata.first; + Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + ED_uvedit_center_from_pivot(sima, scene, view_layer, r_center, sima->around); + } +} + /** * Convert origin (or any other point) from view to region space. */ @@ -187,7 +242,7 @@ static int gizmo2d_modal(bContext *C, ARegion *ar = CTX_wm_region(C); float origin[3]; - gizmo2d_calc_bounds(C, origin, NULL, NULL); + gizmo2d_calc_center(C, origin); gizmo2d_origin_to_region(ar, origin); WM_gizmo_set_matrix_location(widget, origin); @@ -196,7 +251,7 @@ static int gizmo2d_modal(bContext *C, return OPERATOR_RUNNING_MODAL; } -void ED_widgetgroup_gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) +static void gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { wmOperatorType *ot_translate = WM_operatortype_find("TRANSFORM_OT_translate", true); GizmoGroup2D *ggd = gizmogroup2d_init(gzgroup); @@ -299,18 +354,23 @@ void ED_widgetgroup_gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup } } -void ED_widgetgroup_gizmo2d_xform_setup_no_cage(const bContext *C, wmGizmoGroup *gzgroup) +static void gizmo2d_xform_setup_no_cage(const bContext *C, wmGizmoGroup *gzgroup) { - ED_widgetgroup_gizmo2d_xform_setup(C, gzgroup); + gizmo2d_xform_setup(C, gzgroup); GizmoGroup2D *ggd = gzgroup->customdata; ggd->no_cage = true; } -void ED_widgetgroup_gizmo2d_xform_refresh(const bContext *C, wmGizmoGroup *gzgroup) +static void gizmo2d_xform_refresh(const bContext *C, wmGizmoGroup *gzgroup) { GizmoGroup2D *ggd = gzgroup->customdata; float origin[3]; - gizmo2d_calc_bounds(C, origin, ggd->min, ggd->max); + if (ggd->no_cage) { + gizmo2d_calc_center(C, origin); + } + else { + gizmo2d_calc_bounds(C, origin, ggd->min, ggd->max); + } copy_v2_v2(ggd->origin, origin); bool show_cage = !ggd->no_cage && !equals_v2v2(ggd->min, ggd->max); @@ -379,7 +439,7 @@ void ED_widgetgroup_gizmo2d_xform_refresh(const bContext *C, wmGizmoGroup *gzgro } } -void ED_widgetgroup_gizmo2d_xform_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) +static void gizmo2d_xform_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { ARegion *ar = CTX_wm_region(C); GizmoGroup2D *ggd = gzgroup->customdata; @@ -403,7 +463,7 @@ void ED_widgetgroup_gizmo2d_xform_draw_prepare(const bContext *C, wmGizmoGroup * * - Called on every redraw, better to do a more simple poll and check for selection in _refresh * - UV editing only, could be expanded for other things. */ -bool ED_widgetgroup_gizmo2d_xform_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) +static bool gizmo2d_xform_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { if ((U.gizmo_flag & USER_GIZMO_DRAW) == 0) { return false; @@ -439,6 +499,32 @@ bool ED_widgetgroup_gizmo2d_xform_poll(const bContext *C, wmGizmoGroupType *UNUS return false; } +static void gizmo2d_xform_no_cage_message_subscribe(const struct bContext *C, + struct wmGizmoGroup *gzgroup, + struct wmMsgBus *mbus) +{ + bScreen *screen = CTX_wm_screen(C); + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + gizmo2d_pivot_point_message_subscribe(gzgroup, mbus, screen, sa, ar); +} + +void ED_widgetgroup_gizmo2d_xform_callbacks_set(wmGizmoGroupType *gzgt) +{ + gzgt->poll = gizmo2d_xform_poll; + gzgt->setup = gizmo2d_xform_setup; + gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag; + gzgt->refresh = gizmo2d_xform_refresh; + gzgt->draw_prepare = gizmo2d_xform_draw_prepare; +} + +void ED_widgetgroup_gizmo2d_xform_no_cage_callbacks_set(wmGizmoGroupType *gzgt) +{ + ED_widgetgroup_gizmo2d_xform_callbacks_set(gzgt); + gzgt->setup = gizmo2d_xform_setup_no_cage; + gzgt->message_subscribe = gizmo2d_xform_no_cage_message_subscribe; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -446,10 +532,7 @@ bool ED_widgetgroup_gizmo2d_xform_poll(const bContext *C, wmGizmoGroupType *UNUS * * Defines public functions, not the gizmo it's self: * - * - #ED_widgetgroup_gizmo2d_resize_setup - * - #ED_widgetgroup_gizmo2d_resize_refresh - * - #ED_widgetgroup_gizmo2d_resize_draw_prepare - * - #ED_widgetgroup_gizmo2d_resize_poll + * - #ED_widgetgroup_gizmo2d_resize_callbacks_set * * \{ */ @@ -472,15 +555,15 @@ static GizmoGroup_Resize2D *gizmogroup2d_resize_init(wmGizmoGroup *gzgroup) return ggd; } -void ED_widgetgroup_gizmo2d_resize_refresh(const bContext *C, wmGizmoGroup *gzgroup) +static void gizmo2d_resize_refresh(const bContext *C, wmGizmoGroup *gzgroup) { GizmoGroup_Resize2D *ggd = gzgroup->customdata; float origin[3]; - gizmo2d_calc_bounds(C, origin, NULL, NULL); + gizmo2d_calc_center(C, origin); copy_v2_v2(ggd->origin, origin); } -void ED_widgetgroup_gizmo2d_resize_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) +static void gizmo2d_resize_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { ARegion *ar = CTX_wm_region(C); GizmoGroup_Resize2D *ggd = gzgroup->customdata; @@ -504,12 +587,12 @@ void ED_widgetgroup_gizmo2d_resize_draw_prepare(const bContext *C, wmGizmoGroup } } -bool ED_widgetgroup_gizmo2d_resize_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) +static bool gizmo2d_resize_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { - return ED_widgetgroup_gizmo2d_xform_poll(C, NULL); + return gizmo2d_xform_poll(C, NULL); } -void ED_widgetgroup_gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) +static void gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { wmOperatorType *ot_resize = WM_operatortype_find("TRANSFORM_OT_resize", true); @@ -566,6 +649,26 @@ void ED_widgetgroup_gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup } } +static void gizmo2d_resize_message_subscribe(const struct bContext *C, + struct wmGizmoGroup *gzgroup, + struct wmMsgBus *mbus) +{ + bScreen *screen = CTX_wm_screen(C); + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + gizmo2d_pivot_point_message_subscribe(gzgroup, mbus, screen, sa, ar); +} + +void ED_widgetgroup_gizmo2d_resize_callbacks_set(wmGizmoGroupType *gzgt) +{ + gzgt->poll = gizmo2d_resize_poll; + gzgt->setup = gizmo2d_resize_setup; + gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag; + gzgt->refresh = gizmo2d_resize_refresh; + gzgt->draw_prepare = gizmo2d_resize_draw_prepare; + gzgt->message_subscribe = gizmo2d_resize_message_subscribe; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -574,9 +677,6 @@ void ED_widgetgroup_gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup * Defines public functions, not the gizmo it's self: * * - #ED_widgetgroup_gizmo2d_rotate_setup - * - #ED_widgetgroup_gizmo2d_rotate_refresh - * - #ED_widgetgroup_gizmo2d_rotate_draw_prepare - * - #ED_widgetgroup_gizmo2d_rotate_poll * * \{ */ @@ -596,15 +696,15 @@ static GizmoGroup_Rotate2D *gizmogroup2d_rotate_init(wmGizmoGroup *gzgroup) return ggd; } -void ED_widgetgroup_gizmo2d_rotate_refresh(const bContext *C, wmGizmoGroup *gzgroup) +static void gizmo2d_rotate_refresh(const bContext *C, wmGizmoGroup *gzgroup) { GizmoGroup_Rotate2D *ggd = gzgroup->customdata; float origin[3]; - gizmo2d_calc_bounds(C, origin, NULL, NULL); + gizmo2d_calc_center(C, origin); copy_v2_v2(ggd->origin, origin); } -void ED_widgetgroup_gizmo2d_rotate_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) +static void gizmo2d_rotate_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { ARegion *ar = CTX_wm_region(C); GizmoGroup_Rotate2D *ggd = gzgroup->customdata; @@ -626,12 +726,12 @@ void ED_widgetgroup_gizmo2d_rotate_draw_prepare(const bContext *C, wmGizmoGroup WM_gizmo_set_matrix_location(gz, origin); } -bool ED_widgetgroup_gizmo2d_rotate_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) +static bool gizmo2d_rotate_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { - return ED_widgetgroup_gizmo2d_xform_poll(C, NULL); + return gizmo2d_xform_poll(C, NULL); } -void ED_widgetgroup_gizmo2d_rotate_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) +static void gizmo2d_rotate_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { wmOperatorType *ot_resize = WM_operatortype_find("TRANSFORM_OT_rotate", true); @@ -663,4 +763,24 @@ void ED_widgetgroup_gizmo2d_rotate_setup(const bContext *UNUSED(C), wmGizmoGroup } } +static void gizmo2d_rotate_message_subscribe(const struct bContext *C, + struct wmGizmoGroup *gzgroup, + struct wmMsgBus *mbus) +{ + bScreen *screen = CTX_wm_screen(C); + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + gizmo2d_pivot_point_message_subscribe(gzgroup, mbus, screen, sa, ar); +} + +void ED_widgetgroup_gizmo2d_rotate_callbacks_set(wmGizmoGroupType *gzgt) +{ + gzgt->poll = gizmo2d_rotate_poll; + gzgt->setup = gizmo2d_rotate_setup; + gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag; + gzgt->refresh = gizmo2d_rotate_refresh; + gzgt->draw_prepare = gizmo2d_rotate_draw_prepare; + gzgt->message_subscribe = gizmo2d_rotate_message_subscribe; +} + /** \} */ -- cgit v1.2.3 From ce5a5b553d382f269e35d12d1ff9f92be8190a34 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 9 Jan 2020 16:58:51 +1100 Subject: Fix multiple UV gizmos being linked at once This happened when reloading the file after using different gizmos. --- source/blender/editors/transform/transform_gizmo_2d.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c index dc8d820b075..84309c541af 100644 --- a/source/blender/editors/transform/transform_gizmo_2d.c +++ b/source/blender/editors/transform/transform_gizmo_2d.c @@ -46,6 +46,7 @@ #include "wm.h" /* XXX */ #include "WM_message.h" +#include "ED_gizmo_utils.h" #include "ED_image.h" #include "ED_screen.h" #include "ED_uvedit.h" @@ -463,8 +464,12 @@ static void gizmo2d_xform_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) * - Called on every redraw, better to do a more simple poll and check for selection in _refresh * - UV editing only, could be expanded for other things. */ -static bool gizmo2d_xform_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) +static bool gizmo2d_xform_poll(const bContext *C, wmGizmoGroupType *gzgt) { + if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) { + return false; + } + if ((U.gizmo_flag & USER_GIZMO_DRAW) == 0) { return false; } @@ -587,9 +592,9 @@ static void gizmo2d_resize_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup } } -static bool gizmo2d_resize_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) +static bool gizmo2d_resize_poll(const bContext *C, wmGizmoGroupType *gzgt) { - return gizmo2d_xform_poll(C, NULL); + return gizmo2d_xform_poll(C, gzgt); } static void gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) @@ -726,9 +731,9 @@ static void gizmo2d_rotate_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup WM_gizmo_set_matrix_location(gz, origin); } -static bool gizmo2d_rotate_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) +static bool gizmo2d_rotate_poll(const bContext *C, wmGizmoGroupType *gzgt) { - return gizmo2d_xform_poll(C, NULL); + return gizmo2d_xform_poll(C, gzgt); } static void gizmo2d_rotate_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) -- cgit v1.2.3 From f681e9ea4988940e0d23ec818f21f3af5e9a7222 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 9 Jan 2020 17:50:52 +1100 Subject: Fix UV gizmos poll failing with multiple objects Only the active objects UV selection was checked. This also avoids checking UV selection for every poll call, now this is only done on refresh. --- .../blender/editors/transform/transform_gizmo_2d.c | 234 +++++++++++---------- 1 file changed, 118 insertions(+), 116 deletions(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c index 84309c541af..793552865a6 100644 --- a/source/blender/editors/transform/transform_gizmo_2d.c +++ b/source/blender/editors/transform/transform_gizmo_2d.c @@ -58,6 +58,30 @@ /** \name Shared Callback's */ +static bool gizmo2d_generic_poll(const bContext *C, wmGizmoGroupType *gzgt) +{ + if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) { + return false; + } + + if ((U.gizmo_flag & USER_GIZMO_DRAW) == 0) { + return false; + } + + ScrArea *sa = CTX_wm_area(C); + switch (sa->spacetype) { + case SPACE_IMAGE: { + SpaceImage *sima = sa->spacedata.first; + Object *obedit = CTX_data_edit_object(C); + if (!ED_space_image_show_uvedit(sima, obedit)) { + return false; + } + } + } + + return true; +} + static void gizmo2d_pivot_point_message_subscribe(struct wmGizmoGroup *gzgroup, struct wmMsgBus *mbus, /* Additional args. */ @@ -180,7 +204,7 @@ static GizmoGroup2D *gizmogroup2d_init(wmGizmoGroup *gzgroup) /** * Calculates origin in view space, use with #gizmo2d_origin_to_region. */ -static void gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min, float *r_max) +static bool gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min, float *r_max) { float min_buf[2], max_buf[2]; if (r_min == NULL) { @@ -191,6 +215,7 @@ static void gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min } ScrArea *sa = CTX_wm_area(C); + bool changed = false; if (sa->spacetype == SPACE_IMAGE) { SpaceImage *sima = sa->spacedata.first; Scene *scene = CTX_data_scene(C); @@ -199,29 +224,33 @@ static void gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min uint objects_len = 0; Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs( view_layer, NULL, &objects_len); - if (!ED_uvedit_minmax_multi(scene, ima, objects, objects_len, r_min, r_max)) { - zero_v2(r_min); - zero_v2(r_max); + if (ED_uvedit_minmax_multi(scene, ima, objects, objects_len, r_min, r_max)) { + changed = true; } MEM_freeN(objects); } - else { + + if (changed == false) { zero_v2(r_min); zero_v2(r_max); } + mid_v2_v2v2(r_center, r_min, r_max); + return changed; } -static void gizmo2d_calc_center(const bContext *C, float r_center[2]) +static bool gizmo2d_calc_center(const bContext *C, float r_center[2]) { ScrArea *sa = CTX_wm_area(C); + bool has_select = false; zero_v2(r_center); if (sa->spacetype == SPACE_IMAGE) { SpaceImage *sima = sa->spacedata.first; Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - ED_uvedit_center_from_pivot(sima, scene, view_layer, r_center, sima->around); + ED_uvedit_center_from_pivot_ex(sima, scene, view_layer, r_center, sima->around, &has_select); } + return has_select; } /** @@ -366,11 +395,12 @@ static void gizmo2d_xform_refresh(const bContext *C, wmGizmoGroup *gzgroup) { GizmoGroup2D *ggd = gzgroup->customdata; float origin[3]; + bool has_select; if (ggd->no_cage) { - gizmo2d_calc_center(C, origin); + has_select = gizmo2d_calc_center(C, origin); } else { - gizmo2d_calc_bounds(C, origin, ggd->min, ggd->max); + has_select = gizmo2d_calc_bounds(C, origin, ggd->min, ggd->max); } copy_v2_v2(ggd->origin, origin); bool show_cage = !ggd->no_cage && !equals_v2v2(ggd->min, ggd->max); @@ -385,58 +415,66 @@ static void gizmo2d_xform_refresh(const bContext *C, wmGizmoGroup *gzgroup) } } - if (show_cage) { - ggd->cage->flag &= ~WM_GIZMO_HIDDEN; + if (has_select == false) { for (int i = 0; i < ARRAY_SIZE(ggd->translate_xy); i++) { - wmGizmo *gz = ggd->translate_xy[i]; - gz->flag |= WM_GIZMO_HIDDEN; + ggd->translate_xy[i]->flag |= WM_GIZMO_HIDDEN; } + ggd->cage->flag |= WM_GIZMO_HIDDEN; } else { - ggd->cage->flag |= WM_GIZMO_HIDDEN; - for (int i = 0; i < ARRAY_SIZE(ggd->translate_xy); i++) { - wmGizmo *gz = ggd->translate_xy[i]; - gz->flag &= ~WM_GIZMO_HIDDEN; + if (show_cage) { + ggd->cage->flag &= ~WM_GIZMO_HIDDEN; + for (int i = 0; i < ARRAY_SIZE(ggd->translate_xy); i++) { + wmGizmo *gz = ggd->translate_xy[i]; + gz->flag |= WM_GIZMO_HIDDEN; + } + } + else { + ggd->cage->flag |= WM_GIZMO_HIDDEN; + for (int i = 0; i < ARRAY_SIZE(ggd->translate_xy); i++) { + wmGizmo *gz = ggd->translate_xy[i]; + gz->flag &= ~WM_GIZMO_HIDDEN; + } } - } - if (show_cage) { - wmGizmoOpElem *gzop; - float mid[2]; - const float *min = ggd->min; - const float *max = ggd->max; - mid_v2_v2v2(mid, min, max); - - gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X); - PropertyRNA *prop_center_override = RNA_struct_find_property(&gzop->ptr, "center_override"); - RNA_property_float_set_array( - &gzop->ptr, prop_center_override, (float[3]){max[0], mid[1], 0.0f}); - gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X); - RNA_property_float_set_array( - &gzop->ptr, prop_center_override, (float[3]){min[0], mid[1], 0.0f}); - gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y); - RNA_property_float_set_array( - &gzop->ptr, prop_center_override, (float[3]){mid[0], max[1], 0.0f}); - gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y); - RNA_property_float_set_array( - &gzop->ptr, prop_center_override, (float[3]){mid[0], min[1], 0.0f}); - - gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y); - RNA_property_float_set_array( - &gzop->ptr, prop_center_override, (float[3]){max[0], max[1], 0.0f}); - gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y); - RNA_property_float_set_array( - &gzop->ptr, prop_center_override, (float[3]){max[0], min[1], 0.0f}); - gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y); - RNA_property_float_set_array( - &gzop->ptr, prop_center_override, (float[3]){min[0], max[1], 0.0f}); - gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y); - RNA_property_float_set_array( - &gzop->ptr, prop_center_override, (float[3]){min[0], min[1], 0.0f}); - - gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_ROTATE); - RNA_property_float_set_array( - &gzop->ptr, prop_center_override, (float[3]){mid[0], mid[1], 0.0f}); + if (show_cage) { + wmGizmoOpElem *gzop; + float mid[2]; + const float *min = ggd->min; + const float *max = ggd->max; + mid_v2_v2v2(mid, min, max); + + gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X); + PropertyRNA *prop_center_override = RNA_struct_find_property(&gzop->ptr, "center_override"); + RNA_property_float_set_array( + &gzop->ptr, prop_center_override, (float[3]){max[0], mid[1], 0.0f}); + gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X); + RNA_property_float_set_array( + &gzop->ptr, prop_center_override, (float[3]){min[0], mid[1], 0.0f}); + gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y); + RNA_property_float_set_array( + &gzop->ptr, prop_center_override, (float[3]){mid[0], max[1], 0.0f}); + gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y); + RNA_property_float_set_array( + &gzop->ptr, prop_center_override, (float[3]){mid[0], min[1], 0.0f}); + + gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y); + RNA_property_float_set_array( + &gzop->ptr, prop_center_override, (float[3]){max[0], max[1], 0.0f}); + gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y); + RNA_property_float_set_array( + &gzop->ptr, prop_center_override, (float[3]){max[0], min[1], 0.0f}); + gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y); + RNA_property_float_set_array( + &gzop->ptr, prop_center_override, (float[3]){min[0], max[1], 0.0f}); + gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y); + RNA_property_float_set_array( + &gzop->ptr, prop_center_override, (float[3]){min[0], min[1], 0.0f}); + + gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_ROTATE); + RNA_property_float_set_array( + &gzop->ptr, prop_center_override, (float[3]){mid[0], mid[1], 0.0f}); + } } } @@ -460,50 +498,6 @@ static void gizmo2d_xform_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) ggd->cage->matrix_offset[1][1] = (ggd->max[1] - ggd->min[1]); } -/* TODO (Julian) - * - Called on every redraw, better to do a more simple poll and check for selection in _refresh - * - UV editing only, could be expanded for other things. - */ -static bool gizmo2d_xform_poll(const bContext *C, wmGizmoGroupType *gzgt) -{ - if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) { - return false; - } - - if ((U.gizmo_flag & USER_GIZMO_DRAW) == 0) { - return false; - } - - SpaceImage *sima = CTX_wm_space_image(C); - Object *obedit = CTX_data_edit_object(C); - - if (ED_space_image_show_uvedit(sima, obedit)) { - Image *ima = ED_space_image(sima); - Scene *scene = CTX_data_scene(C); - BMEditMesh *em = BKE_editmesh_from_object(obedit); - BMFace *efa; - BMLoop *l; - BMIter iter, liter; - - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - - /* check if there's a selected poly */ - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, obedit, ima, efa)) { - continue; - } - - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - return true; - } - } - } - } - - return false; -} - static void gizmo2d_xform_no_cage_message_subscribe(const struct bContext *C, struct wmGizmoGroup *gzgroup, struct wmMsgBus *mbus) @@ -516,7 +510,7 @@ static void gizmo2d_xform_no_cage_message_subscribe(const struct bContext *C, void ED_widgetgroup_gizmo2d_xform_callbacks_set(wmGizmoGroupType *gzgt) { - gzgt->poll = gizmo2d_xform_poll; + gzgt->poll = gizmo2d_generic_poll; gzgt->setup = gizmo2d_xform_setup; gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag; gzgt->refresh = gizmo2d_xform_refresh; @@ -564,8 +558,19 @@ static void gizmo2d_resize_refresh(const bContext *C, wmGizmoGroup *gzgroup) { GizmoGroup_Resize2D *ggd = gzgroup->customdata; float origin[3]; - gizmo2d_calc_center(C, origin); - copy_v2_v2(ggd->origin, origin); + const bool has_select = gizmo2d_calc_center(C, origin); + + if (has_select == false) { + for (int i = 0; i < ARRAY_SIZE(ggd->gizmo_xy); i++) { + ggd->gizmo_xy[i]->flag |= WM_GIZMO_HIDDEN; + } + } + else { + for (int i = 0; i < ARRAY_SIZE(ggd->gizmo_xy); i++) { + ggd->gizmo_xy[i]->flag &= ~WM_GIZMO_HIDDEN; + } + copy_v2_v2(ggd->origin, origin); + } } static void gizmo2d_resize_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) @@ -592,11 +597,6 @@ static void gizmo2d_resize_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup } } -static bool gizmo2d_resize_poll(const bContext *C, wmGizmoGroupType *gzgt) -{ - return gizmo2d_xform_poll(C, gzgt); -} - static void gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { @@ -666,7 +666,7 @@ static void gizmo2d_resize_message_subscribe(const struct bContext *C, void ED_widgetgroup_gizmo2d_resize_callbacks_set(wmGizmoGroupType *gzgt) { - gzgt->poll = gizmo2d_resize_poll; + gzgt->poll = gizmo2d_generic_poll; gzgt->setup = gizmo2d_resize_setup; gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag; gzgt->refresh = gizmo2d_resize_refresh; @@ -705,8 +705,15 @@ static void gizmo2d_rotate_refresh(const bContext *C, wmGizmoGroup *gzgroup) { GizmoGroup_Rotate2D *ggd = gzgroup->customdata; float origin[3]; - gizmo2d_calc_center(C, origin); - copy_v2_v2(ggd->origin, origin); + const bool has_select = gizmo2d_calc_center(C, origin); + + if (has_select == false) { + ggd->gizmo->flag |= WM_GIZMO_HIDDEN; + } + else { + ggd->gizmo->flag &= ~WM_GIZMO_HIDDEN; + copy_v2_v2(ggd->origin, origin); + } } static void gizmo2d_rotate_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) @@ -731,11 +738,6 @@ static void gizmo2d_rotate_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup WM_gizmo_set_matrix_location(gz, origin); } -static bool gizmo2d_rotate_poll(const bContext *C, wmGizmoGroupType *gzgt) -{ - return gizmo2d_xform_poll(C, gzgt); -} - static void gizmo2d_rotate_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { @@ -780,7 +782,7 @@ static void gizmo2d_rotate_message_subscribe(const struct bContext *C, void ED_widgetgroup_gizmo2d_rotate_callbacks_set(wmGizmoGroupType *gzgt) { - gzgt->poll = gizmo2d_rotate_poll; + gzgt->poll = gizmo2d_generic_poll; gzgt->setup = gizmo2d_rotate_setup; gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag; gzgt->refresh = gizmo2d_rotate_refresh; -- cgit v1.2.3 From 389fc62f6c4e039902c94c3da36fd24a351c8a8d Mon Sep 17 00:00:00 2001 From: mano-wii Date: Mon, 13 Jan 2020 13:47:05 -0300 Subject: Fix T72094: Multiple snap targets don't work when Increment is enabled The `poll_modal_item` was too restrictive. `!validSnap(t)` already solves these cases, but for better readability (and efficiency), I found it best to keep the `tsnap.mode` test. --- source/blender/editors/transform/transform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 9a98a2b8a00..62a61a3a05a 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -856,7 +856,7 @@ static bool transform_modal_item_poll(const wmOperator *op, int value) if (t->spacetype != SPACE_VIEW3D) { return false; } - else if (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) { + else if ((t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) == 0) { return false; } else if (!validSnap(t)) { -- cgit v1.2.3 From 003be8aa7c6d837d43bdadb99f60cd5f6dca72bd Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Thu, 16 Jan 2020 12:08:17 +0100 Subject: UI: Use same precision in "Move" redo panel as elsewhere The floating "Move" redo panel showed transform values with less precision than in other places (e.g. sidebar and properties editor). With Millimeters as unit it would even round to full integers, which may be an issue since you typically work at higher precisions with this unit. Note that this only applies to the visual precision, internally we use full floating point `float`s still. Fixes T70367. --- source/blender/editors/transform/transform_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index b2d8671fbce..09992e8be0e 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -720,7 +720,7 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot) ot->poll = ED_operator_screenactive; ot->poll_property = transform_poll_property; - RNA_def_float_vector_xyz( + RNA_def_float_translation( ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Move", "", -FLT_MAX, FLT_MAX); WM_operatortype_props_advanced_begin(ot); -- cgit v1.2.3 From 9a6551543b92d54e7d565570988271e461104a89 Mon Sep 17 00:00:00 2001 From: mano-wii Date: Thu, 16 Jan 2020 09:14:27 -0300 Subject: Fix crash with Proportional Edit Connected in UV editing Caused by rB86a2ffc3ab32 --- .../editors/transform/transform_convert_mesh.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c index 006f913f218..5d3d1d936a2 100644 --- a/source/blender/editors/transform/transform_convert_mesh.c +++ b/source/blender/editors/transform/transform_convert_mesh.c @@ -1451,7 +1451,8 @@ void createTransUVs(bContext *C, TransInfo *t) if (is_prop_connected || is_island_center) { /* create element map with island information */ const bool use_facesel = (ts->uv_flag & UV_SYNC_SELECTION) == 0; - elementmap = BM_uv_element_map_create(em->bm, scene, use_facesel, true, false, true); + const bool use_uvsel = !is_prop_connected; + elementmap = BM_uv_element_map_create(em->bm, scene, use_facesel, use_uvsel, false, true); if (elementmap == NULL) { continue; } @@ -1547,16 +1548,17 @@ void createTransUVs(bContext *C, TransInfo *t) if (is_prop_connected || is_island_center) { UvElement *element = BM_uv_element_get(elementmap, efa, l); - - if (is_prop_connected) { - if (!BLI_BITMAP_TEST(island_enabled, element->island)) { - count_rejected++; - continue; + if (element) { + if (is_prop_connected) { + if (!BLI_BITMAP_TEST(island_enabled, element->island)) { + count_rejected++; + continue; + } } - } - if (is_island_center) { - center = island_center[element->island].co; + if (is_island_center) { + center = island_center[element->island].co; + } } } -- cgit v1.2.3 From c22d2f9e015a66951b96104dca51d40d40eed1ce Mon Sep 17 00:00:00 2001 From: mano-wii Date: Fri, 17 Jan 2020 09:17:36 -0300 Subject: Fix T73159: Crash transforming 0 edited grease objects --- source/blender/editors/transform/transform_convert_gpencil.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform_convert_gpencil.c b/source/blender/editors/transform/transform_convert_gpencil.c index 234e383be5f..80c0afc3f56 100644 --- a/source/blender/editors/transform/transform_convert_gpencil.c +++ b/source/blender/editors/transform/transform_convert_gpencil.c @@ -63,6 +63,10 @@ static void createTransGPencil_center_get(bGPDstroke *gps, float r_center[3]) void createTransGPencil(bContext *C, TransInfo *t) { + if (t->data_container_len == 0) { + return; + } + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); bGPdata *gpd = ED_gpencil_data_get_active(C); ToolSettings *ts = CTX_data_tool_settings(C); -- cgit v1.2.3 From 2bd62ca7eb2cbfae504a0c4d9120c5c7ed916ce9 Mon Sep 17 00:00:00 2001 From: mano-wii Date: Fri, 24 Jan 2020 10:06:27 -0300 Subject: Fix T73349: X-Ray Mode - snapping through object stop working on value = 1 --- source/blender/editors/transform/transform_snap_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 4fe2ae5321b..63b9eb3937a 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -833,7 +833,7 @@ static bool raycastObj(SnapObjectContext *sctx, { bool retval = false; if (use_occlusion_test) { - if (use_obedit && sctx->use_v3d && XRAY_ENABLED(sctx->v3d_data.v3d)) { + if (use_obedit && sctx->use_v3d && XRAY_FLAG_ENABLED(sctx->v3d_data.v3d)) { /* Use of occlude geometry in editing mode disabled. */ return false; } -- cgit v1.2.3 From 497be89f28c112c173dea9a75a43bdceba7b7cea Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 25 Jan 2020 17:08:25 +1100 Subject: Cleanup: remove source file added by accident --- source/blender/editors/transform/transform_draw.c | 114 ---------------------- 1 file changed, 114 deletions(-) delete mode 100644 source/blender/editors/transform/transform_draw.c (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform_draw.c b/source/blender/editors/transform/transform_draw.c deleted file mode 100644 index e44442b7e49..00000000000 --- a/source/blender/editors/transform/transform_draw.c +++ /dev/null @@ -1,114 +0,0 @@ - -/* -------------------------------------------------------------------- */ -/** \name Auto-Key (Pixel Space) - * \{ */ - -/* just draw a little warning message in the top-right corner of the viewport - * to warn that autokeying is enabled */ -static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar) -{ - const char *printable = IFACE_("Auto Keying On"); - float printable_size[2]; - int xco, yco; - - const rcti *rect = ED_region_visible_rect(ar); - - const int font_id = BLF_default(); - BLF_width_and_height( - font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]); - - xco = (rect->xmax - U.widget_unit) - (int)printable_size[0]; - yco = (rect->ymax - U.widget_unit); - - /* warning text (to clarify meaning of overlays) - * - original color was red to match the icon, but that clashes badly with a less nasty border - */ - unsigned char color[3]; - UI_GetThemeColorShade3ubv(TH_TEXT_HI, -50, color); - BLF_color3ubv(font_id, color); -#ifdef WITH_INTERNATIONAL - BLF_draw_default(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX); -#else - BLF_draw_default_ascii(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX); -#endif - - /* autokey recording icon... */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); - - xco -= U.widget_unit; - yco -= (int)printable_size[1] / 2; - - UI_icon_draw(xco, yco, ICON_REC); - - GPU_blend(false); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Constraints (View Space) - * \{ */ - -/* called from drawview.c, as an extra per-window draw option */ -void drawPropCircle(const struct bContext *C, TransInfo *t) -{ - if (t->flag & T_PROP_EDIT) { - RegionView3D *rv3d = CTX_wm_region_view3d(C); - float tmat[4][4], imat[4][4]; - int depth_test_enabled; - - if (t->spacetype == SPACE_VIEW3D && rv3d != NULL) { - copy_m4_m4(tmat, rv3d->viewmat); - invert_m4_m4(imat, tmat); - } - else { - unit_m4(tmat); - unit_m4(imat); - } - - GPU_matrix_push(); - - if (t->spacetype == SPACE_VIEW3D) { - /* pass */ - } - else if (t->spacetype == SPACE_IMAGE) { - GPU_matrix_scale_2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]); - } - else if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_ACTION)) { - /* only scale y */ - rcti *mask = &t->ar->v2d.mask; - rctf *datamask = &t->ar->v2d.cur; - float xsize = BLI_rctf_size_x(datamask); - float ysize = BLI_rctf_size_y(datamask); - float xmask = BLI_rcti_size_x(mask); - float ymask = BLI_rcti_size_y(mask); - GPU_matrix_scale_2f(1.0f, (ysize / xsize) * (xmask / ymask)); - } - - depth_test_enabled = GPU_depth_test_enabled(); - if (depth_test_enabled) { - GPU_depth_test(false); - } - - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(TH_GRID); - - GPU_logic_op_invert_set(true); - imm_drawcircball(t->center_global, t->prop_size, imat, pos); - GPU_logic_op_invert_set(false); - - immUnbindProgram(); - - if (depth_test_enabled) { - GPU_depth_test(true); - } - - GPU_matrix_pop(); - } -} - -/** \} */ -- cgit v1.2.3 From 67a60504990a6203304527a8bdb3a09041ca28d0 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Tue, 28 Jan 2020 11:54:27 +0100 Subject: Fix T55622: Proportional editing for Gpencil/Masks in dope sheet not taking proportional size into account Transform would always move all keyframes (e.g even when Proportional size is 0.0). 'calculatePropRatio()' was setting td->factor correctly, but this was not being considered in 'applyTimeTranslateValue()' if there was no action [which greasepencil and masks do not have]. Maniphest Tasks: T55622 Differential Revision: https://developer.blender.org/D6697 --- source/blender/editors/transform/transform.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 9a98a2b8a00..31ecf4f0c88 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -8777,9 +8777,10 @@ static void applyTimeTranslateValue(TransInfo *t, float value) /* It doesn't matter whether we apply to t->data or * t->data2d, but t->data2d is more convenient. */ for (i = 0; i < tc->data_len; i++, td++, td2d++) { - /* it is assumed that td->extra is a pointer to the AnimData, - * whose active action is where this keyframe comes from + /* It is assumed that td->extra is a pointer to the AnimData, + * whose active action is where this keyframe comes from. * (this is only valid when not in NLA) + * (also: masks and gpencil dont have animadata) */ AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL; @@ -8810,7 +8811,7 @@ static void applyTimeTranslateValue(TransInfo *t, float value) val = floorf(val + 0.5f); } - *(td->val) = td->ival + val; + *(td->val) = td->ival + val * td->factor; } /* apply nearest snapping */ -- cgit v1.2.3 From aa123555d7a75c784f479b9572145f45862bcb2b Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Fri, 10 Jan 2020 13:33:25 +0100 Subject: Fix T73014: Marker sync does not work correctly if moving strip so it overlaps another strip Need to also offset markers in BKE_sequence_base_shuffle_time(). Also clarify/correct related comments. Maniphest Tasks: T73014 Differential Revision: https://developer.blender.org/D6555 --- source/blender/editors/transform/transform.c | 2 +- source/blender/editors/transform/transform_convert.c | 4 ++-- source/blender/editors/transform/transform_convert_sequencer.c | 10 +++++++--- 3 files changed, 10 insertions(+), 6 deletions(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 31ecf4f0c88..441a6eb0ea5 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2561,7 +2561,7 @@ int transformEnd(bContext *C, TransInfo *t) /* aftertrans does insert keyframes, and clears base flags; doesn't read transdata */ special_aftertrans_update(C, t); - /* free data */ + /* Free data, also handles overlap [in freeTransCustomData()]. */ postTrans(C, t); /* send events out for redraws */ diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c index a214eb1c80b..869c23de74c 100644 --- a/source/blender/editors/transform/transform_convert.c +++ b/source/blender/editors/transform/transform_convert.c @@ -1892,8 +1892,8 @@ void special_aftertrans_update(bContext *C, TransInfo *t) SpaceSeq *sseq = (SpaceSeq *)t->sa->spacedata.first; - /* marker transform, not especially nice but we may want to move markers - * at the same time as keyframes in the dope sheet. */ + /* Marker transform, not especially nice but we may want to move markers + * at the same time as strips in the Video Sequencer. */ if ((sseq->flag & SEQ_MARKER_TRANS) && (canceled == 0)) { /* cant use TFM_TIME_EXTEND * for some reason EXTEND is changed into TRANSLATE, so use frame_side instead */ diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c index 86b6ebe3ffa..4baf0e8a3cb 100644 --- a/source/blender/editors/transform/transform_convert_sequencer.c +++ b/source/blender/editors/transform/transform_convert_sequencer.c @@ -381,6 +381,10 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c } if (overlap) { + const bool use_sync_markers = (((SpaceSeq *)t->sa->spacedata.first)->flag & + SEQ_MARKER_TRANS) != 0; + ListBase *markers = &t->scene->markers; + bool has_effect_root = false, has_effect_any = false; for (seq = seqbasep->first; seq; seq = seq->next) { seq->tmp = NULL; @@ -425,7 +429,7 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c } } - BKE_sequence_base_shuffle_time(seqbasep, t->scene); + BKE_sequence_base_shuffle_time(seqbasep, t->scene, markers, use_sync_markers); for (seq = seqbasep->first; seq; seq = seq->next) { if (seq->machine >= MAXSEQ * 2) { @@ -437,10 +441,10 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c } } - BKE_sequence_base_shuffle_time(seqbasep, t->scene); + BKE_sequence_base_shuffle_time(seqbasep, t->scene, markers, use_sync_markers); } else { - BKE_sequence_base_shuffle_time(seqbasep, t->scene); + BKE_sequence_base_shuffle_time(seqbasep, t->scene, markers, use_sync_markers); } if (has_effect_any) { -- cgit v1.2.3