From a399364c85efef719b8f0f1d1a81fc57a60b4601 Mon Sep 17 00:00:00 2001 From: prascle Date: Thu, 1 Jul 2010 14:46:31 +0000 Subject: [PATCH] PR: downward connectivity --- doc/salome/tui/doxyfile.in | 1 + src/OBJECT/SMESH_vtkPVUpdateSuppressor.cxx | 153 +- src/OBJECT/SMESH_vtkPVUpdateSuppressor.h | 53 +- src/SMDS/Makefile.am | 6 +- src/SMDS/ObjectPool.hxx | 84 +- src/SMDS/SMDS_Downward.cxx | 1889 ++++++++++++++++++++ src/SMDS/SMDS_Downward.hxx | 327 ++++ src/SMDS/SMDS_LinearEdge.cxx | 114 +- src/SMDS/SMDS_LinearEdge.hxx | 37 +- src/SMDS/SMDS_Mesh.cxx | 1 + src/SMDS/SMDS_MeshCell.cxx | 7 +- src/SMDS/SMDS_MeshCell.hxx | 14 +- src/SMDS/SMDS_MeshNodeIDFactory.cxx | 17 +- src/SMDS/SMDS_MeshNodeIDFactory.hxx | 8 +- src/SMDS/SMDS_UnstructuredGrid.cxx | 837 ++++++--- src/SMDS/SMDS_UnstructuredGrid.hxx | 61 +- src/SMDS/SMDS_VtkCellIterator.cxx | 101 +- src/SMDS/SMDS_VtkCellIterator.hxx | 15 +- src/SMDS/SMDS_VtkEdge.cxx | 74 +- src/SMDS/SMDS_VtkFace.cxx | 137 +- src/SMDS/SMDS_VtkVolume.cxx | 215 ++- src/SMDS/SMDS_VtkVolume.hxx | 5 +- src/SMDS/chrono.cxx | 85 + src/SMDS/chrono.hxx | 73 + src/SMESH/memoire.h | 15 +- src/SMESHDS/SMESHDS_Mesh.cxx | 2 +- 26 files changed, 3621 insertions(+), 710 deletions(-) create mode 100644 src/SMDS/SMDS_Downward.cxx create mode 100644 src/SMDS/SMDS_Downward.hxx create mode 100644 src/SMDS/chrono.cxx create mode 100644 src/SMDS/chrono.hxx diff --git a/doc/salome/tui/doxyfile.in b/doc/salome/tui/doxyfile.in index 0eb988674..27fa7ebdc 100755 --- a/doc/salome/tui/doxyfile.in +++ b/doc/salome/tui/doxyfile.in @@ -40,6 +40,7 @@ STRIP_FROM_PATH = @top_srcdir@ @top_builddir@ STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = YES +QT_AUTOBRIEF = YES MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = NO INHERIT_DOCS = YES diff --git a/src/OBJECT/SMESH_vtkPVUpdateSuppressor.cxx b/src/OBJECT/SMESH_vtkPVUpdateSuppressor.cxx index a9fd819dc..bbab763f9 100644 --- a/src/OBJECT/SMESH_vtkPVUpdateSuppressor.cxx +++ b/src/OBJECT/SMESH_vtkPVUpdateSuppressor.cxx @@ -1,17 +1,17 @@ /*========================================================================= - Program: ParaView - Module: $RCSfile$ + Program: ParaView + Module: $RCSfile$ - Copyright (c) Kitware, Inc. - All rights reserved. - See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details. + Copyright (c) Kitware, Inc. + All rights reserved. + See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details. - This software is distributed WITHOUT ANY WARRANTY; without even - the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. See the above copyright notice for more information. + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. -=========================================================================*/ + =========================================================================*/ #include "SMESH_vtkPVUpdateSuppressor.h" #include "vtkAlgorithmOutput.h" @@ -40,8 +40,10 @@ # define vtkMyDebug(x) #endif -vtkCxxRevisionMacro(vtkPVUpdateSuppressor, "$Revision$"); -vtkStandardNewMacro(vtkPVUpdateSuppressor); +vtkCxxRevisionMacro(vtkPVUpdateSuppressor, "$Revision$") +; +vtkStandardNewMacro(vtkPVUpdateSuppressor) +; //---------------------------------------------------------------------------- vtkPVUpdateSuppressor::vtkPVUpdateSuppressor() { @@ -51,16 +53,15 @@ vtkPVUpdateSuppressor::vtkPVUpdateSuppressor() this->UpdateTime = 0.0; this->UpdateTimeInitialized = false; - this->Enabled = 1; -// vtkProcessModule* pm = vtkProcessModule::GetProcessModule(); -// -// if (pm) -// { -// this->UpdateNumberOfPieces = pm->GetNumberOfLocalPartitions(); -// this->UpdatePiece = pm->GetPartitionId(); -// } + // vtkProcessModule* pm = vtkProcessModule::GetProcessModule(); + // + // if (pm) + // { + // this->UpdateNumberOfPieces = pm->GetNumberOfLocalPartitions(); + // this->UpdatePiece = pm->GetPartitionId(); + // } } //---------------------------------------------------------------------------- @@ -74,8 +75,8 @@ void vtkPVUpdateSuppressor::SetUpdateTime(double utime) this->UpdateTimeInitialized = true; if (this->UpdateTime != utime) { - this->Modified(); - this->UpdateTime = utime; + this->Modified(); + this->UpdateTime = utime; } } @@ -84,29 +85,29 @@ void vtkPVUpdateSuppressor::SetEnabled(int enable) { if (this->Enabled == enable) { - return; + return; } this->Enabled = enable; this->Modified(); -// vtkUpdateSuppressorPipeline* executive = -// vtkUpdateSuppressorPipeline::SafeDownCast(this->GetExecutive()); -// if (executive) -// { -// executive->SetEnabled(enable); -// } + // vtkUpdateSuppressorPipeline* executive = + // vtkUpdateSuppressorPipeline::SafeDownCast(this->GetExecutive()); + // if (executive) + // { + // executive->SetEnabled(enable); + // } } //---------------------------------------------------------------------------- void vtkPVUpdateSuppressor::ForceUpdate() -{ +{ // Make sure that output type matches input type this->UpdateInformation(); vtkDataObject *input = this->GetInput(); if (input == 0) { - vtkErrorMacro("No valid input."); - return; + vtkErrorMacro("No valid input."); + return; } vtkDataObject *output = this->GetOutput(); @@ -115,41 +116,38 @@ void vtkPVUpdateSuppressor::ForceUpdate() // Client needs to modify the collection filter because it is not // connected to a pipeline. vtkAlgorithm *source = input->GetProducerPort()->GetProducer(); - if (source && - (source->IsA("vtkMPIMoveData") || - source->IsA("vtkCollectPolyData") || - source->IsA("vtkM2NDuplicate") || - source->IsA("vtkM2NCollect") || - source->IsA("vtkOrderedCompositeDistributor") || - source->IsA("vtkClientServerMoveData"))) + if (source && (source->IsA("vtkMPIMoveData") + || source->IsA("vtkCollectPolyData") || source->IsA("vtkM2NDuplicate") + || source->IsA("vtkM2NCollect") + || source->IsA("vtkOrderedCompositeDistributor") + || source->IsA("vtkClientServerMoveData"))) { - source->Modified(); + source->Modified(); } vtkInformation* info = input->GetPipelineInformation(); - vtkStreamingDemandDrivenPipeline* sddp = - vtkStreamingDemandDrivenPipeline::SafeDownCast( - vtkExecutive::PRODUCER()->GetExecutive(info)); + vtkStreamingDemandDrivenPipeline + * sddp = + vtkStreamingDemandDrivenPipeline::SafeDownCast( + vtkExecutive::PRODUCER()->GetExecutive( + info)); if (sddp) { - sddp->SetUpdateExtent(info, - this->UpdatePiece, - this->UpdateNumberOfPieces, - 0); + sddp->SetUpdateExtent(info, this->UpdatePiece, + this->UpdateNumberOfPieces, 0); } else { - input->SetUpdatePiece(this->UpdatePiece); - input->SetUpdateNumberOfPieces(this->UpdateNumberOfPieces); - input->SetUpdateGhostLevel(0); - } - vtkMyDebug("ForceUpdate "); + input->SetUpdatePiece(this->UpdatePiece); + input->SetUpdateNumberOfPieces(this->UpdateNumberOfPieces); + input->SetUpdateGhostLevel(0); + } vtkMyDebug("ForceUpdate "); if (this->UpdateTimeInitialized) { - info->Set(vtkCompositeDataPipeline::UPDATE_TIME_STEPS(), &this->UpdateTime, 1); - vtkMyDebug(this->UpdateTime); - } - vtkMyDebug(endl); + info->Set(vtkCompositeDataPipeline::UPDATE_TIME_STEPS(), + &this->UpdateTime, 1); + vtkMyDebug(this->UpdateTime); + } vtkMyDebug(endl); input->Update(); // Input may have changed, we obtain the pointer again. @@ -159,7 +157,6 @@ void vtkPVUpdateSuppressor::ForceUpdate() this->PipelineUpdateTime.Modified(); } - //---------------------------------------------------------------------------- vtkExecutive* vtkPVUpdateSuppressor::CreateDefaultExecutive() { @@ -170,35 +167,36 @@ vtkExecutive* vtkPVUpdateSuppressor::CreateDefaultExecutive() //---------------------------------------------------------------------------- int vtkPVUpdateSuppressor::RequestDataObject( - vtkInformation* vtkNotUsed(reqInfo), - vtkInformationVector** inputVector , - vtkInformationVector* outputVector) + vtkInformation* vtkNotUsed(reqInfo), + vtkInformationVector** inputVector, + vtkInformationVector* outputVector) { vtkInformation* inInfo = inputVector[0]->GetInformationObject(0); if (!inInfo) { - return 0; + return 0; } - + vtkDataObject *input = inInfo->Get(vtkDataObject::DATA_OBJECT()); if (input) { - // for each output - for(int i=0; i < this->GetNumberOfOutputPorts(); ++i) - { - vtkInformation* outInfo = outputVector->GetInformationObject(i); - vtkDataObject *output = outInfo->Get(vtkDataObject::DATA_OBJECT()); - - if (!output || !output->IsA(input->GetClassName())) + // for each output + for (int i = 0; i < this->GetNumberOfOutputPorts(); ++i) { - vtkDataObject* newOutput = input->NewInstance(); - newOutput->SetPipelineInformation(outInfo); - newOutput->Delete(); - this->GetOutputPortInformation(i)->Set( - vtkDataObject::DATA_EXTENT_TYPE(), newOutput->GetExtentType()); + vtkInformation* outInfo = outputVector->GetInformationObject(i); + vtkDataObject *output = outInfo->Get(vtkDataObject::DATA_OBJECT()); + + if (!output || !output->IsA(input->GetClassName())) + { + vtkDataObject* newOutput = input->NewInstance(); + newOutput->SetPipelineInformation(outInfo); + newOutput->Delete(); + this->GetOutputPortInformation(i)->Set( + vtkDataObject::DATA_EXTENT_TYPE(), + newOutput->GetExtentType()); + } } - } - return 1; + return 1; } return 0; @@ -223,9 +221,10 @@ int vtkPVUpdateSuppressor::RequestData(vtkInformation* vtkNotUsed(reqInfo), //---------------------------------------------------------------------------- void vtkPVUpdateSuppressor::PrintSelf(ostream& os, vtkIndent indent) { - this->Superclass::PrintSelf(os,indent); + this->Superclass::PrintSelf(os, indent); os << indent << "UpdatePiece: " << this->UpdatePiece << endl; - os << indent << "UpdateNumberOfPieces: " << this->UpdateNumberOfPieces << endl; + os << indent << "UpdateNumberOfPieces: " << this->UpdateNumberOfPieces + << endl; os << indent << "Enabled: " << this->Enabled << endl; os << indent << "UpdateTime: " << this->UpdateTime << endl; } diff --git a/src/OBJECT/SMESH_vtkPVUpdateSuppressor.h b/src/OBJECT/SMESH_vtkPVUpdateSuppressor.h index bf023a45b..4cd0624e7 100644 --- a/src/OBJECT/SMESH_vtkPVUpdateSuppressor.h +++ b/src/OBJECT/SMESH_vtkPVUpdateSuppressor.h @@ -1,17 +1,17 @@ /*========================================================================= - Program: ParaView - Module: $RCSfile$ + Program: ParaView + Module: $RCSfile$ - Copyright (c) Kitware, Inc. - All rights reserved. - See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details. + Copyright (c) Kitware, Inc. + All rights reserved. + See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details. - This software is distributed WITHOUT ANY WARRANTY; without even - the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. See the above copyright notice for more information. + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. -=========================================================================*/ + =========================================================================*/ // .NAME vtkPVUpdateSuppressor - prevents propagation of update // .SECTION Description // vtkPVUpdateSuppressor now uses the vtkProcessModule singleton to set up the @@ -25,10 +25,11 @@ #include "vtkDataObjectAlgorithm.h" -class VTK_EXPORT vtkPVUpdateSuppressor : public vtkDataObjectAlgorithm +class VTK_EXPORT vtkPVUpdateSuppressor: public vtkDataObjectAlgorithm { public: - vtkTypeRevisionMacro(vtkPVUpdateSuppressor,vtkDataObjectAlgorithm); +vtkTypeRevisionMacro(vtkPVUpdateSuppressor,vtkDataObjectAlgorithm) + ; void PrintSelf(ostream& os, vtkIndent indent); // Description: @@ -44,30 +45,37 @@ public: // This causes the filter to ingore the request from the output. // It is here because the user may not have celled update on the output // before calling force update (it is an easy fix). - vtkSetMacro(UpdatePiece, int); - vtkGetMacro(UpdatePiece, int); - vtkSetMacro(UpdateNumberOfPieces, int); - vtkGetMacro(UpdateNumberOfPieces, int); + vtkSetMacro(UpdatePiece, int) + ; + vtkGetMacro(UpdatePiece, int) + ; + vtkSetMacro(UpdateNumberOfPieces, int) + ; + vtkGetMacro(UpdateNumberOfPieces, int) + ; // Description: // Get/Set if the update suppressor is enabled. If the update suppressor // is not enabled, it won't supress any updates. Enabled by default. void SetEnabled(int); - vtkGetMacro(Enabled, int); + vtkGetMacro(Enabled, int) + ; // Description: // Get/Set the update time that is sent up the pipeline. void SetUpdateTime(double utime); - vtkGetMacro(UpdateTime, double); + vtkGetMacro(UpdateTime, double) + ; protected: vtkPVUpdateSuppressor(); ~vtkPVUpdateSuppressor(); - int RequestDataObject(vtkInformation* request, vtkInformationVector **inputVector, - vtkInformationVector *outputVector); + int RequestDataObject(vtkInformation* request, + vtkInformationVector **inputVector, + vtkInformationVector *outputVector); int RequestData(vtkInformation* request, vtkInformationVector **inputVector, - vtkInformationVector *outputVector); + vtkInformationVector *outputVector); int UpdatePiece; int UpdateNumberOfPieces; @@ -79,13 +87,12 @@ protected: vtkTimeStamp PipelineUpdateTime; - // Create a default executive. virtual vtkExecutive* CreateDefaultExecutive(); private: - vtkPVUpdateSuppressor(const vtkPVUpdateSuppressor&); // Not implemented. - void operator=(const vtkPVUpdateSuppressor&); // Not implemented. + vtkPVUpdateSuppressor(const vtkPVUpdateSuppressor&); // Not implemented. + void operator=(const vtkPVUpdateSuppressor&); // Not implemented. }; #endif diff --git a/src/SMDS/Makefile.am b/src/SMDS/Makefile.am index dc6e47408..c4dd2bf11 100644 --- a/src/SMDS/Makefile.am +++ b/src/SMDS/Makefile.am @@ -27,6 +27,7 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am # header files salomeinclude_HEADERS = \ + chrono.hxx \ ObjectPool.hxx \ SMDS_TypeOfPosition.hxx \ SMDSAbs_ElementType.hxx \ @@ -71,6 +72,7 @@ salomeinclude_HEADERS = \ SMESH_SMDS.hxx \ SMDS_MeshInfo.hxx \ SMDS_UnstructuredGrid.hxx \ + SMDS_Downward.hxx \ SMDS_StdIterator.hxx @@ -78,6 +80,7 @@ salomeinclude_HEADERS = \ lib_LTLIBRARIES = libSMDS.la dist_libSMDS_la_SOURCES = \ + chrono.cxx \ SMDS_MeshObject.cxx \ SMDS_MeshElement.cxx \ SMDS_MeshCell.cxx \ @@ -112,7 +115,8 @@ dist_libSMDS_la_SOURCES = \ SMDS_QuadraticEdge.cxx \ SMDS_QuadraticFaceOfNodes.cxx \ SMDS_QuadraticVolumeOfNodes.cxx \ - SMDS_UnstructuredGrid.cxx + SMDS_UnstructuredGrid.cxx \ + SMDS_Downward.cxx # additionnal information to compil and link file libSMDS_la_CPPFLAGS = \ diff --git a/src/SMDS/ObjectPool.hxx b/src/SMDS/ObjectPool.hxx index d800bc4ee..6e2fc1d2a 100644 --- a/src/SMDS/ObjectPool.hxx +++ b/src/SMDS/ObjectPool.hxx @@ -19,10 +19,10 @@ private: { for (int i = _nextFree; i < _maxAvail; i++) if (_freeList[i] == true) - { - return i; - break; - } + { + return i; + break; + } return _maxAvail; } @@ -60,21 +60,21 @@ public: X *obj = 0; _nextFree = getNextFree(); if (_nextFree == _maxAvail) - { - X* newChunk = new X[_chunkSize]; - _chunkList.push_back(newChunk); - _freeList.insert(_freeList.end(), _chunkSize, true); - _maxAvail += _chunkSize; - _freeList[_nextFree] = false; - obj = newChunk; // &newChunk[0]; - } + { + X* newChunk = new X[_chunkSize]; + _chunkList.push_back(newChunk); + _freeList.insert(_freeList.end(), _chunkSize, true); + _maxAvail += _chunkSize; + _freeList[_nextFree] = false; + obj = newChunk; // &newChunk[0]; + } else - { - int chunkId = _nextFree / _chunkSize; - int rank = _nextFree - chunkId * _chunkSize; - _freeList[_nextFree] = false; - obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank]; - } + { + int chunkId = _nextFree / _chunkSize; + int rank = _nextFree - chunkId * _chunkSize; + _freeList[_nextFree] = false; + obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank]; + } //obj->init(); return obj; } @@ -83,32 +83,32 @@ public: { long adrobj = (long) (obj); for (int i = 0; i < _chunkList.size(); i++) - { - X* chunk = _chunkList[i]; - long adrmin = (long) (chunk); - if (adrobj < adrmin) - continue; - long adrmax = (long) (chunk + _chunkSize); - if (adrobj >= adrmax) - continue; - int rank = (adrobj - adrmin) / sizeof(X); - int toFree = i * _chunkSize + rank; - _freeList[toFree] = true; - if (toFree < _nextFree) - _nextFree = toFree; - //obj->clean(); - //checkDelete(i); compactage non fait - break; - } + { + X* chunk = _chunkList[i]; + long adrmin = (long) (chunk); + if (adrobj < adrmin) + continue; + long adrmax = (long) (chunk + _chunkSize); + if (adrobj >= adrmax) + continue; + int rank = (adrobj - adrmin) / sizeof(X); + int toFree = i * _chunkSize + rank; + _freeList[toFree] = true; + if (toFree < _nextFree) + _nextFree = toFree; + //obj->clean(); + //checkDelete(i); compactage non fait + break; + } } -// void destroy(int toFree) -// { -// // no control 0<= toFree < _freeList.size() -// _freeList[toFree] = true; -// if (toFree < _nextFree) -// _nextFree = toFree; -// } + // void destroy(int toFree) + // { + // // no control 0<= toFree < _freeList.size() + // _freeList[toFree] = true; + // if (toFree < _nextFree) + // _nextFree = toFree; + // } }; diff --git a/src/SMDS/SMDS_Downward.cxx b/src/SMDS/SMDS_Downward.cxx new file mode 100644 index 000000000..561b10b20 --- /dev/null +++ b/src/SMDS/SMDS_Downward.cxx @@ -0,0 +1,1889 @@ +/* + * SMDS_Downward.cxx + * + * Created on: 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) +{ + 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()) + { + _cellDimension.resize(VTK_QUADRATIC_PYRAMID + 1, 0); + _cellDimension[VTK_LINE] = 1; + _cellDimension[VTK_QUADRATIC_EDGE] = 1; + _cellDimension[VTK_TRIANGLE] = 2; + _cellDimension[VTK_QUADRATIC_TRIANGLE] = 2; + _cellDimension[VTK_QUAD] = 2; + _cellDimension[VTK_QUADRATIC_QUAD] = 2; + _cellDimension[VTK_TETRA] = 3; + _cellDimension[VTK_QUADRATIC_TETRA] = 3; + _cellDimension[VTK_HEXAHEDRON] = 3; + _cellDimension[VTK_QUADRATIC_HEXAHEDRON] = 3; + _cellDimension[VTK_WEDGE] = 3; + _cellDimension[VTK_QUADRATIC_WEDGE] = 3; + _cellDimension[VTK_PYRAMID] = 3; + _cellDimension[VTK_QUADRATIC_PYRAMID] = 3; + } +} + +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]]; +} + +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[100]; + int cellCnt[100]; + 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<100); + 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 + { + 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]; +} + +/*! 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[100]; + int cellCnt[100]; + 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<100); + 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; +} + +int SMDS_Down3D::FindFaceByNodes(int cellId, ElemByNodesType& faceByNodes) +{ + int *faces = &_cellIds[_nbDownCells * cellId]; + int faceNodeSet[10]; + int npoints = 0; + + for (int i = 0; i < _nbDownCells; i++) + { + if ((faces[i] >= 0) && (faceByNodes.vtkType == _cellTypes[i])) + { + if (npoints == 0) + { + for (int j = 0; j < faceByNodes.nbNodes; j++) + faceNodeSet[j] = faceByNodes.nodeIds[j]; + 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 *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_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::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::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[7]; + facesWithNodes.elems[1].nodeIds[5] = nodes[8]; + 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[7]; + facesWithNodes.elems[2].nodeIds[5] = nodes[9]; + 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[8]; + facesWithNodes.elems[3].nodeIds[5] = nodes[9]; + 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::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::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[9]; + facesWithNodes.elems[1].nodeIds[5] = nodes[10]; + 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[10]; + facesWithNodes.elems[2].nodeIds[5] = nodes[11]; + 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[11]; + facesWithNodes.elems[3].nodeIds[5] = nodes[12]; + 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::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 < 2; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + else + { + //ASSERT(aType == VTK_TRIANGLE); + for (int i = 2; 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::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 < 2; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + else + { + //ASSERT(aType == VTK_QUADRATIC_TRIANGLE); + for (int i = 2; 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::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::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; +} + +// --------------------------------------------------------------------------- + diff --git a/src/SMDS/SMDS_Downward.hxx b/src/SMDS/SMDS_Downward.hxx new file mode 100644 index 000000000..fd4eca020 --- /dev/null +++ b/src/SMDS/SMDS_Downward.hxx @@ -0,0 +1,327 @@ +/* + * SMDS_Downward.hxx + * + * Created on: Jun 3, 2010 + * Author: prascle + */ + +#ifndef SMDS_DOWNWARD_HXX_ +#define SMDS_DOWNWARD_HXX_ + +#include "SMDS_UnstructuredGrid.hxx" + +#include +#include + +typedef struct +{ + int nodeIds[8]; //!< max number of nodes in a face or edge: quad quad = 8 + int nbNodes; + unsigned char vtkType; +} ElemByNodesType; // TODO resize for polyhedrons + +typedef struct +{ + ElemByNodesType elems[6]; //!< max number of faces in a volume or edges in a face : hexahedron = 6 + int nbElems; +} ListElemByNodesType; // TODO resize for polyhedrons + +class SMDS_Downward +{ + friend class SMDS_UnstructuredGrid; + friend class SMDS_Down2D; + friend class SMDS_Down3D; +public: + virtual int getNumberOfDownCells(int cellId); + virtual const int* getDownCells(int cellId); + virtual const unsigned char* getDownTypes(int cellId); + virtual int getNumberOfUpCells(int cellId) = 0; + virtual const int* getUpCells(int cellId) = 0; + virtual const unsigned char* getUpTypes(int cellId) = 0; + int getVtkCellId(int cellId) + { + return _vtkCellIds[cellId]; + } + int getMaxId() + { + return _maxId; + } + static int getCellDimension(unsigned char cellType); +protected: + SMDS_Downward(SMDS_UnstructuredGrid *grid, int nbDownCells); + ~SMDS_Downward(); + int addCell(int vtkId = -1); + virtual void initCell(int cellId); + virtual void allocate(int nbElems) = 0; + virtual void compactStorage() = 0; + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's + virtual void addUpCell(int cellId, int upCellId, unsigned char aType); //!< Id's are downward connectivity id's + virtual int getNodeSet(int cellId, int* nodeSet); + + SMDS_UnstructuredGrid* _grid; + int _maxId; + int _nbDownCells; //!< the same number for all cells of a derived class + std::vector _cellIds; //!< growing size: all the down cell id's, size = _maxId * _nbDownCells + std::vector _vtkCellIds; //!< growing size: size = _maxId, either vtkId or -1 + std::vector _cellTypes; //!< fixed size: the same vector for all cells of a derived class + + static std::vector _cellDimension; //!< conversion table: type --> dimension +}; + +class SMDS_Down1D: public SMDS_Downward +{ + friend class SMDS_UnstructuredGrid; +public: + virtual int getNumberOfUpCells(int cellId); + virtual const int* getUpCells(int cellId); + virtual const unsigned char* getUpTypes(int cellId); +protected: + SMDS_Down1D(SMDS_UnstructuredGrid *grid, int nbDownCells); + ~SMDS_Down1D(); + virtual void initCell(int cellId); + virtual void allocate(int nbElems); + virtual void compactStorage(); + virtual void addUpCell(int cellId, int upCellId, unsigned char aType); //!< Id's are downward connectivity id's + virtual int getNodeSet(int cellId, int* nodeSet); + void setNodes(int cellId, int vtkId); + void setNodes(int cellId, const int* nodeIds); + int computeVtkCells(int cellId, std::vector& vtkIds); + int computeVtkCells(int* pts, std::vector& vtkIds); + int computeFaces(int cellId, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes); + int computeFaces(int* pts, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes); + + std::vector > _upCellIdsVector; //!< the number of faces sharing an edge is not known + std::vector > _upCellTypesVector; //!< the number of faces sharing an edge is not known + std::vector _upCellIds; //!< compacted storage after connectivity calculation + std::vector _upCellTypes; //!< compacted storage after connectivity calculation + std::vector _upCellIndex; //!< compacted storage after connectivity calculation +}; + +class SMDS_Down2D: public SMDS_Downward +{ + friend class SMDS_UnstructuredGrid; + friend class SMDS_Down1D; +public: + virtual int getNumberOfUpCells(int cellId); + virtual const int* getUpCells(int cellId); + virtual const unsigned char* getUpTypes(int cellId); +protected: + SMDS_Down2D(SMDS_UnstructuredGrid *grid, int nbDownCells); + ~SMDS_Down2D(); + virtual void allocate(int nbElems); + virtual void compactStorage(); + virtual void addUpCell(int cellId, int upCellId, unsigned char aType); + virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) = 0; + virtual int getNodeSet(int cellId, int* nodeSet); + int computeVolumeIds(int cellId, int* ids); + int computeVolumeIds(ElemByNodesType& faceByNodes, int* ids); + int computeVolumeIdsFromNodesFace(int* nodes, int nbNodes, int* ids); + void setTempNodes(int cellId, int vtkId); + void setTempNodes(int cellId, ElemByNodesType& faceByNodes); + bool isInFace(int cellId, int *pts, int npts); + int FindEdgeByNodes(int cellId, ElemByNodesType& edgeByNodes); + + std::vector _upCellIds; //!< 2 volumes max. per face + std::vector _upCellTypes; //!< 2 volume types per face + std::vector _tempNodes; //!< temporary storage of nodes, until downward connectivity completion + int _nbNodes; //!< number of nodes in a face +}; + +class SMDS_Down3D: public SMDS_Downward +{ + friend class SMDS_UnstructuredGrid; +public: + virtual int getNumberOfUpCells(int cellId); + virtual const int* getUpCells(int cellId); + virtual const unsigned char* getUpTypes(int cellId); +protected: + SMDS_Down3D(SMDS_UnstructuredGrid *grid, int nbDownCells); + ~SMDS_Down3D(); + virtual void allocate(int nbElems); + virtual void compactStorage(); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) = 0; + int FindFaceByNodes(int cellId, ElemByNodesType& faceByNodes); +}; + +class SMDS_DownEdge: public SMDS_Down1D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownEdge(SMDS_UnstructuredGrid *grid); + ~SMDS_DownEdge(); +}; + +class SMDS_DownQuadEdge: public SMDS_Down1D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownQuadEdge(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadEdge(); +}; + +class SMDS_DownTriangle: public SMDS_Down2D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownTriangle(SMDS_UnstructuredGrid *grid); + ~SMDS_DownTriangle(); + virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's +}; + +class SMDS_DownQuadTriangle: public SMDS_Down2D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownQuadTriangle(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadTriangle(); + virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's +}; + +class SMDS_DownQuadrangle: public SMDS_Down2D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownQuadrangle(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadrangle(); + virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's +}; + +class SMDS_DownQuadQuadrangle: public SMDS_Down2D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownQuadQuadrangle(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadQuadrangle(); + virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's +}; + +//class SMDS_DownPolygon: public SMDS_Down2D +//{ +//public: +// SMDS_DownPolygon(SMDS_UnstructuredGrid *grid); +// ~SMDS_DownPolygon(); +//protected: +//}; + +//class SMDS_DownQuadPolygon: public SMDS_Down2D +//{ +//public: +// SMDS_DownQuadPolygon(SMDS_UnstructuredGrid *grid); +// ~SMDS_DownQuadPolygon(); +//protected: +//}; + +class SMDS_DownTetra: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownTetra(SMDS_UnstructuredGrid *grid); + ~SMDS_DownTetra(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownQuadTetra: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownQuadTetra(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadTetra(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownPyramid: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownPyramid(SMDS_UnstructuredGrid *grid); + ~SMDS_DownPyramid(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownQuadPyramid: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownQuadPyramid(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadPyramid(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownPenta: public SMDS_Down3D +{ +public: + SMDS_DownPenta(SMDS_UnstructuredGrid *grid); + ~SMDS_DownPenta(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +protected: +}; + +class SMDS_DownQuadPenta: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownQuadPenta(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadPenta(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownHexa: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownHexa(SMDS_UnstructuredGrid *grid); + ~SMDS_DownHexa(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownQuadHexa: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownQuadHexa(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadHexa(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +//class SMDS_DownPolyhedra: public SMDS_Down3D +//{ +//public: +// SMDS_DownPolyhedra(SMDS_UnstructuredGrid *grid); +// ~SMDS_DownPolyhedra(); +//protected: +//}; + +//class SMDS_DownQuadPolyhedra: public SMDS_Down3D +//{ +//public: +// SMDS_DownQuadPolyhedra(SMDS_UnstructuredGrid *grid); +// ~SMDS_DownQuadPolyhedra(); +//protected: +//}; + +#endif /* SMDS_DOWNWARD_HXX_ */ diff --git a/src/SMDS/SMDS_LinearEdge.cxx b/src/SMDS/SMDS_LinearEdge.cxx index 017f74cfa..21d7d84b0 100644 --- a/src/SMDS/SMDS_LinearEdge.cxx +++ b/src/SMDS/SMDS_LinearEdge.cxx @@ -41,11 +41,11 @@ using namespace std; //======================================================================= SMDS_LinearEdge::SMDS_LinearEdge(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2) -{ - //MESSAGE("SMDS_LinearEdge " << GetID()); - myNodes[0]=node1; - myNodes[1]=node2; + const SMDS_MeshNode * node2) +{ + //MESSAGE("SMDS_LinearEdge " << GetID()); + myNodes[0] = node1; + myNodes[1] = node2; } //======================================================================= @@ -55,80 +55,88 @@ SMDS_LinearEdge::SMDS_LinearEdge(const SMDS_MeshNode * node1, void SMDS_LinearEdge::Print(ostream & OS) const { - OS << "edge <" << GetID() << "> : (" << myNodes[0] << " , " << myNodes[1] << - ") " << endl; + OS << "edge <" << GetID() << "> : (" << myNodes[0] << " , " << myNodes[1] + << ") " << endl; } int SMDS_LinearEdge::NbNodes() const { - return 2; + return 2; } int SMDS_LinearEdge::NbEdges() const { - return 1; + return 1; } -class SMDS_LinearEdge_MyNodeIterator:public SMDS_ElemIterator +class SMDS_LinearEdge_MyNodeIterator: public SMDS_ElemIterator { - const SMDS_MeshNode *const* myNodes; + const SMDS_MeshNode * const * myNodes; int myIndex; - public: - SMDS_LinearEdge_MyNodeIterator(const SMDS_MeshNode * const* nodes): - myNodes(nodes),myIndex(0) {} +public: + SMDS_LinearEdge_MyNodeIterator(const SMDS_MeshNode * const * nodes) : + myNodes(nodes), myIndex(0) + { + } bool more() { - return myIndex<2; + return myIndex < 2; } const SMDS_MeshElement* next() { myIndex++; - return myNodes[myIndex-1]; + return myNodes[myIndex - 1]; } }; -SMDS_ElemIteratorPtr SMDS_LinearEdge:: - elementsIterator(SMDSAbs_ElementType type) const +SMDS_ElemIteratorPtr SMDS_LinearEdge::elementsIterator(SMDSAbs_ElementType type) const { - switch(type) + switch (type) { - case SMDSAbs_Edge: - return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge); - case SMDSAbs_Node: - return SMDS_ElemIteratorPtr(new SMDS_LinearEdge_MyNodeIterator(myNodes)); - default: - return SMDS_ElemIteratorPtr - (new SMDS_IteratorOfElements - (this,type, SMDS_ElemIteratorPtr(new SMDS_LinearEdge_MyNodeIterator(myNodes)))); + case SMDSAbs_Edge: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_LinearEdge_MyNodeIterator(myNodes)); + default: + return SMDS_ElemIteratorPtr( + new SMDS_IteratorOfElements( + this, + type, + SMDS_ElemIteratorPtr( + new SMDS_LinearEdge_MyNodeIterator( + myNodes)))); } } bool operator<(const SMDS_LinearEdge & e1, const SMDS_LinearEdge & e2) { - int id11=e1.myNodes[0]->GetID(); - int id21=e2.myNodes[0]->GetID(); - int id12=e1.myNodes[1]->GetID(); - int id22=e2.myNodes[1]->GetID(); - int tmp; - - if(id11>=id12) - { - tmp=id11; - id11=id12; - id12=tmp; - } - if(id21>=id22) - { - tmp=id21; - id21=id22; - id22=tmp; - } - - if(id11GetID(); + int id21 = e2.myNodes[0]->GetID(); + int id12 = e1.myNodes[1]->GetID(); + int id22 = e2.myNodes[1]->GetID(); + int tmp; + + if (id11 >= id12) + { + tmp = id11; + id11 = id12; + id12 = tmp; + } + if (id21 >= id22) + { + tmp = id21; + id21 = id22; + id22 = tmp; + } + + if (id11 < id21) + return true; + else if (id11 == id21) + return (id21 < id22); + else + return false; } /*! @@ -138,7 +146,7 @@ bool operator<(const SMDS_LinearEdge & e1, const SMDS_LinearEdge & e2) */ const SMDS_MeshNode* SMDS_LinearEdge::GetNode(const int ind) const { - return myNodes[ ind ]; + return myNodes[ind]; } //======================================================================= @@ -147,9 +155,9 @@ const SMDS_MeshNode* SMDS_LinearEdge::GetNode(const int ind) const //======================================================================= bool SMDS_LinearEdge::ChangeNodes(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2) + const SMDS_MeshNode * node2) { - myNodes[0]=node1; - myNodes[1]=node2; + myNodes[0] = node1; + myNodes[1] = node2; return true; } diff --git a/src/SMDS/SMDS_LinearEdge.hxx b/src/SMDS/SMDS_LinearEdge.hxx index a9f89c9c9..f8c702506 100644 --- a/src/SMDS/SMDS_LinearEdge.hxx +++ b/src/SMDS/SMDS_LinearEdge.hxx @@ -31,34 +31,35 @@ #include "SMDS_MeshEdge.hxx" #include -class SMDS_EXPORT SMDS_LinearEdge:public SMDS_MeshEdge +class SMDS_EXPORT SMDS_LinearEdge: public SMDS_MeshEdge { - public: - SMDS_LinearEdge(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2); - bool ChangeNodes(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2); - void Print(std::ostream & OS) const; +public: + SMDS_LinearEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2); + bool ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2); + void Print(std::ostream & OS) const; - virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Edge; } - int NbNodes() const; - int NbEdges() const; - friend bool operator<(const SMDS_LinearEdge& e1, const SMDS_LinearEdge& e2); + virtual SMDSAbs_EntityType GetEntityType() const + { + return SMDSEntity_Edge; + } + int NbNodes() const; + int NbEdges() const; + friend bool operator<(const SMDS_LinearEdge& e1, const SMDS_LinearEdge& e2); /*! * \brief Return node by its index - * \param ind - node index - * \retval const SMDS_MeshNode* - the node + * \param ind - node index + * \retval const SMDS_MeshNode* - the node */ virtual const SMDS_MeshNode* GetNode(const int ind) const; - protected: - SMDS_ElemIteratorPtr - elementsIterator(SMDSAbs_ElementType type) const; +protected: + SMDS_ElemIteratorPtr + elementsIterator(SMDSAbs_ElementType type) const; - protected: - const SMDS_MeshNode* myNodes[3]; +protected: + const SMDS_MeshNode* myNodes[3]; }; #endif diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index bb53cb6b6..2c2aa6ed6 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -148,6 +148,7 @@ SMDS_Mesh::SMDS_Mesh() myIDElements.clear(); myVtkIndex.clear(); myGrid = SMDS_UnstructuredGrid::New(); + myGrid->setSMDS_mesh(this); myGrid->Initialize(); myGrid->Allocate(); vtkPoints* points = vtkPoints::New(); diff --git a/src/SMDS/SMDS_MeshCell.cxx b/src/SMDS/SMDS_MeshCell.cxx index 2feea3d18..4cfd2a0a7 100644 --- a/src/SMDS/SMDS_MeshCell.cxx +++ b/src/SMDS/SMDS_MeshCell.cxx @@ -1,4 +1,3 @@ - #include "SMDS_MeshCell.hxx" #include "utilities.h" @@ -6,12 +5,12 @@ using namespace std; int SMDS_MeshCell::nbCells = 0; - -SMDS_MeshCell::SMDS_MeshCell() : SMDS_MeshElement(-1) +SMDS_MeshCell::SMDS_MeshCell() : + SMDS_MeshElement(-1) { nbCells++; myVtkID = -1; -}; +} SMDS_MeshCell::~SMDS_MeshCell() { diff --git a/src/SMDS/SMDS_MeshCell.hxx b/src/SMDS/SMDS_MeshCell.hxx index fb291d1ee..96108c095 100644 --- a/src/SMDS/SMDS_MeshCell.hxx +++ b/src/SMDS/SMDS_MeshCell.hxx @@ -7,13 +7,21 @@ * \brief Base class for all cells */ -class SMDS_EXPORT SMDS_MeshCell:public SMDS_MeshElement +class SMDS_EXPORT SMDS_MeshCell: public SMDS_MeshElement { public: SMDS_MeshCell(); virtual ~SMDS_MeshCell(); - inline void setVtkId(int vtkId) { myVtkID = vtkId; }; - inline int getVtkId() const {return myVtkID; }; + inline void setVtkId(int vtkId) + { + myVtkID = vtkId; + } + + inline int getVtkId() const + { + return myVtkID; + } + static int nbCells; protected: int myVtkID; diff --git a/src/SMDS/SMDS_MeshNodeIDFactory.cxx b/src/SMDS/SMDS_MeshNodeIDFactory.cxx index 5eb2d6a86..34259a2e2 100644 --- a/src/SMDS/SMDS_MeshNodeIDFactory.cxx +++ b/src/SMDS/SMDS_MeshNodeIDFactory.cxx @@ -41,9 +41,8 @@ using namespace std; //function : SMDS_MeshNodeIDFactory //purpose : //======================================================================= -SMDS_MeshNodeIDFactory::SMDS_MeshNodeIDFactory(): - SMDS_MeshIDFactory(), - myMin(0), myMax(0) +SMDS_MeshNodeIDFactory::SMDS_MeshNodeIDFactory() : + SMDS_MeshIDFactory(), myMin(0), myMax(0) { } @@ -53,7 +52,7 @@ SMDS_MeshNodeIDFactory::SMDS_MeshNodeIDFactory(): //======================================================================= bool SMDS_MeshNodeIDFactory::BindID(int ID, SMDS_MeshElement * elem) { - updateMinMax (ID); + updateMinMax(ID); return true; } @@ -63,10 +62,10 @@ bool SMDS_MeshNodeIDFactory::BindID(int ID, SMDS_MeshElement * elem) //======================================================================= SMDS_MeshElement* SMDS_MeshNodeIDFactory::MeshElement(int ID) { - if ((ID<0) || (ID>myMax)) + if ((ID < 0) || (ID > myMax)) return NULL; const SMDS_MeshElement* elem = GetMesh()->FindNode(ID); - return (SMDS_MeshElement*)(elem); + return (SMDS_MeshElement*) (elem); } //======================================================================= @@ -77,9 +76,9 @@ void SMDS_MeshNodeIDFactory::ReleaseID(const int ID) { SMDS_MeshIDFactory::ReleaseID(ID); if (ID == myMax) - myMax = 0; // --- force updateMinMax + myMax = 0; // --- force updateMinMax if (ID == myMin) - myMax = 0; // --- force updateMinMax + myMax = 0; // --- force updateMinMax } //======================================================================= @@ -120,7 +119,7 @@ void SMDS_MeshNodeIDFactory::updateMinMax() const SMDS_ElemIteratorPtr SMDS_MeshNodeIDFactory::elementsIterator() const { - return myMesh->elementsIterator(SMDSAbs_Node); + return myMesh->elementsIterator(SMDSAbs_Node); } void SMDS_MeshNodeIDFactory::Clear() diff --git a/src/SMDS/SMDS_MeshNodeIDFactory.hxx b/src/SMDS/SMDS_MeshNodeIDFactory.hxx index 941ce66d0..4caadf465 100644 --- a/src/SMDS/SMDS_MeshNodeIDFactory.hxx +++ b/src/SMDS/SMDS_MeshNodeIDFactory.hxx @@ -35,7 +35,7 @@ class SMDS_MeshElement; -class SMDS_EXPORT SMDS_MeshNodeIDFactory:public SMDS_MeshIDFactory +class SMDS_EXPORT SMDS_MeshNodeIDFactory: public SMDS_MeshIDFactory { public: SMDS_MeshNodeIDFactory(); @@ -51,8 +51,10 @@ protected: void updateMinMax() const; void updateMinMax(int id) const { - if (id > myMax) myMax = id; - if (id < myMin) myMin = id; + if (id > myMax) + myMax = id; + if (id < myMin) + myMin = id; } mutable int myMin, myMax; diff --git a/src/SMDS/SMDS_UnstructuredGrid.cxx b/src/SMDS/SMDS_UnstructuredGrid.cxx index eef966593..4713a19a8 100644 --- a/src/SMDS/SMDS_UnstructuredGrid.cxx +++ b/src/SMDS/SMDS_UnstructuredGrid.cxx @@ -1,6 +1,9 @@ - - +#define CHRONODEF #include "SMDS_UnstructuredGrid.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDS_MeshInfo.hxx" +#include "SMDS_Downward.hxx" + #include "utilities.h" #include @@ -14,261 +17,651 @@ using namespace std; SMDS_UnstructuredGrid* SMDS_UnstructuredGrid::New() { - MESSAGE("SMDS_UnstructuredGrid::New"); - return new SMDS_UnstructuredGrid(); + MESSAGE("SMDS_UnstructuredGrid::New"); + return new SMDS_UnstructuredGrid(); } -SMDS_UnstructuredGrid::SMDS_UnstructuredGrid() : vtkUnstructuredGrid() +SMDS_UnstructuredGrid::SMDS_UnstructuredGrid() : + vtkUnstructuredGrid() { + _cellIdToDownId.clear(); + _downTypes.clear(); + _downArray.clear(); + _mesh = 0; + _counters = new counters(100); } SMDS_UnstructuredGrid::~SMDS_UnstructuredGrid() { } - unsigned long SMDS_UnstructuredGrid::GetMTime() { - unsigned long mtime = vtkUnstructuredGrid::GetMTime(); - MESSAGE("vtkUnstructuredGrid::GetMTime: " << mtime); - return mtime; + unsigned long mtime = vtkUnstructuredGrid::GetMTime(); + MESSAGE("vtkUnstructuredGrid::GetMTime: " << mtime); + return mtime; } void SMDS_UnstructuredGrid::Update() { - MESSAGE("SMDS_UnstructuredGrid::Update"); - return vtkUnstructuredGrid::Update(); + MESSAGE("SMDS_UnstructuredGrid::Update"); + return vtkUnstructuredGrid::Update(); } void SMDS_UnstructuredGrid::UpdateInformation() { - MESSAGE("SMDS_UnstructuredGrid::UpdateInformation"); - return vtkUnstructuredGrid::UpdateInformation(); + MESSAGE("SMDS_UnstructuredGrid::UpdateInformation"); + return vtkUnstructuredGrid::UpdateInformation(); +} + +void SMDS_UnstructuredGrid::setSMDS_mesh(SMDS_Mesh *mesh) +{ + _mesh = mesh; } void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int newNodeSize, - std::vector& idCellsOldToNew, int newCellSize) + std::vector& idCellsOldToNew, int newCellSize) { - MESSAGE("------------------------- SMDS_UnstructuredGrid::compactGrid " << newNodeSize << " " << newCellSize); - - int startHole = 0; - int endHole = 0; - int startBloc = 0; - int endBloc = 0; - int alreadyCopied = 0; - int holes = 0; - - typedef enum {lookHoleStart, lookHoleEnd, lookBlocEnd} enumState; - enumState compactState = lookHoleStart; - -// if (this->Links) -// { -// this->Links->UnRegister(this); -// this->Links = 0; -// } - - // --- if newNodeSize, create a new compacted vtkPoints - - vtkPoints *newPoints = 0; - if (newNodeSize) - { - MESSAGE("-------------- compactGrid, newNodeSize " << newNodeSize); - newPoints = vtkPoints::New(); - newPoints->Initialize(); - newPoints->Allocate(newNodeSize); - newPoints->SetNumberOfPoints(newNodeSize); - int oldNodeSize = idNodesOldToNew.size(); - - for (int i=0; i< oldNodeSize; i++) - { - switch(compactState) - { - case lookHoleStart: - if (idNodesOldToNew[i] < 0) - { - MESSAGE("-------------- newNodeSize, startHole " << i << " " << oldNodeSize); - startHole = i; - if (!alreadyCopied) // copy the first bloc - { - MESSAGE("--------- copy first nodes before hole " << i << " " << oldNodeSize); - copyNodes(newPoints, idNodesOldToNew, alreadyCopied, 0, startHole); - } - compactState = lookHoleEnd; - } - break; - case lookHoleEnd: - if (idNodesOldToNew[i] >= 0) - { - MESSAGE("-------------- newNodeSize, endHole " << i << " " << oldNodeSize); - endHole = i; - startBloc = i; - compactState = lookBlocEnd; - } - break; - case lookBlocEnd: - if (idNodesOldToNew[i] < 0) endBloc = i; // see nbPoints below - else if (i == (oldNodeSize-1)) endBloc = i+1; - if (endBloc) - { - MESSAGE("-------------- newNodeSize, endbloc " << endBloc << " " << oldNodeSize); - copyNodes(newPoints, idNodesOldToNew, alreadyCopied, startBloc, endBloc); - compactState = lookHoleStart; - startHole = i; - endHole = 0; - startBloc = 0; - endBloc = 0; - } - break; - } - } - if (!alreadyCopied) // no hole, but shorter, no need to modify idNodesOldToNew - { - MESSAGE("------------- newNodeSize, shorter " << oldNodeSize); - copyNodes(newPoints, idNodesOldToNew, alreadyCopied, 0, newNodeSize); - } - newPoints->Squeeze(); - } - - // --- create new compacted Connectivity, Locations and Types - - int oldCellSize = this->Types->GetNumberOfTuples(); - - 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(); - //newTypes->Allocate(oldCellSize); - newTypes->SetNumberOfValues(newCellSize); - - vtkIdTypeArray *newLocations = vtkIdTypeArray::New(); - newLocations->Initialize(); - //newLocations->Allocate(oldCellSize); - newLocations->SetNumberOfValues(newCellSize); - - startHole = 0; - endHole = 0; - startBloc = 0; - endBloc = 0; - alreadyCopied = 0; - holes = 0; - compactState = lookHoleStart; - - vtkIdType tmpid[50]; - vtkIdType *pointsCell =&tmpid[0]; // --- points id to fill a new cell - - for (int i=0; iLinks) + // { + // this->Links->UnRegister(this); + // this->Links = 0; + // } + + // --- if newNodeSize, create a new compacted vtkPoints + + vtkPoints *newPoints = 0; + if (newNodeSize) + { + MESSAGE("-------------- compactGrid, newNodeSize " << newNodeSize); + newPoints = vtkPoints::New(); + newPoints->Initialize(); + newPoints->Allocate(newNodeSize); + newPoints->SetNumberOfPoints(newNodeSize); + int oldNodeSize = idNodesOldToNew.size(); + + for (int i = 0; i < oldNodeSize; i++) + { + switch (compactState) + { + case lookHoleStart: + if (idNodesOldToNew[i] < 0) + { + MESSAGE("-------------- newNodeSize, startHole " << i << " " << oldNodeSize); + startHole = i; + if (!alreadyCopied) // copy the first bloc + { + MESSAGE("--------- copy first nodes before hole " << i << " " << oldNodeSize); + copyNodes(newPoints, idNodesOldToNew, alreadyCopied, 0, startHole); + } + compactState = lookHoleEnd; + } + break; + case lookHoleEnd: + if (idNodesOldToNew[i] >= 0) + { + MESSAGE("-------------- newNodeSize, endHole " << i << " " << oldNodeSize); + endHole = i; + startBloc = i; + compactState = lookBlocEnd; + } + break; + case lookBlocEnd: + if (idNodesOldToNew[i] < 0) + endBloc = i; // see nbPoints below + else if (i == (oldNodeSize - 1)) + endBloc = i + 1; + if (endBloc) + { + MESSAGE("-------------- newNodeSize, endbloc " << endBloc << " " << oldNodeSize); + copyNodes(newPoints, idNodesOldToNew, alreadyCopied, startBloc, endBloc); + compactState = lookHoleStart; + startHole = i; + endHole = 0; + startBloc = 0; + endBloc = 0; + } + break; + } + } + if (!alreadyCopied) // no hole, but shorter, no need to modify idNodesOldToNew + { + MESSAGE("------------- newNodeSize, shorter " << oldNodeSize); + copyNodes(newPoints, idNodesOldToNew, alreadyCopied, 0, newNodeSize); + } + newPoints->Squeeze(); + } + + // --- create new compacted Connectivity, Locations and Types + + int oldCellSize = this->Types->GetNumberOfTuples(); + + 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(); + //newTypes->Allocate(oldCellSize); + newTypes->SetNumberOfValues(newCellSize); + + vtkIdTypeArray *newLocations = vtkIdTypeArray::New(); + newLocations->Initialize(); + //newLocations->Allocate(oldCellSize); + newLocations->SetNumberOfValues(newCellSize); + + startHole = 0; + endHole = 0; + startBloc = 0; + endBloc = 0; + alreadyCopied = 0; + holes = 0; + compactState = lookHoleStart; + + vtkIdType tmpid[50]; + vtkIdType *pointsCell = &tmpid[0]; // --- points id to fill a new cell + + for (int i = 0; i < oldCellSize; i++) + { + switch (compactState) + { + case lookHoleStart: + if (this->Types->GetValue(i) == VTK_EMPTY_CELL) + { + MESSAGE(" -------- newCellSize, startHole " << i << " " << oldCellSize); + startHole = i; + compactState = lookHoleEnd; + if (!alreadyCopied) // copy the first bloc + { + MESSAGE("--------- copy first bloc before hole " << i << " " << oldCellSize); + copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell, + alreadyCopied, 0, startHole); + } + } + break; + case lookHoleEnd: + if (this->Types->GetValue(i) != VTK_EMPTY_CELL) + { + MESSAGE(" -------- newCellSize, EndHole " << i << " " << oldCellSize); + endHole = i; + startBloc = i; + compactState = lookBlocEnd; + holes += endHole - startHole; + //alreadyCopied = startBloc -holes; + } + break; + case lookBlocEnd: + endBloc = 0; + if (this->Types->GetValue(i) == VTK_EMPTY_CELL) + endBloc = i; + else if (i == (oldCellSize - 1)) + endBloc = i + 1; + if (endBloc) + { + MESSAGE(" -------- newCellSize, endBloc " << endBloc << " " << oldCellSize); + copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell, + alreadyCopied, startBloc, endBloc); + compactState = lookHoleStart; + } + break; + } + } + if (!alreadyCopied) // no hole, but shorter { - switch(compactState) - { - case lookHoleStart: - if (this->Types->GetValue(i) == VTK_EMPTY_CELL) - { - MESSAGE(" -------- newCellSize, startHole " << i << " " << oldCellSize); - startHole = i; - compactState = lookHoleEnd; - if (!alreadyCopied) // copy the first bloc - { - MESSAGE("--------- copy first bloc before hole " << i << " " << oldCellSize); - copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell, alreadyCopied, 0, startHole); - } - } - break; - case lookHoleEnd: - if (this->Types->GetValue(i) != VTK_EMPTY_CELL) - { - MESSAGE(" -------- newCellSize, EndHole " << i << " " << oldCellSize); - endHole = i; - startBloc = i; - compactState = lookBlocEnd; - holes += endHole - startHole; - //alreadyCopied = startBloc -holes; - } - break; - case lookBlocEnd: - endBloc =0; - if (this->Types->GetValue(i) == VTK_EMPTY_CELL) endBloc =i; - else if (i == (oldCellSize-1)) endBloc = i+1; - if (endBloc) - { - MESSAGE(" -------- newCellSize, endBloc " << endBloc << " " << oldCellSize); - copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell, alreadyCopied, startBloc, endBloc); - compactState = lookHoleStart; - } - break; - } + MESSAGE(" -------- newCellSize, shorter " << oldCellSize); + copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell, alreadyCopied, 0, + oldCellSize); } - if (!alreadyCopied) // no hole, but shorter + + newConnectivity->Squeeze(); + //newTypes->Squeeze(); + //newLocations->Squeeze(); + + if (newNodeSize) { - MESSAGE(" -------- newCellSize, shorter " << oldCellSize); - copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell, alreadyCopied, 0, oldCellSize); + MESSAGE("------- newNodeSize, setPoints"); + this->SetPoints(newPoints); + MESSAGE("NumberOfPoints: " << this->GetNumberOfPoints()); } + this->SetCells(newTypes, newLocations, newConnectivity); + this->BuildLinks(); +} - newConnectivity->Squeeze(); - //newTypes->Squeeze(); - //newLocations->Squeeze(); +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; + if (nbPoints > 0) + { + memcpy(target, source, 3 * sizeof(float) * nbPoints); + for (int j = start; j < end; j++) + idNodesOldToNew[j] = alreadyCopied++; + } +} - if (newNodeSize) +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++) { - MESSAGE("------- newNodeSize, setPoints"); - this->SetPoints(newPoints); - MESSAGE("NumberOfPoints: " << this->GetNumberOfPoints()); + newTypes->SetValue(alreadyCopied, this->Types->GetValue(j)); + idCellsOldToNew[j] = alreadyCopied; + vtkIdType oldLoc = this->Locations->GetValue(j); + vtkIdType nbpts; + vtkIdType *oldPtsCell = 0; + this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell); + //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++; } - this->SetCells(newTypes, newLocations, newConnectivity); - this->BuildLinks(); } -void SMDS_UnstructuredGrid::copyNodes(vtkPoints *newPoints, - std::vector& idNodesOldToNew, - int& alreadyCopied, - int start, - int end) +int SMDS_UnstructuredGrid::CellIdToDownId(int vtkCellId) +{ + // ASSERT((vtkCellId >= 0) && (vtkCellId < _cellIdToDownId.size())); + return _cellIdToDownId[vtkCellId]; +} + +void SMDS_UnstructuredGrid::setCellIdToDownId(int vtkCellId, int downId) { - 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; - if (nbPoints >0) - { - memcpy(target, source, 3*sizeof(float)*nbPoints); - for (int j=start; j= 0) && (vtkCellId < _cellIdToDownId.size())); + _cellIdToDownId[vtkCellId] = downId; } -void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes, - std::vector& idCellsOldToNew, - std::vector& idNodesOldToNew, - vtkCellArray* newConnectivity, - vtkIdTypeArray* newLocations, - vtkIdType* pointsCell, - int& alreadyCopied, - int start, - int end) +/*! Build downward connectivity: to do only when needed because heavy memory load. + * Downward connectivity is no more valid if vtkUnstructuredGrid is modified. + * + */ +void SMDS_UnstructuredGrid::BuildDownwardConnectivity() { - MESSAGE("copyBloc " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start); - for (int j=start; jSetValue(alreadyCopied, this->Types->GetValue(j)); - idCellsOldToNew[j] = alreadyCopied; - vtkIdType oldLoc = this->Locations->GetValue(j); - vtkIdType nbpts; - vtkIdType *oldPtsCell = 0; - this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell); - //MESSAGE(j << " " << alreadyCopied << " " << (int)this->Types->GetValue(j) << " " << oldLoc << " " << nbpts ); - for (int l=0; lInsertNextCell(nbpts, pointsCell); - int newLoc = newConnectivity->GetInsertLocation(nbpts); - //MESSAGE(newcnt << " " << newLoc); - newLocations->SetValue(alreadyCopied, newLoc); - alreadyCopied++; - } + MESSAGE("SMDS_UnstructuredGrid::BuildDownwardConnectivity");CHRONO(2); + + // --- erase previous data if any + + for (int i = 0; i < _downArray.size(); i++) + { + if (_downArray[i]) + delete _downArray[i]; + _downArray[i] = 0; + } + _cellIdToDownId.clear(); + + // --- create SMDS_Downward structures (in _downArray vector[vtkCellType]) + + _downArray.resize(VTK_QUADRATIC_PYRAMID + 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); + + // --- 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 nbQuadEdgeGuess = int((4.0 / 3.0) * nbQuadTetra + 2 * nbQuadPrism + 2.5 * nbQuadPyra + 3 * nbQuadHexa); + 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 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); + + // --- iteration on vtkUnstructuredGrid cells, only faces + // for each vtk face: + // create a downward face entry with its downward id. + // compute vtk volumes, create downward volumes entry. + // mark face in downward volumes + // mark volumes in downward face + + MESSAGE("--- iteration on vtkUnstructuredGrid cells, only faces");CHRONO(20); + int cellSize = this->Types->GetNumberOfTuples(); + _cellIdToDownId.resize(cellSize, -1); + + for (int i = 0; i < cellSize; i++) + { + int vtkFaceType = this->GetCellType(i); + if (SMDS_Downward::getCellDimension(vtkFaceType) == 2) + { + int vtkFaceId = i; + //ASSERT(_downArray[vtkFaceType]); + int connFaceId = _downArray[vtkFaceType]->addCell(vtkFaceId); + SMDS_Down2D* downFace = static_cast (_downArray[vtkFaceType]); + downFace->setTempNodes(connFaceId, vtkFaceId); + int vols[2] = { -1, -1 }; + int nbVolumes = downFace->computeVolumeIds(vtkFaceId, vols); + //MESSAGE("nbVolumes="<< nbVolumes); + for (int ivol = 0; ivol < nbVolumes; ivol++) + { + int vtkVolId = vols[ivol]; + int vtkVolType = this->GetCellType(vtkVolId); + //ASSERT(_downArray[vtkVolType]); + int connVolId = _downArray[vtkVolType]->addCell(vtkVolId); + _downArray[vtkVolType]->addDownCell(connVolId, connFaceId, vtkFaceType); + _downArray[vtkFaceType]->addUpCell(connFaceId, connVolId, vtkVolType); + // MESSAGE("Face " << vtkFaceId << " belongs to volume " << vtkVolId); + } + } + } + + // --- iteration on vtkUnstructuredGrid cells, only volumes + // for each vtk volume: + // create downward volumes entry if not already done + // build a temporary list of faces described with their nodes + // for each face + // compute the vtk volumes containing this face + // check if the face is already listed in the volumes (comparison of ordered list of nodes) + // if not, create a downward face entry (resizing of structure required) + // (the downward faces store a temporary list of nodes to ease the comparison) + // create downward volumes entry if not already done + // mark volumes in downward face + // mark face in downward volumes + + CHRONOSTOP(20); + MESSAGE("--- iteration on vtkUnstructuredGrid cells, only volumes");CHRONO(21); + + for (int i = 0; i < cellSize; i++) + { + int vtkType = this->GetCellType(i); + if (SMDS_Downward::getCellDimension(vtkType) == 3) + { + //CHRONO(31); + int vtkVolId = i; + // MESSAGE("vtk volume " << vtkVolId); + //ASSERT(_downArray[vtkType]); + int connVolId = _downArray[vtkType]->addCell(vtkVolId); + + // --- find all the faces of the volume, describe the faces by their nodes + + SMDS_Down3D* downVol = static_cast (_downArray[vtkType]); + ListElemByNodesType facesWithNodes; + downVol->computeFacesWithNodes(vtkVolId, facesWithNodes); + // MESSAGE("vtk volume " << vtkVolId << " contains " << facesWithNodes.nbElems << " faces"); + //CHRONOSTOP(31); + for (int iface = 0; iface < facesWithNodes.nbElems; iface++) + { + // --- find the volumes containing the face + + //CHRONO(32); + int vtkFaceType = facesWithNodes.elems[iface].vtkType; + SMDS_Down2D* downFace = static_cast (_downArray[vtkFaceType]); + int vols[2] = { -1, -1 }; + int *nodes = &facesWithNodes.elems[iface].nodeIds[0]; + int lg = facesWithNodes.elems[iface].nbNodes; + int nbVolumes = downFace->computeVolumeIdsFromNodesFace(nodes, lg, vols); + // MESSAGE("vtk volume " << vtkVolId << " face " << iface << " belongs to " << nbVolumes << " volumes"); + + // --- check if face is registered in the volumes + //CHRONOSTOP(32); + + //CHRONO(33); + int connFaceId = -1; + for (int ivol = 0; ivol < nbVolumes; ivol++) + { + int vtkVolId2 = vols[ivol]; + int vtkVolType = this->GetCellType(vtkVolId2); + //ASSERT(_downArray[vtkVolType]); + int connVolId2 = _downArray[vtkVolType]->addCell(vtkVolId2); + SMDS_Down3D* downVol2 = static_cast (_downArray[vtkVolType]); + connFaceId = downVol2->FindFaceByNodes(connVolId2, facesWithNodes.elems[iface]); + if (connFaceId >= 0) + break; // --- face already created + }//CHRONOSTOP(33); + + // --- if face is not registered in the volumes, create face + + //CHRONO(34); + if (connFaceId < 0) + { + connFaceId = _downArray[vtkFaceType]->addCell(); + downFace->setTempNodes(connFaceId, facesWithNodes.elems[iface]); + }//CHRONOSTOP(34); + + // --- mark volumes in downward face and mark face in downward volumes + + //CHRONO(35); + for (int ivol = 0; ivol < nbVolumes; ivol++) + { + int vtkVolId2 = vols[ivol]; + int vtkVolType = this->GetCellType(vtkVolId2); + //ASSERT(_downArray[vtkVolType]); + int connVolId2 = _downArray[vtkVolType]->addCell(vtkVolId2); + _downArray[vtkVolType]->addDownCell(connVolId2, connFaceId, vtkFaceType); + _downArray[vtkFaceType]->addUpCell(connFaceId, connVolId2, vtkVolType); + // MESSAGE(" From volume " << vtkVolId << " face " << connFaceId << " belongs to volume " << vtkVolId2); + }//CHRONOSTOP(35); + } + } + } + + // --- iteration on vtkUnstructuredGrid cells, only edges + // for each vtk edge: + // create downward edge entry + // store the nodes id's in downward edge (redundant with vtkUnstructuredGrid) + // find downward faces + // (from vtk faces or volumes, get downward faces, they have a temporary list of nodes) + // mark edge in downward faces + // mark faces in downward edge + + CHRONOSTOP(21); + MESSAGE("--- iteration on vtkUnstructuredGrid cells, only edges");CHRONO(22); + + for (int i = 0; i < cellSize; i++) + { + int vtkEdgeType = this->GetCellType(i); + if (SMDS_Downward::getCellDimension(vtkEdgeType) == 1) + { + int vtkEdgeId = i; + //ASSERT(_downArray[vtkEdgeType]); + int connEdgeId = _downArray[vtkEdgeType]->addCell(vtkEdgeId); + SMDS_Down1D* downEdge = static_cast (_downArray[vtkEdgeType]); + downEdge->setNodes(connEdgeId, vtkEdgeId); + vector vtkIds; + int nbVtkCells = downEdge->computeVtkCells(connEdgeId, vtkIds); + int downFaces[100]; + unsigned char downTypes[100]; + int nbDownFaces = downEdge->computeFaces(connEdgeId, &vtkIds[0], nbVtkCells, downFaces, downTypes); + for (int n = 0; n < nbDownFaces; n++) + { + _downArray[downTypes[n]]->addDownCell(downFaces[n], connEdgeId, vtkEdgeType); + _downArray[vtkEdgeType]->addUpCell(connEdgeId, downFaces[n], downTypes[n]); + } + } + } + + // --- iteration on downward faces (they are all listed now) + // for each downward face: + // build a temporary list of edges with their ordered list of nodes + // for each edge: + // find all the vtk cells containing this edge + // then identify all the downward faces containing the edge, from the vtk cells + // check if the edge is already listed in the faces (comparison of ordered list of nodes) + // if not, create a downward edge entry with the node id's + // mark edge in downward faces + // mark downward faces in edge (size of list unknown, to be allocated) + + CHRONOSTOP(22);CHRONO(23); + + for (int vtkFaceType = 0; vtkFaceType < VTK_QUADRATIC_PYRAMID; vtkFaceType++) + { + if (SMDS_Downward::getCellDimension(vtkFaceType) != 2) + continue; + + // --- find all the edges of the face, describe the edges by their nodes + + SMDS_Down2D* downFace = static_cast (_downArray[vtkFaceType]); + int maxId = downFace->getMaxId(); + for (int faceId = 0; faceId < maxId; faceId++) + { + //CHRONO(40); + ListElemByNodesType edgesWithNodes; + downFace->computeEdgesWithNodes(faceId, edgesWithNodes); + // MESSAGE("downward face type " << vtkFaceType << " num " << faceId << " contains " << edgesWithNodes.nbElems << " edges"); + + //CHRONOSTOP(40); + for (int iedge = 0; iedge < edgesWithNodes.nbElems; iedge++) + { + + // --- check if the edge is already registered by exploration of the faces + + //CHRONO(41); + vector vtkIds; + unsigned char vtkEdgeType = edgesWithNodes.elems[iedge].vtkType; + int *pts = &edgesWithNodes.elems[iedge].nodeIds[0]; + SMDS_Down1D* downEdge = static_cast (_downArray[vtkEdgeType]); + int nbVtkCells = downEdge->computeVtkCells(pts, vtkIds); + //CHRONOSTOP(41);CHRONO(42); + int downFaces[100]; + unsigned char downTypes[100]; + int nbDownFaces = downEdge->computeFaces(pts, &vtkIds[0], nbVtkCells, downFaces, downTypes); + //CHRONOSTOP(42); + + //CHRONO(43); + int connEdgeId = -1; + for (int idf = 0; idf < nbDownFaces; idf++) + { + int faceId2 = downFaces[idf]; + int faceType = downTypes[idf]; + //ASSERT(_downArray[faceType]); + SMDS_Down2D* downFace2 = static_cast (_downArray[faceType]); + connEdgeId = downFace2->FindEdgeByNodes(faceId2, edgesWithNodes.elems[iedge]); + if (connEdgeId >= 0) + break; // --- edge already created + }//CHRONOSTOP(43); + + // --- if edge is not registered in the faces, create edge + + if (connEdgeId < 0) + { + //CHRONO(44); + connEdgeId = _downArray[vtkEdgeType]->addCell(); + downEdge->setNodes(connEdgeId, edgesWithNodes.elems[iedge].nodeIds); + //CHRONOSTOP(44); + } + + // --- mark faces in downward edge and mark edge in downward faces + + //CHRONO(45); + for (int idf = 0; idf < nbDownFaces; idf++) + { + int faceId2 = downFaces[idf]; + int faceType = downTypes[idf]; + //ASSERT(_downArray[faceType]); + SMDS_Down2D* downFace2 = static_cast (_downArray[faceType]); + _downArray[vtkEdgeType]->addUpCell(connEdgeId, faceId2, faceType); + _downArray[faceType]->addDownCell(faceId2, connEdgeId, vtkEdgeType); + // MESSAGE(" From face t:" << vtkFaceType << " " << faceId << + // " edge " << connEdgeId << " belongs to face t:" << faceType << " " << faceId2); + }//CHRONOSTOP(45); + } + } + } + + CHRONOSTOP(23);CHRONO(24); + + // compact downward connectivity structure: adjust downward arrays size, replace vector> by a single 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--) + { + if (SMDS_Downward *down = _downArray[vtkType]) + { + down->compactStorage(); + } + } + + // --- Statistics + + for (int vtkType = 0; vtkType <= VTK_QUADRATIC_PYRAMID; vtkType++) + { + if (SMDS_Downward *down = _downArray[vtkType]) + { + if (down->getMaxId()) + { + MESSAGE("Cells of Type " << vtkType << " : number of entities, est: " + << GuessSize[vtkType] << " real: " << down->getMaxId()); + } + } + }CHRONOSTOP(24);CHRONOSTOP(2); + _counters->stats(); } diff --git a/src/SMDS/SMDS_UnstructuredGrid.hxx b/src/SMDS/SMDS_UnstructuredGrid.hxx index 87ae00eb7..30a074753 100644 --- a/src/SMDS/SMDS_UnstructuredGrid.hxx +++ b/src/SMDS/SMDS_UnstructuredGrid.hxx @@ -11,36 +11,47 @@ #include #include +#include "chrono.hxx" + +class SMDS_Downward; +class SMDS_Mesh; class SMDS_UnstructuredGrid: public vtkUnstructuredGrid { public: - void compactGrid(std::vector& idNodesOldToNew, int newNodeSize, - std::vector& idCellsOldToNew, int newCellSize); - - virtual unsigned long GetMTime(); - virtual void Update(); - virtual void UpdateInformation(); - - static SMDS_UnstructuredGrid* New(); + void setSMDS_mesh(SMDS_Mesh *mesh); + void compactGrid(std::vector& idNodesOldToNew, int newNodeSize, std::vector& idCellsOldToNew, + int newCellSize); + + virtual unsigned long GetMTime(); + virtual void Update(); + virtual void UpdateInformation(); + + int CellIdToDownId(int vtkCellId); + void setCellIdToDownId(int vtkCellId, int downId); + void BuildDownwardConnectivity(); + vtkCellLinks* GetLinks() + { + return Links; + } + SMDS_Downward* getDownArray(unsigned char vtkType) + { + return _downArray[vtkType]; + } + static SMDS_UnstructuredGrid* New(); protected: - SMDS_UnstructuredGrid(); - ~SMDS_UnstructuredGrid(); - void copyNodes(vtkPoints *newPoints, - std::vector& idNodesOldToNew, - int& alreadyCopied, - int start, - int end); - void copyBloc(vtkUnsignedCharArray *newTypes, - std::vector& idCellsOldToNew, - std::vector& idNodesOldToNew, - vtkCellArray* newConnectivity, - vtkIdTypeArray* newLocations, - vtkIdType* pointsCell, - int& alreadyCopied, - int start, - int end); - + SMDS_UnstructuredGrid(); + ~SMDS_UnstructuredGrid(); + void copyNodes(vtkPoints *newPoints, std::vector& idNodesOldToNew, int& alreadyCopied, int start, int end); + void copyBloc(vtkUnsignedCharArray *newTypes, std::vector& idCellsOldToNew, std::vector& idNodesOldToNew, + vtkCellArray* newConnectivity, vtkIdTypeArray* newLocations, vtkIdType* pointsCell, int& alreadyCopied, + int start, int end); + + SMDS_Mesh *_mesh; + std::vector _cellIdToDownId; //!< convert vtk Id to downward[vtkType] id, initialized with -1 + std::vector _downTypes; + std::vector _downArray; + counters *_counters; }; #endif /* _SMDS_UNSTRUCTUREDGRID_HXX */ diff --git a/src/SMDS/SMDS_VtkCellIterator.cxx b/src/SMDS/SMDS_VtkCellIterator.cxx index 1d0138f1b..d888a58ba 100644 --- a/src/SMDS/SMDS_VtkCellIterator.cxx +++ b/src/SMDS/SMDS_VtkCellIterator.cxx @@ -1,6 +1,7 @@ #include "SMDS_VtkCellIterator.hxx" -SMDS_VtkCellIterator::SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) : +SMDS_VtkCellIterator::SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, + SMDSAbs_EntityType aType) : _mesh(mesh), _cellId(vtkCellId), _index(0), _type(aType) { vtkUnstructuredGrid* grid = _mesh->getGrid(); @@ -11,62 +12,62 @@ SMDS_VtkCellIterator::SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSA switch (_type) { case SMDSEntity_Tetra: - { - this->exchange(1, 2); - break; - } + { + this->exchange(1, 2); + break; + } case SMDSEntity_Pyramid: - { - this->exchange(1, 3); - break; - } + { + this->exchange(1, 3); + break; + } case SMDSEntity_Penta: - { - //this->exchange(1, 2); - //this->exchange(4, 5); - break; - } + { + //this->exchange(1, 2); + //this->exchange(4, 5); + break; + } case SMDSEntity_Hexa: - { - this->exchange(1, 3); - this->exchange(5, 7); - break; - } + { + this->exchange(1, 3); + this->exchange(5, 7); + break; + } case SMDSEntity_Quad_Tetra: - { - this->exchange(1, 2); - this->exchange(4, 6); - this->exchange(8, 9); - break; - } + { + this->exchange(1, 2); + this->exchange(4, 6); + this->exchange(8, 9); + break; + } case SMDSEntity_Quad_Pyramid: - { - this->exchange(1, 3); - this->exchange(5, 8); - this->exchange(6, 7); - this->exchange(10, 12); - break; - } + { + this->exchange(1, 3); + this->exchange(5, 8); + this->exchange(6, 7); + this->exchange(10, 12); + break; + } case SMDSEntity_Quad_Penta: - { - //this->exchange(1, 2); - //this->exchange(4, 5); - //this->exchange(6, 8); - //this->exchange(9, 11); - //this->exchange(13, 14); - break; - } + { + //this->exchange(1, 2); + //this->exchange(4, 5); + //this->exchange(6, 8); + //this->exchange(9, 11); + //this->exchange(13, 14); + break; + } case SMDSEntity_Quad_Hexa: - { - this->exchange(1, 3); - this->exchange(5, 7); - this->exchange(8, 11); - this->exchange(9, 10); - this->exchange(12, 15); - this->exchange(13, 14); - this->exchange(17, 19); - break; - } + { + this->exchange(1, 3); + this->exchange(5, 7); + this->exchange(8, 11); + this->exchange(9, 10); + this->exchange(12, 15); + this->exchange(13, 14); + this->exchange(17, 19); + break; + } default: break; } diff --git a/src/SMDS/SMDS_VtkCellIterator.hxx b/src/SMDS/SMDS_VtkCellIterator.hxx index 3a98cfac9..537c76d2c 100644 --- a/src/SMDS/SMDS_VtkCellIterator.hxx +++ b/src/SMDS/SMDS_VtkCellIterator.hxx @@ -8,16 +8,21 @@ #include #include -class SMDS_VtkCellIterator : public SMDS_ElemIterator +class SMDS_VtkCellIterator: public SMDS_ElemIterator { public: - SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType); + SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, + SMDSAbs_EntityType aType); virtual ~SMDS_VtkCellIterator(); virtual bool more(); virtual const SMDS_MeshElement* next(); - inline void exchange(vtkIdType a, vtkIdType b) { vtkIdType t = _vtkIdList->GetId(a); - _vtkIdList->SetId(a, _vtkIdList->GetId(b)); - _vtkIdList->SetId(b, t); }; + inline void exchange(vtkIdType a, vtkIdType b) + { + vtkIdType t = _vtkIdList->GetId(a); + _vtkIdList->SetId(a, _vtkIdList->GetId(b)); + _vtkIdList->SetId(b, t); + } + protected: SMDS_Mesh* _mesh; int _cellId; diff --git a/src/SMDS/SMDS_VtkEdge.cxx b/src/SMDS/SMDS_VtkEdge.cxx index 3b3e25882..34745b44f 100644 --- a/src/SMDS/SMDS_VtkEdge.cxx +++ b/src/SMDS/SMDS_VtkEdge.cxx @@ -16,7 +16,7 @@ SMDS_VtkEdge::SMDS_VtkEdge() SMDS_VtkEdge::SMDS_VtkEdge(std::vector nodeIds, SMDS_Mesh* mesh) { - init(nodeIds, mesh); + init(nodeIds, mesh); } SMDS_VtkEdge::~SMDS_VtkEdge() @@ -25,53 +25,53 @@ SMDS_VtkEdge::~SMDS_VtkEdge() void SMDS_VtkEdge::init(std::vector nodeIds, SMDS_Mesh* mesh) { - vtkUnstructuredGrid* grid = mesh->getGrid(); - myIdInShape = -1; - myMeshId = mesh->getMeshId(); - vtkIdType aType = VTK_LINE; - if (nodeIds.size() == 3) - aType = VTK_QUADRATIC_EDGE; - myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]); + vtkUnstructuredGrid* grid = mesh->getGrid(); + myIdInShape = -1; + myMeshId = mesh->getMeshId(); + vtkIdType aType = VTK_LINE; + if (nodeIds.size() == 3) + aType = VTK_QUADRATIC_EDGE; + myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]); } bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2) + const SMDS_MeshNode * node2) { - return true; + return true; } void SMDS_VtkEdge::Print(std::ostream & OS) const { - OS << "edge <" << GetID() << "> : "; + OS << "edge <" << GetID() << "> : "; } int SMDS_VtkEdge::NbNodes() const { - vtkUnstructuredGrid* grid =SMDS_Mesh::_meshList[myMeshId]->getGrid(); - int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints(); - assert(nbPoints >=2); - return nbPoints; + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints(); + assert(nbPoints >= 2); + return nbPoints; } int SMDS_VtkEdge::NbEdges() const { - return 1; + return 1; } SMDSAbs_EntityType SMDS_VtkEdge::GetEntityType() const { - if (NbNodes() == 2) - return SMDSEntity_Edge; - else - return SMDSEntity_Quad_Edge; + if (NbNodes() == 2) + return SMDSEntity_Edge; + else + return SMDSEntity_Quad_Edge; } vtkIdType SMDS_VtkEdge::GetVtkType() const { - if (NbNodes() == 2) - return VTK_LINE; - else - return VTK_QUADRATIC_EDGE; + if (NbNodes() == 2) + return VTK_LINE; + else + return VTK_QUADRATIC_EDGE; } @@ -89,20 +89,24 @@ SMDS_VtkEdge::GetNode(const int ind) const bool SMDS_VtkEdge::IsQuadratic() const { if (this->NbNodes() > 2) - return true; + return true; else - return false; + return false; } SMDS_ElemIteratorPtr SMDS_VtkEdge::elementsIterator(SMDSAbs_ElementType type) const { - switch (type) - { - case SMDSAbs_Node: - return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator( - SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); - default: - MESSAGE("ERROR : Iterator not implemented"); - return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); - } + switch (type) + { + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr( + new SMDS_VtkCellIterator( + SMDS_Mesh::_meshList[myMeshId], + myVtkID, + GetEntityType())); + default: + MESSAGE("ERROR : Iterator not implemented") + ; + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); + } } diff --git a/src/SMDS/SMDS_VtkFace.cxx b/src/SMDS/SMDS_VtkFace.cxx index ad53647cc..ade2f5ce0 100644 --- a/src/SMDS/SMDS_VtkFace.cxx +++ b/src/SMDS/SMDS_VtkFace.cxx @@ -15,7 +15,7 @@ SMDS_VtkFace::SMDS_VtkFace() SMDS_VtkFace::SMDS_VtkFace(std::vector nodeIds, SMDS_Mesh* mesh) { - init(nodeIds, mesh); + init(nodeIds, mesh); } SMDS_VtkFace::~SMDS_VtkFace() @@ -24,54 +24,68 @@ SMDS_VtkFace::~SMDS_VtkFace() void SMDS_VtkFace::init(std::vector nodeIds, SMDS_Mesh* mesh) { - vtkUnstructuredGrid* grid = mesh->getGrid(); - myIdInShape = -1; - myMeshId = mesh->getMeshId(); - vtkIdType aType = VTK_TRIANGLE; - switch(nodeIds.size()) - { - case 3: aType = VTK_TRIANGLE; break; - case 4: aType = VTK_QUAD; break; - case 6: aType = VTK_QUADRATIC_TRIANGLE; break; - case 8: aType = VTK_QUADRATIC_QUAD; break; - default: aType = VTK_TRIANGLE; break; - } - myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]); + vtkUnstructuredGrid* grid = mesh->getGrid(); + myIdInShape = -1; + myMeshId = mesh->getMeshId(); + vtkIdType aType = VTK_TRIANGLE; + switch (nodeIds.size()) + { + case 3: + aType = VTK_TRIANGLE; + break; + case 4: + aType = VTK_QUAD; + break; + case 6: + aType = VTK_QUADRATIC_TRIANGLE; + break; + case 8: + aType = VTK_QUADRATIC_QUAD; + break; + default: + aType = VTK_TRIANGLE; + break; + } + myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]); } bool SMDS_VtkFace::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) { - return true; + return true; } void SMDS_VtkFace::Print(std::ostream & OS) const { - OS << "edge <" << GetID() << "> : "; + OS << "edge <" << GetID() << "> : "; } int SMDS_VtkFace::NbEdges() const { - switch(NbNodes()) - { - case 3: - case 6: return 3; - case 4: - case 8: return 4; - default: MESSAGE("invalid number of nodes"); - } - return 0; + switch (NbNodes()) + { + case 3: + case 6: + return 3; + case 4: + case 8: + return 4; + default: + MESSAGE("invalid number of nodes") + ; + } + return 0; } int SMDS_VtkFace::NbFaces() const { - return 1; + return 1; } int SMDS_VtkFace::NbNodes() const { - vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); - int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints(); - return nbPoints; + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints(); + return nbPoints; } /*! @@ -88,44 +102,57 @@ SMDS_VtkFace::GetNode(const int ind) const bool SMDS_VtkFace::IsQuadratic() const { if (this->NbNodes() > 5) - return true; + return true; else - return false; + return false; } SMDSAbs_EntityType SMDS_VtkFace::GetEntityType() const { - SMDSAbs_EntityType aType = SMDSEntity_Triangle; - switch(NbNodes()) - { - case 3: - case 6: aType = SMDSEntity_Triangle; break; - case 4: - case 8: aType = SMDSEntity_Quadrangle; break; - } - return aType; + SMDSAbs_EntityType aType = SMDSEntity_Triangle; + switch (NbNodes()) + { + case 3: + case 6: + aType = SMDSEntity_Triangle; + break; + case 4: + case 8: + aType = SMDSEntity_Quadrangle; + break; + } + return aType; } vtkIdType SMDS_VtkFace::GetVtkType() const { - switch(NbNodes()) - { - case 3: return VTK_TRIANGLE; - case 6: return VTK_QUADRATIC_TRIANGLE; - case 4: return VTK_QUAD; - case 8: return VTK_QUADRATIC_QUAD; - } + switch (NbNodes()) + { + case 3: + return VTK_TRIANGLE; + case 6: + return VTK_QUADRATIC_TRIANGLE; + case 4: + return VTK_QUAD; + case 8: + return VTK_QUADRATIC_QUAD; + } } SMDS_ElemIteratorPtr SMDS_VtkFace::elementsIterator(SMDSAbs_ElementType type) const { - switch (type) - { - case SMDSAbs_Node: - return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); - default: - MESSAGE("ERROR : Iterator not implemented"); - return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); - } + switch (type) + { + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr( + new SMDS_VtkCellIterator( + SMDS_Mesh::_meshList[myMeshId], + myVtkID, + GetEntityType())); + default: + MESSAGE("ERROR : Iterator not implemented") + ; + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); + } } diff --git a/src/SMDS/SMDS_VtkVolume.cxx b/src/SMDS/SMDS_VtkVolume.cxx index ebcc20851..c8865d6ba 100644 --- a/src/SMDS/SMDS_VtkVolume.cxx +++ b/src/SMDS/SMDS_VtkVolume.cxx @@ -1,4 +1,3 @@ - #include "SMDS_VtkVolume.hxx" #include "SMDS_MeshNode.hxx" #include "SMDS_Mesh.hxx" @@ -8,7 +7,6 @@ #include - SMDS_VtkVolume::SMDS_VtkVolume() { } @@ -27,23 +25,41 @@ void SMDS_VtkVolume::init(std::vector nodeIds, SMDS_Mesh* mesh) myIdInShape = -1; myMeshId = mesh->getMeshId(); vtkIdType aType = VTK_TETRA; - switch(nodeIds.size()) - { - case 4: aType = VTK_TETRA; break; - case 5: aType = VTK_PYRAMID; break; - case 6: aType = VTK_WEDGE; break; - case 8: aType = VTK_HEXAHEDRON; break; - case 10: aType = VTK_QUADRATIC_TETRA; break; - case 13: aType = VTK_QUADRATIC_PYRAMID; break; - case 15: aType = VTK_QUADRATIC_WEDGE; break; - case 20: aType = VTK_QUADRATIC_HEXAHEDRON; break; - default: aType = VTK_HEXAHEDRON; break; - } + switch (nodeIds.size()) + { + case 4: + aType = VTK_TETRA; + break; + case 5: + aType = VTK_PYRAMID; + break; + case 6: + aType = VTK_WEDGE; + break; + case 8: + aType = VTK_HEXAHEDRON; + break; + case 10: + aType = VTK_QUADRATIC_TETRA; + break; + case 13: + aType = VTK_QUADRATIC_PYRAMID; + break; + case 15: + aType = VTK_QUADRATIC_WEDGE; + break; + case 20: + aType = VTK_QUADRATIC_HEXAHEDRON; + break; + default: + aType = VTK_HEXAHEDRON; + break; + } myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]); } bool SMDS_VtkVolume::ChangeNodes(const SMDS_MeshNode* nodes[], - const int nbNodes) + const int nbNodes) { // utilise dans SMDS_Mesh return true; @@ -60,55 +76,72 @@ void SMDS_VtkVolume::Print(ostream & OS) const int SMDS_VtkVolume::NbFaces() const { - switch(NbNodes()) - { - case 4: - case 10: return 4; - case 5: - case 13: return 5; - case 6: - case 15: return 5; - case 8: - case 20: return 6; - default: MESSAGE("invalid number of nodes"); - } + switch (NbNodes()) + { + case 4: + case 10: + return 4; + case 5: + case 13: + return 5; + case 6: + case 15: + return 5; + case 8: + case 20: + return 6; + default: + MESSAGE("invalid number of nodes") + ; + } return 0; } int SMDS_VtkVolume::NbNodes() const { - vtkUnstructuredGrid* grid =SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints(); return nbPoints; } int SMDS_VtkVolume::NbEdges() const { - switch(NbNodes()) - { - case 4: - case 10: return 6; - case 5: - case 13: return 8; - case 6: - case 15: return 9; - case 8: - case 20: return 12; - default: MESSAGE("invalid number of nodes"); - } + switch (NbNodes()) + { + case 4: + case 10: + return 6; + case 5: + case 13: + return 8; + case 6: + case 15: + return 9; + case 8: + case 20: + return 12; + default: + MESSAGE("invalid number of nodes") + ; + } return 0; } SMDS_ElemIteratorPtr SMDS_VtkVolume::elementsIterator(SMDSAbs_ElementType type) const { - switch(type) - { + switch (type) + { case SMDSAbs_Node: - return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); + return SMDS_ElemIteratorPtr( + new SMDS_VtkCellIterator( + SMDS_Mesh::_meshList[myMeshId], + myVtkID, + GetEntityType())); default: - MESSAGE("ERROR : Iterator not implemented"); - return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL); - } + MESSAGE("ERROR : Iterator not implemented") + ; + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); + } } SMDSAbs_ElementType SMDS_VtkVolume::GetType() const @@ -129,43 +162,79 @@ const SMDS_MeshNode* SMDS_VtkVolume::GetNode(const int ind) const bool SMDS_VtkVolume::IsQuadratic() const { if (this->NbNodes() > 9) - return true; + return true; else - return false; + return false; } SMDSAbs_EntityType SMDS_VtkVolume::GetEntityType() const { SMDSAbs_EntityType aType = SMDSEntity_Tetra; - switch(NbNodes()) - { - case 4: aType = SMDSEntity_Tetra; break; - case 5: aType = SMDSEntity_Pyramid; break; - case 6: aType = SMDSEntity_Penta; break; - case 8: aType = SMDSEntity_Hexa; break; - case 10: aType = SMDSEntity_Quad_Tetra; break; - case 13: aType = SMDSEntity_Quad_Pyramid; break; - case 15: aType = SMDSEntity_Quad_Penta; break; - case 20: aType = SMDSEntity_Quad_Hexa; break; - default: aType = SMDSEntity_Hexa; break; - } + switch (NbNodes()) + { + case 4: + aType = SMDSEntity_Tetra; + break; + case 5: + aType = SMDSEntity_Pyramid; + break; + case 6: + aType = SMDSEntity_Penta; + break; + case 8: + aType = SMDSEntity_Hexa; + break; + case 10: + aType = SMDSEntity_Quad_Tetra; + break; + case 13: + aType = SMDSEntity_Quad_Pyramid; + break; + case 15: + aType = SMDSEntity_Quad_Penta; + break; + case 20: + aType = SMDSEntity_Quad_Hexa; + break; + default: + aType = SMDSEntity_Hexa; + break; + } return aType; } vtkIdType SMDS_VtkVolume::GetVtkType() const { vtkIdType aType = VTK_TETRA; - switch(NbNodes()) - { - case 4: aType = VTK_TETRA; break; - case 5: aType = VTK_PYRAMID; break; - case 6: aType = VTK_WEDGE; break; - case 8: aType = VTK_HEXAHEDRON; break; - case 10: aType = VTK_QUADRATIC_TETRA; break; - case 13: aType = VTK_QUADRATIC_PYRAMID; break; - case 15: aType = VTK_QUADRATIC_WEDGE; break; - case 20: aType = VTK_QUADRATIC_HEXAHEDRON; break; - default: aType = VTK_HEXAHEDRON; break; - } - return aType; + switch (NbNodes()) + { + case 4: + aType = VTK_TETRA; + break; + case 5: + aType = VTK_PYRAMID; + break; + case 6: + aType = VTK_WEDGE; + break; + case 8: + aType = VTK_HEXAHEDRON; + break; + case 10: + aType = VTK_QUADRATIC_TETRA; + break; + case 13: + aType = VTK_QUADRATIC_PYRAMID; + break; + case 15: + aType = VTK_QUADRATIC_WEDGE; + break; + case 20: + aType = VTK_QUADRATIC_HEXAHEDRON; + break; + default: + aType = VTK_HEXAHEDRON; + break; + } + return aType; } diff --git a/src/SMDS/SMDS_VtkVolume.hxx b/src/SMDS/SMDS_VtkVolume.hxx index 078533ba6..9ee9f81df 100644 --- a/src/SMDS/SMDS_VtkVolume.hxx +++ b/src/SMDS/SMDS_VtkVolume.hxx @@ -7,15 +7,14 @@ #include #include -class SMDS_EXPORT SMDS_VtkVolume:public SMDS_MeshVolume +class SMDS_EXPORT SMDS_VtkVolume: public SMDS_MeshVolume { public: SMDS_VtkVolume(); SMDS_VtkVolume(std::vector nodeIds, SMDS_Mesh* mesh); ~SMDS_VtkVolume(); void init(std::vector nodeIds, SMDS_Mesh* mesh); - bool ChangeNodes(const SMDS_MeshNode* nodes[], - const int nbNodes); + bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes); void Print(std::ostream & OS) const; int NbFaces() const; diff --git a/src/SMDS/chrono.cxx b/src/SMDS/chrono.cxx new file mode 100644 index 000000000..d33856aaa --- /dev/null +++ b/src/SMDS/chrono.cxx @@ -0,0 +1,85 @@ +// Copyright (C) 2006-2010 CEA/DEN, EDF R&D +// +// 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 +// + +#include "chrono.hxx" +#include "utilities.h" + +using namespace std; + +cntStruct* counters::_ctrs = 0; + +counters::counters(int nb) +{ + MESSAGE("counters::counters(int nb)"); + _nbChrono = nb; + _ctrs = new cntStruct[_nbChrono]; + + for (int i=0; i< _nbChrono; i++) + { + _ctrs[i]._ctrNames = 0; + _ctrs[i]._ctrLines = 0; + _ctrs[i]._ctrOccur = 0; + _ctrs[i]._ctrCumul = 0; + } + + MESSAGE("counters::counters()"); +} + +counters::~counters() +{ + stats(); +} + +void counters::stats() +{ + MESSAGE("counters::stats()"); + for (int i=0; i < _nbChrono; i++) + if (_ctrs[i]._ctrOccur) + { + MESSAGE("Compteur[" << i << "]: "<< _ctrs[i]._ctrNames << "[" << _ctrs[i]._ctrLines << "]"); + MESSAGE(" " << _ctrs[i]._ctrOccur); + MESSAGE(" " << _ctrs[i]._ctrCumul); + } +} + + + +chrono::chrono(int i) : _ctr(i), _run(true) +{ + //MESSAGE("chrono::chrono " << _ctr << " " << _run); + _start = clock(); +} + +chrono::~chrono() +{ + if (_run) stop(); +} + +void chrono::stop() +{ + //MESSAGE("chrono::stop " << _ctr << " " << _run); + if (_run) + { + _run = false; + _end = clock(); + double elapse = double(_end - _start)/double(CLOCKS_PER_SEC); + counters::_ctrs[_ctr]._ctrOccur++; + counters::_ctrs[_ctr]._ctrCumul += elapse; + } +} diff --git a/src/SMDS/chrono.hxx b/src/SMDS/chrono.hxx new file mode 100644 index 000000000..c48ec8514 --- /dev/null +++ b/src/SMDS/chrono.hxx @@ -0,0 +1,73 @@ +// Copyright (C) 2006-2010 CEA/DEN, EDF R&D +// +// 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 +// + +#ifndef _CHRONO_HXX_ +#define _CHRONO_HXX_ + +#include +#include +#include +#include + +typedef struct acnt +{ + char* _ctrNames; + int _ctrLines; + int _ctrOccur; + double _ctrCumul; +} cntStruct; + +class counters +{ +public: + static cntStruct *_ctrs; + counters(int nb); + ~counters(); + void stats(); +protected: + int _nbChrono; +}; + +class chrono +{ +public: + chrono(int i); + ~chrono(); + void stop(); +protected: + bool _run; + int _ctr; + clock_t _start, _end; +}; + +#ifdef CHRONODEF +#define CHRONO(i) counters::_ctrs[i]._ctrNames = (char *)__FILE__; \ + counters::_ctrs[i]._ctrLines = __LINE__; \ + chrono aChrono##i(i); + +#define CHRONOSTOP(i) aChrono##i.stop(); + +#else // CHRONODEF + +#define CHRONO(i) +#define CHRONOSTOP(i) + +#endif // CHRONODEF + +#endif // _CHRONO_HXX_ diff --git a/src/SMESH/memoire.h b/src/SMESH/memoire.h index 2754222f1..f9323bc0e 100644 --- a/src/SMESH/memoire.h +++ b/src/SMESH/memoire.h @@ -1,19 +1,18 @@ - #ifndef _MEMOIRE_H_ #define _MEMOIRE_H_ #include #include -void memostat( const char* f, int l); +void memostat(const char* f, int l); -void memostat( const char* f, int l) +void memostat(const char* f, int l) { -/* struct mallinfo mem = mallinfo(); */ -/* std::cerr << f << ":"<< l << " " << mem.arena << " " << mem.ordblks << " " << mem.hblks << " " << mem.hblkhd << " " << mem.uordblks << " " << mem.fordblks << " " << mem.keepcost << std::endl; */ -std::cerr << f << ":"<< l << " --------------------------"<< std::endl; - malloc_stats(); -std::cerr << f << ":"<< l << " --------------------------"<< std::endl; + /* struct mallinfo mem = mallinfo(); */ + /* std::cerr << f << ":"<< l << " " << mem.arena << " " << mem.ordblks << " " << mem.hblks << " " << mem.hblkhd << " " << mem.uordblks << " " << mem.fordblks << " " << mem.keepcost << std::endl; */ + std::cerr << f << ":" << l << " --------------------------" << std::endl; + malloc_stats(); + std::cerr << f << ":" << l << " --------------------------" << std::endl; } #define MEMOSTAT memostat( __FILE__, __LINE__ ) diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index bb77e3bbd..a7afa4c9f 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -1914,7 +1914,7 @@ void SMESHDS_Mesh::compactMesh() myVtkIndex.swap(newVtkToSmds); MESSAGE("myCells.size()=" << myCells.size() << " myIDElements.size()=" << myIDElements.size() << " myVtkIndex.size()=" << myVtkIndex.size() ); - + myGrid->BuildDownwardConnectivity(); // ---TODO: myNodes, myElements in submeshes -- 2.39.2