diff --git a/Mesh/meshRecombine2D.cpp b/Mesh/meshRecombine2D.cpp index c28768c0b3d22998c42f669faeee1801fcb8dfda..36f2e7a8318efb9b5431ce442f873a3bf0469e8b 100644 --- a/Mesh/meshRecombine2D.cpp +++ b/Mesh/meshRecombine2D.cpp @@ -326,9 +326,9 @@ int Recombine2D::apply() _gf->quadrangles = _quads; _applied = true; - _gf->model()->writeMSH("recSquare.msh"); - laplaceSmoothing(_gf,100); - _gf->model()->writeMSH("aftSquare.msh"); + //_gf->model()->writeMSH("recSquare.msh"); + laplaceSmoothing(_gf,10); + //_gf->model()->writeMSH("aftSquare.msh"); return 1; } diff --git a/Mesh/meshRecombine2D.h b/Mesh/meshRecombine2D.h index 5c624db8e584fd81aa8e4f3c8c1fd470b2bab031..eecfd57ca12b0b18859730aa7e3e86ea549f2411 100644 --- a/Mesh/meshRecombine2D.h +++ b/Mesh/meshRecombine2D.h @@ -22,16 +22,184 @@ class RecombTriangle; class Recomb2D_Node; class TrianglesUnion; class Rec2d_vertex; +class list_actions; +class Recombine2D; +//class list_actions; +//class list_actions::iterator; struct lessRecombTri { bool operator()(RecombTriangle *rt1, RecombTriangle *rt2) const; }; struct lessTriUnion { bool operator()(TrianglesUnion *, TrianglesUnion *) const; }; - +struct lessTriUnionInv { + bool operator()(TrianglesUnion *, TrianglesUnion *) const; +}; typedef std::set<RecombTriangle*,lessRecombTri> Set_Recomb; typedef std::map<MElement*,std::set<RecombTriangle*> > Map_Tri_Recomb; typedef std::map<MElement*,Recomb2D_Node*> Map_Tri_Node; +typedef std::map<MTriangle*, std::set<TrianglesUnion*> > mapTriUnion; +typedef std::set<TrianglesUnion*, lessTriUnionInv> setTriUnion; +typedef std::vector<setTriUnion> vectSetTriUnion; + +class list_actions { + private : + vectSetTriUnion _cont; + + public : + list_actions(int h) {_cont.reserve(h);} + + class iterator { + private : + int pos; + list_actions *la; + setTriUnion::iterator it; + + public : + void print() { + Msg::Info("iterator(pos %d, la %d, tu %d)", pos, la, *it); + } + iterator(list_actions *l, int i, setTriUnion::iterator t) { + pos = i; + la = l; + it = t; + } + iterator() { + pos = -1; + } + bool operator==(iterator a) const { + if (pos != a.pos) + return false; + if (pos < 0) + return true; + return it == a.it; + } + bool operator!=(iterator a) const { + if (pos != a.pos) + return true; + if (pos < 0) + return false; + return it != a.it; + } + iterator& operator=(const iterator &a) { + if (this != &a) { + pos = a.pos; + la = a.la; + it = a.it; + } + return *this; + } + TrianglesUnion* operator*() const { + //Msg::Info("pos %d", pos); + //Msg::Info(" "); + if (pos < 0) + return NULL; + return *it; + } + iterator& operator++() { + int p = pos; + ++it; + while (it == la->_end(p) && ++p != la->_size()) { + ++pos; + it = la->_begin(pos); + if (p != pos) + Msg::Error(" "); + } + return *this; + } + iterator operator++(int n) { + iterator t = *this; + int p = pos; + ++it; + while (it == la->_end(p) && ++p != la->_size()) { + ++pos; + it = la->_begin(pos); + } + return t; + } + inline int getPos() {return pos;} + }; + + int add(setTriUnion &s) { + setTriUnion::iterator it = s.begin(); + while (it != s.end()) { + if (find(*it) != end()) + s.erase(it++); + else + ++it; + } + _cont.push_back(s); + return _cont.size() - 1; + } + void remove(int a) { + for (; a < _cont.size(); a++) + _cont.pop_back(); + } + iterator find(TrianglesUnion* tu) { + if (_cont.empty()) + return end(); + for (int i = 0; i < _cont.size(); ++i) { + setTriUnion::iterator it = _cont[i].find(tu); + if (it != _cont[i].end()) + return iterator(this, i, it); + } + return end(); + } + iterator begin() { + if (_cont.empty()) + return iterator(this, -1, _begin()); + return iterator(this, 0, _begin()); + } + iterator end() { + return iterator(this, _cont.size() - 1, _end()); + } + void pop_back() { + _cont.pop_back(); + } + + void sizes(){ + switch (_cont.size()) { + case 3 : + Msg::Info("--Actions : %d + %d + %d", _cont[0].size(), _cont[1].size(), _cont[2].size()); + break; + case 2 : + Msg::Info("--Actions : %d + %d", _cont[0].size(), _cont[1].size()); + break; + case 1 : + Msg::Info("--Actions : %d", _cont[0].size()); + break; + default : + break; + } + //Msg::Info("%d sets", _cont.size()); + //for (int i = 0; i < _cont.size(); ++i) + // Msg::Info("[%d] %d", i+1, _cont[i].size()); + } + + private : + setTriUnion::iterator _end(int pos = -1) { + if (_cont.size() == 0) { + setTriUnion::iterator it; + return it; // Not clean ! + } + if (pos < 0) + return _cont.back().end(); + return _cont[pos].end(); + } + setTriUnion::iterator _begin(int pos = -1) { + if (_cont.size() == 0) { + setTriUnion::iterator it; + return it; // Not clean ! + } + if (pos < 0) + return _cont.front().begin(); + return _cont[pos].begin(); + } + inline int _size() {return _cont.size();} + +}; + + class Recombine2D { private : @@ -43,6 +211,7 @@ class Recombine2D { Map_Tri_Recomb _possibleRecomb; std::set<MElement*> _isolated; std::vector<MQuadrangle*> _quads; + static int ra; template <class E> void _buildEdgeToElement(std::vector<E*> &, e2t_cont &); @@ -57,15 +226,27 @@ class Recombine2D { ~Recombine2D(); int apply(); - int apply(bool); inline double getBenef() const {return _benef;} inline int numTriangle() const {return _isolated.size();} private : //std::set<TrianglesUnion*, lessTriUnion> _setQuads; std::list<TrianglesUnion*> _setQuads; - void _removeImpossible(std::list<TrianglesUnion*>::iterator); + std::list<TrianglesUnion*> _lastQuad; + mapTriUnion _possibleActions; + mapTriUnion _lessActions; + void _removeImpossible(TrianglesUnion*); void _recombine(bool); + + void _lookAhead(std::list<TrianglesUnion*>&, int horiz); + void _getIncompatibles(const TrianglesUnion*, setTriUnion&); + void _getNeighbors(const TrianglesUnion*, setTriUnion&); + void _addNeighbors(int horiz, std::vector<list_actions::iterator>&, int current, list_actions*); + void _removeNeighbors(int horiz, int current, list_actions*); + int _checkIsolatedTri(std::vector<list_actions::iterator>&, int size, std::set<MTriangle*>&); + + public : + int apply(bool); }; class RecombTriangle { @@ -135,9 +316,6 @@ class Rec2d_vertex { // GEntity : virtual Range<double> parBounds(int i) static double **_Vvalues; static double **_Vbenefs; - - void _initStaticTable(); - double _computeAngle(MVertex *, std::list<MTriangle*> &, std::set<GEdge*> &); public : Rec2d_vertex(MVertex *, std::list<MTriangle*> &, @@ -146,6 +324,12 @@ class Rec2d_vertex { inline void changeNumEl(int c) {_numEl += c;} double getReward(); double getReward(int); + //int onwhat() {return _onWhat;} + //int numel() {return _numEl;} + + private : + void _initStaticTable(); + double _computeAngle(MVertex *, std::list<MTriangle*> &, std::set<GEdge*> &); }; class TrianglesUnion { @@ -155,24 +339,31 @@ class TrianglesUnion { Rec2d_vertex **_vertices; MTriangle **_triangles; static int _RECOMPUTE; //incremented when a recombination is executed + public: static int _NumEdge, _NumVert; static double _ValEdge, _ValVert; private: - double _computeEdgeLength(GFace *, MVertex **, double *u, double *v, - int numIntermedPoint= 1); - double _computeAlignment(MEdge &, std::list<MTriangle*> &); - void _update(); - public : TrianglesUnion(GFace *, std::list<MTriangle*> &, std::list<MEdge> &, std::list<Rec2d_vertex*> &, std::map<MVertex*,double> &); bool operator<(TrianglesUnion &other); - inline double getEdgeValue() {return _embEdgeValue;} - inline double getNumTriangles() {return _numTri;} - inline MTriangle *getTriangle(int num) {return _triangles[num];} + void addTri(std::set<MTriangle*>&) const; + void removeTri(std::set<MTriangle*>&) const; + bool isIn(std::set<MTriangle*>&) const; + void addInfluence(int*, double*, std::map<Rec2d_vertex*, int>&) const; + void removeInfluence(int*, double*, std::map<Rec2d_vertex*, int>&) const; + static double computeReturn(const int*, const double*, const std::map<Rec2d_vertex*, int>&); + inline double getEdgeValue() const {return _embEdgeValue;} + inline double getVertValue() const {return _embVertValue;} + inline int getNumVerts() const {return _numEmbVert;} + inline int getNumEdges() const {return _numEmbEdge;} + inline int getNumVertices() const {return _numBoundVert;} + inline Rec2d_vertex* getVertex(int num) const {return _vertices[num];} + inline int getNumTriangles() const {return _numTri;} + inline MTriangle* getTriangle(int num) const {return _triangles[num];} void select() { _ValEdge -= _embEdgeValue; _NumEdge -= _numEmbEdge; @@ -184,7 +375,7 @@ class TrianglesUnion { } _RECOMPUTE++; } - MQuadrangle *createQuad() const; + MQuadrangle* createQuad() const; void print() { Msg::Info("Printing TU (%d,%d,%d,%d)", _numEmbVert, _numBoundVert, _numEmbEdge, _numTri); for (int i = 0; i < _numTri; i++) @@ -192,5 +383,11 @@ class TrianglesUnion { } static inline void addRec() {_RECOMPUTE++;} inline double getReturn() {return _globValIfExecuted;} + + private: + double _computeEdgeLength(GFace *, MVertex **, double *u, double *v, + int numIntermedPoint= 1); + double _computeAlignment(MEdge &, std::list<MTriangle*> &); + void _update(); }; #endif diff --git a/Mesh/meshRecombine2D_2.cpp b/Mesh/meshRecombine2D_2.cpp index 1543764f200ee781e8a56af7255e7ec5ff81d01c..1fcb2584beff77438ad65d1fc24eb5afd273008e 100644 --- a/Mesh/meshRecombine2D_2.cpp +++ b/Mesh/meshRecombine2D_2.cpp @@ -17,8 +17,8 @@ #include "Context.h" #include "OpenFile.h"//pas propre #include "Field.h" - -static int HORIZ = 20; +#include "OS.h" +#define HORIZ2 7 double **Rec2d_vertex::_Vvalues = NULL; double **Rec2d_vertex::_Vbenefs = NULL; @@ -27,6 +27,16 @@ int TrianglesUnion::_NumEdge = 0; int TrianglesUnion::_NumVert = 0; double TrianglesUnion::_ValEdge = .0; double TrianglesUnion::_ValVert = .0; +int Recombine2D::ra = 0; + +/* + a faire : + - modifier gain des edges + - fonction retournant qualite + - verifier la qualite + - action supplementaire (faire classe de base) + - Faire un super conteneur pour les actions +*/ Recombine2D::Recombine2D(GFace *gf) : _horizon(0), _gf(gf), _benef(.0), _applied(true) @@ -69,10 +79,10 @@ Recombine2D::Recombine2D(GFace *gf) std::map<MVertex*, Rec2d_vertex*>::iterator itV2N = mapV2N.begin(); std::list<std::map<MVertex*, std::list<MTriangle*> >::iterator> fourTri; for (; itvert != mapVert.end(); itvert++) { - if ((*itvert).second.size() == 4 && (*itvert).first->onWhat()->dim() == 2) + if (itvert->second.size() == 4 && itvert->first->onWhat()->dim() == 2) fourTri.push_back(itvert); - Rec2d_vertex *n = new Rec2d_vertex((*itvert).first, (*itvert).second, mapCornerVert); - itV2N = mapV2N.insert(itV2N, std::make_pair((*itvert).first,n)); + Rec2d_vertex *n = new Rec2d_vertex(itvert->first, itvert->second, mapCornerVert); + itV2N = mapV2N.insert(itV2N, std::make_pair(itvert->first,n)); TrianglesUnion::_NumVert++; TrianglesUnion::_ValVert += n->getReward(); } @@ -98,13 +108,13 @@ Recombine2D::Recombine2D(GFace *gf) { std::set<MVertex*> setVert; std::multiset<MEdge, Less_Edge> msetEdge; - std::list<MTriangle*>::iterator itTri = (*(*it4)).second.begin(); - for (; itTri != (*(*it4)).second.end(); itTri++) { + std::list<MTriangle*>::iterator itTri = (*it4)->second.begin(); + for (; itTri != (*it4)->second.end(); itTri++) { MVertex *vt; for (int i = 0; i < 3; i++) { msetEdge.insert((*itTri)->getEdge(i)); vt = (*itTri)->getVertex(i); - if (vt != (*(*it4)).first) + if (vt != (*it4)->first) setVert.insert(vt); } } @@ -118,10 +128,14 @@ Recombine2D::Recombine2D(GFace *gf) std::set<MVertex*>::iterator itsVert = setVert.begin(); for (; itsVert != setVert.end(); itsVert++) listVert.push_back(mapV2N[*itsVert]); - listVert.push_back(mapV2N[(*(*it4)).first]); + listVert.push_back(mapV2N[(*it4)->first]); } Msg::Info("%d",++j); - _setQuads.push_back(new TrianglesUnion(gf, (*(*it4)).second, listEmbEdge, listVert, mapV2LcUV)); + TrianglesUnion *tu = new TrianglesUnion(gf, (*it4)->second, listEmbEdge, listVert, mapV2LcUV); + std::list<MTriangle*>::iterator itTri = (*it4)->second.begin(); + for (; itTri != (*it4)->second.end(); itTri++) + _possibleActions[*itTri].insert(tu); + _setQuads.push_back(tu); } // Create 'TrianglesUnion' for pattern of 2 triangles @@ -134,22 +148,25 @@ Recombine2D::Recombine2D(GFace *gf) */ std::map<MEdge, std::list<MTriangle*> >::iterator itedge = mapEdge.begin(); for (; itedge != mapEdge.end(); itedge++) { - if ((*itedge).second.size() == 2) { + if (itedge->second.size() == 2) { std::list<MEdge> listEmbEdge; - listEmbEdge.push_back((*itedge).first); + listEmbEdge.push_back(itedge->first); std::list<Rec2d_vertex*> listVert; - listVert.push_back(mapV2N[(*itedge).first.getVertex(0)]); - listVert.push_back(mapV2N[(*itedge).first.getVertex(1)]); - TrianglesUnion *tu = new TrianglesUnion(gf, (*itedge).second, listEmbEdge, listVert, mapV2LcUV); + listVert.push_back(mapV2N[itedge->first.getVertex(0)]); + listVert.push_back(mapV2N[itedge->first.getVertex(1)]); + TrianglesUnion *tu = new TrianglesUnion(gf, itedge->second, listEmbEdge, listVert, mapV2LcUV); _setQuads.push_back(tu); TrianglesUnion::_NumEdge++; TrianglesUnion::_ValEdge += tu->getEdgeValue(); + std::list<MTriangle*>::iterator itTri = itedge->second.begin(); + for (; itTri != itedge->second.end(); itTri++) + _possibleActions[*itTri].insert(tu); } else - ;//Msg::Info("[bord] %d", (*itedge).second.size()); + ;//Msg::Info("[bord] %d", itedge->second.size()); } TrianglesUnion::addRec(); - _setQuads.sort(lessTriUnion()); + //_setQuads.sort(lessTriUnion()); _recombine(true); _applied = false; @@ -161,31 +178,324 @@ void Recombine2D::_recombine(bool a) SetBoundingBox(); int i = 0; - while (!_setQuads.empty() && i < 1000) { - std::list<TrianglesUnion*>::iterator it = _setQuads.begin(); - Msg::Info("------------------ %d", _setQuads.size()); - { - Msg::Info("Expected return %lf", (*it)->getReturn()); + std::list<TrianglesUnion*> vectTu; + + while (!_setQuads.empty() && i < 2000) { + TrianglesUnion *tu; + if (_lastQuad.empty()) { + if (vectTu.size() < 2) + tu = *std::max_element(_setQuads.begin(), _setQuads.end(), lessTriUnion()); + else { + vectTu.pop_front(); + //tu = *std::max_element(vectTu.begin(),vectTu.end(), lessTriUnion()); + tu = *vectTu.begin(); + } + vectTu.clear(); + vectTu.insert(vectTu.begin(), tu); + + Msg::Info("------------------ %d", _setQuads.size()); + _lookAhead(vectTu, HORIZ2); + } + else { + tu = *_lastQuad.begin(); + vectTu.clear(); + vectTu.insert(vectTu.begin(), tu); + std::set<MTriangle*> touched; + for (int i = 0; i < tu->getNumTriangles(); i++) { + touched.insert(tu->getTriangle(i)); + } + std::list<TrianglesUnion*>::iterator it = _lastQuad.begin(); + while (it != _lastQuad.end()) { + bool toBeErased = false; + for (int i = 0; i < (*it)->getNumTriangles(); i++) { + if (touched.find((*it)->getTriangle(i)) != touched.end()) + toBeErased = true; + } + if (toBeErased) + _lastQuad.erase(it++); + else + ++it; + } + //_lastQuad.erase(_lastQuad.begin()); + } + tu = *vectTu.begin(); + tu->select(); + _quads.push_back(tu->createQuad()); + _removeImpossible(tu); + { // draw Mesh + Msg::Info("Expected return %lf", tu->getReturn()); _applied = false; - apply(); + apply(true); _applied = false; CTX::instance()->mesh.changed = (ENT_ALL); //drawContext::global()->draw(); - //FlGui::instance()->check(); + FlGui::instance()->check(); drawContext::global()->draw(); - //if (!Msg::GetAnswer("Continue ?", 1, "no", "yes")) - // Msg::Info("I continue anyway :p"); - } - (*it)->select(); + double t = Cpu(); + while (Cpu() - t < .0001); + if (i % 1000 == 0) + if (!Msg::GetAnswer("Continue ?", 1, "no", "yes")) + Msg::Info("I continue anyway :p"); + } + + ++i; + } + Msg::Info("Done %d (%d)", i, _pairs.size()); +} + +void printIt(std::vector<list_actions::iterator> &vIt, int size) +{ + switch (size) { + case 3 : + Msg::Info("--Iterators : %d , %d , %d", vIt[0].getPos(), vIt[1].getPos(), vIt[2].getPos()); + break; + case 2 : + Msg::Info("--Iterators : %d , %d", vIt[0].getPos(), vIt[1].getPos()); + break; + case 1 : + Msg::Info("--Iterators : %d", vIt[0].getPos()); + break; + default : + break; + } +} + +void Recombine2D::_lookAhead(std::list<TrianglesUnion*> &candidate, int horiz) +{ + if (horiz < 1) + horiz = 1; + _lessActions.clear(); + + double maxReturn = .0; + //TrianglesUnion *bestAction; + int numbers[2] = {0, 0}; // number of embedded verts & edges + double values[2] = {.0, .0}; // embedded vert & edge values + std::set<MTriangle*> setTri; + std::map<Rec2d_vertex*, int> modifiedVert; + std::vector<list_actions::iterator> vecIt(horiz); + std::vector<std::pair<TrianglesUnion*, int> > bestSequence; + + list_actions la(horiz); + { + setTriUnion candidates; + _getIncompatibles(*candidate.begin(), candidates); + la.add(candidates); + } + + vecIt[0] = la.begin(); + (*vecIt[0])->addTri(setTri); + (*vecIt[0])->addInfluence(numbers, values, modifiedVert); + _addNeighbors(horiz, vecIt, 0, &la); + + int current = 1; + int num=0; + + while (current > 0) { + bool best = false; + // set first acceptable action for each step + while (current < horiz && vecIt[current-1] != la.end()) { + vecIt[current] = vecIt[current-1]; + while (++vecIt[current] != la.end() && (*vecIt[current])->isIn(setTri)); + if (vecIt[current] != la.end()) { + (*vecIt[current])->addTri(setTri); + (*vecIt[current])->addInfluence(numbers, values, modifiedVert); + _addNeighbors(horiz, vecIt, current, &la); + } + ++current; + } + + { // color + for (int i = 1; i < current && vecIt[i] != la.end(); ++i) { + TrianglesUnion *tu = *vecIt[i]; + int pos = vecIt[i].getPos(); + double frac = (double)pos / (double)(horiz-1); + unsigned int col; + //la.sizes(); + //Msg::Info("%d / %d -> %d", pos, horiz, (int)(200.*frac)); + col = CTX::instance()->packColor(50 - (int)(25.*frac), 200 - (int)(25.*frac), (int)(200.*frac), 255); + for (int j = 0; j < tu->getNumTriangles(); ++j) { + tu->getTriangle(j)->setCol(col); + } + } + } + + double expectedReturn = TrianglesUnion::computeReturn(numbers, values, modifiedVert); + if (maxReturn < expectedReturn) { + int sizeSequence = current; + if (vecIt[sizeSequence - 1] == la.end()) + --sizeSequence; + expectedReturn -= .1 * _checkIsolatedTri(vecIt, sizeSequence, setTri); + if (maxReturn < expectedReturn) { + maxReturn = expectedReturn; + //bestAction = *vecIt[0]; + bestSequence.resize(sizeSequence); + for (int i = 0; i < sizeSequence; ++i) + bestSequence[i] = std::make_pair(*vecIt[i], vecIt[i].getPos()); + { //color + best = true; + TrianglesUnion *tu = *vecIt[0]; + unsigned int col; + col = CTX::instance()->packColor(190, 0, 190, 255); + for (int j = 0; j < tu->getNumTriangles(); ++j) { + tu->getTriangle(j)->setCol(col); + } + } + } + } + else { //color + TrianglesUnion *tu = *vecIt[0]; + unsigned int col; + col = CTX::instance()->packColor(190, 0, 0, 255); + for (int j = 0; j < tu->getNumTriangles(); ++j) { + tu->getTriangle(j)->setCol(col); + } + } - _quads.push_back((*it)->createQuad()); + if (true || best) { // draw mesh + apply(false); + CTX::instance()->mesh.changed = (ENT_ALL); + FlGui::instance()->check(); + drawContext::global()->draw(); + double t = Cpu(); + while (Cpu() - t < .0001); + //if (i % 1 == 0) + if (/*false && best &&*/ !Msg::GetAnswer("Continue ?", 1, "no", "yes")) + Msg::Info("I continue anyway :p"); + best = false; + } - _removeImpossible(it); + { // decolor + for (int i = 0; i < current && vecIt[i] != la.end(); ++i) { + TrianglesUnion *tu = *vecIt[i]; + int pos = vecIt[i].getPos(); + double frac = (double)pos / (double)horiz; + unsigned int col; + col = CTX::instance()->packColor(255, 255, 0, 255); + for (int j = 0; j < tu->getNumTriangles(); ++j) { + tu->getTriangle(j)->setCol(col); + } + } + } - _setQuads.sort(lessTriUnion()); - i++; + if (vecIt[current-1] != la.end() || --current > 0) { + do { + (*vecIt[current-1])->removeTri(setTri); + (*vecIt[current-1])->removeInfluence(numbers, values, modifiedVert); + _removeNeighbors(horiz, current - 1, &la); + while (++vecIt[current-1] != la.end() && (*vecIt[current-1])->isIn(setTri)); + } while (vecIt[current-1] == la.end() && --current > 0); + if (current > 0) { + (*vecIt[current-1])->addTri(setTri); + (*vecIt[current-1])->addInfluence(numbers, values, modifiedVert); + _addNeighbors(horiz, vecIt, current - 1, &la); + } + } } - Msg::Info("Done %d (%d)", i, _pairs.size()); + + { // color + for (int i = 1; i < bestSequence.size(); ++i) { + TrianglesUnion *tu = bestSequence[i].first; + unsigned int col = CTX::instance()->packColor(50, 200, 0, 255); + for (int j = 0; j < tu->getNumTriangles(); ++j) { + tu->getTriangle(j)->setCol(col); + } + } + } + + candidate.clear(); + for (int i = 0; i < bestSequence.size(); ++i) { + candidate.insert(candidate.end(), bestSequence[i].first); + } +} + +void Recombine2D::_getIncompatibles(const TrianglesUnion *tu, setTriUnion &set) +{ + for (int i = 0; i < tu->getNumTriangles(); i++) { + mapTriUnion::iterator it = _lessActions.find(tu->getTriangle(i)); + if (it == _lessActions.end()) { + it = _possibleActions.find(tu->getTriangle(i)); + if (it == _possibleActions.end()) { + Msg::Error("[Rec2D] error no triangle !, stopping with partially filled set"); + } + _lessActions.insert(*it); + } + setTriUnion::iterator it2 = it->second.begin(); + for (; it2 != it->second.end(); ++it2) { + set.insert(*it2); + } + } +} + +void Recombine2D::_getNeighbors(const TrianglesUnion *tu, setTriUnion &set) +{ + setTriUnion incomp; + setTriUnion neighbors; + _getIncompatibles(tu, incomp); + setTriUnion::iterator it = incomp.begin(); + for (; it != incomp.end(); ++it) + _getIncompatibles(*it, neighbors); + it = incomp.begin(); + for (; it != incomp.end(); ++it) + neighbors.erase(*it); + it = neighbors.begin(); + for (; it != neighbors.end(); ++it) + set.insert(*it); +} + +void Recombine2D::_addNeighbors(int horiz, std::vector<list_actions::iterator> &vecIt, int current, list_actions *la) +{ + if (current < horiz - 1 && current > -1) { + //Msg::Info("+ra %d", ++ra); + setTriUnion neighbors; + _getNeighbors(*vecIt[current], neighbors); + la->add(neighbors); + } +} + +void Recombine2D::_removeNeighbors(int horiz, int current, list_actions *la) +{ + if (current < horiz - 1 && current > -1) { + //Msg::Info("-ra %d", --ra); + la->pop_back(); + } +} + + +int Recombine2D::_checkIsolatedTri(std::vector<list_actions::iterator> &vecIt, int size, std::set<MTriangle*> &seqTri) +{ + setTriUnion setTu; + for (int i = 0; i < size; ++i) { + _getIncompatibles(*vecIt[i], setTu); + } + + std::set<MTriangle*> setBoundaryTri; + setTriUnion::iterator it = setTu.begin(); + for (; it != setTu.end(); ++it) { + for (int i = 0; i < (*it)->getNumTriangles(); i++) + if (seqTri.find((*it)->getTriangle(i)) == seqTri.end()) + setBoundaryTri.insert((*it)->getTriangle(i)); + } + + int num = 0; + std::set<MTriangle*>::iterator itTri = setBoundaryTri.begin(); + for (; itTri != setBoundaryTri.end(); ++itTri) { + mapTriUnion::iterator it1 = _lessActions.find(*itTri); + if (it1 == _lessActions.end()) { + it1 = _possibleActions.find(*itTri); + if (it1 == _possibleActions.end()) { + Msg::Error("[Rec2D] error no triangle !, stopping with partially filled set"); + } + _lessActions.insert(*it1); + } + int numPossibleRecombinations = 0; + setTriUnion::iterator it2 = it1->second.begin(); + for (; it2 != it1->second.end(); ++it2) + if (setTu.find(*it2) == setTu.end()) + ++numPossibleRecombinations; + if (!numPossibleRecombinations) + ++num; + } + return num; } MQuadrangle *TrianglesUnion::createQuad() const @@ -222,24 +532,24 @@ MQuadrangle *TrianglesUnion::createQuad() const v2 = listBoundEdge.begin()->getMaxVertex(); std::list<MEdge>::iterator it = listBoundEdge.begin(); for (it++; it != listBoundEdge.end(); it++) { - if (v2 == (*it).getMinVertex()) { - v3 = (*it).getMaxVertex(); + if (v2 == it->getMinVertex()) { + v3 = it->getMaxVertex(); listBoundEdge.erase(it); break; } - if (v2 == (*it).getMaxVertex()) { - v3 = (*it).getMinVertex(); + if (v2 == it->getMaxVertex()) { + v3 = it->getMinVertex(); listBoundEdge.erase(it); break; } } for (it = listBoundEdge.begin(); it != listBoundEdge.end(); it++) { - if (v3 == (*it).getMinVertex()) { - v4 = (*it).getMaxVertex(); + if (v3 == it->getMinVertex()) { + v4 = it->getMaxVertex(); break; } - if (v3 == (*it).getMaxVertex()) { - v4 = (*it).getMinVertex(); + if (v3 == it->getMaxVertex()) { + v4 = it->getMinVertex(); break; } } @@ -250,50 +560,96 @@ MQuadrangle *TrianglesUnion::createQuad() const int Recombine2D::apply(bool a) { - if (!_haveParam || _applied) return 0; - - std::vector<MTriangle*> triangles2; - for (int i = 0; i < _gf->triangles.size(); i++) { - if (_isolated.find(_gf->triangles[i]) != _isolated.end()) - delete _gf->triangles[i]; - else - triangles2.push_back(_gf->triangles[i]); + //Msg::Info("(%d, %d, %d)", _quads.size(), _gf->triangles.size(), _isolated.size()); + if (a) { + std::vector<MTriangle*> triangles2; + for (int i = 0; i < _gf->triangles.size(); i++) { + if (_isolated.find(_gf->triangles[i]) != _isolated.end()) + delete _gf->triangles[i]; + else + triangles2.push_back(_gf->triangles[i]); + } + _gf->triangles = triangles2; + _gf->quadrangles = _quads; + _isolated.clear(); } - _gf->triangles = triangles2; - _gf->quadrangles = _quads; - _isolated.clear(); _applied = true; return 1; } -void Recombine2D::_removeImpossible(std::list<TrianglesUnion*>::iterator it) +void Recombine2D::_removeImpossible(TrianglesUnion *tu) { - std::set<MTriangle *> touched; + for (int i = 0; i < tu->getNumTriangles(); i++) { + _isolated.insert(tu->getTriangle(i)); + }// for test + + std::set<MTriangle*> touched; + for (int i = 0; i < tu->getNumTriangles(); i++) { + touched.insert(tu->getTriangle(i)); + } + + setTriUnion incomp; + std::set<MTriangle*>::iterator itTri = touched.begin(); + for (; itTri != touched.end(); ++itTri) { + mapTriUnion::iterator it = _possibleActions.find(*itTri); + if (it != _possibleActions.end()) { + setTriUnion::iterator it2 = it->second.begin(); + for (; it2 != it->second.end(); ++it2) + incomp.insert(*it2); + } + } + + setTriUnion::iterator itTu = incomp.begin(); + for (; itTu != incomp.end(); ++itTu) { + for (int i = 0; i < (*itTu)->getNumTriangles(); i++) { + mapTriUnion::iterator it4 = _possibleActions.find((*itTu)->getTriangle(i)); + it4->second.erase(*itTu); + TrianglesUnion *tu; + if (touched.find(it4->first) == touched.end()) + switch (it4->second.size()) { + case 1 : + _lastQuad.insert(_lastQuad.begin(), *it4->second.begin()); + tu = *it4->second.begin(); + unsigned int col; + col = CTX::instance()->packColor(0, 0, 0, 0); + for (int j = 0; j < tu->getNumTriangles(); ++j) + tu->getTriangle(j)->setCol(col); + break; + case 0 : + default : + break; + } + } + //_setQuads.erase(*itTu); //marche pas avec list + } - for (int i = 0; i < (*it)->getNumTriangles(); i++) { - touched.insert((*it)->getTriangle(i)); + std::list<TrianglesUnion*>::iterator it = _setQuads.begin(); + while (it != _setQuads.end()) { + if (incomp.find(*it) != incomp.end()) + it = _setQuads.erase(it); // replacement de _setQuads.erase(*itTu); + else + ++it; + } + + for (int i = 0; i < tu->getNumTriangles(); i++) { + _possibleActions.erase(tu->getTriangle(i)); } - for (it = _setQuads.begin(); it != _setQuads.end();) { + /*std::list<TrianglesUnion*>::iterator it = _setQuads.begin(); + while (it != _setQuads.end()) { bool b = false; for (int i = 0; i < (*it)->getNumTriangles(); i++) { if (touched.find((*it)->getTriangle(i)) != touched.end()) b = true; } - if (b) { - for (int i = 0; i < (*it)->getNumTriangles(); i++) { - _isolated.insert((*it)->getTriangle(i)); - } - _setQuads.erase(it++); - } + if (b) + it = _setQuads.erase(it); else - it++; - } + ++it; + }*/ } - - Rec2d_vertex::Rec2d_vertex(MVertex *v, std::list<MTriangle*> &setTri, std::map<MVertex*, std::set<GEdge*> > &mapVert) @@ -304,7 +660,7 @@ Rec2d_vertex::Rec2d_vertex(MVertex *v, if (_onWhat < 0) { std::map<MVertex*, std::set<GEdge*> >::iterator it = mapVert.find(v); if (it != mapVert.end()) { - _angle = _computeAngle(v, setTri, (*it).second); + _angle = _computeAngle(v, setTri, it->second); } else { Msg::Warning("[meshRecombine2D] Can't compute corner angle, setting angle to pi/2"); @@ -324,7 +680,7 @@ void Rec2d_vertex::_initStaticTable() int nE = 5, nF = 10; _Vvalues = new double*[2]; - _Vvalues[0] = new double[nE]; //AVERIFIER SI CA MARCHE + _Vvalues[0] = new double[nE]; for (int i = 0; i < nE; i++) _Vvalues[0][i] = 1. - fabs(2. / (i+1) - 1.); _Vvalues[1] = new double[nF]; @@ -345,7 +701,7 @@ void Rec2d_vertex::_initStaticTable() double Rec2d_vertex::_computeAngle(MVertex *v, std::list<MTriangle*> &setTri, std::set<GEdge*> &setEdge) -{ + { if (setEdge.size() != 2) { Msg::Warning("[meshRecombine2D] Wrong number of edge : %d, returning pi/2", setEdge.size()); return M_PI / 2.; @@ -364,9 +720,9 @@ double Rec2d_vertex::_computeAngle(MVertex *v, vectub -= vectv; double normlb, normub; if ((normlb = norm(vectlb)) > prec * (normub = norm(vectub))) - firstDer1 = vectub; + firstDer1 = ge->firstDer(ge->getUpperBound()); else if (normub > prec * normlb) - firstDer1 = vectlb; + firstDer1 = ge->firstDer(ge->getLowerBound()); else { Msg::Warning("[meshRecombine2D] Bad precision, returning pi/2"); return M_PI / 2.; @@ -375,12 +731,8 @@ double Rec2d_vertex::_computeAngle(MVertex *v, firstDer0 = firstDer1; } - Msg::Info("-- %lf, %lf, %lf", norm(firstDer0), norm(firstDer1), dot(firstDer0, firstDer1)); - double n = 1 / norm(firstDer0); - firstDer0 = firstDer0 * n; - n = 1 / norm(firstDer1); - firstDer1 = firstDer1 * n; - Msg::Info("--Angles : %lf, %lf, %lf", norm(firstDer0), norm(firstDer1), dot(firstDer0, firstDer1)); + firstDer0 = firstDer0 * (1 / norm(firstDer0)); + firstDer1 = firstDer1 * (1 / norm(firstDer1)); double angle1 = acos(dot(firstDer0, firstDer1)); double angle2 = 2. * M_PI - angle1; @@ -399,10 +751,6 @@ double Rec2d_vertex::_computeAngle(MVertex *v, angleMesh += angle3Vertices(t->getVertex((k+1)%3), v, t->getVertex((k+2)%3)); } - Msg::Info("Angles : %lf, %lf, %lf", angle1, angleMesh, angle2); - - return M_PI / 2.; - if (angleMesh < M_PI) return angle1; return angle2; @@ -420,10 +768,14 @@ double Rec2d_vertex::getReward(int n) { if (n == 0) return .0; if (_onWhat > -1) { - if (n > 0) - return _Vbenefs[_onWhat][_numEl-1]; - else - return - _Vbenefs[_onWhat][_numEl-2]; + switch (n) { + case 1 : + return _Vbenefs[_onWhat][_numEl-1]; + case -1 : + return - _Vbenefs[_onWhat][_numEl-2]; + default : + return _Vvalues[_onWhat][_numEl-1+n] - _Vvalues[_onWhat][_numEl-1]; + } } else return fabs(2./M_PI*_angle/_numEl - 1.) - fabs(2./M_PI*_angle/(_numEl + n) - 1.); @@ -452,7 +804,7 @@ TrianglesUnion::TrianglesUnion(GFace *gf, double sumlc = .0, u[2], v[2]; MVertex *vert[2]; for (int i = 0; i < 2; i++) { - vert[i] = (*ite).getVertex(i); + vert[i] = ite->getVertex(i); vert[i]->getParameter(0, u[i]); vert[i]->getParameter(1, v[i]); // Warning : should check if vertex on face or on edge std::map<MVertex*,double>::iterator itlc; @@ -460,13 +812,13 @@ TrianglesUnion::TrianglesUnion(GFace *gf, sumlc += v2lcUV[vert[i]] = BGM_MeshSize(gf, u[i], v[i], vert[i]->x(), vert[i]->y(), vert[i]->z()); } else - sumlc += (*itlc).second; + sumlc += itlc->second; } sumlc = .2; // FIXME BGM_MeshSize returns wrong meshsize double length = _computeEdgeLength(gf, vert, u, v, 0); - double a = 0; + double a = .0; _embEdgeValue += length / sumlc * (a + (2-a) *_computeAlignment(*ite, t)); //Msg::Info("Edge a : {%lf/.1 = %lf <-> %lf} => %lf", length, 2 * length / sumlc, 1 - _computeAlignment(*ite, t),length / sumlc * (1 + _computeAlignment(*ite, t))); } @@ -536,17 +888,77 @@ void TrianglesUnion::_update() { if (_computation >= _RECOMPUTE) return; - double r = _globValIfExecuted; double alpha = _ValVert - _embVertValue; for (int i = 0; i < _numBoundVert; i++) { alpha += _vertices[i]->getReward(-1); } alpha /= _NumVert - _numEmbVert; double beta = (_ValEdge - _embEdgeValue) / (_NumEdge - _numEmbEdge); - _globValIfExecuted = alpha * beta; + _globValIfExecuted = alpha * alpha * beta; _computation = _RECOMPUTE; } + +void TrianglesUnion::addTri(std::set<MTriangle*> &setTri) const +{ + for (int i = 0; i < _numTri; ++i) + setTri.insert(_triangles[i]); +} + +void TrianglesUnion::removeTri(std::set<MTriangle*> &setTri) const +{ + for (int i = 0; i < _numTri; ++i) + setTri.erase(_triangles[i]); +} + +bool TrianglesUnion::isIn(std::set<MTriangle*> &setTri) const +{ + for (int i = 0; i < _numTri; ++i) + if (setTri.find(_triangles[i]) != setTri.end()) + return true; + return false; +} + +void TrianglesUnion::addInfluence(int *num, double *val, std::map<Rec2d_vertex*, int> &mapVert) const +{ + num[0] += _numEmbVert; + num[1] += _numEmbEdge; + val[0] += _embVertValue; + val[1] += _embEdgeValue; + for (int i = 0; i < _numBoundVert; ++i) { + if (mapVert.find(_vertices[i]) == mapVert.end()) + mapVert[_vertices[i]] = -1; + else + mapVert[_vertices[i]] -= 1; + } +} + +void TrianglesUnion::removeInfluence(int *num, double *val, std::map<Rec2d_vertex*, int> &mapVert) const +{ + num[0] -= _numEmbVert; + num[1] -= _numEmbEdge; + val[0] -= _embVertValue; + val[1] -= _embEdgeValue; + for (int i = 0; i < _numBoundVert; ++i) { + mapVert[_vertices[i]] += 1; + } +} + +double TrianglesUnion::computeReturn(const int *num, + const double *val, + const std::map<Rec2d_vertex*, + int> &mapVert) +{ + double alpha = _ValVert - val[0]; + std::map<Rec2d_vertex*, int>::const_iterator it = mapVert.begin(); + for (; it != mapVert.end(); ++it) { + alpha += it->first->getReward(it->second); + } + alpha /= _NumVert - num[0]; + double beta = (_ValEdge - val[1]) / (_NumEdge - num[1]); + return alpha * beta; +} + bool TrianglesUnion::operator<(TrianglesUnion &other) { _update(); @@ -555,6 +967,11 @@ bool TrianglesUnion::operator<(TrianglesUnion &other) } bool lessTriUnion::operator()(TrianglesUnion *tu1, TrianglesUnion *tu2) const +{ + return *tu1 < *tu2; +} + +bool lessTriUnionInv::operator()(TrianglesUnion *tu1, TrianglesUnion *tu2) const { return *tu2 < *tu1; }