diff --git a/Mesh/meshGFaceRecombine.cpp b/Mesh/meshGFaceRecombine.cpp index 6dd00867c26d158c4be44a4d4c591be7dcc6402c..53bfff83778452ed2900f928d48b66fdc8433eb7 100644 --- a/Mesh/meshGFaceRecombine.cpp +++ b/Mesh/meshGFaceRecombine.cpp @@ -7,13 +7,10 @@ // Amaury Johnen (a.johnen@ulg.ac.be) // -#define REC2D_EDGE_BASE 1 -#define REC2D_EDGE_QUAD 1 -#define REC2D_ALIGNMENT .5 #define REC2D_WAIT_TIME .01 #define REC2D_NUM_ACTIO 1000 -// #define REC2D_SMOOTH + #define REC2D_SMOOTH #define REC2D_DRAW #include "meshGFaceRecombine.h" @@ -44,6 +41,7 @@ int otherParity(int a) { /*******************/ Recombine2D::Recombine2D(GFace *gf) : _gf(gf) { + laplaceSmoothing(_gf,100); if (Recombine2D::_current != NULL) { Msg::Warning("[Recombine2D] An instance already in execution"); return; @@ -234,9 +232,12 @@ bool Recombine2D::recombine() delete nextAction; } + _data->printState(); #ifdef REC2D_SMOOTH laplaceSmoothing(_gf,100); #endif + CTX::instance()->mesh.changed = (ENT_ALL); + drawContext::global()->draw(); return 1; } @@ -350,10 +351,8 @@ bool Recombine2D::_remainAllQuad(Rec2DAction *action) v->setAssumedParity(par); v->getTriangles(neighbours); } - else if (p[i+j] != par) { - Msg::Info("oui a %d, %d", p[i+j], par); + else if (p[i+j] != par) Rec2DData::associateAssumedParity(p[i+j], par, touched); - } } } @@ -369,7 +368,7 @@ bool Recombine2D::_remainAllQuad(Rec2DAction *action) int p[3]; (*itTri)->getAssumedParities(p); - //Msg::Info("tri %d [%d %d %d]", (*itel)->getNum(), p[0], p[1], p[2]); + //Msg::Info("tri %d [%d %d %d]", (*itel)->getNum(), p[0], p[1], p[2]); bool hasIdentical = false; for (int i = 0; i < 3; ++i) { @@ -384,7 +383,7 @@ bool Recombine2D::_remainAllQuad(Rec2DAction *action) Rec2DData::revertAssumedParities(); return false; } - //Msg::Info("has identical"); + //Msg::Info("has identical"); bool hasAction = false; std::map<Rec2DVertex*, std::vector<int> > suggestions; @@ -397,7 +396,7 @@ bool Recombine2D::_remainAllQuad(Rec2DAction *action) Rec2DData::revertAssumedParities(); return false; } - //Msg::Info("suggest %d", suggestions.size()); + //Msg::Info("suggest %d", suggestions.size()); std::map<Rec2DVertex*, std::vector<int> >::iterator itSug; itSug = suggestions.begin(); @@ -423,7 +422,6 @@ bool Recombine2D::_remainAllQuad(Rec2DAction *action) } else if ((par/2)*2 != (oldPar/2)*2) { //Msg::Info("c"); - Msg::Info("oui b %d, %d", oldPar, par); if (oldPar < par) { int a = oldPar; oldPar = par; @@ -441,8 +439,6 @@ bool Recombine2D::_remainAllQuad(Rec2DAction *action) Rec2DData::revertAssumedParities(); return false; } - else - Msg::Error("SHOULD NOT HAPPEN 2"); } } neighbours.erase(itTri); @@ -513,6 +509,9 @@ void Rec2DData::remove(Rec2DEdge *re) void Rec2DData::remove(Rec2DVertex *rv) { _current->_vertices.erase(rv); + static int a = -1; + if (++a < 1) + Msg::Warning("FIXME Verifier element supprim�"); } void Rec2DData::remove(Rec2DElement *rel) @@ -588,19 +587,17 @@ void Rec2DData::printState() iter_re ite; long double valEdge = .0; for (ite = firstEdge(); ite != lastEdge(); ++ite) { - valEdge += (*ite)->getQual(); + valEdge += (long double)(*ite)->getQual(); } - Msg::Info("valEdge : %g >< %g", valEdge, _valEdge); + Msg::Info("valEdge : %g >< %g", (double)valEdge, _valEdge); iter_rv itv; long double valVert = .0; for (itv = firstVertex(); itv != lastVertex(); ++itv) { - valVert += (*itv)->getQual(); + valVert += (long double)(*itv)->getQual(); if ((*itv)->getParity() == -1 || (*itv)->getParity() == 1) Msg::Error("parity %d, I'm very angry", (*itv)->getParity()); } - Msg::Info("valVert : %g >< %g", valVert, _valVert); - Msg::Info(" : %g", valVert); - Msg::Info(" : %g", _valVert); + Msg::Info("valVert : %g >< %g", (double)valVert, _valVert); } int Rec2DData::getNewParity() @@ -635,7 +632,7 @@ void Rec2DData::removeParity(Rec2DVertex *rv, int p) ++i; } if (!b) - Msg::Error("[Rec2DData] No vertex"); + Msg::Error("[Rec2DData] No vertex 1"); } void Rec2DData::associateParity(int pOld, int pNew) @@ -709,7 +706,7 @@ void Rec2DData::removeAssumedParity(Rec2DVertex *rv, int p) ++i; } if (!b) - Msg::Error("[Rec2DData] No vertex"); + Msg::Error("[Rec2DData] No vertex 2"); } void Rec2DData::saveAssumedParity(Rec2DVertex *rv, int p) @@ -1039,7 +1036,8 @@ bool Rec2DTwoTri2Quad::whatWouldYouDo /** Rec2DEdge **/ /*****************/ Rec2DEdge::Rec2DEdge(Rec2DVertex *rv0, Rec2DVertex *rv1) -: _rv0(rv0), _rv1(rv1), _weight(REC2D_EDGE_BASE), _boundary(-1), _lastUpdate(-2) +: _rv0(rv0), _rv1(rv1), _boundary(-1), _lastUpdate(-2), + _weight(REC2D_EDGE_BASE+2*REC2D_EDGE_QUAD) { _rv0->add(this); _rv1->add(this); @@ -1076,22 +1074,18 @@ double Rec2DEdge::getQual() return _qual; } -double Rec2DEdge::addNeighbour() -{ - if (++_boundary > 1) - Msg::Error("[Rec2DEdge] Too much boundary element"); -} - -double Rec2DEdge::addQuadNeighbour() +void Rec2DEdge::_addWeight(double val) { - _weight += REC2D_EDGE_QUAD; + _weight += val; if (_weight > REC2D_EDGE_BASE + 2*REC2D_EDGE_QUAD) - Msg::Error("[Rec2DEdge] Weight too higher : %d (%d max)", + Msg::Error("[Rec2DEdge] Weight too high : %d (%d max)", _weight, REC2D_EDGE_BASE + 2*REC2D_EDGE_QUAD ); - Rec2DData::addEdge(REC2D_EDGE_QUAD, REC2D_EDGE_QUAD*getQual()); + if (_weight < REC2D_EDGE_BASE) + Msg::Error("[Rec2DEdge] Weight too low : %d (%d min)", + _weight, REC2D_EDGE_BASE ); + Rec2DData::addEdge(val, val*getQual()); } - Rec2DElement* Rec2DEdge::getSingleElement(Rec2DEdge *re) { std::vector<Rec2DElement*> elem; @@ -1198,8 +1192,10 @@ Rec2DVertex::~Rec2DVertex() Rec2DData::removeParity(this, _parity); if (_assumedParity) Rec2DData::removeAssumedParity(this, _assumedParity); - Rec2DData::remove(this); - Rec2DData::addVert(-1, -getQual()); + if (_isMesh) { + Rec2DData::remove(this); + Rec2DData::addVert(-1, -getQual()); + } } void Rec2DVertex::initStaticTable() @@ -1297,6 +1293,19 @@ bool Rec2DVertex::_recursiveBoundParity(Rec2DVertex *prevRV, int p0, int p1) return false; } +void Rec2DVertex::setOnBoundary() +{ + if (_onWhat > 0) { + if (_isMesh) { + Rec2DData::addValVert(-getQual()); + _onWhat = 0; + Rec2DData::addValVert(getQual()); + } + else + _onWhat = 0; + } +} + void Rec2DVertex::setParity(int p) { if (_parity) { @@ -1304,7 +1313,10 @@ void Rec2DVertex::setParity(int p) Rec2DData::removeParity(this, _parity); } _parity = p; - _assumedParity = 0; + if (_assumedParity) { + Rec2DData::removeAssumedParity(this, _assumedParity); + _assumedParity = 0; + } Rec2DData::addParity(this, _parity); } @@ -1316,7 +1328,10 @@ void Rec2DVertex::setParityWD(int pOld, int pNew) if (pOld != _parity) Msg::Error("[Rec2DVertex] Old parity was not correct"); _parity = pNew; - _assumedParity = 0; + if (_assumedParity) { + Rec2DData::removeAssumedParity(this, _assumedParity); + _assumedParity = 0; + } } int Rec2DVertex::getAssumedParity() const @@ -1329,7 +1344,7 @@ int Rec2DVertex::getAssumedParity() const bool Rec2DVertex::setAssumedParity(int p) { if (p == _assumedParity) { - Msg::Warning("[Rec2DVertex] Already have this assumed parity"); + //Msg::Warning("[Rec2DVertex] Already have this assumed parity"); return false; } if (p == _parity) { @@ -1365,8 +1380,13 @@ void Rec2DVertex::revertAssumedParity(int p) _assumedParity = 0; } } - else + else { + if (_assumedParity) { + Rec2DData::removeAssumedParity(this, _assumedParity); + } _assumedParity = p; + Rec2DData::addAssumedParity(this, _assumedParity); + } } void Rec2DVertex::getTriangles(std::set<Rec2DElement*> &tri) @@ -1479,7 +1499,9 @@ void Rec2DVertex::remove(Rec2DElement *rel) { unsigned int i = 0; while (i < _elements.size()) { - if (_elements[i] == rel) { + if (_elements[i] == rel) { + if (_isMesh) + Rec2DData::addValVert(getGain(-1)); _elements[i] = _elements.back(); _elements.pop_back(); return; @@ -1514,6 +1536,7 @@ Rec2DElement::Rec2DElement(Rec2DEdge **edges) : _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); @@ -1531,6 +1554,10 @@ Rec2DElement::~Rec2DElement() if (_actions.size()) Msg::Error("[Rec2DElement] I didn't want to be deleted :'("); for (int i = 0; i < _numEdge; ++i) { + if (_numEdge == 3) + _edges[i]->remHasTri(); + else + _edges[i]->remHasQuad(); if (_elements[i]) _elements[i]->removeNeighbour(_edges[i], this); } @@ -1558,9 +1585,10 @@ void Rec2DElement::add(Rec2DEdge *re) if (i == _numEdge) Msg::Error("[Rec2DElement] Already %d edges, can't add anymore", _numEdge); - if (_numEdge == 4) - re->addQuadNeighbour(); - re->addNeighbour(); + if (_numEdge == 3) + re->addHasTri(); + else + re->addHasQuad(); } bool Rec2DElement::has(Rec2DEdge *re) const diff --git a/Mesh/meshGFaceRecombine.h b/Mesh/meshGFaceRecombine.h index 4ced625328a908ea603f849138795b0f01b2a0ab..241152687621068f1730e1bee0d6664a8d9fbe8a 100644 --- a/Mesh/meshGFaceRecombine.h +++ b/Mesh/meshGFaceRecombine.h @@ -10,6 +10,10 @@ #ifndef _MESH_GFACE_RECOMBINE_H_ #define _MESH_GFACE_RECOMBINE_H_ +#define REC2D_EDGE_BASE 2 +#define REC2D_EDGE_QUAD 1 +#define REC2D_ALIGNMENT .5 + #include "GFace.h" #include "BackgroundMesh.h" //#include "GModel.h" @@ -190,29 +194,31 @@ class Rec2DEdge { Rec2DVertex *_rv0, *_rv1; double _qual; int _lastUpdate, _weight; - int _boundary; + int _boundary; // pourrait faire sans ! public : Rec2DEdge(Rec2DVertex*, Rec2DVertex*); ~Rec2DEdge(); double getQual(); - double addNeighbour(); - double addQuadNeighbour(); + inline double addHasTri() {_addWeight(-REC2D_EDGE_QUAD); ++_boundary;} + inline double remHasTri() {_addWeight(REC2D_EDGE_QUAD); --_boundary;} + inline double addHasQuad() {++_boundary;} + inline double remHasQuad() {--_boundary;} inline bool isOnBoundary() const {return !_boundary;} - inline Rec2DVertex* getVertex(int i) const {if (i) return _rv1; return _rv0;} + inline Rec2DVertex* getVertex(int i) const {if (i) return _rv1; return _rv0;} + Rec2DVertex* getOtherVertex(Rec2DVertex*) const; static Rec2DElement* getSingleElement(Rec2DEdge*); void swap(Rec2DVertex *oldRV, Rec2DVertex *newRV); - Rec2DVertex* getOtherVertex(Rec2DVertex*) const; - private : void _computeQual(); double _straightAdimLength() const; double _straightAlignment() const; + void _addWeight(double); }; struct AngleData { @@ -247,7 +253,7 @@ class Rec2DVertex { static void getCommonElements(Rec2DVertex*, Rec2DVertex*, std::vector<Rec2DElement*>&); - inline void setOnBoundary() {if (_onWhat > 0) _onWhat = 0;} + inline void setOnBoundary(); inline bool getOnBoundary() const {return _onWhat < 1;} bool setBoundaryParity(int p0, int p1);