From fef27a9152a36effb967ae42c731bd449db4a96e Mon Sep 17 00:00:00 2001 From: Amaury Johnan <amjohnen@gmail.com> Date: Tue, 11 Oct 2011 09:41:46 +0000 Subject: [PATCH] --- Mesh/meshRecombine2D.h | 48 ++- Mesh/meshRecombine2D_2.cpp | 587 +++++++++++++++++++++++++++++++------ 2 files changed, 530 insertions(+), 105 deletions(-) diff --git a/Mesh/meshRecombine2D.h b/Mesh/meshRecombine2D.h index eecfd57ca1..31aab68bc1 100644 --- a/Mesh/meshRecombine2D.h +++ b/Mesh/meshRecombine2D.h @@ -102,11 +102,19 @@ class list_actions { while (it == la->_end(p) && ++p != la->_size()) { ++pos; it = la->_begin(pos); - if (p != pos) - Msg::Error(" "); } return *this; } + iterator& operator--() { + int p = pos; + while (it == la->_begin(p) && --p > -1) { + --pos; + it = la->_end(pos); + } + if (p > -1) + --it; + return *this; + } iterator operator++(int n) { iterator t = *this; int p = pos; @@ -238,12 +246,21 @@ class Recombine2D { 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 _lookAhead(std::list<TrianglesUnion*> &, int horiz); + void _lookAhead2(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*>&); + int _checkIsolatedTri(const std::vector<list_actions::iterator> &, + int size, std::set<MTriangle*> &); + double _realisticReturn(const int *num, + const double *val, + const std::map<Rec2d_vertex*, int> &, + const std::vector<list_actions::iterator> &, + int size, + const std::set<MTriangle*> &); public : int apply(bool); @@ -334,8 +351,8 @@ class Rec2d_vertex { class TrianglesUnion { private : - int _numEmbEdge, _numEmbVert, _numBoundVert, _numTri, _computation; - double _embEdgeValue, _embVertValue, _globValIfExecuted; + int _numEmbEdge, _numboundEdge, _numEmbVert, _numBoundVert, _numTri, _computation; + double _embEdgeValue, _boundEdgeValue, _embVertValue, _globValIfExecuted; Rec2d_vertex **_vertices; MTriangle **_triangles; static int _RECOMPUTE; //incremented when a recombination is executed @@ -347,7 +364,8 @@ class TrianglesUnion { public : TrianglesUnion(GFace *, std::list<MTriangle*> &, std::list<MEdge> &, - std::list<Rec2d_vertex*> &, std::map<MVertex*,double> &); + std::list<Rec2d_vertex*> &, std::map<MVertex*,double> &, + std::map<MEdge, std::list<MTriangle*>, Less_Edge>&); bool operator<(TrianglesUnion &other); void addTri(std::set<MTriangle*>&) const; @@ -367,6 +385,8 @@ class TrianglesUnion { void select() { _ValEdge -= _embEdgeValue; _NumEdge -= _numEmbEdge; + _ValEdge += _boundEdgeValue; + _NumEdge += _numboundEdge; _ValVert -= _embVertValue; _NumVert -= _numEmbVert; for (int i = 0; i < _numBoundVert; i++) { @@ -383,11 +403,15 @@ class TrianglesUnion { } static inline void addRec() {_RECOMPUTE++;} inline double getReturn() {return _globValIfExecuted;} + inline static double getActualReturn() { + return _ValEdge/_NumEdge * _ValVert/_NumVert * _ValVert/_NumVert; + } private: - double _computeEdgeLength(GFace *, MVertex **, double *u, double *v, + double _computeEdgeLength(GFace*, MVertex**, double *u, double *v, int numIntermedPoint= 1); - double _computeAlignment(MEdge &, std::list<MTriangle*> &); + double _computeAlignment(const MEdge&, std::list<MTriangle*>&, + std::map<MEdge, std::list<MTriangle*>, Less_Edge>&); void _update(); }; #endif diff --git a/Mesh/meshRecombine2D_2.cpp b/Mesh/meshRecombine2D_2.cpp index 1fcb2584be..dccf2ed103 100644 --- a/Mesh/meshRecombine2D_2.cpp +++ b/Mesh/meshRecombine2D_2.cpp @@ -18,7 +18,7 @@ #include "OpenFile.h"//pas propre #include "Field.h" #include "OS.h" -#define HORIZ2 7 +#define HORIZ2 2 double **Rec2d_vertex::_Vvalues = NULL; double **Rec2d_vertex::_Vbenefs = NULL; @@ -36,16 +36,16 @@ int Recombine2D::ra = 0; - verifier la qualite - action supplementaire (faire classe de base) - Faire un super conteneur pour les actions + - pourquoi infini + - implementer field + - si qu1, ajouter (Comment gŽrer) + - limiter sequence */ Recombine2D::Recombine2D(GFace *gf) : _horizon(0), _gf(gf), _benef(.0), _applied(true) -{ +{ Msg::Warning("[meshRecombine2D] Alignement computation ok uniquely for xy or yz plane mesh !"); - { - FieldManager *fields = gf->model()->getFields(); - fields->newField(fields->newId(), "Param"); - } // be able to compute geometrical angle at corners std::map<MVertex*, std::set<GEdge*> > mapCornerVert; @@ -131,7 +131,7 @@ Recombine2D::Recombine2D(GFace *gf) listVert.push_back(mapV2N[(*it4)->first]); } Msg::Info("%d",++j); - TrianglesUnion *tu = new TrianglesUnion(gf, (*it4)->second, listEmbEdge, listVert, mapV2LcUV); + TrianglesUnion *tu = new TrianglesUnion(gf, (*it4)->second, listEmbEdge, listVert, mapV2LcUV, mapEdge); std::list<MTriangle*>::iterator itTri = (*it4)->second.begin(); for (; itTri != (*it4)->second.end(); itTri++) _possibleActions[*itTri].insert(tu); @@ -154,7 +154,7 @@ Recombine2D::Recombine2D(GFace *gf) 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); + TrianglesUnion *tu = new TrianglesUnion(gf, itedge->second, listEmbEdge, listVert, mapV2LcUV, mapEdge); _setQuads.push_back(tu); TrianglesUnion::_NumEdge++; TrianglesUnion::_ValEdge += tu->getEdgeValue(); @@ -168,6 +168,8 @@ Recombine2D::Recombine2D(GFace *gf) TrianglesUnion::addRec(); //_setQuads.sort(lessTriUnion()); + laplaceSmoothing(_gf,10); + _recombine(true); _applied = false; } @@ -182,7 +184,8 @@ void Recombine2D::_recombine(bool a) while (!_setQuads.empty() && i < 2000) { TrianglesUnion *tu; - if (_lastQuad.empty()) { + laplaceSmoothing(_gf,1); + if (/*true ||*/ _lastQuad.empty()) { if (vectTu.size() < 2) tu = *std::max_element(_setQuads.begin(), _setQuads.end(), lessTriUnion()); else { @@ -194,7 +197,7 @@ void Recombine2D::_recombine(bool a) vectTu.insert(vectTu.begin(), tu); Msg::Info("------------------ %d", _setQuads.size()); - _lookAhead(vectTu, HORIZ2); + _lookAhead2(vectTu, HORIZ2); } else { tu = *_lastQuad.begin(); @@ -216,7 +219,6 @@ void Recombine2D::_recombine(bool a) else ++it; } - //_lastQuad.erase(_lastQuad.begin()); } tu = *vectTu.begin(); tu->select(); @@ -266,7 +268,10 @@ void Recombine2D::_lookAhead(std::list<TrianglesUnion*> &candidate, int horiz) horiz = 1; _lessActions.clear(); - double maxReturn = .0; + int t = (int) Cpu() * 100; + bool newt = true; + + double maxReturn = -100.; //TrianglesUnion *bestAction; int numbers[2] = {0, 0}; // number of embedded verts & edges double values[2] = {.0, .0}; // embedded vert & edge values @@ -324,7 +329,7 @@ void Recombine2D::_lookAhead(std::list<TrianglesUnion*> &candidate, int horiz) int sizeSequence = current; if (vecIt[sizeSequence - 1] == la.end()) --sizeSequence; - expectedReturn -= .1 * _checkIsolatedTri(vecIt, sizeSequence, setTri); + expectedReturn = _realisticReturn(numbers, values, modifiedVert, vecIt, sizeSequence, setTri); if (maxReturn < expectedReturn) { maxReturn = expectedReturn; //bestAction = *vecIt[0]; @@ -351,18 +356,22 @@ void Recombine2D::_lookAhead(std::list<TrianglesUnion*> &candidate, int horiz) } } - if (true || best) { // draw mesh + if (/*true ||*/ best /*|| (((int)(Cpu()*100) - t) % 5 == 0 && newt)*/) { // draw mesh + newt = false; apply(false); + laplaceSmoothing(_gf,1); 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")) + if (false && best && !Msg::GetAnswer("Continue ?", 1, "no", "yes")) Msg::Info("I continue anyway :p"); best = false; } + /*if (((int)(Cpu()*100) - t) % 5 != 0) + newt = true;*/ { // decolor for (int i = 0; i < current && vecIt[i] != la.end(); ++i) { @@ -408,6 +417,236 @@ void Recombine2D::_lookAhead(std::list<TrianglesUnion*> &candidate, int horiz) } } +void Recombine2D::_lookAhead2(std::list<TrianglesUnion*> &candidate, int horiz) +{ + if (horiz < 1) + horiz = 1; + _lessActions.clear(); + + //int t = (int) Cpu() * 100; + //bool newt = true; + + double maxReturn = -100.; + 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); + + std::vector<list_actions::iterator> lastLayer(horiz); + std::vector<int> numLayer(horiz); + lastLayer[0] = la.end(); + numLayer[0] = 0; + bool haveSequence = false; + int current = 1, currentLayer = 0, maxLayer = 0; + 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] != lastLayer[currentLayer] + && (*vecIt[current])->isIn(setTri) ); + vecIt[current].print(); lastLayer[currentLayer].print(); + if (vecIt[current] != lastLayer[currentLayer]) { + (*vecIt[current])->addTri(setTri); + (*vecIt[current])->addInfluence(numbers, values, modifiedVert); + ++current; + } + else { + Msg::Info("in else"); + if (!haveSequence) { + ++maxLayer; + list_actions::iterator it = --la.end(); + //it.print(); + //la.sizes(); + for (int i = numLayer[currentLayer]; i < current; ++i) { + _addNeighbors(horiz, vecIt, i, &la); + } + //la.sizes(); + lastLayer[currentLayer] = ++it; + //it.print(); + ++currentLayer; + lastLayer[currentLayer] = la.end(); + numLayer[currentLayer] = current; + } + else if (currentLayer < maxLayer) { + /*for (int i = numLayer[currentLayer]; i < current; ++i) { + _addNeighbors(horiz, vecIt, i, &la); + }*/ + ++currentLayer; + lastLayer[currentLayer] = la.end(); + numLayer[currentLayer] = current; + } + else + ++current; + + + /*if (!haveSequence) + ++maxLayer; + if (currentLayer < maxLayer) { + for (int i = numLayer[currentLayer]; i < current; ++i) { + _addNeighbors(horiz, vecIt, i, &la); + } + ++currentLayer; + lastLayer[currentLayer] = la.end(); + numLayer[currentLayer] = current; + } + else + ++current;*/ + } + } + haveSequence = true; + Msg::Info("maxLayer %d, current %d", maxLayer, 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 = _realisticReturn(numbers, values, modifiedVert, vecIt, sizeSequence, setTri); + if (maxReturn < expectedReturn) { + //Msg::Info("best"); + //Msg::Info(" "); + 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); + } + } + + if (true || best /*|| (((int)(Cpu()*100) - t) % 5 == 0 && newt)*/) { // draw mesh + //newt = false; + apply(false); + CTX::instance()->mesh.changed = (ENT_ALL); + FlGui::instance()->check(); + //Msg::Info("before"); + //Msg::Info(" "); + drawContext::global()->draw(); + //Msg::Info("after"); + //Msg::Info(" "); + 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; + } + /*if (((int)(Cpu()*100) - t) % 5 != 0) + newt = true;*/ + + { // 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); + } + } + } + + if (vecIt[current-1] != lastLayer[currentLayer] || + --current - 1 >= numLayer[currentLayer] || + --currentLayer >= 0 ) { + bool lessLayer = false; + do { + (*vecIt[current-1])->removeTri(setTri); + (*vecIt[current-1])->removeInfluence(numbers, values, modifiedVert); + Msg::Info("current %d, currentLayer %d", current, currentLayer); + if (currentLayer < maxLayer) { + _removeNeighbors(horiz, current - 1, &la); + lastLayer[currentLayer+1] = la.end(); + if (current-1 == numLayer[currentLayer]) + lastLayer[currentLayer] = la.end(); + } + while (++vecIt[current-1] != lastLayer[currentLayer] + && (*vecIt[current-1])->isIn(setTri) ); + Msg::Info("b %d, %d - %d, %d", vecIt[current-1] == lastLayer[currentLayer], current, numLayer[currentLayer], currentLayer); + } while (vecIt[current-1] == lastLayer[currentLayer] && + (--current - 1 >= numLayer[currentLayer] || + --currentLayer >= 0 ) ); + Msg::Info("current %d, currentLayer %d", current, currentLayer); + if (current > 0 && currentLayer >= 0) { + (*vecIt[current-1])->addTri(setTri); + (*vecIt[current-1])->addInfluence(numbers, values, modifiedVert); + if (currentLayer < maxLayer) { + if (current-1 == numLayer[currentLayer]) + --lastLayer[currentLayer]; + _addNeighbors(horiz, vecIt, current - 1, &la); + if (current-1 == numLayer[currentLayer]) + ++lastLayer[currentLayer]; + lastLayer[currentLayer+1] = la.end(); + } + } + } + } + + { // 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++) { @@ -461,7 +700,115 @@ void Recombine2D::_removeNeighbors(int horiz, int current, list_actions *la) } -int Recombine2D::_checkIsolatedTri(std::vector<list_actions::iterator> &vecIt, int size, std::set<MTriangle*> &seqTri) +double Recombine2D::_realisticReturn(const int *num, + const double *val, + const std::map<Rec2d_vertex*, int> &mapVert, + const std::vector<list_actions::iterator> &vecIt, + int size, + const std::set<MTriangle*> &seqTri) +{ + //Msg::Info("before (%d) : %lf -> %lf", size, TrianglesUnion::getActualReturn(), TrianglesUnion::computeReturn(num, val, mapVert)); + int newNum[2] = {num[0], num[1]}, numIsolatedTri, numRecomb = size; + double newVal[2] = {val[0], val[1]}; + std::map<Rec2d_vertex*, int> newMapVert = mapVert; + + setTriUnion setIncompTu; + for (int i = 0; i < size; ++i) { + _getIncompatibles(*vecIt[i], setIncompTu); + } + + std::set<MTriangle*> setTri = seqTri, touched; + + numIsolatedTri = _checkIsolatedTri(vecIt, size, setTri); + //Msg::Info("numisolated %d, last %d", numIsolatedTri, setTri.size()); + + std::set<MTriangle*>::iterator itTri = setTri.begin(); + int kl = 0; + while (itTri != setTri.end()) { + //Msg::Info("%d.", ++kl); + mapTriUnion::iterator itTmp = _possibleActions.find(*itTri); + setTriUnion::iterator it_tu = itTmp->second.begin(); + TrianglesUnion *tu; + int numPossible = 0; + for (; it_tu != itTmp->second.end(); ++it_tu) { + bool possible = true; + TrianglesUnion *tu1 = *it_tu; + for (int i = 0; i < tu1->getNumTriangles(); i++) + if (seqTri.find(tu1->getTriangle(i)) != seqTri.end() || + touched.find(tu1->getTriangle(i)) != touched.end() ) + possible = false; + if (possible) { + tu = tu1; + ++numPossible; + } + } + + setTri.erase(itTri); + + if (numPossible < 1){ + ++numIsolatedTri; + Msg::Info("'m here"); + } + else if (numPossible > 1) + Msg::Info("Oh oh, trouble"); + else { + //Msg::Info("possible"); + ++numRecomb; + tu->addInfluence(newNum, newVal, newMapVert); + for (int i = 0; i < tu->getNumTriangles(); i++) { + touched.insert(tu->getTriangle(i)); + setTri.erase(tu->getTriangle(i)); + } + _getIncompatibles(tu, setIncompTu); + + setTriUnion setTu; + setTu.clear(); + _getIncompatibles(tu, 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() && + touched.find((*it)->getTriangle(i)) == touched.end() ) + setBoundaryTri.insert((*it)->getTriangle(i)); + } + + //Msg::Info("size boundary : %d", setBoundaryTri.size()); + + std::set<MTriangle*>::iterator itTri2 = setBoundaryTri.begin(); + for (; itTri2 != setBoundaryTri.end(); ++itTri2) { + mapTriUnion::iterator it1 = _possibleActions.find(*itTri2); + if (it1 == _possibleActions.end()) { + Msg::Error("[Rec2D] error no triangle !, stopping with partially filled set"); + Msg::Error(" "); + } + int numPossibleRecombinations = 0; + setTriUnion::iterator it2 = it1->second.begin(); + for (; it2 != it1->second.end(); ++it2) + if (setIncompTu.find(*it2) == setIncompTu.end()) + ++numPossibleRecombinations; + if (!numPossibleRecombinations) { + ++numIsolatedTri; + setTri.erase(*itTri2); + } + if (numPossibleRecombinations == 1) + setTri.insert(*itTri2); + } + } + itTri = setTri.begin(); + } + + double oldReturn = TrianglesUnion::getActualReturn(); + double newReturn = TrianglesUnion::computeReturn(newNum, newVal, newMapVert); + + //Msg::Info("after (%d) : %lf -> %lf - %d", numRecomb, TrianglesUnion::getActualReturn(), (newReturn-oldReturn) * size/numRecomb + oldReturn, numIsolatedTri); + + return (newReturn-oldReturn) * size/numRecomb + oldReturn - numIsolatedTri; +} + +int Recombine2D::_checkIsolatedTri(const std::vector<list_actions::iterator> &vecIt, + int size, std::set<MTriangle*> &seqTri) { setTriUnion setTu; for (int i = 0; i < size; ++i) { @@ -476,6 +823,8 @@ int Recombine2D::_checkIsolatedTri(std::vector<list_actions::iterator> &vecIt, i setBoundaryTri.insert((*it)->getTriangle(i)); } + seqTri.clear(); + int num = 0; std::set<MTriangle*>::iterator itTri = setBoundaryTri.begin(); for (; itTri != setBoundaryTri.end(); ++itTri) { @@ -494,70 +843,12 @@ int Recombine2D::_checkIsolatedTri(std::vector<list_actions::iterator> &vecIt, i ++numPossibleRecombinations; if (!numPossibleRecombinations) ++num; + if (numPossibleRecombinations == 1) + seqTri.insert(*itTri); } return num; } -MQuadrangle *TrianglesUnion::createQuad() const -{ - std::list<MEdge> listBoundEdge; - { - std::multiset<MEdge, Less_Edge> msetEdge; - for (int i = 0; i < _numTri; i++) { - MTriangle *t = _triangles[i]; - for (int i = 0; i < 3; i++) { - msetEdge.insert(t->getEdge(i)); - } - } - std::multiset<MEdge>::iterator itEdge = msetEdge.begin(); - MEdge me = *(itEdge++); - bool precWasSame = false; - for (; itEdge != msetEdge.end(); itEdge++) { - if (*itEdge == me) - precWasSame = true; - else if (precWasSame) - precWasSame = false; - else - listBoundEdge.push_back(me); - me = *itEdge; - } - if (!precWasSame) - listBoundEdge.push_back(me); - } - if (listBoundEdge.size() != 4) - Msg::Warning("[meshRecombine2D] Not 4 edges !"); - - MVertex *v1, *v2, *v3, *v4; - v1 = listBoundEdge.begin()->getMinVertex(); - v2 = listBoundEdge.begin()->getMaxVertex(); - std::list<MEdge>::iterator it = listBoundEdge.begin(); - for (it++; it != listBoundEdge.end(); it++) { - if (v2 == it->getMinVertex()) { - v3 = it->getMaxVertex(); - listBoundEdge.erase(it); - break; - } - 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(); - break; - } - if (v3 == it->getMaxVertex()) { - v4 = it->getMinVertex(); - break; - } - } - - return new MQuadrangle(v1, v2, v3, v4); -} - - int Recombine2D::apply(bool a) { //Msg::Info("(%d, %d, %d)", _quads.size(), _gf->triangles.size(), _isolated.size()); @@ -766,7 +1057,7 @@ double Rec2d_vertex::getReward() double Rec2d_vertex::getReward(int n) { - if (n == 0) return .0; + static double t= Cpu(); if (_onWhat > -1) { switch (n) { case 1 : @@ -786,7 +1077,8 @@ TrianglesUnion::TrianglesUnion(GFace *gf, std::list<MTriangle*> &t, std::list<MEdge> &e, std::list<Rec2d_vertex*> &v, - std::map<MVertex*,double> &v2lcUV) + std::map<MVertex*,double> &v2lcUV, + std::map<MEdge, std::list<MTriangle*>, Less_Edge> &mapEdge) { _numTri = t.size(); _numEmbEdge = e.size(); @@ -796,8 +1088,13 @@ TrianglesUnion::TrianglesUnion(GFace *gf, _triangles = new MTriangle*[_numTri]; std::list<MTriangle*>::iterator itt = t.begin(); - for (int k = 0; itt != t.end(); itt++, k++) + std::set<MEdge, Less_Edge> setEdge; + for (int k = 0; itt != t.end(); itt++, k++) { _triangles[k] = *itt; + for (int i = 0; i < 3; ++i) { + setEdge.insert((*itt)->getEdge(i)); + } + } std::list<MEdge>::iterator ite = e.begin(); for (; ite != e.end(); ite++) { @@ -807,8 +1104,8 @@ TrianglesUnion::TrianglesUnion(GFace *gf, 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; - if ((itlc = v2lcUV.find(vert[i])) == v2lcUV.end()) { + std::map<MVertex*,double>::iterator itlc = v2lcUV.find(vert[i]); + if (itlc == v2lcUV.end()) { sumlc += v2lcUV[vert[i]] = BGM_MeshSize(gf, u[i], v[i], vert[i]->x(), vert[i]->y(), vert[i]->z()); } else @@ -819,10 +1116,35 @@ TrianglesUnion::TrianglesUnion(GFace *gf, double length = _computeEdgeLength(gf, vert, u, v, 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))); + _embEdgeValue += length / sumlc * (a + (2-a)*_computeAlignment(*ite, t, mapEdge)); + setEdge.erase(*ite); } + std::set<MEdge, Less_Edge>::iterator ite2 = setEdge.begin(); + for (; ite2 != setEdge.end(); ite2++) { + double sumlc = .0, u[2], v[2]; + MVertex *vert[2]; + for (int i = 0; i < 2; i++) { + vert[i] = ite2->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 = v2lcUV.find(vert[i]); + if (itlc == v2lcUV.end()) { + 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 = .2; // FIXME BGM_MeshSize returns wrong meshsize + + double length = _computeEdgeLength(gf, vert, u, v, 0); + double a = .0; + _boundEdgeValue += length / sumlc * (a + (2-a)*_computeAlignment(*ite2, t, mapEdge)); + } + _boundEdgeValue /= 2.; + _numboundEdge = 2; + _vertices = new Rec2d_vertex*[_numBoundVert]; std::list<Rec2d_vertex*>::iterator itv = v.begin(); for (int k = 0; itv != v.end() && k < _numBoundVert; itv++, k++) @@ -830,7 +1152,7 @@ TrianglesUnion::TrianglesUnion(GFace *gf, for (_numEmbVert = 0; itv != v.end(); itv++, _numEmbVert++) _embVertValue += (*itv)->getReward(); - _computation = _RECOMPUTE; + _computation = _RECOMPUTE - 1; } @@ -862,11 +1184,12 @@ double TrianglesUnion::_computeEdgeLength(GFace *gf, MVertex **vert, } return l; } -double TrianglesUnion::_computeAlignment(MEdge &e, std::list<MTriangle*> <) +double TrianglesUnion::_computeAlignment(const MEdge &e, std::list<MTriangle*> <, + std::map<MEdge, std::list<MTriangle*>, Less_Edge> &mapEdge) { std::list<MTriangle*>::iterator itlt = lt.begin(); - if (lt.size() == 2) - return Temporary::compute_alignment(e, *itlt, *(++itlt)); + //if (lt.size() == 2) + // return Temporary::compute_alignment(e, *itlt, *(++itlt)); MVertex *v0 = e.getVertex(0); MVertex *v1 = e.getVertex(1); @@ -878,9 +1201,25 @@ double TrianglesUnion::_computeAlignment(MEdge &e, std::list<MTriangle*> <) (t->getVertex(0) == v1 || t->getVertex(1) == v1 || t->getVertex(2) == v1) ) tris[k++] = t; } + if (k < 2) { + k = 0; + std::map<MEdge, std::list<MTriangle*> >::iterator itmEdge = mapEdge.find(e); + if (itmEdge == mapEdge.end()) { + Msg::Info("g po :( (szie %d)", mapEdge.size()); + return .0; + } + itlt = itmEdge->second.begin(); + int num = 0; + for (; itlt != itmEdge->second.end(); itlt++) { + MTriangle *t = *itlt; + if ((t->getVertex(0) == v0 || t->getVertex(1) == v0 || t->getVertex(2) == v0) && + (t->getVertex(0) == v1 || t->getVertex(1) == v1 || t->getVertex(2) == v1) ) + tris[k++] = t; + } + } if (k < 2 || k > 2) { - Msg::Warning("[meshRecombine2D] error in alignment computation, returning 0"); - return .0; + //Msg::Warning("[meshRecombine2D] error in alignment computation, returning 1"); + return 1.; } return Temporary::compute_alignment(e, tris[0], tris[1]); } @@ -893,12 +1232,71 @@ void TrianglesUnion::_update() alpha += _vertices[i]->getReward(-1); } alpha /= _NumVert - _numEmbVert; - double beta = (_ValEdge - _embEdgeValue) / (_NumEdge - _numEmbEdge); + double beta = (_ValEdge - _embEdgeValue + _boundEdgeValue) / (_NumEdge - _numEmbEdge + _numboundEdge); _globValIfExecuted = alpha * alpha * beta; _computation = _RECOMPUTE; } +MQuadrangle *TrianglesUnion::createQuad() const +{ + std::list<MEdge> listBoundEdge; + { + std::multiset<MEdge, Less_Edge> msetEdge; + for (int i = 0; i < _numTri; i++) { + MTriangle *t = _triangles[i]; + for (int i = 0; i < 3; i++) { + msetEdge.insert(t->getEdge(i)); + } + } + std::multiset<MEdge>::iterator itEdge = msetEdge.begin(); + MEdge me = *(itEdge++); + bool precWasSame = false; + for (; itEdge != msetEdge.end(); itEdge++) { + if (*itEdge == me) + precWasSame = true; + else if (precWasSame) + precWasSame = false; + else + listBoundEdge.push_back(me); + me = *itEdge; + } + if (!precWasSame) + listBoundEdge.push_back(me); + } + if (listBoundEdge.size() != 4) + Msg::Warning("[meshRecombine2D] Not 4 edges !"); + + MVertex *v1, *v2, *v3, *v4; + v1 = listBoundEdge.begin()->getMinVertex(); + v2 = listBoundEdge.begin()->getMaxVertex(); + std::list<MEdge>::iterator it = listBoundEdge.begin(); + for (it++; it != listBoundEdge.end(); it++) { + if (v2 == it->getMinVertex()) { + v3 = it->getMaxVertex(); + listBoundEdge.erase(it); + break; + } + 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(); + break; + } + if (v3 == it->getMaxVertex()) { + v4 = it->getMinVertex(); + break; + } + } + + return new MQuadrangle(v1, v2, v3, v4); +} + void TrianglesUnion::addTri(std::set<MTriangle*> &setTri) const { for (int i = 0; i < _numTri; ++i) @@ -923,8 +1321,10 @@ void TrianglesUnion::addInfluence(int *num, double *val, std::map<Rec2d_vertex*, { num[0] += _numEmbVert; num[1] += _numEmbEdge; + num[1] -= _numboundEdge; val[0] += _embVertValue; val[1] += _embEdgeValue; + val[1] -= _boundEdgeValue; for (int i = 0; i < _numBoundVert; ++i) { if (mapVert.find(_vertices[i]) == mapVert.end()) mapVert[_vertices[i]] = -1; @@ -937,8 +1337,10 @@ void TrianglesUnion::removeInfluence(int *num, double *val, std::map<Rec2d_verte { num[0] -= _numEmbVert; num[1] -= _numEmbEdge; + num[1] += _numboundEdge; val[0] -= _embVertValue; val[1] -= _embEdgeValue; + val[1] += _boundEdgeValue; for (int i = 0; i < _numBoundVert; ++i) { mapVert[_vertices[i]] += 1; } @@ -946,8 +1348,7 @@ void TrianglesUnion::removeInfluence(int *num, double *val, std::map<Rec2d_verte double TrianglesUnion::computeReturn(const int *num, const double *val, - const std::map<Rec2d_vertex*, - int> &mapVert) + const std::map<Rec2d_vertex*, int> &mapVert) { double alpha = _ValVert - val[0]; std::map<Rec2d_vertex*, int>::const_iterator it = mapVert.begin(); @@ -956,7 +1357,7 @@ double TrianglesUnion::computeReturn(const int *num, } alpha /= _NumVert - num[0]; double beta = (_ValEdge - val[1]) / (_NumEdge - num[1]); - return alpha * beta; + return alpha * alpha * beta; } bool TrianglesUnion::operator<(TrianglesUnion &other) -- GitLab