diff --git a/Fltk/GUI_Classifier.cpp b/Fltk/GUI_Classifier.cpp index e157eda55fc5451d39d8c8ea94456f8f5f78f223..3c4a5ce87f88da83f8898ff92fefe09acf5c79a5 100644 --- a/Fltk/GUI_Classifier.cpp +++ b/Fltk/GUI_Classifier.cpp @@ -18,6 +18,36 @@ extern Context_T CTX; void buildListOfEdgeAngle ( e2t_cont adj,std::vector<edge_angle> &edges_detected,std::vector<edge_angle> &edges_lonly); +void NoElementsSelectedMode (classificationEditor *e) +{ + e->_buttons[CLASSBUTTON_DEL]->deactivate(); + e->_buttons[CLASSBUTTON_ADD]->deactivate(); + e->_buttons[CLASSBUTTON_CLEAR]->deactivate(); + // e->_buttons[CLASSBUTTON_OK]->deactivate(); + e->_togbuttons[CLASSTOGBUTTON_CLOS]->deactivate(); + e->_inputs[CLASSVALUE_ANGLE]->deactivate(); + + e->_buttons[CLASSBUTTON_SELECT]->activate(); + e->_togbuttons[CLASSTOGBUTTON_HIDE]->activate(); + +} + +void ElementsSelectedMode (classificationEditor *e) +{ + + e->_buttons[CLASSBUTTON_DEL]->activate(); + e->_buttons[CLASSBUTTON_ADD]->activate(); + e->_buttons[CLASSBUTTON_CLEAR]->activate(); + e->_togbuttons[CLASSTOGBUTTON_CLOS]->activate(); + e->_inputs[CLASSVALUE_ANGLE]->activate(); + // e->_buttons[CLASSBUTTON_OK]->activate(); + + e->_buttons[CLASSBUTTON_SELECT]->deactivate(); + e->_togbuttons[CLASSTOGBUTTON_HIDE]->deactivate(); +} + + + int maxEdgeNum () { GModel::eiter it = GModel::current()->firstEdge(); @@ -56,13 +86,15 @@ struct compareMLinePtr void recurClassify ( MTri3 *t , - std::vector<MTriangle *> &triangles, + GFace *gf, std::map<MLine*, GEdge*, compareMLinePtr> &lines, - std::set<GEdge*> &closure) + std::map<MTriangle*, GFace*> &reverse) { if (!t->isDeleted()) { - triangles.push_back(t->tri()); + gf->triangles.push_back(t->tri()); + reverse[t->tri()] = gf; + t->setDeleted ( true ); for (int i=0;i<3;i++) @@ -74,10 +106,68 @@ void recurClassify ( MTri3 *t , MLine ml (exf.v[0],exf.v[1]); std::map<MLine*, GEdge*, compareMLinePtr>::iterator it = lines.find(&ml); if (it==lines.end()) - recurClassify (tn, triangles,lines, closure); - else - closure.insert(it->second); + recurClassify (tn, gf,lines, reverse); + } + } + } +} + + +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; + int i1 = std::min(t1,t2); + int i2 = std::max(t1,t2); + + if (i1 == i2) return 0; + + std::map< std::pair <int, int> , GEdge* >::iterator it = newEdges.find(std::make_pair<int,int>(i1,i2)); + if (it == newEdges.end()) + { + gmshEdge *temporary = new gmshEdge ( GModel::current(), maxEdgeNum() + 1); + GModel::current()->add (temporary); + newEdges[std::make_pair<int,int>(i1,i2)] = temporary; + + return temporary; + } + else + return it->second; +} + + +void recurClassifyEdges ( MTri3 *t , + std::map<MTriangle*, GFace*> &reverse, + std::map<MLine*, GEdge*, compareMLinePtr> &lines, + std::set<MLine*> &touched, + std::map< std::pair <int, int> , GEdge* > &newEdges) +{ + if (!t->isDeleted()) + { + t->setDeleted ( true ); + + GFace *gf1 = reverse[t->tri()]; + for (int i=0;i<3;i++) + { + GFace *gf2 = 0; + MTri3 *tn = t->getNeigh(i); + if (tn) + gf2 = reverse[tn->tri()]; + + edgeXface exf ( t, i); + MLine ml (exf.v[0],exf.v[1]); + std::map<MLine*, GEdge*, compareMLinePtr>::iterator it = lines.find(&ml); + if (it != lines.end()) + { + if (touched.find(it->first) == touched.end()) + { + GEdge *ge = getNewModelEdge (gf1, gf2, newEdges); + if (ge) ge->lines.push_back(it->first); + touched.insert(it->first); + } } + if (tn) + recurClassifyEdges (tn, reverse,lines, touched,newEdges); } } } @@ -117,22 +207,36 @@ void class_color_cb(Fl_Widget* w, void* data) connectTriangles (tris); { + std::map<MTriangle*,GFace*> reverse; + + // color all triangles std::list<MTri3*> ::iterator it = tris.begin(); while (it != tris.end()) { if (!(*it)->isDeleted()) { - std::set<GEdge*> closure; - std::vector<MTriangle*> triangles; gmshFace *temporary = new gmshFace ( GModel::current(), maxFaceNum() + 1); - recurClassify ( *it , temporary->triangles,lines, closure); + recurClassify ( *it , temporary,lines, reverse); GModel::current()->add (temporary); - e->tempFaces.push_back(temporary); } ++it; } + // color some lines it = tris.begin(); + while (it != tris.end()) + { + (*it)->setDeleted(false); + ++it; + } + + it = tris.begin(); + + std::map< std::pair <int, int> , GEdge* > newEdges; + std::set< MLine* > touched; + recurClassifyEdges ( *it , reverse , lines, touched,newEdges); + GModel::current()->remove(e->saved); + while (it != tris.end()) { delete *it; @@ -236,6 +340,17 @@ void buildListOfEdgeAngle ( e2t_cont adj,std::vector<edge_angle> &edges_detected classificationEditor::classificationEditor() { + op[0]=opt_mesh_lines(0, GMSH_GET, 0.); + op[1]=opt_mesh_surfaces_edges(0, GMSH_GET, 0.); + op[2]=opt_mesh_surfaces_faces(0, GMSH_GET, 0.); + op[3]=opt_mesh_line_width(0, GMSH_SET | GMSH_GET,0.); + + opt_mesh_lines(0, GMSH_SET | GMSH_GUI, 1); + opt_mesh_surfaces_edges(0, GMSH_SET | GMSH_GUI, 0); + opt_mesh_surfaces_faces(0, GMSH_SET | GMSH_GUI, 1); + opt_mesh_line_width(0, GMSH_SET | GMSH_GUI, 1.5); + + // construct GUI in terms of standard sizes const int BH = 2 * GetFontSize() + 1, BB = 12 * GetFontSize(), WB = 7; const int width = (int)(3.5 * BB), height = 10 * BH; @@ -245,9 +360,14 @@ classificationEditor::classificationEditor() Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 2 * WB); { Fl_Group *o = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Edge Detection"); + edge_detec = o; // o->hide(); // create all widgets (we construct this once, we never deallocate!) + _buttons[CLASSBUTTON_OK] = + new Fl_Button (4*WB+2*BB, 7*WB+6*BH, BB, BH, "OK"); + _buttons[CLASSBUTTON_OK]->callback(class_ok_cb, this); + _buttons[CLASSBUTTON_SELECT] = new Fl_Button (2*WB, 2*WB+1*BH, BB, BH, "Select Elements"); _buttons[CLASSBUTTON_SELECT]->callback(class_select_cb, this); @@ -257,11 +377,11 @@ classificationEditor::classificationEditor() _togbuttons[CLASSTOGBUTTON_HIDE]->callback(class_hide_cb,this); _togbuttons[CLASSTOGBUTTON_CLOS] = - new Fl_Toggle_Button(4*WB+2*BB, 2*WB+1*BH, BB, BH, "Include Closure"); + new Fl_Toggle_Button(2*WB, 4*WB+3*BH, BB, BH, "Include Closure"); _togbuttons[CLASSTOGBUTTON_CLOS]->callback(updateedges_cb,this); _inputs[CLASSVALUE_ANGLE] = - new Fl_Value_Input(2*WB, 3*WB+2*BH, BB, BH, "Treshold Angle"); + new Fl_Value_Input(3*WB+BB, 4*WB+3*BH, BB, BH, "Treshold Angle"); _inputs[CLASSVALUE_ANGLE]->value(40); _inputs [CLASSVALUE_ANGLE]->maximum(90); _inputs[CLASSVALUE_ANGLE]->minimum(0); @@ -273,16 +393,23 @@ classificationEditor::classificationEditor() _buttons[CLASSBUTTON_DEL] = new Fl_Button (2*WB, 5*WB+4*BH, BB, BH, "Delete Edge"); _buttons[CLASSBUTTON_DEL]->callback(class_deleteedge_cb, this); + _buttons[CLASSBUTTON_DEL]->deactivate(); + _buttons[CLASSBUTTON_ADD] = new Fl_Button (2*WB, 6*WB+5*BH, BB, BH, "Save Selection"); _buttons[CLASSBUTTON_ADD]->callback(class_save_cb, this); + _buttons[CLASSBUTTON_ADD]->deactivate(); + _buttons[CLASSBUTTON_CLEAR] = - new Fl_Button (2*WB, 7*WB+6*BH, BB, BH, "Clear All"); + new Fl_Button (2*WB, 7*WB+6*BH, BB, BH, "Clear Selection"); _buttons[CLASSBUTTON_CLEAR]->callback(class_clear_cb, this); + _buttons[CLASSBUTTON_CLEAR]->deactivate(); o->end(); } { Fl_Group *o = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Face Colouring"); + face_color = o; + o->deactivate(); o->hide(); _buttons[CLASSBUTTON_SELFAC] = new Fl_Button (2*WB, 2*WB+1*BH, BB, BH, "Select Model Face"); @@ -292,6 +419,14 @@ classificationEditor::classificationEditor() _buttons[CLASSBUTTON_COLOR]->callback(class_color_cb, this); o->end(); } + { + Fl_Group *o = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Reverse Engineer Surfaces"); + reverse_eng = o; + o->hide(); + o->deactivate(); + o->end(); + } + NoElementsSelectedMode (this); // allocate detected edges // temporary for the selection @@ -355,6 +490,7 @@ void class_select_cb(Fl_Widget *w, void *data) e2t_cont adj; buildEdgeToTriangle (ele , adj ); buildListOfEdgeAngle ( adj,e->edges_detected,e->edges_lonly); + ElementsSelectedMode (e); break; } // do nothing @@ -500,6 +636,7 @@ void class_save_cb(Fl_Widget *w, void *data) CTX.mesh.changed = ENT_ALL; CTX.pick_elements = 0; + NoElementsSelectedMode (e); Draw(); Msg(ONSCREEN, ""); } @@ -514,18 +651,40 @@ void class_clear_cb(Fl_Widget *w, void *data) } e->temporary->lines.clear(); - for (int i=0;i<e->saved->lines.size();i++) - { - delete e->saved->lines[i]; - } - e->saved->lines.clear(); - CTX.mesh.changed = ENT_ALL; CTX.pick_elements = 0; + NoElementsSelectedMode (e); Draw(); Msg(ONSCREEN, ""); } +void class_ok_cb(Fl_Widget *w, void *data) +{ + classificationEditor *e = (classificationEditor*)data; + e->edge_detec->deactivate(); + e->edge_detec->hide(); + e->face_color->activate(); + e->face_color->show(); + class_save_cb(w,data); + opt_mesh_lines(0, GMSH_SET | GMSH_GUI, e->op[0]); + opt_mesh_surfaces_edges(0, GMSH_SET | GMSH_GUI, e->op[1]); + opt_mesh_surfaces_faces(0, GMSH_SET | GMSH_GUI, e->op[2]); + opt_mesh_line_width(0, GMSH_SET | GMSH_GUI, e->op[3]); + + Msg(ONSCREEN, ""); +} + +void class_okcolor_cb(Fl_Widget *w, void *data) +{ + classificationEditor *e = (classificationEditor*)data; + e->edge_detec->deactivate(); + e->edge_detec->show(); + e->face_color->deactivate(); + e->face_color->hide(); + // class_save_cb(w,data); + Msg(ONSCREEN, ""); +} + void mesh_classify_cb(Fl_Widget* w, void* data) diff --git a/Fltk/GUI_Classifier.h b/Fltk/GUI_Classifier.h index c56da299a7a14308343d0a888ba0ed1efc481a0e..047d3d4a07c20fd3a5631e76869b3ad8a94a0640 100644 --- a/Fltk/GUI_Classifier.h +++ b/Fltk/GUI_Classifier.h @@ -18,6 +18,8 @@ void class_save_cb(Fl_Widget *w, void *data); void class_clear_cb(Fl_Widget *w, void *data); void class_deleteedge_cb(Fl_Widget *w, void *data); void class_color_cb(Fl_Widget *w, void *data); +void class_ok_cb(Fl_Widget *w, void *data); +void class_okcolor_cb(Fl_Widget *w, void *data); #define CLASSBUTTON_SELECT 0 #define CLASSBUTTON_DEL 1 @@ -44,6 +46,7 @@ class edge_angle class classificationEditor { public: + double op[10]; std::vector<MTriangle*> _elements; std::set<GFace*> _faces; Fl_Window *_window; @@ -58,5 +61,6 @@ class classificationEditor { classificationEditor(); void show(){ _window->show();} std::vector<MTriangle*> &getElements() { return _elements; } + Fl_Group *edge_detec,*face_color,*reverse_eng; }; #endif diff --git a/Geo/gmshFace.cpp b/Geo/gmshFace.cpp index a1aca8329f068596371f77870ef2606af2f218c1..62fcc2c28832dad716b9be350671525a2d971b3e 100644 --- a/Geo/gmshFace.cpp +++ b/Geo/gmshFace.cpp @@ -1,4 +1,4 @@ -// $Id: gmshFace.cpp,v 1.40 2007-09-04 13:47:01 remacle Exp $ +// $Id: gmshFace.cpp,v 1.41 2007-09-10 13:37:21 remacle Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -100,6 +100,16 @@ gmshFace::gmshFace(GModel *m, int num) Tree_Add(THEM->Surfaces, &s); } +void gmshFace::setModelEdges(std::list<GEdge*>&ed) +{ + for (std::list<GEdge*>::iterator it = ed.begin(); it!=ed.end() ; ++it) + { + l_edges.push_back(*it); + (*it)->addFace(this); + l_dirs.push_back( 1 ); + } +} + void gmshFace::resetMeshAttributes() { meshAttributes.recombine = s->Recombine; diff --git a/Geo/gmshFace.h b/Geo/gmshFace.h index acc622367a3a5ffa5e2b94c358dc04169479066b..efe694fb0b5a35a274d3b7afd2aeae8fa2255572 100644 --- a/Geo/gmshFace.h +++ b/Geo/gmshFace.h @@ -34,6 +34,7 @@ class gmshFace : public GFace { gmshFace(GModel *m, int num); virtual ~gmshFace(){} Range<double> parBounds(int i) const; + void setModelEdges(std::list<GEdge*>&); virtual int paramDegeneracies(int dir, double *par) { return 0; } virtual GPoint point(double par1, double par2) const; diff --git a/Mesh/meshGFaceDelaunayInsertion.cpp b/Mesh/meshGFaceDelaunayInsertion.cpp index 16e81e7d5f705fda5bc5f04e1d761ff4b6a5b6db..3d995473573fa96aa99d1e02d6c773afffc2a622 100644 --- a/Mesh/meshGFaceDelaunayInsertion.cpp +++ b/Mesh/meshGFaceDelaunayInsertion.cpp @@ -1,4 +1,4 @@ -// $Id: meshGFaceDelaunayInsertion.cpp,v 1.4 2007-09-05 13:19:15 remacle Exp $ +// $Id: meshGFaceDelaunayInsertion.cpp,v 1.5 2007-09-10 13:37:21 remacle Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -573,13 +573,9 @@ void insertVerticesInFace (GFace *gf, BDS_Mesh *bds) if (AllTris.begin() == AllTris.end() ) break; MTri3 *worst = *AllTris.begin(); if (worst->isDeleted()) - { delete worst->tri(); - } else - { - gf->triangles.push_back(worst->tri()); - } + gf->triangles.push_back(worst->tri()); delete worst; AllTris.erase(AllTris.begin()); }