File: PolyhedralSurf_rings.h

package info (click to toggle)
cgal 6.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 141,840 kB
  • sloc: cpp: 797,081; ansic: 203,398; sh: 490; python: 411; makefile: 286; javascript: 174
file content (164 lines) | stat: -rw-r--r-- 5,385 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#ifndef CGAL_PSURF_RINGS_H_
#define CGAL_PSURF_RINGS_H_

#include <cassert>

using namespace std;

template < class TPoly , class VertexPropertyMap> class T_PolyhedralSurf_rings
{
protected:
  //Polyhedron
  typedef typename TPoly::Vertex Vertex;
  typedef typename TPoly::Halfedge Halfedge;
  typedef typename TPoly::Facet Facet;
  typedef typename TPoly::Halfedge_around_vertex_circulator  Halfedge_around_vertex_circulator;
  typedef typename TPoly::Vertex_iterator Vertex_iterator;

  //vertex property map
//   typedef typename boost::property_traits<VertexPropertyMap>::value_type vpm_value_type;
//   typedef typename boost::property_traits<VertexPropertyMap>::key_type vpm_key_type;

  //vertex indices are initialized to -1
  static void reset_ring_indices(std::vector < Vertex * >&vces,
                                 VertexPropertyMap& vpm);

  //i >= 1; from a start vertex on the current i-1 ring, push non-visited neighbors
  //of start in the nextRing and set indices to i. Also add these vertices in all.
  static void push_neighbors_of(Vertex * start, int ith,
                          std::vector < Vertex * >&nextRing,
                          std::vector < Vertex * >&all,
                          VertexPropertyMap& vpm);

  //i >= 1, from a currentRing i-1, collect all neighbors, set indices
  //to i and store them in nextRing and all.
  static void collect_ith_ring(int ith,
                        std::vector < Vertex * >&currentRing,
                        std::vector < Vertex * >&nextRing,
                        std::vector < Vertex * >&all,
                        VertexPropertyMap& vpm);

 public:
  //collect i>=1 rings : all neighbors up to the ith ring,
  static void
    collect_i_rings(Vertex* v,
                    int ring_i,
                    std::vector < Vertex * >& all,
                    VertexPropertyMap& vpm);

  //collect enough rings (at least 1), to get at least min_nb of neighbors
  static void
    collect_enough_rings(Vertex* v,
                         unsigned int min_nb,
                         std::vector < Vertex * >& all,
                         VertexPropertyMap& vpm);
};

////IMPLEMENTATION/////////////////////////////////////////////////////////////////////

template < class TPoly , class VertexPropertyMap>
void T_PolyhedralSurf_rings <TPoly, VertexPropertyMap>::
push_neighbors_of(Vertex * start, int ith,
                  std::vector < Vertex * >&nextRing,
                  std::vector < Vertex * >&all,
                  VertexPropertyMap& vpm)
{
  Vertex *v;
  Halfedge_around_vertex_circulator
    hedgeb = start->vertex_begin(), hedgee = hedgeb;

 CGAL_For_all(hedgeb, hedgee)
  {
    v = &*(hedgeb->opposite()->vertex());
    if(get(vpm, v) != -1) continue;//if visited: next

    put(vpm, v, ith);
    nextRing.push_back(v);
    all.push_back(v);
  }
}

template <class TPoly, class VertexPropertyMap>
void T_PolyhedralSurf_rings <TPoly, VertexPropertyMap>::
collect_ith_ring(int ith, std::vector < Vertex * >&currentRing,
                 std::vector < Vertex * >&nextRing,
                 std::vector < Vertex * >&all,
                 VertexPropertyMap& vpm)
{
  typename std::vector < Vertex * >::iterator
    itb =    currentRing.begin(), ite = currentRing.end();

  CGAL_For_all(itb, ite) push_neighbors_of(*itb, ith, nextRing, all, vpm);
}

template <class TPoly, class VertexPropertyMap>
  void T_PolyhedralSurf_rings <TPoly, VertexPropertyMap>::
reset_ring_indices(std::vector < Vertex * >&vces,
                   VertexPropertyMap& vpm)
{
  typename std::vector < Vertex * >::iterator
    itb = vces.begin(), ite = vces.end();
  CGAL_For_all(itb, ite)  put(vpm, *itb, -1);
}

template <class TPoly, class VertexPropertyMap>
  void T_PolyhedralSurf_rings <TPoly, VertexPropertyMap>::
collect_i_rings(Vertex* v,
                int ring_i,
                std::vector < Vertex * >& all,
                VertexPropertyMap& vpm)
{
  std::vector<Vertex*> current_ring, next_ring;
  std::vector<Vertex*> *p_current_ring, *p_next_ring;
  assert(ring_i >= 1);
  //initialize
  p_current_ring = &current_ring;
  p_next_ring = &next_ring;
  put(vpm, v, 0);
  current_ring.push_back(v);
  all.push_back(v);

  for (int i=1; i<=ring_i; i++)
    {
      collect_ith_ring(i, *p_current_ring, *p_next_ring, all, vpm);
      //next round must be launched from p_nextRing...
      p_current_ring->clear();
      std::swap(p_current_ring, p_next_ring);
    }
  //clean up
  reset_ring_indices(all, vpm);
}

template <class TPoly, class VertexPropertyMap>
  void T_PolyhedralSurf_rings <TPoly, VertexPropertyMap>::
collect_enough_rings(Vertex* v,
                     unsigned int min_nb,
                     std::vector < Vertex * >& all,
                     VertexPropertyMap& vpm)
{
  std::vector<Vertex*> current_ring, next_ring;
  std::vector<Vertex*> *p_current_ring, *p_next_ring;

  //initialize
  p_current_ring = &current_ring;
  p_next_ring = &next_ring;
  put(vpm, v, 0);
  current_ring.push_back(v);
  all.push_back(v);

  int i = 1;

  while ( (all.size() < min_nb) &&  (p_current_ring->size() != 0) )
    {
      collect_ith_ring(i, *p_current_ring, *p_next_ring, all, vpm);
      //next round must be launched from p_nextRing...
      p_current_ring->clear();
      std::swap(p_current_ring, p_next_ring);
      i++;
    }
  //clean up
  reset_ring_indices(all, vpm);
}


#endif