mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-12-29 19:00:35 +05:00
smds_memimp_joints
This commit is contained in:
parent
0c16e57723
commit
4eb3d62127
@ -869,6 +869,19 @@ module SMESH
|
||||
*/
|
||||
boolean Make2DMeshFrom3D();
|
||||
|
||||
/*!
|
||||
* \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
|
||||
* The list of groups must describe a partition of the mesh volumes.
|
||||
* The nodes of the internal faces at the boundaries of the groups are doubled.
|
||||
* In option, the internal faces are replaced by flat elements.
|
||||
* Triangles are transformed in prisms, and quadrangles in hexahedrons.
|
||||
* \param theDomains - list of groups of volumes
|
||||
* \param createJointElems - if TRUE, create the elements
|
||||
* \return TRUE if operation has been completed successfully, FALSE otherwise
|
||||
*/
|
||||
boolean DoubleNodesOnGroupBoundaries( in ListOfGroups theDomains,
|
||||
in boolean createJointElems );
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -265,6 +265,12 @@ const unsigned char* SMDS_Down1D::getUpTypes(int cellId)
|
||||
return &_upCellTypes[_upCellIndex[cellId]];
|
||||
}
|
||||
|
||||
void SMDS_Down1D::getNodeIds(int cellId, std::set<int>& nodeSet)
|
||||
{
|
||||
for (int i = 0; i < _nbDownCells; i++)
|
||||
nodeSet.insert(_cellIds[_nbDownCells * cellId + i]);
|
||||
}
|
||||
|
||||
int SMDS_Down1D::getNodeSet(int cellId, int* nodeSet)
|
||||
{
|
||||
for (int i = 0; i < _nbDownCells; i++)
|
||||
@ -481,6 +487,16 @@ const unsigned char* SMDS_Down2D::getUpTypes(int cellId)
|
||||
return &_upCellTypes[2 * cellId];
|
||||
}
|
||||
|
||||
void SMDS_Down2D::getNodeIds(int cellId, std::set<int>& nodeSet)
|
||||
{
|
||||
for (int i = 0; i < _nbDownCells; i++)
|
||||
{
|
||||
int downCellId = _cellIds[_nbDownCells * cellId + i];
|
||||
unsigned char cellType = _cellTypes[i];
|
||||
this->_grid->getDownArray(cellType)->getNodeIds(downCellId, nodeSet);
|
||||
}
|
||||
}
|
||||
|
||||
/*! 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.
|
||||
@ -753,6 +769,16 @@ const unsigned char* SMDS_Down3D::getUpTypes(int cellId)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SMDS_Down3D::getNodeIds(int cellId, std::set<int>& nodeSet)
|
||||
{
|
||||
int vtkId = this->_vtkCellIds[cellId];
|
||||
vtkIdType npts = 0;
|
||||
vtkIdType *nodes; // will refer to the point id's of the volume
|
||||
_grid->GetCellPoints(vtkId, npts, nodes);
|
||||
for (int i = 0; i < npts; i++)
|
||||
nodeSet.insert(nodes[i]);
|
||||
}
|
||||
|
||||
int SMDS_Down3D::FindFaceByNodes(int cellId, ElemByNodesType& faceByNodes)
|
||||
{
|
||||
int *faces = &_cellIds[_nbDownCells * cellId];
|
||||
@ -1074,6 +1100,37 @@ SMDS_DownTetra::~SMDS_DownTetra()
|
||||
{
|
||||
}
|
||||
|
||||
void SMDS_DownTetra::getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes)
|
||||
{
|
||||
set<int> setNodes;
|
||||
setNodes.clear();
|
||||
for (int i = 0; i < orderedNodes.size(); i++)
|
||||
setNodes.insert(orderedNodes[i]);
|
||||
//MESSAGE("cellId = " << cellId);
|
||||
|
||||
vtkIdType npts = 0;
|
||||
vtkIdType *nodes; // will refer to the point id's of the volume
|
||||
_grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
|
||||
|
||||
set<int> tofind;
|
||||
int ids[12] = { 0, 1, 2, 0, 1, 3, 0, 2, 3, 1, 2, 3 };
|
||||
for (int k = 0; k < 4; k++)
|
||||
{
|
||||
tofind.clear();
|
||||
for (int i = 0; i < 3; i++)
|
||||
tofind.insert(nodes[ids[3 * k + i]]);
|
||||
if (setNodes == tofind)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
orderedNodes[i] = nodes[ids[3 * k + i]];
|
||||
return;
|
||||
}
|
||||
}
|
||||
MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
|
||||
MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
|
||||
MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
|
||||
}
|
||||
|
||||
void SMDS_DownTetra::addDownCell(int cellId, int lowCellId, unsigned char aType)
|
||||
{
|
||||
//ASSERT((cellId >=0)&& (cellId < _maxId));
|
||||
@ -1150,6 +1207,11 @@ SMDS_DownQuadTetra::~SMDS_DownQuadTetra()
|
||||
{
|
||||
}
|
||||
|
||||
void SMDS_DownQuadTetra::getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void SMDS_DownQuadTetra::addDownCell(int cellId, int lowCellId, unsigned char aType)
|
||||
{
|
||||
//ASSERT((cellId >=0)&& (cellId < _maxId));
|
||||
@ -1241,6 +1303,11 @@ SMDS_DownPyramid::~SMDS_DownPyramid()
|
||||
{
|
||||
}
|
||||
|
||||
void SMDS_DownPyramid::getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void SMDS_DownPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType)
|
||||
{
|
||||
//ASSERT((cellId >=0) && (cellId < _maxId));
|
||||
@ -1340,6 +1407,11 @@ SMDS_DownQuadPyramid::~SMDS_DownQuadPyramid()
|
||||
{
|
||||
}
|
||||
|
||||
void SMDS_DownQuadPyramid::getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void SMDS_DownQuadPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType)
|
||||
{
|
||||
//ASSERT((cellId >=0) && (cellId < _maxId));
|
||||
@ -1456,6 +1528,11 @@ SMDS_DownPenta::~SMDS_DownPenta()
|
||||
{
|
||||
}
|
||||
|
||||
void SMDS_DownPenta::getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void SMDS_DownPenta::addDownCell(int cellId, int lowCellId, unsigned char aType)
|
||||
{
|
||||
//ASSERT((cellId >=0) && (cellId < _maxId));
|
||||
@ -1559,6 +1636,11 @@ SMDS_DownQuadPenta::~SMDS_DownQuadPenta()
|
||||
{
|
||||
}
|
||||
|
||||
void SMDS_DownQuadPenta::getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void SMDS_DownQuadPenta::addDownCell(int cellId, int lowCellId, unsigned char aType)
|
||||
{
|
||||
//ASSERT((cellId >=0) && (cellId < _maxId));
|
||||
@ -1682,6 +1764,11 @@ SMDS_DownHexa::~SMDS_DownHexa()
|
||||
{
|
||||
}
|
||||
|
||||
void SMDS_DownHexa::getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void SMDS_DownHexa::addDownCell(int cellId, int lowCellId, unsigned char aType)
|
||||
{
|
||||
//ASSERT((cellId >=0)&& (cellId < _maxId));
|
||||
@ -1780,6 +1867,11 @@ SMDS_DownQuadHexa::~SMDS_DownQuadHexa()
|
||||
{
|
||||
}
|
||||
|
||||
void SMDS_DownQuadHexa::getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void SMDS_DownQuadHexa::addDownCell(int cellId, int lowCellId, unsigned char aType)
|
||||
{
|
||||
//ASSERT((cellId >=0)&& (cellId < _maxId));
|
||||
|
@ -26,6 +26,28 @@ typedef struct
|
||||
int nbElems;
|
||||
} ListElemByNodesType; // TODO resize for polyhedrons
|
||||
|
||||
class DownIdType
|
||||
{
|
||||
public:
|
||||
DownIdType(int a, unsigned char b) :
|
||||
cellId(a), cellType(b)
|
||||
{
|
||||
}
|
||||
int cellId;
|
||||
unsigned char cellType;
|
||||
};
|
||||
|
||||
struct DownIdCompare
|
||||
{
|
||||
bool operator ()(const DownIdType e1, const DownIdType e2) const
|
||||
{
|
||||
if (e1.cellId == e2.cellId)
|
||||
return (e1.cellType < e2.cellType);
|
||||
else
|
||||
return (e1.cellId < e2.cellId);
|
||||
}
|
||||
};
|
||||
|
||||
class SMDS_Downward
|
||||
{
|
||||
friend class SMDS_UnstructuredGrid;
|
||||
@ -38,6 +60,7 @@ public:
|
||||
virtual int getNumberOfUpCells(int cellId) = 0;
|
||||
virtual const int* getUpCells(int cellId) = 0;
|
||||
virtual const unsigned char* getUpTypes(int cellId) = 0;
|
||||
virtual void getNodeIds(int cellId, std::set<int>& nodeSet) = 0;
|
||||
int getVtkCellId(int cellId)
|
||||
{
|
||||
return _vtkCellIds[cellId];
|
||||
@ -75,6 +98,7 @@ public:
|
||||
virtual int getNumberOfUpCells(int cellId);
|
||||
virtual const int* getUpCells(int cellId);
|
||||
virtual const unsigned char* getUpTypes(int cellId);
|
||||
virtual void getNodeIds(int cellId, std::set<int>& nodeSet);
|
||||
protected:
|
||||
SMDS_Down1D(SMDS_UnstructuredGrid *grid, int nbDownCells);
|
||||
~SMDS_Down1D();
|
||||
@ -105,6 +129,7 @@ public:
|
||||
virtual int getNumberOfUpCells(int cellId);
|
||||
virtual const int* getUpCells(int cellId);
|
||||
virtual const unsigned char* getUpTypes(int cellId);
|
||||
virtual void getNodeIds(int cellId, std::set<int>& nodeSet);
|
||||
protected:
|
||||
SMDS_Down2D(SMDS_UnstructuredGrid *grid, int nbDownCells);
|
||||
~SMDS_Down2D();
|
||||
@ -134,6 +159,8 @@ public:
|
||||
virtual int getNumberOfUpCells(int cellId);
|
||||
virtual const int* getUpCells(int cellId);
|
||||
virtual const unsigned char* getUpTypes(int cellId);
|
||||
virtual void getNodeIds(int cellId, std::set<int>& nodeSet);
|
||||
virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes) = 0;
|
||||
protected:
|
||||
SMDS_Down3D(SMDS_UnstructuredGrid *grid, int nbDownCells);
|
||||
~SMDS_Down3D();
|
||||
@ -225,6 +252,7 @@ class SMDS_DownTetra: public SMDS_Down3D
|
||||
{
|
||||
friend class SMDS_UnstructuredGrid;
|
||||
public:
|
||||
virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes);
|
||||
protected:
|
||||
SMDS_DownTetra(SMDS_UnstructuredGrid *grid);
|
||||
~SMDS_DownTetra();
|
||||
@ -236,6 +264,7 @@ class SMDS_DownQuadTetra: public SMDS_Down3D
|
||||
{
|
||||
friend class SMDS_UnstructuredGrid;
|
||||
public:
|
||||
virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes);
|
||||
protected:
|
||||
SMDS_DownQuadTetra(SMDS_UnstructuredGrid *grid);
|
||||
~SMDS_DownQuadTetra();
|
||||
@ -247,6 +276,7 @@ class SMDS_DownPyramid: public SMDS_Down3D
|
||||
{
|
||||
friend class SMDS_UnstructuredGrid;
|
||||
public:
|
||||
virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes);
|
||||
protected:
|
||||
SMDS_DownPyramid(SMDS_UnstructuredGrid *grid);
|
||||
~SMDS_DownPyramid();
|
||||
@ -258,6 +288,7 @@ class SMDS_DownQuadPyramid: public SMDS_Down3D
|
||||
{
|
||||
friend class SMDS_UnstructuredGrid;
|
||||
public:
|
||||
virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes);
|
||||
protected:
|
||||
SMDS_DownQuadPyramid(SMDS_UnstructuredGrid *grid);
|
||||
~SMDS_DownQuadPyramid();
|
||||
@ -267,18 +298,21 @@ protected:
|
||||
|
||||
class SMDS_DownPenta: public SMDS_Down3D
|
||||
{
|
||||
friend class SMDS_UnstructuredGrid;
|
||||
public:
|
||||
virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes);
|
||||
protected:
|
||||
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:
|
||||
virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes);
|
||||
protected:
|
||||
SMDS_DownQuadPenta(SMDS_UnstructuredGrid *grid);
|
||||
~SMDS_DownQuadPenta();
|
||||
@ -290,6 +324,7 @@ class SMDS_DownHexa: public SMDS_Down3D
|
||||
{
|
||||
friend class SMDS_UnstructuredGrid;
|
||||
public:
|
||||
virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes);
|
||||
protected:
|
||||
SMDS_DownHexa(SMDS_UnstructuredGrid *grid);
|
||||
~SMDS_DownHexa();
|
||||
@ -301,6 +336,7 @@ class SMDS_DownQuadHexa: public SMDS_Down3D
|
||||
{
|
||||
friend class SMDS_UnstructuredGrid;
|
||||
public:
|
||||
virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes);
|
||||
protected:
|
||||
SMDS_DownQuadHexa(SMDS_UnstructuredGrid *grid);
|
||||
~SMDS_DownQuadHexa();
|
||||
|
@ -20,7 +20,7 @@
|
||||
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
//
|
||||
|
||||
// SMESH SMDS : implementaion of Salome mesh data structure
|
||||
// SMESH SMDS : implementation of Salome mesh data structure
|
||||
//
|
||||
#ifndef _SMDS_FaceOfEdges_HeaderFile
|
||||
#define _SMDS_FaceOfEdges_HeaderFile
|
||||
@ -48,6 +48,7 @@ class SMDS_EXPORT SMDS_FaceOfEdges:public SMDS_MeshFace
|
||||
|
||||
SMDSAbs_ElementType GetType() const;
|
||||
virtual SMDSAbs_EntityType GetEntityType() const;
|
||||
virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) {return false;};
|
||||
int NbNodes() const;
|
||||
int NbEdges() const;
|
||||
int NbFaces() const;
|
||||
|
@ -43,6 +43,10 @@ public:
|
||||
{
|
||||
return SMDSEntity_Edge;
|
||||
}
|
||||
virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int NbNodes() const;
|
||||
int NbEdges() const;
|
||||
friend bool operator<(const SMDS_LinearEdge& e1, const SMDS_LinearEdge& e2);
|
||||
|
@ -209,6 +209,7 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
|
||||
if(!node){
|
||||
//if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
|
||||
//SMDS_MeshNode * node=new SMDS_MeshNode(ID, myMeshId, -1, x, y, z);
|
||||
myNodeIDFactory->adjustMaxId(ID);
|
||||
SMDS_MeshNode * node = myNodePool->getNew();
|
||||
node->init(ID, myMeshId, -1, x, y, z);
|
||||
if (ID >= myNodes.size())
|
||||
@ -1453,6 +1454,7 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
|
||||
const SMDS_MeshNode * nodes[],
|
||||
const int nbnodes)
|
||||
{
|
||||
// TODO use polymorphism, check number of nodes and type are unchanged.
|
||||
MYASSERT(0); // REVOIR LES TYPES
|
||||
// keep current nodes of elem
|
||||
set<const SMDS_MeshElement*> oldNodes;
|
||||
@ -1465,47 +1467,51 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
|
||||
|
||||
// change nodes
|
||||
bool Ok = false;
|
||||
SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
|
||||
switch ( elem->GetType() )
|
||||
{
|
||||
case SMDSAbs_0DElement: {
|
||||
if ( SMDS_Mesh0DElement* elem0d = dynamic_cast<SMDS_Mesh0DElement*>( elem ))
|
||||
Ok = elem0d->ChangeNode( nodes[0] );
|
||||
break;
|
||||
}
|
||||
case SMDSAbs_Edge: {
|
||||
if ( nbnodes == 2 ) {
|
||||
if ( SMDS_VtkEdge* edge = dynamic_cast<SMDS_VtkEdge*>( elem ))
|
||||
Ok = edge->ChangeNodes( nodes[0], nodes[1] );
|
||||
}
|
||||
else if ( nbnodes == 3 ) {
|
||||
if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
|
||||
Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SMDSAbs_Face: {
|
||||
if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
|
||||
Ok = face->ChangeNodes( nodes, nbnodes );
|
||||
else
|
||||
if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
|
||||
Ok = QF->ChangeNodes( nodes, nbnodes );
|
||||
else
|
||||
if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
|
||||
Ok = face->ChangeNodes(nodes, nbnodes);
|
||||
break;
|
||||
}
|
||||
case SMDSAbs_Volume: {
|
||||
if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
|
||||
Ok = vol->ChangeNodes( nodes, nbnodes );
|
||||
else
|
||||
if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
|
||||
Ok = QV->ChangeNodes( nodes, nbnodes );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MESSAGE ( "WRONG ELEM TYPE");
|
||||
}
|
||||
SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
|
||||
if (cell)
|
||||
Ok = cell->ChangeNodes(nodes, nbnodes);
|
||||
|
||||
// SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
|
||||
// switch ( elem->GetType() )
|
||||
// {
|
||||
// case SMDSAbs_0DElement: {
|
||||
// if ( SMDS_Mesh0DElement* elem0d = dynamic_cast<SMDS_Mesh0DElement*>( elem ))
|
||||
// Ok = elem0d->ChangeNode( nodes[0] );
|
||||
// break;
|
||||
// }
|
||||
// case SMDSAbs_Edge: {
|
||||
// if ( nbnodes == 2 ) {
|
||||
// if ( SMDS_VtkEdge* edge = dynamic_cast<SMDS_VtkEdge*>( elem ))
|
||||
// Ok = edge->ChangeNodes( nodes[0], nodes[1] );
|
||||
// }
|
||||
// else if ( nbnodes == 3 ) {
|
||||
// if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
|
||||
// Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// case SMDSAbs_Face: {
|
||||
// if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
|
||||
// Ok = face->ChangeNodes( nodes, nbnodes );
|
||||
// else
|
||||
// if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
|
||||
// Ok = QF->ChangeNodes( nodes, nbnodes );
|
||||
// else
|
||||
// if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
|
||||
// Ok = face->ChangeNodes(nodes, nbnodes);
|
||||
// break;
|
||||
// }
|
||||
// case SMDSAbs_Volume: {
|
||||
// if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
|
||||
// Ok = vol->ChangeNodes( nodes, nbnodes );
|
||||
// else
|
||||
// if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
|
||||
// Ok = QV->ChangeNodes( nodes, nbnodes );
|
||||
// break;
|
||||
// }
|
||||
// default:
|
||||
// MESSAGE ( "WRONG ELEM TYPE");
|
||||
// }
|
||||
|
||||
if ( Ok ) { // update InverseElements
|
||||
|
||||
@ -1516,7 +1522,7 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
|
||||
it = oldNodes.find( nodes[i] );
|
||||
if ( it == oldNodes.end() )
|
||||
// new node
|
||||
const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
|
||||
const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( cell );
|
||||
else
|
||||
// remove from oldNodes a node that remains in elem
|
||||
oldNodes.erase( it );
|
||||
@ -1526,7 +1532,7 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
|
||||
{
|
||||
SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
|
||||
(const_cast<SMDS_MeshElement *>( *it ));
|
||||
n->RemoveInverseElement( elem );
|
||||
n->RemoveInverseElement( cell );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ public:
|
||||
static std::vector<SMDS_Mesh*> _meshList;
|
||||
|
||||
//! actual nodes coordinates, cells definition and reverse connectivity are stored in a vtkUnstructuredGrid
|
||||
inline vtkUnstructuredGrid* getGrid() {return myGrid; };
|
||||
inline SMDS_UnstructuredGrid* getGrid() {return myGrid; };
|
||||
inline int getMeshId() {return myMeshId; };
|
||||
|
||||
SMDS_NodeIteratorPtr nodesIterator(bool idInceasingOrder=false) const;
|
||||
@ -573,7 +573,6 @@ public:
|
||||
void incrementCellsCapacity(int nbCells);
|
||||
void adjustStructure();
|
||||
void dumpGrid(string ficdump="dumpGrid");
|
||||
|
||||
static int chunkSize;
|
||||
|
||||
protected:
|
||||
@ -608,8 +607,9 @@ protected:
|
||||
inline void adjustmyCellsCapacity(int ID)
|
||||
{
|
||||
assert(ID >= 0);
|
||||
myElementIDFactory->adjustMaxId(ID);
|
||||
if (ID >= myCells.size())
|
||||
myCells.resize(ID+SMDS_Mesh::chunkSize,0);
|
||||
myCells.resize(ID+SMDS_Mesh::chunkSize,0);
|
||||
};
|
||||
|
||||
// Fields PRIVATE
|
||||
|
@ -35,6 +35,7 @@ class SMDS_EXPORT SMDS_Mesh0DElement: public SMDS_MeshCell
|
||||
public:
|
||||
SMDS_Mesh0DElement (const SMDS_MeshNode * node);
|
||||
bool ChangeNode (const SMDS_MeshNode * node);
|
||||
virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) {return false;};
|
||||
void Print (std::ostream & OS) const;
|
||||
|
||||
SMDSAbs_ElementType GetType() const;
|
||||
|
@ -12,6 +12,9 @@ class SMDS_EXPORT SMDS_MeshCell: public SMDS_MeshElement
|
||||
public:
|
||||
SMDS_MeshCell();
|
||||
virtual ~SMDS_MeshCell();
|
||||
|
||||
virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)= 0;
|
||||
|
||||
inline void setVtkId(int vtkId)
|
||||
{
|
||||
myVtkID = vtkId;
|
||||
|
@ -111,3 +111,4 @@ void SMDS_MeshIDFactory::emptyPool(int maxId)
|
||||
myMaxID = maxId-1;
|
||||
myPoolOfID.clear();
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
SMDS_Mesh* GetMesh();
|
||||
inline bool isPoolIdEmpty() { return myPoolOfID.empty(); };
|
||||
void emptyPool(int maxId);
|
||||
inline void adjustMaxId(int ID) { if (ID > myMaxID) myMaxID = ID;};
|
||||
protected:
|
||||
SMDS_MeshIDFactory();
|
||||
int myMaxID;
|
||||
|
@ -303,9 +303,10 @@ void SMDS_UnstructuredGrid::setCellIdToDownId(int vtkCellId, int downId)
|
||||
* Downward connectivity is no more valid if vtkUnstructuredGrid is modified.
|
||||
*
|
||||
*/
|
||||
void SMDS_UnstructuredGrid::BuildDownwardConnectivity()
|
||||
void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges)
|
||||
{
|
||||
MESSAGE("SMDS_UnstructuredGrid::BuildDownwardConnectivity");CHRONO(2);
|
||||
// TODO calcul partiel sans edges
|
||||
|
||||
// --- erase previous data if any
|
||||
|
||||
@ -665,3 +666,107 @@ void SMDS_UnstructuredGrid::BuildDownwardConnectivity()
|
||||
}CHRONOSTOP(24);CHRONOSTOP(2);
|
||||
_counters->stats();
|
||||
}
|
||||
|
||||
/*! Get the neighbors of a cell.
|
||||
* Only the neighbors having the dimension of the cell are taken into account
|
||||
* (neighbors of a volume are the volumes sharing a face with this volume,
|
||||
* neighbors of a face are the faces sharing an edge with this face...).
|
||||
* @param neighborsVtkIds vector of neighbors vtk id's to fill (reserve enough space).
|
||||
* @param downIds downward id's of cells of dimension n-1, to fill (reserve enough space).
|
||||
* @param downTypes vtk types of cells of dimension n-1, to fill (reserve enough space).
|
||||
* @param vtkId the vtk id of the cell
|
||||
* @return number of neighbors
|
||||
*/
|
||||
int SMDS_UnstructuredGrid::GetNeighbors(int* neighborsVtkIds, int* downIds, unsigned char* downTypes, int vtkId)
|
||||
{
|
||||
int vtkType = this->GetCellType(vtkId);
|
||||
int cellDim = SMDS_Downward::getCellDimension(vtkType);
|
||||
if (cellDim != 3)
|
||||
return 0; // TODO voisins des faces ou edges
|
||||
int cellId = this->_cellIdToDownId[vtkId];
|
||||
|
||||
int nbCells = _downArray[vtkType]->getNumberOfDownCells(cellId);
|
||||
const int *downCells = _downArray[vtkType]->getDownCells(cellId);
|
||||
const unsigned char* downTyp = _downArray[vtkType]->getDownTypes(cellId);
|
||||
|
||||
// --- iteration on faces of the 3D cell.
|
||||
|
||||
int nb = 0;
|
||||
for (int i = 0; i < nbCells; i++)
|
||||
{
|
||||
int downId = downCells[i];
|
||||
int cellType = downTyp[i];
|
||||
int nbUp = _downArray[cellType]->getNumberOfUpCells(downId);
|
||||
const int *upCells = _downArray[cellType]->getUpCells(downId);
|
||||
const unsigned char* upTypes = _downArray[cellType]->getUpTypes(downId);
|
||||
|
||||
// --- max 2 upCells, one is this cell, the other is a neighbor
|
||||
|
||||
for (int j = 0; j < nbUp; j++)
|
||||
{
|
||||
if ((upCells[j] == cellId) && (upTypes[j] == vtkType))
|
||||
continue;
|
||||
int vtkNeighbor = _downArray[upTypes[j]]->getVtkCellId(upCells[j]);
|
||||
neighborsVtkIds[nb] = vtkNeighbor;
|
||||
downIds[nb] = downId;
|
||||
downTypes[nb] = cellType;
|
||||
nb++;
|
||||
}
|
||||
if (nb >= NBMAXNEIGHBORS)
|
||||
assert(0);
|
||||
}
|
||||
return nb;
|
||||
}
|
||||
|
||||
/*! get the node id's of a cell.
|
||||
* The cell is defined by it's downward connectivity id and type.
|
||||
* @param nodeSet set of of vtk node id's to fill.
|
||||
* @param downId downward connectivity id of the cell.
|
||||
* @param downType type of cell.
|
||||
*/
|
||||
void SMDS_UnstructuredGrid::GetNodeIds(std::set<int>& nodeSet, int downId, unsigned char downType)
|
||||
{
|
||||
_downArray[downType]->getNodeIds(downId, nodeSet);
|
||||
}
|
||||
|
||||
/*! change some nodes in cell without modifying type or internal connectivity.
|
||||
* Nodes inverse connectivity is maintained up to date.
|
||||
* @param vtkVolId vtk id of the cell
|
||||
* @param localClonedNodeIds map old node id to new node id.
|
||||
*/
|
||||
void SMDS_UnstructuredGrid::ModifyCellNodes(int vtkVolId, std::map<int, int> localClonedNodeIds)
|
||||
{
|
||||
vtkIdType npts = 0;
|
||||
vtkIdType *pts; // will refer to the point id's of the face
|
||||
this->GetCellPoints(vtkVolId, npts, pts);
|
||||
for (int i = 0; i < npts; i++)
|
||||
{
|
||||
if (localClonedNodeIds.count(pts[i]))
|
||||
{
|
||||
vtkIdType oldpt = pts[i];
|
||||
pts[i] = localClonedNodeIds[oldpt];
|
||||
//MESSAGE(oldpt << " --> " << pts[i]);
|
||||
//this->RemoveReferenceToCell(oldpt, vtkVolId);
|
||||
//this->AddReferenceToCell(pts[i], vtkVolId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! Create a volume (prism or hexahedron) by duplication of a face.
|
||||
* the nodes of the new face are already created.
|
||||
* @param vtkVolId vtk id of a volume containing the face, to get an orientation for the face.
|
||||
* @param localClonedNodeIds map old node id to new node id.
|
||||
* @return vtk id of the new volume.
|
||||
*/
|
||||
int SMDS_UnstructuredGrid::getOrderedNodesOfFace(int vtkVolId, std::vector<int>& orderedNodes)
|
||||
{
|
||||
int vtkType = this->GetCellType(vtkVolId);
|
||||
int cellDim = SMDS_Downward::getCellDimension(vtkType);
|
||||
if (cellDim != 3)
|
||||
return 0;
|
||||
SMDS_Down3D *downvol = static_cast<SMDS_Down3D*> (_downArray[vtkType]);
|
||||
int downVolId = this->_cellIdToDownId[vtkVolId];
|
||||
downvol->getOrderedNodesOfFace(downVolId, orderedNodes);
|
||||
return orderedNodes.size();
|
||||
}
|
||||
|
||||
|
@ -9,10 +9,14 @@
|
||||
#define _SMDS_UNSTRUCTUREDGRID_HXX
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#include <vtkUnstructuredGrid.h>
|
||||
#include "chrono.hxx"
|
||||
|
||||
#define NBMAXNEIGHBORS 10
|
||||
|
||||
class SMDS_Downward;
|
||||
class SMDS_Mesh;
|
||||
|
||||
@ -29,7 +33,11 @@ public:
|
||||
|
||||
int CellIdToDownId(int vtkCellId);
|
||||
void setCellIdToDownId(int vtkCellId, int downId);
|
||||
void BuildDownwardConnectivity();
|
||||
void BuildDownwardConnectivity(bool withEdges);
|
||||
int GetNeighbors(int* neighborsVtkIds, int* downIds, unsigned char* downTypes, int vtkId);
|
||||
void GetNodeIds(std::set<int>& nodeSet, int downId, unsigned char downType);
|
||||
void ModifyCellNodes(int vtkVolId, std::map<int, int> localClonedNodeIds);
|
||||
int getOrderedNodesOfFace(int vtkVolId, std::vector<int>& orderedNodes);
|
||||
vtkCellLinks* GetLinks()
|
||||
{
|
||||
return Links;
|
||||
@ -39,6 +47,7 @@ public:
|
||||
return _downArray[vtkType];
|
||||
}
|
||||
static SMDS_UnstructuredGrid* New();
|
||||
SMDS_Mesh *_mesh;
|
||||
protected:
|
||||
SMDS_UnstructuredGrid();
|
||||
~SMDS_UnstructuredGrid();
|
||||
@ -47,7 +56,6 @@ protected:
|
||||
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;
|
||||
|
@ -56,6 +56,7 @@ class SMDS_EXPORT SMDS_VolumeOfFaces:public SMDS_MeshVolume
|
||||
const SMDS_MeshFace * face6);
|
||||
|
||||
virtual SMDSAbs_EntityType GetEntityType() const;
|
||||
virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) {return false;};
|
||||
void Print(std::ostream & OS) const;
|
||||
|
||||
int NbFaces() const;
|
||||
|
@ -37,6 +37,13 @@ void SMDS_VtkEdge::init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
|
||||
bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode * node1,
|
||||
const SMDS_MeshNode * node2)
|
||||
{
|
||||
// TODO remove
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
|
||||
{
|
||||
// TODO
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ public:
|
||||
~SMDS_VtkEdge();
|
||||
void init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
|
||||
bool ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2);
|
||||
virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes);
|
||||
|
||||
void Print(std::ostream & OS) const;
|
||||
int NbNodes() const;
|
||||
|
@ -51,6 +51,7 @@ void SMDS_VtkFace::init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
|
||||
|
||||
bool SMDS_VtkFace::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
|
||||
{
|
||||
// TODO
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ void SMDS_VtkVolume::init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
|
||||
bool SMDS_VtkVolume::ChangeNodes(const SMDS_MeshNode* nodes[],
|
||||
const int nbNodes)
|
||||
{
|
||||
// utilise dans SMDS_Mesh
|
||||
// TODO utilise dans SMDS_Mesh
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "SMDS_QuadraticFaceOfNodes.hxx"
|
||||
#include "SMDS_MeshGroup.hxx"
|
||||
#include "SMDS_LinearEdge.hxx"
|
||||
#include "SMDS_Downward.hxx"
|
||||
|
||||
#include "SMESHDS_Group.hxx"
|
||||
#include "SMESHDS_Mesh.hxx"
|
||||
@ -798,7 +799,7 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1,
|
||||
return false;
|
||||
|
||||
//MESSAGE( endl << tr1 << tr2 );
|
||||
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
GetMeshDS()->ChangeElementNodes( tr1, aNodes, 4 );
|
||||
myLastCreatedElems.Append(tr1);
|
||||
GetMeshDS()->RemoveElement( tr2 );
|
||||
@ -844,6 +845,7 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1,
|
||||
aNodes[6] = N2[3];
|
||||
aNodes[7] = N1[5];
|
||||
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
|
||||
myLastCreatedElems.Append(tr1);
|
||||
GetMeshDS()->RemoveElement( tr2 );
|
||||
@ -1017,11 +1019,13 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
|
||||
|
||||
if ( aBadRate1 <= aBadRate2 ) {
|
||||
// tr1 + tr2 is better
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( elem, aNodes, 3 );
|
||||
newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
|
||||
}
|
||||
else {
|
||||
// tr3 + tr4 is better
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
|
||||
newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
|
||||
}
|
||||
@ -1097,6 +1101,7 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
|
||||
newElem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
|
||||
aNodes[7], aNodes[4], newN );
|
||||
}
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( elem, N, 6 );
|
||||
|
||||
} // quadratic case
|
||||
@ -1729,10 +1734,12 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
|
||||
int aShapeId = FindShape( elem );
|
||||
const SMDS_MeshElement* newElem = 0;
|
||||
if ( the13Diag ) {
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( elem, aNodes, 3 );
|
||||
newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
|
||||
}
|
||||
else {
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
|
||||
newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
|
||||
}
|
||||
@ -1818,6 +1825,7 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
|
||||
aNodes[7], aNodes[4], newN );
|
||||
}
|
||||
myLastCreatedElems.Append(newElem);
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( elem, N, 6 );
|
||||
// put a new triangle on the same shape and add to the same groups
|
||||
if ( aShapeId )
|
||||
@ -2119,11 +2127,13 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
|
||||
mapLi_listEl.erase( *link12 );
|
||||
if(tr1->NbNodes()==3) {
|
||||
if( tr1->GetID() < tr2->GetID() ) {
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( tr1, n12, 4 );
|
||||
myLastCreatedElems.Append(tr1);
|
||||
aMesh->RemoveElement( tr2 );
|
||||
}
|
||||
else {
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( tr2, n12, 4 );
|
||||
myLastCreatedElems.Append(tr2);
|
||||
aMesh->RemoveElement( tr1);
|
||||
@ -2146,11 +2156,13 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
|
||||
aNodes[6] = N2[3];
|
||||
aNodes[7] = N1[5];
|
||||
if( tr1->GetID() < tr2->GetID() ) {
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
|
||||
myLastCreatedElems.Append(tr1);
|
||||
GetMeshDS()->RemoveElement( tr2 );
|
||||
}
|
||||
else {
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
GetMeshDS()->ChangeElementNodes( tr2, aNodes, 8 );
|
||||
myLastCreatedElems.Append(tr2);
|
||||
GetMeshDS()->RemoveElement( tr1 );
|
||||
@ -2164,11 +2176,13 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
|
||||
mapLi_listEl.erase( *link13 );
|
||||
if(tr1->NbNodes()==3) {
|
||||
if( tr1->GetID() < tr2->GetID() ) {
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( tr1, n13, 4 );
|
||||
myLastCreatedElems.Append(tr1);
|
||||
aMesh->RemoveElement( tr3 );
|
||||
}
|
||||
else {
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( tr3, n13, 4 );
|
||||
myLastCreatedElems.Append(tr3);
|
||||
aMesh->RemoveElement( tr1 );
|
||||
@ -2191,11 +2205,13 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
|
||||
aNodes[6] = N2[3];
|
||||
aNodes[7] = N1[5];
|
||||
if( tr1->GetID() < tr2->GetID() ) {
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
|
||||
myLastCreatedElems.Append(tr1);
|
||||
GetMeshDS()->RemoveElement( tr3 );
|
||||
}
|
||||
else {
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
GetMeshDS()->ChangeElementNodes( tr3, aNodes, 8 );
|
||||
myLastCreatedElems.Append(tr3);
|
||||
GetMeshDS()->RemoveElement( tr1 );
|
||||
@ -3872,6 +3888,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes,
|
||||
if ( !f )
|
||||
myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ));
|
||||
else if ( nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( f, nodes, nbn );
|
||||
break;
|
||||
}
|
||||
@ -3880,6 +3897,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes,
|
||||
if ( !f )
|
||||
myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ));
|
||||
else if ( nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( f, nodes, nbn );
|
||||
break;
|
||||
}
|
||||
@ -3900,6 +3918,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes,
|
||||
tmpnodes[3] = nodes[1];
|
||||
tmpnodes[4] = nodes[3];
|
||||
tmpnodes[5] = nodes[5];
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( f, tmpnodes, nbn );
|
||||
}
|
||||
}
|
||||
@ -3920,6 +3939,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes,
|
||||
tmpnodes[5] = nodes[3];
|
||||
tmpnodes[6] = nodes[5];
|
||||
tmpnodes[7] = nodes[7];
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( f, tmpnodes, nbn );
|
||||
}
|
||||
}
|
||||
@ -3930,6 +3950,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes,
|
||||
if ( !f )
|
||||
myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes));
|
||||
else if ( nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( f, nodes, nbn );
|
||||
}
|
||||
}
|
||||
@ -8645,6 +8666,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace,
|
||||
newNodes[ 1 ] = linkNodes[ i2 ];
|
||||
newNodes[ 2 ] = nodes[ iSplit >= iBestQuad ? i3 : i4 ];
|
||||
newNodes[ 3 ] = nodes[ i4 ];
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 );
|
||||
} // end if(!theFace->IsQuadratic())
|
||||
else { // theFace is quadratic
|
||||
@ -9740,6 +9762,7 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1,
|
||||
// elemIDsToRemove.push_back( e->GetID() );
|
||||
// else
|
||||
if ( nbReplaced )
|
||||
// TODO problem ChangeElementNodes : not the same number of nodes, not the same type
|
||||
aMesh->ChangeElementNodes( e, & nodes[0], nbNodes );
|
||||
}
|
||||
}
|
||||
@ -10234,6 +10257,192 @@ bool SMESH_MeshEditor::DoubleNodesInRegion( const TIDSortedElemSet& theElems,
|
||||
return DoubleNodes( theElems, theNodesNot, anAffected );
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
|
||||
* The list of groups must describe a partition of the mesh volumes.
|
||||
* The nodes of the internal faces at the boundaries of the groups are doubled.
|
||||
* In option, the internal faces are replaced by flat elements.
|
||||
* Triangles are transformed in prisms, and quadrangles in hexahedrons.
|
||||
* @param theElems - list of groups of volumes, where a group of volume is a set of
|
||||
* SMDS_MeshElements sorted by Id.
|
||||
* @param createJointElems - if TRUE, create the elements
|
||||
* @return TRUE if operation has been completed successfully, FALSE otherwise
|
||||
*/
|
||||
bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSortedElemSet>& theElems,
|
||||
bool createJointElems)
|
||||
{
|
||||
MESSAGE("------------------------------------------------------");
|
||||
MESSAGE("SMESH_MeshEditor::CreateJointElementsOnGroupBoundaries");
|
||||
MESSAGE("------------------------------------------------------");
|
||||
|
||||
SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS();
|
||||
meshDS->BuildDownWardConnectivity(false);
|
||||
SMDS_UnstructuredGrid *grid = meshDS->getGrid();
|
||||
|
||||
// --- build the list of faces shared by 2 domains (group of elements), with their domain and volume indexes
|
||||
// build the list of nodes shared by 2 or more domains, with their domain indexes
|
||||
|
||||
std::map<DownIdType, std::map<int,int>, DownIdCompare> faceDomains; // 2x(id domain --> id volume)
|
||||
std::map<int, std::map<int,int> > nodeDomains; //oldId -> (domainId -> newId)
|
||||
faceDomains.clear();
|
||||
nodeDomains.clear();
|
||||
std::map<int,int> emptyMap;
|
||||
emptyMap.clear();
|
||||
|
||||
for (int idom = 0; idom < theElems.size(); idom++)
|
||||
{
|
||||
|
||||
// --- build a map (face to duplicate --> volume to modify)
|
||||
// with all the faces shared by 2 domains (group of elements)
|
||||
// and corresponding volume of this domain, for each shared face.
|
||||
// a volume has a face shared by 2 domains if it has a neighbor which is not in is domain.
|
||||
|
||||
const TIDSortedElemSet& domain = theElems[idom];
|
||||
TIDSortedElemSet::const_iterator elemItr = domain.begin();
|
||||
for (; elemItr != domain.end(); ++elemItr)
|
||||
{
|
||||
SMDS_MeshElement* anElem = (SMDS_MeshElement*) *elemItr;
|
||||
if (!anElem)
|
||||
continue;
|
||||
int vtkId = meshDS->fromSmdsToVtk(anElem->getId());
|
||||
int neighborsVtkIds[NBMAXNEIGHBORS];
|
||||
int downIds[NBMAXNEIGHBORS];
|
||||
unsigned char downTypes[NBMAXNEIGHBORS];
|
||||
int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId);
|
||||
for (int n = 0; n < nbNeighbors; n++)
|
||||
{
|
||||
int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]);
|
||||
const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
|
||||
if (! domain.count(elem)) // neighbor is in another domain : face is shared
|
||||
{
|
||||
DownIdType face(downIds[n], downTypes[n]);
|
||||
if (!faceDomains.count(face))
|
||||
faceDomains[face] = emptyMap; // create an empty entry for face
|
||||
if (!faceDomains[face].count(idom))
|
||||
{
|
||||
faceDomains[face][idom] = vtkId; // volume associated to face in this domain
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MESSAGE("Number of shared faces " << faceDomains.size());
|
||||
|
||||
// --- for each shared face, get the nodes
|
||||
// for each node, for each domain of the face, create a clone of the node
|
||||
|
||||
std::map<DownIdType, std::map<int,int>, DownIdCompare>::iterator itface = faceDomains.begin();
|
||||
for( ; itface != faceDomains.end();++itface )
|
||||
{
|
||||
DownIdType face = itface->first;
|
||||
std::map<int,int> domvol = itface->second;
|
||||
std::set<int> oldNodes;
|
||||
oldNodes.clear();
|
||||
grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
|
||||
std::set<int>::iterator itn = oldNodes.begin();
|
||||
for (;itn != oldNodes.end(); ++itn)
|
||||
{
|
||||
int oldId = *itn;
|
||||
if (!nodeDomains.count(oldId))
|
||||
nodeDomains[oldId] = emptyMap; // create an empty entry for node
|
||||
std::map<int,int>::iterator itdom = domvol.begin();
|
||||
for(; itdom != domvol.end(); ++itdom)
|
||||
{
|
||||
int idom = itdom->first;
|
||||
if ( nodeDomains[oldId].empty() )
|
||||
nodeDomains[oldId][idom] = oldId; // keep the old node in the first domain
|
||||
else
|
||||
{
|
||||
double *coords = grid->GetPoint(oldId);
|
||||
SMDS_MeshNode *newNode = meshDS->AddNode(coords[0], coords[1], coords[2]);
|
||||
int newId = newNode->GetID();
|
||||
nodeDomains[oldId][idom] = newId; // cloned node for other domains
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- iterate on shared faces (volumes to modify, face to extrude)
|
||||
// get node id's of the face (id SMDS = id VTK)
|
||||
// create flat element with old and new nodes if requested
|
||||
|
||||
if (createJointElems)
|
||||
{
|
||||
itface = faceDomains.begin();
|
||||
for( ; itface != faceDomains.end();++itface )
|
||||
{
|
||||
DownIdType face = itface->first;
|
||||
std::set<int> oldNodes;
|
||||
std::set<int>::iterator itn;
|
||||
oldNodes.clear();
|
||||
grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
|
||||
std::map<int,int> localClonedNodeIds;
|
||||
|
||||
std::map<int,int> domvol = itface->second;
|
||||
std::map<int,int>::iterator itdom = domvol.begin();
|
||||
int dom1 = itdom->first;
|
||||
int vtkVolId = itdom->second;
|
||||
itdom++;
|
||||
int dom2 = itdom->first;
|
||||
|
||||
localClonedNodeIds.clear();
|
||||
for (itn = oldNodes.begin(); itn != oldNodes.end(); ++itn)
|
||||
{
|
||||
int oldId = *itn;
|
||||
int refid = oldId;
|
||||
if (nodeDomains[oldId].count(dom1))
|
||||
refid = nodeDomains[oldId][dom1];
|
||||
else
|
||||
MESSAGE("--- problem domain node " << dom1 << " " << oldId);
|
||||
int newid = oldId;
|
||||
if (nodeDomains[oldId].count(dom2))
|
||||
newid = nodeDomains[oldId][dom2];
|
||||
else
|
||||
MESSAGE("--- problem domain node " << dom2 << " " << oldId);
|
||||
localClonedNodeIds[oldId] = newid;
|
||||
}
|
||||
int smdsId = meshDS->fromVtkToSmds(vtkVolId);
|
||||
meshDS->extrudeVolumeFromFace(smdsId, localClonedNodeIds);
|
||||
}
|
||||
}
|
||||
|
||||
// --- iterate on shared faces (volumes to modify, face to extrude)
|
||||
// get node id's of the face (id SMDS = id VTK)
|
||||
// replace old nodes by new nodes in volumes, and update inverse connectivity
|
||||
|
||||
itface = faceDomains.begin();
|
||||
for( ; itface != faceDomains.end();++itface )
|
||||
{
|
||||
DownIdType face = itface->first;
|
||||
std::set<int> oldNodes;
|
||||
std::set<int>::iterator itn;
|
||||
oldNodes.clear();
|
||||
grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
|
||||
std::map<int,int> localClonedNodeIds;
|
||||
|
||||
std::map<int,int> domvol = itface->second;
|
||||
std::map<int,int>::iterator itdom = domvol.begin();
|
||||
for(; itdom != domvol.end(); ++itdom)
|
||||
{
|
||||
int idom = itdom->first;
|
||||
int vtkVolId = itdom->second;
|
||||
localClonedNodeIds.clear();
|
||||
for (itn = oldNodes.begin(); itn != oldNodes.end(); ++itn)
|
||||
{
|
||||
int oldId = *itn;
|
||||
if (nodeDomains[oldId].count(idom))
|
||||
localClonedNodeIds[oldId] = nodeDomains[oldId][idom];
|
||||
}
|
||||
int smdsId = meshDS->fromVtkToSmds(vtkVolId);
|
||||
meshDS->ModifyCellNodes(smdsId, localClonedNodeIds);
|
||||
}
|
||||
}
|
||||
grid->BuildLinks();
|
||||
|
||||
// TODO replace also old nodes by new nodes in faces and edges
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Generated skin mesh (containing 2D cells) from 3D mesh
|
||||
|
@ -627,6 +627,9 @@ public:
|
||||
const TIDSortedElemSet& theNodesNot,
|
||||
const TopoDS_Shape& theShape );
|
||||
|
||||
bool DoubleNodesOnGroupBoundaries( const std::vector<TIDSortedElemSet>& theElems,
|
||||
bool createJointElems);
|
||||
|
||||
/*!
|
||||
* \brief Generated skin mesh (containing 2D cells) from 3D mesh
|
||||
* The created 2D mesh elements based on nodes of free faces of boundary volumes
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "SMDS_EdgePosition.hxx"
|
||||
#include "SMDS_FacePosition.hxx"
|
||||
#include "SMDS_SpacePosition.hxx"
|
||||
#include "SMDS_Downward.hxx"
|
||||
#include "SMESHDS_GroupOnGeom.hxx"
|
||||
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
@ -1914,8 +1915,6 @@ void SMESHDS_Mesh::compactMesh()
|
||||
myVtkIndex.swap(newVtkToSmds);
|
||||
MESSAGE("myCells.size()=" << myCells.size() << " myIDElements.size()=" << myIDElements.size() << " myVtkIndex.size()=" << myVtkIndex.size() );
|
||||
|
||||
myGrid->BuildDownwardConnectivity();
|
||||
|
||||
// ---TODO: myNodes, myElements in submeshes
|
||||
|
||||
// map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.begin();
|
||||
@ -1926,3 +1925,53 @@ void SMESHDS_Mesh::compactMesh()
|
||||
|
||||
}
|
||||
|
||||
void SMESHDS_Mesh::BuildDownWardConnectivity(bool withEdges)
|
||||
{
|
||||
myGrid->BuildDownwardConnectivity(withEdges);
|
||||
}
|
||||
|
||||
/*! change some nodes in cell without modifying type or internal connectivity.
|
||||
* Nodes inverse connectivity is maintained up to date.
|
||||
* @param smdsVolId smds id of the cell.
|
||||
* @param localClonedNodeIds map old node id to new node id.
|
||||
* @return ok if success.
|
||||
*/
|
||||
bool SMESHDS_Mesh::ModifyCellNodes(int smdsVolId, std::map<int,int> localClonedNodeIds)
|
||||
{
|
||||
int vtkVolId = this->fromSmdsToVtk(smdsVolId);
|
||||
myGrid->ModifyCellNodes(vtkVolId, localClonedNodeIds);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*! Create a volume (prism or hexahedron) by duplication of a face.
|
||||
* the nodes of the new face are already created.
|
||||
* @param vtkVolId vtk id of a volume containing the face, to get an orientation for the face.
|
||||
* @param localClonedNodeIds map old node id to new node id. The old nodes define the face in the volume.
|
||||
* @return ok if success.
|
||||
*/
|
||||
bool SMESHDS_Mesh::extrudeVolumeFromFace(int smdsVolId, std::map<int,int> localClonedNodeIds)
|
||||
{
|
||||
int vtkVolId = this->fromSmdsToVtk(smdsVolId);
|
||||
//MESSAGE(smdsVolId << " " << vtkVolId);
|
||||
vector<int> orderedNodes;
|
||||
orderedNodes.clear();
|
||||
map<int, int>::iterator it = localClonedNodeIds.begin();
|
||||
for (; it != localClonedNodeIds.end(); ++it)
|
||||
orderedNodes.push_back(it->first);
|
||||
|
||||
int nbNodes = myGrid->getOrderedNodesOfFace(vtkVolId, orderedNodes);
|
||||
if (nbNodes == 3)
|
||||
{
|
||||
int newVtkVolId =myElementIDFactory->GetFreeID();
|
||||
SMDS_MeshVolume *vol = this->AddVolumeWithID(orderedNodes[0],
|
||||
orderedNodes[1],
|
||||
orderedNodes[2],
|
||||
localClonedNodeIds[orderedNodes[0]],
|
||||
localClonedNodeIds[orderedNodes[1]],
|
||||
localClonedNodeIds[orderedNodes[2]],
|
||||
newVtkVolId);
|
||||
}
|
||||
|
||||
// TODO update subshape list of elements and nodes
|
||||
return true;
|
||||
}
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include "SMESHDS_DataMapOfShape.hxx"
|
||||
|
||||
class SMESHDS_GroupBase;
|
||||
class DownIdType;
|
||||
|
||||
class SMESHDS_EXPORT SMESHDS_Mesh:public SMDS_Mesh{
|
||||
public:
|
||||
@ -397,6 +398,8 @@ public:
|
||||
bool ChangePolyhedronNodes(const SMDS_MeshElement * elem,
|
||||
std::vector<const SMDS_MeshNode*> nodes,
|
||||
std::vector<int> quantities);
|
||||
bool ModifyCellNodes(int smdsVolId, std::map<int,int> localClonedNodeIds);
|
||||
bool extrudeVolumeFromFace(int smdsVolId, std::map<int,int> localClonedNodeIds);
|
||||
void Renumber (const bool isNodes, const int startID=1, const int deltaID=1);
|
||||
|
||||
void SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S);
|
||||
@ -440,6 +443,7 @@ public:
|
||||
bool IsGroupOfSubShapes (const TopoDS_Shape& aSubShape) const;
|
||||
|
||||
void compactMesh();
|
||||
void BuildDownWardConnectivity(bool withEdges);
|
||||
|
||||
~SMESHDS_Mesh();
|
||||
|
||||
|
@ -4766,3 +4766,51 @@ CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
|
||||
TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
|
||||
* The list of groups must describe a partition of the mesh volumes.
|
||||
* The nodes of the internal faces at the boundaries of the groups are doubled.
|
||||
* In option, the internal faces are replaced by flat elements.
|
||||
* Triangles are transformed in prisms, and quadrangles in hexahedrons.
|
||||
* @param theDomains - list of groups of volumes
|
||||
* @param createJointElems - if TRUE, create the elements
|
||||
* @return TRUE if operation has been completed successfully, FALSE otherwise
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
|
||||
CORBA::Boolean createJointElems )
|
||||
{
|
||||
initData();
|
||||
|
||||
::SMESH_MeshEditor aMeshEditor( myMesh );
|
||||
|
||||
SMESHDS_Mesh* aMeshDS = GetMeshDS();
|
||||
|
||||
vector<TIDSortedElemSet> domains;
|
||||
domains.clear();
|
||||
|
||||
for ( int i = 0, n = theDomains.length(); i < n; i++ )
|
||||
{
|
||||
SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
|
||||
if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
|
||||
{
|
||||
TIDSortedElemSet domain;
|
||||
domain.clear();
|
||||
domains.push_back(domain);
|
||||
SMESH::long_array_var anIDs = aGrp->GetIDs();
|
||||
arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
|
||||
}
|
||||
}
|
||||
|
||||
bool aResult = aMeshEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems );
|
||||
|
||||
storeResult( aMeshEditor) ;
|
||||
|
||||
// Update Python script
|
||||
TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
|
||||
<< ", " << createJointElems << " )";
|
||||
return aResult;
|
||||
}
|
||||
|
@ -647,6 +647,20 @@ public:
|
||||
*/
|
||||
CORBA::Boolean Make2DMeshFrom3D();
|
||||
|
||||
/*!
|
||||
* \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
|
||||
* The list of groups must describe a partition of the mesh volumes.
|
||||
* The nodes of the internal faces at the boundaries of the groups are doubled.
|
||||
* In option, the internal faces are replaced by flat elements.
|
||||
* Triangles are transformed in prisms, and quadrangles in hexahedrons.
|
||||
* @param theDomains - list of groups of volumes
|
||||
* @param createJointElems - if TRUE, create the elements
|
||||
* @return TRUE if operation has been completed successfully, FALSE otherwise
|
||||
*/
|
||||
CORBA::Boolean DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
|
||||
CORBA::Boolean createJointElems );
|
||||
|
||||
|
||||
private: //!< private methods
|
||||
|
||||
SMESHDS_Mesh * GetMeshDS() { return myMesh->GetMeshDS(); }
|
||||
|
@ -3719,6 +3719,17 @@ class Mesh:
|
||||
# @ingroup l2_modif_edit
|
||||
def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
|
||||
return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
|
||||
|
||||
## Double nodes on shared faces between groups of volumes and create flat elements on demand.
|
||||
# The list of groups must describe a partition of the mesh volumes.
|
||||
# The nodes of the internal faces at the boundaries of the groups are doubled.
|
||||
# In option, the internal faces are replaced by flat elements.
|
||||
# Triangles are transformed in prisms, and quadrangles in hexahedrons.
|
||||
# @param theDomains - list of groups of volumes
|
||||
# @param createJointElems - if TRUE, create the elements
|
||||
# @return TRUE if operation has been completed successfully, FALSE otherwise
|
||||
def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems ):
|
||||
return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems )
|
||||
|
||||
## The mother class to define algorithm, it is not recommended to use it directly.
|
||||
#
|
||||
|
Loading…
Reference in New Issue
Block a user