43 #include "HexahedralMeshTopologyKernel.hh"
48 HexahedralMeshTopologyKernel::HexahedralMeshTopologyKernel() {
55 HexahedralMeshTopologyKernel::~HexahedralMeshTopologyKernel() {
64 if(_halfedges.size() != 4) {
66 std::cerr <<
"HexahedralMeshTopologyKernel::add_face(): Face valence is not four! Returning" << std::endl;
67 std::cerr <<
"invalid handle." << std::endl;
69 return TopologyKernel::InvalidFaceHandle;
81 if(_vertices.size() != 4) {
83 std::cerr <<
"HexahedralMeshTopologyKernel::add_face(): Face valence is not four! Returning" << std::endl;
84 std::cerr <<
"invalid handle." << std::endl;
86 return TopologyKernel::InvalidFaceHandle;
98 if(_halffaces.size() != 6) {
101 std::cerr <<
"Cell valence is not six! Aborting." << std::endl;
103 return TopologyKernel::InvalidCellHandle;
105 for(std::vector<HalfFaceHandle>::const_iterator it = _halffaces.begin();
106 it != _halffaces.end(); ++it) {
109 std::cerr <<
"Incident face does not have valence four! Aborting." << std::endl;
111 return TopologyKernel::InvalidCellHandle;
116 std::vector<HalfFaceHandle> ordered_halffaces;
122 bool ordered = check_halfface_ordering(_halffaces);
127 std::cerr <<
"The specified half-faces are not in correct order. Trying automatic re-ordering." << std::endl;
131 const int orderTop[] = {2, 4, 3, 5};
134 ordered_halffaces.resize(6, TopologyKernel::InvalidHalfFaceHandle);
137 ordered_halffaces[0] = _halffaces[0];
141 unsigned int idx = 0;
142 for(std::vector<HalfEdgeHandle>::const_iterator he_it = hes.begin();
143 he_it != hes.end(); ++he_it) {
145 HalfFaceHandle ahfh = get_adjacent_halfface(ordered_halffaces[0], *he_it, _halffaces);
146 if(ahfh == TopologyKernel::InvalidHalfFaceHandle) {
148 std::cerr <<
"The current halfface is invalid!" << std::endl;
152 ordered_halffaces[orderTop[idx]] = ahfh;
159 cur_hf = get_adjacent_halfface(cur_hf, cur_he, _halffaces);
160 cur_he = TopologyKernel::opposite_halfedge_handle(cur_he);
163 cur_hf = get_adjacent_halfface(cur_hf, cur_he, _halffaces);
165 if(cur_hf != TopologyKernel::InvalidHalfFaceHandle) {
166 ordered_halffaces[1] = cur_hf;
169 std::cerr <<
"The current halfface is invalid!" << std::endl;
171 return TopologyKernel::InvalidCellHandle;
176 ordered_halffaces = _halffaces;
181 ordered_halffaces = _halffaces;
189 bool HexahedralMeshTopologyKernel::check_halfface_ordering(
const std::vector<HalfFaceHandle>& _hfs)
const {
214 const int orderTop[] = {2, 4, 3, 5};
215 const int orderBot[] = {3, 4, 2, 5};
217 HalfFaceHandle hfhTop = _hfs[0];
218 HalfFaceHandle hfhBot = _hfs[1];
227 for(std::vector<HalfEdgeHandle>::const_iterator it = halfedgesTop.begin();
228 it != halfedgesTop.end(); ++it) {
230 HalfFaceHandle ahfh = get_adjacent_halfface(hfhTop, *it, _hfs);
232 if(offsetTop == -1) {
233 if(ahfh == _hfs[2]) offsetTop = 0;
234 else if(ahfh == _hfs[4]) offsetTop = 1;
235 else if(ahfh == _hfs[3]) offsetTop = 2;
236 else if(ahfh == _hfs[5]) offsetTop = 3;
238 offsetTop = (offsetTop + 1) % 4;
239 if(ahfh != _hfs[orderTop[offsetTop]]) {
241 std::cerr <<
"Faces not in right order!" << std::endl;
248 if(offsetTop == -1) {
250 std::cerr <<
"Faces not in right order!" << std::endl;
256 for(std::vector<HalfEdgeHandle>::const_iterator it = halfedgesBot.begin();
257 it != halfedgesBot.end(); ++it) {
259 HalfFaceHandle ahfh = get_adjacent_halfface(hfhBot, *it, _hfs);
261 if(offsetBot == -1) {
262 if(ahfh == _hfs[3]) offsetBot = 0;
263 else if(ahfh == _hfs[4]) offsetBot = 1;
264 else if(ahfh == _hfs[2]) offsetBot = 2;
265 else if(ahfh == _hfs[5]) offsetBot = 3;
267 offsetBot = (offsetBot + 1) % 4;
268 if(ahfh != _hfs[orderBot[offsetBot]]) {
270 std::cerr <<
"Faces not in right order!" << std::endl;
277 if(offsetBot == -1) {
279 std::cerr <<
"Faces not in right order!" << std::endl;
293 assert(TopologyKernel::has_full_bottom_up_incidences());
294 assert(_vertices.size() == 8);
297 if(!TopologyKernel::has_full_bottom_up_incidences()) {
301 if(_vertices.size() != 8) {
307 std::vector<VertexHandle> vs;
310 vs.push_back(_vertices[3]);
311 vs.push_back(_vertices[2]);
312 vs.push_back(_vertices[1]);
313 vs.push_back(_vertices[0]);
317 vs.push_back(_vertices[7]);
318 vs.push_back(_vertices[6]);
319 vs.push_back(_vertices[5]);
320 vs.push_back(_vertices[4]);
324 vs.push_back(_vertices[1]);
325 vs.push_back(_vertices[2]);
326 vs.push_back(_vertices[6]);
327 vs.push_back(_vertices[7]);
331 vs.push_back(_vertices[4]);
332 vs.push_back(_vertices[5]);
333 vs.push_back(_vertices[3]);
334 vs.push_back(_vertices[0]);
338 vs.push_back(_vertices[1]);
339 vs.push_back(_vertices[7]);
340 vs.push_back(_vertices[4]);
341 vs.push_back(_vertices[0]);
345 vs.push_back(_vertices[2]);
346 vs.push_back(_vertices[3]);
347 vs.push_back(_vertices[5]);
348 vs.push_back(_vertices[6]);
351 if(!hf0.is_valid()) {
354 vs.push_back(_vertices[3]); vs.push_back(_vertices[2]);
355 vs.push_back(_vertices[1]); vs.push_back(_vertices[0]);
360 if(!hf1.is_valid()) {
363 vs.push_back(_vertices[7]); vs.push_back(_vertices[6]);
364 vs.push_back(_vertices[5]); vs.push_back(_vertices[4]);
369 if(!hf2.is_valid()) {
372 vs.push_back(_vertices[1]); vs.push_back(_vertices[2]);
373 vs.push_back(_vertices[6]); vs.push_back(_vertices[7]);
378 if(!hf3.is_valid()) {
381 vs.push_back(_vertices[4]); vs.push_back(_vertices[5]);
382 vs.push_back(_vertices[3]); vs.push_back(_vertices[0]);
387 if(!hf4.is_valid()) {
390 vs.push_back(_vertices[1]); vs.push_back(_vertices[7]);
391 vs.push_back(_vertices[4]); vs.push_back(_vertices[0]);
396 if(!hf5.is_valid()) {
399 vs.push_back(_vertices[2]); vs.push_back(_vertices[3]);
400 vs.push_back(_vertices[5]); vs.push_back(_vertices[6]);
405 assert(hf0.is_valid()); assert(hf1.is_valid()); assert(hf2.is_valid());
406 assert(hf3.is_valid()); assert(hf4.is_valid()); assert(hf5.is_valid());
409 std::vector<HalfFaceHandle> hfs;
410 hfs.push_back(hf0); hfs.push_back(hf1); hfs.push_back(hf2);
411 hfs.push_back(hf3); hfs.push_back(hf4); hfs.push_back(hf5);
413 if (_topologyCheck) {
422 std::set<HalfEdgeHandle> incidentHalfedges;
423 std::set<EdgeHandle> incidentEdges;
425 for(std::vector<HalfFaceHandle>::const_iterator it = hfs.begin(),
426 end = hfs.end(); it != end; ++it) {
429 for(std::vector<HalfEdgeHandle>::const_iterator he_it = hface.halfedges().begin(),
430 he_end = hface.halfedges().end(); he_it != he_end; ++he_it) {
431 incidentHalfedges.insert(*he_it);
436 if(incidentHalfedges.size() != (incidentEdges.size() * 2u)) {
438 std::cerr <<
"The specified halffaces are not connected!" << std::endl;
440 return InvalidCellHandle;
444 if(has_face_bottom_up_incidences()) {
446 for(std::vector<HalfFaceHandle>::const_iterator it = hfs.begin(),
447 end = hfs.end(); it != end; ++it) {
450 std::cerr <<
"Warning: One of the specified half-faces is already incident to another cell!" << std::endl;
452 return InvalidCellHandle;
467 const std::vector<HalfFaceHandle>& _halffaces)
const {
471 HalfEdgeHandle o_he = TopologyKernel::opposite_halfedge_handle(_heh);
473 for(std::vector<HalfFaceHandle>::const_iterator it = _halffaces.begin();
474 it != _halffaces.end(); ++it) {
475 if(*it == _hfh)
continue;
477 for(std::vector<HalfEdgeHandle>::const_iterator h_it = halfedges.begin();
478 h_it != halfedges.end(); ++h_it) {
479 if(*h_it == o_he)
return *it;
483 return TopologyKernel::InvalidHalfFaceHandle;
virtual CellHandle add_cell(const std::vector< HalfFaceHandle > &_halffaces, bool _topologyCheck=false)
Overridden function.
CellHandle incident_cell(const HalfFaceHandle &_halfFaceHandle) const
Get cell that is incident to the given halfface.
virtual CellHandle add_cell(const std::vector< HalfFaceHandle > &_halffaces, bool _topologyCheck=false)
Add cell via incident halffaces.
virtual FaceHandle add_face(const std::vector< HalfEdgeHandle > &_halfedges, bool _topologyCheck=false)
Add face via incident edges.
Face halfface(const HalfFaceHandle &_halfFaceHandle) const
Get face that corresponds to halfface with handle _halfFaceHandle.
HalfFaceHandle halfface_extensive(const std::vector< VertexHandle > &_vs) const
static HalfFaceHandle halfface_handle(const FaceHandle &_h, const unsigned char _subIdx)
Conversion function.
static EdgeHandle edge_handle(const HalfEdgeHandle &_h)
Handle conversion.
virtual FaceHandle add_face(const std::vector< HalfEdgeHandle > &_halfedges, bool _topologyCheck=false)
Add face via incident edges.
HalfEdgeHandle next_halfedge_in_halfface(const HalfEdgeHandle &_heh, const HalfFaceHandle &_hfh) const
Get next halfedge within a halfface.