Back to index

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