#include "SMDS_QuadraticEdge.hxx"
#include "SMDS_QuadraticFaceOfNodes.hxx"
#include "SMDS_QuadraticVolumeOfNodes.hxx"
+#include "SMDS_SpacePosition.hxx"
#include <vtkUnstructuredGrid.h>
+#include <vtkUnsignedCharArray.h>
#include <algorithm>
#include <map>
#include <sys/sysinfo.h>
#endif
-// number of added entitis to check memory after
+// number of added entities to check memory after
#define CHECKMEMORY_INTERVAL 1000
vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
-int SMDS_Mesh::chunkSize = 1000;
+int SMDS_Mesh::chunkSize = 1024;
+
//================================================================================
/*!
myElementIDFactory(new SMDS_MeshElementIDFactory()),
myHasConstructionEdges(false), myHasConstructionFaces(false),
myHasInverseElements(true),
- myNodeMin(0), myNodeMax(0), myCellLinksSize(0)
+ myNodeMin(0), myNodeMax(0), myCellLinksSize(0),
+ myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0)
{
myMeshId = _meshList.size(); // --- index of the mesh to push back in the vector
MESSAGE("myMeshId=" << myMeshId);
+ MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) );
+ MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) );
+ MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) );
+ MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) );
+ MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) );
+ MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) );
myNodeIDFactory->SetMesh(this);
myElementIDFactory->SetMesh(this);
_meshList.push_back(this);
+ myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
+ myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
+ myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
+ myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
+
myNodes.clear();
myCells.clear();
+ myIDElements.clear();
+ myVtkIndex.clear();
myGrid = vtkUnstructuredGrid::New();
myGrid->Initialize();
myGrid->Allocate();
///////////////////////////////////////////////////////////////////////////////
SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
:myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
- myElementIDFactory(parent->myElementIDFactory),
- myHasConstructionEdges(false), myHasConstructionFaces(false),
- myHasInverseElements(true)
+ myElementIDFactory(parent->myElementIDFactory),
+ myHasConstructionEdges(false), myHasConstructionFaces(false),
+ myHasInverseElements(true),
+ myNodePool(parent->myNodePool),
+ myEdgePool(parent->myEdgePool),
+ myFacePool(parent->myFacePool),
+ myVolumePool(parent->myVolumePool)
{
}
const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
if(!node){
//if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
- SMDS_MeshNode * node=new SMDS_MeshNode(ID, myMeshId, -1, x, y, z);
+ //SMDS_MeshNode * node=new SMDS_MeshNode(ID, myMeshId, -1, x, y, z);
+ SMDS_MeshNode * node = myNodePool->getNew();
+ node->init(ID, myMeshId, -1, x, y, z);
if (ID >= myNodes.size())
{
myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
int ID)
{
if ( !n1 || !n2 ) return 0;
+ SMDS_MeshEdge * edge = 0;
+
+ // --- retreive nodes ID
+ vector<vtkIdType> nodeIds;
+ nodeIds.clear();
+ nodeIds.push_back(n1->getId());
+ nodeIds.push_back(n2->getId());
- //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
- //MESSAGE("AddEdgeWithID " << ID)
- SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
+ SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
+ edgevtk->init(nodeIds, this);
+ edge = edgevtk;
adjustmyCellsCapacity(ID);
myCells[ID] = edge;
myInfo.myNbEdges++;
int ID)
{
//MESSAGE("AddFaceWithID " << ID)
- SMDS_MeshFace * face=createTriangle(n1, n2, n3);
+ SMDS_MeshFace * face=createTriangle(n1, n2, n3, myElementIDFactory->GetFreeID());
if (face && !registerElement(ID, face)) {
RemoveElement(face, false);
return NULL;
}
else {
- volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
+ // --- retrieve nodes ID
+ vector<vtkIdType> nodeIds;
+ nodeIds.clear();
+ nodeIds.push_back(n1->getId());
+ nodeIds.push_back(n3->getId()); // order SMDS-->VTK
+ nodeIds.push_back(n2->getId());
+ nodeIds.push_back(n4->getId());
+
+ SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+ volvtk->init(nodeIds, this);
+ volume = volvtk;
adjustmyCellsCapacity(ID);
myCells[ID] = volume;
myInfo.myNbTetras++;
return NULL;
}
else {
- volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
+ // --- retrieve nodes ID
+ vector<vtkIdType> nodeIds;
+ nodeIds.clear();
+ nodeIds.push_back(n1->getId());
+ nodeIds.push_back(n4->getId());
+ nodeIds.push_back(n3->getId());
+ nodeIds.push_back(n2->getId());
+ nodeIds.push_back(n5->getId());
+
+ SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+ volvtk->init(nodeIds, this);
+ volume = volvtk;
adjustmyCellsCapacity(ID);
myCells[ID] = volume;
myInfo.myNbPyramids++;
return NULL;
}
else {
- volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
+ // --- retrieve nodes ID
+ vector<vtkIdType> nodeIds;
+ nodeIds.clear();
+ nodeIds.push_back(n1->getId());
+ nodeIds.push_back(n3->getId());
+ nodeIds.push_back(n2->getId());
+ nodeIds.push_back(n4->getId());
+ nodeIds.push_back(n6->getId());
+ nodeIds.push_back(n5->getId());
+
+ SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+ volvtk->init(nodeIds, this);
+ volume = volvtk;
adjustmyCellsCapacity(ID);
myCells[ID] = volume;
myInfo.myNbPrisms++;
return NULL;
}
else {
-// volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
- volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
+ // --- retrieve nodes ID
+ vector<vtkIdType> nodeIds;
+ nodeIds.clear();
+ nodeIds.push_back(n1->getId());
+ nodeIds.push_back(n4->getId());
+ nodeIds.push_back(n3->getId());
+ nodeIds.push_back(n2->getId());
+ nodeIds.push_back(n5->getId());
+ nodeIds.push_back(n8->getId());
+ nodeIds.push_back(n7->getId());
+ nodeIds.push_back(n6->getId());
+
+ SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+ volvtk->init(nodeIds, this);
+ volume = volvtk;
adjustmyCellsCapacity(ID);
myCells[ID] = volume;
myInfo.myNbHexas++;
}
-
+
if (!registerElement(ID, volume)) {
RemoveElement(volume, false);
volume = NULL;
///////////////////////////////////////////////////////////////////////////////
/// Registers element with the given ID, maintains inverse connections
///////////////////////////////////////////////////////////////////////////////
-bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
+bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
{
- //MESSAGE("registerElement " << ID)
- if (myElementIDFactory->BindID(ID, element)) {
- return true;
+ //MESSAGE("registerElement " << ID)
+ if ((ID < myIDElements.size()) && myIDElements[ID] >= 0) // --- already bound
+ {
+ MESSAGE(" --------------------------------- already bound "<< ID << " " << myIDElements[ID]);
+ return false;
}
- MESSAGE("BindID " << ID << " false!---------------");
- return false;
+
+ element->myID = ID;
+ element->myMeshId = myMeshId;
+
+ SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
+ MYASSERT(cell);
+ int vtkId = cell->getVtkId();
+ if (vtkId == -1)
+ vtkId = myElementIDFactory->SetInVtkGrid(element);
+
+ if (ID >= myIDElements.size()) // --- resize local vector
+ {
+ MESSAGE(" ------------------- resize myIDElements " << ID << " --> " << ID + SMDS_Mesh::chunkSize);
+ myIDElements.resize(ID + SMDS_Mesh::chunkSize, -1); // fill new elements with -1
+ }
+
+ myIDElements[ID] = vtkId;
+ //MESSAGE("smds:" << ID << " vtk:" << cellId );
+
+ if (vtkId >= myVtkIndex.size()) // --- resize local vector
+ {
+ MESSAGE(" --------------------- resize myVtkIndex " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
+ myVtkIndex.resize(vtkId + SMDS_Mesh::chunkSize, -1);
+ }
+ myVtkIndex[vtkId] = ID;
+
+ myElementIDFactory->updateMinMax(ID);
+ return true;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
{
- if (ID <0 || ID >= myNodes.size())
- return NULL;
+ if (ID < 0 || ID >= myNodes.size())
+ {
+ MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
+ return 0;
+ }
return (const SMDS_MeshNode *)myNodes[ID];
}
///////////////////////////////////////////////////////////////////////////////
-///Create a triangle and add it to the current mesh. This methode do not bind a
+///Create a triangle and add it to the current mesh. This method do not bind an
///ID to the create triangle.
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
const SMDS_MeshNode * node2,
- const SMDS_MeshNode * node3)
+ const SMDS_MeshNode * node3,
+ int ID)
{
if ( !node1 || !node2 || !node3) return 0;
// if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
edge2=FindEdgeOrCreate(node2,node3);
edge3=FindEdgeOrCreate(node3,node1);
- int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
+ //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
adjustmyCellsCapacity(ID);
myCells[ID] = face;
}
else
{
- int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
- SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
+ // --- retrieve nodes ID
+ vector<vtkIdType> nodeIds;
+ nodeIds.clear();
+ nodeIds.push_back(node1->getId());
+ nodeIds.push_back(node2->getId());
+ nodeIds.push_back(node3->getId());
+
+ SMDS_MeshFace * face = 0;
+ SMDS_VtkFace *facevtk = myFacePool->getNew();
+ facevtk->init(nodeIds, this);
+ face = facevtk;
adjustmyCellsCapacity(ID);
myCells[ID] = face;
myInfo.myNbTriangles++;
}
else
{
- //MESSAGE("createQuadrangle " << ID);
- SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
+ // --- retrieve nodes ID
+ vector<vtkIdType> nodeIds;
+ nodeIds.clear();
+ nodeIds.push_back(node1->getId());
+ nodeIds.push_back(node2->getId());
+ nodeIds.push_back(node3->getId());
+ nodeIds.push_back(node4->getId());
+
+ SMDS_MeshFace * face = 0;
+ SMDS_VtkFace *facevtk = myFacePool->getNew();
+ facevtk->init(nodeIds, this);
+ face = facevtk;
adjustmyCellsCapacity(ID);
myCells[ID] = face;
myInfo.myNbQuadrangles++;
const SMDS_MeshNode * nodes[],
const int nbnodes)
{
+ MYASSERT(0); // REVOIR LES TYPES
// keep current nodes of elem
set<const SMDS_MeshElement*> oldNodes;
SMDS_ElemIteratorPtr itn = element->nodesIterator();
}
case SMDSAbs_Edge: {
if ( nbnodes == 2 ) {
- if ( SMDS_MeshEdge* edge = dynamic_cast<SMDS_MeshEdge*>( elem ))
+ if ( SMDS_VtkEdge* edge = dynamic_cast<SMDS_VtkEdge*>( elem ))
Ok = edge->ChangeNodes( nodes[0], nodes[1] );
}
else if ( nbnodes == 3 ) {
//if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
adjustmyCellsCapacity(ID);
- toReturn=new SMDS_MeshEdge(node1,node2);
+ vector<vtkIdType> nodeIds;
+ nodeIds.clear();
+ nodeIds.push_back(node1->getId());
+ nodeIds.push_back(node2->getId());
+
+ SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
+ edgevtk->init(nodeIds, this);
+ toReturn = edgevtk;
myCells[ID] = toReturn;
myInfo.myNbEdges++;
}
SMDS_MeshFace * toReturn=NULL;
toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
if(toReturn==NULL) {
- toReturn = createTriangle(node1,node2,node3);
+ int ID = myElementIDFactory->GetFreeID();
+ toReturn = createTriangle(node1,node2,node3, ID);
}
return toReturn;
}
const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
{
if ((IDelem < 0) || IDelem >= myCells.size())
- return 0;
+ {
+ MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
+ return 0;
+ }
return myCells[IDelem];
}
}
///////////////////////////////////////////////////////////////////////////////
-/// Return the list of finit elements owning the given element
+/// Return the list of finite elements owning the given element: elements
+/// containing all the nodes of the given element, for instance faces and
+/// volumes containing a given edge.
///////////////////////////////////////////////////////////////////////////////
static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
{
int i=0;
while(itNodes->more())
{
- const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
+ const SMDS_MeshElement* node = itNodes->next();
+ MYASSERT(node);
+ const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
//initSet[i]=set<const SMDS_MeshElement*>();
while(itFe->more())
- initSet[i].insert(itFe->next());
+ {
+ const SMDS_MeshElement* elem = itFe->next();
+ MYASSERT(elem);
+ initSet[i].insert(elem);
+
+ }
i++;
}
set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
+ MESSAGE("nb elems " << i << " intersection " << retSet->size());
delete [] initSet;
return retSet;
}
///////////////////////////////////////////////////////////////////////////////
///@param elem The element to delete
-///@param removedElems contains all removed elements
-///@param removedNodes contains all removed nodes
+///@param removedElems to be filled with all removed elements
+///@param removedNodes to be filled with all removed nodes
///@param removenodes if true remaining nodes will be removed
///////////////////////////////////////////////////////////////////////////////
void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
list<const SMDS_MeshElement *>& removedNodes,
bool removenodes)
{
+ MESSAGE("SMDS_Mesh::RemoveElement " << elem->GetID() << " " << removenodes);
// get finite elements built on elem
set<const SMDS_MeshElement*> * s1;
if (elem->GetType() == SMDSAbs_0DElement ||
switch((*it)->GetType())
{
case SMDSAbs_Node:
- MESSAGE("Internal Error: This should not happen");
+ MYASSERT("Internal Error: This should not happen");
break;
case SMDSAbs_0DElement:
myCells[(*it)->GetID()] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
//MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
removedElems.push_back( (*it) );
myElementIDFactory->ReleaseID((*it)->GetID());
+ MYASSERT("problem delete elem")
delete (*it);
it++;
}
myInfo.myNbNodes--;
myNodeIDFactory->ReleaseID((*it)->GetID());
removedNodes.push_back( (*it) );
+ MYASSERT("problem delete node")
delete *it;
it++;
}
///////////////////////////////////////////////////////////////////////////////
void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
{
+ int elemId = elem->GetID();
+ MESSAGE("SMDS_Mesh::RemoveFreeElement " << elemId);
SMDSAbs_ElementType aType = elem->GetType();
+ SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
if (aType == SMDSAbs_Node) {
// only free node can be removed by this method
- const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
+ const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
if (!itFe->more()) { // free node
- myNodes[elem->GetID()] = 0;
+ myNodes[elemId] = 0;
myInfo.myNbNodes--;
- myNodeIDFactory->ReleaseID(elem->GetID());
- delete elem;
+ myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
+ myNodeIDFactory->ReleaseID(elemId);
}
} else {
if (hasConstructionEdges() || hasConstructionFaces())
// this methods is only for meshes without descendants
return;
+ int vtkid = this->fromSmdsToVtk(elemId);
+
// Remove element from <InverseElements> of its nodes
SMDS_ElemIteratorPtr itn = elem->nodesIterator();
while (itn->more()) {
}
// in meshes without descendants elements are always free
- switch (aType) {
+ switch (aType) {
case SMDSAbs_0DElement:
- myCells[elem->GetID()] = 0;
+ myCells[elemId] = 0;
myInfo.remove(elem);
+ delete elem;
break;
case SMDSAbs_Edge:
- myCells[elem->GetID()] = 0;
+ myCells[elemId] = 0;
myInfo.RemoveEdge(elem);
+ myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
break;
case SMDSAbs_Face:
- myCells[elem->GetID()] = 0;
+ myCells[elemId] = 0;
myInfo.RemoveFace(elem);
+ myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
break;
case SMDSAbs_Volume:
- myCells[elem->GetID()] = 0;
+ myCells[elemId] = 0;
myInfo.RemoveVolume(elem);
+ myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
break;
default:
break;
}
- myElementIDFactory->ReleaseID(elem->GetID());
- delete elem;
+ myElementIDFactory->ReleaseID(elemId);
+
+ this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
+ // --- to do: keep vtkid in a list of reusable cells
}
}
while (!myNodes[myNodeMax] && (myNodeMin>=0))
myNodeMin--;
}
+
+void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
+{
+ int val = myIDElements.size();
+ MESSAGE(" ------------------- resize myIDElements " << val << " --> " << val + nbNodes);
+ myIDElements.resize(val + nbNodes, -1); // fill new elements with -1
+ val = myNodes.size();
+ MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
+ myNodes.resize(val +nbNodes, 0);
+}
+
+void SMDS_Mesh::incrementCellsCapacity(int nbCells)
+{
+ int val = myVtkIndex.size();
+ MESSAGE(" ------------------- resize myVtkIndex " << val << " --> " << val + nbCells);
+ myVtkIndex.resize(val + nbCells, -1); // fill new elements with -1
+ val = myCells.size();
+ MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
+ myNodes.resize(val +nbCells, 0);
+}
+
+void SMDS_Mesh::adjustStructure()
+{
+ myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID()+1);
+}
+