X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMDS%2FSMDS_UnstructuredGrid.cxx;h=1eb5c445d60e5e13ed1af797359a7f258ceb53d5;hb=d627437f5d8c20e0750973df76c62d55fc19a5e7;hp=869e6079c8b5ea75511650a3249fd00ac74dd0d9;hpb=4ac8d075849b2ff7d0934a811dda5b6972873540;p=modules%2Fsmesh.git diff --git a/src/SMDS/SMDS_UnstructuredGrid.cxx b/src/SMDS/SMDS_UnstructuredGrid.cxx index 869e6079c..1eb5c445d 100644 --- a/src/SMDS/SMDS_UnstructuredGrid.cxx +++ b/src/SMDS/SMDS_UnstructuredGrid.cxx @@ -1,3 +1,22 @@ +// Copyright (C) 2010-2012 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. +// +// 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 +// + #define CHRONODEF #include "SMDS_UnstructuredGrid.hxx" #include "SMDS_Mesh.hxx" @@ -8,7 +27,9 @@ #include "utilities.h" #include +#include #include +#include #include #include @@ -199,10 +220,12 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n ++i; int endBloc = i; if ( endBloc > startBloc ) - copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell, - alreadyCopied, startBloc, endBloc); + copyBloc(newTypes, + idCellsOldToNew, idNodesOldToNew, + newConnectivity, newLocations, + pointsCell, alreadyCopied, + startBloc, endBloc); } - newConnectivity->Squeeze(); if (1/*newNodeSize*/) @@ -212,6 +235,19 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n MESSAGE("NumberOfPoints: " << this->GetNumberOfPoints()); } + if (vtkDoubleArray* diameters = + vtkDoubleArray::SafeDownCast( vtkDataSet::CellData->GetScalars() )) // Balls + { + for (int oldCellID = 0; oldCellID < oldCellSize; oldCellID++) + { + if (this->Types->GetValue(oldCellID) == VTK_EMPTY_CELL) + continue; + int newCellId = idCellsOldToNew[ oldCellID ]; + if (newTypes->GetValue(newCellId) == VTK_POLY_VERTEX) + diameters->SetValue( newCellId, diameters->GetValue( oldCellID )); + } + } + if (this->FaceLocations) { vtkIdTypeArray *newFaceLocations = vtkIdTypeArray::New(); @@ -256,7 +292,9 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n newFaces->Delete(); } else + { this->SetCells(newTypes, newLocations, newConnectivity, FaceLocations, Faces); + } newPoints->Delete(); newTypes->Delete(); @@ -280,10 +318,15 @@ void SMDS_UnstructuredGrid::copyNodes(vtkPoints *newPoints, std::vector& id } } -void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes, std::vector& idCellsOldToNew, - std::vector& idNodesOldToNew, vtkCellArray* newConnectivity, - vtkIdTypeArray* newLocations, vtkIdType* pointsCell, int& alreadyCopied, - int start, int end) +void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes, + std::vector& idCellsOldToNew, + std::vector& idNodesOldToNew, + vtkCellArray* newConnectivity, + vtkIdTypeArray* newLocations, + vtkIdType* pointsCell, + int& alreadyCopied, + int start, + int end) { MESSAGE("copyBloc " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start); for (int j = start; j < end; j++) @@ -312,7 +355,12 @@ void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes, std::vector int SMDS_UnstructuredGrid::CellIdToDownId(int vtkCellId) { - // ASSERT((vtkCellId >= 0) && (vtkCellId < _cellIdToDownId.size())); + if((vtkCellId < 0) || (vtkCellId >= _cellIdToDownId.size())) + { + //MESSAGE("SMDS_UnstructuredGrid::CellIdToDownId structure not up to date: vtkCellId=" + // << vtkCellId << " max="<< _cellIdToDownId.size()); + return -1; + } return _cellIdToDownId[vtkCellId]; } @@ -322,6 +370,17 @@ void SMDS_UnstructuredGrid::setCellIdToDownId(int vtkCellId, int downId) _cellIdToDownId[vtkCellId] = downId; } +void SMDS_UnstructuredGrid::CleanDownwardConnectivity() +{ + for (int i = 0; i < _downArray.size(); i++) + { + if (_downArray[i]) + delete _downArray[i]; + _downArray[i] = 0; + } + _cellIdToDownId.clear(); +} + /*! Build downward connectivity: to do only when needed because heavy memory load. * Downward connectivity is no more valid if vtkUnstructuredGrid is modified. * @@ -333,83 +392,87 @@ void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges) // --- erase previous data if any - for (int i = 0; i < _downArray.size(); i++) - { - if (_downArray[i]) - delete _downArray[i]; - _downArray[i] = 0; - } - _cellIdToDownId.clear(); + this->CleanDownwardConnectivity(); // --- create SMDS_Downward structures (in _downArray vector[vtkCellType]) - _downArray.resize(VTK_MAXTYPE + 1, 0); // --- max. type value = VTK_QUADRATIC_PYRAMID - - _downArray[VTK_LINE] = new SMDS_DownEdge(this); - _downArray[VTK_QUADRATIC_EDGE] = new SMDS_DownQuadEdge(this); - _downArray[VTK_TRIANGLE] = new SMDS_DownTriangle(this); - _downArray[VTK_QUADRATIC_TRIANGLE] = new SMDS_DownQuadTriangle(this); - _downArray[VTK_QUAD] = new SMDS_DownQuadrangle(this); - _downArray[VTK_QUADRATIC_QUAD] = new SMDS_DownQuadQuadrangle(this); - _downArray[VTK_TETRA] = new SMDS_DownTetra(this); - _downArray[VTK_QUADRATIC_TETRA] = new SMDS_DownQuadTetra(this); - _downArray[VTK_PYRAMID] = new SMDS_DownPyramid(this); - _downArray[VTK_QUADRATIC_PYRAMID] = new SMDS_DownQuadPyramid(this); - _downArray[VTK_WEDGE] = new SMDS_DownPenta(this); - _downArray[VTK_QUADRATIC_WEDGE] = new SMDS_DownQuadPenta(this); - _downArray[VTK_HEXAHEDRON] = new SMDS_DownHexa(this); - _downArray[VTK_QUADRATIC_HEXAHEDRON] = new SMDS_DownQuadHexa(this); + _downArray.resize(VTK_MAXTYPE + 1, 0); + + _downArray[VTK_LINE] = new SMDS_DownEdge(this); + _downArray[VTK_QUADRATIC_EDGE] = new SMDS_DownQuadEdge(this); + _downArray[VTK_TRIANGLE] = new SMDS_DownTriangle(this); + _downArray[VTK_QUADRATIC_TRIANGLE] = new SMDS_DownQuadTriangle(this); + _downArray[VTK_QUAD] = new SMDS_DownQuadrangle(this); + _downArray[VTK_QUADRATIC_QUAD] = new SMDS_DownQuadQuadrangle(this); + _downArray[VTK_BIQUADRATIC_QUAD] = new SMDS_DownQuadQuadrangle(this); + _downArray[VTK_TETRA] = new SMDS_DownTetra(this); + _downArray[VTK_QUADRATIC_TETRA] = new SMDS_DownQuadTetra(this); + _downArray[VTK_PYRAMID] = new SMDS_DownPyramid(this); + _downArray[VTK_QUADRATIC_PYRAMID] = new SMDS_DownQuadPyramid(this); + _downArray[VTK_WEDGE] = new SMDS_DownPenta(this); + _downArray[VTK_QUADRATIC_WEDGE] = new SMDS_DownQuadPenta(this); + _downArray[VTK_HEXAHEDRON] = new SMDS_DownHexa(this); + _downArray[VTK_QUADRATIC_HEXAHEDRON] = new SMDS_DownQuadHexa(this); + _downArray[VTK_TRIQUADRATIC_HEXAHEDRON] = new SMDS_DownQuadHexa(this); + _downArray[VTK_HEXAGONAL_PRISM] = new SMDS_DownPenta(this); // --- get detailed info of number of cells of each type, allocate SMDS_downward structures const SMDS_MeshInfo &meshInfo = _mesh->GetMeshInfo(); - int nbLinTetra = meshInfo.NbTetras(ORDER_LINEAR); - int nbQuadTetra = meshInfo.NbTetras(ORDER_QUADRATIC); - int nbLinPyra = meshInfo.NbPyramids(ORDER_LINEAR); - int nbQuadPyra = meshInfo.NbPyramids(ORDER_QUADRATIC); - int nbLinPrism = meshInfo.NbPrisms(ORDER_LINEAR); - int nbQuadPrism = meshInfo.NbPrisms(ORDER_QUADRATIC); - int nbLinHexa = meshInfo.NbHexas(ORDER_LINEAR); - int nbQuadHexa = meshInfo.NbHexas(ORDER_QUADRATIC); - - int nbLineGuess = int((4.0 / 3.0) * nbLinTetra + 2 * nbLinPrism + 2.5 * nbLinPyra + 3 * nbLinHexa); + int nbLinTetra = meshInfo.NbTetras (ORDER_LINEAR); + int nbQuadTetra = meshInfo.NbTetras (ORDER_QUADRATIC); + int nbLinPyra = meshInfo.NbPyramids(ORDER_LINEAR); + int nbQuadPyra = meshInfo.NbPyramids(ORDER_QUADRATIC); + int nbLinPrism = meshInfo.NbPrisms (ORDER_LINEAR); + int nbQuadPrism = meshInfo.NbPrisms (ORDER_QUADRATIC); + int nbLinHexa = meshInfo.NbHexas (ORDER_LINEAR); + int nbQuadHexa = meshInfo.NbHexas (ORDER_QUADRATIC); + int nbHexPrism = meshInfo.NbHexPrisms(); + + int nbLineGuess = int((4.0 / 3.0) * nbLinTetra + 2 * nbLinPrism + 2.5 * nbLinPyra + 3 * nbLinHexa); int nbQuadEdgeGuess = int((4.0 / 3.0) * nbQuadTetra + 2 * nbQuadPrism + 2.5 * nbQuadPyra + 3 * nbQuadHexa); - int nbLinTriaGuess = 2 * nbLinTetra + nbLinPrism + 2 * nbLinPyra; + int nbLinTriaGuess = 2 * nbLinTetra + nbLinPrism + 2 * nbLinPyra; int nbQuadTriaGuess = 2 * nbQuadTetra + nbQuadPrism + 2 * nbQuadPyra; - int nbLinQuadGuess = int((2.0 / 3.0) * nbLinPrism + (1.0 / 2.0) * nbLinPyra + 3 * nbLinHexa); + int nbLinQuadGuess = int((2.0 / 3.0) * nbLinPrism + (1.0 / 2.0) * nbLinPyra + 3 * nbLinHexa); int nbQuadQuadGuess = int((2.0 / 3.0) * nbQuadPrism + (1.0 / 2.0) * nbQuadPyra + 3 * nbQuadHexa); - int GuessSize[VTK_QUADRATIC_TETRA]; - GuessSize[VTK_LINE] = nbLineGuess; - GuessSize[VTK_QUADRATIC_EDGE] = nbQuadEdgeGuess; - GuessSize[VTK_TRIANGLE] = nbLinTriaGuess; - GuessSize[VTK_QUADRATIC_TRIANGLE] = nbQuadTriaGuess; - GuessSize[VTK_QUAD] = nbLinQuadGuess; - GuessSize[VTK_QUADRATIC_QUAD] = nbQuadQuadGuess; - GuessSize[VTK_TETRA] = nbLinTetra; - GuessSize[VTK_QUADRATIC_TETRA] = nbQuadTetra; - GuessSize[VTK_PYRAMID] = nbLinPyra; - GuessSize[VTK_QUADRATIC_PYRAMID] = nbQuadPyra; - GuessSize[VTK_WEDGE] = nbLinPrism; - GuessSize[VTK_QUADRATIC_WEDGE] = nbQuadPrism; - GuessSize[VTK_HEXAHEDRON] = nbLinHexa; - GuessSize[VTK_QUADRATIC_HEXAHEDRON] = nbQuadHexa; - - _downArray[VTK_LINE]->allocate(nbLineGuess); - _downArray[VTK_QUADRATIC_EDGE]->allocate(nbQuadEdgeGuess); - _downArray[VTK_TRIANGLE]->allocate(nbLinTriaGuess); - _downArray[VTK_QUADRATIC_TRIANGLE]->allocate(nbQuadTriaGuess); - _downArray[VTK_QUAD]->allocate(nbLinQuadGuess); - _downArray[VTK_QUADRATIC_QUAD]->allocate(nbQuadQuadGuess); - _downArray[VTK_TETRA]->allocate(nbLinTetra); - _downArray[VTK_QUADRATIC_TETRA]->allocate(nbQuadTetra); - _downArray[VTK_PYRAMID]->allocate(nbLinPyra); - _downArray[VTK_QUADRATIC_PYRAMID]->allocate(nbQuadPyra); - _downArray[VTK_WEDGE]->allocate(nbLinPrism); - _downArray[VTK_QUADRATIC_WEDGE]->allocate(nbQuadPrism); - _downArray[VTK_HEXAHEDRON]->allocate(nbLinHexa); - _downArray[VTK_QUADRATIC_HEXAHEDRON]->allocate(nbQuadHexa); + int GuessSize[VTK_MAXTYPE]; + GuessSize[VTK_LINE] = nbLineGuess; + GuessSize[VTK_QUADRATIC_EDGE] = nbQuadEdgeGuess; + GuessSize[VTK_TRIANGLE] = nbLinTriaGuess; + GuessSize[VTK_QUADRATIC_TRIANGLE] = nbQuadTriaGuess; + GuessSize[VTK_QUAD] = nbLinQuadGuess; + GuessSize[VTK_QUADRATIC_QUAD] = nbQuadQuadGuess; + GuessSize[VTK_BIQUADRATIC_QUAD] = nbQuadQuadGuess; + GuessSize[VTK_TETRA] = nbLinTetra; + GuessSize[VTK_QUADRATIC_TETRA] = nbQuadTetra; + GuessSize[VTK_PYRAMID] = nbLinPyra; + GuessSize[VTK_QUADRATIC_PYRAMID] = nbQuadPyra; + GuessSize[VTK_WEDGE] = nbLinPrism; + GuessSize[VTK_QUADRATIC_WEDGE] = nbQuadPrism; + GuessSize[VTK_HEXAHEDRON] = nbLinHexa; + GuessSize[VTK_QUADRATIC_HEXAHEDRON] = nbQuadHexa; + GuessSize[VTK_TRIQUADRATIC_HEXAHEDRON] = nbQuadHexa; + GuessSize[VTK_HEXAGONAL_PRISM] = nbHexPrism; + + _downArray[VTK_LINE] ->allocate(nbLineGuess); + _downArray[VTK_QUADRATIC_EDGE] ->allocate(nbQuadEdgeGuess); + _downArray[VTK_TRIANGLE] ->allocate(nbLinTriaGuess); + _downArray[VTK_QUADRATIC_TRIANGLE] ->allocate(nbQuadTriaGuess); + _downArray[VTK_QUAD] ->allocate(nbLinQuadGuess); + _downArray[VTK_QUADRATIC_QUAD] ->allocate(nbQuadQuadGuess); + _downArray[VTK_BIQUADRATIC_QUAD] ->allocate(nbQuadQuadGuess); + _downArray[VTK_TETRA] ->allocate(nbLinTetra); + _downArray[VTK_QUADRATIC_TETRA] ->allocate(nbQuadTetra); + _downArray[VTK_PYRAMID] ->allocate(nbLinPyra); + _downArray[VTK_QUADRATIC_PYRAMID] ->allocate(nbQuadPyra); + _downArray[VTK_WEDGE] ->allocate(nbLinPrism); + _downArray[VTK_QUADRATIC_WEDGE] ->allocate(nbQuadPrism); + _downArray[VTK_HEXAHEDRON] ->allocate(nbLinHexa); + _downArray[VTK_QUADRATIC_HEXAHEDRON] ->allocate(nbQuadHexa); + _downArray[VTK_TRIQUADRATIC_HEXAHEDRON]->allocate(nbQuadHexa); + _downArray[VTK_HEXAGONAL_PRISM] ->allocate(nbHexPrism); // --- iteration on vtkUnstructuredGrid cells, only faces // for each vtk face: @@ -700,7 +763,7 @@ void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges) * @param vtkId the vtk id of the cell * @return number of neighbors */ -int SMDS_UnstructuredGrid::GetNeighbors(int* neighborsVtkIds, int* downIds, unsigned char* downTypes, int vtkId) +int SMDS_UnstructuredGrid::GetNeighbors(int* neighborsVtkIds, int* downIds, unsigned char* downTypes, int vtkId, bool getSkin) { int vtkType = this->GetCellType(vtkId); int cellDim = SMDS_Downward::getCellDimension(vtkType); @@ -735,9 +798,27 @@ int SMDS_UnstructuredGrid::GetNeighbors(int* neighborsVtkIds, int* downIds, unsi downIds[nb] = downId; downTypes[nb] = cellType; nb++; + if (nb >= NBMAXNEIGHBORS) + { + INFOS("SMDS_UnstructuredGrid::GetNeighbors problem: NBMAXNEIGHBORS=" <getVtkCellId(downId); // OK if skin present + downIds[nb] = downId; + downTypes[nb] = cellType; + nb++; + if (nb >= NBMAXNEIGHBORS) + { + INFOS("SMDS_UnstructuredGrid::GetNeighbors problem: NBMAXNEIGHBORS=" <= NBMAXNEIGHBORS) - assert(0); } return nb; } @@ -752,18 +833,21 @@ int SMDS_UnstructuredGrid::GetParentVolumes(int* volVtkIds, int vtkId) int vtkType = this->GetCellType(vtkId); int dim = SMDS_Downward::getCellDimension(vtkType); int nbFaces = 0; - int faces[1000]; unsigned char cellTypes[1000]; int downCellId[1000]; if (dim == 1) { int downId = this->CellIdToDownId(vtkId); + if (downId < 0) + { + MESSAGE("Downward structure not up to date: new edge not taken into account"); + return 0; + } nbFaces = _downArray[vtkType]->getNumberOfUpCells(downId); const int *upCells = _downArray[vtkType]->getUpCells(downId); const unsigned char* upTypes = _downArray[vtkType]->getUpTypes(downId); for (int i=0; i< nbFaces; i++) { - faces[i] = _downArray[upTypes[i]]->getVtkCellId(upCells[i]); cellTypes[i] = upTypes[i]; downCellId[i] = upCells[i]; } @@ -771,9 +855,14 @@ int SMDS_UnstructuredGrid::GetParentVolumes(int* volVtkIds, int vtkId) else if (dim == 2) { nbFaces = 1; - faces[0] = vtkId; cellTypes[0] = this->GetCellType(vtkId); - downCellId[0] = this->CellIdToDownId(vtkId); + int downId = this->CellIdToDownId(vtkId); + if (downId < 0) + { + MESSAGE("Downward structure not up to date: new face not taken into account"); + return 0; + } + downCellId[0] = downId; } int nbvol =0; @@ -805,7 +894,6 @@ int SMDS_UnstructuredGrid::GetParentVolumes(int* volVtkIds, int downId, unsigned int vtkType = downType; int dim = SMDS_Downward::getCellDimension(vtkType); int nbFaces = 0; - int faces[1000]; unsigned char cellTypes[1000]; int downCellId[1000]; if (dim == 1) @@ -815,7 +903,6 @@ int SMDS_UnstructuredGrid::GetParentVolumes(int* volVtkIds, int downId, unsigned const unsigned char* upTypes = _downArray[vtkType]->getUpTypes(downId); for (int i=0; i< nbFaces; i++) { - faces[i] = _downArray[upTypes[i]]->getVtkCellId(upCells[i]); cellTypes[i] = upTypes[i]; downCellId[i] = upCells[i]; } @@ -884,15 +971,17 @@ void SMDS_UnstructuredGrid::ModifyCellNodes(int vtkVolId, std::map loc * @param orderedNodes list of nodes to reorder (in out) * @return size of the list */ -int SMDS_UnstructuredGrid::getOrderedNodesOfFace(int vtkVolId, std::vector& orderedNodes) +int SMDS_UnstructuredGrid::getOrderedNodesOfFace(int vtkVolId, int& dim, std::vector& orderedNodes) { int vtkType = this->GetCellType(vtkVolId); - int cellDim = SMDS_Downward::getCellDimension(vtkType); - if (cellDim != 3) - return 0; - SMDS_Down3D *downvol = static_cast (_downArray[vtkType]); - int downVolId = this->_cellIdToDownId[vtkVolId]; - downvol->getOrderedNodesOfFace(downVolId, orderedNodes); + dim = SMDS_Downward::getCellDimension(vtkType); + if (dim == 3) + { + SMDS_Down3D *downvol = static_cast (_downArray[vtkType]); + int downVolId = this->_cellIdToDownId[vtkVolId]; + downvol->getOrderedNodesOfFace(downVolId, orderedNodes); + } + // else nothing to do; return orderedNodes.size(); } @@ -925,7 +1014,7 @@ void SMDS_UnstructuredGrid::BuildLinks() * @param nodeDomains: map(original id --> map(domain --> duplicated node id)) * @return ok if success. */ -SMDS_MeshVolume* SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId, +SMDS_MeshCell* SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId, int domain1, int domain2, std::set& originalNodes, @@ -939,65 +1028,136 @@ SMDS_MeshVolume* SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId, for (; it != originalNodes.end(); ++it) orderedOriginals.push_back(*it); - int nbNodes = this->getOrderedNodesOfFace(vtkVolId, orderedOriginals); + int dim = 0; + int nbNodes = this->getOrderedNodesOfFace(vtkVolId, dim, orderedOriginals); vector orderedNodes; + bool isQuadratic = false; switch (orderedOriginals.size()) { case 3: - case 4: - for (int i = 0; i < nbNodes; i++) - orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); - for (int i = 0; i < nbNodes; i++) - orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); + if (dim == 2) + isQuadratic = true; break; case 6: case 8: - { - long dom1 = domain1; - long dom2 = domain2; - long dom1_2; // for nodeQuadDomains - if (domain1 < domain2) - dom1_2 = dom1 + INT_MAX * dom2; - else - dom1_2 = dom2 + INT_MAX * dom1; - //cerr << "dom1=" << dom1 << " dom2=" << dom2 << " dom1_2=" << dom1_2 << endl; - int ima = orderedOriginals.size(); - int mid = orderedOriginals.size() / 2; - //cerr << "ima=" << ima << " mid=" << mid << endl; - for (int i = 0; i < mid; i++) - orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); - for (int i = 0; i < mid; i++) - orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); - for (int i = mid; i < ima; i++) - orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); - for (int i = mid; i < ima; i++) - orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); - for (int i = 0; i < mid; i++) - { - int oldId = orderedOriginals[i]; - int newId; - if (nodeQuadDomains.count(oldId) && nodeQuadDomains[oldId].count(dom1_2)) - newId = nodeQuadDomains[oldId][dom1_2]; - else - { - double *coords = this->GetPoint(oldId); - SMDS_MeshNode *newNode = _mesh->AddNode(coords[0], coords[1], coords[2]); - newId = newNode->getVtkId(); - std::map emptyMap; - nodeQuadDomains[oldId] = emptyMap; - nodeQuadDomains[oldId][dom1_2] = newId; - } - orderedNodes.push_back(newId); - } - } + isQuadratic = true; break; default: - ASSERT(0); + isQuadratic = false; + break; + } + + if (isQuadratic) + { + long dom1 = domain1; + long dom2 = domain2; + long dom1_2; // for nodeQuadDomains + if (domain1 < domain2) + dom1_2 = dom1 + INT_MAX * dom2; + else + dom1_2 = dom2 + INT_MAX * dom1; + //cerr << "dom1=" << dom1 << " dom2=" << dom2 << " dom1_2=" << dom1_2 << endl; + int ima = orderedOriginals.size(); + int mid = orderedOriginals.size() / 2; + //cerr << "ima=" << ima << " mid=" << mid << endl; + for (int i = 0; i < mid; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); + for (int i = 0; i < mid; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); + for (int i = mid; i < ima; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); + for (int i = mid; i < ima; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); + for (int i = 0; i < mid; i++) + { + int oldId = orderedOriginals[i]; + int newId; + if (nodeQuadDomains.count(oldId) && nodeQuadDomains[oldId].count(dom1_2)) + newId = nodeQuadDomains[oldId][dom1_2]; + else + { + double *coords = this->GetPoint(oldId); + SMDS_MeshNode *newNode = _mesh->AddNode(coords[0], coords[1], coords[2]); + newId = newNode->getVtkId(); + std::map emptyMap; + nodeQuadDomains[oldId] = emptyMap; + nodeQuadDomains[oldId][dom1_2] = newId; + } + orderedNodes.push_back(newId); + } + } + else + { + for (int i = 0; i < nbNodes; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); + if (dim == 3) + for (int i = 0; i < nbNodes; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); + else + for (int i = nbNodes-1; i >= 0; i--) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); + + } + + if (dim == 3) + { + SMDS_MeshVolume *vol = _mesh->AddVolumeFromVtkIds(orderedNodes); + return vol; + } + else if (dim == 2) + { + SMDS_MeshFace *face = _mesh->AddFaceFromVtkIds(orderedNodes); + return face; + } + + // TODO update sub-shape list of elements and nodes + return 0; +} + +//================================================================================ +/*! + * \brief Allocates data array for ball diameters + * \param MaxVtkID - max ID of a ball element + */ +//================================================================================ + +void SMDS_UnstructuredGrid::AllocateDiameters( vtkIdType MaxVtkID ) +{ + SetBallDiameter( MaxVtkID, 0 ); +} + +//================================================================================ +/*! + * \brief Sets diameter of a ball element + * \param vtkID - vtk id of the ball element + * \param diameter - diameter of the ball element + */ +//================================================================================ + +void SMDS_UnstructuredGrid::SetBallDiameter( vtkIdType vtkID, double diameter ) +{ + vtkDoubleArray* array = vtkDoubleArray::SafeDownCast( vtkDataSet::CellData->GetScalars() ); + if ( !array ) + { + array = vtkDoubleArray::New(); + array->SetNumberOfComponents(1); + vtkDataSet::CellData->SetScalars( array ); } + array->InsertValue( vtkID, diameter ); +} - SMDS_MeshVolume *vol = _mesh->AddVolumeFromVtkIds(orderedNodes); +//================================================================================ +/*! + * \brief Returns diameter of a ball element + * \param vtkID - vtk id of the ball element + */ +//================================================================================ - // TODO update subshape list of elements and nodes - return vol; +double SMDS_UnstructuredGrid::GetBallDiameter( vtkIdType vtkID ) const +{ + if ( vtkDataSet::CellData ) + return vtkDoubleArray::SafeDownCast( vtkDataSet::CellData->GetScalars() )->GetValue( vtkID ); + return 0; } +