1 // Copyright (C) 2010-2014 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, or (at your option) any later version.
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_BIQUADRATIC_TRIANGLE] = 2;
54 _cellDimension[VTK_QUAD] = 2;
55 _cellDimension[VTK_QUADRATIC_QUAD] = 2;
56 _cellDimension[VTK_BIQUADRATIC_QUAD] = 2;
57 _cellDimension[VTK_TETRA] = 3;
58 _cellDimension[VTK_QUADRATIC_TETRA] = 3;
59 _cellDimension[VTK_HEXAHEDRON] = 3;
60 _cellDimension[VTK_QUADRATIC_HEXAHEDRON] = 3;
61 _cellDimension[VTK_TRIQUADRATIC_HEXAHEDRON] = 3;
62 _cellDimension[VTK_WEDGE] = 3;
63 _cellDimension[VTK_QUADRATIC_WEDGE] = 3;
64 _cellDimension[VTK_PYRAMID] = 3;
65 _cellDimension[VTK_QUADRATIC_PYRAMID] = 3;
66 _cellDimension[VTK_HEXAGONAL_PRISM] = 3;
68 return _cellDimension[cellType];
71 // ---------------------------------------------------------------------------
73 /*! Generic constructor for all the downward connectivity structures (one per vtk cell type).
74 * The static structure for cell dimension is set only once.
75 * @param grid unstructured grid associated to the mesh.
76 * @param nbDownCells number of downward entities associated to this vtk type of cell.
79 SMDS_Downward::SMDS_Downward(SMDS_UnstructuredGrid *grid, int nbDownCells) :
80 _grid(grid), _nbDownCells(nbDownCells)
83 this->_cellIds.clear();
84 this->_cellTypes.clear();
85 if (_cellDimension.empty())
86 getCellDimension( VTK_LINE );
89 SMDS_Downward::~SMDS_Downward()
93 /*! Give or create an entry for downward connectivity structure relative to a cell.
94 * If the entry already exists, just return its id, otherwise, create it.
95 * The internal storage memory is allocated if needed.
96 * The SMDS_UnstructuredGrid::_cellIdToDownId vector is completed for vtkUnstructuredGrid cells.
97 * @param vtkId for a vtkUnstructuredGrid cell or -1 (default) for a created downward cell.
98 * @return the rank in downward[vtkType] structure.
100 int SMDS_Downward::addCell(int vtkId)
104 localId = _grid->CellIdToDownId(vtkId);
108 localId = this->_maxId;
110 this->allocate(_maxId);
113 this->_vtkCellIds[localId] = vtkId;
114 _grid->setCellIdToDownId(vtkId, localId);
116 this->initCell(localId);
120 /*! generic method do nothing. see derived methods
124 void SMDS_Downward::initCell(int cellId)
128 /*! Get the number of downward entities associated to a cell (always the same for a given vtk type of cell)
130 * @param cellId not used here.
133 int SMDS_Downward::getNumberOfDownCells(int cellId)
138 /*! get a pointer on the downward entities id's associated to a cell.
139 * @see SMDS_Downward::getNumberOfDownCells for the number of downward entities.
140 * @see SMDS_Downward::getDownTypes for the vtk cell types associated to the downward entities.
141 * @param cellId index of the cell in the downward structure relative to a given vtk cell type.
142 * @return table of downward entities id's.
144 const int* SMDS_Downward::getDownCells(int cellId)
146 //ASSERT((cellId >=0) && (cellId < _maxId));
147 return &_cellIds[_nbDownCells * cellId];
150 /*! get a list of vtk cell types associated to downward entities of a given cell, in the same order
151 * than the downward entities id's list (@see SMDS_Downward::getDownCells).
153 * @param cellId index of the cell in the downward structure relative to a vtk cell type.
154 * @return table of downward entities types.
156 const unsigned char* SMDS_Downward::getDownTypes(int cellId)
158 return &_cellTypes[0];
161 /*! add a downward entity of dimension n-1 (cell or node) to a given cell.
162 * Actual implementation is done in derived methods.
163 * @param cellId index of the parent cell (dimension n) in the downward structure relative to a vtk cell type.
164 * @param lowCellId index of the children cell to add (dimension n-1)
165 * @param aType vtk cell type of the cell to add (needed to find the SMDS_Downward structure containing the cell to add).
167 void SMDS_Downward::addDownCell(int cellId, int lowCellId, unsigned char aType)
169 ASSERT(0); // must be re-implemented in derived class
172 /*! add a downward entity of dimension n+1 to a given cell.
173 * Actual implementation is done in derived methods.
174 * @param cellId index of the children cell (dimension n) in the downward structure relative to a vtk cell type.
175 * @param upCellId index of the parent cell to add (dimension n+1)
176 * @param aType vtk cell type of the cell to add (needed to find the SMDS_Downward structure containing the cell to add).
178 void SMDS_Downward::addUpCell(int cellId, int upCellId, unsigned char aType)
180 ASSERT(0); // must be re-implemented in derived class
183 int SMDS_Downward::getNodeSet(int cellId, int* nodeSet)
188 // ---------------------------------------------------------------------------
190 SMDS_Down1D::SMDS_Down1D(SMDS_UnstructuredGrid *grid, int nbDownCells) :
191 SMDS_Downward(grid, nbDownCells)
193 _upCellIdsVector.clear();
194 _upCellTypesVector.clear();
196 _upCellTypes.clear();
197 _upCellIndex.clear();
200 SMDS_Down1D::~SMDS_Down1D()
204 /*! clear vectors used to reference 2D cells containing the edge
208 void SMDS_Down1D::initCell(int cellId)
210 _upCellIdsVector[cellId].clear();
211 _upCellTypesVector[cellId].clear();
214 /*! Resize the downward connectivity storage vector if needed.
216 * @param nbElems total number of elements of the same type required
218 void SMDS_Down1D::allocate(int nbElems)
220 if (nbElems >= _vtkCellIds.size())
222 _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1);
223 _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1);
224 _upCellIdsVector.resize(nbElems + SMDS_Mesh::chunkSize);
225 _upCellTypesVector.resize(nbElems + SMDS_Mesh::chunkSize);
229 void SMDS_Down1D::compactStorage()
231 _cellIds.resize(_nbDownCells * _maxId);
232 _vtkCellIds.resize(_maxId);
235 for (int i = 0; i < _maxId; i++)
236 sizeUpCells += _upCellIdsVector[i].size();
237 _upCellIds.resize(sizeUpCells, -1);
238 _upCellTypes.resize(sizeUpCells);
239 _upCellIndex.resize(_maxId + 1, -1); // id and types of rank i correspond to [ _upCellIndex[i], _upCellIndex[i+1] [
241 for (int i = 0; i < _maxId; i++)
243 _upCellIndex[i] = current;
244 for (int j = 0; j < _upCellIdsVector[i].size(); j++)
246 _upCellIds[current] = _upCellIdsVector[i][j];
247 _upCellTypes[current] = _upCellTypesVector[i][j];
251 _upCellIndex[_maxId] = current;
253 _upCellIdsVector.clear();
254 _upCellTypesVector.clear();
257 void SMDS_Down1D::addUpCell(int cellId, int upCellId, unsigned char aType)
259 //ASSERT((cellId >=0) && (cellId < _maxId));
260 int nbFaces = _upCellIdsVector[cellId].size();
261 for (int i = 0; i < nbFaces; i++)
263 if ((_upCellIdsVector[cellId][i] == upCellId) && (_upCellTypesVector[cellId][i] == aType))
265 return; // already done
268 _upCellIdsVector[cellId].push_back(upCellId);
269 _upCellTypesVector[cellId].push_back(aType);
272 int SMDS_Down1D::getNumberOfUpCells(int cellId)
274 //ASSERT((cellId >=0) && (cellId < _maxId));
275 return _upCellIndex[cellId + 1] - _upCellIndex[cellId];
278 const int* SMDS_Down1D::getUpCells(int cellId)
280 //ASSERT((cellId >=0) && (cellId < _maxId));
281 return &_upCellIds[_upCellIndex[cellId]];
284 const unsigned char* SMDS_Down1D::getUpTypes(int cellId)
286 //ASSERT((cellId >=0) && (cellId < _maxId));
287 return &_upCellTypes[_upCellIndex[cellId]];
290 void SMDS_Down1D::getNodeIds(int cellId, std::set<int>& nodeSet)
292 for (int i = 0; i < _nbDownCells; i++)
293 nodeSet.insert(_cellIds[_nbDownCells * cellId + i]);
296 int SMDS_Down1D::getNodeSet(int cellId, int* nodeSet)
298 for (int i = 0; i < _nbDownCells; i++)
299 nodeSet[i] = _cellIds[_nbDownCells * cellId + i];
303 void SMDS_Down1D::setNodes(int cellId, int vtkId)
306 vtkIdType *pts; // will refer to the point id's of the face
307 _grid->GetCellPoints(vtkId, npts, pts);
308 // MESSAGE(vtkId << " " << npts << " " << _nbDownCells);
309 //ASSERT(npts == _nbDownCells);
310 for (int i = 0; i < npts; i++)
312 _cellIds[_nbDownCells * cellId + i] = pts[i];
316 void SMDS_Down1D::setNodes(int cellId, const int* nodeIds)
318 //ASSERT(nodeIds.size() == _nbDownCells);
319 for (int i = 0; i < _nbDownCells; i++)
321 _cellIds[_nbDownCells * cellId + i] = nodeIds[i];
325 /*! Build the list of vtkUnstructuredGrid cells containing the edge.
326 * We keep in the list the cells that contains all the nodes, we keep only volumes and faces.
327 * @param cellId id of the edge in the downward structure
328 * @param vtkIds vector of vtk id's
329 * @return number of vtk cells (size of vector)
331 int SMDS_Down1D::computeVtkCells(int cellId, std::vector<int>& vtkIds)
335 // --- find all the cells the points belong to, and how many of the points belong to a given cell
337 int *pts = &_cellIds[_nbDownCells * cellId];
338 int ncells = this->computeVtkCells(pts, vtkIds);
342 /*! Build the list of vtkUnstructuredGrid cells containing the edge.
344 * @param pts list of points id's defining an edge
345 * @param vtkIds vector of vtk id's
346 * @return number of vtk cells (size of vector)
348 int SMDS_Down1D::computeVtkCells(int *pts, std::vector<int>& vtkIds)
351 // --- find all the cells the points belong to, and how many of the points belong to a given cell
356 for (int i = 0; i < _nbDownCells; i++)
358 vtkIdType point = pts[i];
359 int numCells = _grid->GetLinks()->GetNcells(point);
360 vtkIdType *cells = _grid->GetLinks()->GetCells(point);
361 for (int j = 0; j < numCells; j++)
363 int vtkCellId = cells[j];
365 for (int k = 0; k < cnt; k++)
367 if (cellIds[k] == vtkCellId)
376 cellIds[cnt] = vtkCellId;
378 // TODO ASSERT(cnt<1000);
384 // --- find the face and volume cells: they contains all the points and are of type volume or face
387 for (int i = 0; i < cnt; i++)
389 if (cellCnt[i] == _nbDownCells)
391 int vtkElemId = cellIds[i];
392 int vtkType = _grid->GetCellType(vtkElemId);
393 if (SMDS_Downward::getCellDimension(vtkType) > 1)
395 vtkIds.push_back(vtkElemId);
404 /*! Build the list of downward faces from a list of vtk cells.
406 * @param cellId id of the edge in the downward structure
407 * @param vtkIds vector of vtk id's
408 * @param downFaces vector of face id's in downward structures
409 * @param downTypes vector of face types
410 * @return number of downward faces
412 int SMDS_Down1D::computeFaces(int cellId, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes)
414 int *pts = &_cellIds[_nbDownCells * cellId];
415 int nbFaces = this->computeFaces(pts, vtkIds, nbcells, downFaces, downTypes);
419 /*! Build the list of downward faces from a list of vtk cells.
421 * @param pts list of points id's defining an edge
422 * @param vtkIds vector of vtk id's
423 * @param downFaces vector of face id's in downward structures
424 * @param downTypes vector of face types
425 * @return number of downward faces
427 int SMDS_Down1D::computeFaces(int* pts, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes)
430 for (int i = 0; i < nbcells; i++)
432 int vtkId = vtkIds[i];
433 int vtkType = _grid->GetCellType(vtkId);
434 if (SMDS_Downward::getCellDimension(vtkType) == 2)
436 int faceId = _grid->CellIdToDownId(vtkId);
437 downFaces[cnt] = faceId;
438 downTypes[cnt] = vtkType;
441 else if (SMDS_Downward::getCellDimension(vtkType) == 3)
443 int volId = _grid->CellIdToDownId(vtkId);
444 SMDS_Downward * downvol = _grid->getDownArray(vtkType);
445 //const int *downIds = downvol->getDownCells(volId);
446 const unsigned char* downTypesVol = downvol->getDownTypes(volId);
447 int nbFaces = downvol->getNumberOfDownCells(volId);
448 const int* faceIds = downvol->getDownCells(volId);
449 for (int n = 0; n < nbFaces; n++)
451 SMDS_Down2D *downFace = static_cast<SMDS_Down2D*> (_grid->getDownArray(downTypesVol[n]));
452 bool isInFace = downFace->isInFace(faceIds[n], pts, _nbDownCells);
455 bool alreadySet = false;
456 for (int k = 0; k < cnt; k++)
457 if (faceIds[n] == downFaces[k])
464 downFaces[cnt] = faceIds[n];
465 downTypes[cnt] = downTypesVol[n];
475 // ---------------------------------------------------------------------------
477 SMDS_Down2D::SMDS_Down2D(SMDS_UnstructuredGrid *grid, int nbDownCells) :
478 SMDS_Downward(grid, nbDownCells)
481 _upCellTypes.clear();
486 SMDS_Down2D::~SMDS_Down2D()
490 int SMDS_Down2D::getNumberOfUpCells(int cellId)
493 if (_upCellIds[2 * cellId] >= 0)
495 if (_upCellIds[2 * cellId + 1] >= 0)
500 const int* SMDS_Down2D::getUpCells(int cellId)
502 //ASSERT((cellId >=0) && (cellId < _maxId));
503 return &_upCellIds[2 * cellId];
506 const unsigned char* SMDS_Down2D::getUpTypes(int cellId)
508 //ASSERT((cellId >=0) && (cellId < _maxId));
509 return &_upCellTypes[2 * cellId];
512 void SMDS_Down2D::getNodeIds(int cellId, std::set<int>& nodeSet)
514 for (int i = 0; i < _nbDownCells; i++)
516 int downCellId = _cellIds[_nbDownCells * cellId + i];
517 unsigned char cellType = _cellTypes[i];
518 this->_grid->getDownArray(cellType)->getNodeIds(downCellId, nodeSet);
522 /*! Find in vtkUnstructuredGrid the volumes containing a face already stored in vtkUnstructuredGrid.
523 * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses
524 * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes.
525 * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid.
526 * @param cellId the face cell id in vkUnstructuredGrid
527 * @param ids a couple of vtkId, initialized at -1 (no parent volume)
528 * @return number of volumes (0, 1 or 2)
530 int SMDS_Down2D::computeVolumeIds(int cellId, int* ids)
532 // --- find point id's of the face
535 vtkIdType *pts; // will refer to the point id's of the face
536 _grid->GetCellPoints(cellId, npts, pts);
538 for (int i = 0; i < npts; i++)
539 nodes.push_back(pts[i]);
540 int nvol = this->computeVolumeIdsFromNodesFace(&nodes[0], npts, ids);
544 /*! Find in vtkUnstructuredGrid the volumes containing a face described by it's nodes
545 * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses
546 * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes.
547 * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid.
549 * @param ids a couple of vtkId, initialized at -1 (no parent volume)
550 * @return number of volumes (0, 1 or 2)
552 int SMDS_Down2D::computeVolumeIds(ElemByNodesType& faceByNodes, int* ids)
554 int nvol = this->computeVolumeIdsFromNodesFace(&faceByNodes.nodeIds[0], faceByNodes.nbNodes, ids);
558 /*! Find in vtkUnstructuredGrid the volumes containing a face described by it's nodes
559 * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses
560 * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes.
561 * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid.
562 * @param pts array of vtk node id's
563 * @param npts number of nodes
565 * @return number of volumes (0, 1 or 2)
567 int SMDS_Down2D::computeVolumeIdsFromNodesFace(int* pts, int npts, int* ids)
570 // --- find all the cells the points belong to, and how many of the points belong to a given cell
575 for (int i = 0; i < npts; i++)
577 vtkIdType point = pts[i];
578 int numCells = _grid->GetLinks()->GetNcells(point);
579 //MESSAGE("cells pour " << i << " " << numCells);
580 vtkIdType *cells = _grid->GetLinks()->GetCells(point);
581 for (int j = 0; j < numCells; j++)
583 int vtkCellId = cells[j];
585 for (int k = 0; k < cnt; k++)
587 if (cellIds[k] == vtkCellId)
596 cellIds[cnt] = vtkCellId;
598 // TODO ASSERT(cnt<1000);
604 // --- find the volume cells: they contains all the points and are of type volume
607 for (int i = 0; i < cnt; i++)
609 //MESSAGE("cell " << cellIds[i] << " points " << cellCnt[i]);
610 if (cellCnt[i] == npts)
612 int vtkElemId = cellIds[i];
613 int vtkType = _grid->GetCellType(vtkElemId);
614 if (SMDS_Downward::getCellDimension(vtkType) == 3)
616 ids[nvol] = vtkElemId; // store the volume id in given vector
627 void SMDS_Down2D::setTempNodes(int cellId, int vtkId)
630 vtkIdType *pts; // will refer to the point id's of the face
631 _grid->GetCellPoints(vtkId, npts, pts);
632 // MESSAGE(vtkId << " " << npts << " " << _nbNodes);
633 //ASSERT(npts == _nbNodes);
634 for (int i = 0; i < npts; i++)
636 _tempNodes[_nbNodes * cellId + i] = pts[i];
640 void SMDS_Down2D::setTempNodes(int cellId, ElemByNodesType& faceByNodes)
642 for (int i = 0; i < faceByNodes.nbNodes; i++)
643 _tempNodes[_nbNodes * cellId + i] = faceByNodes.nodeIds[i];
646 /*! Find if all the nodes belongs to the face.
648 * @param cellId the face cell Id
649 * @param nodeSet set of node id's to be found in the face list of nodes
652 bool SMDS_Down2D::isInFace(int cellId, int *pts, int npts)
655 int *nodes = &_tempNodes[_nbNodes * cellId];
656 for (int j = 0; j < npts; j++)
659 for (int i = 0; i < _nbNodes; i++)
661 if (nodes[i] == point)
668 return (nbFound == npts);
671 /*! Resize the downward connectivity storage vector if needed.
673 * @param nbElems total number of elements of the same type required
675 void SMDS_Down2D::allocate(int nbElems)
677 if (nbElems >= _vtkCellIds.size())
679 _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1);
680 _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1);
681 _upCellIds.resize(2 * (nbElems + SMDS_Mesh::chunkSize), -1);
682 _upCellTypes.resize(2 * (nbElems + SMDS_Mesh::chunkSize), -1);
683 _tempNodes.resize(_nbNodes * (nbElems + SMDS_Mesh::chunkSize), -1);
687 void SMDS_Down2D::compactStorage()
689 _cellIds.resize(_nbDownCells * _maxId);
690 _upCellIds.resize(2 * _maxId);
691 _upCellTypes.resize(2 * _maxId);
692 _vtkCellIds.resize(_maxId);
696 void SMDS_Down2D::addUpCell(int cellId, int upCellId, unsigned char aType)
698 //ASSERT((cellId >=0)&& (cellId < _maxId));
699 int *vols = &_upCellIds[2 * cellId];
700 unsigned char *types = &_upCellTypes[2 * cellId];
701 for (int i = 0; i < 2; i++)
705 vols[i] = upCellId; // use non affected volume
709 if ((vols[i] == upCellId) && (types[i] == aType)) // already done
715 int SMDS_Down2D::getNodeSet(int cellId, int* nodeSet)
717 for (int i = 0; i < _nbNodes; i++)
718 nodeSet[i] = _tempNodes[_nbNodes * cellId + i];
722 int SMDS_Down2D::FindEdgeByNodes(int cellId, ElemByNodesType& edgeByNodes)
724 int *edges = &_cellIds[_nbDownCells * cellId];
725 for (int i = 0; i < _nbDownCells; i++)
727 if ((edges[i] >= 0) && (edgeByNodes.vtkType == _cellTypes[i]))
730 int npts = this->_grid->getDownArray(edgeByNodes.vtkType)->getNodeSet(edges[i], nodeSet);
732 for (int j = 0; j < npts; j++)
734 int point = edgeByNodes.nodeIds[j];
736 for (int k = 0; k < npts; k++)
738 if (nodeSet[k] == point)
754 // ---------------------------------------------------------------------------
756 SMDS_Down3D::SMDS_Down3D(SMDS_UnstructuredGrid *grid, int nbDownCells) :
757 SMDS_Downward(grid, nbDownCells)
761 SMDS_Down3D::~SMDS_Down3D()
765 void SMDS_Down3D::allocate(int nbElems)
767 if (nbElems >= _vtkCellIds.size())
769 _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1);
770 _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1);
774 void SMDS_Down3D::compactStorage()
776 // nothing to do, size was known before
779 int SMDS_Down3D::getNumberOfUpCells(int cellId)
784 const int* SMDS_Down3D::getUpCells(int cellId)
789 const unsigned char* SMDS_Down3D::getUpTypes(int cellId)
794 void SMDS_Down3D::getNodeIds(int cellId, std::set<int>& nodeSet)
796 int vtkId = this->_vtkCellIds[cellId];
798 vtkIdType *nodes; // will refer to the point id's of the volume
799 _grid->GetCellPoints(vtkId, npts, nodes);
800 for (int i = 0; i < npts; i++)
801 nodeSet.insert(nodes[i]);
804 int SMDS_Down3D::FindFaceByNodes(int cellId, ElemByNodesType& faceByNodes)
806 int *faces = &_cellIds[_nbDownCells * cellId];
809 for (int i = 0; i < _nbDownCells; i++)
811 if ((faces[i] >= 0) && (faceByNodes.vtkType == _cellTypes[i]))
814 npoints = faceByNodes.nbNodes;
817 int npts = this->_grid->getDownArray(faceByNodes.vtkType)->getNodeSet(faces[i], nodeSet);
819 continue; // skip this face
821 for (int j = 0; j < npts; j++)
823 int point = faceByNodes.nodeIds[j];
825 for (int k = 0; k < npts; k++)
827 if (nodeSet[k] == point)
830 break; // point j is in the 2 faces, skip remaining k values
834 break; // point j is not in the 2 faces, skip the remaining tests
843 // ---------------------------------------------------------------------------
845 SMDS_DownEdge::SMDS_DownEdge(SMDS_UnstructuredGrid *grid) :
848 _cellTypes.push_back(VTK_VERTEX);
849 _cellTypes.push_back(VTK_VERTEX);
852 SMDS_DownEdge::~SMDS_DownEdge()
856 // ---------------------------------------------------------------------------
858 SMDS_DownQuadEdge::SMDS_DownQuadEdge(SMDS_UnstructuredGrid *grid) :
861 _cellTypes.push_back(VTK_VERTEX);
862 _cellTypes.push_back(VTK_VERTEX);
863 _cellTypes.push_back(VTK_VERTEX);
866 SMDS_DownQuadEdge::~SMDS_DownQuadEdge()
870 // ---------------------------------------------------------------------------
872 SMDS_DownTriangle::SMDS_DownTriangle(SMDS_UnstructuredGrid *grid) :
875 _cellTypes.push_back(VTK_LINE);
876 _cellTypes.push_back(VTK_LINE);
877 _cellTypes.push_back(VTK_LINE);
881 SMDS_DownTriangle::~SMDS_DownTriangle()
885 void SMDS_DownTriangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
887 int *nodes = &_tempNodes[_nbNodes * cellId];
888 edgesWithNodes.nbElems = 3;
890 edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
891 edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
892 edgesWithNodes.elems[0].nbNodes = 2;
893 edgesWithNodes.elems[0].vtkType = VTK_LINE;
895 edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
896 edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
897 edgesWithNodes.elems[1].nbNodes = 2;
898 edgesWithNodes.elems[1].vtkType = VTK_LINE;
900 edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
901 edgesWithNodes.elems[2].nodeIds[1] = nodes[0];
902 edgesWithNodes.elems[2].nbNodes = 2;
903 edgesWithNodes.elems[2].vtkType = VTK_LINE;
906 void SMDS_DownTriangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
908 //ASSERT((cellId >=0)&& (cellId < _maxId));
909 //ASSERT(aType == VTK_LINE);
910 int *faces = &_cellIds[_nbDownCells * cellId];
911 for (int i = 0; i < _nbDownCells; i++)
915 faces[i] = lowCellId;
918 if (faces[i] == lowCellId)
924 // ---------------------------------------------------------------------------
926 SMDS_DownQuadTriangle::SMDS_DownQuadTriangle(SMDS_UnstructuredGrid *grid) :
929 _cellTypes.push_back(VTK_QUADRATIC_EDGE);
930 _cellTypes.push_back(VTK_QUADRATIC_EDGE);
931 _cellTypes.push_back(VTK_QUADRATIC_EDGE);
935 SMDS_DownQuadTriangle::~SMDS_DownQuadTriangle()
939 void SMDS_DownQuadTriangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
941 int *nodes = &_tempNodes[_nbNodes * cellId];
942 edgesWithNodes.nbElems = 3;
944 edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
945 edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
946 edgesWithNodes.elems[0].nodeIds[2] = nodes[3];
947 edgesWithNodes.elems[0].nbNodes = 3;
948 edgesWithNodes.elems[0].vtkType = VTK_QUADRATIC_EDGE;
950 edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
951 edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
952 edgesWithNodes.elems[1].nodeIds[2] = nodes[4];
953 edgesWithNodes.elems[1].nbNodes = 3;
954 edgesWithNodes.elems[1].vtkType = VTK_QUADRATIC_EDGE;
956 edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
957 edgesWithNodes.elems[2].nodeIds[1] = nodes[0];
958 edgesWithNodes.elems[2].nodeIds[2] = nodes[5];
959 edgesWithNodes.elems[2].nbNodes = 3;
960 edgesWithNodes.elems[2].vtkType = VTK_QUADRATIC_EDGE;
963 void SMDS_DownQuadTriangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
965 //ASSERT((cellId >=0)&& (cellId < _maxId));
966 //ASSERT(aType == VTK_QUADRATIC_EDGE);
967 int *edges = &_cellIds[_nbDownCells * cellId];
968 for (int i = 0; i < _nbDownCells; i++)
972 edges[i] = lowCellId;
975 if (edges[i] == lowCellId)
981 // ---------------------------------------------------------------------------
983 SMDS_DownQuadrangle::SMDS_DownQuadrangle(SMDS_UnstructuredGrid *grid) :
986 _cellTypes.push_back(VTK_LINE);
987 _cellTypes.push_back(VTK_LINE);
988 _cellTypes.push_back(VTK_LINE);
989 _cellTypes.push_back(VTK_LINE);
993 SMDS_DownQuadrangle::~SMDS_DownQuadrangle()
997 void SMDS_DownQuadrangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
999 int *nodes = &_tempNodes[_nbNodes * cellId];
1000 edgesWithNodes.nbElems = 4;
1002 edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
1003 edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
1004 edgesWithNodes.elems[0].nbNodes = 2;
1005 edgesWithNodes.elems[0].vtkType = VTK_LINE;
1007 edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
1008 edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
1009 edgesWithNodes.elems[1].nbNodes = 2;
1010 edgesWithNodes.elems[1].vtkType = VTK_LINE;
1012 edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
1013 edgesWithNodes.elems[2].nodeIds[1] = nodes[3];
1014 edgesWithNodes.elems[2].nbNodes = 2;
1015 edgesWithNodes.elems[2].vtkType = VTK_LINE;
1017 edgesWithNodes.elems[3].nodeIds[0] = nodes[3];
1018 edgesWithNodes.elems[3].nodeIds[1] = nodes[0];
1019 edgesWithNodes.elems[3].nbNodes = 2;
1020 edgesWithNodes.elems[3].vtkType = VTK_LINE;
1023 void SMDS_DownQuadrangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
1025 //ASSERT((cellId >=0)&& (cellId < _maxId));
1026 //ASSERT(aType == VTK_LINE);
1027 int *faces = &_cellIds[_nbDownCells * cellId];
1028 for (int i = 0; i < _nbDownCells; i++)
1032 faces[i] = lowCellId;
1035 if (faces[i] == lowCellId)
1041 // ---------------------------------------------------------------------------
1043 SMDS_DownQuadQuadrangle::SMDS_DownQuadQuadrangle(SMDS_UnstructuredGrid *grid) :
1044 SMDS_Down2D(grid, 4)
1046 _cellTypes.push_back(VTK_QUADRATIC_EDGE);
1047 _cellTypes.push_back(VTK_QUADRATIC_EDGE);
1048 _cellTypes.push_back(VTK_QUADRATIC_EDGE);
1049 _cellTypes.push_back(VTK_QUADRATIC_EDGE);
1053 SMDS_DownQuadQuadrangle::~SMDS_DownQuadQuadrangle()
1057 void SMDS_DownQuadQuadrangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
1059 int *nodes = &_tempNodes[_nbNodes * cellId];
1060 edgesWithNodes.nbElems = 4;
1062 edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
1063 edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
1064 edgesWithNodes.elems[0].nodeIds[2] = nodes[4];
1065 edgesWithNodes.elems[0].nbNodes = 3;
1066 edgesWithNodes.elems[0].vtkType = VTK_QUADRATIC_EDGE;
1068 edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
1069 edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
1070 edgesWithNodes.elems[1].nodeIds[2] = nodes[5];
1071 edgesWithNodes.elems[1].nbNodes = 3;
1072 edgesWithNodes.elems[1].vtkType = VTK_QUADRATIC_EDGE;
1074 edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
1075 edgesWithNodes.elems[2].nodeIds[1] = nodes[3];
1076 edgesWithNodes.elems[2].nodeIds[2] = nodes[6];
1077 edgesWithNodes.elems[2].nbNodes = 3;
1078 edgesWithNodes.elems[2].vtkType = VTK_QUADRATIC_EDGE;
1080 edgesWithNodes.elems[3].nodeIds[0] = nodes[3];
1081 edgesWithNodes.elems[3].nodeIds[1] = nodes[0];
1082 edgesWithNodes.elems[3].nodeIds[2] = nodes[7];
1083 edgesWithNodes.elems[3].nbNodes = 3;
1084 edgesWithNodes.elems[3].vtkType = VTK_QUADRATIC_EDGE;
1087 void SMDS_DownQuadQuadrangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
1089 //ASSERT((cellId >=0)&& (cellId < _maxId));
1090 //ASSERT(aType == VTK_QUADRATIC_EDGE);
1091 int *faces = &_cellIds[_nbDownCells * cellId];
1092 for (int i = 0; i < _nbDownCells; i++)
1096 faces[i] = lowCellId;
1099 if (faces[i] == lowCellId)
1105 // ---------------------------------------------------------------------------
1107 SMDS_DownTetra::SMDS_DownTetra(SMDS_UnstructuredGrid *grid) :
1108 SMDS_Down3D(grid, 4)
1110 _cellTypes.push_back(VTK_TRIANGLE);
1111 _cellTypes.push_back(VTK_TRIANGLE);
1112 _cellTypes.push_back(VTK_TRIANGLE);
1113 _cellTypes.push_back(VTK_TRIANGLE);
1116 SMDS_DownTetra::~SMDS_DownTetra()
1120 void SMDS_DownTetra::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
1124 for (int i = 0; i < orderedNodes.size(); i++)
1125 setNodes.insert(orderedNodes[i]);
1126 //MESSAGE("cellId = " << cellId);
1129 vtkIdType *nodes; // will refer to the point id's of the volume
1130 _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
1133 int ids[12] = { 0, 1, 2, 0, 3, 1, 2, 3, 0, 1, 3, 2 };
1134 //int ids[12] = { 2, 1, 0, 1, 3, 0, 0, 3, 2, 2, 3, 1 };
1135 for (int k = 0; k < 4; k++)
1138 for (int i = 0; i < 3; i++)
1139 tofind.insert(nodes[ids[3 * k + i]]);
1140 if (setNodes == tofind)
1142 for (int i = 0; i < 3; i++)
1143 orderedNodes[i] = nodes[ids[3 * k + i]];
1147 MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
1148 MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
1149 MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
1152 void SMDS_DownTetra::addDownCell(int cellId, int lowCellId, unsigned char aType)
1154 //ASSERT((cellId >=0)&& (cellId < _maxId));
1155 //ASSERT(aType == VTK_TRIANGLE);
1156 int *faces = &_cellIds[_nbDownCells * cellId];
1157 for (int i = 0; i < _nbDownCells; i++)
1161 faces[i] = lowCellId;
1164 if (faces[i] == lowCellId)
1170 /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's
1171 * The linear tetrahedron is defined by four points.
1172 * @see vtkTetra.h in Filtering.
1173 * @param cellId volumeId in vtkUnstructuredGrid
1174 * @param facesWithNodes vector of face descriptors to be filled
1176 void SMDS_DownTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
1178 // --- find point id's of the volume
1181 vtkIdType *nodes; // will refer to the point id's of the volume
1182 _grid->GetCellPoints(cellId, npts, nodes);
1184 // --- create all the ordered list of node id's for each face
1186 facesWithNodes.nbElems = 4;
1188 facesWithNodes.elems[0].nodeIds[0] = nodes[0];
1189 facesWithNodes.elems[0].nodeIds[1] = nodes[1];
1190 facesWithNodes.elems[0].nodeIds[2] = nodes[2];
1191 facesWithNodes.elems[0].nbNodes = 3;
1192 facesWithNodes.elems[0].vtkType = VTK_TRIANGLE;
1194 facesWithNodes.elems[1].nodeIds[0] = nodes[0];
1195 facesWithNodes.elems[1].nodeIds[1] = nodes[1];
1196 facesWithNodes.elems[1].nodeIds[2] = nodes[3];
1197 facesWithNodes.elems[1].nbNodes = 3;
1198 facesWithNodes.elems[1].vtkType = VTK_TRIANGLE;
1200 facesWithNodes.elems[2].nodeIds[0] = nodes[0];
1201 facesWithNodes.elems[2].nodeIds[1] = nodes[2];
1202 facesWithNodes.elems[2].nodeIds[2] = nodes[3];
1203 facesWithNodes.elems[2].nbNodes = 3;
1204 facesWithNodes.elems[2].vtkType = VTK_TRIANGLE;
1206 facesWithNodes.elems[3].nodeIds[0] = nodes[1];
1207 facesWithNodes.elems[3].nodeIds[1] = nodes[2];
1208 facesWithNodes.elems[3].nodeIds[2] = nodes[3];
1209 facesWithNodes.elems[3].nbNodes = 3;
1210 facesWithNodes.elems[3].vtkType = VTK_TRIANGLE;
1213 // ---------------------------------------------------------------------------
1215 SMDS_DownQuadTetra::SMDS_DownQuadTetra(SMDS_UnstructuredGrid *grid) :
1216 SMDS_Down3D(grid, 4)
1218 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1219 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1220 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1221 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1224 SMDS_DownQuadTetra::~SMDS_DownQuadTetra()
1228 void SMDS_DownQuadTetra::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
1232 for (int i = 0; i < orderedNodes.size(); i++)
1233 setNodes.insert(orderedNodes[i]);
1234 //MESSAGE("cellId = " << cellId);
1237 vtkIdType *nodes; // will refer to the point id's of the volume
1238 _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
1241 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 };
1242 //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 };
1243 for (int k = 0; k < 4; k++)
1246 for (int i = 0; i < 6; i++)
1247 tofind.insert(nodes[ids[6 * k + i]]);
1248 if (setNodes == tofind)
1250 for (int i = 0; i < 6; i++)
1251 orderedNodes[i] = nodes[ids[6 * k + i]];
1255 MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
1256 MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
1257 MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
1260 void SMDS_DownQuadTetra::addDownCell(int cellId, int lowCellId, unsigned char aType)
1262 //ASSERT((cellId >=0)&& (cellId < _maxId));
1263 //ASSERT(aType == VTK_QUADRATIC_TRIANGLE);
1264 int *faces = &_cellIds[_nbDownCells * cellId];
1265 for (int i = 0; i < _nbDownCells; i++)
1269 faces[i] = lowCellId;
1272 if (faces[i] == lowCellId)
1278 /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's
1279 * The ordering of the ten points defining the quadratic tetrahedron cell is point id's (0-3,4-9)
1280 * where id's 0-3 are the four tetrahedron vertices;
1281 * 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).
1282 * @see vtkQuadraticTetra.h in Filtering.
1283 * @param cellId volumeId in vtkUnstructuredGrid
1284 * @param facesWithNodes vector of face descriptors to be filled
1286 void SMDS_DownQuadTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
1288 // --- find point id's of the volume
1291 vtkIdType *nodes; // will refer to the point id's of the volume
1292 _grid->GetCellPoints(cellId, npts, nodes);
1294 // --- create all the ordered list of node id's for each face
1296 facesWithNodes.nbElems = 4;
1298 facesWithNodes.elems[0].nodeIds[0] = nodes[0];
1299 facesWithNodes.elems[0].nodeIds[1] = nodes[1];
1300 facesWithNodes.elems[0].nodeIds[2] = nodes[2];
1301 facesWithNodes.elems[0].nodeIds[3] = nodes[4];
1302 facesWithNodes.elems[0].nodeIds[4] = nodes[5];
1303 facesWithNodes.elems[0].nodeIds[5] = nodes[6];
1304 facesWithNodes.elems[0].nbNodes = 6;
1305 facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_TRIANGLE;
1307 facesWithNodes.elems[1].nodeIds[0] = nodes[0];
1308 facesWithNodes.elems[1].nodeIds[1] = nodes[1];
1309 facesWithNodes.elems[1].nodeIds[2] = nodes[3];
1310 facesWithNodes.elems[1].nodeIds[3] = nodes[4];
1311 facesWithNodes.elems[1].nodeIds[4] = nodes[8];
1312 facesWithNodes.elems[1].nodeIds[5] = nodes[7];
1313 facesWithNodes.elems[1].nbNodes = 6;
1314 facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE;
1316 facesWithNodes.elems[2].nodeIds[0] = nodes[0];
1317 facesWithNodes.elems[2].nodeIds[1] = nodes[2];
1318 facesWithNodes.elems[2].nodeIds[2] = nodes[3];
1319 facesWithNodes.elems[2].nodeIds[3] = nodes[6];
1320 facesWithNodes.elems[2].nodeIds[4] = nodes[9];
1321 facesWithNodes.elems[2].nodeIds[5] = nodes[7];
1322 facesWithNodes.elems[2].nbNodes = 6;
1323 facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE;
1325 facesWithNodes.elems[3].nodeIds[0] = nodes[1];
1326 facesWithNodes.elems[3].nodeIds[1] = nodes[2];
1327 facesWithNodes.elems[3].nodeIds[2] = nodes[3];
1328 facesWithNodes.elems[3].nodeIds[3] = nodes[5];
1329 facesWithNodes.elems[3].nodeIds[4] = nodes[9];
1330 facesWithNodes.elems[3].nodeIds[5] = nodes[8];
1331 facesWithNodes.elems[3].nbNodes = 6;
1332 facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
1335 // ---------------------------------------------------------------------------
1337 SMDS_DownPyramid::SMDS_DownPyramid(SMDS_UnstructuredGrid *grid) :
1338 SMDS_Down3D(grid, 5)
1340 _cellTypes.push_back(VTK_QUAD);
1341 _cellTypes.push_back(VTK_TRIANGLE);
1342 _cellTypes.push_back(VTK_TRIANGLE);
1343 _cellTypes.push_back(VTK_TRIANGLE);
1344 _cellTypes.push_back(VTK_TRIANGLE);
1347 SMDS_DownPyramid::~SMDS_DownPyramid()
1351 void SMDS_DownPyramid::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
1355 for (int i = 0; i < orderedNodes.size(); i++)
1356 setNodes.insert(orderedNodes[i]);
1357 //MESSAGE("cellId = " << cellId);
1360 vtkIdType *nodes; // will refer to the point id's of the volume
1361 _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
1364 int ids[16] = { 0, 1, 2, 3, 0, 3, 4, 3, 2, 4, 2, 1, 4, 1, 0, 4 };
1366 // Quadrangular face
1368 for (int i = 0; i < 4; i++)
1369 tofind.insert(nodes[ids[i]]);
1370 if (setNodes == tofind)
1372 for (int i = 0; i < 4; i++)
1373 orderedNodes[i] = nodes[ids[i]];
1377 for (int k = 0; k < 4; k++)
1380 for (int i = 0; i < 3; i++)
1381 tofind.insert(nodes[ids[4 + 3 * k + i]]);
1382 if (setNodes == tofind)
1384 for (int i = 0; i < 3; i++)
1385 orderedNodes[i] = nodes[ids[4 + 3 * k + i]];
1389 MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
1390 MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
1391 MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
1394 void SMDS_DownPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType)
1396 //ASSERT((cellId >=0) && (cellId < _maxId));
1397 int *faces = &_cellIds[_nbDownCells * cellId];
1398 if (aType == VTK_QUAD)
1402 faces[0] = lowCellId;
1405 if (faces[0] == lowCellId)
1410 //ASSERT(aType == VTK_TRIANGLE);
1411 for (int i = 1; i < _nbDownCells; i++)
1415 faces[i] = lowCellId;
1418 if (faces[i] == lowCellId)
1425 /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's
1426 * The pyramid is defined by the five points (0-4) where (0,1,2,3) is the base of the pyramid which,
1427 * using the right hand rule, forms a quadrilateral whose normal points in the direction of the
1428 * pyramid apex at vertex #4.
1429 * @see vtkPyramid.h in Filtering.
1430 * @param cellId volumeId in vtkUnstructuredGrid
1431 * @param facesWithNodes vector of face descriptors to be filled
1433 void SMDS_DownPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
1435 // --- find point id's of the volume
1438 vtkIdType *nodes; // will refer to the point id's of the volume
1439 _grid->GetCellPoints(cellId, npts, nodes);
1441 // --- create all the ordered list of node id's for each face
1443 facesWithNodes.nbElems = 5;
1445 facesWithNodes.elems[0].nodeIds[0] = nodes[0];
1446 facesWithNodes.elems[0].nodeIds[1] = nodes[1];
1447 facesWithNodes.elems[0].nodeIds[2] = nodes[2];
1448 facesWithNodes.elems[0].nodeIds[3] = nodes[3];
1449 facesWithNodes.elems[0].nbNodes = 4;
1450 facesWithNodes.elems[0].vtkType = VTK_QUAD;
1452 facesWithNodes.elems[1].nodeIds[0] = nodes[0];
1453 facesWithNodes.elems[1].nodeIds[1] = nodes[1];
1454 facesWithNodes.elems[1].nodeIds[2] = nodes[4];
1455 facesWithNodes.elems[1].nbNodes = 3;
1456 facesWithNodes.elems[1].vtkType = VTK_TRIANGLE;
1458 facesWithNodes.elems[2].nodeIds[0] = nodes[1];
1459 facesWithNodes.elems[2].nodeIds[1] = nodes[2];
1460 facesWithNodes.elems[2].nodeIds[2] = nodes[4];
1461 facesWithNodes.elems[2].nbNodes = 3;
1462 facesWithNodes.elems[2].vtkType = VTK_TRIANGLE;
1464 facesWithNodes.elems[3].nodeIds[0] = nodes[2];
1465 facesWithNodes.elems[3].nodeIds[1] = nodes[3];
1466 facesWithNodes.elems[3].nodeIds[2] = nodes[4];
1467 facesWithNodes.elems[3].nbNodes = 3;
1468 facesWithNodes.elems[3].vtkType = VTK_TRIANGLE;
1470 facesWithNodes.elems[4].nodeIds[0] = nodes[3];
1471 facesWithNodes.elems[4].nodeIds[1] = nodes[0];
1472 facesWithNodes.elems[4].nodeIds[2] = nodes[4];
1473 facesWithNodes.elems[4].nbNodes = 3;
1474 facesWithNodes.elems[4].vtkType = VTK_TRIANGLE;
1477 // ---------------------------------------------------------------------------
1479 SMDS_DownQuadPyramid::SMDS_DownQuadPyramid(SMDS_UnstructuredGrid *grid) :
1480 SMDS_Down3D(grid, 5)
1482 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
1483 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1484 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1485 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1486 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1489 SMDS_DownQuadPyramid::~SMDS_DownQuadPyramid()
1493 void SMDS_DownQuadPyramid::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
1495 // MESSAGE("SMDS_DownQuadPyramid::getOrderedNodesOfFace cellId = " << cellId);
1498 for (int i = 0; i < orderedNodes.size(); i++)
1499 setNodes.insert(orderedNodes[i]);
1500 //MESSAGE("cellId = " << cellId);
1503 vtkIdType *nodes; // will refer to the point id's of the volume
1504 _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
1507 int ids[32] = { 0, 1, 2, 3, 5, 6, 7, 8,
1508 0, 3, 4, 8, 12, 9, 3, 2, 4, 7 , 11, 12, 2, 1, 4, 6, 10, 11, 1, 0, 4, 5, 9, 10 };
1510 // Quadrangular face
1512 for (int i = 0; i < 8; i++)
1513 tofind.insert(nodes[ids[i]]);
1514 if (setNodes == tofind)
1516 for (int i = 0; i < 8; i++)
1517 orderedNodes[i] = nodes[ids[i]];
1521 for (int k = 0; k < 4; k++)
1524 for (int i = 0; i < 6; i++)
1525 tofind.insert(nodes[ids[8 + 6 * k + i]]);
1526 if (setNodes == tofind)
1528 for (int i = 0; i < 6; i++)
1529 orderedNodes[i] = nodes[ids[8 + 6 * k + i]];
1533 MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
1534 MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]);
1535 MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
1538 void SMDS_DownQuadPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType)
1540 //ASSERT((cellId >=0) && (cellId < _maxId));
1541 int *faces = &_cellIds[_nbDownCells * cellId];
1542 if (aType == VTK_QUADRATIC_QUAD)
1546 faces[0] = lowCellId;
1549 if (faces[0] == lowCellId)
1554 //ASSERT(aType == VTK_QUADRATIC_TRIANGLE);
1555 for (int i = 1; i < _nbDownCells; i++)
1559 faces[i] = lowCellId;
1562 if (faces[i] == lowCellId)
1569 /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's
1570 * The ordering of the thirteen points defining the quadratic pyramid cell is point id's (0-4,5-12)
1571 * where point id's 0-4 are the five corner vertices of the pyramid; followed
1572 * by eight mid-edge nodes (5-12). Note that these mid-edge nodes lie on the edges defined by
1573 * 5(0,1), 6(1,2), 7(2,3), 8(3,0), 9(0,4), 10(1,4), 11(2,4), 12(3,4).
1574 * @see vtkQuadraticPyramid.h in Filtering.
1575 * @param cellId volumeId in vtkUnstructuredGrid
1576 * @param facesWithNodes vector of face descriptors to be filled
1578 void SMDS_DownQuadPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
1580 // --- find point id's of the volume
1583 vtkIdType *nodes; // will refer to the point id's of the volume
1584 _grid->GetCellPoints(cellId, npts, nodes);
1586 // --- create all the ordered list of node id's for each face
1588 facesWithNodes.nbElems = 5;
1590 facesWithNodes.elems[0].nodeIds[0] = nodes[0];
1591 facesWithNodes.elems[0].nodeIds[1] = nodes[1];
1592 facesWithNodes.elems[0].nodeIds[2] = nodes[2];
1593 facesWithNodes.elems[0].nodeIds[3] = nodes[3];
1594 facesWithNodes.elems[0].nodeIds[4] = nodes[5];
1595 facesWithNodes.elems[0].nodeIds[5] = nodes[6];
1596 facesWithNodes.elems[0].nodeIds[6] = nodes[7];
1597 facesWithNodes.elems[0].nodeIds[7] = nodes[8];
1598 facesWithNodes.elems[0].nbNodes = 8;
1599 facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD;
1601 facesWithNodes.elems[1].nodeIds[0] = nodes[0];
1602 facesWithNodes.elems[1].nodeIds[1] = nodes[1];
1603 facesWithNodes.elems[1].nodeIds[2] = nodes[4];
1604 facesWithNodes.elems[1].nodeIds[3] = nodes[5];
1605 facesWithNodes.elems[1].nodeIds[4] = nodes[10];
1606 facesWithNodes.elems[1].nodeIds[5] = nodes[9];
1607 facesWithNodes.elems[1].nbNodes = 6;
1608 facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE;
1610 facesWithNodes.elems[2].nodeIds[0] = nodes[1];
1611 facesWithNodes.elems[2].nodeIds[1] = nodes[2];
1612 facesWithNodes.elems[2].nodeIds[2] = nodes[4];
1613 facesWithNodes.elems[2].nodeIds[3] = nodes[6];
1614 facesWithNodes.elems[2].nodeIds[4] = nodes[11];
1615 facesWithNodes.elems[2].nodeIds[5] = nodes[10];
1616 facesWithNodes.elems[2].nbNodes = 6;
1617 facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE;
1619 facesWithNodes.elems[3].nodeIds[0] = nodes[2];
1620 facesWithNodes.elems[3].nodeIds[1] = nodes[3];
1621 facesWithNodes.elems[3].nodeIds[2] = nodes[4];
1622 facesWithNodes.elems[3].nodeIds[3] = nodes[7];
1623 facesWithNodes.elems[3].nodeIds[4] = nodes[12];
1624 facesWithNodes.elems[3].nodeIds[5] = nodes[11];
1625 facesWithNodes.elems[3].nbNodes = 6;
1626 facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
1628 facesWithNodes.elems[4].nodeIds[0] = nodes[3];
1629 facesWithNodes.elems[4].nodeIds[1] = nodes[0];
1630 facesWithNodes.elems[4].nodeIds[2] = nodes[4];
1631 facesWithNodes.elems[4].nodeIds[3] = nodes[8];
1632 facesWithNodes.elems[4].nodeIds[4] = nodes[9];
1633 facesWithNodes.elems[4].nodeIds[5] = nodes[12];
1634 facesWithNodes.elems[4].nbNodes = 6;
1635 facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_TRIANGLE;
1638 // ---------------------------------------------------------------------------
1640 SMDS_DownPenta::SMDS_DownPenta(SMDS_UnstructuredGrid *grid) :
1641 SMDS_Down3D(grid, 5)
1643 _cellTypes.push_back(VTK_QUAD);
1644 _cellTypes.push_back(VTK_QUAD);
1645 _cellTypes.push_back(VTK_QUAD);
1646 _cellTypes.push_back(VTK_TRIANGLE);
1647 _cellTypes.push_back(VTK_TRIANGLE);
1650 SMDS_DownPenta::~SMDS_DownPenta()
1654 void SMDS_DownPenta::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
1658 for (int i = 0; i < orderedNodes.size(); i++)
1659 setNodes.insert(orderedNodes[i]);
1660 //MESSAGE("cellId = " << cellId);
1663 vtkIdType *nodes; // will refer to the point id's of the volume
1664 _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
1667 //int ids[18] = { 0, 2, 1, 3, 4, 5, 0, 1, 4, 3, 1, 2, 5, 4, 2, 0, 3, 5 };
1668 int ids[18] = { 0, 1, 2, 3, 5, 4, 0, 3, 4, 1, 1, 4, 5, 2, 2, 5, 3, 0 };
1671 for (int k = 0; k < 2; k++)
1674 for (int i = 0; i < 3; i++)
1675 tofind.insert(nodes[ids[3 * k + i]]);
1676 if (setNodes == tofind)
1678 for (int i = 0; i < 3; i++)
1679 orderedNodes[i] = nodes[ids[3 * k + i]];
1683 // Quadrangular faces
1684 for (int k = 0; k < 3; k++)
1687 for (int i = 0; i < 4; i++)
1688 tofind.insert(nodes[ids[6 + 4 * k + i]]);
1689 if (setNodes == tofind)
1691 for (int i = 0; i < 4; i++)
1692 orderedNodes[i] = nodes[ids[6 + 4 * k + i]];
1696 MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
1697 MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
1698 MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
1701 void SMDS_DownPenta::addDownCell(int cellId, int lowCellId, unsigned char aType)
1703 //ASSERT((cellId >=0) && (cellId < _maxId));
1704 int *faces = &_cellIds[_nbDownCells * cellId];
1705 if (aType == VTK_QUAD)
1706 for (int i = 0; i < 3; i++)
1710 faces[i] = lowCellId;
1713 if (faces[i] == lowCellId)
1718 //ASSERT(aType == VTK_TRIANGLE);
1719 for (int i = 3; i < _nbDownCells; i++)
1723 faces[i] = lowCellId;
1726 if (faces[i] == lowCellId)
1733 /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's.
1734 * A wedge or pentahedron consists of two triangular and three quadrilateral faces
1735 * and is defined by the six points (0-5) where (0,1,2) is the base of the wedge which,
1736 * using the right hand rule, forms a triangle whose normal points outward
1737 * (away from the triangular face (3,4,5)).
1738 * @see vtkWedge.h in Filtering
1739 * @param cellId volumeId in vtkUnstructuredGrid
1740 * @param facesWithNodes vector of face descriptors to be filled
1742 void SMDS_DownPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
1744 // --- find point id's of the volume
1747 vtkIdType *nodes; // will refer to the point id's of the volume
1748 _grid->GetCellPoints(cellId, npts, nodes);
1750 // --- create all the ordered list of node id's for each face
1752 facesWithNodes.nbElems = 5;
1754 facesWithNodes.elems[0].nodeIds[0] = nodes[0];
1755 facesWithNodes.elems[0].nodeIds[1] = nodes[2];
1756 facesWithNodes.elems[0].nodeIds[2] = nodes[5];
1757 facesWithNodes.elems[0].nodeIds[3] = nodes[3];
1758 facesWithNodes.elems[0].nbNodes = 4;
1759 facesWithNodes.elems[0].vtkType = VTK_QUAD;
1761 facesWithNodes.elems[1].nodeIds[0] = nodes[1];
1762 facesWithNodes.elems[1].nodeIds[1] = nodes[2];
1763 facesWithNodes.elems[1].nodeIds[2] = nodes[5];
1764 facesWithNodes.elems[1].nodeIds[3] = nodes[4];
1765 facesWithNodes.elems[1].nbNodes = 4;
1766 facesWithNodes.elems[1].vtkType = VTK_QUAD;
1768 facesWithNodes.elems[2].nodeIds[0] = nodes[0];
1769 facesWithNodes.elems[2].nodeIds[1] = nodes[1];
1770 facesWithNodes.elems[2].nodeIds[2] = nodes[4];
1771 facesWithNodes.elems[2].nodeIds[3] = nodes[3];
1772 facesWithNodes.elems[2].nbNodes = 4;
1773 facesWithNodes.elems[2].vtkType = VTK_QUAD;
1775 facesWithNodes.elems[3].nodeIds[0] = nodes[0];
1776 facesWithNodes.elems[3].nodeIds[1] = nodes[1];
1777 facesWithNodes.elems[3].nodeIds[2] = nodes[2];
1778 facesWithNodes.elems[3].nbNodes = 3;
1779 facesWithNodes.elems[3].vtkType = VTK_TRIANGLE;
1781 facesWithNodes.elems[4].nodeIds[0] = nodes[3];
1782 facesWithNodes.elems[4].nodeIds[1] = nodes[4];
1783 facesWithNodes.elems[4].nodeIds[2] = nodes[5];
1784 facesWithNodes.elems[4].nbNodes = 3;
1785 facesWithNodes.elems[4].vtkType = VTK_TRIANGLE;
1788 // ---------------------------------------------------------------------------
1790 SMDS_DownQuadPenta::SMDS_DownQuadPenta(SMDS_UnstructuredGrid *grid) :
1791 SMDS_Down3D(grid, 5)
1793 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
1794 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
1795 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
1796 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1797 _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
1800 SMDS_DownQuadPenta::~SMDS_DownQuadPenta()
1804 void SMDS_DownQuadPenta::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
1808 for (int i = 0; i < orderedNodes.size(); i++)
1809 setNodes.insert(orderedNodes[i]);
1810 //MESSAGE("cellId = " << cellId);
1813 vtkIdType *nodes; // will refer to the point id's of the volume
1814 _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
1817 //int ids[18] = { 0, 2, 1, 3, 4, 5, 0, 1, 4, 3, 1, 2, 5, 4, 2, 0, 3, 5 };
1818 int ids[36] = { 0, 1, 2, 6, 7, 8, 3, 5, 4, 11, 10, 9,
1819 0, 3, 4, 1, 12, 9, 13, 6, 1, 4, 5, 2, 13, 10, 14, 7, 2, 5, 3, 0, 14, 11, 12, 8 };
1822 for (int k = 0; k < 2; k++)
1825 for (int i = 0; i < 6; i++)
1826 tofind.insert(nodes[ids[6 * k + i]]);
1827 if (setNodes == tofind)
1829 for (int i = 0; i < 6; i++)
1830 orderedNodes[i] = nodes[ids[6 * k + i]];
1834 // Quadrangular faces
1835 for (int k = 0; k < 3; k++)
1838 for (int i = 0; i < 8; i++)
1839 tofind.insert(nodes[ids[12 + 8 * k + i]]);
1840 if (setNodes == tofind)
1842 for (int i = 0; i < 8; i++)
1843 orderedNodes[i] = nodes[ids[12 + 8 * k + i]];
1847 MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
1848 MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
1849 MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
1852 void SMDS_DownQuadPenta::addDownCell(int cellId, int lowCellId, unsigned char aType)
1854 //ASSERT((cellId >=0) && (cellId < _maxId));
1855 int *faces = &_cellIds[_nbDownCells * cellId];
1856 if (aType == VTK_QUADRATIC_QUAD)
1857 for (int i = 0; i < 3; i++)
1861 faces[i] = lowCellId;
1864 if (faces[i] == lowCellId)
1869 //ASSERT(aType == VTK_QUADRATIC_TRIANGLE);
1870 for (int i = 3; i < _nbDownCells; i++)
1874 faces[i] = lowCellId;
1877 if (faces[i] == lowCellId)
1884 /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's
1885 * The quadratic wedge (or pentahedron) is defined by fifteen points.
1886 * The ordering of the fifteen points defining the cell is point id's (0-5,6-14)
1887 * where point id's 0-5 are the six corner vertices of the wedge, followed by
1888 * nine mid-edge nodes (6-14). Note that these mid-edge nodes lie on the edges defined by
1889 * (0,1), (1,2), (2,0), (3,4), (4,5), (5,3), (0,3), (1,4), (2,5).
1890 * @see vtkQuadraticWedge.h in Filtering
1891 * @param cellId volumeId in vtkUnstructuredGrid
1892 * @param facesWithNodes vector of face descriptors to be filled
1894 void SMDS_DownQuadPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
1896 // --- find point id's of the volume
1899 vtkIdType *nodes; // will refer to the point id's of the volume
1900 _grid->GetCellPoints(cellId, npts, nodes);
1902 // --- create all the ordered list of node id's for each face
1904 facesWithNodes.nbElems = 5;
1906 facesWithNodes.elems[0].nodeIds[0] = nodes[0];
1907 facesWithNodes.elems[0].nodeIds[1] = nodes[2];
1908 facesWithNodes.elems[0].nodeIds[2] = nodes[5];
1909 facesWithNodes.elems[0].nodeIds[3] = nodes[3];
1910 facesWithNodes.elems[0].nodeIds[4] = nodes[8];
1911 facesWithNodes.elems[0].nodeIds[5] = nodes[14];
1912 facesWithNodes.elems[0].nodeIds[6] = nodes[11];
1913 facesWithNodes.elems[0].nodeIds[7] = nodes[12];
1914 facesWithNodes.elems[0].nbNodes = 8;
1915 facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD;
1917 facesWithNodes.elems[1].nodeIds[0] = nodes[1];
1918 facesWithNodes.elems[1].nodeIds[1] = nodes[2];
1919 facesWithNodes.elems[1].nodeIds[2] = nodes[5];
1920 facesWithNodes.elems[1].nodeIds[3] = nodes[4];
1921 facesWithNodes.elems[1].nodeIds[4] = nodes[7];
1922 facesWithNodes.elems[1].nodeIds[5] = nodes[14];
1923 facesWithNodes.elems[1].nodeIds[6] = nodes[10];
1924 facesWithNodes.elems[1].nodeIds[7] = nodes[13];
1925 facesWithNodes.elems[1].nbNodes = 8;
1926 facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_QUAD;
1928 facesWithNodes.elems[2].nodeIds[0] = nodes[0];
1929 facesWithNodes.elems[2].nodeIds[1] = nodes[1];
1930 facesWithNodes.elems[2].nodeIds[2] = nodes[4];
1931 facesWithNodes.elems[2].nodeIds[3] = nodes[3];
1932 facesWithNodes.elems[2].nodeIds[4] = nodes[6];
1933 facesWithNodes.elems[2].nodeIds[5] = nodes[13];
1934 facesWithNodes.elems[2].nodeIds[6] = nodes[9];
1935 facesWithNodes.elems[2].nodeIds[7] = nodes[12];
1936 facesWithNodes.elems[2].nbNodes = 8;
1937 facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_QUAD;
1939 facesWithNodes.elems[3].nodeIds[0] = nodes[0];
1940 facesWithNodes.elems[3].nodeIds[1] = nodes[1];
1941 facesWithNodes.elems[3].nodeIds[2] = nodes[2];
1942 facesWithNodes.elems[3].nodeIds[3] = nodes[6];
1943 facesWithNodes.elems[3].nodeIds[4] = nodes[7];
1944 facesWithNodes.elems[3].nodeIds[5] = nodes[8];
1945 facesWithNodes.elems[3].nbNodes = 6;
1946 facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
1948 facesWithNodes.elems[4].nodeIds[0] = nodes[3];
1949 facesWithNodes.elems[4].nodeIds[1] = nodes[4];
1950 facesWithNodes.elems[4].nodeIds[2] = nodes[5];
1951 facesWithNodes.elems[4].nodeIds[3] = nodes[9];
1952 facesWithNodes.elems[4].nodeIds[4] = nodes[10];
1953 facesWithNodes.elems[4].nodeIds[5] = nodes[11];
1954 facesWithNodes.elems[4].nbNodes = 6;
1955 facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_TRIANGLE;
1958 // ---------------------------------------------------------------------------
1960 SMDS_DownHexa::SMDS_DownHexa(SMDS_UnstructuredGrid *grid) :
1961 SMDS_Down3D(grid, 6)
1963 _cellTypes.push_back(VTK_QUAD);
1964 _cellTypes.push_back(VTK_QUAD);
1965 _cellTypes.push_back(VTK_QUAD);
1966 _cellTypes.push_back(VTK_QUAD);
1967 _cellTypes.push_back(VTK_QUAD);
1968 _cellTypes.push_back(VTK_QUAD);
1971 SMDS_DownHexa::~SMDS_DownHexa()
1975 void SMDS_DownHexa::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
1979 for (int i = 0; i < orderedNodes.size(); i++)
1980 setNodes.insert(orderedNodes[i]);
1981 //MESSAGE("cellId = " << cellId);
1984 vtkIdType *nodes; // will refer to the point id's of the volume
1985 _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
1988 //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};
1989 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};
1990 for (int k = 0; k < 6; k++) // loop on the 6 faces
1993 for (int i = 0; i < 4; i++)
1994 tofind.insert(nodes[ids[4 * k + i]]); // node ids of the face i
1995 if (setNodes == tofind)
1997 for (int i = 0; i < 4; i++)
1998 orderedNodes[i] = nodes[ids[4 * k + i]];
2002 MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
2003 MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]);
2004 MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
2005 MESSAGE(nodes[4] << " " << nodes[5] << " " << nodes[6] << " " << nodes[7]);
2008 void SMDS_DownHexa::addDownCell(int cellId, int lowCellId, unsigned char aType)
2010 //ASSERT((cellId >=0)&& (cellId < _maxId));
2011 int *faces = &_cellIds[_nbDownCells * cellId];
2012 for (int i = 0; i < _nbDownCells; i++)
2016 faces[i] = lowCellId;
2019 if (faces[i] == lowCellId)
2023 // MESSAGE("-------------------------------------> trop de faces ! " << cellId << " " << lowCellId);
2026 /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's
2027 * The hexahedron is defined by the eight points (0-7), where (0,1,2,3) is the base
2028 * of the hexahedron which, using the right hand rule, forms a quadrilateral whose normal
2029 * points in the direction of the opposite face (4,5,6,7).
2030 * @see vtkHexahedron.h in Filtering
2031 * @param cellId volumeId in vtkUnstructuredGrid
2032 * @param facesWithNodes vector of face descriptors to be filled
2034 void SMDS_DownHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
2036 // --- find point id's of the volume
2039 vtkIdType *nodes; // will refer to the point id's of the volume
2040 _grid->GetCellPoints(cellId, npts, nodes);
2042 // --- create all the ordered list of node id's for each face
2044 facesWithNodes.nbElems = 6;
2046 facesWithNodes.elems[0].nodeIds[0] = nodes[0];
2047 facesWithNodes.elems[0].nodeIds[1] = nodes[1];
2048 facesWithNodes.elems[0].nodeIds[2] = nodes[2];
2049 facesWithNodes.elems[0].nodeIds[3] = nodes[3];
2050 facesWithNodes.elems[0].nbNodes = 4;
2051 facesWithNodes.elems[0].vtkType = VTK_QUAD;
2053 facesWithNodes.elems[1].nodeIds[0] = nodes[4];
2054 facesWithNodes.elems[1].nodeIds[1] = nodes[5];
2055 facesWithNodes.elems[1].nodeIds[2] = nodes[6];
2056 facesWithNodes.elems[1].nodeIds[3] = nodes[7];
2057 facesWithNodes.elems[1].nbNodes = 4;
2058 facesWithNodes.elems[1].vtkType = VTK_QUAD;
2060 facesWithNodes.elems[2].nodeIds[0] = nodes[0];
2061 facesWithNodes.elems[2].nodeIds[1] = nodes[1];
2062 facesWithNodes.elems[2].nodeIds[2] = nodes[5];
2063 facesWithNodes.elems[2].nodeIds[3] = nodes[4];
2064 facesWithNodes.elems[2].nbNodes = 4;
2065 facesWithNodes.elems[2].vtkType = VTK_QUAD;
2067 facesWithNodes.elems[3].nodeIds[0] = nodes[1];
2068 facesWithNodes.elems[3].nodeIds[1] = nodes[2];
2069 facesWithNodes.elems[3].nodeIds[2] = nodes[6];
2070 facesWithNodes.elems[3].nodeIds[3] = nodes[5];
2071 facesWithNodes.elems[3].nbNodes = 4;
2072 facesWithNodes.elems[3].vtkType = VTK_QUAD;
2074 facesWithNodes.elems[4].nodeIds[0] = nodes[2];
2075 facesWithNodes.elems[4].nodeIds[1] = nodes[6];
2076 facesWithNodes.elems[4].nodeIds[2] = nodes[7];
2077 facesWithNodes.elems[4].nodeIds[3] = nodes[3];
2078 facesWithNodes.elems[4].nbNodes = 4;
2079 facesWithNodes.elems[4].vtkType = VTK_QUAD;
2081 facesWithNodes.elems[5].nodeIds[0] = nodes[3];
2082 facesWithNodes.elems[5].nodeIds[1] = nodes[7];
2083 facesWithNodes.elems[5].nodeIds[2] = nodes[4];
2084 facesWithNodes.elems[5].nodeIds[3] = nodes[0];
2085 facesWithNodes.elems[5].nbNodes = 4;
2086 facesWithNodes.elems[5].vtkType = VTK_QUAD;
2089 // ---------------------------------------------------------------------------
2091 SMDS_DownQuadHexa::SMDS_DownQuadHexa(SMDS_UnstructuredGrid *grid) :
2092 SMDS_Down3D(grid, 6)
2094 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
2095 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
2096 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
2097 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
2098 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
2099 _cellTypes.push_back(VTK_QUADRATIC_QUAD);
2102 SMDS_DownQuadHexa::~SMDS_DownQuadHexa()
2106 void SMDS_DownQuadHexa::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
2110 for (int i = 0; i < orderedNodes.size(); i++)
2111 setNodes.insert(orderedNodes[i]);
2112 //MESSAGE("cellId = " << cellId);
2115 vtkIdType *nodes; // will refer to the point id's of the volume
2116 _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
2119 //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};
2120 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,
2121 4, 0, 1, 5,16, 8,17,12, 5, 1, 2, 6,17, 9,18,13, 6, 2, 3, 7,18,10,19,14};
2122 for (int k = 0; k < 6; k++)
2125 for (int i = 0; i < 8; i++)
2126 tofind.insert(nodes[ids[8 * k + i]]);
2127 if (setNodes == tofind)
2129 for (int i = 0; i < 8; i++)
2130 orderedNodes[i] = nodes[ids[8 * k + i]];
2134 MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
2135 MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]);
2136 MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
2139 void SMDS_DownQuadHexa::addDownCell(int cellId, int lowCellId, unsigned char aType)
2141 //ASSERT((cellId >=0)&& (cellId < _maxId));
2142 int *faces = &_cellIds[_nbDownCells * cellId];
2143 for (int i = 0; i < _nbDownCells; i++)
2147 faces[i] = lowCellId;
2150 if (faces[i] == lowCellId)
2156 /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's
2157 * The ordering of the twenty points defining the quadratic hexahedron cell is point id's (0-7,8-19)
2158 * where point id's 0-7 are the eight corner vertices of the cube, followed by twelve mid-edge nodes (8-19).
2159 * Note that these mid-edge nodes lie on the edges defined by
2160 * (0,1), (1,2), (2,3), (3,0), (4,5), (5,6), (6,7), (7,4), (0,4), (1,5), (2,6), (3,7).
2161 * @see vtkQuadraticHexahedron.h in Filtering
2162 * @param cellId volumeId in vtkUnstructuredGrid
2163 * @param facesWithNodes vector of face descriptors to be filled
2165 void SMDS_DownQuadHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
2167 // --- find point id's of the volume
2170 vtkIdType *nodes; // will refer to the point id's of the volume
2171 _grid->GetCellPoints(cellId, npts, nodes);
2173 // --- create all the ordered list of node id's for each face
2175 facesWithNodes.nbElems = 6;
2177 facesWithNodes.elems[0].nodeIds[0] = nodes[0];
2178 facesWithNodes.elems[0].nodeIds[1] = nodes[1];
2179 facesWithNodes.elems[0].nodeIds[2] = nodes[2];
2180 facesWithNodes.elems[0].nodeIds[3] = nodes[3];
2181 facesWithNodes.elems[0].nodeIds[4] = nodes[8];
2182 facesWithNodes.elems[0].nodeIds[5] = nodes[9];
2183 facesWithNodes.elems[0].nodeIds[6] = nodes[10];
2184 facesWithNodes.elems[0].nodeIds[7] = nodes[11];
2185 facesWithNodes.elems[0].nbNodes = 8;
2186 facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD;
2188 facesWithNodes.elems[1].nodeIds[0] = nodes[4];
2189 facesWithNodes.elems[1].nodeIds[1] = nodes[5];
2190 facesWithNodes.elems[1].nodeIds[2] = nodes[6];
2191 facesWithNodes.elems[1].nodeIds[3] = nodes[7];
2192 facesWithNodes.elems[1].nodeIds[4] = nodes[12];
2193 facesWithNodes.elems[1].nodeIds[5] = nodes[13];
2194 facesWithNodes.elems[1].nodeIds[6] = nodes[14];
2195 facesWithNodes.elems[1].nodeIds[7] = nodes[15];
2196 facesWithNodes.elems[1].nbNodes = 8;
2197 facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_QUAD;
2199 facesWithNodes.elems[2].nodeIds[0] = nodes[0];
2200 facesWithNodes.elems[2].nodeIds[1] = nodes[1];
2201 facesWithNodes.elems[2].nodeIds[2] = nodes[5];
2202 facesWithNodes.elems[2].nodeIds[3] = nodes[4];
2203 facesWithNodes.elems[2].nodeIds[4] = nodes[8];
2204 facesWithNodes.elems[2].nodeIds[5] = nodes[17];
2205 facesWithNodes.elems[2].nodeIds[6] = nodes[12];
2206 facesWithNodes.elems[2].nodeIds[7] = nodes[16];
2207 facesWithNodes.elems[2].nbNodes = 8;
2208 facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_QUAD;
2210 facesWithNodes.elems[3].nodeIds[0] = nodes[1];
2211 facesWithNodes.elems[3].nodeIds[1] = nodes[2];
2212 facesWithNodes.elems[3].nodeIds[2] = nodes[6];
2213 facesWithNodes.elems[3].nodeIds[3] = nodes[5];
2214 facesWithNodes.elems[3].nodeIds[4] = nodes[9];
2215 facesWithNodes.elems[3].nodeIds[5] = nodes[18];
2216 facesWithNodes.elems[3].nodeIds[6] = nodes[13];
2217 facesWithNodes.elems[3].nodeIds[7] = nodes[17];
2218 facesWithNodes.elems[3].nbNodes = 8;
2219 facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_QUAD;
2221 facesWithNodes.elems[4].nodeIds[0] = nodes[2];
2222 facesWithNodes.elems[4].nodeIds[1] = nodes[6];
2223 facesWithNodes.elems[4].nodeIds[2] = nodes[7];
2224 facesWithNodes.elems[4].nodeIds[3] = nodes[3];
2225 facesWithNodes.elems[4].nodeIds[4] = nodes[18];
2226 facesWithNodes.elems[4].nodeIds[5] = nodes[14];
2227 facesWithNodes.elems[4].nodeIds[6] = nodes[19];
2228 facesWithNodes.elems[4].nodeIds[7] = nodes[10];
2229 facesWithNodes.elems[4].nbNodes = 8;
2230 facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_QUAD;
2232 facesWithNodes.elems[5].nodeIds[0] = nodes[3];
2233 facesWithNodes.elems[5].nodeIds[1] = nodes[7];
2234 facesWithNodes.elems[5].nodeIds[2] = nodes[4];
2235 facesWithNodes.elems[5].nodeIds[3] = nodes[0];
2236 facesWithNodes.elems[5].nodeIds[4] = nodes[19];
2237 facesWithNodes.elems[5].nodeIds[5] = nodes[15];
2238 facesWithNodes.elems[5].nodeIds[6] = nodes[16];
2239 facesWithNodes.elems[5].nodeIds[7] = nodes[11];
2240 facesWithNodes.elems[5].nbNodes = 8;
2241 facesWithNodes.elems[5].vtkType = VTK_QUADRATIC_QUAD;
2244 // ---------------------------------------------------------------------------