1 // This is brl/bbas/bmsh3d/bmsh3d_vertex.h 2 //--------------------------------------------------------------------- 3 #ifndef bmsh3d_vertex_h_ 4 #define bmsh3d_vertex_h_ 5 //: 6 // \file 7 // \brief Basic 3d point sample on a mesh 8 // 9 // \author 10 // MingChing Chang April 22, 2005 11 // 12 // \verbatim 13 // Modifications 14 // Peter Vanroose - 6 Sep 2008 - avoid some const-casting-away warnings by changing signature of some methods 15 // \endverbatim 16 // 17 //------------------------------------------------------------------------- 18 19 #include <iostream> 20 #include <set> 21 #include <string> 22 #include <sstream> 23 #ifdef _MSC_VER 24 # include <vcl_msvc_warnings.h> 25 #endif 26 #include <cassert> 27 #include <vgl/vgl_point_3d.h> 28 29 #include "bmsh3d_ptr_list.h" 30 #include "bmsh3d_utils.h" 31 32 //####################################################### 33 // The Mesh Library Data Structure 34 // (Combined IndexedFaceSet and Half-Edge.) 35 // Can handle: 36 // 1) Point Cloud 37 // 2) Point Cloud with Edges (Indexed Line Set) 38 // 3) Point Cloud with Edges and Faces (ILS and IFS) 39 // 4) Non-Manifold Mesh (IFS) 40 // 5) Manifold Mesh 41 // 6) Triangle Manifold Mesh 42 // Need to revise the HalfEdge design by 43 // changing each vertex's halfedge pointer to an edge pointer! 44 //####################################################### 45 46 class bmsh3d_edge; 47 class bmsh3d_halfedge; 48 class bmsh3d_face; 49 50 //: Typology of a mesh vertex. 51 typedef enum 52 { 53 BOGUS_VTOPO_TYPE = 0, 54 VTOPO_ISOLATED = 1, 55 VTOPO_EDGE_ONLY = 2, 56 VTOPO_EDGE_JUNCTION = 3, 57 VTOPO_2_MANIFOLD = 4, 58 VTOPO_2_MANIFOLD_1RING = 5, 59 VTOPO_NON_MANIFOLD = 6, 60 VTOPO_NON_MANIFOLD_1RING = 7, 61 } VTOPO_TYPE; 62 63 class bmsh3d_vertex : public vispt_elm 64 { 65 protected: 66 int id_; 67 68 vgl_point_3d<double> pt_; 69 70 //: link list to store incident mesh edges 71 bmsh3d_ptr_node* E_list_; 72 73 //: link list to incident mesh faces for intermediate processing. 74 bmsh3d_ptr_node* F_list_; 75 76 //: To optimize C++ class object size, this variable is used for: 77 // - i_visited_: the visited flag for mesh hypergraph traversal. 78 // - vid_: for (IFS) keeping the order of vertices of a face. 79 // - b_valid_: valid or not 80 int i_value_; 81 82 //: This variable is used for: 83 // - b_meshed_: is this vertex meshed or not. 84 // - type info for dbsk3d_fs_node_elm. 85 // It's here to optimize C++ class object size. 86 char c_value_; 87 88 //: This variable is used in shocks. 89 char flow_type_; 90 91 public: 92 //###### Constructor/Destructor ###### bmsh3d_vertex(int id)93 bmsh3d_vertex(int id) { 94 E_list_ = nullptr; 95 F_list_ = nullptr; 96 id_ = id; 97 i_value_ = 0; 98 c_value_ = '?'; 99 flow_type_ = '?'; 100 } bmsh3d_vertex(const double & x,const double & y,const double & z,const int id)101 bmsh3d_vertex(const double& x, const double& y, const double& z, const int id) { 102 E_list_ = nullptr; 103 F_list_ = nullptr; 104 id_ = id; 105 i_value_ = 0; 106 c_value_ = '?'; 107 flow_type_ = '?'; 108 pt_.set(x, y, z); 109 } ~bmsh3d_vertex()110 ~bmsh3d_vertex() override { 111 //can not delete a vertex with any incident edge 112 assert(E_list_ == nullptr); 113 } 114 115 //###### Data access functions ###### pt()116 const vgl_point_3d<double>& pt() const { 117 return pt_; 118 } get_pt()119 vgl_point_3d<double>& get_pt() { 120 return pt_; 121 } set_pt(const vgl_point_3d<double> & pt)122 void set_pt(const vgl_point_3d<double>& pt) { 123 pt_ = pt; 124 } set_pt(const double & x,const double & y,const double & z)125 void set_pt(const double& x, const double& y, const double& z) { 126 pt_.set(x, y, z); 127 } 128 E_list()129 bmsh3d_ptr_node* E_list() const { 130 return E_list_; 131 } F_list()132 bmsh3d_ptr_node* F_list() const { 133 return F_list_; 134 } set_F_list(bmsh3d_ptr_node * F_list)135 void set_F_list(bmsh3d_ptr_node* F_list) { 136 F_list_ = F_list; 137 } get_Fs(std::set<const void * > & ptrs)138 unsigned int get_Fs(std::set<const void*>& ptrs) { 139 return get_all_ptrs(F_list_, ptrs); 140 } 141 #if 0 // DEPRECATED: calls the deprecated non-const get_all_ptrs() version 142 // \deprecated 143 unsigned int get_Fs(std::set<void*>& ptrs) { 144 return get_all_ptrs(F_list_, ptrs); 145 } 146 #endif clear_F_list()147 unsigned int clear_F_list() { 148 return clear_ptr_list(F_list_); 149 } add_F(void * F)150 void add_F(void* F) { 151 bmsh3d_ptr_node* curr = new bmsh3d_ptr_node(F); 152 add_to_ptr_list_head_(F_list_, curr); 153 } 154 id()155 int id() const { 156 return id_; 157 } set_id(const int id)158 void set_id(const int id) { 159 id_ = id; 160 } 161 i_value()162 int i_value() const { 163 return i_value_; 164 } set_i_value(const int v)165 void set_i_value(const int v) { 166 i_value_ = v; 167 } vid()168 int vid() const { 169 return i_value_; 170 } set_vid(int vid)171 void set_vid(int vid) { 172 i_value_ = vid; 173 } 174 is_visited()175 bool is_visited() const { 176 return i_value_ != 0; 177 } 178 //: if i_value_ less than i_traverse_flag, it's not visited is_visited(const int traverse_value)179 bool is_visited(const int traverse_value) const { 180 return i_value_ >= traverse_value; 181 } set_i_visited(const int traverse_value)182 void set_i_visited(const int traverse_value) { 183 i_value_ = traverse_value; 184 } 185 is_valid()186 bool is_valid() const { 187 return i_value_ != 0; 188 } set_valid(const bool v)189 void set_valid(const bool v) { 190 if (v) 191 i_value_ = 1; 192 else 193 i_value_ = 0; 194 } 195 b_meshed()196 bool b_meshed() const { 197 return c_value_ == 'm'; 198 } set_meshed(const bool b)199 void set_meshed(const bool b) { 200 if (b) 201 c_value_ = 'm'; 202 else 203 c_value_ = '?'; 204 } 205 206 //: Return a platform-independent name of the class is_a()207 virtual std::string is_a() const 208 {return "bmsh3d_vertex"; } 209 210 //###### Handle the incident edges ###### get_incident_Es(std::set<void const * > & incident_Es)211 unsigned int get_incident_Es(std::set<void const*>& incident_Es) const { 212 return get_all_ptrs(E_list_, incident_Es); 213 } 214 #if 0 // DEPRECATED! -- use the above "const" version instead 215 // \deprecated 216 unsigned int get_incident_Es(std::set<void*>& incident_Es) const { 217 return get_all_ptrs(E_list_, incident_Es); 218 } 219 #endif // 0 n_incident_Es()220 unsigned int n_incident_Es() const { 221 return count_all_ptrs(E_list_); 222 } clear_incident_E_list()223 unsigned int clear_incident_E_list() { 224 return clear_ptr_list(E_list_); 225 } has_incident_Es()226 bool has_incident_Es() const { 227 return E_list_!=nullptr; 228 } is_E_incident(const bmsh3d_edge * E)229 bool is_E_incident(const bmsh3d_edge* E) const { 230 return is_in_ptr_list(E_list_, E); 231 } add_incident_E(const bmsh3d_edge * E)232 void add_incident_E(const bmsh3d_edge* E) { 233 add_ptr_to_list(E_list_, E); //add_ptr_check 234 } check_add_incident_E(const bmsh3d_edge * E)235 bool check_add_incident_E(const bmsh3d_edge* E) { 236 return check_add_ptr(E_list_, E); 237 } del_incident_E(const bmsh3d_edge * E)238 bool del_incident_E(const bmsh3d_edge* E) { 239 return del_ptr(E_list_, E); 240 } 241 get_1st_incident_E()242 const bmsh3d_edge* get_1st_incident_E() const { 243 if (E_list_ == nullptr) 244 return nullptr; 245 return (const bmsh3d_edge*)E_list_->ptr(); 246 } 247 248 const bmsh3d_halfedge* get_1st_bnd_HE() const; 249 250 //: function to return all incident faces of this vertex 251 int get_incident_Fs(std::set<bmsh3d_face*>& face_set); 252 253 //: return the vertex topology type 254 VTOPO_TYPE detect_vtopo_type() const; 255 unsigned int check_2_manifold_(const bmsh3d_edge* startE, VTOPO_TYPE& cond) const; 256 const bmsh3d_edge* find_unvisited_E_() const; 257 258 //###### Other functions ###### 259 void getInfo(std::ostringstream& ostrm) override; 260 261 //###### For the face of a 2-manifold mesh only ###### 262 // these functions start with a tag m2 (manifold-2) 263 bmsh3d_halfedge* m2_get_ordered_HEs(std::vector<const bmsh3d_halfedge*>& ordered_halfedges) const; 264 265 bmsh3d_halfedge* m2_get_next_bnd_HE(const bmsh3d_halfedge* inputHE) const; 266 267 //: return true if it is on the boundary of the mesh. 268 // Start tracing from input_he to see if the loop back to input_he 269 bool m2_is_on_bnd(bmsh3d_halfedge* inputHE) const; 270 271 //: return the sum_theta at this vertex 272 double m2_sum_theta() const; 273 }; 274 275 //: Find the mesh edge sharing the two vertices. 276 bmsh3d_edge* E_sharing_2V(const bmsh3d_vertex* V1, const bmsh3d_vertex* V2); 277 278 //: Find the mesh face sharing the given vertices. 279 bmsh3d_face* find_F_sharing_Vs(std::vector<bmsh3d_vertex*>& vertices); 280 281 bmsh3d_face* get_non_manifold_1ring_extra_Fs(bmsh3d_vertex* V); 282 283 bool is_F_V_incidence(bmsh3d_vertex* V, const bmsh3d_vertex* V1, const bmsh3d_vertex* V2); 284 285 const bmsh3d_edge* V_find_other_E(const bmsh3d_vertex* V, const bmsh3d_edge* inputE); 286 287 #endif // bmsh3d_vertex_h_ 288