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')
-rw-r--r--source/blender/editors/transform/transform.c103
-rw-r--r--source/blender/editors/transform/transform.h9
-rw-r--r--source/blender/editors/transform/transform_conversions.c342
-rw-r--r--source/blender/editors/transform/transform_generics.c284
-rw-r--r--source/blender/editors/transform/transform_ops.c1
-rw-r--r--source/blender/editors/transform/transform_snap.c25
6 files changed, 440 insertions, 324 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 7128bd9c6a9..81e2e44954a 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -322,7 +322,7 @@ static void viewRedrawForce(bContext *C, TransInfo *t)
else if(t->spacetype == SPACE_NODE)
{
//ED_area_tag_redraw(t->sa);
- WM_event_add_notifier(C, NC_SPACE|ND_SPACE_NODE, NULL);
+ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_NODE_VIEW, NULL);
}
else if(t->spacetype == SPACE_SEQ)
{
@@ -1124,15 +1124,8 @@ void drawHelpline(const struct bContext *C, TransInfo *t)
projectFloatView(t, vecrot, cent); // no overflow in extreme cases
- glDisable(GL_DEPTH_TEST);
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glMatrixMode(GL_MODELVIEW);
glPushMatrix();
- ED_region_pixelspace(t->ar);
-
switch(t->helpline)
{
case HLP_SPRING:
@@ -1238,22 +1231,23 @@ void drawHelpline(const struct bContext *C, TransInfo *t)
}
}
- glMatrixMode(GL_PROJECTION);
glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-
- glEnable(GL_DEPTH_TEST);
}
}
-void drawTransform(const struct bContext *C, struct ARegion *ar, void *arg)
+void drawTransformView(const struct bContext *C, struct ARegion *ar, void *arg)
{
TransInfo *t = arg;
drawConstraint(C, t);
drawPropCircle(C, t);
drawSnapping(C, t);
+}
+
+void drawTransformPixel(const struct bContext *C, struct ARegion *ar, void *arg)
+{
+ TransInfo *t = arg;
+
drawHelpline(C, t);
}
@@ -1373,11 +1367,13 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
//calc_manipulator_stats(curarea);
initTransformOrientation(C, t);
- t->draw_handle = ED_region_draw_cb_activate(t->ar->type, drawTransform, t, REGION_DRAW_POST);
+ t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
+ t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
}
else if(t->spacetype == SPACE_IMAGE) {
Mat3One(t->spacemtx);
- t->draw_handle = ED_region_draw_cb_activate(t->ar->type, drawTransform, t, REGION_DRAW_POST);
+ t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
+ t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
}
else
Mat3One(t->spacemtx);
@@ -1638,7 +1634,7 @@ static void protectedRotateBits(short protectflag, float *eul, float *oldeul)
/* this function only does the delta rotation */
/* axis-angle is usually internally stored as quats... */
-static void protectedAxisAngleBits(short protectflag, float *quat, float *oldquat)
+static void protectedAxisAngleBits(short protectflag, float axis[3], float *angle, float oldAxis[3], float oldAngle)
{
/* check that protection flags are set */
if ((protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) == 0)
@@ -1647,21 +1643,20 @@ static void protectedAxisAngleBits(short protectflag, float *quat, float *oldqua
if (protectflag & OB_LOCK_ROT4D) {
/* axis-angle getting limited as 4D entities that they are... */
if (protectflag & OB_LOCK_ROTW)
- quat[0]= oldquat[0];
+ *angle= oldAngle;
if (protectflag & OB_LOCK_ROTX)
- quat[1]= oldquat[1];
+ axis[0]= oldAxis[0];
if (protectflag & OB_LOCK_ROTY)
- quat[2]= oldquat[2];
+ axis[1]= oldAxis[1];
if (protectflag & OB_LOCK_ROTZ)
- quat[3]= oldquat[3];
+ axis[2]= oldAxis[2];
}
else {
/* axis-angle get limited with euler... */
- float eul[3], oldeul[3], quat1[4];
+ float eul[3], oldeul[3];
- QUATCOPY(quat1, quat);
- AxisAngleToEulO(quat+1, quat[0], eul, EULER_ORDER_DEFAULT);
- AxisAngleToEulO(oldquat+1, oldquat[0], oldeul, EULER_ORDER_DEFAULT);
+ AxisAngleToEulO(axis, *angle, eul, EULER_ORDER_DEFAULT);
+ AxisAngleToEulO(oldAxis, oldAngle, oldeul, EULER_ORDER_DEFAULT);
if (protectflag & OB_LOCK_ROTX)
eul[0]= oldeul[0];
@@ -1670,12 +1665,12 @@ static void protectedAxisAngleBits(short protectflag, float *quat, float *oldqua
if (protectflag & OB_LOCK_ROTZ)
eul[2]= oldeul[2];
- EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, quat+1, quat);
+ EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, axis, angle);
/* when converting to axis-angle, we need a special exception for the case when there is no axis */
- if (IS_EQ(quat[1], quat[2]) && IS_EQ(quat[2], quat[3])) {
+ if (IS_EQ(axis[0], axis[1]) && IS_EQ(axis[1], axis[2])) {
/* for now, rotate around y-axis then (so that it simply becomes the roll) */
- quat[2]= 1.0f;
+ axis[1]= 1.0f;
}
}
}
@@ -2694,22 +2689,18 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
}
else if (td->rotOrder == ROT_MODE_AXISANGLE) {
/* calculate effect based on quats */
- float iquat[4];
+ float iquat[4], tquat[4];
- /* td->ext->(i)quat is in axis-angle form, not quats! */
- AxisAngleToQuat(iquat, &td->ext->iquat[1], td->ext->iquat[0]);
+ AxisAngleToQuat(iquat, td->ext->irotAxis, td->ext->irotAngle);
Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
Mat3ToQuat(fmat, quat); // Actual transform
+ QuatMul(tquat, quat, iquat);
- QuatMul(td->ext->quat, quat, iquat);
-
- /* make temp copy (since stored in same place) */
- QUATCOPY(quat, td->ext->quat); // this is just a 4d vector copying macro
- QuatToAxisAngle(quat, &td->ext->quat[1], &td->ext->quat[0]);
+ QuatToAxisAngle(tquat, td->ext->rotAxis, td->ext->rotAngle);
/* this function works on end result */
- protectedAxisAngleBits(td->protectflag, td->ext->quat, td->ext->iquat);
+ protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis, td->ext->irotAngle);
}
else {
float eulmat[3][3];
@@ -2766,22 +2757,18 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
}
else if (td->rotOrder == ROT_MODE_AXISANGLE) {
/* calculate effect based on quats */
- float iquat[4];
+ float iquat[4], tquat[4];
- /* td->ext->(i)quat is in axis-angle form, not quats! */
- AxisAngleToQuat(iquat, &td->ext->iquat[1], td->ext->iquat[0]);
+ AxisAngleToQuat(iquat, td->ext->irotAxis, td->ext->irotAngle);
Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
Mat3ToQuat(fmat, quat); // Actual transform
+ QuatMul(tquat, quat, iquat);
- QuatMul(td->ext->quat, quat, iquat);
-
- /* make temp copy (since stored in same place) */
- QUATCOPY(quat, td->ext->quat); // this is just a 4d vector copying macro
- QuatToAxisAngle(quat, &td->ext->quat[1], &td->ext->quat[0]);
+ QuatToAxisAngle(quat, td->ext->rotAxis, td->ext->rotAngle);
/* this function works on end result */
- protectedAxisAngleBits(td->protectflag, td->ext->quat, td->ext->iquat);
+ protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis, td->ext->irotAngle);
}
else {
float obmat[3][3];
@@ -3956,10 +3943,8 @@ static int createSlideVerts(TransInfo *t)
LinkNode *edgelist = NULL, *vertlist=NULL, *look;
GHash *vertgh;
TransDataSlideVert *tempsv;
- float perc = 0, percp = 0,vertdist; // XXX, projectMat[4][4];
- float shiftlabda= 0.0f,len = 0.0f;
- int i, j, numsel, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0,flip=0;
- int wasshift = 0;
+ float vertdist; // XXX, projectMat[4][4];
+ int i, j, numsel, numadded=0, timesthrough = 0, vertsel=0;
/* UV correction vars */
GHash **uvarray= NULL;
SlideData *sld = MEM_callocN(sizeof(*sld), "sld");
@@ -3970,8 +3955,7 @@ static int createSlideVerts(TransInfo *t)
float projectMat[4][4];
float start[3] = {0.0f, 0.0f, 0.0f}, end[3] = {0.0f, 0.0f, 0.0f};
float vec[3];
- //short mval[2], mvalo[2];
- float labda = 0.0f, totvec=0.0;
+ float totvec=0.0;
if (!v3d) {
/*ok, let's try to survive this*/
@@ -3979,8 +3963,7 @@ static int createSlideVerts(TransInfo *t)
} else {
view3d_get_object_project_mat(v3d, t->obedit, projectMat);
}
-
- //mvalo[0] = -1; mvalo[1] = -1;
+
numsel =0;
// Get number of selected edges and clear some flags
@@ -4486,23 +4469,20 @@ int doEdgeSlide(TransInfo *t, float perc)
Mesh *me= t->obedit->data;
EditMesh *em = me->edit_mesh;
SlideData *sld = t->customData;
- EditEdge *first=NULL,*last=NULL, *temp = NULL;
EditVert *ev, *nearest = sld->nearest;
EditVert *centerVert, *upVert, *downVert;
- LinkNode *edgelist = sld->edgelist, *vertlist=sld->vertlist, *look;
+ LinkNode *vertlist=sld->vertlist, *look;
GHash *vertgh = sld->vhash;
TransDataSlideVert *tempsv;
- float shiftlabda= 0.0f,len = 0.0f;
- int i = 0, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0,flip=0;
- int wasshift = 0;
+ float len = 0.0f;
+ int prop=1, flip=0;
/* UV correction vars */
GHash **uvarray= sld->uvhash;
int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
int uvlay_idx;
- TransDataSlideUv *slideuvs=sld->slideuv, *suv=sld->slideuv, *suv_last=NULL;
+ TransDataSlideUv *suv=sld->slideuv;
float uv_tmp[2];
LinkNode *fuv_link;
- float labda = 0.0f;
len = 0.0f;
@@ -4597,7 +4577,6 @@ int doEdgeSlide(TransInfo *t, float perc)
int EdgeSlide(TransInfo *t, short mval[2])
{
- TransData *td = t->data;
char str[50];
float final;
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index fc31fad622a..819cb95d948 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -125,12 +125,18 @@ typedef struct TransCon {
typedef struct TransDataExtension {
float drot[3]; /* Initial object drot */
+ float drotAngle; /* Initial object drotAngle */
+ float drotAxis[3]; /* Initial object drotAxis */
float dquat[4]; /* Initial object dquat */
float dsize[3]; /* Initial object dsize */
float *rot; /* Rotation of the data to transform (Faculative) */
float irot[3]; /* Initial rotation */
float *quat; /* Rotation quaternion of the data to transform (Faculative) */
float iquat[4]; /* Initial rotation quaternion */
+ float *rotAngle; /* Rotation angle of the data to transform (Faculative) */
+ float irotAngle; /* Initial rotation angle */
+ float *rotAxis; /* Rotation axis of the data to transform (Faculative) */
+ float irotAxis[4]; /* Initial rotation axis */
float *size; /* Size of the data to transform (Faculative) */
float isize[3]; /* Initial size */
float obmat[4][4]; /* Object matrix */
@@ -302,7 +308,8 @@ typedef struct TransInfo {
struct wmTimer *animtimer;
short mval[2]; /* current mouse position */
struct Object *obedit;
- void *draw_handle;
+ void *draw_handle_view;
+ void *draw_handle_pixel;
} TransInfo;
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 764256c476d..68c647710a9 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -578,12 +578,25 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
if (pchan->rotmode > 0) {
td->ext->rot= pchan->eul;
+ td->ext->rotAxis= NULL;
+ td->ext->rotAngle= NULL;
td->ext->quat= NULL;
VECCOPY(td->ext->irot, pchan->eul);
}
+ else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
+ td->ext->rot= NULL;
+ td->ext->rotAxis= pchan->rotAxis;
+ td->ext->rotAngle= &pchan->rotAngle;
+ td->ext->quat= NULL;
+
+ td->ext->irotAngle= pchan->rotAngle;
+ VECCOPY(td->ext->irotAxis, pchan->rotAxis);
+ }
else {
td->ext->rot= NULL;
+ td->ext->rotAxis= NULL;
+ td->ext->rotAngle= NULL;
td->ext->quat= pchan->quat;
QUATCOPY(td->ext->iquat, pchan->quat);
@@ -1337,7 +1350,7 @@ static void calc_distanceCurveVerts(TransData *head, TransData *tail) {
}
/* Utility function for getting the handle data from bezier's */
-TransDataCurveHandleFlags *initTransDataCurveHandes(TransData *td, struct BezTriple *bezt) {
+TransDataCurveHandleFlags *initTransDataCurveHandles(TransData *td, struct BezTriple *bezt) {
TransDataCurveHandleFlags *hdata;
td->flag |= TD_BEZTRIPLE;
hdata = td->hdata = MEM_mallocN(sizeof(TransDataCurveHandleFlags), "CuHandle Data");
@@ -1427,7 +1440,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
td->ext = NULL;
td->val = NULL;
- hdata = initTransDataCurveHandes(td, bezt);
+ hdata = initTransDataCurveHandles(td, bezt);
Mat3CpyMat3(td->smtx, smtx);
Mat3CpyMat3(td->mtx, mtx);
@@ -1462,7 +1475,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
if ((bezt->f1&SELECT)==0 && (bezt->f3&SELECT)==0)
/* If the middle is selected but the sides arnt, this is needed */
if (hdata==NULL) { /* if the handle was not saved by the previous handle */
- hdata = initTransDataCurveHandes(td, bezt);
+ hdata = initTransDataCurveHandles(td, bezt);
}
td++;
@@ -1487,7 +1500,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
td->val = NULL;
if (hdata==NULL) { /* if the handle was not saved by the previous handle */
- hdata = initTransDataCurveHandes(td, bezt);
+ hdata = initTransDataCurveHandles(td, bezt);
}
Mat3CpyMat3(td->smtx, smtx);
@@ -1506,7 +1519,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
if (propmode && head != tail)
calc_distanceCurveVerts(head, tail-1);
- /* TODO - in the case of tilt and radius we can also avoid allocating the initTransDataCurveHandes
+ /* TODO - in the case of tilt and radius we can also avoid allocating the initTransDataCurveHandles
* but for now just dont change handle types */
if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT) == 0)
testhandlesNurb(nu); /* sets the handles based on their selection, do this after the data is copied to the TransData */
@@ -2246,7 +2259,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
/* detect CrazySpace [tm] */
if(propmode==0) {
- if(modifiers_getCageIndex(t->obedit, NULL)>=0) {
+ if(modifiers_getCageIndex(t->obedit, NULL, 1)>=0) {
if(modifiers_isDeformed(t->scene, t->obedit)) {
/* check if we can use deform matrices for modifier from the
start up to stack, they are more accurate than quats */
@@ -2399,8 +2412,8 @@ void flushTransSeq(TransInfo *t)
{
ListBase *seqbasep= seq_give_editing(t->scene, FALSE)->seqbasep; /* Editing null check alredy done */
int a, new_frame;
- TransData *td= t->data;
- TransData2D *td2d= t->data2d;
+ TransData *td= NULL;
+ TransData2D *td2d= NULL;
TransDataSeq *tdsq= NULL;
Sequence *seq;
@@ -2412,7 +2425,7 @@ void flushTransSeq(TransInfo *t)
Sequence *seq_prev= NULL;
/* flush to 2d vector from internally used 3d vector */
- for(a=0; a<t->total; a++, td++, td2d++) {
+ for(a=0, td= t->data, td2d= t->data2d; a<t->total; a++, td++, td2d++) {
tdsq= (TransDataSeq *)td->extra;
seq= tdsq->seq;
@@ -2446,16 +2459,30 @@ void flushTransSeq(TransInfo *t)
* children are ALWAYS transformed first
* so we dont need to do this in another loop. */
calc_sequence(seq);
+ }
+ else {
+ calc_sequence_disp(seq);
+ }
+ }
+ seq_prev= seq;
+ }
+
+ /* need to do the overlap check in a new loop otherwise adjacent strips
+ * will not be updated and we'll get false positives */
+ seq_prev= NULL;
+ for(a=0, td= t->data, td2d= t->data2d; a<t->total; a++, td++, td2d++) {
+ tdsq= (TransDataSeq *)td->extra;
+ seq= tdsq->seq;
+
+ if (seq != seq_prev) {
+ if(seq->depth==0) {
/* test overlap, displayes red outline */
seq->flag &= ~SEQ_OVERLAP;
if( seq_test_overlap(seqbasep, seq) ) {
seq->flag |= SEQ_OVERLAP;
}
}
- else {
- calc_sequence_disp(seq);
- }
}
seq_prev= seq;
}
@@ -3404,6 +3431,7 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt,
static void createTransGraphEditData(bContext *C, TransInfo *t)
{
+ SpaceIpo *sipo= CTX_wm_space_graph(C);
Scene *scene= CTX_data_scene(C);
ARegion *ar= CTX_wm_region(C);
View2D *v2d= &ar->v2d;
@@ -3416,7 +3444,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
bAnimListElem *ale;
int filter;
- BezTriple *bezt, *prevbezt;
+ BezTriple *bezt;
int count=0, i;
float cfra;
char side;
@@ -3435,7 +3463,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
/* only side on which mouse is gets transformed */
float xmouse, ymouse;
- UI_view2d_region_to_view(&ac.ar->v2d, t->imval[0], t->imval[1], &xmouse, &ymouse);
+ UI_view2d_region_to_view(v2d, t->imval[0], t->imval[1], &xmouse, &ymouse);
side = (xmouse > CFRA) ? 'R' : 'L'; // XXX use t->frame_side
}
else {
@@ -3456,29 +3484,28 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
else
cfra = (float)CFRA;
+ /* F-Curve may not have any keyframes */
+ if (fcu->bezt == NULL)
+ continue;
+
/* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse */
- if (fcu->bezt) {
- for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
- if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
- if (v2d->around == V3D_LOCAL) {
- /* for local-pivot we only need to count the number of selected handles only, so that centerpoitns don't
- * don't get moved wrong
- */
- if (bezt->ipo == BEZT_IPO_BEZ) {
- if (bezt->f1 & SELECT) count++;
- if (bezt->f3 & SELECT) count++;
- }
- else if (bezt->f2 & SELECT) count++;
- }
- else {
- /* for 'normal' pivots */
- if (bezt->ipo == BEZT_IPO_BEZ) {
- if (bezt->f1 & SELECT) count++;
- if (bezt->f2 & SELECT) count++;
- if (bezt->f3 & SELECT) count++;
- }
- else if (bezt->f2 & SELECT) count++;
+ for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
+ if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
+ if (sipo->around == V3D_LOCAL) {
+ /* for local-pivot we only need to count the number of selected handles only, so that centerpoints don't
+ * don't get moved wrong
+ */
+ if (bezt->ipo == BEZT_IPO_BEZ) {
+ if (bezt->f1 & SELECT) count++;
+ if (bezt->f3 & SELECT) count++;
}
+ else if (bezt->f2 & SELECT) count++; // TODO: could this cause problems?
+ }
+ else {
+ /* for 'normal' pivots - just include anything that is selected */
+ if (bezt->f1 & SELECT) count++;
+ if (bezt->f2 & SELECT) count++;
+ if (bezt->f3 & SELECT) count++;
}
}
}
@@ -3514,49 +3541,46 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
else
cfra = (float)CFRA;
+
+ /* F-Curve may not have any keyframes */
+ if (fcu->bezt == NULL)
+ continue;
/* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse (if applicable) */
- bezt= fcu->bezt;
- prevbezt= NULL;
-
- for (i=0; i < fcu->totvert; i++, prevbezt=bezt, bezt++) {
+ for (i=0, bezt= fcu->bezt; i < fcu->totvert; i++, bezt++) {
if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
TransDataCurveHandleFlags *hdata = NULL;
short h1=1, h2=1;
- /* only include handles if selected, and interpolaton mode uses beztriples */
- if ( (!prevbezt && (bezt->ipo==BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo==BEZT_IPO_BEZ)) ) {
- if (bezt->f1 & SELECT) {
- hdata = initTransDataCurveHandes(td, bezt);
- bezt_to_transdata(td++, td2d++, adt, bezt->vec[0], bezt->vec[1], 1, 1, intvals);
- }
- else
- h1= 0;
+ /* only include handles if selected, irrespective of the interpolation modes */
+ if (bezt->f1 & SELECT) {
+ hdata = initTransDataCurveHandles(td, bezt);
+ bezt_to_transdata(td++, td2d++, adt, bezt->vec[0], bezt->vec[1], 1, 1, intvals);
}
- if (bezt->ipo == BEZT_IPO_BEZ) {
- if (bezt->f3 & SELECT) {
- if (hdata==NULL)
- hdata = initTransDataCurveHandes(td, bezt);
- bezt_to_transdata(td++, td2d++, adt, bezt->vec[2], bezt->vec[1], 1, 1, intvals);
- }
- else
- h2= 0;
+ else
+ h1= 0;
+ if (bezt->f3 & SELECT) {
+ if (hdata==NULL)
+ hdata = initTransDataCurveHandles(td, bezt);
+ bezt_to_transdata(td++, td2d++, adt, bezt->vec[2], bezt->vec[1], 1, 1, intvals);
}
+ else
+ h2= 0;
/* only include main vert if selected */
if (bezt->f2 & SELECT) {
- /* if scaling around individuals centers, do no include keyframes */
- if (v2d->around != V3D_LOCAL) {
+ /* if scaling around individuals centers, do not include keyframes */
+ if (sipo->around != V3D_LOCAL) {
/* if handles were not selected, store their selection status */
if (!(bezt->f1 & SELECT) && !(bezt->f3 & SELECT)) {
if (hdata == NULL)
- hdata = initTransDataCurveHandes(td, bezt);
+ hdata = initTransDataCurveHandles(td, bezt);
}
bezt_to_transdata(td++, td2d++, adt, bezt->vec[1], bezt->vec[1], 1, 0, intvals);
}
- /* special hack (must be done after initTransDataCurveHandes(), as that stores handle settings to restore...):
+ /* special hack (must be done after initTransDataCurveHandles(), as that stores handle settings to restore...):
* - Check if we've got entire BezTriple selected and we're scaling/rotating that point,
* then check if we're using auto-handles.
* - If so, change them auto-handles to aligned handles so that handles get affected too
@@ -4089,6 +4113,100 @@ static int SeqToTransData_Recursive(TransInfo *t, ListBase *seqbase, TransData *
return tot;
}
+static void freeSeqData(TransInfo *t)
+{
+ Editing *ed= seq_give_editing(t->scene, FALSE);
+
+ if(ed != NULL) {
+ ListBase *seqbasep= ed->seqbasep;
+ TransData *td= t->data;
+ int a;
+
+ /* prevent updating the same seq twice
+ * if the transdata order is changed this will mess up
+ * but so will TransDataSeq */
+ Sequence *seq_prev= NULL;
+ Sequence *seq;
+
+
+ if (!(t->state == TRANS_CANCEL)) {
+
+#if 0 // default 2.4 behavior
+
+ /* flush to 2d vector from internally used 3d vector */
+ for(a=0; a<t->total; a++, td++) {
+ if ((seq != seq_prev) && (seq->depth==0) && (seq->flag & SEQ_OVERLAP)) {
+ seq= ((TransDataSeq *)td->extra)->seq;
+ shuffle_seq(seqbasep, seq);
+ }
+
+ seq_prev= seq;
+ }
+
+#else // durian hack
+ {
+ int overlap= 0;
+
+ for(a=0; a<t->total; a++, td++) {
+ seq_prev= NULL;
+ seq= ((TransDataSeq *)td->extra)->seq;
+ if ((seq != seq_prev) && (seq->depth==0) && (seq->flag & SEQ_OVERLAP)) {
+ overlap= 1;
+ break;
+ }
+ seq_prev= seq;
+ }
+
+ if(overlap) {
+ for(seq= seqbasep->first; seq; seq= seq->next)
+ seq->tmp= NULL;
+
+ td= t->data;
+ seq_prev= NULL;
+ for(a=0; a<t->total; a++, td++) {
+ seq= ((TransDataSeq *)td->extra)->seq;
+ if ((seq != seq_prev)) {
+ seq->tmp= 1;
+ }
+ }
+
+ shuffle_seq_time(seqbasep);
+ }
+ }
+#endif
+
+ for(seq= seqbasep->first; seq; seq= seq->next) {
+ /* We might want to build a list of effects that need to be updated during transform */
+ if(seq->type & SEQ_EFFECT) {
+ if (seq->seq1 && seq->seq1->flag & SELECT) calc_sequence(seq);
+ else if (seq->seq2 && seq->seq2->flag & SELECT) calc_sequence(seq);
+ else if (seq->seq3 && seq->seq3->flag & SELECT) calc_sequence(seq);
+ }
+ }
+
+ sort_seq(t->scene);
+ }
+ else {
+ /* Cancelled, need to update the strips display */
+ for(a=0; a<t->total; a++, td++) {
+ seq= ((TransDataSeq *)td->extra)->seq;
+ if ((seq != seq_prev) && (seq->depth==0)) {
+ calc_sequence_disp(seq);
+ }
+ seq_prev= seq;
+ }
+ }
+ }
+
+ if (t->customData) {
+ MEM_freeN(t->customData);
+ t->customData= NULL;
+ }
+ if (t->data) {
+ MEM_freeN(t->data); // XXX postTrans usually does this
+ t->data= NULL;
+ }
+}
static void createTransSeqData(bContext *C, TransInfo *t)
{
@@ -4107,6 +4225,8 @@ static void createTransSeqData(bContext *C, TransInfo *t)
return;
}
+ t->customFree= freeSeqData;
+
/* which side of the current frame should be allowed */
if (t->mode == TFM_TIME_EXTEND) {
/* only side on which mouse is gets transformed */
@@ -4195,14 +4315,37 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object *
td->loc = ob->loc;
VECCOPY(td->iloc, td->loc);
-
- td->ext->rot = ob->rot;
- VECCOPY(td->ext->irot, ob->rot);
- VECCOPY(td->ext->drot, ob->drot);
- td->ext->quat = ob->quat;
- QUATCOPY(td->ext->iquat, ob->quat);
- QUATCOPY(td->ext->dquat, ob->dquat);
+ if (ob->rotmode > 0) {
+ td->ext->rot= ob->rot;
+ td->ext->rotAxis= NULL;
+ td->ext->rotAngle= NULL;
+ td->ext->quat= NULL;
+
+ VECCOPY(td->ext->irot, ob->rot);
+ VECCOPY(td->ext->drot, ob->drot);
+ }
+ else if (ob->rotmode == ROT_MODE_AXISANGLE) {
+ td->ext->rot= NULL;
+ td->ext->rotAxis= ob->rotAxis;
+ td->ext->rotAngle= &ob->rotAngle;
+ td->ext->quat= NULL;
+
+ td->ext->irotAngle= ob->rotAngle;
+ VECCOPY(td->ext->irotAxis, ob->rotAxis);
+ td->ext->drotAngle= ob->drotAngle;
+ VECCOPY(td->ext->drotAxis, ob->drotAxis);
+ }
+ else {
+ td->ext->rot= NULL;
+ td->ext->rotAxis= NULL;
+ td->ext->rotAngle= NULL;
+ td->ext->quat= ob->quat;
+
+ QUATCOPY(td->ext->iquat, ob->quat);
+ QUATCOPY(td->ext->dquat, ob->dquat);
+ }
+ td->rotOrder=ob->rotmode;
td->ext->size = ob->size;
VECCOPY(td->ext->isize, ob->size);
@@ -4558,6 +4701,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
/* inserting keys, refresh ipo-keys, pointcache, redraw events... (ton) */
/* note: transdata has been freed already! */
/* note: this runs even when createTransData exits early because (t->total==0), is this correct?... (campbell) */
+/* note: sequencer freeing has its own function now because of a conflict with transform's order of freeing (campbell)*/
void special_aftertrans_update(TransInfo *t)
{
Object *ob;
@@ -4568,71 +4712,13 @@ void special_aftertrans_update(TransInfo *t)
if (t->spacetype==SPACE_VIEW3D) {
if (t->obedit) {
if (cancelled==0) {
- EM_automerge(t->scene, t->obedit, 1);
+ EDBM_automerge(t->scene, t->obedit, 1);
}
}
}
-
- if (t->spacetype == SPACE_SEQ) {
- Editing *ed= seq_give_editing(t->scene, FALSE);
- if (ed && !cancelled) {
- ListBase *seqbasep= ed->seqbasep;
- Sequence *seq;
-#if 0 // TRANSFORM_FIX_ME, Would prefer to use this since the array takes into
- // account what where transforming (with extend, locked strips etc)
- // But at the moment t->data is freed in postTrans so for now re-shuffeling selected strips works ok. - Campbell
-
- int a;
- TransData *td= t->data;
-
- /* prevent updating the same seq twice
- * if the transdata order is changed this will mess up
- * but so will TransDataSeq */
- Sequence *seq_prev= NULL;
-
- /* flush to 2d vector from internally used 3d vector */
- for(a=0; a<t->total; a++, td++) {
- seq= ((TransDataSeq *)td->extra)->seq;
- if ((seq != seq_prev) && (seq->depth==0) && (seq->flag & SEQ_OVERLAP)) {
- shuffle_seq(seqbasep, seq);
- }
-
- seq_prev= seq;
- }
-#else // while t->data is not available...
- int machine, max_machine = 0;
-
- /* update in order so we always move bottom strips first */
- for(seq= seqbasep->first; seq; seq= seq->next) {
- max_machine = MAX2(max_machine, seq->machine);
- }
-
- for (machine = 0; machine <= max_machine; machine++)
- {
- for(seq= seqbasep->first; seq; seq= seq->next) {
- if (seq->machine == machine && seq->depth == 0 && (seq->flag & (SELECT|SEQ_LEFTSEL|SEQ_RIGHTSEL)) != 0 && (seq->flag & SEQ_OVERLAP)) {
- shuffle_seq(seqbasep, seq);
- }
- }
- }
-#endif
-
- for(seq= seqbasep->first; seq; seq= seq->next) {
- /* We might want to build a list of effects that need to be updated during transform */
- if(seq->type & SEQ_EFFECT) {
- if (seq->seq1 && seq->seq1->flag & SELECT) calc_sequence(seq);
- else if (seq->seq2 && seq->seq2->flag & SELECT) calc_sequence(seq);
- else if (seq->seq3 && seq->seq3->flag & SELECT) calc_sequence(seq);
- }
- }
-
- sort_seq(t->scene);
- }
-
- if (t->customData)
- MEM_freeN(t->customData);
- if (t->data)
- MEM_freeN(t->data); // XXX postTrans usually does this
+ else if (t->spacetype == SPACE_SEQ) {
+ /* freeSeqData in transform_conversions.c does this
+ * keep here so the else at the end wont run... */
}
else if (t->spacetype == SPACE_ACTION) {
SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 66b46ab5b96..d8f7696840d 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -261,7 +261,7 @@ static void editbmesh_apply_to_mirror(TransInfo *t)
continue;
eve = td->extra;
- if(eve) {
+ if (eve) {
eve->co[0]= -td->loc[0];
eve->co[1]= td->loc[1];
eve->co[2]= td->loc[2];
@@ -270,9 +270,9 @@ static void editbmesh_apply_to_mirror(TransInfo *t)
if (td->flag & TD_MIRROR_EDGE)
{
td->loc[0] = 0;
+ }
}
}
-}
/* tags the given ID block for refreshes (if applicable) due to
* Animation Editor editing
@@ -286,15 +286,8 @@ static void animedit_refresh_id_tags (Scene *scene, ID *id)
if (adt)
adt->recalc |= ADT_RECALC_ANIM;
- /* if ID-block is Object, set recalc flags */
- switch (GS(id->name)) {
- case ID_OB:
- {
- Object *ob= (Object *)id;
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */
- }
- break;
- }
+ /* set recalc flags */
+ DAG_id_flush_update(id, OB_RECALC); // XXX or do we want something more restrictive?
}
}
@@ -352,11 +345,6 @@ void recalcData(TransInfo *t)
Scene *scene = t->scene;
Base *base = scene->basact;
- if (t->obedit) {
- }
- else if(base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(scene, base->object)) {
- flushTransParticles(t);
- }
if (t->spacetype==SPACE_NODE) {
flushTransNodes(t);
}
@@ -683,144 +671,147 @@ void recalcData(TransInfo *t)
EDBM_RecalcNormals(em);
BMEdit_RecalcTesselation(em);
}
- else if(t->obedit->type==OB_ARMATURE) { /* no recalc flag, does pose */
- bArmature *arm= t->obedit->data;
- ListBase *edbo = arm->edbo;
- EditBone *ebo;
- TransData *td = t->data;
- int i;
+ else if(t->obedit->type==OB_ARMATURE) { /* no recalc flag, does pose */
+ bArmature *arm= t->obedit->data;
+ ListBase *edbo = arm->edbo;
+ EditBone *ebo;
+ TransData *td = t->data;
+ int i;
- /* Ensure all bones are correctly adjusted */
- for (ebo = edbo->first; ebo; ebo = ebo->next){
+ /* Ensure all bones are correctly adjusted */
+ for (ebo = edbo->first; ebo; ebo = ebo->next){
- if ((ebo->flag & BONE_CONNECTED) && ebo->parent){
- /* If this bone has a parent tip that has been moved */
- if (ebo->parent->flag & BONE_TIPSEL){
- VECCOPY (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{
- VECCOPY (ebo->parent->tail, ebo->head);
- if(t->mode==TFM_BONE_ENVELOPE) ebo->parent->rad_tail= ebo->rad_head;
+ if ((ebo->flag & BONE_CONNECTED) && ebo->parent){
+ /* If this bone has a parent tip that has been moved */
+ if (ebo->parent->flag & BONE_TIPSEL){
+ VECCOPY (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{
+ VECCOPY (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= VecLenf(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;
+ /* on extrude bones, oldlength==0.0f, so we scale radius of points */
+ ebo->length= VecLenf(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;
}
}
- 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 (t->mode != TFM_BONE_ROLL)
- {
- /* fix roll */
- for(i = 0; i < t->total; i++, td++)
+ if (t->mode != TFM_BONE_ROLL)
{
- if (td->extra)
+ /* fix roll */
+ for(i = 0; i < t->total; i++, td++)
{
- float vec[3], up_axis[3];
- float qrot[4];
+ if (td->extra)
+ {
+ float vec[3], up_axis[3];
+ float qrot[4];
- ebo = td->extra;
- VECCOPY(up_axis, td->axismtx[2]);
+ ebo = td->extra;
+ VECCOPY(up_axis, td->axismtx[2]);
- if (t->mode != TFM_ROTATION)
- {
- VecSubf(vec, ebo->tail, ebo->head);
- Normalize(vec);
- RotationBetweenVectorsToQuat(qrot, td->axismtx[1], vec);
- QuatMulVecf(qrot, up_axis);
- }
- else
- {
- Mat3MulVecfl(t->mat, up_axis);
- }
+ if (t->mode != TFM_ROTATION)
+ {
+ VecSubf(vec, ebo->tail, ebo->head);
+ Normalize(vec);
+ RotationBetweenVectorsToQuat(qrot, td->axismtx[1], vec);
+ QuatMulVecf(qrot, up_axis);
+ }
+ else
+ {
+ Mat3MulVecfl(t->mat, up_axis);
+ }
- ebo->roll = ED_rollBoneToVector(ebo, up_axis);
+ ebo->roll = ED_rollBoneToVector(ebo, up_axis);
+ }
}
}
- }
- if(arm->flag & ARM_MIRROR_EDIT)
- transform_armature_mirror_update(t->obedit);
+ if(arm->flag & ARM_MIRROR_EDIT)
+ transform_armature_mirror_update(t->obedit);
+ }
+ else
+ DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */
}
- else
- DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */
- }
- else if( (t->flag & T_POSE) && t->poseobj) {
- Object *ob= t->poseobj;
- bArmature *arm= ob->data;
+ else if( (t->flag & T_POSE) && t->poseobj) {
+ Object *ob= t->poseobj;
+ bArmature *arm= ob->data;
- /* if animtimer is running, and the object already has animation data,
- * check if the auto-record feature means that we should record 'samples'
- * (i.e. uneditable animation values)
- */
- // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
- if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
- int targetless_ik= (t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet!
+ /* if animtimer is running, and the object already has animation data,
+ * check if the auto-record feature means that we should record 'samples'
+ * (i.e. uneditable animation values)
+ */
+ // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
+ if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
+ int targetless_ik= (t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet!
+
+ animrecord_check_state(t->scene, &ob->id, t->animtimer);
+ autokeyframe_pose_cb_func(t->scene, (View3D *)t->view, ob, t->mode, targetless_ik);
+ }
- animrecord_check_state(t->scene, &ob->id, t->animtimer);
- autokeyframe_pose_cb_func(t->scene, (View3D *)t->view, ob, t->mode, targetless_ik);
+ /* old optimize trick... this enforces to bypass the depgraph */
+ if (!(arm->flag & ARM_DELAYDEFORM)) {
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */
+ }
+ else
+ where_is_pose(scene, ob);
}
-
- /* old optimize trick... this enforces to bypass the depgraph */
- if (!(arm->flag & ARM_DELAYDEFORM)) {
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */
+ else if(base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(scene, base->object)) {
+ flushTransParticles(t);
}
- else
- where_is_pose(scene, ob);
- }
- else {
- for(base= FIRSTBASE; base; base= base->next) {
- Object *ob= base->object;
+ else {
+ for(base= FIRSTBASE; base; base= base->next) {
+ Object *ob= base->object;
- /* this flag is from depgraph, was stored in initialize phase, handled in drawview.c */
- if(base->flag & BA_HAS_RECALC_OB)
- ob->recalc |= OB_RECALC_OB;
- if(base->flag & BA_HAS_RECALC_DATA)
- ob->recalc |= OB_RECALC_DATA;
+ /* this flag is from depgraph, was stored in initialize phase, handled in drawview.c */
+ if(base->flag & BA_HAS_RECALC_OB)
+ ob->recalc |= OB_RECALC_OB;
+ if(base->flag & BA_HAS_RECALC_DATA)
+ ob->recalc |= OB_RECALC_DATA;
- /* if object/base is selected */
- if ((base->flag & SELECT) || (ob->flag & SELECT)) {
- /* if animtimer is running, and the object already has animation data,
- * check if the auto-record feature means that we should record 'samples'
- * (i.e. uneditable animation values)
- */
- // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
- if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
- animrecord_check_state(t->scene, &ob->id, t->animtimer);
- autokeyframe_ob_cb_func(t->scene, (View3D *)t->view, ob, t->mode);
+ /* if object/base is selected */
+ if ((base->flag & SELECT) || (ob->flag & SELECT)) {
+ /* if animtimer is running, and the object already has animation data,
+ * check if the auto-record feature means that we should record 'samples'
+ * (i.e. uneditable animation values)
+ */
+ // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
+ if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
+ animrecord_check_state(t->scene, &ob->id, t->animtimer);
+ autokeyframe_ob_cb_func(t->scene, (View3D *)t->view, ob, t->mode);
+ }
}
- }
- /* proxy exception */
- if(ob->proxy)
- ob->proxy->recalc |= ob->recalc;
- if(ob->proxy_group)
- group_tag_recalc(ob->proxy_group->dup_group);
+ /* proxy exception */
+ if(ob->proxy)
+ ob->proxy->recalc |= ob->recalc;
+ if(ob->proxy_group)
+ group_tag_recalc(ob->proxy_group->dup_group);
+ }
}
- }
if(((View3D*)t->view)->drawtype == OB_SHADED)
- reshadeall_displist(t->scene);
-}
+ reshadeall_displist(t->scene);
+ }
}
void drawLine(TransInfo *t, float *center, float *dir, char axis, short options)
@@ -964,11 +955,18 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
t->view = &ar->v2d;
t->around = sima->around;
}
+ else if(t->spacetype==SPACE_IPO)
+ {
+ SpaceIpo *sipo= sa->spacedata.first;
+ t->view = &ar->v2d;
+ t->around = sipo->around;
+ }
else
{
// 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
t->around = V3D_CENTER;
}
@@ -1057,9 +1055,18 @@ void postTrans (TransInfo *t)
{
TransData *td;
- if (t->draw_handle)
- {
- ED_region_draw_cb_exit(t->ar->type, t->draw_handle);
+ if (t->draw_handle_view)
+ ED_region_draw_cb_exit(t->ar->type, t->draw_handle_view);
+ if (t->draw_handle_pixel)
+ ED_region_draw_cb_exit(t->ar->type, t->draw_handle_pixel);
+
+
+ if (t->customFree) {
+ /* Can take over freeing t->data and data2d etc... */
+ t->customFree(t);
+ }
+ else if (t->customData) {
+ MEM_freeN(t->customData);
}
/* postTrans can be called when nothing is selected, so data is NULL already */
@@ -1090,13 +1097,14 @@ void postTrans (TransInfo *t)
{
MEM_freeN(t->mouse.data);
}
-
+
if (t->customFree) {
t->customFree(t);
}
else if (t->customData) {
- MEM_freeN(t->customData);
- }}
+ MEM_freeN(t->customData);
+ }
+}
void applyTransObjects(TransInfo *t)
{
@@ -1205,6 +1213,18 @@ void calculateCenterCursor2D(TransInfo *t)
calculateCenter2D(t);
}
+void calculateCenterCursorGraph2D(TransInfo *t)
+{
+ SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first;
+ Scene *scene= t->scene;
+
+ /* cursor is combination of current frame, and graph-editor cursor value */
+ t->center[0]= (float)(scene->r.cfra);
+ t->center[1]= sipo->cursorVal;
+
+ calculateCenter2D(t);
+}
+
void calculateCenterMedian(TransInfo *t)
{
float partial[3] = {0.0f, 0.0f, 0.0f};
@@ -1276,6 +1296,8 @@ void calculateCenter(TransInfo *t)
case V3D_CURSOR:
if(t->spacetype==SPACE_IMAGE)
calculateCenterCursor2D(t);
+ else if(t->spacetype==SPACE_IPO)
+ calculateCenterCursorGraph2D(t);
else
calculateCenterCursor(t);
break;
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index fe8e5b34b54..a362bdf770e 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -327,6 +327,7 @@ static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event)
t->flag |= T_MODAL; // XXX meh maybe somewhere else
+ op->flag |= OP_GRAB_POINTER; // XXX maybe we want this with the manipulator only?
return OPERATOR_RUNNING_MODAL;
}
}
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index a2a7577c8d6..6a6ad562db5 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -346,6 +346,7 @@ void initSnapping(TransInfo *t, wmOperator *op)
{
ToolSettings *ts = t->settings;
Object *obedit = t->obedit;
+ Scene *scene = t->scene;
int snapping = 0;
short snap_mode = t->settings->snap_target;
@@ -409,6 +410,15 @@ void initSnapping(TransInfo *t, wmOperator *op)
t->tsnap.mode = SNAP_ALL;
}
}
+ /* Particles edit mode*/
+ else if (t->tsnap.applySnap != NULL && // A snapping function actually exist
+ (snapping) && // Only if the snap flag is on
+ (obedit == NULL && BASACT->object && BASACT->object->mode & OB_MODE_PARTICLE_EDIT ))
+ {
+ t->tsnap.status |= SNAP_ON;
+ t->tsnap.modePoint = SNAP_GEO;
+ t->tsnap.mode = SNAP_ALL;
+ }
/* Object mode */
else if (t->tsnap.applySnap != NULL && // A snapping function actually exist
(snapping) && // Only if the snap flag is on
@@ -625,7 +635,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
DepthPeel *p1, *p2;
float *last_p = NULL;
float dist = FLT_MAX;
- float p[3];
+ float p[3] = {0.0f, 0.0f, 0.0f};
depth_peels.first = depth_peels.last = NULL;
@@ -1468,9 +1478,20 @@ int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, float mv
if (mode == SNAP_ALL && obedit)
{
Object *ob = obedit;
-
+
retval |= snapObject(scene, ar, ob, 1, ob->obmat, ray_start, ray_normal, mval, loc, no, dist, &depth);
}
+
+ /* Need an exception for particle edit because the base is flagged with BA_HAS_RECALC_DATA
+ * which makes the loop skip it, even the derived mesh will never change
+ *
+ * To solve that problem, we do it first as an exception.
+ * */
+ if(BASACT->object && BASACT->object->mode & OB_MODE_PARTICLE_EDIT)
+ {
+ Object *ob = BASACT->object;
+ retval |= snapObject(scene, ar, ob, 0, ob->obmat, ray_start, ray_normal, mval, loc, no, dist, &depth);
+ }
base= FIRSTBASE;
for ( base = FIRSTBASE; base != NULL; base = base->next ) {