diff options
4 files changed, 165 insertions, 100 deletions
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index d8843d4fbce..b03efce87c4 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -59,6 +59,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): (("transform.rotate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),)), ("Scale", None, (("transform.resize", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),)), + ("Scale Cage", "VIEW3D_WGT_xform_cage", None), ) _tools = { diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index c6702ae3eaf..8fd0c8c68a8 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -159,6 +159,7 @@ void Transform_Properties(struct wmOperatorType *ot, int flags); /* transform manipulators */ void TRANSFORM_WGT_manipulator(struct wmManipulatorGroupType *wgt); +void VIEW3D_WGT_xform_cage(struct wmManipulatorGroupType *wgt); bool ED_widgetgroup_manipulator2d_poll(const struct bContext *C, struct wmManipulatorGroupType *wgt); void ED_widgetgroup_manipulator2d_setup(const struct bContext *C, struct wmManipulatorGroup *mgroup); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 2267c12f100..6ca4db2e056 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -743,6 +743,8 @@ static void view3d_widgets(void) WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_camera_view); WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_empty_image); WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_armature_spline); + + WM_manipulatorgrouptype_append(VIEW3D_WGT_xform_cage); } diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 680e5597197..0eae89266ef 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -87,7 +87,6 @@ #include "GPU_matrix.h" #define USE_AXIS_BOUNDS -#define USE_CAGE3D /* return codes for select, and drawing flags */ @@ -156,10 +155,6 @@ typedef struct ManipulatorGroup { bool all_hidden; struct wmManipulator *manipulators[MAN_AXIS_LAST]; - -#ifdef USE_CAGE3D - struct wmManipulator *cage; -#endif } ManipulatorGroup; struct TransformBounds { @@ -173,7 +168,9 @@ struct TransformBounds { #endif }; -/* **************** Utilities **************** */ +/* -------------------------------------------------------------------- */ +/** \name Utilities + * \{ */ /* loop over axes */ #define MAN_ITER_AXES_BEGIN(axis, axis_idx) \ @@ -1107,7 +1104,12 @@ static void manipulator_line_range(const View3D *v3d, const short axis_type, flo *r_len -= *r_start; } -/* **************** Actual Widget Stuff **************** */ +/** \} */ + + +/* -------------------------------------------------------------------- */ +/** \name Transform Manipulator + * \{ */ static ManipulatorGroup *manipulatorgroup_init(wmManipulatorGroup *mgroup) { @@ -1162,17 +1164,6 @@ static ManipulatorGroup *manipulatorgroup_init(wmManipulatorGroup *mgroup) MANIPULATOR_NEW_PRIM(MAN_AXIS_TRANS_YZ, ED_MANIPULATOR_PRIMITIVE_STYLE_PLANE); MANIPULATOR_NEW_PRIM(MAN_AXIS_TRANS_ZX, ED_MANIPULATOR_PRIMITIVE_STYLE_PLANE); -#ifdef USE_CAGE3D - { - const wmManipulatorType *wt_cage = WM_manipulatortype_find("MANIPULATOR_WT_cage_3d", true); - man->cage = WM_manipulator_new_ptr(wt_cage, mgroup, NULL); - - RNA_enum_set(man->cage->ptr, "transform", - ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE | - ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE); - } -#endif - return man; } @@ -1314,34 +1305,6 @@ static void WIDGETGROUP_manipulator_setup(const bContext *UNUSED(C), wmManipulat RNA_boolean_set(ptr, "release_confirm", 1); } MAN_ITER_AXES_END; - -#ifdef USE_CAGE3D - { - wmOperatorType *ot_resize = WM_operatortype_find("TRANSFORM_OT_resize", true); - PointerRNA *ptr; - - /* assign operator */ - PropertyRNA *prop_release_confirm = NULL; - PropertyRNA *prop_constraint_axis = NULL; - - int i = ED_MANIPULATOR_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z; - for (int x = 0; x < 3; x++) { - for (int y = 0; y < 3; y++) { - for (int z = 0; z < 3; z++) { - int constraint[3] = {x != 1, y != 1, z != 1}; - ptr = WM_manipulator_operator_set(man->cage, i, ot_resize, NULL); - if (prop_release_confirm == NULL) { - prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm"); - prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis"); - } - RNA_property_boolean_set(ptr, prop_release_confirm, true); - RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint); - i++; - } - } - } - } -#endif } static void WIDGETGROUP_manipulator_refresh(const bContext *C, wmManipulatorGroup *mgroup) @@ -1407,47 +1370,6 @@ static void WIDGETGROUP_manipulator_refresh(const bContext *C, wmManipulatorGrou } } MAN_ITER_AXES_END; - -#ifdef USE_CAGE3D - if (((v3d->twtype & V3D_MANIP_SCALE) == 0) || - equals_v3v3(rv3d->tw_axis_min, rv3d->tw_axis_max)) - { - WM_manipulator_set_flag(man->cage, WM_MANIPULATOR_HIDDEN, true); - } - else { - WM_manipulator_set_flag(man->cage, WM_MANIPULATOR_HIDDEN, false); - - float dims[3]; - sub_v3_v3v3(dims, rv3d->tw_axis_max, rv3d->tw_axis_min); - RNA_float_set_array(man->cage->ptr, "dimensions", dims); - mul_v3_fl(dims, 0.5f); - - copy_m4_m3(man->cage->matrix_offset, rv3d->tw_axis_matrix); - mid_v3_v3v3(man->cage->matrix_offset[3], rv3d->tw_axis_max, rv3d->tw_axis_min); - mul_m3_v3(rv3d->tw_axis_matrix, man->cage->matrix_offset[3]); - - PropertyRNA *prop_center_override = NULL; - float center[3]; - float center_global[3]; - int i = ED_MANIPULATOR_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z; - for (int x = 0; x < 3; x++) { - center[0] = (float)(1 - x) * dims[0]; - for (int y = 0; y < 3; y++) { - center[1] = (float)(1 - y) * dims[1]; - for (int z = 0; z < 3; z++) { - center[2] = (float)(1 - z) * dims[2]; - struct wmManipulatorOpElem *mpop = WM_manipulator_operator_get(man->cage, i); - if (prop_center_override == NULL) { - prop_center_override = RNA_struct_find_property(&mpop->ptr, "center_override"); - } - mul_v3_m4v3(center_global, man->cage->matrix_offset, center); - RNA_property_float_set_array(&mpop->ptr, prop_center_override, center_global); - i++; - } - } - } - } -#endif } static void WIDGETGROUP_manipulator_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup) @@ -1500,19 +1422,6 @@ static void WIDGETGROUP_manipulator_draw_prepare(const bContext *C, wmManipulato } } MAN_ITER_AXES_END; - -#ifdef USE_CAGE3D - { - SceneLayer *sl = CTX_data_scene_layer(C); - Object *ob = OBACT_NEW(sl); - if (ob && ob->mode & OB_MODE_EDIT) { - copy_m4_m4(man->cage->matrix_space, ob->obmat); - } - else { - unit_m4(man->cage->matrix_space); - } - } -#endif } static bool WIDGETGROUP_manipulator_poll(const struct bContext *C, struct wmManipulatorGroupType *UNUSED(wgt)) @@ -1538,3 +1447,155 @@ void TRANSFORM_WGT_manipulator(wmManipulatorGroupType *wgt) wgt->refresh = WIDGETGROUP_manipulator_refresh; wgt->draw_prepare = WIDGETGROUP_manipulator_draw_prepare; } + +/** \} */ + + +/* -------------------------------------------------------------------- */ +/** \name Scale Cage Manipulator + * \{ */ + +struct XFormCageWidgetGroup { + wmManipulator *manipulator; +}; + +static bool WIDGETGROUP_xform_cage_poll(const bContext *C, wmManipulatorGroupType *wgt) +{ + WorkSpace *workspace = CTX_wm_workspace(C); + if (!STREQ(wgt->idname, workspace->tool.manipulator_group)) { + WM_manipulator_group_type_remove_ptr_delayed(wgt); + return false; + } + return true; +} + +static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup) +{ + struct XFormCageWidgetGroup *xmgroup = MEM_mallocN(sizeof(struct XFormCageWidgetGroup), __func__); + const wmManipulatorType *wt_cage = WM_manipulatortype_find("MANIPULATOR_WT_cage_3d", true); + xmgroup->manipulator = WM_manipulator_new_ptr(wt_cage, mgroup, NULL); + wmManipulator *mpr = xmgroup->manipulator; + + RNA_enum_set(mpr->ptr, "transform", + ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE | + ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE); + + mpr->color[0] = 1; + mpr->color_hi[0]=1; + + mgroup->customdata = xmgroup; + + { + wmOperatorType *ot_resize = WM_operatortype_find("TRANSFORM_OT_resize", true); + PointerRNA *ptr; + + /* assign operator */ + PropertyRNA *prop_release_confirm = NULL; + PropertyRNA *prop_constraint_axis = NULL; + + int i = ED_MANIPULATOR_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z; + for (int x = 0; x < 3; x++) { + for (int y = 0; y < 3; y++) { + for (int z = 0; z < 3; z++) { + int constraint[3] = {x != 1, y != 1, z != 1}; + ptr = WM_manipulator_operator_set(mpr, i, ot_resize, NULL); + if (prop_release_confirm == NULL) { + prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm"); + prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis"); + } + RNA_property_boolean_set(ptr, prop_release_confirm, true); + RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint); + i++; + } + } + } + } +} + +static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmManipulatorGroup *mgroup) +{ + ScrArea *sa = CTX_wm_area(C); + View3D *v3d = sa->spacedata.first; + ARegion *ar = CTX_wm_region(C); + RegionView3D *rv3d = ar->regiondata; + + struct XFormCageWidgetGroup *xmgroup = mgroup->customdata; + wmManipulator *mpr = xmgroup->manipulator; + + struct TransformBounds tbounds; + + if ((calc_manipulator_stats(C, &tbounds) == 0) || + equals_v3v3(rv3d->tw_axis_min, rv3d->tw_axis_max)) + { + WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, true); + } + else { + manipulator_prepare_mat(C, v3d, rv3d, &tbounds); + + WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, false); + + float dims[3]; + sub_v3_v3v3(dims, rv3d->tw_axis_max, rv3d->tw_axis_min); + RNA_float_set_array(mpr->ptr, "dimensions", dims); + mul_v3_fl(dims, 0.5f); + + copy_m4_m3(mpr->matrix_offset, rv3d->tw_axis_matrix); + mid_v3_v3v3(mpr->matrix_offset[3], rv3d->tw_axis_max, rv3d->tw_axis_min); + mul_m3_v3(rv3d->tw_axis_matrix, mpr->matrix_offset[3]); + + PropertyRNA *prop_center_override = NULL; + float center[3]; + float center_global[3]; + int i = ED_MANIPULATOR_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z; + for (int x = 0; x < 3; x++) { + center[0] = (float)(1 - x) * dims[0]; + for (int y = 0; y < 3; y++) { + center[1] = (float)(1 - y) * dims[1]; + for (int z = 0; z < 3; z++) { + center[2] = (float)(1 - z) * dims[2]; + struct wmManipulatorOpElem *mpop = WM_manipulator_operator_get(mpr, i); + if (prop_center_override == NULL) { + prop_center_override = RNA_struct_find_property(&mpop->ptr, "center_override"); + } + mul_v3_m4v3(center_global, mpr->matrix_offset, center); + RNA_property_float_set_array(&mpop->ptr, prop_center_override, center_global); + i++; + } + } + } + } +} + +static void WIDGETGROUP_xform_cage_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup) +{ + struct XFormCageWidgetGroup *xmgroup = mgroup->customdata; + wmManipulator *mpr = xmgroup->manipulator; + + SceneLayer *sl = CTX_data_scene_layer(C); + Object *ob = OBACT_NEW(sl); + if (ob && ob->mode & OB_MODE_EDIT) { + copy_m4_m4(mpr->matrix_space, ob->obmat); + } + else { + unit_m4(mpr->matrix_space); + } +} + +void VIEW3D_WGT_xform_cage(wmManipulatorGroupType *wgt) +{ + wgt->name = "Transform Cage"; + wgt->idname = "VIEW3D_WGT_xform_cage"; + + wgt->flag |= (WM_MANIPULATORGROUPTYPE_3D | + WM_MANIPULATORGROUPTYPE_DEPTH_3D); + + wgt->mmap_params.spaceid = SPACE_VIEW3D; + wgt->mmap_params.regionid = RGN_TYPE_WINDOW; + + wgt->poll = WIDGETGROUP_xform_cage_poll; + wgt->setup = WIDGETGROUP_xform_cage_setup; + wgt->refresh = WIDGETGROUP_xform_cage_refresh; + wgt->draw_prepare = WIDGETGROUP_xform_cage_draw_prepare; +} + +/** \} */ |