polygon.cpp

Go to the documentation of this file.
00001 /*
00002     mesh3d
00003     Copyright (C) 2010  Timo Suoranta
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Lesser General Public
00007     License as published by the Free Software Foundation; either
00008     version 2.1 of the License, or (at your option) any later version.
00009 
00010     This library 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 GNU
00013     Lesser General Public License for more details.
00014 
00015     You should have received a copy of the GNU Lesser General Public
00016     License along with this library; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00018 */
00019 
00020 #include "mesh3d/polygon.h"
00021 #include "mesh3d/point.h"
00022 #include "mesh3d/corner.h"
00023 #include "mesh3d/attribute_map.h"
00024 #include <cassert>
00025 #include <cmath>
00026 #include <exception>
00027 
00035 namespace mesh3d {
00036 
00037 polygon::~polygon()
00038 {
00039     for(
00040         corner_collection::iterator i = m_corners.begin();
00041         i != m_corners.end();
00042         ++i
00043     )
00044     {
00045         mesh3d::corner *cor = *i;
00046         delete cor;
00047         *i = 0;
00048     }
00049     m_corners.clear();
00050 }
00051 
00052 void polygon::compute_normal(
00053     std::tr1::shared_ptr<attribute_map<mesh3d::polygon*, mesh3d::vec3> > polygon_normals,
00054     std::tr1::shared_ptr<attribute_map<mesh3d::point*,   mesh3d::vec3> > point_locations
00055 )
00056 {
00057     if(m_corners.size() > 2)
00058     {
00059         corner_collection::iterator i = m_corners.begin();
00060         mesh3d::corner *c0 = *i; ++i;           /*  first  point in polygon  */ 
00061         mesh3d::corner *c1 = *i;                /*  second point in polygon  */ 
00062         mesh3d::corner *c2 = m_corners.back();  /*  last   point in polygon  */ 
00063         mesh3d::point  *p0 = c0->point();
00064         mesh3d::point  *p1 = c1->point();
00065         mesh3d::point  *p2 = c2->point();
00066 
00067         /*  Make sure all points are unique from others  */ 
00068         if(
00069             (p0 != p1) &&
00070             (p0 != p2) &&
00071             (p1 != p2)
00072         )
00073         {
00074             vec3 pos0   = point_locations->value(p0);
00075             vec3 pos1   = point_locations->value(p1);
00076             vec3 pos2   = point_locations->value(p2);
00077             vec3 normal = cross((pos2 - pos0), (pos1 - pos0));
00078             normal = normalize(normal);
00079             polygon_normals->set_value(this, normal);
00080         }
00081         else
00082         {
00083             throw std::exception("polygons with duplicate points\n");
00084         }
00085 
00086     }
00087 }
00088 
00089 void polygon::compute_centroid(
00090     std::tr1::shared_ptr<attribute_map<mesh3d::polygon*, mesh3d::vec3> >  polygon_centroids,
00091     std::tr1::shared_ptr<attribute_map<mesh3d::point*,   mesh3d::vec3> >  point_locations
00092 )
00093 {
00094     mesh3d::vec3 centroid = mesh3d::vec3(0.0f, 0.0f, 0.0f);
00095     int count = 0;
00096     for(
00097         corner_collection::iterator i = m_corners.begin();
00098         i != m_corners.end();
00099         ++i
00100     )
00101     {
00102         mesh3d::corner  *cor  = *i;
00103         mesh3d::point   *pnt  = cor->point();
00104         mesh3d::vec3    pos0 = point_locations->value(pnt);
00105         centroid += pos0;
00106         ++count;
00107     }
00108     if(count > 0)
00109     {
00110         centroid /= (float)(count);
00111         polygon_centroids->set_value(this, centroid);
00112     }
00113     else
00114     {
00115         polygon_centroids->set_value(this, centroid);
00116     }
00117 }
00118 
00119 void polygon::compute_corner_normals(
00120     std::tr1::shared_ptr<attribute_map<mesh3d::corner*,  mesh3d::vec3> > corner_normals, 
00121     std::tr1::shared_ptr<attribute_map<mesh3d::polygon*, mesh3d::vec3> > polygon_normals, 
00122     std::tr1::shared_ptr<attribute_map<mesh3d::point*,   mesh3d::vec3> > point_locations,
00123     float                                                                cos_max_smoothing_angle
00124 )
00125 {
00126     if(m_corners.size() > 2)
00127     {
00128         for(
00129             corner_collection::iterator i = m_corners.begin();
00130             i != m_corners.end();
00131             ++i
00132         )
00133         {
00134             mesh3d::corner *cor = *i;
00135             cor->compute_normal(
00136                 corner_normals,
00137                 polygon_normals,
00138                 point_locations,
00139                 cos_max_smoothing_angle
00140             );
00141         }
00142     }
00143 }
00144 
00145 void polygon::copy_polygon_normal_to_corners(
00146     std::tr1::shared_ptr<attribute_map<mesh3d::corner*,  mesh3d::vec3> > corner_normals, 
00147     std::tr1::shared_ptr<attribute_map<mesh3d::polygon*, mesh3d::vec3> > polygon_normals
00148 )
00149 {
00150     if(m_corners.size() > 2)
00151     {
00152         mesh3d::vec3 pol_normal = polygon_normals->value(this);
00153         for(
00154             corner_collection::iterator i = m_corners.begin();
00155             i != m_corners.end();
00156             ++i
00157         )
00158         {
00159             mesh3d::corner *cor = *i;
00160             corner_normals->set_value(cor, pol_normal);
00161         }
00162     }
00163 }
00164 
00165 mesh3d::corner *polygon::corner(mesh3d::point *pnt)
00166 {
00167     for(
00168         corner_collection::iterator i = m_corners.begin();
00169         i != m_corners.end();
00170         ++i
00171     )
00172     {
00173         mesh3d::corner *cor = *i;
00174         if(pnt == cor->point())
00175         {
00176             return cor;
00177         }
00178     }
00179     return 0;
00180 }
00181 
00182 mesh3d::corner *polygon::make_corner(mesh3d::point *pnt)
00183 {
00184     mesh3d::corner *cor = new mesh3d::corner(pnt, this);
00185     pnt->add_corner(cor);
00186     m_corners.push_back(cor);
00187     return cor;
00188 }
00189 
00190 }  /*  namespace mesh3d  */ 
00191 
Generated on Sun Apr 11 12:23:08 2010 for RenderStack by  doxygen 1.6.3