diff options
Diffstat (limited to 'source/blender/editors/transform/transform_generics.c')
-rw-r--r-- | source/blender/editors/transform/transform_generics.c | 450 |
1 files changed, 277 insertions, 173 deletions
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 08e8e8fe175..2ab6d0d0900 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -82,6 +82,7 @@ #include "BKE_tracking.h" #include "BKE_mask.h" #include "BKE_workspace.h" +#include "BKE_layer.h" #include "DEG_depsgraph.h" @@ -127,8 +128,10 @@ void getViewVector(TransInfo *t, float coord[3], float vec[3]) /* ************************** GENERICS **************************** */ -static void clipMirrorModifier(TransInfo *t, Object *ob) +static void clipMirrorModifier(TransInfo *t) { + 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; @@ -154,7 +157,6 @@ static void clipMirrorModifier(TransInfo *t, Object *ob) if (axis) { float mtx[4][4], imtx[4][4]; int i; - TransData *td = t->data; if (mmd->mirror_ob) { float obinv[4][4]; @@ -164,7 +166,8 @@ static void clipMirrorModifier(TransInfo *t, Object *ob) invert_m4_m4(imtx, mtx); } - for (i = 0; i < t->total; i++, td++) { + TransData *td = tc->data; + for (i = 0; i < tc->data_len; i++, td++) { int clip; float loc[3], iloc[3]; @@ -222,16 +225,18 @@ 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; + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + TransData *td = tc->data; BMVert *eve; int i; - - for (i = 0; i < t->total; i++, td++) { + + for (i = 0; i < tc->data_len; i++, td++) { if (td->flag & TD_NOACTION) break; if (td->loc == NULL) @@ -250,6 +255,7 @@ static void editbmesh_apply_to_mirror(TransInfo *t) td->loc[0] = 0; } } + } } /* for the realtime animation recording feature, handle overlapping data */ @@ -432,12 +438,14 @@ static void recalcData_nla(TransInfo *t) Scene *scene = t->scene; 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; @@ -654,14 +662,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(); - - DEG_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); + } + } } } @@ -716,19 +728,21 @@ static void recalcData_objects(TransInfo *t) { 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); } - - DEG_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; + + 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 */ @@ -743,25 +757,28 @@ static void recalcData_objects(TransInfo *t) 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); } - - DEG_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); @@ -773,26 +790,30 @@ static void recalcData_objects(TransInfo *t) projectVertSlideData(t, false); } - DEG_id_tag_update(t->obedit->data, 0); /* sets recalc flags */ - + 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); } - + + 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; + /* Ensure all bones are correctly adjusted */ for (ebo = edbo->first; ebo; ebo = ebo->next) { ebo_parent = (ebo->flag & BONE_CONNECTED) ? ebo->parent : NULL; - + if (ebo_parent) { /* If this bone has a parent tip that has been moved */ if (ebo_parent->flag & BONE_TIPSEL) { @@ -832,7 +853,7 @@ static void recalcData_objects(TransInfo *t) 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++) { + for (i = 0; i < tc->data_len; i++, td++) { if (td->extra) { float vec[3], up_axis[3]; float qrot[4]; @@ -859,23 +880,32 @@ static void recalcData_objects(TransInfo *t) } } } - + if (arm->flag & ARM_MIRROR_EDIT) { - if (t->state != TRANS_CANCEL) - ED_armature_edit_transform_mirror_update(t->obedit); - else - restoreBones(t); + if (t->state != TRANS_CANCEL) { + ED_armature_edit_transform_mirror_update(tc->obedit); + } + else { + restoreBones(tc); + } + } } } else { if (t->state != TRANS_CANCEL) { applyProject(t); } - DEG_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; + 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, @@ -900,6 +930,7 @@ static void recalcData_objects(TransInfo *t) } else BKE_pose_where_is(&t->eval_ctx, t->scene, ob); + } } else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(t->scene, base->object)) @@ -915,9 +946,11 @@ static void recalcData_objects(TransInfo *t) if (t->state != TRANS_CANCEL) { applyProject(t); } - - for (i = 0; i < t->total; i++) { - TransData *td = t->data + i; + + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + TransData *td = tc->data; + + for (i = 0; i < tc->data_len; i++, td++) { Object *ob = td->ob; if (td->flag & TD_NOACTION) @@ -944,6 +977,7 @@ static void recalcData_objects(TransInfo *t) if (t->flag & T_TEXTURE) DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } + } } } @@ -954,7 +988,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; @@ -979,8 +1015,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; @@ -1078,11 +1116,17 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis */ void resetTransModal(TransInfo *t) { + FOREACH_TRANS_DATA_CONTAINER (t, tc) { if (t->mode == TFM_EDGE_SLIDE) { - freeEdgeSlideVerts(t, &t->custom.mode); + freeEdgeSlideVerts(t, tc, &tc->custom.mode); } else if (t->mode == TFM_VERT_SLIDE) { - freeVertSlideVerts(t, &t->custom.mode); + freeVertSlideVerts(t, tc, &tc->custom.mode); + } + else { + /* no need to keep looping... */ + break; + } } } @@ -1105,6 +1149,40 @@ 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]; + copy_m3_m4(tc->obedit_mat, tc->obedit->obmat); + normalize_m3(tc->obedit_mat); + } + else if (object_mode & OB_MODE_POSE) { + tc->poseobj = objects[i]; + } + } + MEM_freeN(objects); + } +} + /** * Setup internal data, mouse, vectors * @@ -1118,11 +1196,12 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve 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); RenderEngineType *engine_type = CTX_data_engine_type(C); PropertyRNA *prop; @@ -1133,22 +1212,21 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve t->engine_type = engine_type; 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) { @@ -1169,12 +1247,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); @@ -1260,13 +1337,13 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve 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; @@ -1295,7 +1372,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) { @@ -1385,7 +1462,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; } @@ -1406,7 +1484,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) { @@ -1421,7 +1499,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; } } @@ -1467,8 +1545,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; } @@ -1476,11 +1554,25 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve initNumInput(&t->num); } +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++) { + 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; + } + } +} + /* 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) @@ -1491,46 +1583,37 @@ void postTrans(bContext *C, TransInfo *t) WM_paint_cursor_end(CTX_wm_manager(C), t->draw_handle_cursor); /* 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); } + MEM_SAFE_FREE(t->data_container); + t->data_container = NULL; + BLI_freelistN(&t->tsnap.points); - if (t->ext) MEM_freeN(t->ext); - if (t->data2d) { - MEM_freeN(t->data2d); - t->data2d = NULL; - } - if (t->spacetype == SPACE_IMAGE) { if (t->options & (CTX_MASK | CTX_PAINT_CURVE)) { /* pass */ @@ -1558,9 +1641,11 @@ void postTrans(bContext *C, TransInfo *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); @@ -1609,14 +1694,16 @@ static void restoreElement(TransData *td) void restoreTransObjects(TransInfo *t) { + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + TransData *td; TransData2D *td2d; - for (td = t->data; td < t->data + t->total; td++) { + for (td = tc->data; td < tc->data + tc->data_len; td++) { restoreElement(td); } - for (td2d = t->data2d; t->data2d && td2d < t->data2d + t->total; td2d++) { + 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]; @@ -1628,6 +1715,8 @@ void restoreTransObjects(TransInfo *t) } unit_m3(t->mat); + + } recalcData(t); } @@ -1635,32 +1724,26 @@ 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); + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + float obinv[4][4]; + Object *ob = tc->obedit ? tc->obedit : tc->poseobj; + invert_m4_m4(obinv, ob->obmat); + mul_v3_m4v3(tc->center_local, obinv, center_global); + } } else { - copy_v3_v3(r_center_global, center_local); + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + copy_v3_v3(tc->center_local, center_global); + } } } @@ -1672,16 +1755,7 @@ void calculateCenterCursor(TransInfo *t, float r_center[3]) 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; @@ -1755,16 +1829,26 @@ void calculateCenterMedian(TransInfo *t, float r_center[3]) { float partial[3] = {0.0f, 0.0f, 0.0f}; int total = 0; + + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + Object *ob_xform = tc->obedit ? tc->obedit : tc->poseobj; 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); + for (i = 0; i < tc->data_len; i++) { + if (tc->data[i].flag & TD_SELECTED) { + if (!(tc->data[i].flag & TD_NOCENTER)) { + if (ob_xform) { + float v[3]; + mul_v3_m4v3(v, ob_xform->obmat, tc->data[i].center); + add_v3_v3(partial, v); + } + else { + add_v3_v3(partial, tc->data[i].center); + } total++; } } } + } if (total) { mul_v3_fl(partial, 1.0f / (float)total); } @@ -1776,18 +1860,31 @@ 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); + bool is_first = true; + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + Object *ob_xform = tc->obedit ? tc->obedit : tc->poseobj; + for (i = 0; i < tc->data_len; i++) { + if (is_first == false) { + if (tc->data[i].flag & TD_SELECTED) { + if (!(tc->data[i].flag & TD_NOCENTER)) { + if (ob_xform) { + float v[3]; + mul_v3_m4v3(v, ob_xform->obmat, tc->data[i].center); + minmax_v3v3_v3(min, max, v); + } + else { + minmax_v3v3_v3(min, max, tc->data[i].center); + } + } } + is_first = false; } else { - copy_v3_v3(max, t->data[i].center); - copy_v3_v3(min, t->data[i].center); + copy_v3_v3(max, tc->data[i].center); + copy_v3_v3(min, tc->data[i].center); } } + } mid_v3_v3v3(r_center, min, max); } @@ -1796,10 +1893,13 @@ 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; } } @@ -1810,6 +1910,7 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3]) 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(tc->obedit->obmat, r_center); ok = true; } } @@ -1874,14 +1975,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; } @@ -1899,16 +1999,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); } } } @@ -1942,8 +2041,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; @@ -1951,7 +2049,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; @@ -1960,7 +2057,9 @@ void calculatePropRatio(TransInfo *t) if (t->flag & T_PROP_EDIT) { const char *pet_id = NULL; - for (i = 0; i < t->total; i++, td++) { + 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; } @@ -2029,6 +2128,8 @@ void calculatePropRatio(TransInfo *t) } } } + } + switch (t->prop_mode) { case PROP_SHARP: pet_id = N_("(Sharp)"); @@ -2063,8 +2164,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; + } } } } |