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