contrib/brl/bbas/imesh/imesh_vertex.h
Go to the documentation of this file.
00001 // This is brl/bbas/imesh/imesh_vertex.h
00002 #ifndef imesh_vertex_h_
00003 #define imesh_vertex_h_
00004 //:
00005 // \file
00006 // \brief A mesh vertex
00007 // \author Matt Leotta (mleotta@lems.brown.edu)
00008 // \date May 5, 2008
00009 //
00010 // \verbatim
00011 //  Modifications
00012 //   <none yet>
00013 // \endverbatim
00014 
00015 #include <vcl_cassert.h>
00016 #include <vgl/vgl_point_2d.h>
00017 #include <vgl/vgl_point_3d.h>
00018 #include <vgl/vgl_vector_3d.h>
00019 
00020 #define imesh_invalid_idx (static_cast<unsigned int>(-1))
00021 
00022 
00023 //: A mesh face with a fixed number of vertices
00024 template <unsigned d>
00025 class imesh_vertex
00026 {
00027  public:
00028   //: Default Constructor
00029   imesh_vertex() { for (unsigned i=0; i<d; ++i) coords_[i]=0.0; }
00030 
00031   //: Constructor from a vector
00032   imesh_vertex(const vcl_vector<double>& coords)
00033   {assert(coords.size()==d); for (unsigned i=0; i<d; ++i) coords_[i]=coords[i];}
00034 
00035   //: return the dimension of the vertex
00036   unsigned int dim() const { return d; }
00037 
00038   //: Accessor
00039   double operator[] (unsigned int i) const { return coords_[i]; }
00040   double& operator[] (unsigned int i) { return coords_[i]; }
00041 
00042  protected:
00043   double coords_[d];
00044 };
00045 
00046 
00047 //: A 2d vertex specialization with extra capabilities
00048 VCL_DEFINE_SPECIALIZATION
00049 class imesh_vertex<2>
00050 {
00051  public:
00052   //: Default Constructor
00053   imesh_vertex() { coords_[0]=0.0; coords_[1]=0.0;}
00054 
00055   //: Constructor (from 2 doubles)
00056   imesh_vertex(double x, double y)
00057   {
00058     coords_[0] = x;
00059     coords_[1] = y;
00060   }
00061 
00062   //: Constructor (from vgl point)
00063   imesh_vertex(const vgl_point_2d<double>& pt)
00064   {
00065     coords_[0] = pt.x();
00066     coords_[1] = pt.y();
00067   }
00068 
00069   //: convert to a vgl point
00070   operator vgl_point_2d<double>() const
00071   {
00072     return vgl_point_2d<double>(coords_[0],coords_[1]);
00073   }
00074 
00075   //: Constructor from a vector
00076   imesh_vertex(const vcl_vector<double>& coords)
00077   {assert(coords.size()==2); coords_[0]=coords[0]; coords_[1]=coords[1];}
00078 
00079   //: return the dimension of the vertex
00080   unsigned int dim() const { return 2; }
00081 
00082   //: Accessor
00083   double operator[] (unsigned int i) const { return coords_[i]; }
00084   double& operator[] (unsigned int i) { return coords_[i]; }
00085 
00086  protected:
00087   double coords_[2];
00088 };
00089 
00090 
00091 //: A 3d vertex specialization with extra capabilities
00092 VCL_DEFINE_SPECIALIZATION
00093 class imesh_vertex<3>
00094 {
00095  public:
00096   //: Default Constructor
00097   imesh_vertex() {coords_[0]=0.0; coords_[1]=0.0; coords_[2]=0.0; }
00098 
00099   //: Constructor (from 2 doubles)
00100   imesh_vertex(double x, double y, double z)
00101   {
00102     coords_[0] = x;
00103     coords_[1] = y;
00104     coords_[2] = z;
00105   }
00106 
00107   //: Constructor (from vgl point)
00108   imesh_vertex(const vgl_point_3d<double>& pt)
00109   {
00110     coords_[0] = pt.x();
00111     coords_[1] = pt.y();
00112     coords_[2] = pt.z();
00113   }
00114 
00115   //: Constructor from a vector
00116   imesh_vertex(const vcl_vector<double>& coords)
00117   {
00118     assert(coords.size()==3);
00119     coords_[0]=coords[0];
00120     coords_[1]=coords[1];
00121     coords_[2]=coords[2];
00122   }
00123 
00124   //: convert to a vgl point
00125   operator vgl_point_3d<double>() const
00126   {
00127     return vgl_point_3d<double>(coords_[0],coords_[1],coords_[2]);
00128   }
00129 
00130   //: return the dimension of the vertex
00131   unsigned int dim() const { return 3; }
00132 
00133   //: Accessor
00134   double operator[] (unsigned int i) const { return coords_[i]; }
00135   double& operator[] (unsigned int i) { return coords_[i]; }
00136 
00137  protected:
00138   double coords_[3];
00139 };
00140 
00141 
00142 //: Abstract base class for a collection of vertices
00143 class imesh_vertex_array_base
00144 {
00145  public:
00146   //: Destructor
00147   virtual ~imesh_vertex_array_base() {}
00148 
00149   //: returns the number of vertices
00150   virtual unsigned int size() const = 0;
00151 
00152   //: returns the dimension of the vertices
00153   virtual unsigned int dim() const = 0;
00154 
00155   //: Access a vertex coordinate by vertex index and coordinate index
00156   virtual double operator() (unsigned int v, unsigned int i) const = 0;
00157 
00158   //: Produce a clone of this object (dynamic copy)
00159   virtual imesh_vertex_array_base* clone() const = 0;
00160 
00161   //: Append these vertices (assuming the same type)
00162   virtual void append(const imesh_vertex_array_base& verts)
00163   {
00164     if (this->has_normals() && verts.has_normals())
00165       normals_.insert(normals_.end(), verts.normals_.begin(), verts.normals_.end());
00166     else
00167       normals_.clear();
00168   }
00169 
00170   //: Return true if the vertices have normals
00171   bool has_normals() const { return !normals_.empty(); }
00172 
00173   //: Set the vertex normals
00174   void set_normals(const vcl_vector<vgl_vector_3d<double> >& n)
00175   { assert(n.size() == this->size()); normals_ = n; }
00176 
00177   //: Access a vertex normal
00178   vgl_vector_3d<double>& normal(unsigned int v) { return normals_[v]; }
00179   const vgl_vector_3d<double>& normal(unsigned int v) const { return normals_[v]; }
00180 
00181   //: Access the normals
00182   const vcl_vector<vgl_vector_3d<double> >& normals() const { return normals_; }
00183 
00184  protected:
00185   vcl_vector<vgl_vector_3d<double> > normals_;
00186 };
00187 
00188 
00189 //: An array of vertices of dimension d
00190 template <unsigned int d>
00191 class imesh_vertex_array : public imesh_vertex_array_base
00192 {
00193   vcl_vector<imesh_vertex<d> > verts_;
00194 
00195  public:
00196   //: Default Constructor
00197   imesh_vertex_array<d>() {}
00198 
00199   //: Constructor (from size)
00200   imesh_vertex_array<d>(unsigned int size)
00201   : verts_(size) {}
00202 
00203   //: Constructor (from vector)
00204   imesh_vertex_array<d>(const vcl_vector<imesh_vertex<d> >& verts)
00205   : verts_(verts) {}
00206 
00207   //: Produce a clone of this object (dynamic copy)
00208   virtual imesh_vertex_array_base* clone() const
00209   {
00210     return new imesh_vertex_array<d>(*this);
00211   }
00212 
00213   //: returns the number of vertices
00214   virtual unsigned int size() const { return verts_.size(); }
00215 
00216   //: returns the dimension of the vertices
00217   virtual unsigned int dim() const { return d; }
00218 
00219   //: Access a vertex coordinate by vertex index and coordinate index
00220   virtual double operator() (unsigned int v, unsigned int i) const { return verts_[v][i]; }
00221 
00222   //: Append these vertices (assuming the same type)
00223   virtual void append(const imesh_vertex_array_base& verts)
00224   {
00225     assert(verts.dim() == d);
00226     const imesh_vertex_array<d>& v = static_cast<const imesh_vertex_array<d>&>(verts);
00227     verts_.insert(verts_.end(), v.verts_.begin(), v.verts_.end());
00228     imesh_vertex_array_base::append(verts);
00229   }
00230 
00231   //: Add a vertex to the array
00232   void push_back(const imesh_vertex<d>& v) { verts_.push_back(v); }
00233 
00234   //: Access a vertex
00235   imesh_vertex<d>& operator[] (unsigned int v) { return verts_[v]; }
00236   const imesh_vertex<d>& operator[] (unsigned int v) const { return verts_[v]; }
00237 
00238   //=====================================================
00239   // Vertex Iterators
00240   typedef typename vcl_vector<imesh_vertex<d> >::iterator iterator;
00241   typedef typename vcl_vector<imesh_vertex<d> >::const_iterator const_iterator;
00242 
00243   iterator begin() { return verts_.begin(); }
00244   const_iterator begin() const { return verts_.begin(); }
00245 
00246   iterator end() { return verts_.end(); }
00247   const_iterator end() const { return verts_.end(); }
00248 };
00249 
00250 
00251 //: compute the vector normal to the plane defined by 3 vertices
00252 vgl_vector_3d<double> imesh_tri_normal(const imesh_vertex<3>& a,
00253                                        const imesh_vertex<3>& b,
00254                                        const imesh_vertex<3>& c);
00255 
00256 #endif // imesh_vertex_h_