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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/transform/transform_generics.c')
-rw-r--r--source/blender/editors/transform/transform_generics.c450
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;
+ }
}
}
}