// Copyright (C) 2010-2014 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // File: SMDS_Downward.cxx // Created: Jun 3, 2010 // Author: prascle #include "SMDS_Downward.hxx" #include "SMDS_Mesh.hxx" #include "utilities.h" #include #include #include using namespace std; // --------------------------------------------------------------------------- vector SMDS_Downward::_cellDimension; /*! get the dimension of a cell (1,2,3 for 1D, 2D 3D) given the vtk cell type * * @param cellType vtk cell type @see vtkCellType.h * @return 1,2 or 3 */ int SMDS_Downward::getCellDimension(unsigned char cellType) { if (_cellDimension.empty()) { _cellDimension.resize(VTK_MAXTYPE + 1, 0); _cellDimension[VTK_LINE] = 1; _cellDimension[VTK_QUADRATIC_EDGE] = 1; _cellDimension[VTK_TRIANGLE] = 2; _cellDimension[VTK_QUADRATIC_TRIANGLE] = 2; _cellDimension[VTK_BIQUADRATIC_TRIANGLE] = 2; _cellDimension[VTK_QUAD] = 2; _cellDimension[VTK_QUADRATIC_QUAD] = 2; _cellDimension[VTK_BIQUADRATIC_QUAD] = 2; _cellDimension[VTK_TETRA] = 3; _cellDimension[VTK_QUADRATIC_TETRA] = 3; _cellDimension[VTK_HEXAHEDRON] = 3; _cellDimension[VTK_QUADRATIC_HEXAHEDRON] = 3; _cellDimension[VTK_TRIQUADRATIC_HEXAHEDRON] = 3; _cellDimension[VTK_WEDGE] = 3; _cellDimension[VTK_QUADRATIC_WEDGE] = 3; _cellDimension[VTK_PYRAMID] = 3; _cellDimension[VTK_QUADRATIC_PYRAMID] = 3; _cellDimension[VTK_HEXAGONAL_PRISM] = 3; } return _cellDimension[cellType]; } // --------------------------------------------------------------------------- /*! Generic constructor for all the downward connectivity structures (one per vtk cell type). * The static structure for cell dimension is set only once. * @param grid unstructured grid associated to the mesh. * @param nbDownCells number of downward entities associated to this vtk type of cell. * @return */ SMDS_Downward::SMDS_Downward(SMDS_UnstructuredGrid *grid, int nbDownCells) : _grid(grid), _nbDownCells(nbDownCells) { this->_maxId = 0; this->_cellIds.clear(); this->_cellTypes.clear(); if (_cellDimension.empty()) getCellDimension( VTK_LINE ); } SMDS_Downward::~SMDS_Downward() { } /*! Give or create an entry for downward connectivity structure relative to a cell. * If the entry already exists, just return its id, otherwise, create it. * The internal storage memory is allocated if needed. * The SMDS_UnstructuredGrid::_cellIdToDownId vector is completed for vtkUnstructuredGrid cells. * @param vtkId for a vtkUnstructuredGrid cell or -1 (default) for a created downward cell. * @return the rank in downward[vtkType] structure. */ int SMDS_Downward::addCell(int vtkId) { int localId = -1; if (vtkId >= 0) localId = _grid->CellIdToDownId(vtkId); if (localId >= 0) return localId; localId = this->_maxId; this->_maxId++; this->allocate(_maxId); if (vtkId >= 0) { this->_vtkCellIds[localId] = vtkId; _grid->setCellIdToDownId(vtkId, localId); } this->initCell(localId); return localId; } /*! generic method do nothing. see derived methods * * @param cellId */ void SMDS_Downward::initCell(int cellId) { } /*! Get the number of downward entities associated to a cell (always the same for a given vtk type of cell) * * @param cellId not used here. * @return */ int SMDS_Downward::getNumberOfDownCells(int cellId) { return _nbDownCells; } /*! get a pointer on the downward entities id's associated to a cell. * @see SMDS_Downward::getNumberOfDownCells for the number of downward entities. * @see SMDS_Downward::getDownTypes for the vtk cell types associated to the downward entities. * @param cellId index of the cell in the downward structure relative to a given vtk cell type. * @return table of downward entities id's. */ const int* SMDS_Downward::getDownCells(int cellId) { //ASSERT((cellId >=0) && (cellId < _maxId)); return &_cellIds[_nbDownCells * cellId]; } /*! get a list of vtk cell types associated to downward entities of a given cell, in the same order * than the downward entities id's list (@see SMDS_Downward::getDownCells). * * @param cellId index of the cell in the downward structure relative to a vtk cell type. * @return table of downward entities types. */ const unsigned char* SMDS_Downward::getDownTypes(int cellId) { return &_cellTypes[0]; } /*! add a downward entity of dimension n-1 (cell or node) to a given cell. * Actual implementation is done in derived methods. * @param cellId index of the parent cell (dimension n) in the downward structure relative to a vtk cell type. * @param lowCellId index of the children cell to add (dimension n-1) * @param aType vtk cell type of the cell to add (needed to find the SMDS_Downward structure containing the cell to add). */ void SMDS_Downward::addDownCell(int cellId, int lowCellId, unsigned char aType) { ASSERT(0); // must be re-implemented in derived class } /*! add a downward entity of dimension n+1 to a given cell. * Actual implementation is done in derived methods. * @param cellId index of the children cell (dimension n) in the downward structure relative to a vtk cell type. * @param upCellId index of the parent cell to add (dimension n+1) * @param aType vtk cell type of the cell to add (needed to find the SMDS_Downward structure containing the cell to add). */ void SMDS_Downward::addUpCell(int cellId, int upCellId, unsigned char aType) { ASSERT(0); // must be re-implemented in derived class } int SMDS_Downward::getNodeSet(int cellId, int* nodeSet) { return 0; } // --------------------------------------------------------------------------- SMDS_Down1D::SMDS_Down1D(SMDS_UnstructuredGrid *grid, int nbDownCells) : SMDS_Downward(grid, nbDownCells) { _upCellIdsVector.clear(); _upCellTypesVector.clear(); _upCellIds.clear(); _upCellTypes.clear(); _upCellIndex.clear(); } SMDS_Down1D::~SMDS_Down1D() { } /*! clear vectors used to reference 2D cells containing the edge * * @param cellId */ void SMDS_Down1D::initCell(int cellId) { _upCellIdsVector[cellId].clear(); _upCellTypesVector[cellId].clear(); } /*! Resize the downward connectivity storage vector if needed. * * @param nbElems total number of elements of the same type required */ void SMDS_Down1D::allocate(int nbElems) { if (nbElems >= _vtkCellIds.size()) { _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1); _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1); _upCellIdsVector.resize(nbElems + SMDS_Mesh::chunkSize); _upCellTypesVector.resize(nbElems + SMDS_Mesh::chunkSize); } } void SMDS_Down1D::compactStorage() { _cellIds.resize(_nbDownCells * _maxId); _vtkCellIds.resize(_maxId); int sizeUpCells = 0; for (int i = 0; i < _maxId; i++) sizeUpCells += _upCellIdsVector[i].size(); _upCellIds.resize(sizeUpCells, -1); _upCellTypes.resize(sizeUpCells); _upCellIndex.resize(_maxId + 1, -1); // id and types of rank i correspond to [ _upCellIndex[i], _upCellIndex[i+1] [ int current = 0; for (int i = 0; i < _maxId; i++) { _upCellIndex[i] = current; for (int j = 0; j < _upCellIdsVector[i].size(); j++) { _upCellIds[current] = _upCellIdsVector[i][j]; _upCellTypes[current] = _upCellTypesVector[i][j]; current++; } } _upCellIndex[_maxId] = current; _upCellIdsVector.clear(); _upCellTypesVector.clear(); } void SMDS_Down1D::addUpCell(int cellId, int upCellId, unsigned char aType) { //ASSERT((cellId >=0) && (cellId < _maxId)); int nbFaces = _upCellIdsVector[cellId].size(); for (int i = 0; i < nbFaces; i++) { if ((_upCellIdsVector[cellId][i] == upCellId) && (_upCellTypesVector[cellId][i] == aType)) { return; // already done } } _upCellIdsVector[cellId].push_back(upCellId); _upCellTypesVector[cellId].push_back(aType); } int SMDS_Down1D::getNumberOfUpCells(int cellId) { //ASSERT((cellId >=0) && (cellId < _maxId)); return _upCellIndex[cellId + 1] - _upCellIndex[cellId]; } const int* SMDS_Down1D::getUpCells(int cellId) { //ASSERT((cellId >=0) && (cellId < _maxId)); return &_upCellIds[_upCellIndex[cellId]]; } const unsigned char* SMDS_Down1D::getUpTypes(int cellId) { //ASSERT((cellId >=0) && (cellId < _maxId)); return &_upCellTypes[_upCellIndex[cellId]]; } void SMDS_Down1D::getNodeIds(int cellId, std::set& nodeSet) { for (int i = 0; i < _nbDownCells; i++) nodeSet.insert(_cellIds[_nbDownCells * cellId + i]); } int SMDS_Down1D::getNodeSet(int cellId, int* nodeSet) { for (int i = 0; i < _nbDownCells; i++) nodeSet[i] = _cellIds[_nbDownCells * cellId + i]; return _nbDownCells; } void SMDS_Down1D::setNodes(int cellId, int vtkId) { vtkIdType npts = 0; vtkIdType *pts; // will refer to the point id's of the face _grid->GetCellPoints(vtkId, npts, pts); // MESSAGE(vtkId << " " << npts << " " << _nbDownCells); //ASSERT(npts == _nbDownCells); for (int i = 0; i < npts; i++) { _cellIds[_nbDownCells * cellId + i] = pts[i]; } } void SMDS_Down1D::setNodes(int cellId, const int* nodeIds) { //ASSERT(nodeIds.size() == _nbDownCells); for (int i = 0; i < _nbDownCells; i++) { _cellIds[_nbDownCells * cellId + i] = nodeIds[i]; } } /*! Build the list of vtkUnstructuredGrid cells containing the edge. * We keep in the list the cells that contains all the nodes, we keep only volumes and faces. * @param cellId id of the edge in the downward structure * @param vtkIds vector of vtk id's * @return number of vtk cells (size of vector) */ int SMDS_Down1D::computeVtkCells(int cellId, std::vector& vtkIds) { vtkIds.clear(); // --- find all the cells the points belong to, and how many of the points belong to a given cell int *pts = &_cellIds[_nbDownCells * cellId]; int ncells = this->computeVtkCells(pts, vtkIds); return ncells; } /*! Build the list of vtkUnstructuredGrid cells containing the edge. * * @param pts list of points id's defining an edge * @param vtkIds vector of vtk id's * @return number of vtk cells (size of vector) */ int SMDS_Down1D::computeVtkCells(int *pts, std::vector& vtkIds) { // --- find all the cells the points belong to, and how many of the points belong to a given cell int cellIds[1000]; int cellCnt[1000]; int cnt = 0; for (int i = 0; i < _nbDownCells; i++) { vtkIdType point = pts[i]; int numCells = _grid->GetLinks()->GetNcells(point); vtkIdType *cells = _grid->GetLinks()->GetCells(point); for (int j = 0; j < numCells; j++) { int vtkCellId = cells[j]; bool found = false; for (int k = 0; k < cnt; k++) { if (cellIds[k] == vtkCellId) { cellCnt[k] += 1; found = true; break; } } if (!found) { cellIds[cnt] = vtkCellId; cellCnt[cnt] = 1; // TODO ASSERT(cnt<1000); cnt++; } } } // --- find the face and volume cells: they contains all the points and are of type volume or face int ncells = 0; for (int i = 0; i < cnt; i++) { if (cellCnt[i] == _nbDownCells) { int vtkElemId = cellIds[i]; int vtkType = _grid->GetCellType(vtkElemId); if (SMDS_Downward::getCellDimension(vtkType) > 1) { vtkIds.push_back(vtkElemId); ncells++; } } } return ncells; } /*! Build the list of downward faces from a list of vtk cells. * * @param cellId id of the edge in the downward structure * @param vtkIds vector of vtk id's * @param downFaces vector of face id's in downward structures * @param downTypes vector of face types * @return number of downward faces */ int SMDS_Down1D::computeFaces(int cellId, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes) { int *pts = &_cellIds[_nbDownCells * cellId]; int nbFaces = this->computeFaces(pts, vtkIds, nbcells, downFaces, downTypes); return nbFaces; } /*! Build the list of downward faces from a list of vtk cells. * * @param pts list of points id's defining an edge * @param vtkIds vector of vtk id's * @param downFaces vector of face id's in downward structures * @param downTypes vector of face types * @return number of downward faces */ int SMDS_Down1D::computeFaces(int* pts, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes) { int cnt = 0; for (int i = 0; i < nbcells; i++) { int vtkId = vtkIds[i]; int vtkType = _grid->GetCellType(vtkId); if (SMDS_Downward::getCellDimension(vtkType) == 2) { int faceId = _grid->CellIdToDownId(vtkId); downFaces[cnt] = faceId; downTypes[cnt] = vtkType; cnt++; } else if (SMDS_Downward::getCellDimension(vtkType) == 3) { int volId = _grid->CellIdToDownId(vtkId); SMDS_Downward * downvol = _grid->getDownArray(vtkType); //const int *downIds = downvol->getDownCells(volId); const unsigned char* downTypesVol = downvol->getDownTypes(volId); int nbFaces = downvol->getNumberOfDownCells(volId); const int* faceIds = downvol->getDownCells(volId); for (int n = 0; n < nbFaces; n++) { SMDS_Down2D *downFace = static_cast (_grid->getDownArray(downTypesVol[n])); bool isInFace = downFace->isInFace(faceIds[n], pts, _nbDownCells); if (isInFace) { bool alreadySet = false; for (int k = 0; k < cnt; k++) if (faceIds[n] == downFaces[k]) { alreadySet = true; break; } if (!alreadySet) { downFaces[cnt] = faceIds[n]; downTypes[cnt] = downTypesVol[n]; cnt++; } } } } } return cnt; } // --------------------------------------------------------------------------- SMDS_Down2D::SMDS_Down2D(SMDS_UnstructuredGrid *grid, int nbDownCells) : SMDS_Downward(grid, nbDownCells) { _upCellIds.clear(); _upCellTypes.clear(); _tempNodes.clear(); _nbNodes = 0; } SMDS_Down2D::~SMDS_Down2D() { } int SMDS_Down2D::getNumberOfUpCells(int cellId) { int nbup = 0; if (_upCellIds[2 * cellId] >= 0) nbup++; if (_upCellIds[2 * cellId + 1] >= 0) nbup++; return nbup; } const int* SMDS_Down2D::getUpCells(int cellId) { //ASSERT((cellId >=0) && (cellId < _maxId)); return &_upCellIds[2 * cellId]; } const unsigned char* SMDS_Down2D::getUpTypes(int cellId) { //ASSERT((cellId >=0) && (cellId < _maxId)); return &_upCellTypes[2 * cellId]; } void SMDS_Down2D::getNodeIds(int cellId, std::set& nodeSet) { for (int i = 0; i < _nbDownCells; i++) { int downCellId = _cellIds[_nbDownCells * cellId + i]; unsigned char cellType = _cellTypes[i]; this->_grid->getDownArray(cellType)->getNodeIds(downCellId, nodeSet); } } /*! Find in vtkUnstructuredGrid the volumes containing a face already stored in vtkUnstructuredGrid. * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes. * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid. * @param cellId the face cell id in vkUnstructuredGrid * @param ids a couple of vtkId, initialized at -1 (no parent volume) * @return number of volumes (0, 1 or 2) */ int SMDS_Down2D::computeVolumeIds(int cellId, int* ids) { // --- find point id's of the face vtkIdType npts = 0; vtkIdType *pts; // will refer to the point id's of the face _grid->GetCellPoints(cellId, npts, pts); vector nodes; for (int i = 0; i < npts; i++) nodes.push_back(pts[i]); int nvol = this->computeVolumeIdsFromNodesFace(&nodes[0], npts, ids); return nvol; } /*! Find in vtkUnstructuredGrid the volumes containing a face described by it's nodes * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes. * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid. * @param faceByNodes * @param ids a couple of vtkId, initialized at -1 (no parent volume) * @return number of volumes (0, 1 or 2) */ int SMDS_Down2D::computeVolumeIds(ElemByNodesType& faceByNodes, int* ids) { int nvol = this->computeVolumeIdsFromNodesFace(&faceByNodes.nodeIds[0], faceByNodes.nbNodes, ids); return nvol; } /*! Find in vtkUnstructuredGrid the volumes containing a face described by it's nodes * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes. * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid. * @param pts array of vtk node id's * @param npts number of nodes * @param ids * @return number of volumes (0, 1 or 2) */ int SMDS_Down2D::computeVolumeIdsFromNodesFace(int* pts, int npts, int* ids) { // --- find all the cells the points belong to, and how many of the points belong to a given cell int cellIds[1000]; int cellCnt[1000]; int cnt = 0; for (int i = 0; i < npts; i++) { vtkIdType point = pts[i]; int numCells = _grid->GetLinks()->GetNcells(point); //MESSAGE("cells pour " << i << " " << numCells); vtkIdType *cells = _grid->GetLinks()->GetCells(point); for (int j = 0; j < numCells; j++) { int vtkCellId = cells[j]; bool found = false; for (int k = 0; k < cnt; k++) { if (cellIds[k] == vtkCellId) { cellCnt[k] += 1; found = true; break; } } if (!found) { cellIds[cnt] = vtkCellId; cellCnt[cnt] = 1; // TODO ASSERT(cnt<1000); cnt++; } } } // --- find the volume cells: they contains all the points and are of type volume int nvol = 0; for (int i = 0; i < cnt; i++) { //MESSAGE("cell " << cellIds[i] << " points " << cellCnt[i]); if (cellCnt[i] == npts) { int vtkElemId = cellIds[i]; int vtkType = _grid->GetCellType(vtkElemId); if (SMDS_Downward::getCellDimension(vtkType) == 3) { ids[nvol] = vtkElemId; // store the volume id in given vector nvol++; } } if (nvol == 2) break; } return nvol; } void SMDS_Down2D::setTempNodes(int cellId, int vtkId) { vtkIdType npts = 0; vtkIdType *pts; // will refer to the point id's of the face _grid->GetCellPoints(vtkId, npts, pts); // MESSAGE(vtkId << " " << npts << " " << _nbNodes); //ASSERT(npts == _nbNodes); for (int i = 0; i < npts; i++) { _tempNodes[_nbNodes * cellId + i] = pts[i]; } } void SMDS_Down2D::setTempNodes(int cellId, ElemByNodesType& faceByNodes) { for (int i = 0; i < faceByNodes.nbNodes; i++) _tempNodes[_nbNodes * cellId + i] = faceByNodes.nodeIds[i]; } /*! Find if all the nodes belongs to the face. * * @param cellId the face cell Id * @param nodeSet set of node id's to be found in the face list of nodes * @return */ bool SMDS_Down2D::isInFace(int cellId, int *pts, int npts) { int nbFound = 0; int *nodes = &_tempNodes[_nbNodes * cellId]; for (int j = 0; j < npts; j++) { int point = pts[j]; for (int i = 0; i < _nbNodes; i++) { if (nodes[i] == point) { nbFound++; break; } } } return (nbFound == npts); } /*! Resize the downward connectivity storage vector if needed. * * @param nbElems total number of elements of the same type required */ void SMDS_Down2D::allocate(int nbElems) { if (nbElems >= _vtkCellIds.size()) { _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1); _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1); _upCellIds.resize(2 * (nbElems + SMDS_Mesh::chunkSize), -1); _upCellTypes.resize(2 * (nbElems + SMDS_Mesh::chunkSize), -1); _tempNodes.resize(_nbNodes * (nbElems + SMDS_Mesh::chunkSize), -1); } } void SMDS_Down2D::compactStorage() { _cellIds.resize(_nbDownCells * _maxId); _upCellIds.resize(2 * _maxId); _upCellTypes.resize(2 * _maxId); _vtkCellIds.resize(_maxId); _tempNodes.clear(); } void SMDS_Down2D::addUpCell(int cellId, int upCellId, unsigned char aType) { //ASSERT((cellId >=0)&& (cellId < _maxId)); int *vols = &_upCellIds[2 * cellId]; unsigned char *types = &_upCellTypes[2 * cellId]; for (int i = 0; i < 2; i++) { if (vols[i] < 0) { vols[i] = upCellId; // use non affected volume types[i] = aType; return; } if ((vols[i] == upCellId) && (types[i] == aType)) // already done return; } ASSERT(0); } int SMDS_Down2D::getNodeSet(int cellId, int* nodeSet) { for (int i = 0; i < _nbNodes; i++) nodeSet[i] = _tempNodes[_nbNodes * cellId + i]; return _nbNodes; } int SMDS_Down2D::FindEdgeByNodes(int cellId, ElemByNodesType& edgeByNodes) { int *edges = &_cellIds[_nbDownCells * cellId]; for (int i = 0; i < _nbDownCells; i++) { if ((edges[i] >= 0) && (edgeByNodes.vtkType == _cellTypes[i])) { int nodeSet[3]; int npts = this->_grid->getDownArray(edgeByNodes.vtkType)->getNodeSet(edges[i], nodeSet); bool found = false; for (int j = 0; j < npts; j++) { int point = edgeByNodes.nodeIds[j]; found = false; for (int k = 0; k < npts; k++) { if (nodeSet[k] == point) { found = true; break; } } if (!found) break; } if (found) return edges[i]; } } return -1; } // --------------------------------------------------------------------------- SMDS_Down3D::SMDS_Down3D(SMDS_UnstructuredGrid *grid, int nbDownCells) : SMDS_Downward(grid, nbDownCells) { } SMDS_Down3D::~SMDS_Down3D() { } void SMDS_Down3D::allocate(int nbElems) { if (nbElems >= _vtkCellIds.size()) { _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1); _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1); } } void SMDS_Down3D::compactStorage() { // nothing to do, size was known before } int SMDS_Down3D::getNumberOfUpCells(int cellId) { return 0; } const int* SMDS_Down3D::getUpCells(int cellId) { return 0; } const unsigned char* SMDS_Down3D::getUpTypes(int cellId) { return 0; } void SMDS_Down3D::getNodeIds(int cellId, std::set& nodeSet) { int vtkId = this->_vtkCellIds[cellId]; vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(vtkId, npts, nodes); for (int i = 0; i < npts; i++) nodeSet.insert(nodes[i]); } int SMDS_Down3D::FindFaceByNodes(int cellId, ElemByNodesType& faceByNodes) { int *faces = &_cellIds[_nbDownCells * cellId]; int npoints = 0; for (int i = 0; i < _nbDownCells; i++) { if ((faces[i] >= 0) && (faceByNodes.vtkType == _cellTypes[i])) { if (npoints == 0) npoints = faceByNodes.nbNodes; int nodeSet[10]; int npts = this->_grid->getDownArray(faceByNodes.vtkType)->getNodeSet(faces[i], nodeSet); if (npts != npoints) continue; // skip this face bool found = false; for (int j = 0; j < npts; j++) { int point = faceByNodes.nodeIds[j]; found = false; for (int k = 0; k < npts; k++) { if (nodeSet[k] == point) { found = true; break; // point j is in the 2 faces, skip remaining k values } } if (!found) break; // point j is not in the 2 faces, skip the remaining tests } if (found) return faces[i]; } } return -1; } // --------------------------------------------------------------------------- SMDS_DownEdge::SMDS_DownEdge(SMDS_UnstructuredGrid *grid) : SMDS_Down1D(grid, 2) { _cellTypes.push_back(VTK_VERTEX); _cellTypes.push_back(VTK_VERTEX); } SMDS_DownEdge::~SMDS_DownEdge() { } // --------------------------------------------------------------------------- SMDS_DownQuadEdge::SMDS_DownQuadEdge(SMDS_UnstructuredGrid *grid) : SMDS_Down1D(grid, 3) { _cellTypes.push_back(VTK_VERTEX); _cellTypes.push_back(VTK_VERTEX); _cellTypes.push_back(VTK_VERTEX); } SMDS_DownQuadEdge::~SMDS_DownQuadEdge() { } // --------------------------------------------------------------------------- SMDS_DownTriangle::SMDS_DownTriangle(SMDS_UnstructuredGrid *grid) : SMDS_Down2D(grid, 3) { _cellTypes.push_back(VTK_LINE); _cellTypes.push_back(VTK_LINE); _cellTypes.push_back(VTK_LINE); _nbNodes = 3; } SMDS_DownTriangle::~SMDS_DownTriangle() { } void SMDS_DownTriangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes) { int *nodes = &_tempNodes[_nbNodes * cellId]; edgesWithNodes.nbElems = 3; edgesWithNodes.elems[0].nodeIds[0] = nodes[0]; edgesWithNodes.elems[0].nodeIds[1] = nodes[1]; edgesWithNodes.elems[0].nbNodes = 2; edgesWithNodes.elems[0].vtkType = VTK_LINE; edgesWithNodes.elems[1].nodeIds[0] = nodes[1]; edgesWithNodes.elems[1].nodeIds[1] = nodes[2]; edgesWithNodes.elems[1].nbNodes = 2; edgesWithNodes.elems[1].vtkType = VTK_LINE; edgesWithNodes.elems[2].nodeIds[0] = nodes[2]; edgesWithNodes.elems[2].nodeIds[1] = nodes[0]; edgesWithNodes.elems[2].nbNodes = 2; edgesWithNodes.elems[2].vtkType = VTK_LINE; } void SMDS_DownTriangle::addDownCell(int cellId, int lowCellId, unsigned char aType) { //ASSERT((cellId >=0)&& (cellId < _maxId)); //ASSERT(aType == VTK_LINE); int *faces = &_cellIds[_nbDownCells * cellId]; for (int i = 0; i < _nbDownCells; i++) { if (faces[i] < 0) { faces[i] = lowCellId; return; } if (faces[i] == lowCellId) return; } ASSERT(0); } // --------------------------------------------------------------------------- SMDS_DownQuadTriangle::SMDS_DownQuadTriangle(SMDS_UnstructuredGrid *grid) : SMDS_Down2D(grid, 3) { _cellTypes.push_back(VTK_QUADRATIC_EDGE); _cellTypes.push_back(VTK_QUADRATIC_EDGE); _cellTypes.push_back(VTK_QUADRATIC_EDGE); _nbNodes = 6; } SMDS_DownQuadTriangle::~SMDS_DownQuadTriangle() { } void SMDS_DownQuadTriangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes) { int *nodes = &_tempNodes[_nbNodes * cellId]; edgesWithNodes.nbElems = 3; edgesWithNodes.elems[0].nodeIds[0] = nodes[0]; edgesWithNodes.elems[0].nodeIds[1] = nodes[1]; edgesWithNodes.elems[0].nodeIds[2] = nodes[3]; edgesWithNodes.elems[0].nbNodes = 3; edgesWithNodes.elems[0].vtkType = VTK_QUADRATIC_EDGE; edgesWithNodes.elems[1].nodeIds[0] = nodes[1]; edgesWithNodes.elems[1].nodeIds[1] = nodes[2]; edgesWithNodes.elems[1].nodeIds[2] = nodes[4]; edgesWithNodes.elems[1].nbNodes = 3; edgesWithNodes.elems[1].vtkType = VTK_QUADRATIC_EDGE; edgesWithNodes.elems[2].nodeIds[0] = nodes[2]; edgesWithNodes.elems[2].nodeIds[1] = nodes[0]; edgesWithNodes.elems[2].nodeIds[2] = nodes[5]; edgesWithNodes.elems[2].nbNodes = 3; edgesWithNodes.elems[2].vtkType = VTK_QUADRATIC_EDGE; } void SMDS_DownQuadTriangle::addDownCell(int cellId, int lowCellId, unsigned char aType) { //ASSERT((cellId >=0)&& (cellId < _maxId)); //ASSERT(aType == VTK_QUADRATIC_EDGE); int *edges = &_cellIds[_nbDownCells * cellId]; for (int i = 0; i < _nbDownCells; i++) { if (edges[i] < 0) { edges[i] = lowCellId; return; } if (edges[i] == lowCellId) return; } ASSERT(0); } // --------------------------------------------------------------------------- SMDS_DownQuadrangle::SMDS_DownQuadrangle(SMDS_UnstructuredGrid *grid) : SMDS_Down2D(grid, 4) { _cellTypes.push_back(VTK_LINE); _cellTypes.push_back(VTK_LINE); _cellTypes.push_back(VTK_LINE); _cellTypes.push_back(VTK_LINE); _nbNodes = 4; } SMDS_DownQuadrangle::~SMDS_DownQuadrangle() { } void SMDS_DownQuadrangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes) { int *nodes = &_tempNodes[_nbNodes * cellId]; edgesWithNodes.nbElems = 4; edgesWithNodes.elems[0].nodeIds[0] = nodes[0]; edgesWithNodes.elems[0].nodeIds[1] = nodes[1]; edgesWithNodes.elems[0].nbNodes = 2; edgesWithNodes.elems[0].vtkType = VTK_LINE; edgesWithNodes.elems[1].nodeIds[0] = nodes[1]; edgesWithNodes.elems[1].nodeIds[1] = nodes[2]; edgesWithNodes.elems[1].nbNodes = 2; edgesWithNodes.elems[1].vtkType = VTK_LINE; edgesWithNodes.elems[2].nodeIds[0] = nodes[2]; edgesWithNodes.elems[2].nodeIds[1] = nodes[3]; edgesWithNodes.elems[2].nbNodes = 2; edgesWithNodes.elems[2].vtkType = VTK_LINE; edgesWithNodes.elems[3].nodeIds[0] = nodes[3]; edgesWithNodes.elems[3].nodeIds[1] = nodes[0]; edgesWithNodes.elems[3].nbNodes = 2; edgesWithNodes.elems[3].vtkType = VTK_LINE; } void SMDS_DownQuadrangle::addDownCell(int cellId, int lowCellId, unsigned char aType) { //ASSERT((cellId >=0)&& (cellId < _maxId)); //ASSERT(aType == VTK_LINE); int *faces = &_cellIds[_nbDownCells * cellId]; for (int i = 0; i < _nbDownCells; i++) { if (faces[i] < 0) { faces[i] = lowCellId; return; } if (faces[i] == lowCellId) return; } ASSERT(0); } // --------------------------------------------------------------------------- SMDS_DownQuadQuadrangle::SMDS_DownQuadQuadrangle(SMDS_UnstructuredGrid *grid) : SMDS_Down2D(grid, 4) { _cellTypes.push_back(VTK_QUADRATIC_EDGE); _cellTypes.push_back(VTK_QUADRATIC_EDGE); _cellTypes.push_back(VTK_QUADRATIC_EDGE); _cellTypes.push_back(VTK_QUADRATIC_EDGE); _nbNodes = 8; } SMDS_DownQuadQuadrangle::~SMDS_DownQuadQuadrangle() { } void SMDS_DownQuadQuadrangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes) { int *nodes = &_tempNodes[_nbNodes * cellId]; edgesWithNodes.nbElems = 4; edgesWithNodes.elems[0].nodeIds[0] = nodes[0]; edgesWithNodes.elems[0].nodeIds[1] = nodes[1]; edgesWithNodes.elems[0].nodeIds[2] = nodes[4]; edgesWithNodes.elems[0].nbNodes = 3; edgesWithNodes.elems[0].vtkType = VTK_QUADRATIC_EDGE; edgesWithNodes.elems[1].nodeIds[0] = nodes[1]; edgesWithNodes.elems[1].nodeIds[1] = nodes[2]; edgesWithNodes.elems[1].nodeIds[2] = nodes[5]; edgesWithNodes.elems[1].nbNodes = 3; edgesWithNodes.elems[1].vtkType = VTK_QUADRATIC_EDGE; edgesWithNodes.elems[2].nodeIds[0] = nodes[2]; edgesWithNodes.elems[2].nodeIds[1] = nodes[3]; edgesWithNodes.elems[2].nodeIds[2] = nodes[6]; edgesWithNodes.elems[2].nbNodes = 3; edgesWithNodes.elems[2].vtkType = VTK_QUADRATIC_EDGE; edgesWithNodes.elems[3].nodeIds[0] = nodes[3]; edgesWithNodes.elems[3].nodeIds[1] = nodes[0]; edgesWithNodes.elems[3].nodeIds[2] = nodes[7]; edgesWithNodes.elems[3].nbNodes = 3; edgesWithNodes.elems[3].vtkType = VTK_QUADRATIC_EDGE; } void SMDS_DownQuadQuadrangle::addDownCell(int cellId, int lowCellId, unsigned char aType) { //ASSERT((cellId >=0)&& (cellId < _maxId)); //ASSERT(aType == VTK_QUADRATIC_EDGE); int *faces = &_cellIds[_nbDownCells * cellId]; for (int i = 0; i < _nbDownCells; i++) { if (faces[i] < 0) { faces[i] = lowCellId; return; } if (faces[i] == lowCellId) return; } ASSERT(0); } // --------------------------------------------------------------------------- SMDS_DownTetra::SMDS_DownTetra(SMDS_UnstructuredGrid *grid) : SMDS_Down3D(grid, 4) { _cellTypes.push_back(VTK_TRIANGLE); _cellTypes.push_back(VTK_TRIANGLE); _cellTypes.push_back(VTK_TRIANGLE); _cellTypes.push_back(VTK_TRIANGLE); } SMDS_DownTetra::~SMDS_DownTetra() { } void SMDS_DownTetra::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) { set setNodes; setNodes.clear(); for (int i = 0; i < orderedNodes.size(); i++) setNodes.insert(orderedNodes[i]); //MESSAGE("cellId = " << cellId); vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); set tofind; int ids[12] = { 0, 1, 2, 0, 3, 1, 2, 3, 0, 1, 3, 2 }; //int ids[12] = { 2, 1, 0, 1, 3, 0, 0, 3, 2, 2, 3, 1 }; for (int k = 0; k < 4; k++) { tofind.clear(); for (int i = 0; i < 3; i++) tofind.insert(nodes[ids[3 * k + i]]); if (setNodes == tofind) { for (int i = 0; i < 3; i++) orderedNodes[i] = nodes[ids[3 * k + i]]; return; } } MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); } void SMDS_DownTetra::addDownCell(int cellId, int lowCellId, unsigned char aType) { //ASSERT((cellId >=0)&& (cellId < _maxId)); //ASSERT(aType == VTK_TRIANGLE); int *faces = &_cellIds[_nbDownCells * cellId]; for (int i = 0; i < _nbDownCells; i++) { if (faces[i] < 0) { faces[i] = lowCellId; return; } if (faces[i] == lowCellId) return; } ASSERT(0); } /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's * The linear tetrahedron is defined by four points. * @see vtkTetra.h in Filtering. * @param cellId volumeId in vtkUnstructuredGrid * @param facesWithNodes vector of face descriptors to be filled */ void SMDS_DownTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) { // --- find point id's of the volume vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(cellId, npts, nodes); // --- create all the ordered list of node id's for each face facesWithNodes.nbElems = 4; facesWithNodes.elems[0].nodeIds[0] = nodes[0]; facesWithNodes.elems[0].nodeIds[1] = nodes[1]; facesWithNodes.elems[0].nodeIds[2] = nodes[2]; facesWithNodes.elems[0].nbNodes = 3; facesWithNodes.elems[0].vtkType = VTK_TRIANGLE; facesWithNodes.elems[1].nodeIds[0] = nodes[0]; facesWithNodes.elems[1].nodeIds[1] = nodes[1]; facesWithNodes.elems[1].nodeIds[2] = nodes[3]; facesWithNodes.elems[1].nbNodes = 3; facesWithNodes.elems[1].vtkType = VTK_TRIANGLE; facesWithNodes.elems[2].nodeIds[0] = nodes[0]; facesWithNodes.elems[2].nodeIds[1] = nodes[2]; facesWithNodes.elems[2].nodeIds[2] = nodes[3]; facesWithNodes.elems[2].nbNodes = 3; facesWithNodes.elems[2].vtkType = VTK_TRIANGLE; facesWithNodes.elems[3].nodeIds[0] = nodes[1]; facesWithNodes.elems[3].nodeIds[1] = nodes[2]; facesWithNodes.elems[3].nodeIds[2] = nodes[3]; facesWithNodes.elems[3].nbNodes = 3; facesWithNodes.elems[3].vtkType = VTK_TRIANGLE; } // --------------------------------------------------------------------------- SMDS_DownQuadTetra::SMDS_DownQuadTetra(SMDS_UnstructuredGrid *grid) : SMDS_Down3D(grid, 4) { _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); } SMDS_DownQuadTetra::~SMDS_DownQuadTetra() { } void SMDS_DownQuadTetra::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) { set setNodes; setNodes.clear(); for (int i = 0; i < orderedNodes.size(); i++) setNodes.insert(orderedNodes[i]); //MESSAGE("cellId = " << cellId); vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); set tofind; 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 }; //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 }; for (int k = 0; k < 4; k++) { tofind.clear(); for (int i = 0; i < 6; i++) tofind.insert(nodes[ids[6 * k + i]]); if (setNodes == tofind) { for (int i = 0; i < 6; i++) orderedNodes[i] = nodes[ids[6 * k + i]]; return; } } MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); } void SMDS_DownQuadTetra::addDownCell(int cellId, int lowCellId, unsigned char aType) { //ASSERT((cellId >=0)&& (cellId < _maxId)); //ASSERT(aType == VTK_QUADRATIC_TRIANGLE); int *faces = &_cellIds[_nbDownCells * cellId]; for (int i = 0; i < _nbDownCells; i++) { if (faces[i] < 0) { faces[i] = lowCellId; return; } if (faces[i] == lowCellId) return; } ASSERT(0); } /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's * The ordering of the ten points defining the quadratic tetrahedron cell is point id's (0-3,4-9) * where id's 0-3 are the four tetrahedron vertices; * 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). * @see vtkQuadraticTetra.h in Filtering. * @param cellId volumeId in vtkUnstructuredGrid * @param facesWithNodes vector of face descriptors to be filled */ void SMDS_DownQuadTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) { // --- find point id's of the volume vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(cellId, npts, nodes); // --- create all the ordered list of node id's for each face facesWithNodes.nbElems = 4; facesWithNodes.elems[0].nodeIds[0] = nodes[0]; facesWithNodes.elems[0].nodeIds[1] = nodes[1]; facesWithNodes.elems[0].nodeIds[2] = nodes[2]; facesWithNodes.elems[0].nodeIds[3] = nodes[4]; facesWithNodes.elems[0].nodeIds[4] = nodes[5]; facesWithNodes.elems[0].nodeIds[5] = nodes[6]; facesWithNodes.elems[0].nbNodes = 6; facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_TRIANGLE; facesWithNodes.elems[1].nodeIds[0] = nodes[0]; facesWithNodes.elems[1].nodeIds[1] = nodes[1]; facesWithNodes.elems[1].nodeIds[2] = nodes[3]; facesWithNodes.elems[1].nodeIds[3] = nodes[4]; facesWithNodes.elems[1].nodeIds[4] = nodes[8]; facesWithNodes.elems[1].nodeIds[5] = nodes[7]; facesWithNodes.elems[1].nbNodes = 6; facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE; facesWithNodes.elems[2].nodeIds[0] = nodes[0]; facesWithNodes.elems[2].nodeIds[1] = nodes[2]; facesWithNodes.elems[2].nodeIds[2] = nodes[3]; facesWithNodes.elems[2].nodeIds[3] = nodes[6]; facesWithNodes.elems[2].nodeIds[4] = nodes[9]; facesWithNodes.elems[2].nodeIds[5] = nodes[7]; facesWithNodes.elems[2].nbNodes = 6; facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE; facesWithNodes.elems[3].nodeIds[0] = nodes[1]; facesWithNodes.elems[3].nodeIds[1] = nodes[2]; facesWithNodes.elems[3].nodeIds[2] = nodes[3]; facesWithNodes.elems[3].nodeIds[3] = nodes[5]; facesWithNodes.elems[3].nodeIds[4] = nodes[9]; facesWithNodes.elems[3].nodeIds[5] = nodes[8]; facesWithNodes.elems[3].nbNodes = 6; facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE; } // --------------------------------------------------------------------------- SMDS_DownPyramid::SMDS_DownPyramid(SMDS_UnstructuredGrid *grid) : SMDS_Down3D(grid, 5) { _cellTypes.push_back(VTK_QUAD); _cellTypes.push_back(VTK_TRIANGLE); _cellTypes.push_back(VTK_TRIANGLE); _cellTypes.push_back(VTK_TRIANGLE); _cellTypes.push_back(VTK_TRIANGLE); } SMDS_DownPyramid::~SMDS_DownPyramid() { } void SMDS_DownPyramid::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) { set setNodes; setNodes.clear(); for (int i = 0; i < orderedNodes.size(); i++) setNodes.insert(orderedNodes[i]); //MESSAGE("cellId = " << cellId); vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); set tofind; int ids[16] = { 0, 1, 2, 3, 0, 3, 4, 3, 2, 4, 2, 1, 4, 1, 0, 4 }; // Quadrangular face tofind.clear(); for (int i = 0; i < 4; i++) tofind.insert(nodes[ids[i]]); if (setNodes == tofind) { for (int i = 0; i < 4; i++) orderedNodes[i] = nodes[ids[i]]; return; } // Triangular faces for (int k = 0; k < 4; k++) { tofind.clear(); for (int i = 0; i < 3; i++) tofind.insert(nodes[ids[4 + 3 * k + i]]); if (setNodes == tofind) { for (int i = 0; i < 3; i++) orderedNodes[i] = nodes[ids[4 + 3 * k + i]]; return; } } MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); } void SMDS_DownPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType) { //ASSERT((cellId >=0) && (cellId < _maxId)); int *faces = &_cellIds[_nbDownCells * cellId]; if (aType == VTK_QUAD) { if (faces[0] < 0) { faces[0] = lowCellId; return; } if (faces[0] == lowCellId) return; } else { //ASSERT(aType == VTK_TRIANGLE); for (int i = 1; i < _nbDownCells; i++) { if (faces[i] < 0) { faces[i] = lowCellId; return; } if (faces[i] == lowCellId) return; } } ASSERT(0); } /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's * The pyramid is defined by the five points (0-4) where (0,1,2,3) is the base of the pyramid which, * using the right hand rule, forms a quadrilateral whose normal points in the direction of the * pyramid apex at vertex #4. * @see vtkPyramid.h in Filtering. * @param cellId volumeId in vtkUnstructuredGrid * @param facesWithNodes vector of face descriptors to be filled */ void SMDS_DownPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) { // --- find point id's of the volume vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(cellId, npts, nodes); // --- create all the ordered list of node id's for each face facesWithNodes.nbElems = 5; facesWithNodes.elems[0].nodeIds[0] = nodes[0]; facesWithNodes.elems[0].nodeIds[1] = nodes[1]; facesWithNodes.elems[0].nodeIds[2] = nodes[2]; facesWithNodes.elems[0].nodeIds[3] = nodes[3]; facesWithNodes.elems[0].nbNodes = 4; facesWithNodes.elems[0].vtkType = VTK_QUAD; facesWithNodes.elems[1].nodeIds[0] = nodes[0]; facesWithNodes.elems[1].nodeIds[1] = nodes[1]; facesWithNodes.elems[1].nodeIds[2] = nodes[4]; facesWithNodes.elems[1].nbNodes = 3; facesWithNodes.elems[1].vtkType = VTK_TRIANGLE; facesWithNodes.elems[2].nodeIds[0] = nodes[1]; facesWithNodes.elems[2].nodeIds[1] = nodes[2]; facesWithNodes.elems[2].nodeIds[2] = nodes[4]; facesWithNodes.elems[2].nbNodes = 3; facesWithNodes.elems[2].vtkType = VTK_TRIANGLE; facesWithNodes.elems[3].nodeIds[0] = nodes[2]; facesWithNodes.elems[3].nodeIds[1] = nodes[3]; facesWithNodes.elems[3].nodeIds[2] = nodes[4]; facesWithNodes.elems[3].nbNodes = 3; facesWithNodes.elems[3].vtkType = VTK_TRIANGLE; facesWithNodes.elems[4].nodeIds[0] = nodes[3]; facesWithNodes.elems[4].nodeIds[1] = nodes[0]; facesWithNodes.elems[4].nodeIds[2] = nodes[4]; facesWithNodes.elems[4].nbNodes = 3; facesWithNodes.elems[4].vtkType = VTK_TRIANGLE; } // --------------------------------------------------------------------------- SMDS_DownQuadPyramid::SMDS_DownQuadPyramid(SMDS_UnstructuredGrid *grid) : SMDS_Down3D(grid, 5) { _cellTypes.push_back(VTK_QUADRATIC_QUAD); _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); } SMDS_DownQuadPyramid::~SMDS_DownQuadPyramid() { } void SMDS_DownQuadPyramid::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) { // MESSAGE("SMDS_DownQuadPyramid::getOrderedNodesOfFace cellId = " << cellId); set setNodes; setNodes.clear(); for (int i = 0; i < orderedNodes.size(); i++) setNodes.insert(orderedNodes[i]); //MESSAGE("cellId = " << cellId); vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); set tofind; int ids[32] = { 0, 1, 2, 3, 5, 6, 7, 8, 0, 3, 4, 8, 12, 9, 3, 2, 4, 7 , 11, 12, 2, 1, 4, 6, 10, 11, 1, 0, 4, 5, 9, 10 }; // Quadrangular face tofind.clear(); for (int i = 0; i < 8; i++) tofind.insert(nodes[ids[i]]); if (setNodes == tofind) { for (int i = 0; i < 8; i++) orderedNodes[i] = nodes[ids[i]]; return; } // Triangular faces for (int k = 0; k < 4; k++) { tofind.clear(); for (int i = 0; i < 6; i++) tofind.insert(nodes[ids[8 + 6 * k + i]]); if (setNodes == tofind) { for (int i = 0; i < 6; i++) orderedNodes[i] = nodes[ids[8 + 6 * k + i]]; return; } } MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]); MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); } void SMDS_DownQuadPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType) { //ASSERT((cellId >=0) && (cellId < _maxId)); int *faces = &_cellIds[_nbDownCells * cellId]; if (aType == VTK_QUADRATIC_QUAD) { if (faces[0] < 0) { faces[0] = lowCellId; return; } if (faces[0] == lowCellId) return; } else { //ASSERT(aType == VTK_QUADRATIC_TRIANGLE); for (int i = 1; i < _nbDownCells; i++) { if (faces[i] < 0) { faces[i] = lowCellId; return; } if (faces[i] == lowCellId) return; } } ASSERT(0); } /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's * The ordering of the thirteen points defining the quadratic pyramid cell is point id's (0-4,5-12) * where point id's 0-4 are the five corner vertices of the pyramid; followed * by eight mid-edge nodes (5-12). Note that these mid-edge nodes lie on the edges defined by * 5(0,1), 6(1,2), 7(2,3), 8(3,0), 9(0,4), 10(1,4), 11(2,4), 12(3,4). * @see vtkQuadraticPyramid.h in Filtering. * @param cellId volumeId in vtkUnstructuredGrid * @param facesWithNodes vector of face descriptors to be filled */ void SMDS_DownQuadPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) { // --- find point id's of the volume vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(cellId, npts, nodes); // --- create all the ordered list of node id's for each face facesWithNodes.nbElems = 5; facesWithNodes.elems[0].nodeIds[0] = nodes[0]; facesWithNodes.elems[0].nodeIds[1] = nodes[1]; facesWithNodes.elems[0].nodeIds[2] = nodes[2]; facesWithNodes.elems[0].nodeIds[3] = nodes[3]; facesWithNodes.elems[0].nodeIds[4] = nodes[5]; facesWithNodes.elems[0].nodeIds[5] = nodes[6]; facesWithNodes.elems[0].nodeIds[6] = nodes[7]; facesWithNodes.elems[0].nodeIds[7] = nodes[8]; facesWithNodes.elems[0].nbNodes = 8; facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD; facesWithNodes.elems[1].nodeIds[0] = nodes[0]; facesWithNodes.elems[1].nodeIds[1] = nodes[1]; facesWithNodes.elems[1].nodeIds[2] = nodes[4]; facesWithNodes.elems[1].nodeIds[3] = nodes[5]; facesWithNodes.elems[1].nodeIds[4] = nodes[10]; facesWithNodes.elems[1].nodeIds[5] = nodes[9]; facesWithNodes.elems[1].nbNodes = 6; facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE; facesWithNodes.elems[2].nodeIds[0] = nodes[1]; facesWithNodes.elems[2].nodeIds[1] = nodes[2]; facesWithNodes.elems[2].nodeIds[2] = nodes[4]; facesWithNodes.elems[2].nodeIds[3] = nodes[6]; facesWithNodes.elems[2].nodeIds[4] = nodes[11]; facesWithNodes.elems[2].nodeIds[5] = nodes[10]; facesWithNodes.elems[2].nbNodes = 6; facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE; facesWithNodes.elems[3].nodeIds[0] = nodes[2]; facesWithNodes.elems[3].nodeIds[1] = nodes[3]; facesWithNodes.elems[3].nodeIds[2] = nodes[4]; facesWithNodes.elems[3].nodeIds[3] = nodes[7]; facesWithNodes.elems[3].nodeIds[4] = nodes[12]; facesWithNodes.elems[3].nodeIds[5] = nodes[11]; facesWithNodes.elems[3].nbNodes = 6; facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE; facesWithNodes.elems[4].nodeIds[0] = nodes[3]; facesWithNodes.elems[4].nodeIds[1] = nodes[0]; facesWithNodes.elems[4].nodeIds[2] = nodes[4]; facesWithNodes.elems[4].nodeIds[3] = nodes[8]; facesWithNodes.elems[4].nodeIds[4] = nodes[9]; facesWithNodes.elems[4].nodeIds[5] = nodes[12]; facesWithNodes.elems[4].nbNodes = 6; facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_TRIANGLE; } // --------------------------------------------------------------------------- SMDS_DownPenta::SMDS_DownPenta(SMDS_UnstructuredGrid *grid) : SMDS_Down3D(grid, 5) { _cellTypes.push_back(VTK_QUAD); _cellTypes.push_back(VTK_QUAD); _cellTypes.push_back(VTK_QUAD); _cellTypes.push_back(VTK_TRIANGLE); _cellTypes.push_back(VTK_TRIANGLE); } SMDS_DownPenta::~SMDS_DownPenta() { } void SMDS_DownPenta::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) { set setNodes; setNodes.clear(); for (int i = 0; i < orderedNodes.size(); i++) setNodes.insert(orderedNodes[i]); //MESSAGE("cellId = " << cellId); vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); set tofind; //int ids[18] = { 0, 2, 1, 3, 4, 5, 0, 1, 4, 3, 1, 2, 5, 4, 2, 0, 3, 5 }; int ids[18] = { 0, 1, 2, 3, 5, 4, 0, 3, 4, 1, 1, 4, 5, 2, 2, 5, 3, 0 }; // Triangular faces for (int k = 0; k < 2; k++) { tofind.clear(); for (int i = 0; i < 3; i++) tofind.insert(nodes[ids[3 * k + i]]); if (setNodes == tofind) { for (int i = 0; i < 3; i++) orderedNodes[i] = nodes[ids[3 * k + i]]; return; } } // Quadrangular faces for (int k = 0; k < 3; k++) { tofind.clear(); for (int i = 0; i < 4; i++) tofind.insert(nodes[ids[6 + 4 * k + i]]); if (setNodes == tofind) { for (int i = 0; i < 4; i++) orderedNodes[i] = nodes[ids[6 + 4 * k + i]]; return; } } MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); } void SMDS_DownPenta::addDownCell(int cellId, int lowCellId, unsigned char aType) { //ASSERT((cellId >=0) && (cellId < _maxId)); int *faces = &_cellIds[_nbDownCells * cellId]; if (aType == VTK_QUAD) for (int i = 0; i < 3; i++) { if (faces[i] < 0) { faces[i] = lowCellId; return; } if (faces[i] == lowCellId) return; } else { //ASSERT(aType == VTK_TRIANGLE); for (int i = 3; i < _nbDownCells; i++) { if (faces[i] < 0) { faces[i] = lowCellId; return; } if (faces[i] == lowCellId) return; } } ASSERT(0); } /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's. * A wedge or pentahedron consists of two triangular and three quadrilateral faces * and is defined by the six points (0-5) where (0,1,2) is the base of the wedge which, * using the right hand rule, forms a triangle whose normal points outward * (away from the triangular face (3,4,5)). * @see vtkWedge.h in Filtering * @param cellId volumeId in vtkUnstructuredGrid * @param facesWithNodes vector of face descriptors to be filled */ void SMDS_DownPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) { // --- find point id's of the volume vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(cellId, npts, nodes); // --- create all the ordered list of node id's for each face facesWithNodes.nbElems = 5; facesWithNodes.elems[0].nodeIds[0] = nodes[0]; facesWithNodes.elems[0].nodeIds[1] = nodes[2]; facesWithNodes.elems[0].nodeIds[2] = nodes[5]; facesWithNodes.elems[0].nodeIds[3] = nodes[3]; facesWithNodes.elems[0].nbNodes = 4; facesWithNodes.elems[0].vtkType = VTK_QUAD; facesWithNodes.elems[1].nodeIds[0] = nodes[1]; facesWithNodes.elems[1].nodeIds[1] = nodes[2]; facesWithNodes.elems[1].nodeIds[2] = nodes[5]; facesWithNodes.elems[1].nodeIds[3] = nodes[4]; facesWithNodes.elems[1].nbNodes = 4; facesWithNodes.elems[1].vtkType = VTK_QUAD; facesWithNodes.elems[2].nodeIds[0] = nodes[0]; facesWithNodes.elems[2].nodeIds[1] = nodes[1]; facesWithNodes.elems[2].nodeIds[2] = nodes[4]; facesWithNodes.elems[2].nodeIds[3] = nodes[3]; facesWithNodes.elems[2].nbNodes = 4; facesWithNodes.elems[2].vtkType = VTK_QUAD; facesWithNodes.elems[3].nodeIds[0] = nodes[0]; facesWithNodes.elems[3].nodeIds[1] = nodes[1]; facesWithNodes.elems[3].nodeIds[2] = nodes[2]; facesWithNodes.elems[3].nbNodes = 3; facesWithNodes.elems[3].vtkType = VTK_TRIANGLE; facesWithNodes.elems[4].nodeIds[0] = nodes[3]; facesWithNodes.elems[4].nodeIds[1] = nodes[4]; facesWithNodes.elems[4].nodeIds[2] = nodes[5]; facesWithNodes.elems[4].nbNodes = 3; facesWithNodes.elems[4].vtkType = VTK_TRIANGLE; } // --------------------------------------------------------------------------- SMDS_DownQuadPenta::SMDS_DownQuadPenta(SMDS_UnstructuredGrid *grid) : SMDS_Down3D(grid, 5) { _cellTypes.push_back(VTK_QUADRATIC_QUAD); _cellTypes.push_back(VTK_QUADRATIC_QUAD); _cellTypes.push_back(VTK_QUADRATIC_QUAD); _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); } SMDS_DownQuadPenta::~SMDS_DownQuadPenta() { } void SMDS_DownQuadPenta::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) { set setNodes; setNodes.clear(); for (int i = 0; i < orderedNodes.size(); i++) setNodes.insert(orderedNodes[i]); //MESSAGE("cellId = " << cellId); vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); set tofind; //int ids[18] = { 0, 2, 1, 3, 4, 5, 0, 1, 4, 3, 1, 2, 5, 4, 2, 0, 3, 5 }; int ids[36] = { 0, 1, 2, 6, 7, 8, 3, 5, 4, 11, 10, 9, 0, 3, 4, 1, 12, 9, 13, 6, 1, 4, 5, 2, 13, 10, 14, 7, 2, 5, 3, 0, 14, 11, 12, 8 }; // Triangular faces for (int k = 0; k < 2; k++) { tofind.clear(); for (int i = 0; i < 6; i++) tofind.insert(nodes[ids[6 * k + i]]); if (setNodes == tofind) { for (int i = 0; i < 6; i++) orderedNodes[i] = nodes[ids[6 * k + i]]; return; } } // Quadrangular faces for (int k = 0; k < 3; k++) { tofind.clear(); for (int i = 0; i < 8; i++) tofind.insert(nodes[ids[12 + 8 * k + i]]); if (setNodes == tofind) { for (int i = 0; i < 8; i++) orderedNodes[i] = nodes[ids[12 + 8 * k + i]]; return; } } MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); } void SMDS_DownQuadPenta::addDownCell(int cellId, int lowCellId, unsigned char aType) { //ASSERT((cellId >=0) && (cellId < _maxId)); int *faces = &_cellIds[_nbDownCells * cellId]; if (aType == VTK_QUADRATIC_QUAD) for (int i = 0; i < 3; i++) { if (faces[i] < 0) { faces[i] = lowCellId; return; } if (faces[i] == lowCellId) return; } else { //ASSERT(aType == VTK_QUADRATIC_TRIANGLE); for (int i = 3; i < _nbDownCells; i++) { if (faces[i] < 0) { faces[i] = lowCellId; return; } if (faces[i] == lowCellId) return; } } ASSERT(0); } /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's * The quadratic wedge (or pentahedron) is defined by fifteen points. * The ordering of the fifteen points defining the cell is point id's (0-5,6-14) * where point id's 0-5 are the six corner vertices of the wedge, followed by * nine mid-edge nodes (6-14). Note that these mid-edge nodes lie on the edges defined by * (0,1), (1,2), (2,0), (3,4), (4,5), (5,3), (0,3), (1,4), (2,5). * @see vtkQuadraticWedge.h in Filtering * @param cellId volumeId in vtkUnstructuredGrid * @param facesWithNodes vector of face descriptors to be filled */ void SMDS_DownQuadPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) { // --- find point id's of the volume vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(cellId, npts, nodes); // --- create all the ordered list of node id's for each face facesWithNodes.nbElems = 5; facesWithNodes.elems[0].nodeIds[0] = nodes[0]; facesWithNodes.elems[0].nodeIds[1] = nodes[2]; facesWithNodes.elems[0].nodeIds[2] = nodes[5]; facesWithNodes.elems[0].nodeIds[3] = nodes[3]; facesWithNodes.elems[0].nodeIds[4] = nodes[8]; facesWithNodes.elems[0].nodeIds[5] = nodes[14]; facesWithNodes.elems[0].nodeIds[6] = nodes[11]; facesWithNodes.elems[0].nodeIds[7] = nodes[12]; facesWithNodes.elems[0].nbNodes = 8; facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD; facesWithNodes.elems[1].nodeIds[0] = nodes[1]; facesWithNodes.elems[1].nodeIds[1] = nodes[2]; facesWithNodes.elems[1].nodeIds[2] = nodes[5]; facesWithNodes.elems[1].nodeIds[3] = nodes[4]; facesWithNodes.elems[1].nodeIds[4] = nodes[7]; facesWithNodes.elems[1].nodeIds[5] = nodes[14]; facesWithNodes.elems[1].nodeIds[6] = nodes[10]; facesWithNodes.elems[1].nodeIds[7] = nodes[13]; facesWithNodes.elems[1].nbNodes = 8; facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_QUAD; facesWithNodes.elems[2].nodeIds[0] = nodes[0]; facesWithNodes.elems[2].nodeIds[1] = nodes[1]; facesWithNodes.elems[2].nodeIds[2] = nodes[4]; facesWithNodes.elems[2].nodeIds[3] = nodes[3]; facesWithNodes.elems[2].nodeIds[4] = nodes[6]; facesWithNodes.elems[2].nodeIds[5] = nodes[13]; facesWithNodes.elems[2].nodeIds[6] = nodes[9]; facesWithNodes.elems[2].nodeIds[7] = nodes[12]; facesWithNodes.elems[2].nbNodes = 8; facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_QUAD; facesWithNodes.elems[3].nodeIds[0] = nodes[0]; facesWithNodes.elems[3].nodeIds[1] = nodes[1]; facesWithNodes.elems[3].nodeIds[2] = nodes[2]; facesWithNodes.elems[3].nodeIds[3] = nodes[6]; facesWithNodes.elems[3].nodeIds[4] = nodes[7]; facesWithNodes.elems[3].nodeIds[5] = nodes[8]; facesWithNodes.elems[3].nbNodes = 6; facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE; facesWithNodes.elems[4].nodeIds[0] = nodes[3]; facesWithNodes.elems[4].nodeIds[1] = nodes[4]; facesWithNodes.elems[4].nodeIds[2] = nodes[5]; facesWithNodes.elems[4].nodeIds[3] = nodes[9]; facesWithNodes.elems[4].nodeIds[4] = nodes[10]; facesWithNodes.elems[4].nodeIds[5] = nodes[11]; facesWithNodes.elems[4].nbNodes = 6; facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_TRIANGLE; } // --------------------------------------------------------------------------- SMDS_DownHexa::SMDS_DownHexa(SMDS_UnstructuredGrid *grid) : SMDS_Down3D(grid, 6) { _cellTypes.push_back(VTK_QUAD); _cellTypes.push_back(VTK_QUAD); _cellTypes.push_back(VTK_QUAD); _cellTypes.push_back(VTK_QUAD); _cellTypes.push_back(VTK_QUAD); _cellTypes.push_back(VTK_QUAD); } SMDS_DownHexa::~SMDS_DownHexa() { } void SMDS_DownHexa::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) { set setNodes; setNodes.clear(); for (int i = 0; i < orderedNodes.size(); i++) setNodes.insert(orderedNodes[i]); //MESSAGE("cellId = " << cellId); vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); set tofind; //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}; 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}; for (int k = 0; k < 6; k++) // loop on the 6 faces { tofind.clear(); for (int i = 0; i < 4; i++) tofind.insert(nodes[ids[4 * k + i]]); // node ids of the face i if (setNodes == tofind) { for (int i = 0; i < 4; i++) orderedNodes[i] = nodes[ids[4 * k + i]]; return; } } MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]); MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); MESSAGE(nodes[4] << " " << nodes[5] << " " << nodes[6] << " " << nodes[7]); } void SMDS_DownHexa::addDownCell(int cellId, int lowCellId, unsigned char aType) { //ASSERT((cellId >=0)&& (cellId < _maxId)); int *faces = &_cellIds[_nbDownCells * cellId]; for (int i = 0; i < _nbDownCells; i++) { if (faces[i] < 0) { faces[i] = lowCellId; return; } if (faces[i] == lowCellId) return; } ASSERT(0); // MESSAGE("-------------------------------------> trop de faces ! " << cellId << " " << lowCellId); } /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's * The hexahedron is defined by the eight points (0-7), where (0,1,2,3) is the base * of the hexahedron which, using the right hand rule, forms a quadrilateral whose normal * points in the direction of the opposite face (4,5,6,7). * @see vtkHexahedron.h in Filtering * @param cellId volumeId in vtkUnstructuredGrid * @param facesWithNodes vector of face descriptors to be filled */ void SMDS_DownHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) { // --- find point id's of the volume vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(cellId, npts, nodes); // --- create all the ordered list of node id's for each face facesWithNodes.nbElems = 6; facesWithNodes.elems[0].nodeIds[0] = nodes[0]; facesWithNodes.elems[0].nodeIds[1] = nodes[1]; facesWithNodes.elems[0].nodeIds[2] = nodes[2]; facesWithNodes.elems[0].nodeIds[3] = nodes[3]; facesWithNodes.elems[0].nbNodes = 4; facesWithNodes.elems[0].vtkType = VTK_QUAD; facesWithNodes.elems[1].nodeIds[0] = nodes[4]; facesWithNodes.elems[1].nodeIds[1] = nodes[5]; facesWithNodes.elems[1].nodeIds[2] = nodes[6]; facesWithNodes.elems[1].nodeIds[3] = nodes[7]; facesWithNodes.elems[1].nbNodes = 4; facesWithNodes.elems[1].vtkType = VTK_QUAD; facesWithNodes.elems[2].nodeIds[0] = nodes[0]; facesWithNodes.elems[2].nodeIds[1] = nodes[1]; facesWithNodes.elems[2].nodeIds[2] = nodes[5]; facesWithNodes.elems[2].nodeIds[3] = nodes[4]; facesWithNodes.elems[2].nbNodes = 4; facesWithNodes.elems[2].vtkType = VTK_QUAD; facesWithNodes.elems[3].nodeIds[0] = nodes[1]; facesWithNodes.elems[3].nodeIds[1] = nodes[2]; facesWithNodes.elems[3].nodeIds[2] = nodes[6]; facesWithNodes.elems[3].nodeIds[3] = nodes[5]; facesWithNodes.elems[3].nbNodes = 4; facesWithNodes.elems[3].vtkType = VTK_QUAD; facesWithNodes.elems[4].nodeIds[0] = nodes[2]; facesWithNodes.elems[4].nodeIds[1] = nodes[6]; facesWithNodes.elems[4].nodeIds[2] = nodes[7]; facesWithNodes.elems[4].nodeIds[3] = nodes[3]; facesWithNodes.elems[4].nbNodes = 4; facesWithNodes.elems[4].vtkType = VTK_QUAD; facesWithNodes.elems[5].nodeIds[0] = nodes[3]; facesWithNodes.elems[5].nodeIds[1] = nodes[7]; facesWithNodes.elems[5].nodeIds[2] = nodes[4]; facesWithNodes.elems[5].nodeIds[3] = nodes[0]; facesWithNodes.elems[5].nbNodes = 4; facesWithNodes.elems[5].vtkType = VTK_QUAD; } // --------------------------------------------------------------------------- SMDS_DownQuadHexa::SMDS_DownQuadHexa(SMDS_UnstructuredGrid *grid) : SMDS_Down3D(grid, 6) { _cellTypes.push_back(VTK_QUADRATIC_QUAD); _cellTypes.push_back(VTK_QUADRATIC_QUAD); _cellTypes.push_back(VTK_QUADRATIC_QUAD); _cellTypes.push_back(VTK_QUADRATIC_QUAD); _cellTypes.push_back(VTK_QUADRATIC_QUAD); _cellTypes.push_back(VTK_QUADRATIC_QUAD); } SMDS_DownQuadHexa::~SMDS_DownQuadHexa() { } void SMDS_DownQuadHexa::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) { set setNodes; setNodes.clear(); for (int i = 0; i < orderedNodes.size(); i++) setNodes.insert(orderedNodes[i]); //MESSAGE("cellId = " << cellId); vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); set tofind; //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}; 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, 4, 0, 1, 5,16, 8,17,12, 5, 1, 2, 6,17, 9,18,13, 6, 2, 3, 7,18,10,19,14}; for (int k = 0; k < 6; k++) { tofind.clear(); for (int i = 0; i < 8; i++) tofind.insert(nodes[ids[8 * k + i]]); if (setNodes == tofind) { for (int i = 0; i < 8; i++) orderedNodes[i] = nodes[ids[8 * k + i]]; return; } } MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]); MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); } void SMDS_DownQuadHexa::addDownCell(int cellId, int lowCellId, unsigned char aType) { //ASSERT((cellId >=0)&& (cellId < _maxId)); int *faces = &_cellIds[_nbDownCells * cellId]; for (int i = 0; i < _nbDownCells; i++) { if (faces[i] < 0) { faces[i] = lowCellId; return; } if (faces[i] == lowCellId) return; } ASSERT(0); } /*! Create a list of faces described by a vtk Type and an ordered set of Node Id's * The ordering of the twenty points defining the quadratic hexahedron cell is point id's (0-7,8-19) * where point id's 0-7 are the eight corner vertices of the cube, followed by twelve mid-edge nodes (8-19). * Note that these mid-edge nodes lie on the edges defined by * (0,1), (1,2), (2,3), (3,0), (4,5), (5,6), (6,7), (7,4), (0,4), (1,5), (2,6), (3,7). * @see vtkQuadraticHexahedron.h in Filtering * @param cellId volumeId in vtkUnstructuredGrid * @param facesWithNodes vector of face descriptors to be filled */ void SMDS_DownQuadHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) { // --- find point id's of the volume vtkIdType npts = 0; vtkIdType *nodes; // will refer to the point id's of the volume _grid->GetCellPoints(cellId, npts, nodes); // --- create all the ordered list of node id's for each face facesWithNodes.nbElems = 6; facesWithNodes.elems[0].nodeIds[0] = nodes[0]; facesWithNodes.elems[0].nodeIds[1] = nodes[1]; facesWithNodes.elems[0].nodeIds[2] = nodes[2]; facesWithNodes.elems[0].nodeIds[3] = nodes[3]; facesWithNodes.elems[0].nodeIds[4] = nodes[8]; facesWithNodes.elems[0].nodeIds[5] = nodes[9]; facesWithNodes.elems[0].nodeIds[6] = nodes[10]; facesWithNodes.elems[0].nodeIds[7] = nodes[11]; facesWithNodes.elems[0].nbNodes = 8; facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD; facesWithNodes.elems[1].nodeIds[0] = nodes[4]; facesWithNodes.elems[1].nodeIds[1] = nodes[5]; facesWithNodes.elems[1].nodeIds[2] = nodes[6]; facesWithNodes.elems[1].nodeIds[3] = nodes[7]; facesWithNodes.elems[1].nodeIds[4] = nodes[12]; facesWithNodes.elems[1].nodeIds[5] = nodes[13]; facesWithNodes.elems[1].nodeIds[6] = nodes[14]; facesWithNodes.elems[1].nodeIds[7] = nodes[15]; facesWithNodes.elems[1].nbNodes = 8; facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_QUAD; facesWithNodes.elems[2].nodeIds[0] = nodes[0]; facesWithNodes.elems[2].nodeIds[1] = nodes[1]; facesWithNodes.elems[2].nodeIds[2] = nodes[5]; facesWithNodes.elems[2].nodeIds[3] = nodes[4]; facesWithNodes.elems[2].nodeIds[4] = nodes[8]; facesWithNodes.elems[2].nodeIds[5] = nodes[17]; facesWithNodes.elems[2].nodeIds[6] = nodes[12]; facesWithNodes.elems[2].nodeIds[7] = nodes[16]; facesWithNodes.elems[2].nbNodes = 8; facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_QUAD; facesWithNodes.elems[3].nodeIds[0] = nodes[1]; facesWithNodes.elems[3].nodeIds[1] = nodes[2]; facesWithNodes.elems[3].nodeIds[2] = nodes[6]; facesWithNodes.elems[3].nodeIds[3] = nodes[5]; facesWithNodes.elems[3].nodeIds[4] = nodes[9]; facesWithNodes.elems[3].nodeIds[5] = nodes[18]; facesWithNodes.elems[3].nodeIds[6] = nodes[13]; facesWithNodes.elems[3].nodeIds[7] = nodes[17]; facesWithNodes.elems[3].nbNodes = 8; facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_QUAD; facesWithNodes.elems[4].nodeIds[0] = nodes[2]; facesWithNodes.elems[4].nodeIds[1] = nodes[6]; facesWithNodes.elems[4].nodeIds[2] = nodes[7]; facesWithNodes.elems[4].nodeIds[3] = nodes[3]; facesWithNodes.elems[4].nodeIds[4] = nodes[18]; facesWithNodes.elems[4].nodeIds[5] = nodes[14]; facesWithNodes.elems[4].nodeIds[6] = nodes[19]; facesWithNodes.elems[4].nodeIds[7] = nodes[10]; facesWithNodes.elems[4].nbNodes = 8; facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_QUAD; facesWithNodes.elems[5].nodeIds[0] = nodes[3]; facesWithNodes.elems[5].nodeIds[1] = nodes[7]; facesWithNodes.elems[5].nodeIds[2] = nodes[4]; facesWithNodes.elems[5].nodeIds[3] = nodes[0]; facesWithNodes.elems[5].nodeIds[4] = nodes[19]; facesWithNodes.elems[5].nodeIds[5] = nodes[15]; facesWithNodes.elems[5].nodeIds[6] = nodes[16]; facesWithNodes.elems[5].nodeIds[7] = nodes[11]; facesWithNodes.elems[5].nbNodes = 8; facesWithNodes.elems[5].vtkType = VTK_QUADRATIC_QUAD; } // ---------------------------------------------------------------------------