Developer Documentation
HoleInfoT_impl.hh
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 
43 #define HOLEINFO_C
44 
45 #include "HoleInfoT.hh"
46 
48 
49 #include <algorithm>
50 
52 template< class MeshT >
54  : mesh_(_mesh), filler_(0)
55 {
56 }
57 
59 template< class MeshT >
61 {
62  if (filler_ != 0)
63  delete filler_;
64 }
65 
67 template< class MeshT >
69 {
70 
71  // Property for the active mesh to mark already visited edges
72  OpenMesh::EPropHandleT< bool > boundary_search;
73 
74  // Add a property to the mesh to store original vertex positions
75  mesh_->add_property( boundary_search, "Boundary search" );
76 
77  // Initialize Property
78  typename MeshT::EdgeIter e_it, e_end=mesh_->edges_end();
79  for (e_it=mesh_->edges_begin(); e_it!=e_end; ++e_it) {
80  mesh_->property( boundary_search , *e_it ) = false;
81  }
82 
83  holes_.clear();
84 
85  for (e_it=mesh_->edges_begin(); e_it!=e_end; ++e_it) {
86 
87  // Skip already visited edges
88  if ( mesh_->property( boundary_search , *e_it ) )
89  continue;
90 
91  // Check only boundary edges
92  if ( !mesh_->is_boundary(*e_it))
93  continue;
94 
95  // Get boundary halfedge
96  typename MeshT::HalfedgeHandle hh = mesh_->halfedge_handle( *e_it, 0 );
97  if ( ! mesh_->is_boundary( hh ) )
98  hh = mesh_->opposite_halfedge_handle( hh );
99 
100 
101  typename MeshT::Point center(0,0,0);
102 
103  Hole currentHole;
104 
105  // Collect boundary edges
106  typename MeshT::HalfedgeHandle ch = hh;
107  do {
108  currentHole.push_back( mesh_->edge_handle(ch) );
109 
110  center += mesh_->point( mesh_->from_vertex_handle(ch) );
111 
112  mesh_->property( boundary_search , mesh_->edge_handle(ch) ) = true;
113 
114  //check number of outgoing boundary HEH's at Vertex
115  int c = 0;
116  typename MeshT::VertexHandle vh = mesh_->to_vertex_handle(ch);
117 
118  for ( typename MeshT::VertexOHalfedgeIter voh_it(*mesh_,vh); voh_it.is_valid(); ++voh_it)
119  if ( mesh_->is_boundary( *voh_it ) )
120  c++;
121 
122  if ( c >= 2){
123  typename MeshT::HalfedgeHandle op = mesh_->opposite_halfedge_handle( ch );
124  typename MeshT::VertexOHalfedgeIter voh_it(*mesh_,op);
125 
126  ch = *(++voh_it);
127 
128  } else
129  ch = mesh_->next_halfedge_handle( ch );
130 
131  } while ( ch != hh );
132 
133 
134  center /= currentHole.size();
135 
136  bool isHole = true;
137 
138  int err = 0;
139 
140  for (unsigned int i=0; i < currentHole.size(); i++){
141  typename MeshT::HalfedgeHandle hh = mesh_->halfedge_handle( currentHole[i], 0 );
142 
143  if ( ! mesh_->is_boundary( hh ) )
144  hh = mesh_->opposite_halfedge_handle( hh );
145 
146  typename MeshT::VertexHandle vh = mesh_->from_vertex_handle(hh);
147 
148  typename MeshT::Normal n = mesh_->normal( vh );
149 
150  typename MeshT::Point p = mesh_->point( vh );
151 
152  if ( (p - center).norm() < (p + n - center).norm() ){
153 // isHole = false;
154 // break;
155  err++;
156  }
157  }
158 
159 // std::cerr << "Errors " << err << " Size " << hole.count << std::endl;
160  if (isHole)
161  holes_.push_back(currentHole);
162  }
163 
164  mesh_->remove_property( boundary_search);
165 
166 }
167 
169 template< class MeshT >
170 void HoleInfo< MeshT >::fillHole(int _index, int _stages)
171 {
172 
173  if ( (uint) _index > holes_.size()){
174  std::cerr << "Cannot fill hole. Index invalid." << std::endl;
175  return;
176  }
177 
178  if (filler_ == 0)
179  filler_ = new HoleFiller< MeshT >(*mesh_);
180 
181  filler_->fill_hole( holes_[_index][0], _stages );
182 
183  mesh_->garbage_collection();
184 
185  MeshSelection::clearEdgeSelection(mesh_);
186 
187  mesh_->update_normals();
188 }
189 
191 template< class MeshT >
192 void HoleInfo< MeshT >::fillHole(typename MeshT::EdgeHandle _eh, int _stages)
193 {
194  if (filler_ == 0)
195  filler_ = new HoleFiller< MeshT >(*mesh_);
196 
197  filler_->fill_hole( _eh, _stages );
198 
199  mesh_->garbage_collection();
200 
201  MeshSelection::clearEdgeSelection(mesh_);
202 
203  mesh_->update_normals();
204 }
205 
207 template< class MeshT >
209 {
210 
211  if (filler_ == 0)
212  filler_ = new HoleFiller< MeshT >(*mesh_);
213 
214  filler_->fill_all_holes( _stages );
215 
216 }
217 
219 template< class MeshT >
221 {
222 
223  if ( (uint) _index > holes_.size()){
224  std::cerr << "Cannot select hole. Index invalid." << std::endl;
225  return;
226  }
227 
228  for ( uint i = 0 ; i < (holes_[_index]).size() ; ++i ) {
229  mesh_->status( (holes_[_index])[i] ).set_selected(true);
230  }
231 
232 }
233 
234 template< class MeshT >
235 void HoleInfo< MeshT >::getHolePostitionInfo(const int _index, typename MeshT::Normal& _holeNormal, typename MeshT::Point& _holeCenter) const
236 {
237 
238  _holeCenter = typename MeshT::Point(0.0,0.0,0.0);
239  _holeNormal = typename MeshT::Normal(0.0,0.0,0.0);
240 
241  // Center of gravity of hole and an average normal at the hole boundary
242  for ( size_t i = 0 ; i < holes_[_index].size() ; ++i ) {
243  const typename MeshT::HalfedgeHandle he = mesh_->halfedge_handle(holes_[_index][i],0);
244  const typename MeshT::VertexHandle vh_to = mesh_->to_vertex_handle(he);
245 
246  _holeCenter += mesh_->point(vh_to);
247  _holeNormal += mesh_->normal(vh_to);
248  }
249 
250  _holeCenter /= typename MeshT::Scalar(holes_[_index].size());
251  _holeNormal /= typename MeshT::Scalar(holes_[_index].size());
252  _holeNormal.normalize();
253 
254 }
255 
256 template< class MeshT >
257 void HoleInfo< MeshT >::getHoleInfo(const unsigned int _index, size_t& _edges, typename MeshT::Scalar& _diagonal, typename MeshT::Scalar& _boundaryLength) const
258 {
259 
260  if ( _index >= holes_.size() ) {
261  std::cerr << "Invalid hole index " << _index << std::endl;
262  return;
263  }
264 
265  _boundaryLength = 0.0;
266 
267  typename MeshT::Point minCoord = typename MeshT::Point(std::numeric_limits<typename MeshT::Scalar>::max(),std::numeric_limits<typename MeshT::Scalar>::max(),std::numeric_limits<typename MeshT::Scalar>::max());
268  typename MeshT::Point maxCoord = typename MeshT::Point(-std::numeric_limits<typename MeshT::Scalar>::max(),-std::numeric_limits<typename MeshT::Scalar>::max(),-std::numeric_limits<typename MeshT::Scalar>::max());
269 
270  for (size_t i = 0 ; i < holes_[_index].size() ; ++i) {
271  _boundaryLength += mesh_->calc_edge_length(holes_[_index][i]);
272 
273  typename MeshT::Point pos = mesh_->point(mesh_->from_vertex_handle(mesh_->halfedge_handle(holes_[_index][i],0)));
274  minCoord[0] = std::min(minCoord[0],pos[0]);
275  minCoord[1] = std::min(minCoord[1],pos[1]);
276  minCoord[2] = std::min(minCoord[2],pos[2]);
277 
278  maxCoord[0] = std::max(maxCoord[0],pos[0]);
279  maxCoord[1] = std::max(maxCoord[1],pos[1]);
280  maxCoord[2] = std::max(maxCoord[2],pos[2]);
281  }
282 
283  _edges = holes_[_index].size();
284  _diagonal = (maxCoord - minCoord).length();
285 
286 }
287 
288 
290 template< class MeshT >
291 std::vector< std::vector< typename MeshT::EdgeHandle > >* HoleInfo< MeshT >::holes()
292 {
293  return &holes_;
294 }
295 
296 
void getHoleInfo(const unsigned int _index, size_t &_edges, typename MeshT::Scalar &_diagonal, typename MeshT::Scalar &_boundaryLength) const
~HoleInfo()
Destruktor.
void selectHole(int _index)
select a hole with given index
void fillAllHoles(int _stages=3)
fill all holes
Functions for selection on a mesh.
void fillHole(int _index, int _stages=3)
fill hole with given index
void getHoles()
get all holes and store them internally
void getHolePostitionInfo(const int _index, typename MeshT::Normal &_holeNormal, typename MeshT::Point &_holeCenter) const
Collect information to fly to a hole.
std::vector< std::vector< typename MeshT::EdgeHandle > > * holes()
get the holes vector
HoleInfo(MeshT *_mesh)
Konstruktor.