diff --git a/Mesh/meshGFaceRecombine.cpp b/Mesh/meshGFaceRecombine.cpp index 7bf9ccdeef62407c72dccbf24ca632746a08ad7d..7271a843ae803bd9df2f1641f28f28a5b12dcb13 100644 --- a/Mesh/meshGFaceRecombine.cpp +++ b/Mesh/meshGFaceRecombine.cpp @@ -7,7 +7,7 @@ // Amaury Johnen (a.johnen@ulg.ac.be) // -#define REC2D_WAIT_TIME .01 +#define REC2D_WAIT_TIME 2 #define REC2D_NUM_ACTIO 1000 // #define REC2D_SMOOTH @@ -176,7 +176,7 @@ Recombine2D::Recombine2D(GFace *gf) : _gf(gf), _strategy(0), _numChange(0) else { elem[0]->addNeighbour(*it, elem[1]); elem[1]->addNeighbour(*it, elem[0]); - new Rec2DTwoTri2Quad(elem[0], elem[1]); + new Rec2DCollapse(new Rec2DTwoTri2Quad(elem[0], elem[1])); } } } @@ -258,27 +258,36 @@ bool Recombine2D::recombine() double Recombine2D::recombine(int depth) { + double time = Cpu(); Rec2DData::clearChanges(); double bestGlobalQuality; +#ifdef REC2D_DRAW // draw state at origin + _gf->triangles = _data->_tri; + _gf->quadrangles = _data->_quad; + CTX::instance()->mesh.changed = ENT_ALL; + drawContext::global()->draw(); + while (Cpu()-time < REC2D_WAIT_TIME) + FlGui::instance()->check(); + time = Cpu(); +#endif Rec2DNode *root = new Rec2DNode(NULL, NULL, bestGlobalQuality, depth); Rec2DNode *currentNode = root->selectBestNode(); - double time = Cpu(); - //int num = 20, i = 0; - //double dx = .0, dy = .0; + static int num = 20, i = 0; + static double dx = .0, dy = .0; while (currentNode) { FlGui::instance()->check(); -#if 0//def REC2D_DRAW // draw state at origin +#ifdef REC2D_DRAW // draw state at origin _gf->triangles = _data->_tri; _gf->quadrangles = _data->_quad; CTX::instance()->mesh.changed = ENT_ALL; drawContext::global()->draw(); - while (Cpu()-time < REC2D_WAIT_TIME) + //while (Cpu()-time < REC2D_WAIT_TIME) FlGui::instance()->check(); time = Cpu(); #endif -#if 0//def REC2D_DRAW // draw all states +#ifdef REC2D_DRAW // draw all states if ( !((i+1) % ((int)std::sqrt(num)+1)) ) { dx = .0; dy -= 1.1; @@ -288,7 +297,7 @@ double Recombine2D::recombine(int depth) drawState(dx, dy); CTX::instance()->mesh.changed = ENT_ALL; drawContext::global()->draw(); - while (Cpu()-time < REC2D_WAIT_TIME) + //while (Cpu()-time < REC2D_WAIT_TIME) FlGui::instance()->check(); ++i; time = Cpu(); @@ -876,7 +885,7 @@ void Rec2DData::associateParity(int pOld, int pNew, Rec2DDataChange *rdc) if (rdc) rdc->saveParity(*vect); for (unsigned int i = 0; i < vect->size(); ++i) - vect->at(i)->setParityWD(pOld, pNew); + (*vect)[i]->setParityWD(pOld, pNew); vectNew = &_current->_parities[pNew]; vectNew->insert(vectNew->end(), vect->begin(), vect->end()); _current->_parities.erase(it); @@ -894,7 +903,7 @@ void Rec2DData::associateParity(int pOld, int pNew, Rec2DDataChange *rdc) if (rdc) rdc->saveParity(*vect); for (unsigned int i = 0; i < vect->size(); ++i) - vect->at(i)->setParityWD(pOld, pNew); + (*vect)[i]->setParityWD(pOld, pNew); vectNew = &_current->_parities[pNew]; vectNew->insert(vectNew->end(), vect->begin(), vect->end()); _current->_parities.erase(it); @@ -1058,7 +1067,8 @@ void Rec2DData::drawChanges(double shiftx, double shifty) const std::map<int, std::vector<double> > data; int k = 0; for (unsigned int i = 0; i < _changes.size(); ++i) { - data[_changes[i]->getAction()->getNum(shiftx, shifty)].push_back(++k); + if (_changes[i]->getAction()->haveElem()) + data[_changes[i]->getAction()->getNum(shiftx, shifty)].push_back(++k); } new PView("Changes", "ElementData", Recombine2D::getGFace()->model(), data); } @@ -1094,69 +1104,494 @@ void Rec2DData::sortEndNode() moreRec2DNode() ); } -/** Rec2DDataChange **/ -/***********************/ -void Rec2DDataChange::hide(Rec2DEdge *re) +/** Rec2DChange **/ +/*******************/ +Rec2DChange::Rec2DChange(Rec2DEdge *re, bool toHide) : _entity(re), _info(NULL) { - _hiddenEdge.push_back(re); - re->hide(); + if (toHide) { + re->hide(); + _type = HideEdge; + } + else + _type = CreatedEdge; } -void Rec2DDataChange::hide(Rec2DElement *rel) +Rec2DChange::Rec2DChange(Rec2DVertex *rv, bool toHide) : _entity(rv), _info(NULL) { - _hiddenElement.push_back(rel); - rel->hide(); + if (toHide) { + rv->hide(); + _type = HideVertex; + } + else + _type = CreatedVertex; } -void Rec2DDataChange::hide(std::vector<Rec2DAction*> actions) +Rec2DChange::Rec2DChange(Rec2DElement *rel, bool toHide) : _entity(rel), _info(NULL) { - _hiddenAction.insert(_hiddenAction.end(), actions.begin(), actions.end()); - for (unsigned int i = 0; i < actions.size(); ++i) { - actions[i]->hide(); + if (toHide) { + rel->hide(); + _type = HideElement; } + else + _type = CreatedElement; } -void Rec2DDataChange::hide(Rec2DAction *action) +Rec2DChange::Rec2DChange(Rec2DAction *ra, bool toHide) : _entity(ra), _info(NULL) { - _hiddenAction.push_back(action); - action->hide(); + if (toHide) { + ra->hide(); + _type = HideAction; + } + else + _type = CreatedAction; } -void Rec2DDataChange::append(const Rec2DElement *rel) +Rec2DChange::Rec2DChange(const std::vector<Rec2DAction*> &actions, bool toHide) : _info(NULL) { - _newElement.push_back((Rec2DElement*)rel); + std::vector<Rec2DAction*> *vect = new std::vector<Rec2DAction*>(); + *vect = actions; + _entity = vect; + if (toHide) { + for (unsigned int i = 0; i < actions.size(); ++i) + actions[i]->hide(); + _type = HideActions; + } + else + _type = CreatedActions; } -void Rec2DDataChange::changeParity(Rec2DVertex *rv, int par) +Rec2DChange::Rec2DChange(Rec2DVertex *rv, int newPar, Rec2DChangeType type) { - for (unsigned int i = 0; i < _oldParity.size(); ++i) { - if (_oldParity[i].first == rv) - return; + if (type == ChangePar) { + _type = ChangePar; + _entity = rv; + int *oldPar = new int; + *oldPar = rv->getParity(); + _info = oldPar; + rv->setParity(newPar); + return; } - _oldParity.push_back(std::make_pair(rv, rv->getParity())); - rv->setParity(par); + _type = Error; + _entity = _info = NULL; } -void Rec2DDataChange::saveParity(std::vector<Rec2DVertex*> &vect) +Rec2DChange::Rec2DChange(const std::vector<Rec2DVertex*> &verts, + Rec2DChangeType type ) { - int sizeOldParity = _oldParity.size(); - for (unsigned int i = 0; i < vect.size(); ++i) { - bool notThere = true; - for (int j = 0; j < sizeOldParity; ++j) { - if (_oldParity[j].first == vect[i]) - notThere = false; - } - if (notThere) { - _oldParity.push_back(std::make_pair(vect[i], vect[i]->getParity())); + if (type == SavePar) { + _type = SavePar; + std::vector<Rec2DVertex*> *vect = new std::vector<Rec2DVertex*>(); + *vect = verts; + _entity = vect; + std::vector<int> *parities = new std::vector<int>(verts.size()); + _info = parities; + for (unsigned int i = 0; i < verts.size(); ++i) + (*parities)[i] = verts[i]->getParity(); + return; + } + _type = Error; + _entity = _info = NULL; +} + +Rec2DChange::Rec2DChange(Rec2DVertex *rv, SPoint2 newCoord) +: _type(Relocate), _entity(rv) +{ + SPoint2 *oldCoord = new SPoint2(); + rv->getParam(oldCoord); + _info = oldCoord; + rv->relocate(newCoord); +} + +Rec2DChange::Rec2DChange(Rec2DVertex *rv, + const std::vector<Rec2DElement*> &elem, + Rec2DChangeType type ) +{ + std::vector<Rec2DElement*> *vect = new std::vector<Rec2DElement*>(); + _type = type; + _entity = rv; + _info = vect; + switch (type) { + case AddElem : + *vect = elem; + for (unsigned int i = 0; i < elem.size(); ++i) + rv->add(elem[i]); + break; + + case RemoveElem : + *vect = elem; + for (int i = (int)elem.size()-1; i > -1; --i) + rv->rmv(elem[i]); + break; + + default : + delete vect; + _type = Error; + _entity = _info = NULL; + } +} + +Rec2DChange::Rec2DChange(Rec2DVertex *rv0, Rec2DVertex *rv1, + const std::vector<Rec2DEdge*> &edges, + Rec2DChangeType type ) +{ + if (type == SwapVertInEdge) { + _type = type; + std::vector<Rec2DEdge*> *vect = new std::vector<Rec2DEdge*>(); + *vect = edges; + _entity = vect; + std::pair<Rec2DVertex*, Rec2DVertex*> *pairVert; + pairVert = new std::pair<Rec2DVertex*, Rec2DVertex*>(rv1, rv0); + _info = pairVert; + for (unsigned int i = 0; i < edges.size(); ++i) + edges[i]->swap(rv0, rv1); + return; + } + _type = Error; + _entity = _info = NULL; +} + +Rec2DChange::Rec2DChange(Rec2DVertex *rv0, Rec2DVertex *rv1, + const std::vector<Rec2DAction*> &actions, + Rec2DChangeType type ) +{ + if (type == SwapVertInAction) { + _type = type; + std::vector<Rec2DAction*> *vect = new std::vector<Rec2DAction*>(); + *vect = actions; + _entity = vect; + std::pair<Rec2DVertex*, Rec2DVertex*> *pairVert; + pairVert = new std::pair<Rec2DVertex*, Rec2DVertex*>(rv1, rv0); + _info = pairVert; + for (unsigned int i = 0; i < actions.size(); ++i) + actions[i]->swap(rv0, rv1); + return; + } + _type = Error; + _entity = _info = NULL; +} + +Rec2DChange::Rec2DChange(Rec2DEdge *re0, Rec2DEdge *re1, + const std::vector<Rec2DAction*> &actions, + Rec2DChangeType type ) +{ + if (type == SwapEdgeInAction) { + _type = type; + std::vector<Rec2DAction*> *vect = new std::vector<Rec2DAction*>(); + *vect = actions; + _entity = vect; + std::pair<Rec2DEdge*, Rec2DEdge*> *pairVert; + pairVert = new std::pair<Rec2DEdge*, Rec2DEdge*>(re1, re0); + _info = pairVert; + for (unsigned int i = 0; i < actions.size(); ++i) + actions[i]->swap(re0, re1); + return; + } + _type = Error; + _entity = _info = NULL; +} + +Rec2DChange::Rec2DChange(Rec2DEdge *re0, Rec2DEdge *re1, + Rec2DChangeType type ) +{ + if (type == SwapEdgeInElem) { + _type = type; + Rec2DElement *rel = Rec2DEdge::getUniqueElement(re0); + if (!rel) { + { + Rec2DElement *elem[2]; + Rec2DEdge::getElements(re0, elem); + int a, b = a = NULL; + if (elem[0]) + a = elem[0]->getNum(); + if (elem[1]) + b = elem[1]->getNum(); + Rec2DEdge::getElements(re1, elem); + int c, d = c = NULL; + if (elem[0]) + c = elem[0]->getNum(); + if (elem[1]) + d = elem[1]->getNum(); + Msg::Error("[Rec2DElement] (edge %d %d -> edge %d %d)", a, b, c, d); + } + Msg::Error("[Rec2DDataChange] invalid swapping edges"); + _type = Error; + _entity = _info = NULL; + return; } + _entity = rel; + std::pair<Rec2DEdge*, Rec2DEdge*> *pairEdge; + pairEdge = new std::pair<Rec2DEdge*, Rec2DEdge*>(re1, re0); + _info = pairEdge; + rel->swap(re0, re1); + return; } + _type = Error; + _entity = _info = NULL; } -void Rec2DDataChange::checkObsoleteActions() +void Rec2DChange::revert() +{ + switch (_type) { + case HideEdge : + ((Rec2DEdge*)_entity)->reveal(); + break; + + case HideVertex : + ((Rec2DVertex*)_entity)->reveal(); + break; + + case HideElement : + ((Rec2DElement*)_entity)->reveal(); + break; + + case CreatedEdge : + delete (Rec2DEdge*)_entity; + break; + + case CreatedVertex : + delete (Rec2DVertex*)_entity; + break; + + case CreatedElement : + delete (Rec2DElement*)_entity; + break; + + case HideAction : + ((Rec2DAction*)_entity)->reveal(); + break; + + case CreatedAction : + delete (Rec2DAction*)_entity; + break; + + case HideActions : + { + std::vector<Rec2DAction*> *vect = (std::vector<Rec2DAction*>*)_entity; + for (unsigned int i = 0; i < vect->size(); ++i) + (*vect)[i]->reveal(); + delete vect; + } + break; + + case CreatedActions : + { + std::vector<Rec2DAction*> *vect = (std::vector<Rec2DAction*>*)_entity; + for (unsigned int i = 0; i < vect->size(); ++i) + delete (*vect)[i]; + delete vect; + } + break; + + case SwapEdgeInAction : + { + std::vector<Rec2DAction*> *vect = (std::vector<Rec2DAction*>*)_entity; + std::pair<Rec2DEdge*, Rec2DEdge*> *pairEdge; + pairEdge = (std::pair<Rec2DEdge*, Rec2DEdge*>*)_info; + for (unsigned int i = 0; i < vect->size(); ++i) + (*vect)[i]->swap(pairEdge->first, pairEdge->second); + delete vect; + delete pairEdge; + } + break; + + case SwapEdgeInElem : + { + std::pair<Rec2DEdge*, Rec2DEdge*> *pairEdge; + pairEdge = (std::pair<Rec2DEdge*, Rec2DEdge*>*)_info; + ((Rec2DElement*)_entity)->swap(pairEdge->first, pairEdge->second); + delete pairEdge; + } + break; + + case SwapVertInAction : + { + std::vector<Rec2DAction*> *vect = (std::vector<Rec2DAction*>*)_entity; + std::pair<Rec2DVertex*, Rec2DVertex*> *pairVert; + pairVert = (std::pair<Rec2DVertex*, Rec2DVertex*>*)_info; + for (unsigned int i = 0; i < vect->size(); ++i) + (*vect)[i]->swap(pairVert->first, pairVert->second); + delete vect; + delete pairVert; + } + break; + + case SwapVertInEdge : + { + std::vector<Rec2DEdge*> *edges = (std::vector<Rec2DEdge*>*)_entity; + std::pair<Rec2DVertex*, Rec2DVertex*> *pairVert; + pairVert = (std::pair<Rec2DVertex*, Rec2DVertex*>*)_info; + for (unsigned int i = 0; i < edges->size(); ++i) + (*edges)[i]->swap(pairVert->first, pairVert->second); + delete edges; + delete pairVert; + } + break; + + case RemoveElem : + { + std::vector<Rec2DElement*> *elem = (std::vector<Rec2DElement*>*)_info; + for (unsigned int i = 0; i < elem->size(); ++i) + ((Rec2DVertex*)_entity)->add((*elem)[i]); + delete elem; + } + break; + + case AddElem : + { + std::vector<Rec2DElement*> *elem = (std::vector<Rec2DElement*>*)_info; + for (unsigned int i = 0; i < elem->size(); ++i) + ((Rec2DVertex*)_entity)->rmv((*elem)[i]); + delete elem; + } + break; + + case Relocate : + ((Rec2DVertex*)_entity)->relocate(*(SPoint2*)_info); + delete (SPoint2*)_info; + break; + + case ChangePar : + ((Rec2DVertex*)_entity)->setParity(*(int*)_info); + delete (int*)_info; + break; + + case SavePar : + { + std::vector<Rec2DVertex*> *verts = (std::vector<Rec2DVertex*>*)_entity; + std::vector<int> *parities = (std::vector<int>*)_info; + for (unsigned int i = 0; i < verts->size(); ++i) + (*verts)[i]->setParity((*parities)[i]); + delete verts; + delete parities; + } + break; + + case Error : + Msg::Error("[Rec2DChange] There was an error"); + return; + + case Reverted : + Msg::Error("[Rec2DChange] Multiple revert"); + return; + + default : + Msg::Error("[Rec2DChange] Unknown type (%d)", _type); + return; + } + _type = Reverted; +} + + +/** Rec2DDataChange **/ +/***********************/ +//void Rec2DDataChange::hide(Rec2DEdge *re) +//{ +// _hiddenEdge.push_back(re); +// re->hide(); +//} +// +//void Rec2DDataChange::hide(Rec2DVertex *rv) +//{ +// _hiddenVertex.push_back(rv); +// rv->hide(); +//} +// +//void Rec2DDataChange::hide(Rec2DElement *rel) +//{ +// _hiddenElement.push_back(rel); +// rel->hide(); +//} +// +//void Rec2DDataChange::hide(std::vector<Rec2DAction*> actions) +//{ +// _hiddenAction.insert(_hiddenAction.end(), actions.begin(), actions.end()); +// for (unsigned int i = 0; i < actions.size(); ++i) { +// actions[i]->hide(); +// } +//} +// +//void Rec2DDataChange::hide(Rec2DAction *action) +//{ +// _hiddenAction.push_back(action); +// action->hide(); +//} +// +//void Rec2DDataChange::append(const Rec2DElement *rel) +//{ +// _newElement.push_back((Rec2DElement*)rel); +//} +// +//void Rec2DDataChange::append(const Rec2DAction *ra) +//{ +// _newAction.push_back((Rec2DAction*)ra); +//} +// +//void Rec2DDataChange::swapFor(Rec2DEdge *re1, Rec2DEdge *re2) +//{ +// Rec2DElement *rel = Rec2DEdge::getUniqueElement(re1); +// if (!rel) { +// Msg::Error("[Rec2DDataChange] invalid swapping edges"); +// return; +// } +// _edgeSwap.push_back(std::make_pair(rel, std::make_pair(re2, re1) )); +// rel->swap(re1, re2); +//} +// +//void Rec2DDataChange::swapFor(Rec2DVertex *rv1, Rec2DVertex *rv2) +//{ +// std::vector<Rec2DElement*> elem; +// rv1->getElements(elem); +// for (unsigned int i = 0; i < elem.size(); ++i) { +// _vertSwapEL.push_back(std::make_pair(elem[i], std::make_pair(rv2, rv1) )); +// rv1->rmv(elem[i]); +// } +// std::vector<Rec2DEdge*> edges; +// rv1->getEdges(edges); +// for (unsigned int i = 0; i < edges.size(); ++i) { +// _vertSwapE.push_back(std::make_pair(edges[i], std::make_pair(rv2, rv1) )); +// edges[i]->swap(rv1, rv2); +// } +// for (unsigned int i = 0; i < elem.size(); ++i) { +// rv2->add(elem[i]); +// } +//} +// +//void Rec2DDataChange::relocate(Rec2DVertex *rv, double u, double v) +//{ +// _oldCoordinate.push_back(std::make_pair(rv, SPoint2(rv->u(), rv->v()))); +// rv->relocate(SPoint2(u, v)); +//} +// +//void Rec2DDataChange::changeParity(Rec2DVertex *rv, int par) +//{ +// for (unsigned int i = 0; i < _oldParity.size(); ++i) { +// if (_oldParity[i].first == rv) +// return; +// } +// _oldParity.push_back(std::make_pair(rv, rv->getParity())); +// rv->setParity(par); +//} +// +//void Rec2DDataChange::saveParity(std::vector<Rec2DVertex*> &vect) +//{ +// int sizeOldParity = _oldParity.size(); +// for (unsigned int i = 0; i < vect.size(); ++i) { +// bool notThere = true; +// for (int j = 0; j < sizeOldParity; ++j) { +// if (_oldParity[j].first == vect[i]) +// notThere = false; +// } +// if (notThere) { +// _oldParity.push_back(std::make_pair(vect[i], vect[i]->getParity())); +// } +// } +//} +// +void Rec2DDataChange::checkObsoleteActions(Rec2DVertex *const*verts, int size) { std::vector<Rec2DAction*> actions; - for (unsigned int i = 0; i < _oldParity.size(); ++i) { - _oldParity[i].first->getUniqueActions(actions); + for (int i = 0; i < size; ++i) { + verts[i]->getUniqueActions(actions); } for (unsigned int i = 0; i < actions.size(); ++i) { if (actions[i]->isObsolete()) @@ -1164,40 +1599,101 @@ void Rec2DDataChange::checkObsoleteActions() } } +//void Rec2DDataChange::revert() +//{ +// for (unsigned int i = 0; i < _oldParity.size(); ++i) +// _oldParity[i].first->setParity(_oldParity[i].second); +// for (unsigned int i = 0; i < _oldCoordinate.size(); ++i) +// _oldCoordinate[i].first->relocate(_oldCoordinate[i].second); +// +// for (unsigned int i = 0; i < _newAction.size(); ++i) +// delete _newAction[i]; +// for (unsigned int i = 0; i < _newElement.size(); ++i) +// delete _newElement[i]; +// //for (unsigned int i = 0; i < _newEdge.size(); ++i) +// // delete _newEdge[i]; +// //for (unsigned int i = 0; i < _newVertex.size(); ++i) +// // delete _newVertex[i]; +// +// for (unsigned int i = 0; i < _hiddenVertex.size(); ++i) +// _hiddenVertex[i]->reveal(); +// for (unsigned int i = 0; i < _hiddenEdge.size(); ++i) +// _hiddenEdge[i]->reveal(); +// +// for (unsigned int i = 0; i < _edgeSwap.size(); ++i) { +// _edgeSwap[i].first->swap(_edgeSwap[i].second.first, +// _edgeSwap[i].second.second); +// } +// for (unsigned int i = 0; i < _vertSwapE.size(); ++i) { +// _vertSwapE[i].first->swap(_vertSwapE[i].second.first, +// _vertSwapE[i].second.second); +// } +// for (unsigned int i = 0; i < _vertSwapEL.size(); ++i) { +// _vertSwapEL[i].first->swap(_vertSwapEL[i].second.first, +// _vertSwapEL[i].second.second); +// } +// +// for (unsigned int i = 0; i < _hiddenElement.size(); ++i) +// _hiddenElement[i]->reveal(); +// for (unsigned int i = 0; i < _hiddenAction.size(); ++i) +// _hiddenAction[i]->reveal(); +// _oldParity.clear(); +// _oldCoordinate.clear(); +// //_newEdge.clear(); +// //_newVertex.clear(); +// _newAction.clear(); +// _newElement.clear(); +// _hiddenEdge.clear(); +// _hiddenVertex.clear(); +// _hiddenAction.clear(); +// _hiddenElement.clear(); +//} + +Rec2DDataChange::~Rec2DDataChange() +{ + for (unsigned int i = 0; i < _changes.size(); ++i) + delete _changes[i]; +} + +void Rec2DDataChange::swapFor(Rec2DEdge *re0, Rec2DEdge *re1) +{ + std::vector<Rec2DAction*> actions; + Rec2DElement *elem[2]; + Rec2DEdge::getElements(re0, elem); + if (elem[0]) { + elem[0]->getUniqueActions(actions); + if (elem[1]) + elem[1]->getUniqueActions(actions); + } + Rec2DAction::removeDuplicate(actions); + _changes.push_back(new Rec2DChange(re0, re1, actions, SwapEdgeInAction)); + _changes.push_back(new Rec2DChange(re0, re1, SwapEdgeInElem)); +} + +void Rec2DDataChange::swapFor(Rec2DVertex *rv0, Rec2DVertex *rv1) +{ + std::vector<Rec2DElement*> elem; + std::vector<Rec2DEdge*> edges; + std::vector<Rec2DAction*> actions; + rv0->getElements(elem); + rv0->getEdges(edges); + for (unsigned int i = 0; i < elem.size(); ++i) { + elem[i]->getUniqueActions(actions); + } + Rec2DAction::removeDuplicate(actions); + _changes.push_back(new Rec2DChange(rv0, rv1, actions, SwapVertInAction)); + _changes.push_back(new Rec2DChange(rv0, elem, RemoveElem)); + _changes.push_back(new Rec2DChange(rv0, rv1, edges, SwapVertInEdge)); + _changes.push_back(new Rec2DChange(rv1, elem, AddElem)); +} + void Rec2DDataChange::revert() { - for (unsigned int i = 0; i < _oldParity.size(); ++i) - _oldParity[i].first->setParity(_oldParity[i].second); - //for (unsigned int i = 0; i < _oldCoordinate.size(); ++i) - // _oldCoordinate[i].first->relocate(_oldCoordinate[i].second); - - for (unsigned int i = 0; i < _newAction.size(); ++i) - delete _newAction[i]; - for (unsigned int i = 0; i < _newElement.size(); ++i) - delete _newElement[i]; - for (unsigned int i = 0; i < _newEdge.size(); ++i) - delete _newEdge[i]; - for (unsigned int i = 0; i < _newVertex.size(); ++i) - delete _newVertex[i]; - - for (unsigned int i = 0; i < _hiddenVertex.size(); ++i) - _hiddenVertex[i]->reveal(); - for (unsigned int i = 0; i < _hiddenEdge.size(); ++i) - _hiddenEdge[i]->reveal(); - for (unsigned int i = 0; i < _hiddenElement.size(); ++i) - _hiddenElement[i]->reveal(); - for (unsigned int i = 0; i < _hiddenAction.size(); ++i) - _hiddenAction[i]->reveal(); - _oldParity.clear(); - _oldCoordinate.clear(); - _newEdge.clear(); - _newVertex.clear(); - _newAction.clear(); - _newElement.clear(); - _hiddenEdge.clear(); - _hiddenVertex.clear(); - _hiddenAction.clear(); - _hiddenElement.clear(); + static int num = 0; + Msg::Info("reverting %d", ++num); + for (int i = (int)_changes.size() - 1; i > -1; --i) + _changes[i]->revert(); + Msg::Info("."); } @@ -1224,6 +1720,22 @@ bool Rec2DAction::operator<(Rec2DAction &other) return getReward() < other.getReward(); } +void Rec2DAction::removeDuplicate(std::vector<Rec2DAction*> &actions) +{ + unsigned int i = -1; + while (++i < actions.size()) { + Rec2DAction *ra = actions[i]->getBase(); + if (ra) for (unsigned int j = 0; j < actions.size(); ++j) { + if (ra == actions[j]) { + actions[j] = actions.back(); + actions.pop_back(); + --i; + break; + } + } + } +} + double Rec2DAction::getReward() { if (_lastUpdate < Recombine2D::getNumChange()) @@ -1249,6 +1761,9 @@ Rec2DTwoTri2Quad::Rec2DTwoTri2Quad(Rec2DElement *el0, Rec2DElement *el1) if (edges[i] != _edges[4]) _edges[++k] = edges[i]; } + if (k > 3) + Msg::Error("[Rec2DTwoTri2Quad] too much edges"); + // reoder edges if needed if (edges[1] == _edges[4]) { Rec2DEdge *re = _edges[0]; _edges[0] = _edges[1]; @@ -1259,8 +1774,6 @@ Rec2DTwoTri2Quad::Rec2DTwoTri2Quad(Rec2DElement *el0, Rec2DElement *el1) _edges[2] = _edges[3]; _edges[3] = re; } - if (k > 3) - Msg::Error("[Rec2DTwoTri2Quad] too much edges"); _vertices[0] = _edges[4]->getVertex(0); _vertices[1] = _edges[4]->getVertex(1); @@ -1395,6 +1908,8 @@ void Rec2DTwoTri2Quad::apply(std::vector<Rec2DVertex*> &newPar) void Rec2DTwoTri2Quad::apply(Rec2DDataChange *rdc) const { + static int num = 0; + Msg::Info("Applying Rec2DTwoTri2Quad %d |%d|%d|", ++num, _triangles[0]->getNum(), _triangles[1]->getNum()); if (isObsolete()) { Msg::Error("[Rec2DTwoTri2Quad] I was obsolete !"); } @@ -1413,6 +1928,7 @@ void Rec2DTwoTri2Quad::apply(Rec2DDataChange *rdc) const rdc->hide(_edges[4]); rdc->append(new Rec2DElement((MQuadrangle*)NULL, (const Rec2DEdge**)_edges)); Recombine2D::incNumChange(); + Msg::Info("."); } void Rec2DTwoTri2Quad::_doWhatYouHaveToDoWithParity(Rec2DDataChange *rdc) const @@ -1444,7 +1960,9 @@ void Rec2DTwoTri2Quad::_doWhatYouHaveToDoWithParity(Rec2DDataChange *rdc) const Rec2DData::associateParity(_vertices[i+j]->getParity(), par, rdc); } } - rdc->checkObsoleteActions(); + rdc->checkObsoleteActions(_vertices, 4); + static int a = -1; + if (++a < 1) Msg::Warning("FIXME should check obsolete ?"); } } @@ -1572,12 +2090,226 @@ int Rec2DTwoTri2Quad::getNum(double shiftx, double shifty) return quad->getNum(); } +void Rec2DTwoTri2Quad::swap(Rec2DVertex *rv0, Rec2DVertex *rv1) +{ + for (int i = 0; i < 4; ++i) { + if (_vertices[i] == rv0) { + _vertices[i] = rv1; + return; + } + } + Msg::Error("[Rec2DTwoTri2Quad] Can't swap your vertex"); +} + +void Rec2DTwoTri2Quad::swap(Rec2DEdge *re0, Rec2DEdge *re1) +{ + for (int i = 0; i < 4; ++i) { + if (_edges[i] == re0) { + _edges[i] = re1; + return; + } + } + Msg::Error("[Rec2DTwoTri2Quad] Can't swap your edge (is middle : %d)", re0 == _edges[4]); +} + Rec2DElement* Rec2DTwoTri2Quad::getRandomElement() const { return _triangles[rand() % 2]; } +/** Rec2DCollapse **/ +/*********************/ +Rec2DCollapse::Rec2DCollapse(Rec2DTwoTri2Quad *rec) : _rec(rec)//, +// _triangles(rec->_triangles), _edges(_rec->_edges), _vertices(_rec->_vertices) +{ + _rec->_triangles[0]->add(this); + _rec->_triangles[1]->add(this); + Rec2DData::add(this); +} + +void Rec2DCollapse::hide() +{ + if (_rec->_triangles[0]) + _rec->_triangles[0]->remove(this); + if (_rec->_triangles[1]) + _rec->_triangles[1]->remove(this); + Rec2DData::remove(this); +} + +void Rec2DCollapse::reveal() +{ + if (_rec->_triangles[0]) + _rec->_triangles[0]->add(this); + if (_rec->_triangles[1]) + _rec->_triangles[1]->add(this); + Rec2DData::add(this); +} + +void Rec2DCollapse::_computeGlobQual() +{ + delete (new Rec2DNode(NULL, this, _globQualIfExecuted, 0)); +} + +void Rec2DCollapse::apply(std::vector<Rec2DVertex*> &newPar) +{ + static int a = -1; + if (++a < 1) Msg::Error("FIXME Need definition Rec2DTwoTri2Quad::apply(newPar)"); +} + +void Rec2DCollapse::apply(Rec2DDataChange *rdc) const +{ + static int num = 0; + Msg::Info("Applying Rec2DCollapse %d |%d|%d|", ++num, _rec->_triangles[0]->getNum(), _rec->_triangles[1]->getNum()); + if (isObsolete()) { + Msg::Error("[Rec2DTwoTri2Quad] I was obsolete !"); + } +#ifdef REC2D_DRAW + rdc->setAction(this); +#endif + std::vector<Rec2DAction*> actions; + _rec->_triangles[0]->getUniqueActions(actions); + _rec->_triangles[1]->getUniqueActions(actions); + rdc->hide(actions); + rdc->hide(_rec->_triangles[0]); + rdc->hide(_rec->_triangles[1]); + rdc->hide(_rec->_edges[4]); + Rec2DVertex *vOK, *vKO; + if (_rec->_vertices[0]->getOnBoundary()) { + SPoint2 p(_rec->_vertices[0]->u(), _rec->_vertices[0]->v()); + rdc->relocate(_rec->_vertices[1], p); + vOK = _rec->_vertices[0]; + vKO = _rec->_vertices[1]; + } + else if (_rec->_vertices[1]->getOnBoundary()) { + SPoint2 p(_rec->_vertices[1]->u(), _rec->_vertices[1]->v()); + rdc->relocate(_rec->_vertices[0], p); + vOK = _rec->_vertices[1]; + vKO = _rec->_vertices[0]; + } + else { + double u = (_rec->_vertices[0]->u() + _rec->_vertices[1]->u()) / 2; + double v = (_rec->_vertices[0]->v() + _rec->_vertices[1]->v()) / 2; + rdc->relocate(_rec->_vertices[1], SPoint2(u, v)); + rdc->relocate(_rec->_vertices[0], SPoint2(u, v)); + vOK = _rec->_vertices[0]; + vKO = _rec->_vertices[1]; + } + bool edge12KO = _rec->_edges[1]->getVertex(0) == vKO || + _rec->_edges[1]->getVertex(1) == vKO ; + rdc->swapFor(vKO, vOK); + rdc->hide(vKO); + static int a = -1; + if (++a < 1) Msg::Error("FIXME maj qualite edge"); + + int i0, i1, i2, i3; + if (edge12KO) { + i0 = 1; i1 = 2; + i2 = 0; i3 = 3; + } + else { + i0 = 0; i1 = 3; + i2 = 1; i3 = 2; + } + { + /*_rec->_edges[i0]->getActions(actions); + Rec2DAction::removeDuplicate(actions); + for (unsigned int i = 0; i < actions.size(); ++i) { + Msg::Info("b1 %d", i); + actions[i]->swap(_rec->_edges[i0], _rec->_edges[i2]); + actions[i]->swap(vKO, vOK); + static int a = -1; + if (++a < 1) Msg::Error("FIXME swap dans rdc"); + } + _rec->_edges[i1]->getActions(actions); + Rec2DAction::removeDuplicate(actions); + for (unsigned int i = 0; i < actions.size(); ++i) { + Msg::Info("b2 %d", i); + actions[i]->swap(_rec->_edges[i1], _rec->_edges[i3]); + actions[i]->swap(vKO, vOK); + }*/ + rdc->swapFor(_rec->_edges[i0], _rec->_edges[i2]); + rdc->swapFor(_rec->_edges[i1], _rec->_edges[i3]); + rdc->hide(_rec->_edges[i0]); + rdc->hide(_rec->_edges[i1]); + _rec->_edges[i2]->print(); + _rec->_edges[i3]->print(); + } + + int parKO, parOK; + if ((parKO = vKO->getParity())) { + if (!(parOK = vOK->getParity())) { + rdc->changeParity(vOK, parKO); + Rec2DVertex *v[1] = {vOK}; + rdc->checkObsoleteActions(v, 1); + } + else if (parOK/2 != parKO/2) { + Msg::Error("FIXME implement associate"); + } + } + + + /*Rec2DElement *elem[2]; + Rec2DTwoTri2Quad *newAction; + + Rec2DEdge::getElements(_rec->_edges[0], elem); + Msg::Info("%d %d", elem[0], elem[1]); + Msg::Info(" "); + newAction = new Rec2DTwoTri2Quad(elem[0], elem[1]); + rdc->append(new Rec2DCollapse(newAction)); + rdc->append(newAction); + + Rec2DEdge::getElements(_rec->_edges[3], elem); + newAction = new Rec2DTwoTri2Quad(elem[0], elem[1]); + rdc->append(new Rec2DCollapse(newAction)); + rdc->append(newAction);*/ + + Recombine2D::incNumChange(); + Msg::Info("."); +} + +bool Rec2DCollapse::isObsolete() const +{ + int p[2]; + p[0] = _rec->_vertices[0]->getParity(); + p[1] = _rec->_vertices[1]->getParity(); + return Rec2DCollapse::isObsolete(p) || + (_rec->_vertices[0]->getOnBoundary() && + _rec->_vertices[1]->getOnBoundary() ); +} + +bool Rec2DCollapse::isAssumedObsolete() const +{ + int p[2]; + p[0] = _rec->_vertices[0]->getAssumedParity(); + p[1] = _rec->_vertices[1]->getAssumedParity(); + return Rec2DCollapse::isObsolete(p) || + (_rec->_vertices[0]->getOnBoundary() && + _rec->_vertices[1]->getOnBoundary() ); +} + +bool Rec2DCollapse::isObsolete(const int *p) +{ + if (p[0] && p[0]/2 == p[1]/2 && p[0]%2 != p[1]%2) + return true; + return false; +} + +void Rec2DCollapse::getAssumedParities(int *par) const +{ + static int a = -1; + if (++a < 1) Msg::Error("FIXME Rec2DTwoTri2Quad::getAssumedParities not ok"); +} + +bool Rec2DCollapse::whatWouldYouDo + (std::map<Rec2DVertex*, std::vector<int> > &suggestions) +{ + static int a = -1; + if (++a < 1) Msg::Error("FIXME Need definition Rec2DTwoTri2Quad::whatWouldYouDo"); + return false; +} + + /** Rec2DEdge **/ /*****************/ Rec2DEdge::Rec2DEdge(Rec2DVertex *rv0, Rec2DVertex *rv1) @@ -1649,12 +2381,33 @@ double Rec2DEdge::getWeightedQual() const return (double)_weight * _qual; } +void Rec2DEdge::print() const +{ + Rec2DElement *elem[2]; + Rec2DEdge::getElements(this, elem); + int a, b = a = NULL; + if (elem[0]) + a = elem[0]->getNum(); + if (elem[1]) + b = elem[1]->getNum(); + + Msg::Info(" edge , %d--%d , %d/%d", _rv0->getNum(), _rv1->getNum(), a, b); +} + void Rec2DEdge::_addWeight(int w) { _weight += w; - if (_weight > REC2D_EDGE_BASE + 2*REC2D_EDGE_QUAD) - Msg::Error("[Rec2DEdge] Weight too high : %d (%d max)", - _weight, REC2D_EDGE_BASE + 2*REC2D_EDGE_QUAD ); + if (_weight > REC2D_EDGE_BASE + 2*REC2D_EDGE_QUAD) { + Rec2DElement *elem[2]; + Rec2DEdge::getElements(this, elem); + int a, b = a = NULL; + if (elem[0]) + a = elem[0]->getNum(); + if (elem[1]) + b = elem[1]->getNum(); + Msg::Error("[Rec2DEdge] Weight too high : %d (%d max) (im %d %d)", + _weight, REC2D_EDGE_BASE + 2*REC2D_EDGE_QUAD, a, b ); + } if (_weight < REC2D_EDGE_BASE) Msg::Error("[Rec2DEdge] Weight too low : %d (%d min)", _weight, REC2D_EDGE_BASE ); @@ -1665,15 +2418,58 @@ Rec2DElement* Rec2DEdge::getUniqueElement(const Rec2DEdge *re) { std::vector<Rec2DElement*> elem; Rec2DVertex::getCommonElements(re->getVertex(0), re->getVertex(1), elem); + unsigned int i = 0; + while (i < elem.size()) { + if (!elem[i]->has(re)) { + elem[i] = elem.back(); + elem.pop_back(); + } + else + ++i; + } if (elem.size() == 1) return elem[0]; - if (elem.size() != 0) + if (elem.size() != 0) { + Msg::Info("size(%d) %d %d", elem.size(), elem[0]->getNum(), elem[1]->getNum()); Msg::Error("[Rec2DEdge] Edge bound %d elements, returning NULL", elem.size()); + } return NULL; } -void Rec2DEdge::swap(Rec2DVertex *oldRV, Rec2DVertex *newRV) +void Rec2DEdge::getElements(const Rec2DEdge *re, Rec2DElement **elem) { + elem[0] = NULL; + elem[1] = NULL; + std::vector<Rec2DElement*> vectElem; + Rec2DVertex::getCommonElements(re->getVertex(0), re->getVertex(1), vectElem); + unsigned int i = 0; + while (i < vectElem.size()) { + if (!vectElem[i]->has(re)) { + vectElem[i] = vectElem.back(); + vectElem.pop_back(); + } + else + ++i; + } + switch (vectElem.size()) { + case 2 : + elem[1] = vectElem[1]; + case 1 : + elem[0] = vectElem[0]; + return; + case 0 : + return; + default : + Msg::Error("[Rec2DEdge] my integrity is not respected :'("); + } +} + +void Rec2DEdge::swap(Rec2DVertex *oldRV, Rec2DVertex *newRV, bool upVert) +{ + if (upVert) { + oldRV->rmv(this); + newRV->add(this); + } if (_rv0 == oldRV) { _rv0 = newRV; return; @@ -1732,6 +2528,19 @@ Rec2DVertex* Rec2DEdge::getOtherVertex(const Rec2DVertex *rv) const return NULL; } +void Rec2DEdge::getActions(std::vector<Rec2DAction*> &actions) const +{ + actions.clear(); + Rec2DElement *elem[2]; + Rec2DEdge::getElements(this, elem); + if (elem[0]) { + elem[0]->getUniqueActions(actions); + if (elem[1]) + elem[1]->getUniqueActions(actions); + } + +} + /** Rec2DVertex **/ /*******************/ @@ -1758,7 +2567,7 @@ Rec2DVertex::Rec2DVertex(Rec2DVertex *rv, double ang) if (++a < -1) Msg::Warning("FIXME Edges really necessary ?"); for (unsigned int i = 0; i < _edges.size(); ++i) { - _edges[i]->swap(rv, this); + _edges[i]->swap(rv, this, false); } Rec2DData::add(this); if (_elements.size()) @@ -1779,8 +2588,10 @@ void Rec2DVertex::hide() Rec2DData::removeAssumedParity(this, _assumedParity); Rec2DData::remove(this); - if (_elements.size()) + if (_elements.size()) { + Msg::Error("[Rec2DVertex] normal ?"); Rec2DData::addVert(-2, -getQual()); + } } void Rec2DVertex::reveal() @@ -2000,6 +2811,16 @@ void Rec2DVertex::revertAssumedParity(int p) } } +void Rec2DVertex::relocate(SPoint2 p) +{ + _param = p; + GPoint gpt = Recombine2D::getGFace()->point(p); + _v->x() = gpt.x(); + _v->y() = gpt.y(); + _v->z() = gpt.z(); + _lastMove = Recombine2D::getNumChange(); +} + void Rec2DVertex::getTriangles(std::set<Rec2DElement*> &tri) const { for (unsigned int i = 0; i < _elements.size(); ++i) { @@ -2008,6 +2829,14 @@ void Rec2DVertex::getTriangles(std::set<Rec2DElement*> &tri) const } } +void Rec2DVertex::getElements(std::vector<Rec2DElement*> &elem) const +{ + elem.clear(); + for (unsigned int i = 0; i < _elements.size(); ++i) { + elem.push_back(_elements[i]); + } +} + double Rec2DVertex::getQualDegree(int numEl) const { int nEl = numEl > -1 ? numEl : _elements.size(); @@ -2330,10 +3159,27 @@ void Rec2DElement::addNeighbour(const Rec2DEdge *re, const Rec2DElement *rel) return; } } - Msg::Error("[Rec2DElement] Edge not found"); + + Rec2DElement *elem[2]; + Rec2DEdge::getElements(re, elem); + int a, b = a = NULL; + if (elem[0]) + a = elem[0]->getNum(); + if (elem[1]) + b = elem[1]->getNum(); + Msg::Error("[Rec2DElement] Edge not found (add) (im %d, edge %d %d)", getNum(), a, b); + for (int i = 0; i < _numEdge; ++i) { + Rec2DElement *elem[2]; + Rec2DEdge::getElements(_edges[i], elem); + int a, b = a = NULL; + if (elem[0]) + a = elem[0]->getNum(); + if (elem[1]) + b = elem[1]->getNum(); + Msg::Error("edge%d : %d %d", i+1, a, b); + } } - void Rec2DElement::rmvNeighbour(const Rec2DEdge *re, const Rec2DElement *rel) { for (int i = 0; i < _numEdge; ++i) { @@ -2345,9 +3191,71 @@ void Rec2DElement::rmvNeighbour(const Rec2DEdge *re, const Rec2DElement *rel) return; } } - Msg::Error("[Rec2DElement] Edge not found"); + + Rec2DElement *elem[2]; + Rec2DEdge::getElements(re, elem); + int a, b = a = NULL; + if (elem[0]) + a = elem[0]->getNum(); + if (elem[1]) + b = elem[1]->getNum(); + Msg::Error("[Rec2DElement] Edge not found (rmv) (im %d, edge %d %d)", getNum(), a, b); } +void Rec2DElement::swap(Rec2DEdge *re1, Rec2DEdge *re2) +{ + for (int i = 0; i < _numEdge; ++i) { + if (_edges[i] == re1) { + if (_numEdge == 3) + re1->remHasTri(); + else + re1->remHasQuad(); + if (_elements[i]) + _elements[i]->rmvNeighbour(_edges[i], this); + Rec2DElement *elem[2]; + Rec2DEdge::getElements(re2, elem); + _edges[i] = (Rec2DEdge*)re2; + if (_numEdge == 3) + re2->addHasTri(); + else + re2->addHasQuad(); + if (elem[1]) + Msg::Error("[Rec2DElement] Invalid swapping (there are %d and %d)", elem[0]->getNum(), elem[1]->getNum()); + else if (elem[0]) { + _elements[i] = elem[0]; + elem[0]->addNeighbour(re2, this); + } + else + _elements[i] = NULL; + return; + } + } + + Rec2DElement *elem[2]; + Rec2DEdge::getElements(re1, elem); + int a, b = a = NULL; + if (elem[0]) + a = elem[0]->getNum(); + if (elem[1]) + b = elem[1]->getNum(); + Rec2DEdge::getElements(re2, elem); + int c, d = c = NULL; + if (elem[0]) + c = elem[0]->getNum(); + if (elem[1]) + d = elem[1]->getNum(); + Msg::Error("[Rec2DElement] Try to give me the good edge (im %d, edge %d %d -> edge %d %d)", getNum(), a, b, c, d); + for (int i = 0; i < _numEdge; ++i) { + Rec2DElement *elem[2]; + Rec2DEdge::getElements(_edges[i], elem); + int a, b = a = NULL; + if (elem[0]) + a = elem[0]->getNum(); + if (elem[1]) + b = elem[1]->getNum(); + Msg::Error("edge%d : %d %d", i+1, a, b); + } +} double Rec2DElement::getAngle(const Rec2DVertex *rv) const { @@ -2568,7 +3476,8 @@ Rec2DNode::Rec2DNode(Rec2DNode *father, Rec2DAction *ra, std::vector<Rec2DElement*> neighbours; if (_ra) { - _ra->getNeighbourElements(neighbours); + if (depth) + _ra->getNeighbourElements(neighbours); _dataChange = Rec2DData::getNewDataChange(); _ra->apply(_dataChange); } @@ -2579,7 +3488,7 @@ Rec2DNode::Rec2DNode(Rec2DNode *father, Rec2DAction *ra, _remainingTri = Rec2DData::getNumElement(); _globalQuality = Rec2DData::getGlobalQuality(); - if (depth != 0) { + if (depth) { std::vector<Rec2DAction*> actions; Recombine2D::nextTreeActions(actions, neighbours); @@ -2715,6 +3624,14 @@ bool Rec2DNode::makeChanges() if (_dataChange || !_ra) return false; _dataChange = Rec2DData::getNewDataChange(); +#ifdef REC2D_DRAW // draw state at origin + double time = Cpu(); + _ra->color(0, 0, 200); + CTX::instance()->mesh.changed = ENT_ALL; + drawContext::global()->draw(); + while (Cpu()-time < REC2D_WAIT_TIME) + FlGui::instance()->check(); +#endif _ra->apply(_dataChange); Rec2DData::setNumTri(_remainingTri); return true; @@ -2725,3 +3642,4 @@ bool Rec2DNode::operator<(Rec2DNode &other) return _globalQuality < other._globalQuality; } + diff --git a/Mesh/meshGFaceRecombine.h b/Mesh/meshGFaceRecombine.h index 0a0739eb30fff457f20d30db9f591ab8f590b7d4..fd321e8a0160062e4f60c8e50cfd4f221c2dc9b1 100644 --- a/Mesh/meshGFaceRecombine.h +++ b/Mesh/meshGFaceRecombine.h @@ -13,7 +13,7 @@ #define REC2D_EDGE_BASE 2 #define REC2D_EDGE_QUAD 1 #define REC2D_ALIGNMENT .5 -#define REC2D_NUM_SON 3 +#define REC2D_NUM_SON 6 #include "GFace.h" #include "BackgroundMesh.h" @@ -28,6 +28,7 @@ class Rec2DElement; class Rec2DAction; class Rec2DData; class Rec2DDataChange; +class Rec2DCollapse; struct lessRec2DAction { bool operator()(Rec2DAction*, Rec2DAction*) const; }; @@ -206,28 +207,108 @@ class Rec2DData { static void revertAssumedParities(); }; +enum Rec2DChangeType { + HideEdge, HideVertex, HideElement, + CreatedEdge, CreatedVertex, CreatedElement, + HideAction, HideActions, + CreatedAction, CreatedActions, + SwapVertInAction, SwapVertInEdge, + SwapEdgeInAction, SwapEdgeInElem, + RemoveElem, AddElem, Relocate, ChangePar, SavePar, + Error, Reverted +}; + +class Rec2DChange { + private : + Rec2DChangeType _type; + void *_entity; + void *_info; + + public : + Rec2DChange() {Msg::Error("[Rec2DChange] I should not be created in this manner");} + Rec2DChange(Rec2DEdge*, bool toHide = false); + Rec2DChange(Rec2DVertex*, bool toHide = false); + Rec2DChange(Rec2DElement*, bool toHide = false); + Rec2DChange(Rec2DAction*, bool toHide = false); + Rec2DChange(const std::vector<Rec2DAction*>&, bool toHide = false); + Rec2DChange(Rec2DVertex*, int newParity, Rec2DChangeType); + Rec2DChange(Rec2DVertex*, SPoint2 newCoord); + Rec2DChange(const std::vector<Rec2DVertex*>&, Rec2DChangeType); // save Parity + Rec2DChange(Rec2DVertex*, const std::vector<Rec2DElement*>&, + Rec2DChangeType ); // add or remove element in vertex + Rec2DChange(Rec2DVertex*, Rec2DVertex*, + const std::vector<Rec2DEdge*>&, + Rec2DChangeType ); // swap vertex1 to vertex2 (edge) + Rec2DChange(Rec2DVertex*, Rec2DVertex*, + const std::vector<Rec2DAction*>&, + Rec2DChangeType ); // swap vertex1 to vertex2 (action) + Rec2DChange(Rec2DEdge*, Rec2DEdge*, Rec2DChangeType); // swap edge1 to edge2 (element) + Rec2DChange(Rec2DEdge*, Rec2DEdge*, + const std::vector<Rec2DAction*>&, + Rec2DChangeType ); // swap edge1 to edge2 (action) + + void revert(); +}; + class Rec2DDataChange { private : - std::vector<Rec2DEdge*> _hiddenEdge, _newEdge; - std::vector<Rec2DVertex*> _hiddenVertex, _newVertex; - std::vector<Rec2DElement*> _hiddenElement, _newElement; - std::vector<Rec2DAction*> _hiddenAction, _newAction; - std::vector<std::pair<Rec2DVertex*, SPoint2> > _oldCoordinate; - std::vector<std::pair<Rec2DVertex*, int> > _oldParity; - + std::vector<Rec2DChange*> _changes; Rec2DAction *_ra; + //std::vector<Rec2DEdge*> _hiddenEdge/*, _newEdge*/; + //std::vector<Rec2DVertex*> _hiddenVertex/*, _newVertex*/; + //std::vector<Rec2DElement*> _hiddenElement, _newElement; + //std::vector<Rec2DAction*> _hiddenAction, _newAction; + //std::vector<std::pair<Rec2DVertex*, SPoint2> > _oldCoordinate; + //std::vector<std::pair<Rec2DVertex*, int> > _oldParity; + //std::vector<std::pair<Rec2DEdge*, std::pair<Rec2DVertex*, Rec2DVertex*> > > _vertSwapE; + //std::vector<std::pair<Rec2DElement*, std::pair<Rec2DEdge*, Rec2DEdge*> > > _edgeSwap; + //std::vector<std::pair<Rec2DElement*, std::pair<Rec2DVertex*, Rec2DVertex*> > > _vertSwapEL; + + public : - void hide(Rec2DEdge*); - void hide(Rec2DElement*); - void hide(Rec2DAction*); - void hide(std::vector<Rec2DAction*>); + ~Rec2DDataChange(); + + inline void hide(Rec2DEdge *re) {_changes.push_back(new Rec2DChange(re, 1));} + inline void hide(Rec2DVertex *rv) {_changes.push_back(new Rec2DChange(rv, 1));} + inline void hide(Rec2DElement *rel) {_changes.push_back(new Rec2DChange(rel, 1));} + inline void hide(Rec2DAction *ra) {_changes.push_back(new Rec2DChange(ra, 1));} + inline void hide(std::vector<Rec2DAction*> &vect) {_changes.push_back(new Rec2DChange(vect, 1));} - void append(const Rec2DElement*); + inline void append(Rec2DElement *rel) {_changes.push_back(new Rec2DChange(rel));} + inline void append(Rec2DAction *ra) {_changes.push_back(new Rec2DChange(ra));} - void changeParity(Rec2DVertex*, int); - void saveParity(std::vector<Rec2DVertex*>&); - void checkObsoleteActions(); + void swapFor(Rec2DEdge*, Rec2DEdge*); + void swapFor(Rec2DVertex*, Rec2DVertex*); + + inline void relocate(Rec2DVertex *rv, const SPoint2 &p) { + _changes.push_back(new Rec2DChange(rv, p)); + } + inline void changeParity(Rec2DVertex *rv, int p) { + _changes.push_back(new Rec2DChange(rv, p, ChangePar)); + } + inline void saveParity(const std::vector<Rec2DVertex*> &verts) { + _changes.push_back(new Rec2DChange(verts, SavePar)); + } + //void checkObsoleteActions() {_changes.push_back(new Rec2DChange());} + + //void hide(Rec2DEdge*); {_elementaryChanges.push_back(new Rec2DChange(re));} + //void hide(Rec2DVertex*); + //void hide(Rec2DElement*); + //void hide(Rec2DAction*); + //void hide(std::vector<Rec2DAction*>); + // + //void append(const Rec2DElement*); + //void append(const Rec2DAction*); + // + //void swapFor(Rec2DEdge*, Rec2DEdge*); + //void swapFor(Rec2DVertex*, Rec2DVertex*); + // + //void relocate(Rec2DVertex*, double, double); + // + //void changeParity(Rec2DVertex*, int); + //void saveParity(std::vector<Rec2DVertex*>&); + void checkObsoleteActions(Rec2DVertex*const*, int size); void revert(); @@ -262,6 +343,11 @@ class Rec2DAction { virtual int getNum(double shiftx, double shifty) = 0; virtual Rec2DElement* getRandomElement() const = 0; //virtual void print() = 0; + virtual bool haveElem() = 0; + inline virtual Rec2DAction* getBase() const = 0; + static void removeDuplicate(std::vector<Rec2DAction*>&); + virtual void swap(Rec2DVertex*, Rec2DVertex*) = 0; + virtual void swap(Rec2DEdge*, Rec2DEdge*) = 0; private : virtual void _computeGlobQual() = 0; @@ -272,6 +358,7 @@ class Rec2DTwoTri2Quad : public Rec2DAction { Rec2DElement *_triangles[2]; Rec2DEdge *_edges[5]; // 4 boundary, 1 embedded Rec2DVertex *_vertices[4]; // 4 boundary (2 on embedded edge + 2) + friend class Rec2DCollapse; public : Rec2DTwoTri2Quad(Rec2DElement*, Rec2DElement*); @@ -294,14 +381,69 @@ class Rec2DTwoTri2Quad : public Rec2DAction { virtual void getElements(std::vector<Rec2DElement*>&) const; virtual void getNeighbourElements(std::vector<Rec2DElement*>&) const; virtual int getNum(double shiftx, double shifty); - virtual Rec2DElement* getRandomElement() const; + virtual inline Rec2DElement* getRandomElement() const; //virtual void print(); + virtual bool haveElem() {return true;} + inline virtual Rec2DAction* getBase() const {return NULL;} + virtual void swap(Rec2DVertex*, Rec2DVertex*); + virtual void swap(Rec2DEdge*, Rec2DEdge*); private : virtual void _computeGlobQual(); void _doWhatYouHaveToDoWithParity(Rec2DDataChange*) const; }; +class Rec2DCollapse : public Rec2DAction { + private : + Rec2DTwoTri2Quad *_rec; + //Rec2DElement **const&_triangles; + //Rec2DEdge **const&_edges; + //Rec2DVertex **const&_vertices; + + public : + Rec2DCollapse(Rec2DTwoTri2Quad*); + ~Rec2DCollapse() {hide();} + virtual void hide(); + virtual void reveal(); + + virtual void color(int c1, int c2, int c3) const { + _rec->color(c1, c2, c3); + } + virtual void apply(std::vector<Rec2DVertex*> &newPar); + virtual void apply(Rec2DDataChange*) const; + + virtual bool isObsolete() const; + virtual bool isAssumedObsolete() const; + static bool isObsolete(const int*); + virtual void getAssumedParities(int*) const; + virtual bool whatWouldYouDo(std::map<Rec2DVertex*, std::vector<int> >&); + + virtual inline Rec2DVertex* getVertex(int i) const { + return _rec->getVertex(i); + } + virtual inline int getNumElement() {return 2;} + virtual void getElements(std::vector<Rec2DElement*> &vec) const { + _rec->getElements(vec); + } + virtual void getNeighbourElements(std::vector<Rec2DElement*> &vec) const { + _rec->getNeighbourElements(vec); + } + virtual int getNum(double shiftx, double shifty) { + return -1; + } + virtual inline Rec2DElement* getRandomElement() const { + return _rec->getRandomElement(); + } + //virtual void print(); + virtual bool haveElem() {return false;} + inline virtual Rec2DAction* getBase() const {return _rec;} + inline virtual void swap(Rec2DVertex *rv0, Rec2DVertex *rv1) {_rec->swap(rv0, rv1);} + inline virtual void swap(Rec2DEdge *re0, Rec2DEdge *re1) {_rec->swap(re0, re1);} + + private : + virtual void _computeGlobQual(); +}; + class Rec2DEdge { private : Rec2DVertex *_rv0, *_rv1; @@ -319,6 +461,7 @@ class Rec2DEdge { //double getQualL() const; //double getQualO() const; double getWeightedQual() const; + void print() const; inline void addHasTri() {_addWeight(-REC2D_EDGE_QUAD); ++_boundary;} inline void remHasTri() {_addWeight(REC2D_EDGE_QUAD); --_boundary;} @@ -329,8 +472,10 @@ class Rec2DEdge { inline Rec2DVertex* getVertex(int i) const {if (i) return _rv1; return _rv0;} Rec2DVertex* getOtherVertex(const Rec2DVertex*) const; static Rec2DElement* getUniqueElement(const Rec2DEdge*); + static void getElements(const Rec2DEdge*, Rec2DElement**); + void getActions(std::vector<Rec2DAction*>&) const; - void swap(Rec2DVertex *oldRV, Rec2DVertex *newRV); + void swap(Rec2DVertex *oldRV, Rec2DVertex *newRV, bool upVert = true); private : void _computeQual(); @@ -368,6 +513,7 @@ class Rec2DVertex { void hide(); void reveal(); + inline int getNum() const {return _v->getNum();} inline double getAngle() const {return _angle;} inline double getQual() const {return getQualDegree() + getQualAngle();} inline double getQualAngle() const {return _sumQualAngle/(double)_elements.size();} @@ -388,7 +534,9 @@ class Rec2DVertex { void revertAssumedParity(int); inline int getNumElements() const {return _elements.size();} + inline void getEdges(std::vector<Rec2DEdge*> &v) const {v = _edges;} void getTriangles(std::set<Rec2DElement*>&) const; + void getElements(std::vector<Rec2DElement*>&) const; inline MVertex* getMVertex() const {return _v;} inline int getLastMove() const {return _lastMove;} @@ -399,6 +547,8 @@ class Rec2DVertex { } inline double u() const {return _param[0];} inline double v() const {return _param[1];} + void relocate(SPoint2 p); + inline void getParam(SPoint2 *p) {*p = _param;} void add(Rec2DEdge*); bool has(Rec2DEdge*) const; @@ -447,6 +597,8 @@ class Rec2DElement { void addNeighbour(const Rec2DEdge*, const Rec2DElement*); void rmvNeighbour(const Rec2DEdge*, const Rec2DElement*); + void swap(Rec2DEdge*, Rec2DEdge*); + inline MElement* getMElement() const {return _mEl;} #ifdef REC2D_DRAW MTriangle* getMTriangle() { @@ -481,6 +633,7 @@ class Rec2DElement { void getMoreNeighbours(std::vector<Rec2DElement*>&) const; Rec2DVertex* getOtherVertex(const Rec2DVertex*, const Rec2DVertex*) const; static Rec2DEdge* getCommonEdge(const Rec2DElement*, const Rec2DElement*); + static void getElements(const Rec2DEdge*, Rec2DElement**); inline int getNum() const {return _mEl->getNum();}