diff --git a/Mesh/meshGFaceRecombine.cpp b/Mesh/meshGFaceRecombine.cpp index 2f52a874fc2e615637fab8324cda2c4c99379ed4..105a4c32e8cd14e053d259a3fb768ef9f0edac20 100644 --- a/Mesh/meshGFaceRecombine.cpp +++ b/Mesh/meshGFaceRecombine.cpp @@ -7,7 +7,7 @@ // Amaury Johnen (a.johnen@ulg.ac.be) // -#define REC2D_WAIT_TIME .1 +#define REC2D_WAIT_TIME .02 #define REC2D_NUM_ACTIO 1000 // #define REC2D_SMOOTH @@ -101,11 +101,13 @@ int otherParity(int a) return a + 1; } -namespace std +namespace std //swap { template <> void swap(Rec2DData::Action& a0, Rec2DData::Action& a1) { + ((Rec2DAction*)a0.action)->_dataAction = &a1; + ((Rec2DAction*)a1.action)->_dataAction = &a0; int pos0 = a0.position; a0.position = a1.position; a1.position = pos0; @@ -251,7 +253,7 @@ Recombine2D::Recombine2D(GFace *gf) : _gf(gf), _strategy(0), _numChange(0) } } } - // set parity on boundary, create the 'Rec2DFourTri2Quad', add quality of angle at vertices + // set parity on boundary, create the 'Rec2DFourTri2Quad' { Rec2DData::iter_rv it = Rec2DData::firstVertex(); for (; it != Rec2DData::lastVertex(); ++it) { @@ -281,7 +283,9 @@ Recombine2D::~Recombine2D() bool Recombine2D::recombine() { - Rec2DAction *nextAction; + static int a = -1; + if (++a < 1) Msg::Error("FIXME Need new definition Recombine2D::recombine()"); + /*Rec2DAction *nextAction; while ((nextAction = Rec2DData::getBestAction())) { #ifdef REC2D_DRAW FlGui::instance()->check(); @@ -324,7 +328,7 @@ bool Recombine2D::recombine() laplaceSmoothing(_gf,100); #endif CTX::instance()->mesh.changed = ENT_ALL; - drawContext::global()->draw(); + drawContext::global()->draw();*/ return 1; } @@ -346,19 +350,19 @@ double Recombine2D::recombine(int depth) Rec2DNode *root = new Rec2DNode(NULL, NULL, bestGlobalQuality, depth); Rec2DNode *currentNode = root->selectBestNode(); - static int num = 20, i = 0; - static double dx = .0, dy = .0; + //static int num = 20, i = 0; + //static double dx = .0, dy = .0; while (currentNode) { //_data->checkQuality(); FlGui::instance()->check(); -#ifdef REC2D_DRAW // draw state at origin +#if 0//def REC2D_DRAW // draw state at origin drawStateOrigin(); - //while (Cpu()-time < REC2D_WAIT_TIME) + while (Cpu()-time < REC2D_WAIT_TIME) FlGui::instance()->check(); time = Cpu(); #endif -#ifdef REC2D_DRAW // draw all states +#if 0//def REC2D_DRAW // draw all states if ( !((i+1) % ((int)std::sqrt(num)+1)) ) { dx = .0; dy -= 1.1; @@ -389,7 +393,7 @@ int Recombine2D::getNumTri() const void Recombine2D::clearChanges() { Rec2DData::clearChanges(); -#ifdef REC2D_DRAW +#if 0//def REC2D_DRAW CTX::instance()->mesh.changed = ENT_ALL; drawContext::global()->draw(); #endif @@ -411,7 +415,8 @@ bool Recombine2D::developTree() } void Recombine2D::nextTreeActions(std::vector<Rec2DAction*> &actions, - const std::vector<Rec2DElement*> &neighbourEl) + const std::vector<Rec2DElement*> &neighbourEl, + Rec2DElement *&rel ) { actions.clear(); if (_cur->_strategy == 4) { @@ -423,7 +428,6 @@ void Recombine2D::nextTreeActions(std::vector<Rec2DAction*> &actions, } std::vector<Rec2DElement*> elements; Rec2DAction *ra = NULL; - Rec2DElement *rel = NULL; switch (_cur->_strategy) { case 0 : // random triangle of random action ra = Rec2DData::getRandomAction(); @@ -433,9 +437,8 @@ void Recombine2D::nextTreeActions(std::vector<Rec2DAction*> &actions, default : case 3 : // triangle of best neighbour action - for (unsigned int i = 0; i < neighbourEl.size(); ++i) { + for (unsigned int i = 0; i < neighbourEl.size(); ++i) neighbourEl[i]->getUniqueActions(actions); - } std::sort(actions.begin(), actions.end(), gterRec2DAction()); if (actions.size()) { actions[0]->getElements(elements); @@ -580,7 +583,7 @@ bool Rec2DData::gterAction::operator()(Action *ra1, Action *ra2) const return *((Rec2DAction*)ra2->action) < *((Rec2DAction*)ra1->action); } -Rec2DData::Rec2DData() +Rec2DData::Rec2DData() : _remainingTri(0) { if (Rec2DData::_cur != NULL) { Msg::Error("[Rec2DData] An instance in execution"); @@ -623,6 +626,7 @@ void Rec2DData::add(const Rec2DElement *rel) Msg::Error("[Rec2DData] elem already there"); return; } + if (rel->isTri()) ++_cur->_remainingTri; ((Rec2DElement*)rel)->_pos = _cur->_elements.size(); _cur->_elements.push_back((Rec2DElement*)rel); @@ -640,6 +644,7 @@ void Rec2DData::add(const Rec2DAction *ra) { if (ra->_dataAction) { Msg::Error("[Rec2DData] action already there"); + ra->printIdentity(); return; } _cur->_actions.push_back(new Action(ra, _cur->_actions.size())); @@ -676,6 +681,7 @@ void Rec2DData::rmv(const Rec2DElement *rel) Msg::Error("[Rec2DData] vert not there"); return; } + if (rel->isTri()) --_cur->_remainingTri; _cur->_elements.back()->_pos = rel->_pos; _cur->_elements[rel->_pos] = _cur->_elements.back(); _cur->_elements.pop_back(); @@ -711,15 +717,19 @@ void Rec2DData::rmv(const Rec2DAction *ra) { if (!ra->_dataAction) { Msg::Error("[Rec2DData] action not there"); + return; } - else { - int pos = ((Action*)ra->_dataAction)->position; - ((Rec2DAction*)ra)->_dataAction = NULL; - delete _cur->_actions[pos]; - _cur->_actions[pos] = _cur->_actions.back(); - _cur->_actions[pos]->position = pos; - _cur->_actions.pop_back(); - } + std::swap(*((Action*)ra->_dataAction), *_cur->_actions.back()); + ((Rec2DAction*)_cur->_actions.back()->action)->_dataAction = NULL; + delete _cur->_actions.back(); + _cur->_actions.pop_back(); +} + +bool Rec2DData::has(const Rec2DAction *ra) +{ + for (unsigned int i = 0; i < _cur->_actions.size(); ++i) + if (_cur->_actions[i]->action == ra) return true; + return false; } void Rec2DData::printState() const @@ -989,14 +999,8 @@ void Rec2DData::checkObsolete() obsoletes.push_back((Rec2DAction*)_cur->_actions[i]->action); } - for (unsigned int i = 0; i < obsoletes.size(); ++i) { - if (obsoletes[i]->getInfant()) { - obsoletes[i]->hide(); - _cur->_hiddenActions.push_back(obsoletes[i]); - } - else - delete obsoletes[i]; - } + for (unsigned int i = 0; i < obsoletes.size(); ++i) + delete obsoletes[i]; } void Rec2DData::drawTriangles(double shiftx, double shifty) const @@ -1026,6 +1030,24 @@ void Rec2DData::drawChanges(double shiftx, double shifty) const new PView("Changes", "ElementData", Recombine2D::getGFace()->model(), data); } +void Rec2DData::addEndNode(const Rec2DNode *rn) +{ + static int k = 0; + if (_cur->_endNodes.size() > 9999) { + Msg::Info("%d", ++k); + sortEndNode(); + int newLast = 4999; + for (unsigned int i = newLast + 1; i < 10000; ++i) { + if (_cur->_endNodes[i]->canBeDeleted()) + delete _cur->_endNodes[i]; + else + _cur->_endNodes[++newLast] = _cur->_endNodes[i]; + } + _cur->_endNodes.resize(newLast + 1); + } + _cur->_endNodes.push_back((Rec2DNode*)rn); +} + void Rec2DData::drawEndNode(int num) { double dx = .0, dy = .0; @@ -1040,13 +1062,16 @@ void Rec2DData::drawEndNode(int num) } else dx += 1.2; - while (currentNode && currentNode->getAction()) { + currentNode->draw(dx, dy); + Rec2DData::clearChanges(); + /*while (currentNode && currentNode->getAction()) { //Msg::Info("%g", currentNode->getGlobQual()); //data[currentNode->getNum()].push_back(currentNode->getGlobQual()); - data[currentNode->getAction()->getNum(dx, dy)].push_back(++k); + if (currentNode->getAction()->haveElem()) + data[currentNode->getAction()->getNum(dx, dy)].push_back(++k); currentNode = currentNode->getFather(); - } - new PView("Jmin_bad", "ElementData", Recombine2D::getGFace()->model(), data); + }*/ + //new PView("Jmin_bad", "ElementData", Recombine2D::getGFace()->model(), data); } } @@ -1054,7 +1079,7 @@ void Rec2DData::sortEndNode() { std::sort(_cur->_endNodes.begin(), _cur->_endNodes.end(), - moreRec2DNode() ); + gterRec2DNode() ); } /** Rec2DChange **/ @@ -1096,7 +1121,8 @@ Rec2DChange::Rec2DChange(Rec2DAction *ra, bool toHide) : _entity(ra), _info(NULL _type = HideAction; } else { - ra->addPointing(); + static int a = -1; + if (++a < 1) Msg::Warning("FIXME peut pas faire sans pointing ?"); _type = CreatedAction; } } @@ -1320,20 +1346,7 @@ void Rec2DChange::revert() break; case CreatedAction : - { - Rec2DAction *ra = (Rec2DAction*)_entity; - if (ra->getPointing()) { - ra->hide(); - } - else { - if (ra->getInfant()) { - ra->hide(); - Rec2DData::addHidden(ra); - } - else - delete ra; - } - } + delete (Rec2DAction*)_entity; break; case HideActions : @@ -1348,19 +1361,8 @@ void Rec2DChange::revert() case CreatedActions : { std::vector<Rec2DAction*> *vect = (std::vector<Rec2DAction*>*)_entity; - for (unsigned int i = 0; i < vect->size(); ++i) { - if ((*vect)[i]->getPointing()) { - (*vect)[i]->hide(); - } - else { - if ((*vect)[i]->getInfant()) { - (*vect)[i]->hide(); - Rec2DData::addHidden((*vect)[i]); - } - else - delete (*vect)[i]; - } - } + for (unsigned int i = 0; i < vect->size(); ++i) + delete (*vect)[i]; delete vect; } break; @@ -1552,7 +1554,6 @@ bool gterRec2DAction::operator()(Rec2DAction *ra1, Rec2DAction *ra2) const Rec2DAction::Rec2DAction() : _globQualIfExecuted(.0), _lastUpdate(-2), _numPointing(0), _dataAction(NULL) { - } bool Rec2DAction::operator<(Rec2DAction &other) @@ -1627,6 +1628,24 @@ Rec2DTwoTri2Quad::Rec2DTwoTri2Quad(Rec2DElement *el0, Rec2DElement *el1) if (!edgesInOrder(_edges, 4)) Msg::Error("recomb |%d|%d|", _triangles[0]->getNum(), _triangles[1]->getNum()); } +void Rec2DTwoTri2Quad::operator delete(void *p) +{ + if (!p) return; + Rec2DTwoTri2Quad *ra = (Rec2DTwoTri2Quad*)p; + if (ra->_dataAction) { // ra->hide() + ra->_triangles[0]->remove(ra); + ra->_triangles[1]->remove(ra); + Rec2DData::rmv(ra); + } + if (!ra->_numPointing) { + //Msg::Info("del ac %d", p); + if (ra->_col) + Rec2DData::addHidden((Rec2DAction*)p); + else + free(p); + } +} + void Rec2DTwoTri2Quad::hide() { static int a = -1; @@ -1790,7 +1809,9 @@ void Rec2DTwoTri2Quad::color(int a, int b, int c) const void Rec2DTwoTri2Quad::apply(std::vector<Rec2DVertex*> &newPar) { - if (isObsolete()) { + static int a = -1; + if (++a < 1) Msg::Error("FIXME Need new definition Rec2DTwoTri2Quad::apply(newPar)"); + /*if (isObsolete()) { Msg::Error("[Rec2DTwoTri2Quad] No way ! I won't apply ! Find someone else..."); return; } @@ -1827,6 +1848,7 @@ void Rec2DTwoTri2Quad::apply(std::vector<Rec2DVertex*> &newPar) _triangles[0]->remove(this); _triangles[1]->remove(this); + // hide() instead std::vector<Rec2DAction*> actions; _triangles[0]->getUniqueActions(actions); @@ -1842,7 +1864,7 @@ void Rec2DTwoTri2Quad::apply(std::vector<Rec2DVertex*> &newPar) new Rec2DElement((MQuadrangle*)NULL, (const Rec2DEdge**)_edges); - Recombine2D::incNumChange(); + Recombine2D::incNumChange();*/ } void Rec2DTwoTri2Quad::apply(Rec2DDataChange *rdc, @@ -1926,14 +1948,15 @@ void Rec2DTwoTri2Quad::getElements(std::vector<Rec2DElement*> &elem) const elem.push_back(_triangles[1]); } -void Rec2DTwoTri2Quad::getNeighbourElements(std::vector<Rec2DElement*> &elem) const +void Rec2DTwoTri2Quad::getNeighbourElements(std::vector<Rec2DElement*> &elem, + Rec2DElement *rel ) const { elem.clear(); _triangles[0]->getMoreNeighbours(elem); _triangles[1]->getMoreNeighbours(elem); unsigned int i = 0; while (i < elem.size()) { - if (elem[i] == _triangles[0] || elem[i] == _triangles[0]) { + if (elem[i] == _triangles[0] || elem[i] == _triangles[1]) { elem[i] = elem.back(); elem.pop_back(); } @@ -1941,9 +1964,11 @@ void Rec2DTwoTri2Quad::getNeighbourElements(std::vector<Rec2DElement*> &elem) co } } -void Rec2DTwoTri2Quad::getNeighbElemWithActions(std::vector<Rec2DElement*> &elem) const +void Rec2DTwoTri2Quad:: + getNeighbElemWithActions(std::vector<Rec2DElement*> &elem, + Rec2DElement *rel ) const { - getNeighbourElements(elem); + getNeighbourElements(elem, rel); unsigned int i = 0; while (i < elem.size()) { if (!elem[i]->getNumActions()) { @@ -2021,6 +2046,22 @@ Rec2DCollapse::Rec2DCollapse(Rec2DTwoTri2Quad *rec) : _rec(rec)//, Rec2DData::add(this); } +void Rec2DCollapse::operator delete(void *p) +{ + if (!p) return; + Rec2DCollapse *ra = (Rec2DCollapse*)p; + if (ra->_dataAction) { // ra->hide() + ra->_rec->_triangles[0]->remove(ra); + ra->_rec->_triangles[1]->remove(ra); + Rec2DData::rmv(ra); + } + if (!ra->_numPointing) { + //Msg::Info("del ac %d", p); + ra->_rec->_col = NULL; + free(p); + } +} + void Rec2DCollapse::hide() { if (_rec->_triangles[0]) @@ -2129,8 +2170,10 @@ void Rec2DCollapse::_computeGlobQual() _rec->_vertices[1]->getMoreNeighbourVertices(verts); unsigned int i = 0; while (i < verts.size() && verts[i]->getLastUpdate() <= _lastUpdate) ++i; - if (i >= verts.size()) + if (i >= verts.size()) { + _lastUpdate = Recombine2D::getNumChange(); return; + } SPoint2 p[2]; _rec->_vertices[0]->getParam(&p[0]); @@ -2200,7 +2243,7 @@ void Rec2DCollapse::printIdentity() const void Rec2DCollapse::apply(std::vector<Rec2DVertex*> &newPar) { static int a = -1; - if (++a < 1) Msg::Error("FIXME Need definition Rec2DTwoTri2Quad::apply(newPar)"); + if (++a < 1) Msg::Error("FIXME Need definition Rec2DCollapse::apply(newPar)"); } void Rec2DCollapse::apply(Rec2DDataChange *rdc, @@ -2327,6 +2370,45 @@ bool Rec2DCollapse::isObsolete() const _rec->_vertices[3]->getNumElements() < 4 ; } +void Rec2DCollapse:: + getNeighbourElements(std::vector<Rec2DElement*> &elem, + Rec2DElement *rel ) const +{ + if (!rel) { + _rec->getNeighbourElements(elem, rel); + return; + } + if (rel != _rec->_triangles[0] && rel != _rec->_triangles[1]) { + Msg::Error("[Rec2DTwoTri2Quad] Wrong element for getNeighbour"); + return; + } + elem.clear(); + rel->getMoreNeighbours(elem); + unsigned int i = 0; + while (i < elem.size()) { + if (elem[i] == _rec->_triangles[0] || elem[i] == _rec->_triangles[1]) { + elem[i] = elem.back(); + elem.pop_back(); + } + else ++i; + } +} + +void Rec2DCollapse:: + getNeighbElemWithActions(std::vector<Rec2DElement*> &elem, + Rec2DElement *rel ) const +{ + getNeighbourElements(elem, rel); + unsigned int i = 0; + while (i < elem.size()) { + if (!elem[i]->getNumActions()) { + elem[i] = elem.back(); + elem.pop_back(); + } + else ++i; + } +} + bool Rec2DCollapse::_hasIdenticalElement() const { return _rec->_triangles[0]->hasIdenticalNeighbour() || @@ -2599,9 +2681,9 @@ Rec2DVertex::Rec2DVertex(Rec2DVertex *rv, double ang) for (unsigned int i = 0; i < _edges.size(); ++i) { _edges[i]->swap(rv, this, false); } - Rec2DData::add(this); - if (_elements.size()) - Rec2DData::addVert(REC2D_NUMB_VERT, getQual()); + reveal(); + + rv->_edges.clear(); delete rv; #ifdef REC2D_DRAW if (_v) @@ -2613,16 +2695,14 @@ Rec2DVertex::Rec2DVertex(Rec2DVertex *rv, double ang) void Rec2DVertex::hide() { - if (_elements.size() || _edges.size()) + if (_elements.size() && _edges.size()) Msg::Error("[Rec2DVertex] I have %d elements and %d edges", _elements.size(), _edges.size()); if (_parity) Rec2DData::removeParity(this, _parity); Rec2DData::rmv(this); - if (_elements.size()) { - Msg::Error("[Rec2DVertex] normal ?"); + if (_elements.size()) Rec2DData::addVert(-REC2D_NUMB_VERT, -getQual()); - } } void Rec2DVertex::reveal() @@ -3200,6 +3280,21 @@ bool Rec2DElement::has(const Rec2DElement *rel) const return false; } +void Rec2DElement::print() const +{ + int num[4]; + for (int i = 0; i < _numEdge; ++i) { + if (_elements[i]) + num[i] = _elements[i]->getNum(); + else + num[i] = 0; + } + if (_numEdge == 3) + Msg::Info("tri %d - %d %d %d - nRA %d", getNum(), num[0], num[1], num[2], _actions.size()); + if (_numEdge == 4) + Msg::Info("quad %d - %d %d %d %d - nRA %d", getNum(), num[0], num[1], num[2], num[3], _actions.size()); +} + void Rec2DElement::add(Rec2DEdge *re) { int i; @@ -3375,8 +3470,8 @@ double Rec2DElement::getAngle(const Rec2DVertex *rv) const double ang = atan2(vert[i0]->v() - rv->v(), vert[i0]->u() - rv->u()) - atan2(vert[i1]->v() - rv->v(), vert[i1]->u() - rv->u()); - static int a = -1; - if (++a < 1) Msg::Warning("FIXME use real angle instead of parametric angle"); + static unsigned int a = 0; + if (++a < 2) Msg::Warning("FIXME use real angle instead of parametric angle"); if (ang < .0) return ang + 2.*M_PI; @@ -3554,10 +3649,12 @@ bool moreRec2DNode::operator()(Rec2DNode *rn1, Rec2DNode *rn2) const } Rec2DNode::Rec2DNode(Rec2DNode *father, Rec2DAction *ra, - double &bestEndGlobQual, int depth ) -: _father(father), _ra(ra), _globalQuality(.0), _bestEndGlobQual(.0), - _createdActions(NULL), _dataChange(NULL) + double &bestEndGlobQual, int depth) +: _father(NULL), _ra(ra), _globalQuality(.0), _bestEndGlobQual(.0), + _createdActions(NULL), _dataChange(NULL), _remainingTri(Rec2DData::getNumTri()), + _d(depth), _elementOrigin(NULL) { + if (_ra) _ra->addPointing(); for (int i = 0; i < REC2D_NUMB_SONS; ++i) _son[i] = NULL; @@ -3568,23 +3665,27 @@ Rec2DNode::Rec2DNode(Rec2DNode *father, Rec2DAction *ra, if (!depth) { _globalQuality = _ra->getReward(); - _remainingTri = father->getNumTri() - _ra->getNumElement(); _bestEndGlobQual = bestEndGlobQual = _globalQuality; } else { std::vector<Rec2DElement*> neighbours; if (_ra) { - _ra->getNeighbElemWithActions(neighbours); + if (_father) + _elementOrigin = _father->_elementOrigin; // else, = NULL + _ra->getNeighbElemWithActions(neighbours, _elementOrigin); _dataChange = Rec2DData::getNewDataChange(); _ra->apply(_dataChange, _createdActions); - _ra->addPointing(); + if (_createdActions) { + for (unsigned int i = 0; i < _createdActions->size(); ++i) + (*_createdActions)[i]->addPointing(); + } + _remainingTri = Rec2DData::getNumTri(); } - _remainingTri = Rec2DData::getNumElement(); _globalQuality = Rec2DData::getGlobalQuality(); Recombine2D::incNumChange(); std::vector<Rec2DAction*> actions; - Recombine2D::nextTreeActions(actions, neighbours); + Recombine2D::nextTreeActions(actions, neighbours, _elementOrigin); if (actions.empty()) { _bestEndGlobQual = _globalQuality; @@ -3593,6 +3694,11 @@ Rec2DNode::Rec2DNode(Rec2DNode *father, Rec2DAction *ra, } else { for (unsigned int i = 0; i < actions.size(); ++i) { + + if (depth < 0 && depth > -7) { + Msg::Info("| %d %d/%d", -depth, i+1, actions.size()); + } + double bestSonEGQ; _son[i] = new Rec2DNode(this, actions[i], bestSonEGQ, depth-1); if (bestSonEGQ > _bestEndGlobQual) { @@ -3612,19 +3718,46 @@ Rec2DNode::Rec2DNode(Rec2DNode *father, Rec2DAction *ra, _dataChange = NULL; } } + _father = father; } Rec2DNode::~Rec2DNode() { - for (int i = 0; i < REC2D_NUMB_SONS; ++i) + int i = -1; + while (++i < REC2D_NUMB_SONS && _son[i]) { + _son[i]->rmvFather(this); delete _son[i]; - if (_ra) + } + if (_createdActions) { + for (unsigned int i = 0; i < _createdActions->size(); ++i) { + //Msg::Info("want to del action %d", (*_createdActions)[i]); + (*_createdActions)[i]->rmvPointing(); + delete (*_createdActions)[i]; + } + delete _createdActions; + } + if (_ra) { _ra->rmvPointing(); + _ra = NULL; + } + if (_father) { + _father->rmvSon(this); + if (!_father->hasSon() && _father->canBeDeleted()) + delete _father; + } +} + +bool Rec2DNode::canBeDeleted() +{ + return _father && _father->_father; } Rec2DNode* Rec2DNode::selectBestNode() { for (int i = 1; i < REC2D_NUMB_SONS; ++i) { + static int a = -1; + if (++a < 1) Msg::Warning("FIXME !!!"); + if (_son[i]) _son[i]->rmvFather(this); delete _son[i]; _son[i] = NULL; } @@ -3645,13 +3778,22 @@ void Rec2DNode::develop(int depth, double &bestEndGlobQual) bool delChange = !_dataChange; _bestEndGlobQual = .0; std::vector<Rec2DElement*> neighbours; - if (!_son[0]) - _ra->getNeighbElemWithActions(neighbours); + if (!_son[0]) { + Rec2DElement *elemOrigin = NULL; + if (_father) + elemOrigin = _father->_elementOrigin; + _ra->getNeighbElemWithActions(neighbours, elemOrigin); + } if (!_dataChange) { + bool hadAction = _createdActions; _dataChange = Rec2DData::getNewDataChange(); _ra->apply(_dataChange, _createdActions); - _ra->addPointing(); + if (_createdActions && !hadAction) { + for (unsigned int i = 0; i < _createdActions->size(); ++i) + (*_createdActions)[i]->addPointing(); + } + _remainingTri = Rec2DData::getNumTri(); } if (_son[0]) { @@ -3671,7 +3813,7 @@ void Rec2DNode::develop(int depth, double &bestEndGlobQual) else { Recombine2D::incNumChange(); std::vector<Rec2DAction*> actions; - Recombine2D::nextTreeActions(actions, neighbours); + Recombine2D::nextTreeActions(actions, neighbours, _elementOrigin); if (actions.empty()) _bestEndGlobQual = _globalQuality; @@ -3703,16 +3845,14 @@ bool Rec2DNode::makeChanges() if (_dataChange || !_ra) return false; _dataChange = Rec2DData::getNewDataChange(); -#ifdef REC2D_DRAW // draw state at origin - //double time = Cpu(); - _ra->color(0, 0, 200); - CTX::instance()->mesh.changed = ENT_ALL; - drawContext::global()->draw(); - //while (Cpu()-time < REC2D_WAIT_TIME) +#if 0//def REC2D_DRAW // draw state at origin + double time = Cpu(); + //_ra->color(0, 0, 200); + Recombine2D::drawStateOrigin(); + while (Cpu()-time < REC2D_WAIT_TIME) FlGui::instance()->check(); #endif _ra->apply(_dataChange, _createdActions); - Rec2DData::setNumTri(_remainingTri); Recombine2D::incNumChange(); return true; } diff --git a/Mesh/meshGFaceRecombine.h b/Mesh/meshGFaceRecombine.h index de80ad662be644b0aebca408de5e566452f9701b..f91c87327e8ce8d7669191c1463d3174e3374325 100644 --- a/Mesh/meshGFaceRecombine.h +++ b/Mesh/meshGFaceRecombine.h @@ -12,7 +12,7 @@ #define REC2D_EDGE_BASE 2 #define REC2D_EDGE_QUAD 1 -#define REC2D_NUMB_VERT 2 +#define REC2D_NUMB_VERT 1 #define REC2D_ALIGNMENT .5 #define REC2D_NUMB_SONS 6 @@ -65,10 +65,12 @@ class Recombine2D { bool developTree(); int getNumTri() const; static void nextTreeActions(std::vector<Rec2DAction*>&, - const std::vector<Rec2DElement*> &neighbours); + const std::vector<Rec2DElement*> &neighbours, + Rec2DElement*& ); inline void setStrategy(int s) {_strategy = s;} void drawState(double shiftx, double shifty) const; + static void drawStateCur(double dx, double dy) {_cur->drawState(dx, dy);} void printState() const; static void drawStateOrigin(); @@ -96,8 +98,7 @@ class Rec2DData { Action(const Rec2DAction *ra, unsigned int pos) : action((Rec2DAction*)ra), position((int)pos) {} }; - template<class T> - friend void std::swap(T&, T&); + template<class T> friend void std::swap(T&, T&); struct gterAction { bool operator()(Action*, Action*) const; }; @@ -138,7 +139,6 @@ class Rec2DData { std::vector<MQuadrangle*> _quad; #endif static inline int getNumTri() {return _cur->_remainingTri;} - static inline void setNumTri(int n) {_cur->_remainingTri = n;} static inline int getNumEndNode() {return _cur->_endNodes.size();} static inline int getNumElement() {return _cur->_elements.size();} @@ -196,10 +196,9 @@ class Rec2DData { static void rmv(const Rec2DVertex*); static void rmv(const Rec2DElement*); static void rmv(const Rec2DAction*); + static bool has(const Rec2DAction*); - static inline void addEndNode(const Rec2DNode *rn) { - _cur->_endNodes.push_back((Rec2DNode*)rn); - } + static void addEndNode(const Rec2DNode*); static void sortEndNode(); static inline void drawEndNode(int num); @@ -303,11 +302,13 @@ class Rec2DAction { void *_dataAction; // Rec2DData::Action* friend void Rec2DData::add(const Rec2DAction*); friend void Rec2DData::rmv(const Rec2DAction*); + template<class T> friend void std::swap(T&, T&); public : Rec2DAction(); - virtual ~Rec2DAction() {Msg::Error("deleting %d", this);} + virtual ~Rec2DAction() {} virtual void hide() = 0; + static void hide(Rec2DAction*); virtual void reveal() = 0; virtual bool checkCoherence() const = 0; @@ -321,8 +322,10 @@ class Rec2DAction { virtual Rec2DVertex* getVertex(int) const = 0; virtual int getNumElement() = 0; virtual void getElements(std::vector<Rec2DElement*>&) const = 0; - virtual void getNeighbourElements(std::vector<Rec2DElement*>&) const = 0; - virtual void getNeighbElemWithActions(std::vector<Rec2DElement*>&) const = 0; + virtual void getNeighbourElements(std::vector<Rec2DElement*>&, + Rec2DElement* ) const = 0; + virtual void getNeighbElemWithActions(std::vector<Rec2DElement*>&, + Rec2DElement* ) const = 0; virtual int getNum(double shiftx, double shifty) = 0; virtual Rec2DElement* getRandomElement() const = 0; //virtual void print() = 0; @@ -354,7 +357,8 @@ class Rec2DTwoTri2Quad : public Rec2DAction { public : Rec2DTwoTri2Quad(Rec2DElement*, Rec2DElement*); - ~Rec2DTwoTri2Quad() {Msg::Error("deleting %d", this);if (_col) Msg::Error("[Rec2DTwoTri2Quad] have collapse");hide();} + ~Rec2DTwoTri2Quad() {} + void operator delete(void*); virtual void hide(); virtual void reveal(); virtual bool checkCoherence() const; @@ -368,8 +372,10 @@ class Rec2DTwoTri2Quad : public Rec2DAction { virtual inline Rec2DVertex* getVertex(int i) const {return _vertices[i];} //- virtual inline int getNumElement() {return 2;} virtual void getElements(std::vector<Rec2DElement*>&) const; - virtual void getNeighbourElements(std::vector<Rec2DElement*>&) const; - virtual void getNeighbElemWithActions(std::vector<Rec2DElement*>&) const; + virtual void getNeighbourElements(std::vector<Rec2DElement*>&, + Rec2DElement* ) const; + virtual void getNeighbElemWithActions(std::vector<Rec2DElement*>&, + Rec2DElement* ) const; virtual int getNum(double shiftx, double shifty); virtual Rec2DElement* getRandomElement() const; //virtual void print(); @@ -396,7 +402,8 @@ class Rec2DCollapse : public Rec2DAction { public : Rec2DCollapse(Rec2DTwoTri2Quad*); - ~Rec2DCollapse() {Msg::Error("deleting %d", this);_rec->_col = NULL; hide();} + ~Rec2DCollapse() {} + void operator delete(void*); virtual void hide(); virtual void reveal(); virtual bool checkCoherence() const {return _rec->checkCoherence();} @@ -417,12 +424,10 @@ class Rec2DCollapse : public Rec2DAction { virtual void getElements(std::vector<Rec2DElement*> &vec) const { _rec->getElements(vec); } - virtual void getNeighbourElements(std::vector<Rec2DElement*> &vec) const { - _rec->getNeighbourElements(vec); - } - virtual void getNeighbElemWithActions(std::vector<Rec2DElement*> &vec) const { - _rec->getNeighbElemWithActions(vec); - } + virtual void getNeighbourElements(std::vector<Rec2DElement*> &, + Rec2DElement* ) const; + virtual void getNeighbElemWithActions(std::vector<Rec2DElement*> &vec, + Rec2DElement *rel ) const; virtual int getNum(double shiftx, double shifty) { return -1; } @@ -456,7 +461,7 @@ class Rec2DEdge { public : Rec2DEdge(Rec2DVertex*, Rec2DVertex*); - ~Rec2DEdge() {hide();} + ~Rec2DEdge() {if (_pos > -1) hide();} void hide(); void reveal(); bool checkCoherence() const; @@ -518,7 +523,7 @@ class Rec2DVertex { public : Rec2DVertex(MVertex*); Rec2DVertex(Rec2DVertex*, double angle); - ~Rec2DVertex() {hide();} + ~Rec2DVertex() {if (_pos > -1) hide();} void hide(); void reveal(); bool checkCoherence() const; @@ -583,7 +588,18 @@ class Rec2DVertex { bool _recursiveBoundParity(const Rec2DVertex *prev, int p0, int p1); void _updateQualAngle(); inline double _angle2Qual(double ang) const { - return 1. - fabs(ang*2./M_PI - 1.); + static int a = -1; + if (++a < 1) Msg::Warning("regarder angle 2 qual"); + static const double angMin = M_PI/200; + static const double angMax = M_PI - angMin; + static const double min = std::log(4/M_PI*angMin) / std::log(2); + static const double log2 = std::log(2); + + if (ang < angMin || ang > angMax) return min; + if (ang < M_PI/2) + return std::log(4/M_PI * ang) / log2; + else + return std::log(4 - 4/M_PI * ang) / log2; } }; @@ -593,7 +609,7 @@ class Rec2DElement { int _numEdge; Rec2DEdge *_edges[4]; Rec2DElement *_elements[4]; // NULL if no neighbour - std::vector<Rec2DAction*> _actions; + std::vector<Rec2DAction*> _actions;; int _pos; friend void Rec2DData::add(const Rec2DElement*); @@ -602,12 +618,13 @@ class Rec2DElement { public : Rec2DElement(MTriangle*, const Rec2DEdge**, Rec2DVertex **rv = NULL); Rec2DElement(MQuadrangle*, const Rec2DEdge**, Rec2DVertex **rv = NULL); - ~Rec2DElement() {hide();} + ~Rec2DElement() {if (_pos > -1) hide();} void hide(); void reveal(Rec2DVertex **rv = NULL); bool checkCoherence() const; bool has(const Rec2DVertex*) const; bool has(const Rec2DElement*) const; + void print() const; bool inline isTri() const {return _numEdge == 3;} bool inline isQuad() const {return _numEdge == 4;} @@ -671,21 +688,56 @@ class Rec2DNode { Rec2DNode *_son[REC2D_NUMB_SONS]; Rec2DAction *_ra; double _globalQuality, _bestEndGlobQual; - int _remainingTri; std::vector<Rec2DAction*> *_createdActions; - Rec2DDataChange *_dataChange; + int _remainingTri; + const int _d; + Rec2DElement *_elementOrigin; public : Rec2DNode(Rec2DNode *father, Rec2DAction*, double &bestEndGlobQual, int depth = -1); ~Rec2DNode(); + bool canBeDeleted(); Rec2DNode* selectBestNode(); void recoverSequence(); - void rmvSon(Rec2DNode*); + //void rmvSon(Rec2DNode*); void develop(int depth, double &bestEndGlobQual); inline bool hasSon() const {return _son[0];} + void rmvFather(Rec2DNode *n) { + if (_father != n) { + Msg::Error("have not this father"); + return; + } + _father = NULL; + } + bool rmvSon(Rec2DNode *n) { + int indexSon = -1, i = -1; + while (++i < REC2D_NUMB_SONS && _son[i]) { + if (_son[i] == n) indexSon = i; + } + if (indexSon == -1) { + Msg::Info("im %d", this); + for (int i = 0; i < REC2D_NUMB_SONS; ++i) { + Msg::Info("son%d %d", i, _son[i]); + } + Msg::Error("son %d not found", n); + return false; + } + else { + if (indexSon != --i) + _son[indexSon] = _son[i]; + _son[i] = NULL; + } + return true; + } + bool hasSon(Rec2DNode *n) { + if (!n) return false; + int i = -1; + while (++i < REC2D_NUMB_SONS && _son[i] != n); + return i < REC2D_NUMB_SONS; + } bool makeChanges(); bool revertChanges(); @@ -694,6 +746,29 @@ class Rec2DNode { inline Rec2DAction* getAction() const {return _ra;} inline double getGlobQual() const {return _globalQuality;} inline int getNumTri() const {return _remainingTri;} + + void draw(double dx, double dy) { + if (_father) + _father->_mkChgSinceBeginning(); + if (_dataChange) Msg::Error("_Ber_"); + _dataChange = Rec2DData::getNewDataChange(); + _ra->apply(_dataChange, _createdActions); + _dataChange = NULL; + Recombine2D::drawStateCur(dx, dy); + } + + private : + void _mkChgSinceBeginning() { + if (_father) + _father->_mkChgSinceBeginning(); + else if (!_ra) return; + if (_dataChange) Msg::Error("_Ber_"); + _dataChange = Rec2DData::getNewDataChange(); + _ra->apply(_dataChange, _createdActions); + _dataChange = NULL; + static int a = -1; + if (++a < 1) Msg::Warning("FIXME pas propre du tout"); + } }; #endif