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