in src/compositor/mesh.c [1693:2295]
static void mesh_extrude_path_intern(GF_Mesh *mesh, GF_Path *path, MFVec3f *thespine, Fixed creaseAngle, Fixed min_cx, Fixed min_cy, Fixed width_cx, Fixed width_cy, Bool begin_cap, Bool end_cap, MFRotation *spine_ori, MFVec2f *spine_scale, Bool tx_along_spine)
{
GF_Mesh **faces;
GF_Vertex vx;
struct face_info *faces_info;
struct pt_info *pts_info;
GF_Matrix mx;
SCP *SCPs, SCPbegin, SCPend;
SCPInfo *SCPi;
Bool smooth_normals, spine_closed, check_first_spine_vec, do_close;
u32 i, j, k, nb_scp, nb_spine, face_count, pt_count, faces_per_cross, begin_face, end_face, face_spines, pts_per_cross, cur_pts_in_cross,cur, nb_pts, convexity;
SFVec3f *spine, v1, v2, n, spine_vec;
Fixed cross_len, spine_len, cur_cross, cur_spine;
SFRotation r;
SFVec2f scale;
if (!path->n_contours) return;
if (path->n_points<2) return;
if (thespine->count<2) return;
spine_closed = 0;
if (gf_vec_equal(thespine->vals[0], thespine->vals[thespine->count-1])) spine_closed = 1;
if (spine_closed && (thespine->count==2)) return;
gf_path_flatten(path);
memset(&vx, 0, sizeof(GF_Vertex));
pts_per_cross = 0;
cross_len = 0;
cur = 0;
for (i=0; i<path->n_contours; i++) {
nb_pts = 1 + path->contours[i] - cur;
pts_per_cross += nb_pts;
v1.z = 0;
for (j=1; j<nb_pts; j++) {
v1.x = path->points[j+cur].x - path->points[j-1+cur].x;
v1.y = path->points[j+cur].y - path->points[j-1+cur].y;
cross_len += gf_vec_len(v1);
}
}
faces_per_cross = pts_per_cross - path->n_contours;
begin_face = end_face = 0;
face_spines = face_count = (thespine->count-1)*faces_per_cross;
if (begin_cap) {
begin_face = face_count;
face_count ++;
}
if (end_cap) {
end_face = face_count;
face_count ++;
}
pt_count = pts_per_cross * thespine->count;
smooth_normals = NEAR_ZERO(creaseAngle) ? 0 : 1;
faces = (GF_Mesh**)gf_malloc(sizeof(GF_Mesh *)*face_count);
for (i=0; i<face_count; i++) faces[i] = new_mesh();
faces_info = NULL;
pts_info = NULL;
/*alloc face & normals tables*/
if (smooth_normals) {
faces_info = (struct face_info*)gf_malloc(sizeof(struct face_info)*face_count);
memset(faces_info, 0, sizeof(struct face_info)*face_count);
pts_info = (struct pt_info*)gf_malloc(sizeof(struct pt_info)*pt_count);
memset(pts_info, 0, sizeof(struct pt_info)*pt_count);
}
spine = thespine->vals;
nb_spine = thespine->count;
SCPs = (SCP *)gf_malloc(sizeof(SCP) * nb_spine);
memset(SCPs, 0, sizeof(SCP) * nb_spine);
SCPi = (SCPInfo *) gf_malloc(sizeof(SCPInfo) * nb_spine);
memset(SCPi, 0, sizeof(SCPInfo) * nb_spine);
/*collect all # SCPs:
1- if a spine has identical consecutive points with # orientation, these points use the same SCPs
2- if 2 segs of the spine are colinear, they also use the same SCP
*/
SCPi[0].pt = spine[0];
SCPi[0].max_idx = 0;
nb_scp=1;
spine_len = 0;
check_first_spine_vec = 1;
for (i=1; i<nb_spine; i++) {
Fixed len;
/*also get spine length for txcoord*/
gf_vec_diff(v2, spine[i], spine[i-1]);
len = gf_vec_len(v2);
spine_len += len;
if (check_first_spine_vec && len) {
check_first_spine_vec = 0;
spine_vec = v2;
}
/*case 1: same point, same SCP*/
if (gf_vec_equal(SCPi[nb_scp-1].pt, spine[i])) {
SCPi[nb_scp-1].max_idx = i;
continue;
}
/*last point in spine*/
if (i+1 == nb_spine) {
nb_scp++;
SCPi[nb_scp-1].pt = spine[i];
SCPi[nb_scp-1].max_idx = i;
break;
}
gf_vec_diff(v1, spine[i+1], spine[i]);
gf_vec_diff(v2, SCPi[nb_scp-1].pt, spine[i]);
n = gf_vec_cross(v1, v2);
/*case 2: spine segs are colinear*/
if (!n.x && !n.y && !n.z) {
SCPi[nb_scp-1].max_idx = i;
}
/*OK new SCP*/
else {
nb_scp++;
SCPi[nb_scp-1].pt = spine[i];
SCPi[nb_scp-1].max_idx = i;
}
}
/*all colinear!!*/
if (nb_scp<=2) {
SCPi[0].xaxis.x = FIX_ONE;
SCPi[0].xaxis.y = 0;
SCPi[0].xaxis.z = 0;
SCPi[0].yaxis.x = 0;
SCPi[0].yaxis.y = FIX_ONE;
SCPi[0].yaxis.z = 0;
SCPi[0].zaxis.x = 0;
SCPi[0].zaxis.y = 0;
SCPi[0].zaxis.z = FIX_ONE;
/*compute rotation from (0, 1, 0) to spine_vec*/
if (!check_first_spine_vec) {
Fixed alpha, gamma;
Fixed cos_a, sin_a, sin_g, cos_g;
gf_vec_norm(&spine_vec);
if (! NEAR_ZERO(spine_vec.x) ) {
if (spine_vec.x >= FIX_ONE-FIX_EPSILON) alpha = GF_PI2;
else if (spine_vec.x <= -FIX_ONE+FIX_EPSILON) alpha = -GF_PI2;
else alpha = gf_asin(spine_vec.x);
cos_a = gf_cos(alpha);
sin_a = spine_vec.x;
sin_g = 0;
if (NEAR_ZERO(cos_a)) gamma = 0;
else {
Fixed __abs;
gamma = gf_acos(gf_divfix(spine_vec.y, cos_a));
sin_g = gf_sin(gamma);
__abs = gf_divfix(spine_vec.z, cos_a) + sin_g;
if (ABS(__abs) > ABS(sin_g) ) gamma *= -1;
}
cos_g = gf_cos(gamma);
if (NEAR_ZERO(cos_g)) {
cos_g = 0;
sin_g = FIX_ONE;
} else {
sin_g = gf_sin(gamma);
}
SCPi[0].yaxis.y = gf_mulfix(cos_a, sin_g);
SCPi[0].yaxis.z = gf_mulfix(cos_a, cos_g);
SCPi[0].yaxis.x = sin_a;
SCPi[0].zaxis.y = -gf_mulfix(sin_a, sin_g);
SCPi[0].zaxis.z = -gf_mulfix(sin_a, cos_g);
SCPi[0].zaxis.x = cos_a;
}
if (! NEAR_ZERO(spine_vec.z) ) {
if (spine_vec.z >= FIX_ONE-FIX_EPSILON) alpha = GF_PI2;
else if (spine_vec.z <= -FIX_ONE+FIX_EPSILON) alpha = -GF_PI2;
else alpha = gf_asin(spine_vec.z);
cos_a = gf_cos(alpha);
sin_a = spine_vec.z;
sin_g = 0;
if (NEAR_ZERO(cos_a) ) gamma = 0;
else {
Fixed __abs;
gamma = gf_acos(gf_divfix(spine_vec.y, cos_a));
sin_g = gf_sin(gamma);
__abs = gf_divfix(spine_vec.x, cos_a) + sin_g;
if (ABS(__abs) > ABS(sin_g) ) gamma *= -1;
}
cos_g = gf_cos(gamma);
sin_g = gf_sin(gamma);
SCPi[0].yaxis.y = gf_mulfix(cos_a, sin_g);
SCPi[0].yaxis.x = gf_mulfix(cos_a, cos_g);
SCPi[0].yaxis.z = sin_a;
SCPi[0].zaxis.y = -gf_mulfix(sin_a, sin_g);
SCPi[0].zaxis.x = -gf_mulfix(sin_a, cos_g);
SCPi[0].zaxis.z = cos_a;
}
}
for (i=0; i<nb_spine; i++) {
SCPs[i].xaxis = SCPi[0].xaxis;
SCPs[i].yaxis = SCPi[0].yaxis;
SCPs[i].zaxis = SCPi[0].zaxis;
}
}
/*not colinear*/
else {
assert(nb_scp<=nb_spine);
/*now non-cap SCPs axis*/
for (i=1; i<nb_scp-1; i++) {
/*get Y axis*/
gf_vec_diff(SCPi[i].yaxis, SCPi[i+1].pt, SCPi[i-1].pt);
/*get Z axis*/
gf_vec_diff(v1, SCPi[i+1].pt, SCPi[i].pt);
gf_vec_diff(v2, SCPi[i-1].pt, SCPi[i].pt);
SCPi[i].zaxis = gf_vec_cross(v1, v2);
}
/*compute head and tail*/
if (spine_closed) {
gf_vec_diff(SCPi[0].yaxis, SCPi[1].pt, SCPi[nb_scp-2].pt);
gf_vec_diff(v1, SCPi[1].pt, SCPi[0].pt);
gf_vec_diff(v2, SCPi[nb_scp-2].pt, SCPi[0].pt);
SCPi[0].zaxis = gf_vec_cross(v1, v2);
SCPi[nb_scp-1].yaxis = SCPi[0].yaxis;
SCPi[nb_scp-1].zaxis = SCPi[0].zaxis;
} else {
gf_vec_diff(SCPi[0].yaxis, SCPi[1].pt, SCPi[0].pt);
SCPi[0].zaxis = SCPi[1].zaxis;
gf_vec_diff(SCPi[nb_scp-1].yaxis, SCPi[nb_scp-1].pt, SCPi[nb_scp-2].pt);
SCPi[nb_scp-1].zaxis = SCPi[nb_scp-2].zaxis;
}
/*check orientation*/
for (i=1; i<nb_scp; i++) {
Fixed res = gf_vec_dot(SCPi[i].zaxis, SCPi[i-1].zaxis);
if (res<0) gf_vec_rev(SCPi[i].zaxis);
}
/*and assign SCPs*/
j=0;
for (i=0; i<nb_scp; i++) {
/*compute X, norm vectors*/
SCPi[i].xaxis = gf_vec_cross(SCPi[i].yaxis, SCPi[i].zaxis);
gf_vec_norm(&SCPi[i].xaxis);
gf_vec_norm(&SCPi[i].yaxis);
gf_vec_norm(&SCPi[i].zaxis);
/*assign SCPs*/
while (j<=SCPi[i].max_idx) {
SCPs[j].xaxis = SCPi[i].xaxis;
SCPs[j].yaxis = SCPi[i].yaxis;
SCPs[j].zaxis = SCPi[i].zaxis;
j++;
}
}
}
gf_free(SCPi);
SCPbegin = SCPs[0];
SCPend = SCPs[nb_spine-1];
r.x = r.q = r.z = 0;
r.y = FIX_ONE;
scale.x = scale.y = FIX_ONE;
cur_spine = 0;
/*insert all points of the extrusion*/
for (i=0; i<nb_spine; i++) {
u32 cur_face_in_cross;
SCP *curSCP;
if (spine_closed && (i+1==nb_spine)) {
curSCP = &SCPs[0];
do_close = 1;
} else {
curSCP = &SCPs[i];
do_close = 0;
/*compute X*/
curSCP->xaxis = gf_vec_cross(curSCP->yaxis, curSCP->zaxis);
gf_vec_norm(&curSCP->xaxis);
gf_vec_norm(&curSCP->yaxis);
gf_vec_norm(&curSCP->zaxis);
if (spine_ori && (i<spine_ori->count)) r = spine_ori->vals[i];
if (spine_scale && (i<spine_scale->count)) scale = spine_scale->vals[i];
gf_mx_init(mx);
gf_mx_add_rotation(&mx, r.q, r.x, r.y, r.z);
gf_mx_apply_vec(&mx, &curSCP->xaxis);
gf_mx_apply_vec(&mx, &curSCP->yaxis);
gf_mx_apply_vec(&mx, &curSCP->zaxis);
}
vx.texcoords.y = gf_divfix(cur_spine, spine_len);
cur_pts_in_cross = 0;
cur_face_in_cross = 0;
cur = 0;
for (j=0; j<path->n_contours; j++) {
Bool subpath_closed;
nb_pts = 1+path->contours[j] - cur;
cur_cross = 0;
subpath_closed = 0;
if ((path->points[cur].x==path->points[path->contours[j]].x) && (path->points[cur].y==path->points[path->contours[j]].y))
subpath_closed = 1;
for (k=0; k<nb_pts; k++) {
u32 pidx = k + cur_pts_in_cross + i*pts_per_cross;
if (do_close) pidx = k + cur_pts_in_cross;
v1.x = path->points[k+cur].x;
v1.z = path->points[k+cur].y;
if (tx_along_spine) {
vx.texcoords.x = gf_divfix(cur_cross, cross_len);
} else {
vx.texcoords.x = gf_divfix(v1.x - min_cx, width_cx);
vx.texcoords.y = gf_divfix(v1.z - min_cy, width_cy);
}
/*handle closed cross-section*/
if (subpath_closed && (k+1==nb_pts)) {
pidx = cur_pts_in_cross + i*pts_per_cross;
if (do_close) pidx = cur_pts_in_cross;
v1.x = path->points[cur].x;
v1.z = path->points[cur].y;
}
v1.x = gf_mulfix(v1.x, scale.x);
v1.z = gf_mulfix(v1.z, scale.y);
v1.y = 0;
vx.pos.x = gf_mulfix(v1.x, curSCP->xaxis.x) + gf_mulfix(v1.y, curSCP->yaxis.x) + gf_mulfix(v1.z, curSCP->zaxis.x) + spine[i].x;
vx.pos.y = gf_mulfix(v1.x, curSCP->xaxis.y) + gf_mulfix(v1.y, curSCP->yaxis.y) + gf_mulfix(v1.z, curSCP->zaxis.y) + spine[i].y;
vx.pos.z = gf_mulfix(v1.x, curSCP->xaxis.z) + gf_mulfix(v1.y, curSCP->yaxis.z) + gf_mulfix(v1.z, curSCP->zaxis.z) + spine[i].z;
/*in current spine*/
if (i+1<nb_spine) {
/*current face*/
if (k<nb_pts-1) REGISTER_POINT_FACE(k + cur_face_in_cross + i*faces_per_cross);
/*previous face*/
if (k) REGISTER_POINT_FACE(k-1 + cur_face_in_cross + i*faces_per_cross);
}
/*first spine*/
else if (smooth_normals && do_close) {
if (k<nb_pts-1) {
register_point_in_face(&faces_info[k + cur_face_in_cross], pidx);
register_face_in_point(&pts_info[pidx], k + cur_face_in_cross);
}
/*previous face*/
if (k) {
register_point_in_face(&faces_info[k-1 + cur_face_in_cross], pidx);
register_face_in_point(&pts_info[pidx], k-1 + cur_face_in_cross);
}
}
/*in previous spine*/
if (i) {
/*face "below" face*/
if (k<nb_pts-1) REGISTER_POINT_FACE(k + cur_face_in_cross + (i-1)*faces_per_cross);
/*previous face "below" face*/
if (k) REGISTER_POINT_FACE(k-1 + cur_face_in_cross + (i-1)*faces_per_cross);
}
if (k+1<nb_pts) {
v1.z = 0;
v1.x = path->points[k+1+cur].x - path->points[k+cur].x;
v1.y = path->points[k+1+cur].y - path->points[k+cur].y;
cur_cross += gf_vec_len(v1);
}
}
cur_face_in_cross += nb_pts-1;
cur_pts_in_cross += nb_pts;
cur += nb_pts;
}
if (i+1<nb_spine) {
gf_vec_diff(v1, spine[i+1], spine[i]);
cur_spine += gf_vec_len(v1);
}
}
/*generate triangles & normals*/
for (i=0; i<face_spines; i++) {
mesh_set_triangle(faces[i], 0, 1, 3);
mesh_set_triangle(faces[i], 0, 3, 2);
gf_vec_diff(v1, faces[i]->vertices[1].pos, faces[i]->vertices[0].pos);
gf_vec_diff(v2, faces[i]->vertices[3].pos, faces[i]->vertices[0].pos);
n = gf_vec_cross(v1, v2);
gf_vec_norm(&n);
for (j=0; j<faces[i]->v_count; j++) {
MESH_SET_NORMAL(faces[i]->vertices[j], n);
if (smooth_normals) faces_info[i].nor = n;
}
}
/*generate begin cap*/
if (begin_face) {
SFVec3f n;
scale.x = scale.y = FIX_ONE;
if (spine_scale && spine_scale->count) scale = spine_scale->vals[0];
/*get first SCP after rotation*/
SCPbegin = SCPs[0];
n = SCPbegin.yaxis;
gf_vec_norm(&n);
convexity = gf_polygone2d_get_convexity(path->points, path->n_points);
switch (convexity) {
case GF_POLYGON_CONVEX_CCW:
case GF_POLYGON_COMPLEX_CCW:
break;
default:
gf_vec_rev(n);
break;
}
MESH_SET_NORMAL(vx, n);
if (smooth_normals) {
faces_info[begin_face].nor = n;
assert(gf_vec_len(n));
}
cur_pts_in_cross = 0;
cur = 0;
for (i=0; i<path->n_contours; i++) {
Bool subpath_closed = 0;
nb_pts = 1 + path->contours[i] - cur;
if ((path->points[cur].x==path->points[path->contours[i]].x) && (path->points[cur].y==path->points[path->contours[i]].y))
subpath_closed = 1;
for (j=0; j<nb_pts; j++) {
u32 pidx = j + (pts_per_cross-1-cur_pts_in_cross);
v1.x = path->points[j+cur].x;
v1.z = path->points[j+cur].y;
vx.texcoords.x = gf_divfix(v1.x - min_cx, width_cx);
vx.texcoords.y = gf_divfix(v1.z - min_cy, width_cy);
/*handle closed cross-section*/
if (subpath_closed && (j+1==nb_pts)) {
pidx = (pts_per_cross-1-cur_pts_in_cross);
v1.x = path->points[cur].x;
v1.z = path->points[cur].y;
}
v1.x = gf_mulfix(v1.x , scale.x);
v1.z = gf_mulfix(v1.z , scale.y);
v1.y = 0;
vx.pos.x = gf_mulfix(v1.x, SCPbegin.xaxis.x) + gf_mulfix(v1.y, SCPbegin.yaxis.x) + gf_mulfix(v1.z, SCPbegin.zaxis.x) + spine[0].x;
vx.pos.y = gf_mulfix(v1.x, SCPbegin.xaxis.y) + gf_mulfix(v1.y, SCPbegin.yaxis.y) + gf_mulfix(v1.z, SCPbegin.zaxis.y) + spine[0].y;
vx.pos.z = gf_mulfix(v1.x, SCPbegin.xaxis.z) + gf_mulfix(v1.y, SCPbegin.yaxis.z) + gf_mulfix(v1.z, SCPbegin.zaxis.z) + spine[0].z;
REGISTER_POINT_FACE(begin_face);
}
cur_pts_in_cross += nb_pts;
cur += nb_pts;
}
}
/*generate end cap*/
if (end_face) {
SFVec3f n;
scale.x = scale.y = FIX_ONE;
if (spine_scale && (nb_spine-1<spine_scale->count)) scale = spine_scale->vals[nb_spine-1];
/*get last SCP after rotation*/
SCPend = SCPs[nb_spine-1];
n = SCPend.yaxis;
gf_vec_norm(&n);
MESH_SET_NORMAL(vx, n);
convexity = gf_polygone2d_get_convexity(path->points, path->n_points);
switch (convexity) {
case GF_POLYGON_CONVEX_CCW:
case GF_POLYGON_COMPLEX_CCW:
gf_vec_rev(vx.normal);
gf_vec_rev(n);
break;
}
if (smooth_normals) {
faces_info[end_face].nor = n;
assert(gf_vec_len(n));
}
cur_pts_in_cross = 0;
cur = 0;
for (i=0; i<path->n_contours; i++) {
Bool subpath_closed = 0;
nb_pts = 1 + path->contours[i] - cur;
if ((path->points[cur].x==path->points[path->contours[i]].x) && (path->points[cur].y==path->points[path->contours[i]].y))
subpath_closed = 1;
for (j=0; j<nb_pts; j++) {
u32 pidx = j + cur_pts_in_cross + (nb_spine-1)*pts_per_cross;
v1.x = path->points[j+cur].x;
v1.z = path->points[j+cur].y;
vx.texcoords.x = gf_divfix(v1.x - min_cx, width_cx);
vx.texcoords.y = gf_divfix(v1.z - min_cy, width_cy);
/*handle closed cross-section*/
if (subpath_closed && (j+1==nb_pts)) {
pidx = cur_pts_in_cross + (nb_spine-1)*pts_per_cross;
v1.x = path->points[cur].x;
v1.z = path->points[cur].y;
}
v1.x = gf_mulfix(v1.x, scale.x);
v1.z = gf_mulfix(v1.z, scale.y);
v1.y = 0;
vx.pos.x = gf_mulfix(v1.x, SCPend.xaxis.x) + gf_mulfix(v1.y, SCPend.yaxis.x) + gf_mulfix(v1.z, SCPend.zaxis.x) + spine[nb_spine-1].x;
vx.pos.y = gf_mulfix(v1.x, SCPend.xaxis.y) + gf_mulfix(v1.y, SCPend.yaxis.y) + gf_mulfix(v1.z, SCPend.zaxis.y) + spine[nb_spine-1].y;
vx.pos.z = gf_mulfix(v1.x, SCPend.xaxis.z) + gf_mulfix(v1.y, SCPend.yaxis.z) + gf_mulfix(v1.z, SCPend.zaxis.z) + spine[nb_spine-1].z;
REGISTER_POINT_FACE(end_face);
}
cur_pts_in_cross += nb_pts;
cur += nb_pts;
}
}
if (smooth_normals) {
Fixed cosCrease;
/*we only support 0->PI, whatever exceeds is smoothest*/
if (creaseAngle>GF_PI) cosCrease = -FIX_ONE;
else cosCrease = gf_cos(creaseAngle);
for (i=0; i<face_count; i++) {
for (j=0; j<faces[i]->v_count; j++) {
SFVec3f n = smooth_face_normals(pts_info, pt_count, faces_info, face_count, j, i, cosCrease);
MESH_SET_NORMAL(faces[i]->vertices[j], n);
}
}
if (faces_info) {
for (i=0; i<face_count; i++) if (faces_info[i].idx) gf_free(faces_info[i].idx);
gf_free(faces_info);
}
if (pts_info) {
for (i=0; i<pt_count; i++) if (pts_info[i].faces) gf_free(pts_info[i].faces);
gf_free(pts_info);
}
mesh->flags |= MESH_IS_SMOOTHED;
}
mesh->mesh_type = MESH_TRIANGLES;
for (i=0; i<face_spines; i++) {
if (faces[i]->v_count) {
u32 init_idx;
GF_Mesh *face = faces[i];
init_idx = mesh->v_count;
/*quads only*/
mesh_set_vertex_vx(mesh, &face->vertices[0]);
mesh_set_vertex_vx(mesh, &face->vertices[1]);
mesh_set_vertex_vx(mesh, &face->vertices[2]);
mesh_set_vertex_vx(mesh, &face->vertices[3]);
mesh_set_triangle(mesh, init_idx + 0, init_idx + 1, init_idx + 3);
mesh_set_triangle(mesh, init_idx + 0, init_idx + 3, init_idx + 2);
}
mesh_free(faces[i]);
}
if (begin_face) {
if (path->n_contours>1) {
#ifdef GPAC_HAS_GLU
u32 *ptsPerFace = gf_malloc(sizeof(u32)*path->n_contours);
/*we reversed begin cap!!!*/
cur = 0;
for (i=0; i<path->n_contours; i++) {
nb_pts = 1+path->contours[i] - cur;
cur+=nb_pts;
ptsPerFace[i] = nb_pts;
}
TesselateFaceMeshComplex(mesh, faces[begin_face], path->n_contours, ptsPerFace);
gf_free(ptsPerFace);
#endif
} else {
TesselateFaceMesh(mesh, faces[begin_face]);
}
mesh_free(faces[begin_face]);
}
if (end_face) {
if (path->n_contours>1) {
#ifdef GPAC_HAS_GLU
u32 *ptsPerFace = gf_malloc(sizeof(u32)*path->n_contours);
cur = 0;
for (i=0; i<path->n_contours; i++) {
nb_pts = 1+path->contours[i] - cur;
cur+=nb_pts;
ptsPerFace[i] = nb_pts;
}
TesselateFaceMeshComplex(mesh, faces[end_face], path->n_contours, ptsPerFace);
gf_free(ptsPerFace);
#endif
} else {
TesselateFaceMesh(mesh, faces[end_face]);
}
mesh_free(faces[end_face]);
}
gf_free(faces);
gf_free(SCPs);
/*FIXME: this is correct except we need to handle path cw/ccw - until then no possibility
to get correct lighting*/
/*
if (path->subpathlen && path->subpath[0]->closed && ((begin_face && end_face) || spine_closed))
mesh->flags |= MESH_IS_SOLID;
else
mesh->flags &= ~MESH_IS_SOLID;
*/
}