Skip to content
Snippets Groups Projects
Commit 9f93b591 authored by Amaury Johnen's avatar Amaury Johnen
Browse files

No commit message

No commit message
parent a341a511
No related branches found
No related tags found
No related merge requests found
...@@ -9,21 +9,20 @@ ...@@ -9,21 +9,20 @@
#include "meshRecombine2D.h" #include "meshRecombine2D.h"
#include "GFace.h" #include "GFace.h"
#include <cmath>
#include <FL/Fl.H>
#include "drawContext.h"
#include "FlGui.h"
#include "Context.h"
#include "OpenFile.h"//pas propre
static int HORIZ = 25; static int HORIZ = 20;
static int NUM_NEW = 0;
static int NEW_REC = 0;
static int NEW_NODE = 0; static int NEW_NODE = 0;
static int NEW_QUAD = 0;
static int NUM_DEL = 0;
static int DEL_REC = 0;
static int DEL_NODE = 0; static int DEL_NODE = 0;
static int DEL_QUAD = 0;
Recombine2D::Recombine2D(GFace *gf, int horizon) Recombine2D::Recombine2D(GFace *gf, int horizon)
: _horizon(horizon), _gf(gf), _benef(.0), _applied(false) : _horizon(horizon), _gf(gf), _benef(.0), _applied(true)
{ {
if (_horizon < 1) _horizon = 1; if (_horizon < 1) _horizon = 1;
...@@ -45,12 +44,11 @@ Recombine2D::Recombine2D(GFace *gf, int horizon) ...@@ -45,12 +44,11 @@ Recombine2D::Recombine2D(GFace *gf, int horizon)
for (e2t_cont::iterator it = adj.begin(); it != adj.end(); ++it) { for (e2t_cont::iterator it = adj.begin(); it != adj.end(); ++it) {
if (it->second.second) { if (it->second.second) {
RecombTriangle *rt = new RecombTriangle(it->first, it->second.first, it->second.second); RecombTriangle *rt = new RecombTriangle(it->first, it->second.first, it->second.second);
NUM_NEW++; ret = _pairs.insert(rt);
NEW_REC++; while (ret.second == false) {
do {
rt->touch(); rt->touch();
ret = _pairs.insert(rt); ret = _pairs.insert(rt);
} while (ret.second == false); }
_possibleRecomb[it->second.first].insert(rt); _possibleRecomb[it->second.first].insert(rt);
_possibleRecomb[it->second.second].insert(rt); _possibleRecomb[it->second.second].insert(rt);
} }
...@@ -70,8 +68,6 @@ NEW_REC++; ...@@ -70,8 +68,6 @@ NEW_REC++;
rt = new RecombTriangle(itt->first, -100); rt = new RecombTriangle(itt->first, -100);
else else
rt = new RecombTriangle(itt->first, -200); rt = new RecombTriangle(itt->first, -200);
NUM_NEW++;
NEW_REC++;
ret = _pairs.insert(rt); ret = _pairs.insert(rt);
while (!ret.second) { while (!ret.second) {
...@@ -87,18 +83,16 @@ NEW_REC++; ...@@ -87,18 +83,16 @@ NEW_REC++;
_recombine(); _recombine();
Msg::Info("new %d = %d + %d + %d", NUM_NEW, NEW_REC, NEW_NODE, NEW_QUAD); Msg::Info("new %d ", NEW_NODE);
Msg::Info("del %d = %d + %d + %d", NUM_DEL, DEL_REC, DEL_NODE, DEL_QUAD); Msg::Info("del %d ", DEL_NODE);
_applied = false;
} }
Recombine2D::~Recombine2D() Recombine2D::~Recombine2D()
{ {
if (!_applied) if (!_applied)
for (int i = 0; i < _quads.size(); i++) { for (int i = 0; i < _quads.size(); i++)
delete _quads[i]; delete _quads[i];
NUM_DEL++;
DEL_QUAD++;
}
} }
template <class E> template <class E>
...@@ -121,17 +115,53 @@ void Recombine2D::_buildEdgeToElement(std::vector<E*> &elements, e2t_cont &adj) ...@@ -121,17 +115,53 @@ void Recombine2D::_buildEdgeToElement(std::vector<E*> &elements, e2t_cont &adj)
void Recombine2D::_recombine() void Recombine2D::_recombine()
{ {
SetBoundingBox();
int i = 0; int i = 0;
while ((!_pairs.empty() || !_lastRecomb.empty()) && i < 1000) { while ((!_pairs.empty() || !_lastRecomb.empty()) && i < 1000) {
Msg::Info("%d",i); Msg::Info("%d",i);
Set_Recomb::iterator it = _bestNextRecombination(); Set_Recomb::iterator it = _bestNextRecombination();
if (it != _pairs.begin()) {
std::set<MElement*> isolatedCP(_isolated);
_isolated.clear();
Set_Recomb::iterator itnp = _pairs.begin();
int n = 0;
while (itnp != it) {
n++;
for (int k = 0; k < (*itnp)->numTriangles(); k++){
Msg::Info("recomb[%d] %d : %d", n, k+1, (*itnp)->triangle(k)->getNum());
_isolated.insert((*itnp)->triangle(k));
}
itnp++;
}
Msg::Info("%d triangles et %d quads", _gf->triangles.size(), _gf->quadrangles.size());
_applied = false;
apply();
_applied = false;
CTX::instance()->mesh.changed = (ENT_ALL);
drawContext::global()->draw();
FlGui::instance()->check();
drawContext::global()->draw();
if (!Msg::GetAnswer("Continue ?", 1, "no", "yes"))
Msg::Info("I continue anyway :p");
_isolated = isolatedCP;
}
_benef += (*it)->getBenef(); _benef += (*it)->getBenef();
if ((*it)->isQuad()) if ((*it)->isQuad())
_quads.push_back((*it)->createQuad()); _quads.push_back((*it)->createQuad());
else else
for (int i = 0; i < (*it)->numTriangles(); i++) for (int i = 0; i < (*it)->numTriangles(); i++)
_isolated.insert((*it)->triangle(i)); _isolated.insert((*it)->triangle(i));
/*Set_Recomb::iterator itmp = _pairs.begin();
while (itmp != it) {
_rmRT(*itmp);
itmp = _pairs.begin();
}*/
_removeImpossible(it); _removeImpossible(it);
i++; i++;
} }
Msg::Info("Done %d (%d)", i, _pairs.size()); Msg::Info("Done %d (%d)", i, _pairs.size());
...@@ -142,18 +172,17 @@ Set_Recomb::iterator Recombine2D::_bestNextRecombination() ...@@ -142,18 +172,17 @@ Set_Recomb::iterator Recombine2D::_bestNextRecombination()
if (!_lastRecomb.empty()) if (!_lastRecomb.empty())
return _lastRecomb.begin(); return _lastRecomb.begin();
int h = 0, nSkip = 0;
double maxBenef = _horizon * -200.;
Map_Tri_Node touched; Map_Tri_Node touched;
std::vector<Node*> nodes(_horizon); std::vector<Recomb2D_Node*> nodes(_horizon);
Set_Recomb::iterator it = _pairs.begin(), itmax = _pairs.begin(); Set_Recomb::iterator it = _pairs.begin(), itmax = _pairs.begin();
bool end = false; int h = 0, nSkip = 0;
double maxBenef = _horizon * -200.;
bool haveOptimal = false;
int numb = 0; int numb = 0;
while (!end) { while (!haveOptimal) {
numb++; numb++;
while (h < _horizon && it != _pairs.end()) { while (h < _horizon && it != _pairs.end()) {
bool possible = true; bool possible = true;
...@@ -168,20 +197,21 @@ Set_Recomb::iterator Recombine2D::_bestNextRecombination() ...@@ -168,20 +197,21 @@ Set_Recomb::iterator Recombine2D::_bestNextRecombination()
} }
if (possible) { if (possible) {
if (h == 0) nodes[h] = new Node(it, touched, nSkip); if (h == 0) nodes[h] = new Recomb2D_Node(it, nSkip, _horizon, touched);
else nodes[h] = new Node(it, touched, nSkip, nodes[h-1]->getTotBenef()); else nodes[h] = new Recomb2D_Node(it, nSkip, nodes[h-1]);
NUM_NEW++;
NEW_NODE++; NEW_NODE++;
h++; h++;
nSkip = 0; nSkip = 0;
if (h >= _horizon || nodes[h - 1]->getBound() < maxBenef)
break;
} }
else
nSkip++;
it++; it++;
} }
if (nodes[--h]->getTotBenef() > maxBenef) { if (--h < 0) haveOptimal = true;
if (nodes[h]->getTotBenef() > maxBenef) {
maxBenef = nodes[h]->getTotBenef(); maxBenef = nodes[h]->getTotBenef();
itmax = nodes[0]->getItRecomb(); itmax = nodes[0]->getItRecomb();
} }
...@@ -197,22 +227,19 @@ NEW_NODE++; ...@@ -197,22 +227,19 @@ NEW_NODE++;
nodes[h]->getnSkip() >= 2 * (_horizon - h)) nodes[h]->getnSkip() >= 2 * (_horizon - h))
nodes[h--]->erase();*/ nodes[h--]->erase();*/
delete nodes[h]; delete nodes[h];
NUM_DEL++;
DEL_NODE++; DEL_NODE++;
while (--h >= 0 && while (--h >= 0 &&
(nodes[h]->isBetter() || (nodes[h]->isBetter() ||
nodes[h]->getnSkip() >= 2 * (_horizon - h))){ nodes[h]->getnSkip() >= 2 * (_horizon - h) - 1)){
NUM_DEL++;
DEL_NODE++; DEL_NODE++;
delete nodes[h]; delete nodes[h];
} }
if (h < 0) end = true; if (h < 0) haveOptimal = true;
else { else {
it = ++nodes[h]->getItRecomb(); it = ++nodes[h]->getItRecomb();
nSkip = nodes[h]->getnSkip() + 1; nSkip = nodes[h]->getnSkip() + 1;
delete nodes[h]; delete nodes[h];
NUM_DEL++;
DEL_NODE++; DEL_NODE++;
} }
} }
...@@ -230,19 +257,14 @@ void Recombine2D::_removeImpossible(Set_Recomb::iterator it) ...@@ -230,19 +257,14 @@ void Recombine2D::_removeImpossible(Set_Recomb::iterator it)
Map_Tri_Recomb::iterator itm; Map_Tri_Recomb::iterator itm;
std::set<RecombTriangle*>::iterator itrt; std::set<RecombTriangle*>::iterator itrt;
for (int i = 0; i < t.size(); i++) { for (int i = 0; i < t.size(); i++) // loop over touched triangles
if ((itm = _possibleRecomb.find(t[i])) != _possibleRecomb.end()) {
itm = _possibleRecomb.find(t[i]);
if (itm == _possibleRecomb.end())
Msg::Info("not _possibleRecomb");
else {
itrt = itm->second.begin(); itrt = itm->second.begin();
while (itrt != itm->second.end()) { // loop over unusable RecombTriangle while (itrt != itm->second.end()) { // loop over incompatible RecombTriangle
if (*itrt != *it) if (*itrt != *it)
_rmRT(*itrt, t[i]); _rmRT(*itrt, t[i]);
itrt++; itrt++;
} }
}
_possibleRecomb.erase(itm); _possibleRecomb.erase(itm);
} }
...@@ -250,8 +272,6 @@ void Recombine2D::_removeImpossible(Set_Recomb::iterator it) ...@@ -250,8 +272,6 @@ void Recombine2D::_removeImpossible(Set_Recomb::iterator it)
if (!_lastRecomb.erase(*it)) if (!_lastRecomb.erase(*it))
_pairs.erase(it); _pairs.erase(it);
delete rt; delete rt;
NUM_DEL++;
DEL_REC++;
} }
void Recombine2D::_rmRT(RecombTriangle *rt, MElement *el) void Recombine2D::_rmRT(RecombTriangle *rt, MElement *el)
...@@ -260,16 +280,13 @@ void Recombine2D::_rmRT(RecombTriangle *rt, MElement *el) ...@@ -260,16 +280,13 @@ void Recombine2D::_rmRT(RecombTriangle *rt, MElement *el)
Map_Tri_Recomb::iterator itmtri; Map_Tri_Recomb::iterator itmtri;
for (int i = 0; i < rt->numTriangles(); i++) for (int i = 0; i < rt->numTriangles(); i++)
if ((tri = rt->triangle(i)) != el) { if ((tri = rt->triangle(i)) != el &&
itmtri = _possibleRecomb.find(tri); (itmtri = _possibleRecomb.find(tri)) != _possibleRecomb.end()) {
if (itmtri == _possibleRecomb.end())
Msg::Info("-not _possibleRecomb");
else {
itmtri->second.erase(rt); itmtri->second.erase(rt);
switch (itmtri->second.size()) { switch (itmtri->second.size()) {
case 1 : case 1 :
_pairs.erase(*itmtri->second.begin()); //_pairs.erase(*itmtri->second.begin());
_lastRecomb.insert(*itmtri->second.begin()); //_lastRecomb.insert(*itmtri->second.begin());
break; break;
case 0 : case 0 :
_isolated.insert(tri); _isolated.insert(tri);
...@@ -277,22 +294,20 @@ void Recombine2D::_rmRT(RecombTriangle *rt, MElement *el) ...@@ -277,22 +294,20 @@ void Recombine2D::_rmRT(RecombTriangle *rt, MElement *el)
default :; default :;
} }
} }
}
_pairs.erase(rt); _pairs.erase(rt);
_lastRecomb.erase(rt); _lastRecomb.erase(rt);
delete rt; delete rt;
NUM_DEL++;
DEL_REC++;
} }
int Recombine2D::apply() int Recombine2D::apply()
{ {
if (!_haveParam && !_applied) return 0; if (!_haveParam || _applied) return 0;
std::vector<MTriangle*> triangles2; std::vector<MTriangle*> triangles2;
for (int i = 0; i < _gf->triangles.size(); i++) { for (int i = 0; i < _gf->triangles.size(); i++) {
if (_isolated.find(_gf->triangles[i]) == _isolated.end()) if (_isolated.find(_gf->triangles[i]) == _isolated.end())
delete _gf->triangles[i]; ;//delete _gf->triangles[i];
else else
triangles2.push_back(_gf->triangles[i]); triangles2.push_back(_gf->triangles[i]);
} }
...@@ -310,6 +325,7 @@ RecombTriangle::RecombTriangle(const MEdge &me, MElement *t1, MElement *t2) ...@@ -310,6 +325,7 @@ RecombTriangle::RecombTriangle(const MEdge &me, MElement *t1, MElement *t2)
_t.push_back(t2); _t.push_back(t2);
_n1 = me.getVertex(0); _n1 = me.getVertex(0);
_n2 = me.getVertex(1); _n2 = me.getVertex(1);
_sign = (std::rand() % 2) * 2 - 1;
if(t1->getVertex(0) != _n1 && t1->getVertex(0) != _n2) _n3 = t1->getVertex(0); if(t1->getVertex(0) != _n1 && t1->getVertex(0) != _n2) _n3 = t1->getVertex(0);
else if(t1->getVertex(1) != _n1 && t1->getVertex(1) != _n2) _n3 = t1->getVertex(1); else if(t1->getVertex(1) != _n1 && t1->getVertex(1) != _n2) _n3 = t1->getVertex(1);
...@@ -336,23 +352,22 @@ RecombTriangle::RecombTriangle(const MEdge &me, MElement *t1, MElement *t2) ...@@ -336,23 +352,22 @@ RecombTriangle::RecombTriangle(const MEdge &me, MElement *t1, MElement *t2)
} }
RecombTriangle::RecombTriangle(MElement *t, double a) RecombTriangle::RecombTriangle(MElement *t, double a)
: _benefit(a), _formingQuad(false) { : _benefit(a), _formingQuad(false)
{
_t.push_back(t); _t.push_back(t);
_sign = (std::rand() % 2) * 2 - 1;
} }
double RecombTriangle::touch() double RecombTriangle::touch()
{ {
double prec = 1e-10; if (_benefit == .0)
return _benefit = _sign * std::pow(2., -1022);
double a = (double)(rand() - RAND_MAX / 2) / RAND_MAX * prec; else // add smaller possible value
_benefit += a; return _benefit += _sign * std::pow(2., std::floor(std::log(std::fabs(_benefit))/std::log(2.))-52);
return a;
} }
MQuadrangle *RecombTriangle::createQuad() const MQuadrangle *RecombTriangle::createQuad() const
{ {
NUM_NEW++;
NEW_QUAD++;
switch (_t.size()) { switch (_t.size()) {
case 1 : case 1 :
{ {
...@@ -402,30 +417,54 @@ bool lessRecombTri::operator()(RecombTriangle *rt1, RecombTriangle *rt2) const ...@@ -402,30 +417,54 @@ bool lessRecombTri::operator()(RecombTriangle *rt1, RecombTriangle *rt2) const
return *rt2 < *rt1; return *rt2 < *rt1;
} }
Node::Node(Set_Recomb::iterator it, //{Recomb2D_Node::Recomb2D_Node(Set_Recomb::iterator it,
Map_Tri_Node &touched, // Map_Tri_Node &touched,
int nskp, double ben) : _nskip(nskp), _recomb(it) // int nskp, double ben) : _nskip(nskp), _recomb(it)
//{
// _benef = (*it)->getBenef();
// _totBenef = ben + _benef;
// for (int i = 0; i < (*it)->numTriangles(); i++)
// _vit.push_back(touched.insert( touched.begin(), std::make_pair((*it)->triangle(i), this) ));
// _touch = &touched;
//}
//}
Recomb2D_Node::Recomb2D_Node(Set_Recomb::iterator it, int nskp, int horiz,
Map_Tri_Node &touched)
: _nskip(nskp), _recomb(it)
{ {
_benef = (*it)->getBenef(); _benef = (*it)->getBenef();
_totBenef = ben + _benef; _totBenef = _benef;
_depth = horiz - 1;
for (int i = 0; i < (*it)->numTriangles(); i++) for (int i = 0; i < (*it)->numTriangles(); i++)
_vit.push_back(touched.insert( touched.begin(), std::make_pair((*it)->triangle(i), this) )); _vit.push_back(touched.insert( touched.begin(), std::make_pair((*it)->triangle(i), this) ));
_touch = &touched; _touch = &touched;
} }
Node::~Node() Recomb2D_Node::Recomb2D_Node(Set_Recomb::iterator it, int nskp, Recomb2D_Node *n)
: _nskip(nskp), _recomb(it)
{
_benef = (*it)->getBenef();
_totBenef = n->_benef + _benef;
_depth = n->_depth - 1;
_touch = n->_touch;
for (int i = 0; i < (*it)->numTriangles(); i++)
_vit.push_back(_touch->insert( _touch->begin(), std::make_pair((*it)->triangle(i), this) ));
}
Recomb2D_Node::~Recomb2D_Node()
{ {
for (int i = 0; i < _vit.size(); i++) for (int i = 0; i < _vit.size(); i++)
_touch->erase(_vit[i]); _touch->erase(_vit[i]);
} }
void Node::erase() void Recomb2D_Node::erase()
{ {
for (int i = 0; i < _vit.size(); i++) for (int i = 0; i < _vit.size(); i++)
_touch->erase(_vit[i]); _touch->erase(_vit[i]);
} }
void Node::blocking(const Map_Tri_Node::iterator &it) void Recomb2D_Node::blocking(const Map_Tri_Node::iterator &it)
{ {
for (int i = 0; i < _vit.size(); i++) { for (int i = 0; i < _vit.size(); i++) {
if (it == _vit[i]) { if (it == _vit[i]) {
......
...@@ -19,14 +19,14 @@ ...@@ -19,14 +19,14 @@
#include "meshGFaceOptimize.h" #include "meshGFaceOptimize.h"
class RecombTriangle; class RecombTriangle;
class Node; class Recomb2D_Node;
struct lessRecombTri { struct lessRecombTri {
bool operator()(RecombTriangle *rt1, RecombTriangle *rt2) const; bool operator()(RecombTriangle *rt1, RecombTriangle *rt2) const;
}; };
typedef std::set<RecombTriangle*,lessRecombTri> Set_Recomb; typedef std::set<RecombTriangle*,lessRecombTri> Set_Recomb;
typedef std::map<MElement*,std::set<RecombTriangle*> > Map_Tri_Recomb; typedef std::map<MElement*,std::set<RecombTriangle*> > Map_Tri_Recomb;
typedef std::map<MElement*,Node*> Map_Tri_Node; typedef std::map<MElement*,Recomb2D_Node*> Map_Tri_Node;
class Recombine2D { class Recombine2D {
private : private :
...@@ -44,7 +44,7 @@ class Recombine2D { ...@@ -44,7 +44,7 @@ class Recombine2D {
void _recombine(); void _recombine();
Set_Recomb::iterator _bestNextRecombination(); Set_Recomb::iterator _bestNextRecombination();
void _removeImpossible(Set_Recomb::iterator); void _removeImpossible(Set_Recomb::iterator);
void _rmRT(RecombTriangle *, MElement *); void _rmRT(RecombTriangle *, MElement *e = NULL);
public : public :
Recombine2D(GFace*, int horizon); Recombine2D(GFace*, int horizon);
...@@ -62,6 +62,7 @@ class RecombTriangle { ...@@ -62,6 +62,7 @@ class RecombTriangle {
double _angle; double _angle;
double _benefit; double _benefit;
bool _formingQuad; bool _formingQuad;
int _sign;
public : public :
RecombTriangle(const MEdge &, MElement *, MElement *); RecombTriangle(const MEdge &, MElement *, MElement *);
...@@ -85,10 +86,10 @@ class RecombTriangle { ...@@ -85,10 +86,10 @@ class RecombTriangle {
double compute_alignment(const MEdge&, MElement*, MElement*); double compute_alignment(const MEdge&, MElement*, MElement*);
}; };
class Node { class Recomb2D_Node {
private : private :
double _benef, _totBenef; double _benef, _totBenef;
int _nskip; int _nskip, _depth;
Set_Recomb::iterator _recomb; Set_Recomb::iterator _recomb;
Map_Tri_Node *_touch; Map_Tri_Node *_touch;
std::vector<Map_Tri_Node::iterator> _vit; std::vector<Map_Tri_Node::iterator> _vit;
...@@ -96,15 +97,19 @@ class Node { ...@@ -96,15 +97,19 @@ class Node {
public : public :
//Node(){} //Node(){}
Node(Set_Recomb::iterator, Map_Tri_Node &, int, double ben = .0); //Recomb2D_Node(Set_Recomb::iterator, Map_Tri_Node &, int, double ben = .0);
~Node();
Recomb2D_Node(Set_Recomb::iterator, int nskip, int depth, Map_Tri_Node &);
Recomb2D_Node(Set_Recomb::iterator, int nskip, Recomb2D_Node *);
~Recomb2D_Node();
void erase(); void erase();
void blocking(const Map_Tri_Node::iterator &); void blocking(const Map_Tri_Node::iterator &);
bool isBetter() {return _blocking.size() < 2;} bool isBetter() {return _blocking.size() < 2;}
Set_Recomb::iterator getItRecomb() {return _recomb;} Set_Recomb::iterator getItRecomb() {return _recomb;}
double getTotBenef() {return _totBenef;} double getTotBenef() {return _totBenef;}
double getnSkip() {return _nskip;} int getnSkip() {return _nskip;}
double getBound() {return _totBenef + _benef * _depth;}
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment