diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-07-24 17:56:36 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-07-24 17:56:36 +0400 |
commit | b6f58d0ea1c2d1b3b87293da1858b370d857a481 (patch) | |
tree | ca4ca51211c7b0adc0e821683d3305c1a6591bff /source/blender/editors/transform | |
parent | 57a4070b9d6da6151f1ff3d9cb4f88342be2dc5f (diff) |
- add individual origin support for curves and improve the orientation calculations for curve handles,
- add support for using the active point's orientation.
- add support for creating new custom orientations from curves.
- fix error where only the last selected curve handle was taken into account for manipulator orientations.
Diffstat (limited to 'source/blender/editors/transform')
4 files changed, 114 insertions, 31 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 0019cae9c4e..6c854ef6795 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -110,7 +110,7 @@ static bool transdata_check_local_center(TransInfo *t) { return ((t->around == V3D_LOCAL) && ( (t->flag & (T_OBJECT | T_POSE)) || - (t->obedit && ELEM3(t->obedit->type, OB_MESH, OB_MBALL, OB_ARMATURE)) || + (t->obedit && ELEM4(t->obedit->type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE)) || (t->spacetype == SPACE_IPO)) ); } @@ -7355,7 +7355,7 @@ bool checkUseAxisMatrix(TransInfo *t) { /* currenly only checks for editmode */ if (t->flag & T_EDIT) { - if ((t->around == V3D_LOCAL) && (ELEM3(t->obedit->type, OB_MESH, OB_MBALL, OB_ARMATURE))) { + if ((t->around == V3D_LOCAL) && (ELEM4(t->obedit->type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE))) { /* not all editmode supports axis-matrix */ return true; } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 911d4b0a623..4a1c4203a43 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -725,7 +725,7 @@ void initTransformOrientation(struct bContext *C, TransInfo *t); /* Those two fill in mat and return non-zero on success */ bool createSpaceNormal(float mat[3][3], const float normal[3]); -bool createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]); +bool createSpaceNormalTangent(float mat[3][3], const float normal[3], const float tangent[3]); struct TransformOrientation *addMatrixSpace(struct bContext *C, float mat[3][3], char name[], int overwrite); void applyTransformOrientation(const struct bContext *C, float mat[3][3], char *name); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 15df06be3d6..0a8687339a5 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1417,6 +1417,23 @@ static void createTransCurveVerts(TransInfo *t) for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { if (bezt->hide == 0) { TransDataCurveHandleFlags *hdata = NULL; + float axismtx[3][3]; + + if (t->around == V3D_LOCAL) { + float normal[3], plane[3]; + + BKE_nurb_bezt_calc_normal(nu, bezt, normal); + BKE_nurb_bezt_calc_plane(nu, bezt, plane); + + if (createSpaceNormalTangent(axismtx, normal, plane)) { + /* pass */ + } + else { + normalize_v3(normal); + axis_dominant_v3_to_m3(axismtx, normal); + invert_m3(axismtx); + } + } if (propmode || ((bezt->f2 & SELECT) && hide_handles) || @@ -1440,6 +1457,9 @@ static void createTransCurveVerts(TransInfo *t) copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); + if (t->around == V3D_LOCAL) { + copy_m3_m3(td->axismtx, axismtx); + } td++; count++; @@ -1469,6 +1489,9 @@ static void createTransCurveVerts(TransInfo *t) copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); + if (t->around == V3D_LOCAL) { + copy_m3_m3(td->axismtx, axismtx); + } if ((bezt->f1 & SELECT) == 0 && (bezt->f3 & SELECT) == 0) /* If the middle is selected but the sides arnt, this is needed */ @@ -1504,6 +1527,9 @@ static void createTransCurveVerts(TransInfo *t) copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); + if (t->around == V3D_LOCAL) { + copy_m3_m3(td->axismtx, axismtx); + } td++; count++; diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 2be4a072d49..c6cc7bc1330 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -166,6 +166,26 @@ static TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, c return addMatrixSpace(C, mat, name, overwrite); } +static TransformOrientation *createCurveSpace(bContext *C, ReportList *reports, char *name, int overwrite) +{ + float mat[3][3]; + float normal[3], plane[3]; + + getTransformOrientation(C, normal, plane, 0); + + if (createSpaceNormalTangent(mat, normal, plane) == 0) { + BKE_reports_prepend(reports, "Cannot use zero-length curve"); + return NULL; + } + + if (name[0] == 0) { + strcpy(name, "Curve"); + } + + return addMatrixSpace(C, mat, name, overwrite); +} + + static TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, char *name, int overwrite) { float mat[3][3]; @@ -236,26 +256,28 @@ bool createSpaceNormal(float mat[3][3], const float normal[3]) return true; } -bool createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]) +bool createSpaceNormalTangent(float mat[3][3], const float normal[3], const float tangent[3]) { - copy_v3_v3(mat[2], normal); - if (normalize_v3(mat[2]) == 0.0f) { + if (normalize_v3_v3(mat[2], normal) == 0.0f) { return false; /* error return */ } - + + copy_v3_v3(mat[1], tangent); /* preempt zero length tangent from causing trouble */ - if (tangent[0] == 0 && tangent[1] == 0 && tangent[2] == 0) { - tangent[2] = 1; + if (is_zero_v3(mat[1])) { + mat[1][2] = 1.0f; } - cross_v3_v3v3(mat[0], mat[2], tangent); + cross_v3_v3v3(mat[0], mat[2], mat[1]); if (normalize_v3(mat[0]) == 0.0f) { return false; /* error return */ } cross_v3_v3v3(mat[1], mat[2], mat[0]); + normalize_v3(mat[1]); - normalize_m3(mat); + /* final matrix must be normalized, do inline */ + // normalize_m3(mat); return true; } @@ -276,6 +298,8 @@ void BIF_createTransformOrientation(bContext *C, ReportList *reports, char *name ts = createMeshSpace(C, reports, name, overwrite); else if (obedit->type == OB_ARMATURE) ts = createBoneSpace(C, reports, name, overwrite); + else if (obedit->type == OB_CURVE) + ts = createCurveSpace(C, reports, name, overwrite); } else if (ob && (ob->mode & OB_MODE_POSE)) { ts = createBoneSpace(C, reports, name, overwrite); @@ -675,34 +699,67 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], int a; ListBase *nurbs = BKE_curve_editNurbs_get(cu); - for (nu = nurbs->first; nu; nu = nu->next) { - /* only bezier has a normal */ - if (nu->type == CU_BEZIER) { - bezt = nu->bezt; - a = nu->pntsu; - while (a--) { - /* exception */ - if ((bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT) { - sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[2]); + if (activeOnly && cu->lastsel) { + for (nu = nurbs->first; nu; nu = nu->next) { + if (nu->type == CU_BEZIER) { + if (ARRAY_HAS_ITEM((BezTriple *)cu->lastsel, nu->bezt, nu->pntsu)) { + bezt = cu->lastsel; + BKE_nurb_bezt_calc_normal(nu, bezt, normal); + BKE_nurb_bezt_calc_plane(nu, bezt, plane); + break; } - else { - if (bezt->f1) { - sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[1]); - } - if (bezt->f2) { - sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[2]); - } - if (bezt->f3) { - sub_v3_v3v3(normal, bezt->vec[1], bezt->vec[2]); + } + else { + if (ARRAY_HAS_ITEM((BPoint *)cu->lastsel, nu->bp, nu->pntsu)) { + /* do nothing */ + break; + } + } + } + } + else { + for (nu = nurbs->first; nu; nu = nu->next) { + /* only bezier has a normal */ + if (nu->type == CU_BEZIER) { + bezt = nu->bezt; + a = nu->pntsu; + while (a--) { + /* exception */ + if ((bezt->f1 | bezt->f2 | bezt->f3) & SELECT) { + float tvec[3]; + if ((bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT) { + BKE_nurb_bezt_calc_normal(nu, bezt, tvec); + add_v3_v3(normal, tvec); + } + else { + if (bezt->f1 & SELECT) { + sub_v3_v3v3(tvec, bezt->vec[0], bezt->vec[1]); + normalize_v3(tvec); + add_v3_v3(normal, tvec); + } + if (bezt->f2 & SELECT) { + sub_v3_v3v3(tvec, bezt->vec[0], bezt->vec[2]); + normalize_v3(tvec); + add_v3_v3(normal, tvec); + } + if (bezt->f3 & SELECT) { + sub_v3_v3v3(tvec, bezt->vec[1], bezt->vec[2]); + normalize_v3(tvec); + add_v3_v3(normal, tvec); + } + } + + BKE_nurb_bezt_calc_plane(nu, bezt, tvec); + add_v3_v3(plane, tvec); } + bezt++; } - bezt++; } } } if (!is_zero_v3(normal)) { - result = ORIENTATION_NORMAL; + result = ORIENTATION_FACE; } } else if (obedit->type == OB_MBALL) { |