1 // Copyright (C) 2010-2011 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File: SMDS_Downward.cxx
21 // Created: Jun 3, 2010
24 #include "SMDS_Downward.hxx"
25 #include "SMDS_Mesh.hxx"
26 #include "utilities.h"
28 #include <vtkCellType.h>
29 #include <vtkCellLinks.h>
35 // ---------------------------------------------------------------------------
37 vector<int> SMDS_Downward::_cellDimension;
39 /*! get the dimension of a cell (1,2,3 for 1D, 2D 3D) given the vtk cell type
41 * @param cellType vtk cell type @see vtkCellType.h
44 int SMDS_Downward::getCellDimension(unsigned char cellType)
46 if (_cellDimension.empty())
48 _cellDimension.resize(VTK_MAXTYPE + 1, 0);
49 _cellDimension[VTK_LINE] = 1;
50 _cellDimension[VTK_QUADRATIC_EDGE] = 1;
51 _cellDimension[VTK_TRIANGLE] = 2;
52 _cellDimension[VTK_QUADRATIC_TRIANGLE] = 2;
53 _cellDimension[VTK_QUAD] = 2;
54 _cellDimension[VTK_QUADRATIC_QUAD] = 2;
55 _cellDimension[VTK_BIQUADRATIC_QUAD] = 2;
56 _cellDimension[VTK_TETRA] = 3;
57 _cellDimension[VTK_QUADRATIC_TETRA] = 3;
58 _cellDimension[VTK_HEXAHEDRON] = 3;
59 _cellDimension[VTK_QUADRATIC_HEXAHEDRON] = 3;
60 _cellDimension[VTK_TRIQUADRATIC_HEXAHEDRON] = 3;
61 _cellDimension[VTK_WEDGE] = 3;
62 _cellDimension[VTK_QUADRATIC_WEDGE] = 3;
63 _cellDimension[VTK_PYRAMID] = 3;
64 _cellDimension[VTK_QUADRATIC_PYRAMID] = 3;
65 _cellDimension[VTK_HEXAGONAL_PRISM] = 3;
67 return _cellDimension[cellType];
70 // ---------------------------------------------------------------------------
72 /*! Generic constructor for all the downward connectivity structures (one per vtk cell type).
73 * The static structure for cell dimension is set only once.
74 * @param grid unstructured grid associated to the mesh.
75 * @param nbDownCells number of downward entities associated to this vtk type of cell.
78 SMDS_Downward::SMDS_Downward(SMDS_UnstructuredGrid *grid, int nbDownCells) :
79 _grid(grid), _nbDownCells(nbDownCells)
82 this->_cellIds.clear();
83 this->_cellTypes.clear();
84 if (_cellDimension.empty())
85 getCellDimension( VTK_LINE );
88 SMDS_Downward::~SMDS_Downward()
92 /*! Give or create an entry for downward connectivity structure relative to a cell.
93 * If the entry already exists, just return its id, otherwise, create it.
94 * The internal storage memory is allocated if needed.
95 * The SMDS_UnstructuredGrid::_cellIdToDownId vector is completed for vtkUnstructuredGrid cells.
96 * @param vtkId for a vtkUnstructuredGrid cell or -1 (default) for a created downward cell.
97 * @return the rank in downward[vtkType] structure.
99 int SMDS_Downward::addCell(int vtkId)
103 localId = _grid->CellIdToDownId(vtkId);
107 localId = this->_maxId;
109 this->allocate(_maxId);
112 this->_vtkCellIds[localId] = vtkId;
113 _grid->setCellIdToDownId(vtkId, localId);
115 this->initCell(localId);
119 /*! generic method do nothing. see derived methods
123 void SMDS_Downward::initCell(int cellId)
127 /*! Get the number of downward entities associated to a cell (always the same for a given vtk type of cell)
129 * @param cellId not used here.
132 int SMDS_Downward::getNumberOfDownCells(int cellId)
137 /*! get a pointer on the downward entities id's associated to a cell.
138 * @see SMDS_Downward::getNumberOfDownCells for the number of downward entities.
139 * @see SMDS_Downward::getDownTypes for the vtk cell types associated to the downward entities.
140 * @param cellId index of the cell in the downward structure relative to a given vtk cell type.
141 * @return table of downward entities id's.
143 const int* SMDS_Downward::getDownCells(int cellId)
145 //ASSERT((cellId >=0) && (cellId < _maxId));
146 return &_cellIds[_nbDownCells * cellId];
149 /*! get a list of vtk cell types associated to downward entities of a given cell, in the same order
150 * than the downward entities id's list (@see SMDS_Downward::getDownCells).
152 * @param cellId index of the cell in the downward structure relative to a vtk cell type.
153 * @return table of downward entities types.
155 const unsigned char* SMDS_Downward::getDownTypes(int cellId)
157 return &_cellTypes[0];
160 /*! add a downward entity of dimension n-1 (cell or node) to a given cell.
161 * Actual implementation is done in derived methods.
162 * @param cellId index of the parent cell (dimension n) in the downward structure relative to a vtk cell type.
163 * @param lowCellId index of the children cell to add (dimension n-1)
164 * @param aType vtk cell type of the cell to add (needed to find the SMDS_Downward structure containing the cell to add).
166 void SMDS_Downward::addDownCell(int cellId, int lowCellId, unsigned char aType)
168 ASSERT(0); // must be re-implemented in derived class
171 /*! add a downward entity of dimension n+1 to a given cell.
172 * Actual implementation is done in derived methods.
173 * @param cellId index of the children cell (dimension n) in the downward structure relative to a vtk cell type.
174 * @param upCellId index of the parent cell to add (dimension n+1)
175 * @param aType vtk cell type of the cell to add (needed to find the SMDS_Downward structure containing the cell to add).
177 void SMDS_Downward::addUpCell(int cellId, int upCellId, unsigned char aType)
179 ASSERT(0); // must be re-implemented in derived class
182 int SMDS_Downward::getNodeSet(int cellId, int* nodeSet)
187 // ---------------------------------------------------------------------------
189 SMDS_Down1D::SMDS_Down1D(SMDS_UnstructuredGrid *grid, int nbDownCells) :
190 SMDS_Downward(grid, nbDownCells)
192 _upCellIdsVector.clear();
193 _upCellTypesVector.clear();
195 _upCellTypes.clear();
196 _upCellIndex.clear();
199 SMDS_Down1D::~SMDS_Down1D()
203 /*! clear vectors used to reference 2D cells containing the edge
207 void SMDS_Down1D::initCell(int cellId)
209 _upCellIdsVector[cellId].clear();
210 _upCellTypesVector[cellId].clear();
213 /*! Resize the downward connectivity storage vector if needed.
215 * @param nbElems total number of elements of the same type required
217 void SMDS_Down1D::allocate(int nbElems)
219 if (nbElems >= _vtkCellIds.size())
221 _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1);
222 _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1);
223 _upCellIdsVector.resize(nbElems + SMDS_Mesh::chunkSize);
224 _upCellTypesVector.resize(nbElems + SMDS_Mesh::chunkSize);
228 void SMDS_Down1D::compactStorage()
230 _cellIds.resize(_nbDownCells * _maxId);
231 _vtkCellIds.resize(_maxId);
234 for (int i = 0; i < _maxId; i++)
235 sizeUpCells += _upCellIdsVector[i].size();
236 _upCellIds.resize(sizeUpCells, -1);
237 _upCellTypes.resize(sizeUpCells);
238 _upCellIndex.resize(_maxId + 1, -1); // id and types of rank i correspond to [ _upCellIndex[i], _upCellIndex[i+1] [
240 for (int i = 0; i < _maxId; i++)
242 _upCellIndex[i] = current;
243 for (int j = 0; j < _upCellIdsVector[i].size(); j++)
245 _upCellIds[current] = _upCellIdsVector[i][j];
246 _upCellTypes[current] = _upCellTypesVector[i][j];
250 _upCellIndex[_maxId] = current;
252 _upCellIdsVector.clear();
253 _upCellTypesVector.clear();
256 void SMDS_Down1D::addUpCell(int cellId, int upCellId, unsigned char aType)
258 //ASSERT((cellId >=0) && (cellId < _maxId));
259 int nbFaces = _upCellIdsVector[cellId].size();
260 for (int i = 0; i < nbFaces; i++)
262 if ((_upCellIdsVector[cellId][i] == upCellId) && (_upCellTypesVector[cellId][i] == aType))
264 return; // already done
267 _upCellIdsVector[cellId].push_back(upCellId);
268 _upCellTypesVector[cellId].push_back(aType);
271 int SMDS_Down1D::getNumberOfUpCells(int cellId)
273 //ASSERT((cellId >=0) && (cellId < _maxId));
274 return _upCellIndex[cellId + 1] - _upCellIndex[cellId];
277 const int* SMDS_Down1D::getUpCells(int cellId)
279 //ASSERT((cellId >=0) && (cellId < _maxId));
280 return &_upCellIds[_upCellIndex[cellId]];
283 const unsigned char* SMDS_Down1D::getUpTypes(int cellId)
285 //ASSERT((cellId >=0) && (cellId < _maxId));
286 return &_upCellTypes[_upCellIndex[cellId]];
289 void SMDS_Down1D::getNodeIds(int cellId, std::set<int>& nodeSet)
291 for (int i = 0; i < _nbDownCells; i++)
292 nodeSet.insert(_cellIds[_nbDownCells * cellId + i]);
295 int SMDS_Down1D::getNodeSet(int cellId, int* nodeSet)
297 for (int i = 0; i < _nbDownCells; i++)
298 nodeSet[i] = _cellIds[_nbDownCells * cellId + i];
302 void SMDS_Down1D::setNodes(int cellId, int vtkId)
305 vtkIdType *pts; // will refer to the point id's of the face
306 _grid->GetCellPoints(vtkId, npts, pts);
307 // MESSAGE(vtkId << " " << npts << " " << _nbDownCells);
308 //ASSERT(npts == _nbDownCells);
309 for (int i = 0; i < npts; i++)
311 _cellIds[_nbDownCells * cellId + i] = pts[i];
315 void SMDS_Down1D::setNodes(int cellId, const int* nodeIds)
317 //ASSERT(nodeIds.size() == _nbDownCells);
318 for (int i = 0; i < _nbDownCells; i++)
320 _cellIds[_nbDownCells * cellId + i] = nodeIds[i];
324 /*! Build the list of vtkUnstructuredGrid cells containing the edge.
325 * We keep in the list the cells that contains all the nodes, we keep only volumes and faces.
326 * @param cellId id of the edge in the downward structure
327 * @param vtkIds vector of vtk id's
328 * @return number of vtk cells (size of vector)
330 int SMDS_Down1D::computeVtkCells(int cellId, std::vector<int>& vtkIds)
334 // --- find all the cells the points belong to, and how many of the points belong to a given cell
336 int *pts = &_cellIds[_nbDownCells * cellId];
337 int ncells = this->computeVtkCells(pts, vtkIds);
341 /*! Build the list of vtkUnstructuredGrid cells containing the edge.
343 * @param pts list of points id's defining an edge
344 * @param vtkIds vector of vtk id's
345 * @return number of vtk cells (size of vector)
347 int SMDS_Down1D::computeVtkCells(int *pts, std::vector<int>& vtkIds)
350 // --- find all the cells the points belong to, and how many of the points belong to a given cell
355 for (int i = 0; i < _nbDownCells; i++)
357 vtkIdType point = pts[i];
358 int numCells = _grid->GetLinks()->GetNcells(point);
359 vtkIdType *cells = _grid->GetLinks()->GetCells(point);
360 for (int j = 0; j < numCells; j++)
362 int vtkCellId = cells[j];
364 for (int k = 0; k < cnt; k++)
366 if (cellIds[k] == vtkCellId)
375 cellIds[cnt] = vtkCellId;
377 // TODO ASSERT(cnt<1000);
383 // --- find the face and volume cells: they contains all the points and are of type volume or face
386 for (int i = 0; i < cnt; i++)
388 if (cellCnt[i] == _nbDownCells)
390 int vtkElemId = cellIds[i];
391 int vtkType = _grid->GetCellType(vtkElemId);
392 if (SMDS_Downward::getCellDimension(vtkType) > 1)
394 vtkIds.push_back(vtkElemId);
403 /*! Build the list of downward faces from a list of vtk cells.
405 * @param cellId id of the edge in the downward structure
406 * @param vtkIds vector of vtk id's
407 * @param downFaces vector of face id's in downward structures
408 * @param downTypes vector of face types
409 * @return number of downward faces
411 int SMDS_Down1D::computeFaces(int cellId, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes)
413 int *pts = &_cellIds[_nbDownCells * cellId];
414 int nbFaces = this->computeFaces(pts, vtkIds, nbcells, downFaces, downTypes);
418 /*! Build the list of downward faces from a list of vtk cells.
420 * @param pts list of points id's defining an edge
421 * @param vtkIds vector of vtk id's
422 * @param downFaces vector of face id's in downward structures
423 * @param downTypes vector of face types
424 * @return number of downward faces
426 int SMDS_Down1D::computeFaces(int* pts, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes)
429 for (int i = 0; i < nbcells; i++)
431 int vtkId = vtkIds[i];
432 int vtkType = _grid->GetCellType(vtkId);
433 if (SMDS_Downward::getCellDimension(vtkType) == 2)
435 int faceId = _grid->CellIdToDownId(vtkId);
436 downFaces[cnt] = faceId;
437 downTypes[cnt] = vtkType;
440 else if (SMDS_Downward::getCellDimension(vtkType) == 3)
442 int volId = _grid->CellIdToDownId(vtkId);
443 SMDS_Downward * downvol = _grid->getDownArray(vtkType);
444 //const int *downIds = downvol->getDownCells(volId);
445 const unsigned char* downTypesVol = downvol->getDownTypes(volId);
446 int nbFaces = downvol->getNumberOfDownCells(volId);
447 const int* faceIds = downvol->getDownCells(volId);
448 for (int n = 0; n < nbFaces; n++)
450 SMDS_Down2D *downFace = static_cast<SMDS_Down2D*> (_grid->getDownArray(downTypesVol[n]));
451 bool isInFace = downFace->isInFace(faceIds[n], pts, _nbDownCells);
454 bool alreadySet = false;
455 for (int k = 0; k < cnt; k++)
456 if (faceIds[n] == downFaces[k])
463 downFaces[cnt] = faceIds[n];
464 downTypes[cnt] = downTypesVol[n];
474 // ---------------------------------------------------------------------------
476 SMDS_Down2D::SMDS_Down2D(SMDS_UnstructuredGrid *grid, int nbDownCells) :
477 SMDS_Downward(grid, nbDownCells)
480 _upCellTypes.clear();
485 SMDS_Down2D::~SMDS_Down2D()
489 int SMDS_Down2D::getNumberOfUpCells(int cellId)
492 if (_upCellIds[2 * cellId] >= 0)
494 if (_upCellIds[2 * cellId + 1] >= 0)
499 const int* SMDS_Down2D::getUpCells(int cellId)
501 //ASSERT((cellId >=0) && (cellId < _maxId));
502 return &_upCellIds[2 * cellId];
505 const unsigned char* SMDS_Down2D::getUpTypes(int cellId)
507 //ASSERT((cellId >=0) && (cellId < _maxId));
508 return &_upCellTypes[2 * cellId];
511 void SMDS_Down2D::getNodeIds(int cellId, std::set<int>& nodeSet)
513 for (int i = 0; i < _nbDownCells; i++)
515 int downCellId = _cellIds[_nbDownCells * cellId + i];
516 unsigned char cellType = _cellTypes[i];
517 this->_grid->getDownArray(cellType)->getNodeIds(downCellId, nodeSet);
521 /*! Find in vtkUnstructuredGrid the volumes containing a face already stored in vtkUnstructuredGrid.
522 * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses
523 * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes.
524 * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid.
525 * @param cellId the face cell id in vkUnstructuredGrid
526 * @param ids a couple of vtkId, initialized at -1 (no parent volume)
527 * @return number of volumes (0, 1 or 2)
529 int SMDS_Down2D::computeVolumeIds(int cellId, int* ids)
531 // --- find point id's of the face
534 vtkIdType *pts; // will refer to the point id's of the face
535 _grid->GetCellPoints(cellId, npts, pts);
537 for (int i = 0; i < npts; i++)
538 nodes.push_back(pts[i]);
539 int nvol = this->computeVolumeIdsFromNodesFace(&nodes[0], npts, ids);
543 /*! Find in vtkUnstructuredGrid the volumes containing a face described by it's nodes
544 * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses
545 * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes.
546 * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid.
548 * @param ids a couple of vtkId, initialized at -1 (no parent volume)
549 * @return number of volumes (0, 1 or 2)
551 int SMDS_Down2D::computeVolumeIds(ElemByNodesType& faceByNodes, int* ids)
553 int nvol = this->computeVolumeIdsFromNodesFace(&faceByNodes.nodeIds[0], faceByNodes.nbNodes, ids);
557 /*! Find in vtkUnstructuredGrid the volumes containing a face described by it's nodes
558 * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses
559 * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes.
560 * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid.
561 * @param pts array of vtk node id's
562 * @param npts number of nodes
564 * @return number of volumes (0, 1 or 2)
566 int SMDS_Down2D::computeVolumeIdsFromNodesFace(int* pts, int npts, int* ids)
569 // --- find all the cells the points belong to, and how many of the points belong to a given cell
574 for (int i = 0; i < npts; i++)
576 vtkIdType point = pts[i];
577 int numCells = _grid->GetLinks()->GetNcells(point);
578 //MESSAGE("cells pour " << i << " " << numCells);
579 vtkIdType *cells = _grid->GetLinks()->GetCells(point);
580 for (int j = 0; j < numCells; j++)
582 int vtkCellId = cells[j];
584 for (int k = 0; k < cnt; k++)
586 if (cellIds[k] == vtkCellId)
595 cellIds[cnt] = vtkCellId;
597 // TODO ASSERT(cnt<1000);
603 // --- find the volume cells: they contains all the points and are of type volume
606 for (int i = 0; i < cnt; i++)
608 //MESSAGE("cell " << cellIds[i] << " points " << cellCnt[i]);
609 if (cellCnt[i] == npts)
611 int vtkElemId = cellIds[i];
612 int vtkType = _grid->GetCellType(vtkElemId);
613 if (SMDS_Downward::getCellDimension(vtkType) == 3)
615 ids[nvol] = vtkElemId; // store the volume id in given vector
626 void SMDS_Down2D::setTempNodes(int cellId, int vtkId)
629 vtkIdType *pts; // will refer to the point id's of the face
630 _grid->GetCellPoints(vtkId, npts, pts);
631 // MESSAGE(vtkId << " " << npts << " " << _nbNodes);
632 //ASSERT(npts == _nbNodes);
633 for (int i = 0; i < npts; i++)
635 _tempNodes[_nbNodes * cellId + i] = pts[i];
639 void SMDS_Down2D::setTempNodes(int cellId, ElemByNodesType& faceByNodes)
641 for (int i = 0; i < faceByNodes.nbNodes; i++)
642 _tempNodes[_nbNodes * cellId + i] = faceByNodes.nodeIds[i];
645 /*! Find if all the nodes belongs to the face.
647 * @param cellId the face cell Id
648 * @param nodeSet set of node id's to be found in the face list of nodes
651 bool SMDS_Down2D::isInFace(int cellId, int *pts, int npts)
654 int *nodes = &_tempNodes[_nbNodes * cellId];
655 for (int j = 0; j < npts; j++)
658 for (int i = 0; i < _nbNodes; i++)
660 if (nodes[i] == point)
667 return (nbFound == npts);
670 /*! Resize the downward connectivity storage vector if needed.
672 * @param nbElems total number of elements of the same type required
674 void SMDS_Down2D::allocate(int nbElems)
676 if (nbElems >= _vtkCellIds.size())
678 _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1);
679 _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1);
680 _upCellIds.resize(2 * (nbElems + SMDS_Mesh::chunkSize), -1);
681 _upCellTypes.resize(2 * (nbElems + SMDS_Mesh::chunkSize), -1);
682 _tempNodes.resize(_nbNodes * (nbElems + SMDS_Mesh::chunkSize), -1);
686 void SMDS_Down2D::compactStorage()
688 _cellIds.resize(_nbDownCells * _maxId);
689 _upCellIds.resize(2 * _maxId);
690 _upCellTypes.resize(2 * _maxId);
691 _vtkCellIds.resize(_maxId);
695 void SMDS_Down2D::addUpCell(int cellId, int upCellId, unsigned char aType)
697 //ASSERT((cellId >=0)&& (cellId < _maxId));
698 int *vols = &_upCellIds[2 * cellId];
699 unsigned char *types = &_upCellTypes[2 * cellId];
700 for (int i = 0; i < 2; i++)
704 vols[i] = upCellId; // use non affected volume
708 if ((vols[i] == upCellId) && (types[i] == aType)) // already done
714 int SMDS_Down2D::getNodeSet(int cellId, int* nodeSet)
716 for (int i = 0; i < _nbNodes; i++)
717 nodeSet[i] = _tempNodes[_nbNodes * cellId + i];
721 int SMDS_Down2D::FindEdgeByNodes(int cellId, ElemByNodesType& edgeByNodes)
723 int *edges = &_cellIds[_nbDownCells * cellId];
724 for (int i = 0; i < _nbDownCells; i++)
726 if ((edges[i] >= 0) && (edgeByNodes.vtkType == _cellTypes[i]))
729 int npts = this->_grid->getDownArray(edgeByNodes.vtkType)->getNodeSet(edges[i], nodeSet);
731 for (int j = 0; j < npts; j++)
733 int point = edgeByNodes.nodeIds[j];
735 for (int k = 0; k < npts; k++)
737 if (nodeSet[k] == point)
753 // ---------------------------------------------------------------------------
755 SMDS_Down3D::SMDS_Down3D(SMDS_UnstructuredGrid *grid, int nbDownCells) :
756 SMDS_Downward(grid, nbDownCells)
760 SMDS_Down3D::~SMDS_Down3D()
764 void SMDS_Down3D::allocate(int nbElems)
766 if (nbElems >= _vtkCellIds.size())
768 _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1);
769 _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1);
773 void SMDS_Down3D::compactStorage()
775 // nothing to do, size was known before
778 int SMDS_Down3D::getNumberOfUpCells(int cellId)
783 const int* SMDS_Down3D::getUpCells(int cellId)
788 const unsigned char* SMDS_Down3D::getUpTypes(int cellId)
793 void SMDS_Down3D::getNodeIds(int cellId, std::set<int>& nodeSet)
795 int vtkId = this->_vtkCellIds[cellId];
797 vtkIdType *nodes; // will refer to the point id's of the volume
798 _grid->GetCellPoints(vtkId, npts, nodes);
799 for (int i = 0; i < npts; i++)
800 nodeSet.insert(nodes[i]);
803 int SMDS_Down3D::FindFaceByNodes(int cellId, ElemByNodesType& faceByNodes)
805 int *faces = &_cellIds[_nbDownCells * cellId];
808 for (int i = 0; i < _nbDownCells; i++)
810 if ((faces[i] >= 0) && (faceByNodes.vtkType == _cellTypes[i]))
813 npoints = faceByNodes.nbNodes;
816 int npts = this->_grid->getDownArray(faceByNodes.vtkType)->getNodeSet(faces[i], nodeSet);
818 continue; // skip this face
820 for (int j = 0; j < npts; j++)
822 int point = faceByNodes.nodeIds[j];
824 for (int k = 0; k < npts; k++)
826 if (nodeSet[k] == point)
829 break; // point j is in the 2 faces, skip remaining k values
833 break; // point j is not in the 2 faces, skip the remaining tests
842 // ---------------------------------------------------------------------------
844 SMDS_DownEdge::SMDS_DownEdge(SMDS_UnstructuredGrid *grid) :
847 _cellTypes.push_back(VTK_VERTEX);
848 _cellTypes.push_back(VTK_VERTEX);
851 SMDS_DownEdge::~SMDS_DownEdge()
855 // ---------------------------------------------------------------------------
857 SMDS_DownQuadEdge::SMDS_DownQuadEdge(SMDS_UnstructuredGrid *grid) :
860 _cellTypes.push_back(VTK_VERTEX);
861 _cellTypes.push_back(VTK_VERTEX);
862 _cellTypes.push_back(VTK_VERTEX);
865 SMDS_DownQuadEdge::~SMDS_DownQuadEdge()
869 // ---------------------------------------------------------------------------
871 SMDS_DownTriangle::SMDS_DownTriangle(SMDS_UnstructuredGrid *grid) :
874 _cellTypes.push_back(VTK_LINE);
875 _cellTypes.push_back(VTK_LINE);
876 _cellTypes.push_back(VTK_LINE);
880 SMDS_DownTriangle::~SMDS_DownTriangle()
884 void SMDS_DownTriangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
886 int *nodes = &_tempNodes[_nbNodes * cellId];
887 edgesWithNodes.nbElems = 3;
889 edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
890 edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
891 edgesWithNodes.elems[0].nbNodes = 2;
892 edgesWithNodes.elems[0].vtkType = VTK_LINE;
894 edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
895 edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
896 edgesWithNodes.elems[1].nbNodes = 2;
897 edgesWithNodes.elems[1].vtkType = VTK_LINE;
899 edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
900 edgesWithNodes.elems[2].nodeIds[1] = nodes[0];
901 edgesWithNodes.elems[2].nbNodes = 2;
902 edgesWithNodes.elems[2].vtkType = VTK_LINE;
905 void SMDS_DownTriangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
907 //ASSERT((cellId >=0)&& (cellId < _maxId));
908 //ASSERT(aType == VTK_LINE);
909 int *faces = &_cellIds[_nbDownCells * cellId];
910 for (int i = 0; i < _nbDownCells; i++)
914 faces[i] = lowCellId;
917 if (faces[i] == lowCellId)
923 // ---------------------------------------------------------------------------
925 SMDS_DownQuadTriangle::SMDS_DownQuadTriangle(SMDS_UnstructuredGrid *grid) :
928 _cellTypes.push_back(VTK_QUADRATIC_EDGE);
929 _cellTypes.push_back(VTK_QUADRATIC_EDGE);
930 _cellTypes.push_back(VTK_QUADRATIC_EDGE);
934 SMDS_DownQuadTriangle::~SMDS_DownQuadTriangle()
938 void SMDS_DownQuadTriangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
940 int *nodes = &_tempNodes[_nbNodes * cellId];
941 edgesWithNodes.nbElems = 3;
943 edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
944 edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
945 edgesWithNodes.elems[0].nodeIds[2] = nodes[3];
946 edgesWithNodes.elems[0].nbNodes = 3;
947 edgesWithNodes.elems[0].vtkType = VTK_QUADRATIC_EDGE;
949 edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
950 edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
951 edgesWithNodes.elems[1].nodeIds[2] = nodes[4];
952 edgesWithNodes.elems[1].nbNodes = 3;
953 edgesWithNodes.elems[1].vtkType = VTK_QUADRATIC_EDGE;
955 edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
956 edgesWithNodes.elems[2].nodeIds[1] = nodes[0];
957 edgesWithNodes.elems[2].nodeIds[2] = nodes[5];
958 edgesWithNodes.elems[2].nbNodes = 3;
959 edgesWithNodes.elems[2].vtkType = VTK_QUADRATIC_EDGE;
962 void SMDS_DownQuadTriangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
964 //ASSERT((cellId >=0)&& (cellId < _maxId));
965 //ASSERT(aType == VTK_QUADRATIC_EDGE);
966 int *edges = &_cellIds[_nbDownCells * cellId];
967 for (int i = 0; i < _nbDownCells; i++)
971 edges[i] = lowCellId;
974 if (edges[i] == lowCellId)
980 // ---------------------------------------------------------------------------
982 SMDS_DownQuadrangle::SMDS_DownQuadrangle(SMDS_UnstructuredGrid *grid) :
985 _cellTypes.push_back(VTK_LINE);
986 _cellTypes.push_back(VTK_LINE);
987 _cellTypes.push_back(VTK_LINE);
988 _cellTypes.push_back(VTK_LINE);
992 SMDS_DownQuadrangle::~SMDS_DownQuadrangle()
996 void SMDS_DownQuadrangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
998 int *nodes = &_tempNodes[_nbNodes * cellId];
999 edgesWithNodes.nbElems = 4;
1001 edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
1002 edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
1003 edgesWithNodes.elems[0].nbNodes = 2;
1004 edgesWithNodes.elems[0].vtkType = VTK_LINE;
1006 edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
1007 edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
1008 edgesWithNodes.elems[1].nbNodes = 2;
1009 edgesWithNodes.elems[1].vtkType = VTK_LINE;
1011 edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
1012 edgesWithNodes.elems[2].nodeIds[1] = nodes[3];
1013 edgesWithNodes.elems[2].nbNodes = 2;
1014 edgesWithNodes.elems[2].vtkType = VTK_LINE;
1016 edgesWithNodes.elems[3].nodeIds[0] = nodes[3];
1017 edgesWithNodes.elems[3].nodeIds[1] = nodes[0];
1018 edgesWithNodes.elems[3].nbNodes = 2;
1019 edgesWithNodes.elems[3].vtkType = VTK_LINE;
1022 void SMDS_DownQuadrangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
1024 //ASSERT((cellId >=0)&& (cellId < _maxId));
1025 //ASSERT(aType == VTK_LINE);
1026 int *faces = &_cellIds[_nbDownCells * cellId];
1027 for (int i = 0; i < _nbDownCells; i++)
1031 faces[i] = lowCellId;
1034 if (faces[i] == lowCellId)
1040 // ---------------------------------------------------------------------------
1042 SMDS_DownQuadQuadrangle::SMDS_DownQuadQuadrangle(SMDS_UnstructuredGrid *grid) :
1043 SMDS_Down2D(grid, 4)
1045 _cellTypes.push_back(VTK_QUADRATIC_EDGE);
1046 _cellTypes.push_back(VTK_QUADRATIC_EDGE);
1047 _cellTypes.push_back(VTK_QUADRATIC_EDGE);
1048 _cellTypes.push_back(VTK_QUADRATIC_EDGE);
1052 SMDS_DownQuadQuadrangle::~SMDS_DownQuadQuadrangle()
1056 void SMDS_DownQuadQuadrangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
1058 int *nodes = &_tempNodes[_nbNodes * cellId];
1059 edgesWithNodes.nbElems = 4;
1061 edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
1062 edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
1063 edgesWithNodes.elems[0].nodeIds[2] = nodes[4];
1064 edgesWithNodes.elems[0].nbNodes = 3;
1065 edgesWithNodes.elems[0].vtkType = VTK_QUADRATIC_EDGE;
1067 edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
1068 edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
1069 edgesWithNodes.elems[1].nodeIds[2] = nodes[5];
1070 edgesWithNodes.elems[1].nbNodes = 3;
1071 edgesWithNodes.elems[1].vtkType = VTK_QUADRATIC_EDGE;
1073 edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
1074 edgesWithNodes.elems[2].nodeIds[1] = nodes[3];
1075 edgesWithNodes.elems[2].nodeIds[2] = nodes[6];
1076 edgesWithNodes.elems[2].nbNodes = 3;
1077 edgesWithNodes.elems[2].vtkType = VTK_QUADRATIC_EDGE;
1079 edgesWithNodes.elems[3].nodeIds[0] = nodes[3];
1080 edgesWithNodes.elems[3].nodeIds[1] = nodes[0];
1081 edgesWithNodes.elems[3].nodeIds[2] = nodes[7];
1082 edgesWithNodes.elems[3].nbNodes = 3;
1083 edgesWithNodes.elems[3].vtkType = VTK_QUADRATIC_EDGE;
1086 void SMDS_DownQuadQuadrangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
1088 //ASSERT((cellId >=0)&& (cellId < _maxId));
1089 //ASSERT(aType == VTK_QUADRATIC_EDGE);
1090 int *faces = &_cellIds[_nbDownCells * cellId];
1091 for (int i = 0; i < _nbDownCells; i++)
1095 faces[i] = lowCellId;
1098 if (faces[i] == lowCellId)
1104 // ---------------------------------------------------------------------------
1106 SMDS_DownTetra::SMDS_DownTetra(SMDS_UnstructuredGrid *grid) :
1107 SMDS_Down3D(grid, 4)
1109 _cellTypes.push_back(VTK_TRIANGLE);
1110 _cellTypes.push_back(VTK_TRIANGLE);
1111 _cellTypes.push_back(VTK_TRIANGLE);
1112 _cellTypes.push_back(VTK_TRIANGLE);
1115 SMDS_DownTetra::~SMDS_DownTetra()
1119 void SMDS_DownTetra::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
1123 for (int i = 0; i < orderedNodes.size(); i++)
1124 setNodes.insert(orderedNodes[i]);
1125 //MESSAGE("cellId = " << cellId);
1128 vtkIdType *nodes; // will refer to the point id's of the volume
1129 _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
1132 int ids[12] = { 0, 1, 2, 0, 3, 1, 2, 3, 0, 1, 3, 2 };
1133 //int ids[12] = { 2, 1, 0, 1, 3, 0, 0, 3, 2, 2, 3, 1 };
1134 for (int k = 0; k < 4; k++)
1137 for (int i = 0; i < 3; i++)
1138 tofind.insert(nodes[ids[3 * k + i]]);
1139 if (setNodes == tofind)
1141 for (int i = 0; i < 3; i++)
1142 orderedNodes[i] = nodes[ids[3 * k + i]];
1146 MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
1147 MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
1148 MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
1151 void SMDS_DownTetra::addDownCell(int cellId, int lowCellId, unsigned char aType)
1153 //ASSERT((cellId >=0)&& (cellId < _maxId));
1154 //ASSERT(aType == VTK_TRIANGLE);
1155 int *faces = &_cellIds[_nbDownCells * cellId];
1156 for (int i = 0; i < _nbDownCells; i++)
1160 faces[i] = lowCellId;
1163 if (faces[i] == lowCellId)
1169 /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's
1170 * The linear tetrahedron is defined by four points.
1171 * @see vtkTetra.h in Filtering.
1172 * @param cellId volumeId in vtkUnstructuredGrid
1173 * @param facesWithNodes vector of face descriptors to be filled
1175 void SMDS_DownTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
1177 // --- find point id's of the volume
1180 vtkIdType *nodes; // will refer to the point id's of the volume
1181 _grid->GetCellPoints(cellId, npts, nodes);
1183 // --- create all the ordered list of node id's for each face
1185 facesWithNodes.nbElems = 4;
1187 facesWithNodes.elems[0].nodeIds[0] = nodes[0];
1188 facesWithNodes.elems[0].nodeIds[1] = nodes[1];
1189 facesWithNodes.elems[0].nodeIds[2] = nodes[2];
1190 facesWithNodes.elems[0].nbNodes = 3;
1191 facesWithNodes.elems[0].vtkType = VTK_TRIANGLE;
1193 facesWithNodes.elems[1].nodeIds[0] = nodes[0];
1194 facesWithNodes.elems[1].nodeIds[1] = nodes[1];
1195 facesWithNodes.elems[1].nodeIds[2] = nodes[3];
1196 facesWithNodes.elems[1].nbNodes = 3;
1197 facesWithNodes.elems[1].vtkType = VTK_TRIANGLE;
1199 facesWithNodes.elems[2].nodeIds[0] = nodes[0];
1200 facesWithNodes.elems[2].nodeIds[1] = nodes[2];
1201 facesWithNodes.elems[2].nodeIds[2] = nodes[3];
1202 facesWithNodes.elems[2].nbNodes = 3;
1203 facesWithNodes.elems[2].vtkType = VTK_TRIANGLE;
1205 facesWithNodes.elems[3].nodeIds[0] = nodes[1];
1206 facesWithNodes.elems[3].nodeIds[1] = nodes[2];
1207 facesWithNodes.elems[3].nodeIds[2] = nodes[3];
1208 facesWithNodes.elems[3].nbNodes = 3;
1209 facesWithNodes.elems[3].vtkType = VTK_TRIANGLE;
1212 // ---------------------------------------------------------------------------
1214 SMDS_DownQuadTetra::SMDS_DownQuadTetra(SMDS_UnstructuredGrid *grid) :
1215 SMDS_Down3D(grid, 4)
1217 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1218 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1219 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1220 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1223 SMDS_DownQuadTetra::~SMDS_DownQuadTetra()
1227 void SMDS_DownQuadTetra::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
1231 for (int i = 0; i < orderedNodes.size(); i++)
1232 setNodes.insert(orderedNodes[i]);
1233 //MESSAGE("cellId = " << cellId);
1236 vtkIdType *nodes; // will refer to the point id's of the volume
1237 _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
1240 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 };
1241 //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 };
1242 for (int k = 0; k < 4; k++)
1245 for (int i = 0; i < 6; i++)
1246 tofind.insert(nodes[ids[6 * k + i]]);
1247 if (setNodes == tofind)
1249 for (int i = 0; i < 6; i++)
1250 orderedNodes[i] = nodes[ids[6 * k + i]];
1254 MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
1255 MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
1256 MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
1259 void SMDS_DownQuadTetra::addDownCell(int cellId, int lowCellId, unsigned char aType)
1261 //ASSERT((cellId >=0)&& (cellId < _maxId));
1262 //ASSERT(aType == VTK_QUADRATIC_TRIANGLE);
1263 int *faces = &_cellIds[_nbDownCells * cellId];
1264 for (int i = 0; i < _nbDownCells; i++)
1268 faces[i] = lowCellId;
1271 if (faces[i] == lowCellId)
1277 /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's
1278 * The ordering of the ten points defining the quadratic tetrahedron cell is point id's (0-3,4-9)
1279 * where id's 0-3 are the four tetrahedron vertices;
1280 * and point id's 4-9 are the mid-edge nodes between (0,1), (1,2), (2,0), (0,3), (1,3), and (2,3).
1281 * @see vtkQuadraticTetra.h in Filtering.
1282 * @param cellId volumeId in vtkUnstructuredGrid
1283 * @param facesWithNodes vector of face descriptors to be filled
1285 void SMDS_DownQuadTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
1287 // --- find point id's of the volume
1290 vtkIdType *nodes; // will refer to the point id's of the volume
1291 _grid->GetCellPoints(cellId, npts, nodes);
1293 // --- create all the ordered list of node id's for each face
1295 facesWithNodes.nbElems = 4;
1297 facesWithNodes.elems[0].nodeIds[0] = nodes[0];
1298 facesWithNodes.elems[0].nodeIds[1] = nodes[1];
1299 facesWithNodes.elems[0].nodeIds[2] = nodes[2];
1300 facesWithNodes.elems[0].nodeIds[3] = nodes[4];
1301 facesWithNodes.elems[0].nodeIds[4] = nodes[5];
1302 facesWithNodes.elems[0].nodeIds[5] = nodes[6];
1303 facesWithNodes.elems[0].nbNodes = 6;
1304 facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_TRIANGLE;
1306 facesWithNodes.elems[1].nodeIds[0] = nodes[0];
1307 facesWithNodes.elems[1].nodeIds[1] = nodes[1];
1308 facesWithNodes.elems[1].nodeIds[2] = nodes[3];
1309 facesWithNodes.elems[1].nodeIds[3] = nodes[4];
1310 facesWithNodes.elems[1].nodeIds[4] = nodes[8];
1311 facesWithNodes.elems[1].nodeIds[5] = nodes[7];
1312 facesWithNodes.elems[1].nbNodes = 6;
1313 facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE;
1315 facesWithNodes.elems[2].nodeIds[0] = nodes[0];
1316 facesWithNodes.elems[2].nodeIds[1] = nodes[2];
1317 facesWithNodes.elems[2].nodeIds[2] = nodes[3];
1318 facesWithNodes.elems[2].nodeIds[3] = nodes[6];
1319 facesWithNodes.elems[2].nodeIds[4] = nodes[9];
1320 facesWithNodes.elems[2].nodeIds[5] = nodes[7];
1321 facesWithNodes.elems[2].nbNodes = 6;
1322 facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE;
1324 facesWithNodes.elems[3].nodeIds[0] = nodes[1];
1325 facesWithNodes.elems[3].nodeIds[1] = nodes[2];
1326 facesWithNodes.elems[3].nodeIds[2] = nodes[3];
1327 facesWithNodes.elems[3].nodeIds[3] = nodes[5];
1328 facesWithNodes.elems[3].nodeIds[4] = nodes[9];
1329 facesWithNodes.elems[3].nodeIds[5] = nodes[8];
1330 facesWithNodes.elems[3].nbNodes = 6;
1331 facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
1334 // ---------------------------------------------------------------------------
1336 SMDS_DownPyramid::SMDS_DownPyramid(SMDS_UnstructuredGrid *grid) :
1337 SMDS_Down3D(grid, 5)
1339 _cellTypes.push_back(VTK_QUAD);
1340 _cellTypes.push_back(VTK_TRIANGLE);
1341 _cellTypes.push_back(VTK_TRIANGLE);
1342 _cellTypes.push_back(VTK_TRIANGLE);
1343 _cellTypes.push_back(VTK_TRIANGLE);
1346 SMDS_DownPyramid::~SMDS_DownPyramid()
1350 void SMDS_DownPyramid::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
1354 for (int i = 0; i < orderedNodes.size(); i++)
1355 setNodes.insert(orderedNodes[i]);
1356 //MESSAGE("cellId = " << cellId);
1359 vtkIdType *nodes; // will refer to the point id's of the volume
1360 _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
1363 int ids[16] = { 0, 1, 2, 3, 0, 3, 4, 3, 2, 4, 2, 1, 4, 1, 0, 4 };
1366 for (int i = 0; i < 4; i++)
1367 tofind.insert(nodes[ids[i]]);
1368 if (setNodes == tofind)
1370 for (int i = 0; i < 4; i++)
1371 orderedNodes[i] = nodes[ids[i]];
1374 for (int k = 0; k < 4; k++)
1377 for (int i = 0; i < 3; i++)
1378 tofind.insert(nodes[ids[4 + 3 * k + i]]);
1379 if (setNodes == tofind)
1381 for (int i = 0; i < 3; i++)
1382 orderedNodes[i] = nodes[ids[4 + 3 * k + i]];
1386 MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
1387 MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
1388 MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
1391 void SMDS_DownPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType)
1393 //ASSERT((cellId >=0) && (cellId < _maxId));
1394 int *faces = &_cellIds[_nbDownCells * cellId];
1395 if (aType == VTK_QUAD)
1399 faces[0] = lowCellId;
1402 if (faces[0] == lowCellId)
1407 //ASSERT(aType == VTK_TRIANGLE);
1408 for (int i = 1; i < _nbDownCells; i++)
1412 faces[i] = lowCellId;
1415 if (faces[i] == lowCellId)
1422 /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's
1423 * The pyramid is defined by the five points (0-4) where (0,1,2,3) is the base of the pyramid which,
1424 * using the right hand rule, forms a quadrilateral whose normal points in the direction of the
1425 * pyramid apex at vertex #4.
1426 * @see vtkPyramid.h in Filtering.
1427 * @param cellId volumeId in vtkUnstructuredGrid
1428 * @param facesWithNodes vector of face descriptors to be filled
1430 void SMDS_DownPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
1432 // --- find point id's of the volume
1435 vtkIdType *nodes; // will refer to the point id's of the volume
1436 _grid->GetCellPoints(cellId, npts, nodes);
1438 // --- create all the ordered list of node id's for each face
1440 facesWithNodes.nbElems = 5;
1442 facesWithNodes.elems[0].nodeIds[0] = nodes[0];
1443 facesWithNodes.elems[0].nodeIds[1] = nodes[1];
1444 facesWithNodes.elems[0].nodeIds[2] = nodes[2];
1445 facesWithNodes.elems[0].nodeIds[3] = nodes[3];
1446 facesWithNodes.elems[0].nbNodes = 4;
1447 facesWithNodes.elems[0].vtkType = VTK_QUAD;
1449 facesWithNodes.elems[1].nodeIds[0] = nodes[0];
1450 facesWithNodes.elems[1].nodeIds[1] = nodes[1];
1451 facesWithNodes.elems[1].nodeIds[2] = nodes[4];
1452 facesWithNodes.elems[1].nbNodes = 3;
1453 facesWithNodes.elems[1].vtkType = VTK_TRIANGLE;
1455 facesWithNodes.elems[2].nodeIds[0] = nodes[1];
1456 facesWithNodes.elems[2].nodeIds[1] = nodes[2];
1457 facesWithNodes.elems[2].nodeIds[2] = nodes[4];
1458 facesWithNodes.elems[2].nbNodes = 3;
1459 facesWithNodes.elems[2].vtkType = VTK_TRIANGLE;
1461 facesWithNodes.elems[3].nodeIds[0] = nodes[2];
1462 facesWithNodes.elems[3].nodeIds[1] = nodes[3];
1463 facesWithNodes.elems[3].nodeIds[2] = nodes[4];
1464 facesWithNodes.elems[3].nbNodes = 3;
1465 facesWithNodes.elems[3].vtkType = VTK_TRIANGLE;
1467 facesWithNodes.elems[4].nodeIds[0] = nodes[3];
1468 facesWithNodes.elems[4].nodeIds[1] = nodes[0];
1469 facesWithNodes.elems[4].nodeIds[2] = nodes[4];
1470 facesWithNodes.elems[4].nbNodes = 3;
1471 facesWithNodes.elems[4].vtkType = VTK_TRIANGLE;
1474 // ---------------------------------------------------------------------------
1476 SMDS_DownQuadPyramid::SMDS_DownQuadPyramid(SMDS_UnstructuredGrid *grid) :
1477 SMDS_Down3D(grid, 5)
1479 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
1480 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1481 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1482 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1483 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1486 SMDS_DownQuadPyramid::~SMDS_DownQuadPyramid()
1490 void SMDS_DownQuadPyramid::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
1494 for (int i = 0; i < orderedNodes.size(); i++)
1495 setNodes.insert(orderedNodes[i]);
1496 //MESSAGE("cellId = " << cellId);
1499 vtkIdType *nodes; // will refer to the point id's of the volume
1500 _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
1503 int ids[32] = { 0, 1, 2, 3, 5, 6, 7, 8,
1504 0, 3, 4, 8, 12, 9, 3, 2, 4, 7 , 11, 12, 2, 1, 4, 6, 10, 11, 1, 0, 4, 5, 9, 10 };
1507 for (int i = 0; i < 4; i++)
1508 tofind.insert(nodes[ids[i]]);
1509 if (setNodes == tofind)
1511 for (int i = 0; i < 8; i++)
1512 orderedNodes[i] = nodes[ids[i]];
1515 for (int k = 0; k < 4; k++)
1518 for (int i = 0; i < 6; i++)
1519 tofind.insert(nodes[ids[8 + 6 * k + i]]);
1520 if (setNodes == tofind)
1522 for (int i = 0; i < 6; i++)
1523 orderedNodes[i] = nodes[ids[8 + 6 * k + i]];
1527 MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
1528 MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
1529 MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
1532 void SMDS_DownQuadPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType)
1534 //ASSERT((cellId >=0) && (cellId < _maxId));
1535 int *faces = &_cellIds[_nbDownCells * cellId];
1536 if (aType == VTK_QUADRATIC_QUAD)
1540 faces[0] = lowCellId;
1543 if (faces[0] == lowCellId)
1548 //ASSERT(aType == VTK_QUADRATIC_TRIANGLE);
1549 for (int i = 1; i < _nbDownCells; i++)
1553 faces[i] = lowCellId;
1556 if (faces[i] == lowCellId)
1563 /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's
1564 * The ordering of the thirteen points defining the quadratic pyramid cell is point id's (0-4,5-12)
1565 * where point id's 0-4 are the five corner vertices of the pyramid; followed
1566 * by eight mid-edge nodes (5-12). Note that these mid-edge nodes lie on the edges defined by
1567 * 5(0,1), 6(1,2), 7(2,3), 8(3,0), 9(0,4), 10(1,4), 11(2,4), 12(3,4).
1568 * @see vtkQuadraticPyramid.h in Filtering.
1569 * @param cellId volumeId in vtkUnstructuredGrid
1570 * @param facesWithNodes vector of face descriptors to be filled
1572 void SMDS_DownQuadPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
1574 // --- find point id's of the volume
1577 vtkIdType *nodes; // will refer to the point id's of the volume
1578 _grid->GetCellPoints(cellId, npts, nodes);
1580 // --- create all the ordered list of node id's for each face
1582 facesWithNodes.nbElems = 5;
1584 facesWithNodes.elems[0].nodeIds[0] = nodes[0];
1585 facesWithNodes.elems[0].nodeIds[1] = nodes[1];
1586 facesWithNodes.elems[0].nodeIds[2] = nodes[2];
1587 facesWithNodes.elems[0].nodeIds[3] = nodes[3];
1588 facesWithNodes.elems[0].nodeIds[4] = nodes[5];
1589 facesWithNodes.elems[0].nodeIds[5] = nodes[6];
1590 facesWithNodes.elems[0].nodeIds[6] = nodes[7];
1591 facesWithNodes.elems[0].nodeIds[7] = nodes[8];
1592 facesWithNodes.elems[0].nbNodes = 8;
1593 facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD;
1595 facesWithNodes.elems[1].nodeIds[0] = nodes[0];
1596 facesWithNodes.elems[1].nodeIds[1] = nodes[1];
1597 facesWithNodes.elems[1].nodeIds[2] = nodes[4];
1598 facesWithNodes.elems[1].nodeIds[3] = nodes[5];
1599 facesWithNodes.elems[1].nodeIds[4] = nodes[10];
1600 facesWithNodes.elems[1].nodeIds[5] = nodes[9];
1601 facesWithNodes.elems[1].nbNodes = 6;
1602 facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE;
1604 facesWithNodes.elems[2].nodeIds[0] = nodes[1];
1605 facesWithNodes.elems[2].nodeIds[1] = nodes[2];
1606 facesWithNodes.elems[2].nodeIds[2] = nodes[4];
1607 facesWithNodes.elems[2].nodeIds[3] = nodes[6];
1608 facesWithNodes.elems[2].nodeIds[4] = nodes[11];
1609 facesWithNodes.elems[2].nodeIds[5] = nodes[10];
1610 facesWithNodes.elems[2].nbNodes = 6;
1611 facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE;
1613 facesWithNodes.elems[3].nodeIds[0] = nodes[2];
1614 facesWithNodes.elems[3].nodeIds[1] = nodes[3];
1615 facesWithNodes.elems[3].nodeIds[2] = nodes[4];
1616 facesWithNodes.elems[3].nodeIds[3] = nodes[7];
1617 facesWithNodes.elems[3].nodeIds[4] = nodes[12];
1618 facesWithNodes.elems[3].nodeIds[5] = nodes[11];
1619 facesWithNodes.elems[3].nbNodes = 6;
1620 facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
1622 facesWithNodes.elems[4].nodeIds[0] = nodes[3];
1623 facesWithNodes.elems[4].nodeIds[1] = nodes[0];
1624 facesWithNodes.elems[4].nodeIds[2] = nodes[4];
1625 facesWithNodes.elems[4].nodeIds[3] = nodes[8];
1626 facesWithNodes.elems[4].nodeIds[4] = nodes[9];
1627 facesWithNodes.elems[4].nodeIds[5] = nodes[12];
1628 facesWithNodes.elems[4].nbNodes = 6;
1629 facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_TRIANGLE;
1632 // ---------------------------------------------------------------------------
1634 SMDS_DownPenta::SMDS_DownPenta(SMDS_UnstructuredGrid *grid) :
1635 SMDS_Down3D(grid, 5)
1637 _cellTypes.push_back(VTK_QUAD);
1638 _cellTypes.push_back(VTK_QUAD);
1639 _cellTypes.push_back(VTK_QUAD);
1640 _cellTypes.push_back(VTK_TRIANGLE);
1641 _cellTypes.push_back(VTK_TRIANGLE);
1644 SMDS_DownPenta::~SMDS_DownPenta()
1648 void SMDS_DownPenta::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
1652 for (int i = 0; i < orderedNodes.size(); i++)
1653 setNodes.insert(orderedNodes[i]);
1654 //MESSAGE("cellId = " << cellId);
1657 vtkIdType *nodes; // will refer to the point id's of the volume
1658 _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
1661 //int ids[18] = { 0, 2, 1, 3, 4, 5, 0, 1, 4, 3, 1, 2, 5, 4, 2, 0, 3, 5 };
1662 int ids[18] = { 0, 1, 2, 3, 5, 4, 0, 3, 4, 1, 1, 4, 5, 2, 2, 5, 3, 0 };
1664 for (int k = 0; k < 2; k++)
1667 for (int i = 0; i < 3; i++)
1668 tofind.insert(nodes[ids[3 * k + i]]);
1669 if (setNodes == tofind)
1671 for (int i = 0; i < 3; i++)
1672 orderedNodes[i] = nodes[ids[3 * k + i]];
1676 for (int k = 0; k < 3; k++)
1679 for (int i = 0; i < 4; i++)
1680 tofind.insert(nodes[ids[6 + 4 * k + i]]);
1681 if (setNodes == tofind)
1683 for (int i = 0; i < 4; i++)
1684 orderedNodes[i] = nodes[ids[6 + 4 * k + i]];
1688 MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
1689 MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
1690 MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
1693 void SMDS_DownPenta::addDownCell(int cellId, int lowCellId, unsigned char aType)
1695 //ASSERT((cellId >=0) && (cellId < _maxId));
1696 int *faces = &_cellIds[_nbDownCells * cellId];
1697 if (aType == VTK_QUAD)
1698 for (int i = 0; i < 3; i++)
1702 faces[i] = lowCellId;
1705 if (faces[i] == lowCellId)
1710 //ASSERT(aType == VTK_TRIANGLE);
1711 for (int i = 3; i < _nbDownCells; i++)
1715 faces[i] = lowCellId;
1718 if (faces[i] == lowCellId)
1725 /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's.
1726 * A wedge or pentahedron consists of two triangular and three quadrilateral faces
1727 * and is defined by the six points (0-5) where (0,1,2) is the base of the wedge which,
1728 * using the right hand rule, forms a triangle whose normal points outward
1729 * (away from the triangular face (3,4,5)).
1730 * @see vtkWedge.h in Filtering
1731 * @param cellId volumeId in vtkUnstructuredGrid
1732 * @param facesWithNodes vector of face descriptors to be filled
1734 void SMDS_DownPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
1736 // --- find point id's of the volume
1739 vtkIdType *nodes; // will refer to the point id's of the volume
1740 _grid->GetCellPoints(cellId, npts, nodes);
1742 // --- create all the ordered list of node id's for each face
1744 facesWithNodes.nbElems = 5;
1746 facesWithNodes.elems[0].nodeIds[0] = nodes[0];
1747 facesWithNodes.elems[0].nodeIds[1] = nodes[2];
1748 facesWithNodes.elems[0].nodeIds[2] = nodes[5];
1749 facesWithNodes.elems[0].nodeIds[3] = nodes[3];
1750 facesWithNodes.elems[0].nbNodes = 4;
1751 facesWithNodes.elems[0].vtkType = VTK_QUAD;
1753 facesWithNodes.elems[1].nodeIds[0] = nodes[1];
1754 facesWithNodes.elems[1].nodeIds[1] = nodes[2];
1755 facesWithNodes.elems[1].nodeIds[2] = nodes[5];
1756 facesWithNodes.elems[1].nodeIds[3] = nodes[4];
1757 facesWithNodes.elems[1].nbNodes = 4;
1758 facesWithNodes.elems[1].vtkType = VTK_QUAD;
1760 facesWithNodes.elems[2].nodeIds[0] = nodes[0];
1761 facesWithNodes.elems[2].nodeIds[1] = nodes[1];
1762 facesWithNodes.elems[2].nodeIds[2] = nodes[4];
1763 facesWithNodes.elems[2].nodeIds[3] = nodes[3];
1764 facesWithNodes.elems[2].nbNodes = 4;
1765 facesWithNodes.elems[2].vtkType = VTK_QUAD;
1767 facesWithNodes.elems[3].nodeIds[0] = nodes[0];
1768 facesWithNodes.elems[3].nodeIds[1] = nodes[1];
1769 facesWithNodes.elems[3].nodeIds[2] = nodes[2];
1770 facesWithNodes.elems[3].nbNodes = 3;
1771 facesWithNodes.elems[3].vtkType = VTK_TRIANGLE;
1773 facesWithNodes.elems[4].nodeIds[0] = nodes[3];
1774 facesWithNodes.elems[4].nodeIds[1] = nodes[4];
1775 facesWithNodes.elems[4].nodeIds[2] = nodes[5];
1776 facesWithNodes.elems[4].nbNodes = 3;
1777 facesWithNodes.elems[4].vtkType = VTK_TRIANGLE;
1780 // ---------------------------------------------------------------------------
1782 SMDS_DownQuadPenta::SMDS_DownQuadPenta(SMDS_UnstructuredGrid *grid) :
1783 SMDS_Down3D(grid, 5)
1785 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
1786 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
1787 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
1788 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1789 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1792 SMDS_DownQuadPenta::~SMDS_DownQuadPenta()
1796 void SMDS_DownQuadPenta::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
1800 for (int i = 0; i < orderedNodes.size(); i++)
1801 setNodes.insert(orderedNodes[i]);
1802 //MESSAGE("cellId = " << cellId);
1805 vtkIdType *nodes; // will refer to the point id's of the volume
1806 _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
1809 //int ids[18] = { 0, 2, 1, 3, 4, 5, 0, 1, 4, 3, 1, 2, 5, 4, 2, 0, 3, 5 };
1810 int ids[36] = { 0, 1, 2, 6, 7, 8, 3, 5, 4, 11, 10, 9,
1811 0, 3, 4, 1, 12, 9, 13, 6, 1, 4, 5, 2, 13, 10, 14, 7, 2, 5, 3, 0, 14, 11, 12, 8 };
1813 for (int k = 0; k < 2; k++)
1816 for (int i = 0; i < 6; i++)
1817 tofind.insert(nodes[ids[6 * k + i]]);
1818 if (setNodes == tofind)
1820 for (int i = 0; i < 6; i++)
1821 orderedNodes[i] = nodes[ids[6 * k + i]];
1825 for (int k = 0; k < 3; k++)
1828 for (int i = 0; i < 8; i++)
1829 tofind.insert(nodes[ids[12 + 8 * k + i]]);
1830 if (setNodes == tofind)
1832 for (int i = 0; i < 8; i++)
1833 orderedNodes[i] = nodes[ids[12 + 8 * k + i]];
1837 MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
1838 MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
1839 MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
1842 void SMDS_DownQuadPenta::addDownCell(int cellId, int lowCellId, unsigned char aType)
1844 //ASSERT((cellId >=0) && (cellId < _maxId));
1845 int *faces = &_cellIds[_nbDownCells * cellId];
1846 if (aType == VTK_QUADRATIC_QUAD)
1847 for (int i = 0; i < 3; i++)
1851 faces[i] = lowCellId;
1854 if (faces[i] == lowCellId)
1859 //ASSERT(aType == VTK_QUADRATIC_TRIANGLE);
1860 for (int i = 3; i < _nbDownCells; i++)
1864 faces[i] = lowCellId;
1867 if (faces[i] == lowCellId)
1874 /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's
1875 * The quadratic wedge (or pentahedron) is defined by fifteen points.
1876 * The ordering of the fifteen points defining the cell is point id's (0-5,6-14)
1877 * where point id's 0-5 are the six corner vertices of the wedge, followed by
1878 * nine mid-edge nodes (6-14). Note that these mid-edge nodes lie on the edges defined by
1879 * (0,1), (1,2), (2,0), (3,4), (4,5), (5,3), (0,3), (1,4), (2,5).
1880 * @see vtkQuadraticWedge.h in Filtering
1881 * @param cellId volumeId in vtkUnstructuredGrid
1882 * @param facesWithNodes vector of face descriptors to be filled
1884 void SMDS_DownQuadPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
1886 // --- find point id's of the volume
1889 vtkIdType *nodes; // will refer to the point id's of the volume
1890 _grid->GetCellPoints(cellId, npts, nodes);
1892 // --- create all the ordered list of node id's for each face
1894 facesWithNodes.nbElems = 5;
1896 facesWithNodes.elems[0].nodeIds[0] = nodes[0];
1897 facesWithNodes.elems[0].nodeIds[1] = nodes[2];
1898 facesWithNodes.elems[0].nodeIds[2] = nodes[5];
1899 facesWithNodes.elems[0].nodeIds[3] = nodes[3];
1900 facesWithNodes.elems[0].nodeIds[4] = nodes[8];
1901 facesWithNodes.elems[0].nodeIds[5] = nodes[14];
1902 facesWithNodes.elems[0].nodeIds[6] = nodes[11];
1903 facesWithNodes.elems[0].nodeIds[7] = nodes[12];
1904 facesWithNodes.elems[0].nbNodes = 8;
1905 facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD;
1907 facesWithNodes.elems[1].nodeIds[0] = nodes[1];
1908 facesWithNodes.elems[1].nodeIds[1] = nodes[2];
1909 facesWithNodes.elems[1].nodeIds[2] = nodes[5];
1910 facesWithNodes.elems[1].nodeIds[3] = nodes[4];
1911 facesWithNodes.elems[1].nodeIds[4] = nodes[7];
1912 facesWithNodes.elems[1].nodeIds[5] = nodes[14];
1913 facesWithNodes.elems[1].nodeIds[6] = nodes[10];
1914 facesWithNodes.elems[1].nodeIds[7] = nodes[13];
1915 facesWithNodes.elems[1].nbNodes = 8;
1916 facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_QUAD;
1918 facesWithNodes.elems[2].nodeIds[0] = nodes[0];
1919 facesWithNodes.elems[2].nodeIds[1] = nodes[1];
1920 facesWithNodes.elems[2].nodeIds[2] = nodes[4];
1921 facesWithNodes.elems[2].nodeIds[3] = nodes[3];
1922 facesWithNodes.elems[2].nodeIds[4] = nodes[6];
1923 facesWithNodes.elems[2].nodeIds[5] = nodes[13];
1924 facesWithNodes.elems[2].nodeIds[6] = nodes[9];
1925 facesWithNodes.elems[2].nodeIds[7] = nodes[12];
1926 facesWithNodes.elems[2].nbNodes = 8;
1927 facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_QUAD;
1929 facesWithNodes.elems[3].nodeIds[0] = nodes[0];
1930 facesWithNodes.elems[3].nodeIds[1] = nodes[1];
1931 facesWithNodes.elems[3].nodeIds[2] = nodes[2];
1932 facesWithNodes.elems[3].nodeIds[3] = nodes[6];
1933 facesWithNodes.elems[3].nodeIds[4] = nodes[7];
1934 facesWithNodes.elems[3].nodeIds[5] = nodes[8];
1935 facesWithNodes.elems[3].nbNodes = 6;
1936 facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
1938 facesWithNodes.elems[4].nodeIds[0] = nodes[3];
1939 facesWithNodes.elems[4].nodeIds[1] = nodes[4];
1940 facesWithNodes.elems[4].nodeIds[2] = nodes[5];
1941 facesWithNodes.elems[4].nodeIds[3] = nodes[9];
1942 facesWithNodes.elems[4].nodeIds[4] = nodes[10];
1943 facesWithNodes.elems[4].nodeIds[5] = nodes[11];
1944 facesWithNodes.elems[4].nbNodes = 6;
1945 facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_TRIANGLE;
1948 // ---------------------------------------------------------------------------
1950 SMDS_DownHexa::SMDS_DownHexa(SMDS_UnstructuredGrid *grid) :
1951 SMDS_Down3D(grid, 6)
1953 _cellTypes.push_back(VTK_QUAD);
1954 _cellTypes.push_back(VTK_QUAD);
1955 _cellTypes.push_back(VTK_QUAD);
1956 _cellTypes.push_back(VTK_QUAD);
1957 _cellTypes.push_back(VTK_QUAD);
1958 _cellTypes.push_back(VTK_QUAD);
1961 SMDS_DownHexa::~SMDS_DownHexa()
1965 void SMDS_DownHexa::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
1969 for (int i = 0; i < orderedNodes.size(); i++)
1970 setNodes.insert(orderedNodes[i]);
1971 //MESSAGE("cellId = " << cellId);
1974 vtkIdType *nodes; // will refer to the point id's of the volume
1975 _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
1978 //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};
1979 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};
1980 for (int k = 0; k < 6; k++) // loop on the 6 faces
1983 for (int i = 0; i < 4; i++)
1984 tofind.insert(nodes[ids[4 * k + i]]); // node ids of the face i
1985 if (setNodes == tofind)
1987 for (int i = 0; i < 4; i++)
1988 orderedNodes[i] = nodes[ids[4 * k + i]];
1992 MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
1993 MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]);
1994 MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
1995 MESSAGE(nodes[4] << " " << nodes[5] << " " << nodes[6] << " " << nodes[7]);
1998 void SMDS_DownHexa::addDownCell(int cellId, int lowCellId, unsigned char aType)
2000 //ASSERT((cellId >=0)&& (cellId < _maxId));
2001 int *faces = &_cellIds[_nbDownCells * cellId];
2002 for (int i = 0; i < _nbDownCells; i++)
2006 faces[i] = lowCellId;
2009 if (faces[i] == lowCellId)
2013 // MESSAGE("-------------------------------------> trop de faces ! " << cellId << " " << lowCellId);
2016 /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's
2017 * The hexahedron is defined by the eight points (0-7), where (0,1,2,3) is the base
2018 * of the hexahedron which, using the right hand rule, forms a quadrilateral whose normal
2019 * points in the direction of the opposite face (4,5,6,7).
2020 * @see vtkHexahedron.h in Filtering
2021 * @param cellId volumeId in vtkUnstructuredGrid
2022 * @param facesWithNodes vector of face descriptors to be filled
2024 void SMDS_DownHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
2026 // --- find point id's of the volume
2029 vtkIdType *nodes; // will refer to the point id's of the volume
2030 _grid->GetCellPoints(cellId, npts, nodes);
2032 // --- create all the ordered list of node id's for each face
2034 facesWithNodes.nbElems = 6;
2036 facesWithNodes.elems[0].nodeIds[0] = nodes[0];
2037 facesWithNodes.elems[0].nodeIds[1] = nodes[1];
2038 facesWithNodes.elems[0].nodeIds[2] = nodes[2];
2039 facesWithNodes.elems[0].nodeIds[3] = nodes[3];
2040 facesWithNodes.elems[0].nbNodes = 4;
2041 facesWithNodes.elems[0].vtkType = VTK_QUAD;
2043 facesWithNodes.elems[1].nodeIds[0] = nodes[4];
2044 facesWithNodes.elems[1].nodeIds[1] = nodes[5];
2045 facesWithNodes.elems[1].nodeIds[2] = nodes[6];
2046 facesWithNodes.elems[1].nodeIds[3] = nodes[7];
2047 facesWithNodes.elems[1].nbNodes = 4;
2048 facesWithNodes.elems[1].vtkType = VTK_QUAD;
2050 facesWithNodes.elems[2].nodeIds[0] = nodes[0];
2051 facesWithNodes.elems[2].nodeIds[1] = nodes[1];
2052 facesWithNodes.elems[2].nodeIds[2] = nodes[5];
2053 facesWithNodes.elems[2].nodeIds[3] = nodes[4];
2054 facesWithNodes.elems[2].nbNodes = 4;
2055 facesWithNodes.elems[2].vtkType = VTK_QUAD;
2057 facesWithNodes.elems[3].nodeIds[0] = nodes[1];
2058 facesWithNodes.elems[3].nodeIds[1] = nodes[2];
2059 facesWithNodes.elems[3].nodeIds[2] = nodes[6];
2060 facesWithNodes.elems[3].nodeIds[3] = nodes[5];
2061 facesWithNodes.elems[3].nbNodes = 4;
2062 facesWithNodes.elems[3].vtkType = VTK_QUAD;
2064 facesWithNodes.elems[4].nodeIds[0] = nodes[2];
2065 facesWithNodes.elems[4].nodeIds[1] = nodes[6];
2066 facesWithNodes.elems[4].nodeIds[2] = nodes[7];
2067 facesWithNodes.elems[4].nodeIds[3] = nodes[3];
2068 facesWithNodes.elems[4].nbNodes = 4;
2069 facesWithNodes.elems[4].vtkType = VTK_QUAD;
2071 facesWithNodes.elems[5].nodeIds[0] = nodes[3];
2072 facesWithNodes.elems[5].nodeIds[1] = nodes[7];
2073 facesWithNodes.elems[5].nodeIds[2] = nodes[4];
2074 facesWithNodes.elems[5].nodeIds[3] = nodes[0];
2075 facesWithNodes.elems[5].nbNodes = 4;
2076 facesWithNodes.elems[5].vtkType = VTK_QUAD;
2079 // ---------------------------------------------------------------------------
2081 SMDS_DownQuadHexa::SMDS_DownQuadHexa(SMDS_UnstructuredGrid *grid) :
2082 SMDS_Down3D(grid, 6)
2084 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
2085 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
2086 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
2087 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
2088 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
2089 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
2092 SMDS_DownQuadHexa::~SMDS_DownQuadHexa()
2096 void SMDS_DownQuadHexa::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
2100 for (int i = 0; i < orderedNodes.size(); i++)
2101 setNodes.insert(orderedNodes[i]);
2102 //MESSAGE("cellId = " << cellId);
2105 vtkIdType *nodes; // will refer to the point id's of the volume
2106 _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
2109 //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};
2110 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,
2111 4, 0, 1, 5,16, 8,17,12, 5, 1, 2, 6,17, 9,18,13, 6, 2, 3, 7,18,10,19,14};
2112 for (int k = 0; k < 6; k++)
2115 for (int i = 0; i < 8; i++)
2116 tofind.insert(nodes[ids[8 * k + i]]);
2117 if (setNodes == tofind)
2119 for (int i = 0; i < 8; i++)
2120 orderedNodes[i] = nodes[ids[8 * k + i]];
2124 MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
2125 MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]);
2126 MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
2129 void SMDS_DownQuadHexa::addDownCell(int cellId, int lowCellId, unsigned char aType)
2131 //ASSERT((cellId >=0)&& (cellId < _maxId));
2132 int *faces = &_cellIds[_nbDownCells * cellId];
2133 for (int i = 0; i < _nbDownCells; i++)
2137 faces[i] = lowCellId;
2140 if (faces[i] == lowCellId)
2146 /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's
2147 * The ordering of the twenty points defining the quadratic hexahedron cell is point id's (0-7,8-19)
2148 * where point id's 0-7 are the eight corner vertices of the cube, followed by twelve mid-edge nodes (8-19).
2149 * Note that these mid-edge nodes lie on the edges defined by
2150 * (0,1), (1,2), (2,3), (3,0), (4,5), (5,6), (6,7), (7,4), (0,4), (1,5), (2,6), (3,7).
2151 * @see vtkQuadraticHexahedron.h in Filtering
2152 * @param cellId volumeId in vtkUnstructuredGrid
2153 * @param facesWithNodes vector of face descriptors to be filled
2155 void SMDS_DownQuadHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
2157 // --- find point id's of the volume
2160 vtkIdType *nodes; // will refer to the point id's of the volume
2161 _grid->GetCellPoints(cellId, npts, nodes);
2163 // --- create all the ordered list of node id's for each face
2165 facesWithNodes.nbElems = 6;
2167 facesWithNodes.elems[0].nodeIds[0] = nodes[0];
2168 facesWithNodes.elems[0].nodeIds[1] = nodes[1];
2169 facesWithNodes.elems[0].nodeIds[2] = nodes[2];
2170 facesWithNodes.elems[0].nodeIds[3] = nodes[3];
2171 facesWithNodes.elems[0].nodeIds[4] = nodes[8];
2172 facesWithNodes.elems[0].nodeIds[5] = nodes[9];
2173 facesWithNodes.elems[0].nodeIds[6] = nodes[10];
2174 facesWithNodes.elems[0].nodeIds[7] = nodes[11];
2175 facesWithNodes.elems[0].nbNodes = 8;
2176 facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD;
2178 facesWithNodes.elems[1].nodeIds[0] = nodes[4];
2179 facesWithNodes.elems[1].nodeIds[1] = nodes[5];
2180 facesWithNodes.elems[1].nodeIds[2] = nodes[6];
2181 facesWithNodes.elems[1].nodeIds[3] = nodes[7];
2182 facesWithNodes.elems[1].nodeIds[4] = nodes[12];
2183 facesWithNodes.elems[1].nodeIds[5] = nodes[13];
2184 facesWithNodes.elems[1].nodeIds[6] = nodes[14];
2185 facesWithNodes.elems[1].nodeIds[7] = nodes[15];
2186 facesWithNodes.elems[1].nbNodes = 8;
2187 facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_QUAD;
2189 facesWithNodes.elems[2].nodeIds[0] = nodes[0];
2190 facesWithNodes.elems[2].nodeIds[1] = nodes[1];
2191 facesWithNodes.elems[2].nodeIds[2] = nodes[5];
2192 facesWithNodes.elems[2].nodeIds[3] = nodes[4];
2193 facesWithNodes.elems[2].nodeIds[4] = nodes[8];
2194 facesWithNodes.elems[2].nodeIds[5] = nodes[17];
2195 facesWithNodes.elems[2].nodeIds[6] = nodes[12];
2196 facesWithNodes.elems[2].nodeIds[7] = nodes[16];
2197 facesWithNodes.elems[2].nbNodes = 8;
2198 facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_QUAD;
2200 facesWithNodes.elems[3].nodeIds[0] = nodes[1];
2201 facesWithNodes.elems[3].nodeIds[1] = nodes[2];
2202 facesWithNodes.elems[3].nodeIds[2] = nodes[6];
2203 facesWithNodes.elems[3].nodeIds[3] = nodes[5];
2204 facesWithNodes.elems[3].nodeIds[4] = nodes[9];
2205 facesWithNodes.elems[3].nodeIds[5] = nodes[18];
2206 facesWithNodes.elems[3].nodeIds[6] = nodes[13];
2207 facesWithNodes.elems[3].nodeIds[7] = nodes[17];
2208 facesWithNodes.elems[3].nbNodes = 8;
2209 facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_QUAD;
2211 facesWithNodes.elems[4].nodeIds[0] = nodes[2];
2212 facesWithNodes.elems[4].nodeIds[1] = nodes[6];
2213 facesWithNodes.elems[4].nodeIds[2] = nodes[7];
2214 facesWithNodes.elems[4].nodeIds[3] = nodes[3];
2215 facesWithNodes.elems[4].nodeIds[4] = nodes[18];
2216 facesWithNodes.elems[4].nodeIds[5] = nodes[14];
2217 facesWithNodes.elems[4].nodeIds[6] = nodes[19];
2218 facesWithNodes.elems[4].nodeIds[7] = nodes[10];
2219 facesWithNodes.elems[4].nbNodes = 8;
2220 facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_QUAD;
2222 facesWithNodes.elems[5].nodeIds[0] = nodes[3];
2223 facesWithNodes.elems[5].nodeIds[1] = nodes[7];
2224 facesWithNodes.elems[5].nodeIds[2] = nodes[4];
2225 facesWithNodes.elems[5].nodeIds[3] = nodes[0];
2226 facesWithNodes.elems[5].nodeIds[4] = nodes[19];
2227 facesWithNodes.elems[5].nodeIds[5] = nodes[15];
2228 facesWithNodes.elems[5].nodeIds[6] = nodes[16];
2229 facesWithNodes.elems[5].nodeIds[7] = nodes[11];
2230 facesWithNodes.elems[5].nbNodes = 8;
2231 facesWithNodes.elems[5].vtkType = VTK_QUADRATIC_QUAD;
2234 // ---------------------------------------------------------------------------