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

No commit message

No commit message
parent 2b269858
No related branches found
No related tags found
No related merge requests found
......@@ -7,6 +7,12 @@
// 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 550
#include "meshGFaceRecombine.h"
#include "MElement.h"
#include "MTriangle.h"
......@@ -18,10 +24,6 @@
#include "Context.h"
#include "OS.h"
#define REC2D_EDGE_BASE 1
#define REC2D_EDGE_QUAD 1
#define REC2D_WAIT_TIME 1
// #define REC2D_SMOOTH
#define REC2D_DRAW
......@@ -30,20 +32,28 @@ bool Recombine2D::bo = 0;
double **Rec2DVertex::_qualVSnum = NULL;
double **Rec2DVertex::_gains = NULL;
int otherParity(int a) {
if (a % 2)
return a - 1;
return a + 1;
}
/*
TODO :
- map -> myset<pair> (mapCornerVert, mapVert, mapEdge)
- set -> myset
(_vertices, _edges, _elements) -> set
(_vertices, _edges, _elements) -> set
*/
void Recombine2D::associateParity(int pOld, int pNew)
{
std::set<Rec2DVertex*>::iterator it = _current->_parities[pOld].begin();
for (; it != _current->_parities[pOld].end(); ++it)
(*it)->setParity(pNew);
_current->_parities.erase(pOld);
if (pOld % 2)
pOld -= 1;
else
pOld +=1;
if (pNew % 2)
pNew -= 1;
else
pNew +=1;
pOld = otherParity(pOld);
pNew = otherParity(pNew);
it = _current->_parities[pOld].begin();
for (; it != _current->_parities[pOld].end(); ++it)
(*it)->setParity(pNew);
......@@ -55,21 +65,22 @@ void Recombine2D::associateParity(int pOld, int pNew)
Recombine2D::Recombine2D(GFace *gf) : _gf(gf)
{
if (Recombine2D::_current != NULL) {
Msg::Info("An instance of recombination is already in execution");
Msg::Warning("An instance of recombination is already in execution");
return;
}
Recombine2D::_current = this;
_numChange = 0;
backgroundMesh::set(gf);
_bgm = backgroundMesh::current();
Rec2DVertex::initStaticTable();
_numChange = 0;
_numEdge = _numVert = 0;
_valEdge = _valVert = .0;
Rec2DVertex::initStaticTable();
_tri = _gf->triangles;
// Be able to compute geometrical angle at corners
std::map<MVertex*, std::set<GEdge*> > mapCornerVert;
std::map<MVertex*, std::set<GEdge*> > mapCornerVert; // TOBE myset
{
std::list<GEdge*> listge = gf->edges();
std::list<GEdge*>::iterator itge = listge.begin();
......@@ -81,11 +92,13 @@ Recombine2D::Recombine2D(GFace *gf) : _gf(gf)
}
}
// Find all Vertices and edges
std::map<MVertex*, std::list<MTriangle*> > mapVert;
std::map<MEdge, std::list<MTriangle*>, Less_Edge> mapEdge;
// Find all Vertices and edges and create the 'Rec2DElement'
std::map<MVertex*, std::vector<MTriangle*> > mapVert; // TOBE myset
std::map<MEdge, std::vector<MTriangle*>, Less_Edge> mapEdge; // TOBE myset
for (unsigned int i = 0; i < gf->triangles.size(); ++i) {
MTriangle *t = gf->triangles[i];
Rec2DElement *el = new Rec2DElement(t);
_elements[t] = el; // ISITTOKEEP keep only list of relem, map local
for (int j = 0; j < 3; ++j) {
mapVert[t->getVertex(j)].push_back(t);
mapEdge[t->getEdge(j)].push_back(t);
......@@ -93,34 +106,31 @@ Recombine2D::Recombine2D(GFace *gf) : _gf(gf)
}
// Create the 'Rec2DVertex' and store iterator to vertices which have degree 4
std::list<std::map<MVertex*, std::list<MTriangle*> >::iterator> fourTri;
std::list<std::map<MVertex*, std::vector<MTriangle*> >::iterator> fourTri; // TOBE vector
{
mapofVertices::iterator itV2N = _vertices.begin();
std::map<MVertex*, std::list<MTriangle*> >::iterator itvert = mapVert.begin();
std::map<MVertex*, std::vector<MTriangle*> >::iterator itvert = mapVert.begin();
for (; itvert != mapVert.end(); ++itvert) {
MVertex *v = itvert->first;
int onWhat = 1;
if (mapCornerVert.find(v) != mapCornerVert.end())
onWhat = -1;
Rec2DVertex *rv = new Rec2DVertex(v, itvert->second, onWhat, mapCornerVert);
itV2N = _vertices.insert(itV2N, std::make_pair(v,rv));
++_numVert;
itV2N = _vertices.insert(itV2N, std::make_pair(v,rv)); // ISITTOKEEP keep only list of rvert, map local
if (itvert->second.size() == 4)
fourTri.push_back(itvert);
}
}
// Create the 'Rec2DEdge' and store boundary edges
std::map<MVertex*, std::list<MEdge> > boundV2E;
std::map<MVertex*, std::list<MEdge> > boundV2E; // TOBE myset
{
mapofEdges::iterator itE2E = _edges.begin();
std::map<MEdge, std::list<MTriangle*> >::iterator itedge = mapEdge.begin();
std::map<MEdge, std::vector<MTriangle*> >::iterator itedge = mapEdge.begin();
for (; itedge != mapEdge.end(); ++itedge) {
MEdge e = itedge->first;
Rec2DEdge *re = new Rec2DEdge(e, _vertices, itedge->second);
itE2E = _edges.insert(itE2E, std::make_pair(e,re));
_vertices[e.getVertex(0)]->add(re);
_vertices[e.getVertex(1)]->add(re);
_numEdge += REC2D_EDGE_BASE;
_valEdge += REC2D_EDGE_BASE * re->getQual();
if (itedge->second.size() == 1) {
......@@ -137,9 +147,11 @@ Recombine2D::Recombine2D(GFace *gf) : _gf(gf)
// We know now on what are vertices, compute reward
{
mapofVertices::iterator itV2N = _vertices.begin();
for (; itV2N != _vertices.end(); ++itV2N)
for (; itV2N != _vertices.end(); ++itV2N) {
++_numVert;
_valVert += itV2N->second->getQual();
}
}
// Be dealing with "parity" on boundaries
{
......@@ -186,14 +198,14 @@ Recombine2D::Recombine2D(GFace *gf) : _gf(gf)
// Create the 'Rec2DTwoTri2Quad' and 'Rec2DCollapseTri'
{
mapofEdges::iterator itE2E = _edges.begin();
std::map<MEdge, std::list<MTriangle*> >::iterator ite = mapEdge.begin();
std::map<MEdge, std::vector<MTriangle*> >::iterator ite = mapEdge.begin();
for (; ite != mapEdge.end(); ++ite)
if (ite->second.size() == 2) {
Rec2DTwoTri2Quad *q = new Rec2DTwoTri2Quad(_edges[ite->first], ite->second);
//Rec2DCollapseTri *c = new Rec2DCollapseTri(_edges[ite->first], ite->second);
_actions.push_back(q);
//_actions.insert(c);
std::list<MTriangle*>::iterator it = ite->second.begin();
std::vector<MTriangle*>::iterator it = ite->second.begin();
_mea[*it].insert(q);
//_mea[*it].insert(c);
++it;
......@@ -202,58 +214,24 @@ Recombine2D::Recombine2D(GFace *gf) : _gf(gf)
}
}
// Rec2DTwoTri2Quad
/*{
std::list<std::map<MVertex*, std::list<MTriangle*> >::iterator>::iterator it4;
for (it4 = fourTri.begin(); it4 != fourTri.end(); it4++) {
Rec2DVertex *rv = _vertices[(*it4)->first];
std::set<MEdge, Less_Edge> setEdge;
{
std::list<MTriangle*>::iterator it = (*it4)->second.begin();
for (; it != (*it4)->second.end(); ++it) {
setEdge.insert((*it)->getEdge(0));
setEdge.insert((*it)->getEdge(1));
setEdge.insert((*it)->getEdge(2));
}
}
std::set<MEdge>::iterator it = setEdge.begin();
for (; it != setEdge.end(); ++it) {
std::map<MEdge, std::list<MTriangle*> >::iterator it2;
it2 = mapEdge.find(*it);
if (it2 != mapEdge.end())
if (it2->second.size() == 2) {
Rec2DTwoTri2Quad *q = new Rec2DTwoTri2Quad(_edges[it2->first], it2->second);
_actions.insert(q);
std::list<MTriangle*>::iterator it = it2->second.begin();
_mea[*it].insert(q);
++it;
_mea[*it].insert(q);
}
else
Msg::Error("fjdaks;lfjkdsa;");
}
}
}*/
// Create the 'Rec2DFourTri2Quad' and 'Rec2DCollapseTri'
{
std::list<std::map<MVertex*, std::list<MTriangle*> >::iterator>::iterator it4;
for (it4 = fourTri.begin(); it4 != fourTri.end(); it4++) {
Rec2DVertex *rv = _vertices[(*it4)->first];
if (!rv->getIsOnBoundary()) {
Rec2DFourTri2Quad *q = new Rec2DFourTri2Quad(rv, (*it4)->second);
//Rec2DCollapseTri *c = new Rec2DCollapseTri(rv, (*it4)->second);
_actions.push_back(q);
//_actions.insert(c);
std::list<MTriangle*>::iterator it = (*it4)->second.begin();
for (; it != (*it4)->second.end(); ++it) {
_mea[*it].insert(q);
//_mea[*it].insert(c);
}
}
}
}
//{
// std::list<std::map<MVertex*, std::vector<MTriangle*> >::iterator>::iterator it4;
// for (it4 = fourTri.begin(); it4 != fourTri.end(); it4++) {
// Rec2DVertex *rv = _vertices[(*it4)->first];
// if (!rv->getIsOnBoundary()) {
// Rec2DFourTri2Quad *q = new Rec2DFourTri2Quad(rv, (*it4)->second);
// //Rec2DCollapseTri *c = new Rec2DCollapseTri(rv, (*it4)->second);
// _actions.push_back(q);
// //_actions.insert(c);
// std::vector<MTriangle*>::iterator it = (*it4)->second.begin();
// for (; it != (*it4)->second.end(); ++it) {
// _mea[*it].insert(q);
// //_mea[*it].insert(c);
// }
// }
// }
//}
Msg::Info("State");
Msg::Info("-----");
......@@ -278,34 +256,43 @@ Recombine2D::Recombine2D(GFace *gf) : _gf(gf)
Recombine2D::~Recombine2D()
{
Recombine2D::_current = NULL;
//delete vertices, edges, actions;
//delete vertices, edges, elements, actions;
}
bool Recombine2D::recombine()
{
Rec2DAction *nextAction;
while (_actions.size() > 0) {
int i = -1;
while (_actions.size() > 0 && ++i < REC2D_NUM_ACTIO) {
double t = Cpu();
nextAction = *std::max_element(_actions.begin(), _actions.end(),
lessRec2DAction() );
if (nextAction->getReward() > 0) {
nextAction->color(0, 0, 200);
CTX::instance()->mesh.changed = (ENT_ALL);
FlGui::instance()->check();
drawContext::global()->draw();
//if (nextAction->getReward() > 0) {
if (_isAllQuad(nextAction))
_choose(nextAction);
else {
nextAction->color(190, 0, 0);
_removeReference(nextAction);
}
}
/*}
else {
nextAction->color(0, 100, 0);
_removeReference(nextAction);
}
}*/
_gf->triangles = _tri;
_gf->quadrangles = _quad;
#ifdef REC2D_DRAW
//Msg::Info("%d", REC2D_NUM_ACTIO-i);
//Msg::GetAnswer("Continue ?", 1, "no", "yes");
CTX::instance()->mesh.changed = (ENT_ALL);
FlGui::instance()->check();
if (i%5 == 0)
drawContext::global()->draw();
while (Cpu()-t < REC2D_WAIT_TIME)
FlGui::instance()->check();
......@@ -316,45 +303,62 @@ bool Recombine2D::recombine()
std::map<int, std::set<Rec2DVertex*> >::iterator it = _parities.begin();
for (; it != _parities.end(); ++it) {
Msg::Info("par %d, #%d", it->first, it->second.size());
}
}
Msg::Info("State");
Msg::Info("-----");
Msg::Info("numEdge %d (%d), valEdge %g", _numEdge, _edges.size(), _valEdge);
Msg::Info("numVert %d (%d), valVert %g", _numVert, _vertices.size(), _valVert);
Msg::Info("global Value %g", Recombine2D::getGlobalValue(0,0,0,0));
Msg::Info("num action %d", _actions.size());
std::map<int, std::set<Rec2DVertex*> >::iterator it = _parities.begin();
for (; it != _parities.end(); ++it) {
Msg::Info("par %d, #%d", it->first, it->second.size());
//Msg::Info("par %d, #%d", it->first, it->second.size());
}
mapofElementActions::iterator it2 = _mea.begin();
int a = 0;
for (; it2 != _mea.end(); ++it2) {
a += it2->second.size();
}
if (a > 0)
Msg::Info("%d elements in mapof elem to action, with average action %g", _mea.size(), (double)a/_mea.size());
Msg::Info(" ");
//
// Msg::Info("State");
// Msg::Info("-----");
// Msg::Info("numEdge %d (%d), valEdge %g", _numEdge, _edges.size(), _valEdge);
// Msg::Info("numVert %d (%d), valVert %g", _numVert, _vertices.size(), _valVert);
// Msg::Info("global Value %g", Recombine2D::getGlobalValue(0,0,0,0));
// Msg::Info("num action %d", _actions.size());
// std::map<int, std::set<Rec2DVertex*> >::iterator it = _parities.begin();
// for (; it != _parities.end(); ++it) {
// Msg::Info("par %d, #%d", it->first, it->second.size());
// }
// mapofElementActions::iterator it2 = _mea.begin();
// int a = 0;
// for (; it2 != _mea.end(); ++it2) {
// a += it2->second.size();
// }
// if (a > 0)
// Msg::Info("%d elements in mapof elem to action, with average action %g", _mea.size(), (double)a/_mea.size());
// Msg::Info(" ");
//
return 1;
}
bool Recombine2D::_isAllQuad(Rec2DAction *action)
{
//Msg::Info(" ---new isAllQuad---");
int p[4];
action->getParities(p);
if (p[0] < 0 && p[1] < 0 && p[2] < 0 && p[3] < 0)
if (p[0] < 0 && p[1] < 0 && p[2] < 0 && p[3] < 0) {
Msg::Info("is isolated");
return true;
}
if (action->isObsolete()) {
Msg::Error("[Recombine2D] obsolete action");
Msg::Error("[Recombine2D] obsolete action (allQuad)");
return false;
}
std::set<Rec2DVertex*> setRv;
std::set<Rec2DElement*> neighbours, checked;
for (int i = 0; i < Recombine2D::getNumVertAllQuad(); ++i) {
if (Recombine2D::getVertAllQuad(i)->hasTriangle())
Recombine2D::getVertAllQuad(i)->getElements(neighbours);
else
setRv.insert(Recombine2D::getVertAllQuad(i));
}
std::set<Rec2DVertex*>::iterator itit = setRv.begin();
for (; itit != setRv.end(); ++itit)
Recombine2D::removeVertAllQuad(*itit);
setRv.clear();
int min = 100, index;
for (int i = 0; i < 4; ++i) {
if (p[i] > -1 && min > p[i]) {
......@@ -362,253 +366,243 @@ bool Recombine2D::_isAllQuad(Rec2DAction *action)
index = i;
}
}
//Quid si p[0..4] = -1 ?
//Msg::Info("Passsed through there, [%d %d %d %d] -> min %d", p[0], p[1], p[2], p[3], min);
std::map<Rec2DVertex*, int> newParVert;
std::map<Rec2DVertex*, int>::iterator it2;
std::map<int, int> parAssoc; // first parity value become second parity value
std::map<int, int>::iterator itassoc;
for (int i = 0; i < 4; i += 2) {
int par;
if ((index/2) * 2 == i)
par = min;
else if (min % 2)
par = min - 1;
else
par = min + 1;
par = otherParity(min);
for (int j = 0; j < 2; ++j) {
if (p[i+j] == -1)
if (p[i+j] == -1) {
newParVert.insert(std::make_pair(action->getRVertex(i+j), par));
else if (p[i+j] != par)
parAssoc.insert(std::make_pair(p[i+j], par));
action->getRVertex(i+j)->getElements(neighbours);
}
else if (p[i+j] != par) {
if (parAssoc.find(p[i+j]) == parAssoc.end()) {
parAssoc[p[i+j]] = par;
parAssoc[otherParity(p[i+j])] = otherParity(par);
_getElemToLook(p[i+j], neighbours);
_getElemToLook(otherParity(p[i+j]), neighbours);
}
std::set<Rec2DAction*> neighbours;
_getNeighbours(action, neighbours);
while (neighbours.size() > 0) {
std::set<Rec2DAction*>::iterator it = neighbours.begin();
if ((*it)->getNum() != 1) {
neighbours.erase(it);
continue;
}
Rec2DVertex *v0 = (*it)->getRVertex(0);
Rec2DVertex *v1 = (*it)->getRVertex(1);
std::map<Rec2DVertex*, int>::iterator it2;
int p0 = v0->getParity(), p1 = v1->getParity();
if (p0 < 0 && (it2 = newParVert.find(v0)) == newParVert.end()) {
neighbours.erase(it);
continue;
}
if (p0 < 0)
p0 = it2->second;
if (p1 < 0 && (it2 = newParVert.find(v1)) == newParVert.end()) {
neighbours.erase(it);
continue;
}
if (p1 < 0)
p1 = it2->second;
std::map<int, int>::iterator it3;
if ((it3 = parAssoc.find(p0)) != parAssoc.end())
p0 = it3->second;
if ((it3 = parAssoc.find(p1)) != parAssoc.end())
p1 = it3->second;
while (neighbours.size() > 0) {
//Msg::Info("num vert %d, num neigh %d", newParVert.size(), neighbours.size());
if (p0 != p1) {
neighbours.erase(it);
std::set<Rec2DElement*>::iterator itel = neighbours.begin();
Rec2DElement *element = *itel;
if (element->isQuad()) {
neighbours.erase(itel);
continue;
}
int par;
bool hasChange = false;
if (p0 % 2)
par = p0 - 1;
else
par = p0 + 1;
(*it)->getParities(p);
for (int j = 2; j < 4; ++j) {
if (p[j] == -1) {
if ((it2 = newParVert.find((*it)->getRVertex(j))) == newParVert.end()) {
newParVert.insert(std::make_pair(action->getRVertex(j), par));
hasChange = true;
}
else if (it2->second != par)
return false;
Rec2DVertex *v[3];
element->getVertices(v);
int p[3];
for (int i = 0; i < 3; ++i) {
if ((it2 = newParVert.find(v[i])) != newParVert.end()) {
p[i] = it2->second;
while ((itassoc = parAssoc.find(p[i])) != parAssoc.end()) {
p[i] = itassoc->second;
}
else if (p[j] != par) {
if ((it3 = parAssoc.find(p[j])) == parAssoc.end()) {
parAssoc.insert(std::make_pair(p[j], par));
hasChange = true;
it2->second = p[i];
}
else {
int a = it3->second;
while (a != par && (it3 = parAssoc.find(a)) != parAssoc.end()) {
a = it3->second;
p[i] = v[i]->getParity();
if ((itassoc = parAssoc.find(p[i])) != parAssoc.end()) {
do
p[i] = itassoc->second;
while ((itassoc = parAssoc.find(p[i])) != parAssoc.end());
newParVert[v[i]] = p[i];
}
if (a != par)
return false;
}
}
//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) {
if (p[i] > -1 && p[i] == p[(i+1)%3]) hasIdentical = true;
}
Rec2DAction *ra = *it;
neighbours.erase(it);
if (hasChange)
_getNeighbours(ra, neighbours);
if (!hasIdentical) {
neighbours.erase(itel);
continue;
}
return true;
if (p[0] == p[1] && p[0] == p[2]) {
Msg::Info("3 identical par");
return false;
}
//Msg::Info("has identical");
void Recombine2D::_choose(Rec2DAction *action)
{
action->apply();
_removeIncompatible(action);
++_numChange;
bool hasAction = false;
std::map<Rec2DVertex*, std::vector<int> > suggestions;
for (int i = 0; i < element->getNumActions(); ++i) {
if (element->getAction(i)->whatImply(v, p, suggestions))
hasAction = true;
}
//Msg::Info("suggest %d", suggestions.size());
void Recombine2D::_removeIncompatible(Rec2DAction *action)
{
std::set<MTriangle*> touchedTri;
action->getTriangles(touchedTri);
std::set<MTriangle*>::iterator itTouched;
if (!hasAction) {
Msg::Info("No action %d", (*itel)->getNum());
return false;
}
std::set<Rec2DAction*> incomp;
{
itTouched = touchedTri.begin();
for (; itTouched != touchedTri.end(); ++itTouched) {
mapofElementActions::iterator ite2a = _mea.find(*itTouched);
if (ite2a != _mea.end()) {
std::set<Rec2DAction*>::iterator ita = ite2a->second.begin();
for (; ita != ite2a->second.end(); ++ita)
incomp.insert(*ita);
std::map<Rec2DVertex*, std::vector<int> >::iterator itsug;
itsug = suggestions.begin();
for (; itsug != suggestions.end(); ++itsug) {
int par = itsug->second.front();
bool onlyOnePar = true;
for (unsigned int i = 1; i < itsug->second.size(); ++i) {
if (itsug->second[i] != par) {
onlyOnePar = false;
break;
}
else
Msg::Error("[Recombine2D] didn't found triangle %d (rmIncomp1)", (*itTouched)->getNum());
}
if (onlyOnePar) {
if ((itassoc = parAssoc.find(par)) != parAssoc.end()) {
do
par = itassoc->second;
while ((itassoc = parAssoc.find(par)) != parAssoc.end());
}
std::set<Rec2DAction*>::iterator itIncomp = incomp.begin();
for (; itIncomp != incomp.end(); ++itIncomp) {
std::set<MTriangle*> touched;
(*itIncomp)->getTriangles(touched);
for (itTouched = touched.begin(); itTouched != touched.end(); ++itTouched) {
mapofElementActions::iterator ite2a = _mea.find(*itTouched);
if (ite2a != _mea.end()) {
bool b = ite2a->second.erase(*itIncomp);
if (!b)
Msg::Error("[Recombine2D] Tri->Action not found (rmIncomp)");
int oldPar;
Rec2DVertex *v = itsug->first;
if ((it2 = newParVert.find(v)) != newParVert.end()) {
oldPar = it2->second;
while ((itassoc = parAssoc.find(oldPar)) != parAssoc.end()) {
oldPar = itassoc->second;
}
else
Msg::Error("[Recombine2D] didn't found triangle %d (rmIncomp)", (*itTouched)->getNum());
it2->second = oldPar;
}
//bool b = _actions.erase(*itIncomp);
setofRec2DAction::iterator it2 = _actions.begin();
bool b = false;
while (it2 != _actions.end()) {
if (*it2 == *itIncomp) {
_actions.erase(it2);
b = true;
break;
else {
oldPar = v->getParity();
if ((itassoc = parAssoc.find(oldPar)) != parAssoc.end()) {
do
oldPar = itassoc->second;
while ((itassoc = parAssoc.find(oldPar)) != parAssoc.end());
newParVert[v] = oldPar;
}
}
//Msg::Info("a %d, %d", par, oldPar);
if (oldPar == -1) {
//Msg::Info("b");
newParVert[v] = par;
v->getElements(neighbours);
}
else if ((par/2)*2 != (oldPar/2)*2) {
//Msg::Info("c");
if (oldPar < par) {
int a = oldPar;
oldPar = par;
par = a;
}
parAssoc[oldPar] = par;
parAssoc[otherParity(oldPar)] = otherParity(par);
_getElemToLook(oldPar, neighbours);
_getElemToLook(otherParity(oldPar), neighbours);
}
else if (par%2 != oldPar%2) {
//Msg::Info("d");
Msg::Info("not all quad");
return false;
}
++it2;
}
if (!b)
Msg::Error("[Recombine2D] action not found (rmIncomp2)");
delete *itIncomp;
}
itTouched = touchedTri.begin();
for (; itTouched != touchedTri.end(); ++itTouched) {
bool b = _mea.erase(*itTouched);
if (!b)
Msg::Error("[Recombine2D] triangle not found %d", (*itTouched)->getNum());
neighbours.erase(itel);
}
Msg::Info("all quad");
return true;
}
void Recombine2D::_removeReference(Rec2DAction *action)
void Recombine2D::_choose(Rec2DAction *action)
{
std::set<MTriangle*> touchedTri;
action->getTriangles(touchedTri);
std::set<MTriangle*>::iterator it = touchedTri.begin();
for (; it != touchedTri.end(); ++it) {
mapofElementActions::iterator ite2a = _mea.find(*it);
if (ite2a != _mea.end()) {
bool b = ite2a->second.erase(action);
if (!b)
Msg::Error("[Recombine2D] Tri->Action not found (rmRef)");
}
else
Msg::Error("[Recombine2D] didn't found triangle %d (rmRef)", (*it)->getNum());
}
//bool b = _actions.erase(action);
setofRec2DAction::iterator it2 = _actions.begin();
bool b = false;
while (it2 != _actions.end()) {
if (*it2 == action) {
_actions.erase(it2);
b = true;
break;
}
++it2;
}
if (!b)
Msg::Error("[Recombine2D] action not found (rmRef)");
delete action;
action->apply(); //to check
_removeIncompatible(action); //to check
++_numChange; //to check
}
void Recombine2D::_getNeighbours(Rec2DAction *ra, std::set<Rec2DAction*> &actions)
void Recombine2D::_removeIncompatible(Rec2DAction *action) //to check
{
std::set<MTriangle*> touchedTri;
ra->getTriangles(touchedTri);
std::set<MTriangle*>::iterator itTouched;
std::set<Rec2DElement*> touchedTri;
action->getRTriangles(touchedTri);
std::set<Rec2DElement*>::iterator itTri;
std::set<Rec2DAction*> incomp;
{
itTouched = touchedTri.begin();
for (; itTouched != touchedTri.end(); ++itTouched) {
mapofElementActions::iterator ite2a = _mea.find(*itTouched);
if (ite2a != _mea.end()) {
std::set<Rec2DAction*>::iterator ita = ite2a->second.begin();
for (; ita != ite2a->second.end(); ++ita)
incomp.insert(*ita);
itTri = touchedTri.begin();
for (; itTri != touchedTri.end(); ++itTri)
(*itTri)->getActions(incomp);
}
else
Msg::Error("[Recombine2D.] didn't found triangle %d (rmIncomp1)", (*itTouched)->getNum());
//Msg::Warning("size %d", incomp.size());
std::set<Rec2DAction*>::iterator itAction = incomp.begin();
for (; itAction != incomp.end(); ++itAction) {
delete *itAction;
}
}
std::set<Rec2DAction*>::iterator it = incomp.begin();
for (; it != incomp.end(); ++it) {
(*it)->getTriangles(touchedTri);
void Recombine2D::_removeReference(Rec2DAction *action)
{
delete action;
}
std::set<Rec2DAction*> neighbours;
//void Recombine2D::_getNeighbours(Rec2DAction *ra, std::set<Rec2DAction*> &actions)
//{
// std::set<Rec2DElement*> touchedTri, neighbourTri;
// ra->getRTriangles(touchedTri);
// std::set<Rec2DElement*>::iterator itTri;
//
// {
// itTri = touchedTri.begin();
// for (; itTri != touchedTri.end(); ++itTri)
// (*itTri)->getNeighbours(neighbourTri);
// //itTri = touchedTri.begin();
// //for (; itTri != touchedTri.end(); ++itTri)
// // neighbourTri.erase(*itTri);
// }
//
// std::set<Rec2DAction*> incomp, neighbours;
// {
// itTri = touchedTri.begin();
// for (; itTri != touchedTri.end(); ++itTri)
// (*itTri)->getActions(neighbours);
// itTri = neighbourTri.begin();
// for (; itTri != neighbourTri.end(); ++itTri)
// (*itTri)->getActions(neighbours);
// }
//
// std::set<Rec2DAction*>::iterator itAction = incomp.begin();
// for (; itAction != incomp.end(); ++itAction) {
// bool b = neighbours.erase(*itAction);
// if (!b)
// Msg::Error("[Recombine2D] didn't found incomp action");
// }
//
// for (itAction = neighbours.begin(); itAction != neighbours.end(); ++itAction) {
// actions.insert(*itAction);
// }
//}
void Recombine2D::_getElemToLook(int par, std::set<Rec2DElement*> &elem)
{
itTouched = touchedTri.begin();
for (; itTouched != touchedTri.end(); ++itTouched) {
mapofElementActions::iterator ite2a = _mea.find(*itTouched);
if (ite2a != _mea.end()) {
std::set<Rec2DAction*>::iterator ita = ite2a->second.begin();
for (; ita != ite2a->second.end(); ++ita)
neighbours.insert(*ita);
}
else
Msg::Error("[Recombine2D.] didn't found triangle %d (rmIncomp1)", (*itTouched)->getNum());
}
std::set<Rec2DAction*>::iterator itIncomp = incomp.begin();
for (; itIncomp != incomp.end(); ++itIncomp) {
bool b = neighbours.erase(*itIncomp);
if (!b)
Msg::Error("[Recombine2D] didn't found incomp action");
std::set<Rec2DVertex*>::iterator it = _parities[par].begin();
std::set<Rec2DVertex*>::iterator itend = _parities[par].end();
for (; it != itend; ++it) {
(*it)->getElements(elem);
}
}
for (it = neighbours.begin(); it != neighbours.end(); ++it) {
actions.insert(*it);
}
}
double Recombine2D::getGlobalValue(int numEdge, double valEdge,
int numVert, double valVert )
......@@ -617,6 +611,15 @@ double Recombine2D::getGlobalValue(int numEdge, double valEdge,
return (_current->_valEdge + valEdge) / (_current->_numEdge + numEdge) * a * a;
}
//Rec2DVertex* Recombine2D::getRVertex(MVertex *v)
//{
// mapofVertices::iterator it = _current->_vertices.find(v);
// if (it != _current->_vertices.end())
// return it->second;
// Msg::Error("[Recombine2D::getRVertex] vertex not found");
// return NULL;
//}
Rec2DEdge* Recombine2D::getREdge(MEdge e)
{
mapofEdges::iterator it = _current->_edges.find(e);
......@@ -626,12 +629,12 @@ Rec2DEdge* Recombine2D::getREdge(MEdge e)
return NULL;
}
Rec2DVertex* Recombine2D::getRVertex(MVertex *v)
Rec2DElement* Recombine2D::getRElement(MElement *el)
{
mapofVertices::iterator it = _current->_vertices.find(v);
if (it != _current->_vertices.end())
mapofElements::iterator it = _current->_elements.find(el);
if (it != _current->_elements.end())
return it->second;
Msg::Error("[Recombine2D::getRVertex] vertex not found");
Msg::Error("[Recombine2D::getRElement] element not found");
return NULL;
}
......@@ -653,16 +656,38 @@ void Recombine2D::remove(MVertex *v)
Msg::Error("[Recombine2D::getRVertex] vertex not found");
}
void Recombine2D::remove(MTriangle *tri)
void Recombine2D::remove(Rec2DElement *tri)
{
Rec2DVertex *v[3];
tri->getVertices(v);
for (int i = 0; i < 3; ++i) {
v[i]->remove(tri);
}
MTriangle *t = tri->getMTriangle();
std::vector<MTriangle*>::iterator it = _current->_tri.begin();
for (; it != _current->_tri.end(); ++it) {
if (*it == tri) {
if (*it == t) {
_current->_tri.erase(it);
return;
}
}
Msg::Error("[Recombine2D] triangle %d was not there", tri->getNum());
Msg::Error("[Recombine2D] triangle was not there");
}
void Recombine2D::remove(Rec2DAction *ra)
{
setofRec2DAction::iterator itAction = _current->_actions.begin();
bool b = false;
while (itAction != _current->_actions.end()) {
if (*itAction == ra) {
_current->_actions.erase(itAction);
b = true;
break;
}
++itAction;
}
if (!b)
Msg::Error("[Recombine2D] action to delete not found");
}
void Recombine2D::add(MQuadrangle *quad)
......@@ -673,6 +698,12 @@ void Recombine2D::add(MQuadrangle *quad)
/** Rec2DAction **/
/*******************/
bool lessRec2DAction::operator()(Rec2DAction *ra1, Rec2DAction *ra2) const
{
return *ra1 < *ra2;
}
bool Rec2DAction::operator<(Rec2DAction &other)
{
return getReward() < other.getReward();
......@@ -680,6 +711,7 @@ bool Rec2DAction::operator<(Rec2DAction &other)
MQuadrangle* Rec2DAction::_createQuad(std::vector<Rec2DEdge*> &boundEdge) const
{
//Msg::Info("Imhere");
if (boundEdge.size() != 4) {
Msg::Error("[Rec2DAction] Not 4 edges for quad creation");
return new MQuadrangle(NULL, NULL, NULL, NULL);
......@@ -717,16 +749,17 @@ MQuadrangle* Rec2DAction::_createQuad(std::vector<Rec2DEdge*> &boundEdge) const
/** Rec2DTwoTri2Quad **/
/************************/
Rec2DTwoTri2Quad::Rec2DTwoTri2Quad(Rec2DEdge *re, std::list<MTriangle*> &tri)
Rec2DTwoTri2Quad::Rec2DTwoTri2Quad(Rec2DEdge *re, std::vector<MTriangle*> &tri)
{
int i;
std::set<MEdge, Less_Edge> extEdges;
{
std::list<MTriangle*>::iterator it = tri.begin();
std::vector<MTriangle*>::iterator it = tri.begin();
for (i = 0; it != tri.end() && i < 2; ++it, ++i) {
_rtriangles[i] = Recombine2D::getRElement(*it);
_rtriangles[i]->add(this);
for (int j = 0; j < 3; ++j)
extEdges.insert((*it)->getEdge(j));
_triangles[i] = *it;
}
if (it != tri.end() || i < 2)
Msg::Error("[Rec2DTwoTri2Quad] Wrong number of triangles");
......@@ -742,34 +775,39 @@ Rec2DTwoTri2Quad::Rec2DTwoTri2Quad(Rec2DEdge *re, std::list<MTriangle*> &tri)
_vertices[0] = re->getRVertex(0);
_vertices[1] = re->getRVertex(1);
MVertex *v2, *v3;
v2 = _triangles[0]->getOtherVertex(_vertices[0]->getMVertex(),
_vertices[1]->getMVertex());
v3 = _triangles[1]->getOtherVertex(_vertices[0]->getMVertex(),
_vertices[1]->getMVertex());
_vertices[2] = Recombine2D::getRVertex(v2);
_vertices[3] = Recombine2D::getRVertex(v3);
_vertices[2] = _rtriangles[0]->getOtherVertex(_vertices[0], _vertices[1]);
_vertices[3] = _rtriangles[1]->getOtherVertex(_vertices[0], _vertices[1]);
_computeGlobVal();
}
Rec2DTwoTri2Quad::~Rec2DTwoTri2Quad()
{
_rtriangles[0]->remove(this);
_rtriangles[1]->remove(this);
}
bool Rec2DTwoTri2Quad::isObsolete()
{
int p0 = _vertices[0]->getParity();
int p1 = _vertices[1]->getParity();
int p2 = _vertices[2]->getParity();
int p3 = _vertices[3]->getParity();
if (p0>-1 && p1>-1 && p0/2 == p1/2 && p0 % 2 != p1 % 2 ||
p2>-1 && p3>-1 && p2/2 == p3/2 && p2 % 2 != p3 % 2 ||
p0>-1 && p0 == p2 ||
p0>-1 && p0 == p3 ||
p1>-1 && p1 == p2 ||
p1>-1 && p1 == p3 )
int p[4];
p[0] = _vertices[0]->getParity();
p[1] = _vertices[1]->getParity();
p[2] = _vertices[2]->getParity();
p[3] = _vertices[3]->getParity();
return Rec2DTwoTri2Quad::isObsolete(p);
}
bool Rec2DTwoTri2Quad::isObsolete(int *p)
{
if (p[0]>-1 && p[1]>-1 && p[0]/2 == p[1]/2 && p[0]%2 != p[1]%2 ||
p[2]>-1 && p[3]>-1 && p[2]/2 == p[3]/2 && p[2]%2 != p[3]%2 ||
p[0]>-1 && (p[0] == p[2] || p[0] == p[3]) ||
p[1]>-1 && (p[1] == p[2] || p[1] == p[3]) )
return true;
return false;
}
void Rec2DTwoTri2Quad::apply()
void Rec2DTwoTri2Quad::apply() //to check
{
if (isObsolete()) {
Msg::Error("[Rec2DTwoTri2Quad] Applying obsolet action");
......@@ -778,8 +816,8 @@ void Rec2DTwoTri2Quad::apply()
int min = 100, index = -1;
for (int i = 0; i < 4; ++i) {
if (_vertices[0]->getParity() > -1 && min > _vertices[0]->getParity()) {
min = _vertices[0]->getParity();
if (_vertices[i]->getParity() > -1 && min > _vertices[i]->getParity()) {
min = _vertices[i]->getParity();
index = i;
}
}
......@@ -789,21 +827,23 @@ void Rec2DTwoTri2Quad::apply()
_vertices[1]->setParity(par);
_vertices[2]->setParity(par+1);
_vertices[3]->setParity(par+1);
Recombine2D::addVertAllQuad(_vertices[0]);
Recombine2D::addVertAllQuad(_vertices[1]);
Recombine2D::addVertAllQuad(_vertices[2]);
Recombine2D::addVertAllQuad(_vertices[3]);
}
else {
for (int i = 0; i < 4; i += 2) {
int par;
if ((index/2) * 2 == i)
par = min;
else if (min % 2)
par = min - 1;
else
par = min + 1;
Msg::Info("%d", par);
par = otherParity(min);
for (int j = 0; j < 2; ++j) {
Msg::Info(" %d %d", _vertices[i+j]->getParity(), par);
if (_vertices[i+j]->getParity() == -1)
if (_vertices[i+j]->getParity() == -1) {
_vertices[i+j]->setParity(par);
Recombine2D::addVertAllQuad(_vertices[i+j]);
}
else if (_vertices[i+j]->getParity() != par)
Recombine2D::associateParity(_vertices[0]->getParity(), par);
}
......@@ -818,8 +858,8 @@ void Rec2DTwoTri2Quad::apply()
Recombine2D::addValEdge(valEdge);
//Recombine2D::addValVert(_vertices[0]->getGain(-1) + _vertices[1]->getGain(-1));
Recombine2D::remove(_triangles[0]); // FIXME not performant at all !!!
Recombine2D::remove(_triangles[1]);
Recombine2D::remove(_rtriangles[0]); // FIXME not performant at all !!!
Recombine2D::remove(_rtriangles[1]);
std::vector<Rec2DEdge*> edges;
for (int i = 1; i < 5; ++i)
edges.push_back(_edges[i]);
......@@ -855,408 +895,473 @@ void Rec2DTwoTri2Quad::_computeGlobVal()
void Rec2DTwoTri2Quad::color(int a, int b, int c)
{
unsigned int col = CTX::instance()->packColor(a, b, c, 255);
_triangles[0]->setCol(col);
_triangles[1]->setCol(col);
_rtriangles[0]->getMElement()->setCol(col);
_rtriangles[1]->getMElement()->setCol(col);
}
/** Rec2DFourTri2Quad **/
/*************************/
Rec2DFourTri2Quad::Rec2DFourTri2Quad(Rec2DVertex *rv, std::list<MTriangle*> &tri)
bool Rec2DTwoTri2Quad::whatImply(
Rec2DVertex **rv, int *par,
std::map<Rec2DVertex*, std::vector<int> > &suggestions)
{
int i, j;
std::set<MEdge, Less_Edge> edges;
{
std::list<MTriangle*>::iterator it = tri.begin();
for (i = 0; it != tri.end() && i < 4; ++it, ++i) {
for (j = 0; j < 3; ++j)
edges.insert((*it)->getEdge(j));
_triangles[i] = *it;
}
if (it != tri.end() || i < 4)
Msg::Error("[Rec2DFourTri2Quad] Wrong number of triangles");
}
std::set<MEdge>::iterator ite = edges.begin();
for (i = 0, j = 4; ite != edges.end() && (i < 4 || j < 8); ++ite) {
if ((*ite).getVertex(0) == rv->getMVertex() ||
(*ite).getVertex(1) == rv->getMVertex() )
_edges[i++] = Recombine2D::getREdge(*ite);
else if (j < 8)
_edges[j++] = Recombine2D::getREdge(*ite);
else
Msg::Error("[Rec2DFourTri2Quad] Too much exterior edges");
}
if (edges.size() > 8 || ite != edges.end() || i < 4 || i > 4 || j < 8)
Msg::Error("[Rec2DFourTri2Quad] Wrong number of edges");
_vertices[4] = rv;
// the 4 other must be in order : 2 non adjacent + last 2
_vertices[1] = _edges[4]->getRVertex(0);
_vertices[3] = _edges[4]->getRVertex(1);
for (int i = 5; i < 8; ++i) {
if (_edges[i]->getRVertex(0) == _vertices[1])
_vertices[0] = _edges[i]->getRVertex(1);
if (_edges[i]->getRVertex(1) == _vertices[1])
_vertices[0] = _edges[i]->getRVertex(0);
if (_edges[i]->getRVertex(0) == _vertices[3])
_vertices[2] = _edges[i]->getRVertex(1);
if (_edges[i]->getRVertex(1) == _vertices[3])
_vertices[2] = _edges[i]->getRVertex(0);
}
_computeGlobVal();
}
bool Rec2DFourTri2Quad::isObsolete()
{
int p0 = _vertices[0]->getParity();
int p1 = _vertices[1]->getParity();
int p2 = _vertices[2]->getParity();
int p3 = _vertices[3]->getParity();
if (p0>-1 && p1>-1 && p0/2 == p1/2 && p0 % 2 != p1 % 2 ||
p2>-1 && p3>-1 && p2/2 == p3/2 && p2 % 2 != p3 % 2 ||
p0>-1 && p0 == p2 ||
p0>-1 && p0 == p3 ||
p1>-1 && p1 == p2 ||
p1>-1 && p1 == p3 )
return true;
return false;
}
void Rec2DFourTri2Quad::apply()
{
double valEdge = 0;
for (int i = 0; i < 4; ++i)
valEdge -= REC2D_EDGE_BASE * _edges[i]->getQual();
for (int i = 4; i < 8; ++i)
valEdge += REC2D_EDGE_QUAD * _edges[i]->getQual();
double valVert = - _vertices[4]->getQual();
for (int i = 0; i < 4; ++i)
valEdge += _vertices[i]->getGain(-1);
Recombine2D::addNumEdge(4*REC2D_EDGE_QUAD - 4*REC2D_EDGE_BASE);
Recombine2D::addNumVert(-1);
Recombine2D::addValEdge(valEdge);
Recombine2D::addValVert(valVert);
Recombine2D::remove(_triangles[0]); // FIXME not performant at all !!!
Recombine2D::remove(_triangles[1]);
Recombine2D::remove(_triangles[2]);
Recombine2D::remove(_triangles[3]);
std::vector<Rec2DEdge*> edges;
for (int i = 4; i < 8; ++i)
edges.push_back(_edges[i]);
Recombine2D::add(_createQuad(edges));
int num = 0, p[4];
for (int i = 0; i < 4; ++i) {
_edges[i]->getRVertex(0)->remove(_edges[i]);
_edges[i]->getRVertex(1)->remove(_edges[i]);
Recombine2D::remove(_edges[i]->getMEdge());
delete _edges[i];
}
Recombine2D::remove(_vertices[4]->getMVertex());
delete _vertices[4];
bool b = false;
for (int j = 0; j < 3; ++j) {
if (_vertices[i] == rv[j]) {
++num;
p[i] = par[j];
b = true;
}
void Rec2DFourTri2Quad::getParities(int *par)
{
par[0] = _vertices[0]->getParity();
par[1] = _vertices[1]->getParity();
par[2] = _vertices[2]->getParity();
par[3] = _vertices[3]->getParity();
}
void Rec2DFourTri2Quad::_computeGlobVal()
{
double valEdge = 0;
for (int i = 0; i < 4; ++i)
valEdge -= REC2D_EDGE_BASE * _edges[i]->getQual();
for (int i = 4; i < 8; ++i)
valEdge += REC2D_EDGE_QUAD * _edges[i]->getQual();
double valVert = - _vertices[4]->getQual();
for (int i = 0; i < 4; ++i)
valEdge += _vertices[i]->getGain(-1);
_globValIfExecuted = Recombine2D::getGlobalValue(4*REC2D_EDGE_QUAD - 4*REC2D_EDGE_BASE,
valEdge, -1, valVert );
_lastUpdate = Recombine2D::getNumChange();
if (!b)
p[i] = _vertices[i]->getParity();
}
if (num != 3)
Msg::Error("[Rec2DTwoTri2Quad] %d corresponding vertices instead of 3", num);
void Rec2DFourTri2Quad::color(int a, int b, int c)
{
unsigned int col = CTX::instance()->packColor(a, b, c, 255);
_triangles[0]->setCol(col);
_triangles[1]->setCol(col);
_triangles[2]->setCol(col);
_triangles[3]->setCol(col);
if (Rec2DTwoTri2Quad::isObsolete(p)) {
//Msg::Info(" obsolete action");
return false;
}
//Msg::Info(" [%d %d %d %d]", p[0], p[1], p[2], p[3]);
/** Rec2DCollapseTri **/
/*********************/
Rec2DCollapseTri::Rec2DCollapseTri(Rec2DVertex *rv, std::list<MTriangle*> &tri)
{
int i;
std::set<MEdge, Less_Edge> extEdges;
{
std::list<MTriangle*>::iterator it = tri.begin();
for (i = 0; it != tri.end() && i < 4; ++it, ++i) {
for (int j = 0; j < 3; ++j)
if ((*it)->getEdge(j).getVertex(0) != rv->getMVertex() &&
(*it)->getEdge(j).getVertex(1) != rv->getMVertex() )
extEdges.insert((*it)->getEdge(j));
}
if (it != tri.end() || i < 4)
Msg::Error("[Rec2DFourTri2Quad] Wrong number of triangles");
int min = 100, index = -1;
for (int i = 0; i < 4; ++i) {
if (p[i] > -1 && min > p[i]) {
min = p[i];
index = i;
}
_vertices[4] = rv;
// the 4 other must be in order : 2 non adjacent + last 2
std::set<MEdge>::iterator ite = extEdges.begin();
Rec2DEdge *re = Recombine2D::getREdge(*ite);
_vertices[1] = re->getRVertex(0);
_vertices[3] = re->getRVertex(1);
++ite;
for (; ite != extEdges.end(); ++ite) {
re = Recombine2D::getREdge(*ite);
if (re->getRVertex(0) == _vertices[1])
_vertices[0] = re->getRVertex(1);
if (re->getRVertex(1) == _vertices[1])
_vertices[0] = re->getRVertex(0);
if (re->getRVertex(0) == _vertices[3])
_vertices[2] = re->getRVertex(1);
if (re->getRVertex(1) == _vertices[3])
_vertices[2] = re->getRVertex(0);
}
_computeGlobVal();
if (index == -1) {
Msg::Error("[Rec2DTwoTri2Quad] no parities");
return false;
}
Rec2DCollapseTri::Rec2DCollapseTri(Rec2DEdge *re, std::list<MTriangle*> &tri)
: _edge(re)
{
int i;
std::set<MEdge, Less_Edge> extEdges;
{
std::list<MTriangle*>::iterator it = tri.begin();
for (i = 0; it != tri.end() && i < 2; ++it, ++i) {
for (int j = 0; j < 3; ++j)
extEdges.insert((*it)->getEdge(j));
_triangles[i] = *it;
}
if (it != tri.end() || i < 2)
Msg::Error("[Rec2DTwoTri2Quad] Wrong number of triangles");
extEdges.erase(re->getMEdge());
for (int i = 0; i < 4; i += 2) {
int par;
if ((index/2)*2 == i)
par = min;
else
par = otherParity(min);
for (int j = 0; j < 2; ++j) {
if (p[i+j] != par)
suggestions[_vertices[i+j]].push_back(par);
}
_triangles[2] = _triangles[3] = NULL;
_vertices[0] = re->getRVertex(0);
_vertices[1] = re->getRVertex(1);
MVertex *v2, *v3;
v2 = _triangles[0]->getOtherVertex(_vertices[0]->getMVertex(),
_vertices[1]->getMVertex());
v3 = _triangles[1]->getOtherVertex(_vertices[0]->getMVertex(),
_vertices[1]->getMVertex());
_vertices[2] = Recombine2D::getRVertex(v2);
_vertices[3] = Recombine2D::getRVertex(v3);
_vertices[4] = NULL;
_computeGlobVal();
}
bool Rec2DCollapseTri::isObsolete()
{
int p0 = _vertices[0]->getParity();
int p1 = _vertices[1]->getParity();
int p2 = _vertices[2]->getParity();
int p3 = _vertices[3]->getParity();
int b0 = _vertices[0]->getIsOnBoundary();
int b1 = _vertices[1]->getIsOnBoundary();
int b2 = _vertices[2]->getIsOnBoundary();
int b3 = _vertices[3]->getIsOnBoundary();
if ((b0 && b1) || (p0>-1 && p1>-1 && p0/2 == p1/2 && p0 % 2 != p1 % 2) &&
(b2 && b3) || (p2>-1 && p3>-1 && p2/2 == p3/2 && p2 % 2 != p3 % 2) )
//Msg::Info(" ok");
return true;
return false;
}
void Rec2DCollapseTri::apply()
{
return;
}
void Rec2DCollapseTri::getParities(int *par)
{
par[0] = _vertices[0]->getParity();
par[1] = _vertices[1]->getParity();
par[2] = _vertices[2]->getParity();
par[3] = _vertices[3]->getParity();
}
void Rec2DCollapseTri::_computeGlobVal()
{
int b0 = _vertices[0]->getIsOnBoundary();
int b1 = _vertices[1]->getIsOnBoundary();
int b2 = _vertices[2]->getIsOnBoundary();
int b3 = _vertices[3]->getIsOnBoundary();
std::map<Rec2DVertex*, int> neighbourVert;
std::set<Rec2DEdge*> neighbourEdge;
if (!b0 || !b1) {
_vertices[0]->getNeighbours(neighbourVert, neighbourEdge);
_vertices[1]->getNeighbours(neighbourVert, neighbourEdge);
if (_vertices[4]) {
neighbourVert.erase(_vertices[4]);
_vertices[4]->getNeighbourEdges(neighbourEdge);
}
///** Rec2DFourTri2Quad **/
///*************************/
//Rec2DFourTri2Quad::Rec2DFourTri2Quad(Rec2DVertex *rv, std::vector<MTriangle*> &tri)
//{
// int i, j;
// std::set<MEdge, Less_Edge> edges;
// {
// std::vector<MTriangle*>::iterator it = tri.begin();
// for (i = 0; it != tri.end() && i < 4; ++it, ++i) {
// for (j = 0; j < 3; ++j)
// edges.insert((*it)->getEdge(j));
// _rtriangles[i] = Recombine2D::getRElement(*it);
// _rtriangles[i]->add(this);
// }
// if (it != tri.end() || i < 4)
// Msg::Error("[Rec2DFourTri2Quad] Wrong number of triangles");
// }
//
// std::set<MEdge>::iterator ite = edges.begin();
// for (i = 0, j = 4; ite != edges.end() && (i < 4 || j < 8); ++ite) {
// if ((*ite).getVertex(0) == rv->getMVertex() ||
// (*ite).getVertex(1) == rv->getMVertex() )
// _edges[i++] = Recombine2D::getREdge(*ite);
// else if (j < 8)
// _edges[j++] = Recombine2D::getREdge(*ite);
// else
// Msg::Error("[Rec2DFourTri2Quad] Too much exterior edges");
// }
// if (edges.size() > 8 || ite != edges.end() || i < 4 || i > 4 || j < 8)
// Msg::Error("[Rec2DFourTri2Quad] Wrong number of edges");
//
// _vertices[4] = rv;
// // the 4 other must be in order : 2 non adjacent + last 2
// _vertices[1] = _edges[4]->getRVertex(0);
// _vertices[3] = _edges[4]->getRVertex(1);
// for (int i = 5; i < 8; ++i) {
// if (_edges[i]->getRVertex(0) == _vertices[1])
// _vertices[0] = _edges[i]->getRVertex(1);
// if (_edges[i]->getRVertex(1) == _vertices[1])
// _vertices[0] = _edges[i]->getRVertex(0);
// if (_edges[i]->getRVertex(0) == _vertices[3])
// _vertices[2] = _edges[i]->getRVertex(1);
// if (_edges[i]->getRVertex(1) == _vertices[3])
// _vertices[2] = _edges[i]->getRVertex(0);
// }
//
// _computeGlobVal();
//}
//
//Rec2DFourTri2Quad::~Rec2DFourTri2Quad()
//{
// _rtriangles[0]->remove(this);
// _rtriangles[1]->remove(this);
// _rtriangles[2]->remove(this);
// _rtriangles[3]->remove(this);
//}
//
//bool Rec2DFourTri2Quad::isObsolete()
//{
// int p[4];
// p[0] = _vertices[0]->getParity();
// p[1] = _vertices[1]->getParity();
// p[2] = _vertices[2]->getParity();
// p[3] = _vertices[3]->getParity();
// return Rec2DTwoTri2Quad::isObsolete(p);
//}
//
//void Rec2DFourTri2Quad::apply()
//{
// double valEdge = 0;
// for (int i = 0; i < 4; ++i)
// valEdge -= REC2D_EDGE_BASE * _edges[i]->getQual();
// for (int i = 4; i < 8; ++i)
// valEdge += REC2D_EDGE_QUAD * _edges[i]->getQual();
//
// double valVert = - _vertices[4]->getQual();
// for (int i = 0; i < 4; ++i)
// valEdge += _vertices[i]->getGain(-1);
//
// Recombine2D::addNumEdge(4*REC2D_EDGE_QUAD - 4*REC2D_EDGE_BASE);
// Recombine2D::addNumVert(-1);
// Recombine2D::addValEdge(valEdge);
// Recombine2D::addValVert(valVert);
//
// Recombine2D::remove(_rtriangles[0]); // FIXME not performant at all !!!
// Recombine2D::remove(_rtriangles[1]);
// Recombine2D::remove(_rtriangles[2]);
// Recombine2D::remove(_rtriangles[3]);
// std::vector<Rec2DEdge*> edges;
// for (int i = 4; i < 8; ++i)
// edges.push_back(_edges[i]);
// Recombine2D::add(_createQuad(edges));
//
// for (int i = 0; i < 4; ++i) {
// _edges[i]->getRVertex(0)->remove(_edges[i]);
// _edges[i]->getRVertex(1)->remove(_edges[i]);
// Recombine2D::remove(_edges[i]->getMEdge());
// delete _edges[i];
// }
// Recombine2D::remove(_vertices[4]->getMVertex());
// delete _vertices[4];
//}
//
//void Rec2DFourTri2Quad::getParities(int *par)
//{
// par[0] = _vertices[0]->getParity();
// par[1] = _vertices[1]->getParity();
// par[2] = _vertices[2]->getParity();
// par[3] = _vertices[3]->getParity();
//}
//
//void Rec2DFourTri2Quad::_computeGlobVal()
//{
// double valEdge = 0;
// for (int i = 0; i < 4; ++i)
// valEdge -= REC2D_EDGE_BASE * _edges[i]->getQual();
// for (int i = 4; i < 8; ++i)
// valEdge += REC2D_EDGE_QUAD * _edges[i]->getQual();
//
// double valVert = - _vertices[4]->getQual();
// for (int i = 0; i < 4; ++i)
// valEdge += _vertices[i]->getGain(-1);
//
// _globValIfExecuted = Recombine2D::getGlobalValue(4*REC2D_EDGE_QUAD - 4*REC2D_EDGE_BASE,
// valEdge, -1, valVert );
// _lastUpdate = Recombine2D::getNumChange();
//}
//
//void Rec2DFourTri2Quad::color(int a, int b, int c)
//{
// unsigned int col = CTX::instance()->packColor(a, b, c, 255);
// _rtriangles[0]->getMElement()->setCol(col);
// _rtriangles[1]->getMElement()->setCol(col);
// _rtriangles[2]->getMElement()->setCol(col);
// _rtriangles[3]->getMElement()->setCol(col);
//}
//
//
///** Rec2DCollapseTri **/
///*********************/
//Rec2DCollapseTri::Rec2DCollapseTri(Rec2DVertex *rv, std::vector<MTriangle*> &tri)
//{
// int i;
// std::set<MEdge, Less_Edge> extEdges;
// {
// std::vector<MTriangle*>::iterator it = tri.begin();
// for (i = 0; it != tri.end() && i < 4; ++it, ++i) {
// for (int j = 0; j < 3; ++j) {
// if ((*it)->getEdge(j).getVertex(0) != rv->getMVertex() &&
// (*it)->getEdge(j).getVertex(1) != rv->getMVertex() )
// extEdges.insert((*it)->getEdge(j));
// }
// _rtriangles[i] = Recombine2D::getRElement(*it);
// _rtriangles[i]->add(this);
// }
// if (it != tri.end() || i < 4)
// Msg::Error("[Rec2DFourTri2Quad] Wrong number of triangles");
// }
//
// _vertices[4] = rv;
// // the 4 other must be in order : 2 non adjacent + last 2
// std::set<MEdge>::iterator ite = extEdges.begin();
// Rec2DEdge *re = Recombine2D::getREdge(*ite);
// _vertices[1] = re->getRVertex(0);
// _vertices[3] = re->getRVertex(1);
// ++ite;
// for (; ite != extEdges.end(); ++ite) {
// re = Recombine2D::getREdge(*ite);
// if (re->getRVertex(0) == _vertices[1])
// _vertices[0] = re->getRVertex(1);
// if (re->getRVertex(1) == _vertices[1])
// _vertices[0] = re->getRVertex(0);
// if (re->getRVertex(0) == _vertices[3])
// _vertices[2] = re->getRVertex(1);
// if (re->getRVertex(1) == _vertices[3])
// _vertices[2] = re->getRVertex(0);
// }
//
// _computeGlobVal();
//}
//
//Rec2DCollapseTri::Rec2DCollapseTri(Rec2DEdge *re, std::vector<MTriangle*> &tri)
//: _edge(re)
//{
// int i;
// std::set<MEdge, Less_Edge> extEdges;
// {
// std::vector<MTriangle*>::iterator it = tri.begin();
// for (i = 0; it != tri.end() && i < 2; ++it, ++i) {
// for (int j = 0; j < 3; ++j)
// extEdges.insert((*it)->getEdge(j));
// _rtriangles[i] = Recombine2D::getRElement(*it);
// _rtriangles[i]->add(this);
// }
// if (it != tri.end() || i < 2)
// Msg::Error("[Rec2DTwoTri2Quad] Wrong number of triangles");
// extEdges.erase(re->getMEdge());
// }
// _rtriangles[2] = _rtriangles[3] = NULL;
//
// _vertices[0] = re->getRVertex(0);
// _vertices[1] = re->getRVertex(1);
// _vertices[2] = _rtriangles[0]->getOtherVertex(_vertices[0], _vertices[1]);
// _vertices[3] = _rtriangles[1]->getOtherVertex(_vertices[0], _vertices[1]);
// _vertices[4] = NULL;
//
// _computeGlobVal();
//}
//
//Rec2DCollapseTri::~Rec2DCollapseTri()
//{
// //_rtriangles[0]->remove(this);
// //_rtriangles[1]->remove(this);
//}
//
//bool Rec2DCollapseTri::isObsolete()
//{
// int p0 = _vertices[0]->getParity();
// int p1 = _vertices[1]->getParity();
// int p2 = _vertices[2]->getParity();
// int p3 = _vertices[3]->getParity();
// int b0 = _vertices[0]->getIsOnBoundary();
// int b1 = _vertices[1]->getIsOnBoundary();
// int b2 = _vertices[2]->getIsOnBoundary();
// int b3 = _vertices[3]->getIsOnBoundary();
// if ((b0 && b1) || (p0>-1 && p1>-1 && p0/2 == p1/2 && p0 % 2 != p1 % 2) &&
// (b2 && b3) || (p2>-1 && p3>-1 && p2/2 == p3/2 && p2 % 2 != p3 % 2) )
// return true;
// return false;
//}
//
//void Rec2DCollapseTri::apply()
//{
// return;
//}
//
//void Rec2DCollapseTri::getParities(int *par)
//{
// par[0] = _vertices[0]->getParity();
// par[1] = _vertices[1]->getParity();
// par[2] = _vertices[2]->getParity();
// par[3] = _vertices[3]->getParity();
//}
//
//void Rec2DCollapseTri::_computeGlobVal()
//{
// int b0 = _vertices[0]->getIsOnBoundary();
// int b1 = _vertices[1]->getIsOnBoundary();
// int b2 = _vertices[2]->getIsOnBoundary();
// int b3 = _vertices[3]->getIsOnBoundary();
//
// std::map<Rec2DVertex*, int> neighbourVert;
// std::set<Rec2DEdge*> neighbourEdge;
// if (!b0 || !b1) {
// _vertices[0]->getNeighbours(neighbourVert, neighbourEdge);
// _vertices[1]->getNeighbours(neighbourVert, neighbourEdge);
// if (_vertices[4]) {
// neighbourVert.erase(_vertices[4]);
// _vertices[4]->getNeighbourEdges(neighbourEdge);
// }
// //else
// // neighbourEdge.insert(_edge);
//
// int numEdge = 0, numVert = 0;
// double valEdge = .0, valVert = .0;
// {
// std::set<Rec2DEdge*>::iterator it = neighbourEdge.begin();
// for (; it != neighbourEdge.end(); ++it) {
// valEdge -= (*it)->getWeightedQual();
// numEdge -= (*it)->getWeight();
// }
// valVert -= _vertices[0]->getQual();
// valVert -= _vertices[1]->getQual();
// if (_vertices[4]) {
// valVert -= _vertices[4]->getQual();
// numVert -= 1;
// valVert += _vertices[2]->getGain(-2);
// valVert += _vertices[3]->getGain(-2);
// }
// else {
// valVert += _vertices[2]->getGain(-1);
// valVert += _vertices[3]->getGain(-1);
// }
// }
// if (b0)
// _qualCavity(valVert, valEdge, numEdge, neighbourVert, _vertices[0]);
// else if (b1)
// _qualCavity(valVert, valEdge, numEdge, neighbourVert, _vertices[1]);
// else
// _qualCavity(valVert, valEdge, numEdge, neighbourVert);
// numVert -= 1;
//
// _globValIfExecuted =
// Recombine2D::getGlobalValue(numEdge, valEdge, numVert, valVert);
// }
// else
// _globValIfExecuted = -1.;
//
//
// neighbourVert.clear();
// neighbourEdge.clear();
// if (!b2 || !b3) {
// _vertices[2]->getNeighbours(neighbourVert, neighbourEdge);
// _vertices[3]->getNeighbours(neighbourVert, neighbourEdge);
// if (_vertices[4]) {
// neighbourVert.erase(_vertices[4]);
// _vertices[4]->getNeighbourEdges(neighbourEdge);
// }
// else
// neighbourEdge.insert(_edge);
int numEdge = 0, numVert = 0;
double valEdge = .0, valVert = .0;
{
std::set<Rec2DEdge*>::iterator it = neighbourEdge.begin();
for (; it != neighbourEdge.end(); ++it) {
valEdge -= (*it)->getWeightedQual();
numEdge -= (*it)->getWeight();
}
valVert -= _vertices[0]->getQual();
valVert -= _vertices[1]->getQual();
if (_vertices[4]) {
valVert -= _vertices[4]->getQual();
numVert -= 1;
valVert += _vertices[2]->getGain(-2);
valVert += _vertices[3]->getGain(-2);
}
else {
valVert += _vertices[2]->getGain(-1);
valVert += _vertices[3]->getGain(-1);
}
}
if (b0)
_qualCavity(valVert, valEdge, numEdge, neighbourVert, _vertices[0]);
else if (b1)
_qualCavity(valVert, valEdge, numEdge, neighbourVert, _vertices[1]);
else
_qualCavity(valVert, valEdge, numEdge, neighbourVert);
numVert -= 1;
_globValIfExecuted =
Recombine2D::getGlobalValue(numEdge, valEdge, numVert, valVert);
}
else
_globValIfExecuted = -1.;
neighbourVert.clear();
neighbourEdge.clear();
if (!b2 || !b3) {
_vertices[2]->getNeighbours(neighbourVert, neighbourEdge);
_vertices[3]->getNeighbours(neighbourVert, neighbourEdge);
if (_vertices[4]) {
neighbourVert.erase(_vertices[4]);
_vertices[4]->getNeighbourEdges(neighbourEdge);
}
else
neighbourEdge.insert(_edge);
int numEdge = 0, numVert = 0;
double valEdge = .0, valVert = .0;
{
std::set<Rec2DEdge*>::iterator it = neighbourEdge.begin();
for (; it != neighbourEdge.end(); ++it) {
valEdge -= (*it)->getWeightedQual();
numEdge -= (*it)->getWeight();
}
valVert -= _vertices[2]->getQual();
valVert -= _vertices[3]->getQual();
if (_vertices[4]) {
valVert -= _vertices[4]->getQual();
numVert -= 1;
valVert += _vertices[0]->getGain(-2);
valVert += _vertices[1]->getGain(-2);
}
else {
valVert += _vertices[0]->getGain(-2);
valVert += _vertices[1]->getGain(-2);
}
}
if (b2)
_qualCavity(valVert, valEdge, numEdge, neighbourVert, _vertices[2]);
else if (b3)
_qualCavity(valVert, valEdge, numEdge, neighbourVert, _vertices[3]);
else
_qualCavity(valVert, valEdge, numEdge, neighbourVert);
numVert -= 1;
_globValIfExecuted2 =
Recombine2D::getGlobalValue(numEdge, valEdge, numVert, valVert);
}
else
_globValIfExecuted2 = -1.;
_lastUpdate = Recombine2D::getNumChange();
}
void Rec2DCollapseTri::_qualCavity(double &valVert, double &valEdge,
int &numEdge,
std::map<Rec2DVertex*, int> &vert,
Rec2DVertex *imposedVert )
{
Recombine2D::bo = true;
std::map<Rec2DVertex*, int>::iterator it;
Rec2DVertex *rv = imposedVert;
if (rv == NULL) {
double u, v = u = .0;
it = vert.begin();
for (; it != vert.end(); ++it) {
u += it->first->u();
v += it->first->v();
}
u /= vert.size();
v /= vert.size();
rv = new Rec2DVertex(u, v);
}
valVert = rv->getQual(vert.size());
it = vert.begin();
for (; it != vert.end(); ++it) {
Rec2DEdge re(rv, it->first);
valEdge += it->second * re.getQual();
numEdge += it->second;
}
if (imposedVert == NULL) {
rv->deleteMVertex();
delete rv;
}
}
void Rec2DCollapseTri::color(int a, int b, int c)
{
unsigned int col = CTX::instance()->packColor(a, b, c, 255);
_triangles[0]->setCol(col);
_triangles[1]->setCol(col);
if (_triangles[2]) {
_triangles[2]->setCol(col);
_triangles[3]->setCol(col);
}
}
//
// int numEdge = 0, numVert = 0;
// double valEdge = .0, valVert = .0;
// {
// std::set<Rec2DEdge*>::iterator it = neighbourEdge.begin();
// for (; it != neighbourEdge.end(); ++it) {
// valEdge -= (*it)->getWeightedQual();
// numEdge -= (*it)->getWeight();
// }
// valVert -= _vertices[2]->getQual();
// valVert -= _vertices[3]->getQual();
// if (_vertices[4]) {
// valVert -= _vertices[4]->getQual();
// numVert -= 1;
// valVert += _vertices[0]->getGain(-2);
// valVert += _vertices[1]->getGain(-2);
// }
// else {
// valVert += _vertices[0]->getGain(-2);
// valVert += _vertices[1]->getGain(-2);
// }
// }
// if (b2)
// _qualCavity(valVert, valEdge, numEdge, neighbourVert, _vertices[2]);
// else if (b3)
// _qualCavity(valVert, valEdge, numEdge, neighbourVert, _vertices[3]);
// else
// _qualCavity(valVert, valEdge, numEdge, neighbourVert);
// numVert -= 1;
//
// _globValIfExecuted2 =
// Recombine2D::getGlobalValue(numEdge, valEdge, numVert, valVert);
// }
// else
// _globValIfExecuted2 = -1.;
//
// _lastUpdate = Recombine2D::getNumChange();
//}
//
//void Rec2DCollapseTri::_qualCavity(double &valVert, double &valEdge,
// int &numEdge,
// std::map<Rec2DVertex*, int> &vert,
// Rec2DVertex *imposedVert )
//{
// Recombine2D::bo = true;
// std::map<Rec2DVertex*, int>::iterator it;
// Rec2DVertex *rv = imposedVert;
// if (rv == NULL) {
// double u, v = u = .0;
// it = vert.begin();
// for (; it != vert.end(); ++it) {
// u += it->first->u();
// v += it->first->v();
// }
// u /= vert.size();
// v /= vert.size();
//
// rv = new Rec2DVertex(u, v);
// }
// valVert = rv->getQual(vert.size());
// it = vert.begin();
// for (; it != vert.end(); ++it) {
// Rec2DEdge re(rv, it->first);
// valEdge += it->second * re.getQual();
// numEdge += it->second;
// }
// if (imposedVert == NULL) {
// rv->deleteMVertex();
// delete rv;
// }
//}
//
//void Rec2DCollapseTri::color(int a, int b, int c)
//{
// unsigned int col = CTX::instance()->packColor(a, b, c, 255);
// _rtriangles[0]->getMElement()->setCol(col);
// _rtriangles[1]->getMElement()->setCol(col);
// if (_rtriangles[2]) {
// _rtriangles[2]->getMElement()->setCol(col);
// _rtriangles[3]->getMElement()->setCol(col);
// }
//}
//
//
/** Rec2DVertex **/
/*******************/
Rec2DVertex::Rec2DVertex(MVertex *v, std::list<MTriangle*> tri, int onWhat,
Rec2DVertex::Rec2DVertex(MVertex *v, std::vector<MTriangle*> tri, int onWhat,
std::map<MVertex*, std::set<GEdge*> > gEdges)
: _v(v), _onWhat(onWhat), _parity(-1), _lastChange(-1), _numEl(tri.size())
{
for (unsigned int i = 0; i < tri.size(); ++i)
_elements.push_back(Recombine2D::getRElement(tri[i]));
if (_onWhat == -1) {
std::map<MVertex*, std::set<GEdge*> >::iterator it = gEdges.find(_v);
if (it != gEdges.end()) {
if (it != gEdges.end())
_angle = _computeAngle(_v, tri, it->second);
}
else {
Msg::Warning("[meshRecombine2D] Can't compute corner angle, setting angle to pi/2");
_angle = M_PI / 2.;
......@@ -1280,7 +1385,7 @@ Rec2DVertex::Rec2DVertex(double u, double v)
}
double Rec2DVertex::_computeAngle(MVertex *v,
std::list<MTriangle*> &listTri,
std::vector<MTriangle*> &tri,
std::set<GEdge*> &setEdge)
{
if (setEdge.size() != 2) {
......@@ -1319,8 +1424,8 @@ double Rec2DVertex::_computeAngle(MVertex *v,
double angle2 = 2. * M_PI - angle1;
double angleMesh = .0;
std::list<MTriangle*>::iterator it2 = listTri.begin();
for (; it2 != listTri.end(); ++it2) {
std::vector<MTriangle*>::iterator it2 = tri.begin();
for (; it2 != tri.end(); ++it2) {
MTriangle *t = *it2;
int k = 0;
while (t->getVertex(k) != v && k < 3)
......@@ -1357,6 +1462,14 @@ double Rec2DVertex::getQual(int numEdge)
return _qual;
}
bool Rec2DVertex::hasTriangle()
{
bool b = false;
for (int i = 0; i < _elements.size(); ++i)
if (!_elements[i]->isQuad()) b = true;
return b;
}
void Rec2DVertex::_computeQual()
{
if (_onWhat > -1)
......@@ -1450,15 +1563,31 @@ void Rec2DVertex::remove(Rec2DEdge *re)
Msg::Error("[Rec2DVertex] Edge not found");
}
void Rec2DVertex::getElements(std::set<Rec2DElement*> &elem)
{
for (unsigned int i = 0; i < _elements.size(); ++i)
elem.insert(_elements[i]);
}
/** Rec2DEdge **/
/*****************/
Rec2DEdge::Rec2DEdge(MEdge e, mapofVertices &vert, std::list<MTriangle*> &tri)
Rec2DEdge::Rec2DEdge(MEdge e, mapofVertices &vert, std::vector<MTriangle*> &tri)
: _lastChange(-1), _qual(.0), _weight(REC2D_EDGE_BASE),
_rv1(vert[e.getVertex(0)]), _rv2(vert[e.getVertex(1)])
{
_rv1->add(this);
_rv2->add(this);
if (tri.size() == 2) {
Rec2DElement *t0 = Recombine2D::getRElement(tri[0]);
Rec2DElement *t1 = Recombine2D::getRElement(tri[1]);
t0->add(this, t1);
t1->add(this, t0);
}
else if (tri.size() == 1)
Recombine2D::getRElement(tri[0])->add(this);
else
Msg::Error("[Rec2DEdge] Wrong number of triangles");
}
Rec2DEdge::Rec2DEdge(Rec2DVertex *rv1, Rec2DVertex *rv2)
......@@ -1475,6 +1604,8 @@ double Rec2DEdge::getQual()
void Rec2DEdge::_computeQual() //*
{
//if (!_rv1->update() && !_rv2->update())
// return;
static int i = 0; if (++i < 2) Msg::Warning("FIXME compute qual edge and update of vertex");
//_rv1->update();
//_rv2->update();
......@@ -1482,7 +1613,7 @@ void Rec2DEdge::_computeQual() //*
double alignment = _straightAlignment();
if (adimLength > 1)
adimLength = 1/adimLength;
_qual = Recombine2D::edgeReward(adimLength, alignment);
_qual = adimLength * ((1-REC2D_ALIGNMENT) + REC2D_ALIGNMENT * alignment);
_lastChange = Recombine2D::getNumChange();
}
......@@ -1527,7 +1658,26 @@ double Rec2DEdge::_straightAlignment()
return (alpha1/lc1 + alpha2/lc2) / (1/lc1 + 1/lc2);
}
bool lessRec2DAction::operator()(Rec2DAction *ra1, Rec2DAction *ra2) const
/** Rec2DElement **/
/********************/
void Rec2DElement::add(Rec2DEdge *re)
{
return *ra1 < *ra2;
int i = -1;
while (_redges[++i] && i < 4);
if (_redges[i])
Msg::Error("[Rec2DElement] too much edges");
_redges[i] = re;
}
void Rec2DElement::add(Rec2DEdge *re, Rec2DElement *el)
{
int i = -1;
while (_redges[++i] && i < 4);
if (_redges[i])
Msg::Error("[Rec2DElement] too much edges");
_redges[i] = re;
_relements[i] = el;
}
......@@ -15,13 +15,15 @@
#include "MEdge.h"
#include "BackgroundMesh.h"
class Rec2DEdge;
class Rec2DVertex;
class Rec2DEdge;
class Rec2DElement;
class Rec2DAction;
typedef std::list<Rec2DAction*> setofRec2DAction;
typedef std::map<MVertex*, Rec2DVertex*> mapofVertices;
typedef std::map<MEdge, Rec2DEdge*, Less_Edge> mapofEdges;
typedef std::map<MElement*, Rec2DElement*> mapofElements;
typedef std::map<MElement*, std::set<Rec2DAction*> > mapofElementActions;
typedef std::map<MQuadrangle*, std::set<MElement*> > mapofAdjacencies;
......@@ -35,8 +37,9 @@ class Recombine2D {
double _valEdge, _valVert;
GFace *_gf;
backgroundMesh *_bgm;
mapofEdges _edges;
mapofVertices _vertices;
mapofEdges _edges;
mapofElements _elements;
setofRec2DAction _actions;
mapofElementActions _mea;
mapofAdjacencies _ma;
......@@ -46,6 +49,7 @@ class Recombine2D {
std::vector<MTriangle*> _tri;
std::vector<MQuadrangle*> _quad;
std::vector<Rec2DVertex*> _checkAllQuad;
public :
static bool bo;
......@@ -57,14 +61,30 @@ class Recombine2D {
bool recombine();
void apply(bool){return;}
static inline double edgeReward(double adimLength, double alignment)
{return adimLength * (.5 + .5 * alignment);}
static int getNumVertAllQuad() {return _current->_checkAllQuad.size();}
static Rec2DVertex* getVertAllQuad(int i) {return _current->_checkAllQuad[i];}
static void removeVertAllQuad(Rec2DVertex *rv) {
std::vector<Rec2DVertex*>::iterator it = _current->_checkAllQuad.begin();
while (it != _current->_checkAllQuad.end()) {
if (*it == rv)
it = _current->_checkAllQuad.erase(it);
else
++it;
}
}
static void addVertAllQuad(Rec2DVertex *rv) {
_current->_checkAllQuad.push_back(rv);
}
//static inline double edgeReward(double adimLength, double alignment)
// {return adimLength * ((1-REC2D_ALIGNMENT) + REC2D_ALIGNMENT * alignment);}
static inline int getNumChange() {return _current->_numChange;}
static inline backgroundMesh* bgm() {return _current->_bgm;}
static inline double getGlobalValue(int numEdge, double valEdge,
static double getGlobalValue(int numEdge, double valEdge,
int numVert, double valVert );
//static Rec2DVertex* getRVertex(MVertex*);
static Rec2DEdge* getREdge(MEdge);
static Rec2DVertex* getRVertex(MVertex*);
static Rec2DElement* getRElement(MElement*);
static void remove(MEdge);
static void remove(MVertex*);
static inline GFace* getGFace() {return _current->_gf;}
......@@ -76,7 +96,8 @@ class Recombine2D {
static inline void addValEdge(double a) {_current->_valEdge += a;}
static inline void addValVert(double a) {_current->_valVert += a;}
static void remove(MTriangle*);
static void remove(Rec2DElement*);
static void remove(Rec2DAction*);
static void add(MQuadrangle*);
static inline void addVert2Par(Rec2DVertex *rv, int a)
......@@ -86,7 +107,7 @@ class Recombine2D {
std::map<int, std::set<Rec2DVertex*> >::iterator it;
it = _current->_parities.end();
--it;
return it->first;
return it->first + 1;
}
private :
......@@ -95,6 +116,7 @@ class Recombine2D {
void _removeIncompatible(Rec2DAction*);
void _removeReference(Rec2DAction*);
void _getNeighbours(Rec2DAction*, std::set<Rec2DAction*>&);
void _getElemToLook(int par, std::set<Rec2DElement*>&);
};
class Rec2DAction {
......@@ -102,10 +124,11 @@ class Rec2DAction {
int _position;
protected :
int _lastUpdate;
int _lastUpdate; // + _lastCheck
double _globValIfExecuted;
public :
virtual ~Rec2DAction() {Recombine2D::remove(this);}
bool operator<(Rec2DAction&);
inline int getVectPosition() const {return _position;}
inline void setVectPosition(int p) {_position = p;}
......@@ -117,12 +140,14 @@ class Rec2DAction {
return _globValIfExecuted - Recombine2D::getGlobalValue(0, .0, 0, .0);
}
virtual bool isObsolete() = 0;
virtual void getTriangles(std::set<MTriangle*>&) = 0;
virtual MTriangle* getTriangle(int) = 0;
virtual void getRTriangles(std::set<Rec2DElement*>&) = 0;
virtual Rec2DElement* getRTriangle(int) = 0;
virtual void apply() = 0;
virtual void getParities(int*) = 0;
virtual Rec2DVertex* getRVertex(int) = 0;
virtual void color(int, int, int) = 0;
virtual bool whatImply(Rec2DVertex**, int*,
std::map<Rec2DVertex*, std::vector<int> >&) = 0;
protected :
MQuadrangle* _createQuad(std::vector<Rec2DEdge*>&) const;
......@@ -133,52 +158,60 @@ class Rec2DAction {
class Rec2DTwoTri2Quad : public Rec2DAction {
private :
MTriangle *_triangles[2];
Rec2DElement *_rtriangles[2];
Rec2DEdge *_edges[5]; // 1 embedded, 4 boundary
Rec2DVertex *_vertices[4]; // 4 boundary (2 on embedded edge + 2)
public :
Rec2DTwoTri2Quad(Rec2DEdge*, std::list<MTriangle*>&);
Rec2DTwoTri2Quad(Rec2DEdge*, std::vector<MTriangle*>&);
~Rec2DTwoTri2Quad();
bool isObsolete();
void getTriangles(std::set<MTriangle*> &tri) {
tri.insert(_triangles[0]);
tri.insert(_triangles[1]);
void getRTriangles(std::set<Rec2DElement*> &tri) {
tri.insert(_rtriangles[0]);
tri.insert(_rtriangles[1]);
}
MTriangle* getTriangle(int a) {
return _triangles[a];
Rec2DElement* getRTriangle(int a) {
return _rtriangles[a];
}
void apply();
void getParities(int*);
Rec2DVertex* getRVertex(int i) {return _vertices[i];}
void color(int, int, int);
virtual bool whatImply(Rec2DVertex**, int*,
std::map<Rec2DVertex*, std::vector<int> >&);
static bool isObsolete(int*);
int getNum() {return 1;}
private :
void _computeGlobVal();
};
class Rec2DFourTri2Quad : public Rec2DAction {
/*class Rec2DFourTri2Quad : public Rec2DAction {
private :
MTriangle *_triangles[4];
Rec2DElement *_rtriangles[4];
Rec2DEdge *_edges[8]; // 4 embedded, 4 boundary
Rec2DVertex *_vertices[5]; // 4 boundary (2 non adjacent + 2), 1 embedded
public :
Rec2DFourTri2Quad(Rec2DVertex*, std::list<MTriangle*>&);
Rec2DFourTri2Quad(Rec2DVertex*, std::vector<MTriangle*>&);
~Rec2DFourTri2Quad();
bool isObsolete();
void getTriangles(std::set<MTriangle*> &tri) {
tri.insert(_triangles[0]);
tri.insert(_triangles[1]);
tri.insert(_triangles[2]);
tri.insert(_triangles[3]);
void getRTriangles(std::set<Rec2DElement*> &tri) {
tri.insert(_rtriangles[0]);
tri.insert(_rtriangles[1]);
tri.insert(_rtriangles[2]);
tri.insert(_rtriangles[3]);
}
MTriangle* getTriangle(int a) {
return _triangles[a];
Rec2DElement* getRTriangle(int a) {
return _rtriangles[a];
}
void apply();
void getParities(int*);
Rec2DVertex* getRVertex(int i) {return _vertices[i];}
void color(int, int, int);
virtual void whatImply(Rec2DVertex**, int*,
std::map<Rec2DVertex*, std::vector<int> >&)
{return;}
int getNum() {return 2;}
private :
......@@ -187,34 +220,38 @@ class Rec2DFourTri2Quad : public Rec2DAction {
class Rec2DCollapseTri : public Rec2DAction {
private :
MTriangle *_triangles[4]; // either 2 or 4 triangles
Rec2DElement *_rtriangles[4]; // either 2 or 4 triangles
Rec2DEdge *_edge; // 1 embedded or NULL
Rec2DVertex *_vertices[5]; // 4 boundary (2 on embedded edge + 2), 1 embedded or NULL
double _globValIfExecuted2;
public :
Rec2DCollapseTri(Rec2DVertex*, std::list<MTriangle*>&);
Rec2DCollapseTri(Rec2DEdge*, std::list<MTriangle*>&);
Rec2DCollapseTri(Rec2DVertex*, std::vector<MTriangle*>&);
Rec2DCollapseTri(Rec2DEdge*, std::vector<MTriangle*>&);
~Rec2DCollapseTri();
double getReward() {
return std::max(_globValIfExecuted, _globValIfExecuted2)
- Recombine2D::getGlobalValue(0, .0, 0, .0);
}
bool isObsolete();
void getTriangles(std::set<MTriangle*> &tri) {
tri.insert(_triangles[0]);
tri.insert(_triangles[1]);
if (_triangles[2]) {
tri.insert(_triangles[2]);
tri.insert(_triangles[3]);
void getRTriangles(std::set<Rec2DElement*> &tri) {
tri.insert(_rtriangles[0]);
tri.insert(_rtriangles[1]);
if (_rtriangles[2]) {
tri.insert(_rtriangles[2]);
tri.insert(_rtriangles[3]);
}
}
MTriangle* getTriangle(int a) {
return _triangles[a];
Rec2DElement* getRTriangle(int a) {
return _rtriangles[a];
}
void apply();
void getParities(int*);
Rec2DVertex* getRVertex(int i) {return _vertices[i];}
void color(int, int, int);
virtual void whatImply(Rec2DVertex**, int*,
std::map<Rec2DVertex*, std::vector<int> >&)
{return;}
int getNum() {return 3;}
private :
......@@ -222,7 +259,8 @@ class Rec2DCollapseTri : public Rec2DAction {
void _qualCavity(double &valVert, double &valEdge, int &numEdge,
std::map<Rec2DVertex*, int> &vertices,
Rec2DVertex *imposedVert = NULL );
};
};*/
//
class Rec2DListAction {
private :
......@@ -236,7 +274,8 @@ class Rec2DVertex {
private :
MVertex *_v;
std::vector<Rec2DEdge*> _edges;
int _onWhat, _numEl, _parity, _lastChange;
std::vector<Rec2DElement*> _elements;
int _onWhat, _numEl, _parity, _lastChange; //lastMove
// _onWhat={-1:corner,0:edge,1:face,(2:volume)}
double _angle, _qual;
SPoint2 _param;
......@@ -245,10 +284,11 @@ class Rec2DVertex {
static double **_gains;
public :
Rec2DVertex(MVertex*, std::list<MTriangle*>, int onWhat,
Rec2DVertex(MVertex*, std::vector<MTriangle*>, int onWhat,
std::map<MVertex*, std::set<GEdge*> >);
Rec2DVertex(double u, double v);
bool hasTriangle();
inline void add(Rec2DEdge *re) {_edges.push_back(re);}
void remove(Rec2DEdge*);
inline void setOnBoundary() {if (_onWhat > 0) _onWhat = 0;
......@@ -270,22 +310,33 @@ class Rec2DVertex {
double getGain(int);
void getNeighbours(std::map<Rec2DVertex*, int>&, std::set<Rec2DEdge*>&);
void getNeighbourEdges(std::set<Rec2DEdge*>&);
void getElements(std::set<Rec2DElement*>&);
void remove(Rec2DElement *rel) {
std::vector<Rec2DElement*>::iterator it = _elements.begin();
while (it != _elements.end()) {
if (*it == rel)
it = _elements.erase(it);
else
++it;
}
}
static void initStaticTable();
private :
void _computeQual();
double _computeAngle(MVertex*, std::list<MTriangle*>&, std::set<GEdge*>&);
double _computeAngle(MVertex*, std::vector<MTriangle*>&, std::set<GEdge*>&);
};
class Rec2DEdge {
private :
Rec2DVertex *_rv1, *_rv2;
double _qual;
int _lastChange, _weight;
int _lastChange, _weight; //lastUpdate
public :
Rec2DEdge(MEdge, mapofVertices&, std::list<MTriangle*>&);
Rec2DEdge(MEdge, mapofVertices&, std::vector<MTriangle*>&);
Rec2DEdge(Rec2DVertex*, Rec2DVertex*);
double getQual();
......@@ -300,4 +351,74 @@ class Rec2DEdge {
double _straightAlignment();
};
class Rec2DElement {
private :
Rec2DEdge *_redges[4]; // if triangle, _redges[3] == NULL
Rec2DElement *_relements[4]; // NULL if no neighbour
MElement *_mEl; // can be NULL
std::vector<Rec2DAction*> _actions;
public :
Rec2DElement(MTriangle *t) : _mEl((MElement *)t) {
for (int i = 0; i < 4; ++i) {
_redges[i] = NULL;
}
}
void add(Rec2DEdge*);
void add(Rec2DEdge*, Rec2DElement*);
inline MElement* getMElement() {return _mEl;}
inline MTriangle* getMTriangle()
{if (_redges[3])return NULL; return (MTriangle*) _mEl;}
inline bool isQuad() {return _redges[3];}
inline void add(Rec2DAction *ra) {_actions.push_back(ra);}
void remove(Rec2DAction *ra) {
std::vector<Rec2DAction*>::iterator it = _actions.begin();
while (it != _actions.end()) {
if (*it == ra) it = _actions.erase(it);
else ++it;
}
}
inline int getNum() {return _mEl->getNum();}
inline int getNumActions() {return _actions.size();}
inline Rec2DAction* getAction(int i) {return _actions[i];}
void getVertices(Rec2DVertex **v) {
v[0] = _redges[0]->getRVertex(0);
v[1] = _redges[0]->getRVertex(1);
if (_redges[1]->getRVertex(0) == v[0] ||
_redges[1]->getRVertex(0) == v[1] )
v[2] = _redges[1]->getRVertex(1);
else
v[2] = _redges[1]->getRVertex(0);
}
void getActions(std::set<Rec2DAction*> &actions) {
for (unsigned int i = 0; i < _actions.size(); ++i)
actions.insert(_actions[i]);
}
void getNeighbours(std::set<Rec2DElement*> &elem) {
for (int i = 0; i < 4; ++i) {
if (_relements[i])
elem.insert(_relements[i]);
}
}
Rec2DVertex* getOtherVertex(Rec2DVertex *rv1, Rec2DVertex *rv2) {
if (_redges[3]) {
Msg::Error("[Rec2DElement] I'm not a triangle");
return NULL;
}
std::set<Rec2DVertex*> vert;
for (int i = 0; i < 3; ++i) {
vert.insert(_redges[i]->getRVertex(0));
vert.insert(_redges[i]->getRVertex(1));
}
std::set<Rec2DVertex*>::iterator it = vert.begin();
for (; it != vert.end(); ++it) {
if (*it != rv1 && *it != rv2)
return *it;
}
Msg::Error("[Rec2DElement] I should not be here... Why this happen to me ?");
return NULL;
}
};
#endif
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment