|
|
|
|
@@ -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,56 +1926,106 @@ 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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if(bl->nr>2) {
|
|
|
|
|
} /* 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--) {
|
|
|
|
|
|
|
|
|
|
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];
|
|
|
|
|
QuatMul(quat, q, quat);
|
|
|
|
|
|
|
|
|
|
QuatToMat3(quat, bevp1->mat);
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
@@ -1980,11 +2033,62 @@ void makeBevelList(Object *ob)
|
|
|
|
|
|
|
|
|
|
calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bevp0= bevp1;
|
|
|
|
|
bevp1= bevp2;
|
|
|
|
|
bevp2++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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 */
|
|
|
|
|
|
|
|
|
|
/* 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) {
|
|
|
|
|
|