38 if(gf->
edges().empty())
return false;
42 if(gr->
faces().empty())
return false;
50 std::vector<GEdge *> _all;
51 std::set<MLine *> _lines;
52 std::map<MVertex *, std::pair<MLine *, MLine *> > _conn;
57 for(std::size_t i = 0; i < ge->
lines.size(); i++) {
58 _lines.insert(ge->
lines[i]);
59 for(
int j = 0; j < 2; j++) {
60 auto it = _conn.find(ge->
lines[i]->getVertex(j));
62 _conn[ge->
lines[i]->getVertex(j)] =
63 std::make_pair(ge->
lines[i], (
MLine *)
nullptr);
65 it->second.second = ge->
lines[i];
69 std::vector<std::vector<MLine *> > _parts;
70 while(!_lines.empty()) {
71 std::stack<MLine *> _stack;
72 _stack.push(*_lines.begin());
73 std::vector<MLine *> _part;
74 while(!_stack.empty()) {
75 MLine *l = _stack.top();
79 if(!_part.size() || _part[_part.size() - 1] != l) { _part.push_back(l); }
80 for(
int j = 0; j < 2; j++) {
82 if(it->second.first == l && it->second.second !=
nullptr &&
83 _lines.find(it->second.second) != _lines.end()) {
84 _stack.push(it->second.second);
86 else if(it->second.second == l &&
87 _lines.find(it->second.first) != _lines.end()) {
88 _stack.push(it->second.first);
92 _parts.push_back(_part);
98 else if(_parts.size() > 1) {
99 Msg::Info(
"Curve %d is not simply connected: splitting it in %d parts",
100 ge->
tag(), _parts.size());
103 for(
size_t i = 0; i < _parts.size(); i++) {
105 ge->
lines = _parts[i];
111 newE->
lines = _parts[i];
112 _all.push_back(newE);
122 for(
auto it = _f.begin(); it != _f.end(); ++it) {
123 if((*it)->getNumVertices() == 3)
125 else if((*it)->getNumVertices() == 4)
132 std::map<MEdge, std::pair<MElement *, MElement *>,
MEdgeLessThan> _pairs;
133 std::set<MEdge, MEdgeLessThan> _nonManifold;
135 std::set<MElement *> _allFaces;
142 if(_nonManifold.find(ed) == _nonManifold.end()) {
143 auto it = _pairs.find(ed);
144 if(it == _pairs.end()) {
145 _pairs[ed] = std::make_pair(e, (
MElement *)
nullptr);
148 if(it->second.second ==
nullptr) { it->second.second = e; }
150 _nonManifold.insert(ed);
157 if(_nonManifold.empty())
return;
159 std::vector<std::set<MElement *> > _sub;
160 while(!_allFaces.empty()) {
161 std::stack<MElement *> _stack;
162 _stack.push(*_allFaces.begin());
163 std::set<MElement *> _f;
164 while(!_stack.empty()) {
171 if(_nonManifold.find(ed) == _nonManifold.end()) {
172 auto it = _pairs.find(ed);
173 if(it->second.second !=
nullptr) {
175 it->second.second == e ? it->second.first : it->second.second;
176 if(_f.find(other) == _f.end()) _stack.push(other);
184 Msg::Info(
"Surface %d is non-manifold: splitting it in %d parts", gf->
tag(),
187 for(std::size_t i = 0; i < _sub.size(); i++) {
201 std::vector<GFace *>
f;
221 mVertexToGVertex[mv] = gv;
222 Msg::Debug(
"The model already has point %i, containing node %i",
235 for(std::size_t i = 0; i < (*it)->lines.size(); i++) {
236 MLine *e = (*it)->lines[i];
237 for(
int j = 0; j < 2; j++) {
239 auto gIter = mVertexToGVertex.find(mv);
240 if(gIter != mVertexToGVertex.end())
241 gEdgeToGVertices[ge].insert(gIter->second);
243 auto it = mVertexToGEdges.find(mv);
244 if(it != mVertexToGEdges.end() &&
245 it->second.find(ge) != it->second.end()) {
247 mVertexToGEdges.erase(it);
250 mVertexToGEdges[mv].insert(ge);
259 for(
auto mvIter = mVertexToGEdges.begin(); mvIter != mVertexToGEdges.end();
262 std::set<GEdge *> &gEdges = mvIter->second;
267 mVertexToGVertex[mv] = dv;
270 for(
auto gEIter = gEdges.begin(); gEIter != gEdges.end(); ++gEIter) {
272 gEdgeToGVertices[ge].insert(dv);
279 for(
auto gEIter = gEdgeToGVertices.begin(); gEIter != gEdgeToGVertices.end();
281 GEdge *ge = gEIter->first;
282 std::set<GVertex *> gVerts = gEIter->second;
284 if(gVerts.size() == 2) {
285 GVertex *gv1 = *(gVerts.begin());
286 GVertex *gv2 = *(gVerts.rbegin());
296 if(splits.size() == 1) {
297 GVertex *gv1 = *(gVerts.begin());
303 std::ostringstream gVertexList;
304 for(
auto gvIter = gVerts.begin(); gvIter != gVerts.end(); ++gvIter) {
305 gVertexList <<
" " << (*gvIter)->tag();
308 "Found single/multiply ended GEdge %i in model (GVertices:%s)",
309 ge->
tag(), gVertexList.str().c_str());
318 if(!(*it)->getBeginVertex() || !(*it)->getEndVertex()) {
320 MVertex *v = (*it)->lines[0]->getVertex(0);
327 (*it)->setBeginVertex(dv);
328 (*it)->setEndVertex(dv);
329 gEdgeToGVertices[*it].insert(dv);
377 for(std::size_t i = 0; i < (*it)->lines.size(); i++) {
379 tEdgeToGEdge[te] = ge;
390 for(std::size_t i = 0; i < (*it)->getNumMeshElements(); i++) {
391 MElement *e = (*it)->getMeshElement(i);
395 auto eIter = tEdgeToGEdge.find(te);
396 if(eIter != tEdgeToGEdge.end())
397 gFaceToGEdges[gf].insert(eIter->second);
399 auto it = tEdgeToGFaces.find(te);
400 if(it != tEdgeToGFaces.end() &&
401 it->second.find(gf) != it->second.end()) {
403 tEdgeToGFaces.erase(it);
406 tEdgeToGFaces[te].insert(gf);
419 for(
auto it = tEdgeToGFaces.begin(); it != tEdgeToGFaces.end(); ++it) {
420 std::set<GFace *> &gfaces = it->second;
421 auto gfIter = gFacesToGEdge.find(gfaces);
422 if(gfIter == gFacesToGEdge.end()) {
427 auto gfIter = gfaces.begin();
428 for(; gfIter != gfaces.end(); ++gfIter) gFaceToGEdges[*gfIter].insert(de);
429 gFacesToGEdge[gfaces] = de;
437 for(
auto it = tEdgeToGFaces.begin(); it != tEdgeToGFaces.end(); ++it) {
439 std::set<GFace *> &gfaces = it->second;
441 auto gfIter = gFacesToGEdge.find(gfaces);
443 if(gfIter != gFacesToGEdge.end()) {
444 GEdge *ge = gfIter->second;
449 std::vector<MVertex *> vtcs;
460 ge->
lines.push_back(edge);
464 std::map<GEdge *, std::vector<GEdge *> > splitEdge;
467 if(split.size() != 1) splitEdge[*it] = split;
472 for(
auto gfToge = gFaceToGEdges.begin(); gfToge != gFaceToGEdges.end();
474 std::set<GEdge *> &edgeSet = gfToge->second;
475 std::set<GEdge *> newEdgeSet;
476 auto eIter = edgeSet.begin();
477 for(; eIter != edgeSet.end(); ++eIter) {
478 auto pIter = splitEdge.find(*eIter);
479 if(pIter != splitEdge.end()) {
480 std::vector<GEdge *> &
edges = pIter->second;
481 newEdgeSet.insert(
edges.begin(),
edges.end());
484 edgeSet.insert(newEdgeSet.begin(), newEdgeSet.end());
489 for(
auto gfToge = gFaceToGEdges.begin(); gfToge != gFaceToGEdges.end();
491 GFace *gf = gfToge->first;
492 std::set<GEdge *> &gEdgeSet = gfToge->second;
494 std::vector<GEdge *> gEdges;
495 gEdges.insert(gEdges.begin(), gEdgeSet.begin(), gEdgeSet.end());
498 auto eIter = gEdgeSet.begin();
499 for(; eIter != gEdgeSet.end(); eIter++) (*eIter)->addFace(gf);
516 switch(
vtcs.size()) {
531 std::vector<MVertex *> tmp;
541 typedef std::map<topoFace, std::pair<GRegion *, GRegion *> >
545 typedef std::map<std::pair<GRegion *, GRegion *>,
GFace *>
554 for(
unsigned i = 0; i < (*it)->triangles.size(); i++) {
555 topoFace tf((*it)->triangles[i], 0);
556 tFaceToGFace.insert(std::make_pair(tf, *it));
558 for(
unsigned i = 0; i < (*it)->quadrangles.size(); i++) {
559 topoFace tf((*it)->quadrangles[i], 0);
560 tFaceToGFace.insert(std::make_pair(tf, *it));
576 auto ffIter = tFaceToGFace.find(
f);
577 if(ffIter != tFaceToGFace.end())
578 gRegionToGFaces[gr].insert(ffIter->second);
580 auto frIter = tFaceToGRegionPair.find(
f);
581 if(frIter == tFaceToGRegionPair.end()) {
582 tFaceToGRegionPair[
f] = std::make_pair((
GRegion *)
nullptr, *it);
585 frIter->second.first = gr;
595 auto it = tFaceToGRegionPair.begin();
596 for(; it != tFaceToGRegionPair.end(); ++it) {
597 GRegion *r1 = it->second.first;
598 GRegion *r2 = it->second.second;
600 std::pair<GRegion *, GRegion *> gRegionPair;
602 gRegionPair = std::make_pair(std::min(r1, r2), std::max(r1, r2));
604 gRegionPair = std::make_pair(r1, r2);
605 auto iter = gRegionPairToGFace.find(gRegionPair);
606 if(iter == gRegionPairToGFace.end()) {
611 if(r1) gRegionToGFaces[r1].insert(
df);
612 if(r2) gRegionToGFaces[r2].insert(
df);
613 gRegionPairToGFace[gRegionPair] =
df;
621 for(it = tFaceToGRegionPair.begin(); it != tFaceToGRegionPair.end(); ++it) {
623 std::pair<GRegion *, GRegion *> grPair = it->second;
625 auto grTogfIter = gRegionPairToGFace.find(grPair);
627 if(grTogfIter != gRegionPairToGFace.end()) {
628 GFace *gf = grTogfIter->second;
633 std::vector<MVertex *> vtcs;
652 auto itTo = gRegionToGFaces.begin();
653 for(; itTo != gRegionToGFaces.end(); ++itTo) {
655 std::vector<GFace *>
faces;
656 faces.insert(
faces.begin(), itTo->second.begin(), itTo->second.end());
658 for(
auto it3 =
faces.begin(); it3 !=
faces.end(); ++it3)
659 (*it3)->addRegion(itTo->first);
666 Msg::Info(
"Topology exists: no need to create one from mesh");
673 Msg::Info(
"Creating topology from mesh...");
674 int numF = 0, numE = 0, numV = 0;
687 Msg::Info(
"Done creating topology from mesh (Wall %gs, CPU %gs)", w2 -
w1,