diff --git a/Mesh/meshGFaceRecombine.cpp b/Mesh/meshGFaceRecombine.cpp index 138225d30374b1b937e3aa475797262e9cc8fb82..016556ed7010195739ac903a78276b8643941739 100644 --- a/Mesh/meshGFaceRecombine.cpp +++ b/Mesh/meshGFaceRecombine.cpp @@ -237,48 +237,30 @@ bool Recombine2D::recombine() return 1; } -bool Recombine2D::recombine() +bool Recombine2D::developTree() { - Rec2DAction *nextAction; - while (nextAction = Rec2DData::getBestAction()) { -#ifdef REC2D_DRAW - FlGui::instance()->check(); - double time = Cpu(); - nextAction->color(0, 0, 200); - CTX::instance()->mesh.changed = (ENT_ALL); - drawContext::global()->draw(); -#endif - - if (!_remainAllQuad(nextAction)) { - nextAction->color(190, 0, 0); - delete nextAction; - continue; - } - ++_numChange; - std::vector<Rec2DVertex*> newPar; - nextAction->apply(newPar); - - // forall v in newPar : check obsoletes action; - -#ifdef REC2D_DRAW - _gf->triangles = _data->_tri; - _gf->quadrangles = _data->_quad; - CTX::instance()->mesh.changed = (ENT_ALL); - drawContext::global()->draw(); - while (Cpu()-time < REC2D_WAIT_TIME) - FlGui::instance()->check(); -#endif - - delete nextAction; - } + double bestGlobalValue; + Rec2DNode root(NULL, NULL, bestGlobalValue); - _data->printState(); -#ifdef REC2D_SMOOTH - laplaceSmoothing(_gf,100); -#endif - CTX::instance()->mesh.changed = (ENT_ALL); - drawContext::global()->draw(); - return 1; + Msg::Info("best global value : %g", bestGlobalValue); + Msg::Info("num end node : %d", Rec2DData::getNumEndNode()); + + Rec2DData::sortEndNode(); + Rec2DData::drawEndNode(10); +} + +void Recombine2D::nextTreeActions(Rec2DAction *ra, + std::vector<Rec2DAction*> &actions) +{ + Rec2DAction *next = Rec2DData::getBestNonHiddenAction(); + if (!next) + return; + std::vector<Rec2DElement*> elements; + next->getElements(elements); + for (int i = 0; i < elements[0]->getNumActions(); ++i) { + if (!Rec2DData::isOutOfDate(elements[0]->getAction(i))) + actions.push_back(elements[0]->getAction(i)); + } } double Recombine2D::_geomAngle(MVertex *v, @@ -838,6 +820,44 @@ Rec2DAction* Rec2DData::getBestAction() _current->_actions.end(), lessRec2DAction()); } +Rec2DAction* Rec2DData::getBestNonHiddenAction() +{ + _current->_actions.sort(lessRec2DAction()); + std::list<Rec2DAction*>::iterator it = _current->_actions.begin(); + while (it != _current->_actions.end() && Rec2DData::isOutOfDate(*it)) ++it; + if (it == _current->_actions.end()) + return NULL; + return *it; +} + +bool Rec2DData::isOutOfDate(Rec2DAction *ra) +{ + std::vector<Rec2DElement*> elements; + ra->getElements(elements); + bool b = false; + for (unsigned int i = 0; i < elements.size(); ++i) { + if (_current->_hiddenElements.find(elements[i]) != + _current->_hiddenElements.end() ) { + b = true; + break; + } + } + return b; +} + +void Rec2DData::drawEndNode(int num) +{ + /*std::list<Rec2DNode*>::iterator it = _endNodes.begin(); + for (int i = 0; i < num && it != _endNodes.end(); ++i, ++it) { + std::map<int, std::vector<double> > data; + Rec2DNode *currentNode = *it; + + for (unsigned int i = 0; i < invalids.size(); ++i) + computeMinMax(&invalids[i], 1, &data); + + } + new PView("Jmin_bad", "ElementData", _m, data);*/ +} /** Rec2DAction **/ /*******************/ @@ -975,59 +995,22 @@ void Rec2DTwoTri2Quad::apply(std::vector<Rec2DVertex*> &newPar) /*new Rec2DCollapse(*/new Rec2DElement(_edges)/*)*/; } -void Rec2DTwoTri2Quad::choose() -{ - if (isObsolete()) { - Msg::Error("[Rec2DTwoTri2Quad] No way ! I won't apply ! Find someone else..."); - return; - } +void Rec2DTwoTri2Quad::choose(Rec2DElement *&rel) +{ + _edges[4]->hide(); + _triangles[0]->hide(); + _triangles[1]->hide(); - int min = Rec2DData::getNewParity(), index = -1; - for (int i = 0; i < 4; ++i) { - if (_vertices[i]->getParity() && min > _vertices[i]->getParity()) { - min = _vertices[i]->getParity(); - index = i; - } - } - if (index == -1) { - _vertices[0]->setParity(min); - _vertices[1]->setParity(min); - _vertices[2]->setParity(min+1); - _vertices[3]->setParity(min+1); - } - else { - for (int i = 0; i < 4; i += 2) { - int par; - if ((index/2) * 2 == i) - par = min; - else - par = otherParity(min); - for (int j = 0; j < 2; ++j) { - if (!_vertices[i+j]->getParity()) - _vertices[i+j]->setParity(par); - else if (_vertices[i+j]->getParity() != par && - _vertices[i+j]->getParity() != otherParity(par)) - Rec2DData::associateParity(_vertices[i+j]->getParity(), par); - } - } - } - - _triangles[0]->remove(this); - _triangles[1]->remove(this); - - std::vector<Rec2DAction*> actions; - _triangles[0]->getUniqueActions(actions); - _triangles[1]->getUniqueActions(actions); - for (unsigned int i = 0; i < actions.size(); ++i) - delete actions[i]; - - delete _triangles[0]; - delete _triangles[1]; - _triangles[0] = NULL; - _triangles[1] = NULL; - delete _edges[4]; + rel = new Rec2DElement(_edges, true); +} + +void Rec2DTwoTri2Quad::unChoose(Rec2DElement *rel) +{ + delete rel; - /*new Rec2DCollapse(*/new Rec2DElement(_edges)/*)*/; + _edges[4]->reveal(); + _triangles[0]->reveal(); + _triangles[1]->reveal(); } bool Rec2DTwoTri2Quad::isObsolete() @@ -1107,6 +1090,12 @@ bool Rec2DTwoTri2Quad::whatWouldYouDo return true; } +void Rec2DTwoTri2Quad::getElements(std::vector<Rec2DElement*> &elem) +{ + elem.clear(); + elem.push_back(_triangles[0]); + elem.push_back(_triangles[1]); +} /** Rec2DEdge **/ /*****************/ @@ -1129,6 +1118,22 @@ Rec2DEdge::~Rec2DEdge() Rec2DData::addEdge(-_weight, -_weight*getQual()); } +void Rec2DEdge::hide() +{ + //_rv0->remove(this); + //_rv1->remove(this); + //Rec2DData::remove(this); + Rec2DData::addEdge(-_weight, -_weight*getQual()); +} + +void Rec2DEdge::reveal() +{ + //_rv0->add(this); + //_rv1->add(this); + //Rec2DData::remove(this); + Rec2DData::addEdge(_weight, _weight*getQual()); +} + void Rec2DEdge::_computeQual() //* { double adimLength = _straightAdimLength(); @@ -1381,9 +1386,9 @@ void Rec2DVertex::setOnBoundary() } } -void Rec2DVertex::setParity(int p) +void Rec2DVertex::setParity(int p, bool tree) { - if (_parity) { + if (_parity && !tree) { Msg::Warning("[Rec2DVertex] I don't like to do it. Think about that !"); Rec2DData::removeParity(this, _parity); } @@ -1607,14 +1612,19 @@ Rec2DElement::Rec2DElement(MQuadrangle *q) : _mEl((MElement *)q), _numEdge(4) Rec2DData::add(this); } -Rec2DElement::Rec2DElement(Rec2DEdge **edges) : _mEl(NULL), _numEdge(4) +Rec2DElement::Rec2DElement(Rec2DEdge **edges, bool tree) : _mEl(NULL), _numEdge(4) { for (int i = 0; i < 4; ++i) { _edges[i] = edges[i]; _edges[i]->addHasQuad(); - _elements[i] = Rec2DEdge::getSingleElement(edges[i]); - if (_elements[i]) - _elements[i]->addNeighbour(_edges[i], this); + if (tree) { + _elements[i] = NULL; + } + else { + _elements[i] = Rec2DEdge::getSingleElement(edges[i]); + if (_elements[i]) + _elements[i]->addNeighbour(_edges[i], this); + } } std::vector<Rec2DVertex*> vertices(4); getVertices(vertices); @@ -1644,6 +1654,38 @@ Rec2DElement::~Rec2DElement() Rec2DData::remove(this); } +void Rec2DElement::hide() +{ + for (int i = 0; i < _numEdge; ++i) { + if (_numEdge == 3) + _edges[i]->remHasTri(); + else + _edges[i]->remHasQuad(); + } + std::vector<Rec2DVertex*> vertices(_numEdge); + getVertices(vertices); + for (unsigned int i = 0; i < _numEdge; ++i) { + vertices[i]->remove(this); + } + Rec2DData::addHidden(this); +} + +void Rec2DElement::reveal() +{ + for (int i = 0; i < _numEdge; ++i) { + if (_numEdge == 3) + _edges[i]->addHasTri(); + else + _edges[i]->addHasQuad(); + } + std::vector<Rec2DVertex*> vertices(_numEdge); + getVertices(vertices); + for (unsigned int i = 0; i < _numEdge; ++i) { + vertices[i]->add(this); + } + Rec2DData::remHidden(this); +} + void Rec2DElement::add(Rec2DEdge *re) { int i; @@ -1846,28 +1888,40 @@ MQuadrangle* Rec2DElement::_createQuad() const /** Rec2DNode **/ /*****************/ -Rec2DNode::Rec2DNode(Rec2DNode *father, Rec2DEction *ra, double &bestEndGlobVal) -: _father(father), _ra(ra), _son0(NULL), _son1(NULL), _son2(NULL), - _globalValue(.0), _bestEndGlobVal(.0) +/*bool lessRec2DNode::operator()(Rec2DNode *rn1, Rec2DNode *rn2) const { - int parities[4]; - _ra.choose(parities); + return *rn1 < *rn2; +} + + */Rec2DNode::Rec2DNode(Rec2DNode *father, Rec2DAction *ra, double &bestEndGlobVal) +: _father(father), _ra(ra), _globalValue(.0), _bestEndGlobVal(.0) +{ + _son[0] = NULL; + _son[1] = NULL; + _son[2] = NULL; + Rec2DElement *newElement; + if (_ra) + _ra->choose(newElement); - double 2; - int k = 0; - Rec2DElement *rel = Recombine2D::nextTreeActions(_ra); - for (int i = 0; i < rel->getNumActions(); ++i) { - if (!rel->getAction(i)->is'Obsolete'()) { - son[k] = new Rec2DNode(this, rel->getAction(i), endGlobValSon); - _bestEndGlobVal = max(_bestEndGlobVal, endGlobValSon); - ++k; - } - } + _globalValue = Rec2DData::getGlobalValue(); + + std::vector<Rec2DAction*> actions; + Recombine2D::nextTreeActions(_ra, actions); - if (k == 0) { + if (actions.empty()) { Rec2DData::addEndNode(this); + _bestEndGlobVal = _globalValue; } + else + for (int i = 0; i < actions.size(); ++i) { + double bestSonEndGlobVal; + _son[i] = new Rec2DNode(this, actions[i], bestSonEndGlobVal); + _bestEndGlobVal = std::max(_bestEndGlobVal, bestSonEndGlobVal); + } + bestEndGlobVal = _bestEndGlobVal; - _ra.revert(parities); + + if (_ra) + _ra->unChoose(newElement); } diff --git a/Mesh/meshGFaceRecombine.h b/Mesh/meshGFaceRecombine.h index f800bbc9c47a9faf06e4904d205d5555c63b7804..bff0cd36c73265312a0420865bdcfba183804a80 100644 --- a/Mesh/meshGFaceRecombine.h +++ b/Mesh/meshGFaceRecombine.h @@ -19,6 +19,7 @@ //#include "GModel.h" //#include "MEdge.h" +class Rec2DNode; class Rec2DVertex; class Rec2DEdge; class Rec2DElement; @@ -47,6 +48,7 @@ class Recombine2D { bool recombine(); bool developTree(); + static void nextTreeActions(Rec2DAction*, std::vector<Rec2DAction*>&); static inline GFace* getGFace() {return _current->_gf;} static inline int getNumChange() {return _current->_numChange;} @@ -68,9 +70,10 @@ class Rec2DData { std::set<Rec2DEdge*> _edges; std::set<Rec2DVertex*> _vertices; - std::set<Rec2DElement*> _elements; + std::set<Rec2DElement*> _elements, _hiddenElements; std::list<Rec2DAction*> _actions; + std::list<Rec2DNode*> _endNodes; std::map<int, std::vector<Rec2DVertex*> > _parities; std::map<int, std::vector<Rec2DVertex*> > _assumedParities; @@ -86,6 +89,8 @@ class Rec2DData { std::vector<MQuadrangle*> _quad; #endif + static double getNumEndNode() {return _current->_endNodes.size();} + static double getGlobalValue(); static double getGlobalValue(int numEdge, double valEdge, int numVert, double valVert ); @@ -100,6 +105,7 @@ class Rec2DData { } static Rec2DAction* getBestAction(); + static Rec2DAction* getBestNonHiddenAction(); typedef std::set<Rec2DEdge*>::iterator iter_re; typedef std::set<Rec2DVertex*>::iterator iter_rv; @@ -124,6 +130,21 @@ class Rec2DData { static void remove(Rec2DElement*); static void remove(Rec2DAction*); + static inline void addEndNode(Rec2DNode *rn) { + _current->_endNodes.push_back(rn); + } + static inline void sortEndNode() { + /*_current->_endNodes.sort(lessRec2DNode());*/ + } + static inline void drawEndNode(int num); + static inline void addHidden(Rec2DElement *rel) { + _current->_hiddenElements.insert(rel); + } + static inline void remHidden(Rec2DElement *rel) { + _current->_hiddenElements.erase(rel); + } + static bool isOutOfDate(Rec2DAction*); + static int getNewParity(); static void removeParity(Rec2DVertex*, int); static inline void addParity(Rec2DVertex *rv, int p) { @@ -162,6 +183,9 @@ class Rec2DAction { virtual void getAssumedParities(int*) = 0; virtual bool whatWouldYouDo(std::map<Rec2DVertex*, std::vector<int> >&) = 0; virtual Rec2DVertex* getVertex(int) = 0; + virtual void choose(Rec2DElement*&) = 0; + virtual void unChoose(Rec2DElement*) = 0; + virtual void getElements(std::vector<Rec2DElement*>&) = 0; private : virtual void _computeGlobVal() = 0; @@ -185,6 +209,9 @@ class Rec2DTwoTri2Quad : public Rec2DAction { virtual void getAssumedParities(int*); virtual bool whatWouldYouDo(std::map<Rec2DVertex*, std::vector<int> >&); virtual inline Rec2DVertex* getVertex(int i) {return _vertices[i];} //- + virtual void choose(Rec2DElement*&); + virtual void unChoose(Rec2DElement*); + virtual void getElements(std::vector<Rec2DElement*>&); private : virtual void _computeGlobVal(); @@ -200,6 +227,8 @@ class Rec2DEdge { public : Rec2DEdge(Rec2DVertex*, Rec2DVertex*); ~Rec2DEdge(); + void hide(); + void reveal(); double getQual(); @@ -257,7 +286,7 @@ class Rec2DVertex { bool setBoundaryParity(int p0, int p1); inline int getParity() const {return _parity;} - void setParity(int); + void setParity(int, bool tree = false); void setParityWD(int pOld, int pNew); int getAssumedParity() const; bool setAssumedParity(int); @@ -305,8 +334,10 @@ class Rec2DElement { public : Rec2DElement(MTriangle*); Rec2DElement(MQuadrangle*); - Rec2DElement(Rec2DEdge**); + Rec2DElement(Rec2DEdge**, bool tree = false); ~Rec2DElement(); + void hide(); + void reveal(); bool inline isTri() {return _numEdge == 3;} bool inline isQuad() {return _numEdge == 4;} @@ -352,15 +383,19 @@ class Rec2DElement { MQuadrangle* _createQuad() const; }; +/*struct lessRec2DNode { + bool operator()(Rec2DNode*, Rec2DNode*) const; +}; +*/ class Rec2DNode { private : Rec2DNode *_father; - Rec2DNode *_son0, *_son1, *_son2; + Rec2DNode *_son[3]; Rec2DAction *_ra; double _globalValue, _bestEndGlobVal; public : - Rec2DNode(Rec2DAction*); + Rec2DNode(Rec2DNode *father, Rec2DAction*, double &bestEndGlobVal); }; #endif \ No newline at end of file