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:
authorJoseph Eagar <joeedh@gmail.com>2009-09-16 21:43:09 +0400
committerJoseph Eagar <joeedh@gmail.com>2009-09-16 21:43:09 +0400
commitdeebf4f8f0d79169a0e6c2a391670419b6492bfe (patch)
tree2a0aaf4042aa78e9d1d835f4544e07c6123e67a9 /source/blender/editors/transform
parent6b0679a3999d8e5abc60730f523879eadbedcd8f (diff)
merge with 2.5/trunk at r23271
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r--source/blender/editors/transform/transform.c187
-rw-r--r--source/blender/editors/transform/transform.h1
-rw-r--r--source/blender/editors/transform/transform_conversions.c239
-rw-r--r--source/blender/editors/transform/transform_generics.c16
-rw-r--r--source/blender/editors/transform/transform_manipulator.c22
-rw-r--r--source/blender/editors/transform/transform_ops.c27
-rw-r--r--source/blender/editors/transform/transform_orientations.c2
7 files changed, 329 insertions, 165 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index dd7cebdfe3f..e877f1fecae 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -333,7 +333,7 @@ static void viewRedrawForce(bContext *C, TransInfo *t)
else force_draw(0);
#endif
- WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, t->obedit);
+ WM_event_add_notifier(C, NC_GEOM|ND_DATA, t->obedit->data);
}
}
@@ -1257,13 +1257,16 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
int constraint_axis[3] = {0, 0, 0};
int proportional = 0;
- if (t->flag & T_AUTOVALUES)
- {
- RNA_float_set_array(op->ptr, "value", t->auto_values);
- }
- else
+ if (RNA_struct_find_property(op->ptr, "value"))
{
- RNA_float_set_array(op->ptr, "value", t->values);
+ if (t->flag & T_AUTOVALUES)
+ {
+ RNA_float_set_array(op->ptr, "value", t->auto_values);
+ }
+ else
+ {
+ RNA_float_set_array(op->ptr, "value", t->values);
+ }
}
/* XXX convert stupid flag to enum */
@@ -1607,28 +1610,88 @@ static void protectedRotateBits(short protectflag, float *eul, float *oldeul)
eul[2]= oldeul[2];
}
-static void protectedQuaternionBits(short protectflag, float *quat, float *oldquat)
-{
- /* quaternions get limited with euler... */
- /* this function only does the delta rotation */
- if(protectflag) {
+/* this function only does the delta rotation */
+/* axis-angle is usually internally stored as quats... */
+static void protectedAxisAngleBits(short protectflag, float *quat, float *oldquat)
+{
+ /* check that protection flags are set */
+ if ((protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) == 0)
+ return;
+
+ if (protectflag & OB_LOCK_ROT4D) {
+ /* axis-angle getting limited as 4D entities that they are... */
+ if (protectflag & OB_LOCK_ROTW)
+ quat[0]= oldquat[0];
+ if (protectflag & OB_LOCK_ROTX)
+ quat[1]= oldquat[1];
+ if (protectflag & OB_LOCK_ROTY)
+ quat[2]= oldquat[2];
+ if (protectflag & OB_LOCK_ROTZ)
+ quat[3]= oldquat[3];
+ }
+ else {
+ /* axis-angle get limited with euler... */
float eul[3], oldeul[3], quat1[4];
+
+ QUATCOPY(quat1, quat);
+ AxisAngleToEulO(quat+1, quat[0], eul, EULER_ORDER_DEFAULT);
+ AxisAngleToEulO(oldquat+1, oldquat[0], oldeul, EULER_ORDER_DEFAULT);
+
+ if (protectflag & OB_LOCK_ROTX)
+ eul[0]= oldeul[0];
+ if (protectflag & OB_LOCK_ROTY)
+ eul[1]= oldeul[1];
+ if (protectflag & OB_LOCK_ROTZ)
+ eul[2]= oldeul[2];
+
+ EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, quat+1, quat);
+
+ /* 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])) {
+ /* for now, rotate around y-axis then (so that it simply becomes the roll) */
+ quat[2]= 1.0f;
+ }
+ }
+}
+/* this function only does the delta rotation */
+static void protectedQuaternionBits(short protectflag, float *quat, float *oldquat)
+{
+ /* check that protection flags are set */
+ if ((protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) == 0)
+ return;
+
+ if (protectflag & OB_LOCK_ROT4D) {
+ /* quaternions getting limited as 4D entities that they are... */
+ if (protectflag & OB_LOCK_ROTW)
+ quat[0]= oldquat[0];
+ if (protectflag & OB_LOCK_ROTX)
+ quat[1]= oldquat[1];
+ if (protectflag & OB_LOCK_ROTY)
+ quat[2]= oldquat[2];
+ if (protectflag & OB_LOCK_ROTZ)
+ quat[3]= oldquat[3];
+ }
+ else {
+ /* quaternions get limited with euler... (compatability mode) */
+ float eul[3], oldeul[3], quat1[4];
+
QUATCOPY(quat1, quat);
QuatToEul(quat, eul);
QuatToEul(oldquat, oldeul);
-
- if(protectflag & OB_LOCK_ROTX)
+
+ if (protectflag & OB_LOCK_ROTX)
eul[0]= oldeul[0];
- if(protectflag & OB_LOCK_ROTY)
+ if (protectflag & OB_LOCK_ROTY)
eul[1]= oldeul[1];
- if(protectflag & OB_LOCK_ROTZ)
+ if (protectflag & OB_LOCK_ROTZ)
eul[2]= oldeul[2];
-
+
EulToQuat(eul, quat);
+
/* quaternions flip w sign to accumulate rotations correctly */
- if( (quat1[0]<0.0f && quat[0]>0.0f) || (quat1[0]>0.0f && quat[0]<0.0f) ) {
+ if ( (quat1[0]<0.0f && quat[0]>0.0f) || (quat1[0]>0.0f && quat[0]<0.0f) ) {
QuatMulf(quat, -1.0f);
}
}
@@ -1729,40 +1792,47 @@ static void constraintRotLim(TransInfo *t, TransData *td)
else
return;
}
- else if (td->tdi) {
+ else if (td->tdi) { // XXX depreceated
/* ipo-keys eulers */
TransDataIpokey *tdi= td->tdi;
float eul[3];
-
+
eul[0]= tdi->rotx[0];
eul[1]= tdi->roty[0];
eul[2]= tdi->rotz[0];
-
- EulToMat4(eul, cob.matrix);
+
+ EulOToMat4(eul, td->rotOrder, cob.matrix);
+ }
+ else if (td->rotOrder == PCHAN_ROT_AXISANGLE) {
+ /* axis angle */
+ if (td->ext)
+ AxisAngleToMat4(&td->ext->quat[1], td->ext->quat[0], cob.matrix);
+ else
+ return;
}
else {
/* eulers */
if (td->ext)
- EulToMat4(td->ext->rot, cob.matrix);
+ EulOToMat4(td->ext->rot, td->rotOrder, cob.matrix);
else
return;
}
-
+
/* Evaluate valid constraints */
for (con= td->con; con; con= con->next) {
/* only consider constraint if enabled */
if (con->flag & CONSTRAINT_DISABLE) continue;
if (con->enforce == 0.0f) continue;
-
+
/* we're only interested in Limit-Rotation constraints */
if (con->type == CONSTRAINT_TYPE_ROTLIMIT) {
bRotLimitConstraint *data= con->data;
float tmat[4][4];
-
+
/* only use it if it's tagged for this purpose */
if ((data->flag2 & LIMIT_TRANSFORM)==0)
continue;
-
+
/* do space conversions */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
@@ -1773,10 +1843,10 @@ static void constraintRotLim(TransInfo *t, TransData *td)
/* skip... incompatable spacetype */
continue;
}
-
+
/* do constraint */
cti->evaluate_constraint(con, &cob, NULL);
-
+
/* convert spaces again */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
@@ -1785,7 +1855,7 @@ static void constraintRotLim(TransInfo *t, TransData *td)
}
}
}
-
+
/* copy results from cob->matrix */
if (td->flag & TD_USEQUAT) {
/* quats */
@@ -1795,16 +1865,20 @@ static void constraintRotLim(TransInfo *t, TransData *td)
/* ipo-keys eulers */
TransDataIpokey *tdi= td->tdi;
float eul[3];
-
- Mat4ToEul(cob.matrix, eul);
-
+
+ Mat4ToEulO(cob.matrix, eul, td->rotOrder);
+
tdi->rotx[0]= eul[0];
tdi->roty[0]= eul[1];
tdi->rotz[0]= eul[2];
}
+ else if (td->rotOrder == PCHAN_ROT_AXISANGLE) {
+ /* axis angle */
+ Mat4ToAxisAngle(cob.matrix, &td->ext->quat[1], &td->ext->quat[0]);
+ }
else {
/* eulers */
- Mat4ToEul(cob.matrix, td->ext->rot);
+ Mat4ToEulO(cob.matrix, td->ext->rot, td->rotOrder);
}
}
}
@@ -2660,7 +2734,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
/* rotation */
if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself
- /* euler or quaternion? */
+ /* euler or quaternion/axis-angle? */
if (td->flag & TD_USEQUAT) {
Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
@@ -2669,27 +2743,47 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
QuatMul(td->ext->quat, quat, td->ext->iquat);
/* this function works on end result */
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
+
}
- else {
+ else if (td->rotOrder == PCHAN_ROT_AXISANGLE) {
+ /* calculate effect based on quats */
+ float iquat[4];
+
+ /* td->ext->(i)quat is in axis-angle form, not quats! */
+ AxisAngleToQuat(iquat, &td->ext->iquat[1], td->ext->iquat[0]);
+
+ Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
+ Mat3ToQuat(fmat, quat); // Actual transform
+
+ 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]);
+
+ /* this function works on end result */
+ protectedAxisAngleBits(td->protectflag, td->ext->quat, td->ext->iquat);
+ }
+ else {
float eulmat[3][3];
-
+
Mat3MulMat3(totmat, mat, td->mtx);
Mat3MulMat3(smat, td->smtx, totmat);
-
+
/* calculate the total rotatation in eulers */
VECCOPY(eul, td->ext->irot);
- EulToMat3(eul, eulmat);
-
+ EulOToMat3(eul, td->rotOrder, eulmat);
+
/* mat = transform, obmat = bone rotation */
Mat3MulMat3(fmat, smat, eulmat);
-
- Mat3ToCompatibleEul(fmat, eul, td->ext->rot);
-
+
+ Mat3ToCompatibleEulO(fmat, eul, td->ext->rot, td->rotOrder);
+
/* and apply (to end result only) */
protectedRotateBits(td->protectflag, eul, td->ext->irot);
VECCOPY(td->ext->rot, eul);
}
-
+
constraintRotLim(t, td);
}
}
@@ -4145,7 +4239,10 @@ int Mirror(TransInfo *t, short mval[2])
recalcData(t);
- ED_area_headerprint(t->sa, "Select a mirror axis (X, Y, Z)");
+ if(t->flag & T_2D_EDIT)
+ ED_area_headerprint(t->sa, "Select a mirror axis (X, Y)");
+ else
+ ED_area_headerprint(t->sa, "Select a mirror axis (X, Y, Z)");
}
return 1;
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index efa60b15293..e5bd405c0cd 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -199,6 +199,7 @@ typedef struct TransData {
void *extra; /* extra data (mirrored element pointer, in editmode mesh to EditVert) (editbone for roll fixing) (...) */
short flag; /* Various flags */
short protectflag; /* If set, copy of Object or PoseChannel protection */
+ int rotOrder; /* rotation order (for eulers), as defined in BLI_arithb.h */
} TransData;
typedef struct MouseInput {
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 22d12477624..2783bf7ac99 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -504,22 +504,33 @@ static short apply_targetless_ik(Object *ob)
/* apply and decompose, doesn't work for constraints or non-uniform scale well */
{
- float rmat3[3][3], qmat[3][3], imat[3][3], smat[3][3];
+ float rmat3[3][3], qrmat[3][3], imat[3][3], smat[3][3];
Mat3CpyMat4(rmat3, rmat);
-
- /* quaternion */
- Mat3ToQuat(rmat3, parchan->quat);
-
+
+ /* rotation */
+ if (parchan->rotmode > 0)
+ Mat3ToEulO(rmat3, parchan->eul, parchan->rotmode);
+ else if (parchan->rotmode == PCHAN_ROT_AXISANGLE)
+ Mat3ToAxisAngle(rmat3, &parchan->quat[1], &parchan->quat[0]);
+ else
+ Mat3ToQuat(rmat3, parchan->quat);
+
/* for size, remove rotation */
/* causes problems with some constraints (so apply only if needed) */
if (data->flag & CONSTRAINT_IK_STRETCH) {
- QuatToMat3(parchan->quat, qmat);
- Mat3Inv(imat, qmat);
+ if (parchan->rotmode > 0)
+ EulOToMat3(parchan->eul, parchan->rotmode, qrmat);
+ else if (parchan->rotmode == PCHAN_ROT_AXISANGLE)
+ AxisAngleToMat3(&parchan->quat[1], parchan->quat[0], qrmat);
+ else
+ QuatToMat3(parchan->quat, qrmat);
+
+ Mat3Inv(imat, qrmat);
Mat3MulMat3(smat, rmat3, imat);
Mat3ToSize(smat, parchan->size);
}
-
+
/* causes problems with some constraints (e.g. childof), so disable this */
/* as it is IK shouldn't affect location directly */
/* VECCOPY(parchan->loc, rmat[3]); */
@@ -547,7 +558,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
td->ob = ob;
td->flag = TD_SELECTED;
- if (pchan->rotmode == PCHAN_ROT_QUAT)
+ if (pchan->rotmode == PCHAN_ROT_QUAT)
{
td->flag |= TD_USEQUAT;
}
@@ -570,18 +581,21 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
td->ext->size= pchan->size;
VECCOPY(td->ext->isize, pchan->size);
- if (pchan->rotmode) {
+ if (pchan->rotmode > 0) {
td->ext->rot= pchan->eul;
td->ext->quat= NULL;
-
+
VECCOPY(td->ext->irot, pchan->eul);
+ td->rotOrder= pchan->rotmode;
}
else {
td->ext->rot= NULL;
td->ext->quat= pchan->quat;
-
+
QUATCOPY(td->ext->iquat, pchan->quat);
+ td->rotOrder= pchan->rotmode;
}
+
/* proper way to get parent transform + own transform + constraints transform */
Mat3CpyMat4(omat, ob->obmat);
@@ -1360,16 +1374,17 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
int a;
int count=0, countsel=0;
int propmode = t->flag & T_PROP_EDIT;
-
+ short hide_handles = (cu->drawflag & CU_HIDE_HANDLES);
+
/* to be sure */
if(cu->editnurb==NULL) return;
/* count total of vertices, check identical as in 2nd loop for making transdata! */
for(nu= cu->editnurb->first; nu; nu= nu->next) {
- if((nu->type & 7)==CU_BEZIER) {
+ if(nu->type == CU_BEZIER) {
for(a=0, bezt= nu->bezt; a<nu->pntsu; a++, bezt++) {
if(bezt->hide==0) {
- if (G.f & G_HIDDENHANDLES) {
+ if (hide_handles) {
if(bezt->f2 & SELECT) countsel+=3;
if(propmode) count+= 3;
} else {
@@ -1402,7 +1417,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
td = t->data;
for(nu= cu->editnurb->first; nu; nu= nu->next) {
- if((nu->type & 7)==CU_BEZIER) {
+ if(nu->type == CU_BEZIER) {
TransData *head, *tail;
head = tail = td;
for(a=0, bezt= nu->bezt; a<nu->pntsu; a++, bezt++) {
@@ -1410,13 +1425,13 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
TransDataCurveHandleFlags *hdata = NULL;
if( propmode ||
- ((bezt->f2 & SELECT) && (G.f & G_HIDDENHANDLES)) ||
- ((bezt->f1 & SELECT) && (G.f & G_HIDDENHANDLES)==0)
+ ((bezt->f2 & SELECT) && hide_handles) ||
+ ((bezt->f1 & SELECT) && hide_handles == 0)
) {
VECCOPY(td->iloc, bezt->vec[0]);
td->loc= bezt->vec[0];
VECCOPY(td->center, bezt->vec[1]);
- if (G.f & G_HIDDENHANDLES) {
+ if (hide_handles) {
if(bezt->f2 & SELECT) td->flag= TD_SELECTED;
else td->flag= 0;
} else {
@@ -1471,13 +1486,13 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
tail++;
}
if( propmode ||
- ((bezt->f2 & SELECT) && (G.f & G_HIDDENHANDLES)) ||
- ((bezt->f3 & SELECT) && (G.f & G_HIDDENHANDLES)==0)
+ ((bezt->f2 & SELECT) && hide_handles) ||
+ ((bezt->f3 & SELECT) && hide_handles == 0)
) {
VECCOPY(td->iloc, bezt->vec[2]);
td->loc= bezt->vec[2];
VECCOPY(td->center, bezt->vec[1]);
- if (G.f & G_HIDDENHANDLES) {
+ if (hide_handles) {
if(bezt->f2 & SELECT) td->flag= TD_SELECTED;
else td->flag= 0;
} else {
@@ -1619,31 +1634,32 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
TransDataExtension *tx;
Base *base = CTX_data_active_base(C);
Object *ob = CTX_data_active_object(C);
- ParticleSystem *psys = PE_get_current(t->scene, ob);
- ParticleSystemModifierData *psmd = NULL;
ParticleEditSettings *pset = PE_settings(t->scene);
- ParticleData *pa = NULL;
- ParticleEdit *edit;
- ParticleEditKey *key;
+ PTCacheEdit *edit = PE_get_current(t->scene, ob);
+ ParticleSystem *psys = NULL;
+ ParticleSystemModifierData *psmd = NULL;
+ PTCacheEditPoint *point;
+ PTCacheEditKey *key;
float mat[4][4];
- int i,k, totpart, transformparticle;
+ int i,k, transformparticle;
int count = 0, hasselected = 0;
int propmode = t->flag & T_PROP_EDIT;
- if(psys==NULL || t->settings->particle.selectmode==SCE_SELECT_PATH) return;
+ if(edit==NULL || t->settings->particle.selectmode==SCE_SELECT_PATH) return;
+
+ psys = edit->psys;
- psmd = psys_get_modifier(ob,psys);
+ if(psys)
+ psmd = psys_get_modifier(ob,psys);
- edit = psys->edit;
- totpart = psys->totpart;
base->flag |= BA_HAS_RECALC_DATA;
- for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
- pa->flag &= ~PARS_TRANSFORM;
+ for(i=0, point=edit->points; i<edit->totpoint; i++, point++) {
+ point->flag &= ~PEP_TRANSFORM;
transformparticle= 0;
- if((pa->flag & PARS_HIDE)==0) {
- for(k=0, key=edit->keys[i]; k<pa->totkey; k++, key++) {
+ if((point->flag & PEP_HIDE)==0) {
+ for(k=0, key=point->keys; k<point->totkey; k++, key++) {
if((key->flag&PEK_HIDE)==0) {
if(key->flag&PEK_SELECT) {
hasselected= 1;
@@ -1656,8 +1672,8 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
}
if(transformparticle) {
- count += pa->totkey;
- pa->flag |= PARS_TRANSFORM;
+ count += point->totkey;
+ point->flag |= PEP_TRANSFORM;
}
}
@@ -1676,18 +1692,23 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
Mat4Invert(ob->imat,ob->obmat);
- for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
+ for(i=0, point=edit->points; i<edit->totpoint; i++, point++) {
TransData *head, *tail;
head = tail = td;
- if(!(pa->flag & PARS_TRANSFORM)) continue;
+ if(!(point->flag & PEP_TRANSFORM)) continue;
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, mat);
+ if(psys && !(psys->flag & PSYS_GLOBAL_HAIR))
+ psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles + i, mat);
- for(k=0, key=edit->keys[i]; k<pa->totkey; k++, key++) {
- VECCOPY(key->world_co, key->co);
- Mat4MulVecfl(mat, key->world_co);
- td->loc = key->world_co;
+ for(k=0, key=point->keys; k<point->totkey; k++, key++) {
+ if(key->flag & PEK_USE_WCO) {
+ VECCOPY(key->world_co, key->co);
+ Mat4MulVecfl(mat, key->world_co);
+ td->loc = key->world_co;
+ }
+ else
+ td->loc = key->co;
VECCOPY(td->iloc, td->loc);
VECCOPY(td->center, td->loc);
@@ -1701,7 +1722,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
Mat3One(td->smtx);
/* don't allow moving roots */
- if(k==0 && pset->flag & PE_LOCK_FIRST)
+ if(k==0 && pset->flag & PE_LOCK_FIRST && (!psys || !(psys->flag & PSYS_GLOBAL_HAIR)))
td->protectflag |= OB_LOCK_LOC;
td->ob = ob;
@@ -1715,7 +1736,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
if(k==0) tx->size = 0;
else tx->size = (key - 1)->time;
- if(k == pa->totkey - 1) tx->quat = 0;
+ if(k == point->totkey - 1) tx->quat = 0;
else tx->quat = (key + 1)->time;
}
@@ -1733,35 +1754,42 @@ void flushTransParticles(TransInfo *t)
{
Scene *scene = t->scene;
Object *ob = OBACT;
- ParticleSystem *psys = PE_get_current(scene, ob);
- ParticleSystemModifierData *psmd;
- ParticleData *pa;
- ParticleEditKey *key;
+ PTCacheEdit *edit = PE_get_current(scene, ob);
+ ParticleSystem *psys = edit->psys;
+ ParticleSystemModifierData *psmd = NULL;
+ PTCacheEditPoint *point;
+ PTCacheEditKey *key;
TransData *td;
float mat[4][4], imat[4][4], co[3];
int i, k, propmode = t->flag & T_PROP_EDIT;
- psmd = psys_get_modifier(ob, psys);
+ if(psys)
+ psmd = psys_get_modifier(ob, psys);
/* we do transform in world space, so flush world space position
- * back to particle local space */
+ * back to particle local space (only for hair particles) */
td= t->data;
- for(i=0, pa=psys->particles; i<psys->totpart; i++, pa++, td++) {
- if(!(pa->flag & PARS_TRANSFORM)) continue;
+ for(i=0, point=edit->points; i<edit->totpoint; i++, point++, td++) {
+ if(!(point->flag & PEP_TRANSFORM)) continue;
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, mat);
- Mat4Invert(imat,mat);
+ if(psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
+ psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles + i, mat);
+ Mat4Invert(imat,mat);
- for(k=0, key=psys->edit->keys[i]; k<pa->totkey; k++, key++) {
- VECCOPY(co, key->world_co);
- Mat4MulVecfl(imat, co);
+ for(k=0, key=point->keys; k<point->totkey; k++, key++) {
+ VECCOPY(co, key->world_co);
+ Mat4MulVecfl(imat, co);
- /* optimization for proportional edit */
- if(!propmode || !FloatCompare(key->co, co, 0.0001f)) {
- VECCOPY(key->co, co);
- pa->flag |= PARS_EDIT_RECALC;
+
+ /* optimization for proportional edit */
+ if(!propmode || !FloatCompare(key->co, co, 0.0001f)) {
+ VECCOPY(key->co, co);
+ point->flag |= PEP_EDIT_RECALC;
+ }
}
}
+ else
+ point->flag |= PEP_EDIT_RECALC;
}
PE_update_object(scene, OBACT, 1);
@@ -4400,12 +4428,14 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
AnimData *adt= ob->adt;
float cfra= (float)CFRA; // xxx this will do for now
short flag = 0;
-
+
if (IS_AUTOKEY_FLAG(INSERTNEEDED))
flag |= INSERTKEY_NEEDED;
if (IS_AUTOKEY_FLAG(AUTOMATKEY))
flag |= INSERTKEY_MATRIX;
-
+ if (IS_AUTOKEY_MODE(scene, EDITKEYS))
+ flag |= INSERTKEY_REPLACE;
+
if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
/* only key on available channels */
if (adt && adt->action) {
@@ -4417,7 +4447,7 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
}
else if (IS_AUTOKEY_FLAG(INSERTNEEDED)) {
short doLoc=0, doRot=0, doScale=0;
-
+
/* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */
if (tmode == TFM_TRANSLATION) {
doLoc = 1;
@@ -4429,7 +4459,7 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
}
else if (v3d->around == V3D_CURSOR)
doLoc = 1;
-
+
if ((v3d->flag & V3D_ALIGN)==0)
doRot = 1;
}
@@ -4440,11 +4470,11 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
}
else if (v3d->around == V3D_CURSOR)
doLoc = 1;
-
+
if ((v3d->flag & V3D_ALIGN)==0)
doScale = 1;
}
-
+
// TODO: the group names here are temporary...
// TODO: should this be made to use the builtin KeyingSets instead?
if (doLoc) {
@@ -4469,16 +4499,16 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
insert_keyframe(id, NULL, "Object Transform", "location", 0, cfra, flag);
insert_keyframe(id, NULL, "Object Transform", "location", 1, cfra, flag);
insert_keyframe(id, NULL, "Object Transform", "location", 2, cfra, flag);
-
+
insert_keyframe(id, NULL, "Object Transform", "rotation", 0, cfra, flag);
insert_keyframe(id, NULL, "Object Transform", "rotation", 1, cfra, flag);
insert_keyframe(id, NULL, "Object Transform", "rotation", 2, cfra, flag);
-
+
insert_keyframe(id, NULL, "Object Transform", "scale", 0, cfra, flag);
insert_keyframe(id, NULL, "Object Transform", "scale", 1, cfra, flag);
insert_keyframe(id, NULL, "Object Transform", "scale", 2, cfra, flag);
}
-
+
// XXX todo... find a way to send notifiers from here...
}
}
@@ -4502,7 +4532,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
float cfra= (float)CFRA;
short flag= 0;
char buf[512];
-
+
/* flag is initialised from UserPref keyframing settings
* - special exception for targetless IK - INSERTKEY_MATRIX keyframes should get
* visual keyframes even if flag not set, as it's not that useful otherwise
@@ -4512,12 +4542,14 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
flag |= INSERTKEY_MATRIX;
if (IS_AUTOKEY_FLAG(INSERTNEEDED))
flag |= INSERTKEY_NEEDED;
-
+ if (IS_AUTOKEY_MODE(scene, EDITKEYS))
+ flag |= INSERTKEY_REPLACE;
+
for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) {
if (pchan->bone->flag & BONE_TRANSFORM) {
/* clear any 'unkeyed' flag it may have */
pchan->bone->flag &= ~BONE_UNKEYED;
-
+
/* only insert into available channels? */
if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
if (act) {
@@ -4528,7 +4560,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
/* only insert keyframe if needed? */
else if (IS_AUTOKEY_FLAG(INSERTNEEDED)) {
short doLoc=0, doRot=0, doScale=0;
-
+
/* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */
if (tmode == TFM_TRANSLATION) {
if (targetless_ik)
@@ -4539,18 +4571,18 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
else if (tmode == TFM_ROTATION) {
if (ELEM(v3d->around, V3D_CURSOR, V3D_ACTIVE))
doLoc = 1;
-
+
if ((v3d->flag & V3D_ALIGN)==0)
doRot = 1;
}
else if (tmode == TFM_RESIZE) {
if (ELEM(v3d->around, V3D_CURSOR, V3D_ACTIVE))
doLoc = 1;
-
+
if ((v3d->flag & V3D_ALIGN)==0)
doScale = 1;
}
-
+
if (doLoc) {
sprintf(buf, "pose.pose_channels[\"%s\"].location", pchan->name);
insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
@@ -4585,7 +4617,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
-
+
if (pchan->rotmode == PCHAN_ROT_QUAT) {
sprintf(buf, "pose.pose_channels[\"%s\"].rotation", pchan->name);
insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
@@ -4599,7 +4631,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
}
-
+
sprintf(buf, "pose.pose_channels[\"%s\"].scale", pchan->name);
insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
@@ -4607,14 +4639,14 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
}
}
}
-
+
// XXX todo... figure out way to get appropriate notifiers sent
-
+
/* do the bone paths */
-#if 0 // TRANSFORM_FIX_ME
+#if 0 // XXX TRANSFORM FIX ME
if (arm->pathflag & ARM_PATH_ACFRA) {
- pose_clear_paths(ob);
- pose_recalculate_paths(ob);
+ //pose_clear_paths(ob); // XXX for now, don't need to clear
+ ED_pose_recalculate_paths(C, scene, ob);
}
#endif
}
@@ -4770,9 +4802,9 @@ void special_aftertrans_update(TransInfo *t)
ob->ctime= -1234567.0f;
if (ob->pose || ob_get_key(ob))
- DAG_object_flush_update(scene, ob, OB_RECALC);
+ DAG_id_flush_update(&ob->id, OB_RECALC);
else
- DAG_object_flush_update(scene, ob, OB_RECALC_OB);
+ DAG_id_flush_update(&ob->id, OB_RECALC_OB);
}
/* Do curve cleanups? */
@@ -4796,7 +4828,7 @@ void special_aftertrans_update(TransInfo *t)
}
#endif // XXX old animation system
- DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA);
+ DAG_id_flush_update(&OBACT->id, OB_RECALC_DATA);
}
#if 0 // XXX future of this is still not clear
else if (ac.datatype == ANIMCONT_GPENCIL) {
@@ -4810,7 +4842,7 @@ void special_aftertrans_update(TransInfo *t)
* - sync this with actdata_filter_gpencil() in editaction.c
*/
for (sa= sc->areabase.first; sa; sa= sa->next) {
- bGPdata *gpd= gpencil_data_getactive(sa);
+ bGPdata *gpd= gpencil_data_get_active(sa);
if (gpd)
posttrans_gpd_clean(gpd);
@@ -4960,15 +4992,15 @@ void special_aftertrans_update(TransInfo *t)
/* automatic inserting of keys and unkeyed tagging - only if transform wasn't cancelled (or TFM_DUMMY) */
if (!cancelled && (t->mode != TFM_DUMMY)) {
autokeyframe_pose_cb_func(t->scene, (View3D *)t->view, ob, t->mode, targetless_ik);
- DAG_object_flush_update(t->scene, ob, OB_RECALC_DATA);
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
}
else if (arm->flag & ARM_DELAYDEFORM) {
/* old optimize trick... this enforces to bypass the depgraph */
- DAG_object_flush_update(t->scene, ob, OB_RECALC_DATA);
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
ob->recalc= 0; // is set on OK position already by recalcData()
}
else
- DAG_object_flush_update(t->scene, ob, OB_RECALC_DATA);
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
//if (t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE)
// allqueue(REDRAWBUTSEDIT, 0);
@@ -4988,15 +5020,25 @@ void special_aftertrans_update(TransInfo *t)
ob= base->object;
if (base->flag & SELECT && (t->mode != TFM_DUMMY)) {
+ ListBase pidlist;
+ PTCacheID *pid;
+
+ /* flag object caches as outdated */
+ BKE_ptcache_ids_from_object(&pidlist, ob);
+ for(pid=pidlist.first; pid; pid=pid->next) {
+ if(pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */
+ pid->cache->flag |= PTCACHE_OUTDATED;
+ }
+
/* pointcache refresh */
- if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH))
+ if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_OUTDATED))
ob->recalc |= OB_RECALC_DATA;
/* Needed for proper updating of "quick cached" dynamics. */
/* Creates troubles for moving animated objects without */
/* autokey though, probably needed is an anim sys override? */
/* Please remove if some other solution is found. -jahka */
- DAG_object_flush_update(scene, ob, OB_RECALC_OB);
+ DAG_id_flush_update(&ob->id, OB_RECALC_OB);
/* Set autokey if necessary */
if (!cancelled)
@@ -5330,7 +5372,8 @@ void createTransData(bContext *C, TransInfo *t)
}
CTX_DATA_END;
}
- else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_can_edit(PE_get_current(scene, ob))) {
+ else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)
+ && PE_start_edit(PE_get_current(scene, ob))) {
createTransParticleVerts(C, t);
if(t->data && t->flag & T_PROP_EDIT) {
@@ -5349,7 +5392,7 @@ void createTransData(bContext *C, TransInfo *t)
if (t->ar->regiontype == RGN_TYPE_WINDOW)
{
View3D *v3d = t->view;
- RegionView3D *rv3d = t->ar->regiondata;
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
if((t->flag & T_OBJECT) && v3d->camera == OBACT && rv3d->persp==V3D_CAMOB)
{
t->flag |= T_CAMERA;
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index b96cb2601ec..36ee9b81623 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -285,7 +285,7 @@ static void animedit_refresh_id_tags (Scene *scene, ID *id)
case ID_OB:
{
Object *ob= (Object *)id;
- DAG_object_flush_update(scene, ob, OB_RECALC_DATA); /* sets recalc flags */
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */
}
break;
}
@@ -623,7 +623,7 @@ void recalcData(TransInfo *t)
Curve *cu= t->obedit->data;
Nurb *nu= cu->editnurb->first;
- DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */
+ DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */
if (t->state == TRANS_CANCEL) {
while(nu) {
@@ -643,7 +643,7 @@ void recalcData(TransInfo *t)
}
else if(t->obedit->type==OB_LATTICE) {
Lattice *la= t->obedit->data;
- DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */
+ DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */
if(la->editlatt->flag & LT_OUTSIDE) outside_lattice(la->editlatt);
}
@@ -655,7 +655,7 @@ void recalcData(TransInfo *t)
if(sima->flag & SI_LIVE_UNWRAP)
ED_uvedit_live_unwrap_re_solve();
- DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA);
+ DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);
} else {
BMEditMesh *em = ((Mesh*)t->obedit->data)->edit_btmesh;
/* mirror modifier clipping? */
@@ -670,7 +670,7 @@ void recalcData(TransInfo *t)
if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR))
editbmesh_apply_to_mirror(t);
- DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */
+ DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */
EDBM_RecalcNormals(em);
BMEdit_RecalcTesselation(em);
@@ -755,7 +755,7 @@ void recalcData(TransInfo *t)
}
else
- DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */
+ 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;
@@ -775,7 +775,7 @@ void recalcData(TransInfo *t)
/* old optimize trick... this enforces to bypass the depgraph */
if (!(arm->flag & ARM_DELAYDEFORM)) {
- DAG_object_flush_update(scene, ob, OB_RECALC_DATA); /* sets recalc flags */
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */
}
else
where_is_pose(scene, ob);
@@ -1325,7 +1325,7 @@ void calculateCenter(TransInfo *t)
/* voor panning from cameraview */
if(t->flag & T_OBJECT)
{
- if(t->spacetype==SPACE_VIEW3D)
+ if(t->spacetype==SPACE_VIEW3D && t->ar->regiontype == RGN_TYPE_WINDOW)
{
View3D *v3d = t->view;
Scene *scene = t->scene;
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index e0ab6bcf5f3..664627f1e15 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -62,6 +62,7 @@
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_particle.h"
+#include "BKE_pointcache.h"
#include "BKE_utildefines.h"
#include "BKE_tessmesh.h"
@@ -254,7 +255,7 @@ int calc_manipulator_stats(const bContext *C)
nu= cu->editnurb->first;
while(nu) {
- if((nu->type & 7)==CU_BEZIER) {
+ if(nu->type == CU_BEZIER) {
bezt= nu->bezt;
a= nu->pntsu;
while(a--) {
@@ -262,7 +263,7 @@ int calc_manipulator_stats(const bContext *C)
* if handles are hidden then only check the center points.
* If 2 or more are selected then only use the center point too.
*/
- if (G.f & G_HIDDENHANDLES) {
+ if (cu->drawflag & CU_HIDE_HANDLES) {
if (bezt->f2 & SELECT) {
calc_tw_center(scene, bezt->vec[1]);
totsel++;
@@ -365,18 +366,19 @@ int calc_manipulator_stats(const bContext *C)
;
}
else if(ob && ob->mode & OB_MODE_PARTICLE_EDIT) {
- ParticleSystem *psys= PE_get_current(scene, ob);
- ParticleData *pa = psys->particles;
- ParticleEditKey *ek;
+ PTCacheEdit *edit= PE_get_current(scene, ob);
+ PTCacheEditPoint *point;
+ PTCacheEditKey *ek;
int k;
- if(psys->edit) {
- for(a=0; a<psys->totpart; a++,pa++) {
- if(pa->flag & PARS_HIDE) continue;
+ if(edit) {
+ point = edit->points;
+ for(a=0; a<edit->totpoint; a++,point++) {
+ if(point->flag & PEP_HIDE) continue;
- for(k=0, ek=psys->edit->keys[a]; k<pa->totkey; k++, ek++) {
+ for(k=0, ek=point->keys; k<point->totkey; k++, ek++) {
if(ek->flag & PEK_SELECT) {
- calc_tw_center(scene, ek->world_co);
+ calc_tw_center(scene, ek->flag & PEK_USE_WCO ? ek->world_co : ek->co);
totsel++;
}
}
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 9aef9c217ab..758b89d2e92 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -98,6 +98,7 @@ char OP_WARP[] = "TFM_OT_warp";
char OP_SHRINK_FATTEN[] = "TFM_OT_shrink_fatten";
char OP_TILT[] = "TFM_OT_tilt";
char OP_TRACKBALL[] = "TFM_OT_trackball";
+char OP_MIRROR[] = "TFM_OT_mirror";
TransformModeItem transform_modes[] =
@@ -111,6 +112,7 @@ TransformModeItem transform_modes[] =
{OP_SHRINK_FATTEN, TFM_SHRINKFATTEN},
{OP_TILT, TFM_TILT},
{OP_TRACKBALL, TFM_TRACKBALL},
+ {OP_MIRROR, TFM_MIRROR},
{NULL, 0}
};
@@ -528,6 +530,25 @@ void TFM_OT_tosphere(struct wmOperatorType *ot)
RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
}
+void TFM_OT_mirror(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Mirror";
+ ot->description= "Mirror selected vertices around one or more axes.";
+ ot->idname = OP_MIRROR;
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
+
+ /* api callbacks */
+ ot->invoke = transform_invoke;
+ ot->exec = transform_exec;
+ ot->modal = transform_modal;
+ ot->cancel = transform_cancel;
+ ot->poll = ED_operator_areaactive;
+
+ Properties_Proportional(ot);
+ Properties_Constraints(ot);
+}
+
void TFM_OT_transform(struct wmOperatorType *ot)
{
static EnumPropertyItem transform_mode_types[] = {
@@ -595,6 +616,7 @@ void transform_operatortypes(void)
WM_operatortype_append(TFM_OT_shrink_fatten);
WM_operatortype_append(TFM_OT_tilt);
WM_operatortype_append(TFM_OT_trackball);
+ WM_operatortype_append(TFM_OT_mirror);
WM_operatortype_append(TFM_OT_select_orientation);
}
@@ -619,7 +641,7 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key
km = WM_keymap_add_item(keymap, "TFM_OT_warp", WKEY, KM_PRESS, KM_SHIFT, 0);
- km = WM_keymap_add_item(keymap, "TFM_OT_tosphere", SKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+ km = WM_keymap_add_item(keymap, "TFM_OT_tosphere", SKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0);
km = WM_keymap_add_item(keymap, "TFM_OT_shear", SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0);
@@ -699,8 +721,7 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key
km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0);
- km = WM_keymap_add_item(keymap, "TFM_OT_transform", MKEY, KM_PRESS, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_MIRROR);
+ km = WM_keymap_add_item(keymap, "TFM_OT_mirror", MKEY, KM_PRESS, 0, 0);
break;
default:
break;
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index e5b8d59d515..e73afa919b3 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -748,7 +748,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
for (nu = cu->editnurb->first; nu; nu = nu->next)
{
/* only bezier has a normal */
- if((nu->type & 7) == CU_BEZIER)
+ if(nu->type == CU_BEZIER)
{
bezt= nu->bezt;
a= nu->pntsu;