diff options
author | Joseph Eagar <joeedh@gmail.com> | 2009-11-01 03:06:53 +0300 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2009-11-01 03:06:53 +0300 |
commit | 2d0d4e7de4d31bd2f8485a9b7b4311bf8e254c3d (patch) | |
tree | a6f262fc2e8e7762599e12a0c9984fab02ce2bff /source/blender/editors/transform | |
parent | 672c8926d7801fcc4b45e9dff75022e1ff9d240b (diff) |
commit before doing some hefty shapekey change, will break compilation
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r-- | source/blender/editors/transform/transform.c | 103 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.h | 9 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 342 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_generics.c | 284 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_ops.c | 1 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_snap.c | 25 |
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 ) { |