X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMDS%2FSMDS_UnstructuredGrid.cxx;h=8da9a287b7bfddfa3f729a115878185815f71c70;hp=bf9df36cffc1c1c80eb5fa3b3fde23e680f301a0;hb=cb55604f37e3d2583272fd436bb6557b041948b5;hpb=a1920ff31054e2c882bd94d4f3c04abe53980ce0 diff --git a/src/SMDS/SMDS_UnstructuredGrid.cxx b/src/SMDS/SMDS_UnstructuredGrid.cxx index bf9df36cf..8da9a287b 100644 --- a/src/SMDS/SMDS_UnstructuredGrid.cxx +++ b/src/SMDS/SMDS_UnstructuredGrid.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2010-2020 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 @@ -36,8 +36,6 @@ #include #include -using namespace std; - SMDS_CellLinks* SMDS_CellLinks::New() { return new SMDS_CellLinks(); @@ -48,7 +46,7 @@ void SMDS_CellLinks::ResizeForPoint(vtkIdType vtkID) if ( vtkID > this->MaxId ) { this->MaxId = vtkID; - if ( vtkID >= this->Size ) + if ( vtkID >= this->Size ) vtkCellLinks::Resize( vtkID+SMDS_Mesh::chunkSize ); } } @@ -61,7 +59,7 @@ void SMDS_CellLinks::BuildLinks(vtkDataSet *data, vtkCellArray *Connectivity, vt vtkIdType j, cellId = 0; unsigned short *linkLoc; vtkIdType npts=0; - vtkIdType *pts=0; + vtkIdType const *pts(nullptr); vtkIdType loc = Connectivity->GetTraversalLocation(); // traverse data to determine number of uses of each point @@ -150,7 +148,7 @@ int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *p // --- type = VTK_POLYHEDRON int cellid = this->InsertNextCell(type, npts, pts); - set setOfNodes; + std::set setOfNodes; setOfNodes.clear(); int nbfaces = npts; int i = 0; @@ -160,18 +158,15 @@ int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *p i++; for (int k = 0; k < nbnodes; k++) { - setOfNodes.insert(pts[i]); + if ( setOfNodes.insert( pts[i] ).second ) + { + (static_cast< vtkCellLinks * >(this->Links.GetPointer()))->ResizeCellList( pts[i], 1 ); + (static_cast< vtkCellLinks * >(this->Links.GetPointer()))->AddCellReference( cellid, pts[i] ); + } i++; } } - set::iterator it = setOfNodes.begin(); - for (; it != setOfNodes.end(); ++it) - { - this->Links->ResizeCellList(*it, 1); - this->Links->AddCellReference(cellid, *it); - } - return cellid; } @@ -181,25 +176,24 @@ void SMDS_UnstructuredGrid::setSMDS_mesh(SMDS_Mesh *mesh) } void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int newNodeSize, - std::vector& idCellsOldToNew, int newCellSize) + std::vector& idCellsNewToOld, int newCellSize) { - int alreadyCopied = 0; - this->DeleteLinks(); - // --- if newNodeSize, create a new compacted vtkPoints + // IDs of VTK nodes always correspond to SMDS IDs but there can be "holes" in SMDS numeration. + // We compact only if there were holes - if ( newNodeSize ) + int oldNodeSize = this->GetNumberOfPoints(); + bool updateNodes = ( oldNodeSize > newNodeSize ); + if ( true /*updateNodes*/ ) { - // rnv: to fix bug "21125: EDF 1233 SMESH: Degradation of precision in a test case for quadratic conversion" - // using double type for storing coordinates of nodes instead float. + // 21125: EDF 1233 SMESH: Degradation of precision in a test case for quadratic conversion + // Use double type for storing coordinates of nodes instead float. vtkPoints *newPoints = vtkPoints::New(); - newPoints->SetDataType(VTK_DOUBLE); - newPoints->SetNumberOfPoints(newNodeSize); + newPoints->SetDataType( VTK_DOUBLE ); + newPoints->SetNumberOfPoints( newNodeSize ); - int oldNodeSize = idNodesOldToNew.size(); - - int i = 0; + int i = 0, alreadyCopied = 0; while ( i < oldNodeSize ) { // skip a hole if any @@ -215,30 +209,51 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n this->SetPoints(newPoints); newPoints->Delete(); } - this->Points->Squeeze(); + else + { + this->Points->Squeeze(); + this->Points->Modified(); + } - // --- create new compacted Connectivity, Locations and Types + // Compact cells if VTK IDs do not correspond to SMDS IDs or nodes compacted - int oldCellSize = this->Types->GetNumberOfTuples(); + int oldCellSize = this->Types->GetNumberOfTuples(); + bool updateCells = ( updateNodes || newCellSize != oldCellSize ); + for ( int newID = 0, nbIDs = idCellsNewToOld.size(); newID < nbIDs && !updateCells; ++newID ) + updateCells = ( idCellsNewToOld[ newID ] != newID ); - if ( !newNodeSize && oldCellSize == newCellSize ) // no holes in elements + if ( false /*!updateCells*/ ) // no holes in elements { this->Connectivity->Squeeze(); - this->Locations->Squeeze(); + this->CellLocations->Squeeze(); this->Types->Squeeze(); if ( this->FaceLocations ) { this->FaceLocations->Squeeze(); this->Faces->Squeeze(); } - for ( int i = 0; i < oldCellSize; ++i ) - idCellsOldToNew[i] = i; + this->Connectivity->Modified(); return; } + + if ((int) idNodesOldToNew.size() < oldNodeSize ) + { + idNodesOldToNew.reserve( oldNodeSize ); + for ( int i = idNodesOldToNew.size(); i < oldNodeSize; ++i ) + idNodesOldToNew.push_back( i ); + } + + // --- create new compacted Connectivity, Locations and Types + + int newConnectivitySize = this->Connectivity->GetNumberOfConnectivityEntries(); + if ( newCellSize != oldCellSize ) + for ( int i = 0; i < oldCellSize - 1; ++i ) + if ( this->Types->GetValue( i ) == VTK_EMPTY_CELL ) + newConnectivitySize -= this->Connectivity->GetCellSize( i ); + vtkCellArray *newConnectivity = vtkCellArray::New(); newConnectivity->Initialize(); - int oldCellDataSize = this->Connectivity->GetData()->GetSize(); - newConnectivity->Allocate(oldCellDataSize); + newConnectivity->Allocate( newConnectivitySize ); vtkUnsignedCharArray *newTypes = vtkUnsignedCharArray::New(); newTypes->Initialize(); @@ -248,41 +263,24 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n newLocations->Initialize(); newLocations->SetNumberOfValues(newCellSize); - // TODO some polyhedron may be huge (only in some tests) - vtkIdType tmpid[NBMAXNODESINCELL]; - vtkIdType *pointsCell = &tmpid[0]; // --- points id to fill a new cell + std::vector< vtkIdType > pointsCell(1024); // --- points id to fill a new cell - alreadyCopied = 0; - int i = 0; - while ( i < oldCellSize ) - { - // skip a hole if any - while ( i < oldCellSize && this->Types->GetValue(i) == VTK_EMPTY_CELL ) - ++i; - int startBloc = i; - // look for a block end - while ( i < oldCellSize && this->Types->GetValue(i) != VTK_EMPTY_CELL ) - ++i; - int endBloc = i; - if ( endBloc > startBloc ) - copyBloc(newTypes, - idCellsOldToNew, idNodesOldToNew, - newConnectivity, newLocations, - pointsCell, alreadyCopied, - startBloc, endBloc); - } - newConnectivity->Squeeze(); + copyBloc(newTypes, idCellsNewToOld, idNodesOldToNew, + newConnectivity, newLocations, pointsCell ); if (vtkDoubleArray* diameters = vtkDoubleArray::SafeDownCast( vtkDataSet::CellData->GetScalars() )) // Balls { - for (int oldCellID = 0; oldCellID < oldCellSize; oldCellID++) + vtkDoubleArray* newDiameters = vtkDoubleArray::New(); + newDiameters->SetNumberOfComponents(1); + for ( int newCellID = 0; newCellID < newCellSize; newCellID++ ) { - 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 ( newTypes->GetValue( newCellID ) == VTK_POLY_VERTEX ) + { + int oldCellID = idCellsNewToOld[ newCellID ]; + newDiameters->InsertValue( newCellID, diameters->GetValue( oldCellID )); + } + vtkDataSet::CellData->SetScalars( newDiameters ); } } @@ -294,25 +292,23 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n vtkIdTypeArray *newFaces = vtkIdTypeArray::New(); newFaces->Initialize(); newFaces->Allocate(this->Faces->GetSize()); - for (int i = 0; i < oldCellSize; i++) + for ( int newCellID = 0; newCellID < newCellSize; newCellID++ ) { - if (this->Types->GetValue(i) == VTK_EMPTY_CELL) - continue; - int newCellId = idCellsOldToNew[i]; - if (newTypes->GetValue(newCellId) == VTK_POLYHEDRON) + if ( newTypes->GetValue( newCellID ) == VTK_POLYHEDRON ) { - newFaceLocations->InsertNextValue(newFaces->GetMaxId()+1); - int oldFaceLoc = this->FaceLocations->GetValue(i); - int nCellFaces = this->Faces->GetValue(oldFaceLoc++); - newFaces->InsertNextValue(nCellFaces); - for (int n=0; nInsertNextValue( newFaces->GetMaxId()+1 ); + int oldFaceLoc = this->FaceLocations->GetValue( oldCellId ); + int nCellFaces = this->Faces->GetValue( oldFaceLoc++ ); + newFaces->InsertNextValue( nCellFaces ); + for ( int n = 0; n < nCellFaces; n++ ) { - int nptsInFace = this->Faces->GetValue(oldFaceLoc++); - newFaces->InsertNextValue(nptsInFace); - for (int k=0; kFaces->GetValue( oldFaceLoc++ ); + newFaces->InsertNextValue( nptsInFace ); + for ( int k = 0; k < nptsInFace; k++ ) { - int oldpt = this->Faces->GetValue(oldFaceLoc++); - newFaces->InsertNextValue(idNodesOldToNew[oldpt]); + int oldpt = this->Faces->GetValue( oldFaceLoc++ ); + newFaces->InsertNextValue( idNodesOldToNew[ oldpt ]); } } } @@ -323,13 +319,15 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n } newFaceLocations->Squeeze(); newFaces->Squeeze(); - this->SetCells(newTypes, newLocations, newConnectivity, newFaceLocations, newFaces); + this->SetCells( newTypes, newLocations, newConnectivity, newFaceLocations, newFaces ); + this->CellLocations = newLocations; newFaceLocations->Delete(); newFaces->Delete(); } else { - this->SetCells(newTypes, newLocations, newConnectivity, FaceLocations, Faces); + this->SetCells( newTypes, newLocations, newConnectivity, FaceLocations, Faces ); + this->CellLocations = newLocations; } newTypes->Delete(); @@ -338,7 +336,7 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n } void SMDS_UnstructuredGrid::copyNodes(vtkPoints * newPoints, - std::vector& idNodesOldToNew, + std::vector& /*idNodesOldToNew*/, int& alreadyCopied, int start, int end) @@ -349,39 +347,36 @@ void SMDS_UnstructuredGrid::copyNodes(vtkPoints * newPoints, if (nbPoints > 0) { memcpy(target, source, 3 * sizeof(double) * nbPoints); - for (int j = start; j < end; j++) - idNodesOldToNew[j] = alreadyCopied++; // old vtkId --> new vtkId + alreadyCopied += nbPoints; } } -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, + const std::vector& idCellsNewToOld, + const std::vector& idNodesOldToNew, + vtkCellArray* newConnectivity, + vtkIdTypeArray* newLocations, + std::vector& pointsCell) { - for (int j = start; j < end; j++) + for ( size_t iNew = 0; iNew < idCellsNewToOld.size(); iNew++ ) { - newTypes->SetValue(alreadyCopied, this->Types->GetValue(j)); - idCellsOldToNew[j] = alreadyCopied; // old vtkId --> new vtkId - vtkIdType oldLoc = this->Locations->GetValue(j); + int iOld = idCellsNewToOld[ iNew ]; + newTypes->SetValue( iNew, this->Types->GetValue( iOld )); + + vtkIdType oldLoc = ((vtkIdTypeArray *)(this->Connectivity->GetOffsetsArray()))->GetValue( iOld ); vtkIdType nbpts; - vtkIdType *oldPtsCell = 0; - this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell); - assert(nbpts < NBMAXNODESINCELL); - for (int l = 0; l < nbpts; l++) + vtkIdType const *oldPtsCell(nullptr); + this->Connectivity->GetCell( oldLoc+iOld, nbpts, oldPtsCell ); + if ((vtkIdType) pointsCell.size() < nbpts ) + pointsCell.resize( nbpts ); + for ( int l = 0; l < nbpts; l++ ) { int oldval = oldPtsCell[l]; pointsCell[l] = idNodesOldToNew[oldval]; } - /*int newcnt = */newConnectivity->InsertNextCell(nbpts, pointsCell); - int newLoc = newConnectivity->GetInsertLocation(nbpts); - newLocations->SetValue(alreadyCopied, newLoc); - alreadyCopied++; + /*int newcnt = */newConnectivity->InsertNextCell( nbpts, pointsCell.data() ); + int newLoc = newConnectivity->GetInsertLocation( nbpts ); + newLocations->SetValue( iNew, newLoc ); } } @@ -415,7 +410,7 @@ void SMDS_UnstructuredGrid::CleanDownwardConnectivity() * Downward connectivity is no more valid if vtkUnstructuredGrid is modified. * */ -void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges) +void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool /*withEdges*/) { MESSAGE("SMDS_UnstructuredGrid::BuildDownwardConnectivity");CHRONO(2); // TODO calcul partiel sans edges @@ -487,6 +482,7 @@ void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges) GuessSize[VTK_QUADRATIC_HEXAHEDRON] = nbQuadHexa; GuessSize[VTK_TRIQUADRATIC_HEXAHEDRON] = nbQuadHexa; GuessSize[VTK_HEXAGONAL_PRISM] = nbHexPrism; + (void)GuessSize; // unused in Release mode _downArray[VTK_LINE] ->allocate(nbLineGuess); _downArray[VTK_QUADRATIC_EDGE] ->allocate(nbQuadEdgeGuess); @@ -656,7 +652,7 @@ void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges) int connEdgeId = _downArray[vtkEdgeType]->addCell(vtkEdgeId); SMDS_Down1D* downEdge = static_cast (_downArray[vtkEdgeType]); downEdge->setNodes(connEdgeId, vtkEdgeId); - vector vtkIds; + std::vector vtkIds; int nbVtkCells = downEdge->computeVtkCells(connEdgeId, vtkIds); int downFaces[1000]; unsigned char downTypes[1000]; @@ -705,7 +701,7 @@ void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges) // --- check if the edge is already registered by exploration of the faces //CHRONO(41); - vector vtkIds; + std::vector vtkIds; unsigned char vtkEdgeType = edgesWithNodes.elems[iedge].vtkType; int *pts = &edgesWithNodes.elems[iedge].nodeIds[0]; SMDS_Down1D* downEdge = static_cast (_downArray[vtkEdgeType]); @@ -759,7 +755,7 @@ void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges) CHRONOSTOP(23);CHRONO(24); - // compact downward connectivity structure: adjust downward arrays size, replace vector> by a single vector + // compact downward connectivity structure: adjust downward arrays size, replace std::vector> by a single std::vector // 3D first then 2D and last 1D to release memory before edge upCells reorganization, (temporary memory use) for (int vtkType = VTK_QUADRATIC_PYRAMID; vtkType >= 0; vtkType--) @@ -984,8 +980,10 @@ void SMDS_UnstructuredGrid::GetNodeIds(std::set& nodeSet, int downId, unsig void SMDS_UnstructuredGrid::ModifyCellNodes(int vtkVolId, std::map localClonedNodeIds) { vtkIdType npts = 0; - vtkIdType *pts; // will refer to the point id's of the face - this->GetCellPoints(vtkVolId, npts, pts); + vtkIdType const *tmp(nullptr); // will refer to the point id's of the face + vtkIdType *pts; // will refer to the point id's of the face + this->GetCellPoints(vtkVolId, npts, tmp); + pts = const_cast< vtkIdType*>( tmp ); for (int i = 0; i < npts; i++) { if (localClonedNodeIds.count(pts[i])) @@ -1028,7 +1026,7 @@ void SMDS_UnstructuredGrid::BuildLinks() SMDS_CellLinks* links; this->Links = links = SMDS_CellLinks::New(); - this->Links->Allocate(this->GetNumberOfPoints()); + (static_cast< vtkCellLinks *>(this->Links.GetPointer()))->Allocate(this->GetNumberOfPoints()); this->Links->Register(this); links->BuildLinks(this, this->Connectivity,this->GetCellTypesArray() ); this->Links->Delete(); @@ -1047,7 +1045,7 @@ SMDS_CellLinks* SMDS_UnstructuredGrid::GetLinks() { if ( !this->Links ) BuildLinks(); - return static_cast< SMDS_CellLinks* >( this->Links ); + return static_cast< SMDS_CellLinks* >( this->Links.GetPointer() ); } /*! Create a volume (prism or hexahedron) by duplication of a face. @@ -1073,15 +1071,11 @@ SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId, std::map >& nodeQuadDomains) { //MESSAGE("extrudeVolumeFromFace " << vtkVolId); - vector orderedOriginals; - orderedOriginals.clear(); - set::const_iterator it = originalNodes.begin(); - for (; it != originalNodes.end(); ++it) - orderedOriginals.push_back(*it); + std::vector orderedOriginals( originalNodes.begin(), originalNodes.end() ); int dim = 0; int nbNodes = this->getOrderedNodesOfFace(vtkVolId, dim, orderedOriginals); - vector orderedNodes; + std::vector orderedNodes; bool isQuadratic = false; switch (orderedOriginals.size()) @@ -1130,7 +1124,7 @@ SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId, { double *coords = this->GetPoint(oldId); SMDS_MeshNode *newNode = _mesh->AddNode(coords[0], coords[1], coords[2]); - newId = newNode->getVtkId(); + newId = newNode->GetVtkID(); if (! nodeQuadDomains.count(oldId)) { std::map emptyMap; @@ -1214,4 +1208,3 @@ double SMDS_UnstructuredGrid::GetBallDiameter( vtkIdType vtkID ) const return vtkDoubleArray::SafeDownCast( vtkDataSet::CellData->GetScalars() )->GetValue( vtkID ); return 0; } -