81 static const unsigned char XF = 0;
82 static const unsigned char XB = 1;
83 static const unsigned char YF = 2;
84 static const unsigned char YB = 3;
85 static const unsigned char ZF = 4;
86 static const unsigned char ZB = 5;
87 static const unsigned char INVALID = 6;
89 static inline unsigned char opposite_orientation(
const unsigned char _d) {
90 return static_cast<unsigned char>(_d % 2 == 0 ? _d + 1 : _d - 1);
100 FaceHandle add_face(std::vector<HalfEdgeHandle> _halfedges,
bool _topologyCheck =
false)
override;
103 FaceHandle add_face(
const std::vector<VertexHandle>& _vertices)
override;
106 CellHandle add_cell(std::vector<HalfFaceHandle> _halffaces,
bool _topologyCheck =
false)
override;
110 bool check_halfface_ordering(
const std::vector<HalfFaceHandle>& _hfs)
const;
134 CellHandle add_cell(
const std::vector<VertexHandle>& _vertices,
bool _topologyCheck =
false);
138 friend class CellSheetCellIter;
139 friend class HalfFaceSheetHalfFaceIter;
140 friend class HexVertexIter;
142 typedef class CellSheetCellIter CellSheetCellIter;
143 typedef class HalfFaceSheetHalfFaceIter HalfFaceSheetHalfFaceIter;
144 typedef class HexVertexIter HexVertexIter;
146 using TopologyKernel::is_valid;
148 CellSheetCellIter csc_iter(
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(
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(
HalfFaceHandle _ref_h,
int _max_laps = 1)
const {
159 return HalfFaceSheetHalfFaceIter(_ref_h,
this, _max_laps);
162 std::pair<HalfFaceSheetHalfFaceIter,HalfFaceSheetHalfFaceIter> halfface_sheet_halffaces(
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(
CellHandle _ref_h,
int _max_laps = 1)
const {
169 return HexVertexIter(_ref_h,
this, _max_laps);
172 std::pair<HexVertexIter,HexVertexIter> hex_vertices(
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(is_valid(_hfh));
183 assert(is_valid(_ch));
185 if(orientation(_hfh, _ch) == XF)
return xback_halfface(_ch);
186 if(orientation(_hfh, _ch) == XB)
return xfront_halfface(_ch);
187 if(orientation(_hfh, _ch) == YF)
return yback_halfface(_ch);
188 if(orientation(_hfh, _ch) == YB)
return yfront_halfface(_ch);
189 if(orientation(_hfh, _ch) == ZF)
return zback_halfface(_ch);
190 if(orientation(_hfh, _ch) == ZB)
return zfront_halfface(_ch);
192 return TopologyKernel::InvalidHalfFaceHandle;
196 assert(is_valid(_ch));
198 return TopologyKernel::cell(_ch).halffaces()[XF];
202 assert(is_valid(_ch));
204 return TopologyKernel::cell(_ch).halffaces()[XB];
208 assert(is_valid(_ch));
210 return TopologyKernel::cell(_ch).halffaces()[YF];
214 assert(is_valid(_ch));
216 return TopologyKernel::cell(_ch).halffaces()[YB];
220 assert(is_valid(_ch));
222 return TopologyKernel::cell(_ch).halffaces()[ZF];
226 assert(is_valid(_ch));
228 return TopologyKernel::cell(_ch).halffaces()[ZB];
232 assert(is_valid(_ch));
234 std::vector<HalfFaceHandle> halffaces = TopologyKernel::cell(_ch).halffaces();
235 for(
unsigned int i = 0; i < halffaces.size(); ++i) {
236 if(halffaces[i] == _hfh)
return (
unsigned char)i;
242 static inline unsigned char orthogonal_orientation(
const unsigned char _o1,
const unsigned char _o2) {
244 if(_o1 == XF && _o2 == YF)
return ZF;
245 if(_o1 == XF && _o2 == YB)
return ZB;
246 if(_o1 == XF && _o2 == ZF)
return YB;
247 if(_o1 == XF && _o2 == ZB)
return YF;
248 if(_o1 == XB && _o2 == YF)
return ZB;
249 if(_o1 == XB && _o2 == YB)
return ZF;
250 if(_o1 == XB && _o2 == ZF)
return YF;
251 if(_o1 == XB && _o2 == ZB)
return YB;
253 if(_o1 == YF && _o2 == XF)
return ZB;
254 if(_o1 == YF && _o2 == XB)
return ZF;
255 if(_o1 == YF && _o2 == ZF)
return XF;
256 if(_o1 == YF && _o2 == ZB)
return XB;
257 if(_o1 == YB && _o2 == XF)
return ZF;
258 if(_o1 == YB && _o2 == XB)
return ZB;
259 if(_o1 == YB && _o2 == ZF)
return XB;
260 if(_o1 == YB && _o2 == ZB)
return XF;
262 if(_o1 == ZF && _o2 == YF)
return XB;
263 if(_o1 == ZF && _o2 == YB)
return XF;
264 if(_o1 == ZF && _o2 == XF)
return YF;
265 if(_o1 == ZF && _o2 == XB)
return YB;
266 if(_o1 == ZB && _o2 == YF)
return XF;
267 if(_o1 == ZB && _o2 == YB)
return XB;
268 if(_o1 == ZB && _o2 == XF)
return YB;
269 if(_o1 == ZB && _o2 == XB)
return YF;
277 if(_o == XF)
return xfront_halfface(_ch);
278 if(_o == XB)
return xback_halfface(_ch);
279 if(_o == YF)
return yfront_halfface(_ch);
280 if(_o == YB)
return yback_halfface(_ch);
281 if(_o == ZF)
return zfront_halfface(_ch);
282 if(_o == ZB)
return zback_halfface(_ch);
283 return TopologyKernel::InvalidHalfFaceHandle;
288 if(!TopologyKernel::has_face_bottom_up_incidences()) {
290 std::cerr <<
"No bottom-up incidences computed so far, could not get adjacent halfface on sheet!" << std::endl;
292 return TopologyKernel::InvalidHalfFaceHandle;
300 n_hf = TopologyKernel::adjacent_halfface_in_cell(n_hf, n_he);
301 if(n_hf == TopologyKernel::InvalidHalfFaceHandle)
break;
302 n_hf = TopologyKernel::opposite_halfface_handle(n_hf);
303 if(n_hf == TopologyKernel::InvalidHalfFaceHandle)
break;
304 n_hf = TopologyKernel::adjacent_halfface_in_cell(n_hf, n_he);
305 if(n_hf == TopologyKernel::InvalidHalfFaceHandle)
break;
309 n_hf = TopologyKernel::opposite_halfface_handle(_hfh);
310 n_he = TopologyKernel::opposite_halfedge_handle(_heh);
314 n_hf = TopologyKernel::adjacent_halfface_in_cell(n_hf, n_he);
315 if(n_hf == TopologyKernel::InvalidHalfFaceHandle)
break;
316 n_hf = TopologyKernel::opposite_halfface_handle(n_hf);
317 if(n_hf == TopologyKernel::InvalidHalfFaceHandle)
break;
318 n_hf = TopologyKernel::adjacent_halfface_in_cell(n_hf, n_he);
319 if(n_hf == TopologyKernel::InvalidHalfFaceHandle)
break;
320 else return TopologyKernel::opposite_halfface_handle(n_hf);
323 return TopologyKernel::InvalidHalfFaceHandle;
329 hehf_it.valid(); ++hehf_it) {
330 if(*hehf_it == _hfh)
continue;
331 if(TopologyKernel::is_boundary(*hehf_it)) {
334 if(TopologyKernel::is_boundary(TopologyKernel::opposite_halfface_handle(*hehf_it))) {
335 return TopologyKernel::opposite_halfface_handle(*hehf_it);
338 return TopologyKernel::InvalidHalfFaceHandle;
343 if(!TopologyKernel::has_face_bottom_up_incidences()) {
345 std::cerr <<
"No bottom-up incidences computed so far, could not get neighboring outside halfface!" << std::endl;
347 return TopologyKernel::InvalidHalfFaceHandle;
351 hehf_it; ++hehf_it) {
352 if(*hehf_it == _hfh)
continue;
353 if(TopologyKernel::is_boundary(*hehf_it))
return *hehf_it;
354 if(TopologyKernel::is_boundary(TopologyKernel::opposite_halfface_handle(*hehf_it)))
355 return TopologyKernel::opposite_halfface_handle(*hehf_it);
358 return TopologyKernel::InvalidHalfFaceHandle;
364 const std::vector<HalfFaceHandle>& _halffaces)
const;