diff --git a/Fltk/classificationEditor.cpp b/Fltk/classificationEditor.cpp index d9ea4825c6beb185133665d5c6fa0f4692ae5c84..d61c69ee0fe5e2fe8a1a8d8e8b7764e9cfe60f48 100644 --- a/Fltk/classificationEditor.cpp +++ b/Fltk/classificationEditor.cpp @@ -19,6 +19,18 @@ #include "discreteEdge.h" #include "discreteFace.h" +extern GEdge *getNewModelEdge(GFace *gf1, GFace *gf2, + std::map<std::pair<int, int>, GEdge*> &newEdges); + +extern void recurClassifyEdges(MTri3 *t, std::map<MTriangle*, GFace*> &reverse, + std::map<MLine*, GEdge*, compareMLinePtr> &lines, + std::set<MLine*> &touched, std::set<MTri3*> &trisTouched, + std::map<std::pair<int, int>, GEdge*> &newEdges); + +extern void recurClassify(MTri3 *t, GFace *gf, + std::map<MLine*, GEdge*, compareMLinePtr> &lines, + std::map<MTriangle*, GFace*> &reverse); + static void NoElementsSelectedMode(classificationEditor *e) { e->buttons[CLASS_BUTTON_SELECT_ELEMENTS]->activate(); @@ -207,7 +219,7 @@ static void delete_edge_cb(Fl_Widget *w, void *data) std::sort(ele.begin(), ele.end()); - // look in all selected edges if a deleted one is present and delete it + // look in all selected edges if a deleted one is present and delete it std::vector<MLine*> temp = e->selected->lines; e->selected->lines.clear(); for(unsigned int i = 0; i < temp.size(); i++){ @@ -290,8 +302,119 @@ static void select_surfaces_cb(Fl_Widget *w, void *data) static void classify_cb(Fl_Widget *w, void *data) { classificationEditor *e = (classificationEditor*)data; - // classify faces with respect to coloured edges - GModel::current()->classifyFaces(e->faces); + std::map<MLine*, GEdge*, compareMLinePtr> lines; + for(GModel::eiter it = GModel::current()->firstEdge(); + it != GModel::current()->lastEdge(); ++it){ + for(unsigned int i = 0; i < (*it)->lines.size();i++) + lines[(*it)->lines[i]] = *it; + } + + std::list<MTri3*> tris; + { + std::set<GFace*>::iterator it = e->faces.begin(); + while(it != e->faces.end()){ + GFace *gf = *it; + for(unsigned int i = 0; i < gf->triangles.size(); i++) + tris.push_back(new MTri3(gf->triangles[i], 0)); + gf->triangles.clear(); + ++it; + } + } + if(tris.empty()) return; + + connectTriangles(tris); + + std::map<MTriangle*, GFace*> reverse; + // color all triangles + std::list<MTri3*> ::iterator it = tris.begin(); + while(it != tris.end()){ + if(!(*it)->isDeleted()){ + discreteFace *gf = new discreteFace + (GModel::current(), GModel::current()->getMaxElementaryNumber(2) + 1); + recurClassify(*it, gf, lines, reverse); + GModel::current()->add(gf); + } + ++it; + } + + // color some lines + it = tris.begin(); + while(it != tris.end()){ + (*it)->setDeleted(false); + ++it; + } + + it = tris.begin(); + + // classify edges that are bound by different GFaces + std::map<std::pair<int, int>, GEdge*> newEdges; + std::set<MLine*> touched; + std::set<MTri3*> tritouched; + recurClassifyEdges(*it, reverse, lines, touched, tritouched, newEdges); + + // check if new edges should not be splitted + // splitted if composed of several open or closed edges + for (std::map<std::pair<int, int>, GEdge*>::iterator it = newEdges.begin(); + it != newEdges.end() ; ++it){ + std::list<MLine*> segments; + for(unsigned int i = 0; i < it->second->lines.size(); i++) + segments.push_back(it->second->lines[i]); + while (!segments.empty()) { + std::vector<MLine*> myLines; + std::list<MLine*>::iterator it = segments.begin(); + MVertex *vB = (*it)->getVertex(0); + MVertex *vE = (*it)->getVertex(1); + myLines.push_back(*it); + segments.erase(it); + it++; + for (int i = 0; i < 2; i++) { + for (std::list<MLine*>::iterator it = segments.begin(); + it != segments.end(); ++it){ + MVertex *v1 = (*it)->getVertex(0); + MVertex *v2 = (*it)->getVertex(1); + std::list<MLine*>::iterator itp; + if (v1 == vE){ + myLines.push_back(*it); + itp = it; + it++; + segments.erase(itp); + vE = v2; + i = -1; + } + else if ( v2 == vE){ + myLines.push_back(*it); + itp = it; + it++; + segments.erase(itp); + vE = v1; + i = -1; + } + if (it == segments.end()) break; + } + if (vB == vE) break; + if (segments.empty()) break; + MVertex *temp = vB; + vB = vE; + vE = temp; + } + GEdge *newGe = new discreteEdge + (GModel::current(), GModel::current()->getMaxElementaryNumber(1) + 1, 0, 0); + newGe->lines.insert(newGe->lines.end(), myLines.begin(), myLines.end()); + GModel::current()->add(newGe); + } + } + + for (std::map<std::pair<int, int>, GEdge*>::iterator it = newEdges.begin(); + it != newEdges.end(); ++it){ + GEdge *ge = it->second; + GModel::current()->remove(ge); + } + + while(it != tris.end()){ + delete *it; + ++it; + } + // remove selected, but do not delete its elements if(e->selected){ GModel::current()->remove(e->selected); diff --git a/Fltk/partitionDialog.cpp b/Fltk/partitionDialog.cpp index ffa8a12f5c4755f2357dbb891ec7c8e0f0f028fe..1e2464bea5cb77f45c003552d49fe81cc8b539eb 100644 --- a/Fltk/partitionDialog.cpp +++ b/Fltk/partitionDialog.cpp @@ -491,7 +491,7 @@ void partition_dialog() int y = 0; dlg.window = new paletteWindow - (w, h, CTX::instance()->nonModalWindows ? true : false, "Partitioner Options"); + (w, h, CTX::instance()->nonModalWindows ? true : false, "Partition"); dlg.window->box(GMSH_WINDOW_BOX); dlg.window->callback((Fl_Callback *)partition_cancel_cb, &dlg); diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp index 7b4b0deb4545f6b5a784c0fd7f3024e01622dd47..2cf1873b1d3b26d3b84d9ce83e85d3008fc2e007 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -1997,16 +1997,8 @@ void GModel::insertRegion(GRegion *r) // given a set of mesh edges, build GFaces that separate those // edges. -struct compareMLinePtr { - bool operator () (MLine *l1, MLine *l2) const - { - static Less_Edge le; - return le(l1->getEdge(0), l2->getEdge(0)); - } -}; - -static GEdge *getNewModelEdge(GFace *gf1, GFace *gf2, - std::map<std::pair<int, int>, GEdge*> &newEdges) +GEdge *getNewModelEdge(GFace *gf1, GFace *gf2, + std::map<std::pair<int, int>, GEdge*> &newEdges) { int t1 = gf1 ? gf1->tag() : -1; int t2 = gf2 ? gf2->tag() : -1; @@ -2028,12 +2020,10 @@ static GEdge *getNewModelEdge(GFace *gf1, GFace *gf2, return it->second; } -static void recurClassifyEdges(MTri3 *t, - std::map<MTriangle*, GFace*> &reverse, - std::map<MLine*, GEdge*, compareMLinePtr> &lines, - std::set<MLine*> &touched, - std::set<MTri3*> &trisTouched, - std::map<std::pair<int, int>, GEdge*> &newEdges) +void recurClassifyEdges(MTri3 *t, std::map<MTriangle*, GFace*> &reverse, + std::map<MLine*, GEdge*, compareMLinePtr> &lines, + std::set<MLine*> &touched, std::set<MTri3*> &trisTouched, + std::map<std::pair<int, int>, GEdge*> &newEdges) { if(!t->isDeleted()){ trisTouched.erase(t); @@ -2060,9 +2050,9 @@ static void recurClassifyEdges(MTri3 *t, } } -static void recurClassify(MTri3 *t, GFace *gf, - std::map<MLine*, GEdge*, compareMLinePtr> &lines, - std::map<MTriangle*, GFace*> &reverse) +void recurClassify(MTri3 *t, GFace *gf, + std::map<MLine*, GEdge*, compareMLinePtr> &lines, + std::map<MTriangle*, GFace*> &reverse) { if(!t->isDeleted()){ gf->triangles.push_back(t->tri()); @@ -2196,8 +2186,6 @@ void GModel::classifyFaces(std::set<GFace*> &_faces) while(!trisTouched.empty()) recurClassifyEdges(*trisTouched.begin(), reverse, lines, touched, trisTouched,newEdges); - // printf("%d new edges\n",newEdges.size()); - std::map<discreteFace*,std::vector<int> > newFaceTopology; // check if new edges should not be splitted diff --git a/Geo/MLine.h b/Geo/MLine.h index 0f66d608b13fbb8a17b6e048e0aa8bcbb2f2d1f8..d7eb030499a3df73c5403cf5328abaf4f853e508 100644 --- a/Geo/MLine.h +++ b/Geo/MLine.h @@ -193,4 +193,12 @@ class MLineN : public MLine { } }; +struct compareMLinePtr { + bool operator () (MLine *l1, MLine *l2) const + { + static Less_Edge le; + return le(l1->getEdge(0), l2->getEdge(0)); + } +}; + #endif