X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMDS%2FSMDS_UnstructuredGrid.cxx;h=1f0f799416fe2566e929f07269aa9f914f16352d;hp=99d39e4f08bda5a155263da05df9f94f24be8ddf;hb=eef0bf5cc772a6bdacf6ae2a4d81fdcb9d3a7fdb;hpb=ef59152514df17c64ad01c8abab01331618a1fc4 diff --git a/src/SMDS/SMDS_UnstructuredGrid.cxx b/src/SMDS/SMDS_UnstructuredGrid.cxx index 99d39e4f0..1f0f79941 100644 --- a/src/SMDS/SMDS_UnstructuredGrid.cxx +++ b/src/SMDS/SMDS_UnstructuredGrid.cxx @@ -1,9 +1,9 @@ -// Copyright (C) 2010-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2010-2016 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. +// 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 @@ -24,6 +24,7 @@ #include "SMDS_MeshVolume.hxx" #include "utilities.h" +#include "chrono.hxx" #include #include @@ -39,7 +40,6 @@ using namespace std; SMDS_CellLinks* SMDS_CellLinks::New() { - MESSAGE("SMDS_CellLinks::New"); return new SMDS_CellLinks(); } @@ -53,6 +53,51 @@ void SMDS_CellLinks::ResizeForPoint(vtkIdType vtkID) } } +void SMDS_CellLinks::BuildLinks(vtkDataSet *data, vtkCellArray *Connectivity, vtkUnsignedCharArray* types) +{ + // build links taking into account removed cells + + vtkIdType numPts = data->GetNumberOfPoints(); + vtkIdType j, cellId = 0; + unsigned short *linkLoc; + vtkIdType npts=0; + vtkIdType *pts=0; + vtkIdType loc = Connectivity->GetTraversalLocation(); + + // traverse data to determine number of uses of each point + cellId = 0; + for (Connectivity->InitTraversal(); + Connectivity->GetNextCell(npts,pts); cellId++) + { + if ( types->GetValue( cellId ) != VTK_EMPTY_CELL ) + for (j=0; j < npts; j++) + { + this->IncrementLinkCount(pts[j]); + } + } + + // now allocate storage for the links + this->AllocateLinks(numPts); + this->MaxId = numPts - 1; + + // fill out lists with references to cells + linkLoc = new unsigned short[numPts]; + memset(linkLoc, 0, numPts*sizeof(unsigned short)); + + cellId = 0; + for (Connectivity->InitTraversal(); + Connectivity->GetNextCell(npts,pts); cellId++) + { + if ( types->GetValue( cellId ) != VTK_EMPTY_CELL ) + for (j=0; j < npts; j++) + { + this->InsertCellReference(pts[j], (linkLoc[pts[j]])++, cellId); + } + } + delete [] linkLoc; + Connectivity->SetTraversalLocation(loc); +} + SMDS_CellLinks::SMDS_CellLinks() : vtkCellLinks() { @@ -64,7 +109,6 @@ SMDS_CellLinks::~SMDS_CellLinks() SMDS_UnstructuredGrid* SMDS_UnstructuredGrid::New() { - MESSAGE("SMDS_UnstructuredGrid::New"); return new SMDS_UnstructuredGrid(); } @@ -84,27 +128,23 @@ SMDS_UnstructuredGrid::~SMDS_UnstructuredGrid() unsigned long SMDS_UnstructuredGrid::GetMTime() { unsigned long mtime = vtkUnstructuredGrid::GetMTime(); - MESSAGE("vtkUnstructuredGrid::GetMTime: " << mtime); return mtime; } // OUV_PORTING_VTK6: seems to be useless /* void SMDS_UnstructuredGrid::Update() { - MESSAGE("SMDS_UnstructuredGrid::Update"); return vtkUnstructuredGrid::Update(); } void SMDS_UnstructuredGrid::UpdateInformation() { - MESSAGE("SMDS_UnstructuredGrid::UpdateInformation"); return vtkUnstructuredGrid::UpdateInformation(); } */ vtkPoints* SMDS_UnstructuredGrid::GetPoints() { // TODO erreur incomprehensible de la macro vtk GetPoints apparue avec la version paraview de fin aout 2010 - //MESSAGE("*********************** SMDS_UnstructuredGrid::GetPoints " << this->Points << " " << vtkUnstructuredGrid::GetPoints()); return this->Points; } @@ -115,7 +155,6 @@ int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *p return vtkUnstructuredGrid::InsertNextLinkedCell(type, npts, pts); // --- type = VTK_POLYHEDRON - //MESSAGE("InsertNextLinkedCell VTK_POLYHEDRON"); int cellid = this->InsertNextCell(type, npts, pts); set setOfNodes; @@ -128,7 +167,6 @@ int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *p i++; for (int k = 0; k < nbnodes; k++) { - //MESSAGE(" cell " << cellid << " face " << nf << " node " << pts[i]); setOfNodes.insert(pts[i]); i++; } @@ -137,7 +175,6 @@ int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *p set::iterator it = setOfNodes.begin(); for (; it != setOfNodes.end(); ++it) { - //MESSAGE("reverse link for node " << *it << " cell " << cellid); this->Links->ResizeCellList(*it, 1); this->Links->AddCellReference(cellid, *it); } @@ -154,46 +191,59 @@ void SMDS_UnstructuredGrid::setSMDS_mesh(SMDS_Mesh *mesh) void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int newNodeSize, std::vector& idCellsOldToNew, int newCellSize) { - MESSAGE("------------------------- SMDS_UnstructuredGrid::compactGrid " << newNodeSize << " " << newCellSize);//CHRONO(1); + //MESSAGE("------------------------- compactGrid " << newNodeSize << " " << newCellSize);//CHRONO(1); int alreadyCopied = 0; + this->DeleteLinks(); + // --- if newNodeSize, create a new compacted vtkPoints vtkPoints *newPoints = vtkPoints::New(); newPoints->SetDataType(VTK_DOUBLE); newPoints->SetNumberOfPoints(newNodeSize); if (newNodeSize) - { - MESSAGE("-------------- compactGrid, newNodeSize " << newNodeSize); - // 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. - int oldNodeSize = idNodesOldToNew.size(); + { + // 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. + int oldNodeSize = idNodesOldToNew.size(); - int i = 0; - while ( i < oldNodeSize ) - { - // skip a hole if any - while ( i < oldNodeSize && idNodesOldToNew[i] < 0 ) - ++i; - int startBloc = i; - // look for a block end - while ( i < oldNodeSize && idNodesOldToNew[i] >= 0 ) - ++i; - int endBloc = i; - copyNodes(newPoints, idNodesOldToNew, alreadyCopied, startBloc, endBloc); - } - newPoints->Squeeze(); + int i = 0; + while ( i < oldNodeSize ) + { + // skip a hole if any + while ( i < oldNodeSize && idNodesOldToNew[i] < 0 ) + ++i; + int startBloc = i; + // look for a block end + while ( i < oldNodeSize && idNodesOldToNew[i] >= 0 ) + ++i; + int endBloc = i; + copyNodes(newPoints, idNodesOldToNew, alreadyCopied, startBloc, endBloc); } + newPoints->Squeeze(); + } + + if (1/*newNodeSize*/) + { + this->SetPoints(newPoints); + } + newPoints->Delete(); + // --- create new compacted Connectivity, Locations and Types int oldCellSize = this->Types->GetNumberOfTuples(); + if ( oldCellSize == newCellSize ) + { + for ( int i = 0; i < oldCellSize; ++i ) + idCellsOldToNew[i] = i; + return; + } vtkCellArray *newConnectivity = vtkCellArray::New(); newConnectivity->Initialize(); int oldCellDataSize = this->Connectivity->GetData()->GetSize(); newConnectivity->Allocate(oldCellDataSize); - MESSAGE("oldCellSize="<< oldCellSize << " oldCellDataSize=" << oldCellDataSize); vtkUnsignedCharArray *newTypes = vtkUnsignedCharArray::New(); newTypes->Initialize(); @@ -228,13 +278,6 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n } newConnectivity->Squeeze(); - if (1/*newNodeSize*/) - { - MESSAGE("------- newNodeSize, setPoints"); - this->SetPoints(newPoints); - MESSAGE("NumberOfPoints: " << this->GetNumberOfPoints()); - } - if (vtkDoubleArray* diameters = vtkDoubleArray::SafeDownCast( vtkDataSet::CellData->GetScalars() )) // Balls { @@ -249,62 +292,62 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n } if (this->FaceLocations) + { + vtkIdTypeArray *newFaceLocations = vtkIdTypeArray::New(); + newFaceLocations->Initialize(); + newFaceLocations->Allocate(newTypes->GetSize()); + vtkIdTypeArray *newFaces = vtkIdTypeArray::New(); + newFaces->Initialize(); + newFaces->Allocate(this->Faces->GetSize()); + for (int i = 0; i < oldCellSize; i++) { - vtkIdTypeArray *newFaceLocations = vtkIdTypeArray::New(); - newFaceLocations->Initialize(); - newFaceLocations->Allocate(newTypes->GetSize()); - vtkIdTypeArray *newFaces = vtkIdTypeArray::New(); - newFaces->Initialize(); - newFaces->Allocate(this->Faces->GetSize()); - for (int i = 0; i < oldCellSize; i++) + if (this->Types->GetValue(i) == VTK_EMPTY_CELL) + continue; + int newCellId = idCellsOldToNew[i]; + 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; nTypes->GetValue(i) == VTK_EMPTY_CELL) - continue; - int newCellId = idCellsOldToNew[i]; - 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; nFaces->GetValue(oldFaceLoc++); - newFaces->InsertNextValue(nptsInFace); - for (int k=0; kFaces->GetValue(oldFaceLoc++); - newFaces->InsertNextValue(idNodesOldToNew[oldpt]); - } - } - } - else - { - newFaceLocations->InsertNextValue(-1); - } + int nptsInFace = this->Faces->GetValue(oldFaceLoc++); + newFaces->InsertNextValue(nptsInFace); + for (int k=0; kFaces->GetValue(oldFaceLoc++); + newFaces->InsertNextValue(idNodesOldToNew[oldpt]); + } } - newFaceLocations->Squeeze(); - newFaces->Squeeze(); - this->SetCells(newTypes, newLocations, newConnectivity, newFaceLocations, newFaces); - newFaceLocations->Delete(); - newFaces->Delete(); + } + else + { + newFaceLocations->InsertNextValue(-1); + } } + newFaceLocations->Squeeze(); + newFaces->Squeeze(); + this->SetCells(newTypes, newLocations, newConnectivity, newFaceLocations, newFaces); + newFaceLocations->Delete(); + newFaces->Delete(); + } else { this->SetCells(newTypes, newLocations, newConnectivity, FaceLocations, Faces); } - newPoints->Delete(); newTypes->Delete(); newLocations->Delete(); newConnectivity->Delete(); - this->BuildLinks(); } -void SMDS_UnstructuredGrid::copyNodes(vtkPoints *newPoints, std::vector& idNodesOldToNew, int& alreadyCopied, - int start, int end) +void SMDS_UnstructuredGrid::copyNodes(vtkPoints * newPoints, + std::vector& idNodesOldToNew, + int& alreadyCopied, + int start, + int end) { - MESSAGE("copyNodes " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start); void *target = newPoints->GetVoidPointer(3 * alreadyCopied); void *source = this->Points->GetVoidPointer(3 * start); int nbPoints = end - start; @@ -326,7 +369,6 @@ void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes, int start, int end) { - //MESSAGE("copyBloc " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start); for (int j = start; j < end; j++) { newTypes->SetValue(alreadyCopied, this->Types->GetValue(j)); @@ -336,16 +378,13 @@ void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes, vtkIdType *oldPtsCell = 0; this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell); assert(nbpts < NBMAXNODESINCELL); - //MESSAGE(j << " " << alreadyCopied << " " << (int)this->Types->GetValue(j) << " " << oldLoc << " " << nbpts ); for (int l = 0; l < nbpts; l++) { int oldval = oldPtsCell[l]; pointsCell[l] = idNodesOldToNew[oldval]; - //MESSAGE(" " << oldval << " " << pointsCell[l]); } /*int newcnt = */newConnectivity->InsertNextCell(nbpts, pointsCell); int newLoc = newConnectivity->GetInsertLocation(nbpts); - //MESSAGE(newcnt << " " << newLoc); newLocations->SetValue(alreadyCopied, newLoc); alreadyCopied++; } @@ -353,12 +392,10 @@ void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes, int SMDS_UnstructuredGrid::CellIdToDownId(int vtkCellId) { - if((vtkCellId < 0) || (vtkCellId >= _cellIdToDownId.size())) - { - //MESSAGE("SMDS_UnstructuredGrid::CellIdToDownId structure not up to date: vtkCellId=" - // << vtkCellId << " max="<< _cellIdToDownId.size()); - return -1; - } + if ((vtkCellId < 0) || (vtkCellId >= (int)_cellIdToDownId.size())) + { + return -1; + } return _cellIdToDownId[vtkCellId]; } @@ -370,12 +407,12 @@ void SMDS_UnstructuredGrid::setCellIdToDownId(int vtkCellId, int downId) void SMDS_UnstructuredGrid::CleanDownwardConnectivity() { - for (int i = 0; i < _downArray.size(); i++) - { - if (_downArray[i]) - delete _downArray[i]; - _downArray[i] = 0; - } + for (size_t i = 0; i < _downArray.size(); i++) + { + if (_downArray[i]) + delete _downArray[i]; + _downArray[i] = 0; + } _cellIdToDownId.clear(); } @@ -990,17 +1027,34 @@ void SMDS_UnstructuredGrid::BuildLinks() { // Remove the old links if they are already built if (this->Links) - { + { this->Links->UnRegister(this); - } + } - this->Links = SMDS_CellLinks::New(); + SMDS_CellLinks* links; + this->Links = links = SMDS_CellLinks::New(); this->Links->Allocate(this->GetNumberOfPoints()); this->Links->Register(this); - this->Links->BuildLinks(this, this->Connectivity); + links->BuildLinks(this, this->Connectivity,this->GetCellTypesArray() ); this->Links->Delete(); } +void SMDS_UnstructuredGrid::DeleteLinks() +{ + // Remove the old links if they are already built + if (this->Links) + { + this->Links->UnRegister(this); + this->Links = NULL; + } +} +SMDS_CellLinks* SMDS_UnstructuredGrid::GetLinks() +{ + if ( !this->Links ) + BuildLinks(); + return static_cast< SMDS_CellLinks* >( this->Links ); +} + /*! Create a volume (prism or hexahedron) by duplication of a face. * Designed for use in creation of flat elements separating volume domains. * A face separating two domains is shared by two volume cells. @@ -1015,12 +1069,13 @@ void SMDS_UnstructuredGrid::BuildLinks() * @param nodeDomains: map(original id --> map(domain --> duplicated node id)) * @return ok if success. */ -SMDS_MeshCell* SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId, - int domain1, - int domain2, - std::set& originalNodes, - std::map >& nodeDomains, - std::map >& nodeQuadDomains) +SMDS_MeshCell* +SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId, + int domain1, + int domain2, + std::set& originalNodes, + std::map >& nodeDomains, + std::map >& nodeQuadDomains) { //MESSAGE("extrudeVolumeFromFace " << vtkVolId); vector orderedOriginals; @@ -1036,16 +1091,16 @@ SMDS_MeshCell* SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId, bool isQuadratic = false; switch (orderedOriginals.size()) { - case 3: - if (dim == 2) - isQuadratic = true; - break; - case 6: - case 8: + case 3: + if (dim == 2) isQuadratic = true; - break; - default: - isQuadratic = false; + break; + case 6: + case 8: + isQuadratic = true; + break; + default: + isQuadratic = false; break; } @@ -1081,8 +1136,11 @@ SMDS_MeshCell* SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId, 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; + if (! nodeQuadDomains.count(oldId)) + { + std::map emptyMap; + nodeQuadDomains[oldId] = emptyMap; + } nodeQuadDomains[oldId][dom1_2] = newId; } orderedNodes.push_back(newId);