From e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Apr 2019 06:17:24 +0200 Subject: ClangFormat: apply to source, most of intern Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat --- .../freestyle/intern/winged_edge/Curvature.cpp | 880 ++++---- .../freestyle/intern/winged_edge/Curvature.h | 134 +- .../blender/freestyle/intern/winged_edge/Nature.h | 34 +- .../blender/freestyle/intern/winged_edge/WEdge.cpp | 1010 +++++---- .../blender/freestyle/intern/winged_edge/WEdge.h | 2335 ++++++++++---------- .../freestyle/intern/winged_edge/WFillGrid.cpp | 54 +- .../freestyle/intern/winged_edge/WFillGrid.h | 91 +- .../freestyle/intern/winged_edge/WSFillGrid.cpp | 54 +- .../freestyle/intern/winged_edge/WSFillGrid.h | 90 +- .../freestyle/intern/winged_edge/WXEdge.cpp | 427 ++-- .../blender/freestyle/intern/winged_edge/WXEdge.h | 1399 ++++++------ .../freestyle/intern/winged_edge/WXEdgeBuilder.cpp | 38 +- .../freestyle/intern/winged_edge/WXEdgeBuilder.h | 26 +- .../intern/winged_edge/WingedEdgeBuilder.cpp | 668 +++--- .../intern/winged_edge/WingedEdgeBuilder.h | 235 +- 15 files changed, 3799 insertions(+), 3676 deletions(-) (limited to 'source/blender/freestyle/intern/winged_edge') diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.cpp b/source/blender/freestyle/intern/winged_edge/Curvature.cpp index 28b38ae4854..b42c3f9b0e6 100644 --- a/source/blender/freestyle/intern/winged_edge/Curvature.cpp +++ b/source/blender/freestyle/intern/winged_edge/Curvature.cpp @@ -34,7 +34,7 @@ */ #include -#include // for malloc and free +#include // for malloc and free #include #include @@ -49,56 +49,56 @@ namespace Freestyle { static bool angle_obtuse(WVertex *v, WFace *f) { - WOEdge *e; - f->getOppositeEdge(v, e); + WOEdge *e; + f->getOppositeEdge(v, e); - Vec3r vec1(e->GetaVertex()->GetVertex() - v->GetVertex()); - Vec3r vec2(e->GetbVertex()->GetVertex() - v->GetVertex()); - return ((vec1 * vec2) < 0); + Vec3r vec1(e->GetaVertex()->GetVertex() - v->GetVertex()); + Vec3r vec2(e->GetbVertex()->GetVertex() - v->GetVertex()); + return ((vec1 * vec2) < 0); } // FIXME // WVvertex is useless but kept for history reasons static bool triangle_obtuse(WVertex *, WFace *f) { - bool b = false; - for (int i = 0; i < 3; i++) - b = b || ((f->getEdgeList()[i]->GetVec() * f->getEdgeList()[(i + 1) % 3]->GetVec()) < 0); - return b; + bool b = false; + for (int i = 0; i < 3; i++) + b = b || ((f->getEdgeList()[i]->GetVec() * f->getEdgeList()[(i + 1) % 3]->GetVec()) < 0); + return b; } static real cotan(WVertex *vo, WVertex *v1, WVertex *v2) { - /* cf. Appendix B of [Meyer et al 2002] */ - real udotv, denom; + /* cf. Appendix B of [Meyer et al 2002] */ + real udotv, denom; - Vec3r u(v1->GetVertex() - vo->GetVertex()); - Vec3r v(v2->GetVertex() - vo->GetVertex()); + Vec3r u(v1->GetVertex() - vo->GetVertex()); + Vec3r v(v2->GetVertex() - vo->GetVertex()); - udotv = u * v; - denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv); + udotv = u * v; + denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv); - /* denom can be zero if u==v. Returning 0 is acceptable, based on the callers of this function below. */ - if (denom == 0.0) - return 0.0; - return (udotv / denom); + /* denom can be zero if u==v. Returning 0 is acceptable, based on the callers of this function below. */ + if (denom == 0.0) + return 0.0; + return (udotv / denom); } static real angle_from_cotan(WVertex *vo, WVertex *v1, WVertex *v2) { - /* cf. Appendix B and the caption of Table 1 from [Meyer et al 2002] */ - real udotv, denom; + /* cf. Appendix B and the caption of Table 1 from [Meyer et al 2002] */ + real udotv, denom; - Vec3r u (v1->GetVertex() - vo->GetVertex()); - Vec3r v(v2->GetVertex() - vo->GetVertex()); + Vec3r u(v1->GetVertex() - vo->GetVertex()); + Vec3r v(v2->GetVertex() - vo->GetVertex()); - udotv = u * v; - denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv); + udotv = u * v; + denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv); - /* Note: I assume this is what they mean by using atan2(). -Ray Jones */ + /* Note: I assume this is what they mean by using atan2(). -Ray Jones */ - /* tan = denom/udotv = y/x (see man page for atan2) */ - return (fabs(atan2(denom, udotv))); + /* tan = denom/udotv = y/x (see man page for atan2) */ + return (fabs(atan2(denom, udotv))); } /*! gts_vertex_mean_curvature_normal: @@ -124,48 +124,48 @@ static real angle_from_cotan(WVertex *vo, WVertex *v1, WVertex *v2) */ bool gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &Kh) { - real area = 0.0; + real area = 0.0; - if (!v) - return false; + if (!v) + return false; - /* this operator is not defined for boundary edges */ - if (v->isBoundary()) - return false; + /* this operator is not defined for boundary edges */ + if (v->isBoundary()) + return false; - WVertex::incoming_edge_iterator itE; + WVertex::incoming_edge_iterator itE; - for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) - area += (*itE)->GetaFace()->getArea(); + for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) + area += (*itE)->GetaFace()->getArea(); - Kh = Vec3r(0.0, 0.0, 0.0); + Kh = Vec3r(0.0, 0.0, 0.0); - for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) { - WOEdge *e = (*itE)->getPrevOnFace(); + for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) { + WOEdge *e = (*itE)->getPrevOnFace(); #if 0 - if ((e->GetaVertex() == v) || (e->GetbVertex() == v)) - cerr<< "BUG "; + if ((e->GetaVertex() == v) || (e->GetbVertex() == v)) + cerr<< "BUG "; #endif - WVertex *v1 = e->GetaVertex(); - WVertex *v2 = e->GetbVertex(); - real temp; - - temp = cotan(v1, v, v2); - Kh = Vec3r(Kh + temp * (v2->GetVertex() - v->GetVertex())); - - temp = cotan(v2, v, v1); - Kh = Vec3r(Kh + temp * (v1->GetVertex() - v->GetVertex())); - } - if (area > 0.0) { - Kh[0] /= 2 * area; - Kh[1] /= 2 * area; - Kh[2] /= 2 * area; - } - else { - return false; - } - - return true; + WVertex *v1 = e->GetaVertex(); + WVertex *v2 = e->GetbVertex(); + real temp; + + temp = cotan(v1, v, v2); + Kh = Vec3r(Kh + temp * (v2->GetVertex() - v->GetVertex())); + + temp = cotan(v2, v, v1); + Kh = Vec3r(Kh + temp * (v1->GetVertex() - v->GetVertex())); + } + if (area > 0.0) { + Kh[0] /= 2 * area; + Kh[1] /= 2 * area; + Kh[2] /= 2 * area; + } + else { + return false; + } + + return true; } /*! gts_vertex_gaussian_curvature: @@ -186,35 +186,35 @@ bool gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &Kh) */ bool gts_vertex_gaussian_curvature(WVertex *v, real *Kg) { - real area = 0.0; - real angle_sum = 0.0; - - if (!v) - return false; - if (!Kg) - return false; - - /* this operator is not defined for boundary edges */ - if (v->isBoundary()) { - *Kg = 0.0; - return false; - } - - WVertex::incoming_edge_iterator itE; - for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) { - area += (*itE)->GetaFace()->getArea(); - } - - for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) { - WOEdge *e = (*itE)->getPrevOnFace(); - WVertex *v1 = e->GetaVertex(); - WVertex *v2 = e->GetbVertex(); - angle_sum += angle_from_cotan(v, v1, v2); - } - - *Kg = (2.0 * M_PI - angle_sum) / area; - - return true; + real area = 0.0; + real angle_sum = 0.0; + + if (!v) + return false; + if (!Kg) + return false; + + /* this operator is not defined for boundary edges */ + if (v->isBoundary()) { + *Kg = 0.0; + return false; + } + + WVertex::incoming_edge_iterator itE; + for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) { + area += (*itE)->GetaFace()->getArea(); + } + + for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) { + WOEdge *e = (*itE)->getPrevOnFace(); + WVertex *v1 = e->GetaVertex(); + WVertex *v2 = e->GetbVertex(); + angle_sum += angle_from_cotan(v, v1, v2); + } + + *Kg = (2.0 * M_PI - angle_sum) / area; + + return true; } /*! gts_vertex_principal_curvatures: @@ -230,41 +230,41 @@ bool gts_vertex_gaussian_curvature(WVertex *v, real *Kg) * * The Gaussian curvature can be computed with gts_vertex_gaussian_curvature(). */ -void gts_vertex_principal_curvatures (real Kh, real Kg, real *K1, real *K2) +void gts_vertex_principal_curvatures(real Kh, real Kg, real *K1, real *K2) { - real temp = Kh * Kh - Kg; + real temp = Kh * Kh - Kg; - if (!K1 || !K2) - return; + if (!K1 || !K2) + return; - if (temp < 0.0) - temp = 0.0; - temp = sqrt (temp); - *K1 = Kh + temp; - *K2 = Kh - temp; + if (temp < 0.0) + temp = 0.0; + temp = sqrt(temp); + *K1 = Kh + temp; + *K2 = Kh - temp; } /* from Maple */ static void linsolve(real m11, real m12, real b1, real m21, real m22, real b2, real *x1, real *x2) { - real temp; + real temp; - temp = 1.0 / (m21 * m12 - m11 * m22); - *x1 = (m12 * b2 - m22 * b1) * temp; - *x2 = (m11 * b2 - m21 * b1) * temp; + temp = 1.0 / (m21 * m12 - m11 * m22); + *x1 = (m12 * b2 - m22 * b1) * temp; + *x2 = (m11 * b2 - m21 * b1) * temp; } /* from Maple - largest eigenvector of [a b; b c] */ static void eigenvector(real a, real b, real c, Vec3r e) { - if (b == 0.0) { - e[0] = 0.0; - } - else { - e[0] = -(c - a - sqrt(c * c - 2 * a * c + a * a + 4 * b * b)) / (2 * b); - } - e[1] = 1.0; - e[2] = 0.0; + if (b == 0.0) { + e[0] = 0.0; + } + else { + e[0] = -(c - a - sqrt(c * c - 2 * a * c + a * a + 4 * b * b)) / (2 * b); + } + e[1] = 1.0; + e[2] = 0.0; } /*! gts_vertex_principal_directions: @@ -284,244 +284,249 @@ static void eigenvector(real a, real b, real c, Vec3r e) */ void gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, Vec3r &e2) { - Vec3r N; - real normKh; - - Vec3r basis1, basis2, d, eig; - real ve2, vdotN; - real aterm_da, bterm_da, cterm_da, const_da; - real aterm_db, bterm_db, cterm_db, const_db; - real a, b, c; - real K1, K2; - real *weights, *kappas, *d1s, *d2s; - int edge_count; - real err_e1, err_e2; - int e; - WVertex::incoming_edge_iterator itE; - - /* compute unit normal */ - normKh = Kh.norm(); - - if (normKh > 0.0) { - Kh.normalize(); - } - else { - /* This vertex is a point of zero mean curvature (flat or saddle point). Compute a normal by averaging - * the adjacent triangles - */ - N[0] = N[1] = N[2] = 0.0; - - for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) - N = Vec3r(N + (*itE)->GetaFace()->GetNormal()); - real normN = N.norm(); - if (normN <= 0.0) - return; - N.normalize(); - } - - /* construct a basis from N: */ - /* set basis1 to any component not the largest of N */ - basis1[0] = basis1[1] = basis1[2] = 0.0; - if (fabs (N[0]) > fabs (N[1])) - basis1[1] = 1.0; - else - basis1[0] = 1.0; - - /* make basis2 orthogonal to N */ - basis2 = (N ^ basis1); - basis2.normalize(); - - /* make basis1 orthogonal to N and basis2 */ - basis1 = (N ^ basis2); - basis1.normalize(); - - aterm_da = bterm_da = cterm_da = const_da = 0.0; - aterm_db = bterm_db = cterm_db = const_db = 0.0; - int nb_edges = v->GetEdges().size(); - - weights = (real *)malloc(sizeof(real) * nb_edges); - kappas = (real *)malloc(sizeof(real) * nb_edges); - d1s = (real *)malloc(sizeof(real) * nb_edges); - d2s = (real *)malloc(sizeof(real) * nb_edges); - edge_count = 0; - - for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) { - WOEdge *e; - WFace *f1, *f2; - real weight, kappa, d1, d2; - Vec3r vec_edge; - if (!*itE) - continue; - e = *itE; - - /* since this vertex passed the tests in gts_vertex_mean_curvature_normal(), this should be true. */ - //g_assert(gts_edge_face_number (e, s) == 2); - - /* identify the two triangles bordering e in s */ - f1 = e->GetaFace(); - f2 = e->GetbFace(); - - /* We are solving for the values of the curvature tensor - * B = [ a b ; b c ]. - * The computations here are from section 5 of [Meyer et al 2002]. - * - * The first step is to calculate the linear equations governing the values of (a,b,c). These can be computed - * by setting the derivatives of the error E to zero (section 5.3). - * - * Since a + c = norm(Kh), we only compute the linear equations for dE/da and dE/db. (NB: [Meyer et al 2002] - * has the equation a + b = norm(Kh), but I'm almost positive this is incorrect). - * - * Note that the w_ij (defined in section 5.2) are all scaled by (1/8*A_mixed). We drop this uniform scale - * factor because the solution of the linear equations doesn't rely on it. - * - * The terms of the linear equations are xterm_dy with x in {a,b,c} and y in {a,b}. There are also const_dy - * terms that are the constant factors in the equations. - */ - - /* find the vector from v along edge e */ - vec_edge = Vec3r(-1 * e->GetVec()); - - ve2 = vec_edge.squareNorm(); - vdotN = vec_edge * N; - - /* section 5.2 - There is a typo in the computation of kappa. The edges should be x_j-x_i. */ - kappa = 2.0 * vdotN / ve2; - - /* section 5.2 */ - - /* I don't like performing a minimization where some of the weights can be negative (as can be the case - * if f1 or f2 are obtuse). To ensure all-positive weights, we check for obtuseness. */ - weight = 0.0; - if (!triangle_obtuse(v, f1)) { - weight += ve2 * cotan(f1->GetNextOEdge(e->twin())->GetbVertex(), e->GetaVertex(), e->GetbVertex()) / 8.0; - } - else { - if (angle_obtuse(v, f1)) { - weight += ve2 * f1->getArea() / 4.0; - } - else { - weight += ve2 * f1->getArea() / 8.0; - } - } - - if (!triangle_obtuse(v, f2)) { - weight += ve2 * cotan (f2->GetNextOEdge(e)->GetbVertex(), e->GetaVertex(), e->GetbVertex()) / 8.0; - } - else { - if (angle_obtuse(v, f2)) { - weight += ve2 * f1->getArea() / 4.0; - } - else { - weight += ve2 * f1->getArea() / 8.0; - } - } - - /* projection of edge perpendicular to N (section 5.3) */ - d[0] = vec_edge[0] - vdotN * N[0]; - d[1] = vec_edge[1] - vdotN * N[1]; - d[2] = vec_edge[2] - vdotN * N[2]; - d.normalize(); - - /* not explicit in the paper, but necessary. Move d to 2D basis. */ - d1 = d * basis1; - d2 = d * basis2; - - /* store off the curvature, direction of edge, and weights for later use */ - weights[edge_count] = weight; - kappas[edge_count] = kappa; - d1s[edge_count] = d1; - d2s[edge_count] = d2; - edge_count++; - - /* Finally, update the linear equations */ - aterm_da += weight * d1 * d1 * d1 * d1; - bterm_da += weight * d1 * d1 * 2 * d1 * d2; - cterm_da += weight * d1 * d1 * d2 * d2; - const_da += weight * d1 * d1 * (-kappa); - - aterm_db += weight * d1 * d2 * d1 * d1; - bterm_db += weight * d1 * d2 * 2 * d1 * d2; - cterm_db += weight * d1 * d2 * d2 * d2; - const_db += weight * d1 * d2 * (-kappa); - } - - /* now use the identity (Section 5.3) a + c = |Kh| = 2 * kappa_h */ - aterm_da -= cterm_da; - const_da += cterm_da * normKh; - - aterm_db -= cterm_db; - const_db += cterm_db * normKh; - - /* check for solvability of the linear system */ - if (((aterm_da * bterm_db - aterm_db * bterm_da) != 0.0) && ((const_da != 0.0) || (const_db != 0.0))) { - linsolve(aterm_da, bterm_da, -const_da, aterm_db, bterm_db, -const_db, &a, &b); - - c = normKh - a; - - eigenvector(a, b, c, eig); - } - else { - /* region of v is planar */ - eig[0] = 1.0; - eig[1] = 0.0; - } - - /* Although the eigenvectors of B are good estimates of the principal directions, it seems that which one is - * attached to which curvature direction is a bit arbitrary. This may be a bug in my implementation, or just - * a side-effect of the inaccuracy of B due to the discrete nature of the sampling. - * - * To overcome this behavior, we'll evaluate which assignment best matches the given eigenvectors by comparing - * the curvature estimates computed above and the curvatures calculated from the discrete differential operators. - */ - - gts_vertex_principal_curvatures(0.5 * normKh, Kg, &K1, &K2); - - err_e1 = err_e2 = 0.0; - /* loop through the values previously saved */ - for (e = 0; e < edge_count; e++) { - real weight, kappa, d1, d2; - real temp1, temp2; - real delta; - - weight = weights[e]; - kappa = kappas[e]; - d1 = d1s[e]; - d2 = d2s[e]; - - temp1 = fabs (eig[0] * d1 + eig[1] * d2); - temp1 = temp1 * temp1; - temp2 = fabs (eig[1] * d1 - eig[0] * d2); - temp2 = temp2 * temp2; - - /* err_e1 is for K1 associated with e1 */ - delta = K1 * temp1 + K2 * temp2 - kappa; - err_e1 += weight * delta * delta; - - /* err_e2 is for K1 associated with e2 */ - delta = K2 * temp1 + K1 * temp2 - kappa; - err_e2 += weight * delta * delta; - } - free (weights); - free (kappas); - free (d1s); - free (d2s); - - /* rotate eig by a right angle if that would decrease the error */ - if (err_e2 < err_e1) { - real temp = eig[0]; - - eig[0] = eig[1]; - eig[1] = -temp; - } - - e1[0] = eig[0] * basis1[0] + eig[1] * basis2[0]; - e1[1] = eig[0] * basis1[1] + eig[1] * basis2[1]; - e1[2] = eig[0] * basis1[2] + eig[1] * basis2[2]; - e1.normalize(); - - /* make N,e1,e2 a right handed coordinate sytem */ - e2 = N ^ e1; - e2.normalize(); + Vec3r N; + real normKh; + + Vec3r basis1, basis2, d, eig; + real ve2, vdotN; + real aterm_da, bterm_da, cterm_da, const_da; + real aterm_db, bterm_db, cterm_db, const_db; + real a, b, c; + real K1, K2; + real *weights, *kappas, *d1s, *d2s; + int edge_count; + real err_e1, err_e2; + int e; + WVertex::incoming_edge_iterator itE; + + /* compute unit normal */ + normKh = Kh.norm(); + + if (normKh > 0.0) { + Kh.normalize(); + } + else { + /* This vertex is a point of zero mean curvature (flat or saddle point). Compute a normal by averaging + * the adjacent triangles + */ + N[0] = N[1] = N[2] = 0.0; + + for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) + N = Vec3r(N + (*itE)->GetaFace()->GetNormal()); + real normN = N.norm(); + if (normN <= 0.0) + return; + N.normalize(); + } + + /* construct a basis from N: */ + /* set basis1 to any component not the largest of N */ + basis1[0] = basis1[1] = basis1[2] = 0.0; + if (fabs(N[0]) > fabs(N[1])) + basis1[1] = 1.0; + else + basis1[0] = 1.0; + + /* make basis2 orthogonal to N */ + basis2 = (N ^ basis1); + basis2.normalize(); + + /* make basis1 orthogonal to N and basis2 */ + basis1 = (N ^ basis2); + basis1.normalize(); + + aterm_da = bterm_da = cterm_da = const_da = 0.0; + aterm_db = bterm_db = cterm_db = const_db = 0.0; + int nb_edges = v->GetEdges().size(); + + weights = (real *)malloc(sizeof(real) * nb_edges); + kappas = (real *)malloc(sizeof(real) * nb_edges); + d1s = (real *)malloc(sizeof(real) * nb_edges); + d2s = (real *)malloc(sizeof(real) * nb_edges); + edge_count = 0; + + for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) { + WOEdge *e; + WFace *f1, *f2; + real weight, kappa, d1, d2; + Vec3r vec_edge; + if (!*itE) + continue; + e = *itE; + + /* since this vertex passed the tests in gts_vertex_mean_curvature_normal(), this should be true. */ + //g_assert(gts_edge_face_number (e, s) == 2); + + /* identify the two triangles bordering e in s */ + f1 = e->GetaFace(); + f2 = e->GetbFace(); + + /* We are solving for the values of the curvature tensor + * B = [ a b ; b c ]. + * The computations here are from section 5 of [Meyer et al 2002]. + * + * The first step is to calculate the linear equations governing the values of (a,b,c). These can be computed + * by setting the derivatives of the error E to zero (section 5.3). + * + * Since a + c = norm(Kh), we only compute the linear equations for dE/da and dE/db. (NB: [Meyer et al 2002] + * has the equation a + b = norm(Kh), but I'm almost positive this is incorrect). + * + * Note that the w_ij (defined in section 5.2) are all scaled by (1/8*A_mixed). We drop this uniform scale + * factor because the solution of the linear equations doesn't rely on it. + * + * The terms of the linear equations are xterm_dy with x in {a,b,c} and y in {a,b}. There are also const_dy + * terms that are the constant factors in the equations. + */ + + /* find the vector from v along edge e */ + vec_edge = Vec3r(-1 * e->GetVec()); + + ve2 = vec_edge.squareNorm(); + vdotN = vec_edge * N; + + /* section 5.2 - There is a typo in the computation of kappa. The edges should be x_j-x_i. */ + kappa = 2.0 * vdotN / ve2; + + /* section 5.2 */ + + /* I don't like performing a minimization where some of the weights can be negative (as can be the case + * if f1 or f2 are obtuse). To ensure all-positive weights, we check for obtuseness. */ + weight = 0.0; + if (!triangle_obtuse(v, f1)) { + weight += ve2 * + cotan( + f1->GetNextOEdge(e->twin())->GetbVertex(), e->GetaVertex(), e->GetbVertex()) / + 8.0; + } + else { + if (angle_obtuse(v, f1)) { + weight += ve2 * f1->getArea() / 4.0; + } + else { + weight += ve2 * f1->getArea() / 8.0; + } + } + + if (!triangle_obtuse(v, f2)) { + weight += ve2 * cotan(f2->GetNextOEdge(e)->GetbVertex(), e->GetaVertex(), e->GetbVertex()) / + 8.0; + } + else { + if (angle_obtuse(v, f2)) { + weight += ve2 * f1->getArea() / 4.0; + } + else { + weight += ve2 * f1->getArea() / 8.0; + } + } + + /* projection of edge perpendicular to N (section 5.3) */ + d[0] = vec_edge[0] - vdotN * N[0]; + d[1] = vec_edge[1] - vdotN * N[1]; + d[2] = vec_edge[2] - vdotN * N[2]; + d.normalize(); + + /* not explicit in the paper, but necessary. Move d to 2D basis. */ + d1 = d * basis1; + d2 = d * basis2; + + /* store off the curvature, direction of edge, and weights for later use */ + weights[edge_count] = weight; + kappas[edge_count] = kappa; + d1s[edge_count] = d1; + d2s[edge_count] = d2; + edge_count++; + + /* Finally, update the linear equations */ + aterm_da += weight * d1 * d1 * d1 * d1; + bterm_da += weight * d1 * d1 * 2 * d1 * d2; + cterm_da += weight * d1 * d1 * d2 * d2; + const_da += weight * d1 * d1 * (-kappa); + + aterm_db += weight * d1 * d2 * d1 * d1; + bterm_db += weight * d1 * d2 * 2 * d1 * d2; + cterm_db += weight * d1 * d2 * d2 * d2; + const_db += weight * d1 * d2 * (-kappa); + } + + /* now use the identity (Section 5.3) a + c = |Kh| = 2 * kappa_h */ + aterm_da -= cterm_da; + const_da += cterm_da * normKh; + + aterm_db -= cterm_db; + const_db += cterm_db * normKh; + + /* check for solvability of the linear system */ + if (((aterm_da * bterm_db - aterm_db * bterm_da) != 0.0) && + ((const_da != 0.0) || (const_db != 0.0))) { + linsolve(aterm_da, bterm_da, -const_da, aterm_db, bterm_db, -const_db, &a, &b); + + c = normKh - a; + + eigenvector(a, b, c, eig); + } + else { + /* region of v is planar */ + eig[0] = 1.0; + eig[1] = 0.0; + } + + /* Although the eigenvectors of B are good estimates of the principal directions, it seems that which one is + * attached to which curvature direction is a bit arbitrary. This may be a bug in my implementation, or just + * a side-effect of the inaccuracy of B due to the discrete nature of the sampling. + * + * To overcome this behavior, we'll evaluate which assignment best matches the given eigenvectors by comparing + * the curvature estimates computed above and the curvatures calculated from the discrete differential operators. + */ + + gts_vertex_principal_curvatures(0.5 * normKh, Kg, &K1, &K2); + + err_e1 = err_e2 = 0.0; + /* loop through the values previously saved */ + for (e = 0; e < edge_count; e++) { + real weight, kappa, d1, d2; + real temp1, temp2; + real delta; + + weight = weights[e]; + kappa = kappas[e]; + d1 = d1s[e]; + d2 = d2s[e]; + + temp1 = fabs(eig[0] * d1 + eig[1] * d2); + temp1 = temp1 * temp1; + temp2 = fabs(eig[1] * d1 - eig[0] * d2); + temp2 = temp2 * temp2; + + /* err_e1 is for K1 associated with e1 */ + delta = K1 * temp1 + K2 * temp2 - kappa; + err_e1 += weight * delta * delta; + + /* err_e2 is for K1 associated with e2 */ + delta = K2 * temp1 + K1 * temp2 - kappa; + err_e2 += weight * delta * delta; + } + free(weights); + free(kappas); + free(d1s); + free(d2s); + + /* rotate eig by a right angle if that would decrease the error */ + if (err_e2 < err_e1) { + real temp = eig[0]; + + eig[0] = eig[1]; + eig[1] = -temp; + } + + e1[0] = eig[0] * basis1[0] + eig[1] * basis2[0]; + e1[1] = eig[0] * basis1[1] + eig[1] * basis2[1]; + e1[2] = eig[0] * basis1[2] + eig[1] * basis2[2]; + e1.normalize(); + + /* make N,e1,e2 a right handed coordinate sytem */ + e2 = N ^ e1; + e2.normalize(); } namespace OGF { @@ -529,107 +534,108 @@ namespace OGF { #if 0 inline static real angle(WOEdge *h) { - const Vec3r& n1 = h->GetbFace()->GetNormal(); - const Vec3r& n2 = h->GetaFace()->GetNormal(); - const Vec3r v = h->GetVec(); - real sine = (n1 ^ n2) * v / v.norm(); - if (sine >= 1.0) { - return M_PI / 2.0; - } - if (sine <= -1.0) { - return -M_PI / 2.0; - } - return ::asin(sine); + const Vec3r& n1 = h->GetbFace()->GetNormal(); + const Vec3r& n2 = h->GetaFace()->GetNormal(); + const Vec3r v = h->GetVec(); + real sine = (n1 ^ n2) * v / v.norm(); + if (sine >= 1.0) { + return M_PI / 2.0; + } + if (sine <= -1.0) { + return -M_PI / 2.0; + } + return ::asin(sine); } #endif // precondition1: P is inside the sphere // precondition2: P,V points to the outside of the sphere (i.e. OP.V > 0) -static bool sphere_clip_vector(const Vec3r& O, real r, const Vec3r& P, Vec3r& V) +static bool sphere_clip_vector(const Vec3r &O, real r, const Vec3r &P, Vec3r &V) { - Vec3r W = P - O; - real a = V.squareNorm(); - real b = 2.0 * V * W; - real c = W.squareNorm() - r * r; - real delta = b * b - 4 * a * c; - if (delta < 0) { - // Should not happen, but happens sometimes (numerical precision) - return true; - } - real t = - b + ::sqrt(delta) / (2.0 * a); - if (t < 0.0) { - // Should not happen, but happens sometimes (numerical precision) - return true; - } - if (t >= 1.0) { - // Inside the sphere - return false; - } - - V[0] = (t * V.x()); - V[1] = (t * V.y()); - V[2] = (t * V.z()); - - return true; + Vec3r W = P - O; + real a = V.squareNorm(); + real b = 2.0 * V * W; + real c = W.squareNorm() - r * r; + real delta = b * b - 4 * a * c; + if (delta < 0) { + // Should not happen, but happens sometimes (numerical precision) + return true; + } + real t = -b + ::sqrt(delta) / (2.0 * a); + if (t < 0.0) { + // Should not happen, but happens sometimes (numerical precision) + return true; + } + if (t >= 1.0) { + // Inside the sphere + return false; + } + + V[0] = (t * V.x()); + V[1] = (t * V.y()); + V[2] = (t * V.z()); + + return true; } // TODO: check optimizations: // use marking ? (measure *timings* ...) -void compute_curvature_tensor(WVertex *start, real radius, NormalCycle& nc) +void compute_curvature_tensor(WVertex *start, real radius, NormalCycle &nc) { - // in case we have a non-manifold vertex, skip it... - if (start->isBoundary()) - return; - - std::set vertices; - const Vec3r& O = start->GetVertex(); - std::stack S; - S.push(start); - vertices.insert(start); - while (!S.empty()) { - WVertex *v = S.top(); - S.pop(); - if (v->isBoundary()) - continue; - const Vec3r& P = v->GetVertex(); - WVertex::incoming_edge_iterator woeit = v->incoming_edges_begin(); - WVertex::incoming_edge_iterator woeitend = v->incoming_edges_end(); - for (; woeit != woeitend; ++woeit) { - WOEdge *h = *woeit; - if ((v == start) || h->GetVec() * (O - P) > 0.0) { - Vec3r V(-1 * h->GetVec()); - bool isect = sphere_clip_vector(O, radius, P, V); - assert (h->GetOwner()->GetNumberOfOEdges() == 2); // Because otherwise v->isBoundary() would be true - nc.accumulate_dihedral_angle(V, h->GetAngle()); - - if (!isect) { - WVertex *w = h->GetaVertex(); - if (vertices.find(w) == vertices.end()) { - vertices.insert(w); - S.push(w); - } - } - } - } - } + // in case we have a non-manifold vertex, skip it... + if (start->isBoundary()) + return; + + std::set vertices; + const Vec3r &O = start->GetVertex(); + std::stack S; + S.push(start); + vertices.insert(start); + while (!S.empty()) { + WVertex *v = S.top(); + S.pop(); + if (v->isBoundary()) + continue; + const Vec3r &P = v->GetVertex(); + WVertex::incoming_edge_iterator woeit = v->incoming_edges_begin(); + WVertex::incoming_edge_iterator woeitend = v->incoming_edges_end(); + for (; woeit != woeitend; ++woeit) { + WOEdge *h = *woeit; + if ((v == start) || h->GetVec() * (O - P) > 0.0) { + Vec3r V(-1 * h->GetVec()); + bool isect = sphere_clip_vector(O, radius, P, V); + assert(h->GetOwner()->GetNumberOfOEdges() == + 2); // Because otherwise v->isBoundary() would be true + nc.accumulate_dihedral_angle(V, h->GetAngle()); + + if (!isect) { + WVertex *w = h->GetaVertex(); + if (vertices.find(w) == vertices.end()) { + vertices.insert(w); + S.push(w); + } + } + } + } + } } -void compute_curvature_tensor_one_ring(WVertex *start, NormalCycle& nc) +void compute_curvature_tensor_one_ring(WVertex *start, NormalCycle &nc) { - // in case we have a non-manifold vertex, skip it... - if (start->isBoundary()) - return; - - WVertex::incoming_edge_iterator woeit = start->incoming_edges_begin(); - WVertex::incoming_edge_iterator woeitend = start->incoming_edges_end(); - for (; woeit != woeitend; ++woeit) { - WOEdge *h = (*woeit)->twin(); - nc.accumulate_dihedral_angle(h->GetVec(), h->GetAngle()); - WOEdge *hprev = h->getPrevOnFace(); - nc.accumulate_dihedral_angle(hprev->GetVec(), hprev->GetAngle()); - } + // in case we have a non-manifold vertex, skip it... + if (start->isBoundary()) + return; + + WVertex::incoming_edge_iterator woeit = start->incoming_edges_begin(); + WVertex::incoming_edge_iterator woeitend = start->incoming_edges_end(); + for (; woeit != woeitend; ++woeit) { + WOEdge *h = (*woeit)->twin(); + nc.accumulate_dihedral_angle(h->GetVec(), h->GetAngle()); + WOEdge *hprev = h->getPrevOnFace(); + nc.accumulate_dihedral_angle(hprev->GetVec(), hprev->GetAngle()); + } } -} // OGF namespace +} // namespace OGF } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.h b/source/blender/freestyle/intern/winged_edge/Curvature.h index b8f1a7b3094..32e9ea8b5cf 100644 --- a/source/blender/freestyle/intern/winged_edge/Curvature.h +++ b/source/blender/freestyle/intern/winged_edge/Curvature.h @@ -42,7 +42,7 @@ #include "../system/Precision.h" #ifdef WITH_CXX_GUARDEDALLOC -#include "MEM_guardedalloc.h" +# include "MEM_guardedalloc.h" #endif namespace Freestyle { @@ -51,75 +51,75 @@ using namespace Geometry; class WVertex; -class CurvatureInfo -{ -public: - CurvatureInfo() - { - K1 = 0.0; - K2 = 0.0; - e1 = Vec3r(0.0, 0.0, 0.0); - e2 = Vec3r(0.0, 0.0, 0.0); - Kr = 0.0; - dKr = 0.0; - er = Vec3r(0.0, 0.0, 0.0); - } - - CurvatureInfo(const CurvatureInfo& iBrother) - { - K1 = iBrother.K1; - K2 = iBrother.K2; - e1 = iBrother.e1; - e2 = iBrother.e2; - Kr = iBrother.Kr; - dKr = iBrother.dKr; - er = iBrother.er; - } - - CurvatureInfo(const CurvatureInfo& ca, const CurvatureInfo& cb, real t) - { - K1 = ca.K1 + t * (cb.K1 - ca.K1); - K2 = ca.K2 + t * (cb.K2 - ca.K2); - e1 = ca.e1 + t * (cb.e1 - ca.e1); - e2 = ca.e2 + t * (cb.e2 - ca.e2); - Kr = ca.Kr + t * (cb.Kr - ca.Kr); - dKr = ca.dKr + t * (cb.dKr - ca.dKr); - er = ca.er + t * (cb.er - ca.er); - } - - real K1; // maximum curvature - real K2; // minimum curvature - Vec3r e1; // maximum curvature direction - Vec3r e2; // minimum curvature direction - real Kr; // radial curvature - real dKr; // radial curvature - Vec3r er; // radial curvature direction +class CurvatureInfo { + public: + CurvatureInfo() + { + K1 = 0.0; + K2 = 0.0; + e1 = Vec3r(0.0, 0.0, 0.0); + e2 = Vec3r(0.0, 0.0, 0.0); + Kr = 0.0; + dKr = 0.0; + er = Vec3r(0.0, 0.0, 0.0); + } + + CurvatureInfo(const CurvatureInfo &iBrother) + { + K1 = iBrother.K1; + K2 = iBrother.K2; + e1 = iBrother.e1; + e2 = iBrother.e2; + Kr = iBrother.Kr; + dKr = iBrother.dKr; + er = iBrother.er; + } + + CurvatureInfo(const CurvatureInfo &ca, const CurvatureInfo &cb, real t) + { + K1 = ca.K1 + t * (cb.K1 - ca.K1); + K2 = ca.K2 + t * (cb.K2 - ca.K2); + e1 = ca.e1 + t * (cb.e1 - ca.e1); + e2 = ca.e2 + t * (cb.e2 - ca.e2); + Kr = ca.Kr + t * (cb.Kr - ca.Kr); + dKr = ca.dKr + t * (cb.dKr - ca.dKr); + er = ca.er + t * (cb.er - ca.er); + } + + real K1; // maximum curvature + real K2; // minimum curvature + Vec3r e1; // maximum curvature direction + Vec3r e2; // minimum curvature direction + real Kr; // radial curvature + real dKr; // radial curvature + Vec3r er; // radial curvature direction #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:CurvatureInfo") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:CurvatureInfo") #endif }; -class Face_Curvature_Info -{ -public: - Face_Curvature_Info() {} - - ~Face_Curvature_Info() - { - for (vector::iterator ci = vec_curvature_info.begin(), ciend = vec_curvature_info.end(); - ci != ciend; - ++ci) - { - delete (*ci); - } - vec_curvature_info.clear(); - } - - vector vec_curvature_info; +class Face_Curvature_Info { + public: + Face_Curvature_Info() + { + } + + ~Face_Curvature_Info() + { + for (vector::iterator ci = vec_curvature_info.begin(), + ciend = vec_curvature_info.end(); + ci != ciend; + ++ci) { + delete (*ci); + } + vec_curvature_info.clear(); + } + + vector vec_curvature_info; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Face_Curvature_Info") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Face_Curvature_Info") #endif }; @@ -133,13 +133,13 @@ void gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, V namespace OGF { -class NormalCycle ; +class NormalCycle; -void compute_curvature_tensor( WVertex *start, double radius, NormalCycle& nc); +void compute_curvature_tensor(WVertex *start, double radius, NormalCycle &nc); -void compute_curvature_tensor_one_ring(WVertex *start, NormalCycle& nc); +void compute_curvature_tensor_one_ring(WVertex *start, NormalCycle &nc); -} // OGF namespace +} // namespace OGF } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/winged_edge/Nature.h b/source/blender/freestyle/intern/winged_edge/Nature.h index 71b306ed2d5..91f9f63b412 100644 --- a/source/blender/freestyle/intern/winged_edge/Nature.h +++ b/source/blender/freestyle/intern/winged_edge/Nature.h @@ -32,40 +32,40 @@ namespace Nature { typedef unsigned short VertexNature; /*! true for any 0D element */ -static const VertexNature POINT = 0; // 0 +static const VertexNature POINT = 0; // 0 /*! true for SVertex */ -static const VertexNature S_VERTEX = (1 << 0); // 1 +static const VertexNature S_VERTEX = (1 << 0); // 1 /*! true for ViewVertex */ -static const VertexNature VIEW_VERTEX = (1 << 1); // 2 +static const VertexNature VIEW_VERTEX = (1 << 1); // 2 /*! true for NonTVertex */ -static const VertexNature NON_T_VERTEX = (1 << 2); // 4 +static const VertexNature NON_T_VERTEX = (1 << 2); // 4 /*! true for TVertex */ -static const VertexNature T_VERTEX = (1 << 3); // 8 +static const VertexNature T_VERTEX = (1 << 3); // 8 /*! true for CUSP */ -static const VertexNature CUSP = (1 << 4); // 16 +static const VertexNature CUSP = (1 << 4); // 16 typedef unsigned short EdgeNature; /*! true for non feature edges (always false for 1D elements of the ViewMap) */ -static const EdgeNature NO_FEATURE = 0; // 0 +static const EdgeNature NO_FEATURE = 0; // 0 /*! true for silhouettes */ -static const EdgeNature SILHOUETTE = (1 << 0); // 1 +static const EdgeNature SILHOUETTE = (1 << 0); // 1 /*! true for borders */ -static const EdgeNature BORDER = (1 << 1); // 2 +static const EdgeNature BORDER = (1 << 1); // 2 /*! true for creases */ -static const EdgeNature CREASE = (1 << 2); // 4 +static const EdgeNature CREASE = (1 << 2); // 4 /*! true for ridges */ -static const EdgeNature RIDGE = (1 << 3); // 8 +static const EdgeNature RIDGE = (1 << 3); // 8 /*! true for valleys */ -static const EdgeNature VALLEY = (1 << 4); // 16 +static const EdgeNature VALLEY = (1 << 4); // 16 /*! true for suggestive contours */ -static const EdgeNature SUGGESTIVE_CONTOUR = (1 << 5); // 32 +static const EdgeNature SUGGESTIVE_CONTOUR = (1 << 5); // 32 /*! true for material boundaries */ -static const EdgeNature MATERIAL_BOUNDARY = (1 << 6); // 64 +static const EdgeNature MATERIAL_BOUNDARY = (1 << 6); // 64 /*! true for user-defined edge marks */ -static const EdgeNature EDGE_MARK = (1 << 7); // 128 +static const EdgeNature EDGE_MARK = (1 << 7); // 128 -} // end of namespace Nature +} // end of namespace Nature } /* namespace Freestyle */ -#endif // __FREESTYLE_NATURE_H__ +#endif // __FREESTYLE_NATURE_H__ diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.cpp b/source/blender/freestyle/intern/winged_edge/WEdge.cpp index 12a73491989..629e8ffe901 100644 --- a/source/blender/freestyle/intern/winged_edge/WEdge.cpp +++ b/source/blender/freestyle/intern/winged_edge/WEdge.cpp @@ -26,31 +26,26 @@ namespace Freestyle { /*! Temporary structures */ -class vertexdata -{ -public: - WVertex *_copy; +class vertexdata { + public: + WVertex *_copy; }; -class oedgedata -{ -public: - WOEdge *_copy; +class oedgedata { + public: + WOEdge *_copy; }; -class edgedata -{ -public: - WEdge *_copy; +class edgedata { + public: + WEdge *_copy; }; -class facedata -{ -public: - WFace *_copy; +class facedata { + public: + WFace *_copy; }; - /********************************** * * * * @@ -59,120 +54,120 @@ public: * * **********************************/ -WVertex::WVertex(WVertex& iBrother) +WVertex::WVertex(WVertex &iBrother) { - _Id = iBrother._Id; - _Vertex = iBrother._Vertex; - _EdgeList = iBrother._EdgeList; - - _Shape = iBrother._Shape; - _Smooth = iBrother._Smooth; - _Border = iBrother._Border; - userdata = NULL; - iBrother.userdata = new vertexdata; - ((vertexdata *)(iBrother.userdata))->_copy = this; + _Id = iBrother._Id; + _Vertex = iBrother._Vertex; + _EdgeList = iBrother._EdgeList; + + _Shape = iBrother._Shape; + _Smooth = iBrother._Smooth; + _Border = iBrother._Border; + userdata = NULL; + iBrother.userdata = new vertexdata; + ((vertexdata *)(iBrother.userdata))->_copy = this; } WVertex *WVertex::duplicate() { - WVertex *clone = new WVertex(*this); - return clone; + WVertex *clone = new WVertex(*this); + return clone; } WOEdge *WVertex::incoming_edge_iterator::operator*() { - return _current; + return _current; } void WVertex::incoming_edge_iterator::increment() { - WOEdge *twin = _current->twin(); - if (!twin) { - // we reached a hole - _current = 0; - return; - } - WOEdge *next = twin->getPrevOnFace(); - if (next == _begin) { - next = NULL; - } - _current = next; + WOEdge *twin = _current->twin(); + if (!twin) { + // we reached a hole + _current = 0; + return; + } + WOEdge *next = twin->getPrevOnFace(); + if (next == _begin) { + next = NULL; + } + _current = next; } WFace *WVertex::face_iterator::operator*() { - WOEdge *woedge = *_edge_it; - if (!woedge) - return NULL; - return (woedge)->GetbFace(); + WOEdge *woedge = *_edge_it; + if (!woedge) + return NULL; + return (woedge)->GetbFace(); } #if 0 bool WVertex::isBoundary () const { - return _Border; + return _Border; } #endif -bool WVertex::isBoundary () -{ - if (_Border == 1) - return true; - else if (_Border == 0) - return false; - - vector::const_iterator it; - for (it = _EdgeList.begin(); it != _EdgeList.end(); it++) { - if ((*it)->GetNumberOfOEdges() == 1) { - _Border = 1; - return true; - } - } +bool WVertex::isBoundary() +{ + if (_Border == 1) + return true; + else if (_Border == 0) + return false; + + vector::const_iterator it; + for (it = _EdgeList.begin(); it != _EdgeList.end(); it++) { + if ((*it)->GetNumberOfOEdges() == 1) { + _Border = 1; + return true; + } + } #if 0 - if (!(*it)->GetaOEdge()->GetaFace()) - return true; + if (!(*it)->GetaOEdge()->GetaFace()) + return true; #endif - _Border = 0; - return false; + _Border = 0; + return false; } void WVertex::AddEdge(WEdge *iEdge) { - _EdgeList.push_back(iEdge); + _EdgeList.push_back(iEdge); } WVertex::incoming_edge_iterator WVertex::incoming_edges_begin() { - WOEdge *begin; - WEdge *wedge = _EdgeList.front(); - WOEdge *aOEdge = wedge->GetaOEdge(); - if (aOEdge->GetbVertex() == this) - begin = aOEdge; - else - begin = _EdgeList.front()->GetbOEdge(); - return incoming_edge_iterator(this, begin, begin); + WOEdge *begin; + WEdge *wedge = _EdgeList.front(); + WOEdge *aOEdge = wedge->GetaOEdge(); + if (aOEdge->GetbVertex() == this) + begin = aOEdge; + else + begin = _EdgeList.front()->GetbOEdge(); + return incoming_edge_iterator(this, begin, begin); } WVertex::incoming_edge_iterator WVertex::incoming_edges_end() { - WOEdge *begin; - WOEdge *aOEdge = _EdgeList.front()->GetaOEdge(); - if (aOEdge->GetbVertex() == this) - begin = aOEdge; - else - begin = _EdgeList.front()->GetbOEdge(); - return incoming_edge_iterator(this, begin, 0); + WOEdge *begin; + WOEdge *aOEdge = _EdgeList.front()->GetaOEdge(); + if (aOEdge->GetbVertex() == this) + begin = aOEdge; + else + begin = _EdgeList.front()->GetbOEdge(); + return incoming_edge_iterator(this, begin, 0); } #if 0 WOEdge **WVertex::incoming_edge_iterator::operator->() { - WOEdge **ppaOEdge = (*_iter)->GetaOEdge(); - if (aOEdge->GetbVertex() == _vertex) { - return ppaOEdge; - } - else { - WOEdge *bOEdge = (*_iter)->GetbOEdge(); - return &bOEdge; - } + WOEdge **ppaOEdge = (*_iter)->GetaOEdge(); + if (aOEdge->GetbVertex() == _vertex) { + return ppaOEdge; + } + else { + WOEdge *bOEdge = (*_iter)->GetbOEdge(); + return &bOEdge; + } } #endif @@ -184,35 +179,35 @@ WOEdge **WVertex::incoming_edge_iterator::operator->() * * **********************************/ -WOEdge::WOEdge(WOEdge& iBrother) +WOEdge::WOEdge(WOEdge &iBrother) { - _paVertex = iBrother.GetaVertex(); - _pbVertex = iBrother.GetbVertex(); - _paFace = iBrother.GetaFace(); - _pbFace = iBrother.GetbFace(); - _pOwner = iBrother.GetOwner(); - userdata = NULL; - iBrother.userdata = new oedgedata; - ((oedgedata *)(iBrother.userdata))->_copy = this; - - _vec = iBrother._vec; - _angle = iBrother._angle; + _paVertex = iBrother.GetaVertex(); + _pbVertex = iBrother.GetbVertex(); + _paFace = iBrother.GetaFace(); + _pbFace = iBrother.GetbFace(); + _pOwner = iBrother.GetOwner(); + userdata = NULL; + iBrother.userdata = new oedgedata; + ((oedgedata *)(iBrother.userdata))->_copy = this; + + _vec = iBrother._vec; + _angle = iBrother._angle; } WOEdge *WOEdge::duplicate() { - WOEdge *clone = new WOEdge(*this); - return clone; + WOEdge *clone = new WOEdge(*this); + return clone; } -WOEdge *WOEdge::twin () +WOEdge *WOEdge::twin() { - return GetOwner()->GetOtherOEdge(this); + return GetOwner()->GetOtherOEdge(this); } WOEdge *WOEdge::getPrevOnFace() { - return _pbFace->GetPrevOEdge(this); + return _pbFace->GetPrevOEdge(this); } /********************************** @@ -223,31 +218,31 @@ WOEdge *WOEdge::getPrevOnFace() * * **********************************/ -WEdge::WEdge(WEdge& iBrother) -{ - _paOEdge = NULL; - _pbOEdge = NULL; - WOEdge *aoedge = iBrother.GetaOEdge(); - WOEdge *boedge = iBrother.GetbOEdge(); - userdata = NULL; - - if (aoedge) - //_paOEdge = new WOEdge(*aoedge); - _paOEdge = aoedge->duplicate(); - if (boedge) - //_pbOEdge = new WOEdge(*boedge); - _pbOEdge = boedge->duplicate(); - - _nOEdges = iBrother.GetNumberOfOEdges(); - _Id = iBrother.GetId(); - iBrother.userdata = new edgedata; - ((edgedata *)(iBrother.userdata))->_copy = this; +WEdge::WEdge(WEdge &iBrother) +{ + _paOEdge = NULL; + _pbOEdge = NULL; + WOEdge *aoedge = iBrother.GetaOEdge(); + WOEdge *boedge = iBrother.GetbOEdge(); + userdata = NULL; + + if (aoedge) + //_paOEdge = new WOEdge(*aoedge); + _paOEdge = aoedge->duplicate(); + if (boedge) + //_pbOEdge = new WOEdge(*boedge); + _pbOEdge = boedge->duplicate(); + + _nOEdges = iBrother.GetNumberOfOEdges(); + _Id = iBrother.GetId(); + iBrother.userdata = new edgedata; + ((edgedata *)(iBrother.userdata))->_copy = this; } WEdge *WEdge::duplicate() { - WEdge *clone = new WEdge(*this); - return clone; + WEdge *clone = new WEdge(*this); + return clone; } /********************************** @@ -258,193 +253,192 @@ WEdge *WEdge::duplicate() * * **********************************/ -WFace::WFace(WFace& iBrother) -{ - _OEdgeList = iBrother.getEdgeList(); - _Normal = iBrother.GetNormal(); - _VerticesNormals = iBrother._VerticesNormals; - _VerticesTexCoords = iBrother._VerticesTexCoords; - _Id = iBrother.GetId(); - _FrsMaterialIndex = iBrother._FrsMaterialIndex; - _Mark = iBrother._Mark; - userdata = NULL; - iBrother.userdata = new facedata; - ((facedata *)(iBrother.userdata))->_copy = this; +WFace::WFace(WFace &iBrother) +{ + _OEdgeList = iBrother.getEdgeList(); + _Normal = iBrother.GetNormal(); + _VerticesNormals = iBrother._VerticesNormals; + _VerticesTexCoords = iBrother._VerticesTexCoords; + _Id = iBrother.GetId(); + _FrsMaterialIndex = iBrother._FrsMaterialIndex; + _Mark = iBrother._Mark; + userdata = NULL; + iBrother.userdata = new facedata; + ((facedata *)(iBrother.userdata))->_copy = this; } WFace *WFace::duplicate() { - WFace *clone = new WFace(*this); - return clone; + WFace *clone = new WFace(*this); + return clone; } -const FrsMaterial& WFace::frs_material() +const FrsMaterial &WFace::frs_material() { - return getShape()->frs_material(_FrsMaterialIndex); + return getShape()->frs_material(_FrsMaterialIndex); } WOEdge *WFace::MakeEdge(WVertex *v1, WVertex *v2) { - // First check whether the same oriented edge already exists or not: - vector& v1Edges = v1->GetEdges(); - for (vector::iterator it1 = v1Edges.begin(), end = v1Edges.end(); it1 != end; it1++) { - WEdge *we = (*it1); - WOEdge *woea = we->GetaOEdge(); - - if ((woea->GetaVertex() == v1) && (woea->GetbVertex() == v2)) { - // The oriented edge already exists - cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl; - // Adds the edge to the face - AddEdge(woea); - (*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges() + 1); - //sets these vertices as border: - v1->setBorder(true); - v2->setBorder(true); - return woea; - } - - WOEdge *woeb = we->GetbOEdge(); - if (woeb && (woeb->GetaVertex() == v1) && (woeb->GetbVertex() == v2)) { - // The oriented edge already exists - cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl; - // Adds the edge to the face - AddEdge(woeb); - (*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges() + 1); - //sets these vertices as border: - v1->setBorder(true); - v2->setBorder(true); - return woeb; - } - } - - // the oriented edge we're about to build - WOEdge *pOEdge = new WOEdge; - // The edge containing the oriented edge. - WEdge *edge; - - // checks whether this edge already exists or not - // If it exists, it points outward v2 - bool exist = false; - WOEdge *pInvertEdge = NULL; // The inverted edge if it exists - vector& v2Edges = v2->GetEdges(); - vector::iterator it; - for (it = v2Edges.begin(); it != v2Edges.end(); it++) { - if ((*it)->GetbVertex() == v1) { - // The invert edge already exists - exist = true; - pInvertEdge = (*it)->GetaOEdge(); - break; - } - } - - //DEBUG: - if (true == exist) { // The invert edge already exists - // Retrieves the corresponding edge - edge = pInvertEdge->GetOwner(); - - // Sets the a Face (retrieved from pInvertEdge - pOEdge->setaFace(pInvertEdge->GetbFace()); - - // Updates the invert edge: - pInvertEdge->setaFace(this); - } - else { // The invert edge does not exist yet - // we must create a new edge - //edge = new WEdge; - edge = instanciateEdge(); - - // updates the a,b vertex edges list: - v1->AddEdge(edge); - v2->AddEdge(edge); - } - - pOEdge->setOwner(edge); - // Add the vertices: - pOEdge->setaVertex(v1); - pOEdge->setbVertex(v2); - - // Debug: - if (v1->GetId() == v2->GetId()) - cerr << "Warning: edge " << this << " null with vertex " << v1->GetId() << endl; - - edge->AddOEdge(pOEdge); - //edge->setNumberOfOEdges(edge->GetNumberOfOEdges() + 1); - - // Add this face (the b face) - pOEdge->setbFace(this); - - // Adds the edge to the face - AddEdge(pOEdge); - - return pOEdge; + // First check whether the same oriented edge already exists or not: + vector &v1Edges = v1->GetEdges(); + for (vector::iterator it1 = v1Edges.begin(), end = v1Edges.end(); it1 != end; it1++) { + WEdge *we = (*it1); + WOEdge *woea = we->GetaOEdge(); + + if ((woea->GetaVertex() == v1) && (woea->GetbVertex() == v2)) { + // The oriented edge already exists + cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() + << " appears twice, correcting" << endl; + // Adds the edge to the face + AddEdge(woea); + (*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges() + 1); + //sets these vertices as border: + v1->setBorder(true); + v2->setBorder(true); + return woea; + } + + WOEdge *woeb = we->GetbOEdge(); + if (woeb && (woeb->GetaVertex() == v1) && (woeb->GetbVertex() == v2)) { + // The oriented edge already exists + cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() + << " appears twice, correcting" << endl; + // Adds the edge to the face + AddEdge(woeb); + (*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges() + 1); + //sets these vertices as border: + v1->setBorder(true); + v2->setBorder(true); + return woeb; + } + } + + // the oriented edge we're about to build + WOEdge *pOEdge = new WOEdge; + // The edge containing the oriented edge. + WEdge *edge; + + // checks whether this edge already exists or not + // If it exists, it points outward v2 + bool exist = false; + WOEdge *pInvertEdge = NULL; // The inverted edge if it exists + vector &v2Edges = v2->GetEdges(); + vector::iterator it; + for (it = v2Edges.begin(); it != v2Edges.end(); it++) { + if ((*it)->GetbVertex() == v1) { + // The invert edge already exists + exist = true; + pInvertEdge = (*it)->GetaOEdge(); + break; + } + } + + //DEBUG: + if (true == exist) { // The invert edge already exists + // Retrieves the corresponding edge + edge = pInvertEdge->GetOwner(); + + // Sets the a Face (retrieved from pInvertEdge + pOEdge->setaFace(pInvertEdge->GetbFace()); + + // Updates the invert edge: + pInvertEdge->setaFace(this); + } + else { // The invert edge does not exist yet + // we must create a new edge + //edge = new WEdge; + edge = instanciateEdge(); + + // updates the a,b vertex edges list: + v1->AddEdge(edge); + v2->AddEdge(edge); + } + + pOEdge->setOwner(edge); + // Add the vertices: + pOEdge->setaVertex(v1); + pOEdge->setbVertex(v2); + + // Debug: + if (v1->GetId() == v2->GetId()) + cerr << "Warning: edge " << this << " null with vertex " << v1->GetId() << endl; + + edge->AddOEdge(pOEdge); + //edge->setNumberOfOEdges(edge->GetNumberOfOEdges() + 1); + + // Add this face (the b face) + pOEdge->setbFace(this); + + // Adds the edge to the face + AddEdge(pOEdge); + + return pOEdge; } - bool WFace::getOppositeEdge(const WVertex *v, WOEdge *&e) { - if (_OEdgeList.size() != 3) - return false; - - vector::iterator it; - e = NULL; - for (it = _OEdgeList.begin(); it != _OEdgeList.end(); it++) { - if ((*it)->GetaVertex() == v) - e = *it; - } - if (!e) - return false; - e = NULL; - for (it = _OEdgeList.begin(); it != _OEdgeList.end(); it++) { - if (((*it)->GetaVertex() != v) && ((*it)->GetbVertex() != v)) - e = *it; - } - if (!e) - return false; - else - return true; + if (_OEdgeList.size() != 3) + return false; + + vector::iterator it; + e = NULL; + for (it = _OEdgeList.begin(); it != _OEdgeList.end(); it++) { + if ((*it)->GetaVertex() == v) + e = *it; + } + if (!e) + return false; + e = NULL; + for (it = _OEdgeList.begin(); it != _OEdgeList.end(); it++) { + if (((*it)->GetaVertex() != v) && ((*it)->GetbVertex() != v)) + e = *it; + } + if (!e) + return false; + else + return true; } float WFace::getArea() { - vector::iterator it; - Vec3f origin = (*(_OEdgeList.begin()))->GetaVertex()->GetVertex(); - it = _OEdgeList.begin(); - float a = 0; - for (it = it++; it != _OEdgeList.end(); it++) { - Vec3f v1 = Vec3f((*it)->GetaVertex()->GetVertex() - origin); - Vec3f v2 = Vec3f((*it)->GetbVertex()->GetVertex() - origin); - a += (v1 ^ v2).norm() / 2.0f; - } - return a; + vector::iterator it; + Vec3f origin = (*(_OEdgeList.begin()))->GetaVertex()->GetVertex(); + it = _OEdgeList.begin(); + float a = 0; + for (it = it++; it != _OEdgeList.end(); it++) { + Vec3f v1 = Vec3f((*it)->GetaVertex()->GetVertex() - origin); + Vec3f v2 = Vec3f((*it)->GetbVertex()->GetVertex() - origin); + a += (v1 ^ v2).norm() / 2.0f; + } + return a; } - WOEdge *WFace::GetPrevOEdge(WOEdge *iOEdge) { - vector::iterator woe, woend, woefirst; - woefirst = _OEdgeList.begin(); - woend = _OEdgeList.end(); - WOEdge *prev = *woefirst; - woe = woefirst; - ++woe; - for (; woe != woend; woe++) { - if ((*woe) == iOEdge) - return prev; - prev = *woe; - } - // We left the loop. That means that the first OEdge was the good one: - if ((*woefirst) == iOEdge) - return prev; - - return NULL; + vector::iterator woe, woend, woefirst; + woefirst = _OEdgeList.begin(); + woend = _OEdgeList.end(); + WOEdge *prev = *woefirst; + woe = woefirst; + ++woe; + for (; woe != woend; woe++) { + if ((*woe) == iOEdge) + return prev; + prev = *woe; + } + // We left the loop. That means that the first OEdge was the good one: + if ((*woefirst) == iOEdge) + return prev; + + return NULL; } WShape *WFace::getShape() { - return GetVertex(0)->shape(); + return GetVertex(0)->shape(); } - /********************************** * * * * @@ -457,255 +451,259 @@ unsigned WShape::_SceneCurrentId = 0; WShape *WShape::duplicate() { - WShape *clone = new WShape(*this); - return clone; + WShape *clone = new WShape(*this); + return clone; } -WShape::WShape(WShape& iBrother) +WShape::WShape(WShape &iBrother) { - _Id = iBrother.GetId(); - _Name = iBrother._Name; - _LibraryPath = iBrother._LibraryPath; - _FrsMaterials = iBrother._FrsMaterials; + _Id = iBrother.GetId(); + _Name = iBrother._Name; + _LibraryPath = iBrother._LibraryPath; + _FrsMaterials = iBrother._FrsMaterials; #if 0 - _meanEdgeSize = iBrother._meanEdgeSize; - iBrother.bbox(_min, _max); + _meanEdgeSize = iBrother._meanEdgeSize; + iBrother.bbox(_min, _max); #endif - vector& vertexList = iBrother.getVertexList(); - vector::iterator v = vertexList.begin(), vend = vertexList.end(); - for (; v != vend; ++v) { - //WVertex *newVertex = new WVertex(*(*v)); - WVertex *newVertex = (*v)->duplicate(); - - newVertex->setShape(this); - AddVertex(newVertex); - } - - vector& edgeList = iBrother.getEdgeList(); - vector::iterator e = edgeList.begin(), eend = edgeList.end(); - for (; e != eend; ++e) { - //WEdge *newEdge = new WEdge(*(*e)); - WEdge *newEdge = (*e)->duplicate(); - AddEdge(newEdge); - } - - vector& faceList = iBrother.GetFaceList(); - vector::iterator f = faceList.begin(), fend = faceList.end(); - for (; f != fend; ++f) { - //WFace *newFace = new WFace(*(*f)); - WFace *newFace = (*f)->duplicate(); - AddFace(newFace); - } - - // update all pointed addresses thanks to the newly created objects: - vend = _VertexList.end(); - for (v = _VertexList.begin(); v != vend; ++v) { - const vector& vedgeList = (*v)->GetEdges(); - vector newvedgelist; - unsigned int i; - for (i = 0; i < vedgeList.size(); i++) { - WEdge *current = vedgeList[i]; - edgedata *currentvedata = (edgedata *)current->userdata; - newvedgelist.push_back(currentvedata->_copy); - } - (*v)->setEdges(newvedgelist); - } - - eend = _EdgeList.end(); - for (e = _EdgeList.begin(); e != eend; ++e) { - // update aOedge: - WOEdge *aoEdge = (*e)->GetaOEdge(); - aoEdge->setaVertex(((vertexdata *)(aoEdge->GetaVertex()->userdata))->_copy); - aoEdge->setbVertex(((vertexdata *)(aoEdge->GetbVertex()->userdata))->_copy); - if (aoEdge->GetaFace()) - aoEdge->setaFace(((facedata *)(aoEdge->GetaFace()->userdata))->_copy); - aoEdge->setbFace(((facedata *)(aoEdge->GetbFace()->userdata))->_copy); - aoEdge->setOwner(((edgedata *)(aoEdge->GetOwner()->userdata))->_copy); - - // update bOedge: - WOEdge *boEdge = (*e)->GetbOEdge(); - if (boEdge) { - boEdge->setaVertex(((vertexdata *)(boEdge->GetaVertex()->userdata))->_copy); - boEdge->setbVertex(((vertexdata *)(boEdge->GetbVertex()->userdata))->_copy); - if (boEdge->GetaFace()) - boEdge->setaFace(((facedata *)(boEdge->GetaFace()->userdata))->_copy); - boEdge->setbFace(((facedata *)(boEdge->GetbFace()->userdata))->_copy); - boEdge->setOwner(((edgedata *)(boEdge->GetOwner()->userdata))->_copy); - } - } - - fend = _FaceList.end(); - for (f = _FaceList.begin(); f != fend; ++f) { - unsigned int i; - const vector& oedgeList = (*f)->getEdgeList(); - vector newoedgelist; - - unsigned int n = oedgeList.size(); - for (i = 0; i < n; i++) { - WOEdge *current = oedgeList[i]; - oedgedata *currentoedata = (oedgedata *)current->userdata; - newoedgelist.push_back(currentoedata->_copy); - //oedgeList[i] = currentoedata->_copy; - //oedgeList[i] = ((oedgedata *)(oedgeList[i]->userdata))->_copy; - } - (*f)->setEdgeList(newoedgelist); - } - - // Free all memory (arghh!) - // Vertex - vend = iBrother.getVertexList().end(); - for (v = iBrother.getVertexList().begin(); v != vend; ++v) { - delete (vertexdata *)((*v)->userdata); - (*v)->userdata = NULL; - } - - // Edges and OEdges: - eend = iBrother.getEdgeList().end(); - for (e = iBrother.getEdgeList().begin(); e != eend; ++e) { - delete (edgedata *)((*e)->userdata); - (*e)->userdata = NULL; - // OEdge a: - delete (oedgedata *)((*e)->GetaOEdge()->userdata); - (*e)->GetaOEdge()->userdata = NULL; - // OEdge b: - WOEdge *oedgeb = (*e)->GetbOEdge(); - if (oedgeb) { - delete (oedgedata *)(oedgeb->userdata); - oedgeb->userdata = NULL; - } - } - - // Faces - fend = iBrother.GetFaceList().end(); - for (f = iBrother.GetFaceList().begin(); f != fend; ++f) { - delete (facedata *)((*f)->userdata); - (*f)->userdata = NULL; - } + vector &vertexList = iBrother.getVertexList(); + vector::iterator v = vertexList.begin(), vend = vertexList.end(); + for (; v != vend; ++v) { + //WVertex *newVertex = new WVertex(*(*v)); + WVertex *newVertex = (*v)->duplicate(); + + newVertex->setShape(this); + AddVertex(newVertex); + } + + vector &edgeList = iBrother.getEdgeList(); + vector::iterator e = edgeList.begin(), eend = edgeList.end(); + for (; e != eend; ++e) { + //WEdge *newEdge = new WEdge(*(*e)); + WEdge *newEdge = (*e)->duplicate(); + AddEdge(newEdge); + } + + vector &faceList = iBrother.GetFaceList(); + vector::iterator f = faceList.begin(), fend = faceList.end(); + for (; f != fend; ++f) { + //WFace *newFace = new WFace(*(*f)); + WFace *newFace = (*f)->duplicate(); + AddFace(newFace); + } + + // update all pointed addresses thanks to the newly created objects: + vend = _VertexList.end(); + for (v = _VertexList.begin(); v != vend; ++v) { + const vector &vedgeList = (*v)->GetEdges(); + vector newvedgelist; + unsigned int i; + for (i = 0; i < vedgeList.size(); i++) { + WEdge *current = vedgeList[i]; + edgedata *currentvedata = (edgedata *)current->userdata; + newvedgelist.push_back(currentvedata->_copy); + } + (*v)->setEdges(newvedgelist); + } + + eend = _EdgeList.end(); + for (e = _EdgeList.begin(); e != eend; ++e) { + // update aOedge: + WOEdge *aoEdge = (*e)->GetaOEdge(); + aoEdge->setaVertex(((vertexdata *)(aoEdge->GetaVertex()->userdata))->_copy); + aoEdge->setbVertex(((vertexdata *)(aoEdge->GetbVertex()->userdata))->_copy); + if (aoEdge->GetaFace()) + aoEdge->setaFace(((facedata *)(aoEdge->GetaFace()->userdata))->_copy); + aoEdge->setbFace(((facedata *)(aoEdge->GetbFace()->userdata))->_copy); + aoEdge->setOwner(((edgedata *)(aoEdge->GetOwner()->userdata))->_copy); + + // update bOedge: + WOEdge *boEdge = (*e)->GetbOEdge(); + if (boEdge) { + boEdge->setaVertex(((vertexdata *)(boEdge->GetaVertex()->userdata))->_copy); + boEdge->setbVertex(((vertexdata *)(boEdge->GetbVertex()->userdata))->_copy); + if (boEdge->GetaFace()) + boEdge->setaFace(((facedata *)(boEdge->GetaFace()->userdata))->_copy); + boEdge->setbFace(((facedata *)(boEdge->GetbFace()->userdata))->_copy); + boEdge->setOwner(((edgedata *)(boEdge->GetOwner()->userdata))->_copy); + } + } + + fend = _FaceList.end(); + for (f = _FaceList.begin(); f != fend; ++f) { + unsigned int i; + const vector &oedgeList = (*f)->getEdgeList(); + vector newoedgelist; + + unsigned int n = oedgeList.size(); + for (i = 0; i < n; i++) { + WOEdge *current = oedgeList[i]; + oedgedata *currentoedata = (oedgedata *)current->userdata; + newoedgelist.push_back(currentoedata->_copy); + //oedgeList[i] = currentoedata->_copy; + //oedgeList[i] = ((oedgedata *)(oedgeList[i]->userdata))->_copy; + } + (*f)->setEdgeList(newoedgelist); + } + + // Free all memory (arghh!) + // Vertex + vend = iBrother.getVertexList().end(); + for (v = iBrother.getVertexList().begin(); v != vend; ++v) { + delete (vertexdata *)((*v)->userdata); + (*v)->userdata = NULL; + } + + // Edges and OEdges: + eend = iBrother.getEdgeList().end(); + for (e = iBrother.getEdgeList().begin(); e != eend; ++e) { + delete (edgedata *)((*e)->userdata); + (*e)->userdata = NULL; + // OEdge a: + delete (oedgedata *)((*e)->GetaOEdge()->userdata); + (*e)->GetaOEdge()->userdata = NULL; + // OEdge b: + WOEdge *oedgeb = (*e)->GetbOEdge(); + if (oedgeb) { + delete (oedgedata *)(oedgeb->userdata); + oedgeb->userdata = NULL; + } + } + + // Faces + fend = iBrother.GetFaceList().end(); + for (f = iBrother.GetFaceList().begin(); f != fend; ++f) { + delete (facedata *)((*f)->userdata); + (*f)->userdata = NULL; + } } -WFace *WShape::MakeFace(vector& iVertexList, vector& iFaceEdgeMarksList, unsigned iMaterial) +WFace *WShape::MakeFace(vector &iVertexList, + vector &iFaceEdgeMarksList, + unsigned iMaterial) { - // allocate the new face - WFace *face = instanciateFace(); + // allocate the new face + WFace *face = instanciateFace(); - WFace *result = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial, face); - if (!result) - delete face; - return result; + WFace *result = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial, face); + if (!result) + delete face; + return result; } -WFace *WShape::MakeFace(vector& iVertexList, vector& iNormalsList, vector& iTexCoordsList, - vector& iFaceEdgeMarksList, unsigned iMaterial) +WFace *WShape::MakeFace(vector &iVertexList, + vector &iNormalsList, + vector &iTexCoordsList, + vector &iFaceEdgeMarksList, + unsigned iMaterial) { - // allocate the new face - WFace *face = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial); + // allocate the new face + WFace *face = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial); - if (!face) - return NULL; + if (!face) + return NULL; - // set the list of per-vertex normals - face->setNormalList(iNormalsList); - // set the list of per-vertex tex coords - face->setTexCoordsList(iTexCoordsList); + // set the list of per-vertex normals + face->setNormalList(iNormalsList); + // set the list of per-vertex tex coords + face->setTexCoordsList(iTexCoordsList); - return face; + return face; } -WFace *WShape::MakeFace(vector& iVertexList, vector& iFaceEdgeMarksList, unsigned iMaterial, +WFace *WShape::MakeFace(vector &iVertexList, + vector &iFaceEdgeMarksList, + unsigned iMaterial, WFace *face) { - int id = _FaceList.size(); - - face->setFrsMaterialIndex(iMaterial); - - // Check whether we have a degenerated face: - - // LET'S HACK IT FOR THE TRIANGLE CASE: - - if (3 == iVertexList.size()) { - if ((iVertexList[0] == iVertexList[1]) || - (iVertexList[0] == iVertexList[2]) || - (iVertexList[2] == iVertexList[1])) - { - cerr << "Warning: degenerated triangle detected, correcting" << endl; - return NULL; - } - } - - vector::iterator it; - - // compute the face normal (v1v2 ^ v1v3) - // Double precision numbers are used here to avoid truncation errors [T47705] - Vec3r v1, v2, v3; - it = iVertexList.begin(); - v1 = (*it)->GetVertex(); - it++; - v2 = (*it)->GetVertex(); - it++; - v3 = (*it)->GetVertex(); - - Vec3r vector1(v2 - v1); - Vec3r vector2(v3 - v1); - - Vec3r normal(vector1 ^ vector2); - normal.normalize(); - face->setNormal(normal); - - vector::iterator mit = iFaceEdgeMarksList.begin(); - face->setMark(*mit); - mit++; - - // vertex pointers used to build each edge - vector::iterator va, vb; - - va = iVertexList.begin(); - vb = va; - for (; va != iVertexList.end(); va = vb) { - ++vb; - // Adds va to the vertex list: - //face->AddVertex(*va); - - WOEdge *oedge; - if (*va == iVertexList.back()) - oedge = face->MakeEdge(*va, iVertexList.front()); //for the last (closing) edge - else - oedge = face->MakeEdge(*va, *vb); - - if (!oedge) - return NULL; - - WEdge *edge = oedge->GetOwner(); - if (1 == edge->GetNumberOfOEdges()) { - // means that we just created a new edge and that we must add it to the shape's edges list - edge->setId(_EdgeList.size()); - AddEdge(edge); + int id = _FaceList.size(); + + face->setFrsMaterialIndex(iMaterial); + + // Check whether we have a degenerated face: + + // LET'S HACK IT FOR THE TRIANGLE CASE: + + if (3 == iVertexList.size()) { + if ((iVertexList[0] == iVertexList[1]) || (iVertexList[0] == iVertexList[2]) || + (iVertexList[2] == iVertexList[1])) { + cerr << "Warning: degenerated triangle detected, correcting" << endl; + return NULL; + } + } + + vector::iterator it; + + // compute the face normal (v1v2 ^ v1v3) + // Double precision numbers are used here to avoid truncation errors [T47705] + Vec3r v1, v2, v3; + it = iVertexList.begin(); + v1 = (*it)->GetVertex(); + it++; + v2 = (*it)->GetVertex(); + it++; + v3 = (*it)->GetVertex(); + + Vec3r vector1(v2 - v1); + Vec3r vector2(v3 - v1); + + Vec3r normal(vector1 ^ vector2); + normal.normalize(); + face->setNormal(normal); + + vector::iterator mit = iFaceEdgeMarksList.begin(); + face->setMark(*mit); + mit++; + + // vertex pointers used to build each edge + vector::iterator va, vb; + + va = iVertexList.begin(); + vb = va; + for (; va != iVertexList.end(); va = vb) { + ++vb; + // Adds va to the vertex list: + //face->AddVertex(*va); + + WOEdge *oedge; + if (*va == iVertexList.back()) + oedge = face->MakeEdge(*va, iVertexList.front()); //for the last (closing) edge + else + oedge = face->MakeEdge(*va, *vb); + + if (!oedge) + return NULL; + + WEdge *edge = oedge->GetOwner(); + if (1 == edge->GetNumberOfOEdges()) { + // means that we just created a new edge and that we must add it to the shape's edges list + edge->setId(_EdgeList.size()); + AddEdge(edge); #if 0 - // compute the mean edge value: - _meanEdgeSize += edge->GetaOEdge()->GetVec().norm(); + // compute the mean edge value: + _meanEdgeSize += edge->GetaOEdge()->GetVec().norm(); #endif - } + } - edge->setMark(*mit); - ++mit; - } + edge->setMark(*mit); + ++mit; + } - // Add the face to the shape's faces list: - face->setId(id); - AddFace(face); + // Add the face to the shape's faces list: + face->setId(id); + AddFace(face); - return face; + return face; } real WShape::ComputeMeanEdgeSize() const { - real meanEdgeSize = 0.0; - for (vector::const_iterator it = _EdgeList.begin(), itend = _EdgeList.end(); - it != itend; - it++) - { - meanEdgeSize += (*it)->GetaOEdge()->GetVec().norm(); - } - return meanEdgeSize / (real)_EdgeList.size(); + real meanEdgeSize = 0.0; + for (vector::const_iterator it = _EdgeList.begin(), itend = _EdgeList.end(); + it != itend; + it++) { + meanEdgeSize += (*it)->GetaOEdge()->GetVec().norm(); + } + return meanEdgeSize / (real)_EdgeList.size(); } } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.h b/source/blender/freestyle/intern/winged_edge/WEdge.h index b4807a4d921..79c6a24e6d9 100644 --- a/source/blender/freestyle/intern/winged_edge/WEdge.h +++ b/source/blender/freestyle/intern/winged_edge/WEdge.h @@ -34,7 +34,7 @@ #include "BLI_math.h" #ifdef WITH_CXX_GUARDEDALLOC -#include "MEM_guardedalloc.h" +# include "MEM_guardedalloc.h" #endif using namespace std; @@ -43,7 +43,6 @@ namespace Freestyle { using namespace Geometry; - /********************************** * * * * @@ -52,303 +51,309 @@ using namespace Geometry; * * **********************************/ - class WOEdge; class WEdge; class WShape; class WFace; -class WVertex -{ -protected: - int _Id; // an identificator - Vec3f _Vertex; - vector _EdgeList; - WShape *_Shape; // the shape to which the vertex belongs - bool _Smooth; // flag to indicate whether the Vertex belongs to a smooth edge or not - short _Border; // 1 -> border, 0 -> no border, -1 -> not set - -public: - void *userdata; // designed to store specific user data - inline WVertex(const Vec3f &v) - { - _Id = 0; - _Vertex = v; - userdata = NULL; - _Shape = NULL; - _Smooth = true; - _Border = -1; - } - - /*! Copy constructor */ - WVertex(WVertex& iBrother); - virtual WVertex *duplicate(); - virtual ~WVertex() {} - - /*! accessors */ - inline Vec3f& GetVertex() - { - return _Vertex; - } - - inline vector& GetEdges() - { - return _EdgeList; - } - - inline int GetId() - { - return _Id; - } - - inline WShape *shape() const - { - return _Shape; - } - - inline bool isSmooth() const - { - return _Smooth; - } - - bool isBoundary(); - - /*! modifiers */ - inline void setVertex(const Vec3f& v) - { - _Vertex = v; - } - - inline void setEdges(const vector& iEdgeList) - { - _EdgeList = iEdgeList; - } - - inline void setId(int id) - { - _Id = id; - } - - inline void setShape(WShape *iShape) - { - _Shape = iShape; - } - - inline void setSmooth(bool b) - { - _Smooth = b; - } - - inline void setBorder(bool b) - { - if (b) - _Border = 1; - else - _Border = 0; - } - - /*! Adds an edge to the edges list */ - void AddEdge(WEdge *iEdge); - - virtual void ResetUserData() - { - userdata = NULL; - } - -public: - /*! Iterator to iterate over a vertex incoming edges in the CCW order*/ +class WVertex { + protected: + int _Id; // an identificator + Vec3f _Vertex; + vector _EdgeList; + WShape *_Shape; // the shape to which the vertex belongs + bool _Smooth; // flag to indicate whether the Vertex belongs to a smooth edge or not + short _Border; // 1 -> border, 0 -> no border, -1 -> not set + + public: + void *userdata; // designed to store specific user data + inline WVertex(const Vec3f &v) + { + _Id = 0; + _Vertex = v; + userdata = NULL; + _Shape = NULL; + _Smooth = true; + _Border = -1; + } + + /*! Copy constructor */ + WVertex(WVertex &iBrother); + virtual WVertex *duplicate(); + virtual ~WVertex() + { + } + + /*! accessors */ + inline Vec3f &GetVertex() + { + return _Vertex; + } + + inline vector &GetEdges() + { + return _EdgeList; + } + + inline int GetId() + { + return _Id; + } + + inline WShape *shape() const + { + return _Shape; + } + + inline bool isSmooth() const + { + return _Smooth; + } + + bool isBoundary(); + + /*! modifiers */ + inline void setVertex(const Vec3f &v) + { + _Vertex = v; + } + + inline void setEdges(const vector &iEdgeList) + { + _EdgeList = iEdgeList; + } + + inline void setId(int id) + { + _Id = id; + } + + inline void setShape(WShape *iShape) + { + _Shape = iShape; + } + + inline void setSmooth(bool b) + { + _Smooth = b; + } + + inline void setBorder(bool b) + { + if (b) + _Border = 1; + else + _Border = 0; + } + + /*! Adds an edge to the edges list */ + void AddEdge(WEdge *iEdge); + + virtual void ResetUserData() + { + userdata = NULL; + } + + public: + /*! Iterator to iterate over a vertex incoming edges in the CCW order*/ #if defined(__GNUC__) && (__GNUC__ < 3) - class incoming_edge_iterator : public input_iterator + class incoming_edge_iterator : public input_iterator #else - class incoming_edge_iterator - : public iterator + class incoming_edge_iterator : public iterator #endif - { - private: - WVertex *_vertex; - // - WOEdge *_begin; - WOEdge *_current; - - public: + { + private: + WVertex *_vertex; + // + WOEdge *_begin; + WOEdge *_current; + + public: #if defined(__GNUC__) && (__GNUC__ < 3) - inline incoming_edge_iterator() : input_iterator() {} + inline incoming_edge_iterator() : input_iterator() + { + } #else - inline incoming_edge_iterator() : iterator() {} + inline incoming_edge_iterator() : iterator() + { + } #endif - virtual ~incoming_edge_iterator() {}; //soc + virtual ~incoming_edge_iterator(){}; //soc - protected: - friend class WVertex; - inline incoming_edge_iterator(WVertex *iVertex, WOEdge *iBegin, WOEdge *iCurrent) + protected: + friend class WVertex; + inline incoming_edge_iterator(WVertex *iVertex, WOEdge *iBegin, WOEdge *iCurrent) #if defined(__GNUC__) && (__GNUC__ < 3) - : input_iterator() + : input_iterator() #else - : iterator() + : iterator() #endif - { - _vertex = iVertex; - _begin = iBegin; - _current = iCurrent; - } - - public: - inline incoming_edge_iterator(const incoming_edge_iterator& iBrother) + { + _vertex = iVertex; + _begin = iBegin; + _current = iCurrent; + } + + public: + inline incoming_edge_iterator(const incoming_edge_iterator &iBrother) #if defined(__GNUC__) && (__GNUC__ < 3) - : input_iterator(iBrother) + : input_iterator(iBrother) #else - : iterator(iBrother) + : iterator(iBrother) #endif - { - _vertex = iBrother._vertex; - _begin = iBrother._begin; - _current = iBrother._current; - } - - public: - // operators - // operator corresponding to ++i - virtual incoming_edge_iterator& operator++() - { - increment(); - return *this; - } - - // operator corresponding to i++ - virtual incoming_edge_iterator operator++(int) - { - incoming_edge_iterator tmp = *this; - increment(); - return tmp; - } - - // comparibility - virtual bool operator!=(const incoming_edge_iterator& b) const - { - return ((_current) != (b._current)); - } - - virtual bool operator==(const incoming_edge_iterator& b) const - { - return ((_current) == (b._current)); - } - - // dereferencing - virtual WOEdge *operator*(); - //virtual WOEdge **operator->(); - protected: - virtual void increment(); + { + _vertex = iBrother._vertex; + _begin = iBrother._begin; + _current = iBrother._current; + } + + public: + // operators + // operator corresponding to ++i + virtual incoming_edge_iterator &operator++() + { + increment(); + return *this; + } + + // operator corresponding to i++ + virtual incoming_edge_iterator operator++(int) + { + incoming_edge_iterator tmp = *this; + increment(); + return tmp; + } + + // comparibility + virtual bool operator!=(const incoming_edge_iterator &b) const + { + return ((_current) != (b._current)); + } + + virtual bool operator==(const incoming_edge_iterator &b) const + { + return ((_current) == (b._current)); + } + + // dereferencing + virtual WOEdge *operator*(); + //virtual WOEdge **operator->(); + protected: + virtual void increment(); #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WVertex:incoming_edge_iterator") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WVertex:incoming_edge_iterator") #endif - }; + }; - /*! Iterator to iterate over a vertex faces in the CCW order */ + /*! Iterator to iterate over a vertex faces in the CCW order */ #if defined(__GNUC__) && (__GNUC__ < 3) - class face_iterator : public input_iterator + class face_iterator : public input_iterator #else - class face_iterator : public iterator + class face_iterator : public iterator #endif - { - private: - incoming_edge_iterator _edge_it; + { + private: + incoming_edge_iterator _edge_it; - public: + public: #if defined(__GNUC__) && (__GNUC__ < 3) - inline face_iterator() : input_iterator() {} + inline face_iterator() : input_iterator() + { + } #else - inline face_iterator() : iterator() {} + inline face_iterator() : iterator() + { + } #endif - virtual ~face_iterator() {}; //soc + virtual ~face_iterator(){}; //soc - protected: - friend class WVertex; - inline face_iterator(incoming_edge_iterator it) + protected: + friend class WVertex; + inline face_iterator(incoming_edge_iterator it) #if defined(__GNUC__) && (__GNUC__ < 3) - : input_iterator() + : input_iterator() #else - : iterator() + : iterator() #endif - { - _edge_it = it; - } + { + _edge_it = it; + } - public: - inline face_iterator(const face_iterator& iBrother) + public: + inline face_iterator(const face_iterator &iBrother) #if defined(__GNUC__) && (__GNUC__ < 3) - : input_iterator(iBrother) + : input_iterator(iBrother) #else - : iterator(iBrother) + : iterator(iBrother) #endif - { - _edge_it = iBrother._edge_it; - } - - public: - // operators - // operator corresponding to ++i - virtual face_iterator& operator++() - { - increment(); - return *this; - } - - // operator corresponding to i++ - virtual face_iterator operator++(int) - { - face_iterator tmp = *this; - increment(); - return tmp; - } - - // comparibility - virtual bool operator!=(const face_iterator& b) const - { - return ((_edge_it) != (b._edge_it)); - } - - virtual bool operator==(const face_iterator& b) const - { - return ((_edge_it) == (b._edge_it)); - } - - // dereferencing - virtual WFace *operator*(); - //virtual WOEdge **operator->(); - - protected: - inline void increment() - { - ++_edge_it; - } + { + _edge_it = iBrother._edge_it; + } + + public: + // operators + // operator corresponding to ++i + virtual face_iterator &operator++() + { + increment(); + return *this; + } + + // operator corresponding to i++ + virtual face_iterator operator++(int) + { + face_iterator tmp = *this; + increment(); + return tmp; + } + + // comparibility + virtual bool operator!=(const face_iterator &b) const + { + return ((_edge_it) != (b._edge_it)); + } + + virtual bool operator==(const face_iterator &b) const + { + return ((_edge_it) == (b._edge_it)); + } + + // dereferencing + virtual WFace *operator*(); + //virtual WOEdge **operator->(); + + protected: + inline void increment() + { + ++_edge_it; + } #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WVertex:face_iterator") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WVertex:face_iterator") #endif - }; + }; -public: - /*! iterators access */ - virtual incoming_edge_iterator incoming_edges_begin(); - virtual incoming_edge_iterator incoming_edges_end(); + public: + /*! iterators access */ + virtual incoming_edge_iterator incoming_edges_begin(); + virtual incoming_edge_iterator incoming_edges_end(); - virtual face_iterator faces_begin() - { - return face_iterator(incoming_edges_begin()); - } + virtual face_iterator faces_begin() + { + return face_iterator(incoming_edges_begin()); + } - virtual face_iterator faces_end() - { - return face_iterator(incoming_edges_end()); - } + virtual face_iterator faces_end() + { + return face_iterator(incoming_edges_end()); + } #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WVertex") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WVertex") #endif }; - /********************************** * * * * @@ -360,178 +365,176 @@ public: class WFace; class WEdge; -class WOEdge -{ -protected: +class WOEdge { + protected: #if 0 - WOEdge *_paCWEdge; // edge reached when traveling clockwise on aFace from the edge - WOEdge *_pbCWEdge; // edge reached when traveling clockwise on bFace from the edge - WOEdge *_paCCWEdge; // edge reached when traveling counterclockwise on aFace from the edge - WOEdge *_pbCCWEdge; // edge reached when traveling counterclockwise on bFace from the edge + WOEdge *_paCWEdge; // edge reached when traveling clockwise on aFace from the edge + WOEdge *_pbCWEdge; // edge reached when traveling clockwise on bFace from the edge + WOEdge *_paCCWEdge; // edge reached when traveling counterclockwise on aFace from the edge + WOEdge *_pbCCWEdge; // edge reached when traveling counterclockwise on bFace from the edge #endif - WVertex *_paVertex; // starting vertex - WVertex *_pbVertex; // ending vertex - WFace *_paFace; // when following the edge, face on the right - WFace *_pbFace; // when following the edge, face on the left - WEdge *_pOwner; // Edge + WVertex *_paVertex; // starting vertex + WVertex *_pbVertex; // ending vertex + WFace *_paFace; // when following the edge, face on the right + WFace *_pbFace; // when following the edge, face on the left + WEdge *_pOwner; // Edge - Vec3f _vec; - float _angle; + Vec3f _vec; + float _angle; -public: - void *userdata; + public: + void *userdata; - inline WOEdge() - { + inline WOEdge() + { #if 0 - _paCWEdge = NULL; - _pbCWEdge = NULL; - _paCCWEdge = NULL; - _pbCCWEdge = NULL; + _paCWEdge = NULL; + _pbCWEdge = NULL; + _paCCWEdge = NULL; + _pbCCWEdge = NULL; #endif - _paVertex = NULL; - _pbVertex = NULL; - _paFace = NULL; - _pbFace = NULL; - _pOwner = NULL; - userdata = NULL; - } + _paVertex = NULL; + _pbVertex = NULL; + _paFace = NULL; + _pbFace = NULL; + _pOwner = NULL; + userdata = NULL; + } - virtual ~WOEdge() {}; //soc + virtual ~WOEdge(){}; //soc - /*! copy constructor */ - WOEdge(WOEdge& iBrother); - virtual WOEdge *duplicate(); + /*! copy constructor */ + WOEdge(WOEdge &iBrother); + virtual WOEdge *duplicate(); - /*! accessors */ + /*! accessors */ #if 0 - inline WOEdge *GetaCWEdge() - { - return _paCWEdge; - } - - inline WOEdge *GetbCWEdge() - { - return _pbCWEdge; - } - - inline WOEdge *GetaCCWEdge() - { - return _paCCWEdge; - } - - inline WOEdge *GetbCCWEdge() - { - return _pbCCWEdge; - } + inline WOEdge *GetaCWEdge() + { + return _paCWEdge; + } + + inline WOEdge *GetbCWEdge() + { + return _pbCWEdge; + } + + inline WOEdge *GetaCCWEdge() + { + return _paCCWEdge; + } + + inline WOEdge *GetbCCWEdge() + { + return _pbCCWEdge; + } #endif - inline WVertex *GetaVertex() - { - return _paVertex; - } - - inline WVertex *GetbVertex() - { - return _pbVertex; - } - - inline WFace *GetaFace() - { - return _paFace; - } - - inline WFace *GetbFace() - { - return _pbFace; - } - - inline WEdge *GetOwner() - { - return _pOwner; - } - - inline const Vec3f& GetVec() - { - return _vec; - } - - inline const float GetAngle() - { - return _angle; - } - - /*! modifiers */ + inline WVertex *GetaVertex() + { + return _paVertex; + } + + inline WVertex *GetbVertex() + { + return _pbVertex; + } + + inline WFace *GetaFace() + { + return _paFace; + } + + inline WFace *GetbFace() + { + return _pbFace; + } + + inline WEdge *GetOwner() + { + return _pOwner; + } + + inline const Vec3f &GetVec() + { + return _vec; + } + + inline const float GetAngle() + { + return _angle; + } + + /*! modifiers */ #if 0 - inline void SetaCWEdge(WOEdge *pe) - { - _paCWEdge = pe; - } - - inline void SetbCWEdge(WOEdge *pe) - { - _pbCWEdge = pe; - } - - inline void SetaCCWEdge(WOEdge *pe) - { - _paCCWEdge = pe; - } - - inline void SetbCCCWEdge(WOEdge *pe) - { - _pbCCWEdge = pe; - } + inline void SetaCWEdge(WOEdge *pe) + { + _paCWEdge = pe; + } + + inline void SetbCWEdge(WOEdge *pe) + { + _pbCWEdge = pe; + } + + inline void SetaCCWEdge(WOEdge *pe) + { + _paCCWEdge = pe; + } + + inline void SetbCCCWEdge(WOEdge *pe) + { + _pbCCWEdge = pe; + } #endif - inline void setVecAndAngle(); + inline void setVecAndAngle(); - inline void setaVertex(WVertex *pv) - { - _paVertex = pv; - setVecAndAngle(); - } + inline void setaVertex(WVertex *pv) + { + _paVertex = pv; + setVecAndAngle(); + } - inline void setbVertex(WVertex *pv) - { - _pbVertex = pv; - setVecAndAngle(); - } + inline void setbVertex(WVertex *pv) + { + _pbVertex = pv; + setVecAndAngle(); + } - inline void setaFace(WFace *pf) - { - _paFace = pf; - setVecAndAngle(); - } + inline void setaFace(WFace *pf) + { + _paFace = pf; + setVecAndAngle(); + } - inline void setbFace(WFace *pf) - { - _pbFace = pf; - setVecAndAngle(); - } + inline void setbFace(WFace *pf) + { + _pbFace = pf; + setVecAndAngle(); + } - inline void setOwner(WEdge *pe) - { - _pOwner = pe; - } + inline void setOwner(WEdge *pe) + { + _pOwner = pe; + } - /*! Retrieves the list of edges in CW order */ - inline void RetrieveCWOrderedEdges(vector& oEdges); + /*! Retrieves the list of edges in CW order */ + inline void RetrieveCWOrderedEdges(vector &oEdges); - WOEdge *twin (); - WOEdge *getPrevOnFace(); + WOEdge *twin(); + WOEdge *getPrevOnFace(); - virtual void ResetUserData() - { - userdata = NULL; - } + virtual void ResetUserData() + { + userdata = NULL; + } #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WOEdge") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WOEdge") #endif }; - /********************************** * * * * @@ -540,185 +543,184 @@ public: * * **********************************/ -class WEdge -{ -protected: - WOEdge *_paOEdge; // first oriented edge - WOEdge *_pbOEdge; // second oriented edge - short _nOEdges; // number of oriented edges associated with this edge. (1 means border edge) - bool _Mark; // user-specified edge mark for feature edge detection - int _Id; // Identifier for the edge - -public: - void *userdata; // designed to store specific user data - - inline WEdge() - { - _paOEdge = NULL; - _pbOEdge = NULL; - _nOEdges = 0; - userdata = NULL; - } - - inline WEdge(WOEdge *iOEdge) - { - _paOEdge = iOEdge; - _pbOEdge = NULL; - _nOEdges = 1; - userdata = NULL; - } - - inline WEdge(WOEdge *iaOEdge, WOEdge *ibOEdge) - { - _paOEdge = iaOEdge; - _pbOEdge = ibOEdge; - _nOEdges = 2; - userdata = NULL; - } - - /*! Copy constructor */ - WEdge(WEdge& iBrother); - virtual WEdge *duplicate(); - - virtual ~WEdge() - { - if (_paOEdge) { - delete _paOEdge; - _paOEdge = NULL; - } - - if (_pbOEdge) { - delete _pbOEdge; - _pbOEdge = NULL; - } - } - - /*! checks whether two WEdge have a common vertex. - * Returns a pointer on the common vertex if it exists, NULL otherwise. - */ - static inline WVertex *CommonVertex(WEdge *iEdge1, WEdge *iEdge2) - { - if (!iEdge1 || !iEdge2) - return NULL; - - WVertex *wv1 = iEdge1->GetaOEdge()->GetaVertex(); - WVertex *wv2 = iEdge1->GetaOEdge()->GetbVertex(); - WVertex *wv3 = iEdge2->GetaOEdge()->GetaVertex(); - WVertex *wv4 = iEdge2->GetaOEdge()->GetbVertex(); - - if ((wv1 == wv3) || (wv1 == wv4)) { - return wv1; - } - else if ((wv2 == wv3) || (wv2 == wv4)) { - return wv2; - } - return NULL; - } - - /*! accessors */ - inline WOEdge *GetaOEdge() - { - return _paOEdge; - } - - inline WOEdge *GetbOEdge() - { - return _pbOEdge; - } - - inline short GetNumberOfOEdges() - { - return _nOEdges; - } - - inline bool GetMark() - { - return _Mark; - } - - inline int GetId() - { - return _Id; - } - - inline WVertex *GetaVertex() - { - return _paOEdge->GetaVertex(); - } - - inline WVertex *GetbVertex() - { - return _paOEdge->GetbVertex(); - } - - inline WFace *GetaFace() - { - return _paOEdge->GetaFace(); - } - - inline WFace *GetbFace() - { - return _paOEdge->GetbFace(); - } - - inline WOEdge *GetOtherOEdge(WOEdge *iOEdge) { - if (iOEdge == _paOEdge) - return _pbOEdge; - else - return _paOEdge; - } - - /*! modifiers */ - inline void setaOEdge(WOEdge *iEdge) - { - _paOEdge = iEdge; - } - - inline void setbOEdge(WOEdge *iEdge) - { - _pbOEdge = iEdge; - } - - inline void AddOEdge(WOEdge *iEdge) - { - if (!_paOEdge) { - _paOEdge = iEdge; - _nOEdges++; - return; - } - if (!_pbOEdge) { - _pbOEdge = iEdge; - _nOEdges++; - return; - } - } - - inline void setNumberOfOEdges(short n) - { - _nOEdges = n; - } - - inline void setMark(bool mark) - { - _Mark = mark; - } - - inline void setId(int id) - { - _Id = id; - } - - virtual void ResetUserData() - { - userdata = NULL; - } +class WEdge { + protected: + WOEdge *_paOEdge; // first oriented edge + WOEdge *_pbOEdge; // second oriented edge + short _nOEdges; // number of oriented edges associated with this edge. (1 means border edge) + bool _Mark; // user-specified edge mark for feature edge detection + int _Id; // Identifier for the edge + + public: + void *userdata; // designed to store specific user data + + inline WEdge() + { + _paOEdge = NULL; + _pbOEdge = NULL; + _nOEdges = 0; + userdata = NULL; + } + + inline WEdge(WOEdge *iOEdge) + { + _paOEdge = iOEdge; + _pbOEdge = NULL; + _nOEdges = 1; + userdata = NULL; + } + + inline WEdge(WOEdge *iaOEdge, WOEdge *ibOEdge) + { + _paOEdge = iaOEdge; + _pbOEdge = ibOEdge; + _nOEdges = 2; + userdata = NULL; + } + + /*! Copy constructor */ + WEdge(WEdge &iBrother); + virtual WEdge *duplicate(); + + virtual ~WEdge() + { + if (_paOEdge) { + delete _paOEdge; + _paOEdge = NULL; + } + + if (_pbOEdge) { + delete _pbOEdge; + _pbOEdge = NULL; + } + } + + /*! checks whether two WEdge have a common vertex. + * Returns a pointer on the common vertex if it exists, NULL otherwise. + */ + static inline WVertex *CommonVertex(WEdge *iEdge1, WEdge *iEdge2) + { + if (!iEdge1 || !iEdge2) + return NULL; + + WVertex *wv1 = iEdge1->GetaOEdge()->GetaVertex(); + WVertex *wv2 = iEdge1->GetaOEdge()->GetbVertex(); + WVertex *wv3 = iEdge2->GetaOEdge()->GetaVertex(); + WVertex *wv4 = iEdge2->GetaOEdge()->GetbVertex(); + + if ((wv1 == wv3) || (wv1 == wv4)) { + return wv1; + } + else if ((wv2 == wv3) || (wv2 == wv4)) { + return wv2; + } + return NULL; + } + + /*! accessors */ + inline WOEdge *GetaOEdge() + { + return _paOEdge; + } + + inline WOEdge *GetbOEdge() + { + return _pbOEdge; + } + + inline short GetNumberOfOEdges() + { + return _nOEdges; + } + + inline bool GetMark() + { + return _Mark; + } + + inline int GetId() + { + return _Id; + } + + inline WVertex *GetaVertex() + { + return _paOEdge->GetaVertex(); + } + + inline WVertex *GetbVertex() + { + return _paOEdge->GetbVertex(); + } + + inline WFace *GetaFace() + { + return _paOEdge->GetaFace(); + } + + inline WFace *GetbFace() + { + return _paOEdge->GetbFace(); + } + + inline WOEdge *GetOtherOEdge(WOEdge *iOEdge) + { + if (iOEdge == _paOEdge) + return _pbOEdge; + else + return _paOEdge; + } + + /*! modifiers */ + inline void setaOEdge(WOEdge *iEdge) + { + _paOEdge = iEdge; + } + + inline void setbOEdge(WOEdge *iEdge) + { + _pbOEdge = iEdge; + } + + inline void AddOEdge(WOEdge *iEdge) + { + if (!_paOEdge) { + _paOEdge = iEdge; + _nOEdges++; + return; + } + if (!_pbOEdge) { + _pbOEdge = iEdge; + _nOEdges++; + return; + } + } + + inline void setNumberOfOEdges(short n) + { + _nOEdges = n; + } + + inline void setMark(bool mark) + { + _Mark = mark; + } + + inline void setId(int id) + { + _Id = id; + } + + virtual void ResetUserData() + { + userdata = NULL; + } #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WEdge") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WEdge") #endif }; - /********************************** * * * * @@ -727,281 +729,287 @@ public: * * **********************************/ - -class WFace -{ -protected: - vector _OEdgeList; // list of oriented edges of bording the face - Vec3f _Normal; // normal to the face - // in case there is a normal per vertex. - // The normal number i corresponds to the aVertex of the oedge number i, for that face - vector _VerticesNormals; - vector _VerticesTexCoords; - - int _Id; - unsigned _FrsMaterialIndex; - bool _Mark; // Freestyle face mark (if true, feature edges on this face are ignored) - -public: - void *userdata; - inline WFace() - { - userdata = NULL; - _FrsMaterialIndex = 0; - } - - /*! copy constructor */ - WFace(WFace& iBrother); - virtual WFace *duplicate(); - virtual ~WFace() {} - - /*! accessors */ - inline const vector& getEdgeList() - { - return _OEdgeList; - } - - inline WOEdge *GetOEdge(int i) - { - return _OEdgeList[i]; - } - - inline Vec3f& GetNormal() - { - return _Normal; - } - - inline int GetId() - { - return _Id; - } - - inline unsigned frs_materialIndex() const - { - return _FrsMaterialIndex; - } - - inline bool GetMark() const - { - return _Mark; - } - - const FrsMaterial& frs_material(); - - /*! The vertex of index i corresponds to the a vertex of the edge of index i */ - inline WVertex *GetVertex(unsigned int index) - { +class WFace { + protected: + vector _OEdgeList; // list of oriented edges of bording the face + Vec3f _Normal; // normal to the face + // in case there is a normal per vertex. + // The normal number i corresponds to the aVertex of the oedge number i, for that face + vector _VerticesNormals; + vector _VerticesTexCoords; + + int _Id; + unsigned _FrsMaterialIndex; + bool _Mark; // Freestyle face mark (if true, feature edges on this face are ignored) + + public: + void *userdata; + inline WFace() + { + userdata = NULL; + _FrsMaterialIndex = 0; + } + + /*! copy constructor */ + WFace(WFace &iBrother); + virtual WFace *duplicate(); + virtual ~WFace() + { + } + + /*! accessors */ + inline const vector &getEdgeList() + { + return _OEdgeList; + } + + inline WOEdge *GetOEdge(int i) + { + return _OEdgeList[i]; + } + + inline Vec3f &GetNormal() + { + return _Normal; + } + + inline int GetId() + { + return _Id; + } + + inline unsigned frs_materialIndex() const + { + return _FrsMaterialIndex; + } + + inline bool GetMark() const + { + return _Mark; + } + + const FrsMaterial &frs_material(); + + /*! The vertex of index i corresponds to the a vertex of the edge of index i */ + inline WVertex *GetVertex(unsigned int index) + { #if 0 - if (index >= _OEdgeList.size()) - return NULL; + if (index >= _OEdgeList.size()) + return NULL; #endif - return _OEdgeList[index]->GetaVertex(); - } - - /*! returns the index at which iVertex is stored in the array. - * returns -1 if iVertex doesn't belong to the face. - */ - inline int GetIndex(WVertex *iVertex) - { - int index = 0; - for (vector::iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end(); woe != woend; woe++) { - if ((*woe)->GetaVertex() == iVertex) - return index; - ++index; - } - return -1; - } - - inline void RetrieveVertexList(vector& oVertices) - { - for (vector::iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end(); woe != woend; woe++) { - oVertices.push_back((*woe)->GetaVertex()); - } - } - - inline void RetrieveBorderFaces(vector& oWFaces) - { - for (vector::iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end(); woe != woend; woe++) { - WFace *af; - if ((af = (*woe)->GetaFace())) - oWFaces.push_back(af); - } - } - - inline WFace *GetBordingFace(int index) - { + return _OEdgeList[index]->GetaVertex(); + } + + /*! returns the index at which iVertex is stored in the array. + * returns -1 if iVertex doesn't belong to the face. + */ + inline int GetIndex(WVertex *iVertex) + { + int index = 0; + for (vector::iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end(); + woe != woend; + woe++) { + if ((*woe)->GetaVertex() == iVertex) + return index; + ++index; + } + return -1; + } + + inline void RetrieveVertexList(vector &oVertices) + { + for (vector::iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end(); + woe != woend; + woe++) { + oVertices.push_back((*woe)->GetaVertex()); + } + } + + inline void RetrieveBorderFaces(vector &oWFaces) + { + for (vector::iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end(); + woe != woend; + woe++) { + WFace *af; + if ((af = (*woe)->GetaFace())) + oWFaces.push_back(af); + } + } + + inline WFace *GetBordingFace(int index) + { #if 0 - if (index >= _OEdgeList.size()) - return NULL; + if (index >= _OEdgeList.size()) + return NULL; #endif - return _OEdgeList[index]->GetaFace(); - } - - inline WFace *GetBordingFace(WOEdge *iOEdge) - { - return iOEdge->GetaFace(); - } - - inline vector& GetPerVertexNormals() - { - return _VerticesNormals; - } - - inline vector& GetPerVertexTexCoords() - { - return _VerticesTexCoords; - } - - /*! Returns the normal of the vertex of index index */ - inline Vec3f& GetVertexNormal(int index) - { - return _VerticesNormals[index]; - } - - /*! Returns the tex coords of the vertex of index index */ - inline Vec2f& GetVertexTexCoords(int index) - { - return _VerticesTexCoords[index]; - } - - /*! Returns the normal of the vertex iVertex for that face */ - inline Vec3f& GetVertexNormal(WVertex *iVertex) - { - int i = 0; - int index = 0; - for (vector::const_iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end(); woe != woend; woe++) { - if ((*woe)->GetaVertex() == iVertex) { - index = i; - break; - } - ++i; - } - - return _VerticesNormals[index]; - } - - inline WOEdge *GetNextOEdge(WOEdge *iOEdge) - { - bool found = false; - vector::iterator woe, woend, woefirst; - woefirst = _OEdgeList.begin(); - for (woe = woefirst, woend = _OEdgeList.end(); woe != woend; ++woe) { - if (found) - return (*woe); - - if ((*woe) == iOEdge) { - found = true; - } - } - - // We left the loop. That means that the first OEdge was the good one: - if (found) - return (*woefirst); - - return NULL; - } - - WOEdge *GetPrevOEdge(WOEdge *iOEdge); - - inline int numberOfEdges() const - { - return _OEdgeList.size(); - } - - inline int numberOfVertices() const - { - return _OEdgeList.size(); - } - - /*! Returns true if the face has one ot its edge which is a border edge */ - inline bool isBorder() const - { - for (vector::const_iterator woe = _OEdgeList.begin(), woeend = _OEdgeList.end(); - woe != woeend; - ++woe) - { - if ((*woe)->GetOwner()->GetbOEdge() == 0) - return true; - } - return false; - } - - /*! modifiers */ - inline void setEdgeList(const vector& iEdgeList) - { - _OEdgeList = iEdgeList; - } - - inline void setNormal(const Vec3f& iNormal) - { - _Normal = iNormal; - } - - inline void setNormalList(const vector& iNormalsList) - { - _VerticesNormals = iNormalsList; - } - - inline void setTexCoordsList(const vector& iTexCoordsList) - { - _VerticesTexCoords = iTexCoordsList; - } - - inline void setId(int id) - { - _Id = id; - } - - inline void setFrsMaterialIndex(unsigned iMaterialIndex) - { - _FrsMaterialIndex = iMaterialIndex; - } - - inline void setMark(bool iMark) - { - _Mark = iMark; - } - - /*! designed to build a specialized WEdge for use in MakeEdge */ - virtual WEdge *instanciateEdge() const - { - return new WEdge; - } - - /*! Builds an oriented edge - * Returns the built edge. - * v1, v2 - * Vertices at the edge's extremities - * The edge is oriented from v1 to v2. - */ - virtual WOEdge *MakeEdge(WVertex *v1, WVertex *v2); - - /*! Adds an edge to the edges list */ - inline void AddEdge(WOEdge *iEdge) - { - _OEdgeList.push_back(iEdge); - } - - /*! For triangles, returns the edge opposite to the vertex in e. - * returns false if the face is not a triangle or if the vertex is not found - */ - bool getOppositeEdge (const WVertex *v, WOEdge *&e); - - /*! compute the area of the face */ - float getArea (); - - WShape *getShape(); - virtual void ResetUserData() - { - userdata = NULL; - } + return _OEdgeList[index]->GetaFace(); + } + + inline WFace *GetBordingFace(WOEdge *iOEdge) + { + return iOEdge->GetaFace(); + } + + inline vector &GetPerVertexNormals() + { + return _VerticesNormals; + } + + inline vector &GetPerVertexTexCoords() + { + return _VerticesTexCoords; + } + + /*! Returns the normal of the vertex of index index */ + inline Vec3f &GetVertexNormal(int index) + { + return _VerticesNormals[index]; + } + + /*! Returns the tex coords of the vertex of index index */ + inline Vec2f &GetVertexTexCoords(int index) + { + return _VerticesTexCoords[index]; + } + + /*! Returns the normal of the vertex iVertex for that face */ + inline Vec3f &GetVertexNormal(WVertex *iVertex) + { + int i = 0; + int index = 0; + for (vector::const_iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end(); + woe != woend; + woe++) { + if ((*woe)->GetaVertex() == iVertex) { + index = i; + break; + } + ++i; + } + + return _VerticesNormals[index]; + } + + inline WOEdge *GetNextOEdge(WOEdge *iOEdge) + { + bool found = false; + vector::iterator woe, woend, woefirst; + woefirst = _OEdgeList.begin(); + for (woe = woefirst, woend = _OEdgeList.end(); woe != woend; ++woe) { + if (found) + return (*woe); + + if ((*woe) == iOEdge) { + found = true; + } + } + + // We left the loop. That means that the first OEdge was the good one: + if (found) + return (*woefirst); + + return NULL; + } + + WOEdge *GetPrevOEdge(WOEdge *iOEdge); + + inline int numberOfEdges() const + { + return _OEdgeList.size(); + } + + inline int numberOfVertices() const + { + return _OEdgeList.size(); + } + + /*! Returns true if the face has one ot its edge which is a border edge */ + inline bool isBorder() const + { + for (vector::const_iterator woe = _OEdgeList.begin(), woeend = _OEdgeList.end(); + woe != woeend; + ++woe) { + if ((*woe)->GetOwner()->GetbOEdge() == 0) + return true; + } + return false; + } + + /*! modifiers */ + inline void setEdgeList(const vector &iEdgeList) + { + _OEdgeList = iEdgeList; + } + + inline void setNormal(const Vec3f &iNormal) + { + _Normal = iNormal; + } + + inline void setNormalList(const vector &iNormalsList) + { + _VerticesNormals = iNormalsList; + } + + inline void setTexCoordsList(const vector &iTexCoordsList) + { + _VerticesTexCoords = iTexCoordsList; + } + + inline void setId(int id) + { + _Id = id; + } + + inline void setFrsMaterialIndex(unsigned iMaterialIndex) + { + _FrsMaterialIndex = iMaterialIndex; + } + + inline void setMark(bool iMark) + { + _Mark = iMark; + } + + /*! designed to build a specialized WEdge for use in MakeEdge */ + virtual WEdge *instanciateEdge() const + { + return new WEdge; + } + + /*! Builds an oriented edge + * Returns the built edge. + * v1, v2 + * Vertices at the edge's extremities + * The edge is oriented from v1 to v2. + */ + virtual WOEdge *MakeEdge(WVertex *v1, WVertex *v2); + + /*! Adds an edge to the edges list */ + inline void AddEdge(WOEdge *iEdge) + { + _OEdgeList.push_back(iEdge); + } + + /*! For triangles, returns the edge opposite to the vertex in e. + * returns false if the face is not a triangle or if the vertex is not found + */ + bool getOppositeEdge(const WVertex *v, WOEdge *&e); + + /*! compute the area of the face */ + float getArea(); + + WShape *getShape(); + virtual void ResetUserData() + { + userdata = NULL; + } #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WFace") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WFace") #endif }; - /********************************** * * * * @@ -1010,302 +1018,307 @@ public: * * **********************************/ - -class WShape -{ -protected: - vector _VertexList; - vector _EdgeList; - vector _FaceList; - int _Id; - string _Name; - string _LibraryPath; - static unsigned _SceneCurrentId; +class WShape { + protected: + vector _VertexList; + vector _EdgeList; + vector _FaceList; + int _Id; + string _Name; + string _LibraryPath; + static unsigned _SceneCurrentId; #if 0 - Vec3f _min; - Vec3f _max; + Vec3f _min; + Vec3f _max; #endif - vector _FrsMaterials; + vector _FrsMaterials; #if 0 - float _meanEdgeSize; + float _meanEdgeSize; #endif -public: - inline WShape() - { + public: + inline WShape() + { #if 0 - _meanEdgeSize = 0; + _meanEdgeSize = 0; #endif - _Id = _SceneCurrentId; - _SceneCurrentId++; - } - - /*! copy constructor */ - WShape(WShape& iBrother); - virtual WShape *duplicate(); - - virtual ~WShape() - { - if (_EdgeList.size() != 0) { - vector::iterator e; - for (e = _EdgeList.begin(); e != _EdgeList.end(); ++e) { - delete (*e); - } - _EdgeList.clear(); - } - - if (_VertexList.size() != 0) { - vector::iterator v; - for (v = _VertexList.begin(); v != _VertexList.end(); ++v) { - delete (*v); - } - _VertexList.clear(); - } - - if (_FaceList.size() != 0) { - vector::iterator f; - for (f = _FaceList.begin(); f != _FaceList.end(); ++f) { - delete (*f); - } - _FaceList.clear(); - } - } - - /*! accessors */ - inline vector& getEdgeList() - { - return _EdgeList; - } - - inline vector& getVertexList() - { - return _VertexList; - } - - inline vector& GetFaceList() - { - return _FaceList; - } - - inline unsigned GetId() - { - return _Id; - } + _Id = _SceneCurrentId; + _SceneCurrentId++; + } + + /*! copy constructor */ + WShape(WShape &iBrother); + virtual WShape *duplicate(); + + virtual ~WShape() + { + if (_EdgeList.size() != 0) { + vector::iterator e; + for (e = _EdgeList.begin(); e != _EdgeList.end(); ++e) { + delete (*e); + } + _EdgeList.clear(); + } + + if (_VertexList.size() != 0) { + vector::iterator v; + for (v = _VertexList.begin(); v != _VertexList.end(); ++v) { + delete (*v); + } + _VertexList.clear(); + } + + if (_FaceList.size() != 0) { + vector::iterator f; + for (f = _FaceList.begin(); f != _FaceList.end(); ++f) { + delete (*f); + } + _FaceList.clear(); + } + } + + /*! accessors */ + inline vector &getEdgeList() + { + return _EdgeList; + } + + inline vector &getVertexList() + { + return _VertexList; + } + + inline vector &GetFaceList() + { + return _FaceList; + } + + inline unsigned GetId() + { + return _Id; + } #if 0 - inline void bbox(Vec3f& min, Vec3f& max) - { - min = _min; - max = _max; - } + inline void bbox(Vec3f& min, Vec3f& max) + { + min = _min; + max = _max; + } #endif - inline const FrsMaterial& frs_material(unsigned i) const - { - return _FrsMaterials[i]; - } + inline const FrsMaterial &frs_material(unsigned i) const + { + return _FrsMaterials[i]; + } - inline const vector& frs_materials() const - { - return _FrsMaterials; - } + inline const vector &frs_materials() const + { + return _FrsMaterials; + } #if 0 - inline const float getMeanEdgeSize() const - { - return _meanEdgeSize; - } + inline const float getMeanEdgeSize() const + { + return _meanEdgeSize; + } #endif - inline const string& getName() const - { - return _Name; - } - - inline const string& getLibraryPath() const - { - return _LibraryPath; - } - - /*! modifiers */ - static inline void setCurrentId(const unsigned id) - { - _SceneCurrentId = id; - } - - inline void setEdgeList(const vector& iEdgeList) - { - _EdgeList = iEdgeList; - } - - inline void setVertexList(const vector& iVertexList) - { - _VertexList = iVertexList; - } - - inline void setFaceList(const vector& iFaceList) - { - _FaceList = iFaceList; - } - - inline void setId(int id) - { - _Id = id; - } + inline const string &getName() const + { + return _Name; + } + + inline const string &getLibraryPath() const + { + return _LibraryPath; + } + + /*! modifiers */ + static inline void setCurrentId(const unsigned id) + { + _SceneCurrentId = id; + } + + inline void setEdgeList(const vector &iEdgeList) + { + _EdgeList = iEdgeList; + } + + inline void setVertexList(const vector &iVertexList) + { + _VertexList = iVertexList; + } + + inline void setFaceList(const vector &iFaceList) + { + _FaceList = iFaceList; + } + + inline void setId(int id) + { + _Id = id; + } #if 0 - inline void setBBox(const Vec3f& min, const Vec3f& max) - { - _min = min; - _max = max; - } + inline void setBBox(const Vec3f& min, const Vec3f& max) + { + _min = min; + _max = max; + } #endif - inline void setFrsMaterial(const FrsMaterial& frs_material, unsigned i) - { - _FrsMaterials[i] = frs_material; - } - - inline void setFrsMaterials(const vector& iMaterials) - { - _FrsMaterials = iMaterials; - } - - inline void setName(const string& name) - { - _Name = name; - } - - inline void setLibraryPath(const string& path) - { - _LibraryPath = path; - } - - /*! designed to build a specialized WFace for use in MakeFace */ - virtual WFace *instanciateFace() const - { - return new WFace; - } - - /*! adds a new face to the shape - * returns the built face. - * iVertexList - * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed to be - * already stored when calling MakeFace. - * The order in which the vertices are stored in the list determines the face's edges orientation and (so) the - * face orientation. - * iMaterialIndex - * The material index for this face - */ - virtual WFace *MakeFace(vector& iVertexList, vector& iFaceEdgeMarksList, unsigned iMaterialIndex); - - /*! adds a new face to the shape. The difference with the previous method is that this one is designed - * to build a WingedEdge structure for which there are per vertex normals, opposed to per face normals. - * returns the built face. - * iVertexList - * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed to be - * already stored when calling MakeFace. - * The order in which the vertices are stored in the list determines the face's edges orientation and (so) the - * face orientation. - * iMaterialIndex - * The materialIndex for this face - * iNormalsList - * The list of normals, iNormalsList[i] corresponding to the normal of the vertex iVertexList[i] for that face. - * iTexCoordsList - * The list of tex coords, iTexCoordsList[i] corresponding to the normal of the vertex iVertexList[i] for - * that face. - */ - virtual WFace *MakeFace(vector& iVertexList, vector& iNormalsList, vector& iTexCoordsList, - vector& iFaceEdgeMarksList, unsigned iMaterialIndex); - - inline void AddEdge(WEdge *iEdge) - { - _EdgeList.push_back(iEdge); - } - - inline void AddFace(WFace *iFace) - { - _FaceList.push_back(iFace); - } - - inline void AddVertex(WVertex *iVertex) - { - iVertex->setShape(this); - _VertexList.push_back(iVertex); - } - - inline void ResetUserData() - { - for (vector::iterator v = _VertexList.begin(), vend = _VertexList.end(); v != vend; v++) { - (*v)->ResetUserData(); - } - - for (vector::iterator e = _EdgeList.begin(), eend = _EdgeList.end(); e != eend; e++) { - (*e)->ResetUserData(); - // manages WOEdge: - WOEdge *oe = (*e)->GetaOEdge(); - if (oe) - oe->ResetUserData(); - oe = (*e)->GetbOEdge(); - if (oe) - oe->ResetUserData(); - } - - for (vector::iterator f = _FaceList.begin(), fend = _FaceList.end(); f != fend; f++) { - (*f)->ResetUserData(); - } - } + inline void setFrsMaterial(const FrsMaterial &frs_material, unsigned i) + { + _FrsMaterials[i] = frs_material; + } + + inline void setFrsMaterials(const vector &iMaterials) + { + _FrsMaterials = iMaterials; + } + + inline void setName(const string &name) + { + _Name = name; + } + + inline void setLibraryPath(const string &path) + { + _LibraryPath = path; + } + + /*! designed to build a specialized WFace for use in MakeFace */ + virtual WFace *instanciateFace() const + { + return new WFace; + } + + /*! adds a new face to the shape + * returns the built face. + * iVertexList + * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed to be + * already stored when calling MakeFace. + * The order in which the vertices are stored in the list determines the face's edges orientation and (so) the + * face orientation. + * iMaterialIndex + * The material index for this face + */ + virtual WFace *MakeFace(vector &iVertexList, + vector &iFaceEdgeMarksList, + unsigned iMaterialIndex); + + /*! adds a new face to the shape. The difference with the previous method is that this one is designed + * to build a WingedEdge structure for which there are per vertex normals, opposed to per face normals. + * returns the built face. + * iVertexList + * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed to be + * already stored when calling MakeFace. + * The order in which the vertices are stored in the list determines the face's edges orientation and (so) the + * face orientation. + * iMaterialIndex + * The materialIndex for this face + * iNormalsList + * The list of normals, iNormalsList[i] corresponding to the normal of the vertex iVertexList[i] for that face. + * iTexCoordsList + * The list of tex coords, iTexCoordsList[i] corresponding to the normal of the vertex iVertexList[i] for + * that face. + */ + virtual WFace *MakeFace(vector &iVertexList, + vector &iNormalsList, + vector &iTexCoordsList, + vector &iFaceEdgeMarksList, + unsigned iMaterialIndex); + + inline void AddEdge(WEdge *iEdge) + { + _EdgeList.push_back(iEdge); + } + + inline void AddFace(WFace *iFace) + { + _FaceList.push_back(iFace); + } + + inline void AddVertex(WVertex *iVertex) + { + iVertex->setShape(this); + _VertexList.push_back(iVertex); + } + + inline void ResetUserData() + { + for (vector::iterator v = _VertexList.begin(), vend = _VertexList.end(); v != vend; + v++) { + (*v)->ResetUserData(); + } + + for (vector::iterator e = _EdgeList.begin(), eend = _EdgeList.end(); e != eend; e++) { + (*e)->ResetUserData(); + // manages WOEdge: + WOEdge *oe = (*e)->GetaOEdge(); + if (oe) + oe->ResetUserData(); + oe = (*e)->GetbOEdge(); + if (oe) + oe->ResetUserData(); + } + + for (vector::iterator f = _FaceList.begin(), fend = _FaceList.end(); f != fend; f++) { + (*f)->ResetUserData(); + } + } #if 0 - inline void ComputeBBox() - { - _min = _VertexList[0]->GetVertex(); - _max = _VertexList[0]->GetVertex(); - - Vec3f v; - for (vector::iterator wv = _VertexList.begin(), wvend = _VertexList.end(); wv != wvend; wv++) { - for (unsigned int i = 0; i < 3; i++) { - v = (*wv)->GetVertex(); - if (v[i] < _min[i]) - _min[i] = v[i]; - if (v[i] > _max[i]) - _max[i] = v[i]; - } - } - } + inline void ComputeBBox() + { + _min = _VertexList[0]->GetVertex(); + _max = _VertexList[0]->GetVertex(); + + Vec3f v; + for (vector::iterator wv = _VertexList.begin(), wvend = _VertexList.end(); wv != wvend; wv++) { + for (unsigned int i = 0; i < 3; i++) { + v = (*wv)->GetVertex(); + if (v[i] < _min[i]) + _min[i] = v[i]; + if (v[i] > _max[i]) + _max[i] = v[i]; + } + } + } #endif #if 0 - inline float ComputeMeanEdgeSize() - { - _meanEdgeSize = _meanEdgeSize / _EdgeList.size(); - return _meanEdgeSize; - } + inline float ComputeMeanEdgeSize() + { + _meanEdgeSize = _meanEdgeSize / _EdgeList.size(); + return _meanEdgeSize; + } #else - real ComputeMeanEdgeSize() const; + real ComputeMeanEdgeSize() const; #endif -protected: - /*! Builds the face passed as argument (which as already been allocated) - * iVertexList - * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed to be - * already stored when calling MakeFace. - * The order in which the vertices are stored in the list determines the face's edges orientation and (so) the - * face orientation. - * iMaterialIndex - * The material index for this face - * face - * The Face that is filled in - */ - virtual WFace *MakeFace(vector& iVertexList, vector& iFaceEdgeMarksList, unsigned iMaterialIndex, - WFace *face); + protected: + /*! Builds the face passed as argument (which as already been allocated) + * iVertexList + * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed to be + * already stored when calling MakeFace. + * The order in which the vertices are stored in the list determines the face's edges orientation and (so) the + * face orientation. + * iMaterialIndex + * The material index for this face + * face + * The Face that is filled in + */ + virtual WFace *MakeFace(vector &iVertexList, + vector &iFaceEdgeMarksList, + unsigned iMaterialIndex, + WFace *face); #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WShape") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WShape") #endif }; - /********************************** * * * * @@ -1314,53 +1327,51 @@ protected: * * **********************************/ -class WingedEdge -{ -public: - WingedEdge() { - _numFaces = 0; - } - - ~WingedEdge() - { - clear(); - } - - void clear() - { - for (vector::iterator it = _wshapes.begin(); it != _wshapes.end(); it++) - delete *it; - _wshapes.clear(); - _numFaces = 0; - } - - void addWShape(WShape *wshape) - { - _wshapes.push_back(wshape); - _numFaces += wshape->GetFaceList().size(); - } - - vector& getWShapes() - { - return _wshapes; - } - - unsigned getNumFaces() - { - return _numFaces; - } - -private: - vector _wshapes; - unsigned _numFaces; +class WingedEdge { + public: + WingedEdge() + { + _numFaces = 0; + } + + ~WingedEdge() + { + clear(); + } + + void clear() + { + for (vector::iterator it = _wshapes.begin(); it != _wshapes.end(); it++) + delete *it; + _wshapes.clear(); + _numFaces = 0; + } + + void addWShape(WShape *wshape) + { + _wshapes.push_back(wshape); + _numFaces += wshape->GetFaceList().size(); + } + + vector &getWShapes() + { + return _wshapes; + } + + unsigned getNumFaces() + { + return _numFaces; + } + + private: + vector _wshapes; + unsigned _numFaces; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WingedEdge") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WingedEdge") #endif }; - - /* * ############################################# * ############################################# @@ -1373,35 +1384,35 @@ private: * ############################################# */ /* for inline functions */ -void WOEdge::RetrieveCWOrderedEdges(vector& oEdges) +void WOEdge::RetrieveCWOrderedEdges(vector &oEdges) { - WOEdge *currentOEdge = this; - do { - WOEdge *nextOEdge = currentOEdge->GetbFace()->GetNextOEdge(currentOEdge); - oEdges.push_back(nextOEdge->GetOwner()); - currentOEdge = nextOEdge->GetOwner()->GetOtherOEdge(nextOEdge); - } while (currentOEdge && (currentOEdge->GetOwner() != GetOwner())); + WOEdge *currentOEdge = this; + do { + WOEdge *nextOEdge = currentOEdge->GetbFace()->GetNextOEdge(currentOEdge); + oEdges.push_back(nextOEdge->GetOwner()); + currentOEdge = nextOEdge->GetOwner()->GetOtherOEdge(nextOEdge); + } while (currentOEdge && (currentOEdge->GetOwner() != GetOwner())); } inline void WOEdge::setVecAndAngle() { - if (_paVertex && _pbVertex) { - _vec = _pbVertex->GetVertex() - _paVertex->GetVertex(); - if (_paFace && _pbFace) { - float sine = (_pbFace->GetNormal() ^ _paFace->GetNormal()) * _vec / _vec.norm(); - if (sine >= 1.0) { - _angle = M_PI / 2.0; - return; - } - if (sine <= -1.0) { - _angle = -M_PI / 2.0; - return; - } - _angle = ::asin(sine); - } - } + if (_paVertex && _pbVertex) { + _vec = _pbVertex->GetVertex() - _paVertex->GetVertex(); + if (_paFace && _pbFace) { + float sine = (_pbFace->GetNormal() ^ _paFace->GetNormal()) * _vec / _vec.norm(); + if (sine >= 1.0) { + _angle = M_PI / 2.0; + return; + } + if (sine <= -1.0) { + _angle = -M_PI / 2.0; + return; + } + _angle = ::asin(sine); + } + } } } /* namespace Freestyle */ -#endif // __FREESTYLE_W_EDGE_H__ +#endif // __FREESTYLE_W_EDGE_H__ diff --git a/source/blender/freestyle/intern/winged_edge/WFillGrid.cpp b/source/blender/freestyle/intern/winged_edge/WFillGrid.cpp index ea5e7dcc504..8106bcedd0c 100644 --- a/source/blender/freestyle/intern/winged_edge/WFillGrid.cpp +++ b/source/blender/freestyle/intern/winged_edge/WFillGrid.cpp @@ -26,33 +26,33 @@ namespace Freestyle { void WFillGrid::fillGrid() { - if (!_winged_edge || !_grid) - return; - - vector wshapes = _winged_edge->getWShapes(); - vector fvertices; - vector vectors; - vector faces; - - for (vector::const_iterator it = wshapes.begin(); it != wshapes.end(); ++it) { - faces = (*it)->GetFaceList(); - - for (vector::const_iterator f = faces.begin(); f != faces.end(); ++f) { - (*f)->RetrieveVertexList(fvertices); - - for (vector::const_iterator wv = fvertices.begin(); wv != fvertices.end(); ++wv) - vectors.push_back(Vec3r((*wv)->GetVertex())); - - // occluder will be deleted by the grid - Polygon3r *occluder = new Polygon3r(vectors, (*f)->GetNormal()); - occluder->setId(_polygon_id++); - occluder->userdata = (void *)(*f); - _grid->insertOccluder(occluder); - vectors.clear(); - fvertices.clear(); - } - faces.clear(); - } + if (!_winged_edge || !_grid) + return; + + vector wshapes = _winged_edge->getWShapes(); + vector fvertices; + vector vectors; + vector faces; + + for (vector::const_iterator it = wshapes.begin(); it != wshapes.end(); ++it) { + faces = (*it)->GetFaceList(); + + for (vector::const_iterator f = faces.begin(); f != faces.end(); ++f) { + (*f)->RetrieveVertexList(fvertices); + + for (vector::const_iterator wv = fvertices.begin(); wv != fvertices.end(); ++wv) + vectors.push_back(Vec3r((*wv)->GetVertex())); + + // occluder will be deleted by the grid + Polygon3r *occluder = new Polygon3r(vectors, (*f)->GetNormal()); + occluder->setId(_polygon_id++); + occluder->userdata = (void *)(*f); + _grid->insertOccluder(occluder); + vectors.clear(); + fvertices.clear(); + } + faces.clear(); + } } } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/winged_edge/WFillGrid.h b/source/blender/freestyle/intern/winged_edge/WFillGrid.h index 0e86d1a1684..f9e63464e30 100644 --- a/source/blender/freestyle/intern/winged_edge/WFillGrid.h +++ b/source/blender/freestyle/intern/winged_edge/WFillGrid.h @@ -28,59 +28,60 @@ #include "../geometry/Polygon.h" #ifdef WITH_CXX_GUARDEDALLOC -#include "MEM_guardedalloc.h" +# include "MEM_guardedalloc.h" #endif namespace Freestyle { -class WFillGrid -{ -public: - inline WFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL) - { - _winged_edge = winged_edge; - _grid = grid; - _polygon_id = 0; - } - - virtual ~WFillGrid() {} - - void fillGrid(); - - /*! Accessors */ - WingedEdge *getWingedEdge() - { - return _winged_edge; - } - - Grid *getGrid() - { - return _grid; - } - - /*! Modifiers */ - void setWingedEdge(WingedEdge *winged_edge) - { - if (winged_edge) - _winged_edge = winged_edge; - } - - void setGrid(Grid *grid) - { - if (grid) - _grid = grid; - } - -private: - Grid *_grid; - WingedEdge *_winged_edge; - unsigned _polygon_id; +class WFillGrid { + public: + inline WFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL) + { + _winged_edge = winged_edge; + _grid = grid; + _polygon_id = 0; + } + + virtual ~WFillGrid() + { + } + + void fillGrid(); + + /*! Accessors */ + WingedEdge *getWingedEdge() + { + return _winged_edge; + } + + Grid *getGrid() + { + return _grid; + } + + /*! Modifiers */ + void setWingedEdge(WingedEdge *winged_edge) + { + if (winged_edge) + _winged_edge = winged_edge; + } + + void setGrid(Grid *grid) + { + if (grid) + _grid = grid; + } + + private: + Grid *_grid; + WingedEdge *_winged_edge; + unsigned _polygon_id; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WFillGrid") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WFillGrid") #endif }; } /* namespace Freestyle */ -#endif // __FREESTYLE_W_FILL_GRID_H__ +#endif // __FREESTYLE_W_FILL_GRID_H__ diff --git a/source/blender/freestyle/intern/winged_edge/WSFillGrid.cpp b/source/blender/freestyle/intern/winged_edge/WSFillGrid.cpp index 4ef3f6a775f..cd13775239b 100644 --- a/source/blender/freestyle/intern/winged_edge/WSFillGrid.cpp +++ b/source/blender/freestyle/intern/winged_edge/WSFillGrid.cpp @@ -26,33 +26,33 @@ namespace Freestyle { void WSFillGrid::fillGrid() { - if (!_winged_edge || !_grid) - return; - - vector wshapes = _winged_edge->getWShapes(); - vector fvertices; - vector vectors; - vector faces; - - for (vector::const_iterator it = wshapes.begin(); it != wshapes.end(); ++it) { - faces = (*it)->GetFaceList(); - - for (vector::const_iterator f = faces.begin(); f != faces.end(); ++f) { - (*f)->RetrieveVertexList(fvertices); - - for (vector::const_iterator wv = fvertices.begin(); wv != fvertices.end(); ++wv) - vectors.push_back(Vec3r((*wv)->GetVertex())); - - // occluder will be deleted by the grid - Polygon3r *occluder = new Polygon3r(vectors, (*f)->GetNormal()); - occluder->setId(_polygon_id++); - occluder->userdata = (void *)(*f); - _grid->insertOccluder(occluder); - vectors.clear(); - fvertices.clear(); - } - faces.clear(); - } + if (!_winged_edge || !_grid) + return; + + vector wshapes = _winged_edge->getWShapes(); + vector fvertices; + vector vectors; + vector faces; + + for (vector::const_iterator it = wshapes.begin(); it != wshapes.end(); ++it) { + faces = (*it)->GetFaceList(); + + for (vector::const_iterator f = faces.begin(); f != faces.end(); ++f) { + (*f)->RetrieveVertexList(fvertices); + + for (vector::const_iterator wv = fvertices.begin(); wv != fvertices.end(); ++wv) + vectors.push_back(Vec3r((*wv)->GetVertex())); + + // occluder will be deleted by the grid + Polygon3r *occluder = new Polygon3r(vectors, (*f)->GetNormal()); + occluder->setId(_polygon_id++); + occluder->userdata = (void *)(*f); + _grid->insertOccluder(occluder); + vectors.clear(); + fvertices.clear(); + } + faces.clear(); + } } } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/winged_edge/WSFillGrid.h b/source/blender/freestyle/intern/winged_edge/WSFillGrid.h index 9648c3bab07..2d8ac77a15d 100644 --- a/source/blender/freestyle/intern/winged_edge/WSFillGrid.h +++ b/source/blender/freestyle/intern/winged_edge/WSFillGrid.h @@ -29,55 +29,55 @@ namespace Freestyle { -class WSFillGrid -{ -public: - inline WSFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL) - { - _winged_edge = winged_edge; - _grid = grid; - _polygon_id = 0; - } - - virtual ~WSFillGrid() {} - - void fillGrid(); - - /*! Accessors */ - WingedEdge *getWingedEdge() - { - return _winged_edge; - } - - Grid *getGrid() - { - return _grid; - } - - /*! Modifiers */ - void setWingedEdge(WingedEdge *winged_edge) - { - if (winged_edge) - _winged_edge = winged_edge; - } - - void setGrid(Grid *grid) - { - if (grid) - _grid = grid; - } - -private: - Grid *_grid; - WingedEdge *_winged_edge; - unsigned _polygon_id; +class WSFillGrid { + public: + inline WSFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL) + { + _winged_edge = winged_edge; + _grid = grid; + _polygon_id = 0; + } + + virtual ~WSFillGrid() + { + } + + void fillGrid(); + + /*! Accessors */ + WingedEdge *getWingedEdge() + { + return _winged_edge; + } + + Grid *getGrid() + { + return _grid; + } + + /*! Modifiers */ + void setWingedEdge(WingedEdge *winged_edge) + { + if (winged_edge) + _winged_edge = winged_edge; + } + + void setGrid(Grid *grid) + { + if (grid) + _grid = grid; + } + + private: + Grid *_grid; + WingedEdge *_winged_edge; + unsigned _polygon_id; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WSFillGrid") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WSFillGrid") #endif - }; } /* namespace Freestyle */ -#endif // __FREESTYLE_WS_FILL_GRID_H__ +#endif // __FREESTYLE_WS_FILL_GRID_H__ diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.cpp b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp index 611d7b3a7cf..fcac2b386ea 100644 --- a/source/blender/freestyle/intern/winged_edge/WXEdge.cpp +++ b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp @@ -34,218 +34,219 @@ namespace Freestyle { unsigned int WXFaceLayer::Get0VertexIndex() const { - int i = 0; - int nEdges = _pWXFace->numberOfEdges(); - for (i = 0; i < nEdges; ++i) { - if (_DotP[i] == 0.0f) { // TODO this comparison is weak, check if it actually works - return i; - } - } - return -1; + int i = 0; + int nEdges = _pWXFace->numberOfEdges(); + for (i = 0; i < nEdges; ++i) { + if (_DotP[i] == 0.0f) { // TODO this comparison is weak, check if it actually works + return i; + } + } + return -1; } unsigned int WXFaceLayer::GetSmoothEdgeIndex() const { - int i = 0; - int nEdges = _pWXFace->numberOfEdges(); - for (i = 0; i < nEdges; ++i) { - if ((_DotP[i] == 0.0f) && (_DotP[(i + 1) % nEdges] == 0.0f)) { // TODO ditto - return i; - } - } - return -1; + int i = 0; + int nEdges = _pWXFace->numberOfEdges(); + for (i = 0; i < nEdges; ++i) { + if ((_DotP[i] == 0.0f) && (_DotP[(i + 1) % nEdges] == 0.0f)) { // TODO ditto + return i; + } + } + return -1; } -void WXFaceLayer::RetrieveCuspEdgesIndices(vector& oCuspEdges) +void WXFaceLayer::RetrieveCuspEdgesIndices(vector &oCuspEdges) { - int i = 0; - int nEdges = _pWXFace->numberOfEdges(); - for (i = 0; i < nEdges; ++i) { - if (_DotP[i] * _DotP[(i + 1) % nEdges] < 0.0f) { - // we got one - oCuspEdges.push_back(i); - } - } + int i = 0; + int nEdges = _pWXFace->numberOfEdges(); + for (i = 0; i < nEdges; ++i) { + if (_DotP[i] * _DotP[(i + 1) % nEdges] < 0.0f) { + // we got one + oCuspEdges.push_back(i); + } + } } WXSmoothEdge *WXFaceLayer::BuildSmoothEdge() { - // if the smooth edge has already been built: exit - if (_pSmoothEdge) - return _pSmoothEdge; - float ta, tb; - WOEdge *woea(0), *woeb(0); - bool ok = false; - vector cuspEdgesIndices; - int indexStart, indexEnd; - unsigned nedges = _pWXFace->numberOfEdges(); - if (_nNullDotP == nedges) { - _pSmoothEdge = NULL; - return _pSmoothEdge; - } - if ((_nPosDotP != 0) && (_nPosDotP != _DotP.size()) && (_nNullDotP == 0)) { - // that means that we have a smooth edge that starts from an edge and ends at an edge - //----------------------------- - // We retrieve the 2 edges for which we have opposite signs for each extremity - RetrieveCuspEdgesIndices(cuspEdgesIndices); - if (cuspEdgesIndices.size() != 2) // we necessarly have 2 cusp edges - return 0; + // if the smooth edge has already been built: exit + if (_pSmoothEdge) + return _pSmoothEdge; + float ta, tb; + WOEdge *woea(0), *woeb(0); + bool ok = false; + vector cuspEdgesIndices; + int indexStart, indexEnd; + unsigned nedges = _pWXFace->numberOfEdges(); + if (_nNullDotP == nedges) { + _pSmoothEdge = NULL; + return _pSmoothEdge; + } + if ((_nPosDotP != 0) && (_nPosDotP != _DotP.size()) && (_nNullDotP == 0)) { + // that means that we have a smooth edge that starts from an edge and ends at an edge + //----------------------------- + // We retrieve the 2 edges for which we have opposite signs for each extremity + RetrieveCuspEdgesIndices(cuspEdgesIndices); + if (cuspEdgesIndices.size() != 2) // we necessarly have 2 cusp edges + return 0; - // let us determine which cusp edge corresponds to the starting: - // We can do that because we defined that a silhouette edge had the back facing part on its right. - // So if the WOEdge woea is such that woea[0].dotp > 0 and woea[1].dotp < 0, it is the starting edge. - //------------------------------------------- + // let us determine which cusp edge corresponds to the starting: + // We can do that because we defined that a silhouette edge had the back facing part on its right. + // So if the WOEdge woea is such that woea[0].dotp > 0 and woea[1].dotp < 0, it is the starting edge. + //------------------------------------------- - if (_DotP[cuspEdgesIndices[0]] > 0.0f) { - woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]); - woeb = _pWXFace->GetOEdge(cuspEdgesIndices[1]); - indexStart = cuspEdgesIndices[0]; - indexEnd = cuspEdgesIndices[1]; - } - else { - woea = _pWXFace->GetOEdge(cuspEdgesIndices[1]); - woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]); - indexStart = cuspEdgesIndices[1]; - indexEnd = cuspEdgesIndices[0]; - } + if (_DotP[cuspEdgesIndices[0]] > 0.0f) { + woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]); + woeb = _pWXFace->GetOEdge(cuspEdgesIndices[1]); + indexStart = cuspEdgesIndices[0]; + indexEnd = cuspEdgesIndices[1]; + } + else { + woea = _pWXFace->GetOEdge(cuspEdgesIndices[1]); + woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]); + indexStart = cuspEdgesIndices[1]; + indexEnd = cuspEdgesIndices[0]; + } - // Compute the interpolation: - ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]); - tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]); - ok = true; - } - else if (_nNullDotP == 1) { - // that means that we have exactly one of the 2 extremities of our silhouette edge is a vertex of the mesh - if ((_nPosDotP == 2) || (_nPosDotP == 0)) { - _pSmoothEdge = NULL; - return _pSmoothEdge; - } - RetrieveCuspEdgesIndices(cuspEdgesIndices); - // We should have only one EdgeCusp: - if (cuspEdgesIndices.size() != 1) { - if (G.debug & G_DEBUG_FREESTYLE) { - cout << "Warning in BuildSmoothEdge: weird WXFace configuration" << endl; - } - _pSmoothEdge = NULL; - return NULL; - } - unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index - unsigned nedges = _pWXFace->numberOfEdges(); - if (_DotP[cuspEdgesIndices[0]] > 0.0f) { - woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]); - woeb = _pWXFace->GetOEdge(index0); - indexStart = cuspEdgesIndices[0]; - ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]); - tb = 0.0f; - } - else { - woea = _pWXFace->GetOEdge(index0); - woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]); - indexEnd = cuspEdgesIndices[0]; - ta = 0.0f; - tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]); - } - ok = true; - } - else if (_nNullDotP == 2) { - // that means that the silhouette edge is an edge of the mesh - int index = GetSmoothEdgeIndex(); - if (!_pWXFace->front()) { // is it in the right order ? - // the order of the WOEdge index is wrong - woea = _pWXFace->GetOEdge((index + 1) % nedges); - woeb = _pWXFace->GetOEdge((index - 1) % nedges); - ta = 0.0f; - tb = 1.0f; - ok = true; - } - else { - // here it's not good, our edge is a single point -> skip that face - ok = false; + // Compute the interpolation: + ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]); + tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]); + ok = true; + } + else if (_nNullDotP == 1) { + // that means that we have exactly one of the 2 extremities of our silhouette edge is a vertex of the mesh + if ((_nPosDotP == 2) || (_nPosDotP == 0)) { + _pSmoothEdge = NULL; + return _pSmoothEdge; + } + RetrieveCuspEdgesIndices(cuspEdgesIndices); + // We should have only one EdgeCusp: + if (cuspEdgesIndices.size() != 1) { + if (G.debug & G_DEBUG_FREESTYLE) { + cout << "Warning in BuildSmoothEdge: weird WXFace configuration" << endl; + } + _pSmoothEdge = NULL; + return NULL; + } + unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index + unsigned nedges = _pWXFace->numberOfEdges(); + if (_DotP[cuspEdgesIndices[0]] > 0.0f) { + woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]); + woeb = _pWXFace->GetOEdge(index0); + indexStart = cuspEdgesIndices[0]; + ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]); + tb = 0.0f; + } + else { + woea = _pWXFace->GetOEdge(index0); + woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]); + indexEnd = cuspEdgesIndices[0]; + ta = 0.0f; + tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]); + } + ok = true; + } + else if (_nNullDotP == 2) { + // that means that the silhouette edge is an edge of the mesh + int index = GetSmoothEdgeIndex(); + if (!_pWXFace->front()) { // is it in the right order ? + // the order of the WOEdge index is wrong + woea = _pWXFace->GetOEdge((index + 1) % nedges); + woeb = _pWXFace->GetOEdge((index - 1) % nedges); + ta = 0.0f; + tb = 1.0f; + ok = true; + } + else { + // here it's not good, our edge is a single point -> skip that face + ok = false; #if 0 - // the order of the WOEdge index is good - woea = _pWXFace->GetOEdge((index - 1) % nedges); - woeb = _pWXFace->GetOEdge((index + 1) % nedges); - ta = 1.0f; - tb = 0.0f; + // the order of the WOEdge index is good + woea = _pWXFace->GetOEdge((index - 1) % nedges); + woeb = _pWXFace->GetOEdge((index + 1) % nedges); + ta = 1.0f; + tb = 0.0f; #endif - } - } - if (ok) { - _pSmoothEdge = new WXSmoothEdge; - _pSmoothEdge->setWOeA(woea); - _pSmoothEdge->setWOeB(woeb); - _pSmoothEdge->setTa(ta); - _pSmoothEdge->setTb(tb); - if (_Nature & Nature::SILHOUETTE) { - if (_nNullDotP != 2) { - if (_DotP[_ClosestPointIndex] + 0.01f > 0.0f) - _pSmoothEdge->setFront(true); - else - _pSmoothEdge->setFront(false); - } - } - } + } + } + if (ok) { + _pSmoothEdge = new WXSmoothEdge; + _pSmoothEdge->setWOeA(woea); + _pSmoothEdge->setWOeB(woeb); + _pSmoothEdge->setTa(ta); + _pSmoothEdge->setTb(tb); + if (_Nature & Nature::SILHOUETTE) { + if (_nNullDotP != 2) { + if (_DotP[_ClosestPointIndex] + 0.01f > 0.0f) + _pSmoothEdge->setFront(true); + else + _pSmoothEdge->setFront(false); + } + } + } #if 0 - // check bording edges to see if they have different dotp values in bording faces. - for (int i = 0; i < numberOfEdges(); i++) { - WSFace *bface = (WSFace *)GetBordingFace(i); - if (bface) { - if ((front()) ^ (bface->front())) { // fA->front XOR fB->front (true if one is 0 and the other is 1) - // that means that the edge i of the face is a silhouette edge - // CHECK FIRST WHETHER THE EXACTSILHOUETTEEDGE HAS NOT YET BEEN BUILT ON THE OTHER FACE (1 is enough). - if (((WSExactFace *)bface)->exactSilhouetteEdge()) { - // that means that this silhouette edge has already been built - return ((WSExactFace *)bface)->exactSilhouetteEdge(); - } - // Else we must build it - WOEdge *woea, *woeb; - float ta, tb; - if (!front()) { // is it in the right order ? - // the order of the WOEdge index is wrong - woea = _OEdgeList[(i + 1) % numberOfEdges()]; - if (0 == i) - woeb = _OEdgeList[numberOfEdges() - 1]; - else - woeb = _OEdgeList[(i - 1)]; - ta = 0.0f; - tb = 1.0f; - } - else { - // the order of the WOEdge index is good - if (0 == i) - woea = _OEdgeList[numberOfEdges() - 1]; - else - woea = _OEdgeList[(i - 1)]; - woeb = _OEdgeList[(i + 1) % numberOfEdges()]; - ta = 1.0f; - tb = 0.0f; - } + // check bording edges to see if they have different dotp values in bording faces. + for (int i = 0; i < numberOfEdges(); i++) { + WSFace *bface = (WSFace *)GetBordingFace(i); + if (bface) { + if ((front()) ^ (bface->front())) { // fA->front XOR fB->front (true if one is 0 and the other is 1) + // that means that the edge i of the face is a silhouette edge + // CHECK FIRST WHETHER THE EXACTSILHOUETTEEDGE HAS NOT YET BEEN BUILT ON THE OTHER FACE (1 is enough). + if (((WSExactFace *)bface)->exactSilhouetteEdge()) { + // that means that this silhouette edge has already been built + return ((WSExactFace *)bface)->exactSilhouetteEdge(); + } + // Else we must build it + WOEdge *woea, *woeb; + float ta, tb; + if (!front()) { // is it in the right order ? + // the order of the WOEdge index is wrong + woea = _OEdgeList[(i + 1) % numberOfEdges()]; + if (0 == i) + woeb = _OEdgeList[numberOfEdges() - 1]; + else + woeb = _OEdgeList[(i - 1)]; + ta = 0.0f; + tb = 1.0f; + } + else { + // the order of the WOEdge index is good + if (0 == i) + woea = _OEdgeList[numberOfEdges() - 1]; + else + woea = _OEdgeList[(i - 1)]; + woeb = _OEdgeList[(i + 1) % numberOfEdges()]; + ta = 1.0f; + tb = 0.0f; + } - _pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX); - _pSmoothEdge->setWOeA(woea); - _pSmoothEdge->setWOeA(woeb); - _pSmoothEdge->setTa(ta); - _pSmoothEdge->setTb(tb); + _pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX); + _pSmoothEdge->setWOeA(woea); + _pSmoothEdge->setWOeA(woeb); + _pSmoothEdge->setTa(ta); + _pSmoothEdge->setTb(tb); - return _pSmoothEdge; - } - } - } + return _pSmoothEdge; + } + } + } #endif - return _pSmoothEdge; + return _pSmoothEdge; } - void WXFace::ComputeCenter() { - vector iVertexList; - RetrieveVertexList(iVertexList); - Vec3f center; - for (vector::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) { - center += (*wv)->GetVertex(); - } - center /= (float)iVertexList.size(); - setCenter(center); + vector iVertexList; + RetrieveVertexList(iVertexList); + Vec3f center; + for (vector::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); + wv != wvend; + ++wv) { + center += (*wv)->GetVertex(); + } + center /= (float)iVertexList.size(); + setCenter(center); } /********************************** @@ -256,37 +257,45 @@ void WXFace::ComputeCenter() * * **********************************/ -WFace *WXShape::MakeFace(vector& iVertexList, vector& iFaceEdgeMarksList, unsigned iMaterialIndex) +WFace *WXShape::MakeFace(vector &iVertexList, + vector &iFaceEdgeMarksList, + unsigned iMaterialIndex) { - WFace *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex); - if (!face) - return NULL; + WFace *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex); + if (!face) + return NULL; - Vec3f center; - for (vector::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) { - center += (*wv)->GetVertex(); - } - center /= (float)iVertexList.size(); - ((WXFace *)face)->setCenter(center); + Vec3f center; + for (vector::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); + wv != wvend; + ++wv) { + center += (*wv)->GetVertex(); + } + center /= (float)iVertexList.size(); + ((WXFace *)face)->setCenter(center); - return face; + return face; } -WFace *WXShape::MakeFace(vector& iVertexList, vector& iNormalsList, vector& iTexCoordsList, - vector& iFaceEdgeMarksList, unsigned iMaterialIndex) +WFace *WXShape::MakeFace(vector &iVertexList, + vector &iNormalsList, + vector &iTexCoordsList, + vector &iFaceEdgeMarksList, + unsigned iMaterialIndex) { - WFace *face = WShape::MakeFace(iVertexList, iNormalsList, iTexCoordsList, iFaceEdgeMarksList, iMaterialIndex); + WFace *face = WShape::MakeFace( + iVertexList, iNormalsList, iTexCoordsList, iFaceEdgeMarksList, iMaterialIndex); #if 0 - Vec3f center; - for (vector::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) { - center += (*wv)->GetVertex(); - } - center /= (float)iVertexList.size(); - ((WXFace *)face)->setCenter(center); + Vec3f center; + for (vector::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) { + center += (*wv)->GetVertex(); + } + center /= (float)iVertexList.size(); + ((WXFace *)face)->setCenter(center); #endif - return face; + return face; } } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.h b/source/blender/freestyle/intern/winged_edge/WXEdge.h index acca64b930d..63c2ef4f52b 100644 --- a/source/blender/freestyle/intern/winged_edge/WXEdge.h +++ b/source/blender/freestyle/intern/winged_edge/WXEdge.h @@ -27,7 +27,7 @@ #include "WEdge.h" #ifdef WITH_CXX_GUARDEDALLOC -#include "MEM_guardedalloc.h" +# include "MEM_guardedalloc.h" #endif namespace Freestyle { @@ -42,60 +42,58 @@ typedef Nature::EdgeNature WXNature; * * **********************************/ -class WXVertex : public WVertex -{ -private: - // Curvature info - CurvatureInfo *_curvatures; - -public: - inline WXVertex(const Vec3f &v) : WVertex(v) - { - _curvatures = NULL; - } - - /*! Copy constructor */ - WXVertex(WXVertex& iBrother) : WVertex(iBrother) - { - _curvatures = new CurvatureInfo(*iBrother._curvatures); - } - - virtual WVertex *duplicate() - { - WXVertex *clone = new WXVertex(*this); - return clone; - } - - virtual ~WXVertex() - { - if (_curvatures) - delete _curvatures; - } - - virtual void Reset() - { - if (_curvatures) - _curvatures->Kr = 0.0; - } - - inline void setCurvatures(CurvatureInfo *ci) - { - _curvatures = ci; - } - - inline bool isFeature(); - - inline CurvatureInfo *curvatures() - { - return _curvatures; - } +class WXVertex : public WVertex { + private: + // Curvature info + CurvatureInfo *_curvatures; + + public: + inline WXVertex(const Vec3f &v) : WVertex(v) + { + _curvatures = NULL; + } + + /*! Copy constructor */ + WXVertex(WXVertex &iBrother) : WVertex(iBrother) + { + _curvatures = new CurvatureInfo(*iBrother._curvatures); + } + + virtual WVertex *duplicate() + { + WXVertex *clone = new WXVertex(*this); + return clone; + } + + virtual ~WXVertex() + { + if (_curvatures) + delete _curvatures; + } + + virtual void Reset() + { + if (_curvatures) + _curvatures->Kr = 0.0; + } + + inline void setCurvatures(CurvatureInfo *ci) + { + _curvatures = ci; + } + + inline bool isFeature(); + + inline CurvatureInfo *curvatures() + { + return _curvatures; + } #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXVertex") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXVertex") #endif }; - /********************************** * * * * @@ -104,100 +102,101 @@ public: * * **********************************/ -class WXEdge : public WEdge -{ -private: - // flag to indicate whether the edge is a silhouette edge or not - WXNature _nature; - // 0: the order doesn't matter. 1: the order is the orginal one. -1: the order is not good - short _order; - // A front facing edge is an edge for which the bording face which is the nearest from the viewpoint is front. - // A back facing edge is the opposite. - bool _front; - -public: - inline WXEdge() : WEdge() - { - _nature = Nature::NO_FEATURE; - _front = false; - _order = 0; - } - - inline WXEdge(WOEdge *iOEdge) : WEdge(iOEdge) - { - _nature = Nature::NO_FEATURE; - _front = false; - _order = 0; - } - - inline WXEdge(WOEdge *iaOEdge, WOEdge *ibOEdge) : WEdge(iaOEdge, ibOEdge) - { - _nature = Nature::NO_FEATURE; - _front = false; - _order = 0; - } - - /*! Copy constructor */ - inline WXEdge(WXEdge& iBrother) : WEdge(iBrother) - { - _nature = iBrother.nature(); - _front = iBrother._front; - _order = iBrother._order; - } - - virtual WEdge *duplicate() - { - WXEdge *clone = new WXEdge(*this); - return clone; - } - - virtual ~WXEdge() {} - - virtual void Reset() - { - _nature = _nature & ~Nature::SILHOUETTE; - _nature = _nature & ~Nature::SUGGESTIVE_CONTOUR; - } - - /*! accessors */ - inline WXNature nature() - { - return _nature; - } - - inline bool front() - { - return _front; - } - - inline short order() const - { - return _order; - } - - /*! modifiers */ - inline void setFront(bool iFront) - { - _front = iFront; - } - - inline void setNature(WXNature iNature) - { - _nature = iNature; - } - - inline void AddNature(WXNature iNature) - { - _nature = _nature | iNature; - } - - inline void setOrder(int i) - { - _order = i; - } +class WXEdge : public WEdge { + private: + // flag to indicate whether the edge is a silhouette edge or not + WXNature _nature; + // 0: the order doesn't matter. 1: the order is the orginal one. -1: the order is not good + short _order; + // A front facing edge is an edge for which the bording face which is the nearest from the viewpoint is front. + // A back facing edge is the opposite. + bool _front; + + public: + inline WXEdge() : WEdge() + { + _nature = Nature::NO_FEATURE; + _front = false; + _order = 0; + } + + inline WXEdge(WOEdge *iOEdge) : WEdge(iOEdge) + { + _nature = Nature::NO_FEATURE; + _front = false; + _order = 0; + } + + inline WXEdge(WOEdge *iaOEdge, WOEdge *ibOEdge) : WEdge(iaOEdge, ibOEdge) + { + _nature = Nature::NO_FEATURE; + _front = false; + _order = 0; + } + + /*! Copy constructor */ + inline WXEdge(WXEdge &iBrother) : WEdge(iBrother) + { + _nature = iBrother.nature(); + _front = iBrother._front; + _order = iBrother._order; + } + + virtual WEdge *duplicate() + { + WXEdge *clone = new WXEdge(*this); + return clone; + } + + virtual ~WXEdge() + { + } + + virtual void Reset() + { + _nature = _nature & ~Nature::SILHOUETTE; + _nature = _nature & ~Nature::SUGGESTIVE_CONTOUR; + } + + /*! accessors */ + inline WXNature nature() + { + return _nature; + } + + inline bool front() + { + return _front; + } + + inline short order() const + { + return _order; + } + + /*! modifiers */ + inline void setFront(bool iFront) + { + _front = iFront; + } + + inline void setNature(WXNature iNature) + { + _nature = iNature; + } + + inline void AddNature(WXNature iNature) + { + _nature = _nature | iNature; + } + + inline void setOrder(int i) + { + _order = i; + } #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXEdge") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXEdge") #endif }; @@ -210,106 +209,107 @@ public: **********************************/ /*! Class to store a smooth edge (i.e Hertzman & Zorin smooth silhouette edges) */ -class WXSmoothEdge -{ -public: - typedef unsigned short Configuration; - static const Configuration EDGE_EDGE = 1; - static const Configuration VERTEX_EDGE = 2; - static const Configuration EDGE_VERTEX = 3; - - WOEdge *_woea; // Oriented edge from which the silhouette edge starts - WOEdge *_woeb; // Oriented edge where the silhouette edge ends - float _ta; // The silhouette starting point's coordinates are : _woea[0]+ta*(_woea[1]-_woea[0]) - float _tb; // The silhouette ending point's coordinates are : _woeb[0]+ta*(_woeb[1]-_woeb[0]) - bool _front; - Configuration _config; - - WXSmoothEdge() - { - _woea = NULL; - _woeb = NULL; - _ta = 0.0f; - _tb = 0.0f; - _front = false; - _config = EDGE_EDGE; - } - - WXSmoothEdge(const WXSmoothEdge& iBrother) - { - _woea = iBrother._woea; - _woeb = iBrother._woeb; - _ta = iBrother._ta; - _tb = iBrother._tb; - _config = iBrother._config; - _front = iBrother._front; - } - - ~WXSmoothEdge() {} - - inline WOEdge *woea() - { - return _woea; - } - - inline WOEdge *woeb() - { - return _woeb; - } - - inline float ta() const - { - return _ta; - } - - inline float tb() const - { - return _tb; - } - - inline bool front() const - { - return _front; - } - - inline Configuration configuration() const - { - return _config; - } - - /*! modifiers */ - inline void setWOeA(WOEdge *iwoea) - { - _woea = iwoea; - } - - inline void setWOeB(WOEdge *iwoeb) - { - _woeb = iwoeb; - } - - inline void setTa(float ta) - { - _ta = ta; - } - - inline void setTb(float tb) - { - _tb = tb; - } - - inline void setFront(bool iFront) - { - _front = iFront; - } - - inline void setConfiguration(Configuration iConf) - { - _config = iConf; - } +class WXSmoothEdge { + public: + typedef unsigned short Configuration; + static const Configuration EDGE_EDGE = 1; + static const Configuration VERTEX_EDGE = 2; + static const Configuration EDGE_VERTEX = 3; + + WOEdge *_woea; // Oriented edge from which the silhouette edge starts + WOEdge *_woeb; // Oriented edge where the silhouette edge ends + float _ta; // The silhouette starting point's coordinates are : _woea[0]+ta*(_woea[1]-_woea[0]) + float _tb; // The silhouette ending point's coordinates are : _woeb[0]+ta*(_woeb[1]-_woeb[0]) + bool _front; + Configuration _config; + + WXSmoothEdge() + { + _woea = NULL; + _woeb = NULL; + _ta = 0.0f; + _tb = 0.0f; + _front = false; + _config = EDGE_EDGE; + } + + WXSmoothEdge(const WXSmoothEdge &iBrother) + { + _woea = iBrother._woea; + _woeb = iBrother._woeb; + _ta = iBrother._ta; + _tb = iBrother._tb; + _config = iBrother._config; + _front = iBrother._front; + } + + ~WXSmoothEdge() + { + } + + inline WOEdge *woea() + { + return _woea; + } + + inline WOEdge *woeb() + { + return _woeb; + } + + inline float ta() const + { + return _ta; + } + + inline float tb() const + { + return _tb; + } + + inline bool front() const + { + return _front; + } + + inline Configuration configuration() const + { + return _config; + } + + /*! modifiers */ + inline void setWOeA(WOEdge *iwoea) + { + _woea = iwoea; + } + + inline void setWOeB(WOEdge *iwoeb) + { + _woeb = iwoeb; + } + + inline void setTa(float ta) + { + _ta = ta; + } + + inline void setTb(float tb) + { + _tb = tb; + } + + inline void setFront(bool iFront) + { + _front = iFront; + } + + inline void setConfiguration(Configuration iConf) + { + _config = iConf; + } #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXSmoothEdge") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXSmoothEdge") #endif }; @@ -318,382 +318,374 @@ public: */ class WXFace; -class WXFaceLayer -{ -public: - void *userdata; - WXFace *_pWXFace; - // in case of silhouette: the values obtained when computing the normal-view direction dot product. _DotP[i] is - // this value for the vertex i for that face. - vector _DotP; - WXSmoothEdge *_pSmoothEdge; - WXNature _Nature; - - //oldtmp values - // count the number of positive dot products for vertices. - // if this number is != 0 and !=_DotP.size() -> it is a silhouette fac - unsigned _nPosDotP; - - unsigned _nNullDotP; // count the number of null dot products for vertices. - unsigned _ClosestPointIndex; - bool _viewDependant; - - WXFaceLayer(WXFace *iFace, WXNature iNature, bool viewDependant) - { - _pWXFace = iFace; - _pSmoothEdge = NULL; - _nPosDotP = 0; - _nNullDotP = 0; - _Nature = iNature; - _viewDependant = viewDependant; - userdata = NULL; - } - - WXFaceLayer(const WXFaceLayer& iBrother) - { - _pWXFace = iBrother._pWXFace; - _pSmoothEdge = NULL; - _DotP = iBrother._DotP; - _nPosDotP = iBrother._nPosDotP; - _nNullDotP = iBrother._nNullDotP; - _Nature = iBrother._Nature; - if (iBrother._pSmoothEdge) { // XXX ? It's set to null a few lines above! - _pSmoothEdge = new WXSmoothEdge(*(iBrother._pSmoothEdge)); - } - _viewDependant = iBrother._viewDependant; - userdata = NULL; - } - - virtual ~WXFaceLayer() - { - if (!_DotP.empty()) - _DotP.clear(); - if (_pSmoothEdge) { - delete _pSmoothEdge; - _pSmoothEdge = NULL; - } - } - - inline const float dotP(int i) const - { - return _DotP[i]; - } - - inline unsigned nPosDotP() const - { - return _nPosDotP; - } - - inline unsigned nNullDotP() const - { - return _nNullDotP; - } - - inline int closestPointIndex() const - { - return _ClosestPointIndex; - } - - inline WXNature nature() const - { - return _Nature; - } - - inline bool hasSmoothEdge() const - { - if (_pSmoothEdge) - return true; - return false; - } - - inline WXFace *getFace() - { - return _pWXFace; - } - - inline WXSmoothEdge *getSmoothEdge() - { - return _pSmoothEdge; - } - - inline bool isViewDependant() const - { - return _viewDependant; - } - - inline void setClosestPointIndex(int iIndex) - { - _ClosestPointIndex = iIndex; - } - - inline void removeSmoothEdge() - { - if (!_DotP.empty()) - _DotP.clear(); - if (_pSmoothEdge) { - delete _pSmoothEdge; - _pSmoothEdge = NULL; - } - } - - /*! If one of the face layer vertex has a DotP equal to 0, this method returns the vertex where it happens */ - unsigned int Get0VertexIndex() const; - - /*! In case one of the edge of the triangle is a smooth edge, this method allows to retrieve the concerned edge */ - unsigned int GetSmoothEdgeIndex() const; - - /*! retrieves the edges of the triangle for which the signs are different (a null value is not considered) for - * the dotp values at each edge extrimity - */ - void RetrieveCuspEdgesIndices(vector& oCuspEdges); - - WXSmoothEdge *BuildSmoothEdge(); - - inline void setDotP(const vector& iDotP) - { - _DotP = iDotP; - } - - inline void PushDotP(float iDotP) - { - _DotP.push_back(iDotP); - if (iDotP > 0.0f) - ++_nPosDotP; - if (iDotP == 0.0f) // TODO this comparison is weak, check if it actually works - ++_nNullDotP; - } - - inline void ReplaceDotP(unsigned int index, float newDotP) - { - _DotP[index] = newDotP; - updateDotPInfos(); - } - - inline void updateDotPInfos() - { - _nPosDotP = 0; - _nNullDotP = 0; - for (vector::iterator d = _DotP.begin(), dend = _DotP.end(); d != dend; ++d) { - if ((*d) > 0.0f) - ++_nPosDotP; - if ((*d) == 0.0f) // TODO ditto - ++_nNullDotP; - } - } +class WXFaceLayer { + public: + void *userdata; + WXFace *_pWXFace; + // in case of silhouette: the values obtained when computing the normal-view direction dot product. _DotP[i] is + // this value for the vertex i for that face. + vector _DotP; + WXSmoothEdge *_pSmoothEdge; + WXNature _Nature; + + //oldtmp values + // count the number of positive dot products for vertices. + // if this number is != 0 and !=_DotP.size() -> it is a silhouette fac + unsigned _nPosDotP; + + unsigned _nNullDotP; // count the number of null dot products for vertices. + unsigned _ClosestPointIndex; + bool _viewDependant; + + WXFaceLayer(WXFace *iFace, WXNature iNature, bool viewDependant) + { + _pWXFace = iFace; + _pSmoothEdge = NULL; + _nPosDotP = 0; + _nNullDotP = 0; + _Nature = iNature; + _viewDependant = viewDependant; + userdata = NULL; + } + + WXFaceLayer(const WXFaceLayer &iBrother) + { + _pWXFace = iBrother._pWXFace; + _pSmoothEdge = NULL; + _DotP = iBrother._DotP; + _nPosDotP = iBrother._nPosDotP; + _nNullDotP = iBrother._nNullDotP; + _Nature = iBrother._Nature; + if (iBrother._pSmoothEdge) { // XXX ? It's set to null a few lines above! + _pSmoothEdge = new WXSmoothEdge(*(iBrother._pSmoothEdge)); + } + _viewDependant = iBrother._viewDependant; + userdata = NULL; + } + + virtual ~WXFaceLayer() + { + if (!_DotP.empty()) + _DotP.clear(); + if (_pSmoothEdge) { + delete _pSmoothEdge; + _pSmoothEdge = NULL; + } + } + + inline const float dotP(int i) const + { + return _DotP[i]; + } + + inline unsigned nPosDotP() const + { + return _nPosDotP; + } + + inline unsigned nNullDotP() const + { + return _nNullDotP; + } + + inline int closestPointIndex() const + { + return _ClosestPointIndex; + } + + inline WXNature nature() const + { + return _Nature; + } + + inline bool hasSmoothEdge() const + { + if (_pSmoothEdge) + return true; + return false; + } + + inline WXFace *getFace() + { + return _pWXFace; + } + + inline WXSmoothEdge *getSmoothEdge() + { + return _pSmoothEdge; + } + + inline bool isViewDependant() const + { + return _viewDependant; + } + + inline void setClosestPointIndex(int iIndex) + { + _ClosestPointIndex = iIndex; + } + + inline void removeSmoothEdge() + { + if (!_DotP.empty()) + _DotP.clear(); + if (_pSmoothEdge) { + delete _pSmoothEdge; + _pSmoothEdge = NULL; + } + } + + /*! If one of the face layer vertex has a DotP equal to 0, this method returns the vertex where it happens */ + unsigned int Get0VertexIndex() const; + + /*! In case one of the edge of the triangle is a smooth edge, this method allows to retrieve the concerned edge */ + unsigned int GetSmoothEdgeIndex() const; + + /*! retrieves the edges of the triangle for which the signs are different (a null value is not considered) for + * the dotp values at each edge extrimity + */ + void RetrieveCuspEdgesIndices(vector &oCuspEdges); + + WXSmoothEdge *BuildSmoothEdge(); + + inline void setDotP(const vector &iDotP) + { + _DotP = iDotP; + } + + inline void PushDotP(float iDotP) + { + _DotP.push_back(iDotP); + if (iDotP > 0.0f) + ++_nPosDotP; + if (iDotP == 0.0f) // TODO this comparison is weak, check if it actually works + ++_nNullDotP; + } + + inline void ReplaceDotP(unsigned int index, float newDotP) + { + _DotP[index] = newDotP; + updateDotPInfos(); + } + + inline void updateDotPInfos() + { + _nPosDotP = 0; + _nNullDotP = 0; + for (vector::iterator d = _DotP.begin(), dend = _DotP.end(); d != dend; ++d) { + if ((*d) > 0.0f) + ++_nPosDotP; + if ((*d) == 0.0f) // TODO ditto + ++_nNullDotP; + } + } #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXFaceLayer") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXFaceLayer") #endif }; -class WXFace : public WFace -{ -protected: - Vec3f _center; // center of the face - float _Z; // distance from viewpoint to the center of the face - bool _front; // flag to tell whether the face is front facing or back facing - float _dotp; // value obtained when computing the normal-viewpoint dot product - - vector _SmoothLayers; // The data needed to store one or several smooth edges that traverse the face - -public: - inline WXFace() : WFace() - { - _Z = 0.0f; - _front = false; - } - - /*! Copy constructor */ - WXFace(WXFace& iBrother) : WFace(iBrother) - { - _center = iBrother.center(); - _Z = iBrother.Z(); - _front = iBrother.front(); - for (vector::iterator wxf = iBrother._SmoothLayers.begin(), wxfend = iBrother._SmoothLayers.end(); - wxf != wxfend; - ++wxf) - { - _SmoothLayers.push_back(new WXFaceLayer(**wxf)); - } - } - - virtual WFace *duplicate() - { - WXFace *clone = new WXFace(*this); - return clone; - } - - virtual ~WXFace() - { - if (!_SmoothLayers.empty()) { - for (vector::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); - wxf != wxfend; - ++wxf) - { - delete (*wxf); - } - _SmoothLayers.clear(); - } - } - - /*! designed to build a specialized WEdge for use in MakeEdge */ - virtual WEdge *instanciateEdge() const - { - return new WXEdge; - } - - /*! accessors */ - inline Vec3f& center() - { - return _center; - } - - inline float Z() - { - return _Z; - } - - inline bool front() - { - return _front; - } - - inline float dotp() - { - return _dotp; - } - - inline bool hasSmoothEdges() const - { - for (vector::const_iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); - wxf != wxfend; - ++wxf) - { - if ((*wxf)->hasSmoothEdge()) { - return true; - } - } - return false; - } - - vector& getSmoothLayers() - { - return _SmoothLayers; - } - - /*! retrieve the smooth edges that match the Nature given as argument */ - void retrieveSmoothEdges(WXNature iNature, vector& oSmoothEdges) - { - for (vector::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); - wxf != wxfend; - ++wxf) - { - if ((*wxf)->hasSmoothEdge() && ((*wxf)->_Nature & iNature)) { - oSmoothEdges.push_back((*wxf)->_pSmoothEdge); - } - } - } - - void retrieveSmoothEdgesLayers(WXNature iNature, vector& oSmoothEdgesLayers) - { - for (vector::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); - wxf != wxfend; - ++wxf) - { - if ((*wxf)->hasSmoothEdge() && ((*wxf)->_Nature & iNature)) { - oSmoothEdgesLayers.push_back((*wxf)); - } - } - } - - void retrieveSmoothLayers(WXNature iNature, vector& oSmoothLayers) - { - for (vector::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); - wxf != wxfend; - ++wxf) - { - if ((*wxf)->_Nature & iNature) { - oSmoothLayers.push_back(*wxf); - } - } - } - - /*! modifiers */ - inline void setCenter(const Vec3f& iCenter) - { - _center = iCenter; - } - - void ComputeCenter(); - - inline void setZ(float z) - { - _Z = z; - } - - inline void setFront(bool iFront) - { - _front = iFront; - } - - inline void setDotP(float iDotP) - { - _dotp = iDotP; - if (_dotp > 0.0f) - _front = true; - else - _front = false; - } - - inline void AddSmoothLayer(WXFaceLayer *iLayer) - { - _SmoothLayers.push_back(iLayer); - } - - inline void Reset() - { - vector layersToKeep; - for (vector::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); - wxf != wxfend; - ++wxf) - { - if ((*wxf)->isViewDependant()) - delete (*wxf); - else - layersToKeep.push_back(*wxf); - } - _SmoothLayers = layersToKeep; - } - - /*! Clears everything */ - inline void Clear() - { - for (vector::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); - wxf != wxfend; - ++wxf) - { - delete (*wxf); - } - _SmoothLayers.clear(); - } - - virtual void ResetUserData() - { - WFace::ResetUserData(); - for (vector::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); - wxf != wxfend; - ++wxf) - { - (*wxf)->userdata = NULL; - } - } +class WXFace : public WFace { + protected: + Vec3f _center; // center of the face + float _Z; // distance from viewpoint to the center of the face + bool _front; // flag to tell whether the face is front facing or back facing + float _dotp; // value obtained when computing the normal-viewpoint dot product + + vector + _SmoothLayers; // The data needed to store one or several smooth edges that traverse the face + + public: + inline WXFace() : WFace() + { + _Z = 0.0f; + _front = false; + } + + /*! Copy constructor */ + WXFace(WXFace &iBrother) : WFace(iBrother) + { + _center = iBrother.center(); + _Z = iBrother.Z(); + _front = iBrother.front(); + for (vector::iterator wxf = iBrother._SmoothLayers.begin(), + wxfend = iBrother._SmoothLayers.end(); + wxf != wxfend; + ++wxf) { + _SmoothLayers.push_back(new WXFaceLayer(**wxf)); + } + } + + virtual WFace *duplicate() + { + WXFace *clone = new WXFace(*this); + return clone; + } + + virtual ~WXFace() + { + if (!_SmoothLayers.empty()) { + for (vector::iterator wxf = _SmoothLayers.begin(), + wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf) { + delete (*wxf); + } + _SmoothLayers.clear(); + } + } + + /*! designed to build a specialized WEdge for use in MakeEdge */ + virtual WEdge *instanciateEdge() const + { + return new WXEdge; + } + + /*! accessors */ + inline Vec3f ¢er() + { + return _center; + } + + inline float Z() + { + return _Z; + } + + inline bool front() + { + return _front; + } + + inline float dotp() + { + return _dotp; + } + + inline bool hasSmoothEdges() const + { + for (vector::const_iterator wxf = _SmoothLayers.begin(), + wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf) { + if ((*wxf)->hasSmoothEdge()) { + return true; + } + } + return false; + } + + vector &getSmoothLayers() + { + return _SmoothLayers; + } + + /*! retrieve the smooth edges that match the Nature given as argument */ + void retrieveSmoothEdges(WXNature iNature, vector &oSmoothEdges) + { + for (vector::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf) { + if ((*wxf)->hasSmoothEdge() && ((*wxf)->_Nature & iNature)) { + oSmoothEdges.push_back((*wxf)->_pSmoothEdge); + } + } + } + + void retrieveSmoothEdgesLayers(WXNature iNature, vector &oSmoothEdgesLayers) + { + for (vector::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf) { + if ((*wxf)->hasSmoothEdge() && ((*wxf)->_Nature & iNature)) { + oSmoothEdgesLayers.push_back((*wxf)); + } + } + } + + void retrieveSmoothLayers(WXNature iNature, vector &oSmoothLayers) + { + for (vector::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf) { + if ((*wxf)->_Nature & iNature) { + oSmoothLayers.push_back(*wxf); + } + } + } + + /*! modifiers */ + inline void setCenter(const Vec3f &iCenter) + { + _center = iCenter; + } + + void ComputeCenter(); + + inline void setZ(float z) + { + _Z = z; + } + + inline void setFront(bool iFront) + { + _front = iFront; + } + + inline void setDotP(float iDotP) + { + _dotp = iDotP; + if (_dotp > 0.0f) + _front = true; + else + _front = false; + } + + inline void AddSmoothLayer(WXFaceLayer *iLayer) + { + _SmoothLayers.push_back(iLayer); + } + + inline void Reset() + { + vector layersToKeep; + for (vector::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf) { + if ((*wxf)->isViewDependant()) + delete (*wxf); + else + layersToKeep.push_back(*wxf); + } + _SmoothLayers = layersToKeep; + } + + /*! Clears everything */ + inline void Clear() + { + for (vector::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf) { + delete (*wxf); + } + _SmoothLayers.clear(); + } + + virtual void ResetUserData() + { + WFace::ResetUserData(); + for (vector::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf) { + (*wxf)->userdata = NULL; + } + } #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXFace") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXFace") #endif }; - /********************************** * * * * @@ -702,96 +694,103 @@ public: * * **********************************/ -class WXShape : public WShape -{ +class WXShape : public WShape { #if 0 public: - typedef WXShape type_name; + typedef WXShape type_name; #endif -protected: - bool _computeViewIndependent; // flag to indicate whether the view independent stuff must be computed or not - -public: - inline WXShape() : WShape() - { - _computeViewIndependent = true; - } - - /*! copy constructor */ - inline WXShape(WXShape& iBrother) : WShape(iBrother) - { - _computeViewIndependent = iBrother._computeViewIndependent; - } - - virtual WShape *duplicate() - { - WXShape *clone = new WXShape(*this); - return clone; - } - - virtual ~WXShape() {} - - inline bool getComputeViewIndependentFlag() const - { - return _computeViewIndependent; - } - - inline void setComputeViewIndependentFlag(bool iFlag) - { - _computeViewIndependent = iFlag; - } - - /*! designed to build a specialized WFace for use in MakeFace */ - virtual WFace *instanciateFace() const - { - return new WXFace; - } - - /*! adds a new face to the shape returns the built face. - * iVertexList - * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed - * to be already stored when calling MakeFace. The order in which the vertices are stored in the list - * determines the face's edges orientation and (so) the face orientation. - */ - virtual WFace *MakeFace(vector& iVertexList, vector& iFaceEdgeMarksList, unsigned iMaterialIndex); - - /*! adds a new face to the shape. The difference with the previous method is that this one is designed to build - * a WingedEdge structure for which there are per vertex normals, opposed to per face normals. - * returns the built face. - * iVertexList - * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed to be - * already stored when calling MakeFace. - * The order in which the vertices are stored in the list determines the face's edges orientation and (so) the - * face orientation. - * iNormalsList - * The list of normals, iNormalsList[i] corresponding to the normal of the vertex iVertexList[i] for that face. - * iTexCoordsList - * The list of tex coords, iTexCoordsList[i] corresponding to the normal of the vertex iVertexList[i] for - * that face. - */ - virtual WFace *MakeFace(vector& iVertexList, vector& iNormalsList, vector& iTexCoordsList, - vector& iFaceEdgeMarksList, unsigned iMaterialIndex); - - /*! Reset all edges and vertices flags (which might have been set up on a previous pass) */ - virtual void Reset() - { - // Reset Edges - vector& wedges = getEdgeList(); - for (vector::iterator we = wedges.begin(), weend = wedges.end(); we != weend; ++we) { - ((WXEdge *)(*we))->Reset(); - } - - //Reset faces: - vector& wfaces = GetFaceList(); - for (vector::iterator wf = wfaces.begin(), wfend = wfaces.end(); wf != wfend; ++wf) { - ((WXFace *)(*wf))->Reset(); - } - } - /*! accessors */ + protected: + bool + _computeViewIndependent; // flag to indicate whether the view independent stuff must be computed or not + + public: + inline WXShape() : WShape() + { + _computeViewIndependent = true; + } + + /*! copy constructor */ + inline WXShape(WXShape &iBrother) : WShape(iBrother) + { + _computeViewIndependent = iBrother._computeViewIndependent; + } + + virtual WShape *duplicate() + { + WXShape *clone = new WXShape(*this); + return clone; + } + + virtual ~WXShape() + { + } + + inline bool getComputeViewIndependentFlag() const + { + return _computeViewIndependent; + } + + inline void setComputeViewIndependentFlag(bool iFlag) + { + _computeViewIndependent = iFlag; + } + + /*! designed to build a specialized WFace for use in MakeFace */ + virtual WFace *instanciateFace() const + { + return new WXFace; + } + + /*! adds a new face to the shape returns the built face. + * iVertexList + * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed + * to be already stored when calling MakeFace. The order in which the vertices are stored in the list + * determines the face's edges orientation and (so) the face orientation. + */ + virtual WFace *MakeFace(vector &iVertexList, + vector &iFaceEdgeMarksList, + unsigned iMaterialIndex); + + /*! adds a new face to the shape. The difference with the previous method is that this one is designed to build + * a WingedEdge structure for which there are per vertex normals, opposed to per face normals. + * returns the built face. + * iVertexList + * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed to be + * already stored when calling MakeFace. + * The order in which the vertices are stored in the list determines the face's edges orientation and (so) the + * face orientation. + * iNormalsList + * The list of normals, iNormalsList[i] corresponding to the normal of the vertex iVertexList[i] for that face. + * iTexCoordsList + * The list of tex coords, iTexCoordsList[i] corresponding to the normal of the vertex iVertexList[i] for + * that face. + */ + virtual WFace *MakeFace(vector &iVertexList, + vector &iNormalsList, + vector &iTexCoordsList, + vector &iFaceEdgeMarksList, + unsigned iMaterialIndex); + + /*! Reset all edges and vertices flags (which might have been set up on a previous pass) */ + virtual void Reset() + { + // Reset Edges + vector &wedges = getEdgeList(); + for (vector::iterator we = wedges.begin(), weend = wedges.end(); we != weend; ++we) { + ((WXEdge *)(*we))->Reset(); + } + + //Reset faces: + vector &wfaces = GetFaceList(); + for (vector::iterator wf = wfaces.begin(), wfend = wfaces.end(); wf != wfend; ++wf) { + ((WXFace *)(*wf))->Reset(); + } + } + /*! accessors */ #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXShape") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXShape") #endif }; @@ -810,16 +809,16 @@ public: bool WXVertex::isFeature() { - int counter = 0; - vector& vedges = GetEdges(); - for (vector::iterator ve = vedges.begin(), vend = vedges.end(); ve != vend; ++ve) { - if (((WXEdge *)(*ve))->nature() != Nature::NO_FEATURE) - counter++; - } - - if ((counter == 1) || (counter > 2)) - return true; - return false; + int counter = 0; + vector &vedges = GetEdges(); + for (vector::iterator ve = vedges.begin(), vend = vedges.end(); ve != vend; ++ve) { + if (((WXEdge *)(*ve))->nature() != Nature::NO_FEATURE) + counter++; + } + + if ((counter == 1) || (counter > 2)) + return true; + return false; } } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp index 6fa73c3d212..fb0b6a9b63f 100644 --- a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp +++ b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp @@ -25,29 +25,29 @@ namespace Freestyle { -void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) +void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet &ifs) { - if (_pRenderMonitor && _pRenderMonitor->testBreak()) - return; - WXShape *shape = new WXShape; - if (!buildWShape(*shape, ifs)) { - delete shape; - return; - } - shape->setId(ifs.getId().getFirst()); - shape->setName(ifs.getName()); - shape->setLibraryPath(ifs.getLibraryPath()); - //ifs.setId(shape->GetId()); + if (_pRenderMonitor && _pRenderMonitor->testBreak()) + return; + WXShape *shape = new WXShape; + if (!buildWShape(*shape, ifs)) { + delete shape; + return; + } + shape->setId(ifs.getId().getFirst()); + shape->setName(ifs.getName()); + shape->setLibraryPath(ifs.getLibraryPath()); + //ifs.setId(shape->GetId()); } -void WXEdgeBuilder::buildWVertices(WShape& shape, const float *vertices, unsigned vsize) +void WXEdgeBuilder::buildWVertices(WShape &shape, const float *vertices, unsigned vsize) { - WXVertex *vertex; - for (unsigned int i = 0; i < vsize; i += 3) { - vertex = new WXVertex(Vec3f(vertices[i], vertices[i + 1], vertices[i + 2])); - vertex->setId(i / 3); - shape.AddVertex(vertex); - } + WXVertex *vertex; + for (unsigned int i = 0; i < vsize; i += 3) { + vertex = new WXVertex(Vec3f(vertices[i], vertices[i + 1], vertices[i + 2])); + vertex->setId(i / 3); + shape.AddVertex(vertex); + } } } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h index a4eb270435a..e98832f4fba 100644 --- a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h +++ b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h @@ -29,22 +29,24 @@ namespace Freestyle { -class WXEdgeBuilder : public WingedEdgeBuilder -{ -public: - WXEdgeBuilder() : WingedEdgeBuilder() {} - virtual ~WXEdgeBuilder() {} - VISIT_DECL(IndexedFaceSet) - -protected: - virtual void buildWVertices(WShape& shape, const float *vertices, unsigned vsize); +class WXEdgeBuilder : public WingedEdgeBuilder { + public: + WXEdgeBuilder() : WingedEdgeBuilder() + { + } + virtual ~WXEdgeBuilder() + { + } + VISIT_DECL(IndexedFaceSet) + + protected: + virtual void buildWVertices(WShape &shape, const float *vertices, unsigned vsize); #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXEdgeBuilder") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXEdgeBuilder") #endif - }; } /* namespace Freestyle */ -#endif // __FREESTYLE_WX_EDGE_BUILDER_H__ +#endif // __FREESTYLE_WX_EDGE_BUILDER_H__ diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp index 48b815e0d22..977eb2b4d57 100644 --- a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp +++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp @@ -32,344 +32,416 @@ using namespace std; namespace Freestyle { -void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) +void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet &ifs) { - if (_pRenderMonitor && _pRenderMonitor->testBreak()) - return; - WShape *shape = new WShape; - if (!buildWShape(*shape, ifs)) { - delete shape; - return; - } - shape->setId(ifs.getId().getFirst()); - //ifs.setId(shape->GetId()); + if (_pRenderMonitor && _pRenderMonitor->testBreak()) + return; + WShape *shape = new WShape; + if (!buildWShape(*shape, ifs)) { + delete shape; + return; + } + shape->setId(ifs.getId().getFirst()); + //ifs.setId(shape->GetId()); } -void WingedEdgeBuilder::visitNodeShape(NodeShape& ns) +void WingedEdgeBuilder::visitNodeShape(NodeShape &ns) { - //Sets the current material to iShapeode->material: - _current_frs_material = &(ns.frs_material()); + //Sets the current material to iShapeode->material: + _current_frs_material = &(ns.frs_material()); } -void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn) +void WingedEdgeBuilder::visitNodeTransform(NodeTransform &tn) { - if (!_current_matrix) { - _current_matrix = new Matrix44r(tn.matrix()); - return; - } - - _matrices_stack.push_back(_current_matrix); - Matrix44r *new_matrix = new Matrix44r(*_current_matrix * tn.matrix()); - _current_matrix = new_matrix; + if (!_current_matrix) { + _current_matrix = new Matrix44r(tn.matrix()); + return; + } + + _matrices_stack.push_back(_current_matrix); + Matrix44r *new_matrix = new Matrix44r(*_current_matrix * tn.matrix()); + _current_matrix = new_matrix; } -void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&) +void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform &) { - if (_current_matrix) - delete _current_matrix; + if (_current_matrix) + delete _current_matrix; - if (_matrices_stack.empty()) { - _current_matrix = NULL; - return; - } + if (_matrices_stack.empty()) { + _current_matrix = NULL; + return; + } - _current_matrix = _matrices_stack.back(); - _matrices_stack.pop_back(); + _current_matrix = _matrices_stack.back(); + _matrices_stack.pop_back(); } -bool WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) +bool WingedEdgeBuilder::buildWShape(WShape &shape, IndexedFaceSet &ifs) { - unsigned int vsize = ifs.vsize(); - unsigned int nsize = ifs.nsize(); - //soc unused - unsigned tsize = ifs.tsize(); - - const float *vertices = ifs.vertices(); - const float *normals = ifs.normals(); - const float *texCoords = ifs.texCoords(); - - float *new_vertices; - float *new_normals; - - new_vertices = new float[vsize]; - new_normals = new float[nsize]; - - // transform coordinates from local to world system - if (_current_matrix) { - transformVertices(vertices, vsize, *_current_matrix, new_vertices); - transformNormals(normals, nsize, *_current_matrix, new_normals); - } - else { - memcpy(new_vertices, vertices, vsize * sizeof(*new_vertices)); - memcpy(new_normals, normals, nsize * sizeof(*new_normals)); - } - - const IndexedFaceSet::TRIANGLES_STYLE *faceStyle = ifs.trianglesStyle(); - - vector frs_materials; - if (ifs.msize()) { - const FrsMaterial *const *mats = ifs.frs_materials(); - for (unsigned i = 0; i < ifs.msize(); ++i) - frs_materials.push_back(*(mats[i])); - shape.setFrsMaterials(frs_materials); - } + unsigned int vsize = ifs.vsize(); + unsigned int nsize = ifs.nsize(); + //soc unused - unsigned tsize = ifs.tsize(); + + const float *vertices = ifs.vertices(); + const float *normals = ifs.normals(); + const float *texCoords = ifs.texCoords(); + + float *new_vertices; + float *new_normals; + + new_vertices = new float[vsize]; + new_normals = new float[nsize]; + + // transform coordinates from local to world system + if (_current_matrix) { + transformVertices(vertices, vsize, *_current_matrix, new_vertices); + transformNormals(normals, nsize, *_current_matrix, new_normals); + } + else { + memcpy(new_vertices, vertices, vsize * sizeof(*new_vertices)); + memcpy(new_normals, normals, nsize * sizeof(*new_normals)); + } + + const IndexedFaceSet::TRIANGLES_STYLE *faceStyle = ifs.trianglesStyle(); + + vector frs_materials; + if (ifs.msize()) { + const FrsMaterial *const *mats = ifs.frs_materials(); + for (unsigned i = 0; i < ifs.msize(); ++i) + frs_materials.push_back(*(mats[i])); + shape.setFrsMaterials(frs_materials); + } #if 0 - const FrsMaterial *mat = (ifs.frs_material()); - if (mat) - shape.setFrsMaterial(*mat); - else if (_current_frs_material) - shape.setFrsMaterial(*_current_frs_material); + const FrsMaterial *mat = (ifs.frs_material()); + if (mat) + shape.setFrsMaterial(*mat); + else if (_current_frs_material) + shape.setFrsMaterial(*_current_frs_material); #endif - const IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = ifs.faceEdgeMarks(); - - // sets the current WShape to shape - _current_wshape = &shape; - - // create a WVertex for each vertex - buildWVertices(shape, new_vertices, vsize); - - const unsigned int *vindices = ifs.vindices(); - const unsigned int *nindices = ifs.nindices(); - const unsigned int *tindices = NULL; - if (ifs.tsize()) { - tindices = ifs.tindices(); - } - - const unsigned int *mindices = NULL; - if (ifs.msize()) - mindices = ifs.mindices(); - const unsigned int *numVertexPerFace = ifs.numVertexPerFaces(); - const unsigned int numfaces = ifs.numFaces(); - - for (unsigned int index = 0; index < numfaces; index++) { - switch (faceStyle[index]) { - case IndexedFaceSet::TRIANGLE_STRIP: - buildTriangleStrip(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices, - nindices, mindices, tindices, numVertexPerFace[index]); - break; - case IndexedFaceSet::TRIANGLE_FAN: - buildTriangleFan(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices, - nindices, mindices, tindices, numVertexPerFace[index]); - break; - case IndexedFaceSet::TRIANGLES: - buildTriangles(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices, - nindices, mindices, tindices, numVertexPerFace[index]); - break; - } - vindices += numVertexPerFace[index]; - nindices += numVertexPerFace[index]; - if (mindices) - mindices += numVertexPerFace[index]; - if (tindices) - tindices += numVertexPerFace[index]; - faceEdgeMarks++; - } - - delete[] new_vertices; - delete[] new_normals; - - if (shape.GetFaceList().size() == 0) // this may happen due to degenerate triangles - return false; + const IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = ifs.faceEdgeMarks(); + + // sets the current WShape to shape + _current_wshape = &shape; + + // create a WVertex for each vertex + buildWVertices(shape, new_vertices, vsize); + + const unsigned int *vindices = ifs.vindices(); + const unsigned int *nindices = ifs.nindices(); + const unsigned int *tindices = NULL; + if (ifs.tsize()) { + tindices = ifs.tindices(); + } + + const unsigned int *mindices = NULL; + if (ifs.msize()) + mindices = ifs.mindices(); + const unsigned int *numVertexPerFace = ifs.numVertexPerFaces(); + const unsigned int numfaces = ifs.numFaces(); + + for (unsigned int index = 0; index < numfaces; index++) { + switch (faceStyle[index]) { + case IndexedFaceSet::TRIANGLE_STRIP: + buildTriangleStrip(new_vertices, + new_normals, + frs_materials, + texCoords, + faceEdgeMarks, + vindices, + nindices, + mindices, + tindices, + numVertexPerFace[index]); + break; + case IndexedFaceSet::TRIANGLE_FAN: + buildTriangleFan(new_vertices, + new_normals, + frs_materials, + texCoords, + faceEdgeMarks, + vindices, + nindices, + mindices, + tindices, + numVertexPerFace[index]); + break; + case IndexedFaceSet::TRIANGLES: + buildTriangles(new_vertices, + new_normals, + frs_materials, + texCoords, + faceEdgeMarks, + vindices, + nindices, + mindices, + tindices, + numVertexPerFace[index]); + break; + } + vindices += numVertexPerFace[index]; + nindices += numVertexPerFace[index]; + if (mindices) + mindices += numVertexPerFace[index]; + if (tindices) + tindices += numVertexPerFace[index]; + faceEdgeMarks++; + } + + delete[] new_vertices; + delete[] new_normals; + + if (shape.GetFaceList().size() == 0) // this may happen due to degenerate triangles + return false; #if 0 - // compute bbox - shape.ComputeBBox(); - // compute mean edge size: - shape.ComputeMeanEdgeSize(); + // compute bbox + shape.ComputeBBox(); + // compute mean edge size: + shape.ComputeMeanEdgeSize(); #endif - // Parse the built winged-edge shape to update post-flags - set normalsSet; - vector& wvertices = shape.getVertexList(); - for (vector::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend; ++wv) { - if ((*wv)->isBoundary()) - continue; - if ((*wv)->GetEdges().size() == 0) // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.) - continue; - normalsSet.clear(); - WVertex::face_iterator fit = (*wv)->faces_begin(); - WVertex::face_iterator fitend = (*wv)->faces_end(); - for (; fit != fitend; ++fit) { - WFace *face = *fit; - normalsSet.insert(face->GetVertexNormal(*wv)); - if (normalsSet.size() != 1) { - break; - } - } - if (normalsSet.size() != 1) { - (*wv)->setSmooth(false); - } - } - - // Adds the new WShape to the WingedEdge structure - _winged_edge->addWShape(&shape); - - return true; + // Parse the built winged-edge shape to update post-flags + set normalsSet; + vector &wvertices = shape.getVertexList(); + for (vector::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend; + ++wv) { + if ((*wv)->isBoundary()) + continue; + if ((*wv)->GetEdges().size() == + 0) // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.) + continue; + normalsSet.clear(); + WVertex::face_iterator fit = (*wv)->faces_begin(); + WVertex::face_iterator fitend = (*wv)->faces_end(); + for (; fit != fitend; ++fit) { + WFace *face = *fit; + normalsSet.insert(face->GetVertexNormal(*wv)); + if (normalsSet.size() != 1) { + break; + } + } + if (normalsSet.size() != 1) { + (*wv)->setSmooth(false); + } + } + + // Adds the new WShape to the WingedEdge structure + _winged_edge->addWShape(&shape); + + return true; } -void WingedEdgeBuilder::buildWVertices(WShape& shape, const float *vertices, unsigned vsize) +void WingedEdgeBuilder::buildWVertices(WShape &shape, const float *vertices, unsigned vsize) { - WVertex *vertex; - for (unsigned int i = 0; i < vsize; i += 3) { - vertex = new WVertex(Vec3f(vertices[i], vertices[i + 1], vertices[i + 2])); - vertex->setId(i / 3); - shape.AddVertex(vertex); - } + WVertex *vertex; + for (unsigned int i = 0; i < vsize; i += 3) { + vertex = new WVertex(Vec3f(vertices[i], vertices[i + 1], vertices[i + 2])); + vertex->setId(i / 3); + shape.AddVertex(vertex); + } } -void WingedEdgeBuilder::buildTriangleStrip(const float * /*vertices*/, const float *normals, vector& /*iMaterials*/, - const float *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, - const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, - const unsigned *tindices, const unsigned nvertices) +void WingedEdgeBuilder::buildTriangleStrip(const float * /*vertices*/, + const float *normals, + vector & /*iMaterials*/, + const float *texCoords, + const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, + const unsigned *vindices, + const unsigned *nindices, + const unsigned *mindices, + const unsigned *tindices, + const unsigned nvertices) { - unsigned nDoneVertices = 2; // number of vertices already treated - unsigned nTriangle = 0; // number of the triangle currently being treated - //int nVertex = 0; // vertex number - - WShape *currentShape = _current_wshape; // the current shape being built - vector triangleVertices; - vector triangleNormals; - vector triangleTexCoords; - vector triangleFaceEdgeMarks; - - while (nDoneVertices < nvertices) { - //clear the vertices list: - triangleVertices.clear(); - //Then rebuild it: - if (0 == nTriangle % 2) { // if nTriangle is even - triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]); - triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]); - triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]); - - triangleNormals.push_back(Vec3f(normals[nindices[nTriangle]], normals[nindices[nTriangle] + 1], - normals[nindices[nTriangle] + 2])); - triangleNormals.push_back(Vec3f(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1], - normals[nindices[nTriangle + 1] + 2])); - triangleNormals.push_back(Vec3f(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1], - normals[nindices[nTriangle + 2] + 2])); - - if (texCoords) { - triangleTexCoords.push_back(Vec2f(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1])); - triangleTexCoords.push_back(Vec2f(texCoords[tindices[nTriangle + 1]], - texCoords[tindices[nTriangle + 1] + 1])); - triangleTexCoords.push_back(Vec2f(texCoords[tindices[nTriangle + 2]], - texCoords[tindices[nTriangle + 2] + 1])); - } - } - else { // if nTriangle is odd - triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]); - triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]); - triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]); - - triangleNormals.push_back(Vec3f(normals[nindices[nTriangle]], normals[nindices[nTriangle] + 1], - normals[nindices[nTriangle] + 2])); - triangleNormals.push_back(Vec3f(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1], - normals[nindices[nTriangle + 2] + 2])); - triangleNormals.push_back(Vec3f(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1], - normals[nindices[nTriangle + 1] + 2])); - - if (texCoords) { - triangleTexCoords.push_back(Vec2f(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1])); - triangleTexCoords.push_back(Vec2f(texCoords[tindices[nTriangle + 2]], - texCoords[tindices[nTriangle + 2] + 1])); - triangleTexCoords.push_back(Vec2f(texCoords[tindices[nTriangle + 1]], - texCoords[tindices[nTriangle + 1] + 1])); - } - } - triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::FACE_MARK) != 0); - triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V1V2) != 0); - triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0); - triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0); - if (mindices) { - currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, - mindices[nTriangle / 3]); - } - else { - currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0); - } - nDoneVertices++; // with a strip, each triangle is one vertex more - nTriangle++; - } + unsigned nDoneVertices = 2; // number of vertices already treated + unsigned nTriangle = 0; // number of the triangle currently being treated + //int nVertex = 0; // vertex number + + WShape *currentShape = _current_wshape; // the current shape being built + vector triangleVertices; + vector triangleNormals; + vector triangleTexCoords; + vector triangleFaceEdgeMarks; + + while (nDoneVertices < nvertices) { + //clear the vertices list: + triangleVertices.clear(); + //Then rebuild it: + if (0 == nTriangle % 2) { // if nTriangle is even + triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]); + triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]); + triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]); + + triangleNormals.push_back(Vec3f(normals[nindices[nTriangle]], + normals[nindices[nTriangle] + 1], + normals[nindices[nTriangle] + 2])); + triangleNormals.push_back(Vec3f(normals[nindices[nTriangle + 1]], + normals[nindices[nTriangle + 1] + 1], + normals[nindices[nTriangle + 1] + 2])); + triangleNormals.push_back(Vec3f(normals[nindices[nTriangle + 2]], + normals[nindices[nTriangle + 2] + 1], + normals[nindices[nTriangle + 2] + 2])); + + if (texCoords) { + triangleTexCoords.push_back( + Vec2f(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1])); + triangleTexCoords.push_back( + Vec2f(texCoords[tindices[nTriangle + 1]], texCoords[tindices[nTriangle + 1] + 1])); + triangleTexCoords.push_back( + Vec2f(texCoords[tindices[nTriangle + 2]], texCoords[tindices[nTriangle + 2] + 1])); + } + } + else { // if nTriangle is odd + triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]); + triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]); + triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]); + + triangleNormals.push_back(Vec3f(normals[nindices[nTriangle]], + normals[nindices[nTriangle] + 1], + normals[nindices[nTriangle] + 2])); + triangleNormals.push_back(Vec3f(normals[nindices[nTriangle + 2]], + normals[nindices[nTriangle + 2] + 1], + normals[nindices[nTriangle + 2] + 2])); + triangleNormals.push_back(Vec3f(normals[nindices[nTriangle + 1]], + normals[nindices[nTriangle + 1] + 1], + normals[nindices[nTriangle + 1] + 2])); + + if (texCoords) { + triangleTexCoords.push_back( + Vec2f(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1])); + triangleTexCoords.push_back( + Vec2f(texCoords[tindices[nTriangle + 2]], texCoords[tindices[nTriangle + 2] + 1])); + triangleTexCoords.push_back( + Vec2f(texCoords[tindices[nTriangle + 1]], texCoords[tindices[nTriangle + 1] + 1])); + } + } + triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::FACE_MARK) != + 0); + triangleFaceEdgeMarks.push_back( + (iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V1V2) != 0); + triangleFaceEdgeMarks.push_back( + (iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0); + triangleFaceEdgeMarks.push_back( + (iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0); + if (mindices) { + currentShape->MakeFace(triangleVertices, + triangleNormals, + triangleTexCoords, + triangleFaceEdgeMarks, + mindices[nTriangle / 3]); + } + else { + currentShape->MakeFace( + triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0); + } + nDoneVertices++; // with a strip, each triangle is one vertex more + nTriangle++; + } } -void WingedEdgeBuilder::buildTriangleFan(const float * /*vertices*/, const float * /*normals*/, vector& /*iMaterials*/, - const float * /*texCoords*/, const IndexedFaceSet::FaceEdgeMark * /*iFaceEdgeMarks*/, - const unsigned * /*vindices*/, const unsigned * /*nindices*/, const unsigned * /*mindices*/, - const unsigned * /*tindices*/, const unsigned /*nvertices*/) +void WingedEdgeBuilder::buildTriangleFan(const float * /*vertices*/, + const float * /*normals*/, + vector & /*iMaterials*/, + const float * /*texCoords*/, + const IndexedFaceSet::FaceEdgeMark * /*iFaceEdgeMarks*/, + const unsigned * /*vindices*/, + const unsigned * /*nindices*/, + const unsigned * /*mindices*/, + const unsigned * /*tindices*/, + const unsigned /*nvertices*/) { - // Nothing to be done + // Nothing to be done } -void WingedEdgeBuilder::buildTriangles(const float * /*vertices*/, const float *normals, vector& /*iMaterials*/, - const float *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, - const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, - const unsigned *tindices, const unsigned nvertices) +void WingedEdgeBuilder::buildTriangles(const float * /*vertices*/, + const float *normals, + vector & /*iMaterials*/, + const float *texCoords, + const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, + const unsigned *vindices, + const unsigned *nindices, + const unsigned *mindices, + const unsigned *tindices, + const unsigned nvertices) { - WShape *currentShape = _current_wshape; // the current shape begin built - vector triangleVertices; - vector triangleNormals; - vector triangleTexCoords; - vector triangleFaceEdgeMarks; - - // Each triplet of vertices is considered as an independent triangle - for (unsigned int i = 0; i < nvertices / 3; i++) { - triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i] / 3]); - triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 1] / 3]); - triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 2] / 3]); - - triangleNormals.push_back(Vec3f(normals[nindices[3 * i]], normals[nindices[3 * i] + 1], - normals[nindices[3 * i] + 2])); - triangleNormals.push_back(Vec3f(normals[nindices[3 * i + 1]], normals[nindices[3 * i + 1] + 1], - normals[nindices[3 * i + 1] + 2])); - triangleNormals.push_back(Vec3f(normals[nindices[3 * i + 2]], normals[nindices[3 * i + 2] + 1], - normals[nindices[3 * i + 2] + 2])); - - if (texCoords) { - triangleTexCoords.push_back(Vec2f(texCoords[tindices[3 * i]], texCoords[tindices[3 * i] + 1])); - triangleTexCoords.push_back(Vec2f(texCoords[tindices[3 * i + 1]], texCoords[tindices[3 * i + 1] + 1])); - triangleTexCoords.push_back(Vec2f(texCoords[tindices[3 * i + 2]], texCoords[tindices[3 * i + 2] + 1])); - } - - triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::FACE_MARK) != 0); - triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V1V2) != 0); - triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V2V3) != 0); - triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V3V1) != 0); - } - if (mindices) - currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, - mindices[0]); - else - currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0); + WShape *currentShape = _current_wshape; // the current shape begin built + vector triangleVertices; + vector triangleNormals; + vector triangleTexCoords; + vector triangleFaceEdgeMarks; + + // Each triplet of vertices is considered as an independent triangle + for (unsigned int i = 0; i < nvertices / 3; i++) { + triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i] / 3]); + triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 1] / 3]); + triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 2] / 3]); + + triangleNormals.push_back(Vec3f( + normals[nindices[3 * i]], normals[nindices[3 * i] + 1], normals[nindices[3 * i] + 2])); + triangleNormals.push_back(Vec3f(normals[nindices[3 * i + 1]], + normals[nindices[3 * i + 1] + 1], + normals[nindices[3 * i + 1] + 2])); + triangleNormals.push_back(Vec3f(normals[nindices[3 * i + 2]], + normals[nindices[3 * i + 2] + 1], + normals[nindices[3 * i + 2] + 2])); + + if (texCoords) { + triangleTexCoords.push_back( + Vec2f(texCoords[tindices[3 * i]], texCoords[tindices[3 * i] + 1])); + triangleTexCoords.push_back( + Vec2f(texCoords[tindices[3 * i + 1]], texCoords[tindices[3 * i + 1] + 1])); + triangleTexCoords.push_back( + Vec2f(texCoords[tindices[3 * i + 2]], texCoords[tindices[3 * i + 2] + 1])); + } + + triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::FACE_MARK) != 0); + triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V1V2) != 0); + triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V2V3) != 0); + triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V3V1) != 0); + } + if (mindices) + currentShape->MakeFace( + triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[0]); + else + currentShape->MakeFace( + triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0); } -void WingedEdgeBuilder::transformVertices(const float *vertices, unsigned vsize, const Matrix44r& transform, float *res) +void WingedEdgeBuilder::transformVertices(const float *vertices, + unsigned vsize, + const Matrix44r &transform, + float *res) { - const float *v = vertices; - float *pv = res; - - for (unsigned int i = 0; i < vsize / 3; i++) { - HVec3r hv_tmp(v[0], v[1], v[2]); - HVec3r hv(transform * hv_tmp); - for (unsigned int j = 0; j < 3; j++) - pv[j] = hv[j] / hv[3]; - v += 3; - pv += 3; - } + const float *v = vertices; + float *pv = res; + + for (unsigned int i = 0; i < vsize / 3; i++) { + HVec3r hv_tmp(v[0], v[1], v[2]); + HVec3r hv(transform * hv_tmp); + for (unsigned int j = 0; j < 3; j++) + pv[j] = hv[j] / hv[3]; + v += 3; + pv += 3; + } } -void WingedEdgeBuilder::transformNormals(const float *normals, unsigned nsize, const Matrix44r& transform, float *res) +void WingedEdgeBuilder::transformNormals(const float *normals, + unsigned nsize, + const Matrix44r &transform, + float *res) { - const float *n = normals; - float *pn = res; - - for (unsigned int i = 0; i < nsize / 3; i++) { - Vec3r hn(n[0], n[1], n[2]); - hn = GeomUtils::rotateVector(transform, hn); - for (unsigned int j = 0; j < 3; j++) - pn[j] = hn[j]; - n += 3; - pn += 3; - } + const float *n = normals; + float *pn = res; + + for (unsigned int i = 0; i < nsize / 3; i++) { + Vec3r hn(n[0], n[1], n[2]); + hn = GeomUtils::rotateVector(transform, hn); + for (unsigned int j = 0; j < 3; j++) + pn[j] = hn[j]; + n += 3; + pn += 3; + } } } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h index 30fe7277fdb..606e8561401 100644 --- a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h +++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h @@ -34,119 +34,144 @@ namespace Freestyle { -class WingedEdgeBuilder : public SceneVisitor -{ -public: - inline WingedEdgeBuilder() : SceneVisitor() - { - _current_wshape = NULL; - _current_frs_material = NULL; - _current_matrix = NULL; - _winged_edge = new WingedEdge; // Not deleted by the destructor - _pRenderMonitor = NULL; - } - - virtual ~WingedEdgeBuilder() - { - for (vector::iterator it = _matrices_stack.begin(); it != _matrices_stack.end(); ++it) - delete *it; - _matrices_stack.clear(); - } - - VISIT_DECL(IndexedFaceSet) - VISIT_DECL(NodeShape) - VISIT_DECL(NodeTransform) - - virtual void visitNodeTransformAfter(NodeTransform&); - - // - // Accessors - // - ///////////////////////////////////////////////////////////////////////////// - - inline WingedEdge *getWingedEdge() - { - return _winged_edge; - } - - inline WShape *getCurrentWShape() - { - return _current_wshape; - } - - inline FrsMaterial *getCurrentFrsMaterial() - { - return _current_frs_material; - } - - inline Matrix44r *getCurrentMatrix() - { - return _current_matrix; - } - - // - // Modifiers - // - ///////////////////////////////////////////////////////////////////////////// - - inline void setCurrentWShape(WShape *wshape) - { - _current_wshape = wshape; - } - - inline void setCurrentFrsMaterial(FrsMaterial *mat) - { - _current_frs_material = mat; - } +class WingedEdgeBuilder : public SceneVisitor { + public: + inline WingedEdgeBuilder() : SceneVisitor() + { + _current_wshape = NULL; + _current_frs_material = NULL; + _current_matrix = NULL; + _winged_edge = new WingedEdge; // Not deleted by the destructor + _pRenderMonitor = NULL; + } + + virtual ~WingedEdgeBuilder() + { + for (vector::iterator it = _matrices_stack.begin(); it != _matrices_stack.end(); + ++it) + delete *it; + _matrices_stack.clear(); + } + + VISIT_DECL(IndexedFaceSet) + VISIT_DECL(NodeShape) + VISIT_DECL(NodeTransform) + + virtual void visitNodeTransformAfter(NodeTransform &); + + // + // Accessors + // + ///////////////////////////////////////////////////////////////////////////// + + inline WingedEdge *getWingedEdge() + { + return _winged_edge; + } + + inline WShape *getCurrentWShape() + { + return _current_wshape; + } + + inline FrsMaterial *getCurrentFrsMaterial() + { + return _current_frs_material; + } + + inline Matrix44r *getCurrentMatrix() + { + return _current_matrix; + } + + // + // Modifiers + // + ///////////////////////////////////////////////////////////////////////////// + + inline void setCurrentWShape(WShape *wshape) + { + _current_wshape = wshape; + } + + inline void setCurrentFrsMaterial(FrsMaterial *mat) + { + _current_frs_material = mat; + } #if 0 - inline void setCurrentMatrix(Matrix44r *matrix) - { - _current_matrix = matrix; - } + inline void setCurrentMatrix(Matrix44r *matrix) + { + _current_matrix = matrix; + } #endif - inline void setRenderMonitor(RenderMonitor *iRenderMonitor) { - _pRenderMonitor = iRenderMonitor; - } - -protected: - virtual bool buildWShape(WShape& shape, IndexedFaceSet& ifs); - virtual void buildWVertices(WShape& shape, const float *vertices, unsigned vsize); - - RenderMonitor *_pRenderMonitor; - -private: - void buildTriangleStrip(const float *vertices, const float *normals, vector& iMaterials, - const float *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, - const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, - const unsigned *tindices, const unsigned nvertices); - - void buildTriangleFan(const float *vertices, const float *normals, vector& iMaterials, - const float *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, - const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, - const unsigned *tindices, const unsigned nvertices); - - void buildTriangles(const float *vertices, const float *normals, vector& iMaterials, - const float *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, - const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, - const unsigned *tindices, const unsigned nvertices); - - void transformVertices(const float *vertices, unsigned vsize, const Matrix44r& transform, float *res); - - void transformNormals(const float *normals, unsigned nsize, const Matrix44r& transform, float *res); - - WShape *_current_wshape; - FrsMaterial *_current_frs_material; - WingedEdge *_winged_edge; - Matrix44r *_current_matrix; - vector _matrices_stack; + inline void setRenderMonitor(RenderMonitor *iRenderMonitor) + { + _pRenderMonitor = iRenderMonitor; + } + + protected: + virtual bool buildWShape(WShape &shape, IndexedFaceSet &ifs); + virtual void buildWVertices(WShape &shape, const float *vertices, unsigned vsize); + + RenderMonitor *_pRenderMonitor; + + private: + void buildTriangleStrip(const float *vertices, + const float *normals, + vector &iMaterials, + const float *texCoords, + const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, + const unsigned *vindices, + const unsigned *nindices, + const unsigned *mindices, + const unsigned *tindices, + const unsigned nvertices); + + void buildTriangleFan(const float *vertices, + const float *normals, + vector &iMaterials, + const float *texCoords, + const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, + const unsigned *vindices, + const unsigned *nindices, + const unsigned *mindices, + const unsigned *tindices, + const unsigned nvertices); + + void buildTriangles(const float *vertices, + const float *normals, + vector &iMaterials, + const float *texCoords, + const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, + const unsigned *vindices, + const unsigned *nindices, + const unsigned *mindices, + const unsigned *tindices, + const unsigned nvertices); + + void transformVertices(const float *vertices, + unsigned vsize, + const Matrix44r &transform, + float *res); + + void transformNormals(const float *normals, + unsigned nsize, + const Matrix44r &transform, + float *res); + + WShape *_current_wshape; + FrsMaterial *_current_frs_material; + WingedEdge *_winged_edge; + Matrix44r *_current_matrix; + vector _matrices_stack; #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WingedEdgeBuilder") + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WingedEdgeBuilder") #endif }; } /* namespace Freestyle */ -#endif // __FREESTYLE_WINGED_EDGE_BUILDER_H__ +#endif // __FREESTYLE_WINGED_EDGE_BUILDER_H__ -- cgit v1.2.3