1 // This is brl/bbas/imesh/imesh_mesh.h
2 #ifndef imesh_mesh_h_
3 #define imesh_mesh_h_
4 //:
5 // \file
6 // \brief An indexed face set mesh
7 // \author Matt Leotta (mleotta@lems.brown.edu)
8 // \date May 2, 2008
9 
10 #include <vector>
11 #include <iostream>
12 #include <memory>
13 #ifdef _MSC_VER
14 #  include <vcl_msvc_warnings.h>
15 #endif
16 #include <cassert>
17 
18 #include <imesh/imesh_vertex.h>
19 #include <imesh/imesh_face.h>
20 #include <imesh/imesh_half_edge.h>
21 
22 #include <vgl/vgl_point_2d.h>
23 
24 //for brdb smart pointer
25 #include <vbl/vbl_ref_count.h>
26 #include <vbl/vbl_smart_ptr.h>
27 #include <vsl/vsl_binary_io.h>
28 
29 //: A simple mesh
30 class imesh_mesh : public vbl_ref_count
31 {
32  public:
33   //: Default Constructor
imesh_mesh()34   imesh_mesh() : tex_coord_status_(TEX_COORD_NONE) {}
35 
36   //: Constructor from vertex and face arrays
37   //  Takes ownership of these arrays
imesh_mesh(std::unique_ptr<imesh_vertex_array_base> verts,std::unique_ptr<imesh_face_array_base> faces)38   imesh_mesh(std::unique_ptr<imesh_vertex_array_base> verts, std::unique_ptr<imesh_face_array_base> faces)
39   : verts_(std::move(verts)), faces_(std::move(faces)), tex_coord_status_(TEX_COORD_NONE) {}
40 
41   //: Copy Constructor
42   imesh_mesh(const imesh_mesh& other);
43 
44   //: Assignment operator
45   imesh_mesh& operator=(imesh_mesh const& other);
46 
47   //: Return the number of vertices
num_verts()48   unsigned int num_verts() const {return verts_->size();}
49 
50   //: Return the number of faces
num_faces()51   unsigned int num_faces() const {return faces_->size();}
52 
53   //: Return the number of edges
num_edges()54   unsigned int num_edges() const {return half_edges_.size()/2;}
55 
56   //: Merge the data from another mesh into this one
57   //  Duplicates are not removed
58   void merge(const imesh_mesh& other);
59 
60   //: Return true if the mesh has been initialized
is_init()61   bool is_init() const { return verts_.get() && faces_.get(); }
62 
63   //: Access the vector of vertices
vertices()64   const imesh_vertex_array_base& vertices() const { return *verts_; }
vertices()65   imesh_vertex_array_base& vertices() { return *verts_; }
66 
67   //: Access the vector of vertices cast to a dimension
68   template <unsigned int d>
vertices()69   const imesh_vertex_array<d>& vertices() const
70   {
71     assert(dynamic_cast<imesh_vertex_array<d>*>(verts_.get()));
72     return static_cast<const imesh_vertex_array<d>&>(*verts_);
73   }
74   template <unsigned int d>
vertices()75   imesh_vertex_array<d>& vertices()
76   {
77     assert(dynamic_cast<imesh_vertex_array<d>*>(verts_.get()));
78     return static_cast<imesh_vertex_array<d>&>(*verts_);
79   }
80 
81   //: Access the vector of faces
faces()82   const imesh_face_array_base& faces() const { return *faces_; }
faces()83   imesh_face_array_base& faces() { return *faces_; }
84 
85   //: Set the vertices
set_vertices(std::unique_ptr<imesh_vertex_array_base> verts)86   void set_vertices(std::unique_ptr<imesh_vertex_array_base> verts) { verts_ = std::move(verts); }
87 
88   //: Set the faces
set_faces(std::unique_ptr<imesh_face_array_base> faces)89   void set_faces(std::unique_ptr<imesh_face_array_base> faces) { faces_ = std::move(faces); }
90 
91   //: Returns true if the mesh has computed half edges
has_half_edges()92   bool has_half_edges() const { return half_edges_.size() > 0; }
93 
94   //: Return the half edge set
half_edges()95   const imesh_half_edge_set& half_edges() const { return half_edges_; }
96 
97   //: Construct the half edges graph structure
98   void build_edge_graph();
99 
100   //: Remove the half edge graph structure
remove_edge_graph()101   void remove_edge_graph() { half_edges_.clear(); }
102 
103   //: Compute vertex normals
104   void compute_vertex_normals();
105 
106   //: Compute vertex normals using face normals
107   void compute_vertex_normals_from_faces();
108 
109   //: Compute face normals
110   //  If norm == false the vector lengths are twice the area of the face
111   void compute_face_normals(bool norm = true);
112 
113   //: This type indicates how texture coordinates are indexed
114   // ON_VERT is one coordinate per vertex
115   // ON_CORNER is one coordinate per half edge (i.e. corner)
116   enum tex_coord_type { TEX_COORD_NONE = 0,
117                         TEX_COORD_ON_VERT = 1,
118                         TEX_COORD_ON_CORNER = 2 };
119 
120   //: Returns texture coordinate availability
has_tex_coords()121   tex_coord_type has_tex_coords() const { return tex_coord_status_; }
122 
123   //: Return the texture coordinates
tex_coords()124   const std::vector<vgl_point_2d<double> >& tex_coords() const { return tex_coords_; }
125 
126   //: Set the texture coordinates
127   void set_tex_coords(const std::vector<vgl_point_2d<double> >& tc);
128 
129   //: set the texture sources
set_tex_source(const std::string ts)130   void set_tex_source(const std::string ts) { tex_source_ = ts; }
tex_source()131   const std::string& tex_source() const { return tex_source_; }
132 
133   //: Return a vector indicating which faces have texture
valid_tex_faces()134   const std::vector<bool>& valid_tex_faces() const { return valid_tex_faces_; }
135 
136   //: Set the vector indicating which faces have texture
137   void set_valid_tex_faces(const std::vector<bool>& valid);
138 
139   //: Label all faces with positive (counter clockwise orientation) area as valid
140   //  This requirement refers to the texture map coordinates
141   void label_ccw_tex_faces_valid();
142 
143   //: Map a barycentric coordinate (u,v) on triangle \param tri into texture space
144   vgl_point_2d<double> texture_map(unsigned int tri,
145                                    double u, double v) const;
146 
147 
148  private:
149   std::unique_ptr<imesh_vertex_array_base> verts_;
150   std::unique_ptr<imesh_face_array_base> faces_;
151   imesh_half_edge_set half_edges_;
152 
153   //: vector of texture coordinates
154   std::vector<vgl_point_2d<double> > tex_coords_;
155 
156   //: vector of texture sources
157   std::string tex_source_;
158 
159   //: indicate which faces have texture data
160   std::vector<bool> valid_tex_faces_;
161   //: the type of texture coordinates
162   tex_coord_type tex_coord_status_;
163 };
164 
165 //smartptr
166 typedef vbl_smart_ptr<imesh_mesh> imesh_mesh_sptr;
167 
168 //--- IO read/write for sptrs--------------------------------------------------
169 //: Binary write boxm2_scene scene to stream
170 void vsl_b_write(vsl_b_ostream& os, imesh_mesh_sptr& sptr);
171 void vsl_b_write(vsl_b_ostream& os, imesh_mesh_sptr const& sptr);
172 
173 //: Binary load boxm2_scene scene from stream.
174 void vsl_b_read(vsl_b_istream& is, imesh_mesh_sptr& sptr);
175 void vsl_b_read(vsl_b_istream& is, imesh_mesh_sptr const& sptr);
176 
177 #endif // imesh_mesh_h_
178