35 #ifndef HEXAHEDRALMESHTOPOLOGYKERNEL_HH 36 #define HEXAHEDRALMESHTOPOLOGYKERNEL_HH 43 #include "../Core/TopologyKernel.hh" 44 #include "HexahedralMeshIterators.hh" 45 #include "OpenVolumeMesh/Config/Export.hh" 83 static const unsigned char XF = 0;
84 static const unsigned char XB = 1;
85 static const unsigned char YF = 2;
86 static const unsigned char YB = 3;
87 static const unsigned char ZF = 4;
88 static const unsigned char ZB = 5;
89 static const unsigned char INVALID = 6;
91 static inline unsigned char opposite_orientation(
const unsigned char _d) {
92 return static_cast<unsigned char>(_d % 2 == 0 ? _d + 1 : _d - 1);
102 FaceHandle add_face(
const std::vector<HalfEdgeHandle>& _halfedges,
bool _topologyCheck =
false)
override;
105 FaceHandle add_face(
const std::vector<VertexHandle>& _vertices)
override;
108 CellHandle add_cell(
const std::vector<HalfFaceHandle>& _halffaces,
bool _topologyCheck =
false)
override;
112 bool check_halfface_ordering(
const std::vector<HalfFaceHandle>& _hfs)
const;
136 CellHandle add_cell(
const std::vector<VertexHandle>& _vertices,
bool _topologyCheck =
false);
140 friend class CellSheetCellIter;
141 friend class HalfFaceSheetHalfFaceIter;
142 friend class HexVertexIter;
144 typedef class CellSheetCellIter CellSheetCellIter;
145 typedef class HalfFaceSheetHalfFaceIter HalfFaceSheetHalfFaceIter;
146 typedef class HexVertexIter HexVertexIter;
148 CellSheetCellIter csc_iter(
const CellHandle& _ref_h,
const unsigned char _orthDir,
int _max_laps = 1)
const {
149 return CellSheetCellIter(_ref_h, _orthDir,
this, _max_laps);
152 std::pair<CellSheetCellIter,CellSheetCellIter> cell_sheet_cells(
const CellHandle& _ref_h,
const unsigned char _orthDir,
int _max_laps = 1)
const {
153 CellSheetCellIter begin = csc_iter(_ref_h, _orthDir, _max_laps);
154 CellSheetCellIter end = make_end_circulator(begin);
155 return std::make_pair(begin, end);
158 HalfFaceSheetHalfFaceIter hfshf_iter(
const HalfFaceHandle& _ref_h,
int _max_laps = 1)
const {
159 return HalfFaceSheetHalfFaceIter(_ref_h,
this, _max_laps);
162 std::pair<HalfFaceSheetHalfFaceIter,HalfFaceSheetHalfFaceIter> halfface_sheet_halffaces(
const HalfFaceHandle& _ref_h,
int _max_laps = 1)
const {
163 HalfFaceSheetHalfFaceIter begin = hfshf_iter(_ref_h, _max_laps);
164 HalfFaceSheetHalfFaceIter end = make_end_circulator(begin);
165 return std::make_pair(begin, end);
168 HexVertexIter hv_iter(
const CellHandle& _ref_h,
int _max_laps = 1)
const {
169 return HexVertexIter(_ref_h,
this, _max_laps);
172 std::pair<HexVertexIter,HexVertexIter> hex_vertices(
const CellHandle& _ref_h,
int _max_laps = 1)
const {
173 HexVertexIter begin = hv_iter(_ref_h, _max_laps);
174 HexVertexIter end = make_end_circulator(begin);
175 return std::make_pair(begin, end);
182 assert((
unsigned int)_ch.idx() < TopologyKernel::cells_.size());
184 if(orientation(_hfh, _ch) == XF)
return xback_halfface(_ch);
185 if(orientation(_hfh, _ch) == XB)
return xfront_halfface(_ch);
186 if(orientation(_hfh, _ch) == YF)
return yback_halfface(_ch);
187 if(orientation(_hfh, _ch) == YB)
return yfront_halfface(_ch);
188 if(orientation(_hfh, _ch) == ZF)
return zback_halfface(_ch);
189 if(orientation(_hfh, _ch) == ZB)
return zfront_halfface(_ch);
191 return TopologyKernel::InvalidHalfFaceHandle;
196 assert((
unsigned int)_ch.idx() < TopologyKernel::cells_.size());
203 assert((
unsigned int)_ch.idx() < TopologyKernel::cells_.size());
210 assert((
unsigned int)_ch.idx() < TopologyKernel::cells_.size());
217 assert((
unsigned int)_ch.idx() < TopologyKernel::cells_.size());
224 assert((
unsigned int)_ch.idx() < TopologyKernel::cells_.size());
231 assert((
unsigned int)_ch.idx() < TopologyKernel::cells_.size());
238 assert((
unsigned int)_ch.idx() < TopologyKernel::cells_.size());
241 for(
unsigned int i = 0; i < halffaces.size(); ++i) {
242 if(halffaces[i] == _hfh)
return (
unsigned char)i;
248 static inline unsigned char orthogonal_orientation(
const unsigned char _o1,
const unsigned char _o2) {
250 if(_o1 == XF && _o2 == YF)
return ZF;
251 if(_o1 == XF && _o2 == YB)
return ZB;
252 if(_o1 == XF && _o2 == ZF)
return YB;
253 if(_o1 == XF && _o2 == ZB)
return YF;
254 if(_o1 == XB && _o2 == YF)
return ZB;
255 if(_o1 == XB && _o2 == YB)
return ZF;
256 if(_o1 == XB && _o2 == ZF)
return YF;
257 if(_o1 == XB && _o2 == ZB)
return YB;
259 if(_o1 == YF && _o2 == XF)
return ZB;
260 if(_o1 == YF && _o2 == XB)
return ZF;
261 if(_o1 == YF && _o2 == ZF)
return XF;
262 if(_o1 == YF && _o2 == ZB)
return XB;
263 if(_o1 == YB && _o2 == XF)
return ZF;
264 if(_o1 == YB && _o2 == XB)
return ZB;
265 if(_o1 == YB && _o2 == ZF)
return XB;
266 if(_o1 == YB && _o2 == ZB)
return XF;
268 if(_o1 == ZF && _o2 == YF)
return XB;
269 if(_o1 == ZF && _o2 == YB)
return XF;
270 if(_o1 == ZF && _o2 == XF)
return YF;
271 if(_o1 == ZF && _o2 == XB)
return YB;
272 if(_o1 == ZB && _o2 == YF)
return XF;
273 if(_o1 == ZB && _o2 == YB)
return XB;
274 if(_o1 == ZB && _o2 == XF)
return YB;
275 if(_o1 == ZB && _o2 == XB)
return YF;
283 if(_o == XF)
return xfront_halfface(_ch);
284 if(_o == XB)
return xback_halfface(_ch);
285 if(_o == YF)
return yfront_halfface(_ch);
286 if(_o == YB)
return yback_halfface(_ch);
287 if(_o == ZF)
return zfront_halfface(_ch);
288 if(_o == ZB)
return zback_halfface(_ch);
289 return TopologyKernel::InvalidHalfFaceHandle;
294 if(!TopologyKernel::has_face_bottom_up_incidences()) {
296 std::cerr <<
"No bottom-up incidences computed so far, could not get adjacent halfface on sheet!" << std::endl;
298 return TopologyKernel::InvalidHalfFaceHandle;
307 if(n_hf == TopologyKernel::InvalidHalfFaceHandle)
break;
308 n_hf = TopologyKernel::opposite_halfface_handle(n_hf);
309 if(n_hf == TopologyKernel::InvalidHalfFaceHandle)
break;
310 HalfEdgeHandle o_he = TopologyKernel::opposite_halfedge_handle(n_he);
311 if(o_he == TopologyKernel::InvalidHalfEdgeHandle)
break;
313 if(n_hf == TopologyKernel::InvalidHalfFaceHandle)
break;
317 n_hf = TopologyKernel::opposite_halfface_handle(_hfh);
318 n_he = TopologyKernel::opposite_halfedge_handle(_heh);
323 if(n_hf == TopologyKernel::InvalidHalfFaceHandle)
break;
324 n_hf = TopologyKernel::opposite_halfface_handle(n_hf);
325 if(n_hf == TopologyKernel::InvalidHalfFaceHandle)
break;
326 HalfEdgeHandle o_he = TopologyKernel::opposite_halfedge_handle(n_he);
327 if(o_he == TopologyKernel::InvalidHalfEdgeHandle)
break;
329 if(n_hf == TopologyKernel::InvalidHalfFaceHandle)
break;
330 else return TopologyKernel::opposite_halfface_handle(n_hf);
333 return TopologyKernel::InvalidHalfFaceHandle;
339 hehf_it.valid(); ++hehf_it) {
340 if(*hehf_it == _hfh)
continue;
341 if(TopologyKernel::is_boundary(*hehf_it)) {
344 if(TopologyKernel::is_boundary(TopologyKernel::opposite_halfface_handle(*hehf_it))) {
345 return TopologyKernel::opposite_halfface_handle(*hehf_it);
348 return TopologyKernel::InvalidHalfFaceHandle;
353 if(!TopologyKernel::has_face_bottom_up_incidences()) {
355 std::cerr <<
"No bottom-up incidences computed so far, could not get neighboring outside halfface!" << std::endl;
357 return TopologyKernel::InvalidHalfFaceHandle;
361 hehf_it; ++hehf_it) {
362 if(*hehf_it == _hfh)
continue;
363 if(TopologyKernel::is_boundary(*hehf_it))
return *hehf_it;
364 if(TopologyKernel::is_boundary(TopologyKernel::opposite_halfface_handle(*hehf_it)))
365 return TopologyKernel::opposite_halfface_handle(*hehf_it);
368 return TopologyKernel::InvalidHalfFaceHandle;
374 const std::vector<HalfFaceHandle>& _halffaces)
const;
A data structure basing on PolyhedralMesh with specializations for hexahedra.
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.
const Cell & cell(const CellHandle &_cellHandle) const
Get cell with handle _cellHandle.