1 // This is brl/bbas/imesh/imesh_vertex.h
2 #ifndef imesh_vertex_h_
3 #define imesh_vertex_h_
4 //:
5 // \file
6 // \brief A mesh vertex
7 // \author Matt Leotta (mleotta@lems.brown.edu)
8 // \date May 5, 2008
9 //
10 // \verbatim
11 //  Modifications
12 //   <none yet>
13 // \endverbatim
14 
15 #include <cassert>
16 #ifdef _MSC_VER
17 #  include <vcl_msvc_warnings.h>
18 #endif
19 #include <vgl/vgl_point_2d.h>
20 #include <vgl/vgl_point_3d.h>
21 #include <vgl/vgl_vector_3d.h>
22 
23 #define imesh_invalid_idx (static_cast<unsigned int>(-1))
24 
25 
26 //: A mesh face with a fixed number of vertices
27 template <unsigned d>
28 class imesh_vertex
29 {
30  public:
31   //: Default Constructor
imesh_vertex()32   imesh_vertex() { for (unsigned i=0; i<d; ++i) coords_[i]=0.0; }
33 
34   //: Constructor from a vector
imesh_vertex(const std::vector<double> & coords)35   imesh_vertex(const std::vector<double>& coords)
36   {assert(coords.size()==d); for (unsigned i=0; i<d; ++i) coords_[i]=coords[i];}
37 
38   //: return the dimension of the vertex
dim()39   unsigned int dim() const { return d; }
40 
41   //: Accessor
42   double operator[] (unsigned int i) const { return coords_[i]; }
43   double& operator[] (unsigned int i) { return coords_[i]; }
44 
45  protected:
46   double coords_[d];
47 };
48 
49 
50 //: A 2d vertex specialization with extra capabilities
51 template <>
52 class imesh_vertex<2>
53 {
54  public:
55   //: Default Constructor
imesh_vertex()56   imesh_vertex() { coords_[0]=0.0; coords_[1]=0.0;}
57 
58   //: Constructor (from 2 doubles)
imesh_vertex(double x,double y)59   imesh_vertex(double x, double y)
60   {
61     coords_[0] = x;
62     coords_[1] = y;
63   }
64 
65   //: Constructor (from vgl point)
imesh_vertex(const vgl_point_2d<double> & pt)66   imesh_vertex(const vgl_point_2d<double>& pt)
67   {
68     coords_[0] = pt.x();
69     coords_[1] = pt.y();
70   }
71 
72   //: convert to a vgl point
73   operator vgl_point_2d<double>() const
74   {
75     return {coords_[0],coords_[1]};
76   }
77 
78   //: Constructor from a vector
imesh_vertex(const std::vector<double> & coords)79   imesh_vertex(const std::vector<double>& coords)
80   {assert(coords.size()==2); coords_[0]=coords[0]; coords_[1]=coords[1];}
81 
82   //: return the dimension of the vertex
dim()83   unsigned int dim() const { return 2; }
84 
85   //: Accessor
86   double operator[] (unsigned int i) const { return coords_[i]; }
87   double& operator[] (unsigned int i) { return coords_[i]; }
88 
89  protected:
90   double coords_[2];
91 };
92 
93 
94 //: A 3d vertex specialization with extra capabilities
95 template <>
96 class imesh_vertex<3>
97 {
98  public:
99   //: Default Constructor
imesh_vertex()100   imesh_vertex() {coords_[0]=0.0; coords_[1]=0.0; coords_[2]=0.0; }
101 
102   //: Constructor (from 2 doubles)
imesh_vertex(double x,double y,double z)103   imesh_vertex(double x, double y, double z)
104   {
105     coords_[0] = x;
106     coords_[1] = y;
107     coords_[2] = z;
108   }
109 
110   //: Constructor (from vgl point)
imesh_vertex(const vgl_point_3d<double> & pt)111   imesh_vertex(const vgl_point_3d<double>& pt)
112   {
113     coords_[0] = pt.x();
114     coords_[1] = pt.y();
115     coords_[2] = pt.z();
116   }
117 
118   //: Constructor from a vector
imesh_vertex(const std::vector<double> & coords)119   imesh_vertex(const std::vector<double>& coords)
120   {
121     assert(coords.size()==3);
122     coords_[0]=coords[0];
123     coords_[1]=coords[1];
124     coords_[2]=coords[2];
125   }
126 
127   //: convert to a vgl point
128   operator vgl_point_3d<double>() const
129   {
130     return {coords_[0],coords_[1],coords_[2]};
131   }
132 
133   //: return the dimension of the vertex
dim()134   unsigned int dim() const { return 3; }
135 
136   //: Accessor
137   double operator[] (unsigned int i) const { return coords_[i]; }
138   double& operator[] (unsigned int i) { return coords_[i]; }
139 
140  protected:
141   double coords_[3];
142 };
143 
144 
145 //: Abstract base class for a collection of vertices
146 class imesh_vertex_array_base
147 {
148  public:
149   //: Destructor
150   virtual ~imesh_vertex_array_base() = default;
151 
152   //: returns the number of vertices
153   virtual unsigned int size() const = 0;
154 
155   //: returns the dimension of the vertices
156   virtual unsigned int dim() const = 0;
157 
158   //: Access a vertex coordinate by vertex index and coordinate index
159   virtual double operator() (unsigned int v, unsigned int i) const = 0;
160 
161   //: Produce a clone of this object (dynamic copy)
162   virtual imesh_vertex_array_base* clone() const = 0;
163 
164   //: Append these vertices (assuming the same type)
append(const imesh_vertex_array_base & verts)165   virtual void append(const imesh_vertex_array_base& verts)
166   {
167     if (this->has_normals() && verts.has_normals())
168       normals_.insert(normals_.end(), verts.normals_.begin(), verts.normals_.end());
169     else
170       normals_.clear();
171   }
172 
173   //: Return true if the vertices have normals
has_normals()174   bool has_normals() const { return !normals_.empty(); }
175 
176   //: Set the vertex normals
set_normals(const std::vector<vgl_vector_3d<double>> & n)177   void set_normals(const std::vector<vgl_vector_3d<double> >& n)
178   { assert(n.size() == this->size()); normals_ = n; }
179 
180   //: Access a vertex normal
normal(unsigned int v)181   vgl_vector_3d<double>& normal(unsigned int v) { return normals_[v]; }
normal(unsigned int v)182   const vgl_vector_3d<double>& normal(unsigned int v) const { return normals_[v]; }
183 
184   //: Access the normals
normals()185   const std::vector<vgl_vector_3d<double> >& normals() const { return normals_; }
186 
187  protected:
188   std::vector<vgl_vector_3d<double> > normals_;
189 };
190 
191 
192 //: An array of vertices of dimension d
193 template <unsigned int d>
194 class imesh_vertex_array : public imesh_vertex_array_base
195 {
196   std::vector<imesh_vertex<d> > verts_;
197 
198  public:
199   //: Default Constructor
200   imesh_vertex_array<d>() = default;
201 
202   //: Constructor (from size)
203   imesh_vertex_array<d>(unsigned int size)
verts_(size)204   : verts_(size) {}
205 
206   //: Constructor (from vector)
207   imesh_vertex_array<d>(const std::vector<imesh_vertex<d> >& verts)
verts_(verts)208   : verts_(verts) {}
209 
210   //: Produce a clone of this object (dynamic copy)
clone()211   imesh_vertex_array_base* clone() const override
212   {
213     return new imesh_vertex_array<d>(*this);
214   }
215 
216   //: returns the number of vertices
size()217   unsigned int size() const override { return verts_.size(); }
218 
219   //: returns the dimension of the vertices
dim()220   unsigned int dim() const override { return d; }
221 
222   //: Access a vertex coordinate by vertex index and coordinate index
operator()223   double operator() (unsigned int v, unsigned int i) const override { return verts_[v][i]; }
224 
225   //: Append these vertices (assuming the same type)
append(const imesh_vertex_array_base & verts)226   void append(const imesh_vertex_array_base& verts) override
227   {
228     assert(verts.dim() == d);
229     const imesh_vertex_array<d>& v = static_cast<const imesh_vertex_array<d>&>(verts);
230     verts_.insert(verts_.end(), v.verts_.begin(), v.verts_.end());
231     imesh_vertex_array_base::append(verts);
232   }
233 
234   //: Add a vertex to the array
push_back(const imesh_vertex<d> & v)235   void push_back(const imesh_vertex<d>& v) { verts_.push_back(v); }
236 
237   //: Access a vertex
238   imesh_vertex<d>& operator[] (unsigned int v) { return verts_[v]; }
239   const imesh_vertex<d>& operator[] (unsigned int v) const { return verts_[v]; }
240 
241   //=====================================================
242   // Vertex Iterators
243   typedef typename std::vector<imesh_vertex<d> >::iterator iterator;
244   typedef typename std::vector<imesh_vertex<d> >::const_iterator const_iterator;
245 
begin()246   iterator begin() { return verts_.begin(); }
begin()247   const_iterator begin() const { return verts_.begin(); }
248 
end()249   iterator end() { return verts_.end(); }
end()250   const_iterator end() const { return verts_.end(); }
251 };
252 
253 
254 //: compute the vector normal to the plane defined by 3 vertices
255 vgl_vector_3d<double> imesh_tri_normal(const imesh_vertex<3>& a,
256                                        const imesh_vertex<3>& b,
257                                        const imesh_vertex<3>& c);
258 
259 #endif // imesh_vertex_h_
260