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:
authorCampbell Barton <ideasman42@gmail.com>2009-09-07 12:31:03 +0400
committerCampbell Barton <ideasman42@gmail.com>2009-09-07 12:31:03 +0400
commitd779410600de3061539c8c433c7a8c72cff022c0 (patch)
tree516539b2ca6aafb56121e2d1f2f23eca8c950763
parentf5e80e7a80feb4b516792b961c2310210536aef8 (diff)
parent3b743ac5565663d2fd0be4bbbc92e404afafbce4 (diff)
svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r22935:23022
looks like 2 merges are needed to skip a commit.
-rw-r--r--source/blender/blenkernel/intern/curve.c172
-rw-r--r--source/blender/blenlib/BLI_arithb.h1
-rw-r--r--source/blender/blenlib/intern/arithb.c13
-rw-r--r--source/blender/makesdna/DNA_curve_types.h2
4 files changed, 154 insertions, 34 deletions
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 7dd868278f4..228523aa661 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -1550,7 +1550,7 @@ void makeBevelList(Object *ob)
BPoint *bp;
BevList *bl, *blnew, *blnext;
BevPoint *bevp, *bevp2, *bevp1 = NULL, *bevp0;
- float min, inp, x1, x2, y1, y2, vec[3];
+ float min, inp, x1, x2, y1, y2, vec[3], vec_prev[3], q[4], quat[4], quat_prev[4], cross[3];
float *coord_array, *tilt_array=NULL, *radius_array=NULL, *coord_fp, *tilt_fp=NULL, *radius_fp=NULL;
float *v1, *v2;
struct bevelsort *sortdata, *sd, *sd1;
@@ -1909,7 +1909,10 @@ void makeBevelList(Object *ob)
bl= cu->bev.first;
while(bl) {
- if(bl->nr==2) { /* 2 pnt, treat separate */
+ if(bl->nr < 2) {
+ /* do nothing */
+ }
+ else if(bl->nr==2) { /* 2 pnt, treat separate */
bevp2= (BevPoint *)(bl+1);
bevp1= bevp2+1;
@@ -1923,68 +1926,169 @@ void makeBevelList(Object *ob)
if(cu->flag & CU_3D) { /* 3D */
float quat[4], q[4];
- vec[0]= bevp1->x - bevp2->x;
- vec[1]= bevp1->y - bevp2->y;
- vec[2]= bevp1->z - bevp2->z;
+ VecSubf(vec, &bevp1->x, &bevp2->x);
vectoquat(vec, 5, 1, quat);
- Normalize(vec);
- q[0]= (float)cos(0.5*bevp1->alfa);
- x1= (float)sin(0.5*bevp1->alfa);
- q[1]= x1*vec[0];
- q[2]= x1*vec[1];
- q[3]= x1*vec[2];
+ AxisAngleToQuat(q, vec, bevp1->alfa);
QuatMul(quat, q, quat);
QuatToMat3(quat, bevp1->mat);
Mat3CpyMat3(bevp2->mat, bevp1->mat);
}
+ } /* this has to be >2 points */
+ else if(cu->flag & CU_NO_TWIST && cu->flag & CU_3D && bl->poly != -1) {
+
+ /* Special case, cyclic curve with no twisy. tricky... */
+
+ float quat[4], q[4], cross[3];
+
+ /* correcting a cyclic curve is more complicated, need to be corrected from both ends */
+ float *quat_tmp1, *quat_tmp2; /* store a quat in the matrix temporarily */
+ int iter_dir;
+ BevPoint *bevp_start= (BevPoint *)(bl+1);
+
+ /* loop over the points twice, once up, once back, accumulate the quat rotations
+ * in both directions, then blend them in the 3rd loop and apply the tilt */
+ for(iter_dir = 0; iter_dir < 2; iter_dir++) {
+
+ bevp2= (BevPoint *)(bl+1);
+ bevp1= bevp2+(bl->nr-1);
+ bevp0= bevp1-1;
+
+ nr= bl->nr;
+ while(nr--) {
+
+ /* Normalizes */
+ Vec3ToTangent(vec, &bevp0->x, &bevp1->x, &bevp2->x);
+
+ if(bl->nr==nr+1) { /* first time */
+ vectoquat(vec, 5, 1, quat);
+ }
+ else {
+ float angle = NormalizedVecAngle2(vec_prev, vec);
+
+ if(angle > 0.0f) { /* otherwise we can keep as is */
+ Crossf(cross, vec_prev, vec);
+ AxisAngleToQuat(q, cross, angle);
+ QuatMul(quat, q, quat_prev);
+ }
+ else {
+ QUATCOPY(quat, quat_prev);
+ }
+ }
+ QUATCOPY(quat_prev, quat); /* quat_prev can't have the tilt applied */
+ VECCOPY(vec_prev, vec);
+
+ if(iter_dir==0) { /* up, first time */
+ quat_tmp1= (float *)bevp1->mat;
+
+ bevp0= bevp1;
+ bevp1= bevp2;
+ bevp2++;
+ }
+ else { /* down second time */
+ quat_tmp1= ((float *)bevp1->mat)+4;
+
+ bevp2= bevp1;
+ bevp1= bevp0;
+ bevp0--;
+
+ /* wrap around */
+ if (bevp0 < bevp_start)
+ bevp0= bevp_start+(bl->nr-1);
+ }
+
+ QUATCOPY(quat_tmp1, quat);
+ }
+ }
+
+ /* Now interpolate the 2 quats and apply tilt */
+
+ bevp2= (BevPoint *)(bl+1);
+ bevp1= bevp2+(bl->nr-1);
+ bevp0= bevp1-1;
+
+ nr= bl->nr;
+ while(nr--) {
+
+ Vec3ToTangent(vec, &bevp0->x, &bevp1->x, &bevp2->x);
+
+ quat_tmp1= (float *)bevp1->mat;
+ quat_tmp2= quat_tmp1+4;
+
+ /* blend the 2 rotations gathered from both directions */
+ QuatInterpol(quat, quat_tmp1, quat_tmp2, 1.0 - (((float)nr)/bl->nr));
+
+ AxisAngleToQuat(q, vec, bevp1->alfa);
+ QuatMul(quat, q, quat);
+ QuatToMat3(quat, bevp1->mat);
+
+ /* generic */
+ x1= bevp1->x- bevp0->x;
+ x2= bevp1->x- bevp2->x;
+ y1= bevp1->y- bevp0->y;
+ y2= bevp1->y- bevp2->y;
+
+ calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa));
+
+ bevp0= bevp1;
+ bevp1= bevp2;
+ bevp2++;
+ }
}
- else if(bl->nr>2) {
+ else {
+ /* Any curve with 3 or more points */
+
bevp2= (BevPoint *)(bl+1);
bevp1= bevp2+(bl->nr-1);
bevp0= bevp1-1;
-
nr= bl->nr;
-
while(nr--) {
-
+
if(cu->flag & CU_3D) { /* 3D */
- float quat[4], q[4];
-
- vec[0]= bevp2->x - bevp0->x;
- vec[1]= bevp2->y - bevp0->y;
- vec[2]= bevp2->z - bevp0->z;
-
- Normalize(vec);
- vectoquat(vec, 5, 1, quat);
-
- q[0]= (float)cos(0.5*bevp1->alfa);
- x1= (float)sin(0.5*bevp1->alfa);
- q[1]= x1*vec[0];
- q[2]= x1*vec[1];
- q[3]= x1*vec[2];
+ /* Normalizes */
+ Vec3ToTangent(vec, &bevp0->x, &bevp1->x, &bevp2->x);
+
+ if(bl->nr==nr+1 || !(cu->flag & CU_NO_TWIST)) { /* first time */
+ vectoquat(vec, 5, 1, quat);
+ }
+ else {
+ float angle = NormalizedVecAngle2(vec_prev, vec);
+
+ if(angle > 0.0f) { /* otherwise we can keep as is */
+ Crossf(cross, vec_prev, vec);
+ AxisAngleToQuat(q, cross, angle);
+ QuatMul(quat, q, quat_prev);
+ }
+ else {
+ QUATCOPY(quat, quat_prev);
+ }
+ }
+ QUATCOPY(quat_prev, quat); /* quat_prev can't have the tilt applied */
+ VECCOPY(vec_prev, vec);
+
+ AxisAngleToQuat(q, vec, bevp1->alfa);
QuatMul(quat, q, quat);
-
QuatToMat3(quat, bevp1->mat);
}
-
+
x1= bevp1->x- bevp0->x;
x2= bevp1->x- bevp2->x;
y1= bevp1->y- bevp0->y;
y2= bevp1->y- bevp2->y;
-
+
calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa));
-
-
+
+
bevp0= bevp1;
bevp1= bevp2;
bevp2++;
}
+
/* correct non-cyclic cases */
if(bl->poly== -1) {
if(bl->nr>2) {
diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h
index 2ab60c6a8d0..2ce4e8e268c 100644
--- a/source/blender/blenlib/BLI_arithb.h
+++ b/source/blender/blenlib/BLI_arithb.h
@@ -380,6 +380,7 @@ void AxisAngleToQuat(float *q, float *axis, float angle);
void RotationBetweenVectorsToQuat(float *q, float v1[3], float v2[3]);
void vectoquat(float *vec, short axis, short upflag, float *q);
+void Vec3ToTangent(float *v, float *v1, float *v2, float *v3);
float VecAngle2(float *v1, float *v2);
float VecAngle3(float *v1, float *v2, float *v3);
float NormalizedVecAngle2(float *v1, float *v2);
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index 2e60fbba4c9..55bdc32c4e9 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -3374,6 +3374,19 @@ void VecRotToQuat(float *vec, float phi, float *quat)
}
}
+/* get a direction from 3 vectors that wont depend
+ * on the distance between the points */
+void Vec3ToTangent(float *v, float *v1, float *v2, float *v3)
+{
+ float d_12[3], d_23[3];
+ VecSubf(d_12, v2, v1);
+ VecSubf(d_23, v3, v2);
+ Normalize(d_12);
+ Normalize(d_23);
+ VecAddf(v, d_12, d_23);
+ Normalize(v);
+}
+
/* Return the angle in degrees between vecs 1-2 and 2-3 in degrees
If v1 is a shoulder, v2 is the elbow and v3 is the hand,
this would return the angle at the elbow */
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 3bac2c73bcb..3655c57558a 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -225,6 +225,8 @@ typedef struct Curve {
#define CU_RETOPO 1024
#define CU_DS_EXPAND 2048
+#define CU_NO_TWIST 4096
+
/* spacemode */
#define CU_LEFT 0
#define CU_MIDDLE 1