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
/*=========================================================================
- 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"
# define vtkMyDebug(x)
#endif
-vtkCxxRevisionMacro(vtkPVUpdateSuppressor, "$Revision$");
-vtkStandardNewMacro(vtkPVUpdateSuppressor);
+vtkCxxRevisionMacro(vtkPVUpdateSuppressor, "$Revision$")
+;
+vtkStandardNewMacro(vtkPVUpdateSuppressor)
+;
//----------------------------------------------------------------------------
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();
+ // }
}
//----------------------------------------------------------------------------
this->UpdateTimeInitialized = true;
if (this->UpdateTime != utime)
{
- this->Modified();
- this->UpdateTime = utime;
+ this->Modified();
+ this->UpdateTime = utime;
}
}
{
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();
// 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.
this->PipelineUpdateTime.Modified();
}
-
//----------------------------------------------------------------------------
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;
//----------------------------------------------------------------------------
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;
}
/*=========================================================================
- 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
#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:
// 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;
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
# header files
salomeinclude_HEADERS = \
+ chrono.hxx \
ObjectPool.hxx \
SMDS_TypeOfPosition.hxx \
SMDSAbs_ElementType.hxx \
SMESH_SMDS.hxx \
SMDS_MeshInfo.hxx \
SMDS_UnstructuredGrid.hxx \
+ SMDS_Downward.hxx \
SMDS_StdIterator.hxx
lib_LTLIBRARIES = libSMDS.la
dist_libSMDS_la_SOURCES = \
+ chrono.cxx \
SMDS_MeshObject.cxx \
SMDS_MeshElement.cxx \
SMDS_MeshCell.cxx \
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 = \
{
for (int i = _nextFree; i < _maxAvail; i++)
if (_freeList[i] == true)
- {
- return i;
- break;
- }
+ {
+ return i;
+ break;
+ }
return _maxAvail;
}
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;
}
{
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;
+ // }
};
--- /dev/null
+/*
+ * SMDS_Downward.cxx
+ *
+ * Created on: Jun 3, 2010
+ * Author: prascle
+ */
+
+#include "SMDS_Downward.hxx"
+#include "SMDS_Mesh.hxx"
+#include "utilities.h"
+
+#include <vtkCellType.h>
+#include <vtkCellLinks.h>
+
+#include <map>
+
+using namespace std;
+
+// ---------------------------------------------------------------------------
+
+vector<int> 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<int>& 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<int>& 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<SMDS_Down2D*> (_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<int> 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;
+}
+
+// ---------------------------------------------------------------------------
+
--- /dev/null
+/*
+ * SMDS_Downward.hxx
+ *
+ * Created on: Jun 3, 2010
+ * Author: prascle
+ */
+
+#ifndef SMDS_DOWNWARD_HXX_
+#define SMDS_DOWNWARD_HXX_
+
+#include "SMDS_UnstructuredGrid.hxx"
+
+#include <vector>
+#include <set>
+
+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<int> _cellIds; //!< growing size: all the down cell id's, size = _maxId * _nbDownCells
+ std::vector<int> _vtkCellIds; //!< growing size: size = _maxId, either vtkId or -1
+ std::vector<unsigned char> _cellTypes; //!< fixed size: the same vector for all cells of a derived class
+
+ static std::vector<int> _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<int>& vtkIds);
+ int computeVtkCells(int* pts, std::vector<int>& 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<std::vector<int> > _upCellIdsVector; //!< the number of faces sharing an edge is not known
+ std::vector<std::vector<unsigned char> > _upCellTypesVector; //!< the number of faces sharing an edge is not known
+ std::vector<int> _upCellIds; //!< compacted storage after connectivity calculation
+ std::vector<unsigned char> _upCellTypes; //!< compacted storage after connectivity calculation
+ std::vector<int> _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<int> _upCellIds; //!< 2 volumes max. per face
+ std::vector<unsigned char> _upCellTypes; //!< 2 volume types per face
+ std::vector<int> _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_ */
//=======================================================================
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;
}
//=======================================================================
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(id11<id21) return true;
- else if(id11==id21) return (id21<id22);
- else return false;
+ 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 (id11 < id21)
+ return true;
+ else if (id11 == id21)
+ return (id21 < id22);
+ else
+ return false;
}
/*!
*/
const SMDS_MeshNode* SMDS_LinearEdge::GetNode(const int ind) const
{
- return myNodes[ ind ];
+ return myNodes[ind];
}
//=======================================================================
//=======================================================================
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;
}
#include "SMDS_MeshEdge.hxx"
#include <iostream>
-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
myIDElements.clear();
myVtkIndex.clear();
myGrid = SMDS_UnstructuredGrid::New();
+ myGrid->setSMDS_mesh(this);
myGrid->Initialize();
myGrid->Allocate();
vtkPoints* points = vtkPoints::New();
-
#include "SMDS_MeshCell.hxx"
#include "utilities.h"
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()
{
* \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;
//function : SMDS_MeshNodeIDFactory
//purpose :
//=======================================================================
-SMDS_MeshNodeIDFactory::SMDS_MeshNodeIDFactory():
- SMDS_MeshIDFactory(),
- myMin(0), myMax(0)
+SMDS_MeshNodeIDFactory::SMDS_MeshNodeIDFactory() :
+ SMDS_MeshIDFactory(), myMin(0), myMax(0)
{
}
//=======================================================================
bool SMDS_MeshNodeIDFactory::BindID(int ID, SMDS_MeshElement * elem)
{
- updateMinMax (ID);
+ updateMinMax(ID);
return true;
}
//=======================================================================
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);
}
//=======================================================================
{
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
}
//=======================================================================
SMDS_ElemIteratorPtr SMDS_MeshNodeIDFactory::elementsIterator() const
{
- return myMesh->elementsIterator(SMDSAbs_Node);
+ return myMesh->elementsIterator(SMDSAbs_Node);
}
void SMDS_MeshNodeIDFactory::Clear()
class SMDS_MeshElement;
-class SMDS_EXPORT SMDS_MeshNodeIDFactory:public SMDS_MeshIDFactory
+class SMDS_EXPORT SMDS_MeshNodeIDFactory: public SMDS_MeshIDFactory
{
public:
SMDS_MeshNodeIDFactory();
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;
-
-
+#define CHRONODEF
#include "SMDS_UnstructuredGrid.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_MeshInfo.hxx"
+#include "SMDS_Downward.hxx"
+
#include "utilities.h"
#include <vtkCellArray.h>
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<int>& idNodesOldToNew, int newNodeSize,
- std::vector<int>& idCellsOldToNew, int newCellSize)
+ std::vector<int>& 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; i<oldCellSize; i++)
+ MESSAGE("------------------------- SMDS_UnstructuredGrid::compactGrid " << newNodeSize << " " << newCellSize);CHRONO(1);
+ 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; 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<int>& 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<int>& idCellsOldToNew,
+ std::vector<int>& 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<int>& 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<end; j++)
- idNodesOldToNew[j] = alreadyCopied++;
- }
+ // ASSERT((vtkCellId >= 0) && (vtkCellId < _cellIdToDownId.size()));
+ _cellIdToDownId[vtkCellId] = downId;
}
-void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes,
- std::vector<int>& idCellsOldToNew,
- std::vector<int>& 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; j<end; j++)
- {
- 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++;
- }
+ 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<SMDS_Down2D*> (_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<SMDS_Down3D*> (_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<SMDS_Down2D*> (_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<SMDS_Down3D*> (_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<SMDS_Down1D*> (_downArray[vtkEdgeType]);
+ downEdge->setNodes(connEdgeId, vtkEdgeId);
+ vector<int> 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<SMDS_Down2D*> (_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<int> vtkIds;
+ unsigned char vtkEdgeType = edgesWithNodes.elems[iedge].vtkType;
+ int *pts = &edgesWithNodes.elems[iedge].nodeIds[0];
+ SMDS_Down1D* downEdge = static_cast<SMDS_Down1D*> (_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<SMDS_Down2D*> (_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<SMDS_Down2D*> (_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<vector int>> by a single vector<int>
+ // 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();
}
#include <vector>
#include <vtkUnstructuredGrid.h>
+#include "chrono.hxx"
+
+class SMDS_Downward;
+class SMDS_Mesh;
class SMDS_UnstructuredGrid: public vtkUnstructuredGrid
{
public:
- void compactGrid(std::vector<int>& idNodesOldToNew, int newNodeSize,
- std::vector<int>& 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<int>& idNodesOldToNew, int newNodeSize, std::vector<int>& 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<int>& idNodesOldToNew,
- int& alreadyCopied,
- int start,
- int end);
- void copyBloc(vtkUnsignedCharArray *newTypes,
- std::vector<int>& idCellsOldToNew,
- std::vector<int>& idNodesOldToNew,
- vtkCellArray* newConnectivity,
- vtkIdTypeArray* newLocations,
- vtkIdType* pointsCell,
- int& alreadyCopied,
- int start,
- int end);
-
+ SMDS_UnstructuredGrid();
+ ~SMDS_UnstructuredGrid();
+ void copyNodes(vtkPoints *newPoints, std::vector<int>& idNodesOldToNew, int& alreadyCopied, int start, int end);
+ void copyBloc(vtkUnsignedCharArray *newTypes, std::vector<int>& idCellsOldToNew, std::vector<int>& idNodesOldToNew,
+ vtkCellArray* newConnectivity, vtkIdTypeArray* newLocations, vtkIdType* pointsCell, int& alreadyCopied,
+ int start, int end);
+
+ SMDS_Mesh *_mesh;
+ std::vector<int> _cellIdToDownId; //!< convert vtk Id to downward[vtkType] id, initialized with -1
+ std::vector<unsigned char> _downTypes;
+ std::vector<SMDS_Downward*> _downArray;
+ counters *_counters;
};
#endif /* _SMDS_UNSTRUCTUREDGRID_HXX */
#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();
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;
}
#include <vtkCell.h>
#include <vtkIdList.h>
-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;
SMDS_VtkEdge::SMDS_VtkEdge(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
{
- init(nodeIds, mesh);
+ init(nodeIds, mesh);
}
SMDS_VtkEdge::~SMDS_VtkEdge()
void SMDS_VtkEdge::init(std::vector<vtkIdType> 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;
}
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);
+ }
}
SMDS_VtkFace::SMDS_VtkFace(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
{
- init(nodeIds, mesh);
+ init(nodeIds, mesh);
}
SMDS_VtkFace::~SMDS_VtkFace()
void SMDS_VtkFace::init(std::vector<vtkIdType> 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;
}
/*!
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);
+ }
}
-
#include "SMDS_VtkVolume.hxx"
#include "SMDS_MeshNode.hxx"
#include "SMDS_Mesh.hxx"
#include <vector>
-
SMDS_VtkVolume::SMDS_VtkVolume()
{
}
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;
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
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;
}
#include <vtkUnstructuredGrid.h>
#include <vector>
-class SMDS_EXPORT SMDS_VtkVolume:public SMDS_MeshVolume
+class SMDS_EXPORT SMDS_VtkVolume: public SMDS_MeshVolume
{
public:
SMDS_VtkVolume();
SMDS_VtkVolume(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
~SMDS_VtkVolume();
void init(std::vector<vtkIdType> 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;
--- /dev/null
+// 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;
+ }
+}
--- /dev/null
+// 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 <vector>
+#include <string>
+#include <iostream>
+#include <ctime>
+
+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_
-
#ifndef _MEMOIRE_H_
#define _MEMOIRE_H_
#include <malloc.h>
#include <iostream>
-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__ )
myVtkIndex.swap(newVtkToSmds);
MESSAGE("myCells.size()=" << myCells.size() << " myIDElements.size()=" << myIDElements.size() << " myVtkIndex.size()=" << myVtkIndex.size() );
-
+ myGrid->BuildDownwardConnectivity();
// ---TODO: myNodes, myElements in submeshes