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:
-rw-r--r--source/blender/blenkernel/BKE_curve.h8
-rw-r--r--source/blender/blenkernel/intern/curve.c137
-rw-r--r--source/blender/editors/curve/editcurve.c46
-rw-r--r--source/blender/editors/transform/transform.c4
-rw-r--r--source/blender/editors/transform/transform.h2
-rw-r--r--source/blender/editors/transform/transform_conversions.c26
-rw-r--r--source/blender/editors/transform/transform_orientations.c113
7 files changed, 263 insertions, 73 deletions
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 3be77086336..93f9ec276aa 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -129,6 +129,14 @@ bool BKE_nurb_type_convert(struct Nurb *nu, const short type, const bool use_han
void BKE_nurb_points_add(struct Nurb *nu, int number);
void BKE_nurb_bezierPoints_add(struct Nurb *nu, int number);
+struct BezTriple *BKE_nurb_bezt_get_next(struct Nurb *nu, struct BezTriple *bezt);
+struct BezTriple *BKE_nurb_bezt_get_prev(struct Nurb *nu, struct BezTriple *bezt);
+struct BPoint *BKE_nurb_bpoint_get_next(struct Nurb *nu, struct BPoint *bp);
+struct BPoint *BKE_nurb_bpoint_get_prev(struct Nurb *nu, struct BPoint *bp);
+
+void BKE_nurb_bezt_calc_normal(struct Nurb *nu, struct BezTriple *bezt, float r_normal[3]);
+void BKE_nurb_bezt_calc_plane(struct Nurb *nu, struct BezTriple *bezt, float r_plane[3]);
+
void BKE_nurb_handle_calc(struct BezTriple *bezt, struct BezTriple *prev, struct BezTriple *next, int mode);
void BKE_nurb_handles_calc(struct Nurb *nu);
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index b6c4505bd78..43e5cc101a7 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -681,6 +681,143 @@ void BKE_nurb_bezierPoints_add(Nurb *nu, int number)
nu->pntsu += number;
}
+
+BezTriple *BKE_nurb_bezt_get_next(Nurb *nu, BezTriple *bezt)
+{
+ BezTriple *bezt_next;
+
+ BLI_assert(ARRAY_HAS_ITEM(bezt, nu->bezt, nu->pntsu));
+
+ if (bezt == &nu->bezt[nu->pntsu - 1]) {
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ bezt_next = nu->bezt;
+ }
+ else {
+ bezt_next = NULL;
+ }
+ }
+ else {
+ bezt_next = bezt + 1;
+ }
+
+ return bezt_next;
+}
+
+BPoint *BKE_nurb_bpoint_get_next(Nurb *nu, BPoint *bp)
+{
+ BPoint *bp_next;
+
+ BLI_assert(ARRAY_HAS_ITEM(bp, nu->bp, nu->pntsu));
+
+ if (bp == &nu->bp[nu->pntsu - 1]) {
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ bp_next = nu->bp;
+ }
+ else {
+ bp_next = NULL;
+ }
+ }
+ else {
+ bp_next = bp + 1;
+ }
+
+ return bp_next;
+}
+
+BezTriple *BKE_nurb_bezt_get_prev(Nurb *nu, BezTriple *bezt)
+{
+ BezTriple *bezt_prev;
+
+ BLI_assert(ARRAY_HAS_ITEM(bezt, nu->bezt, nu->pntsu));
+
+ if (bezt == nu->bezt) {
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ bezt_prev = &nu->bezt[nu->pntsu - 1];
+ }
+ else {
+ bezt_prev = NULL;
+ }
+ }
+ else {
+ bezt_prev = bezt - 1;
+ }
+
+ return bezt_prev;
+}
+
+BPoint *BKE_nurb_bpoint_get_prev(Nurb *nu, BPoint *bp)
+{
+ BPoint *bp_prev;
+
+ BLI_assert(ARRAY_HAS_ITEM(bp, nu->bp, nu->pntsu));
+
+ if (bp == nu->bp) {
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ bp_prev = &nu->bp[nu->pntsu - 1];
+ }
+ else {
+ bp_prev = NULL;
+ }
+ }
+ else {
+ bp_prev = bp - 1;
+ }
+
+ return bp_prev;
+}
+
+void BKE_nurb_bezt_calc_normal(struct Nurb *UNUSED(nu), struct BezTriple *bezt, float r_normal[3])
+{
+ /* calculate the axis matrix from the spline */
+ float dir_prev[3], dir_next[3];
+
+ sub_v3_v3v3(dir_prev, bezt->vec[0], bezt->vec[1]);
+ sub_v3_v3v3(dir_next, bezt->vec[1], bezt->vec[2]);
+
+ normalize_v3(dir_prev);
+ normalize_v3(dir_next);
+
+ add_v3_v3v3(r_normal, dir_prev, dir_next);
+ normalize_v3(r_normal);
+}
+
+void BKE_nurb_bezt_calc_plane(struct Nurb *nu, struct BezTriple *bezt, float r_plane[3])
+{
+ float dir_prev[3], dir_next[3];
+
+ sub_v3_v3v3(dir_prev, bezt->vec[0], bezt->vec[1]);
+ sub_v3_v3v3(dir_next, bezt->vec[1], bezt->vec[2]);
+
+ normalize_v3(dir_prev);
+ normalize_v3(dir_next);
+
+ cross_v3_v3v3(r_plane, dir_prev, dir_next);
+ if (normalize_v3(r_plane) < FLT_EPSILON) {
+ BezTriple *bezt_prev = BKE_nurb_bezt_get_prev(nu, bezt);
+ BezTriple *bezt_next = BKE_nurb_bezt_get_next(nu, bezt);
+
+ if (bezt_prev) {
+ sub_v3_v3v3(dir_prev, bezt_prev->vec[1], bezt->vec[1]);
+ normalize_v3(dir_prev);
+ }
+ if (bezt_next) {
+ sub_v3_v3v3(dir_next, bezt->vec[1], bezt_next->vec[1]);
+ normalize_v3(dir_next);
+ }
+ cross_v3_v3v3(r_plane, dir_prev, dir_next);
+ }
+
+ /* matches with bones more closely */
+ {
+ float dir_mid[3], tvec[3];
+ add_v3_v3v3(dir_mid, dir_prev, dir_next);
+ cross_v3_v3v3(tvec, r_plane, dir_mid);
+ copy_v3_v3(r_plane, tvec);
+ }
+
+ normalize_v3(r_plane);
+}
+
/* ~~~~~~~~~~~~~~~~~~~~Non Uniform Rational B Spline calculations ~~~~~~~~~~~ */
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 5352b367d05..a988b2295dc 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -2833,44 +2833,6 @@ void CURVE_OT_reveal(wmOperatorType *ot)
/********************** subdivide operator *********************/
-static BezTriple *next_spline_bezier_point_get(Nurb *nu, BezTriple *bezt)
-{
- BezTriple *nextbezt;
-
- if (bezt == nu->bezt + nu->pntsu - 1) {
- if (nu->flagu & CU_NURB_CYCLIC) {
- nextbezt = nu->bezt;
- }
- else {
- nextbezt = NULL;
- }
- }
- else {
- nextbezt = bezt + 1;
- }
-
- return nextbezt;
-}
-
-static BPoint *next_spline_bpoint_get(Nurb *nu, BPoint *bp)
-{
- BPoint *nextbp;
-
- if (bp == nu->bp + nu->pntsu - 1) {
- if (nu->flagu & CU_NURB_CYCLIC) {
- nextbp = nu->bp;
- }
- else {
- nextbp = NULL;
- }
- }
- else {
- nextbp = bp + 1;
- }
-
- return nextbp;
-}
-
/** Divide the line segments associated with the currently selected
* curve nodes (Bezier or NURB). If there are no valid segment
* selections within the current selection, nothing happens.
@@ -2902,7 +2864,7 @@ static void subdividenurb(Object *obedit, int number_cuts)
a = nu->pntsu;
bezt = nu->bezt;
while (a--) {
- nextbezt = next_spline_bezier_point_get(nu, bezt);
+ nextbezt = BKE_nurb_bezt_get_next(nu, bezt);
if (nextbezt == NULL) {
break;
}
@@ -2924,7 +2886,7 @@ static void subdividenurb(Object *obedit, int number_cuts)
keyIndex_updateBezt(editnurb, bezt, beztn, 1);
beztn++;
- nextbezt = next_spline_bezier_point_get(nu, bezt);
+ nextbezt = BKE_nurb_bezt_get_next(nu, bezt);
if (nextbezt == NULL) {
break;
}
@@ -2988,7 +2950,7 @@ static void subdividenurb(Object *obedit, int number_cuts)
a = nu->pntsu;
bp = nu->bp;
while (a--) {
- nextbp = next_spline_bpoint_get(nu, bp);
+ nextbp = BKE_nurb_bpoint_get_next(nu, bp);
if (nextbp == NULL) {
break;
}
@@ -3013,7 +2975,7 @@ static void subdividenurb(Object *obedit, int number_cuts)
keyIndex_updateBP(editnurb, bp, bpn, 1);
bpn++;
- nextbp = next_spline_bpoint_get(nu, bp);
+ nextbp = BKE_nurb_bpoint_get_next(nu, bp);
if (nextbp == NULL) {
break;
}
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) {