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
52template< class MeshT >
54 : mesh_(_mesh), filler_(0)
55{
56}
57
59template< class MeshT >
61{
62 if (filler_ != 0)
63 delete filler_;
64}
65
67template< 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 for (auto e_it : mesh_->edges()) {
79 mesh_->property( boundary_search , e_it ) = false;
80 }
81
82 holes_.clear();
83
84 for (auto e_it : mesh_->edges()) {
85
86 // Skip already visited edges
87 if ( mesh_->property( boundary_search , e_it ) )
88 continue;
89
90 // Check only boundary edges
91 if ( !e_it.is_boundary())
92 continue;
93
94 // Get boundary halfedge
95 typename OpenMesh::SmartHalfedgeHandle hh = e_it.h0();
96 if ( ! hh.is_boundary() )
97 hh = hh.opp();
98
99
100 typename MeshT::Point center(0,0,0);
101
102 Hole currentHole;
103
104 // Collect boundary edges
105 typename OpenMesh::SmartHalfedgeHandle ch = hh;
106 do {
107 currentHole.push_back( ch.edge() );
108
109 center += mesh_->point( ch.from() );
110
111 mesh_->property( boundary_search , ch.edge() ) = true;
112
113 //check number of outgoing boundary HEH's at Vertex
114 int c = 0;
115 typename OpenMesh::SmartVertexHandle vh = ch.to();
116
117 for ( auto voh_it : vh.outgoing_halfedges())
118 if ( voh_it.is_boundary() )
119 c++;
120
121 if ( c >= 2){
122 typename MeshT::HalfedgeHandle op = ch.opp();
123 typename MeshT::VertexOHalfedgeIter voh_it(*mesh_,op);
124
125 ch = *(++voh_it);
126
127 } else
128 ch = ch.next();
129
130 } while ( ch != hh );
131
132
133 center /= currentHole.size();
134
135 bool isHole = true;
136
137 int err = 0;
138
139 for (unsigned int i=0; i < currentHole.size(); i++){
140 typename MeshT::HalfedgeHandle hh = currentHole[i].h0();
141
142 if ( ! mesh_->is_boundary( hh ) )
143 hh = mesh_->opposite_halfedge_handle( hh );
144
145 typename MeshT::VertexHandle vh = mesh_->from_vertex_handle(hh);
146
147 typename MeshT::Normal n = mesh_->normal( vh );
148
149 typename MeshT::Point p = mesh_->point( vh );
150
151 if ( (p - center).norm() < (p + n - center).norm() ){
152// isHole = false;
153// break;
154 err++;
155 }
156 }
157
158// std::cerr << "Errors " << err << " Size " << hole.count << std::endl;
159 if (isHole)
160 holes_.push_back(currentHole);
161 }
162
163 mesh_->remove_property( boundary_search);
164
165}
166
168template< class MeshT >
169void HoleInfo< MeshT >::fillHole(int _index, int _stages)
170{
171
172 if ( (uint) _index > holes_.size()){
173 std::cerr << "Cannot fill hole. Index invalid." << std::endl;
174 return;
175 }
176
177 if (filler_ == 0)
178 filler_ = new OpenMesh::HoleFiller::HoleFillerT< MeshT >(*mesh_);
179
180 filler_->fill_hole( holes_[_index][0], _stages );
181
182 mesh_->garbage_collection();
183
184 MeshSelection::clearEdgeSelection(mesh_);
185
186 mesh_->update_normals();
187}
188
190template< class MeshT >
191void HoleInfo< MeshT >::fillHole(typename MeshT::EdgeHandle _eh, int _stages)
192{
193 if (filler_ == 0)
194 filler_ = new OpenMesh::HoleFiller::HoleFillerT< MeshT >(*mesh_);
195
196 filler_->fill_hole( _eh, _stages );
197
198 mesh_->garbage_collection();
199
200 MeshSelection::clearEdgeSelection(mesh_);
201
202 mesh_->update_normals();
203}
204
206template< class MeshT >
208{
209
210 if (filler_ == 0)
211 filler_ = new OpenMesh::HoleFiller::HoleFillerT< MeshT >(*mesh_);
212
213 filler_->fill_all_holes( _stages );
214
215}
216
218template< class MeshT >
220{
221
222 if ( (uint) _index > holes_.size()){
223 std::cerr << "Cannot select hole. Index invalid." << std::endl;
224 return;
225 }
226
227 for ( uint i = 0 ; i < (holes_[_index]).size() ; ++i ) {
228 mesh_->status( (holes_[_index])[i] ).set_selected(true);
229 }
230
231}
232
233template< class MeshT >
234void HoleInfo< MeshT >::getHolePostitionInfo(const int _index, typename MeshT::Normal& _holeNormal, typename MeshT::Point& _holeCenter) const
235{
236
237 _holeCenter = typename MeshT::Point(0.0,0.0,0.0);
238 _holeNormal = typename MeshT::Normal(0.0,0.0,0.0);
239
240 // Center of gravity of hole and an average normal at the hole boundary
241 for ( size_t i = 0 ; i < holes_[_index].size() ; ++i ) {
242 const typename MeshT::HalfedgeHandle he = mesh_->halfedge_handle(holes_[_index][i],0);
243 const typename MeshT::VertexHandle vh_to = mesh_->to_vertex_handle(he);
244
245 _holeCenter += mesh_->point(vh_to);
246 _holeNormal += mesh_->normal(vh_to);
247 }
248
249 _holeCenter /= typename MeshT::Scalar(holes_[_index].size());
250 _holeNormal /= typename MeshT::Scalar(holes_[_index].size());
251 _holeNormal.normalize();
252
253}
254
255template< class MeshT >
256void HoleInfo< MeshT >::getHoleInfo(const unsigned int _index, size_t& _edges, typename MeshT::Scalar& _diagonal, typename MeshT::Scalar& _boundaryLength) const
257{
258
259 if ( _index >= holes_.size() ) {
260 std::cerr << "Invalid hole index " << _index << std::endl;
261 return;
262 }
263
264 _boundaryLength = 0.0;
265
266 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());
267 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());
268
269 for (size_t i = 0 ; i < holes_[_index].size() ; ++i) {
270 _boundaryLength += mesh_->calc_edge_length(holes_[_index][i]);
271
272 typename MeshT::Point pos = mesh_->point(mesh_->from_vertex_handle(mesh_->halfedge_handle(holes_[_index][i],0)));
273 minCoord[0] = std::min(minCoord[0],pos[0]);
274 minCoord[1] = std::min(minCoord[1],pos[1]);
275 minCoord[2] = std::min(minCoord[2],pos[2]);
276
277 maxCoord[0] = std::max(maxCoord[0],pos[0]);
278 maxCoord[1] = std::max(maxCoord[1],pos[1]);
279 maxCoord[2] = std::max(maxCoord[2],pos[2]);
280 }
281
282 _edges = holes_[_index].size();
283 _diagonal = (maxCoord - minCoord).length();
284
285}
286
287
289template< class MeshT >
290std::vector< std::vector< typename OpenMesh::SmartEdgeHandle > >* HoleInfo< MeshT >::holes()
291{
292 return &holes_;
293}
294
295
Functions for selection on a mesh.
~HoleInfo()
Destruktor.
void getHoleInfo(const unsigned int _index, size_t &_edges, typename MeshT::Scalar &_diagonal, typename MeshT::Scalar &_boundaryLength) const
void fillAllHoles(int _stages=3)
fill all holes
void getHolePostitionInfo(const int _index, typename MeshT::Normal &_holeNormal, typename MeshT::Point &_holeCenter) const
Collect information to fly to a hole.
void getHoles()
get all holes and store them internally
void selectHole(int _index)
select a hole with given index
std::vector< std::vector< typename OpenMesh::SmartEdgeHandle > > * holes()
get the holes vector
HoleInfo(MeshT *_mesh)
Konstruktor.
void fillHole(int _index, int _stages=3)
fill hole with given index
void update_normals()
Compute normals for all primitives.
Scalar calc_edge_length(EdgeHandle _eh) const
Compute normals for all primitives.
Definition: PolyMeshT.hh:434
bool is_boundary() const
Returns true iff the handle is boundary.
Scalar norm(const VectorT< Scalar, DIM > &_v)
Definition: Vector11T.hh:749
SmartVertexHandle from() const
Returns vertex at start of halfedge.
SmartHalfedgeHandle next() const
Returns next halfedge handle.
SmartEdgeHandle edge() const
Returns incident edge of halfedge.
SmartHalfedgeHandle opp() const
Returns opposite halfedge handle.
SmartVertexHandle to() const
Returns vertex pointed to by halfedge.
Smart version of VertexHandle contains a pointer to the corresponding mesh and allows easier access t...
PolyConnectivity::ConstVertexOHalfedgeRange outgoing_halfedges() const
Returns a range of incoming halfedges incident to the vertex (PolyConnectivity::voh_range())