diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-01-02 05:55:30 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-01-02 05:55:30 +0400 |
commit | 699da2fb0d9012cef5e45cc1b547a01fd92dbc1c (patch) | |
tree | eb6e3de1f90387af1a2628bbc79d51327e3ac248 /source/blender/freestyle/intern/winged_edge | |
parent | 520ab93465d8056bf6d4a4115743daaee4c2fd66 (diff) |
Yet another big style clean-up patch by Bastien Montagne, thanks a lot!
Now the code style is acceptable for the merge now, according to Bastien.
Thanks again Bastien for having this done! :)
Diffstat (limited to 'source/blender/freestyle/intern/winged_edge')
15 files changed, 4447 insertions, 3902 deletions
diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.cpp b/source/blender/freestyle/intern/winged_edge/Curvature.cpp index ce8fc5b98fa..acefe1aa5fc 100644 --- a/source/blender/freestyle/intern/winged_edge/Curvature.cpp +++ b/source/blender/freestyle/intern/winged_edge/Curvature.cpp @@ -1,646 +1,642 @@ -/* GTS - Library for the manipulation of triangulated surfaces - * Copyright (C) 1999-2002 Ray Jones, Stéphane Popinet +/* + * ***** BEGIN GPL LICENSE BLOCK ***** * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * This Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: + * GTS - Library for the manipulation of triangulated surfaces + * Copyright (C) 1999 Stephane Popinet + * and: + * OGF/Graphite: Geometry and Graphics Programming Library + Utilities + * Copyright (C) 2000-2003 Bruno Levy + * Contact: Bruno Levy levy@loria.fr + * ISA Project + * LORIA, INRIA Lorraine, + * Campus Scientifique, BP 239 + * 54506 VANDOEUVRE LES NANCY CEDEX + * FRANCE + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** */ +/** \file blender/freestyle/intern/winged_edge/Curvature.cpp + * \ingroup freestyle + * \brief GTS - Library for the manipulation of triangulated surfaces + * \author Stephane Popinet + * \date 1999 + * \brief OGF/Graphite: Geometry and Graphics Programming Library + Utilities + * \author Bruno Levy + * \date 2000-2003 + */ + +#include <assert.h> #include <cstdlib> // for malloc and free -#include "Curvature.h" #include <math.h> -#include <assert.h> -#include "WEdge.h" -#include "../system/FreestyleConfig.h" -#include "../geometry/normal_cycle.h" #include <set> #include <stack> -static bool angle_obtuse (WVertex * v, WFace * f) +#include "Curvature.h" +#include "WEdge.h" + +#include "../geometry/normal_cycle.h" + +#include "../system/FreestyleConfig.h" + +static bool angle_obtuse(WVertex *v, WFace *f) { - WOEdge * e; - f->getOppositeEdge (v, e); - - Vec3r vec1(e->GetaVertex()->GetVertex()-v->GetVertex()); - Vec3r vec2(e->GetbVertex()->GetVertex()-v->GetVertex()); - return ((vec1 * vec2) < 0); + WOEdge *e; + f->getOppositeEdge(v, e); + + 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) +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) +static real cotan(WVertex *vo, WVertex *v1, WVertex *v2) { - /* cf. Appendix B of [Meyer et al 2002] */ - real udotv, denom; - - Vec3r u(v1->GetVertex()- vo->GetVertex()); - Vec3r v(v2->GetVertex()- vo->GetVertex()); + /* cf. Appendix B of [Meyer et al 2002] */ + real udotv, denom; - udotv = u * v; - denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv); + Vec3r u(v1->GetVertex() - vo->GetVertex()); + Vec3r v(v2->GetVertex() - vo->GetVertex()); - /* 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); + udotv = u * v; + denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv); - 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) +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: - * @v: a #WVertex. - * @s: a #GtsSurface. - * @Kh: the Mean Curvature Normal at @v. +/*! gts_vertex_mean_curvature_normal: + * @v: a #WVertex. + * @s: a #GtsSurface. + * @Kh: the Mean Curvature Normal at @v. * - * Computes the Discrete Mean Curvature Normal approximation at @v. - * The mean curvature at @v is half the magnitude of the vector @Kh. + * Computes the Discrete Mean Curvature Normal approximation at @v. + * The mean curvature at @v is half the magnitude of the vector @Kh. * - * Note: the normal computed is not unit length, and may point either - * into or out of the surface, depending on the curvature at @v. It - * is the responsibility of the caller of the function to use the mean - * curvature normal appropriately. + * Note: the normal computed is not unit length, and may point either into or out of the surface, depending on + * the curvature at @v. It is the responsibility of the caller of the function to use the mean curvature normal + * appropriately. * - * This approximation is from the paper: - * Discrete Differential-Geometry Operators for Triangulated 2-Manifolds - * Mark Meyer, Mathieu Desbrun, Peter Schroder, Alan H. Barr - * VisMath '02, Berlin (Germany) - * http://www-grail.usc.edu/pubs.html + * This approximation is from the paper: + * Discrete Differential-Geometry Operators for Triangulated 2-Manifolds + * Mark Meyer, Mathieu Desbrun, Peter Schroder, Alan H. Barr + * VisMath '02, Berlin (Germany) + * http://www-grail.usc.edu/pubs.html * - * Returns: %TRUE if the operator could be evaluated, %FALSE if the - * evaluation failed for some reason (@v is boundary or is the - * endpoint of a non-manifold edge.) + * Returns: %TRUE if the operator could be evaluated, %FALSE if the evaluation failed for some reason (@v is + * boundary or is the endpoint of a non-manifold edge.) */ -bool gts_vertex_mean_curvature_normal (WVertex * v, Vec3r &Kh) +bool gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &Kh) { 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; - - WVertex::incoming_edge_iterator itE; - - for (itE=v->incoming_edges_begin(); - itE!=v->incoming_edges_end(); itE++) - area+=(*itE)->GetaFace()->getArea(); - - Kh=Vec3r(0.0, 0.0, 0.0); - - for (itE=v->incoming_edges_begin(); - itE!=v->incoming_edges_end(); itE++) - { - WOEdge * e = (*itE)->getPrevOnFace(); - //if ((e->GetaVertex()==v) || (e->GetbVertex()==v)) cerr<< "BUG "; + if (v->isBoundary()) + return false; - WVertex * v1 = e->GetaVertex(); - WVertex * v2 = e->GetbVertex(); - real temp; - - temp = cotan (v1, v, v2); - Kh = Vec3r(Kh+temp*(v2->GetVertex()-v->GetVertex())); + WVertex::incoming_edge_iterator itE; - 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; + for (itE=v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) + area += (*itE)->GetaFace()->getArea(); + + Kh = Vec3r(0.0, 0.0, 0.0); + + 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 "; +#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; } -/** - * gts_vertex_gaussian_curvature: - * @v: a #WVertex. - * @s: a #GtsSurface. - * @Kg: the Discrete Gaussian Curvature approximation at @v. +/*! gts_vertex_gaussian_curvature: + * @v: a #WVertex. + * @s: a #GtsSurface. + * @Kg: the Discrete Gaussian Curvature approximation at @v. * - * Computes the Discrete Gaussian Curvature approximation at @v. + * Computes the Discrete Gaussian Curvature approximation at @v. * - * This approximation is from the paper: - * Discrete Differential-Geometry Operators for Triangulated 2-Manifolds - * Mark Meyer, Mathieu Desbrun, Peter Schroder, Alan H. Barr - * VisMath '02, Berlin (Germany) - * http://www-grail.usc.edu/pubs.html + * This approximation is from the paper: + * Discrete Differential-Geometry Operators for Triangulated 2-Manifolds + * Mark Meyer, Mathieu Desbrun, Peter Schroder, Alan H. Barr + * VisMath '02, Berlin (Germany) + * http://www-grail.usc.edu/pubs.html * - * Returns: %TRUE if the operator could be evaluated, %FALSE if the - * evaluation failed for some reason (@v is boundary or is the - * endpoint of a non-manifold edge.) + * Returns: %TRUE if the operator could be evaluated, %FALSE if the evaluation failed for some reason (@v is + * boundary or is the endpoint of a non-manifold edge.) */ -bool gts_vertex_gaussian_curvature (WVertex * v, real * Kg) +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; + if (!v) + return false; + if (!Kg) + return false; + + /* this operator is not defined for boundary edges */ + if (v->isBoundary()) { + *Kg = 0.0; + 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; + 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: - * @Kh: mean curvature. - * @Kg: Gaussian curvature. - * @K1: first principal curvature. - * @K2: second principal curvature. +/*! gts_vertex_principal_curvatures: + * @Kh: mean curvature. + * @Kg: Gaussian curvature. + * @K1: first principal curvature. + * @K2: second principal curvature. * - * Computes the principal curvatures at a point given the mean and - * Gaussian curvatures at that point. + * Computes the principal curvatures at a point given the mean and Gaussian curvatures at that point. * - * The mean curvature can be computed as one-half the magnitude of the - * vector computed by gts_vertex_mean_curvature_normal(). + * The mean curvature can be computed as one-half the magnitude of the vector computed by + * gts_vertex_mean_curvature_normal(). * - * The Gaussian curvature can be computed with - * gts_vertex_gaussian_curvature(). + * 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) return; - if (!K1) 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) +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) +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: - * @v: a #WVertex. - * @s: a #GtsSurface. - * @Kh: mean curvature normal (a #Vec3r). - * @Kg: Gaussian curvature (a real). - * @e1: first principal curvature direction (direction of largest curvature). - * @e2: second principal curvature direction. +/*! gts_vertex_principal_directions: + * @v: a #WVertex. + * @s: a #GtsSurface. + * @Kh: mean curvature normal (a #Vec3r). + * @Kg: Gaussian curvature (a real). + * @e1: first principal curvature direction (direction of largest curvature). + * @e2: second principal curvature direction. * - * Computes the principal curvature directions at a point given @Kh - * and @Kg, the mean curvature normal and Gaussian curvatures at that - * point, computed with gts_vertex_mean_curvature_normal() and - * gts_vertex_gaussian_curvature(), respectively. + * Computes the principal curvature directions at a point given @Kh and @Kg, the mean curvature normal and + * Gaussian curvatures at that point, computed with gts_vertex_mean_curvature_normal() and + * gts_vertex_gaussian_curvature(), respectively. * - * Note that this computation is very approximate and tends to be - * unstable. Smoothing of the surface or the principal directions may - * be necessary to achieve reasonable results. + * Note that this computation is very approximate and tends to be unstable. Smoothing of the surface or the principal + * directions may be necessary to achieve reasonable results. */ -void gts_vertex_principal_directions (WVertex * v, - Vec3r Kh, real Kg, - Vec3r &e1, Vec3r &e2) +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 { - inline static real angle(WOEdge * h) { - const Vec3r& n1 = h->GetbFace()->GetNormal(); - const Vec3r& n2 = h->GetaFace()->GetNormal(); - const Vec3r v = h->getVec3r(); - 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) ; - } - - // 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 - ) { - - 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 - ) { - // in case we have a non-manifold vertex, skip it... - if(start->isBoundary()) - return; - - std::set<WVertex*> vertices ; - const Vec3r& O = start->GetVertex() ; - std::stack<WVertex*> 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 - ) { - // 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()) ; - } - } +inline static real angle(WOEdge *h) +{ + const Vec3r& n1 = h->GetbFace()->GetNormal(); + const Vec3r& n2 = h->GetaFace()->GetNormal(); + const Vec3r v = h->getVec3r(); + 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); +} + +// 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) +{ + 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) +{ + // in case we have a non-manifold vertex, skip it... + if(start->isBoundary()) + return; + + std::set<WVertex*> vertices; + const Vec3r& O = start->GetVertex(); + std::stack<WVertex*> 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) +{ + // 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 diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.h b/source/blender/freestyle/intern/winged_edge/Curvature.h index b14a5a38337..20450dbdb38 100644 --- a/source/blender/freestyle/intern/winged_edge/Curvature.h +++ b/source/blender/freestyle/intern/winged_edge/Curvature.h @@ -1,29 +1,59 @@ - -/* GTS - Library for the manipulation of triangulated surfaces - * Copyright (C) 1999 Stéphane Popinet +/* + * ***** BEGIN GPL LICENSE BLOCK ***** * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * This Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: + * GTS - Library for the manipulation of triangulated surfaces + * Copyright (C) 1999 Stephane Popinet + * and: + * OGF/Graphite: Geometry and Graphics Programming Library + Utilities + * Copyright (C) 2000-2003 Bruno Levy + * Contact: Bruno Levy levy@loria.fr + * ISA Project + * LORIA, INRIA Lorraine, + * Campus Scientifique, BP 239 + * 54506 VANDOEUVRE LES NANCY CEDEX + * FRANCE + * + * Contributor(s): none yet. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * ***** END GPL LICENSE BLOCK ***** */ -#ifndef __CURVATURE_H__ -#define __CURVATURE_H__ +#ifndef __FREESTYLE_CURVATURE_H__ +#define __FREESTYLE_CURVATURE_H__ + +/** \file blender/freestyle/intern/winged_edge/Curvature.h + * \ingroup freestyle + * \brief GTS - Library for the manipulation of triangulated surfaces + * \author Stephane Popinet + * \date 1999 + * \brief OGF/Graphite: Geometry and Graphics Programming Library + Utilities + * \author Bruno Levy + * \date 2000-2003 + */ + +#include "../geometry/Geom.h" + +#include "../system/FreestyleConfig.h" +#include "../system/Precision.h" -# include "../system/FreestyleConfig.h" -# include "../system/Precision.h" -# include "../geometry/Geom.h" using namespace Geometry; class WVertex; @@ -31,126 +61,83 @@ class WVertex; class LIB_WINGED_EDGE_EXPORT 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 + 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 Face_Curvature_Info{ +class Face_Curvature_Info +{ public: - Face_Curvature_Info() {} - ~Face_Curvature_Info(){ - for(vector<CurvatureInfo*>::iterator ci=vec_curvature_info.begin(), ciend=vec_curvature_info.end(); - ci!=ciend; - ++ci){ - delete (*ci); - } - vec_curvature_info.clear(); - } - vector<CurvatureInfo *> vec_curvature_info; + Face_Curvature_Info() {} + + ~Face_Curvature_Info() + { + for (vector<CurvatureInfo*>::iterator ci = vec_curvature_info.begin(), ciend = vec_curvature_info.end(); + ci != ciend; + ++ci) + { + delete (*ci); + } + vec_curvature_info.clear(); + } + + vector<CurvatureInfo *> vec_curvature_info; }; -bool LIB_WINGED_EDGE_EXPORT gts_vertex_mean_curvature_normal (WVertex * v, - Vec3r &n); +bool LIB_WINGED_EDGE_EXPORT gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &n); -bool LIB_WINGED_EDGE_EXPORT gts_vertex_gaussian_curvature (WVertex * v, - real * Kg); +bool LIB_WINGED_EDGE_EXPORT gts_vertex_gaussian_curvature(WVertex *v, real *Kg); -void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_curvatures (real Kh, - real Kg, - real * K1, - real * K2); +void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_curvatures(real Kh, real Kg, real *K1, real *K2); -void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_directions (WVertex * v, - Vec3r Kh, - real Kg, - Vec3r &e1, - Vec3r &e2); - -/* - * OGF/Graphite: Geometry and Graphics Programming Library + Utilities - * Copyright (C) 2000-2003 Bruno Levy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * If you modify this software, you should include a notice giving the - * name of the person performing the modification, the date of modification, - * and the reason for such modification. - * - * Contact: Bruno Levy - * - * levy@loria.fr - * - * ISA Project - * LORIA, INRIA Lorraine, - * Campus Scientifique, BP 239 - * 54506 VANDOEUVRE LES NANCY CEDEX - * FRANCE - * - * Note that the GNU General Public License does not permit incorporating - * the Software into proprietary programs. - */ - namespace OGF { +void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, Vec3r &e2); - class NormalCycle ; +namespace OGF { - void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor( - WVertex* start, double radius, NormalCycle& nc - ) ; +class NormalCycle ; - void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor_one_ring( - WVertex* start, NormalCycle& nc - ) ; - } +void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor( WVertex *start, double radius, NormalCycle& nc); +void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor_one_ring(WVertex *start, NormalCycle& nc); -#endif /* __CURVATURE_H__ */ +} // OGF namespace +#endif /* __FREESTYLE_CURVATURE_H__ */ diff --git a/source/blender/freestyle/intern/winged_edge/Nature.h b/source/blender/freestyle/intern/winged_edge/Nature.h index 62171fae111..0ce64f3f1cb 100644 --- a/source/blender/freestyle/intern/winged_edge/Nature.h +++ b/source/blender/freestyle/intern/winged_edge/Nature.h @@ -1,79 +1,79 @@ -// -// Filename : Nature.h -// Author(s) : Emmanuel Turquin -// Purpose : Different natures for both vertices and edges -// Date of creation : 01/07/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ -#ifndef NATURE_H -# define NATURE_H +#ifndef __FREESTYLE_NATURE_H__ +#define __FREESTYLE_NATURE_H__ -/*! \file Nature.h - * Definitions of Natures of the ViewMap's elements +/** \file blender/freestyle/intern/winged_edge/Nature.h + * \ingroup freestyle + * \brief Different natures for both vertices and edges + * \author Emmanuel Turquin + * \date 01/07/2003 */ -/*! Namespace gathering the different possible - * natures of 0D and 1D elements of the ViewMap - */ +/*! Namespace gathering the different possible natures of 0D and 1D elements of the ViewMap */ namespace Nature { - - typedef unsigned short VertexNature; - /*! true for any 0D element */ - static const VertexNature POINT = 0; // 0 - /*! true for SVertex */ - static const VertexNature S_VERTEX = (1 << 0); // 1 - /*! true for ViewVertex */ - static const VertexNature VIEW_VERTEX = (1 << 1); // 2 - /*! true for NonTVertex */ - static const VertexNature NON_T_VERTEX = (1 << 2); // 4 - /*! true for TVertex */ - static const VertexNature T_VERTEX = (1 << 3); // 8 - /*! true for CUSP */ - static const VertexNature CUSP = (1 << 4); // 16 +/* XXX Why not using enums??? */ + +typedef unsigned short VertexNature; +/*! true for any 0D element */ +static const VertexNature POINT = 0; // 0 +/*! true for SVertex */ +static const VertexNature S_VERTEX = (1 << 0); // 1 +/*! true for ViewVertex */ +static const VertexNature VIEW_VERTEX = (1 << 1); // 2 +/*! true for NonTVertex */ +static const VertexNature NON_T_VERTEX = (1 << 2); // 4 +/*! true for TVertex */ +static const VertexNature T_VERTEX = (1 << 3); // 8 +/*! true for CUSP */ +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 - /*! true for silhouettes */ - static const EdgeNature SILHOUETTE = (1 << 0); // 1 - /*! true for borders */ - static const EdgeNature BORDER = (1 << 1); // 2 - /*! true for creases */ - static const EdgeNature CREASE = (1 << 2); // 4 - /*! true for ridges */ - static const EdgeNature RIDGE = (1 << 3); // 8 - /*! true for valleys */ - static const EdgeNature VALLEY = (1 << 4); // 16 - /*! true for suggestive contours */ - static const EdgeNature SUGGESTIVE_CONTOUR = (1 << 5); // 32 - /*! true for material boundaries */ - static const EdgeNature MATERIAL_BOUNDARY = (1 << 6); // 64 - /*! true for user-defined edge marks */ - static const EdgeNature EDGE_MARK = (1 << 7); // 128 +typedef unsigned short EdgeNature; +/*! true for non feature edges (always false for 1D elements of the ViewMap) */ +static const EdgeNature NO_FEATURE = 0; // 0 +/*! true for silhouettes */ +static const EdgeNature SILHOUETTE = (1 << 0); // 1 +/*! true for borders */ +static const EdgeNature BORDER = (1 << 1); // 2 +/*! true for creases */ +static const EdgeNature CREASE = (1 << 2); // 4 +/*! true for ridges */ +static const EdgeNature RIDGE = (1 << 3); // 8 +/*! true for valleys */ +static const EdgeNature VALLEY = (1 << 4); // 16 +/*! true for suggestive contours */ +static const EdgeNature SUGGESTIVE_CONTOUR = (1 << 5); // 32 +/*! true for material boundaries */ +static const EdgeNature MATERIAL_BOUNDARY = (1 << 6); // 64 +/*! true for user-defined edge marks */ +static const EdgeNature EDGE_MARK = (1 << 7); // 128 } // end of namespace Nature -#endif // 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 6ef99186a2c..6201d23f9bf 100644 --- a/source/blender/freestyle/intern/winged_edge/WEdge.cpp +++ b/source/blender/freestyle/intern/winged_edge/WEdge.cpp @@ -1,752 +1,713 @@ - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/freestyle/intern/winged_edge/WEdge.cpp + * \ingroup freestyle + * \brief Classes to define a Winged Edge data structure. + * \author Stephane Grabli + * \date 18/02/2002 + */ #include <iostream> + #include "WEdge.h" /*! Temporary structures */ class vertexdata { public: - WVertex *_copy; + WVertex *_copy; }; class oedgedata { public: - WOEdge *_copy; + WOEdge *_copy; }; class edgedata { public: - WEdge *_copy; + WEdge *_copy; }; class facedata { public: - WFace *_copy; + WFace *_copy; }; - /**********************************/ - /* */ - /* */ - /* WVertex */ - /* */ - /* */ - /**********************************/ +/********************************** + * * + * * + * WVertex * + * * + * * + **********************************/ 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 *WVertex::duplicate() { - WVertex *clone = new WVertex(*this); - return clone; + WVertex *clone = new WVertex(*this); + return clone; } - -WOEdge* WVertex::incoming_edge_iterator::operator*() - -{ - return _current; +WOEdge *WVertex::incoming_edge_iterator::operator*() +{ + 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 = 0; - } - _current = next; + +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; } -WFace* WVertex::face_iterator::operator*(){ - WOEdge * woedge = *_edge_it; - if(woedge == 0) - return 0; - return (woedge)->GetbFace(); +WFace *WVertex::face_iterator::operator*() +{ + WOEdge *woedge = *_edge_it; + if (!woedge) + return NULL; + return (woedge)->GetbFace(); } -//bool WVertex::isBoundary () const{ -// return _Border; -//} +#if 0 +bool WVertex::isBoundary () const +{ + return _Border; +} +#endif bool WVertex::isBoundary () { - if(_Border == 1) - return true; - else if(_Border == 0) - return false; - + if (_Border == 1) + return true; + else if (_Border == 0) + return false; + vector<WEdge *>::const_iterator it; - for(it=_EdgeList.begin(); it!=_EdgeList.end(); it++){ - if((*it)->GetNumberOfOEdges() == 1){ - _Border = 1; - return true; - } - } - //if (!(*it)->GetaOEdge()->GetaFace()) return true; - _Border = 0; + for (it = _EdgeList.begin(); it != _EdgeList.end(); it++) { + if ((*it)->GetNumberOfOEdges() == 1) { + _Border = 1; + return true; + } + } +#if 0 + if (!(*it)->GetaOEdge()->GetaFace()) + return true; +#endif + _Border = 0; return false; } -void WVertex::AddEdge(WEdge *iEdge) { - _EdgeList.push_back(iEdge); +void WVertex::AddEdge(WEdge *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); +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); +} + +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); } -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); +#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** WVertex::incoming_edge_iterator::operator->() -//{ -// WOEdge ** ppaOEdge = (*_iter)->GetaOEdge(); -// if(aOEdge->GetbVertex() == _vertex) -// return ppaOEdge; -// else -// { -// WOEdge *bOEdge = (*_iter)->GetbOEdge(); -// return &bOEdge; -// } -// -//} - /**********************************/ - /* */ - /* */ - /* WOEdge */ - /* */ - /* */ - /**********************************/ +#endif + +/********************************** + * * + * * + * WOEdge * + * * + * * + **********************************/ 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 *WOEdge::duplicate() { - WOEdge *clone = new WOEdge(*this); - return clone; + WOEdge *clone = new WOEdge(*this); + return clone; } -Vec3r -WOEdge::getVec3r () +Vec3r WOEdge::getVec3r () { - return Vec3r(_pbVertex->GetVertex() - _paVertex->GetVertex()); -} + return Vec3r(_pbVertex->GetVertex() - _paVertex->GetVertex()); +} -WOEdge * WOEdge::twin () +WOEdge *WOEdge::twin () { - return GetOwner()->GetOtherOEdge(this); + return GetOwner()->GetOtherOEdge(this); } -WOEdge * -WOEdge::getPrevOnFace() +WOEdge *WOEdge::getPrevOnFace() { return _pbFace->GetPrevOEdge(this); } - /**********************************/ - /* */ - /* */ - /* WEdge */ - /* */ - /* */ - /**********************************/ +/********************************** + * * + * * + * WEdge * + * * + * * + **********************************/ WEdge::WEdge(WEdge& iBrother) { - _paOEdge = NULL; - _pbOEdge = NULL; - WOEdge *aoedge = iBrother.GetaOEdge(); - WOEdge *boedge = iBrother.GetbOEdge(); - userdata = NULL; - - if(NULL != aoedge) - //_paOEdge = new WOEdge(*aoedge); - _paOEdge = aoedge->duplicate(); - if(NULL != boedge) - //_pbOEdge = new WOEdge(*boedge); - _pbOEdge = boedge->duplicate(); - - _nOEdges = iBrother.GetNumberOfOEdges(); - _Id = iBrother.GetId(); - iBrother.userdata = new edgedata; - ((edgedata*)(iBrother.userdata))->_copy = this; + _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 *WEdge::duplicate() { - WEdge *clone = new WEdge(*this); - return clone; + WEdge *clone = new WEdge(*this); + return clone; } - /**********************************/ - /* */ - /* */ - /* WFace */ - /* */ - /* */ - /**********************************/ - +/********************************** + * * + * * + * WFace * + * * + * * + **********************************/ 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; + _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 *WFace::duplicate() { - WFace * clone = new WFace(*this); - return clone; + WFace *clone = new WFace(*this); + return clone; } -const FrsMaterial& WFace::frs_material() { - return getShape()->frs_material(_FrsMaterialIndex); +const FrsMaterial& WFace::frs_material() +{ + return getShape()->frs_material(_FrsMaterialIndex); } -WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2) -{ - // First check whether the same oriented edge already exists - // or not: - vector<WEdge *>& v1Edges = v1->GetEdges(); - for(vector<WEdge*>::iterator it1=v1Edges.begin(), end=v1Edges.end(); - it1!=end; - it1++) - { - - WEdge *we=(*it1); - - WOEdge *woea = we->GetaOEdge(); - - if((woea->GetaVertex() == v1) && (woea->GetbVertex() == v2)) - //if((*it1)->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((*it1)->GetaOEdge()); - AddEdge(woea); - (*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges()+1); - //sets these vertices as border: - v1->setBorder(true); - v2->setBorder(true); - //return (*it1)->GetaOEdge(); - return woea; - } - - WOEdge *woeb = we->GetbOEdge(); - if((woeb != 0) && (woeb->GetaVertex() == v1) && (woeb->GetbVertex() == v2)) - - //if((*it1)->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((*it1)->GetaOEdge()); - AddEdge(woeb); - (*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges()+1); - //sets these vertices as border: - v1->setBorder(true); - v2->setBorder(true); - //return (*it1)->GetaOEdge(); - return woeb; - } - } - - // the oriented edge we're about to build - WOEdge *pOEdge = new WOEdge; - - WEdge * edge; // The edge containing the oriented 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<WEdge *>& v2Edges = v2->GetEdges(); - vector<WEdge *>::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; +WOEdge *WFace::MakeEdge(WVertex *v1, WVertex *v2) +{ + // First check whether the same oriented edge already exists or not: + vector<WEdge *>& v1Edges = v1->GetEdges(); + for (vector<WEdge*>::iterator it1 = v1Edges.begin(), end = v1Edges.end(); it1 != end; it1++) { + WEdge *we = (*it1); + WOEdge *woea = we->GetaOEdge(); + + //if ((*it1)->GetbVertex() == v2) { + 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((*it1)->GetaOEdge()); + AddEdge(woea); + (*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges()+1); + //sets these vertices as border: + v1->setBorder(true); + v2->setBorder(true); + //return (*it1)->GetaOEdge(); + return woea; + } + + WOEdge *woeb = we->GetbOEdge(); + //if ((*it1)->GetbVertex() == v2) + 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((*it1)->GetaOEdge()); + AddEdge(woeb); + (*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges()+1); + //sets these vertices as border: + v1->setBorder(true); + v2->setBorder(true); + //return (*it1)->GetaOEdge(); + 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<WEdge *>& v2Edges = v2->GetEdges(); + vector<WEdge *>::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) +bool WFace::getOppositeEdge (const WVertex *v, WOEdge *&e) { - if (_OEdgeList.size()!=3) return false; + if (_OEdgeList.size() != 3) + return false; vector<WOEdge *>::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; + 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; } -real -WFace::getArea () +real WFace::getArea () { vector<WOEdge *>::iterator it; - Vec3r origin=(*(_OEdgeList.begin()))->GetaVertex()->GetVertex(); - it=_OEdgeList.begin(); - real a=0; - for (it=it++; it!=_OEdgeList.end(); it++) { - Vec3r v1=Vec3r((*it)->GetaVertex()->GetVertex() - origin); - Vec3r v2=Vec3r((*it)->GetbVertex()->GetVertex() - origin); - a += (v1 ^ v2).norm() / 2.0; + Vec3r origin = (*(_OEdgeList.begin()))->GetaVertex()->GetVertex(); + it = _OEdgeList.begin(); + real a = 0; + for (it = it++; it != _OEdgeList.end(); it++) { + Vec3r v1 = Vec3r((*it)->GetaVertex()->GetVertex() - origin); + Vec3r v2 = Vec3r((*it)->GetbVertex()->GetVertex() - origin); + a += (v1 ^ v2).norm() / 2.0; } return a; } -WOEdge* -WFace::GetPrevOEdge(WOEdge* iOEdge) - { - vector<WOEdge*>::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; +WOEdge *WFace::GetPrevOEdge(WOEdge* iOEdge) +{ + vector<WOEdge *>::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; + // We left the loop. That means that the first OEdge was the good one: + if ((*woefirst) == iOEdge) + return prev; - return NULL; - } + return NULL; +} -WShape * WFace::getShape() +WShape *WFace::getShape() { - return GetVertex(0)->shape(); + return GetVertex(0)->shape(); } - /**********************************/ - /* */ - /* */ - /* WShape */ - /* */ - /* */ - /**********************************/ +/********************************** + * * + * * + * WShape * + * * + * * + **********************************/ LIB_WINGED_EDGE_EXPORT unsigned WShape::_SceneCurrentId = 0; -WShape * WShape::duplicate() +WShape *WShape::duplicate() { - WShape *clone = new WShape(*this); - return clone; + WShape *clone = new WShape(*this); + return clone; } WShape::WShape(WShape& iBrother) { - _Id = iBrother.GetId(); - _Name = iBrother._Name; - _FrsMaterials = iBrother._FrsMaterials; - _meanEdgeSize = iBrother._meanEdgeSize; - iBrother.bbox(_min, _max); - vector<WVertex*>& vertexList = iBrother.getVertexList(); - vector<WVertex*>::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<WEdge*>& edgeList = iBrother.getEdgeList(); - vector<WEdge*>::iterator e=edgeList.begin(), eend=edgeList.end(); - for(; - e!=eend; - e++) - { - //WEdge *newEdge = new WEdge(*(*e)); - WEdge *newEdge = (*e)->duplicate(); - AddEdge(newEdge); - } - - vector<WFace*>& faceList = iBrother.GetFaceList(); - vector<WFace*>::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<WEdge*>& vedgeList = (*v)->GetEdges(); - vector<WEdge*> 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(NULL != 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 != 0) - { - boEdge->setaVertex(((vertexdata*)(boEdge->GetaVertex()->userdata))->_copy); - boEdge->setbVertex(((vertexdata*)(boEdge->GetbVertex()->userdata))->_copy); - if(NULL != 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 i; - const vector<WOEdge*>& oedgeList = (*f)->getEdgeList(); - vector<WOEdge*> newoedgelist; - - unsigned 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(NULL != 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; - } -} + _Id = iBrother.GetId(); + _Name = iBrother._Name; + _FrsMaterials = iBrother._FrsMaterials; + _meanEdgeSize = iBrother._meanEdgeSize; + iBrother.bbox(_min, _max); + vector<WVertex *>& vertexList = iBrother.getVertexList(); + vector<WVertex *>::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); + } -WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial) -{ - // allocate the new face - WFace *face = instanciateFace(); + vector<WEdge *>& edgeList = iBrother.getEdgeList(); + vector<WEdge *>::iterator e = edgeList.begin(), eend = edgeList.end(); + for (; e != eend; ++e) { + //WEdge *newEdge = new WEdge(*(*e)); + WEdge *newEdge = (*e)->duplicate(); + AddEdge(newEdge); + } - WFace *result = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial, face); - if (0 == result) { - delete face; - return 0; - } - return result; -} + vector<WFace *>& faceList = iBrother.GetFaceList(); + vector<WFace *>::iterator f = faceList.begin(), fend = faceList.end(); + for (; f != fend; ++f) { + //WFace *newFace = new WFace(*(*f)); + WFace *newFace = (*f)->duplicate(); + AddFace(newFace); + } -WFace * WShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial) -{ - // allocate the new face - WFace *face = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial); + // update all pointed addresses thanks to the newly created objects: + vend = _VertexList.end(); + for (v = _VertexList.begin(); v != vend; ++v) { + const vector<WEdge *>& vedgeList = (*v)->GetEdges(); + vector<WEdge *> 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); + } + } - if(0 == face) + fend = _FaceList.end(); + for (f = _FaceList.begin(); f != fend; ++f) { + unsigned int i; + const vector<WOEdge *>& oedgeList = (*f)->getEdgeList(); + vector<WOEdge *> 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); + } - return 0; + // Free all memory (arghh!) + // Vertex + vend = iBrother.getVertexList().end(); + for (v = iBrother.getVertexList().begin(); v != vend; ++v) { + delete (vertexdata *)((*v)->userdata); + (*v)->userdata = NULL; + } - // set the list of per-vertex normals - face->setNormalList(iNormalsList); - // set the list of per-vertex tex coords - face->setTexCoordsList(iTexCoordsList); + // 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; + } + } - return face; + // Faces + fend = iBrother.GetFaceList().end(); + for (f = iBrother.GetFaceList().begin(); f != fend; ++f) { + delete (facedata *)((*f)->userdata); + (*f)->userdata = NULL; + } } -WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial, WFace *face) +WFace *WShape::MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial) { + // allocate the new face + WFace *face = instanciateFace(); - 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 0; - - } + WFace *result = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial, face); + if (!result) + delete face; + return result; +} - } +WFace *WShape::MakeFace(vector<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, + vector<bool>& iFaceEdgeMarksList, unsigned iMaterial) +{ + // allocate the new face + WFace *face = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial); - vector<WVertex*>::iterator it; + if (!face) + return NULL; - // compute the face normal (v1v2 ^ v1v3) - WVertex *v1, *v2, *v3; - it = iVertexList.begin(); - v1 = *it; - it++; - v2 = *it; - it++; - v3 = *it; + // set the list of per-vertex normals + face->setNormalList(iNormalsList); + // set the list of per-vertex tex coords + face->setTexCoordsList(iTexCoordsList); - Vec3r vector1(v2->GetVertex()-v1->GetVertex()); - Vec3r vector2(v3->GetVertex()-v1->GetVertex()); + return face; +} - Vec3r normal(vector1 ^ vector2); - normal.normalize(); - face->setNormal(normal); +WFace *WShape::MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial, + WFace *face) +{ + int id = _FaceList.size(); - vector<bool>::iterator mit = iFaceEdgeMarksList.begin(); - face->setMark(*mit); - mit++; + face->setFrsMaterialIndex(iMaterial); - // vertex pointers used to build each edge - vector<WVertex*>::iterator va, vb; + // Check whether we have a degenerated face: - va = iVertexList.begin(); - vb = va; - for(; va != iVertexList.end(); va = vb) - { - vb++; - // Adds va to the vertex list: - //face->AddVertex(*va); + // LET'S HACK IT FOR THE TRIANGLE CASE: - WOEdge * oedge; - if(*va == iVertexList.back()) - oedge = face->MakeEdge(*va, iVertexList.front()); //for the last (closing) edge - else - oedge = face->MakeEdge(*va, *vb); + 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<WVertex *>::iterator it; - if(oedge == 0) - return 0; + // compute the face normal (v1v2 ^ v1v3) + WVertex *v1, *v2, *v3; + it = iVertexList.begin(); + v1 = *it; + it++; + v2 = *it; + it++; + v3 = *it; + Vec3r vector1(v2->GetVertex() - v1->GetVertex()); + Vec3r vector2(v3->GetVertex() - v1->GetVertex()); - 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); - // compute the mean edge value: - _meanEdgeSize += edge->GetaOEdge()->GetVec().norm(); - } + Vec3r normal(vector1 ^ vector2); + normal.normalize(); + face->setNormal(normal); - edge->setMark(*mit); + vector<bool>::iterator mit = iFaceEdgeMarksList.begin(); + face->setMark(*mit); mit++; - } - // Add the face to the shape's faces list: - face->setId(id); - AddFace(face); + // vertex pointers used to build each edge + vector<WVertex *>::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); + // compute the mean edge value: + _meanEdgeSize += edge->GetaOEdge()->GetVec().norm(); + } + + edge->setMark(*mit); + ++mit; + } + + // Add the face to the shape's faces list: + face->setId(id); + AddFace(face); - return face; -} + return face; +}
\ No newline at end of file diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.h b/source/blender/freestyle/intern/winged_edge/WEdge.h index dc920448add..be9181329d6 100644 --- a/source/blender/freestyle/intern/winged_edge/WEdge.h +++ b/source/blender/freestyle/intern/winged_edge/WEdge.h @@ -1,991 +1,1344 @@ -// -// Filename : WEdge.h -// Author(s) : Stephane Grabli -// Purpose : Classes to define a Winged Edge data structure. -// Date of creation : 18/02/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef WEDGE_H -# define WEDGE_H - -# include <vector> -# include <iterator> -# include <math.h> -# include "../system/FreestyleConfig.h" -# include "../geometry/Geom.h" -# include "../scene_graph/FrsMaterial.h" +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __FREESTYLE_W_EDGE_H__ +#define __FREESTYLE_W_EDGE_H__ + +/** \file blender/freestyle/intern/winged_edge/WEdge.h + * \ingroup freestyle + * \brief Classes to define a Winged Edge data structure. + * \author Stephane Grabli + * \date 18/02/2002 + */ + +#include <iterator> +#include <math.h> +#include <vector> + +#include "../geometry/Geom.h" + +#include "../scene_graph/FrsMaterial.h" + +#include "../system/FreestyleConfig.h" using namespace std; using namespace Geometry; - /**********************************/ - /* */ - /* */ - /* WVertex */ - /* */ - /* */ - /**********************************/ +/********************************** + * * + * * + * WVertex * + * * + * * + **********************************/ class WOEdge; class WEdge; class WShape; class WFace; + class LIB_WINGED_EDGE_EXPORT WVertex { protected: - int _Id; // an identificator - Vec3r _Vertex; - vector<WEdge*> _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 - int _Border; // 1 -> border, 0 -> no border, -1 -> not set - -public: - void * userdata; // designed to store specific user data - inline WVertex(const Vec3r &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 Vec3r& GetVertex() {return _Vertex;} - inline vector<WEdge*>& 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 Vec3r& v) {_Vertex = v;} - inline void setEdges(const vector<WEdge *>& 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 = 0;} - - + int _Id; // an identificator + Vec3r _Vertex; + vector<WEdge*> _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 + int _Border; // 1 -> border, 0 -> no border, -1 -> not set public: + void *userdata; // designed to store specific user data + inline WVertex(const Vec3r &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 Vec3r& GetVertex() + { + return _Vertex; + } + + inline vector<WEdge*>& 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 Vec3r& v) + { + _Vertex = v; + } + + inline void setEdges(const vector<WEdge *>& 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; + } - - - /*! Iterator to iterate over a vertex incoming edges in the CCW order*/ -# if defined(__GNUC__) && (__GNUC__ < 3) - class incoming_edge_iterator : public input_iterator<WOEdge*,ptrdiff_t> -# else - class LIB_WINGED_EDGE_EXPORT incoming_edge_iterator : public iterator<input_iterator_tag, WOEdge*,ptrdiff_t> -# endif - { - private: - WVertex *_vertex; - // - WOEdge *_begin; - WOEdge *_current; - - public: -# if defined(__GNUC__) && (__GNUC__ < 3) - inline incoming_edge_iterator() : input_iterator<WOEdge*,ptrdiff_t>() {} -# else - inline incoming_edge_iterator() : iterator<input_iterator_tag, WOEdge*,ptrdiff_t>() {} -# endif - virtual ~incoming_edge_iterator() {}; //soc - - protected: - friend class WVertex; - inline incoming_edge_iterator( - WVertex *iVertex, - WOEdge * iBegin, - WOEdge * iCurrent) -# if defined(__GNUC__) && (__GNUC__ < 3) - : input_iterator<WOEdge*,ptrdiff_t>() -# else - : iterator<input_iterator_tag, WOEdge*,ptrdiff_t>() -# endif - { - _vertex = iVertex; - _begin = iBegin; - _current = iCurrent; - } - - public: - inline incoming_edge_iterator(const incoming_edge_iterator& iBrother) -# if defined(__GNUC__) && (__GNUC__ < 3) - : input_iterator<WOEdge*,ptrdiff_t>(iBrother) -# else - : iterator<input_iterator_tag, WOEdge*,ptrdiff_t>(iBrother) -# endif - { - _vertex = iBrother._vertex; - _begin = iBrother._begin; - _current = iBrother._current; - } - - public: - // operators - virtual incoming_edge_iterator& operator++() // operator corresponding to ++i - { - increment(); - return *this; - } - virtual incoming_edge_iterator operator++(int) // operator corresponding to i++ - { - 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(); - }; - - - /*! Iterator to iterate over a vertex faces in the CCW order */ -# if defined(__GNUC__) && (__GNUC__ < 3) - class face_iterator : public input_iterator<WFace*,ptrdiff_t> -# else - class LIB_WINGED_EDGE_EXPORT face_iterator : public iterator<input_iterator_tag, WFace*,ptrdiff_t> -# endif - { - private: - incoming_edge_iterator _edge_it; - - public: -# if defined(__GNUC__) && (__GNUC__ < 3) - inline face_iterator() : input_iterator<WFace*,ptrdiff_t>() {} -# else - inline face_iterator() : iterator<input_iterator_tag, WFace*,ptrdiff_t>() {} -# endif - virtual ~face_iterator() {}; //soc - - protected: - friend class WVertex; - inline face_iterator( - incoming_edge_iterator it) -# if defined(__GNUC__) && (__GNUC__ < 3) - : input_iterator<WFace*,ptrdiff_t>() -# else - : iterator<input_iterator_tag, WFace*,ptrdiff_t>() -# endif - { - _edge_it = it; - } - - public: - inline face_iterator(const face_iterator& iBrother) -# if defined(__GNUC__) && (__GNUC__ < 3) - : input_iterator<WFace*,ptrdiff_t>(iBrother) -# else - : iterator<input_iterator_tag, WFace*,ptrdiff_t>(iBrother) -# endif - { - _edge_it = iBrother._edge_it; - } - - public: - // operators - virtual face_iterator& operator++() // operator corresponding to ++i - { - increment(); - return *this; - } - virtual face_iterator operator++(int) // operator corresponding to i++ - { - 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; - } - }; +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<WOEdge *, ptrdiff_t> +#else + class LIB_WINGED_EDGE_EXPORT incoming_edge_iterator + : public iterator<input_iterator_tag, WOEdge *, ptrdiff_t> +#endif + { + private: + WVertex *_vertex; + // + WOEdge *_begin; + WOEdge *_current; + + public: +#if defined(__GNUC__) && (__GNUC__ < 3) + inline incoming_edge_iterator() : input_iterator<WOEdge *, ptrdiff_t>() {} +#else + inline incoming_edge_iterator() : iterator<input_iterator_tag, WOEdge *, ptrdiff_t>() {} +#endif + virtual ~incoming_edge_iterator() {}; //soc + + protected: + friend class WVertex; + inline incoming_edge_iterator(WVertex *iVertex, WOEdge *iBegin, WOEdge *iCurrent) +#if defined(__GNUC__) && (__GNUC__ < 3) + : input_iterator<WOEdge *, ptrdiff_t>() +#else + : iterator<input_iterator_tag, WOEdge *, ptrdiff_t>() +#endif + { + _vertex = iVertex; + _begin = iBegin; + _current = iCurrent; + } + + public: + inline incoming_edge_iterator(const incoming_edge_iterator& iBrother) +#if defined(__GNUC__) && (__GNUC__ < 3) + : input_iterator<WOEdge *, ptrdiff_t>(iBrother) +#else + : iterator<input_iterator_tag, WOEdge *, ptrdiff_t>(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(); + }; + + /*! Iterator to iterate over a vertex faces in the CCW order */ +#if defined(__GNUC__) && (__GNUC__ < 3) + class face_iterator : public input_iterator<WFace *, ptrdiff_t> +#else + class LIB_WINGED_EDGE_EXPORT face_iterator : public iterator<input_iterator_tag, WFace *, ptrdiff_t> +#endif + { + private: + incoming_edge_iterator _edge_it; + + public: +#if defined(__GNUC__) && (__GNUC__ < 3) + inline face_iterator() : input_iterator<WFace *, ptrdiff_t>() {} +#else + inline face_iterator() : iterator<input_iterator_tag, WFace *, ptrdiff_t>() {} +#endif + virtual ~face_iterator() {}; //soc + + protected: + friend class WVertex; + inline face_iterator(incoming_edge_iterator it) +#if defined(__GNUC__) && (__GNUC__ < 3) + : input_iterator<WFace *, ptrdiff_t>() +#else + : iterator<input_iterator_tag, WFace *, ptrdiff_t>() +#endif + { + _edge_it = it; + } + + public: + inline face_iterator(const face_iterator& iBrother) +#if defined(__GNUC__) && (__GNUC__ < 3) + : input_iterator<WFace *, ptrdiff_t>(iBrother) +#else + : iterator<input_iterator_tag, WFace *, ptrdiff_t>(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; + } + }; 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_end() { - return face_iterator(incoming_edges_end()); - } + /*! 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_end() + { + return face_iterator(incoming_edges_end()); + } }; - /**********************************/ - /* */ - /* */ - /* WOEdge */ - /* */ - /* */ - /**********************************/ +/********************************** + * * + * * + * WOEdge * + * * + * * + **********************************/ + class WFace; class WEdge; class LIB_WINGED_EDGE_EXPORT WOEdge { protected: - // 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 - 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 - - Vec3r _vec; - real _angle; +#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 +#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 + + Vec3r _vec; + real _angle; public: - - void *userdata; - inline WOEdge() - { - // _paCWEdge = NULL; - // _pbCWEdge = NULL; - // _paCCWEdge = NULL; - // _pbCCWEdge = NULL; - _paVertex = NULL; - _pbVertex = NULL; - _paFace = NULL; - _pbFace = NULL; - _pOwner = NULL; - userdata = NULL; - } - virtual ~WOEdge() {}; //soc - - /*! copy constructor */ - WOEdge(WOEdge& iBrother); - virtual WOEdge * duplicate(); - - /*! accessors */ - // inline WOEdge *GetaCWEdge() {return _paCWEdge;} - // inline WOEdge *GetbCWEdge() {return _pbCWEdge;} - // inline WOEdge *GetaCCWEdge() {return _paCCWEdge;} - // inline WOEdge *GetbCCWEdge() {return _pbCCWEdge;} - 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 Vec3r& GetVec() { return _vec; } - inline const real GetAngle() { return _angle; } - - - /*! modifiers */ - // 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 setVecAndAngle(); - inline void setaVertex(WVertex *pv) {_paVertex = pv; setVecAndAngle(); } - inline void setbVertex(WVertex *pv) {_pbVertex = pv; setVecAndAngle(); } - inline void setaFace(WFace *pf) {_paFace = pf; setVecAndAngle(); } - inline void setbFace(WFace *pf) {_pbFace = pf; setVecAndAngle(); } - inline void setOwner(WEdge *pe) {_pOwner = pe;} - - /*! Retrieves the list of edges in CW order */ - inline void RetrieveCWOrderedEdges(vector<WEdge*>& oEdges); - /*! returns the vector between the two vertices */ - Vec3r getVec3r (); - WOEdge * twin (); - WOEdge * getPrevOnFace(); - virtual void ResetUserData() {userdata = 0;} + void *userdata; + + inline WOEdge() + { +#if 0 + _paCWEdge = NULL; + _pbCWEdge = NULL; + _paCCWEdge = NULL; + _pbCCWEdge = NULL; +#endif + _paVertex = NULL; + _pbVertex = NULL; + _paFace = NULL; + _pbFace = NULL; + _pOwner = NULL; + userdata = NULL; + } + + virtual ~WOEdge() {}; //soc + + /*! copy constructor */ + WOEdge(WOEdge& iBrother); + virtual WOEdge *duplicate(); + + /*! accessors */ +#if 0 + 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 Vec3r& GetVec() + { + return _vec; + } + + inline const real 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; + } +#endif + + inline void setVecAndAngle(); + + inline void setaVertex(WVertex *pv) + { + _paVertex = pv; + setVecAndAngle(); + } + + inline void setbVertex(WVertex *pv) + { + _pbVertex = pv; + setVecAndAngle(); + } + + inline void setaFace(WFace *pf) + { + _paFace = pf; + setVecAndAngle(); + } + + inline void setbFace(WFace *pf) + { + _pbFace = pf; + setVecAndAngle(); + } + + inline void setOwner(WEdge *pe) + { + _pOwner = pe; + } + + /*! Retrieves the list of edges in CW order */ + inline void RetrieveCWOrderedEdges(vector<WEdge*>& oEdges); + + /*! returns the vector between the two vertices */ + Vec3r getVec3r (); + WOEdge *twin (); + WOEdge *getPrevOnFace(); + + virtual void ResetUserData() + { + userdata = NULL; + } }; - /**********************************/ - /* */ - /* */ - /* WEdge */ - /* */ - /* */ - /**********************************/ +/********************************** + * * + * * + * WEdge * + * * + * * + **********************************/ class LIB_WINGED_EDGE_EXPORT WEdge { protected: - WOEdge *_paOEdge; // first oriented edge - WOEdge *_pbOEdge; // second oriented edge - int _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 - + WOEdge *_paOEdge; // first oriented edge + WOEdge *_pbOEdge; // second oriented edge + int _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(NULL != _paOEdge) - { - delete _paOEdge; - _paOEdge = NULL; - } - - if(NULL != _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((NULL == iEdge1) || (NULL == 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 int 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(NULL == _paOEdge) - { - _paOEdge = iEdge; - _nOEdges++; - return; - } - if(NULL == _pbOEdge) - { - _pbOEdge = iEdge; - _nOEdges++; - return; - } - } - inline void setNumberOfOEdges(int n) {_nOEdges = n;} - inline void setMark(bool mark) {_Mark = mark;} - inline void setId(int id) {_Id = id;} - virtual void ResetUserData() {userdata = 0;} + 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 int 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(int n) + { + _nOEdges = n; + } + + inline void setMark(bool mark) + { + _Mark = mark; + } + + inline void setId(int id) + { + _Id = id; + } + + virtual void ResetUserData() + { + userdata = NULL; + } }; - /**********************************/ - /* */ - /* */ - /* WFace */ - /* */ - /* */ - /**********************************/ + +/********************************** + * * + * * + * WFace * + * * + * * + **********************************/ class LIB_WINGED_EDGE_EXPORT WFace { protected: - vector<WOEdge *> _OEdgeList; // list of oriented edges of bording the face - Vec3r _Normal; // normal to the face - vector<Vec3r> _VerticesNormals; // 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<Vec2r> _VerticesTexCoords; + vector<WOEdge *> _OEdgeList; // list of oriented edges of bording the face + Vec3r _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<Vec3r> _VerticesNormals; + vector<Vec2r> _VerticesTexCoords; - int _Id; - unsigned _FrsMaterialIndex; - bool _Mark; // Freestyle face mark (if true, feature edges on this face are ignored) + 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<WOEdge*>& getEdgeList() {return _OEdgeList;} - inline WOEdge * GetOEdge(int i) {return _OEdgeList[i];} - inline Vec3r& 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(index >= _OEdgeList.size()) - // return NULL; - 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<WOEdge*>::iterator woe=_OEdgeList.begin(), woend=_OEdgeList.end(); - woe!=woend; - woe++){ - if((*woe)->GetaVertex() == iVertex) - return index; - ++index; - } - return -1; - } - inline void RetrieveVertexList(vector<WVertex*>& oVertices) - { - for(vector<WOEdge*>::iterator woe=_OEdgeList.begin(), woend=_OEdgeList.end(); - woe!=woend; - woe++) - { - oVertices.push_back((*woe)->GetaVertex()); - } - } - inline void RetrieveBorderFaces(vector<const WFace*>& oWFaces) - { - for(vector<WOEdge*>::iterator woe=_OEdgeList.begin(), woend=_OEdgeList.end(); - woe!=woend; - woe++) - { - WFace *af; - if(NULL != (af = (*woe)->GetaFace())) - oWFaces.push_back(af); - } - } - inline WFace * GetBordingFace(int index) - { - // if(index >= _OEdgeList.size()) - // return 0; - return _OEdgeList[index]->GetaFace(); - } - inline WFace * GetBordingFace(WOEdge *iOEdge) - { - return iOEdge->GetaFace(); - } - inline vector<Vec3r>& GetPerVertexNormals() - { - return _VerticesNormals; - } - inline vector<Vec2r>& GetPerVertexTexCoords() - { - return _VerticesTexCoords; - } - /*! Returns the normal of the vertex of index index */ - inline Vec3r& GetVertexNormal(int index) - { - return _VerticesNormals[index]; - } - /*! Returns the tex coords of the vertex of index index */ - inline Vec2r& GetVertexTexCoords(int index) - { - return _VerticesTexCoords[index]; - } - /*! Returns the normal of the vertex iVertex for that face */ - inline Vec3r& GetVertexNormal(WVertex *iVertex) - { - int i = 0; - int index = 0; - for(vector<WOEdge*>::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<WOEdge*>::iterator woe,woend, woefirst; - woefirst = _OEdgeList.begin(); - for(woe=woefirst,woend=_OEdgeList.end(); - woe!=woend; - woe++) - { - if(true == 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<WOEdge*>::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<WOEdge*>& iEdgeList) {_OEdgeList = iEdgeList;} - inline void setNormal(const Vec3r& iNormal) {_Normal = iNormal;} - inline void setNormalList(const vector<Vec3r>& iNormalsList) {_VerticesNormals = iNormalsList;} - inline void setTexCoordsList(const vector<Vec2r>& 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 flase 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 */ - real getArea (); - - WShape * getShape() ; - virtual void ResetUserData() {userdata = 0;} + void *userdata; + inline WFace() + { + userdata = NULL; + _FrsMaterialIndex = 0; + } + + /*! copy constructor */ + WFace(WFace& iBrother); + virtual WFace *duplicate(); + virtual ~WFace() {} + + /*! accessors */ + inline const vector<WOEdge*>& getEdgeList() + { + return _OEdgeList; + } + + inline WOEdge *GetOEdge(int i) + { + return _OEdgeList[i]; + } + + inline Vec3r& 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; +#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<WOEdge*>::iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end(); woe != woend; woe++) { + if ((*woe)->GetaVertex() == iVertex) + return index; + ++index; + } + return -1; + } + + inline void RetrieveVertexList(vector<WVertex *>& oVertices) + { + for (vector<WOEdge *>::iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end(); woe != woend; woe++) { + oVertices.push_back((*woe)->GetaVertex()); + } + } + + inline void RetrieveBorderFaces(vector<const WFace *>& oWFaces) + { + for (vector<WOEdge *>::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; +#endif + return _OEdgeList[index]->GetaFace(); + } + + inline WFace *GetBordingFace(WOEdge *iOEdge) + { + return iOEdge->GetaFace(); + } + + inline vector<Vec3r>& GetPerVertexNormals() + { + return _VerticesNormals; + } + + inline vector<Vec2r>& GetPerVertexTexCoords() + { + return _VerticesTexCoords; + } + + /*! Returns the normal of the vertex of index index */ + inline Vec3r& GetVertexNormal(int index) + { + return _VerticesNormals[index]; + } + + /*! Returns the tex coords of the vertex of index index */ + inline Vec2r& GetVertexTexCoords(int index) + { + return _VerticesTexCoords[index]; + } + + /*! Returns the normal of the vertex iVertex for that face */ + inline Vec3r& GetVertexNormal(WVertex *iVertex) + { + int i = 0; + int index = 0; + for (vector<WOEdge *>::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<WOEdge *>::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<WOEdge*>::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<WOEdge *>& iEdgeList) + { + _OEdgeList = iEdgeList; + } + + inline void setNormal(const Vec3r& iNormal) + { + _Normal = iNormal; + } + + inline void setNormalList(const vector<Vec3r>& iNormalsList) + { + _VerticesNormals = iNormalsList; + } + + inline void setTexCoordsList(const vector<Vec2r>& 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 flase 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 */ + real getArea (); + + WShape *getShape(); + virtual void ResetUserData() + { + userdata = NULL; + } }; - /**********************************/ - /* */ - /* */ - /* WShape */ - /* */ - /* */ - /**********************************/ +/********************************** + * * + * * + * WShape * + * * + * * + **********************************/ class LIB_WINGED_EDGE_EXPORT WShape { protected: - vector<WVertex*> _VertexList; - vector<WEdge*> _EdgeList; - vector<WFace*> _FaceList; - int _Id; - string _Name; - static unsigned _SceneCurrentId; - Vec3r _min; - Vec3r _max; - vector<FrsMaterial> _FrsMaterials; - real _meanEdgeSize; + vector<WVertex *> _VertexList; + vector<WEdge *> _EdgeList; + vector<WFace *> _FaceList; + int _Id; + string _Name; + static unsigned _SceneCurrentId; + Vec3r _min; + Vec3r _max; + vector<FrsMaterial> _FrsMaterials; + real _meanEdgeSize; public: - inline WShape() {_meanEdgeSize = 0;_Id = _SceneCurrentId; _SceneCurrentId++;} - /*! copy constructor */ - WShape(WShape& iBrother); - virtual WShape * duplicate(); - virtual ~WShape() - { - if(_EdgeList.size() != 0) - { - vector<WEdge *>::iterator e; - for(e=_EdgeList.begin(); e!=_EdgeList.end(); e++) - { - delete (*e); - } - _EdgeList.clear(); - } - - if(_VertexList.size() != 0) - { - vector<WVertex *>::iterator v; - for(v=_VertexList.begin(); v!=_VertexList.end(); v++) - { - delete (*v); - } - _VertexList.clear(); - } - - if(_FaceList.size() != 0) - { - vector<WFace *>::iterator f; - for(f=_FaceList.begin(); f!=_FaceList.end(); f++) - { - delete (*f); - } - _FaceList.clear(); - } - } - - /*! accessors */ - inline vector<WEdge *>& getEdgeList() {return _EdgeList;} - inline vector<WVertex*>& getVertexList() {return _VertexList;} - inline vector<WFace*>& GetFaceList() {return _FaceList;} - inline unsigned GetId() {return _Id;} - inline void bbox(Vec3r& min, Vec3r& max) {min=_min; max=_max;} - inline const FrsMaterial& frs_material(unsigned i) const {return _FrsMaterials[i];} - inline const vector<FrsMaterial>& frs_materials() const {return _FrsMaterials;} - inline const real getMeanEdgeSize() const {return _meanEdgeSize;} - inline const string& getName() const {return _Name;} - /*! modifiers */ - static inline void setCurrentId(const unsigned id) { _SceneCurrentId = id; } - inline void setEdgeList(const vector<WEdge*>& iEdgeList) {_EdgeList = iEdgeList;} - inline void setVertexList(const vector<WVertex*>& iVertexList) {_VertexList = iVertexList;} - inline void setFaceList(const vector<WFace*>& iFaceList) {_FaceList = iFaceList;} - inline void setId(int id) {_Id = id;} - inline void setBBox(const Vec3r& min, const Vec3r& max) {_min = min; _max=max;} - inline void setFrsMaterial(const FrsMaterial& frs_material, unsigned i) {_FrsMaterials[i]=frs_material;} - inline void setFrsMaterials(const vector<FrsMaterial>& iMaterials) {_FrsMaterials = iMaterials;} - inline void setName(const string& name) {_Name = name;} - - /*! 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<WVertex*>& iVertexList, vector<bool>& 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<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& 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<WVertex*>::iterator v=_VertexList.begin(),vend=_VertexList.end(); - v!=vend; - v++) - { - (*v)->ResetUserData(); - } - - for(vector<WEdge*>::iterator e=_EdgeList.begin(),eend=_EdgeList.end(); - e!=eend; - e++) - { - (*e)->ResetUserData(); - // manages WOEdge: - WOEdge *oe = (*e)->GetaOEdge(); - if(oe != NULL) - oe->ResetUserData(); - oe = (*e)->GetbOEdge(); - if(oe != NULL) - oe->ResetUserData(); - } - - for(vector<WFace*>::iterator f=_FaceList.begin(),fend=_FaceList.end(); - f!=fend; - f++) - { - (*f)->ResetUserData(); - } - - } - - inline void ComputeBBox() - { - _min = _VertexList[0]->GetVertex(); - _max = _VertexList[0]->GetVertex(); - - Vec3r v; - for(vector<WVertex*>::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 real ComputeMeanEdgeSize(){ - _meanEdgeSize = _meanEdgeSize/(_EdgeList.size()); - return _meanEdgeSize; - } + inline WShape() + { + _meanEdgeSize = 0; + _Id = _SceneCurrentId; + _SceneCurrentId++; + } + + /*! copy constructor */ + WShape(WShape& iBrother); + virtual WShape *duplicate(); + + virtual ~WShape() + { + if (_EdgeList.size() != 0) { + vector<WEdge *>::iterator e; + for (e = _EdgeList.begin(); e != _EdgeList.end(); ++e) { + delete (*e); + } + _EdgeList.clear(); + } + + if (_VertexList.size() != 0) { + vector<WVertex *>::iterator v; + for (v = _VertexList.begin(); v != _VertexList.end(); ++v) { + delete (*v); + } + _VertexList.clear(); + } + + if (_FaceList.size() != 0) { + vector<WFace *>::iterator f; + for (f = _FaceList.begin(); f != _FaceList.end(); ++f) { + delete (*f); + } + _FaceList.clear(); + } + } + + /*! accessors */ + inline vector<WEdge *>& getEdgeList() + { + return _EdgeList; + } + + inline vector<WVertex *>& getVertexList() + { + return _VertexList; + } + + inline vector<WFace *>& GetFaceList() + { + return _FaceList; + } + + inline unsigned GetId() + { + return _Id; + } + + inline void bbox(Vec3r& min, Vec3r& max) + { + min = _min; + max = _max; + } + + inline const FrsMaterial& frs_material(unsigned i) const + { + return _FrsMaterials[i]; + } + + inline const vector<FrsMaterial>& frs_materials() const + { + return _FrsMaterials; + } + + inline const real getMeanEdgeSize() const + { + return _meanEdgeSize; + } + + inline const string& getName() const + { + return _Name; + } + + /*! modifiers */ + static inline void setCurrentId(const unsigned id) + { + _SceneCurrentId = id; + } + + inline void setEdgeList(const vector<WEdge *>& iEdgeList) + { + _EdgeList = iEdgeList; + } + + inline void setVertexList(const vector<WVertex *>& iVertexList) + { + _VertexList = iVertexList; + } + + inline void setFaceList(const vector<WFace *>& iFaceList) + { + _FaceList = iFaceList; + } + + inline void setId(int id) + { + _Id = id; + } + + inline void setBBox(const Vec3r& min, const Vec3r& max) + { + _min = min; + _max = max; + } + + inline void setFrsMaterial(const FrsMaterial& frs_material, unsigned i) + { + _FrsMaterials[i] = frs_material; + } + + inline void setFrsMaterials(const vector<FrsMaterial>& iMaterials) + { + _FrsMaterials = iMaterials; + } + + inline void setName(const string& name) + { + _Name = name; + } + + /*! 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<WVertex *>& iVertexList, vector<bool>& 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<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, + vector<bool>& 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<WVertex *>::iterator v = _VertexList.begin(), vend = _VertexList.end(); v != vend; v++) { + (*v)->ResetUserData(); + } + + for (vector<WEdge *>::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<WFace *>::iterator f = _FaceList.begin(), fend = _FaceList.end(); f != fend; f++) { + (*f)->ResetUserData(); + } + } + + inline void ComputeBBox() + { + _min = _VertexList[0]->GetVertex(); + _max = _VertexList[0]->GetVertex(); + + Vec3r v; + for (vector<WVertex *>::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 real ComputeMeanEdgeSize() + { + _meanEdgeSize = _meanEdgeSize / _EdgeList.size(); + return _meanEdgeSize; + } 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<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex, WFace *face); + /*! 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<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex, + WFace *face); }; - /**********************************/ - /* */ - /* */ - /* WingedEdge */ - /* */ - /* */ - /**********************************/ - -class WingedEdge { - - public: +/********************************** + * * + * * + * WingedEdge * + * * + * * + **********************************/ - WingedEdge() {} - - ~WingedEdge() { - clear(); - } - - void clear() { - for (vector<WShape*>::iterator it = _wshapes.begin(); - it != _wshapes.end(); - it++) - delete *it; - _wshapes.clear(); - } - - void addWShape(WShape* wshape) { - _wshapes.push_back(wshape); - } - - vector<WShape*>& getWShapes() { - return _wshapes; - } - - private: - - vector<WShape*> _wshapes; +class WingedEdge +{ +public: + WingedEdge() {} + + ~WingedEdge() + { + clear(); + } + + void clear() + { + for (vector<WShape *>::iterator it = _wshapes.begin(); it != _wshapes.end(); it++) + delete *it; + _wshapes.clear(); + } + + void addWShape(WShape *wshape) + { + _wshapes.push_back(wshape); + } + + vector<WShape *>& getWShapes() + { + return _wshapes; + } + +private: + vector<WShape *> _wshapes; }; /* - - ############################################# - ############################################# - ############################################# - ###### ###### - ###### I M P L E M E N T A T I O N ###### - ###### ###### - ############################################# - ############################################# - ############################################# - + +############################################# +############################################# +############################################# +###### ###### +###### I M P L E M E N T A T I O N ###### +###### ###### +############################################# +############################################# +############################################# + */ /* for inline functions */ -void WOEdge::RetrieveCWOrderedEdges(vector<WEdge*>& oEdges) +void WOEdge::RetrieveCWOrderedEdges(vector<WEdge *>& oEdges) { - - WOEdge *currentOEdge = this; - do - { - WOEdge* nextOEdge = currentOEdge->GetbFace()->GetNextOEdge(currentOEdge); - oEdges.push_back(nextOEdge->GetOwner()); - currentOEdge = nextOEdge->GetOwner()->GetOtherOEdge(nextOEdge); - - } while((currentOEdge != NULL) && (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 != NULL && _pbVertex != NULL ) { - _vec = _pbVertex->GetVertex() - _paVertex->GetVertex(); - if ( _paFace != NULL && _pbFace != NULL ) { - real 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); - } - } +inline void WOEdge::setVecAndAngle() +{ + if (_paVertex && _pbVertex) { + _vec = _pbVertex->GetVertex() - _paVertex->GetVertex(); + if (_paFace && _pbFace) { + real 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); + } + } } -#endif // WEDGE_H +#endif // __FREESTYLE_W_EDGE_H__
\ No newline at end of file diff --git a/source/blender/freestyle/intern/winged_edge/WFillGrid.cpp b/source/blender/freestyle/intern/winged_edge/WFillGrid.cpp index 7d0a2d3c561..8b446791efc 100644 --- a/source/blender/freestyle/intern/winged_edge/WFillGrid.cpp +++ b/source/blender/freestyle/intern/winged_edge/WFillGrid.cpp @@ -1,60 +1,68 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/winged_edge/WFillGrid.cpp + * \ingroup freestyle + * \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures) + * \author Emmanuel Turquin + * \author Stephane Grabli + * \date 03/05/2003 + */ #include "WEdge.h" #include "WFillGrid.h" -void WFillGrid::fillGrid() { - if (!_winged_edge || !_grid) - return; - - vector<WShape*> wshapes = _winged_edge->getWShapes(); - vector<WVertex*> fvertices; - vector<Vec3r> vectors; - vector<WFace*> faces; - - for (vector<WShape*>::const_iterator it = wshapes.begin(); - it != wshapes.end(); - it++) { - faces = (*it)->GetFaceList(); - - for (vector<WFace*>::const_iterator f = faces.begin(); - f != faces.end(); - f++) { - (*f)->RetrieveVertexList(fvertices); - - for (vector<WVertex*>::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(); - } -} +void WFillGrid::fillGrid() +{ + if (!_winged_edge || !_grid) + return; + + vector<WShape *> wshapes = _winged_edge->getWShapes(); + vector<WVertex *> fvertices; + vector<Vec3r> vectors; + vector<WFace *> faces; + + for (vector<WShape *>::const_iterator it = wshapes.begin(); it != wshapes.end(); ++it) { + faces = (*it)->GetFaceList(); + + for (vector<WFace *>::const_iterator f = faces.begin(); f != faces.end(); ++f) { + (*f)->RetrieveVertexList(fvertices); + + for (vector<WVertex*>::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(); + } +}
\ No newline at end of file diff --git a/source/blender/freestyle/intern/winged_edge/WFillGrid.h b/source/blender/freestyle/intern/winged_edge/WFillGrid.h index 2ebbc2f359a..223c5a786d8 100644 --- a/source/blender/freestyle/intern/winged_edge/WFillGrid.h +++ b/source/blender/freestyle/intern/winged_edge/WFillGrid.h @@ -1,80 +1,88 @@ -// -// Filename : WFillGrid.h -// Author(s) : Stephane Grabli -// Emmanuel Turquin -// Purpose : Class to fill in a grid from a SceneGraph -// (uses only the WingedEdge structures) -// Date of creation : 03/05/2003 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef __FREESTYLE_W_FILL_GRID_H__ +#define __FREESTYLE_W_FILL_GRID_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/winged_edge/WFillGrid.h + * \ingroup freestyle + * \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures) + * \author Emmanuel Turquin + * \author Stephane Grabli + * \date 03/05/2003 + */ -#ifndef W_FILL_GRID_H -# define W_FILL_GRID_H +#include "WEdge.h" -# include "../geometry/Grid.h" -# include "../geometry/Polygon.h" -# include "WEdge.h" +#include "../geometry/Grid.h" +#include "../geometry/Polygon.h" class LIB_WINGED_EDGE_EXPORT WFillGrid { public: + inline WFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL) + { + _winged_edge = winged_edge; + _grid = grid; + _polygon_id = 0; + } - inline WFillGrid(Grid* grid = 0, WingedEdge* winged_edge = 0) { - _winged_edge = winged_edge; - _grid = grid; - _polygon_id = 0; - } + virtual ~WFillGrid() {} - virtual ~WFillGrid() {} + void fillGrid(); - void fillGrid(); + /*! Accessors */ + WingedEdge *getWingedEdge() + { + return _winged_edge; + } - /*! Accessors */ - WingedEdge* getWingedEdge() { - return _winged_edge; - } + Grid *getGrid() + { + return _grid; + } - Grid* getGrid() { - return _grid; - } + /*! Modifiers */ + void setWingedEdge(WingedEdge *winged_edge) + { + if (winged_edge) + _winged_edge = winged_edge; + } - /*! Modifiers */ - void setWingedEdge(WingedEdge* winged_edge) { - if (winged_edge) - _winged_edge = winged_edge; - } - - void setGrid(Grid* grid) { - if (grid) - _grid = grid; - } + void setGrid(Grid *grid) + { + if (grid) + _grid = grid; + } private: - - Grid* _grid; - WingedEdge* _winged_edge; - unsigned _polygon_id; + Grid *_grid; + WingedEdge *_winged_edge; + unsigned _polygon_id; }; -#endif // WS_FILL_GRID_H +#endif // __FREESTYLE_W_FILL_GRID_H__
\ No newline at end of file diff --git a/source/blender/freestyle/intern/winged_edge/WSFillGrid.cpp b/source/blender/freestyle/intern/winged_edge/WSFillGrid.cpp index 55fa418d4f5..3504a8ab179 100644 --- a/source/blender/freestyle/intern/winged_edge/WSFillGrid.cpp +++ b/source/blender/freestyle/intern/winged_edge/WSFillGrid.cpp @@ -1,60 +1,67 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/winged_edge/WSFillGrid.cpp + * \ingroup freestyle + * \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures) + * \author Stephane Grabli + * \date 03/05/2003 + */ #include "WEdge.h" #include "WSFillGrid.h" -void WSFillGrid::fillGrid() { - if (!_winged_edge || !_grid) - return; - - vector<WShape*> wshapes = _winged_edge->getWShapes(); - vector<WVertex*> fvertices; - vector<Vec3r> vectors; - vector<WFace*> faces; - - for (vector<WShape*>::const_iterator it = wshapes.begin(); - it != wshapes.end(); - it++) { - faces = (*it)->GetFaceList(); - - for (vector<WFace*>::const_iterator f = faces.begin(); - f != faces.end(); - f++) { - (*f)->RetrieveVertexList(fvertices); - - for (vector<WVertex*>::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(); - } -} +void WSFillGrid::fillGrid() +{ + if (!_winged_edge || !_grid) + return; + + vector<WShape *> wshapes = _winged_edge->getWShapes(); + vector<WVertex *> fvertices; + vector<Vec3r> vectors; + vector<WFace *> faces; + + for (vector<WShape *>::const_iterator it = wshapes.begin(); it != wshapes.end(); ++it) { + faces = (*it)->GetFaceList(); + + for (vector<WFace *>::const_iterator f = faces.begin(); f != faces.end(); ++f) { + (*f)->RetrieveVertexList(fvertices); + + for (vector<WVertex*>::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(); + } +}
\ No newline at end of file diff --git a/source/blender/freestyle/intern/winged_edge/WSFillGrid.h b/source/blender/freestyle/intern/winged_edge/WSFillGrid.h index 2ea5bc6c621..55bedd83cce 100644 --- a/source/blender/freestyle/intern/winged_edge/WSFillGrid.h +++ b/source/blender/freestyle/intern/winged_edge/WSFillGrid.h @@ -1,79 +1,87 @@ -// -// Filename : WSFillGrid.h -// Author(s) : Stephane Grabli -// Purpose : Class to fill in a grid from a SceneGraph -// (uses only the WingedEdge structures) -// Date of creation : 03/05/2003 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef __FREESTYLE_WS_FILL_GRID_H__ +#define __FREESTYLE_WS_FILL_GRID_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/winged_edge/WSFillGrid.h + * \ingroup freestyle + * \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures) + * \author Stephane Grabli + * \date 03/05/2003 + */ -#ifndef WS_FILL_GRID_H -# define WS_FILL_GRID_H +#include "WEdge.h" -# include "../geometry/Grid.h" -# include "../geometry/Polygon.h" -# include "WEdge.h" +#include "../geometry/Grid.h" +#include "../geometry/Polygon.h" class LIB_WINGED_EDGE_EXPORT WSFillGrid { public: + inline WSFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL) + { + _winged_edge = winged_edge; + _grid = grid; + _polygon_id = 0; + } - inline WSFillGrid(Grid* grid = 0, WingedEdge* winged_edge = 0) { - _winged_edge = winged_edge; - _grid = grid; - _polygon_id = 0; - } + virtual ~WSFillGrid() {} - virtual ~WSFillGrid() {} + void fillGrid(); - void fillGrid(); + /*! Accessors */ + WingedEdge *getWingedEdge() + { + return _winged_edge; + } - /*! Accessors */ - WingedEdge* getWingedEdge() { - return _winged_edge; - } + Grid *getGrid() + { + return _grid; + } - Grid* getGrid() { - return _grid; - } + /*! Modifiers */ + void setWingedEdge(WingedEdge *winged_edge) + { + if (winged_edge) + _winged_edge = winged_edge; + } - /*! Modifiers */ - void setWingedEdge(WingedEdge* winged_edge) { - if (winged_edge) - _winged_edge = winged_edge; - } - - void setGrid(Grid* grid) { - if (grid) - _grid = grid; - } + void setGrid(Grid *grid) + { + if (grid) + _grid = grid; + } private: - - Grid* _grid; - WingedEdge* _winged_edge; - unsigned _polygon_id; + Grid *_grid; + WingedEdge *_winged_edge; + unsigned _polygon_id; }; -#endif // WS_FILL_GRID_H +#endif // __FREESTYLE_WS_FILL_GRID_H__
\ No newline at end of file diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.cpp b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp index d238749570c..fed9a1588bb 100644 --- a/source/blender/freestyle/intern/winged_edge/WXEdge.cpp +++ b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp @@ -1,296 +1,298 @@ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/freestyle/intern/winged_edge/WXEdge.cpp + * \ingroup freestyle + * \brief Classes to define an Extended Winged Edge data structure. + * \author Stephane Grabli + * \date 26/10/2003 + */ #include "WXEdge.h" - /**********************************/ - /* */ - /* */ - /* WXFace */ - /* */ - /* */ - /**********************************/ +/********************************** + * * + * * + * WXFace * + * * + * * + **********************************/ -unsigned int WXFaceLayer::Get0VertexIndex() const { - int i = 0; - int nEdges = _pWXFace->numberOfEdges(); - for(i=0; i<nEdges; ++i){ - if(_DotP[i] == 0){ - return i; - } - } - return -1; +unsigned int WXFaceLayer::Get0VertexIndex() const +{ + int i = 0; + int nEdges = _pWXFace->numberOfEdges(); + for (i = 0; i < nEdges; ++i) { + if (_DotP[i] == 0) { + 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) && (_DotP[(i+1)%nEdges] == 0)){ - 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) && (_DotP[(i+1)%nEdges] == 0)) { + return i; + } + } + return -1; } -void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges){ - int i = 0; - int nEdges = _pWXFace->numberOfEdges(); - for(i=0; i<nEdges; ++i){ - if(_DotP[i]*_DotP[(i+1)%nEdges] < 0){ - // we got one - oCuspEdges.push_back(i); - } - } +void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges) +{ + int i = 0; + int nEdges = _pWXFace->numberOfEdges(); + for (i = 0; i < nEdges; ++i) { + if (_DotP[i] * _DotP[(i + 1) % nEdges] < 0) { + // we got one + oCuspEdges.push_back(i); + } + } } - -WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){ - // if the smooth edge has already been - // built: exit - if(0 != _pSmoothEdge) - return _pSmoothEdge; - real ta, tb; - WOEdge *woea(0), *woeb(0); - bool ok = false; - vector<int> cuspEdgesIndices; - int indexStart, indexEnd; - unsigned nedges = _pWXFace->numberOfEdges(); - if(_nNullDotP == nedges){ - _pSmoothEdge = 0; - 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. - //------------------------------------------- - - if(_DotP[cuspEdgesIndices[0]] > 0){ - 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 = 0; - return _pSmoothEdge; - } - RetrieveCuspEdgesIndices(cuspEdgesIndices); - // We should have only one EdgeCusp: - if(cuspEdgesIndices.size() != 1){ - cout << "Warning in BuildSmoothEdge: weird WXFace configuration" << endl; - _pSmoothEdge = 0; - return 0; - } - unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index - unsigned nedges = _pWXFace->numberOfEdges(); - if(_DotP[cuspEdgesIndices[0]] > 0){ - woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]); - woeb = _pWXFace->GetOEdge(index0); - indexStart = cuspEdgesIndices[0]; - ta = _DotP[indexStart]/(_DotP[indexStart]-_DotP[(indexStart+1)%nedges]); - tb = 0.0; - }else{ - woea = _pWXFace->GetOEdge(index0); - woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]); - indexEnd = cuspEdgesIndices[0]; - ta = 0.0; - 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; - tb = 1; - ok = true; - }else{ - // here it's not good, our edge is a single point -> skip that face - ok = false; - // the order of the WOEdge index is good - // woea = _pWXFace->GetOEdge((index-1)%nedges); - // woeb = _pWXFace->GetOEdge((index+1)%nedges); - // ta = 1; - // tb = 0; - } - } - 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.01 > 0) - _pSmoothEdge->setFront(true); - else - _pSmoothEdge->setFront(false); - } - } - } - - // 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 != 0) - // { - // 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 - // // TESTER D'ABORD SI LE EXACTSILHOUETTEEDGE N'A PAS - // // ETE CONSTRUIT SUR L'AUTRE FACE.(1 suffit) - // if(0 != ((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; - // real 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; - // tb = 1; - // } - // 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; - // tb = 0; - // } - // - // _pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX); - // _pSmoothEdge->setWOeA(woea); - // _pSmoothEdge->setWOeA(woeb); - // _pSmoothEdge->setTa(ta); - // _pSmoothEdge->setTb(tb); - // - // return _pSmoothEdge; - // } - // } - //} - return _pSmoothEdge; + +WXSmoothEdge *WXFaceLayer::BuildSmoothEdge() +{ + // if the smooth edge has already been built: exit + if (_pSmoothEdge) + return _pSmoothEdge; + real ta, tb; + WOEdge *woea(0), *woeb(0); + bool ok = false; + vector<int> 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. + //------------------------------------------- + + if (_DotP[cuspEdgesIndices[0]] > 0) { + 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) { + 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) { + woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]); + woeb = _pWXFace->GetOEdge(index0); + indexStart = cuspEdgesIndices[0]; + ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]); + tb = 0.0; + } + else { + woea = _pWXFace->GetOEdge(index0); + woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]); + indexEnd = cuspEdgesIndices[0]; + ta = 0.0; + 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; + tb = 1; + 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; + tb = 0; +#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.01 > 0) + _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; + real 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; + tb = 1; + } + 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; + tb = 0; + } + + _pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX); + _pSmoothEdge->setWOeA(woea); + _pSmoothEdge->setWOeA(woeb); + _pSmoothEdge->setTa(ta); + _pSmoothEdge->setTb(tb); + + return _pSmoothEdge; + } + } + } +#endif + return _pSmoothEdge; } - + void WXFace::ComputeCenter() { - vector<WVertex*> iVertexList; - RetrieveVertexList(iVertexList); - Vec3r center; - for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end(); - wv!=wvend; - wv++) - { - center += (*wv)->GetVertex(); - } - center /= (real)iVertexList.size(); - setCenter(center); + vector<WVertex *> iVertexList; + RetrieveVertexList(iVertexList); + Vec3r center; + for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) { + center += (*wv)->GetVertex(); + } + center /= (real)iVertexList.size(); + setCenter(center); } - /**********************************/ - /* */ - /* */ - /* WXShape */ - /* */ - /* */ - /**********************************/ - +/********************************** + * * + * * + * WXShape * + * * + * * + **********************************/ -WFace* WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex) +WFace *WXShape::MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex) { - WFace *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex); - if(0 == face) - return 0; - - Vec3r center; - for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end(); - wv!=wvend; - wv++) - { - center += (*wv)->GetVertex(); - } - center /= (real)iVertexList.size(); - ((WXFace*)face)->setCenter(center); + WFace *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex); + if (!face) + return NULL; - return face; + Vec3r center; + for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) { + center += (*wv)->GetVertex(); + } + center /= (real)iVertexList.size(); + ((WXFace *)face)->setCenter(center); + + return face; } -WFace * WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex) +WFace *WXShape::MakeFace(vector<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, + vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex) { - WFace *face = WShape::MakeFace(iVertexList, iNormalsList, iTexCoordsList, iFaceEdgeMarksList, iMaterialIndex); - - // Vec3r center; - // for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end(); - // wv!=wvend; - // wv++) - // { - // center += (*wv)->GetVertex(); - // } - // center /= (real)iVertexList.size(); - // ((WSFace*)face)->setCenter(center); + WFace *face = WShape::MakeFace(iVertexList, iNormalsList, iTexCoordsList, iFaceEdgeMarksList, iMaterialIndex); - return face; -} +#if 0 + Vec3r center; + for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) { + center += (*wv)->GetVertex(); + } + center /= (real)iVertexList.size(); + ((WSFace *)face)->setCenter(center); +#endif + return face; +}
\ No newline at end of file diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.h b/source/blender/freestyle/intern/winged_edge/WXEdge.h index c51b6a84a98..9f3522e4e70 100644 --- a/source/blender/freestyle/intern/winged_edge/WXEdge.h +++ b/source/blender/freestyle/intern/winged_edge/WXEdge.h @@ -1,582 +1,809 @@ -// -// Filename : WXEdge.h -// Author(s) : Stephane Grabli -// Purpose : Classes to define an Extended Winged Edge data structure. -// Date of creation : 26/10/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef WXEDGE_H -# define WXEDGE_H - -# include "WEdge.h" -# include "Nature.h" -# include "Curvature.h" +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __FREESTYLE_WX_EDGE_H__ +#define __FREESTYLE_WX_EDGE_H__ + +/** \file blender/freestyle/intern/winged_edge/WXEdge.h + * \ingroup freestyle + * \brief Classes to define an Extended Winged Edge data structure. + * \author Stephane Grabli + * \date 26/10/2003 + */ + +#include "Curvature.h" +#include "Nature.h" +#include "WEdge.h" typedef Nature::EdgeNature WXNature; - /**********************************/ - /* */ - /* */ - /* WXVertex */ - /* */ - /* */ - /**********************************/ +/********************************** + * * + * * + * WXVertex * + * * + * * + **********************************/ class WXVertex : public WVertex -{ +{ private: - // Curvature info - CurvatureInfo *_curvatures; + // Curvature info + CurvatureInfo *_curvatures; public: - inline WXVertex(const Vec3r &v) - : WVertex(v) - {_curvatures = 0;} - /*! 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;} - + inline WXVertex(const Vec3r &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; + } }; +/********************************** + * * + * * + * WXEdge * + * * + * * + **********************************/ - /**********************************/ - /* */ - /* */ - /* WXEdge */ - /* */ - /* */ - /**********************************/ class WXEdge : public WEdge { private: - WXNature _nature; // flag to indicate whether the edge is a silhouette edge or not - int _order; // 0: the order doesn't matter. 1: the order is the orginal one. -1: the order is not good - bool _front; // 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. - + // 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 + int _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 int 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;} - + 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 int 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; + } }; - /**********************************/ - /* */ - /* */ - /* WXFace */ - /* */ - /* */ - /**********************************/ +/********************************** + * * + * * + * WXFace * + * * + * * + **********************************/ /*! Class to store a smooth edge (i.e Hertzman & Zorin smooth silhouette edges) */ -class WXSmoothEdge{ +class WXSmoothEdge +{ public: - typedef enum{ - EDGE_EDGE, - VERTEX_EDGE, - EDGE_VERTEX - } Configuration; - - WOEdge *_woea; // Oriented edge from which the silhouette edge starts - WOEdge *_woeb; // Oriented edge where the silhouette edge ends - real _ta; // The silhouette starting point's coordinates are : _woea[0]+ta*(_woea[1]-_woea[0]) - real _tb; // The silhouette ending point's coordinates are : _woeb[0]+ta*(_woeb[1]-_woeb[0]) - bool _front; - Configuration _config; - - WXSmoothEdge(){ - _woea = 0; - _woeb = 0; - _ta = 0; - _tb = 0; - _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 real ta() const {return _ta;} - inline real 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(real ta) {_ta = ta;} - inline void setTb(real tb) {_tb = tb;} - inline void setFront(bool iFront) {_front = iFront;} - inline void setConfiguration(Configuration iConf) {_config = iConf;} - + typedef enum { + EDGE_EDGE, + VERTEX_EDGE, + EDGE_VERTEX, + } Configuration; + + WOEdge *_woea; // Oriented edge from which the silhouette edge starts + WOEdge *_woeb; // Oriented edge where the silhouette edge ends + real _ta; // The silhouette starting point's coordinates are : _woea[0]+ta*(_woea[1]-_woea[0]) + real _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; + _tb = 0; + _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 real ta() const + { + return _ta; + } + + inline real 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(real ta) + { + _ta = ta; + } + + inline void setTb(real tb) + { + _tb = tb; + } + + inline void setFront(bool iFront) + { + _front = iFront; + } + + inline void setConfiguration(Configuration iConf) + { + _config = iConf; + } }; -/* Class to store a value per vertex and a smooth edge. - * The WXFace stores a list of these + +/* Class to store a value per vertex and a smooth edge. + * The WXFace stores a list of these */ class WXFace; -class LIB_WINGED_EDGE_EXPORT WXFaceLayer{ + +class LIB_WINGED_EDGE_EXPORT WXFaceLayer +{ public: - void * userdata; - WXFace * _pWXFace; - vector<real> _DotP;// 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. - WXSmoothEdge * _pSmoothEdge; - WXNature _Nature; - - //oldtmp values - unsigned _nPosDotP; // count the number of positive dot products for vertices. - // if this number is != 0 and !=_DotP.size() -> it is a silhouette fac - - 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 = 0; - _nPosDotP = 0; - _nNullDotP=0; - _Nature = iNature; - _viewDependant = viewDependant; - userdata = 0; - } - WXFaceLayer(const WXFaceLayer& iBrother){ - _pWXFace = iBrother._pWXFace; - _pSmoothEdge = 0; - _DotP = iBrother._DotP; - _nPosDotP = iBrother._nPosDotP; - _nNullDotP = iBrother._nNullDotP; - _Nature = iBrother._Nature; - if(0 != iBrother._pSmoothEdge) - { - _pSmoothEdge = new WXSmoothEdge(*(iBrother._pSmoothEdge)); - } - _viewDependant = iBrother._viewDependant; - userdata = 0; - } - virtual ~WXFaceLayer() { - if(!_DotP.empty()) - _DotP.clear(); - if(0 != _pSmoothEdge){ - delete _pSmoothEdge; - _pSmoothEdge = 0; - } - } - inline const real 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 Nature::EdgeNature 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 = 0; - } - } - - /*! 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<int>& oCuspEdges); - WXSmoothEdge * BuildSmoothEdge(); - inline void setDotP(const vector<real>& iDotP) {_DotP = iDotP;} - inline void PushDotP(real iDotP) { - _DotP.push_back(iDotP); - if(iDotP > 0) - ++_nPosDotP; - if(iDotP == 0) - ++_nNullDotP; - } - inline void ReplaceDotP(unsigned int index, real newDotP){ - _DotP[index] = newDotP; - updateDotPInfos(); - } - inline void updateDotPInfos() { - _nPosDotP = 0; - _nNullDotP = 0; - for(vector<real>::iterator d=_DotP.begin(), dend=_DotP.end(); - d!=dend; - ++d){ - if((*d) > 0) - ++_nPosDotP; - if((*d) == 0) - ++_nNullDotP; - } - } + 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<real> _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 real 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 Nature::EdgeNature 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<int>& oCuspEdges); + + WXSmoothEdge *BuildSmoothEdge(); + + inline void setDotP(const vector<real>& iDotP) + { + _DotP = iDotP; + } + + inline void PushDotP(real iDotP) + { + _DotP.push_back(iDotP); + if (iDotP > 0) + ++_nPosDotP; + if (iDotP == 0) + ++_nNullDotP; + } + + inline void ReplaceDotP(unsigned int index, real newDotP) + { + _DotP[index] = newDotP; + updateDotPInfos(); + } + + inline void updateDotPInfos() + { + _nPosDotP = 0; + _nNullDotP = 0; + for (vector<real>::iterator d = _DotP.begin(), dend = _DotP.end(); d != dend; ++d) { + if ((*d) > 0) + ++_nPosDotP; + if ((*d) == 0) + ++_nNullDotP; + } + } }; - class WXFace : public WFace { protected: - Vec3r _center; // center of the face - real _Z; // distance from viewpoint to the center of the face - bool _front; // flag to tell whether the face is front facing or back facing - real _dotp; // value obtained when computing the normal-viewpoint dot product - - vector<WXFaceLayer*> _SmoothLayers; // The data needed to store one or several smooth edges that traverse the face + Vec3r _center; // center of the face + real _Z; // distance from viewpoint to the center of the face + bool _front; // flag to tell whether the face is front facing or back facing + real _dotp; // value obtained when computing the normal-viewpoint dot product + + vector<WXFaceLayer *> _SmoothLayers; // The data needed to store one or several smooth edges that traverse the face + public: - inline WXFace() : WFace() {_Z=0.0;_front = false;} - /*! Copy constructor */ - WXFace(WXFace& iBrother) - : WFace(iBrother) - { - _center = iBrother.center(); - _Z = iBrother.Z(); - _front = iBrother.front(); - for(vector<WXFaceLayer*>::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<WXFaceLayer*>::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 Vec3r& center() {return _center;} - inline real Z() {return _Z;} - inline bool front() {return _front;} - inline real dotp() {return _dotp;} - inline bool hasSmoothEdges() const { - for(vector<WXFaceLayer*>::const_iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); - wxf != wxfend; - ++wxf){ - if( ((*wxf)->hasSmoothEdge())){ - return true; - } - } - return false; - } - vector<WXFaceLayer*>& getSmoothLayers() {return _SmoothLayers;} - /*! retrieve the smooth edges that match the Nature given as argument */ - void retrieveSmoothEdges(WXNature iNature, vector<WXSmoothEdge*>& oSmoothEdges){ - for(vector<WXFaceLayer*>::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<WXFaceLayer*>& oSmoothEdgesLayers){ - for(vector<WXFaceLayer*>::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<WXFaceLayer*>& oSmoothLayers){ - for(vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); - wxf != wxfend; - ++wxf){ - if((*wxf)->_Nature & iNature){ - oSmoothLayers.push_back(*wxf); - } - } - } - /*! modifiers */ - inline void setCenter(const Vec3r& iCenter) {_center = iCenter;} - void ComputeCenter(); - inline void setZ(real z) {_Z = z;} - inline void setFront(bool iFront) {_front = iFront;} - inline void setDotP(real iDotP) - { - _dotp = iDotP; - if(_dotp > 0) - _front = true; - else - _front = false; - } - inline void AddSmoothLayer(WXFaceLayer * iLayer){ - _SmoothLayers.push_back(iLayer); - } - inline void Reset() { - vector<WXFaceLayer*> layersToKeep; - for(vector<WXFaceLayer*>::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<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); - wxf != wxfend; - ++wxf){ - delete (*wxf); - } - _SmoothLayers.clear(); - } - virtual void ResetUserData() { - WFace::ResetUserData(); - for(vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); - wxf != wxfend; - ++wxf){ - (*wxf)->userdata = 0; - } - } + inline WXFace() : WFace() + { + _Z = 0.0; + _front = false; + } + + /*! Copy constructor */ + WXFace(WXFace& iBrother) : WFace(iBrother) + { + _center = iBrother.center(); + _Z = iBrother.Z(); + _front = iBrother.front(); + for (vector<WXFaceLayer*>::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<WXFaceLayer*>::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 Vec3r& center() + { + return _center; + } + + inline real Z() + { + return _Z; + } + + inline bool front() + { + return _front; + } + + inline real dotp() + { + return _dotp; + } + + inline bool hasSmoothEdges() const + { + for (vector<WXFaceLayer*>::const_iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf) + { + if ((*wxf)->hasSmoothEdge()) { + return true; + } + } + return false; + } + + vector<WXFaceLayer*>& getSmoothLayers() + { + return _SmoothLayers; + } + + /*! retrieve the smooth edges that match the Nature given as argument */ + void retrieveSmoothEdges(WXNature iNature, vector<WXSmoothEdge *>& oSmoothEdges) + { + for (vector<WXFaceLayer *>::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<WXFaceLayer *>& oSmoothEdgesLayers) + { + for (vector<WXFaceLayer *>::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<WXFaceLayer *>& oSmoothLayers) + { + for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf) + { + if ((*wxf)->_Nature & iNature) { + oSmoothLayers.push_back(*wxf); + } + } + } + + /*! modifiers */ + inline void setCenter(const Vec3r& iCenter) + { + _center = iCenter; + } + + void ComputeCenter(); + + inline void setZ(real z) + { + _Z = z; + } + + inline void setFront(bool iFront) + { + _front = iFront; + } + + inline void setDotP(real iDotP) + { + _dotp = iDotP; + if (_dotp > 0) + _front = true; + else + _front = false; + } + + inline void AddSmoothLayer(WXFaceLayer *iLayer) + { + _SmoothLayers.push_back(iLayer); + } + + inline void Reset() + { + vector<WXFaceLayer *> layersToKeep; + for (vector<WXFaceLayer *>::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<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf) + { + delete (*wxf); + } + _SmoothLayers.clear(); + } + + virtual void ResetUserData() + { + WFace::ResetUserData(); + for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf) + { + (*wxf)->userdata = NULL; + } + } }; - /**********************************/ - /* */ - /* */ - /* WXShape */ - /* */ - /* */ - /**********************************/ - +/********************************** + * * + * * + * WXShape * + * * + * * + **********************************/ class WXShape : public WShape { public: - typedef WXShape type_name; + typedef WXShape type_name; + protected: - bool _computeViewIndependant; // flag to indicate whether the view independant stuff must be computed or not + bool _computeViewIndependant; // flag to indicate whether the view independant stuff must be computed or not + public: - inline WXShape() : WShape() {_computeViewIndependant = true;} - /*! copy constructor */ - inline WXShape(WXShape& iBrother) - :WShape(iBrother) - { - _computeViewIndependant = iBrother._computeViewIndependant; - } - virtual WShape * duplicate() - { - WXShape *clone = new WXShape(*this); - return clone; - } - - virtual ~WXShape() - { - } - - inline bool getComputeViewIndependantFlag() const {return _computeViewIndependant;} - inline void setComputeViewIndependantFlag(bool iFlag) {_computeViewIndependant = 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<WVertex*>& iVertexList, vector<bool>& 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<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& 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<WEdge*>& wedges = getEdgeList(); - for(vector<WEdge*>::iterator we=wedges.begin(),weend=wedges.end(); - we!=weend; - we++){ - ((WXEdge*)(*we))->Reset(); - } - - //Reset faces: - vector<WFace*>& wfaces = GetFaceList(); - for(vector<WFace*>::iterator wf=wfaces.begin(),wfend=wfaces.end(); - wf!=wfend; - wf++){ - ((WXFace*)(*wf))->Reset(); - } - } - /*! accessors */ + inline WXShape() : WShape() + { + _computeViewIndependant = true; + } + + /*! copy constructor */ + inline WXShape(WXShape& iBrother) : WShape(iBrother) + { + _computeViewIndependant = iBrother._computeViewIndependant; + } + + virtual WShape *duplicate() + { + WXShape *clone = new WXShape(*this); + return clone; + } + + virtual ~WXShape() {} + + inline bool getComputeViewIndependantFlag() const + { + return _computeViewIndependant; + } + + inline void setComputeViewIndependantFlag(bool iFlag) + { + _computeViewIndependant = 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<WVertex *>& iVertexList, vector<bool>& 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<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, + vector<bool>& 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<WEdge *>& wedges = getEdgeList(); + for (vector<WEdge *>::iterator we = wedges.begin(), weend = wedges.end(); we != weend; ++we) { + ((WXEdge*)(*we))->Reset(); + } + + //Reset faces: + vector<WFace *>& wfaces = GetFaceList(); + for (vector<WFace *>::iterator wf = wfaces.begin(), wfend = wfaces.end(); wf != wfend; ++wf) { + ((WXFace*)(*wf))->Reset(); + } + } + /*! accessors */ }; /* - - ############################################# - ############################################# - ############################################# - ###### ###### - ###### I M P L E M E N T A T I O N ###### - ###### ###### - ############################################# - ############################################# - ############################################# - + +############################################# +############################################# +############################################# +###### ###### +###### I M P L E M E N T A T I O N ###### +###### ###### +############################################# +############################################# +############################################# + */ /* for inline functions */ -bool WXVertex::isFeature() -{ - int counter = 0; - vector<WEdge*>& vedges = GetEdges(); - for(vector<WEdge*>::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; +bool WXVertex::isFeature() +{ + int counter = 0; + vector<WEdge *>& vedges = GetEdges(); + for (vector<WEdge *>::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; } - -#endif +#endif // __FREESTYLE_WX_EDGE_H__
\ No newline at end of file diff --git a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp index b29f0c7e9ee..51e93f34fa3 100644 --- a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp +++ b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp @@ -1,46 +1,58 @@ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/freestyle/intern/winged_edge/WSBuilder.cpp + * \ingroup freestyle + * \brief Class inherited from WingedEdgeBuilder and designed to build a WX (WingedEdge + extended info + * (silhouette etc...)) structure from a polygonal model + * \author Stephane Grabli + * \date 28/05/2003 + */ -#include "WXEdgeBuilder.h" #include "WXEdge.h" +#include "WXEdgeBuilder.h" void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) { - if (_pRenderMonitor && _pRenderMonitor->testBreak()) - return; - WXShape *shape = new WXShape; - buildWShape(*shape, ifs); - shape->setId(ifs.getId().getFirst()); - shape->setName(ifs.getName()); - //ifs.setId(shape->GetId()); + if (_pRenderMonitor && _pRenderMonitor->testBreak()) + return; + WXShape *shape = new WXShape; + buildWShape(*shape, ifs); + shape->setId(ifs.getId().getFirst()); + shape->setName(ifs.getName()); + //ifs.setId(shape->GetId()); } -void WXEdgeBuilder::buildWVertices(WShape& shape, - const real *vertices, - unsigned vsize) { - WXVertex *vertex; - for (unsigned i = 0; i < vsize; i += 3) { - vertex = new WXVertex(Vec3r(vertices[i], - vertices[i + 1], - vertices[i + 2])); - vertex->setId(i / 3); - shape.AddVertex(vertex); - } -} +void WXEdgeBuilder::buildWVertices(WShape& shape, const real *vertices, unsigned vsize) +{ + WXVertex *vertex; + for (unsigned int i = 0; i < vsize; i += 3) { + vertex = new WXVertex(Vec3r(vertices[i], vertices[i + 1], vertices[i + 2])); + vertex->setId(i / 3); + shape.AddVertex(vertex); + } +}
\ No newline at end of file diff --git a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h index b646d66a285..91e9b389f7c 100644 --- a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h +++ b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h @@ -1,51 +1,54 @@ -#ifndef WXEDGEBUILDER_H -# define WXEDGEBUILDER_H +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ -// -// Filename : WSBuilder.h -// Author(s) : Stephane Grabli -// Purpose : Class inherited from WingedEdgeBuilder and -// designed to build a WX (WingedEdge + extended info(silhouette etc...)) -// structure from a polygonal model -// Date of creation : 28/05/03 -// -/////////////////////////////////////////////////////////////////////////////// +#ifndef __FREESTYLE_WX_EDGE_BUILDER_H__ +#define __FREESTYLE_WX_EDGE_BUILDER_H__ +/** \file blender/freestyle/intern/winged_edge/WSBuilder.h + * \ingroup freestyle + * \brief Class inherited from WingedEdgeBuilder and designed to build a WX (WingedEdge + extended info + * (silhouette etc...)) structure from a polygonal model + * \author Stephane Grabli + * \date 28/05/2003 + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +#include "WingedEdgeBuilder.h" -# include "WingedEdgeBuilder.h" -# include "../scene_graph/IndexedFaceSet.h" +#include "../scene_graph/IndexedFaceSet.h" class LIB_WINGED_EDGE_EXPORT WXEdgeBuilder : public WingedEdgeBuilder { public: WXEdgeBuilder() : WingedEdgeBuilder() {} - virtual ~WXEdgeBuilder() {} - VISIT_DECL(IndexedFaceSet) + virtual ~WXEdgeBuilder() {} + VISIT_DECL(IndexedFaceSet) protected: - virtual void buildWVertices(WShape& shape, - const real *vertices, - unsigned vsize); + virtual void buildWVertices(WShape& shape, const real *vertices, unsigned vsize); }; -#endif // WXEDGEBUILDER_H +#endif // __FREESTYLE_WX_EDGE_BUILDER_H__
\ No newline at end of file diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp index e56ac0f9c42..4ef34bbe3ee 100644 --- a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp +++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp @@ -1,386 +1,373 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp + * \ingroup freestyle + * \brief Class to render a WingedEdge data structure from a polyhedral data structure organized in nodes + * of a scene graph + * \author Stephane Grabli + * \date 28/05/2003 + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +#include <set> + +#include "WingedEdgeBuilder.h" #include "../geometry/GeomUtils.h" + #include "../scene_graph/NodeShape.h" -#include "WingedEdgeBuilder.h" -#include <set> + using namespace std; -void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) { - if (_pRenderMonitor && _pRenderMonitor->testBreak()) - return; - WShape *shape = new WShape; - buildWShape(*shape, ifs); - shape->setId(ifs.getId().getFirst()); - //ifs.setId(shape->GetId()); +void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) +{ + if (_pRenderMonitor && _pRenderMonitor->testBreak()) + return; + WShape *shape = new WShape; + buildWShape(*shape, ifs); + shape->setId(ifs.getId().getFirst()); + //ifs.setId(shape->GetId()); } -void WingedEdgeBuilder::visitNodeShape(NodeShape& ns) { - //Sets the current material to iShapeode->material: - _current_frs_material = &(ns.frs_material()); +void WingedEdgeBuilder::visitNodeShape(NodeShape& ns) +{ + //Sets the current material to iShapeode->material: + _current_frs_material = &(ns.frs_material()); } -void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn) { - if(!_current_matrix) { - _current_matrix = new Matrix44r(tn.matrix()); - return; - } +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; + _matrices_stack.push_back(_current_matrix); + Matrix44r *new_matrix = new Matrix44r(*_current_matrix * tn.matrix()); + _current_matrix = new_matrix; } -void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&) { - if(_current_matrix) - delete _current_matrix; +void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&) +{ + 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(); } -void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) { - unsigned vsize = ifs.vsize(); - unsigned nsize = ifs.nsize(); - //soc unused - unsigned tsize = ifs.tsize(); +void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) +{ + unsigned int vsize = ifs.vsize(); + unsigned int nsize = ifs.nsize(); + //soc unused - unsigned tsize = ifs.tsize(); - const real* vertices = ifs.vertices(); - const real* normals = ifs.normals(); - const real* texCoords = ifs.texCoords(); + const real *vertices = ifs.vertices(); + const real *normals = ifs.normals(); + const real *texCoords = ifs.texCoords(); - real* new_vertices; - real* new_normals; + real *new_vertices; + real *new_normals; new_vertices = new real[vsize]; new_normals = new real[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)); - } + // 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(); + const IndexedFaceSet::TRIANGLES_STYLE *faceStyle = ifs.trianglesStyle(); vector<FrsMaterial> frs_materials; - if(ifs.msize()){ - const FrsMaterial*const* mats = ifs.frs_materials(); - for(unsigned i=0; i<ifs.msize(); ++i) + 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); } - // const FrsMaterial * mat = (ifs.frs_material()); - // if (mat) - // shape.setFrsMaterial(*mat); - // else if(_current_frs_material) - // shape.setFrsMaterial(*_current_frs_material); - - 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* vindices = ifs.vindices(); - const unsigned* nindices = ifs.nindices(); - const unsigned* tindices = 0; - if(ifs.tsize()){ - tindices = ifs.tindices(); - } - - const unsigned *mindices = 0; - if(ifs.msize()) +#if 0 + 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* numVertexPerFace = ifs.numVertexPerFaces(); - const unsigned numfaces = ifs.numFaces(); - - for (unsigned 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) + 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; - - // compute bbox - shape.ComputeBBox(); - // compute mean edge size: - shape.ComputeMeanEdgeSize(); - - // Parse the built winged-edge shape to update post-flags - set<Vec3r> normalsSet; - vector<WVertex*>& wvertices = shape.getVertexList(); - for(vector<WVertex*>::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(); - while(fit!=fitend){ - WFace *face = *fit; - normalsSet.insert(face->GetVertexNormal(*wv)); - if(normalsSet.size()!=1){ - break; - } - ++fit; - } - if(normalsSet.size()!=1){ - (*wv)->setSmooth(false); - } - } - // Adds the new WShape to the WingedEdge structure - _winged_edge->addWShape(&shape); + if (tindices) + tindices += numVertexPerFace[index]; + faceEdgeMarks++; + } + + delete[] new_vertices; + delete[] new_normals; + + // compute bbox + shape.ComputeBBox(); + // compute mean edge size: + shape.ComputeMeanEdgeSize(); + + // Parse the built winged-edge shape to update post-flags + set<Vec3r> normalsSet; + vector<WVertex *>& wvertices = shape.getVertexList(); + for (vector<WVertex *>::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); } -void WingedEdgeBuilder::buildWVertices(WShape& shape, - const real *vertices, - unsigned vsize) { - WVertex *vertex; - for (unsigned i = 0; i < vsize; i += 3) { - vertex = new WVertex(Vec3r(vertices[i], - vertices[i + 1], - vertices[i + 2])); - vertex->setId(i / 3); - shape.AddVertex(vertex); - } +void WingedEdgeBuilder::buildWVertices(WShape& shape, const real *vertices, unsigned vsize) +{ + WVertex *vertex; + for (unsigned int i = 0; i < vsize; i += 3) { + vertex = new WVertex(Vec3r(vertices[i], vertices[i + 1], vertices[i + 2])); + vertex->setId(i / 3); + shape.AddVertex(vertex); + } } -void WingedEdgeBuilder::buildTriangleStrip( const real *vertices, - const real *normals, - vector<FrsMaterial>& iMaterials, - const real *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<WVertex *> triangleVertices; - vector<Vec3r> triangleNormals; - vector<Vec2r> triangleTexCoords; - vector<bool> 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(Vec3r(normals[nindices[nTriangle]],normals[nindices[nTriangle]+1], normals[nindices[nTriangle]+2])); - triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+1]],normals[nindices[nTriangle+1]+1],normals[nindices[nTriangle+1]+2])); - triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+2]], normals[nindices[nTriangle+2]+1], normals[nindices[nTriangle+2]+2])); - - if(texCoords){ - triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]],texCoords[tindices[nTriangle]+1])); - triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+1]],texCoords[tindices[nTriangle+1]+1])); - triangleTexCoords.push_back(Vec2r(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(Vec3r(normals[nindices[nTriangle]],normals[nindices[nTriangle]+1], normals[nindices[nTriangle]+2])); - triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+2]],normals[nindices[nTriangle+2]+1],normals[nindices[nTriangle+2]+2])); - triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+1]], normals[nindices[nTriangle+1]+1], normals[nindices[nTriangle+1]+2])); - - if(texCoords){ - triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]],texCoords[tindices[nTriangle]+1])); - triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+2]],texCoords[tindices[nTriangle+2]+1])); - triangleTexCoords.push_back(Vec2r(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 +void WingedEdgeBuilder::buildTriangleStrip(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials, + const real *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<WVertex *> triangleVertices; + vector<Vec3r> triangleNormals; + vector<Vec2r> triangleTexCoords; + vector<bool> 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(Vec3r(normals[nindices[nTriangle]], normals[nindices[nTriangle] + 1], + normals[nindices[nTriangle] + 2])); + triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1], + normals[nindices[nTriangle + 1] + 2])); + triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1], + normals[nindices[nTriangle + 2] + 2])); + + if (texCoords) { + triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1])); + triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 1]], + texCoords[tindices[nTriangle + 1] + 1])); + triangleTexCoords.push_back(Vec2r(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(Vec3r(normals[nindices[nTriangle]], normals[nindices[nTriangle] + 1], + normals[nindices[nTriangle] + 2])); + triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1], + normals[nindices[nTriangle + 2] + 2])); + triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1], + normals[nindices[nTriangle + 1] + 2])); + + if (texCoords) { + triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1])); + triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 2]], + texCoords[tindices[nTriangle + 2] + 1])); + triangleTexCoords.push_back(Vec2r(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++; - } + } + nDoneVertices++; // with a strip, each triangle is one vertex more + nTriangle++; + } } -void WingedEdgeBuilder::buildTriangleFan( const real *vertices, - const real *normals, - vector<FrsMaterial>& iMaterials, - const real *texCoords, - const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, - const unsigned *vindices, - const unsigned *nindices, - const unsigned *mindices, - const unsigned *tindices, - const unsigned nvertices) { - // Nothing to be done +void WingedEdgeBuilder::buildTriangleFan(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials, + const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, + const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, + const unsigned *tindices, const unsigned nvertices) +{ + // Nothing to be done } -void WingedEdgeBuilder::buildTriangles(const real *vertices, - const real *normals, - vector<FrsMaterial>& iMaterials, - const real *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<WVertex *> triangleVertices; - vector<Vec3r> triangleNormals; - vector<Vec2r> triangleTexCoords; - vector<bool> triangleFaceEdgeMarks; - - // Each triplet of vertices is considered as an independent triangle - for(unsigned 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(Vec3r(normals[nindices[3*i]],normals[nindices[3*i]+1], normals[nindices[3*i]+2])); - triangleNormals.push_back(Vec3r(normals[nindices[3*i+1]],normals[nindices[3*i+1]+1],normals[nindices[3*i+1]+2])); - triangleNormals.push_back(Vec3r(normals[nindices[3*i+2]], normals[nindices[3*i+2]+1], normals[nindices[3*i+2]+2])); - - if(texCoords){ - triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i]],texCoords[tindices[3*i]+1])); - triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+1]],texCoords[tindices[3*i+1]+1])); - triangleTexCoords.push_back(Vec2r(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]); +void WingedEdgeBuilder::buildTriangles(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials, + const real *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<WVertex *> triangleVertices; + vector<Vec3r> triangleNormals; + vector<Vec2r> triangleTexCoords; + vector<bool> 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(Vec3r(normals[nindices[3 * i]], normals[nindices[3 * i] + 1], + normals[nindices[3 * i] + 2])); + triangleNormals.push_back(Vec3r(normals[nindices[3 * i + 1]], normals[nindices[3 * i + 1] + 1], + normals[nindices[3 * i + 1] + 2])); + triangleNormals.push_back(Vec3r(normals[nindices[3 * i + 2]], normals[nindices[3 * i + 2] + 1], + normals[nindices[3 * i + 2] + 2])); + + if (texCoords) { + triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i]], texCoords[tindices[3 * i] + 1])); + triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i + 1]], texCoords[tindices[3 * i + 1] + 1])); + triangleTexCoords.push_back(Vec2r(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 real *vertices, - unsigned vsize, - const Matrix44r& transform, - real *res) { - const real *v = vertices; - real *pv = res; - - for (unsigned i = 0; i < vsize / 3; i++) { - HVec3r hv_tmp(v[0], v[1], v[2]); - HVec3r hv(transform * hv_tmp); - for (unsigned j = 0; j < 3; j++) - pv[j] = hv[j] / hv[3]; - v += 3; - pv += 3; - } +void WingedEdgeBuilder::transformVertices(const real *vertices, unsigned vsize, const Matrix44r& transform, real *res) +{ + const real *v = vertices; + real *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 real *normals, - unsigned nsize, - const Matrix44r& transform, - real* res) { - const real *n = normals; - real *pn = res; - - for (unsigned i = 0; i < nsize / 3; i++) { - Vec3r hn(n[0], n[1], n[2]); - hn = GeomUtils::rotateVector(transform, hn); - for (unsigned j = 0; j < 3; j++) - pn[j] = hn[j]; - n += 3; - pn += 3; - } -} +void WingedEdgeBuilder::transformNormals(const real *normals, unsigned nsize, const Matrix44r& transform, real *res) +{ + const real *n = normals; + real *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; + } +}
\ No newline at end of file diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h index 972d67355d2..cf32c1191b2 100644 --- a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h +++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h @@ -1,171 +1,157 @@ -// -// Filename : WingedEdgeBuilder.h -// Author(s) : Stephane Grabli -// Purpose : Class to render a WingedEdge data structure -// from a polyhedral data structure organized in -// nodes of a scene graph -// Date of creation : 28/05/03 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef WINGED_EDGE_BUILDER_H -# define WINGED_EDGE_BUILDER_H - -# include "../system/FreestyleConfig.h" -# include "../system/RenderMonitor.h" -# include "../scene_graph/SceneVisitor.h" -# include "WEdge.h" -# include "../scene_graph/IndexedFaceSet.h" -# include "../scene_graph/NodeTransform.h" +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __FREESTYLE_WINGED_EDGE_BUILDER_H__ +#define __FREESTYLE_WINGED_EDGE_BUILDER_H__ + +/** \file blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h + * \ingroup freestyle + * \brief Class to render a WingedEdge data structure from a polyhedral data structure organized in nodes + * of a scene graph + * \author Stephane Grabli + * \date 28/05/2003 + */ + +#include "WEdge.h" + +#include "../scene_graph/IndexedFaceSet.h" +#include "../scene_graph/NodeTransform.h" +#include "../scene_graph/SceneVisitor.h" + +#include "../system/FreestyleConfig.h" +#include "../system/RenderMonitor.h" class LIB_WINGED_EDGE_EXPORT 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<Matrix44r*>::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; - } - - // inline void setCurrentMatrix(Matrix44r* matrix) { - // _current_matrix = matrix; - // } - - inline void setRenderMonitor(RenderMonitor *iRenderMonitor) { - _pRenderMonitor = iRenderMonitor; - } - - protected: - - virtual void buildWShape(WShape& shape, IndexedFaceSet& ifs); - virtual void buildWVertices(WShape& shape, - const real *vertices, - unsigned vsize); - - RenderMonitor *_pRenderMonitor; - - private: - - void buildTriangleStrip(const real *vertices, - const real *normals, - vector<FrsMaterial>& iMaterials, - const real *texCoords, - const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, - const unsigned *vindices, - const unsigned *nindices, - const unsigned *mindices, - const unsigned *tindices, - const unsigned nvertices); - - void buildTriangleFan(const real *vertices, - const real *normals, - vector<FrsMaterial>& iMaterials, - const real *texCoords, - const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, - const unsigned *vindices, - const unsigned *nindices, - const unsigned *mindices, - const unsigned *tindices, - const unsigned nvertices); - - void buildTriangles(const real *vertices, - const real *normals, - vector<FrsMaterial>& iMaterials, - const real *texCoords, - const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, - const unsigned *vindices, - const unsigned *nindices, - const unsigned *mindices, - const unsigned *tindices, - const unsigned nvertices); - - void transformVertices(const real *vertices, - unsigned vsize, - const Matrix44r& transform, - real *res); - - void transformNormals(const real *normals, - unsigned nsize, - const Matrix44r& transform, - real *res); - - WShape* _current_wshape; - FrsMaterial* _current_frs_material; - WingedEdge* _winged_edge; - Matrix44r* _current_matrix; - vector<Matrix44r*> _matrices_stack; +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<Matrix44r*>::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; + } +#endif + + inline void setRenderMonitor(RenderMonitor *iRenderMonitor) { + _pRenderMonitor = iRenderMonitor; + } + +protected: + virtual void buildWShape(WShape& shape, IndexedFaceSet& ifs); + virtual void buildWVertices(WShape& shape, const real *vertices, unsigned vsize); + + RenderMonitor *_pRenderMonitor; + +private: + void buildTriangleStrip(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials, + const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, + const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, + const unsigned *tindices, const unsigned nvertices); + + void buildTriangleFan(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials, + const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, + const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, + const unsigned *tindices, const unsigned nvertices); + + void buildTriangles(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials, + const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, + const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, + const unsigned *tindices, const unsigned nvertices); + + void transformVertices(const real *vertices, unsigned vsize, const Matrix44r& transform, real *res); + + void transformNormals(const real *normals, unsigned nsize, const Matrix44r& transform, real *res); + + WShape *_current_wshape; + FrsMaterial *_current_frs_material; + WingedEdge *_winged_edge; + Matrix44r *_current_matrix; + vector<Matrix44r *> _matrices_stack; }; -#endif // WINGED_EDGE_BUILDER_H +#endif // __FREESTYLE_WINGED_EDGE_BUILDER_H__
\ No newline at end of file |