face.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2007 by Pablo Diaz-Gutierrez   *
00003  *   pablo@ics.uci.edu   *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Library General Public License as       *
00007  *   published by the Free Software Foundation; either version 2 of the    *
00008  *   License, or (at your option) any later version.                       *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU Library General Public     *
00016  *   License along with this program; if not, write to the                 *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00021 #ifdef _WIN32
00022 #pragma warning(disable:4786)
00023 #endif
00024 
00025 #include <cassert>
00026 #include "face.h"
00027 #include "vertex.h"
00028 #include "halfedge.h"
00029 
00030 using namespace std;
00031 using namespace Geometry;
00032 using namespace HE;
00033 
00034 
00035 Vector3Df Face::normal() const
00036 {
00037         //static Vector3Df prev(1,0,0); // $$$ Hack to prevent problems with degenerate normals...
00038         Vector3Df N(0,0,0);
00039 #if 0 // We can still compute the normal of a hole... Let the application decide its use.
00040         if (hole())
00041                 return N;
00042 #endif
00043 
00044         const_edge_circulator e = begin();
00045         const_edge_circulator sentinel = e;
00046         do
00047         {
00048                 Vector3Df v(- (*e)->tangent());
00049                 ++e;
00050                 Vector3Df v2((*e)->tangent());
00051                 float a = v.angle(v2);
00052                 Vector3Df n = v2 ^ v;
00053                 N += a*n;
00054         } while (e != sentinel) ;
00055 
00056         N.normalize();
00057 #if 1
00058         return N;
00059 #else
00060         if (!isnan(N[0]) && !isnan(N[1]) && !isnan(N[2]))
00061         {
00062                 prevN = N;
00063                 return N;
00064         }
00065         else
00066         {
00067                 return prevN;
00068         }
00069 #endif
00070 }
00071 
00072 Vector3Df Face::centroid() const
00073 {
00074         Vector3Df C(0,0,0);
00075 
00076         const_edge_circulator e = begin();
00077         const_edge_circulator sentinel = e;
00078         int n = 0;
00079         do
00080         {
00081                 n++;
00082                 C += (*e)->dst()->position();
00083                 ++e;
00084         } while (e != sentinel) ;
00085 
00086         return C / n;
00087 }
00088 
00089 
00090 ostream& HE::operator<< (ostream& out, const Face& f)
00091 {
00092         out << '[' << (int)f.edge() << (f.hole() ? ", hole" : ", solid") << ", " << f.size() << " verts: ";
00093 
00094         Face::const_edge_circulator e = f.begin();
00095         const Face::const_edge_circulator sentinel = e;
00096         do
00097         {
00098                 const Vertex* v = (*e)->dst();
00099                 if (v)
00100                         out << ' ' << v->index();
00101                 else
00102                         out << " NULL";
00103                 ++e;
00104         } while (sentinel != e) ;
00105 
00106    return out << ']';
00107 }
00108 
00109 int Face::size() const
00110 {
00111         Face::const_edge_circulator e = begin();
00112         Face::const_edge_circulator sentinel = e;
00113         int n(0);
00114         do
00115         {
00116                 n++;
00117                 ++e;
00118         } while (sentinel != e) ;
00119 
00120         return n;
00121 }
00122 
00123 bool Face::contains(const HalfEdge* he) const
00124 {
00125         Face::const_edge_circulator e = begin();
00126         Face::const_edge_circulator sentinel = e;
00127         do
00128         {
00129                 if (*e == he)
00130                         return true;
00131                 ++e;
00132         } while (sentinel != e) ;
00133 
00134         return false;
00135 }
00136 
00137 bool Face::contains(const Vertex* v) const
00138 {
00139         Face::const_edge_circulator e = begin();
00140         Face::const_edge_circulator sentinel = e;
00141         do
00142         {
00143                 if ((*e)->dst() == v)
00144                         return true;
00145                 ++e;
00146         } while (sentinel != e) ;
00147 
00148         return false;
00149 }
00150 
00151 const HalfEdge* Face::fromVertex(int v) const
00152 {
00153         Face::const_edge_circulator e = begin();
00154         Face::const_edge_circulator sentinel = e;
00155         do
00156         {
00157                 if ((*e)->dst()->index() == v)
00158                         return (*e)->next();
00159                 ++e;
00160         } while (sentinel != e) ;
00161 
00162         return 0;
00163 }
00164 
00165 const HalfEdge* Face::toVertex(int v) const
00166 {
00167         Face::const_edge_circulator e = begin();
00168         Face::const_edge_circulator sentinel = e;
00169         do
00170         {
00171                 if ((*e)->dst()->index() == v)
00172                         return *e;
00173                 ++e;
00174         } while (sentinel != e) ;
00175 
00176         return 0;
00177 }
00178 
00179 const HalfEdge* Face::fromVertex(Vertex* v) const
00180 {
00181         return fromVertex(v->index());
00182 }
00183 
00184 const HalfEdge* Face::toVertex(Vertex* v) const
00185 {
00186         return toVertex(v->index());
00187 }
00188 
00189 void HE::Face::edge_circulator::operator++()
00190 {
00191         _here = _here->next();
00192 }
00193 
00194 void HE::Face::const_edge_circulator::operator++()
00195 {
00196         _here = _here->next();
00197 }
00198 

Generated on Wed Apr 9 19:22:37 2008 for HalfEdge library by  doxygen 1.5.3