namespace CGoGN { namespace Algo { namespace Topo { // private function template void reverse2MapFaceKeepPhi2(MAP& map, Dart d) { unsigned int first = map.template getEmbedding(d); Dart e=d; do { Dart f=map.phi1(e); unsigned int emb = map.template getEmbedding(f); map.template setDartEmbedding(e,emb); e =f; }while (e!=d); map.template setDartEmbedding(map.phi_1(d),first); map.reverseCycle(d); } // private function inline Dart findOtherInCouplesOfDarts(const std::vector& couples, Dart d) { unsigned int nb = couples.size(); for (unsigned int i=0; i void uniformOrientationCC(MAP& map, Dart faceSeed) { // first bufferize boundary edges std::vector boundEdges; TraversorE travEdge(map); for (Dart d=travEdge.begin(); d!= travEdge.end(); d = travEdge.next()) { if (map.isBoundaryEdge(d)) boundEdges.push_back(d); } // store couple of boundary edges the have same embedding std::vector couples; int nb = boundEdges.size(); int nbm = nb-1; for (int i=0; i< nbm; ++i) { if (boundEdges[i] != NIL) { for (int j=i+1; j< nb; ++j) { if (boundEdges[j] != NIL) { Dart d = boundEdges[i]; Dart d1 = map.phi1(d); Dart e = boundEdges[j]; Dart e1 = map.phi1(e); if ((map.template getEmbedding(d) == map.template getEmbedding(e)) && (map.template getEmbedding(d1) == map.template getEmbedding(e1))) { couples.push_back(d); couples.push_back(e); boundEdges[j] = NIL; // not using the dart again j=nb; // out of the loop } } } } } // vector of front propagation for good orientation std::vector propag; boundEdges.clear(); propag.swap(boundEdges);// reused memory of boundEdges // vector of front propagation for wrong orientation std::vector propag_inv; //vector of faces to invert std::vector face2invert; // optimize memory reserve propag_inv.reserve(1024); face2invert.reserve(1024); DartMarker cmf(map); cmf.template markOrbit(faceSeed); propag.push_back(faceSeed); while (!propag.empty() || !propag_inv.empty()) { if (!propag.empty()) { Dart f = propag.back(); propag.pop_back(); Dart d = f; do { Dart e = map.phi2(d); if (map.template isBoundaryMarked<2>(e)) { e = findOtherInCouplesOfDarts(couples,d); if (e!=NIL) { if (!cmf.isMarked(e)) { propag_inv.push_back(e); face2invert.push_back(e); cmf.template markOrbit(e); } cmf.mark(map.phi2(e));// use cmf also to mark boudary cycle to invert } } else { if (!cmf.isMarked(e)) { propag.push_back(e); cmf.template markOrbit(e); } } d= map.phi1(d); } while (d!=f); } if (!propag_inv.empty()) { Dart f = propag_inv.back(); propag_inv.pop_back(); Dart d = f; do { Dart e = map.phi2(d); if (map.template isBoundaryMarked<2>(e)) { e = findOtherInCouplesOfDarts(couples,d); if (e!=NIL) { if (!cmf.isMarked(e)) { propag.push_back(e); cmf.template markOrbit(e); } cmf.mark(map.phi2(d));// use cmf also to mark boudary cycle to invert } } else { if (!cmf.isMarked(e)) { propag_inv.push_back(e); face2invert.push_back(e); cmf.template markOrbit(e); } } d= map.phi1(d); // traverse all edges of face } while (d!=f); } } // reverse all faces of the wrong orientation for (std::vector::iterator id=face2invert.begin(); id!=face2invert.end(); ++id) reverse2MapFaceKeepPhi2(map,*id); // reverse the boundary cycles that bound reverse faces for (std::vector::iterator id=couples.begin(); id!=couples.end(); ++id) { Dart e = map.phi2(*id); if (cmf.isMarked(e)) // check cmf for wrong orientation { reverse2MapFaceKeepPhi2(map,e); cmf.template unmarkOrbit(e); } } // sew the faces that correspond to couples of boundary edges for (std::vector::iterator id=couples.begin(); id!=couples.end(); ++id)// second ++ inside ! { Dart d = *id++; Dart e = *id; if (cmf.isMarked(d) || cmf.isMarked(e)) map.sewFaces(d,e); } } } // namespace Topo } // namespace Algo } // namespace CGoGN