Version: 6.3.1

src/SMDS/SMDS_Downward.cxx

Go to the documentation of this file.
00001 // Copyright (C) 2010-2011  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 // File: SMDS_Downward.cxx
00021 // Created: Jun 3, 2010
00022 // Author: prascle
00023 
00024 #include "SMDS_Downward.hxx"
00025 #include "SMDS_Mesh.hxx"
00026 #include "utilities.h"
00027 
00028 #include <vtkCellType.h>
00029 #include <vtkCellLinks.h>
00030 
00031 #include <map>
00032 
00033 using namespace std;
00034 
00035 // ---------------------------------------------------------------------------
00036 
00037 vector<int> SMDS_Downward::_cellDimension;
00038 
00044 int SMDS_Downward::getCellDimension(unsigned char cellType)
00045 {
00046   if (_cellDimension.empty())
00047     {
00048       _cellDimension.resize(VTK_MAXTYPE + 1, 0);
00049       _cellDimension[VTK_LINE] = 1;
00050       _cellDimension[VTK_QUADRATIC_EDGE] = 1;
00051       _cellDimension[VTK_TRIANGLE] = 2;
00052       _cellDimension[VTK_QUADRATIC_TRIANGLE] = 2;
00053       _cellDimension[VTK_QUAD] = 2;
00054       _cellDimension[VTK_QUADRATIC_QUAD] = 2;
00055       _cellDimension[VTK_TETRA] = 3;
00056       _cellDimension[VTK_QUADRATIC_TETRA] = 3;
00057       _cellDimension[VTK_HEXAHEDRON] = 3;
00058       _cellDimension[VTK_QUADRATIC_HEXAHEDRON] = 3;
00059       _cellDimension[VTK_WEDGE] = 3;
00060       _cellDimension[VTK_QUADRATIC_WEDGE] = 3;
00061       _cellDimension[VTK_PYRAMID] = 3;
00062       _cellDimension[VTK_QUADRATIC_PYRAMID] = 3;
00063     }
00064   return _cellDimension[cellType];
00065 }
00066 
00067 // ---------------------------------------------------------------------------
00068 
00075 SMDS_Downward::SMDS_Downward(SMDS_UnstructuredGrid *grid, int nbDownCells) :
00076   _grid(grid), _nbDownCells(nbDownCells)
00077 {
00078   this->_maxId = 0;
00079   this->_cellIds.clear();
00080   this->_cellTypes.clear();
00081   if (_cellDimension.empty())
00082     {
00083       _cellDimension.resize(VTK_MAXTYPE + 1, 0);
00084       _cellDimension[VTK_LINE] = 1;
00085       _cellDimension[VTK_QUADRATIC_EDGE] = 1;
00086       _cellDimension[VTK_TRIANGLE] = 2;
00087       _cellDimension[VTK_QUADRATIC_TRIANGLE] = 2;
00088       _cellDimension[VTK_QUAD] = 2;
00089       _cellDimension[VTK_QUADRATIC_QUAD] = 2;
00090       _cellDimension[VTK_TETRA] = 3;
00091       _cellDimension[VTK_QUADRATIC_TETRA] = 3;
00092       _cellDimension[VTK_HEXAHEDRON] = 3;
00093       _cellDimension[VTK_QUADRATIC_HEXAHEDRON] = 3;
00094       _cellDimension[VTK_WEDGE] = 3;
00095       _cellDimension[VTK_QUADRATIC_WEDGE] = 3;
00096       _cellDimension[VTK_PYRAMID] = 3;
00097       _cellDimension[VTK_QUADRATIC_PYRAMID] = 3;
00098     }
00099 }
00100 
00101 SMDS_Downward::~SMDS_Downward()
00102 {
00103 }
00104 
00112 int SMDS_Downward::addCell(int vtkId)
00113 {
00114   int localId = -1;
00115   if (vtkId >= 0)
00116     localId = _grid->CellIdToDownId(vtkId);
00117   if (localId >= 0)
00118     return localId;
00119 
00120   localId = this->_maxId;
00121   this->_maxId++;
00122   this->allocate(_maxId);
00123   if (vtkId >= 0)
00124     {
00125       this->_vtkCellIds[localId] = vtkId;
00126       _grid->setCellIdToDownId(vtkId, localId);
00127     }
00128   this->initCell(localId);
00129   return localId;
00130 }
00131 
00136 void SMDS_Downward::initCell(int cellId)
00137 {
00138 }
00139 
00145 int SMDS_Downward::getNumberOfDownCells(int cellId)
00146 {
00147   return _nbDownCells;
00148 }
00149 
00156 const int* SMDS_Downward::getDownCells(int cellId)
00157 {
00158   //ASSERT((cellId >=0) && (cellId < _maxId));
00159   return &_cellIds[_nbDownCells * cellId];
00160 }
00161 
00168 const unsigned char* SMDS_Downward::getDownTypes(int cellId)
00169 {
00170   return &_cellTypes[0];
00171 }
00172 
00179 void SMDS_Downward::addDownCell(int cellId, int lowCellId, unsigned char aType)
00180 {
00181   ASSERT(0); // must be re-implemented in derived class
00182 }
00183 
00190 void SMDS_Downward::addUpCell(int cellId, int upCellId, unsigned char aType)
00191 {
00192   ASSERT(0); // must be re-implemented in derived class
00193 }
00194 
00195 int SMDS_Downward::getNodeSet(int cellId, int* nodeSet)
00196 {
00197   return 0;
00198 }
00199 
00200 // ---------------------------------------------------------------------------
00201 
00202 SMDS_Down1D::SMDS_Down1D(SMDS_UnstructuredGrid *grid, int nbDownCells) :
00203   SMDS_Downward(grid, nbDownCells)
00204 {
00205   _upCellIdsVector.clear();
00206   _upCellTypesVector.clear();
00207   _upCellIds.clear();
00208   _upCellTypes.clear();
00209   _upCellIndex.clear();
00210 }
00211 
00212 SMDS_Down1D::~SMDS_Down1D()
00213 {
00214 }
00215 
00220 void SMDS_Down1D::initCell(int cellId)
00221 {
00222   _upCellIdsVector[cellId].clear();
00223   _upCellTypesVector[cellId].clear();
00224 }
00225 
00230 void SMDS_Down1D::allocate(int nbElems)
00231 {
00232   if (nbElems >= _vtkCellIds.size())
00233     {
00234       _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1);
00235       _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1);
00236       _upCellIdsVector.resize(nbElems + SMDS_Mesh::chunkSize);
00237       _upCellTypesVector.resize(nbElems + SMDS_Mesh::chunkSize);
00238     }
00239 }
00240 
00241 void SMDS_Down1D::compactStorage()
00242 {
00243   _cellIds.resize(_nbDownCells * _maxId);
00244   _vtkCellIds.resize(_maxId);
00245 
00246   int sizeUpCells = 0;
00247   for (int i = 0; i < _maxId; i++)
00248     sizeUpCells += _upCellIdsVector[i].size();
00249   _upCellIds.resize(sizeUpCells, -1);
00250   _upCellTypes.resize(sizeUpCells);
00251   _upCellIndex.resize(_maxId + 1, -1); // id and types of rank i correspond to [ _upCellIndex[i], _upCellIndex[i+1] [
00252   int current = 0;
00253   for (int i = 0; i < _maxId; i++)
00254     {
00255       _upCellIndex[i] = current;
00256       for (int j = 0; j < _upCellIdsVector[i].size(); j++)
00257         {
00258           _upCellIds[current] = _upCellIdsVector[i][j];
00259           _upCellTypes[current] = _upCellTypesVector[i][j];
00260           current++;
00261         }
00262     }
00263   _upCellIndex[_maxId] = current;
00264 
00265   _upCellIdsVector.clear();
00266   _upCellTypesVector.clear();
00267 }
00268 
00269 void SMDS_Down1D::addUpCell(int cellId, int upCellId, unsigned char aType)
00270 {
00271   //ASSERT((cellId >=0) && (cellId < _maxId));
00272   int nbFaces = _upCellIdsVector[cellId].size();
00273   for (int i = 0; i < nbFaces; i++)
00274     {
00275       if ((_upCellIdsVector[cellId][i] == upCellId) && (_upCellTypesVector[cellId][i] == aType))
00276         {
00277           return; // already done
00278         }
00279     }
00280   _upCellIdsVector[cellId].push_back(upCellId);
00281   _upCellTypesVector[cellId].push_back(aType);
00282 }
00283 
00284 int SMDS_Down1D::getNumberOfUpCells(int cellId)
00285 {
00286   //ASSERT((cellId >=0) && (cellId < _maxId));
00287   return _upCellIndex[cellId + 1] - _upCellIndex[cellId];
00288 }
00289 
00290 const int* SMDS_Down1D::getUpCells(int cellId)
00291 {
00292   //ASSERT((cellId >=0) && (cellId < _maxId));
00293   return &_upCellIds[_upCellIndex[cellId]];
00294 }
00295 
00296 const unsigned char* SMDS_Down1D::getUpTypes(int cellId)
00297 {
00298   //ASSERT((cellId >=0) && (cellId < _maxId));
00299   return &_upCellTypes[_upCellIndex[cellId]];
00300 }
00301 
00302 void SMDS_Down1D::getNodeIds(int cellId, std::set<int>& nodeSet)
00303 {
00304   for (int i = 0; i < _nbDownCells; i++)
00305     nodeSet.insert(_cellIds[_nbDownCells * cellId + i]);
00306 }
00307 
00308 int SMDS_Down1D::getNodeSet(int cellId, int* nodeSet)
00309 {
00310   for (int i = 0; i < _nbDownCells; i++)
00311     nodeSet[i] = _cellIds[_nbDownCells * cellId + i];
00312   return _nbDownCells;
00313 }
00314 
00315 void SMDS_Down1D::setNodes(int cellId, int vtkId)
00316 {
00317   vtkIdType npts = 0;
00318   vtkIdType *pts; // will refer to the point id's of the face
00319   _grid->GetCellPoints(vtkId, npts, pts);
00320   // MESSAGE(vtkId << " " << npts << "  " << _nbDownCells);
00321   //ASSERT(npts == _nbDownCells);
00322   for (int i = 0; i < npts; i++)
00323     {
00324       _cellIds[_nbDownCells * cellId + i] = pts[i];
00325     }
00326 }
00327 
00328 void SMDS_Down1D::setNodes(int cellId, const int* nodeIds)
00329 {
00330   //ASSERT(nodeIds.size() == _nbDownCells);
00331   for (int i = 0; i < _nbDownCells; i++)
00332     {
00333       _cellIds[_nbDownCells * cellId + i] = nodeIds[i];
00334     }
00335 }
00336 
00343 int SMDS_Down1D::computeVtkCells(int cellId, std::vector<int>& vtkIds)
00344 {
00345   vtkIds.clear();
00346 
00347   // --- find all the cells the points belong to, and how many of the points belong to a given cell
00348 
00349   int *pts = &_cellIds[_nbDownCells * cellId];
00350   int ncells = this->computeVtkCells(pts, vtkIds);
00351   return ncells;
00352 }
00353 
00360 int SMDS_Down1D::computeVtkCells(int *pts, std::vector<int>& vtkIds)
00361 {
00362 
00363   // --- find all the cells the points belong to, and how many of the points belong to a given cell
00364 
00365   int cellIds[1000];
00366   int cellCnt[1000];
00367   int cnt = 0;
00368   for (int i = 0; i < _nbDownCells; i++)
00369     {
00370       vtkIdType point = pts[i];
00371       int numCells = _grid->GetLinks()->GetNcells(point);
00372       vtkIdType *cells = _grid->GetLinks()->GetCells(point);
00373       for (int j = 0; j < numCells; j++)
00374         {
00375           int vtkCellId = cells[j];
00376           bool found = false;
00377           for (int k = 0; k < cnt; k++)
00378             {
00379               if (cellIds[k] == vtkCellId)
00380                 {
00381                   cellCnt[k] += 1;
00382                   found = true;
00383                   break;
00384                 }
00385             }
00386           if (!found)
00387             {
00388               cellIds[cnt] = vtkCellId;
00389               cellCnt[cnt] = 1;
00390               // TODO ASSERT(cnt<1000);
00391               cnt++;
00392             }
00393         }
00394     }
00395 
00396   // --- find the face and volume cells: they contains all the points and are of type volume or face
00397 
00398   int ncells = 0;
00399   for (int i = 0; i < cnt; i++)
00400     {
00401       if (cellCnt[i] == _nbDownCells)
00402         {
00403           int vtkElemId = cellIds[i];
00404           int vtkType = _grid->GetCellType(vtkElemId);
00405           if (SMDS_Downward::getCellDimension(vtkType) > 1)
00406             {
00407               vtkIds.push_back(vtkElemId);
00408               ncells++;
00409             }
00410         }
00411     }
00412 
00413   return ncells;
00414 }
00415 
00424 int SMDS_Down1D::computeFaces(int cellId, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes)
00425 {
00426   int *pts = &_cellIds[_nbDownCells * cellId];
00427   int nbFaces = this->computeFaces(pts, vtkIds, nbcells, downFaces, downTypes);
00428   return nbFaces;
00429 }
00430 
00439 int SMDS_Down1D::computeFaces(int* pts, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes)
00440 {
00441   int cnt = 0;
00442   for (int i = 0; i < nbcells; i++)
00443     {
00444       int vtkId = vtkIds[i];
00445       int vtkType = _grid->GetCellType(vtkId);
00446       if (SMDS_Downward::getCellDimension(vtkType) == 2)
00447         {
00448           int faceId = _grid->CellIdToDownId(vtkId);
00449           downFaces[cnt] = faceId;
00450           downTypes[cnt] = vtkType;
00451           cnt++;
00452         }
00453       else if (SMDS_Downward::getCellDimension(vtkType) == 3)
00454         {
00455           int volId = _grid->CellIdToDownId(vtkId);
00456           SMDS_Downward * downvol = _grid->getDownArray(vtkType);
00457           //const int *downIds = downvol->getDownCells(volId);
00458           const unsigned char* downTypesVol = downvol->getDownTypes(volId);
00459           int nbFaces = downvol->getNumberOfDownCells(volId);
00460           const int* faceIds = downvol->getDownCells(volId);
00461           for (int n = 0; n < nbFaces; n++)
00462             {
00463               SMDS_Down2D *downFace = static_cast<SMDS_Down2D*> (_grid->getDownArray(downTypesVol[n]));
00464               bool isInFace = downFace->isInFace(faceIds[n], pts, _nbDownCells);
00465               if (isInFace)
00466                 {
00467                   bool alreadySet = false;
00468                   for (int k = 0; k < cnt; k++)
00469                     if (faceIds[n] == downFaces[k])
00470                       {
00471                         alreadySet = true;
00472                         break;
00473                       }
00474                   if (!alreadySet)
00475                     {
00476                       downFaces[cnt] = faceIds[n];
00477                       downTypes[cnt] = downTypesVol[n];
00478                       cnt++;
00479                     }
00480                 }
00481             }
00482         }
00483     }
00484   return cnt;
00485 }
00486 
00487 // ---------------------------------------------------------------------------
00488 
00489 SMDS_Down2D::SMDS_Down2D(SMDS_UnstructuredGrid *grid, int nbDownCells) :
00490   SMDS_Downward(grid, nbDownCells)
00491 {
00492   _upCellIds.clear();
00493   _upCellTypes.clear();
00494   _tempNodes.clear();
00495   _nbNodes = 0;
00496 }
00497 
00498 SMDS_Down2D::~SMDS_Down2D()
00499 {
00500 }
00501 
00502 int SMDS_Down2D::getNumberOfUpCells(int cellId)
00503 {
00504   int nbup = 0;
00505   if (_upCellIds[2 * cellId] >= 0)
00506     nbup++;
00507   if (_upCellIds[2 * cellId + 1] >= 0)
00508     nbup++;
00509   return nbup;
00510 }
00511 
00512 const int* SMDS_Down2D::getUpCells(int cellId)
00513 {
00514   //ASSERT((cellId >=0) && (cellId < _maxId));
00515   return &_upCellIds[2 * cellId];
00516 }
00517 
00518 const unsigned char* SMDS_Down2D::getUpTypes(int cellId)
00519 {
00520   //ASSERT((cellId >=0) && (cellId < _maxId));
00521   return &_upCellTypes[2 * cellId];
00522 }
00523 
00524 void SMDS_Down2D::getNodeIds(int cellId, std::set<int>& nodeSet)
00525 {
00526   for (int i = 0; i < _nbDownCells; i++)
00527     {
00528       int downCellId = _cellIds[_nbDownCells * cellId + i];
00529       unsigned char cellType = _cellTypes[i];
00530       this->_grid->getDownArray(cellType)->getNodeIds(downCellId, nodeSet);
00531     }
00532 }
00533 
00542 int SMDS_Down2D::computeVolumeIds(int cellId, int* ids)
00543 {
00544   // --- find point id's of the face
00545 
00546   vtkIdType npts = 0;
00547   vtkIdType *pts; // will refer to the point id's of the face
00548   _grid->GetCellPoints(cellId, npts, pts);
00549   vector<int> nodes;
00550   for (int i = 0; i < npts; i++)
00551     nodes.push_back(pts[i]);
00552   int nvol = this->computeVolumeIdsFromNodesFace(&nodes[0], npts, ids);
00553   return nvol;
00554 }
00555 
00564 int SMDS_Down2D::computeVolumeIds(ElemByNodesType& faceByNodes, int* ids)
00565 {
00566   int nvol = this->computeVolumeIdsFromNodesFace(&faceByNodes.nodeIds[0], faceByNodes.nbNodes, ids);
00567   return nvol;
00568 }
00569 
00579 int SMDS_Down2D::computeVolumeIdsFromNodesFace(int* pts, int npts, int* ids)
00580 {
00581 
00582   // --- find all the cells the points belong to, and how many of the points belong to a given cell
00583 
00584   int cellIds[1000];
00585   int cellCnt[1000];
00586   int cnt = 0;
00587   for (int i = 0; i < npts; i++)
00588     {
00589       vtkIdType point = pts[i];
00590       int numCells = _grid->GetLinks()->GetNcells(point);
00591       //MESSAGE("cells pour " << i << " " << numCells);
00592       vtkIdType *cells = _grid->GetLinks()->GetCells(point);
00593       for (int j = 0; j < numCells; j++)
00594         {
00595           int vtkCellId = cells[j];
00596           bool found = false;
00597           for (int k = 0; k < cnt; k++)
00598             {
00599               if (cellIds[k] == vtkCellId)
00600                 {
00601                   cellCnt[k] += 1;
00602                   found = true;
00603                   break;
00604                 }
00605             }
00606           if (!found)
00607             {
00608               cellIds[cnt] = vtkCellId;
00609               cellCnt[cnt] = 1;
00610               // TODO ASSERT(cnt<1000);
00611               cnt++;
00612             }
00613         }
00614     }
00615 
00616   // --- find the volume cells: they contains all the points and are of type volume
00617 
00618   int nvol = 0;
00619   for (int i = 0; i < cnt; i++)
00620     {
00621       //MESSAGE("cell " << cellIds[i] << " points " << cellCnt[i]);
00622       if (cellCnt[i] == npts)
00623         {
00624           int vtkElemId = cellIds[i];
00625           int vtkType = _grid->GetCellType(vtkElemId);
00626           if (SMDS_Downward::getCellDimension(vtkType) == 3)
00627             {
00628               ids[nvol] = vtkElemId; // store the volume id in given vector
00629               nvol++;
00630             }
00631         }
00632       if (nvol == 2)
00633         break;
00634     }
00635 
00636   return nvol;
00637 }
00638 
00639 void SMDS_Down2D::setTempNodes(int cellId, int vtkId)
00640 {
00641   vtkIdType npts = 0;
00642   vtkIdType *pts; // will refer to the point id's of the face
00643   _grid->GetCellPoints(vtkId, npts, pts);
00644   // MESSAGE(vtkId << " " << npts << "  " << _nbNodes);
00645   //ASSERT(npts == _nbNodes);
00646   for (int i = 0; i < npts; i++)
00647     {
00648       _tempNodes[_nbNodes * cellId + i] = pts[i];
00649     }
00650 }
00651 
00652 void SMDS_Down2D::setTempNodes(int cellId, ElemByNodesType& faceByNodes)
00653 {
00654   for (int i = 0; i < faceByNodes.nbNodes; i++)
00655     _tempNodes[_nbNodes * cellId + i] = faceByNodes.nodeIds[i];
00656 }
00657 
00664 bool SMDS_Down2D::isInFace(int cellId, int *pts, int npts)
00665 {
00666   int nbFound = 0;
00667   int *nodes = &_tempNodes[_nbNodes * cellId];
00668   for (int j = 0; j < npts; j++)
00669     {
00670       int point = pts[j];
00671       for (int i = 0; i < _nbNodes; i++)
00672         {
00673           if (nodes[i] == point)
00674             {
00675               nbFound++;
00676               break;
00677             }
00678         }
00679     }
00680   return (nbFound == npts);
00681 }
00682 
00687 void SMDS_Down2D::allocate(int nbElems)
00688 {
00689   if (nbElems >= _vtkCellIds.size())
00690     {
00691       _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1);
00692       _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1);
00693       _upCellIds.resize(2 * (nbElems + SMDS_Mesh::chunkSize), -1);
00694       _upCellTypes.resize(2 * (nbElems + SMDS_Mesh::chunkSize), -1);
00695       _tempNodes.resize(_nbNodes * (nbElems + SMDS_Mesh::chunkSize), -1);
00696     }
00697 }
00698 
00699 void SMDS_Down2D::compactStorage()
00700 {
00701   _cellIds.resize(_nbDownCells * _maxId);
00702   _upCellIds.resize(2 * _maxId);
00703   _upCellTypes.resize(2 * _maxId);
00704   _vtkCellIds.resize(_maxId);
00705   _tempNodes.clear();
00706 }
00707 
00708 void SMDS_Down2D::addUpCell(int cellId, int upCellId, unsigned char aType)
00709 {
00710   //ASSERT((cellId >=0)&& (cellId < _maxId));
00711   int *vols = &_upCellIds[2 * cellId];
00712   unsigned char *types = &_upCellTypes[2 * cellId];
00713   for (int i = 0; i < 2; i++)
00714     {
00715       if (vols[i] < 0)
00716         {
00717           vols[i] = upCellId; // use non affected volume
00718           types[i] = aType;
00719           return;
00720         }
00721       if ((vols[i] == upCellId) && (types[i] == aType)) // already done
00722         return;
00723     }
00724   ASSERT(0);
00725 }
00726 
00727 int SMDS_Down2D::getNodeSet(int cellId, int* nodeSet)
00728 {
00729   for (int i = 0; i < _nbNodes; i++)
00730     nodeSet[i] = _tempNodes[_nbNodes * cellId + i];
00731   return _nbNodes;
00732 }
00733 
00734 int SMDS_Down2D::FindEdgeByNodes(int cellId, ElemByNodesType& edgeByNodes)
00735 {
00736   int *edges = &_cellIds[_nbDownCells * cellId];
00737   for (int i = 0; i < _nbDownCells; i++)
00738     {
00739       if ((edges[i] >= 0) && (edgeByNodes.vtkType == _cellTypes[i]))
00740         {
00741           int nodeSet[3];
00742           int npts = this->_grid->getDownArray(edgeByNodes.vtkType)->getNodeSet(edges[i], nodeSet);
00743           bool found = false;
00744           for (int j = 0; j < npts; j++)
00745             {
00746               int point = edgeByNodes.nodeIds[j];
00747               found = false;
00748               for (int k = 0; k < npts; k++)
00749                 {
00750                   if (nodeSet[k] == point)
00751                     {
00752                       found = true;
00753                       break;
00754                     }
00755                 }
00756               if (!found)
00757                 break;
00758             }
00759           if (found)
00760             return edges[i];
00761         }
00762     }
00763   return -1;
00764 }
00765 
00766 // ---------------------------------------------------------------------------
00767 
00768 SMDS_Down3D::SMDS_Down3D(SMDS_UnstructuredGrid *grid, int nbDownCells) :
00769   SMDS_Downward(grid, nbDownCells)
00770 {
00771 }
00772 
00773 SMDS_Down3D::~SMDS_Down3D()
00774 {
00775 }
00776 
00777 void SMDS_Down3D::allocate(int nbElems)
00778 {
00779   if (nbElems >= _vtkCellIds.size())
00780     {
00781       _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1);
00782       _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1);
00783     }
00784 }
00785 
00786 void SMDS_Down3D::compactStorage()
00787 {
00788   // nothing to do, size was known before
00789 }
00790 
00791 int SMDS_Down3D::getNumberOfUpCells(int cellId)
00792 {
00793   return 0;
00794 }
00795 
00796 const int* SMDS_Down3D::getUpCells(int cellId)
00797 {
00798   return 0;
00799 }
00800 
00801 const unsigned char* SMDS_Down3D::getUpTypes(int cellId)
00802 {
00803   return 0;
00804 }
00805 
00806 void SMDS_Down3D::getNodeIds(int cellId, std::set<int>& nodeSet)
00807 {
00808   int vtkId = this->_vtkCellIds[cellId];
00809   vtkIdType npts = 0;
00810   vtkIdType *nodes; // will refer to the point id's of the volume
00811   _grid->GetCellPoints(vtkId, npts, nodes);
00812   for (int i = 0; i < npts; i++)
00813     nodeSet.insert(nodes[i]);
00814 }
00815 
00816 int SMDS_Down3D::FindFaceByNodes(int cellId, ElemByNodesType& faceByNodes)
00817 {
00818   int *faces = &_cellIds[_nbDownCells * cellId];
00819   int npoints = 0;
00820 
00821   for (int i = 0; i < _nbDownCells; i++)
00822     {
00823       if ((faces[i] >= 0) && (faceByNodes.vtkType == _cellTypes[i]))
00824         {
00825           if (npoints == 0)
00826             npoints = faceByNodes.nbNodes;
00827 
00828           int nodeSet[10];
00829           int npts = this->_grid->getDownArray(faceByNodes.vtkType)->getNodeSet(faces[i], nodeSet);
00830           if (npts != npoints)
00831             continue; // skip this face
00832           bool found = false;
00833           for (int j = 0; j < npts; j++)
00834             {
00835               int point = faceByNodes.nodeIds[j];
00836               found = false;
00837               for (int k = 0; k < npts; k++)
00838                 {
00839                   if (nodeSet[k] == point)
00840                     {
00841                       found = true;
00842                       break; // point j is in the 2 faces, skip remaining k values
00843                     }
00844                 }
00845               if (!found)
00846                 break; // point j is not in the 2 faces, skip the remaining tests
00847             }
00848           if (found)
00849             return faces[i];
00850         }
00851     }
00852   return -1;
00853 }
00854 
00855 // ---------------------------------------------------------------------------
00856 
00857 SMDS_DownEdge::SMDS_DownEdge(SMDS_UnstructuredGrid *grid) :
00858   SMDS_Down1D(grid, 2)
00859 {
00860   _cellTypes.push_back(VTK_VERTEX);
00861   _cellTypes.push_back(VTK_VERTEX);
00862 }
00863 
00864 SMDS_DownEdge::~SMDS_DownEdge()
00865 {
00866 }
00867 
00868 // ---------------------------------------------------------------------------
00869 
00870 SMDS_DownQuadEdge::SMDS_DownQuadEdge(SMDS_UnstructuredGrid *grid) :
00871   SMDS_Down1D(grid, 3)
00872 {
00873   _cellTypes.push_back(VTK_VERTEX);
00874   _cellTypes.push_back(VTK_VERTEX);
00875   _cellTypes.push_back(VTK_VERTEX);
00876 }
00877 
00878 SMDS_DownQuadEdge::~SMDS_DownQuadEdge()
00879 {
00880 }
00881 
00882 // ---------------------------------------------------------------------------
00883 
00884 SMDS_DownTriangle::SMDS_DownTriangle(SMDS_UnstructuredGrid *grid) :
00885   SMDS_Down2D(grid, 3)
00886 {
00887   _cellTypes.push_back(VTK_LINE);
00888   _cellTypes.push_back(VTK_LINE);
00889   _cellTypes.push_back(VTK_LINE);
00890   _nbNodes = 3;
00891 }
00892 
00893 SMDS_DownTriangle::~SMDS_DownTriangle()
00894 {
00895 }
00896 
00897 void SMDS_DownTriangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
00898 {
00899   int *nodes = &_tempNodes[_nbNodes * cellId];
00900   edgesWithNodes.nbElems = 3;
00901 
00902   edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
00903   edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
00904   edgesWithNodes.elems[0].nbNodes = 2;
00905   edgesWithNodes.elems[0].vtkType = VTK_LINE;
00906 
00907   edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
00908   edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
00909   edgesWithNodes.elems[1].nbNodes = 2;
00910   edgesWithNodes.elems[1].vtkType = VTK_LINE;
00911 
00912   edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
00913   edgesWithNodes.elems[2].nodeIds[1] = nodes[0];
00914   edgesWithNodes.elems[2].nbNodes = 2;
00915   edgesWithNodes.elems[2].vtkType = VTK_LINE;
00916 }
00917 
00918 void SMDS_DownTriangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
00919 {
00920   //ASSERT((cellId >=0)&& (cellId < _maxId));
00921   //ASSERT(aType == VTK_LINE);
00922   int *faces = &_cellIds[_nbDownCells * cellId];
00923   for (int i = 0; i < _nbDownCells; i++)
00924     {
00925       if (faces[i] < 0)
00926         {
00927           faces[i] = lowCellId;
00928           return;
00929         }
00930       if (faces[i] == lowCellId)
00931         return;
00932     }
00933   ASSERT(0);
00934 }
00935 
00936 // ---------------------------------------------------------------------------
00937 
00938 SMDS_DownQuadTriangle::SMDS_DownQuadTriangle(SMDS_UnstructuredGrid *grid) :
00939   SMDS_Down2D(grid, 3)
00940 {
00941   _cellTypes.push_back(VTK_QUADRATIC_EDGE);
00942   _cellTypes.push_back(VTK_QUADRATIC_EDGE);
00943   _cellTypes.push_back(VTK_QUADRATIC_EDGE);
00944   _nbNodes = 6;
00945 }
00946 
00947 SMDS_DownQuadTriangle::~SMDS_DownQuadTriangle()
00948 {
00949 }
00950 
00951 void SMDS_DownQuadTriangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
00952 {
00953   int *nodes = &_tempNodes[_nbNodes * cellId];
00954   edgesWithNodes.nbElems = 3;
00955 
00956   edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
00957   edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
00958   edgesWithNodes.elems[0].nodeIds[2] = nodes[3];
00959   edgesWithNodes.elems[0].nbNodes = 3;
00960   edgesWithNodes.elems[0].vtkType = VTK_QUADRATIC_EDGE;
00961 
00962   edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
00963   edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
00964   edgesWithNodes.elems[1].nodeIds[2] = nodes[4];
00965   edgesWithNodes.elems[1].nbNodes = 3;
00966   edgesWithNodes.elems[1].vtkType = VTK_QUADRATIC_EDGE;
00967 
00968   edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
00969   edgesWithNodes.elems[2].nodeIds[1] = nodes[0];
00970   edgesWithNodes.elems[2].nodeIds[2] = nodes[5];
00971   edgesWithNodes.elems[2].nbNodes = 3;
00972   edgesWithNodes.elems[2].vtkType = VTK_QUADRATIC_EDGE;
00973 }
00974 
00975 void SMDS_DownQuadTriangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
00976 {
00977   //ASSERT((cellId >=0)&& (cellId < _maxId));
00978   //ASSERT(aType == VTK_QUADRATIC_EDGE);
00979   int *edges = &_cellIds[_nbDownCells * cellId];
00980   for (int i = 0; i < _nbDownCells; i++)
00981     {
00982       if (edges[i] < 0)
00983         {
00984           edges[i] = lowCellId;
00985           return;
00986         }
00987       if (edges[i] == lowCellId)
00988         return;
00989     }
00990   ASSERT(0);
00991 }
00992 
00993 // ---------------------------------------------------------------------------
00994 
00995 SMDS_DownQuadrangle::SMDS_DownQuadrangle(SMDS_UnstructuredGrid *grid) :
00996   SMDS_Down2D(grid, 4)
00997 {
00998   _cellTypes.push_back(VTK_LINE);
00999   _cellTypes.push_back(VTK_LINE);
01000   _cellTypes.push_back(VTK_LINE);
01001   _cellTypes.push_back(VTK_LINE);
01002   _nbNodes = 4;
01003 }
01004 
01005 SMDS_DownQuadrangle::~SMDS_DownQuadrangle()
01006 {
01007 }
01008 
01009 void SMDS_DownQuadrangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
01010 {
01011   int *nodes = &_tempNodes[_nbNodes * cellId];
01012   edgesWithNodes.nbElems = 4;
01013 
01014   edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
01015   edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
01016   edgesWithNodes.elems[0].nbNodes = 2;
01017   edgesWithNodes.elems[0].vtkType = VTK_LINE;
01018 
01019   edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
01020   edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
01021   edgesWithNodes.elems[1].nbNodes = 2;
01022   edgesWithNodes.elems[1].vtkType = VTK_LINE;
01023 
01024   edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
01025   edgesWithNodes.elems[2].nodeIds[1] = nodes[3];
01026   edgesWithNodes.elems[2].nbNodes = 2;
01027   edgesWithNodes.elems[2].vtkType = VTK_LINE;
01028 
01029   edgesWithNodes.elems[3].nodeIds[0] = nodes[3];
01030   edgesWithNodes.elems[3].nodeIds[1] = nodes[0];
01031   edgesWithNodes.elems[3].nbNodes = 2;
01032   edgesWithNodes.elems[3].vtkType = VTK_LINE;
01033 }
01034 
01035 void SMDS_DownQuadrangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
01036 {
01037   //ASSERT((cellId >=0)&& (cellId < _maxId));
01038   //ASSERT(aType == VTK_LINE);
01039   int *faces = &_cellIds[_nbDownCells * cellId];
01040   for (int i = 0; i < _nbDownCells; i++)
01041     {
01042       if (faces[i] < 0)
01043         {
01044           faces[i] = lowCellId;
01045           return;
01046         }
01047       if (faces[i] == lowCellId)
01048         return;
01049     }
01050   ASSERT(0);
01051 }
01052 
01053 // ---------------------------------------------------------------------------
01054 
01055 SMDS_DownQuadQuadrangle::SMDS_DownQuadQuadrangle(SMDS_UnstructuredGrid *grid) :
01056   SMDS_Down2D(grid, 4)
01057 {
01058   _cellTypes.push_back(VTK_QUADRATIC_EDGE);
01059   _cellTypes.push_back(VTK_QUADRATIC_EDGE);
01060   _cellTypes.push_back(VTK_QUADRATIC_EDGE);
01061   _cellTypes.push_back(VTK_QUADRATIC_EDGE);
01062   _nbNodes = 8;
01063 }
01064 
01065 SMDS_DownQuadQuadrangle::~SMDS_DownQuadQuadrangle()
01066 {
01067 }
01068 
01069 void SMDS_DownQuadQuadrangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
01070 {
01071   int *nodes = &_tempNodes[_nbNodes * cellId];
01072   edgesWithNodes.nbElems = 4;
01073 
01074   edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
01075   edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
01076   edgesWithNodes.elems[0].nodeIds[2] = nodes[4];
01077   edgesWithNodes.elems[0].nbNodes = 3;
01078   edgesWithNodes.elems[0].vtkType = VTK_QUADRATIC_EDGE;
01079 
01080   edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
01081   edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
01082   edgesWithNodes.elems[1].nodeIds[2] = nodes[5];
01083   edgesWithNodes.elems[1].nbNodes = 3;
01084   edgesWithNodes.elems[1].vtkType = VTK_QUADRATIC_EDGE;
01085 
01086   edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
01087   edgesWithNodes.elems[2].nodeIds[1] = nodes[3];
01088   edgesWithNodes.elems[2].nodeIds[2] = nodes[6];
01089   edgesWithNodes.elems[2].nbNodes = 3;
01090   edgesWithNodes.elems[2].vtkType = VTK_QUADRATIC_EDGE;
01091 
01092   edgesWithNodes.elems[3].nodeIds[0] = nodes[3];
01093   edgesWithNodes.elems[3].nodeIds[1] = nodes[0];
01094   edgesWithNodes.elems[3].nodeIds[2] = nodes[7];
01095   edgesWithNodes.elems[3].nbNodes = 3;
01096   edgesWithNodes.elems[3].vtkType = VTK_QUADRATIC_EDGE;
01097 }
01098 
01099 void SMDS_DownQuadQuadrangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
01100 {
01101   //ASSERT((cellId >=0)&& (cellId < _maxId));
01102   //ASSERT(aType == VTK_QUADRATIC_EDGE);
01103   int *faces = &_cellIds[_nbDownCells * cellId];
01104   for (int i = 0; i < _nbDownCells; i++)
01105     {
01106       if (faces[i] < 0)
01107         {
01108           faces[i] = lowCellId;
01109           return;
01110         }
01111       if (faces[i] == lowCellId)
01112         return;
01113     }
01114   ASSERT(0);
01115 }
01116 
01117 // ---------------------------------------------------------------------------
01118 
01119 SMDS_DownTetra::SMDS_DownTetra(SMDS_UnstructuredGrid *grid) :
01120   SMDS_Down3D(grid, 4)
01121 {
01122   _cellTypes.push_back(VTK_TRIANGLE);
01123   _cellTypes.push_back(VTK_TRIANGLE);
01124   _cellTypes.push_back(VTK_TRIANGLE);
01125   _cellTypes.push_back(VTK_TRIANGLE);
01126 }
01127 
01128 SMDS_DownTetra::~SMDS_DownTetra()
01129 {
01130 }
01131 
01132 void SMDS_DownTetra::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
01133 {
01134   set<int> setNodes;
01135   setNodes.clear();
01136   for (int i = 0; i < orderedNodes.size(); i++)
01137     setNodes.insert(orderedNodes[i]);
01138   //MESSAGE("cellId = " << cellId);
01139 
01140   vtkIdType npts = 0;
01141   vtkIdType *nodes; // will refer to the point id's of the volume
01142   _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
01143 
01144   set<int> tofind;
01145   int ids[12] = { 0, 1, 2,  0, 3, 1,  2, 3, 0,   1, 3, 2 };
01146 //int ids[12] = { 2, 1, 0,  1, 3, 0,  0, 3, 2,   2, 3, 1 };
01147   for (int k = 0; k < 4; k++)
01148     {
01149       tofind.clear();
01150       for (int i = 0; i < 3; i++)
01151         tofind.insert(nodes[ids[3 * k + i]]);
01152       if (setNodes == tofind)
01153         {
01154           for (int i = 0; i < 3; i++)
01155             orderedNodes[i] = nodes[ids[3 * k + i]];
01156           return;
01157         }
01158     }
01159   MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
01160   MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
01161   MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
01162 }
01163 
01164 void SMDS_DownTetra::addDownCell(int cellId, int lowCellId, unsigned char aType)
01165 {
01166   //ASSERT((cellId >=0)&& (cellId < _maxId));
01167   //ASSERT(aType == VTK_TRIANGLE);
01168   int *faces = &_cellIds[_nbDownCells * cellId];
01169   for (int i = 0; i < _nbDownCells; i++)
01170     {
01171       if (faces[i] < 0)
01172         {
01173           faces[i] = lowCellId;
01174           return;
01175         }
01176       if (faces[i] == lowCellId)
01177         return;
01178     }
01179   ASSERT(0);
01180 }
01181 
01188 void SMDS_DownTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
01189 {
01190   // --- find point id's of the volume
01191 
01192   vtkIdType npts = 0;
01193   vtkIdType *nodes; // will refer to the point id's of the volume
01194   _grid->GetCellPoints(cellId, npts, nodes);
01195 
01196   // --- create all the ordered list of node id's for each face
01197 
01198   facesWithNodes.nbElems = 4;
01199 
01200   facesWithNodes.elems[0].nodeIds[0] = nodes[0];
01201   facesWithNodes.elems[0].nodeIds[1] = nodes[1];
01202   facesWithNodes.elems[0].nodeIds[2] = nodes[2];
01203   facesWithNodes.elems[0].nbNodes = 3;
01204   facesWithNodes.elems[0].vtkType = VTK_TRIANGLE;
01205 
01206   facesWithNodes.elems[1].nodeIds[0] = nodes[0];
01207   facesWithNodes.elems[1].nodeIds[1] = nodes[1];
01208   facesWithNodes.elems[1].nodeIds[2] = nodes[3];
01209   facesWithNodes.elems[1].nbNodes = 3;
01210   facesWithNodes.elems[1].vtkType = VTK_TRIANGLE;
01211 
01212   facesWithNodes.elems[2].nodeIds[0] = nodes[0];
01213   facesWithNodes.elems[2].nodeIds[1] = nodes[2];
01214   facesWithNodes.elems[2].nodeIds[2] = nodes[3];
01215   facesWithNodes.elems[2].nbNodes = 3;
01216   facesWithNodes.elems[2].vtkType = VTK_TRIANGLE;
01217 
01218   facesWithNodes.elems[3].nodeIds[0] = nodes[1];
01219   facesWithNodes.elems[3].nodeIds[1] = nodes[2];
01220   facesWithNodes.elems[3].nodeIds[2] = nodes[3];
01221   facesWithNodes.elems[3].nbNodes = 3;
01222   facesWithNodes.elems[3].vtkType = VTK_TRIANGLE;
01223 }
01224 
01225 // ---------------------------------------------------------------------------
01226 
01227 SMDS_DownQuadTetra::SMDS_DownQuadTetra(SMDS_UnstructuredGrid *grid) :
01228   SMDS_Down3D(grid, 4)
01229 {
01230   _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
01231   _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
01232   _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
01233   _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
01234 }
01235 
01236 SMDS_DownQuadTetra::~SMDS_DownQuadTetra()
01237 {
01238 }
01239 
01240 void SMDS_DownQuadTetra::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
01241 {
01242   set<int> setNodes;
01243   setNodes.clear();
01244   for (int i = 0; i < orderedNodes.size(); i++)
01245     setNodes.insert(orderedNodes[i]);
01246   //MESSAGE("cellId = " << cellId);
01247 
01248   vtkIdType npts = 0;
01249   vtkIdType *nodes; // will refer to the point id's of the volume
01250   _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
01251 
01252   set<int> tofind;
01253   int ids[24] = { 0, 1, 2, 4, 5, 6,  0, 3, 1, 7, 8, 4,  2, 3, 0, 9, 7, 6,  1, 3, 2, 8, 9, 5 };
01254 //int ids[24] = { 2, 1, 0, 5, 4, 6,  1, 3, 0, 8, 7, 4,  0, 3, 2, 7, 9, 6,  2, 3, 1, 9, 8, 5 };
01255   for (int k = 0; k < 4; k++)
01256     {
01257       tofind.clear();
01258       for (int i = 0; i < 6; i++)
01259         tofind.insert(nodes[ids[6 * k + i]]);
01260       if (setNodes == tofind)
01261         {
01262           for (int i = 0; i < 6; i++)
01263             orderedNodes[i] = nodes[ids[6 * k + i]];
01264           return;
01265         }
01266     }
01267   MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
01268   MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
01269   MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
01270 }
01271 
01272 void SMDS_DownQuadTetra::addDownCell(int cellId, int lowCellId, unsigned char aType)
01273 {
01274   //ASSERT((cellId >=0)&& (cellId < _maxId));
01275   //ASSERT(aType == VTK_QUADRATIC_TRIANGLE);
01276   int *faces = &_cellIds[_nbDownCells * cellId];
01277   for (int i = 0; i < _nbDownCells; i++)
01278     {
01279       if (faces[i] < 0)
01280         {
01281           faces[i] = lowCellId;
01282           return;
01283         }
01284       if (faces[i] == lowCellId)
01285         return;
01286     }
01287   ASSERT(0);
01288 }
01289 
01298 void SMDS_DownQuadTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
01299 {
01300   // --- find point id's of the volume
01301 
01302   vtkIdType npts = 0;
01303   vtkIdType *nodes; // will refer to the point id's of the volume
01304   _grid->GetCellPoints(cellId, npts, nodes);
01305 
01306   // --- create all the ordered list of node id's for each face
01307 
01308   facesWithNodes.nbElems = 4;
01309 
01310   facesWithNodes.elems[0].nodeIds[0] = nodes[0];
01311   facesWithNodes.elems[0].nodeIds[1] = nodes[1];
01312   facesWithNodes.elems[0].nodeIds[2] = nodes[2];
01313   facesWithNodes.elems[0].nodeIds[3] = nodes[4];
01314   facesWithNodes.elems[0].nodeIds[4] = nodes[5];
01315   facesWithNodes.elems[0].nodeIds[5] = nodes[6];
01316   facesWithNodes.elems[0].nbNodes = 6;
01317   facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_TRIANGLE;
01318 
01319   facesWithNodes.elems[1].nodeIds[0] = nodes[0];
01320   facesWithNodes.elems[1].nodeIds[1] = nodes[1];
01321   facesWithNodes.elems[1].nodeIds[2] = nodes[3];
01322   facesWithNodes.elems[1].nodeIds[3] = nodes[4];
01323   facesWithNodes.elems[1].nodeIds[4] = nodes[8];
01324   facesWithNodes.elems[1].nodeIds[5] = nodes[7];
01325   facesWithNodes.elems[1].nbNodes = 6;
01326   facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE;
01327 
01328   facesWithNodes.elems[2].nodeIds[0] = nodes[0];
01329   facesWithNodes.elems[2].nodeIds[1] = nodes[2];
01330   facesWithNodes.elems[2].nodeIds[2] = nodes[3];
01331   facesWithNodes.elems[2].nodeIds[3] = nodes[6];
01332   facesWithNodes.elems[2].nodeIds[4] = nodes[9];
01333   facesWithNodes.elems[2].nodeIds[5] = nodes[7];
01334   facesWithNodes.elems[2].nbNodes = 6;
01335   facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE;
01336 
01337   facesWithNodes.elems[3].nodeIds[0] = nodes[1];
01338   facesWithNodes.elems[3].nodeIds[1] = nodes[2];
01339   facesWithNodes.elems[3].nodeIds[2] = nodes[3];
01340   facesWithNodes.elems[3].nodeIds[3] = nodes[5];
01341   facesWithNodes.elems[3].nodeIds[4] = nodes[9];
01342   facesWithNodes.elems[3].nodeIds[5] = nodes[8];
01343   facesWithNodes.elems[3].nbNodes = 6;
01344   facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
01345 }
01346 
01347 // ---------------------------------------------------------------------------
01348 
01349 SMDS_DownPyramid::SMDS_DownPyramid(SMDS_UnstructuredGrid *grid) :
01350   SMDS_Down3D(grid, 5)
01351 {
01352   _cellTypes.push_back(VTK_QUAD);
01353   _cellTypes.push_back(VTK_TRIANGLE);
01354   _cellTypes.push_back(VTK_TRIANGLE);
01355   _cellTypes.push_back(VTK_TRIANGLE);
01356   _cellTypes.push_back(VTK_TRIANGLE);
01357 }
01358 
01359 SMDS_DownPyramid::~SMDS_DownPyramid()
01360 {
01361 }
01362 
01363 void SMDS_DownPyramid::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
01364 {
01365   set<int> setNodes;
01366   setNodes.clear();
01367   for (int i = 0; i < orderedNodes.size(); i++)
01368     setNodes.insert(orderedNodes[i]);
01369   //MESSAGE("cellId = " << cellId);
01370 
01371   vtkIdType npts = 0;
01372   vtkIdType *nodes; // will refer to the point id's of the volume
01373   _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
01374 
01375   set<int> tofind;
01376   int ids[16] = { 0, 1, 2, 3,   0, 3, 4,   3, 2, 4,   2, 1, 4,   1, 0, 4 };
01377 
01378   tofind.clear();
01379   for (int i = 0; i < 4; i++)
01380     tofind.insert(nodes[ids[i]]);
01381   if (setNodes == tofind)
01382     {
01383       for (int i = 0; i < 4; i++)
01384         orderedNodes[i] = nodes[ids[i]];
01385       return;
01386     }
01387   for (int k = 0; k < 4; k++)
01388     {
01389       tofind.clear();
01390       for (int i = 0; i < 3; i++)
01391         tofind.insert(nodes[ids[4 + 3 * k + i]]);
01392       if (setNodes == tofind)
01393         {
01394           for (int i = 0; i < 3; i++)
01395             orderedNodes[i] = nodes[ids[4 + 3 * k + i]];
01396           return;
01397         }
01398     }
01399   MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
01400   MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
01401   MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
01402 }
01403 
01404 void SMDS_DownPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType)
01405 {
01406   //ASSERT((cellId >=0) && (cellId < _maxId));
01407   int *faces = &_cellIds[_nbDownCells * cellId];
01408   if (aType == VTK_QUAD)
01409     {
01410       if (faces[0] < 0)
01411         {
01412           faces[0] = lowCellId;
01413           return;
01414         }
01415       if (faces[0] == lowCellId)
01416         return;
01417     }
01418   else
01419     {
01420       //ASSERT(aType == VTK_TRIANGLE);
01421       for (int i = 1; i < _nbDownCells; i++)
01422         {
01423           if (faces[i] < 0)
01424             {
01425               faces[i] = lowCellId;
01426               return;
01427             }
01428           if (faces[i] == lowCellId)
01429             return;
01430         }
01431     }
01432   ASSERT(0);
01433 }
01434 
01443 void SMDS_DownPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
01444 {
01445   // --- find point id's of the volume
01446 
01447   vtkIdType npts = 0;
01448   vtkIdType *nodes; // will refer to the point id's of the volume
01449   _grid->GetCellPoints(cellId, npts, nodes);
01450 
01451   // --- create all the ordered list of node id's for each face
01452 
01453   facesWithNodes.nbElems = 5;
01454 
01455   facesWithNodes.elems[0].nodeIds[0] = nodes[0];
01456   facesWithNodes.elems[0].nodeIds[1] = nodes[1];
01457   facesWithNodes.elems[0].nodeIds[2] = nodes[2];
01458   facesWithNodes.elems[0].nodeIds[3] = nodes[3];
01459   facesWithNodes.elems[0].nbNodes = 4;
01460   facesWithNodes.elems[0].vtkType = VTK_QUAD;
01461 
01462   facesWithNodes.elems[1].nodeIds[0] = nodes[0];
01463   facesWithNodes.elems[1].nodeIds[1] = nodes[1];
01464   facesWithNodes.elems[1].nodeIds[2] = nodes[4];
01465   facesWithNodes.elems[1].nbNodes = 3;
01466   facesWithNodes.elems[1].vtkType = VTK_TRIANGLE;
01467 
01468   facesWithNodes.elems[2].nodeIds[0] = nodes[1];
01469   facesWithNodes.elems[2].nodeIds[1] = nodes[2];
01470   facesWithNodes.elems[2].nodeIds[2] = nodes[4];
01471   facesWithNodes.elems[2].nbNodes = 3;
01472   facesWithNodes.elems[2].vtkType = VTK_TRIANGLE;
01473 
01474   facesWithNodes.elems[3].nodeIds[0] = nodes[2];
01475   facesWithNodes.elems[3].nodeIds[1] = nodes[3];
01476   facesWithNodes.elems[3].nodeIds[2] = nodes[4];
01477   facesWithNodes.elems[3].nbNodes = 3;
01478   facesWithNodes.elems[3].vtkType = VTK_TRIANGLE;
01479 
01480   facesWithNodes.elems[4].nodeIds[0] = nodes[3];
01481   facesWithNodes.elems[4].nodeIds[1] = nodes[0];
01482   facesWithNodes.elems[4].nodeIds[2] = nodes[4];
01483   facesWithNodes.elems[4].nbNodes = 3;
01484   facesWithNodes.elems[4].vtkType = VTK_TRIANGLE;
01485 }
01486 
01487 // ---------------------------------------------------------------------------
01488 
01489 SMDS_DownQuadPyramid::SMDS_DownQuadPyramid(SMDS_UnstructuredGrid *grid) :
01490   SMDS_Down3D(grid, 5)
01491 {
01492   _cellTypes.push_back(VTK_QUADRATIC_QUAD);
01493   _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
01494   _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
01495   _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
01496   _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
01497 }
01498 
01499 SMDS_DownQuadPyramid::~SMDS_DownQuadPyramid()
01500 {
01501 }
01502 
01503 void SMDS_DownQuadPyramid::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
01504 {
01505   set<int> setNodes;
01506   setNodes.clear();
01507   for (int i = 0; i < orderedNodes.size(); i++)
01508     setNodes.insert(orderedNodes[i]);
01509   //MESSAGE("cellId = " << cellId);
01510 
01511   vtkIdType npts = 0;
01512   vtkIdType *nodes; // will refer to the point id's of the volume
01513   _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
01514 
01515   set<int> tofind;
01516   int ids[32] = { 0, 1, 2, 3, 5, 6, 7, 8,
01517                   0, 3, 4, 8, 12, 9,   3, 2, 4, 7 , 11, 12,   2, 1, 4, 6, 10, 11,   1, 0, 4, 5, 9, 10 };
01518 
01519   tofind.clear();
01520   for (int i = 0; i < 4; i++)
01521     tofind.insert(nodes[ids[i]]);
01522   if (setNodes == tofind)
01523     {
01524       for (int i = 0; i < 8; i++)
01525         orderedNodes[i] = nodes[ids[i]];
01526       return;
01527     }
01528   for (int k = 0; k < 4; k++)
01529     {
01530       tofind.clear();
01531       for (int i = 0; i < 6; i++)
01532         tofind.insert(nodes[ids[8 + 6 * k + i]]);
01533       if (setNodes == tofind)
01534         {
01535           for (int i = 0; i < 6; i++)
01536             orderedNodes[i] = nodes[ids[8 + 6 * k + i]];
01537           return;
01538         }
01539     }
01540   MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
01541   MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
01542   MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
01543 }
01544 
01545 void SMDS_DownQuadPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType)
01546 {
01547   //ASSERT((cellId >=0) && (cellId < _maxId));
01548   int *faces = &_cellIds[_nbDownCells * cellId];
01549   if (aType == VTK_QUADRATIC_QUAD)
01550     {
01551       if (faces[0] < 0)
01552         {
01553           faces[0] = lowCellId;
01554           return;
01555         }
01556       if (faces[0] == lowCellId)
01557         return;
01558     }
01559   else
01560     {
01561       //ASSERT(aType == VTK_QUADRATIC_TRIANGLE);
01562       for (int i = 1; i < _nbDownCells; i++)
01563         {
01564           if (faces[i] < 0)
01565             {
01566               faces[i] = lowCellId;
01567               return;
01568             }
01569           if (faces[i] == lowCellId)
01570             return;
01571         }
01572     }
01573   ASSERT(0);
01574 }
01575 
01585 void SMDS_DownQuadPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
01586 {
01587   // --- find point id's of the volume
01588 
01589   vtkIdType npts = 0;
01590   vtkIdType *nodes; // will refer to the point id's of the volume
01591   _grid->GetCellPoints(cellId, npts, nodes);
01592 
01593   // --- create all the ordered list of node id's for each face
01594 
01595   facesWithNodes.nbElems = 5;
01596 
01597   facesWithNodes.elems[0].nodeIds[0] = nodes[0];
01598   facesWithNodes.elems[0].nodeIds[1] = nodes[1];
01599   facesWithNodes.elems[0].nodeIds[2] = nodes[2];
01600   facesWithNodes.elems[0].nodeIds[3] = nodes[3];
01601   facesWithNodes.elems[0].nodeIds[4] = nodes[5];
01602   facesWithNodes.elems[0].nodeIds[5] = nodes[6];
01603   facesWithNodes.elems[0].nodeIds[6] = nodes[7];
01604   facesWithNodes.elems[0].nodeIds[7] = nodes[8];
01605   facesWithNodes.elems[0].nbNodes = 8;
01606   facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD;
01607 
01608   facesWithNodes.elems[1].nodeIds[0] = nodes[0];
01609   facesWithNodes.elems[1].nodeIds[1] = nodes[1];
01610   facesWithNodes.elems[1].nodeIds[2] = nodes[4];
01611   facesWithNodes.elems[1].nodeIds[3] = nodes[5];
01612   facesWithNodes.elems[1].nodeIds[4] = nodes[10];
01613   facesWithNodes.elems[1].nodeIds[5] = nodes[9];
01614   facesWithNodes.elems[1].nbNodes = 6;
01615   facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE;
01616 
01617   facesWithNodes.elems[2].nodeIds[0] = nodes[1];
01618   facesWithNodes.elems[2].nodeIds[1] = nodes[2];
01619   facesWithNodes.elems[2].nodeIds[2] = nodes[4];
01620   facesWithNodes.elems[2].nodeIds[3] = nodes[6];
01621   facesWithNodes.elems[2].nodeIds[4] = nodes[11];
01622   facesWithNodes.elems[2].nodeIds[5] = nodes[10];
01623   facesWithNodes.elems[2].nbNodes = 6;
01624   facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE;
01625 
01626   facesWithNodes.elems[3].nodeIds[0] = nodes[2];
01627   facesWithNodes.elems[3].nodeIds[1] = nodes[3];
01628   facesWithNodes.elems[3].nodeIds[2] = nodes[4];
01629   facesWithNodes.elems[3].nodeIds[3] = nodes[7];
01630   facesWithNodes.elems[3].nodeIds[4] = nodes[12];
01631   facesWithNodes.elems[3].nodeIds[5] = nodes[11];
01632   facesWithNodes.elems[3].nbNodes = 6;
01633   facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
01634 
01635   facesWithNodes.elems[4].nodeIds[0] = nodes[3];
01636   facesWithNodes.elems[4].nodeIds[1] = nodes[0];
01637   facesWithNodes.elems[4].nodeIds[2] = nodes[4];
01638   facesWithNodes.elems[4].nodeIds[3] = nodes[8];
01639   facesWithNodes.elems[4].nodeIds[4] = nodes[9];
01640   facesWithNodes.elems[4].nodeIds[5] = nodes[12];
01641   facesWithNodes.elems[4].nbNodes = 6;
01642   facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_TRIANGLE;
01643 }
01644 
01645 // ---------------------------------------------------------------------------
01646 
01647 SMDS_DownPenta::SMDS_DownPenta(SMDS_UnstructuredGrid *grid) :
01648   SMDS_Down3D(grid, 5)
01649 {
01650   _cellTypes.push_back(VTK_QUAD);
01651   _cellTypes.push_back(VTK_QUAD);
01652   _cellTypes.push_back(VTK_QUAD);
01653   _cellTypes.push_back(VTK_TRIANGLE);
01654   _cellTypes.push_back(VTK_TRIANGLE);
01655 }
01656 
01657 SMDS_DownPenta::~SMDS_DownPenta()
01658 {
01659 }
01660 
01661 void SMDS_DownPenta::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
01662 {
01663   set<int> setNodes;
01664   setNodes.clear();
01665   for (int i = 0; i < orderedNodes.size(); i++)
01666     setNodes.insert(orderedNodes[i]);
01667   //MESSAGE("cellId = " << cellId);
01668 
01669   vtkIdType npts = 0;
01670   vtkIdType *nodes; // will refer to the point id's of the volume
01671   _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
01672 
01673   set<int> tofind;
01674 //int ids[18] = { 0, 2, 1,  3, 4, 5,   0, 1, 4, 3,   1, 2, 5, 4,   2, 0, 3, 5 };
01675   int ids[18] = { 0, 1, 2,  3, 5, 4,   0, 3, 4, 1,   1, 4, 5, 2,   2, 5, 3, 0 };
01676 
01677   for (int k = 0; k < 2; k++)
01678     {
01679       tofind.clear();
01680       for (int i = 0; i < 3; i++)
01681         tofind.insert(nodes[ids[3 * k + i]]);
01682       if (setNodes == tofind)
01683         {
01684           for (int i = 0; i < 3; i++)
01685             orderedNodes[i] = nodes[ids[3 * k + i]];
01686           return;
01687         }
01688     }
01689   for (int k = 0; k < 3; k++)
01690     {
01691       tofind.clear();
01692       for (int i = 0; i < 4; i++)
01693         tofind.insert(nodes[ids[6 + 4 * k + i]]);
01694       if (setNodes == tofind)
01695         {
01696           for (int i = 0; i < 4; i++)
01697             orderedNodes[i] = nodes[ids[6 + 4 * k + i]];
01698           return;
01699         }
01700     }
01701   MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
01702   MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
01703   MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
01704 }
01705 
01706 void SMDS_DownPenta::addDownCell(int cellId, int lowCellId, unsigned char aType)
01707 {
01708   //ASSERT((cellId >=0) && (cellId < _maxId));
01709   int *faces = &_cellIds[_nbDownCells * cellId];
01710   if (aType == VTK_QUAD)
01711     for (int i = 0; i < 3; i++)
01712       {
01713         if (faces[i] < 0)
01714           {
01715             faces[i] = lowCellId;
01716             return;
01717           }
01718         if (faces[i] == lowCellId)
01719           return;
01720       }
01721   else
01722     {
01723       //ASSERT(aType == VTK_TRIANGLE);
01724       for (int i = 3; i < _nbDownCells; i++)
01725         {
01726           if (faces[i] < 0)
01727             {
01728               faces[i] = lowCellId;
01729               return;
01730             }
01731           if (faces[i] == lowCellId)
01732             return;
01733         }
01734     }
01735   ASSERT(0);
01736 }
01737 
01747 void SMDS_DownPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
01748 {
01749   // --- find point id's of the volume
01750 
01751   vtkIdType npts = 0;
01752   vtkIdType *nodes; // will refer to the point id's of the volume
01753   _grid->GetCellPoints(cellId, npts, nodes);
01754 
01755   // --- create all the ordered list of node id's for each face
01756 
01757   facesWithNodes.nbElems = 5;
01758 
01759   facesWithNodes.elems[0].nodeIds[0] = nodes[0];
01760   facesWithNodes.elems[0].nodeIds[1] = nodes[2];
01761   facesWithNodes.elems[0].nodeIds[2] = nodes[5];
01762   facesWithNodes.elems[0].nodeIds[3] = nodes[3];
01763   facesWithNodes.elems[0].nbNodes = 4;
01764   facesWithNodes.elems[0].vtkType = VTK_QUAD;
01765 
01766   facesWithNodes.elems[1].nodeIds[0] = nodes[1];
01767   facesWithNodes.elems[1].nodeIds[1] = nodes[2];
01768   facesWithNodes.elems[1].nodeIds[2] = nodes[5];
01769   facesWithNodes.elems[1].nodeIds[3] = nodes[4];
01770   facesWithNodes.elems[1].nbNodes = 4;
01771   facesWithNodes.elems[1].vtkType = VTK_QUAD;
01772 
01773   facesWithNodes.elems[2].nodeIds[0] = nodes[0];
01774   facesWithNodes.elems[2].nodeIds[1] = nodes[1];
01775   facesWithNodes.elems[2].nodeIds[2] = nodes[4];
01776   facesWithNodes.elems[2].nodeIds[3] = nodes[3];
01777   facesWithNodes.elems[2].nbNodes = 4;
01778   facesWithNodes.elems[2].vtkType = VTK_QUAD;
01779 
01780   facesWithNodes.elems[3].nodeIds[0] = nodes[0];
01781   facesWithNodes.elems[3].nodeIds[1] = nodes[1];
01782   facesWithNodes.elems[3].nodeIds[2] = nodes[2];
01783   facesWithNodes.elems[3].nbNodes = 3;
01784   facesWithNodes.elems[3].vtkType = VTK_TRIANGLE;
01785 
01786   facesWithNodes.elems[4].nodeIds[0] = nodes[3];
01787   facesWithNodes.elems[4].nodeIds[1] = nodes[4];
01788   facesWithNodes.elems[4].nodeIds[2] = nodes[5];
01789   facesWithNodes.elems[4].nbNodes = 3;
01790   facesWithNodes.elems[4].vtkType = VTK_TRIANGLE;
01791 }
01792 
01793 // ---------------------------------------------------------------------------
01794 
01795 SMDS_DownQuadPenta::SMDS_DownQuadPenta(SMDS_UnstructuredGrid *grid) :
01796   SMDS_Down3D(grid, 5)
01797 {
01798   _cellTypes.push_back(VTK_QUADRATIC_QUAD);
01799   _cellTypes.push_back(VTK_QUADRATIC_QUAD);
01800   _cellTypes.push_back(VTK_QUADRATIC_QUAD);
01801   _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
01802   _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
01803 }
01804 
01805 SMDS_DownQuadPenta::~SMDS_DownQuadPenta()
01806 {
01807 }
01808 
01809 void SMDS_DownQuadPenta::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
01810 {
01811   set<int> setNodes;
01812   setNodes.clear();
01813   for (int i = 0; i < orderedNodes.size(); i++)
01814     setNodes.insert(orderedNodes[i]);
01815   //MESSAGE("cellId = " << cellId);
01816 
01817   vtkIdType npts = 0;
01818   vtkIdType *nodes; // will refer to the point id's of the volume
01819   _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
01820 
01821   set<int> tofind;
01822 //int ids[18] = { 0, 2, 1,  3, 4, 5,   0, 1, 4, 3,   1, 2, 5, 4,   2, 0, 3, 5 };
01823   int ids[36] = { 0, 1, 2, 6, 7, 8,  3, 5, 4, 11, 10, 9,
01824                   0, 3, 4, 1, 12, 9, 13, 6,   1, 4, 5, 2, 13, 10, 14, 7,   2, 5, 3, 0, 14, 11, 12, 8 };
01825 
01826   for (int k = 0; k < 2; k++)
01827     {
01828       tofind.clear();
01829       for (int i = 0; i < 6; i++)
01830         tofind.insert(nodes[ids[6 * k + i]]);
01831       if (setNodes == tofind)
01832         {
01833           for (int i = 0; i < 6; i++)
01834             orderedNodes[i] = nodes[ids[6 * k + i]];
01835           return;
01836         }
01837     }
01838   for (int k = 0; k < 3; k++)
01839     {
01840       tofind.clear();
01841       for (int i = 0; i < 8; i++)
01842         tofind.insert(nodes[ids[12 + 8 * k + i]]);
01843       if (setNodes == tofind)
01844         {
01845           for (int i = 0; i < 8; i++)
01846             orderedNodes[i] = nodes[ids[12 + 8 * k + i]];
01847           return;
01848         }
01849     }
01850   MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
01851   MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
01852   MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
01853 }
01854 
01855 void SMDS_DownQuadPenta::addDownCell(int cellId, int lowCellId, unsigned char aType)
01856 {
01857   //ASSERT((cellId >=0) && (cellId < _maxId));
01858   int *faces = &_cellIds[_nbDownCells * cellId];
01859   if (aType == VTK_QUADRATIC_QUAD)
01860     for (int i = 0; i < 3; i++)
01861       {
01862         if (faces[i] < 0)
01863           {
01864             faces[i] = lowCellId;
01865             return;
01866           }
01867         if (faces[i] == lowCellId)
01868           return;
01869       }
01870   else
01871     {
01872       //ASSERT(aType == VTK_QUADRATIC_TRIANGLE);
01873       for (int i = 3; i < _nbDownCells; i++)
01874         {
01875           if (faces[i] < 0)
01876             {
01877               faces[i] = lowCellId;
01878               return;
01879             }
01880           if (faces[i] == lowCellId)
01881             return;
01882         }
01883     }
01884   ASSERT(0);
01885 }
01886 
01897 void SMDS_DownQuadPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
01898 {
01899   // --- find point id's of the volume
01900 
01901   vtkIdType npts = 0;
01902   vtkIdType *nodes; // will refer to the point id's of the volume
01903   _grid->GetCellPoints(cellId, npts, nodes);
01904 
01905   // --- create all the ordered list of node id's for each face
01906 
01907   facesWithNodes.nbElems = 5;
01908 
01909   facesWithNodes.elems[0].nodeIds[0] = nodes[0];
01910   facesWithNodes.elems[0].nodeIds[1] = nodes[2];
01911   facesWithNodes.elems[0].nodeIds[2] = nodes[5];
01912   facesWithNodes.elems[0].nodeIds[3] = nodes[3];
01913   facesWithNodes.elems[0].nodeIds[4] = nodes[8];
01914   facesWithNodes.elems[0].nodeIds[5] = nodes[14];
01915   facesWithNodes.elems[0].nodeIds[6] = nodes[11];
01916   facesWithNodes.elems[0].nodeIds[7] = nodes[12];
01917   facesWithNodes.elems[0].nbNodes = 8;
01918   facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD;
01919 
01920   facesWithNodes.elems[1].nodeIds[0] = nodes[1];
01921   facesWithNodes.elems[1].nodeIds[1] = nodes[2];
01922   facesWithNodes.elems[1].nodeIds[2] = nodes[5];
01923   facesWithNodes.elems[1].nodeIds[3] = nodes[4];
01924   facesWithNodes.elems[1].nodeIds[4] = nodes[7];
01925   facesWithNodes.elems[1].nodeIds[5] = nodes[14];
01926   facesWithNodes.elems[1].nodeIds[6] = nodes[10];
01927   facesWithNodes.elems[1].nodeIds[7] = nodes[13];
01928   facesWithNodes.elems[1].nbNodes = 8;
01929   facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_QUAD;
01930 
01931   facesWithNodes.elems[2].nodeIds[0] = nodes[0];
01932   facesWithNodes.elems[2].nodeIds[1] = nodes[1];
01933   facesWithNodes.elems[2].nodeIds[2] = nodes[4];
01934   facesWithNodes.elems[2].nodeIds[3] = nodes[3];
01935   facesWithNodes.elems[2].nodeIds[4] = nodes[6];
01936   facesWithNodes.elems[2].nodeIds[5] = nodes[13];
01937   facesWithNodes.elems[2].nodeIds[6] = nodes[9];
01938   facesWithNodes.elems[2].nodeIds[7] = nodes[12];
01939   facesWithNodes.elems[2].nbNodes = 8;
01940   facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_QUAD;
01941 
01942   facesWithNodes.elems[3].nodeIds[0] = nodes[0];
01943   facesWithNodes.elems[3].nodeIds[1] = nodes[1];
01944   facesWithNodes.elems[3].nodeIds[2] = nodes[2];
01945   facesWithNodes.elems[3].nodeIds[3] = nodes[6];
01946   facesWithNodes.elems[3].nodeIds[4] = nodes[7];
01947   facesWithNodes.elems[3].nodeIds[5] = nodes[8];
01948   facesWithNodes.elems[3].nbNodes = 6;
01949   facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
01950 
01951   facesWithNodes.elems[4].nodeIds[0] = nodes[3];
01952   facesWithNodes.elems[4].nodeIds[1] = nodes[4];
01953   facesWithNodes.elems[4].nodeIds[2] = nodes[5];
01954   facesWithNodes.elems[4].nodeIds[3] = nodes[9];
01955   facesWithNodes.elems[4].nodeIds[4] = nodes[10];
01956   facesWithNodes.elems[4].nodeIds[5] = nodes[11];
01957   facesWithNodes.elems[4].nbNodes = 6;
01958   facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_TRIANGLE;
01959 }
01960 
01961 // ---------------------------------------------------------------------------
01962 
01963 SMDS_DownHexa::SMDS_DownHexa(SMDS_UnstructuredGrid *grid) :
01964   SMDS_Down3D(grid, 6)
01965 {
01966   _cellTypes.push_back(VTK_QUAD);
01967   _cellTypes.push_back(VTK_QUAD);
01968   _cellTypes.push_back(VTK_QUAD);
01969   _cellTypes.push_back(VTK_QUAD);
01970   _cellTypes.push_back(VTK_QUAD);
01971   _cellTypes.push_back(VTK_QUAD);
01972 }
01973 
01974 SMDS_DownHexa::~SMDS_DownHexa()
01975 {
01976 }
01977 
01978 void SMDS_DownHexa::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
01979 {
01980   set<int> setNodes;
01981   setNodes.clear();
01982   for (int i = 0; i < orderedNodes.size(); i++)
01983     setNodes.insert(orderedNodes[i]);
01984   //MESSAGE("cellId = " << cellId);
01985 
01986   vtkIdType npts = 0;
01987   vtkIdType *nodes; // will refer to the point id's of the volume
01988   _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
01989 
01990   set<int> tofind;
01991 //int ids[24] = { 0, 1, 2, 3,  7, 6, 5, 4,  4, 0, 3, 7,  5, 1, 0, 4,  6, 2, 1, 5,  7, 3, 2, 6};
01992   int ids[24] = { 3, 2, 1, 0,  4, 5, 6, 7,  7, 3, 0, 4,  4, 0, 1, 5,  5, 1, 2, 6,  6, 2, 3, 7};
01993   for (int k = 0; k < 6; k++) // loop on the 6 faces
01994     {
01995       tofind.clear();
01996       for (int i = 0; i < 4; i++)
01997         tofind.insert(nodes[ids[4 * k + i]]); // node ids of the face i
01998       if (setNodes == tofind)
01999         {
02000           for (int i = 0; i < 4; i++)
02001             orderedNodes[i] = nodes[ids[4 * k + i]];
02002           return;
02003         }
02004     }
02005   MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
02006   MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]);
02007   MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
02008   MESSAGE(nodes[4] << " " << nodes[5] << " " << nodes[6] << " " << nodes[7]);
02009 }
02010 
02011 void SMDS_DownHexa::addDownCell(int cellId, int lowCellId, unsigned char aType)
02012 {
02013   //ASSERT((cellId >=0)&& (cellId < _maxId));
02014   int *faces = &_cellIds[_nbDownCells * cellId];
02015   for (int i = 0; i < _nbDownCells; i++)
02016     {
02017       if (faces[i] < 0)
02018         {
02019           faces[i] = lowCellId;
02020           return;
02021         }
02022       if (faces[i] == lowCellId)
02023         return;
02024     }
02025   ASSERT(0);
02026   // MESSAGE("-------------------------------------> trop de faces ! " << cellId << " " << lowCellId);
02027 }
02028 
02037 void SMDS_DownHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
02038 {
02039   // --- find point id's of the volume
02040 
02041   vtkIdType npts = 0;
02042   vtkIdType *nodes; // will refer to the point id's of the volume
02043   _grid->GetCellPoints(cellId, npts, nodes);
02044 
02045   // --- create all the ordered list of node id's for each face
02046 
02047   facesWithNodes.nbElems = 6;
02048 
02049   facesWithNodes.elems[0].nodeIds[0] = nodes[0];
02050   facesWithNodes.elems[0].nodeIds[1] = nodes[1];
02051   facesWithNodes.elems[0].nodeIds[2] = nodes[2];
02052   facesWithNodes.elems[0].nodeIds[3] = nodes[3];
02053   facesWithNodes.elems[0].nbNodes = 4;
02054   facesWithNodes.elems[0].vtkType = VTK_QUAD;
02055 
02056   facesWithNodes.elems[1].nodeIds[0] = nodes[4];
02057   facesWithNodes.elems[1].nodeIds[1] = nodes[5];
02058   facesWithNodes.elems[1].nodeIds[2] = nodes[6];
02059   facesWithNodes.elems[1].nodeIds[3] = nodes[7];
02060   facesWithNodes.elems[1].nbNodes = 4;
02061   facesWithNodes.elems[1].vtkType = VTK_QUAD;
02062 
02063   facesWithNodes.elems[2].nodeIds[0] = nodes[0];
02064   facesWithNodes.elems[2].nodeIds[1] = nodes[1];
02065   facesWithNodes.elems[2].nodeIds[2] = nodes[5];
02066   facesWithNodes.elems[2].nodeIds[3] = nodes[4];
02067   facesWithNodes.elems[2].nbNodes = 4;
02068   facesWithNodes.elems[2].vtkType = VTK_QUAD;
02069 
02070   facesWithNodes.elems[3].nodeIds[0] = nodes[1];
02071   facesWithNodes.elems[3].nodeIds[1] = nodes[2];
02072   facesWithNodes.elems[3].nodeIds[2] = nodes[6];
02073   facesWithNodes.elems[3].nodeIds[3] = nodes[5];
02074   facesWithNodes.elems[3].nbNodes = 4;
02075   facesWithNodes.elems[3].vtkType = VTK_QUAD;
02076 
02077   facesWithNodes.elems[4].nodeIds[0] = nodes[2];
02078   facesWithNodes.elems[4].nodeIds[1] = nodes[6];
02079   facesWithNodes.elems[4].nodeIds[2] = nodes[7];
02080   facesWithNodes.elems[4].nodeIds[3] = nodes[3];
02081   facesWithNodes.elems[4].nbNodes = 4;
02082   facesWithNodes.elems[4].vtkType = VTK_QUAD;
02083 
02084   facesWithNodes.elems[5].nodeIds[0] = nodes[3];
02085   facesWithNodes.elems[5].nodeIds[1] = nodes[7];
02086   facesWithNodes.elems[5].nodeIds[2] = nodes[4];
02087   facesWithNodes.elems[5].nodeIds[3] = nodes[0];
02088   facesWithNodes.elems[5].nbNodes = 4;
02089   facesWithNodes.elems[5].vtkType = VTK_QUAD;
02090 }
02091 
02092 // ---------------------------------------------------------------------------
02093 
02094 SMDS_DownQuadHexa::SMDS_DownQuadHexa(SMDS_UnstructuredGrid *grid) :
02095   SMDS_Down3D(grid, 6)
02096 {
02097   _cellTypes.push_back(VTK_QUADRATIC_QUAD);
02098   _cellTypes.push_back(VTK_QUADRATIC_QUAD);
02099   _cellTypes.push_back(VTK_QUADRATIC_QUAD);
02100   _cellTypes.push_back(VTK_QUADRATIC_QUAD);
02101   _cellTypes.push_back(VTK_QUADRATIC_QUAD);
02102   _cellTypes.push_back(VTK_QUADRATIC_QUAD);
02103 }
02104 
02105 SMDS_DownQuadHexa::~SMDS_DownQuadHexa()
02106 {
02107 }
02108 
02109 void SMDS_DownQuadHexa::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
02110 {
02111   set<int> setNodes;
02112   setNodes.clear();
02113   for (int i = 0; i < orderedNodes.size(); i++)
02114     setNodes.insert(orderedNodes[i]);
02115   //MESSAGE("cellId = " << cellId);
02116 
02117   vtkIdType npts = 0;
02118   vtkIdType *nodes; // will refer to the point id's of the volume
02119   _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
02120 
02121   set<int> tofind;
02122   //int ids[24] = { 3, 2, 1, 0,  4, 5, 6, 7,  7, 3, 0, 4,  4, 0, 1, 5,  5, 1, 2, 6,  6, 2, 3, 7};
02123   int ids[48] = { 3, 2, 1, 0,10, 9, 8,11,   4, 5, 6, 7,12,13,14,15,   7, 3, 0, 4,19,11,16,15,
02124                   4, 0, 1, 5,16, 8,17,12,   5, 1, 2, 6,17, 9,18,13,   6, 2, 3, 7,18,10,19,14};
02125   for (int k = 0; k < 6; k++)
02126     {
02127       tofind.clear();
02128       for (int i = 0; i < 8; i++)
02129         tofind.insert(nodes[ids[8 * k + i]]);
02130       if (setNodes == tofind)
02131         {
02132           for (int i = 0; i < 8; i++)
02133             orderedNodes[i] = nodes[ids[8 * k + i]];
02134           return;
02135         }
02136     }
02137   MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
02138   MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]);
02139   MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
02140 }
02141 
02142 void SMDS_DownQuadHexa::addDownCell(int cellId, int lowCellId, unsigned char aType)
02143 {
02144   //ASSERT((cellId >=0)&& (cellId < _maxId));
02145   int *faces = &_cellIds[_nbDownCells * cellId];
02146   for (int i = 0; i < _nbDownCells; i++)
02147     {
02148       if (faces[i] < 0)
02149         {
02150           faces[i] = lowCellId;
02151           return;
02152         }
02153       if (faces[i] == lowCellId)
02154         return;
02155     }
02156   ASSERT(0);
02157 }
02158 
02168 void SMDS_DownQuadHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
02169 {
02170   // --- find point id's of the volume
02171 
02172   vtkIdType npts = 0;
02173   vtkIdType *nodes; // will refer to the point id's of the volume
02174   _grid->GetCellPoints(cellId, npts, nodes);
02175 
02176   // --- create all the ordered list of node id's for each face
02177 
02178   facesWithNodes.nbElems = 6;
02179 
02180   facesWithNodes.elems[0].nodeIds[0] = nodes[0];
02181   facesWithNodes.elems[0].nodeIds[1] = nodes[1];
02182   facesWithNodes.elems[0].nodeIds[2] = nodes[2];
02183   facesWithNodes.elems[0].nodeIds[3] = nodes[3];
02184   facesWithNodes.elems[0].nodeIds[4] = nodes[8];
02185   facesWithNodes.elems[0].nodeIds[5] = nodes[9];
02186   facesWithNodes.elems[0].nodeIds[6] = nodes[10];
02187   facesWithNodes.elems[0].nodeIds[7] = nodes[11];
02188   facesWithNodes.elems[0].nbNodes = 8;
02189   facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD;
02190 
02191   facesWithNodes.elems[1].nodeIds[0] = nodes[4];
02192   facesWithNodes.elems[1].nodeIds[1] = nodes[5];
02193   facesWithNodes.elems[1].nodeIds[2] = nodes[6];
02194   facesWithNodes.elems[1].nodeIds[3] = nodes[7];
02195   facesWithNodes.elems[1].nodeIds[4] = nodes[12];
02196   facesWithNodes.elems[1].nodeIds[5] = nodes[13];
02197   facesWithNodes.elems[1].nodeIds[6] = nodes[14];
02198   facesWithNodes.elems[1].nodeIds[7] = nodes[15];
02199   facesWithNodes.elems[1].nbNodes = 8;
02200   facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_QUAD;
02201 
02202   facesWithNodes.elems[2].nodeIds[0] = nodes[0];
02203   facesWithNodes.elems[2].nodeIds[1] = nodes[1];
02204   facesWithNodes.elems[2].nodeIds[2] = nodes[5];
02205   facesWithNodes.elems[2].nodeIds[3] = nodes[4];
02206   facesWithNodes.elems[2].nodeIds[4] = nodes[8];
02207   facesWithNodes.elems[2].nodeIds[5] = nodes[17];
02208   facesWithNodes.elems[2].nodeIds[6] = nodes[12];
02209   facesWithNodes.elems[2].nodeIds[7] = nodes[16];
02210   facesWithNodes.elems[2].nbNodes = 8;
02211   facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_QUAD;
02212 
02213   facesWithNodes.elems[3].nodeIds[0] = nodes[1];
02214   facesWithNodes.elems[3].nodeIds[1] = nodes[2];
02215   facesWithNodes.elems[3].nodeIds[2] = nodes[6];
02216   facesWithNodes.elems[3].nodeIds[3] = nodes[5];
02217   facesWithNodes.elems[3].nodeIds[4] = nodes[9];
02218   facesWithNodes.elems[3].nodeIds[5] = nodes[18];
02219   facesWithNodes.elems[3].nodeIds[6] = nodes[13];
02220   facesWithNodes.elems[3].nodeIds[7] = nodes[17];
02221   facesWithNodes.elems[3].nbNodes = 8;
02222   facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_QUAD;
02223 
02224   facesWithNodes.elems[4].nodeIds[0] = nodes[2];
02225   facesWithNodes.elems[4].nodeIds[1] = nodes[6];
02226   facesWithNodes.elems[4].nodeIds[2] = nodes[7];
02227   facesWithNodes.elems[4].nodeIds[3] = nodes[3];
02228   facesWithNodes.elems[4].nodeIds[4] = nodes[18];
02229   facesWithNodes.elems[4].nodeIds[5] = nodes[14];
02230   facesWithNodes.elems[4].nodeIds[6] = nodes[19];
02231   facesWithNodes.elems[4].nodeIds[7] = nodes[10];
02232   facesWithNodes.elems[4].nbNodes = 8;
02233   facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_QUAD;
02234 
02235   facesWithNodes.elems[5].nodeIds[0] = nodes[3];
02236   facesWithNodes.elems[5].nodeIds[1] = nodes[7];
02237   facesWithNodes.elems[5].nodeIds[2] = nodes[4];
02238   facesWithNodes.elems[5].nodeIds[3] = nodes[0];
02239   facesWithNodes.elems[5].nodeIds[4] = nodes[19];
02240   facesWithNodes.elems[5].nodeIds[5] = nodes[15];
02241   facesWithNodes.elems[5].nodeIds[6] = nodes[16];
02242   facesWithNodes.elems[5].nodeIds[7] = nodes[11];
02243   facesWithNodes.elems[5].nbNodes = 8;
02244   facesWithNodes.elems[5].vtkType = VTK_QUADRATIC_QUAD;
02245 }
02246 
02247 // ---------------------------------------------------------------------------
02248 
Copyright © 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS