SMDS_VtkCellIterator::SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) :
_mesh(mesh), _cellId(vtkCellId), _index(0), _type(aType)
{
- //MESSAGE("SMDS_VtkCellIterator " << _type);
- _vtkIdList = vtkIdList::New();
vtkUnstructuredGrid* grid = _mesh->getGrid();
- grid->GetCellPoints(_cellId, _vtkIdList);
- _nbNodes = _vtkIdList->GetNumberOfIds();
- switch (_type)
+ _vtkIdList = vtkIdList::New();
+ const std::vector<int>& interlace = SMDS_MeshCell::fromVtkOrder( aType );
+ if ( interlace.empty() )
{
- case SMDSEntity_Tetra:
- {
- this->exchange(1, 2);
- break;
- }
- case SMDSEntity_Pyramid:
- {
- this->exchange(1, 3);
- break;
- }
- case SMDSEntity_Penta:
- {
- //this->exchange(1, 2);
- //this->exchange(4, 5);
- break;
- }
- case SMDSEntity_Hexa:
- {
- 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;
- }
- case SMDSEntity_Quad_Pyramid:
- {
- 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;
- }
- case SMDSEntity_Quad_Hexa:
- {
- MESSAGE("SMDS_VtkCellIterator 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;
- }
- case SMDSEntity_Polyhedra:
- MESSAGE("SMDS_VtkCellIterator Polyhedra (iterate on actual nodes)");
- break;
- default:
- break;
+ grid->GetCellPoints(_cellId, _vtkIdList);
+ _nbNodes = _vtkIdList->GetNumberOfIds();
+ }
+ else
+ {
+ vtkIdType npts, *pts;
+ grid->GetCellPoints( _cellId, npts, pts );
+ _vtkIdList->SetNumberOfIds( _nbNodes = npts );
+ for (int i = 0; i < _nbNodes; i++)
+ _vtkIdList->SetId(i, pts[interlace[i]]);
}
}
break;
}
case SMDSEntity_Quad_Quadrangle:
+ case SMDSEntity_BiQuad_Quadrangle:
{
static int id[] = { 0, 4, 1, 5, 2, 6, 3, 7 };
ids = id;
+ _nbNodes = 8;
break;
}
case SMDSEntity_Quad_Tetra:
break;
}
case SMDSEntity_Quad_Hexa:
+ case SMDSEntity_TriQuad_Hexa:
{
static int id[] = { 0, 8, 1, 9, 2, 10, 3, 11, 16, 17, 18, 19, 4, 12, 5, 13, 6, 14, 7, 15 };
ids = id;
+ _nbNodes = 20;
break;
}
case SMDSEntity_Polygon:
case SMDSEntity_Quad_Polyhedra:
default:
{
- static int id[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29 };
- ids = id;
- break;
+ // static int id[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ // 25, 26, 27, 28, 29 };
+ // ids = id;
+ // break;
}
}
- //MESSAGE("_nbNodes " << _nbNodes);
- for (int i = 0; i < _nbNodes; i++)
- _vtkIdList->SetId(i, pts[ids[i]]);
+ if ( ids )
+ for (int i = 0; i < _nbNodes; i++)
+ _vtkIdList->SetId(i, pts[ids[i]]);
+ else
+ for (int i = 0; i < _nbNodes; i++)
+ _vtkIdList->SetId(i, pts[i]);
}
SMDS_VtkCellIteratorToUNV::~SMDS_VtkCellIteratorToUNV()
const SMDS_MeshNode*
SMDS_VtkEdge::GetNode(const int ind) const
{
- // TODO optimize !!
- return SMDS_MeshElement::GetNode(ind);
+ vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+ vtkIdType npts, *pts;
+ grid->GetCellPoints( this->myVtkID, npts, pts );
+ return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ ind ]);
}
bool SMDS_VtkEdge::IsQuadratic() const
{
}
-SMDS_VtkFace::SMDS_VtkFace(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
+SMDS_VtkFace::SMDS_VtkFace(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
{
init(nodeIds, mesh);
}
{
}
-void SMDS_VtkFace::init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
+void SMDS_VtkFace::init(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
{
SMDS_MeshFace::init();
vtkUnstructuredGrid* grid = mesh->getGrid();
case 8:
aType = VTK_QUADRATIC_QUAD;
break;
+ case 9:
+ aType = VTK_BIQUADRATIC_QUAD;
+ break;
default:
aType = VTK_POLYGON;
break;
}
- myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]);
+ myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType*) &nodeIds[0]);
mesh->setMyModified();
//MESSAGE("SMDS_VtkFace::init myVtkID " << myVtkID);
}
-void SMDS_VtkFace::initPoly(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
+void SMDS_VtkFace::initPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
{
SMDS_MeshFace::init();
vtkUnstructuredGrid* grid = mesh->getGrid();
myMeshId = mesh->getMeshId();
- myVtkID = grid->InsertNextLinkedCell(VTK_POLYGON, nodeIds.size(), &nodeIds[0]);
+ myVtkID = grid->InsertNextLinkedCell(VTK_POLYGON, nodeIds.size(), (vtkIdType*) &nodeIds[0]);
mesh->setMyModified();
}
break;
case VTK_QUAD:
case VTK_QUADRATIC_QUAD:
+ case VTK_BIQUADRATIC_QUAD:
nbEdges = 4;
break;
case VTK_POLYGON:
const SMDS_MeshNode*
SMDS_VtkFace::GetNode(const int ind) const
{
- return SMDS_MeshElement::GetNode(ind); // --- a optimiser !
+ vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+ vtkIdType npts, *pts;
+ grid->GetCellPoints( this->myVtkID, npts, pts );
+ return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ ind ]);
}
bool SMDS_VtkFace::IsQuadratic() const
{
case VTK_QUADRATIC_TRIANGLE:
case VTK_QUADRATIC_QUAD:
+ case VTK_BIQUADRATIC_QUAD:
return true;
break;
default:
rankFirstMedium = 3; // medium nodes are of rank 3,4,5
break;
case VTK_QUADRATIC_QUAD:
+ case VTK_BIQUADRATIC_QUAD:
rankFirstMedium = 4; // medium nodes are of rank 4,5,6,7
break;
default:
return false;
}
+int SMDS_VtkFace::NbCornerNodes() const
+{
+ vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+ int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
+ vtkIdType aVtkType = grid->GetCellType(myVtkID);
+ if ( aVtkType != VTK_POLYGON )
+ return nbPoints <= 4 ? nbPoints : nbPoints / 2;
+ return nbPoints;
+}
+
SMDSAbs_EntityType SMDS_VtkFace::GetEntityType() const
{
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
- SMDSAbs_EntityType aType = SMDSEntity_Polygon;
- switch (aVtkType)
- {
- case VTK_TRIANGLE:
- aType = SMDSEntity_Triangle;
- break;
- case VTK_QUAD:
- aType = SMDSEntity_Quadrangle;
- break;
- case VTK_QUADRATIC_TRIANGLE:
- aType = SMDSEntity_Quad_Triangle;
- break;
- case VTK_QUADRATIC_QUAD:
- aType = SMDSEntity_Quad_Quadrangle;
- break;
- default:
- aType = SMDSEntity_Polygon;
- }
- return aType;
+ return SMDS_MeshCell::toSmdsType( VTKCellType( aVtkType ));
}
vtkIdType SMDS_VtkFace::GetVtkType() const
{
public:
SMDS_VtkFace();
- SMDS_VtkFace(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+ SMDS_VtkFace(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
~SMDS_VtkFace();
- void init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
- void initPoly(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+ void init(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
+ void initPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes);
void ChangeApex(SMDS_MeshNode* node); // to use only for tmp triangles
void Print(std::ostream & OS) const;
virtual bool IsQuadratic() const;
virtual bool IsPoly() const;
virtual bool IsMediumNode(const SMDS_MeshNode* node) const;
+ virtual int NbCornerNodes() const;
virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const;
{
}
-SMDS_VtkVolume::SMDS_VtkVolume(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
+SMDS_VtkVolume::SMDS_VtkVolume(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
{
init(nodeIds, mesh);
}
* typed used are vtk types (@see vtkCellType.h)
* see GetEntityType() for conversion in SMDS type (@see SMDSAbs_ElementType.hxx)
*/
-void SMDS_VtkVolume::init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
+void SMDS_VtkVolume::init(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
{
SMDS_MeshVolume::init();
vtkUnstructuredGrid* grid = mesh->getGrid();
myMeshId = mesh->getMeshId();
vtkIdType aType = VTK_TETRA;
- switch (nodeIds.size())
+ switch (nodeIds.size()) // cases are in order of usage frequency
{
case 4:
aType = VTK_TETRA;
break;
+ case 8:
+ aType = VTK_HEXAHEDRON;
+ 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 20:
+ aType = VTK_QUADRATIC_HEXAHEDRON;
+ break;
case 13:
aType = VTK_QUADRATIC_PYRAMID;
break;
case 15:
aType = VTK_QUADRATIC_WEDGE;
break;
- case 20:
- aType = VTK_QUADRATIC_HEXAHEDRON;
+ case 12:
+ aType = VTK_HEXAGONAL_PRISM;
+ break;
+ case 27:
+ aType = VTK_TRIQUADRATIC_HEXAHEDRON;
break;
default:
aType = VTK_HEXAHEDRON;
break;
}
- myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]);
+ myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType *) &nodeIds[0]);
mesh->setMyModified();
//MESSAGE("SMDS_VtkVolume::init myVtkID " << myVtkID);
}
//#ifdef VTK_HAVE_POLYHEDRON
-void SMDS_VtkVolume::initPoly(std::vector<vtkIdType> nodeIds, std::vector<int> nbNodesPerFace, SMDS_Mesh* mesh)
+void SMDS_VtkVolume::initPoly(const std::vector<vtkIdType>& nodeIds,
+ const std::vector<int>& nbNodesPerFace,
+ SMDS_Mesh* mesh)
{
SMDS_MeshVolume::init();
//MESSAGE("SMDS_VtkVolume::initPoly");
SMDS_UnstructuredGrid* grid = mesh->getGrid();
- double center[3];
- this->gravityCenter(grid, &nodeIds[0], nodeIds.size(), ¢er[0]);
+ //double center[3];
+ //this->gravityCenter(grid, &nodeIds[0], nodeIds.size(), ¢er[0]);
vector<vtkIdType> ptIds;
- ptIds.clear();
vtkIdType nbFaces = nbNodesPerFace.size();
int k = 0;
for (int i = 0; i < nbFaces; i++)
// - either the user should care of order of nodes or
// - the user should use a service method arranging nodes if he
// don't want or can't to do it by him-self
- // The method below works OK only with planar faces
+ // The method below works OK only with planar faces and convex polyhedrones
//
// double a[3];
// double b[3];
// grid->GetPoints()->GetPoint(nodeIds[k + 2], c);
// bool isFaceForward = this->isForward(a, b, c, center);
//MESSAGE("isFaceForward " << i << " " << isFaceForward);
- vtkIdType *facePts = &nodeIds[k];
+ const vtkIdType *facePts = &nodeIds[k];
//if (isFaceForward)
for (int n = 0; n < nf; n++)
ptIds.push_back(facePts[n]);
}
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
- switch (aVtkType)
+ const std::vector<int>& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( aVtkType ));
+ if ( !interlace.empty() )
{
- case VTK_TETRA:
- this->exchange(nodes, 1, 2);
- break;
- case VTK_QUADRATIC_TETRA:
- this->exchange(nodes, 1, 2);
- this->exchange(nodes, 4, 6);
- this->exchange(nodes, 8, 9);
- break;
- case VTK_PYRAMID:
- this->exchange(nodes, 1, 3);
- break;
- case VTK_WEDGE:
- break;
- case VTK_QUADRATIC_PYRAMID:
- this->exchange(nodes, 1, 3);
- this->exchange(nodes, 5, 8);
- this->exchange(nodes, 6, 7);
- this->exchange(nodes, 10, 12);
- break;
- case VTK_QUADRATIC_WEDGE:
- break;
- case VTK_HEXAHEDRON:
- this->exchange(nodes, 1, 3);
- this->exchange(nodes, 5, 7);
- break;
- case VTK_QUADRATIC_HEXAHEDRON:
- this->exchange(nodes, 1, 3);
- this->exchange(nodes, 5, 7);
- this->exchange(nodes, 8, 11);
- this->exchange(nodes, 9, 10);
- this->exchange(nodes, 12, 15);
- this->exchange(nodes, 13, 14);
- this->exchange(nodes, 17, 19);
- break;
- case VTK_POLYHEDRON:
- default:
- break;
+ ASSERT( interlace.size() == nbNodes );
+ std::vector<const SMDS_MeshNode*> initNodes( nodes, nodes+nbNodes );
+ for ( size_t i = 0; i < interlace.size(); ++i )
+ nodes[i] = initNodes[ interlace[i] ];
}
return true;
}
break;
case VTK_HEXAHEDRON:
case VTK_QUADRATIC_HEXAHEDRON:
+ case VTK_TRIQUADRATIC_HEXAHEDRON:
nbFaces = 6;
break;
case VTK_POLYHEDRON:
nbFaces = nFaces;
break;
}
+ case VTK_HEXAGONAL_PRISM:
+ nbFaces = 8;
+ break;
default:
MESSAGE("invalid volume type")
;
break;
case VTK_HEXAHEDRON:
case VTK_QUADRATIC_HEXAHEDRON:
+ case VTK_TRIQUADRATIC_HEXAHEDRON:
nbEdges = 12;
break;
case VTK_POLYHEDRON:
nbEdges = nbEdges / 2;
break;
}
+ case VTK_HEXAGONAL_PRISM:
+ nbEdges = 18;
+ break;
default:
MESSAGE("invalid volume type")
;
/*! polyhedron only,
* return number of nodes for each face
*/
-const std::vector<int> SMDS_VtkVolume::GetQuantities() const
+std::vector<int> SMDS_VtkVolume::GetQuantities() const
{
vector<int> quantities;
quantities.clear();
*/
const SMDS_MeshNode* SMDS_VtkVolume::GetNode(const int ind) const
{
- // TODO optimize if possible (vtkCellIterator)
- return SMDS_MeshElement::GetNode(ind);
+ vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+ vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+ vtkIdType npts, *pts;
+ grid->GetCellPoints( this->myVtkID, npts, pts );
+ const std::vector<int>& interlace = SMDS_MeshCell::fromVtkOrder( VTKCellType( aVtkType ));
+ return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ interlace.empty() ? ind : interlace[ind]] );
}
bool SMDS_VtkVolume::IsQuadratic() const
case VTK_QUADRATIC_PYRAMID:
case VTK_QUADRATIC_WEDGE:
case VTK_QUADRATIC_HEXAHEDRON:
+ case VTK_TRIQUADRATIC_HEXAHEDRON:
return true;
break;
default:
rankFirstMedium = 6; // medium nodes are of rank 6 to 14
break;
case VTK_QUADRATIC_HEXAHEDRON:
+ case VTK_TRIQUADRATIC_HEXAHEDRON:
rankFirstMedium = 8; // medium nodes are of rank 8 to 19
break;
default:
return false;
}
+int SMDS_VtkVolume::NbCornerNodes() const
+{
+ vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+ int nbN = grid->GetCell(myVtkID)->GetNumberOfPoints();
+ vtkIdType aVtkType = grid->GetCellType(myVtkID);
+ switch (aVtkType)
+ {
+ case VTK_QUADRATIC_TETRA: return 4;
+ case VTK_QUADRATIC_PYRAMID: return 5;
+ case VTK_QUADRATIC_WEDGE: return 6;
+ case VTK_QUADRATIC_HEXAHEDRON:
+ case VTK_TRIQUADRATIC_HEXAHEDRON: return 8;
+ default:;
+ }
+ return nbN;
+}
+
SMDSAbs_EntityType SMDS_VtkVolume::GetEntityType() const
{
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
case VTK_QUADRATIC_HEXAHEDRON:
aType = SMDSEntity_Quad_Hexa;
break;
+ case VTK_TRIQUADRATIC_HEXAHEDRON:
+ aType = SMDSEntity_TriQuad_Hexa;
+ break;
+ case VTK_HEXAGONAL_PRISM:
+ aType = SMDSEntity_Hexagonal_Prism;
+ break;
//#ifdef VTK_HAVE_POLYHEDRON
case VTK_POLYHEDRON:
aType = SMDSEntity_Polyhedra;
return aType;
}
-void SMDS_VtkVolume::gravityCenter(SMDS_UnstructuredGrid* grid, vtkIdType *nodeIds, int nbNodes, double* result)
+void SMDS_VtkVolume::gravityCenter(SMDS_UnstructuredGrid* grid,
+ const vtkIdType * nodeIds,
+ int nbNodes,
+ double* result)
{
for (int j = 0; j < 3; j++)
result[j] = 0;
{
public:
SMDS_VtkVolume();
- SMDS_VtkVolume(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+ SMDS_VtkVolume(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
~SMDS_VtkVolume();
- void init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+ void init(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
//#ifdef VTK_HAVE_POLYHEDRON
- void initPoly(std::vector<vtkIdType> nodeIds, std::vector<int> nbNodesPerFace, SMDS_Mesh* mesh);
+ void initPoly(const std::vector<vtkIdType>& nodeIds,
+ const std::vector<int>& nbNodesPerFace, SMDS_Mesh* mesh);
//#endif
virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes);
virtual bool vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes);
virtual bool IsQuadratic() const;
virtual bool IsPoly() const;
virtual bool IsMediumNode(const SMDS_MeshNode* node) const;
+ virtual int NbCornerNodes() const;
static void gravityCenter(SMDS_UnstructuredGrid* grid,
- vtkIdType *nodeIds,
+ const vtkIdType *nodeIds,
int nbNodes,
double* result);
static bool isForward(double* a,double* b,double* c,double* d);
int NbUniqueNodes() const;
SMDS_ElemIteratorPtr uniqueNodesIterator() const;
- const std::vector<int> GetQuantities() const;
+ std::vector<int> GetQuantities() const;
virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const;