Developer Documentation

HexahedralMeshIterators.cc
1 /*===========================================================================*\
2 * *
3 * OpenVolumeMesh *
4 * Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
5 * www.openvolumemesh.org *
6 * *
7 *---------------------------------------------------------------------------*
8 * This file is part of OpenVolumeMesh. *
9 * *
10 * OpenVolumeMesh is free software: you can redistribute it and/or modify *
11 * it under the terms of the GNU Lesser General Public License as *
12 * published by the Free Software Foundation, either version 3 of *
13 * the License, or (at your option) any later version with the *
14 * following exceptions: *
15 * *
16 * If other files instantiate templates or use macros *
17 * or inline functions from this file, or you compile this file and *
18 * link it with other files to produce an executable, this file does *
19 * not by itself cause the resulting executable to be covered by the *
20 * GNU Lesser General Public License. This exception does not however *
21 * invalidate any other reasons why the executable file might be *
22 * covered by the GNU Lesser General Public License. *
23 * *
24 * OpenVolumeMesh is distributed in the hope that it will be useful, *
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27 * GNU Lesser General Public License for more details. *
28 * *
29 * You should have received a copy of the GNU LesserGeneral Public *
30 * License along with OpenVolumeMesh. If not, *
31 * see <http://www.gnu.org/licenses/>. *
32 * *
33 \*===========================================================================*/
34
35 /*===========================================================================*\
36 * *
37 * $Revision$ *
38 * $Date$ *
39 * $LastChangedBy$ *
40 * *
41 \*===========================================================================*/
42
43 #include <set>
44
45 #include "HexahedralMeshIterators.hh"
46 #include "HexahedralMeshTopologyKernel.hh"
47
48 namespace OpenVolumeMesh {
49
50 //================================================================================================
51 // CellSheetCellIter
52 //================================================================================================
53
54
55 CellSheetCellIter::CellSheetCellIter(const CellHandle& _ref_h,
56 const unsigned char _orthDir, const HexahedralMeshTopologyKernel* _mesh, int _max_laps) :
57 BaseIter(_mesh, _ref_h, _max_laps) {
58
59 if(!_mesh->has_face_bottom_up_incidences()) {
60 #ifndef NDEBUG
61 std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
62 #endif
63 BaseIter::valid(false);
64 return;
65 }
66
67 // First off, get all surrounding cells
68 std::vector<HalfFaceHandle> halffaces = _mesh->cell(_ref_h).halffaces();
69 for(std::vector<HalfFaceHandle>::const_iterator hf_it = halffaces.begin();
70 hf_it != halffaces.end(); ++hf_it) {
71 // Add those, that are perpendicular to the specified _orthDir
72 if(_mesh->orientation(*hf_it, _ref_h) != _orthDir &&
73 _mesh->orientation(*hf_it, _ref_h) != _mesh->opposite_orientation(_orthDir)) {
74 CellHandle ch = _mesh->incident_cell(_mesh->opposite_halfface_handle(*hf_it));
75 if(ch != TopologyKernel::InvalidCellHandle) {
76 neighb_sheet_cell_hs_.push_back(ch);
77 }
78 }
79 }
80
81 // Remove all duplicate entries
82 std::sort(neighb_sheet_cell_hs_.begin(), neighb_sheet_cell_hs_.end());
83 neighb_sheet_cell_hs_.resize(std::unique(neighb_sheet_cell_hs_.begin(), neighb_sheet_cell_hs_.end()) - neighb_sheet_cell_hs_.begin());
84
85 cur_index_ = 0;
86 BaseIter::valid(neighb_sheet_cell_hs_.size() > 0);
87 if(BaseIter::valid()) {
88 BaseIter::cur_handle(neighb_sheet_cell_hs_[cur_index_]);
89 }
90 }
91
92
93 CellSheetCellIter& CellSheetCellIter::operator--() {
94
95 if (cur_index_ == 0) {
96 cur_index_ = neighb_sheet_cell_hs_.size() - 1;
97 --lap_;
98 if (lap_ < 0)
99 BaseIter::valid(false);
100 } else {
101 --cur_index_;
102 }
103
104 BaseIter::cur_handle(neighb_sheet_cell_hs_[cur_index_]);
105
106 return *this;
107 }
108
109
110 CellSheetCellIter& CellSheetCellIter::operator++() {
111
112 ++cur_index_;
113 if(cur_index_ == neighb_sheet_cell_hs_.size()) {
114 cur_index_ = 0;
115 ++lap_;
116 if (lap_ >= max_laps_)
117 BaseIter::valid(false);
118 }
119
120 BaseIter::cur_handle(neighb_sheet_cell_hs_[cur_index_]);
121
122 return *this;
123 }
124
125 //================================================================================================
126 // HalfFaceSheetHalfFaceIter
127 //================================================================================================
128
129
130 HalfFaceSheetHalfFaceIter::HalfFaceSheetHalfFaceIter(const HalfFaceHandle& _ref_h,
131 const HexahedralMeshTopologyKernel* _mesh, int _max_laps) :
132 BaseIter(_mesh, _ref_h, _max_laps) {
133
134 if(!_mesh->has_face_bottom_up_incidences()) {
135 #ifndef NDEBUG
136 std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
137 #endif
138 BaseIter::valid(false);
139 return;
140 }
141
142 /*
143 * Each halfface uniquely belongs to either a cell
144 * or the boundary. If the halfface belongs
145 * to a cell, it suffices to determine the local axis
146 * the halfface represents w.r.t. the cell and to
147 * iterate over all neighboring cells orthogonal to
148 * this direction. We have to find those halffaces
149 * of the neighboring cells that contain exactly one
150 * of the initial halfface's opposite halfedges.
151 */
152
153 if(_mesh->is_boundary(_ref_h)) {
154 #ifndef NDEBUG
155 std::cerr << "HalfFaceSheetHalfFaceIter: HalfFace is boundary!" << std::endl;
156 #endif
157 BaseIter::valid(false);
158 return;
159 }
160
161 CellHandle ch = _mesh->incident_cell(_ref_h);
162 unsigned char orientation = _mesh->orientation(_ref_h, ch);
163 std::vector<HalfEdgeHandle> hes_v = _mesh->opposite_halfface(_mesh->halfface(_ref_h)).halfedges();
164 std::set<HalfEdgeHandle> hes;
165 hes.insert(hes_v.begin(), hes_v.end());
166
167 for(CellSheetCellIter csc_it = _mesh->csc_iter(ch, orientation);
168 csc_it.valid(); ++csc_it) {
169
170 std::vector<HalfFaceHandle> hfs = _mesh->cell(*csc_it).halffaces();
171 for(std::vector<HalfFaceHandle>::const_iterator hf_it = hfs.begin();
172 hf_it != hfs.end(); ++hf_it) {
173
174 std::vector<HalfEdgeHandle> hf_hes = _mesh->halfface(*hf_it).halfedges();
175 for(std::vector<HalfEdgeHandle>::const_iterator he_it = hf_hes.begin();
176 he_it != hf_hes.end(); ++he_it) {
177
178 if(hes.count(*he_it) > 0) {
179 // Found halfface that lies on the same sheet
180 adjacent_halffaces_.push_back(*hf_it);
181 common_edges_.push_back(_mesh->edge_handle(*he_it));
182 break;
183 }
184 }
185 }
186 }
187
188 cur_index_ = 0;
189 BaseIter::valid(adjacent_halffaces_.size() > 0);
190 if(BaseIter::valid()) {
191 BaseIter::cur_handle(adjacent_halffaces_[cur_index_]);
192 }
193 }
194
195
196 HalfFaceSheetHalfFaceIter& HalfFaceSheetHalfFaceIter::operator--() {
197
198 if (cur_index_ == 0) {
199 cur_index_ = adjacent_halffaces_.size() - 1;
200 --lap_;
201 if (lap_ < 0)
202 BaseIter::valid(false);
203 } else {
204 --cur_index_;
205 }
206
207 BaseIter::cur_handle(adjacent_halffaces_[cur_index_]);
208
209 return *this;
210 }
211
212
213 HalfFaceSheetHalfFaceIter& HalfFaceSheetHalfFaceIter::operator++() {
214
215 ++cur_index_;
216 if(cur_index_ == adjacent_halffaces_.size()) {
217 cur_index_ = 0;
218 ++lap_;
219 if (lap_ >= max_laps_)
220 BaseIter::valid(false);
221 }
222
223 BaseIter::cur_handle(adjacent_halffaces_[cur_index_]);
224
225 return *this;
226 }
227
228 //================================================================================================
229 // HexVertexIter
230 //================================================================================================
231
232
233 HexVertexIter::HexVertexIter(const CellHandle& _ref_h,
234 const HexahedralMeshTopologyKernel* _mesh, int _max_laps) :
235 BaseIter(_mesh, _ref_h, _max_laps) {
236
237 assert(_ref_h.is_valid());
238 assert(_mesh->cell(_ref_h).halffaces().size() == 6);
239
240 // Get first half-face
241 HalfFaceHandle curHF = *_mesh->cell(_ref_h).halffaces().begin();
242 assert(curHF.is_valid());
243
244 // Get first half-edge
245 assert(_mesh->halfface(curHF).halfedges().size() == 4);
246 HalfEdgeHandle curHE = *_mesh->halfface(curHF).halfedges().begin();
247 assert(curHE.is_valid());
248
249 vertices_.push_back(_mesh->halfedge(curHE).from_vertex());
250
251 curHE = _mesh->prev_halfedge_in_halfface(curHE, curHF);
252
253 vertices_.push_back(_mesh->halfedge(curHE).from_vertex());
254
255 curHE = _mesh->prev_halfedge_in_halfface(curHE, curHF);
256
257 vertices_.push_back(_mesh->halfedge(curHE).from_vertex());
258
259 curHE = _mesh->prev_halfedge_in_halfface(curHE, curHF);
260
261 vertices_.push_back(_mesh->halfedge(curHE).from_vertex());
262
263 curHE = _mesh->prev_halfedge_in_halfface(curHE, curHF);
264 curHF = _mesh->adjacent_halfface_in_cell(curHF, curHE);
265 curHE = _mesh->opposite_halfedge_handle(curHE);
266 curHE = _mesh->next_halfedge_in_halfface(curHE, curHF);
267 curHE = _mesh->next_halfedge_in_halfface(curHE, curHF);
268 curHF = _mesh->adjacent_halfface_in_cell(curHF, curHE);
269 curHE = _mesh->opposite_halfedge_handle(curHE);
270
271 vertices_.push_back(_mesh->halfedge(curHE).to_vertex());
272
273 curHE = _mesh->prev_halfedge_in_halfface(curHE, curHF);
274
275 vertices_.push_back(_mesh->halfedge(curHE).to_vertex());
276
277 curHE = _mesh->prev_halfedge_in_halfface(curHE, curHF);
278
279 vertices_.push_back(_mesh->halfedge(curHE).to_vertex());
280
281 vertices_.push_back(_mesh->halfedge(curHE).from_vertex());
282
283 cur_index_ = 0;
284 BaseIter::valid(vertices_.size() > 0);
285 if(BaseIter::valid()) {
286 BaseIter::cur_handle(vertices_[cur_index_]);
287 }
288 }
289
290
291 HexVertexIter& HexVertexIter::operator--() {
292
293 if (cur_index_ == 0) {
294 cur_index_ = vertices_.size() - 1;
295 --lap_;
296 if (lap_ < 0)
297 BaseIter::valid(false);
298 } else {
299 --cur_index_;
300 }
301
302 BaseIter::cur_handle(vertices_[cur_index_]);
303
304 return *this;
305 }
306
307
308 HexVertexIter& HexVertexIter::operator++() {
309
310 ++cur_index_;
311 if(cur_index_ == vertices_.size()) {
312 cur_index_ = 0;
313 ++lap_;
314 if (lap_ >= max_laps_)
315 BaseIter::valid(false);
316 }
317
318 BaseIter::cur_handle(vertices_[cur_index_]);
319
320 return *this;
321 }
322
323 } // Namespace OpenVolumeMesh
OpenVolumeMesh::TopologyKernel::cell
const Cell & cell(const CellHandle &_cellHandle) const
Get cell with handle _cellHandle.
Definition: TopologyKernel.cc:2009
OpenVolumeMesh::TopologyKernel::opposite_halfface
Face opposite_halfface(const HalfFaceHandle &_halfFaceHandle) const
Get opposite halfface that corresponds to halfface with handle _halfFaceHandle.
Definition: TopologyKernel.cc:2106
OpenVolumeMesh::TopologyKernel::edge_handle
static EdgeHandle edge_handle(const HalfEdgeHandle &_h)
Handle conversion.
Definition: TopologyKernel.hh:933
OpenVolumeMesh::HexahedralMeshTopologyKernel
A data structure basing on PolyhedralMesh with specializations for hexahedra.
Definition: HexahedralMeshTopologyKernel.hh:86
OpenVolumeMesh::TopologyKernel::halfface
Face halfface(const HalfFaceHandle &_halfFaceHandle) const
Get face that corresponds to halfface with handle _halfFaceHandle.
Definition: TopologyKernel.cc:2072
OpenVolumeMesh::TopologyKernel::adjacent_halfface_in_cell
HalfFaceHandle adjacent_halfface_in_cell(const HalfFaceHandle &_halfFaceHandle, const HalfEdgeHandle &_halfEdgeHandle) const
Get halfface that is adjacent (w.r.t. a common halfedge) within the same cell.
Definition: TopologyKernel.cc:2267
OpenVolumeMesh
Definition: ColorAttrib.hh:53
OpenVolumeMesh::TopologyKernel::prev_halfedge_in_halfface
HalfEdgeHandle prev_halfedge_in_halfface(const HalfEdgeHandle &_heh, const HalfFaceHandle &_hfh) const
Get previous halfedge within a halfface.
Definition: TopologyKernel.cc:2246
OpenVolumeMesh::TopologyKernel::incident_cell
CellHandle incident_cell(const HalfFaceHandle &_halfFaceHandle) const
Get cell that is incident to the given halfface.
Definition: TopologyKernel.cc:2310
OpenVolumeMesh::TopologyKernel::halfedge
Edge halfedge(const HalfEdgeHandle &_halfEdgeHandle) const
Get edge that corresponds to halfedge with handle _halfEdgeHandle.
Definition: TopologyKernel.cc:2055
OpenVolumeMesh::TopologyKernel::next_halfedge_in_halfface
HalfEdgeHandle next_halfedge_in_halfface(const HalfEdgeHandle &_heh, const HalfFaceHandle &_hfh) const
Get next halfedge within a halfface.
Definition: TopologyKernel.cc:2226