diff options
Diffstat (limited to 'source/blender/editors/transform/transform_generics.c')
-rw-r--r-- | source/blender/editors/transform/transform_generics.c | 1146 |
1 files changed, 656 insertions, 490 deletions
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 477e1abf80f..053647cbfea 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -58,12 +58,14 @@ #include "BLI_rand.h" #include "BLI_utildefines.h" +#include "PIL_time.h" + #include "BLT_translation.h" #include "RNA_access.h" -#include "BIF_gl.h" -#include "BIF_glutil.h" +#include "GPU_immediate.h" +#include "GPU_matrix.h" #include "BIK_api.h" @@ -71,7 +73,6 @@ #include "BKE_action.h" #include "BKE_armature.h" #include "BKE_curve.h" -#include "BKE_depsgraph.h" #include "BKE_fcurve.h" #include "BKE_lattice.h" #include "BKE_library.h" @@ -83,6 +84,11 @@ #include "BKE_editmesh.h" #include "BKE_tracking.h" #include "BKE_mask.h" +#include "BKE_workspace.h" +#include "BKE_layer.h" +#include "BKE_scene.h" + +#include "DEG_depsgraph.h" #include "ED_anim_api.h" #include "ED_armature.h" @@ -103,6 +109,8 @@ #include "WM_types.h" #include "WM_api.h" +#include "RE_engine.h" + #include "UI_resources.h" #include "UI_view2d.h" @@ -124,98 +132,101 @@ void getViewVector(const TransInfo *t, const float coord[3], float vec[3]) /* ************************** GENERICS **************************** */ -static void clipMirrorModifier(TransInfo *t, Object *ob) +static void clipMirrorModifier(TransInfo *t) { - ModifierData *md = ob->modifiers.first; - float tolerance[3] = {0.0f, 0.0f, 0.0f}; - int axis = 0; - - for (; md; md = md->next) { - if ((md->type == eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) { - MirrorModifierData *mmd = (MirrorModifierData *) md; - - if (mmd->flag & MOD_MIR_CLIPPING) { - axis = 0; - if (mmd->flag & MOD_MIR_AXIS_X) { - axis |= 1; - tolerance[0] = mmd->tolerance; - } - if (mmd->flag & MOD_MIR_AXIS_Y) { - axis |= 2; - tolerance[1] = mmd->tolerance; - } - if (mmd->flag & MOD_MIR_AXIS_Z) { - axis |= 4; - tolerance[2] = mmd->tolerance; - } - if (axis) { - float mtx[4][4], imtx[4][4]; - int i; - TransData *td = t->data; + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + Object *ob = tc->obedit; + ModifierData *md = ob->modifiers.first; + float tolerance[3] = {0.0f, 0.0f, 0.0f}; + int axis = 0; + + for (; md; md = md->next) { + if ((md->type == eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) { + MirrorModifierData *mmd = (MirrorModifierData *) md; + + if (mmd->flag & MOD_MIR_CLIPPING) { + axis = 0; + if (mmd->flag & MOD_MIR_AXIS_X) { + axis |= 1; + tolerance[0] = mmd->tolerance; + } + if (mmd->flag & MOD_MIR_AXIS_Y) { + axis |= 2; + tolerance[1] = mmd->tolerance; + } + if (mmd->flag & MOD_MIR_AXIS_Z) { + axis |= 4; + tolerance[2] = mmd->tolerance; + } + if (axis) { + float mtx[4][4], imtx[4][4]; + int i; - if (mmd->mirror_ob) { - float obinv[4][4]; + if (mmd->mirror_ob) { + float obinv[4][4]; - invert_m4_m4(obinv, mmd->mirror_ob->obmat); - mul_m4_m4m4(mtx, obinv, ob->obmat); - invert_m4_m4(imtx, mtx); - } + invert_m4_m4(obinv, mmd->mirror_ob->obmat); + mul_m4_m4m4(mtx, obinv, ob->obmat); + invert_m4_m4(imtx, mtx); + } - for (i = 0; i < t->total; i++, td++) { - int clip; - float loc[3], iloc[3]; + TransData *td = tc->data; + for (i = 0; i < tc->data_len; i++, td++) { + int clip; + float loc[3], iloc[3]; - if (td->flag & TD_NOACTION) - break; - if (td->loc == NULL) - break; + if (td->flag & TD_NOACTION) + break; + if (td->loc == NULL) + break; - if (td->flag & TD_SKIP) - continue; + if (td->flag & TD_SKIP) + continue; - copy_v3_v3(loc, td->loc); - copy_v3_v3(iloc, td->iloc); + copy_v3_v3(loc, td->loc); + copy_v3_v3(iloc, td->iloc); - if (mmd->mirror_ob) { - mul_m4_v3(mtx, loc); - mul_m4_v3(mtx, iloc); - } + if (mmd->mirror_ob) { + mul_m4_v3(mtx, loc); + mul_m4_v3(mtx, iloc); + } - clip = 0; - if (axis & 1) { - if (fabsf(iloc[0]) <= tolerance[0] || - loc[0] * iloc[0] < 0.0f) - { - loc[0] = 0.0f; - clip = 1; + clip = 0; + if (axis & 1) { + if (fabsf(iloc[0]) <= tolerance[0] || + loc[0] * iloc[0] < 0.0f) + { + loc[0] = 0.0f; + clip = 1; + } } - } - if (axis & 2) { - if (fabsf(iloc[1]) <= tolerance[1] || - loc[1] * iloc[1] < 0.0f) - { - loc[1] = 0.0f; - clip = 1; + if (axis & 2) { + if (fabsf(iloc[1]) <= tolerance[1] || + loc[1] * iloc[1] < 0.0f) + { + loc[1] = 0.0f; + clip = 1; + } } - } - if (axis & 4) { - if (fabsf(iloc[2]) <= tolerance[2] || - loc[2] * iloc[2] < 0.0f) - { - loc[2] = 0.0f; - clip = 1; + if (axis & 4) { + if (fabsf(iloc[2]) <= tolerance[2] || + loc[2] * iloc[2] < 0.0f) + { + loc[2] = 0.0f; + clip = 1; + } } - } - if (clip) { - if (mmd->mirror_ob) { - mul_m4_v3(imtx, loc); + if (clip) { + if (mmd->mirror_ob) { + mul_m4_v3(imtx, loc); + } + copy_v3_v3(td->loc, loc); } - copy_v3_v3(td->loc, loc); } } - } + } } } } @@ -224,27 +235,29 @@ static void clipMirrorModifier(TransInfo *t, Object *ob) /* assumes obedit set to mesh object */ static void editbmesh_apply_to_mirror(TransInfo *t) { - TransData *td = t->data; - BMVert *eve; - int i; + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + TransData *td = tc->data; + BMVert *eve; + int i; - for (i = 0; i < t->total; i++, td++) { - if (td->flag & TD_NOACTION) - break; - if (td->loc == NULL) - break; - if (td->flag & TD_SKIP) - continue; + for (i = 0; i < tc->data_len; i++, td++) { + if (td->flag & TD_NOACTION) + break; + if (td->loc == NULL) + break; + if (td->flag & TD_SKIP) + continue; - eve = td->extra; - if (eve) { - eve->co[0] = -td->loc[0]; - eve->co[1] = td->loc[1]; - eve->co[2] = td->loc[2]; - } + eve = td->extra; + if (eve) { + eve->co[0] = -td->loc[0]; + eve->co[1] = td->loc[1]; + eve->co[2] = td->loc[2]; + } - if (td->flag & TD_MIRROR_EDGE) { - td->loc[0] = 0; + if (td->flag & TD_MIRROR_EDGE) { + td->loc[0] = 0; + } } } } @@ -339,7 +352,7 @@ static bool fcu_test_selected(FCurve *fcu) /* helper for recalcData() - for Action Editor transforms */ static void recalcData_actedit(TransInfo *t) { - Scene *scene = t->scene; + ViewLayer *view_layer = t->view_layer; SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first; bAnimContext ac = {NULL}; @@ -351,7 +364,8 @@ static void recalcData_actedit(TransInfo *t) /* NOTE: sync this with the code in ANIM_animdata_get_context() */ ac.bmain = CTX_data_main(t->context); ac.scene = t->scene; - ac.obact = OBACT; + ac.view_layer = t->view_layer; + ac.obact = OBACT(view_layer); ac.sa = t->sa; ac.ar = t->ar; ac.sl = (t->sa) ? t->sa->spacedata.first : NULL; @@ -376,7 +390,7 @@ static void recalcData_actedit(TransInfo *t) if ((saction->flag & SACTION_NOREALTIMEUPDATES) == 0) { for (ale = anim_data.first; ale; ale = ale->next) { /* set refresh tags for objects using this animation */ - ANIM_list_elem_update(CTX_data_main(t->context), scene, ale); + ANIM_list_elem_update(CTX_data_main(t->context), t->scene, ale); } } @@ -388,7 +402,7 @@ static void recalcData_actedit(TransInfo *t) static void recalcData_graphedit(TransInfo *t) { SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first; - Scene *scene; + ViewLayer *view_layer = t->view_layer; ListBase anim_data = {NULL, NULL}; bAnimContext ac = {NULL}; @@ -400,8 +414,9 @@ static void recalcData_graphedit(TransInfo *t) /* initialize relevant anim-context 'context' data from TransInfo data */ /* NOTE: sync this with the code in ANIM_animdata_get_context() */ ac.bmain = CTX_data_main(t->context); - scene = ac.scene = t->scene; - ac.obact = OBACT; + ac.scene = t->scene; + ac.view_layer = t->view_layer; + ac.obact = OBACT(view_layer); ac.sa = t->sa; ac.ar = t->ar; ac.sl = (t->sa) ? t->sa->spacedata.first : NULL; @@ -454,11 +469,13 @@ static void recalcData_nla(TransInfo *t) double secf = FPS; int i; + TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); + /* for each strip we've got, perform some additional validation of the values that got set before * using RNA to set the value (which does some special operations when setting these values to make * sure that everything works ok) */ - for (i = 0; i < t->total; i++, tdn++) { + for (i = 0; i < tc->data_len; i++, tdn++) { NlaStrip *strip = tdn->strip; PointerRNA strip_ptr; short pExceeded, nExceeded, iter; @@ -663,7 +680,7 @@ static void recalcData_mask_common(TransInfo *t) flushTransMasking(t); - DAG_id_tag_update(&mask->id, 0); + DEG_id_tag_update(&mask->id, 0); } /* helper for recalcData() - for Image Editor transforms */ @@ -675,14 +692,18 @@ static void recalcData_image(TransInfo *t) else if (t->options & CTX_PAINT_CURVE) { flushTransPaintCurve(t); } - else if (t->obedit && t->obedit->type == OB_MESH) { + else if ((t->flag & T_EDIT) && t->obedit_type == OB_MESH) { SpaceImage *sima = t->sa->spacedata.first; flushTransUVs(t); if (sima->flag & SI_LIVE_UNWRAP) ED_uvedit_live_unwrap_re_solve(); - DAG_id_tag_update(t->obedit->data, 0); + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + if (tc->data_len) { + DEG_id_tag_update(tc->obedit->data, 0); + } + } } } @@ -725,7 +746,7 @@ static void recalcData_spaceclip(TransInfo *t) track = track->next; } - DAG_id_tag_update(&clip->id, 0); + DEG_id_tag_update(&clip->id, 0); } else if (t->options & CTX_MASK) { recalcData_mask_common(t); @@ -735,55 +756,59 @@ static void recalcData_spaceclip(TransInfo *t) /* helper for recalcData() - for object transforms, typically in the 3D view */ static void recalcData_objects(TransInfo *t) { - Main *bmain = CTX_data_main(t->context); - Base *base = t->scene->basact; + Base *base = t->view_layer->basact; - if (t->obedit) { - if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) { - Curve *cu = t->obedit->data; - ListBase *nurbs = BKE_curve_editNurbs_get(cu); - Nurb *nu = nurbs->first; + if (t->obedit_type != -1) { + if (ELEM(t->obedit_type, OB_CURVE, OB_SURF)) { if (t->state != TRANS_CANCEL) { - clipMirrorModifier(t, t->obedit); + clipMirrorModifier(t); applyProject(t); } - DAG_id_tag_update(t->obedit->data, 0); /* sets recalc flags */ + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + Curve *cu = tc->obedit->data; + ListBase *nurbs = BKE_curve_editNurbs_get(cu); + Nurb *nu = nurbs->first; - if (t->state == TRANS_CANCEL) { - while (nu) { - BKE_nurb_handles_calc(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */ - nu = nu->next; + DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */ + + if (t->state == TRANS_CANCEL) { + while (nu) { + BKE_nurb_handles_calc(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */ + nu = nu->next; + } } - } - else { - /* Normal updating */ - while (nu) { - BKE_nurb_test2D(nu); - BKE_nurb_handles_calc(nu); - nu = nu->next; + else { + /* Normal updating */ + while (nu) { + BKE_nurb_test2D(nu); + BKE_nurb_handles_calc(nu); + nu = nu->next; + } } } } - else if (t->obedit->type == OB_LATTICE) { - Lattice *la = t->obedit->data; + else if (t->obedit_type == OB_LATTICE) { if (t->state != TRANS_CANCEL) { applyProject(t); } - DAG_id_tag_update(t->obedit->data, 0); /* sets recalc flags */ - - if (la->editlatt->latt->flag & LT_OUTSIDE) outside_lattice(la->editlatt->latt); + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + Lattice *la = tc->obedit->data; + DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */ + if (la->editlatt->latt->flag & LT_OUTSIDE) { + outside_lattice(la->editlatt->latt); + } + } } - else if (t->obedit->type == OB_MESH) { - BMEditMesh *em = BKE_editmesh_from_object(t->obedit); + else if (t->obedit_type == OB_MESH) { /* mirror modifier clipping? */ if (t->state != TRANS_CANCEL) { /* apply clipping after so we never project past the clip plane [#25423] */ applyProject(t); - clipMirrorModifier(t, t->obedit); + clipMirrorModifier(t); } if ((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR)) editbmesh_apply_to_mirror(t); @@ -795,135 +820,152 @@ static void recalcData_objects(TransInfo *t) projectVertSlideData(t, false); } - DAG_id_tag_update(t->obedit->data, 0); /* sets recalc flags */ - - EDBM_mesh_normals_update(em); - BKE_editmesh_tessface_calc(em); + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */ + BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); + EDBM_mesh_normals_update(em); + BKE_editmesh_tessface_calc(em); + } } - else if (t->obedit->type == OB_ARMATURE) { /* no recalc flag, does pose */ - bArmature *arm = t->obedit->data; - ListBase *edbo = arm->edbo; - EditBone *ebo, *ebo_parent; - TransData *td = t->data; - int i; + else if (t->obedit_type == OB_ARMATURE) { /* no recalc flag, does pose */ if (t->state != TRANS_CANCEL) { applyProject(t); } - /* Ensure all bones are correctly adjusted */ - for (ebo = edbo->first; ebo; ebo = ebo->next) { - ebo_parent = (ebo->flag & BONE_CONNECTED) ? ebo->parent : NULL; + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + bArmature *arm = tc->obedit->data; + ListBase *edbo = arm->edbo; + EditBone *ebo, *ebo_parent; + TransData *td = tc->data; + int i; - if (ebo_parent) { - /* If this bone has a parent tip that has been moved */ - if (ebo_parent->flag & BONE_TIPSEL) { - copy_v3_v3(ebo->head, ebo_parent->tail); - if (t->mode == TFM_BONE_ENVELOPE) ebo->rad_head = ebo_parent->rad_tail; - } - /* If this bone has a parent tip that has NOT been moved */ - else { - copy_v3_v3(ebo_parent->tail, ebo->head); - if (t->mode == TFM_BONE_ENVELOPE) ebo_parent->rad_tail = ebo->rad_head; - } - } + /* Ensure all bones are correctly adjusted */ + for (ebo = edbo->first; ebo; ebo = ebo->next) { + ebo_parent = (ebo->flag & BONE_CONNECTED) ? ebo->parent : NULL; - /* on extrude bones, oldlength==0.0f, so we scale radius of points */ - ebo->length = len_v3v3(ebo->head, ebo->tail); - if (ebo->oldlength == 0.0f) { - ebo->rad_head = 0.25f * ebo->length; - ebo->rad_tail = 0.10f * ebo->length; - ebo->dist = 0.25f * ebo->length; - if (ebo->parent) { - if (ebo->rad_head > ebo->parent->rad_tail) - ebo->rad_head = ebo->parent->rad_tail; + if (ebo_parent) { + /* If this bone has a parent tip that has been moved */ + if (ebo_parent->flag & BONE_TIPSEL) { + copy_v3_v3(ebo->head, ebo_parent->tail); + if (t->mode == TFM_BONE_ENVELOPE) ebo->rad_head = ebo_parent->rad_tail; + } + /* If this bone has a parent tip that has NOT been moved */ + else { + copy_v3_v3(ebo_parent->tail, ebo->head); + if (t->mode == TFM_BONE_ENVELOPE) ebo_parent->rad_tail = ebo->rad_head; + } } - } - else if (t->mode != TFM_BONE_ENVELOPE) { - /* if bones change length, lets do that for the deform distance as well */ - ebo->dist *= ebo->length / ebo->oldlength; - ebo->rad_head *= ebo->length / ebo->oldlength; - ebo->rad_tail *= ebo->length / ebo->oldlength; - ebo->oldlength = ebo->length; - if (ebo_parent) { - ebo_parent->rad_tail = ebo->rad_head; + /* on extrude bones, oldlength==0.0f, so we scale radius of points */ + ebo->length = len_v3v3(ebo->head, ebo->tail); + if (ebo->oldlength == 0.0f) { + ebo->rad_head = 0.25f * ebo->length; + ebo->rad_tail = 0.10f * ebo->length; + ebo->dist = 0.25f * ebo->length; + if (ebo->parent) { + if (ebo->rad_head > ebo->parent->rad_tail) + ebo->rad_head = ebo->parent->rad_tail; + } + } + else if (t->mode != TFM_BONE_ENVELOPE) { + /* if bones change length, lets do that for the deform distance as well */ + ebo->dist *= ebo->length / ebo->oldlength; + ebo->rad_head *= ebo->length / ebo->oldlength; + ebo->rad_tail *= ebo->length / ebo->oldlength; + ebo->oldlength = ebo->length; + + if (ebo_parent) { + ebo_parent->rad_tail = ebo->rad_head; + } } } - } - if (!ELEM(t->mode, TFM_BONE_ROLL, TFM_BONE_ENVELOPE, TFM_BONE_ENVELOPE_DIST, TFM_BONESIZE)) { - /* fix roll */ - for (i = 0; i < t->total; i++, td++) { - if (td->extra) { - float vec[3], up_axis[3]; - float qrot[4]; - float roll; + if (!ELEM(t->mode, TFM_BONE_ROLL, TFM_BONE_ENVELOPE, TFM_BONE_ENVELOPE_DIST, TFM_BONESIZE)) { + /* fix roll */ + for (i = 0; i < tc->data_len; i++, td++) { + if (td->extra) { + float vec[3], up_axis[3]; + float qrot[4]; + float roll; - ebo = td->extra; + ebo = td->extra; - if (t->state == TRANS_CANCEL) { - /* restore roll */ - ebo->roll = td->ival; - } - else { - copy_v3_v3(up_axis, td->axismtx[2]); + if (t->state == TRANS_CANCEL) { + /* restore roll */ + ebo->roll = td->ival; + } + else { + copy_v3_v3(up_axis, td->axismtx[2]); - sub_v3_v3v3(vec, ebo->tail, ebo->head); - normalize_v3(vec); - rotation_between_vecs_to_quat(qrot, td->axismtx[1], vec); - mul_qt_v3(qrot, up_axis); + sub_v3_v3v3(vec, ebo->tail, ebo->head); + normalize_v3(vec); + rotation_between_vecs_to_quat(qrot, td->axismtx[1], vec); + mul_qt_v3(qrot, up_axis); - /* roll has a tendency to flip in certain orientations - [#34283], [#33974] */ - roll = ED_armature_ebone_roll_to_vector(ebo, up_axis, false); - ebo->roll = angle_compat_rad(roll, td->ival); + /* roll has a tendency to flip in certain orientations - [#34283], [#33974] */ + roll = ED_armature_ebone_roll_to_vector(ebo, up_axis, false); + ebo->roll = angle_compat_rad(roll, td->ival); + } } } } - } - if (arm->flag & ARM_MIRROR_EDIT) { - if (t->state != TRANS_CANCEL) - ED_armature_edit_transform_mirror_update(t->obedit); - else - restoreBones(t); + if (arm->flag & ARM_MIRROR_EDIT) { + if (t->state != TRANS_CANCEL) { + ED_armature_edit_transform_mirror_update(tc->obedit); + } + else { + restoreBones(tc); + } + } } } else { if (t->state != TRANS_CANCEL) { applyProject(t); } - DAG_id_tag_update(t->obedit->data, 0); /* sets recalc flags */ + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + if (tc->data_len) { + DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */ + } + } } + } - else if ((t->flag & T_POSE) && t->poseobj) { - Object *ob = t->poseobj; - bArmature *arm = ob->data; + else if (t->flag & T_POSE) { + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + Object *ob = tc->poseobj; + bArmature *arm = ob->data; - /* if animtimer is running, and the object already has animation data, - * check if the auto-record feature means that we should record 'samples' - * (i.e. uneditable animation values) - * - * context is needed for keying set poll() functions. - */ - // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes? - if ((t->animtimer) && (t->context) && IS_AUTOKEY_ON(t->scene)) { - int targetless_ik = (t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet! + /* if animtimer is running, and the object already has animation data, + * check if the auto-record feature means that we should record 'samples' + * (i.e. uneditable animation values) + * + * context is needed for keying set poll() functions. + */ + // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes? + if ((t->animtimer) && (t->context) && IS_AUTOKEY_ON(t->scene)) { + int targetless_ik = (t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet! - animrecord_check_state(t->scene, &ob->id, t->animtimer); - autokeyframe_pose_cb_func(t->context, t->scene, (View3D *)t->view, ob, t->mode, targetless_ik); - } + animrecord_check_state(t->scene, &ob->id, t->animtimer); + autokeyframe_pose_cb_func(t->context, t->scene, ob, t->mode, targetless_ik); + } - /* old optimize trick... this enforces to bypass the depgraph */ - if (!(arm->flag & ARM_DELAYDEFORM)) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */ - /* transformation of pose may affect IK tree, make sure it is rebuilt */ - BIK_clear_data(ob->pose); + /* old optimize trick... this enforces to bypass the depgraph */ + if (!(arm->flag & ARM_DELAYDEFORM)) { + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */ + /* transformation of pose may affect IK tree, make sure it is rebuilt */ + BIK_clear_data(ob->pose); + } + else { + BKE_pose_where_is(t->depsgraph, t->scene, ob); + } } - else - BKE_pose_where_is(t->scene, ob); } - else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(bmain, t->scene, base->object)) { + else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && + PE_get_current(t->scene, base->object)) + { if (t->state != TRANS_CANCEL) { applyProject(t); } @@ -936,37 +978,45 @@ static void recalcData_objects(TransInfo *t) applyProject(t); } - for (i = 0; i < t->total; i++) { - TransData *td = t->data + i; - Object *ob = td->ob; + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + TransData *td = tc->data; - if (td->flag & TD_NOACTION) - break; + for (i = 0; i < tc->data_len; i++, td++) { + Object *ob = td->ob; - if (td->flag & TD_SKIP) - continue; + if (td->flag & TD_NOACTION) + break; - /* if animtimer is running, and the object already has animation data, - * check if the auto-record feature means that we should record 'samples' - * (i.e. uneditable animation values) - */ - // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes? - if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) { - animrecord_check_state(t->scene, &ob->id, t->animtimer); - autokeyframe_ob_cb_func(t->context, t->scene, (View3D *)t->view, ob, t->mode); - } + if (td->flag & TD_SKIP) + continue; - /* sets recalc flags fully, instead of flushing existing ones - * otherwise proxies don't function correctly - */ - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + /* if animtimer is running, and the object already has animation data, + * check if the auto-record feature means that we should record 'samples' + * (i.e. uneditable animation values) + */ + // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes? + if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) { + animrecord_check_state(t->scene, &ob->id, t->animtimer); + autokeyframe_ob_cb_func(t->context, t->scene, t->view_layer, ob, t->mode); + } + + /* sets recalc flags fully, instead of flushing existing ones + * otherwise proxies don't function correctly + */ + DEG_id_tag_update(&ob->id, OB_RECALC_OB); - if (t->flag & T_TEXTURE) - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + if (t->flag & T_TEXTURE) + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + } } } } +static void recalcData_cursor(TransInfo *t) +{ + DEG_id_tag_update(&t->scene->id, DEG_TAG_COPY_ON_WRITE); +} + /* helper for recalcData() - for sequencer transforms */ static void recalcData_sequencer(TransInfo *t) { @@ -974,7 +1024,9 @@ static void recalcData_sequencer(TransInfo *t) int a; Sequence *seq_prev = NULL; - for (a = 0, td = t->data; a < t->total; a++, td++) { + TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); + + for (a = 0, td = tc->data; a < tc->data_len; a++, td++) { TransDataSeq *tdsq = (TransDataSeq *) td->extra; Sequence *seq = tdsq->seq; @@ -999,8 +1051,10 @@ static void recalcData_sequencer(TransInfo *t) /* force recalculation of triangles during transformation */ static void recalcData_gpencil_strokes(TransInfo *t) { - TransData *td = t->data; - for (int i = 0; i < t->total; i++, td++) { + TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); + + TransData *td = tc->data; + for (int i = 0; i < tc->data_len; i++, td++) { bGPDstroke *gps = td->extra; if (gps != NULL) { gps->flag |= GP_STROKE_RECALC_CACHES; @@ -1012,7 +1066,10 @@ static void recalcData_gpencil_strokes(TransInfo *t) void recalcData(TransInfo *t) { /* if tests must match createTransData for correct updates */ - if (t->options & CTX_TEXTURE) { + if (t->options & CTX_CURSOR) { + recalcData_cursor(t); + } + else if (t->options & CTX_TEXTURE) { recalcData_objects(t); } else if (t->options & CTX_EDGE) { @@ -1059,10 +1116,7 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis if (t->spacetype == SPACE_VIEW3D) { View3D *v3d = t->view; - glPushMatrix(); - - //if (t->obedit) glLoadMatrixf(t->obedit->obmat); // sets opengl viewing - + gpuPushMatrix(); copy_v3_v3(v3, dir); mul_v3_fl(v3, v3d->far); @@ -1077,15 +1131,20 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis UI_GetThemeColor3ubv(TH_GRID, col); } UI_make_axis_color(col, col2, axis); - glColor3ubv(col2); - setlinestyle(0); - glBegin(GL_LINES); - glVertex3fv(v1); - glVertex3fv(v2); - glEnd(); + unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); + immUniformColor3ubv(col2); + + immBegin(GWN_PRIM_LINES, 2); + immVertex3fv(pos, v1); + immVertex3fv(pos, v2); + immEnd(); + + immUnbindProgram(); - glPopMatrix(); + gpuPopMatrix(); } } @@ -1094,12 +1153,7 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis */ void resetTransModal(TransInfo *t) { - if (t->mode == TFM_EDGE_SLIDE) { - freeEdgeSlideVerts(t, &t->custom.mode); - } - else if (t->mode == TFM_VERT_SLIDE) { - freeVertSlideVerts(t, &t->custom.mode); - } + freeTransCustomDataForMode(t); } void resetTransRestrictions(TransInfo *t) @@ -1121,6 +1175,53 @@ static int initTransInfo_edit_pet_to_flag(const int proportional) } } +void initTransDataContainers_FromObjectData(TransInfo *t) +{ + const eObjectMode object_mode = OBACT(t->view_layer) ? OBACT(t->view_layer)->mode : OB_MODE_OBJECT; + const short object_type = OBACT(t->view_layer) ? OBACT(t->view_layer)->type : -1; + + if ((object_mode & OB_MODE_EDIT) || + ((object_mode & OB_MODE_POSE) && (object_type == OB_ARMATURE))) + { + if (t->data_container) { + MEM_freeN(t->data_container); + } + uint objects_len; + Object **objects = BKE_view_layer_array_from_objects_in_mode( + t->view_layer, &objects_len, { + .object_mode = object_mode, + .no_dup_data = true}); + t->data_container = MEM_callocN(sizeof(*t->data_container) * objects_len, __func__); + t->data_container_len = objects_len; + + for (int i = 0; i < objects_len; i++) { + TransDataContainer *tc = &t->data_container[i]; + if (object_mode & OB_MODE_EDIT) { + tc->obedit = objects[i]; + /* Check needed for UV's */ + if ((t->flag & T_2D_EDIT) == 0) { + tc->use_local_mat = true; + } + } + else if (object_mode & OB_MODE_POSE) { + tc->poseobj = objects[i]; + tc->use_local_mat = true; + } + + if (tc->use_local_mat) { + BLI_assert((t->flag & T_2D_EDIT) == 0); + copy_m4_m4(tc->mat, objects[i]->obmat); + copy_m3_m4(tc->mat3, tc->mat); + invert_m4_m4(tc->imat, tc->mat); + invert_m3_m3(tc->imat3, tc->mat3); + normalize_m3_m3(tc->mat3_unit, tc->mat3); + } + /* Otherwise leave as zero. */ + } + MEM_freeN(objects); + } +} + /** * Setup internal data, mouse, vectors * @@ -1130,34 +1231,38 @@ static int initTransInfo_edit_pet_to_flag(const int proportional) */ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event) { + Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *sce = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + const eObjectMode object_mode = OBACT(view_layer) ? OBACT(view_layer)->mode : OB_MODE_OBJECT; + const short object_type = OBACT(view_layer) ? OBACT(view_layer)->type : -1; ToolSettings *ts = CTX_data_tool_settings(C); ARegion *ar = CTX_wm_region(C); ScrArea *sa = CTX_wm_area(C); - Object *obedit = CTX_data_edit_object(C); - Object *ob = CTX_data_active_object(C); + bGPdata *gpd = CTX_data_gpencil_data(C); PropertyRNA *prop; + t->depsgraph = depsgraph; t->scene = sce; + t->view_layer = view_layer; t->sa = sa; t->ar = ar; - t->obedit = obedit; t->settings = ts; t->reports = op ? op->reports : NULL; - if (obedit) { - copy_m3_m4(t->obedit_mat, obedit->obmat); - normalize_m3(t->obedit_mat); - } - - t->data = NULL; - t->ext = NULL; - t->helpline = HLP_NONE; t->flag = 0; + t->obedit_type = (object_mode == OB_MODE_EDIT) ? object_type : -1; + + /* Many kinds of transform only use a single handle. */ + if (t->data_container == NULL) { + t->data_container = MEM_callocN(sizeof(*t->data_container), __func__); + t->data_container_len = 1; + } + t->redraw = TREDRAW_HARD; /* redraw first time */ if (event) { @@ -1178,12 +1283,11 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve t->transform = NULL; t->handleEvent = NULL; - t->total = 0; + t->data_len_all = 0; t->val = 0.0f; zero_v3(t->vec); - zero_v3(t->center); zero_v3(t->center_global); unit_m3(t->mat); @@ -1232,9 +1336,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve prop_id = "use_even_offset"; } - if (prop_id && (prop = RNA_struct_find_property(op->ptr, prop_id)) && - RNA_property_is_set(op->ptr, prop)) - { + if (prop_id && (prop = RNA_struct_find_property(op->ptr, prop_id))) { SET_FLAG_FROM_TEST(t->flag, RNA_property_boolean_get(op->ptr, prop), T_ALT_TRANSFORM); } } @@ -1247,34 +1349,37 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve t->animtimer = (animscreen) ? animscreen->animtimer : NULL; /* turn manipulator off during transform */ - // FIXME: but don't do this when USING the manipulator... if (t->flag & T_MODAL) { - t->twtype = v3d->twtype; - v3d->twtype = 0; + t->twflag = v3d->twflag; + v3d->twflag = 0; } - if (v3d->flag & V3D_ALIGN) t->flag |= T_V3D_ALIGN; - t->around = v3d->around; + if (t->scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) { + t->flag |= T_V3D_ALIGN; + } + t->around = t->scene->toolsettings->transform_pivot_point; /* bend always uses the cursor */ if (t->mode == TFM_BEND) { t->around = V3D_AROUND_CURSOR; } - t->current_orientation = v3d->twmode; + t->current_orientation = t->scene->orientation_type; + t->custom_orientation = BKE_scene_transform_orientation_find( + t->scene, t->scene->orientation_index_custom); /* exceptional case */ if (t->around == V3D_AROUND_LOCAL_ORIGINS) { if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL)) { const bool use_island = transdata_check_local_islands(t, t->around); - if (obedit && !use_island) { + if ((t->obedit_type != -1) && !use_island) { t->options |= CTX_NO_PET; } } } - if (ob && ob->mode & OB_MODE_ALL_PAINT) { + if (object_mode & OB_MODE_ALL_PAINT) { Paint *p = BKE_paint_get_active_from_context(C); if (p && p->brush && (p->brush->flag & BRUSH_CURVE)) { t->options |= CTX_PAINT_CURVE; @@ -1303,7 +1408,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve t->view = &ar->v2d; t->around = sima->around; - if (ED_space_image_show_uvedit(sima, t->obedit)) { + if (ED_space_image_show_uvedit(sima, OBACT(t->view_layer))) { /* UV transform */ } else if (sima->mode == SI_MODE_MASK) { @@ -1352,11 +1457,22 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve if (op && ((prop = RNA_struct_find_property(op->ptr, "constraint_orientation")) && RNA_property_is_set(op->ptr, prop))) { - t->current_orientation = RNA_property_enum_get(op->ptr, prop); + short orientation = RNA_property_enum_get(op->ptr, prop); + TransformOrientation *custom_orientation = NULL; - if (t->current_orientation >= V3D_MANIP_CUSTOM + BIF_countTransformOrientation(C)) { - t->current_orientation = V3D_MANIP_GLOBAL; + if (orientation >= V3D_MANIP_CUSTOM) { + if (orientation >= V3D_MANIP_CUSTOM + BIF_countTransformOrientation(C)) { + orientation = V3D_MANIP_GLOBAL; + } + else { + custom_orientation = BKE_scene_transform_orientation_find( + t->scene, orientation - V3D_MANIP_CUSTOM); + orientation = V3D_MANIP_CUSTOM; + } } + + t->current_orientation = orientation; + t->custom_orientation = custom_orientation; } if (op && ((prop = RNA_struct_find_property(op->ptr, "release_confirm")) && @@ -1382,7 +1498,8 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve } // Need stuff to take it from edit mesh or whatnot here else if (t->spacetype == SPACE_VIEW3D) { - if (t->obedit && t->obedit->type == OB_MESH && (((Mesh *)t->obedit->data)->editflag & ME_EDIT_MIRROR_X)) { + /* TODO(campbell): xform, get mirror from each object. */ + if (t->obedit_type == OB_MESH && (((Mesh *)OBACT(t->view_layer)->data)->editflag & ME_EDIT_MIRROR_X)) { t->flag |= T_MIRROR; t->mirror = 1; } @@ -1403,7 +1520,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve else if (t->spacetype == SPACE_ACTION) { t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional_action); } - else if (t->obedit) { + else if (t->obedit_type != -1) { t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional); } else if (t->options & CTX_GPENCIL_STROKES) { @@ -1418,7 +1535,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve } } } - else if (t->obedit == NULL && ts->proportional_objects) { + else if ((t->obedit_type == -1) && ts->proportional_objects) { t->flag |= T_PROP_EDIT; } } @@ -1464,8 +1581,8 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve setTransformViewAspect(t, t->aspect); if (op && (prop = RNA_struct_find_property(op->ptr, "center_override")) && RNA_property_is_set(op->ptr, prop)) { - RNA_property_float_get_array(op->ptr, prop, t->center); - mul_v3_v3(t->center, t->aspect); + RNA_property_float_get_array(op->ptr, prop, t->center_global); + mul_v3_v3(t->center_global, t->aspect); t->flag |= T_OVERRIDE_CENTER; } @@ -1473,11 +1590,47 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve initNumInput(&t->num); } + +static void freeTransCustomData( + TransInfo *t, TransDataContainer *tc, + TransCustomData *custom_data) +{ + if (custom_data->free_cb) { + /* Can take over freeing t->data and data_2d etc... */ + custom_data->free_cb(t, tc, custom_data); + BLI_assert(custom_data->data == NULL); + } + else if ((custom_data->data != NULL) && custom_data->use_free) { + MEM_freeN(custom_data->data); + custom_data->data = NULL; + } + /* In case modes are switched in the same transform session. */ + custom_data->free_cb = false; + custom_data->use_free = false; +} + +static void freeTransCustomDataContainer(TransInfo *t, TransDataContainer *tc, TransCustomDataContainer *tcdc) +{ + TransCustomData *custom_data = &tcdc->first_elem; + for (int i = 0; i < TRANS_CUSTOM_DATA_ELEM_MAX; i++, custom_data++) { + freeTransCustomData(t, tc, custom_data); + } +} + +/** + * Needed for mode switching. + */ +void freeTransCustomDataForMode(TransInfo *t) +{ + freeTransCustomData(t, NULL, &t->custom.mode); + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + freeTransCustomData(t, tc, &tc->custom.mode); + } +} + /* Here I would suggest only TransInfo related issues, like free data & reset vars. Not redraws */ void postTrans(bContext *C, TransInfo *t) { - TransData *td; - if (t->draw_handle_view) ED_region_draw_cb_exit(t->ar->type, t->draw_handle_view); if (t->draw_handle_apply) @@ -1487,46 +1640,41 @@ void postTrans(bContext *C, TransInfo *t) if (t->draw_handle_cursor) WM_paint_cursor_end(CTX_wm_manager(C), t->draw_handle_cursor); + if (t->flag & T_MODAL_CURSOR_SET) { + WM_cursor_modal_restore(CTX_wm_window(C)); + } + /* Free all custom-data */ - { - TransCustomData *custom_data = &t->custom.first_elem; - for (int i = 0; i < TRANS_CUSTOM_DATA_ELEM_MAX; i++, custom_data++) { - if (custom_data->free_cb) { - /* Can take over freeing t->data and data2d etc... */ - custom_data->free_cb(t, custom_data); - BLI_assert(custom_data->data == NULL); - } - else if ((custom_data->data != NULL) && custom_data->use_free) { - MEM_freeN(custom_data->data); - custom_data->data = NULL; - } - } + freeTransCustomDataContainer(t, NULL, &t->custom); + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + freeTransCustomDataContainer(t, tc, &tc->custom); } /* postTrans can be called when nothing is selected, so data is NULL already */ - if (t->data) { - - /* free data malloced per trans-data */ - if ((t->obedit && ELEM(t->obedit->type, OB_CURVE, OB_SURF)) || - (t->spacetype == SPACE_IPO)) - { - int a; - for (a = 0, td = t->data; a < t->total; a++, td++) { - if (td->flag & TD_BEZTRIPLE) { - MEM_freeN(td->hdata); + if (t->data_len_all != 0) { + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + /* free data malloced per trans-data */ + if (ELEM(t->obedit_type, OB_CURVE, OB_SURF) || + (t->spacetype == SPACE_IPO)) + { + TransData *td = tc->data; + for (int a = 0; a < tc->data_len; a++, td++) { + if (td->flag & TD_BEZTRIPLE) { + MEM_freeN(td->hdata); + } } } + MEM_freeN(tc->data); + + MEM_SAFE_FREE(tc->data_ext); + MEM_SAFE_FREE(tc->data_2d); } - MEM_freeN(t->data); } - BLI_freelistN(&t->tsnap.points); + MEM_SAFE_FREE(t->data_container); + t->data_container = NULL; - if (t->ext) MEM_freeN(t->ext); - if (t->data2d) { - MEM_freeN(t->data2d); - t->data2d = NULL; - } + BLI_freelistN(&t->tsnap.points); if (t->spacetype == SPACE_IMAGE) { if (t->options & (CTX_MASK | CTX_PAINT_CURVE)) { @@ -1542,7 +1690,7 @@ void postTrans(bContext *C, TransInfo *t) View3D *v3d = t->sa->spacedata.first; /* restore manipulator */ if (t->flag & T_MODAL) { - v3d->twtype = t->twtype; + v3d->twflag = t->twflag; } } @@ -1550,14 +1698,20 @@ void postTrans(bContext *C, TransInfo *t) MEM_freeN(t->mouse.data); } + if (t->rng != NULL) { + BLI_rng_free(t->rng); + } + freeSnapping(t); } void applyTransObjects(TransInfo *t) { + TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); + TransData *td; - for (td = t->data; td < t->data + t->total; td++) { + for (td = tc->data; td < tc->data + tc->data_len; td++) { copy_v3_v3(td->iloc, td->loc); if (td->ext->rot) { copy_v3_v3(td->ext->irot, td->ext->rot); @@ -1606,25 +1760,29 @@ static void restoreElement(TransData *td) void restoreTransObjects(TransInfo *t) { - TransData *td; - TransData2D *td2d; + FOREACH_TRANS_DATA_CONTAINER (t, tc) { - for (td = t->data; td < t->data + t->total; td++) { - restoreElement(td); - } + TransData *td; + TransData2D *td2d; - for (td2d = t->data2d; t->data2d && td2d < t->data2d + t->total; td2d++) { - if (td2d->h1) { - td2d->h1[0] = td2d->ih1[0]; - td2d->h1[1] = td2d->ih1[1]; + for (td = tc->data; td < tc->data + tc->data_len; td++) { + restoreElement(td); } - if (td2d->h2) { - td2d->h2[0] = td2d->ih2[0]; - td2d->h2[1] = td2d->ih2[1]; + + for (td2d = tc->data_2d; tc->data_2d && td2d < tc->data_2d + tc->data_len; td2d++) { + if (td2d->h1) { + td2d->h1[0] = td2d->ih1[0]; + td2d->h1[1] = td2d->ih1[1]; + } + if (td2d->h2) { + td2d->h2[0] = td2d->ih2[0]; + td2d->h2[1] = td2d->ih2[1]; + } } - } - unit_m3(t->mat); + unit_m3(t->mat); + + } recalcData(t); } @@ -1632,32 +1790,21 @@ void restoreTransObjects(TransInfo *t) void calculateCenter2D(TransInfo *t) { BLI_assert(!is_zero_v3(t->aspect)); - - if (t->flag & (T_EDIT | T_POSE)) { - Object *ob = t->obedit ? t->obedit : t->poseobj; - float vec[3]; - - copy_v3_v3(vec, t->center); - mul_m4_v3(ob->obmat, vec); - projectFloatView(t, vec, t->center2d); - } - else { - projectFloatView(t, t->center, t->center2d); - } + projectFloatView(t, t->center_global, t->center2d); } -void calculateCenterGlobal( - TransInfo *t, const float center_local[3], - float r_center_global[3]) +void calculateCenterLocal( + TransInfo *t, const float center_global[3]) { /* setting constraint center */ /* note, init functions may over-ride t->center */ - if (t->flag & (T_EDIT | T_POSE)) { - Object *ob = t->obedit ? t->obedit : t->poseobj; - mul_v3_m4v3(r_center_global, ob->obmat, center_local); - } - else { - copy_v3_v3(r_center_global, center_local); + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + if (tc->use_local_mat) { + mul_v3_m4v3(tc->center_local, tc->imat, center_global); + } + else { + copy_v3_v3(tc->center_local, center_global); + } } } @@ -1665,20 +1812,11 @@ void calculateCenterCursor(TransInfo *t, float r_center[3]) { const float *cursor; - cursor = ED_view3d_cursor3d_get(t->scene, t->view); + cursor = ED_view3d_cursor3d_get(t->scene, t->view)->location; copy_v3_v3(r_center, cursor); /* If edit or pose mode, move cursor in local space */ - if (t->flag & (T_EDIT | T_POSE)) { - Object *ob = t->obedit ? t->obedit : t->poseobj; - float mat[3][3], imat[3][3]; - - sub_v3_v3v3(r_center, r_center, ob->obmat[3]); - copy_m3_m4(mat, ob->obmat); - invert_m3_m3(imat, mat); - mul_m3_v3(imat, r_center); - } - else if (t->options & CTX_PAINT_CURVE) { + if (t->options & CTX_PAINT_CURVE) { if (ED_view3d_project_float_global(t->ar, cursor, r_center, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) { r_center[0] = t->ar->winx / 2.0f; r_center[1] = t->ar->winy / 2.0f; @@ -1752,13 +1890,21 @@ void calculateCenterMedian(TransInfo *t, float r_center[3]) { float partial[3] = {0.0f, 0.0f, 0.0f}; int total = 0; - int i; - for (i = 0; i < t->total; i++) { - if (t->data[i].flag & TD_SELECTED) { - if (!(t->data[i].flag & TD_NOCENTER)) { - add_v3_v3(partial, t->data[i].center); - total++; + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + for (int i = 0; i < tc->data_len; i++) { + if (tc->data[i].flag & TD_SELECTED) { + if (!(tc->data[i].flag & TD_NOCENTER)) { + if (tc->use_local_mat) { + float v[3]; + mul_v3_m4v3(v, tc->mat, tc->data[i].center); + add_v3_v3(partial, v); + } + else { + add_v3_v3(partial, tc->data[i].center); + } + total++; + } } } } @@ -1770,22 +1916,29 @@ void calculateCenterMedian(TransInfo *t, float r_center[3]) void calculateCenterBound(TransInfo *t, float r_center[3]) { - float max[3]; - float min[3]; - int i; - for (i = 0; i < t->total; i++) { - if (i) { - if (t->data[i].flag & TD_SELECTED) { - if (!(t->data[i].flag & TD_NOCENTER)) - minmax_v3v3_v3(min, max, t->data[i].center); + float max[3], min[3]; + bool changed = false; + INIT_MINMAX(min, max); + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + for (int i = 0; i < tc->data_len; i++) { + if (tc->data[i].flag & TD_SELECTED) { + if (!(tc->data[i].flag & TD_NOCENTER)) { + if (tc->use_local_mat) { + float v[3]; + mul_v3_m4v3(v, tc->mat, tc->data[i].center); + minmax_v3v3_v3(min, max, v); + } + else { + minmax_v3v3_v3(min, max, tc->data[i].center); + } + changed = true; + } } } - else { - copy_v3_v3(max, t->data[i].center); - copy_v3_v3(min, t->data[i].center); - } } - mid_v3_v3v3(r_center, min, max); + if (changed) { + mid_v3_v3v3(r_center, min, max); + } } /** @@ -1793,26 +1946,30 @@ void calculateCenterBound(TransInfo *t, float r_center[3]) */ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3]) { + TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_OK(t); + bool ok = false; - if (t->obedit) { - if (ED_object_editmode_calc_active_center(t->obedit, select_only, r_center)) { + if (tc->obedit) { + if (ED_object_editmode_calc_active_center(tc->obedit, select_only, r_center)) { + mul_m4_v3(tc->obedit->obmat, r_center); ok = true; } } else if (t->flag & T_POSE) { - Scene *scene = t->scene; - Object *ob = OBACT; + ViewLayer *view_layer = t->view_layer; + Object *ob = OBACT(view_layer); if (ob) { bPoseChannel *pchan = BKE_pose_channel_active(ob); if (pchan && (!select_only || (pchan->bone->flag & BONE_SELECTED))) { copy_v3_v3(r_center, pchan->pose_head); + mul_m4_v3(ob->obmat, r_center); ok = true; } } } else if (t->options & CTX_PAINT_CURVE) { - Paint *p = BKE_paint_get_active(t->scene); + Paint *p = BKE_paint_get_active(t->scene, t->view_layer); Brush *br = p->brush; PaintCurve *pc = br->paint_curve; copy_v3_v3(r_center, pc->points[pc->add_index - 1].bez.vec[1]); @@ -1821,9 +1978,10 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3]) } else { /* object mode */ - Scene *scene = t->scene; - Object *ob = OBACT; - if (ob && (!select_only || (ob->flag & SELECT))) { + ViewLayer *view_layer = t->view_layer; + Object *ob = OBACT(view_layer); + Base *base = BASACT(view_layer); + if (ob && ((!select_only) || ((base->flag & BASE_SELECTED) != 0))) { copy_v3_v3(r_center, ob->obmat[3]); ok = true; } @@ -1870,14 +2028,13 @@ static void calculateCenter_FromAround(TransInfo *t, int around, float r_center[ void calculateCenter(TransInfo *t) { if ((t->flag & T_OVERRIDE_CENTER) == 0) { - calculateCenter_FromAround(t, t->around, t->center); + calculateCenter_FromAround(t, t->around, t->center_global); } - calculateCenterGlobal(t, t->center, t->center_global); + calculateCenterLocal(t, t->center_global); /* avoid calculating again */ { TransCenterData *cd = &t->center_cache[t->around]; - copy_v3_v3(cd->local, t->center); copy_v3_v3(cd->global, t->center_global); cd->is_set = true; } @@ -1895,16 +2052,15 @@ void calculateCenter(TransInfo *t) normalize_v3(axis); /* 6.0 = 6 grid units */ - axis[0] = t->center[0] - 6.0f * axis[0]; - axis[1] = t->center[1] - 6.0f * axis[1]; - axis[2] = t->center[2] - 6.0f * axis[2]; + axis[0] = t->center_global[0] - 6.0f * axis[0]; + axis[1] = t->center_global[1] - 6.0f * axis[1]; + axis[2] = t->center_global[2] - 6.0f * axis[2]; projectFloatView(t, axis, t->center2d); /* rotate only needs correct 2d center, grab needs ED_view3d_calc_zfac() value */ if (t->mode == TFM_TRANSLATION) { - copy_v3_v3(t->center, axis); - copy_v3_v3(t->center_global, t->center); + copy_v3_v3(t->center_global, axis); } } } @@ -1938,8 +2094,7 @@ const TransCenterData *transformCenter_from_type(TransInfo *t, int around) BLI_assert(around <= V3D_AROUND_ACTIVE); TransCenterData *cd = &t->center_cache[around]; if (cd->is_set == false) { - calculateCenter_FromAround(t, around, cd->local); - calculateCenterGlobal(t, cd->local, cd->global); + calculateCenter_FromAround(t, around, cd->global); cd->is_set = true; } return cd; @@ -1947,7 +2102,6 @@ const TransCenterData *transformCenter_from_type(TransInfo *t, int around) void calculatePropRatio(TransInfo *t) { - TransData *td = t->data; int i; float dist; const bool connected = (t->flag & T_PROP_CONNECTED) != 0; @@ -1956,75 +2110,84 @@ void calculatePropRatio(TransInfo *t) if (t->flag & T_PROP_EDIT) { const char *pet_id = NULL; - for (i = 0; i < t->total; i++, td++) { - if (td->flag & TD_SELECTED) { - td->factor = 1.0f; - } - else if (t->flag & T_MIRROR && td->loc[0] * t->mirror < -0.00001f) { - td->flag |= TD_SKIP; - td->factor = 0.0f; - restoreElement(td); - } - else if ((connected && (td->flag & TD_NOTCONNECTED || td->dist > t->prop_size)) || - (connected == 0 && td->rdist > t->prop_size)) - { - /* - * The elements are sorted according to their dist member in the array, - * that means we can stop when it finds one element outside of the propsize. - * do not set 'td->flag |= TD_NOACTION', the prop circle is being changed. - */ + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + TransData *td = tc->data; + for (i = 0; i < tc->data_len; i++, td++) { + if (td->flag & TD_SELECTED) { + td->factor = 1.0f; + } + else if (t->flag & T_MIRROR && td->loc[0] * t->mirror < -0.00001f) { + td->flag |= TD_SKIP; + td->factor = 0.0f; + restoreElement(td); + } + else if ((connected && (td->flag & TD_NOTCONNECTED || td->dist > t->prop_size)) || + (connected == 0 && td->rdist > t->prop_size)) + { + /* + * The elements are sorted according to their dist member in the array, + * that means we can stop when it finds one element outside of the propsize. + * do not set 'td->flag |= TD_NOACTION', the prop circle is being changed. + */ - td->factor = 0.0f; - restoreElement(td); - } - else { - /* Use rdist for falloff calculations, it is the real distance */ - td->flag &= ~TD_NOACTION; - - if (connected) - dist = (t->prop_size - td->dist) / t->prop_size; - else - dist = (t->prop_size - td->rdist) / t->prop_size; - - /* - * Clamp to positive numbers. - * Certain corner cases with connectivity and individual centers - * can give values of rdist larger than propsize. - */ - if (dist < 0.0f) - dist = 0.0f; + td->factor = 0.0f; + restoreElement(td); + } + else { + /* Use rdist for falloff calculations, it is the real distance */ + td->flag &= ~TD_NOACTION; + + if (connected) + dist = (t->prop_size - td->dist) / t->prop_size; + else + dist = (t->prop_size - td->rdist) / t->prop_size; + + /* + * Clamp to positive numbers. + * Certain corner cases with connectivity and individual centers + * can give values of rdist larger than propsize. + */ + if (dist < 0.0f) + dist = 0.0f; - switch (t->prop_mode) { - case PROP_SHARP: - td->factor = dist * dist; - break; - case PROP_SMOOTH: - td->factor = 3.0f * dist * dist - 2.0f * dist * dist * dist; - break; - case PROP_ROOT: - td->factor = sqrtf(dist); - break; - case PROP_LIN: - td->factor = dist; - break; - case PROP_CONST: - td->factor = 1.0f; - break; - case PROP_SPHERE: - td->factor = sqrtf(2 * dist - dist * dist); - break; - case PROP_RANDOM: - td->factor = BLI_frand() * dist; - break; - case PROP_INVSQUARE: - td->factor = dist * (2.0f - dist); - break; - default: - td->factor = 1; - break; + switch (t->prop_mode) { + case PROP_SHARP: + td->factor = dist * dist; + break; + case PROP_SMOOTH: + td->factor = 3.0f * dist * dist - 2.0f * dist * dist * dist; + break; + case PROP_ROOT: + td->factor = sqrtf(dist); + break; + case PROP_LIN: + td->factor = dist; + break; + case PROP_CONST: + td->factor = 1.0f; + break; + case PROP_SPHERE: + td->factor = sqrtf(2 * dist - dist * dist); + break; + case PROP_RANDOM: + if (t->rng == NULL) { + /* Lazy initialization. */ + uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX); + t->rng = BLI_rng_new(rng_seed); + } + td->factor = BLI_rng_get_float(t->rng) * dist; + break; + case PROP_INVSQUARE: + td->factor = dist * (2.0f - dist); + break; + default: + td->factor = 1; + break; + } } } } + switch (t->prop_mode) { case PROP_SHARP: pet_id = N_("(Sharp)"); @@ -2059,8 +2222,11 @@ void calculatePropRatio(TransInfo *t) } } else { - for (i = 0; i < t->total; i++, td++) { - td->factor = 1.0; + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + TransData *td = tc->data; + for (i = 0; i < tc->data_len; i++, td++) { + td->factor = 1.0; + } } } } |