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.c4171
1 files changed, 2089 insertions, 2082 deletions
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 0f7992e0b4a..46e8447efc6 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -113,1063 +113,1070 @@
void getViewVector(const TransInfo *t, const float coord[3], float vec[3])
{
- if (t->persp != RV3D_ORTHO) {
- sub_v3_v3v3(vec, coord, t->viewinv[3]);
- }
- else {
- copy_v3_v3(vec, t->viewinv[2]);
- }
- normalize_v3(vec);
+ if (t->persp != RV3D_ORTHO) {
+ sub_v3_v3v3(vec, coord, t->viewinv[3]);
+ }
+ else {
+ copy_v3_v3(vec, t->viewinv[2]);
+ }
+ normalize_v3(vec);
}
/* ************************** GENERICS **************************** */
-
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;
-
- 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];
-
- invert_m4_m4(obinv, mmd->mirror_ob->obmat);
- mul_m4_m4m4(mtx, obinv, ob->obmat);
- invert_m4_m4(imtx, mtx);
- }
-
- 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_SKIP)
- continue;
-
- 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);
- }
-
- 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 & 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);
- }
- copy_v3_v3(td->loc, loc);
- }
- }
- }
-
- }
- }
- }
- }
+ 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];
+
+ invert_m4_m4(obinv, mmd->mirror_ob->obmat);
+ mul_m4_m4m4(mtx, obinv, ob->obmat);
+ invert_m4_m4(imtx, mtx);
+ }
+
+ 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_SKIP)
+ continue;
+
+ 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);
+ }
+
+ 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 & 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);
+ }
+ copy_v3_v3(td->loc, loc);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
/* assumes obedit set to mesh object */
static void editbmesh_apply_to_mirror(TransInfo *t)
{
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- if (tc->mirror.axis_flag) {
- TransData *td = tc->data;
- BMVert *eve;
- int i;
-
- 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];
- }
-
- if (td->flag & TD_MIRROR_EDGE) {
- td->loc[0] = 0;
- }
- }
- }
- }
+ FOREACH_TRANS_DATA_CONTAINER(t, tc)
+ {
+ if (tc->mirror.axis_flag) {
+ TransData *td = tc->data;
+ BMVert *eve;
+ int i;
+
+ 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];
+ }
+
+ if (td->flag & TD_MIRROR_EDGE) {
+ td->loc[0] = 0;
+ }
+ }
+ }
+ }
}
/* for the realtime animation recording feature, handle overlapping data */
static void animrecord_check_state(Scene *scene, ID *id, wmTimer *animtimer)
{
- ScreenAnimData *sad = (animtimer) ? animtimer->customdata : NULL;
-
- /* sanity checks */
- if (ELEM(NULL, scene, id, sad))
- return;
-
- /* check if we need a new strip if:
- * - if animtimer is running
- * - we're not only keying for available channels
- * - the option to add new actions for each round is not enabled
- */
- if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL) == 0 && (scene->toolsettings->autokey_flag & ANIMRECORD_FLAG_WITHNLA)) {
- /* if playback has just looped around,
- * we need to add a new NLA track+strip to allow a clean pass to occur */
- if ((sad) && (sad->flag & ANIMPLAY_FLAG_JUMPED)) {
- AnimData *adt = BKE_animdata_from_id(id);
- const bool is_first = (adt) && (adt->nla_tracks.first == NULL);
-
- /* perform push-down manually with some differences
- * NOTE: BKE_nla_action_pushdown() sync warning...
- */
- if ((adt->action) && !(adt->flag & ADT_NLA_EDIT_ON)) {
- float astart, aend;
-
- /* only push down if action is more than 1-2 frames long */
- calc_action_range(adt->action, &astart, &aend, 1);
- if (aend > astart + 2.0f) {
- NlaStrip *strip = BKE_nlastack_add_strip(adt, adt->action);
-
- /* clear reference to action now that we've pushed it onto the stack */
- id_us_min(&adt->action->id);
- adt->action = NULL;
-
- /* adjust blending + extend so that they will behave correctly */
- strip->extendmode = NLASTRIP_EXTEND_NOTHING;
- strip->flag &= ~(NLASTRIP_FLAG_AUTO_BLENDS | NLASTRIP_FLAG_SELECT | NLASTRIP_FLAG_ACTIVE);
-
- /* copy current "action blending" settings from adt to the strip,
- * as it was keyframed with these settings, so omitting them will
- * change the effect [T54766]
- */
- if (is_first == false) {
- strip->blendmode = adt->act_blendmode;
- strip->influence = adt->act_influence;
-
- if (adt->act_influence < 1.0f) {
- /* enable "user-controlled" influence (which will insert a default keyframe)
- * so that the influence doesn't get lost on the new update
- *
- * NOTE: An alternative way would have been to instead hack the influence
- * to not get always get reset to full strength if NLASTRIP_FLAG_USR_INFLUENCE
- * is disabled but auto-blending isn't being used. However, that approach
- * is a bit hacky/hard to discover, and may cause backwards compatibility issues,
- * so it's better to just do it this way.
- */
- strip->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
- BKE_nlastrip_validate_fcurves(strip);
- }
- }
-
- /* also, adjust the AnimData's action extend mode to be on
- * 'nothing' so that previous result still play
- */
- adt->act_extendmode = NLASTRIP_EXTEND_NOTHING;
- }
- }
- }
- }
+ ScreenAnimData *sad = (animtimer) ? animtimer->customdata : NULL;
+
+ /* sanity checks */
+ if (ELEM(NULL, scene, id, sad))
+ return;
+
+ /* check if we need a new strip if:
+ * - if animtimer is running
+ * - we're not only keying for available channels
+ * - the option to add new actions for each round is not enabled
+ */
+ if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL) == 0 &&
+ (scene->toolsettings->autokey_flag & ANIMRECORD_FLAG_WITHNLA)) {
+ /* if playback has just looped around,
+ * we need to add a new NLA track+strip to allow a clean pass to occur */
+ if ((sad) && (sad->flag & ANIMPLAY_FLAG_JUMPED)) {
+ AnimData *adt = BKE_animdata_from_id(id);
+ const bool is_first = (adt) && (adt->nla_tracks.first == NULL);
+
+ /* perform push-down manually with some differences
+ * NOTE: BKE_nla_action_pushdown() sync warning...
+ */
+ if ((adt->action) && !(adt->flag & ADT_NLA_EDIT_ON)) {
+ float astart, aend;
+
+ /* only push down if action is more than 1-2 frames long */
+ calc_action_range(adt->action, &astart, &aend, 1);
+ if (aend > astart + 2.0f) {
+ NlaStrip *strip = BKE_nlastack_add_strip(adt, adt->action);
+
+ /* clear reference to action now that we've pushed it onto the stack */
+ id_us_min(&adt->action->id);
+ adt->action = NULL;
+
+ /* adjust blending + extend so that they will behave correctly */
+ strip->extendmode = NLASTRIP_EXTEND_NOTHING;
+ strip->flag &= ~(NLASTRIP_FLAG_AUTO_BLENDS | NLASTRIP_FLAG_SELECT |
+ NLASTRIP_FLAG_ACTIVE);
+
+ /* copy current "action blending" settings from adt to the strip,
+ * as it was keyframed with these settings, so omitting them will
+ * change the effect [T54766]
+ */
+ if (is_first == false) {
+ strip->blendmode = adt->act_blendmode;
+ strip->influence = adt->act_influence;
+
+ if (adt->act_influence < 1.0f) {
+ /* enable "user-controlled" influence (which will insert a default keyframe)
+ * so that the influence doesn't get lost on the new update
+ *
+ * NOTE: An alternative way would have been to instead hack the influence
+ * to not get always get reset to full strength if NLASTRIP_FLAG_USR_INFLUENCE
+ * is disabled but auto-blending isn't being used. However, that approach
+ * is a bit hacky/hard to discover, and may cause backwards compatibility issues,
+ * so it's better to just do it this way.
+ */
+ strip->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
+ BKE_nlastrip_validate_fcurves(strip);
+ }
+ }
+
+ /* also, adjust the AnimData's action extend mode to be on
+ * 'nothing' so that previous result still play
+ */
+ adt->act_extendmode = NLASTRIP_EXTEND_NOTHING;
+ }
+ }
+ }
+ }
}
static bool fcu_test_selected(FCurve *fcu)
{
- BezTriple *bezt = fcu->bezt;
- unsigned int i;
+ BezTriple *bezt = fcu->bezt;
+ unsigned int i;
- if (bezt == NULL) /* ignore baked */
- return 0;
+ if (bezt == NULL) /* ignore baked */
+ return 0;
- for (i = 0; i < fcu->totvert; i++, bezt++) {
- if (BEZT_ISSEL_ANY(bezt)) return 1;
- }
+ for (i = 0; i < fcu->totvert; i++, bezt++) {
+ if (BEZT_ISSEL_ANY(bezt))
+ return 1;
+ }
- return 0;
+ return 0;
}
/* helper for recalcData() - for Action Editor transforms */
static void recalcData_actedit(TransInfo *t)
{
- ViewLayer *view_layer = t->view_layer;
- SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first;
-
- bAnimContext ac = {NULL};
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* 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);
- 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;
- ac.spacetype = (t->sa) ? t->sa->spacetype : 0;
- ac.regiontype = (t->ar) ? t->ar->regiontype : 0;
-
- ANIM_animdata_context_getdata(&ac);
-
- /* perform flush */
- if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- /* flush transform values back to actual coordinates */
- flushTransIntFrameActionData(t);
- }
-
- if (ac.datatype != ANIMCONT_MASK) {
- /* get animdata blocks visible in editor, assuming that these will be the ones where things changed */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ANIMDATA);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- /* just tag these animdata-blocks to recalc, assuming that some data there changed
- * BUT only do this if realtime updates are enabled
- */
- 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), t->scene, ale);
- }
- }
-
- /* now free temp channels */
- ANIM_animdata_freelist(&anim_data);
- }
+ ViewLayer *view_layer = t->view_layer;
+ SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first;
+
+ bAnimContext ac = {NULL};
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* 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);
+ 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;
+ ac.spacetype = (t->sa) ? t->sa->spacetype : 0;
+ ac.regiontype = (t->ar) ? t->ar->regiontype : 0;
+
+ ANIM_animdata_context_getdata(&ac);
+
+ /* perform flush */
+ if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ /* flush transform values back to actual coordinates */
+ flushTransIntFrameActionData(t);
+ }
+
+ if (ac.datatype != ANIMCONT_MASK) {
+ /* get animdata blocks visible in editor, assuming that these will be the ones where things changed */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ANIMDATA);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* just tag these animdata-blocks to recalc, assuming that some data there changed
+ * BUT only do this if realtime updates are enabled
+ */
+ 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), t->scene, ale);
+ }
+ }
+
+ /* now free temp channels */
+ ANIM_animdata_freelist(&anim_data);
+ }
}
/* helper for recalcData() - for Graph Editor transforms */
static void recalcData_graphedit(TransInfo *t)
{
- SpaceGraph *sipo = (SpaceGraph *)t->sa->spacedata.first;
- ViewLayer *view_layer = t->view_layer;
-
- ListBase anim_data = {NULL, NULL};
- bAnimContext ac = {NULL};
- int filter;
-
- bAnimListElem *ale;
- int dosort = 0;
-
- /* 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);
- 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;
- ac.spacetype = (t->sa) ? t->sa->spacetype : 0;
- ac.regiontype = (t->ar) ? t->ar->regiontype : 0;
-
- ANIM_animdata_context_getdata(&ac);
-
- /* do the flush first */
- flushTransGraphData(t);
-
- /* get curves to check if a re-sort is needed */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- /* now test if there is a need to re-sort */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
-
- /* ignore FC-Curves without any selected verts */
- if (!fcu_test_selected(fcu))
- continue;
-
- /* watch it: if the time is wrong: do not correct handles yet */
- if (test_time_fcurve(fcu))
- dosort++;
- else
- calchandles_fcurve(fcu);
-
- /* set refresh tags for objects using this animation,
- * BUT only if realtime updates are enabled
- */
- if ((sipo->flag & SIPO_NOREALTIMEUPDATES) == 0)
- ANIM_list_elem_update(CTX_data_main(t->context), t->scene, ale);
- }
-
- /* do resort and other updates? */
- if (dosort) remake_graph_transdata(t, &anim_data);
-
- /* now free temp channels */
- ANIM_animdata_freelist(&anim_data);
+ SpaceGraph *sipo = (SpaceGraph *)t->sa->spacedata.first;
+ ViewLayer *view_layer = t->view_layer;
+
+ ListBase anim_data = {NULL, NULL};
+ bAnimContext ac = {NULL};
+ int filter;
+
+ bAnimListElem *ale;
+ int dosort = 0;
+
+ /* 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);
+ 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;
+ ac.spacetype = (t->sa) ? t->sa->spacetype : 0;
+ ac.regiontype = (t->ar) ? t->ar->regiontype : 0;
+
+ ANIM_animdata_context_getdata(&ac);
+
+ /* do the flush first */
+ flushTransGraphData(t);
+
+ /* get curves to check if a re-sort is needed */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* now test if there is a need to re-sort */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
+
+ /* ignore FC-Curves without any selected verts */
+ if (!fcu_test_selected(fcu))
+ continue;
+
+ /* watch it: if the time is wrong: do not correct handles yet */
+ if (test_time_fcurve(fcu))
+ dosort++;
+ else
+ calchandles_fcurve(fcu);
+
+ /* set refresh tags for objects using this animation,
+ * BUT only if realtime updates are enabled
+ */
+ if ((sipo->flag & SIPO_NOREALTIMEUPDATES) == 0)
+ ANIM_list_elem_update(CTX_data_main(t->context), t->scene, ale);
+ }
+
+ /* do resort and other updates? */
+ if (dosort)
+ remake_graph_transdata(t, &anim_data);
+
+ /* now free temp channels */
+ ANIM_animdata_freelist(&anim_data);
}
/* helper for recalcData() - for NLA Editor transforms */
static void recalcData_nla(TransInfo *t)
{
- SpaceNla *snla = (SpaceNla *)t->sa->spacedata.first;
- Scene *scene = t->scene;
- double secf = FPS;
- int i;
-
- TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
- TransDataNla *tdn = tc->custom.type.data;
-
- /* 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 < tc->data_len; i++, tdn++) {
- NlaStrip *strip = tdn->strip;
- PointerRNA strip_ptr;
- short pExceeded, nExceeded, iter;
- int delta_y1, delta_y2;
-
- /* if this tdn has no handles, that means it is just a dummy that should be skipped */
- if (tdn->handle == 0)
- continue;
-
- /* set refresh tags for objects using this animation,
- * BUT only if realtime updates are enabled
- */
- if ((snla->flag & SNLA_NOREALTIMEUPDATES) == 0)
- ANIM_id_update(CTX_data_main(t->context), tdn->id);
-
- /* if canceling transform, just write the values without validating, then move on */
- if (t->state == TRANS_CANCEL) {
- /* clear the values by directly overwriting the originals, but also need to restore
- * endpoints of neighboring transition-strips
- */
-
- /* start */
- strip->start = tdn->h1[0];
-
- if ((strip->prev) && (strip->prev->type == NLASTRIP_TYPE_TRANSITION))
- strip->prev->end = tdn->h1[0];
-
- /* end */
- strip->end = tdn->h2[0];
-
- if ((strip->next) && (strip->next->type == NLASTRIP_TYPE_TRANSITION))
- strip->next->start = tdn->h2[0];
-
- /* flush transforms to child strips (since this should be a meta) */
- BKE_nlameta_flush_transforms(strip);
-
- /* restore to original track (if needed) */
- if (tdn->oldTrack != tdn->nlt) {
- /* just append to end of list for now, since strips get sorted in special_aftertrans_update() */
- BLI_remlink(&tdn->nlt->strips, strip);
- BLI_addtail(&tdn->oldTrack->strips, strip);
- }
-
- continue;
- }
-
- /* firstly, check if the proposed transform locations would overlap with any neighboring strips
- * (barring transitions) which are absolute barriers since they are not being moved
- *
- * this is done as a iterative procedure (done 5 times max for now)
- */
- for (iter = 0; iter < 5; iter++) {
- pExceeded = ((strip->prev) && (strip->prev->type != NLASTRIP_TYPE_TRANSITION) && (tdn->h1[0] < strip->prev->end));
- nExceeded = ((strip->next) && (strip->next->type != NLASTRIP_TYPE_TRANSITION) && (tdn->h2[0] > strip->next->start));
-
- if ((pExceeded && nExceeded) || (iter == 4)) {
- /* both endpoints exceeded (or iteration ping-pong'd meaning that we need a compromise)
- * - simply crop strip to fit within the bounds of the strips bounding it
- * - if there were no neighbors, clear the transforms (make it default to the strip's current values)
- */
- if (strip->prev && strip->next) {
- tdn->h1[0] = strip->prev->end;
- tdn->h2[0] = strip->next->start;
- }
- else {
- tdn->h1[0] = strip->start;
- tdn->h2[0] = strip->end;
- }
- }
- else if (nExceeded) {
- /* move backwards */
- float offset = tdn->h2[0] - strip->next->start;
-
- tdn->h1[0] -= offset;
- tdn->h2[0] -= offset;
- }
- else if (pExceeded) {
- /* more forwards */
- float offset = strip->prev->end - tdn->h1[0];
-
- tdn->h1[0] += offset;
- tdn->h2[0] += offset;
- }
- else /* all is fine and well */
- break;
- }
-
- /* handle auto-snapping
- * NOTE: only do this when transform is still running, or we can't restore
- */
- if (t->state != TRANS_CANCEL) {
- switch (snla->autosnap) {
- case SACTSNAP_FRAME: /* snap to nearest frame */
- case SACTSNAP_STEP: /* frame step - this is basically the same,
- * since we don't have any remapping going on */
- {
- tdn->h1[0] = floorf(tdn->h1[0] + 0.5f);
- tdn->h2[0] = floorf(tdn->h2[0] + 0.5f);
- break;
- }
-
- case SACTSNAP_SECOND: /* snap to nearest second */
- case SACTSNAP_TSTEP: /* second step - this is basically the same,
- * since we don't have any remapping going on */
- {
- /* This case behaves differently from the rest, since lengths of strips
- * may not be multiples of a second. If we just naively resize adjust
- * the handles, things may not work correctly. Instead, we only snap
- * the first handle, and move the other to fit.
- *
- * FIXME: we do run into problems here when user attempts to negatively
- * scale the strip, as it then just compresses down and refuses
- * to expand out the other end.
- */
- float h1_new = (float)(floor(((double)tdn->h1[0] / secf) + 0.5) * secf);
- float delta = h1_new - tdn->h1[0];
-
- tdn->h1[0] = h1_new;
- tdn->h2[0] += delta;
- break;
- }
-
- case SACTSNAP_MARKER: /* snap to nearest marker */
- {
- tdn->h1[0] = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h1[0]);
- tdn->h2[0] = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h2[0]);
- break;
- }
- }
- }
-
- /* Use RNA to write the values to ensure that constraints on these are obeyed
- * (e.g. for transition strips, the values are taken from the neighbors)
- *
- * NOTE: we write these twice to avoid truncation errors which can arise when
- * moving the strips a large distance using numeric input [#33852]
- */
- RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
-
- RNA_float_set(&strip_ptr, "frame_start", tdn->h1[0]);
- RNA_float_set(&strip_ptr, "frame_end", tdn->h2[0]);
-
- RNA_float_set(&strip_ptr, "frame_start", tdn->h1[0]);
- RNA_float_set(&strip_ptr, "frame_end", tdn->h2[0]);
-
- /* flush transforms to child strips (since this should be a meta) */
- BKE_nlameta_flush_transforms(strip);
-
-
- /* now, check if we need to try and move track
- * - we need to calculate both, as only one may have been altered by transform if only 1 handle moved
- */
- delta_y1 = ((int)tdn->h1[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex);
- delta_y2 = ((int)tdn->h2[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex);
-
- if (delta_y1 || delta_y2) {
- NlaTrack *track;
- int delta = (delta_y2) ? delta_y2 : delta_y1;
- int n;
-
- /* move in the requested direction, checking at each layer if there's space for strip to pass through,
- * stopping on the last track available or that we're able to fit in
- */
- if (delta > 0) {
- for (track = tdn->nlt->next, n = 0; (track) && (n < delta); track = track->next, n++) {
- /* check if space in this track for the strip */
- if (BKE_nlatrack_has_space(track, strip->start, strip->end)) {
- /* move strip to this track */
- BLI_remlink(&tdn->nlt->strips, strip);
- BKE_nlatrack_add_strip(track, strip);
-
- tdn->nlt = track;
- tdn->trackIndex++;
- }
- else /* can't move any further */
- break;
- }
- }
- else {
- /* make delta 'positive' before using it, since we now know to go backwards */
- delta = -delta;
-
- for (track = tdn->nlt->prev, n = 0; (track) && (n < delta); track = track->prev, n++) {
- /* check if space in this track for the strip */
- if (BKE_nlatrack_has_space(track, strip->start, strip->end)) {
- /* move strip to this track */
- BLI_remlink(&tdn->nlt->strips, strip);
- BKE_nlatrack_add_strip(track, strip);
-
- tdn->nlt = track;
- tdn->trackIndex--;
- }
- else /* can't move any further */
- break;
- }
- }
- }
- }
+ SpaceNla *snla = (SpaceNla *)t->sa->spacedata.first;
+ Scene *scene = t->scene;
+ double secf = FPS;
+ int i;
+
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+ TransDataNla *tdn = tc->custom.type.data;
+
+ /* 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 < tc->data_len; i++, tdn++) {
+ NlaStrip *strip = tdn->strip;
+ PointerRNA strip_ptr;
+ short pExceeded, nExceeded, iter;
+ int delta_y1, delta_y2;
+
+ /* if this tdn has no handles, that means it is just a dummy that should be skipped */
+ if (tdn->handle == 0)
+ continue;
+
+ /* set refresh tags for objects using this animation,
+ * BUT only if realtime updates are enabled
+ */
+ if ((snla->flag & SNLA_NOREALTIMEUPDATES) == 0)
+ ANIM_id_update(CTX_data_main(t->context), tdn->id);
+
+ /* if canceling transform, just write the values without validating, then move on */
+ if (t->state == TRANS_CANCEL) {
+ /* clear the values by directly overwriting the originals, but also need to restore
+ * endpoints of neighboring transition-strips
+ */
+
+ /* start */
+ strip->start = tdn->h1[0];
+
+ if ((strip->prev) && (strip->prev->type == NLASTRIP_TYPE_TRANSITION))
+ strip->prev->end = tdn->h1[0];
+
+ /* end */
+ strip->end = tdn->h2[0];
+
+ if ((strip->next) && (strip->next->type == NLASTRIP_TYPE_TRANSITION))
+ strip->next->start = tdn->h2[0];
+
+ /* flush transforms to child strips (since this should be a meta) */
+ BKE_nlameta_flush_transforms(strip);
+
+ /* restore to original track (if needed) */
+ if (tdn->oldTrack != tdn->nlt) {
+ /* just append to end of list for now, since strips get sorted in special_aftertrans_update() */
+ BLI_remlink(&tdn->nlt->strips, strip);
+ BLI_addtail(&tdn->oldTrack->strips, strip);
+ }
+
+ continue;
+ }
+
+ /* firstly, check if the proposed transform locations would overlap with any neighboring strips
+ * (barring transitions) which are absolute barriers since they are not being moved
+ *
+ * this is done as a iterative procedure (done 5 times max for now)
+ */
+ for (iter = 0; iter < 5; iter++) {
+ pExceeded = ((strip->prev) && (strip->prev->type != NLASTRIP_TYPE_TRANSITION) &&
+ (tdn->h1[0] < strip->prev->end));
+ nExceeded = ((strip->next) && (strip->next->type != NLASTRIP_TYPE_TRANSITION) &&
+ (tdn->h2[0] > strip->next->start));
+
+ if ((pExceeded && nExceeded) || (iter == 4)) {
+ /* both endpoints exceeded (or iteration ping-pong'd meaning that we need a compromise)
+ * - simply crop strip to fit within the bounds of the strips bounding it
+ * - if there were no neighbors, clear the transforms (make it default to the strip's current values)
+ */
+ if (strip->prev && strip->next) {
+ tdn->h1[0] = strip->prev->end;
+ tdn->h2[0] = strip->next->start;
+ }
+ else {
+ tdn->h1[0] = strip->start;
+ tdn->h2[0] = strip->end;
+ }
+ }
+ else if (nExceeded) {
+ /* move backwards */
+ float offset = tdn->h2[0] - strip->next->start;
+
+ tdn->h1[0] -= offset;
+ tdn->h2[0] -= offset;
+ }
+ else if (pExceeded) {
+ /* more forwards */
+ float offset = strip->prev->end - tdn->h1[0];
+
+ tdn->h1[0] += offset;
+ tdn->h2[0] += offset;
+ }
+ else /* all is fine and well */
+ break;
+ }
+
+ /* handle auto-snapping
+ * NOTE: only do this when transform is still running, or we can't restore
+ */
+ if (t->state != TRANS_CANCEL) {
+ switch (snla->autosnap) {
+ case SACTSNAP_FRAME: /* snap to nearest frame */
+ case SACTSNAP_STEP: /* frame step - this is basically the same,
+ * since we don't have any remapping going on */
+ {
+ tdn->h1[0] = floorf(tdn->h1[0] + 0.5f);
+ tdn->h2[0] = floorf(tdn->h2[0] + 0.5f);
+ break;
+ }
+
+ case SACTSNAP_SECOND: /* snap to nearest second */
+ case SACTSNAP_TSTEP: /* second step - this is basically the same,
+ * since we don't have any remapping going on */
+ {
+ /* This case behaves differently from the rest, since lengths of strips
+ * may not be multiples of a second. If we just naively resize adjust
+ * the handles, things may not work correctly. Instead, we only snap
+ * the first handle, and move the other to fit.
+ *
+ * FIXME: we do run into problems here when user attempts to negatively
+ * scale the strip, as it then just compresses down and refuses
+ * to expand out the other end.
+ */
+ float h1_new = (float)(floor(((double)tdn->h1[0] / secf) + 0.5) * secf);
+ float delta = h1_new - tdn->h1[0];
+
+ tdn->h1[0] = h1_new;
+ tdn->h2[0] += delta;
+ break;
+ }
+
+ case SACTSNAP_MARKER: /* snap to nearest marker */
+ {
+ tdn->h1[0] = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h1[0]);
+ tdn->h2[0] = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h2[0]);
+ break;
+ }
+ }
+ }
+
+ /* Use RNA to write the values to ensure that constraints on these are obeyed
+ * (e.g. for transition strips, the values are taken from the neighbors)
+ *
+ * NOTE: we write these twice to avoid truncation errors which can arise when
+ * moving the strips a large distance using numeric input [#33852]
+ */
+ RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
+
+ RNA_float_set(&strip_ptr, "frame_start", tdn->h1[0]);
+ RNA_float_set(&strip_ptr, "frame_end", tdn->h2[0]);
+
+ RNA_float_set(&strip_ptr, "frame_start", tdn->h1[0]);
+ RNA_float_set(&strip_ptr, "frame_end", tdn->h2[0]);
+
+ /* flush transforms to child strips (since this should be a meta) */
+ BKE_nlameta_flush_transforms(strip);
+
+ /* now, check if we need to try and move track
+ * - we need to calculate both, as only one may have been altered by transform if only 1 handle moved
+ */
+ delta_y1 = ((int)tdn->h1[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex);
+ delta_y2 = ((int)tdn->h2[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex);
+
+ if (delta_y1 || delta_y2) {
+ NlaTrack *track;
+ int delta = (delta_y2) ? delta_y2 : delta_y1;
+ int n;
+
+ /* move in the requested direction, checking at each layer if there's space for strip to pass through,
+ * stopping on the last track available or that we're able to fit in
+ */
+ if (delta > 0) {
+ for (track = tdn->nlt->next, n = 0; (track) && (n < delta); track = track->next, n++) {
+ /* check if space in this track for the strip */
+ if (BKE_nlatrack_has_space(track, strip->start, strip->end)) {
+ /* move strip to this track */
+ BLI_remlink(&tdn->nlt->strips, strip);
+ BKE_nlatrack_add_strip(track, strip);
+
+ tdn->nlt = track;
+ tdn->trackIndex++;
+ }
+ else /* can't move any further */
+ break;
+ }
+ }
+ else {
+ /* make delta 'positive' before using it, since we now know to go backwards */
+ delta = -delta;
+
+ for (track = tdn->nlt->prev, n = 0; (track) && (n < delta); track = track->prev, n++) {
+ /* check if space in this track for the strip */
+ if (BKE_nlatrack_has_space(track, strip->start, strip->end)) {
+ /* move strip to this track */
+ BLI_remlink(&tdn->nlt->strips, strip);
+ BKE_nlatrack_add_strip(track, strip);
+
+ tdn->nlt = track;
+ tdn->trackIndex--;
+ }
+ else /* can't move any further */
+ break;
+ }
+ }
+ }
+ }
}
static void recalcData_mask_common(TransInfo *t)
{
- Mask *mask = CTX_data_edit_mask(t->context);
+ Mask *mask = CTX_data_edit_mask(t->context);
- flushTransMasking(t);
+ flushTransMasking(t);
- DEG_id_tag_update(&mask->id, 0);
+ DEG_id_tag_update(&mask->id, 0);
}
/* helper for recalcData() - for Image Editor transforms */
static void recalcData_image(TransInfo *t)
{
- if (t->options & CTX_MASK) {
- recalcData_mask_common(t);
- }
- else if (t->options & CTX_PAINT_CURVE) {
- flushTransPaintCurve(t);
- }
- 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();
-
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- if (tc->data_len) {
- DEG_id_tag_update(tc->obedit->data, 0);
- }
- }
- }
+ if (t->options & CTX_MASK) {
+ recalcData_mask_common(t);
+ }
+ else if (t->options & CTX_PAINT_CURVE) {
+ flushTransPaintCurve(t);
+ }
+ 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();
+
+ FOREACH_TRANS_DATA_CONTAINER(t, tc)
+ {
+ if (tc->data_len) {
+ DEG_id_tag_update(tc->obedit->data, 0);
+ }
+ }
+ }
}
/* helper for recalcData() - for Movie Clip transforms */
static void recalcData_spaceclip(TransInfo *t)
{
- SpaceClip *sc = t->sa->spacedata.first;
-
- if (ED_space_clip_check_show_trackedit(sc)) {
- MovieClip *clip = ED_space_clip_get_clip(sc);
- ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
- MovieTrackingTrack *track;
- int framenr = ED_space_clip_get_clip_frame_number(sc);
-
- flushTransTracking(t);
-
- track = tracksbase->first;
- while (track) {
- if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
- MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
-
- if (t->mode == TFM_TRANSLATION) {
- if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
- BKE_tracking_marker_clamp(marker, CLAMP_PAT_POS);
- if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))
- BKE_tracking_marker_clamp(marker, CLAMP_SEARCH_POS);
- }
- else if (t->mode == TFM_RESIZE) {
- if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
- BKE_tracking_marker_clamp(marker, CLAMP_PAT_DIM);
- if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))
- BKE_tracking_marker_clamp(marker, CLAMP_SEARCH_DIM);
- }
- else if (t->mode == TFM_ROTATION) {
- if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
- BKE_tracking_marker_clamp(marker, CLAMP_PAT_POS);
- }
- }
-
- track = track->next;
- }
-
- DEG_id_tag_update(&clip->id, 0);
- }
- else if (t->options & CTX_MASK) {
- recalcData_mask_common(t);
- }
+ SpaceClip *sc = t->sa->spacedata.first;
+
+ if (ED_space_clip_check_show_trackedit(sc)) {
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
+ MovieTrackingTrack *track;
+ int framenr = ED_space_clip_get_clip_frame_number(sc);
+
+ flushTransTracking(t);
+
+ track = tracksbase->first;
+ while (track) {
+ if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
+ MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
+
+ if (t->mode == TFM_TRANSLATION) {
+ if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
+ BKE_tracking_marker_clamp(marker, CLAMP_PAT_POS);
+ if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))
+ BKE_tracking_marker_clamp(marker, CLAMP_SEARCH_POS);
+ }
+ else if (t->mode == TFM_RESIZE) {
+ if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
+ BKE_tracking_marker_clamp(marker, CLAMP_PAT_DIM);
+ if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))
+ BKE_tracking_marker_clamp(marker, CLAMP_SEARCH_DIM);
+ }
+ else if (t->mode == TFM_ROTATION) {
+ if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
+ BKE_tracking_marker_clamp(marker, CLAMP_PAT_POS);
+ }
+ }
+
+ track = track->next;
+ }
+
+ DEG_id_tag_update(&clip->id, 0);
+ }
+ else if (t->options & CTX_MASK) {
+ recalcData_mask_common(t);
+ }
}
/* helper for recalcData() - for object transforms, typically in the 3D view */
static void recalcData_objects(TransInfo *t)
{
- Base *base = t->view_layer->basact;
-
- if (t->obedit_type != -1) {
- if (ELEM(t->obedit_type, OB_CURVE, OB_SURF)) {
-
- if (t->state != TRANS_CANCEL) {
- clipMirrorModifier(t);
- applyProject(t);
- }
-
- 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) {
- /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */
- BKE_nurb_handles_calc(nu);
- nu = nu->next;
- }
- }
- else {
- /* Normal updating */
- while (nu) {
- BKE_nurb_test_2d(nu);
- BKE_nurb_handles_calc(nu);
- nu = nu->next;
- }
- }
- }
- }
- else if (t->obedit_type == OB_LATTICE) {
-
- if (t->state != TRANS_CANCEL) {
- applyProject(t);
- }
-
- 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) {
- /* mirror modifier clipping? */
- if (t->state != TRANS_CANCEL) {
- /* apply clipping after so we never project past the clip plane [#25423] */
- applyProject(t);
- clipMirrorModifier(t);
- }
- if ((t->flag & T_NO_MIRROR) == 0 &&
- (t->options & CTX_NO_MIRROR) == 0)
- {
- editbmesh_apply_to_mirror(t);
- }
-
- if (t->mode == TFM_EDGE_SLIDE) {
- projectEdgeSlideData(t, false);
- }
- else if (t->mode == TFM_VERT_SLIDE) {
- projectVertSlideData(t, false);
- }
-
- 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 */
-
- 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) {
- 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;
- }
- }
-
- /* 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 < tc->data_len; i++, td++) {
- if (td->extra) {
- float vec[3], up_axis[3];
- float qrot[4];
- float roll;
-
- ebo = td->extra;
-
- 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);
-
- /* 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(tc->obedit);
- }
- else {
- restoreBones(tc);
- }
- }
- }
- }
- else {
- if (t->state != TRANS_CANCEL) {
- applyProject(t);
- }
- 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) {
- GSet *motionpath_updates = BLI_gset_ptr_new("motionpath updates");
-
- 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. un-editable 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(t->context, t->scene, ob, t->mode, targetless_ik);
- }
-
- if (motionpath_need_update_pose(t->scene, ob)) {
- BLI_gset_insert(motionpath_updates, ob);
- }
-
- /* old optimize trick... this enforces to bypass the depgraph */
- if (!(arm->flag & ARM_DELAYDEFORM)) {
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); /* 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);
- }
- }
-
- /* Update motion paths once for all transformed bones in an object. */
- GSetIterator gs_iter;
- GSET_ITER (gs_iter, motionpath_updates) {
- Object *ob = BLI_gsetIterator_getKey(&gs_iter);
- ED_pose_recalculate_paths(t->context, t->scene, ob, true);
- }
- BLI_gset_free(motionpath_updates, NULL);
- }
- else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) &&
- PE_get_current(t->scene, base->object))
- {
- if (t->state != TRANS_CANCEL) {
- applyProject(t);
- }
- flushTransParticles(t);
- }
- else {
- bool motionpath_update = false;
-
- if (t->state != TRANS_CANCEL) {
- applyProject(t);
- }
-
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
-
- for (int i = 0; i < tc->data_len; i++, td++) {
- Object *ob = td->ob;
-
- if (td->flag & TD_NOACTION)
- break;
-
- if (td->flag & TD_SKIP)
- continue;
-
- /* 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_object(t->context, t->scene, t->view_layer, ob, t->mode);
- }
-
- motionpath_update |= motionpath_need_update_object(t->scene, ob);
-
- /* sets recalc flags fully, instead of flushing existing ones
- * otherwise proxies don't function correctly
- */
- DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
-
- if (t->flag & T_TEXTURE)
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- }
- }
-
- if (motionpath_update) {
- /* Update motion paths once for all transformed objects. */
- ED_objects_recalculate_paths(t->context, t->scene, true);
- }
- }
+ Base *base = t->view_layer->basact;
+
+ if (t->obedit_type != -1) {
+ if (ELEM(t->obedit_type, OB_CURVE, OB_SURF)) {
+
+ if (t->state != TRANS_CANCEL) {
+ clipMirrorModifier(t);
+ applyProject(t);
+ }
+
+ 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) {
+ /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */
+ BKE_nurb_handles_calc(nu);
+ nu = nu->next;
+ }
+ }
+ else {
+ /* Normal updating */
+ while (nu) {
+ BKE_nurb_test_2d(nu);
+ BKE_nurb_handles_calc(nu);
+ nu = nu->next;
+ }
+ }
+ }
+ }
+ else if (t->obedit_type == OB_LATTICE) {
+
+ if (t->state != TRANS_CANCEL) {
+ applyProject(t);
+ }
+
+ 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) {
+ /* mirror modifier clipping? */
+ if (t->state != TRANS_CANCEL) {
+ /* apply clipping after so we never project past the clip plane [#25423] */
+ applyProject(t);
+ clipMirrorModifier(t);
+ }
+ if ((t->flag & T_NO_MIRROR) == 0 && (t->options & CTX_NO_MIRROR) == 0) {
+ editbmesh_apply_to_mirror(t);
+ }
+
+ if (t->mode == TFM_EDGE_SLIDE) {
+ projectEdgeSlideData(t, false);
+ }
+ else if (t->mode == TFM_VERT_SLIDE) {
+ projectVertSlideData(t, false);
+ }
+
+ 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 */
+
+ 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) {
+ 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;
+ }
+ }
+
+ /* 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 < tc->data_len; i++, td++) {
+ if (td->extra) {
+ float vec[3], up_axis[3];
+ float qrot[4];
+ float roll;
+
+ ebo = td->extra;
+
+ 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);
+
+ /* 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(tc->obedit);
+ }
+ else {
+ restoreBones(tc);
+ }
+ }
+ }
+ }
+ else {
+ if (t->state != TRANS_CANCEL) {
+ applyProject(t);
+ }
+ 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) {
+ GSet *motionpath_updates = BLI_gset_ptr_new("motionpath updates");
+
+ 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. un-editable 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(t->context, t->scene, ob, t->mode, targetless_ik);
+ }
+
+ if (motionpath_need_update_pose(t->scene, ob)) {
+ BLI_gset_insert(motionpath_updates, ob);
+ }
+
+ /* old optimize trick... this enforces to bypass the depgraph */
+ if (!(arm->flag & ARM_DELAYDEFORM)) {
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); /* 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);
+ }
+ }
+
+ /* Update motion paths once for all transformed bones in an object. */
+ GSetIterator gs_iter;
+ GSET_ITER (gs_iter, motionpath_updates) {
+ Object *ob = BLI_gsetIterator_getKey(&gs_iter);
+ ED_pose_recalculate_paths(t->context, t->scene, ob, true);
+ }
+ BLI_gset_free(motionpath_updates, NULL);
+ }
+ else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) &&
+ PE_get_current(t->scene, base->object)) {
+ if (t->state != TRANS_CANCEL) {
+ applyProject(t);
+ }
+ flushTransParticles(t);
+ }
+ else {
+ bool motionpath_update = false;
+
+ if (t->state != TRANS_CANCEL) {
+ applyProject(t);
+ }
+
+ FOREACH_TRANS_DATA_CONTAINER(t, tc)
+ {
+ TransData *td = tc->data;
+
+ for (int i = 0; i < tc->data_len; i++, td++) {
+ Object *ob = td->ob;
+
+ if (td->flag & TD_NOACTION)
+ break;
+
+ if (td->flag & TD_SKIP)
+ continue;
+
+ /* 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_object(t->context, t->scene, t->view_layer, ob, t->mode);
+ }
+
+ motionpath_update |= motionpath_need_update_object(t->scene, ob);
+
+ /* sets recalc flags fully, instead of flushing existing ones
+ * otherwise proxies don't function correctly
+ */
+ DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
+
+ if (t->flag & T_TEXTURE)
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ }
+ }
+
+ if (motionpath_update) {
+ /* Update motion paths once for all transformed objects. */
+ ED_objects_recalculate_paths(t->context, t->scene, true);
+ }
+ }
}
static void recalcData_cursor(TransInfo *t)
{
- DEG_id_tag_update(&t->scene->id, ID_RECALC_COPY_ON_WRITE);
+ DEG_id_tag_update(&t->scene->id, ID_RECALC_COPY_ON_WRITE);
}
/* helper for recalcData() - for sequencer transforms */
static void recalcData_sequencer(TransInfo *t)
{
- TransData *td;
- int a;
- Sequence *seq_prev = NULL;
+ TransData *td;
+ int a;
+ Sequence *seq_prev = NULL;
- TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+ 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;
+ for (a = 0, td = tc->data; a < tc->data_len; a++, td++) {
+ TransDataSeq *tdsq = (TransDataSeq *)td->extra;
+ Sequence *seq = tdsq->seq;
- if (seq != seq_prev) {
- if (BKE_sequence_tx_fullupdate_test(seq)) {
- /* A few effect strip types need a complete recache on transform. */
- BKE_sequence_invalidate_cache(t->scene, seq);
- }
- else {
- BKE_sequence_invalidate_dependent(t->scene, seq);
- }
- }
+ if (seq != seq_prev) {
+ if (BKE_sequence_tx_fullupdate_test(seq)) {
+ /* A few effect strip types need a complete recache on transform. */
+ BKE_sequence_invalidate_cache(t->scene, seq);
+ }
+ else {
+ BKE_sequence_invalidate_dependent(t->scene, seq);
+ }
+ }
- seq_prev = seq;
- }
+ seq_prev = seq;
+ }
- BKE_sequencer_preprocessed_cache_cleanup();
+ BKE_sequencer_preprocessed_cache_cleanup();
- flushTransSeq(t);
+ flushTransSeq(t);
}
/* force recalculation of triangles during transformation */
static void recalcData_gpencil_strokes(TransInfo *t)
{
- 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_GEOMETRY;
- }
- }
+ 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_GEOMETRY;
+ }
+ }
}
/* called for updating while transform acts, once per redraw */
void recalcData(TransInfo *t)
{
- /* if tests must match createTransData for correct updates */
- if (t->options & CTX_CURSOR) {
- recalcData_cursor(t);
- }
- else if (t->options & CTX_TEXTURE) {
- recalcData_objects(t);
- }
- else if (t->options & CTX_EDGE) {
- recalcData_objects(t);
- }
- else if (t->options & CTX_PAINT_CURVE) {
- flushTransPaintCurve(t);
- }
- else if (t->options & CTX_GPENCIL_STROKES) {
- /* set recalc triangle cache flag */
- recalcData_gpencil_strokes(t);
- }
- else if (t->spacetype == SPACE_IMAGE) {
- recalcData_image(t);
- }
- else if (t->spacetype == SPACE_ACTION) {
- recalcData_actedit(t);
- }
- else if (t->spacetype == SPACE_NLA) {
- recalcData_nla(t);
- }
- else if (t->spacetype == SPACE_SEQ) {
- recalcData_sequencer(t);
- }
- else if (t->spacetype == SPACE_GRAPH) {
- recalcData_graphedit(t);
- }
- else if (t->spacetype == SPACE_NODE) {
- flushTransNodes(t);
- }
- else if (t->spacetype == SPACE_CLIP) {
- recalcData_spaceclip(t);
- }
- else {
- recalcData_objects(t);
- }
+ /* if tests must match createTransData for correct updates */
+ if (t->options & CTX_CURSOR) {
+ recalcData_cursor(t);
+ }
+ else if (t->options & CTX_TEXTURE) {
+ recalcData_objects(t);
+ }
+ else if (t->options & CTX_EDGE) {
+ recalcData_objects(t);
+ }
+ else if (t->options & CTX_PAINT_CURVE) {
+ flushTransPaintCurve(t);
+ }
+ else if (t->options & CTX_GPENCIL_STROKES) {
+ /* set recalc triangle cache flag */
+ recalcData_gpencil_strokes(t);
+ }
+ else if (t->spacetype == SPACE_IMAGE) {
+ recalcData_image(t);
+ }
+ else if (t->spacetype == SPACE_ACTION) {
+ recalcData_actedit(t);
+ }
+ else if (t->spacetype == SPACE_NLA) {
+ recalcData_nla(t);
+ }
+ else if (t->spacetype == SPACE_SEQ) {
+ recalcData_sequencer(t);
+ }
+ else if (t->spacetype == SPACE_GRAPH) {
+ recalcData_graphedit(t);
+ }
+ else if (t->spacetype == SPACE_NODE) {
+ flushTransNodes(t);
+ }
+ else if (t->spacetype == SPACE_CLIP) {
+ recalcData_spaceclip(t);
+ }
+ else {
+ recalcData_objects(t);
+ }
}
void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis, short options)
{
- float v1[3], v2[3], v3[3];
- unsigned char col[3], col2[3];
+ float v1[3], v2[3], v3[3];
+ unsigned char col[3], col2[3];
- if (t->spacetype == SPACE_VIEW3D) {
- View3D *v3d = t->view;
+ if (t->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = t->view;
- GPU_matrix_push();
+ GPU_matrix_push();
- copy_v3_v3(v3, dir);
- mul_v3_fl(v3, v3d->clip_end);
+ copy_v3_v3(v3, dir);
+ mul_v3_fl(v3, v3d->clip_end);
- sub_v3_v3v3(v2, center, v3);
- add_v3_v3v3(v1, center, v3);
+ sub_v3_v3v3(v2, center, v3);
+ add_v3_v3v3(v1, center, v3);
- if (options & DRAWLIGHT) {
- col[0] = col[1] = col[2] = 220;
- }
- else {
- UI_GetThemeColor3ubv(TH_GRID, col);
- }
- UI_make_axis_color(col, col2, axis);
+ if (options & DRAWLIGHT) {
+ col[0] = col[1] = col[2] = 220;
+ }
+ else {
+ UI_GetThemeColor3ubv(TH_GRID, col);
+ }
+ UI_make_axis_color(col, col2, axis);
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- immUniformColor3ubv(col2);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor3ubv(col2);
- immBegin(GPU_PRIM_LINES, 2);
- immVertex3fv(pos, v1);
- immVertex3fv(pos, v2);
- immEnd();
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex3fv(pos, v1);
+ immVertex3fv(pos, v2);
+ immEnd();
- immUnbindProgram();
+ immUnbindProgram();
- GPU_matrix_pop();
- }
+ GPU_matrix_pop();
+ }
}
/**
@@ -1177,94 +1184,96 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis
*/
void resetTransModal(TransInfo *t)
{
- freeTransCustomDataForMode(t);
+ freeTransCustomDataForMode(t);
}
void resetTransRestrictions(TransInfo *t)
{
- t->flag &= ~T_ALL_RESTRICTIONS;
+ t->flag &= ~T_ALL_RESTRICTIONS;
}
static int initTransInfo_edit_pet_to_flag(const int proportional)
{
- switch (proportional) {
- case PROP_EDIT_ON:
- return T_PROP_EDIT;
- case PROP_EDIT_CONNECTED:
- return T_PROP_EDIT | T_PROP_CONNECTED;
- case PROP_EDIT_PROJECTED:
- return T_PROP_EDIT | T_PROP_PROJECTED;
- default:
- return 0;
- }
+ switch (proportional) {
+ case PROP_EDIT_ON:
+ return T_PROP_EDIT;
+ case PROP_EDIT_CONNECTED:
+ return T_PROP_EDIT | T_PROP_CONNECTED;
+ case PROP_EDIT_PROJECTED:
+ return T_PROP_EDIT | T_PROP_PROJECTED;
+ default:
+ return 0;
+ }
}
-void initTransDataContainers_FromObjectData(TransInfo *t, Object *obact, Object **objects, uint objects_len)
+void initTransDataContainers_FromObjectData(TransInfo *t,
+ Object *obact,
+ Object **objects,
+ uint objects_len)
{
- const eObjectMode object_mode = obact ? obact->mode : OB_MODE_OBJECT;
- const short object_type = obact ? obact->type : -1;
-
- if ((object_mode & OB_MODE_EDIT) || (t->options & CTX_GPENCIL_STROKES) ||
- ((object_mode & OB_MODE_POSE) && (object_type == OB_ARMATURE)))
- {
- if (t->data_container) {
- MEM_freeN(t->data_container);
- }
-
- bool free_objects = false;
- if (objects == NULL) {
- objects = BKE_view_layer_array_from_objects_in_mode(
- t->view_layer,
- (t->spacetype == SPACE_VIEW3D) ? t->view : NULL,
- &objects_len, {
- .object_mode = object_mode,
- .no_dup_data = true,
- });
- free_objects = 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];
- /* TODO, multiple axes. */
- tc->mirror.axis_flag = (
- ((t->flag & T_NO_MIRROR) == 0) &&
- ((t->options & CTX_NO_MIRROR) == 0) &&
- (objects[i]->type == OB_MESH) &&
- (((Mesh *)objects[i]->data)->editflag & ME_EDIT_MIRROR_X) != 0);
-
- 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;
- }
- else if (t->options & CTX_GPENCIL_STROKES) {
- 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. */
- }
-
- if (free_objects) {
- MEM_freeN(objects);
- }
- }
+ const eObjectMode object_mode = obact ? obact->mode : OB_MODE_OBJECT;
+ const short object_type = obact ? obact->type : -1;
+
+ if ((object_mode & OB_MODE_EDIT) || (t->options & CTX_GPENCIL_STROKES) ||
+ ((object_mode & OB_MODE_POSE) && (object_type == OB_ARMATURE))) {
+ if (t->data_container) {
+ MEM_freeN(t->data_container);
+ }
+
+ bool free_objects = false;
+ if (objects == NULL) {
+ objects = BKE_view_layer_array_from_objects_in_mode(
+ t->view_layer,
+ (t->spacetype == SPACE_VIEW3D) ? t->view : NULL,
+ &objects_len,
+ {
+ .object_mode = object_mode,
+ .no_dup_data = true,
+ });
+ free_objects = 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];
+ /* TODO, multiple axes. */
+ tc->mirror.axis_flag = (((t->flag & T_NO_MIRROR) == 0) &&
+ ((t->options & CTX_NO_MIRROR) == 0) &&
+ (objects[i]->type == OB_MESH) &&
+ (((Mesh *)objects[i]->data)->editflag & ME_EDIT_MIRROR_X) != 0);
+
+ 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;
+ }
+ else if (t->options & CTX_GPENCIL_STROKES) {
+ 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. */
+ }
+
+ if (free_objects) {
+ MEM_freeN(objects);
+ }
+ }
}
/**
@@ -1276,437 +1285,431 @@ void initTransDataContainers_FromObjectData(TransInfo *t, Object *obact, Object
*/
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);
-
- 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->settings = ts;
- t->reports = op ? op->reports : NULL;
-
- t->helpline = HLP_NONE;
-
- t->flag = 0;
-
- t->obedit_type = ((object_mode == OB_MODE_EDIT) || (object_mode == OB_MODE_EDIT_GPENCIL)) ? 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) {
- t->mouse.imval[0] = event->mval[0];
- t->mouse.imval[1] = event->mval[1];
- }
- else {
- t->mouse.imval[0] = 0;
- t->mouse.imval[1] = 0;
- }
-
- t->con.imval[0] = t->mouse.imval[0];
- t->con.imval[1] = t->mouse.imval[1];
-
- t->mval[0] = t->mouse.imval[0];
- t->mval[1] = t->mouse.imval[1];
-
- t->transform = NULL;
- t->handleEvent = NULL;
-
- t->data_len_all = 0;
-
- t->val = 0.0f;
-
- zero_v3(t->vec);
- zero_v3(t->center_global);
-
- unit_m3(t->mat);
-
- unit_m3(t->orient_matrix);
- negate_m3(t->orient_matrix);
- /* Leave 't->orient_matrix_is_set' to false,
- * so we overwrite it when we have a useful value. */
-
- /* Default to rotate on the Z axis. */
- t->orient_axis = 2;
- t->orient_axis_ortho = 1;
-
- /* if there's an event, we're modal */
- if (event) {
- t->flag |= T_MODAL;
- }
-
- /* Crease needs edge flag */
- if (ELEM(t->mode, TFM_CREASE, TFM_BWEIGHT)) {
- t->options |= CTX_EDGE;
- }
-
- t->remove_on_cancel = false;
-
- if (op && (prop = RNA_struct_find_property(op->ptr, "remove_on_cancel")) && RNA_property_is_set(op->ptr, prop)) {
- if (RNA_property_boolean_get(op->ptr, prop)) {
- t->remove_on_cancel = true;
- }
- }
-
- /* GPencil editing context */
- if (GPENCIL_EDIT_MODE(gpd)) {
- t->options |= CTX_GPENCIL_STROKES;
- }
-
- /* Assign the space type, some exceptions for running in different mode */
- if (sa == NULL) {
- /* background mode */
- t->spacetype = SPACE_EMPTY;
- }
- else if ((ar == NULL) && (sa->spacetype == SPACE_VIEW3D)) {
- /* running in the text editor */
- t->spacetype = SPACE_EMPTY;
- }
- else {
- /* normal operation */
- t->spacetype = sa->spacetype;
- }
-
- /* handle T_ALT_TRANSFORM initialization, we may use for different operators */
- if (op) {
- const char *prop_id = NULL;
- if (t->mode == TFM_SHRINKFATTEN) {
- prop_id = "use_even_offset";
- }
-
- 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);
- }
- }
-
- if (t->spacetype == SPACE_VIEW3D) {
- View3D *v3d = sa->spacedata.first;
- bScreen *animscreen = ED_screen_animation_playing(CTX_wm_manager(C));
-
- t->view = v3d;
- t->animtimer = (animscreen) ? animscreen->animtimer : NULL;
-
- /* turn gizmo off during transform */
- if (t->flag & T_MODAL) {
- t->gizmo_flag = v3d->gizmo_flag;
- v3d->gizmo_flag = V3D_GIZMO_HIDE;
- }
-
- 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;
- }
-
- TransformOrientationSlot *orient_slot = &t->scene->orientation_slots[SCE_ORIENT_DEFAULT];
- t->orientation.unset = V3D_ORIENT_GLOBAL;
- t->orientation.user = orient_slot->type;
- t->orientation.custom = BKE_scene_transform_orientation_find(t->scene, orient_slot->index_custom);
-
- t->orientation.index = 0;
- ARRAY_SET_ITEMS(
- t->orientation.types,
- &t->orientation.user,
- NULL);
-
- /* Make second orientation local if both are global. */
- if (t->orientation.user == V3D_ORIENT_GLOBAL) {
- t->orientation.user_alt = V3D_ORIENT_LOCAL;
- t->orientation.types[0] = &t->orientation.user_alt;
- SWAP(short *, t->orientation.types[0], t->orientation.types[1]);
- }
-
- /* 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 ((t->obedit_type != -1) && !use_island) {
- t->options |= CTX_NO_PET;
- }
- }
- }
-
- 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;
- }
- }
-
- /* initialize UV transform from */
- if (op && ((prop = RNA_struct_find_property(op->ptr, "correct_uv")))) {
- if (RNA_property_is_set(op->ptr, prop)) {
- if (RNA_property_boolean_get(op->ptr, prop)) {
- t->settings->uvcalc_flag |= UVCALC_TRANSFORM_CORRECT;
- }
- else {
- t->settings->uvcalc_flag &= ~UVCALC_TRANSFORM_CORRECT;
- }
- }
- else {
- RNA_property_boolean_set(op->ptr, prop, (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) != 0);
- }
- }
-
- }
- else if (t->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = sa->spacedata.first;
- // XXX for now, get View2D from the active region
- t->view = &ar->v2d;
- t->around = sima->around;
-
- if (ED_space_image_show_uvedit(sima, OBACT(t->view_layer))) {
- /* UV transform */
- }
- else if (sima->mode == SI_MODE_MASK) {
- t->options |= CTX_MASK;
- }
- else if (sima->mode == SI_MODE_PAINT) {
- Paint *p = &sce->toolsettings->imapaint.paint;
- if (p->brush && (p->brush->flag & BRUSH_CURVE)) {
- t->options |= CTX_PAINT_CURVE;
- }
- }
- /* image not in uv edit, nor in mask mode, can happen for some tools */
- }
- else if (t->spacetype == SPACE_NODE) {
- // XXX for now, get View2D from the active region
- t->view = &ar->v2d;
- t->around = V3D_AROUND_CENTER_BOUNDS;
- }
- else if (t->spacetype == SPACE_GRAPH) {
- SpaceGraph *sipo = sa->spacedata.first;
- t->view = &ar->v2d;
- t->around = sipo->around;
- }
- else if (t->spacetype == SPACE_CLIP) {
- SpaceClip *sclip = sa->spacedata.first;
- t->view = &ar->v2d;
- t->around = sclip->around;
-
- if (ED_space_clip_check_show_trackedit(sclip))
- t->options |= CTX_MOVIECLIP;
- else if (ED_space_clip_check_show_maskedit(sclip))
- t->options |= CTX_MASK;
- }
- else {
- if (ar) {
- // XXX for now, get View2D from the active region
- t->view = &ar->v2d;
- // XXX for now, the center point is the midpoint of the data
- }
- else {
- t->view = NULL;
- }
- t->around = V3D_AROUND_CENTER_BOUNDS;
- }
-
- if (op && (prop = RNA_struct_find_property(op->ptr, "orient_axis"))) {
- t->orient_axis = RNA_property_enum_get(op->ptr, prop);
- }
- if (op && (prop = RNA_struct_find_property(op->ptr, "orient_axis_ortho"))) {
- t->orient_axis_ortho = RNA_property_enum_get(op->ptr, prop);
- }
-
- if (op && ((prop = RNA_struct_find_property(op->ptr, "orient_matrix")) &&
- RNA_property_is_set(op->ptr, prop)) &&
- ((t->flag & T_MODAL) ||
- /* When using redo, don't use the the custom constraint matrix
- * if the user selects a different orientation. */
- (RNA_enum_get(op->ptr, "orient_type") ==
- RNA_enum_get(op->ptr, "orient_matrix_type"))))
- {
- RNA_property_float_get_array(op->ptr, prop, &t->spacemtx[0][0]);
- /* Some transform modes use this to operate on an axis. */
- t->orient_matrix_is_set = true;
- copy_m3_m3(t->orient_matrix, t->spacemtx);
- t->orient_matrix_is_set = true;
- t->orientation.user = V3D_ORIENT_CUSTOM_MATRIX;
- t->orientation.custom = 0;
- if (t->flag & T_MODAL) {
- RNA_enum_set(op->ptr, "orient_matrix_type", RNA_enum_get(op->ptr, "orient_type"));
- }
- }
- else if (op && ((prop = RNA_struct_find_property(op->ptr, "orient_type")) &&
- RNA_property_is_set(op->ptr, prop)))
- {
- short orientation = RNA_property_enum_get(op->ptr, prop);
- TransformOrientation *custom_orientation = NULL;
-
- if (orientation >= V3D_ORIENT_CUSTOM) {
- if (orientation >= V3D_ORIENT_CUSTOM + BIF_countTransformOrientation(C)) {
- orientation = V3D_ORIENT_GLOBAL;
- }
- else {
- custom_orientation = BKE_scene_transform_orientation_find(
- t->scene, orientation - V3D_ORIENT_CUSTOM);
- orientation = V3D_ORIENT_CUSTOM;
- }
- }
-
- t->orientation.user = orientation;
- t->orientation.custom = custom_orientation;
- }
-
- if (op && ((prop = RNA_struct_find_property(op->ptr, "release_confirm")) &&
- RNA_property_is_set(op->ptr, prop)))
- {
- if (RNA_property_boolean_get(op->ptr, prop)) {
- t->flag |= T_RELEASE_CONFIRM;
- }
- }
- else {
- if (U.flag & USER_RELEASECONFIRM) {
- t->flag |= T_RELEASE_CONFIRM;
- }
- }
-
- if (op && ((prop = RNA_struct_find_property(op->ptr, "mirror")) &&
- RNA_property_is_set(op->ptr, prop)))
- {
- if (!RNA_property_boolean_get(op->ptr, prop)) {
- t->flag |= T_NO_MIRROR;
- }
- }
- else if ((t->spacetype == SPACE_VIEW3D) && (t->obedit_type == OB_MESH)) {
- /* pass */
- }
- else {
- /* Avoid mirroring for unsupported contexts. */
- t->options |= CTX_NO_MIRROR;
- }
-
- /* setting PET flag only if property exist in operator. Otherwise, assume it's not supported */
- if (op && (prop = RNA_struct_find_property(op->ptr, "proportional"))) {
- if (RNA_property_is_set(op->ptr, prop)) {
- t->flag |= initTransInfo_edit_pet_to_flag(RNA_property_enum_get(op->ptr, prop));
- }
- else {
- /* use settings from scene only if modal */
- if (t->flag & T_MODAL) {
- if ((t->options & CTX_NO_PET) == 0) {
- if (t->spacetype == SPACE_GRAPH) {
- t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional_fcurve);
- }
- else if (t->spacetype == SPACE_ACTION) {
- t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional_action);
- }
- else if (t->obedit_type != -1) {
- t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional);
- }
- else if (t->options & CTX_GPENCIL_STROKES) {
- t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional);
- }
- else if (t->options & CTX_MASK) {
- if (ts->proportional_mask) {
- t->flag |= T_PROP_EDIT;
-
- if (ts->proportional == PROP_EDIT_CONNECTED) {
- t->flag |= T_PROP_CONNECTED;
- }
- }
- }
- else if ((t->obedit_type == -1) && ts->proportional_objects) {
- t->flag |= T_PROP_EDIT;
- }
- }
- }
- }
-
- if (op && ((prop = RNA_struct_find_property(op->ptr, "proportional_size")) &&
- RNA_property_is_set(op->ptr, prop)))
- {
- t->prop_size = RNA_property_float_get(op->ptr, prop);
- }
- else {
- t->prop_size = ts->proportional_size;
- }
-
-
- /* TRANSFORM_FIX_ME rna restrictions */
- if (t->prop_size <= 0.00001f) {
- printf("Proportional size (%f) under 0.00001, resetting to 1!\n", t->prop_size);
- t->prop_size = 1.0f;
- }
-
- if (op && ((prop = RNA_struct_find_property(op->ptr, "proportional_edit_falloff")) &&
- RNA_property_is_set(op->ptr, prop)))
- {
- t->prop_mode = RNA_property_enum_get(op->ptr, prop);
- }
- else {
- t->prop_mode = ts->prop_mode;
- }
- }
- else { /* add not pet option to context when not available */
- t->options |= CTX_NO_PET;
- }
-
- // Mirror is not supported with PET, turn it off.
+ 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);
+
+ 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->settings = ts;
+ t->reports = op ? op->reports : NULL;
+
+ t->helpline = HLP_NONE;
+
+ t->flag = 0;
+
+ t->obedit_type = ((object_mode == OB_MODE_EDIT) || (object_mode == OB_MODE_EDIT_GPENCIL)) ?
+ 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) {
+ t->mouse.imval[0] = event->mval[0];
+ t->mouse.imval[1] = event->mval[1];
+ }
+ else {
+ t->mouse.imval[0] = 0;
+ t->mouse.imval[1] = 0;
+ }
+
+ t->con.imval[0] = t->mouse.imval[0];
+ t->con.imval[1] = t->mouse.imval[1];
+
+ t->mval[0] = t->mouse.imval[0];
+ t->mval[1] = t->mouse.imval[1];
+
+ t->transform = NULL;
+ t->handleEvent = NULL;
+
+ t->data_len_all = 0;
+
+ t->val = 0.0f;
+
+ zero_v3(t->vec);
+ zero_v3(t->center_global);
+
+ unit_m3(t->mat);
+
+ unit_m3(t->orient_matrix);
+ negate_m3(t->orient_matrix);
+ /* Leave 't->orient_matrix_is_set' to false,
+ * so we overwrite it when we have a useful value. */
+
+ /* Default to rotate on the Z axis. */
+ t->orient_axis = 2;
+ t->orient_axis_ortho = 1;
+
+ /* if there's an event, we're modal */
+ if (event) {
+ t->flag |= T_MODAL;
+ }
+
+ /* Crease needs edge flag */
+ if (ELEM(t->mode, TFM_CREASE, TFM_BWEIGHT)) {
+ t->options |= CTX_EDGE;
+ }
+
+ t->remove_on_cancel = false;
+
+ if (op && (prop = RNA_struct_find_property(op->ptr, "remove_on_cancel")) &&
+ RNA_property_is_set(op->ptr, prop)) {
+ if (RNA_property_boolean_get(op->ptr, prop)) {
+ t->remove_on_cancel = true;
+ }
+ }
+
+ /* GPencil editing context */
+ if (GPENCIL_EDIT_MODE(gpd)) {
+ t->options |= CTX_GPENCIL_STROKES;
+ }
+
+ /* Assign the space type, some exceptions for running in different mode */
+ if (sa == NULL) {
+ /* background mode */
+ t->spacetype = SPACE_EMPTY;
+ }
+ else if ((ar == NULL) && (sa->spacetype == SPACE_VIEW3D)) {
+ /* running in the text editor */
+ t->spacetype = SPACE_EMPTY;
+ }
+ else {
+ /* normal operation */
+ t->spacetype = sa->spacetype;
+ }
+
+ /* handle T_ALT_TRANSFORM initialization, we may use for different operators */
+ if (op) {
+ const char *prop_id = NULL;
+ if (t->mode == TFM_SHRINKFATTEN) {
+ prop_id = "use_even_offset";
+ }
+
+ 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);
+ }
+ }
+
+ if (t->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = sa->spacedata.first;
+ bScreen *animscreen = ED_screen_animation_playing(CTX_wm_manager(C));
+
+ t->view = v3d;
+ t->animtimer = (animscreen) ? animscreen->animtimer : NULL;
+
+ /* turn gizmo off during transform */
+ if (t->flag & T_MODAL) {
+ t->gizmo_flag = v3d->gizmo_flag;
+ v3d->gizmo_flag = V3D_GIZMO_HIDE;
+ }
+
+ 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;
+ }
+
+ TransformOrientationSlot *orient_slot = &t->scene->orientation_slots[SCE_ORIENT_DEFAULT];
+ t->orientation.unset = V3D_ORIENT_GLOBAL;
+ t->orientation.user = orient_slot->type;
+ t->orientation.custom = BKE_scene_transform_orientation_find(t->scene,
+ orient_slot->index_custom);
+
+ t->orientation.index = 0;
+ ARRAY_SET_ITEMS(t->orientation.types, &t->orientation.user, NULL);
+
+ /* Make second orientation local if both are global. */
+ if (t->orientation.user == V3D_ORIENT_GLOBAL) {
+ t->orientation.user_alt = V3D_ORIENT_LOCAL;
+ t->orientation.types[0] = &t->orientation.user_alt;
+ SWAP(short *, t->orientation.types[0], t->orientation.types[1]);
+ }
+
+ /* 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 ((t->obedit_type != -1) && !use_island) {
+ t->options |= CTX_NO_PET;
+ }
+ }
+ }
+
+ 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;
+ }
+ }
+
+ /* initialize UV transform from */
+ if (op && ((prop = RNA_struct_find_property(op->ptr, "correct_uv")))) {
+ if (RNA_property_is_set(op->ptr, prop)) {
+ if (RNA_property_boolean_get(op->ptr, prop)) {
+ t->settings->uvcalc_flag |= UVCALC_TRANSFORM_CORRECT;
+ }
+ else {
+ t->settings->uvcalc_flag &= ~UVCALC_TRANSFORM_CORRECT;
+ }
+ }
+ else {
+ RNA_property_boolean_set(
+ op->ptr, prop, (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) != 0);
+ }
+ }
+ }
+ else if (t->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = sa->spacedata.first;
+ // XXX for now, get View2D from the active region
+ t->view = &ar->v2d;
+ t->around = sima->around;
+
+ if (ED_space_image_show_uvedit(sima, OBACT(t->view_layer))) {
+ /* UV transform */
+ }
+ else if (sima->mode == SI_MODE_MASK) {
+ t->options |= CTX_MASK;
+ }
+ else if (sima->mode == SI_MODE_PAINT) {
+ Paint *p = &sce->toolsettings->imapaint.paint;
+ if (p->brush && (p->brush->flag & BRUSH_CURVE)) {
+ t->options |= CTX_PAINT_CURVE;
+ }
+ }
+ /* image not in uv edit, nor in mask mode, can happen for some tools */
+ }
+ else if (t->spacetype == SPACE_NODE) {
+ // XXX for now, get View2D from the active region
+ t->view = &ar->v2d;
+ t->around = V3D_AROUND_CENTER_BOUNDS;
+ }
+ else if (t->spacetype == SPACE_GRAPH) {
+ SpaceGraph *sipo = sa->spacedata.first;
+ t->view = &ar->v2d;
+ t->around = sipo->around;
+ }
+ else if (t->spacetype == SPACE_CLIP) {
+ SpaceClip *sclip = sa->spacedata.first;
+ t->view = &ar->v2d;
+ t->around = sclip->around;
+
+ if (ED_space_clip_check_show_trackedit(sclip))
+ t->options |= CTX_MOVIECLIP;
+ else if (ED_space_clip_check_show_maskedit(sclip))
+ t->options |= CTX_MASK;
+ }
+ else {
+ if (ar) {
+ // XXX for now, get View2D from the active region
+ t->view = &ar->v2d;
+ // XXX for now, the center point is the midpoint of the data
+ }
+ else {
+ t->view = NULL;
+ }
+ t->around = V3D_AROUND_CENTER_BOUNDS;
+ }
+
+ if (op && (prop = RNA_struct_find_property(op->ptr, "orient_axis"))) {
+ t->orient_axis = RNA_property_enum_get(op->ptr, prop);
+ }
+ if (op && (prop = RNA_struct_find_property(op->ptr, "orient_axis_ortho"))) {
+ t->orient_axis_ortho = RNA_property_enum_get(op->ptr, prop);
+ }
+
+ if (op &&
+ ((prop = RNA_struct_find_property(op->ptr, "orient_matrix")) &&
+ RNA_property_is_set(op->ptr, prop)) &&
+ ((t->flag & T_MODAL) ||
+ /* When using redo, don't use the the custom constraint matrix
+ * if the user selects a different orientation. */
+ (RNA_enum_get(op->ptr, "orient_type") == RNA_enum_get(op->ptr, "orient_matrix_type")))) {
+ RNA_property_float_get_array(op->ptr, prop, &t->spacemtx[0][0]);
+ /* Some transform modes use this to operate on an axis. */
+ t->orient_matrix_is_set = true;
+ copy_m3_m3(t->orient_matrix, t->spacemtx);
+ t->orient_matrix_is_set = true;
+ t->orientation.user = V3D_ORIENT_CUSTOM_MATRIX;
+ t->orientation.custom = 0;
+ if (t->flag & T_MODAL) {
+ RNA_enum_set(op->ptr, "orient_matrix_type", RNA_enum_get(op->ptr, "orient_type"));
+ }
+ }
+ else if (op && ((prop = RNA_struct_find_property(op->ptr, "orient_type")) &&
+ RNA_property_is_set(op->ptr, prop))) {
+ short orientation = RNA_property_enum_get(op->ptr, prop);
+ TransformOrientation *custom_orientation = NULL;
+
+ if (orientation >= V3D_ORIENT_CUSTOM) {
+ if (orientation >= V3D_ORIENT_CUSTOM + BIF_countTransformOrientation(C)) {
+ orientation = V3D_ORIENT_GLOBAL;
+ }
+ else {
+ custom_orientation = BKE_scene_transform_orientation_find(t->scene,
+ orientation - V3D_ORIENT_CUSTOM);
+ orientation = V3D_ORIENT_CUSTOM;
+ }
+ }
+
+ t->orientation.user = orientation;
+ t->orientation.custom = custom_orientation;
+ }
+
+ if (op && ((prop = RNA_struct_find_property(op->ptr, "release_confirm")) &&
+ RNA_property_is_set(op->ptr, prop))) {
+ if (RNA_property_boolean_get(op->ptr, prop)) {
+ t->flag |= T_RELEASE_CONFIRM;
+ }
+ }
+ else {
+ if (U.flag & USER_RELEASECONFIRM) {
+ t->flag |= T_RELEASE_CONFIRM;
+ }
+ }
+
+ if (op && ((prop = RNA_struct_find_property(op->ptr, "mirror")) &&
+ RNA_property_is_set(op->ptr, prop))) {
+ if (!RNA_property_boolean_get(op->ptr, prop)) {
+ t->flag |= T_NO_MIRROR;
+ }
+ }
+ else if ((t->spacetype == SPACE_VIEW3D) && (t->obedit_type == OB_MESH)) {
+ /* pass */
+ }
+ else {
+ /* Avoid mirroring for unsupported contexts. */
+ t->options |= CTX_NO_MIRROR;
+ }
+
+ /* setting PET flag only if property exist in operator. Otherwise, assume it's not supported */
+ if (op && (prop = RNA_struct_find_property(op->ptr, "proportional"))) {
+ if (RNA_property_is_set(op->ptr, prop)) {
+ t->flag |= initTransInfo_edit_pet_to_flag(RNA_property_enum_get(op->ptr, prop));
+ }
+ else {
+ /* use settings from scene only if modal */
+ if (t->flag & T_MODAL) {
+ if ((t->options & CTX_NO_PET) == 0) {
+ if (t->spacetype == SPACE_GRAPH) {
+ t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional_fcurve);
+ }
+ else if (t->spacetype == SPACE_ACTION) {
+ t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional_action);
+ }
+ else if (t->obedit_type != -1) {
+ t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional);
+ }
+ else if (t->options & CTX_GPENCIL_STROKES) {
+ t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional);
+ }
+ else if (t->options & CTX_MASK) {
+ if (ts->proportional_mask) {
+ t->flag |= T_PROP_EDIT;
+
+ if (ts->proportional == PROP_EDIT_CONNECTED) {
+ t->flag |= T_PROP_CONNECTED;
+ }
+ }
+ }
+ else if ((t->obedit_type == -1) && ts->proportional_objects) {
+ t->flag |= T_PROP_EDIT;
+ }
+ }
+ }
+ }
+
+ if (op && ((prop = RNA_struct_find_property(op->ptr, "proportional_size")) &&
+ RNA_property_is_set(op->ptr, prop))) {
+ t->prop_size = RNA_property_float_get(op->ptr, prop);
+ }
+ else {
+ t->prop_size = ts->proportional_size;
+ }
+
+ /* TRANSFORM_FIX_ME rna restrictions */
+ if (t->prop_size <= 0.00001f) {
+ printf("Proportional size (%f) under 0.00001, resetting to 1!\n", t->prop_size);
+ t->prop_size = 1.0f;
+ }
+
+ if (op && ((prop = RNA_struct_find_property(op->ptr, "proportional_edit_falloff")) &&
+ RNA_property_is_set(op->ptr, prop))) {
+ t->prop_mode = RNA_property_enum_get(op->ptr, prop);
+ }
+ else {
+ t->prop_mode = ts->prop_mode;
+ }
+ }
+ else { /* add not pet option to context when not available */
+ t->options |= CTX_NO_PET;
+ }
+
+ // Mirror is not supported with PET, turn it off.
#if 0
- if (t->flag & T_PROP_EDIT) {
- t->flag &= ~T_MIRROR;
- }
+ if (t->flag & T_PROP_EDIT) {
+ t->flag &= ~T_MIRROR;
+ }
#endif
- setTransformViewAspect(t, t->aspect);
+ 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_global);
- mul_v3_v3(t->center_global, t->aspect);
- t->flag |= T_OVERRIDE_CENTER;
- }
+ 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_global);
+ mul_v3_v3(t->center_global, t->aspect);
+ t->flag |= T_OVERRIDE_CENTER;
+ }
- setTransformViewMatrices(t);
- initNumInput(&t->num);
+ setTransformViewMatrices(t);
+ initNumInput(&t->num);
}
-
-static void freeTransCustomData(
- TransInfo *t, TransDataContainer *tc,
- TransCustomData *custom_data)
+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;
+ 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)
+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);
- }
+ TransCustomData *custom_data = &tcdc->first_elem;
+ for (int i = 0; i < TRANS_CUSTOM_DATA_ELEM_MAX; i++, custom_data++) {
+ freeTransCustomData(t, tc, custom_data);
+ }
}
/**
@@ -1714,321 +1717,325 @@ static void freeTransCustomDataContainer(TransInfo *t, TransDataContainer *tc, T
*/
void freeTransCustomDataForMode(TransInfo *t)
{
- freeTransCustomData(t, NULL, &t->custom.mode);
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- freeTransCustomData(t, tc, &tc->custom.mode);
- }
+ 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)
{
- if (t->draw_handle_view)
- ED_region_draw_cb_exit(t->ar->type, t->draw_handle_view);
- if (t->draw_handle_apply)
- ED_region_draw_cb_exit(t->ar->type, t->draw_handle_apply);
- if (t->draw_handle_pixel)
- ED_region_draw_cb_exit(t->ar->type, t->draw_handle_pixel);
- 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 */
- 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_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_GRAPH))
- {
- 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_SAFE_FREE(t->data_container);
- t->data_container = NULL;
-
- BLI_freelistN(&t->tsnap.points);
-
- if (t->spacetype == SPACE_IMAGE) {
- if (t->options & (CTX_MASK | CTX_PAINT_CURVE)) {
- /* pass */
- }
- else {
- SpaceImage *sima = t->sa->spacedata.first;
- if (sima->flag & SI_LIVE_UNWRAP)
- ED_uvedit_live_unwrap_end(t->state == TRANS_CANCEL);
- }
- }
- else if (t->spacetype == SPACE_VIEW3D) {
- View3D *v3d = t->sa->spacedata.first;
- /* restore gizmo */
- if (t->flag & T_MODAL) {
- v3d->gizmo_flag = t->gizmo_flag;
- }
- }
-
- if (t->mouse.data) {
- MEM_freeN(t->mouse.data);
- }
-
- if (t->rng != NULL) {
- BLI_rng_free(t->rng);
- }
-
- freeSnapping(t);
+ if (t->draw_handle_view)
+ ED_region_draw_cb_exit(t->ar->type, t->draw_handle_view);
+ if (t->draw_handle_apply)
+ ED_region_draw_cb_exit(t->ar->type, t->draw_handle_apply);
+ if (t->draw_handle_pixel)
+ ED_region_draw_cb_exit(t->ar->type, t->draw_handle_pixel);
+ 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 */
+ 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_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_GRAPH)) {
+ 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_SAFE_FREE(t->data_container);
+ t->data_container = NULL;
+
+ BLI_freelistN(&t->tsnap.points);
+
+ if (t->spacetype == SPACE_IMAGE) {
+ if (t->options & (CTX_MASK | CTX_PAINT_CURVE)) {
+ /* pass */
+ }
+ else {
+ SpaceImage *sima = t->sa->spacedata.first;
+ if (sima->flag & SI_LIVE_UNWRAP)
+ ED_uvedit_live_unwrap_end(t->state == TRANS_CANCEL);
+ }
+ }
+ else if (t->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = t->sa->spacedata.first;
+ /* restore gizmo */
+ if (t->flag & T_MODAL) {
+ v3d->gizmo_flag = t->gizmo_flag;
+ }
+ }
+
+ if (t->mouse.data) {
+ 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 = 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);
- }
- if (td->ext->size) {
- copy_v3_v3(td->ext->isize, td->ext->size);
- }
- }
- recalcData(t);
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
+ TransData *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);
+ }
+ if (td->ext->size) {
+ copy_v3_v3(td->ext->isize, td->ext->size);
+ }
+ }
+ recalcData(t);
}
static void restoreElement(TransData *td)
{
- /* TransData for crease has no loc */
- if (td->loc) {
- copy_v3_v3(td->loc, td->iloc);
- }
- if (td->val) {
- *td->val = td->ival;
- }
-
- if (td->ext && (td->flag & TD_NO_EXT) == 0) {
- if (td->ext->rot) {
- copy_v3_v3(td->ext->rot, td->ext->irot);
- }
- if (td->ext->rotAngle) {
- *td->ext->rotAngle = td->ext->irotAngle;
- }
- if (td->ext->rotAxis) {
- copy_v3_v3(td->ext->rotAxis, td->ext->irotAxis);
- }
- /* XXX, drotAngle & drotAxis not used yet */
- if (td->ext->size) {
- copy_v3_v3(td->ext->size, td->ext->isize);
- }
- if (td->ext->quat) {
- copy_qt_qt(td->ext->quat, td->ext->iquat);
- }
- }
-
- if (td->flag & TD_BEZTRIPLE) {
- *(td->hdata->h1) = td->hdata->ih1;
- *(td->hdata->h2) = td->hdata->ih2;
- }
+ /* TransData for crease has no loc */
+ if (td->loc) {
+ copy_v3_v3(td->loc, td->iloc);
+ }
+ if (td->val) {
+ *td->val = td->ival;
+ }
+
+ if (td->ext && (td->flag & TD_NO_EXT) == 0) {
+ if (td->ext->rot) {
+ copy_v3_v3(td->ext->rot, td->ext->irot);
+ }
+ if (td->ext->rotAngle) {
+ *td->ext->rotAngle = td->ext->irotAngle;
+ }
+ if (td->ext->rotAxis) {
+ copy_v3_v3(td->ext->rotAxis, td->ext->irotAxis);
+ }
+ /* XXX, drotAngle & drotAxis not used yet */
+ if (td->ext->size) {
+ copy_v3_v3(td->ext->size, td->ext->isize);
+ }
+ if (td->ext->quat) {
+ copy_qt_qt(td->ext->quat, td->ext->iquat);
+ }
+ }
+
+ if (td->flag & TD_BEZTRIPLE) {
+ *(td->hdata->h1) = td->hdata->ih1;
+ *(td->hdata->h2) = td->hdata->ih2;
+ }
}
void restoreTransObjects(TransInfo *t)
{
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
-
- TransData *td;
- TransData2D *td2d;
-
- for (td = tc->data; td < tc->data + tc->data_len; td++) {
- restoreElement(td);
- }
-
- 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);
-
- }
-
- recalcData(t);
+ FOREACH_TRANS_DATA_CONTAINER(t, tc)
+ {
+
+ TransData *td;
+ TransData2D *td2d;
+
+ for (td = tc->data; td < tc->data + tc->data_len; td++) {
+ restoreElement(td);
+ }
+
+ 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);
+ }
+
+ recalcData(t);
}
void calculateCenter2D(TransInfo *t)
{
- BLI_assert(!is_zero_v3(t->aspect));
- projectFloatView(t, t->center_global, t->center2d);
+ BLI_assert(!is_zero_v3(t->aspect));
+ projectFloatView(t, t->center_global, t->center2d);
}
-void calculateCenterLocal(
- TransInfo *t, const float center_global[3])
+void calculateCenterLocal(TransInfo *t, const float center_global[3])
{
- /* setting constraint center */
- /* note, init functions may over-ride t->center */
- 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);
- }
- }
+ /* setting constraint center */
+ /* note, init functions may over-ride t->center */
+ 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);
+ }
+ }
}
void calculateCenterCursor(TransInfo *t, float r_center[3])
{
- const float *cursor = t->scene->cursor.location;
- copy_v3_v3(r_center, cursor);
-
- /* If edit or pose mode, move cursor in local space */
- 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;
- }
- r_center[2] = 0.0f;
- }
+ const float *cursor = t->scene->cursor.location;
+ copy_v3_v3(r_center, cursor);
+
+ /* If edit or pose mode, move cursor in local space */
+ 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;
+ }
+ r_center[2] = 0.0f;
+ }
}
void calculateCenterCursor2D(TransInfo *t, float r_center[2])
{
- const float *cursor = NULL;
-
- if (t->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = (SpaceImage *)t->sa->spacedata.first;
- cursor = sima->cursor;
- }
- else if (t->spacetype == SPACE_CLIP) {
- SpaceClip *space_clip = (SpaceClip *) t->sa->spacedata.first;
- cursor = space_clip->cursor;
- }
-
- if (cursor) {
- if (t->options & CTX_MASK) {
- float co[2];
-
- if (t->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = (SpaceImage *)t->sa->spacedata.first;
- BKE_mask_coord_from_image(sima->image, &sima->iuser, co, cursor);
- }
- else if (t->spacetype == SPACE_CLIP) {
- SpaceClip *space_clip = (SpaceClip *) t->sa->spacedata.first;
- BKE_mask_coord_from_movieclip(space_clip->clip, &space_clip->user, co, cursor);
- }
- else {
- BLI_assert(!"Shall not happen");
- }
-
- r_center[0] = co[0] * t->aspect[0];
- r_center[1] = co[1] * t->aspect[1];
- }
- else if (t->options & CTX_PAINT_CURVE) {
- if (t->spacetype == SPACE_IMAGE) {
- r_center[0] = UI_view2d_view_to_region_x(&t->ar->v2d, cursor[0]);
- r_center[1] = UI_view2d_view_to_region_y(&t->ar->v2d, cursor[1]);
- }
- }
- else {
- r_center[0] = cursor[0] * t->aspect[0];
- r_center[1] = cursor[1] * t->aspect[1];
- }
- }
+ const float *cursor = NULL;
+
+ if (t->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)t->sa->spacedata.first;
+ cursor = sima->cursor;
+ }
+ else if (t->spacetype == SPACE_CLIP) {
+ SpaceClip *space_clip = (SpaceClip *)t->sa->spacedata.first;
+ cursor = space_clip->cursor;
+ }
+
+ if (cursor) {
+ if (t->options & CTX_MASK) {
+ float co[2];
+
+ if (t->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)t->sa->spacedata.first;
+ BKE_mask_coord_from_image(sima->image, &sima->iuser, co, cursor);
+ }
+ else if (t->spacetype == SPACE_CLIP) {
+ SpaceClip *space_clip = (SpaceClip *)t->sa->spacedata.first;
+ BKE_mask_coord_from_movieclip(space_clip->clip, &space_clip->user, co, cursor);
+ }
+ else {
+ BLI_assert(!"Shall not happen");
+ }
+
+ r_center[0] = co[0] * t->aspect[0];
+ r_center[1] = co[1] * t->aspect[1];
+ }
+ else if (t->options & CTX_PAINT_CURVE) {
+ if (t->spacetype == SPACE_IMAGE) {
+ r_center[0] = UI_view2d_view_to_region_x(&t->ar->v2d, cursor[0]);
+ r_center[1] = UI_view2d_view_to_region_y(&t->ar->v2d, cursor[1]);
+ }
+ }
+ else {
+ r_center[0] = cursor[0] * t->aspect[0];
+ r_center[1] = cursor[1] * t->aspect[1];
+ }
+ }
}
void calculateCenterCursorGraph2D(TransInfo *t, float r_center[2])
{
- SpaceGraph *sipo = (SpaceGraph *)t->sa->spacedata.first;
- Scene *scene = t->scene;
-
- /* cursor is combination of current frame, and graph-editor cursor value */
- if (sipo->mode == SIPO_MODE_DRIVERS) {
- r_center[0] = sipo->cursorTime;
- r_center[1] = sipo->cursorVal;
- }
- else {
- r_center[0] = (float)(scene->r.cfra);
- r_center[1] = sipo->cursorVal;
- }
+ SpaceGraph *sipo = (SpaceGraph *)t->sa->spacedata.first;
+ Scene *scene = t->scene;
+
+ /* cursor is combination of current frame, and graph-editor cursor value */
+ if (sipo->mode == SIPO_MODE_DRIVERS) {
+ r_center[0] = sipo->cursorTime;
+ r_center[1] = sipo->cursorVal;
+ }
+ else {
+ r_center[0] = (float)(scene->r.cfra);
+ r_center[1] = sipo->cursorVal;
+ }
}
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) {
- 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++;
- }
- }
- }
- }
- if (total) {
- mul_v3_fl(partial, 1.0f / (float)total);
- }
- copy_v3_v3(r_center, partial);
+ float partial[3] = {0.0f, 0.0f, 0.0f};
+ int total = 0;
+
+ 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++;
+ }
+ }
+ }
+ }
+ if (total) {
+ mul_v3_fl(partial, 1.0f / (float)total);
+ }
+ copy_v3_v3(r_center, partial);
}
void calculateCenterBound(TransInfo *t, float r_center[3])
{
- 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;
- }
- }
- }
- }
- if (changed) {
- mid_v3_v3v3(r_center, min, max);
- }
+ 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;
+ }
+ }
+ }
+ }
+ if (changed) {
+ mid_v3_v3v3(r_center, min, max);
+ }
}
/**
@@ -2036,286 +2043,287 @@ 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);
-
- if (t->spacetype != SPACE_VIEW3D) {
- return false;
- }
- else if (tc->obedit) {
- if (ED_object_calc_active_center_for_editmode(tc->obedit, select_only, r_center)) {
- mul_m4_v3(tc->obedit->obmat, r_center);
- return true;
- }
- }
- else if (t->flag & T_POSE) {
- ViewLayer *view_layer = t->view_layer;
- Object *ob = OBACT(view_layer) ;
- if (ED_object_calc_active_center_for_posemode(ob, select_only, r_center)) {
- mul_m4_v3(ob->obmat, r_center);
- return true;
- }
- }
- else if (t->options & CTX_PAINT_CURVE) {
- 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]);
- r_center[2] = 0.0f;
- return true;
- }
- else {
- /* object mode */
- 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]);
- return true;
- }
- }
-
- return false;
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_OK(t);
+
+ if (t->spacetype != SPACE_VIEW3D) {
+ return false;
+ }
+ else if (tc->obedit) {
+ if (ED_object_calc_active_center_for_editmode(tc->obedit, select_only, r_center)) {
+ mul_m4_v3(tc->obedit->obmat, r_center);
+ return true;
+ }
+ }
+ else if (t->flag & T_POSE) {
+ ViewLayer *view_layer = t->view_layer;
+ Object *ob = OBACT(view_layer);
+ if (ED_object_calc_active_center_for_posemode(ob, select_only, r_center)) {
+ mul_m4_v3(ob->obmat, r_center);
+ return true;
+ }
+ }
+ else if (t->options & CTX_PAINT_CURVE) {
+ 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]);
+ r_center[2] = 0.0f;
+ return true;
+ }
+ else {
+ /* object mode */
+ 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]);
+ return true;
+ }
+ }
+
+ return false;
}
static void calculateCenter_FromAround(TransInfo *t, int around, float r_center[3])
{
- switch (around) {
- case V3D_AROUND_CENTER_BOUNDS:
- calculateCenterBound(t, r_center);
- break;
- case V3D_AROUND_CENTER_MEDIAN:
- calculateCenterMedian(t, r_center);
- break;
- case V3D_AROUND_CURSOR:
- if (ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP))
- calculateCenterCursor2D(t, r_center);
- else if (t->spacetype == SPACE_GRAPH)
- calculateCenterCursorGraph2D(t, r_center);
- else
- calculateCenterCursor(t, r_center);
- break;
- case V3D_AROUND_LOCAL_ORIGINS:
- /* Individual element center uses median center for helpline and such */
- calculateCenterMedian(t, r_center);
- break;
- case V3D_AROUND_ACTIVE:
- {
- if (calculateCenterActive(t, false, r_center)) {
- /* pass */
- }
- else {
- /* fallback */
- calculateCenterMedian(t, r_center);
- }
- break;
- }
- }
+ switch (around) {
+ case V3D_AROUND_CENTER_BOUNDS:
+ calculateCenterBound(t, r_center);
+ break;
+ case V3D_AROUND_CENTER_MEDIAN:
+ calculateCenterMedian(t, r_center);
+ break;
+ case V3D_AROUND_CURSOR:
+ if (ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP))
+ calculateCenterCursor2D(t, r_center);
+ else if (t->spacetype == SPACE_GRAPH)
+ calculateCenterCursorGraph2D(t, r_center);
+ else
+ calculateCenterCursor(t, r_center);
+ break;
+ case V3D_AROUND_LOCAL_ORIGINS:
+ /* Individual element center uses median center for helpline and such */
+ calculateCenterMedian(t, r_center);
+ break;
+ case V3D_AROUND_ACTIVE: {
+ if (calculateCenterActive(t, false, r_center)) {
+ /* pass */
+ }
+ else {
+ /* fallback */
+ calculateCenterMedian(t, r_center);
+ }
+ break;
+ }
+ }
}
void calculateCenter(TransInfo *t)
{
- if ((t->flag & T_OVERRIDE_CENTER) == 0) {
- calculateCenter_FromAround(t, t->around, t->center_global);
- }
- calculateCenterLocal(t, t->center_global);
-
- /* avoid calculating again */
- {
- TransCenterData *cd = &t->center_cache[t->around];
- copy_v3_v3(cd->global, t->center_global);
- cd->is_set = true;
- }
-
- calculateCenter2D(t);
-
- /* for panning from cameraview */
- if ((t->flag & T_OBJECT) && (t->flag & T_OVERRIDE_CENTER) == 0) {
- if (t->spacetype == SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) {
-
- if (t->flag & T_CAMERA) {
- float axis[3];
- /* persinv is nasty, use viewinv instead, always right */
- copy_v3_v3(axis, t->viewinv[2]);
- normalize_v3(axis);
-
- /* 6.0 = 6 grid units */
- 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_global, axis);
- }
- }
- }
- }
-
- if (t->spacetype == SPACE_VIEW3D) {
- /* ED_view3d_calc_zfac() defines a factor for perspective depth correction, used in ED_view3d_win_to_delta() */
-
- /* zfac is only used convertViewVec only in cases operator was invoked in RGN_TYPE_WINDOW
- * and never used in other cases.
- *
- * We need special case here as well, since ED_view3d_calc_zfac will crash when called
- * for a region different from RGN_TYPE_WINDOW.
- */
- if (t->ar->regiontype == RGN_TYPE_WINDOW) {
- t->zfac = ED_view3d_calc_zfac(t->ar->regiondata, t->center_global, NULL);
- }
- else {
- t->zfac = 0.0f;
- }
- }
+ if ((t->flag & T_OVERRIDE_CENTER) == 0) {
+ calculateCenter_FromAround(t, t->around, t->center_global);
+ }
+ calculateCenterLocal(t, t->center_global);
+
+ /* avoid calculating again */
+ {
+ TransCenterData *cd = &t->center_cache[t->around];
+ copy_v3_v3(cd->global, t->center_global);
+ cd->is_set = true;
+ }
+
+ calculateCenter2D(t);
+
+ /* for panning from cameraview */
+ if ((t->flag & T_OBJECT) && (t->flag & T_OVERRIDE_CENTER) == 0) {
+ if (t->spacetype == SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) {
+
+ if (t->flag & T_CAMERA) {
+ float axis[3];
+ /* persinv is nasty, use viewinv instead, always right */
+ copy_v3_v3(axis, t->viewinv[2]);
+ normalize_v3(axis);
+
+ /* 6.0 = 6 grid units */
+ 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_global, axis);
+ }
+ }
+ }
+ }
+
+ if (t->spacetype == SPACE_VIEW3D) {
+ /* ED_view3d_calc_zfac() defines a factor for perspective depth correction, used in ED_view3d_win_to_delta() */
+
+ /* zfac is only used convertViewVec only in cases operator was invoked in RGN_TYPE_WINDOW
+ * and never used in other cases.
+ *
+ * We need special case here as well, since ED_view3d_calc_zfac will crash when called
+ * for a region different from RGN_TYPE_WINDOW.
+ */
+ if (t->ar->regiontype == RGN_TYPE_WINDOW) {
+ t->zfac = ED_view3d_calc_zfac(t->ar->regiondata, t->center_global, NULL);
+ }
+ else {
+ t->zfac = 0.0f;
+ }
+ }
}
-BLI_STATIC_ASSERT(ARRAY_SIZE(((TransInfo *)NULL)->center_cache) == (V3D_AROUND_ACTIVE + 1), "test size");
+BLI_STATIC_ASSERT(ARRAY_SIZE(((TransInfo *)NULL)->center_cache) == (V3D_AROUND_ACTIVE + 1),
+ "test size");
/**
* Lazy initialize transform center data, when we need to access center values from other types.
*/
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->global);
- cd->is_set = true;
- }
- return cd;
+ BLI_assert(around <= V3D_AROUND_ACTIVE);
+ TransCenterData *cd = &t->center_cache[around];
+ if (cd->is_set == false) {
+ calculateCenter_FromAround(t, around, cd->global);
+ cd->is_set = true;
+ }
+ return cd;
}
void calculatePropRatio(TransInfo *t)
{
- int i;
- float dist;
- const bool connected = (t->flag & T_PROP_CONNECTED) != 0;
-
- t->proptext[0] = '\0';
-
- if (t->flag & T_PROP_EDIT) {
- const char *pet_id = NULL;
- 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 (tc->mirror.axis_flag && (td->loc[0] * tc->mirror.sign) < -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;
-
- 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)");
- break;
- case PROP_SMOOTH:
- pet_id = N_("(Smooth)");
- break;
- case PROP_ROOT:
- pet_id = N_("(Root)");
- break;
- case PROP_LIN:
- pet_id = N_("(Linear)");
- break;
- case PROP_CONST:
- pet_id = N_("(Constant)");
- break;
- case PROP_SPHERE:
- pet_id = N_("(Sphere)");
- break;
- case PROP_RANDOM:
- pet_id = N_("(Random)");
- break;
- case PROP_INVSQUARE:
- pet_id = N_("(InvSquare)");
- break;
- default:
- break;
- }
-
- if (pet_id) {
- BLI_strncpy(t->proptext, IFACE_(pet_id), sizeof(t->proptext));
- }
- }
- else {
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- for (i = 0; i < tc->data_len; i++, td++) {
- td->factor = 1.0;
- }
- }
- }
+ int i;
+ float dist;
+ const bool connected = (t->flag & T_PROP_CONNECTED) != 0;
+
+ t->proptext[0] = '\0';
+
+ if (t->flag & T_PROP_EDIT) {
+ const char *pet_id = NULL;
+ 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 (tc->mirror.axis_flag && (td->loc[0] * tc->mirror.sign) < -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;
+
+ 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)");
+ break;
+ case PROP_SMOOTH:
+ pet_id = N_("(Smooth)");
+ break;
+ case PROP_ROOT:
+ pet_id = N_("(Root)");
+ break;
+ case PROP_LIN:
+ pet_id = N_("(Linear)");
+ break;
+ case PROP_CONST:
+ pet_id = N_("(Constant)");
+ break;
+ case PROP_SPHERE:
+ pet_id = N_("(Sphere)");
+ break;
+ case PROP_RANDOM:
+ pet_id = N_("(Random)");
+ break;
+ case PROP_INVSQUARE:
+ pet_id = N_("(InvSquare)");
+ break;
+ default:
+ break;
+ }
+
+ if (pet_id) {
+ BLI_strncpy(t->proptext, IFACE_(pet_id), sizeof(t->proptext));
+ }
+ }
+ else {
+ FOREACH_TRANS_DATA_CONTAINER(t, tc)
+ {
+ TransData *td = tc->data;
+ for (i = 0; i < tc->data_len; i++, td++) {
+ td->factor = 1.0;
+ }
+ }
+ }
}
/**
@@ -2325,101 +2333,100 @@ void calculatePropRatio(TransInfo *t)
*/
void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
{
- float totmat[3][3];
- float smat[3][3];
- float fmat[3][3];
- float obmat[3][3];
-
- float dmat[3][3]; /* delta rotation */
- float dmat_inv[3][3];
-
- mul_m3_m3m3(totmat, mat, td->mtx);
- mul_m3_m3m3(smat, td->smtx, mat);
-
- /* logic from BKE_object_rot_to_mat3 */
- if (use_drot) {
- if (td->ext->rotOrder > 0) {
- eulO_to_mat3(dmat, td->ext->drot, td->ext->rotOrder);
- }
- else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
+ float totmat[3][3];
+ float smat[3][3];
+ float fmat[3][3];
+ float obmat[3][3];
+
+ float dmat[3][3]; /* delta rotation */
+ float dmat_inv[3][3];
+
+ mul_m3_m3m3(totmat, mat, td->mtx);
+ mul_m3_m3m3(smat, td->smtx, mat);
+
+ /* logic from BKE_object_rot_to_mat3 */
+ if (use_drot) {
+ if (td->ext->rotOrder > 0) {
+ eulO_to_mat3(dmat, td->ext->drot, td->ext->rotOrder);
+ }
+ else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
#if 0
- axis_angle_to_mat3(dmat, td->ext->drotAxis, td->ext->drotAngle);
+ axis_angle_to_mat3(dmat, td->ext->drotAxis, td->ext->drotAngle);
#else
- unit_m3(dmat);
+ unit_m3(dmat);
#endif
- }
- else {
- float tquat[4];
- normalize_qt_qt(tquat, td->ext->dquat);
- quat_to_mat3(dmat, tquat);
- }
-
- invert_m3_m3(dmat_inv, dmat);
- }
-
-
- if (td->ext->rotOrder == ROT_MODE_QUAT) {
- float quat[4];
-
- /* calculate the total rotatation */
- quat_to_mat3(obmat, td->ext->iquat);
- if (use_drot) {
- mul_m3_m3m3(obmat, dmat, obmat);
- }
-
- /* mat = transform, obmat = object rotation */
- mul_m3_m3m3(fmat, smat, obmat);
-
- if (use_drot) {
- mul_m3_m3m3(fmat, dmat_inv, fmat);
- }
-
- mat3_to_quat(quat, fmat);
-
- /* apply */
- copy_qt_qt(td->ext->quat, quat);
- }
- else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
- float axis[3], angle;
-
- /* calculate the total rotatation */
- axis_angle_to_mat3(obmat, td->ext->irotAxis, td->ext->irotAngle);
- if (use_drot) {
- mul_m3_m3m3(obmat, dmat, obmat);
- }
-
- /* mat = transform, obmat = object rotation */
- mul_m3_m3m3(fmat, smat, obmat);
-
- if (use_drot) {
- mul_m3_m3m3(fmat, dmat_inv, fmat);
- }
-
- mat3_to_axis_angle(axis, &angle, fmat);
-
- /* apply */
- copy_v3_v3(td->ext->rotAxis, axis);
- *td->ext->rotAngle = angle;
- }
- else {
- float eul[3];
-
- /* calculate the total rotatation */
- eulO_to_mat3(obmat, td->ext->irot, td->ext->rotOrder);
- if (use_drot) {
- mul_m3_m3m3(obmat, dmat, obmat);
- }
-
- /* mat = transform, obmat = object rotation */
- mul_m3_m3m3(fmat, smat, obmat);
-
- if (use_drot) {
- mul_m3_m3m3(fmat, dmat_inv, fmat);
- }
-
- mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
-
- /* apply */
- copy_v3_v3(td->ext->rot, eul);
- }
+ }
+ else {
+ float tquat[4];
+ normalize_qt_qt(tquat, td->ext->dquat);
+ quat_to_mat3(dmat, tquat);
+ }
+
+ invert_m3_m3(dmat_inv, dmat);
+ }
+
+ if (td->ext->rotOrder == ROT_MODE_QUAT) {
+ float quat[4];
+
+ /* calculate the total rotatation */
+ quat_to_mat3(obmat, td->ext->iquat);
+ if (use_drot) {
+ mul_m3_m3m3(obmat, dmat, obmat);
+ }
+
+ /* mat = transform, obmat = object rotation */
+ mul_m3_m3m3(fmat, smat, obmat);
+
+ if (use_drot) {
+ mul_m3_m3m3(fmat, dmat_inv, fmat);
+ }
+
+ mat3_to_quat(quat, fmat);
+
+ /* apply */
+ copy_qt_qt(td->ext->quat, quat);
+ }
+ else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
+ float axis[3], angle;
+
+ /* calculate the total rotatation */
+ axis_angle_to_mat3(obmat, td->ext->irotAxis, td->ext->irotAngle);
+ if (use_drot) {
+ mul_m3_m3m3(obmat, dmat, obmat);
+ }
+
+ /* mat = transform, obmat = object rotation */
+ mul_m3_m3m3(fmat, smat, obmat);
+
+ if (use_drot) {
+ mul_m3_m3m3(fmat, dmat_inv, fmat);
+ }
+
+ mat3_to_axis_angle(axis, &angle, fmat);
+
+ /* apply */
+ copy_v3_v3(td->ext->rotAxis, axis);
+ *td->ext->rotAngle = angle;
+ }
+ else {
+ float eul[3];
+
+ /* calculate the total rotatation */
+ eulO_to_mat3(obmat, td->ext->irot, td->ext->rotOrder);
+ if (use_drot) {
+ mul_m3_m3m3(obmat, dmat, obmat);
+ }
+
+ /* mat = transform, obmat = object rotation */
+ mul_m3_m3m3(fmat, smat, obmat);
+
+ if (use_drot) {
+ mul_m3_m3m3(fmat, dmat_inv, fmat);
+ }
+
+ mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
+
+ /* apply */
+ copy_v3_v3(td->ext->rot, eul);
+ }
}