From 5bed86a1d4dfd3c1fbb3e12ebe086e39cfda20be Mon Sep 17 00:00:00 2001 From: Matti Pellika <matti.pellikka@tut.fi> Date: Sun, 3 Jan 2010 16:28:59 +0000 Subject: [PATCH] Rewrote chain local deformation. --- Geo/CellComplex.cpp | 5 + Geo/CellComplex.h | 5 + Geo/ChainComplex.cpp | 352 ++++++++----------------------------------- Geo/ChainComplex.h | 11 +- 4 files changed, 79 insertions(+), 294 deletions(-) diff --git a/Geo/CellComplex.cpp b/Geo/CellComplex.cpp index ccab617075..a0fe39fb5f 100644 --- a/Geo/CellComplex.cpp +++ b/Geo/CellComplex.cpp @@ -16,6 +16,7 @@ CellComplex::CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> su _subdomain = subdomain; _dim = 0; + _simplicial = true; // find boundary elements find_boundary(domain, subdomain); @@ -167,16 +168,20 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){ } else if(type == MSH_QUA_4 || type == MSH_QUA_8 || type == MSH_QUA_9){ cell = new CQuadrangle(vertices, tag, subdomain, boundary); + _simplicial = false; } /* else if(type == MSH_HEX_8 || type == MSH_HEX_27 || type == MSH_HEX_20){ cell = new CHexahedron(vertices, tag, subdomain, boundary); + _simplicial = false; } else if(type == MSH_PRI_6 || type == MSH_PRI_18 || type == MSH_PRI_15){ cell = new CPrism(vertices, tag, subdomain, boundary); + _simplicial = false; } else if(type == MSH_PYR_5 || type == MSH_PYR_14 || type == MSH_PYR_13){ cell = new CPyramid(vertices, tag, subdomain, boundary); + _simplicial = false; }*/ else printf("Error: mesh element %d not implemented yet! \n", type); tag++; diff --git a/Geo/CellComplex.h b/Geo/CellComplex.h index 41a9bb0e85..da55e8a68a 100644 --- a/Geo/CellComplex.h +++ b/Geo/CellComplex.h @@ -903,6 +903,9 @@ class CellComplex int _dim; + // Is the cell complex simplicial + bool _simplicial; + public: // iterator for the cells of same dimension typedef std::set<Cell*, Less_Cell>::iterator citer; @@ -998,6 +1001,8 @@ class CellComplex int getDim() {return _dim; } + bool simplicial() { return _simplicial; } + std::set<Cell*, Less_Cell> getCells(int dim){ return _cells[dim]; } std::set<Cell*, Less_Cell> getOrgCells(int dim){ return _ocells[dim]; } diff --git a/Geo/ChainComplex.cpp b/Geo/ChainComplex.cpp index 0b8e2ac284..90c2c9f7fc 100644 --- a/Geo/ChainComplex.cpp +++ b/Geo/ChainComplex.cpp @@ -483,325 +483,104 @@ Chain::Chain(std::set<Cell*, Less_Cell> cells, std::vector<int> coeffs, CellComp } -Cell* Chain::findCommonCbdCell(Cell* c1, Cell* c2, Cell* c3){ - /* - c1->printCell(); - c1->printOrgCbd(); - c2->printOrgCbd(); - c2->printCell(); - printf("------ \n"); - */ - - std::map< Cell*, int, Less_Cell > c1Cbd = c1->getOrgCbd(); - for(std::map< Cell*, int, Less_Cell >::iterator it = c1Cbd.begin(); it != c1Cbd.end(); it++){ - Cell* c1CbdCell = (*it).first; - if(c3 == NULL){ - if(c2->hasCoboundary(c1CbdCell, true)) return c1CbdCell; - } - else{ - if(c2->hasCoboundary(c1CbdCell, true) && c3->hasCoboundary(c1CbdCell, true)) return c1CbdCell; - } - } +bool Chain::deform(std::map<Cell*, int, Less_Cell> &cellsInChain, std::map<Cell*, int, Less_Cell> &cellsNotInChain){ - return NULL; - -} - -std::pair<Cell*, int> Chain::findRemainingBoundary(Cell* b, Cell* c1, Cell* c2, Cell* c3){ - std::map<Cell*, int, Less_Cell> bBd = b->getOrgBd(); - for(std::map<Cell*, int, Less_Cell >::iterator it = bBd.begin(); it != bBd.end(); it++){ - Cell* bBdCell = (*it).first; - if(c3 == NULL) { - if( !(*bBdCell == *c1) && !(*bBdCell == *c2)) return *it; - } - else{ - if( !(*bBdCell == *c1) && !(*bBdCell == *c2) && !(*bBdCell == *c3) ) return *it; + std::vector<int> cc; + std::vector<int> bc; + + for(citer cit = cellsInChain.begin(); cit != cellsInChain.end(); cit++){ + Cell* c = (*cit).first; + c->setImmune(false); + if(!c->inSubdomain()) { + cc.push_back(getCoeff(c)); + bc.push_back((*cit).second); } + removeCell(c); } - return std::make_pair(b, 0); -} - -int Chain::findOrientation(Cell* b, Cell* c){ - std::map< Cell*, int, Less_Cell > bBd = b->getOrgBd(); - std::map< Cell*, int, Less_Cell >::iterator it = bBd.find(c); - if(it != bBd.end()) return (*it).second; - return 0; -} - -std::map<Cell*, int, Less_Cell> Chain::getBdCellsInChain(Cell* cell){ - - std::map<Cell*, int, Less_Cell> cells; - std::map<Cell*, int, Less_Cell> boundary = cell->getOrgBd(); - for(citer cit = boundary.begin(); cit != boundary.end(); cit++){ - Cell* BdCell = (*cit).first; - int BdCellO = (*cit).second; - if(hasCell(BdCell) || BdCell->inSubdomain() ) cells.insert( std::make_pair(BdCell, BdCellO) ); + // FIXME: orientations don't get right on 2-chains + int flip = 1; + if(cc[0] != bc[0]) flip = flip*-1; + + int n = 1; + for(citer cit = cellsNotInChain.begin(); cit != cellsNotInChain.end(); cit++){ + Cell* c = (*cit).first; + if(n == 2) c->setImmune(true); + else c->setImmune(false); + int coeff = -1*(*cit).second*flip; + addCell(c, coeff); + n++; } - return cells; + + return true; } -bool Chain::removeBoundary( std::pair<Cell*, int> cell ){ +bool Chain::deformChain(std::pair<Cell*, int> cell, bool straighten, bool bend){ Cell* c1 = cell.first; - int c1c = cell.second; - if(c1c == 0) return false; std::map<Cell*, int, Less_Cell> c1Cbd = c1->getOrgCbd(); for(citer cit = c1Cbd.begin(); cit != c1Cbd.end(); cit++){ - Cell* c1CbdCell = (*cit).first; - std::map<Cell*, int, Less_Cell> cells = getBdCellsInChain(c1CbdCell); + std::map<Cell*, int, Less_Cell> cellsInChain; + std::map<Cell*, int, Less_Cell> cellsNotInChain; - if( (getDim() == 1 && cells.size() == 3) || (getDim() == 2 && cells.size() == 4)){ - for(citer cit2 = cells.begin(); cit2 != cells.end(); cit2++){ - Cell* cell = (*cit2).first; - removeCell(cell); - } - return true; - } - } - return false; -} - -bool Chain::straightenChain( std::pair<Cell*, int> cell ){ - - Cell* c1 = cell.first; - int c1c = cell.second; - int c1o = 0; - if(c1c == 0 || c1->getImmune()) return false; - - if(cell.second == 0 || cell.first->getImmune()) return false; - /* - Cell* c1 = NULL; - int c1c = 0; - int c1o = 0; - */ - Cell* c2 = NULL; - int c2c = 0; - int c2o = 0; - - Cell* c3 = NULL; - int c3c = 0; - int c3o = 0; - - Cell* b = NULL; - - std::map<Cell*, int, Less_Cell> c1Cbd = cell.first->getOrgCbd(); - for(citer cit = c1Cbd.begin(); cit != c1Cbd.end(); cit++){ Cell* c1CbdCell = (*cit).first; - c1o = (*cit).second; - - /* - std::map<Cell*, int, Less_Cell> cells = getBdCellsInChain(c1CbdCell); - //if((getDim() == 1 && cells.size() != 2) || (getDim() == 2 && cells.size() != 3) ) continue; - if( getDim() == 1 && cells.size() == 2){ - - citer cit2 = cells.end(); - c1 = (*cit2).first; - //c1->printCell(); - - c1c = getCoeff(c1); - c1o = (*cit2).second; - - cit2 = cells.begin(); - c2 = (*cit2).first; - c2c = getCoeff(c2); - c2o = (*cit2).second; - b = c1CbdCell; - printf("kakak4 \n"); - } - else if( getDim() == 2 && cells.size() == 3){ - - } - */ - - std::map<Cell*, int, Less_Cell> c1CbdBd = c1CbdCell->getOrgBd(); - int count = 0; for(citer cit2 = c1CbdBd.begin(); cit2 != c1CbdBd.end(); cit2++){ Cell* c1CbdBdCell = (*cit2).first; - int c1CbdBdCellO = (*cit2).second; - int coeff = getCoeff(c1CbdBdCell); - if( (coeff != 0 || c1CbdBdCell->inSubdomain() ) && !(*c1CbdBdCell == *c1) && !c1CbdBdCell->getImmune()){ - if(c1->getDim() == 1){ - count++; - c2 = c1CbdBdCell; c2c = coeff; c2o = c1CbdBdCellO; - b = c1CbdCell; break; - } - else if(c1->getDim() == 2){ - count++; - if(count == 1) { c2 = c1CbdBdCell; c2c = coeff; c2o = c1CbdBdCellO; } - else if(count == 2) { c3 = c1CbdBdCell; c3c = coeff; c3o = c1CbdBdCellO; b = c1CbdCell; break;} - } - } + int coeff = (*cit2).second; + if( (hasCell(c1CbdBdCell) && getCoeff(c1CbdBdCell) != 0) || c1CbdBdCell->inSubdomain()) cellsInChain.insert(std::make_pair(c1CbdBdCell, coeff)); + else cellsNotInChain.insert(std::make_pair(c1CbdBdCell, coeff)); } - if (b != NULL) break; + bool next = false; - } - - if(c1->getDim() == 1 && - b != NULL && c2 != NULL && !(*c2 == *c1)){ - - int temp1 = c1c - c1o; - - std::pair<Cell*, int> c4p = std::make_pair(b, 0); - c4p = findRemainingBoundary(b, c1, c2); - Cell* c4 = c4p.first; - int c4o = c4p.second; + for(citer cit2 = cellsInChain.begin(); cit2 != cellsInChain.end(); cit2++){ + Cell* c = (*cit2).first; + int coeff = getCoeff(c); + if(c->getImmune()) next = true; + if(bend && c->inSubdomain()) next = true; + if(coeff > 1 || coeff < -1) next = true; + } - if(c4o != 0 && !c2->getImmune() && !c4->getImmune() - && ( hasCell(c1) || c1->inSubdomain() ) && (hasCell(c2) || c2->inSubdomain() ) && !hasCell(c4) ){ - - int c4c = -c4o; - if(temp1 != 0) c4c= c4c*-1; - - this->removeCell(c1); - this->removeCell(c2); - c1->setImmune(false); - c2->setImmune(false); - c4->setImmune(false); - if(!c4->inSubdomain()) this->addCell(c4, c4c); - return true; + for(citer cit2 = cellsNotInChain.begin(); cit2 != cellsNotInChain.end(); cit2++){ + Cell* c = (*cit2).first; + if(c->inSubdomain()) next = true; } - } - - else if(c1->getDim() == 2 && - b != NULL && c2 != NULL && c3 != NULL && !(*c2 == *c1) && !(*c1 == *c3) && !(*c2 == *c3)){ - int temp1 = c1c - c1o; + if(next) continue; - std::pair<Cell*, int> c4p = std::make_pair(b, 0); - c4p = findRemainingBoundary(b, c1, c2, c3); - Cell* c4 = c4p.first; - int c4o = c4p.second; + //printf("dim: %d, in chain: %d, not in chain: %d \n", getDim(), cellsInChain.size(), cellsNotInChain.size()); - if(c4o != 0 && !c2->getImmune() && !c3->getImmune() && !c4->getImmune() - && (hasCell(c1) || c1->inSubdomain()) && (hasCell(c2) || c2->inSubdomain()) - && (hasCell(c3) || c3->inSubdomain()) && !hasCell(c4)) { - - int c4c = -c4o; - if(temp1 != 0) c4c= c4c*-1; - - this->removeCell(c1); - this->removeCell(c2); - this->removeCell(c3); - c1->setImmune(false); - c2->setImmune(false); - c3->setImmune(false); - c4->setImmune(false); - if(!c4->inSubdomain()) this->addCell(c4, c4c); + if( (getDim() == 1 && cellsInChain.size() == 2 && cellsNotInChain.size() == 1 && straighten) || + (getDim() == 2 && cellsInChain.size() == 3 && cellsNotInChain.size() == 1 && straighten)){ + //printf("straighten \n"); + deform(cellsInChain, cellsNotInChain); return true; } - - } - return false; -} - -bool Chain::bendChain( std::pair<Cell*, int> cell ){ - - Cell* c1 = cell.first; - int c1c = cell.second; - if(c1c == 0 || c1->getImmune()) return false; - int c1o = 0; - - Cell* c2 = NULL; - int c2c = 0; - int c2o = 0; - - Cell* c3 = NULL; - int c3c = 0; - int c3o = 0; - - Cell* b = NULL; - - std::map<Cell*, int, Less_Cell> c1Cbd = c1->getOrgCbd(); - for(citer cit = c1Cbd.begin(); cit != c1Cbd.end(); cit++){ - Cell* c1CbdCell = (*cit).first; - c1o = (*cit).second; - std::map<Cell*, int, Less_Cell> c1CbdBd = c1CbdCell->getOrgBd(); - - int count = 0; - for(citer cit2 = c1CbdBd.begin(); cit2 != c1CbdBd.end(); cit2++){ - Cell* c1CbdBdCell = (*cit2).first; - int c1CbdBdCellO = (*cit2).second; - if(!hasCell(c1CbdBdCell) && !c1CbdBdCell->getImmune() ){ - count++; - if(count == 1) { c2 = c1CbdBdCell; c2o = c1CbdBdCellO; } - else if(count == 2) { c3 = c1CbdBdCell; c3o = c1CbdBdCellO; b = c1CbdCell; break;} - } - } - - if (b != NULL) break; - else c2 = NULL; - } - - if(c1->getDim() == 2 && - b != NULL && c2 != NULL && c3 != NULL && !(*c2 == *c1) && !(*c1 == *c3) && !(*c2 == *c3) && - (c1c == 1 || c1c == -1) && !c2->getImmune() && !c3->getImmune() ){ - - std::pair<Cell*, int> c4p = std::make_pair(b, 0); - c4p = findRemainingBoundary(b, c1, c2, c3); - int c4c = getCoeff(c4p.first); - Cell* c4 = c4p.first; - - int temp1 = c1c - c1o; - - if(c4p.second != 0 && c4c != 0 && !c2->inSubdomain() && !c3->inSubdomain() - && hasCell(c1) && hasCell(c4) && !hasCell(c2) && !hasCell(c3)) { - - c2c = -c2o; - c3c = -c3o; - if(temp1 != 0) c2c= c2c*-1; - if(temp1 != 0) c3c= c3c*-1; - - this->removeCell(c1); - this->removeCell(c4); - this->addCell(c2, c2c); - this->addCell(c3, c3c); - c1->setImmune(false); - c2->setImmune(true); - c3->setImmune(false); - c4->setImmune(false); + else if ( (getDim() == 1 && cellsInChain.size() == 1 && cellsNotInChain.size() == 2 && bend) || + (getDim() == 2 && cellsInChain.size() == 2 && cellsNotInChain.size() == 2 && bend)){ + //printf("bend \n"); + deform(cellsInChain, cellsNotInChain); return true; } - - } - - else if(c1->getDim() == 1 && - b != NULL && c2 != NULL && c3 != NULL && !(*c2 == *c1) && !(*c1 == *c3) && !(*c2 == *c3) && - (c1c == 1 || c1c == -1) && !c2->getImmune() && !c3->getImmune() ){ - - int temp1 = c1c - c1o; - - if(!c2->inSubdomain() && !c3->inSubdomain() && hasCell(c1) && !hasCell(c2) && !hasCell(c3)) { - - //printf("c2: %d, c3; %d \n", getCoeff(c2), getCoeff(c3)); - - c2c = -c2o; - c3c = -c3o; - if(temp1 != 0) c2c= c2c*-1; - if(temp1 != 0) c3c= c3c*-1; - - this->removeCell(c1); - this->addCell(c2, c2c); - this->addCell(c3, c3c); - c1->setImmune(false); - c2->setImmune(true); - c3->setImmune(false); + else if ((getDim() == 1 && cellsInChain.size() == 3 && cellsNotInChain.size() == 0) || + (getDim() == 2 && cellsInChain.size() == 4 && cellsNotInChain.size() == 0)){ + //printf("remove boundary \n"); + deform(cellsInChain, cellsNotInChain); return true; } - } - return false; } void Chain::smoothenChain(){ + if(!_cellComplex->simplicial()) return; + int start = getSize(); double t1 = Cpu(); @@ -809,8 +588,8 @@ void Chain::smoothenChain(){ for(int i = 0; i < 20; i++){ int size = getSize(); for(citer cit = _cells.begin(); cit != _cells.end(); cit++){ - if(!straightenChain(*cit) && getDim() == 2) bendChain(*cit); - removeBoundary(*cit); + if(!deformChain(*cit, true, false) && getDim() == 2) deformChain(*cit, false, true); + deformChain(*cit, false, false); } deImmuneCells(); eraseNullCells(); @@ -819,9 +598,8 @@ void Chain::smoothenChain(){ if (useless > 5) break; } - for(citer cit = _cells.begin(); cit != _cells.end(); cit++){ - straightenChain(*cit); - } + deImmuneCells(); + for(citer cit = _cells.begin(); cit != _cells.end(); cit++) deformChain(*cit, true, false); eraseNullCells(); double t2 = Cpu(); @@ -877,15 +655,15 @@ void Chain::createPView(){ Cell* cell = (*cit).first; int coeff = (*cit).second; std::vector<MVertex*> v = cell->getVertexVector(); - if(cell->getDim() > 0 && coeff == -1){ // flip orientation + if(cell->getDim() > 0 && coeff < 0){ // flip orientation MVertex* temp = v[0]; v[0] = v[1]; v[1] = temp; } MElement *e = factory.create(cell->getTypeForMSH(), v, cell->getNum(), cell->getPartition()); - elements.push_back(e); + for(int i = 0; i < abs(coeff); i++) elements.push_back(e); - std::vector<double> coeffs (1,1); + std::vector<double> coeffs (1,abs(coeff)); data[e->getNum()] = coeffs; } diff --git a/Geo/ChainComplex.h b/Geo/ChainComplex.h index 3481a4f19e..1b34844e57 100644 --- a/Geo/ChainComplex.h +++ b/Geo/ChainComplex.h @@ -150,13 +150,10 @@ class Chain{ int _dim; - std::pair<Cell*, int> findRemainingBoundary(Cell* b, Cell* c1, Cell* c2, Cell* c3=NULL); - Cell* findCommonCbdCell(Cell* c1, Cell* c2, Cell* c3=NULL); - int findOrientation(Cell* b, Cell* c); - bool straightenChain( std::pair<Cell*, int> cell); - bool bendChain( std::pair<Cell*, int> cell); - bool removeBoundary( std::pair<Cell*, int> cell); - std::map<Cell*, int, Less_Cell> getBdCellsInChain(Cell* cell); + + bool deform(std::map<Cell*, int, Less_Cell> &cellsInChain, std::map<Cell*, int, Less_Cell> &cellsNotInChain); + bool deformChain(std::pair<Cell*, int> cell, bool straighten, bool bend); + public: Chain(){} -- GitLab