X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMDS%2FSMDS_Mesh.cxx;h=353d0789302b0df8272cc73266a5726446847504;hp=5df2090e9abbf6bb74a520d9de7e39c21d042e58;hb=1a39b08ad98ef275f4b75e220cc4fb390381f757;hpb=4ff5bd61540272713e48de1eee75625028c32155 diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index 5df2090e9..353d07893 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -1,54 +1,147 @@ -// SMESH SMDS : implementaion of Salome mesh data structure +// Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// SMESH SMDS : implementation of Salome mesh data structure +// #ifdef _MSC_VER #pragma warning(disable:4786) #endif -#include "utilities.h" #include "SMDS_Mesh.hxx" -#include "SMDS_VolumeOfNodes.hxx" -#include "SMDS_VolumeOfFaces.hxx" -#include "SMDS_FaceOfNodes.hxx" -#include "SMDS_FaceOfEdges.hxx" -#include "SMDS_PolyhedralVolumeOfNodes.hxx" -#include "SMDS_PolygonalFaceOfNodes.hxx" -#include "SMDS_QuadraticEdge.hxx" -#include "SMDS_QuadraticFaceOfNodes.hxx" -#include "SMDS_QuadraticVolumeOfNodes.hxx" + +#include "SMDS_ElementFactory.hxx" +#include "SMDS_ElementHolder.hxx" +#include "SMDS_SetIterator.hxx" +#include "SMDS_SpacePosition.hxx" +#include "SMDS_UnstructuredGrid.hxx" + +#include + +#include +//#include +#include +#include +#include +#include #include -#include -using namespace std; +#include +#include + +#include + +#if !defined WIN32 && !defined __APPLE__ +#include +#endif + +// number of added entities to check memory after +#define CHECKMEMORY_INTERVAL 100000 + +#define MYASSERT(val) if (!(val)) throw SALOME_Exception(LOCALIZED("assertion not verified")); + +int SMDS_Mesh::chunkSize = 1024; + +//================================================================================ +/*! + * \brief Raise an exception if free memory (ram+swap) too low + * \param doNotRaise - if true, suppress exception, just return free memory size + * \retval int - amount of available memory in MB or negative number in failure case + */ +//================================================================================ + +int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc) +{ + return -1; +#if !defined WIN32 && !defined __APPLE__ + struct sysinfo si; + int err = sysinfo( &si ); + if ( err ) + return -1; + + const unsigned long Mbyte = 1024 * 1024; + + static int limit = -1; + if ( limit < 0 ) { + if ( si.totalswap == 0 ) + { + int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM + if (status >= 0 ) { + limit = WEXITSTATUS(status); + } + else { + double factor = ( si.totalswap == 0 ) ? 0.1 : 0.2; + limit = int(( factor * si.totalram * si.mem_unit ) / Mbyte ); + } + } + if ( limit < 20 ) + limit = 20; + else + limit = int ( limit * 1.5 ); + MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" ); + } + + // compute separately to avoid overflow + int freeMb = + ( si.freeram * si.mem_unit ) / Mbyte + + ( si.freeswap * si.mem_unit ) / Mbyte; + + if ( freeMb > limit ) + return freeMb - limit; + + if ( doNotRaise ) + return 0; + + MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" ); + throw std::bad_alloc(); +#else + return -1; +#endif +} /////////////////////////////////////////////////////////////////////////////// /// Create a new mesh object /////////////////////////////////////////////////////////////////////////////// -SMDS_Mesh::SMDS_Mesh() - :myParent(NULL), - myNodeIDFactory(new SMDS_MeshElementIDFactory()), - myElementIDFactory(new SMDS_MeshElementIDFactory()), - myHasConstructionEdges(false), myHasConstructionFaces(false), - myHasInverseElements(true) +SMDS_Mesh::SMDS_Mesh(): + myNodeFactory( new SMDS_NodeFactory( this )), + myCellFactory( new SMDS_ElementFactory( this )), + myParent(NULL), + myModified(false), myModifTime(0), myCompactTime(0), + xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0) { + myGrid = SMDS_UnstructuredGrid::New(); + myGrid->setSMDS_mesh(this); + myGrid->Initialize(); + myGrid->Allocate(); + vtkPoints* points = vtkPoints::New(); + // bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion" + // Use double type for storing coordinates of nodes instead of float. + points->SetDataType(VTK_DOUBLE); + points->SetNumberOfPoints( 0 ); + myGrid->SetPoints( points ); + points->Delete(); + this->Modified(); + + // initialize static maps in SMDS_MeshCell, to be thread-safe + SMDS_MeshCell::InitStaticMembers(); } /////////////////////////////////////////////////////////////////////////////// @@ -56,11 +149,10 @@ SMDS_Mesh::SMDS_Mesh() /// Note that the tree structure of SMDS_Mesh seems to be unused in this version /// (2003-09-08) of SMESH /////////////////////////////////////////////////////////////////////////////// -SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent) - :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory), - myElementIDFactory(parent->myElementIDFactory), - myHasConstructionEdges(false), myHasConstructionFaces(false), - myHasInverseElements(true) +SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent): + myNodeFactory( new SMDS_NodeFactory( this )), + myCellFactory( new SMDS_ElementFactory( this )), + myParent(parent) { } @@ -70,9 +162,9 @@ SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent) SMDS_Mesh *SMDS_Mesh::AddSubMesh() { - SMDS_Mesh *submesh = new SMDS_Mesh(this); - myChildren.insert(myChildren.end(), submesh); - return submesh; + SMDS_Mesh *submesh = new SMDS_Mesh(this); + myChildren.insert(myChildren.end(), submesh); + return submesh; } /////////////////////////////////////////////////////////////////////////////// @@ -83,7 +175,7 @@ SMDS_Mesh *SMDS_Mesh::AddSubMesh() SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z) { - return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID()); + return SMDS_Mesh::AddNodeWithID( x,y,z, myNodeFactory->GetFreeID() ); } /////////////////////////////////////////////////////////////////////////////// @@ -91,17 +183,104 @@ SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z) ///@param ID : The ID of the MeshNode to create ///@return : The created node or NULL if a node with this ID already exists /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID) +SMDS_MeshNode * SMDS_Mesh::AddNodeWithID( double x, double y, double z, int ID ) { // find the MeshNode corresponding to ID - const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID); - if(!node){ - SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z); - myNodes.Add(node); - myNodeIDFactory->BindID(ID,node); - return node; - }else - return NULL; + SMDS_MeshNode *node = myNodeFactory->NewNode( ID ); + if ( node ) + { + node->init( x, y, z ); + myInfo.myNbNodes++; + myModified = true; + this->adjustBoundingBox(x, y, z); + } + return node; +} + +/////////////////////////////////////////////////////////////////////////////// +/// create a Mesh0DElement and add it to the current Mesh +/// @return : The created Mesh0DElement +/////////////////////////////////////////////////////////////////////////////// +SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID) +{ + const SMDS_MeshNode * node = myNodeFactory->FindNode(idnode); + if (!node) return NULL; + return SMDS_Mesh::Add0DElementWithID(node, ID); +} + +/////////////////////////////////////////////////////////////////////////////// +/// create a Mesh0DElement and add it to the current Mesh +/// @return : The created Mesh0DElement +/////////////////////////////////////////////////////////////////////////////// +SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node) +{ + return SMDS_Mesh::Add0DElementWithID( node, myCellFactory->GetFreeID() ); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Create a new Mesh0DElement and at it to the mesh +/// @param idnode ID of the node +/// @param ID ID of the 0D element to create +/// @return The created 0D element or NULL if an element with this +/// ID already exists or if input node is not found. +/////////////////////////////////////////////////////////////////////////////// +SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID) +{ + if (!n) return 0; + + if (Nb0DElements() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); + + if ( SMDS_MeshCell * cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_0D, /*nbNodes=*/1, n ); + myInfo.myNb0DElements++; + return static_cast< SMDS_Mesh0DElement*> ( cell ); + } + + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// +/// create a Ball and add it to the current Mesh +/// @return : The created Ball +/////////////////////////////////////////////////////////////////////////////// +SMDS_BallElement* SMDS_Mesh::AddBallWithID( int idnode, double diameter, int ID ) +{ + const SMDS_MeshNode * node = myNodeFactory->FindNode( idnode ); + if (!node) return NULL; + return SMDS_Mesh::AddBallWithID( node, diameter, ID ); +} + +/////////////////////////////////////////////////////////////////////////////// +/// create a Ball and add it to the current Mesh +/// @return : The created Ball +/////////////////////////////////////////////////////////////////////////////// +SMDS_BallElement* SMDS_Mesh::AddBall(const SMDS_MeshNode * node, double diameter) +{ + return SMDS_Mesh::AddBallWithID(node, diameter, myCellFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Create a new Ball and at it to the mesh +/// @param idnode ID of the node +// @param diameter ball diameter +/// @param ID ID of the 0D element to create +/// @return The created 0D element or NULL if an element with this +/// ID already exists or if input node is not found. +/////////////////////////////////////////////////////////////////////////////// +SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diameter, int ID) +{ + if (!n) return 0; + + if (NbBalls() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); + + SMDS_BallElement* ball = static_cast< SMDS_BallElement*>( myCellFactory->NewElement( ID )); + if ( ball ) + { + ball->init( n, diameter ); + myInfo.myNbBalls++; + } + return ball; } /////////////////////////////////////////////////////////////////////////////// @@ -109,10 +288,10 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID) /// @return : The created MeshEdge /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) +SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) { - SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); - SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + const SMDS_MeshNode * node1 = myNodeFactory->FindNode(idnode1); + const SMDS_MeshNode * node2 = myNodeFactory->FindNode(idnode2); if(!node1 || !node2) return NULL; return SMDS_Mesh::AddEdgeWithID(node1, node2, ID); } @@ -123,9 +302,9 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) /////////////////////////////////////////////////////////////////////////////// SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2) + const SMDS_MeshNode * node2) { - return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID()); + return SMDS_Mesh::AddEdgeWithID(node1, node2, myCellFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// @@ -138,23 +317,18 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1, /////////////////////////////////////////////////////////////////////////////// SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - int ID) -{ - SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2); - if(myElementIDFactory->BindID(ID, edge)) { - SMDS_MeshNode *node1,*node2; - node1=const_cast(n1); - node2=const_cast(n2); - node1->AddInverseElement(edge); - node2->AddInverseElement(edge); - myEdges.Add(edge); - return edge; - } - else { - delete edge; - return NULL; + const SMDS_MeshNode * n2, + int ID) +{ + if ( !n1 || !n2 ) return 0; + + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Edge, /*nbNodes=*/2, n1, n2 ); + myInfo.myNbEdges++; + return static_cast( cell ); } + return 0; } /////////////////////////////////////////////////////////////////////////////// @@ -163,10 +337,10 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, /////////////////////////////////////////////////////////////////////////////// SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3) { - return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID()); + return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myCellFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// @@ -175,11 +349,11 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID) { - SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); - SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); - SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + const SMDS_MeshNode * node1 = myNodeFactory->FindNode(idnode1); + const SMDS_MeshNode * node2 = myNodeFactory->FindNode(idnode2); + const SMDS_MeshNode * node3 = myNodeFactory->FindNode(idnode3); if(!node1 || !node2 || !node3) return NULL; - return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID); + return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID); } /////////////////////////////////////////////////////////////////////////////// @@ -191,13 +365,16 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n3, int ID) { - SMDS_MeshFace * face=createTriangle(n1, n2, n3); + if ( !n1 || !n2 || !n3 ) return 0; + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - if (!registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Triangle, /*nbNodes=*/3, n1, n2, n3 ); + myInfo.myNbTriangles++; + return static_cast( cell ); } - return face; + return 0; } /////////////////////////////////////////////////////////////////////////////// @@ -206,30 +383,30 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, /////////////////////////////////////////////////////////////////////////////// SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4) { - return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID()); + return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myCellFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// /// Add a quadrangle defined by its nodes IDs /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, - int idnode2, - int idnode3, - int idnode4, - int ID) +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int ID) { - SMDS_MeshNode *node1, *node2, *node3, *node4; - node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); - node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); - node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); - node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); - if(!node1 || !node2 || !node3 || !node4) return NULL; - return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID); + const SMDS_MeshNode *node1, *node2, *node3, *node4; + node1 = myNodeFactory->FindNode(idnode1); + node2 = myNodeFactory->FindNode(idnode2); + node3 = myNodeFactory->FindNode(idnode3); + node4 = myNodeFactory->FindNode(idnode4); + if ( !node1 || !node2 || !node3 || !node4 ) return NULL; + return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID); } /////////////////////////////////////////////////////////////////////////////// @@ -242,130 +419,57 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4, int ID) { - SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4); - - if (!registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; - } - return face; -} - -/////////////////////////////////////////////////////////////////////////////// -/// Add a triangle defined by its edges. An ID is automatically assigned to the -/// Created face -/////////////////////////////////////////////////////////////////////////////// - -SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1, - const SMDS_MeshEdge * e2, - const SMDS_MeshEdge * e3) -{ - if (!hasConstructionEdges()) - return NULL; - return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID()); -} - -/////////////////////////////////////////////////////////////////////////////// -/// Add a triangle defined by its edges -/////////////////////////////////////////////////////////////////////////////// - -SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, - const SMDS_MeshEdge * e2, - const SMDS_MeshEdge * e3, - int ID) -{ - if (!hasConstructionEdges()) - return NULL; - SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3); - myFaces.Add(face); - - if (!registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; - } - return face; -} - -/////////////////////////////////////////////////////////////////////////////// -/// Add a quadrangle defined by its edges. An ID is automatically assigned to the -/// Created face -/////////////////////////////////////////////////////////////////////////////// - -SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1, - const SMDS_MeshEdge * e2, - const SMDS_MeshEdge * e3, - const SMDS_MeshEdge * e4) -{ - if (!hasConstructionEdges()) - return NULL; - return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID()); -} - -/////////////////////////////////////////////////////////////////////////////// -/// Add a quadrangle defined by its edges -/////////////////////////////////////////////////////////////////////////////// - -SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, - const SMDS_MeshEdge * e2, - const SMDS_MeshEdge * e3, - const SMDS_MeshEdge * e4, - int ID) -{ - if (!hasConstructionEdges()) - return NULL; - SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4); - myFaces.Add(face); + if ( !n1 || !n2 || !n3 || !n4 ) return 0; + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - if (!registerElement(ID, face)) + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) { - RemoveElement(face, false); - face = NULL; + cell->init( SMDSEntity_Quadrangle, /*nbNodes=*/4, n1, n2, n3, n4 ); + myInfo.myNbQuadrangles++; + return static_cast( cell ); } - return face; + return 0; } /////////////////////////////////////////////////////////////////////////////// -///Create a new tetrahedron and add it to the mesh. -///@return The created tetrahedron +///Create a new tetrahedron and add it to the mesh. +///@return The created tetrahedron /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4) { - int ID = myElementIDFactory->GetFreeID(); - SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID); - if(v==NULL) myElementIDFactory->ReleaseID(ID); - return v; + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, myCellFactory->GetFreeID() ); } /////////////////////////////////////////////////////////////////////////////// -///Create a new tetrahedron and add it to the mesh. +///Create a new tetrahedron and add it to the mesh. ///@param ID The ID of the new volume ///@return The created tetrahedron or NULL if an element with this ID already exists ///or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, - int idnode2, - int idnode3, - int idnode4, - int ID) +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int ID) { - SMDS_MeshNode *node1, *node2, *node3, *node4; - node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); - node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); - node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); - node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + const SMDS_MeshNode *node1, *node2, *node3, *node4; + node1 = myNodeFactory->FindNode(idnode1); + node2 = myNodeFactory->FindNode(idnode2); + node3 = myNodeFactory->FindNode(idnode3); + node4 = myNodeFactory->FindNode(idnode4); if(!node1 || !node2 || !node3 || !node4) return NULL; return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID); } - + /////////////////////////////////////////////////////////////////////////////// -///Create a new tetrahedron and add it to the mesh. +///Create a new tetrahedron and add it to the mesh. ///@param ID The ID of the new volume -///@return The created tetrahedron +///@return The created tetrahedron /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, @@ -374,74 +478,58 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4, int ID) { - SMDS_MeshVolume* volume; - if(hasConstructionFaces()) { - SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); - SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4); - SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4); - SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4); - volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4); - myVolumes.Add(volume); - } - else if(hasConstructionEdges()) { - MESSAGE("Error : Not implemented"); - return NULL; - } - else { - volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4); - myVolumes.Add(volume); - } + if ( !n1 || !n2 || !n3 || !n4 ) return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Tetra, /*nbNodes=*/4, n1, n2, n3, n4 ); + myInfo.myNbTetras++; + return static_cast( cell ); } - return volume; + return 0; } /////////////////////////////////////////////////////////////////////////////// -///Create a new pyramid and add it to the mesh. +///Create a new pyramid and add it to the mesh. ///Nodes 1,2,3 and 4 define the base of the pyramid -///@return The created pyramid +///@return The created pyramid /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5) { - int ID = myElementIDFactory->GetFreeID(); - SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID); - if(v==NULL) myElementIDFactory->ReleaseID(ID); - return v; + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, myCellFactory->GetFreeID() ); } /////////////////////////////////////////////////////////////////////////////// -///Create a new pyramid and add it to the mesh. +///Create a new pyramid and add it to the mesh. ///Nodes 1,2,3 and 4 define the base of the pyramid ///@param ID The ID of the new volume ///@return The created pyramid or NULL if an element with this ID already exists ///or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, - int idnode2, - int idnode3, - int idnode4, - int idnode5, - int ID) +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int idnode5, + int ID) { - SMDS_MeshNode *node1, *node2, *node3, *node4, *node5; - node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); - node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); - node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); - node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); - node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); + const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5; + node1 = myNodeFactory->FindNode(idnode1); + node2 = myNodeFactory->FindNode(idnode2); + node3 = myNodeFactory->FindNode(idnode3); + node4 = myNodeFactory->FindNode(idnode4); + node5 = myNodeFactory->FindNode(idnode5); if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL; return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID); } - + /////////////////////////////////////////////////////////////////////////////// ///Create a new pyramid and add it to the mesh. ///Nodes 1,2,3 and 4 define the base of the pyramid @@ -456,77 +544,61 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n5, int ID) { - SMDS_MeshVolume* volume; - if(hasConstructionFaces()) { - SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); - SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5); - SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5); - SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5); - volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4); - myVolumes.Add(volume); - } - else if(hasConstructionEdges()) { - MESSAGE("Error : Not implemented"); - return NULL; - } - else { - volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5); - myVolumes.Add(volume); - } + if ( !n1 || !n2 || !n3 || !n4 || !n5 ) return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Pyramid, /*nbNodes=*/5, n1, n2, n3, n4, n5 ); + myInfo.myNbPyramids++; + return static_cast( cell ); } - return volume; + return 0; } /////////////////////////////////////////////////////////////////////////////// -///Create a new prism and add it to the mesh. +///Create a new prism and add it to the mesh. ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle. -///@return The created prism +///@return The created prism /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6) { - int ID = myElementIDFactory->GetFreeID(); - SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID); - if(v==NULL) myElementIDFactory->ReleaseID(ID); - return v; + int ID = myCellFactory->GetFreeID(); + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID); } /////////////////////////////////////////////////////////////////////////////// -///Create a new prism and add it to the mesh. +///Create a new prism and add it to the mesh. ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle. ///@param ID The ID of the new volume ///@return The created prism or NULL if an element with this ID already exists ///or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, - int idnode2, - int idnode3, - int idnode4, - int idnode5, - int idnode6, - int ID) -{ - SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6; - node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); - node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); - node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); - node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); - node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); - node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6); - if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL; +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int idnode5, + int idnode6, + int ID) +{ + const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6; + node1 = myNodeFactory->FindNode(idnode1); + node2 = myNodeFactory->FindNode(idnode2); + node3 = myNodeFactory->FindNode(idnode3); + node4 = myNodeFactory->FindNode(idnode4); + node5 = myNodeFactory->FindNode(idnode5); + node6 = myNodeFactory->FindNode(idnode6); return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID); } - + /////////////////////////////////////////////////////////////////////////////// ///Create a new prism and add it to the mesh. ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle. @@ -542,92 +614,83 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n6, int ID) { - SMDS_MeshVolume* volume; - if(hasConstructionFaces()) { - SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); - SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6); - SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2); - SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3); - SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1); - volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); - myVolumes.Add(volume); - } - else if(hasConstructionEdges()) { - MESSAGE("Error : Not implemented"); - return NULL; - } - else { - volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6); - myVolumes.Add(volume); - } + if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 ) return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Penta, /*nbNodes=*/6, n1, n2, n3, n4, n5, n6 ); + myInfo.myNbPrisms++; + return static_cast( cell ); } - return volume; + return 0; } /////////////////////////////////////////////////////////////////////////////// -///Create a new hexahedron and add it to the mesh. -///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges. -///@return The created hexahedron +///Create a new hexagonal prism and add it to the mesh. +///@return The created prism /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, + const SMDS_MeshNode * n12) { - int ID = myElementIDFactory->GetFreeID(); - SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID); - if(v==NULL) myElementIDFactory->ReleaseID(ID); - return v; + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, + n7, n8, n9, n10, n11, n12, + myCellFactory->GetFreeID() ); } /////////////////////////////////////////////////////////////////////////////// -///Create a new hexahedron and add it to the mesh. -///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges. +///Create a new hexagonal prism and add it to the mesh. ///@param ID The ID of the new volume -///@return The created hexahedron or NULL if an element with this ID already -///exists or if input nodes are not found. +///@return The created prism or NULL if an element with this ID already exists +///or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, - int idnode2, - int idnode3, - int idnode4, - int idnode5, - int idnode6, - int idnode7, - int idnode8, - int ID) -{ - SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8; - node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); - node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); - node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); - node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); - node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); - node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6); - node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7); - node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8); - if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8) - return NULL; +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int idnode5, + int idnode6, + int idnode7, + int idnode8, + int idnode9, + int idnode10, + int idnode11, + int idnode12, + int ID) +{ + const SMDS_MeshNode *node1 = myNodeFactory->FindNode(idnode1); + const SMDS_MeshNode *node2 = myNodeFactory->FindNode(idnode2); + const SMDS_MeshNode *node3 = myNodeFactory->FindNode(idnode3); + const SMDS_MeshNode *node4 = myNodeFactory->FindNode(idnode4); + const SMDS_MeshNode *node5 = myNodeFactory->FindNode(idnode5); + const SMDS_MeshNode *node6 = myNodeFactory->FindNode(idnode6); + const SMDS_MeshNode *node7 = myNodeFactory->FindNode(idnode7); + const SMDS_MeshNode *node8 = myNodeFactory->FindNode(idnode8); + const SMDS_MeshNode *node9 = myNodeFactory->FindNode(idnode9); + const SMDS_MeshNode *node10 = myNodeFactory->FindNode(idnode10); + const SMDS_MeshNode *node11 = myNodeFactory->FindNode(idnode11); + const SMDS_MeshNode *node12 = myNodeFactory->FindNode(idnode12); return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, - node7, node8, ID); + node7, node8, node9, node10, node11, node12, + ID); } - + /////////////////////////////////////////////////////////////////////////////// -///Create a new hexahedron and add it to the mesh. -///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges. +///Create a new hexagonal prism and add it to the mesh. ///@param ID The ID of the new volume -///@return The created prism or NULL if an element with this ID already exists -///or if input nodes are not found. +///@return The created prism /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, @@ -638,358 +701,308 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, const SMDS_MeshNode * n8, + const SMDS_MeshNode * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, + const SMDS_MeshNode * n12, int ID) { - SMDS_MeshVolume* volume; - if(hasConstructionFaces()) { - SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); - SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8); - SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5); - SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5); - SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6); - SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7); - volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); - myVolumes.Add(volume); - } - else if(hasConstructionEdges()) { - MESSAGE("Error : Not implemented"); - 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); - myVolumes.Add(volume); - } + SMDS_MeshVolume* volume = 0; + if(!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || + !n7 || !n8 || !n9 || !n10 || !n11 || !n12 ) + return volume; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Hexagonal_Prism, + /*nbNodes=*/12, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12 ); + myInfo.myNbHexPrism++; + return static_cast( cell ); } - return volume; + return 0; } /////////////////////////////////////////////////////////////////////////////// -///Create a new tetrahedron defined by its faces and add it to the mesh. -///@return The created tetrahedron +///Create a new hexahedron and add it to the mesh. +///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges. +///@return The created hexahedron /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, - const SMDS_MeshFace * f2, - const SMDS_MeshFace * f3, - const SMDS_MeshFace * f4) +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8) { - if (!hasConstructionFaces()) - return NULL; - return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID()); + int ID = myCellFactory->GetFreeID(); + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID); } /////////////////////////////////////////////////////////////////////////////// -///Create a new tetrahedron defined by its faces and add it to the mesh. +///Create a new hexahedron and add it to the mesh. +///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges. ///@param ID The ID of the new volume -///@return The created tetrahedron +///@return The created hexahedron or NULL if an element with this ID already +///exists or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, - const SMDS_MeshFace * f2, - const SMDS_MeshFace * f3, - const SMDS_MeshFace * f4, - int ID) -{ - if (!hasConstructionFaces()) - return NULL; - SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4); - myVolumes.Add(volume); - - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } - return volume; +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int idnode5, + int idnode6, + int idnode7, + int idnode8, + int ID) +{ + const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8; + node1 = myNodeFactory->FindNode(idnode1); + node2 = myNodeFactory->FindNode(idnode2); + node3 = myNodeFactory->FindNode(idnode3); + node4 = myNodeFactory->FindNode(idnode4); + node5 = myNodeFactory->FindNode(idnode5); + node6 = myNodeFactory->FindNode(idnode6); + node7 = myNodeFactory->FindNode(idnode7); + node8 = myNodeFactory->FindNode(idnode8); + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, + node7, node8, ID); } /////////////////////////////////////////////////////////////////////////////// -///Create a new pyramid defined by its faces and add it to the mesh. -///@return The created pyramid +///Create a new hexahedron and add it to the mesh. +///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges. +///@param ID The ID of the new volume +///@return The created prism or NULL if an element with this ID already exists +///or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, - const SMDS_MeshFace * f2, - const SMDS_MeshFace * f3, - const SMDS_MeshFace * f4, - const SMDS_MeshFace * f5) +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + int ID) { - if (!hasConstructionFaces()) - return NULL; - return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID()); + SMDS_MeshVolume* volume = 0; + if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Hexa, + /*nbNodes=*/8, n1, n2, n3, n4, n5, n6, n7, n8 ); + myInfo.myNbHexas++; + return static_cast( cell ); + } + return 0; } /////////////////////////////////////////////////////////////////////////////// -///Create a new pyramid defined by its faces and add it to the mesh. -///@param ID The ID of the new volume -///@return The created pyramid +/// Add a polygon defined by its nodes IDs /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, - const SMDS_MeshFace * f2, - const SMDS_MeshFace * f3, - const SMDS_MeshFace * f4, - const SMDS_MeshFace * f5, - int ID) +SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const std::vector & nodes_ids, + const int ID) { - if (!hasConstructionFaces()) - return NULL; - SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); - myVolumes.Add(volume); - - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; + int nbNodes = nodes_ids.size(); + std::vector nodes (nbNodes); + for (int i = 0; i < nbNodes; i++) { + nodes[i] = myNodeFactory->FindNode( nodes_ids[i] ); + if (!nodes[i]) return NULL; } - return volume; + return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID); } /////////////////////////////////////////////////////////////////////////////// -///Create a new prism defined by its faces and add it to the mesh. -///@return The created prism +/// Add a polygon defined by its nodes /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, - const SMDS_MeshFace * f2, - const SMDS_MeshFace * f3, - const SMDS_MeshFace * f4, - const SMDS_MeshFace * f5, - const SMDS_MeshFace * f6) +SMDS_MeshFace* +SMDS_Mesh::AddPolygonalFaceWithID (const std::vector & nodes, + const int ID) { - if (!hasConstructionFaces()) - return NULL; - return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID()); + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + + if ( nodes.empty() ) + throw std::invalid_argument("Polygon without nodes is forbidden"); + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Polygon, nodes ); + myInfo.myNbPolygons++; + return static_cast( cell ); + } + return 0; } /////////////////////////////////////////////////////////////////////////////// -///Create a new prism defined by its faces and add it to the mesh. -///@param ID The ID of the new volume -///@return The created prism +/// Add a polygon defined by its nodes. +/// An ID is automatically affected to the created face. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, - const SMDS_MeshFace * f2, - const SMDS_MeshFace * f3, - const SMDS_MeshFace * f4, - const SMDS_MeshFace * f5, - const SMDS_MeshFace * f6, - int ID) +SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const std::vector & nodes) { - if (!hasConstructionFaces()) - return NULL; - SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); - myVolumes.Add(volume); - - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } - return volume; + return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myCellFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// -/// Add a polygon defined by its nodes IDs +/// Add a quadratic polygon defined by its nodes IDs /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector nodes_ids, - const int ID) +SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector & nodes_ids, + const int ID) { - int nbNodes = nodes_ids.size(); - std::vector nodes (nbNodes); - for (int i = 0; i < nbNodes; i++) { - nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]); + std::vector nodes( nodes_ids.size() ); + for ( size_t i = 0; i < nodes.size(); i++) { + nodes[i] = myNodeFactory->FindNode(nodes_ids[i]); if (!nodes[i]) return NULL; } - return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID); + return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID); } /////////////////////////////////////////////////////////////////////////////// -/// Add a polygon defined by its nodes +/// Add a quadratic polygon defined by its nodes /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID - (std::vector nodes, - const int ID) +SMDS_MeshFace* +SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector & nodes, + const int ID) { - SMDS_MeshFace * face; - - if (hasConstructionEdges()) - { - MESSAGE("Error : Not implemented"); - return NULL; - } - else + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( nodes.empty() ) + throw std::invalid_argument("Polygon without nodes is forbidden"); + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) { - face = new SMDS_PolygonalFaceOfNodes(nodes); - myFaces.Add(face); - } - - if (!registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; + cell->init( SMDSEntity_Quad_Polygon, nodes ); + myInfo.myNbQuadPolygons++; + return static_cast( cell ); } - return face; + return 0; } /////////////////////////////////////////////////////////////////////////////// -/// Add a polygon defined by its nodes. +/// Add a quadratic polygon defined by its nodes. /// An ID is automatically affected to the created face. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector nodes) +SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const std::vector & nodes) { - return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID()); + return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, myCellFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// -/// Create a new polyhedral volume and add it to the mesh. +/// Create a new polyhedral volume and add it to the mesh. /// @param ID The ID of the new volume /// @return The created volume or NULL if an element with this ID already exists /// or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID - (std::vector nodes_ids, - std::vector quantities, - const int ID) +SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector & nodes_ids, + const std::vector & quantities, + const int ID) { int nbNodes = nodes_ids.size(); std::vector nodes (nbNodes); for (int i = 0; i < nbNodes; i++) { - nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]); + nodes[i] = myNodeFactory->FindNode(nodes_ids[i]); if (!nodes[i]) return NULL; } return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); } /////////////////////////////////////////////////////////////////////////////// -/// Create a new polyhedral volume and add it to the mesh. +/// Create a new polyhedral volume and add it to the mesh. /// @param ID The ID of the new volume /// @return The created volume /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID - (std::vector nodes, - std::vector quantities, - const int ID) +SMDS_MeshVolume* +SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector& nodes, + const std::vector & quantities, + const int ID) { - SMDS_MeshVolume* volume; - if (hasConstructionFaces()) { - MESSAGE("Error : Not implemented"); + if ( nodes.empty() || quantities.empty() ) return NULL; - } else if (hasConstructionEdges()) { - MESSAGE("Error : Not implemented"); - return NULL; - } else { - volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities); - myVolumes.Add(volume); - } + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + SMDS_MeshVolume* volume = static_cast( cell ); + volume->init( nodes, quantities ); + myInfo.myNbPolyhedrons++; + return volume; } - return volume; + return 0; } /////////////////////////////////////////////////////////////////////////////// -/// Create a new polyhedral volume and add it to the mesh. +/// Create a new polyhedral volume and add it to the mesh. /// @return The created volume /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume - (std::vector nodes, - std::vector quantities) +(const std::vector & nodes, + const std::vector & quantities) +{ + int ID = myCellFactory->GetFreeID(); + return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); +} + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector& vtkNodeIds) { - int ID = myElementIDFactory->GetFreeID(); - SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); - if (v == NULL) myElementIDFactory->ReleaseID(ID); - return v; + SMDS_MeshCell* cell = myCellFactory->NewCell( myCellFactory->GetFreeID() ); + SMDS_MeshVolume * vol = static_cast( cell ); + vol->init( vtkNodeIds ); + myInfo.add( cell ); + return vol; } -/////////////////////////////////////////////////////////////////////////////// -/// Registers element with the given ID, maintains inverse connections -/////////////////////////////////////////////////////////////////////////////// -bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element) +SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIds(const std::vector& vtkNodeIds) { - if (myElementIDFactory->BindID(ID, element)) { - SMDS_ElemIteratorPtr it = element->nodesIterator(); - while (it->more()) { - SMDS_MeshNode *node = static_cast - (const_cast(it->next())); - node->AddInverseElement(element); - } - return true; - } - return false; + SMDS_MeshCell* cell = myCellFactory->NewCell( myCellFactory->GetFreeID() ); + SMDS_MeshFace * f = static_cast( cell ); + f->init( vtkNodeIds ); + myInfo.add( cell ); + return f; +} + +//======================================================================= +//function : MoveNode +//purpose : +//======================================================================= + +void SMDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z) +{ + SMDS_MeshNode * node=const_cast(n); + node->setXYZ(x,y,z); } /////////////////////////////////////////////////////////////////////////////// -/// Return the node whose ID is 'ID'. +/// Return the node whose SMDS ID is 'ID'. /////////////////////////////////////////////////////////////////////////////// const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const { - return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID); + return myNodeFactory->FindNode( ID ); } /////////////////////////////////////////////////////////////////////////////// -///Create a triangle and add it to the current mesh. This methode do not bind a -///ID to the create triangle. +/// Return the node whose VTK ID is 'vtkId'. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3) +const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const { - if(hasConstructionEdges()) - { - SMDS_MeshEdge *edge1, *edge2, *edge3; - edge1=FindEdgeOrCreate(node1,node2); - edge2=FindEdgeOrCreate(node2,node3); - edge3=FindEdgeOrCreate(node3,node1); + return myNodeFactory->FindNode( vtkId + 1 ); +} - SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3); - myFaces.Add(face); - return face; - } - else - { - SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3); - myFaces.Add(face); - return face; - } -} - -/////////////////////////////////////////////////////////////////////////////// -///Create a quadrangle and add it to the current mesh. This methode do not bind -///a ID to the create triangle. -/////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4) -{ - if(hasConstructionEdges()) - { - SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4; - edge1=FindEdgeOrCreate(node1,node2); - edge2=FindEdgeOrCreate(node2,node3); - edge3=FindEdgeOrCreate(node3,node4); - edge4=FindEdgeOrCreate(node4,node1); - - SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4); - myFaces.Add(face); - return face; - } - else - { - SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4); - myFaces.Add(face); - return face; - } +const SMDS_MeshElement * SMDS_Mesh::FindElementVtk(int IDelem) const +{ + return myCellFactory->FindElement( FromVtkToSmds( IDelem )); } /////////////////////////////////////////////////////////////////////////////// @@ -998,34 +1011,7 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1, void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node) { - RemoveElement(node, true); -} - -/////////////////////////////////////////////////////////////////////////////// -/// Remove an edge and all the elements which own this edge -/////////////////////////////////////////////////////////////////////////////// - -void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge) -{ - RemoveElement(edge,true); -} - -/////////////////////////////////////////////////////////////////////////////// -/// Remove an face and all the elements which own this face -/////////////////////////////////////////////////////////////////////////////// - -void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face) -{ - RemoveElement(face, true); -} - -/////////////////////////////////////////////////////////////////////////////// -/// Remove a volume -/////////////////////////////////////////////////////////////////////////////// - -void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume) -{ - RemoveElement(volume, true); + RemoveElement(node, true); } //======================================================================= @@ -1035,8 +1021,8 @@ void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume) bool SMDS_Mesh::RemoveFromParent() { - if (myParent==NULL) return false; - else return (myParent->RemoveSubMesh(this)); + if (myParent==NULL) return false; + else return (myParent->RemoveSubMesh(this)); } //======================================================================= @@ -1046,413 +1032,248 @@ bool SMDS_Mesh::RemoveFromParent() bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh) { - bool found = false; + bool found = false; + + std::list::iterator itmsh=myChildren.begin(); + for (; itmsh!=myChildren.end() && !found; itmsh++) + { + SMDS_Mesh * submesh = *itmsh; + if (submesh == aMesh) + { + found = true; + myChildren.erase(itmsh); + } + } + + return found; +} + +//======================================================================= +//function : ChangePolyhedronNodes +//purpose : +//======================================================================= + +bool SMDS_Mesh::ChangePolyhedronNodes(const SMDS_MeshElement * element, + const std::vector& nodes, + const std::vector& quantities) +{ + // keep current nodes of element + std::set oldNodes( element->begin_nodes(), element->end_nodes() ); - list::iterator itmsh=myChildren.begin(); - for (; itmsh!=myChildren.end() && !found; itmsh++) - { - SMDS_Mesh * submesh = *itmsh; - if (submesh == aMesh) - { - found = true; - myChildren.erase(itmsh); - } - } + // change nodes + bool Ok = false; + if ( const SMDS_MeshVolume* vol = DownCast( element )) + Ok = vol->ChangeNodes( nodes, quantities ); - return found; + if ( Ok ) + { + setMyModified(); + updateInverseElements( element, &nodes[0], nodes.size(), oldNodes ); + } + return Ok; } //======================================================================= //function : ChangeElementNodes -//purpose : +//purpose : //======================================================================= -bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, +bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element, const SMDS_MeshNode * nodes[], const int nbnodes) { - // keep current nodes of elem - set oldNodes; - SMDS_ElemIteratorPtr itn = elem->nodesIterator(); - while(itn->more()) - oldNodes.insert( itn->next() ); + // keep current nodes of element + std::set oldNodes( element->begin_nodes(), element->end_nodes() ); // change nodes bool Ok = false; - switch ( elem->GetType() ) + if ( SMDS_MeshCell* cell = dynamic_cast((SMDS_MeshElement*) element)) + Ok = cell->ChangeNodes(nodes, nbnodes); + + if ( Ok ) { - case SMDSAbs_Edge: { - if ( nbnodes == 2 ) { - const SMDS_MeshEdge* edge = dynamic_cast( elem ); - if ( edge ) - Ok = const_cast( edge )->ChangeNodes( nodes[0], nodes[1] ); - } - else if ( nbnodes == 3 ) { - const SMDS_QuadraticEdge* edge = dynamic_cast( elem ); - if ( edge ) - Ok = const_cast( edge )->ChangeNodes( nodes[0], nodes[1], nodes[2] ); - } - break; - } - case SMDSAbs_Face: { - const SMDS_FaceOfNodes* face = dynamic_cast( elem ); - if ( face ) { - Ok = const_cast( face )->ChangeNodes( nodes, nbnodes ); - } - else { - const SMDS_QuadraticFaceOfNodes* QF = - dynamic_cast( elem ); - if ( QF ) { - Ok = const_cast( QF )->ChangeNodes( nodes, nbnodes ); - } - else { - /// ??? begin - const SMDS_PolygonalFaceOfNodes* face = dynamic_cast(elem); - if (face) { - Ok = const_cast(face)->ChangeNodes(nodes, nbnodes); - } - /// ??? end - } - } - break; - } - //case SMDSAbs_PolygonalFace: { - // const SMDS_PolygonalFaceOfNodes* face = dynamic_cast(elem); - // if (face) { - // Ok = const_cast(face)->ChangeNodes(nodes, nbnodes); - // } - // break; - //} - case SMDSAbs_Volume: { - const SMDS_VolumeOfNodes* vol = dynamic_cast( elem ); - if ( vol ) { - Ok = const_cast( vol )->ChangeNodes( nodes, nbnodes ); - } - else { - const SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast( elem ); - if ( QV ) { - Ok = const_cast( QV )->ChangeNodes( nodes, nbnodes ); - } - } - break; - } - default: - MESSAGE ( "WRONG ELEM TYPE"); + setMyModified(); + updateInverseElements( element, nodes, nbnodes, oldNodes ); } + return Ok; +} - if ( Ok ) { // update InverseElements +//======================================================================= +//function : updateInverseElements +//purpose : update InverseElements when element changes node +//======================================================================= + +void SMDS_Mesh::updateInverseElements( const SMDS_MeshElement * element, + const SMDS_MeshNode* const* nodes, + const int nbnodes, + std::set& oldNodes ) +{ + if ( GetGrid()->HasLinks() ) // update InverseElements + { + std::set::iterator it; // AddInverseElement to new nodes for ( int i = 0; i < nbnodes; i++ ) - if ( oldNodes.find( nodes[i] ) == oldNodes.end() ) + { + it = oldNodes.find( nodes[i] ); + if ( it == oldNodes.end() ) // new node - const_cast( nodes[i] )->AddInverseElement( elem ); + const_cast( nodes[i] )->AddInverseElement( element ); else // remove from oldNodes a node that remains in elem - oldNodes.erase( nodes[i] ); - - + oldNodes.erase( it ); + } // RemoveInverseElement from the nodes removed from elem - set::iterator it; for ( it = oldNodes.begin(); it != oldNodes.end(); it++ ) { - SMDS_MeshNode * n = static_cast - (const_cast( *it )); - n->RemoveInverseElement( elem ); + SMDS_MeshNode * n = const_cast( *it ); + n->RemoveInverseElement( element ); } } - //MESSAGE ( "::ChangeNodes() Ok = " << Ok); - - return Ok; } -//======================================================================= -//function : ChangePolyhedronNodes -//purpose : to change nodes of polyhedral volume -//======================================================================= -bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, - std::vector nodes, - std::vector quantities) +const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node) { - if (elem->GetType() != SMDSAbs_Volume) { - MESSAGE("WRONG ELEM TYPE"); - return false; - } - - const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast(elem); - if (!vol) { - return false; - } - - // keep current nodes of elem - set oldNodes; - SMDS_ElemIteratorPtr itn = elem->nodesIterator(); - while (itn->more()) { - oldNodes.insert(itn->next()); - } - - // change nodes - bool Ok = const_cast(vol)->ChangeNodes(nodes, quantities); - if (!Ok) { - return false; - } - - // update InverseElements - - // AddInverseElement to new nodes - int nbnodes = nodes.size(); - for (int i = 0; i < nbnodes; i++) { - if (oldNodes.find(nodes[i]) == oldNodes.end()) { - // new node - const_cast(nodes[i])->AddInverseElement(elem); - } else { - // remove from oldNodes a node that remains in elem - oldNodes.erase(nodes[i]); + if (!node) return 0; + const SMDS_Mesh0DElement* toReturn = NULL; + SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement); + while (it1->more() && (toReturn == NULL)) { + const SMDS_MeshElement* e = it1->next(); + if (e->NbNodes() == 1) { + toReturn = static_cast(e); } } - - // RemoveInverseElement from the nodes removed from elem - set::iterator it; - for (it = oldNodes.begin(); it != oldNodes.end(); it++) { - SMDS_MeshNode * n = static_cast - (const_cast( *it )); - n->RemoveInverseElement(elem); - } - - return Ok; + return toReturn; } - -//======================================================================= -//function : FindEdge -//purpose : -//======================================================================= - -const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const +const SMDS_BallElement* SMDS_Mesh::FindBall(const SMDS_MeshNode * node) { - const SMDS_MeshNode * node1=FindNode(idnode1); - const SMDS_MeshNode * node2=FindNode(idnode2); - if((node1==NULL)||(node2==NULL)) return NULL; - return FindEdge(node1,node2); + if (!node) return 0; + const SMDS_BallElement* toReturn = NULL; + SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_Ball); + while (it1->more() && (toReturn == NULL)) { + const SMDS_MeshElement* e = it1->next(); + if (e->GetGeomType() == SMDSGeom_BALL) + toReturn = static_cast(e); + } + return toReturn; } -//#include "Profiler.h" const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2) { + if ( !node1 ) return 0; const SMDS_MeshEdge * toReturn=NULL; - //PROFILER_Init(); - //PROFILER_Set(); - SMDS_ElemIteratorPtr it1=node1->edgesIterator(); - //PROFILER_Get(0); - //PROFILER_Set(); + SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge); while(it1->more()) { - const SMDS_MeshEdge * e=static_cast (it1->next()); - SMDS_ElemIteratorPtr it2=e->nodesIterator(); - while(it2->more()) { - if(it2->next()->GetID()==node2->GetID()) { - toReturn = e; - break; - } + const SMDS_MeshElement * e = it1->next(); + if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) { + toReturn = static_cast( e ); + break; } } - //PROFILER_Get(1); return toReturn; } - -//======================================================================= -//function : FindEdgeOrCreate -//purpose : -//======================================================================= - -SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2) -{ - SMDS_MeshEdge * toReturn=NULL; - toReturn=const_cast(FindEdge(node1,node2)); - if(toReturn==NULL) { - toReturn=new SMDS_MeshEdge(node1,node2); - myEdges.Add(toReturn); - } - return toReturn; -} - - -//======================================================================= -//function : FindEdge -//purpose : -//======================================================================= - -const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2, - int idnode3) const -{ - const SMDS_MeshNode * node1=FindNode(idnode1); - const SMDS_MeshNode * node2=FindNode(idnode2); - const SMDS_MeshNode * node3=FindNode(idnode3); - if( (node1==NULL) || (node2==NULL) || (node3==NULL) ) return NULL; - return FindEdge(node1,node2,node3); -} - const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2, const SMDS_MeshNode * node3) { - const SMDS_MeshEdge * toReturn = NULL; - SMDS_ElemIteratorPtr it1 = node1->edgesIterator(); + if ( !node1 ) return 0; + SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge); while(it1->more()) { - const SMDS_MeshEdge * e = static_cast (it1->next()); - SMDS_ElemIteratorPtr it2 = e->nodesIterator(); - int tmp = 0; - while(it2->more()) { - int nID = it2->next()->GetID(); - if( nID==node2->GetID() || nID==node3->GetID() ) { - tmp++; - if(tmp==2) { - toReturn = e; + const SMDS_MeshElement * e = it1->next(); + if ( e->NbNodes() == 3 ) { + SMDS_ElemIteratorPtr it2 = e->nodesIterator(); + while(it2->more()) { + const SMDS_MeshElement* n = it2->next(); + if( n!=node1 && + n!=node2 && + n!=node3 ) + { + e = 0; break; } } + if ( e ) + return static_cast (e); } } - return toReturn; + return 0; } - //======================================================================= //function : FindFace //purpose : //======================================================================= -const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, - int idnode3) const -{ - const SMDS_MeshNode * node1=FindNode(idnode1); - const SMDS_MeshNode * node2=FindNode(idnode2); - const SMDS_MeshNode * node3=FindNode(idnode3); - if( (node1==NULL) || (node2==NULL) || (node3==NULL) ) return NULL; - return FindFace(node1, node2, node3); -} - const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, const SMDS_MeshNode *node2, const SMDS_MeshNode *node3) { - const SMDS_MeshFace * face; - const SMDS_MeshElement * node; - bool node2found, node3found; - - SMDS_ElemIteratorPtr it1 = node1->facesIterator(); + if ( !node1 ) return 0; + SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face); while(it1->more()) { - face = static_cast(it1->next()); - if(face->NbNodes()!=3) continue; - SMDS_ElemIteratorPtr it2 = face->nodesIterator(); - node2found = false; - node3found = false; - while(it2->more()) { - node = it2->next(); - if(node->GetID()==node2->GetID()) node2found = true; - if(node->GetID()==node3->GetID()) node3found = true; + const SMDS_MeshElement * e = it1->next(); + if ( e->NbNodes() == 3 ) { + SMDS_ElemIteratorPtr it2 = e->nodesIterator(); + while(it2->more()) { + const SMDS_MeshElement* n = it2->next(); + if( n!=node1 && + n!=node2 && + n!=node3 ) + { + e = 0; + break; + } + } + if ( e ) + return static_cast (e); } - if( node2found && node3found ) - return face; - } - return NULL; -} - -SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1, - const SMDS_MeshNode *node2, - const SMDS_MeshNode *node3) -{ - SMDS_MeshFace * toReturn=NULL; - toReturn = const_cast(FindFace(node1,node2,node3)); - if(toReturn==NULL) { - toReturn = createTriangle(node1,node2,node3); } - return toReturn; + return 0; } - //======================================================================= //function : FindFace //purpose : //======================================================================= -const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, - int idnode3, int idnode4) const -{ - const SMDS_MeshNode * node1=FindNode(idnode1); - const SMDS_MeshNode * node2=FindNode(idnode2); - const SMDS_MeshNode * node3=FindNode(idnode3); - const SMDS_MeshNode * node4=FindNode(idnode4); - if( (node1==NULL) || (node2==NULL) || (node3==NULL) || (node4==NULL) ) - return NULL; - return FindFace(node1, node2, node3, node4); -} - const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, const SMDS_MeshNode *node2, const SMDS_MeshNode *node3, const SMDS_MeshNode *node4) { - const SMDS_MeshFace * face; - const SMDS_MeshElement * node; - bool node2found, node3found, node4found; - SMDS_ElemIteratorPtr it1 = node1->facesIterator(); + if ( !node1 ) return 0; + SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face); while(it1->more()) { - face = static_cast(it1->next()); - if(face->NbNodes()!=4) continue; - SMDS_ElemIteratorPtr it2 = face->nodesIterator(); - node2found = false; - node3found = false; - node4found = false; - while(it2->more()) { - node=it2->next(); - if(node->GetID()==node2->GetID()) node2found = true; - if(node->GetID()==node3->GetID()) node3found = true; - if(node->GetID()==node4->GetID()) node4found = true; + const SMDS_MeshElement * e = it1->next(); + if ( e->NbNodes() == 4 ) { + SMDS_ElemIteratorPtr it2 = e->nodesIterator(); + while(it2->more()) { + const SMDS_MeshElement* n = it2->next(); + if( n!=node1 && + n!=node2 && + n!=node3 && + n!=node4 ) + { + e = 0; + break; + } + } + if ( e ) + return static_cast (e); } - if( node2found && node3found && node4found ) - return face; } - return NULL; + return 0; } -SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1, - const SMDS_MeshNode *node2, - const SMDS_MeshNode *node3, - const SMDS_MeshNode *node4) -{ - SMDS_MeshFace * toReturn=NULL; - toReturn=const_cast(FindFace(node1,node2,node3,node4)); - if(toReturn==NULL) { - toReturn=createQuadrangle(node1,node2,node3,node4); - } - return toReturn; -} - - //======================================================================= //function : FindFace //purpose :quadratic triangle //======================================================================= -const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, - int idnode3, int idnode4, - int idnode5, int idnode6) const -{ - const SMDS_MeshNode * node1 = FindNode(idnode1); - const SMDS_MeshNode * node2 = FindNode(idnode2); - const SMDS_MeshNode * node3 = FindNode(idnode3); - const SMDS_MeshNode * node4 = FindNode(idnode4); - const SMDS_MeshNode * node5 = FindNode(idnode5); - const SMDS_MeshNode * node6 = FindNode(idnode6); - if( (node1==NULL) || (node2==NULL) || (node3==NULL) || - (node4==NULL) || (node5==NULL) || (node6==NULL) ) return NULL; - return FindFace(node1, node2, node3, node4, node5, node6); -} - const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, const SMDS_MeshNode *node2, const SMDS_MeshNode *node3, @@ -1460,26 +1281,30 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, const SMDS_MeshNode *node5, const SMDS_MeshNode *node6) { - const SMDS_MeshFace * face; - const SMDS_MeshElement * node; - SMDS_ElemIteratorPtr it1 = node1->facesIterator(); + if ( !node1 ) return 0; + SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face); while(it1->more()) { - face = static_cast(it1->next()); - if(face->NbNodes()!=6) continue; - SMDS_ElemIteratorPtr it2 = face->nodesIterator(); - int tmp = 0; - while(it2->more()) { - node = it2->next(); - if(node->GetID()==node2->GetID()) tmp++; - if(node->GetID()==node3->GetID()) tmp++; - if(node->GetID()==node4->GetID()) tmp++; - if(node->GetID()==node5->GetID()) tmp++; - if(node->GetID()==node6->GetID()) tmp++; + const SMDS_MeshElement * e = it1->next(); + if ( e->NbNodes() == 6 ) { + SMDS_ElemIteratorPtr it2 = e->nodesIterator(); + while(it2->more()) { + const SMDS_MeshElement* n = it2->next(); + if( n!=node1 && + n!=node2 && + n!=node3 && + n!=node4 && + n!=node5 && + n!=node6 ) + { + e = 0; + break; + } + } + if ( e ) + return static_cast (e); } - if( tmp==5 ) - return static_cast(face); } - return NULL; + return 0; } @@ -1488,25 +1313,6 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, //purpose : quadratic quadrangle //======================================================================= -const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, - int idnode3, int idnode4, - int idnode5, int idnode6, - int idnode7, int idnode8) const -{ - const SMDS_MeshNode * node1 = FindNode(idnode1); - const SMDS_MeshNode * node2 = FindNode(idnode2); - const SMDS_MeshNode * node3 = FindNode(idnode3); - const SMDS_MeshNode * node4 = FindNode(idnode4); - const SMDS_MeshNode * node5 = FindNode(idnode5); - const SMDS_MeshNode * node6 = FindNode(idnode6); - const SMDS_MeshNode * node7 = FindNode(idnode7); - const SMDS_MeshNode * node8 = FindNode(idnode8); - if( (node1==NULL) || (node2==NULL) || (node3==NULL) || (node4==NULL) || - (node5==NULL) || (node6==NULL) || (node7==NULL) || (node8==NULL) ) - return NULL; - return FindFace(node1, node2, node3, node4, node5, node6, node7, node8); -} - const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, const SMDS_MeshNode *node2, const SMDS_MeshNode *node3, @@ -1516,28 +1322,32 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, const SMDS_MeshNode *node7, const SMDS_MeshNode *node8) { - const SMDS_MeshFace * face; - const SMDS_MeshElement * node; - SMDS_ElemIteratorPtr it1 = node1->facesIterator(); + if ( !node1 ) return 0; + SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face); while(it1->more()) { - face = static_cast(it1->next()); - if(face->NbNodes()!=8) continue; - SMDS_ElemIteratorPtr it2 = face->nodesIterator(); - int tmp = 0; - while(it2->more()) { - node = it2->next(); - if(node->GetID()==node2->GetID()) tmp++; - if(node->GetID()==node3->GetID()) tmp++; - if(node->GetID()==node4->GetID()) tmp++; - if(node->GetID()==node5->GetID()) tmp++; - if(node->GetID()==node6->GetID()) tmp++; - if(node->GetID()==node7->GetID()) tmp++; - if(node->GetID()==node8->GetID()) tmp++; + const SMDS_MeshElement * e = it1->next(); + if ( e->NbNodes() == 8 ) { + SMDS_ElemIteratorPtr it2 = e->nodesIterator(); + while(it2->more()) { + const SMDS_MeshElement* n = it2->next(); + if( n!=node1 && + n!=node2 && + n!=node3 && + n!=node4 && + n!=node5 && + n!=node6 && + n!=node7 && + n!=node8 ) + { + e = 0; + break; + } + } + if ( e ) + return static_cast (e); } - if( tmp==7 ) - return face; } - return NULL; + return 0; } @@ -1548,7 +1358,7 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const { - return myElementIDFactory->MeshElement(IDelem); + return myCellFactory->FindElement( IDelem ); } //======================================================================= @@ -1556,154 +1366,122 @@ const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const //purpose : find polygon //======================================================================= -const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector nodes_ids) const -{ - int nbnodes = nodes_ids.size(); - std::vector poly_nodes (nbnodes); - for (int inode = 0; inode < nbnodes; inode++) { - const SMDS_MeshNode * node = FindNode(nodes_ids[inode]); - if (node == NULL) return NULL; - } - return FindFace(poly_nodes); -} -const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector nodes) +const SMDS_MeshFace* SMDS_Mesh::FindFace (const std::vector& nodes) { - int nbNodes = nodes.size(); - if (nbNodes < 1) return NULL; + return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face ); +} - bool isFound = true; - const SMDS_MeshFace * face; - set faces; - for (int inode = 0; inode < nbNodes && isFound; inode++) { - set new_faces; +//================================================================================ +/*! + * \brief Return element based on all given nodes + * \param nodes - node of element + * \param type - type of element + * \param noMedium - true if medium nodes of quadratic element are not included in + * \retval const SMDS_MeshElement* - found element or NULL + */ +//================================================================================ - SMDS_ElemIteratorPtr itF = nodes[inode]->facesIterator(); - while (itF->more()) { - face = static_cast(itF->next()); - if (face->NbNodes() == nbNodes) { - if (inode == 0 || faces.find(face) != faces.end()) { - new_faces.insert(face); +const SMDS_MeshElement* SMDS_Mesh::FindElement (const std::vector& nodes, + const SMDSAbs_ElementType type, + const bool noMedium) +{ + if ( nodes.size() > 0 && nodes[0] ) + { + SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type); + while (itF->more()) + { + const SMDS_MeshElement* e = itF->next(); + int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes(); + if ( nbNodesToCheck == (int)nodes.size() ) + { + for ( size_t i = 1; e && i < nodes.size(); ++i ) + { + int nodeIndex = e->GetNodeIndex( nodes[ i ]); + if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck ) + e = 0; } + if ( e ) + return e; } } - faces = new_faces; - if (new_faces.size() == 0) { - isFound = false; - } } - - if (isFound) - return face; - return NULL; } -//======================================================================= -//function : DumpNodes -//purpose : -//======================================================================= +//================================================================================ +/*! + * \brief Return elements including all given nodes + * \param [in] nodes - nodes to find elements around + * \param [out] foundElems - the found elements + * \param [in] type - type of elements to find + * \return int - a number of found elements + */ +//================================================================================ -void SMDS_Mesh::DumpNodes() const +int SMDS_Mesh::GetElementsByNodes(const std::vector& nodes, + std::vector& foundElems, + const SMDSAbs_ElementType type) { - MESSAGE("dump nodes of mesh : "); - SMDS_NodeIteratorPtr itnode=nodesIterator(); - while(itnode->more()) MESSAGE(itnode->next()); -} - -//======================================================================= -//function : DumpEdges -//purpose : -//======================================================================= + // chose a node with minimal number of inverse elements + const SMDS_MeshNode* n0 = nodes[0]; + int minNbInverse = n0 ? n0->NbInverseElements( type ) : 1000; + for ( size_t i = 1; i < nodes.size(); ++i ) + if ( nodes[i] && nodes[i]->NbInverseElements( type ) < minNbInverse ) + { + n0 = nodes[i]; + minNbInverse = n0->NbInverseElements( type ); + } -void SMDS_Mesh::DumpEdges() const -{ - MESSAGE("dump edges of mesh : "); - SMDS_EdgeIteratorPtr itedge=edgesIterator(); - while(itedge->more()) MESSAGE(itedge->next()); + foundElems.clear(); + if ( n0 ) + { + foundElems.reserve( minNbInverse ); + SMDS_ElemIteratorPtr eIt = n0->GetInverseElementIterator( type ); + while ( eIt->more() ) + { + const SMDS_MeshElement* e = eIt->next(); + bool includeAll = true; + for ( size_t i = 0; i < nodes.size() && includeAll; ++i ) + if ( nodes[i] != n0 && e->GetNodeIndex( nodes[i] ) < 0 ) + includeAll = false; + if ( includeAll ) + foundElems.push_back( e ); + } + } + return foundElems.size(); } -//======================================================================= -//function : DumpFaces -//purpose : -//======================================================================= - -void SMDS_Mesh::DumpFaces() const +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of nodes +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbNodes() const { - MESSAGE("dump faces of mesh : "); - SMDS_FaceIteratorPtr itface=facesIterator(); - while(itface->more()) MESSAGE(itface->next()); + return myInfo.NbNodes(); } -//======================================================================= -//function : DumpVolumes -//purpose : -//======================================================================= - -void SMDS_Mesh::DumpVolumes() const +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of elements +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbElements() const { - MESSAGE("dump volumes of mesh : "); - SMDS_VolumeIteratorPtr itvol=volumesIterator(); - while(itvol->more()) MESSAGE(itvol->next()); + return myInfo.NbElements(); } - -//======================================================================= -//function : DebugStats -//purpose : -//======================================================================= - -void SMDS_Mesh::DebugStats() const +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of 0D elements +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::Nb0DElements() const { - MESSAGE("Debug stats of mesh : "); - - MESSAGE("===== NODES ====="<more()) - { - const SMDS_MeshNode *node = itnode->next(); - - sizeofnodes += sizeof(*node); - - SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(); - while(it->more()) - { - const SMDS_MeshElement *me = it->next(); - sizeofnodes += sizeof(me); - } - - } - - SMDS_FaceIteratorPtr itface=facesIterator(); - while(itface->more()) - { - const SMDS_MeshElement *face = itface->next(); - sizeoffaces += sizeof(*face); - - } - MESSAGE("total size of node elements = " << sizeofnodes);; - MESSAGE("total size of face elements = " << sizeoffaces);; - - //#endif + return myInfo.Nb0DElements(); } /////////////////////////////////////////////////////////////////////////////// -/// Return the number of nodes +/// Return the number of 0D elements /////////////////////////////////////////////////////////////////////////////// -int SMDS_Mesh::NbNodes() const +int SMDS_Mesh::NbBalls() const { - return myNodes.Size(); + return myInfo.NbBalls(); } /////////////////////////////////////////////////////////////////////////////// @@ -1711,7 +1489,7 @@ int SMDS_Mesh::NbNodes() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbEdges() const { - return myEdges.Size(); + return myInfo.NbEdges(); } /////////////////////////////////////////////////////////////////////////////// @@ -1719,7 +1497,7 @@ int SMDS_Mesh::NbEdges() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbFaces() const { - return myFaces.Size(); + return myInfo.NbFaces(); } /////////////////////////////////////////////////////////////////////////////// @@ -1727,17 +1505,16 @@ int SMDS_Mesh::NbFaces() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbVolumes() const { - return myVolumes.Size(); + return myInfo.NbVolumes(); } /////////////////////////////////////////////////////////////////////////////// /// Return the number of child mesh of this mesh. -/// Note that the tree structure of SMDS_Mesh seems to be unused in this version -/// (2003-09-08) of SMESH +/// Note that the tree structure of SMDS_Mesh is unused in SMESH /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbSubMesh() const { - return myChildren.size(); + return myChildren.size(); } /////////////////////////////////////////////////////////////////////////////// @@ -1746,383 +1523,280 @@ int SMDS_Mesh::NbSubMesh() const /////////////////////////////////////////////////////////////////////////////// SMDS_Mesh::~SMDS_Mesh() { - list::iterator itc=myChildren.begin(); + std::list::iterator itc=myChildren.begin(); while(itc!=myChildren.end()) { delete *itc; itc++; } - SetOfNodes::Iterator itn(myNodes); - for (; itn.More(); itn.Next()) - delete itn.Value(); + delete myNodeFactory; + delete myCellFactory; - SetOfEdges::Iterator ite(myEdges); - for (; ite.More(); ite.Next()) - { - SMDS_MeshElement* elem = ite.Value(); - if(myParent!=NULL) - myElementIDFactory->ReleaseID(elem->GetID()); - delete elem; - } + myGrid->Delete(); +} - SetOfFaces::Iterator itf(myFaces); - for (; itf.More(); itf.Next()) - { - SMDS_MeshElement* elem = itf.Value(); - if(myParent!=NULL) - myElementIDFactory->ReleaseID(elem->GetID()); - delete elem; - } +//================================================================================ +/*! + * \brief Clear all data + */ +//================================================================================ - SetOfVolumes::Iterator itv(myVolumes); - for (; itv.More(); itv.Next()) - { - SMDS_MeshElement* elem = itv.Value(); - if(myParent!=NULL) - myElementIDFactory->ReleaseID(elem->GetID()); - delete elem; - } +void SMDS_Mesh::Clear() +{ + std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin(); + for ( ; holder != myElemHolders.end(); ++holder ) + (*holder)->clear(); - if(myParent==NULL) - { - delete myNodeIDFactory; - delete myElementIDFactory; - } -} + myNodeFactory->Clear(); + myCellFactory->Clear(); -/////////////////////////////////////////////////////////////////////////////// -/// Return true if this mesh create faces with edges. -/// A false returned value mean that faces are created with nodes. A concequence -/// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable. -/////////////////////////////////////////////////////////////////////////////// -bool SMDS_Mesh::hasConstructionEdges() -{ - return myHasConstructionEdges; -} + std::list::iterator itc=myChildren.begin(); + while(itc!=myChildren.end()) + (*itc)->Clear(); -/////////////////////////////////////////////////////////////////////////////// -/// Return true if this mesh create volumes with faces -/// A false returned value mean that volumes are created with nodes or edges. -/// (see hasConstructionEdges) -/// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be -/// unavailable. -/////////////////////////////////////////////////////////////////////////////// -bool SMDS_Mesh::hasConstructionFaces() -{ - return myHasConstructionFaces; -} + myModified = false; + myModifTime++; + xmin = 0; xmax = 0; + ymin = 0; ymax = 0; + zmin = 0; zmax = 0; -/////////////////////////////////////////////////////////////////////////////// -/// Return true if nodes are linked to the finit elements, they are belonging to. -/// Currently, It always return true. -/////////////////////////////////////////////////////////////////////////////// -bool SMDS_Mesh::hasInverseElements() -{ - return myHasInverseElements; -} + myInfo.Clear(); -/////////////////////////////////////////////////////////////////////////////// -/// Make this mesh creating construction edges (see hasConstructionEdges) -/// @param b true to have construction edges, else false. -/////////////////////////////////////////////////////////////////////////////// -void SMDS_Mesh::setConstructionEdges(bool b) -{ - myHasConstructionEdges=b; + myGrid->Initialize(); + myGrid->Allocate(); + vtkPoints* points = vtkPoints::New(); + // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion" + // using double type for storing coordinates of nodes instead float. + points->SetDataType(VTK_DOUBLE); + points->SetNumberOfPoints( 0 ); + myGrid->SetPoints( points ); + points->Delete(); + myGrid->DeleteLinks(); } /////////////////////////////////////////////////////////////////////////////// -/// Make this mesh creating construction faces (see hasConstructionFaces) -/// @param b true to have construction faces, else false. +/// Return an iterator on nodes of the current mesh factory /////////////////////////////////////////////////////////////////////////////// -void SMDS_Mesh::setConstructionFaces(bool b) + +SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const { - myHasConstructionFaces=b; + return myNodeFactory->GetIterator< SMDS_NodeIterator >( new SMDS_MeshElement::NonNullFilter ); } -/////////////////////////////////////////////////////////////////////////////// -/// Make this mesh creating link from nodes to elements (see hasInverseElements) -/// @param b true to link nodes to elements, else false. -/////////////////////////////////////////////////////////////////////////////// -void SMDS_Mesh::setInverseElements(bool b) +SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) const { - if(!b) MESSAGE("Error : inverseElement=false not implemented"); - myHasInverseElements=b; + int nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type ); + return myCellFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::GeomFilter( type ), + nbElems); } -/////////////////////////////////////////////////////////////////////////////// -/// Return an iterator on nodes of the current mesh factory -/////////////////////////////////////////////////////////////////////////////// -class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator +SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const { - SMDS_ElemIteratorPtr myIterator; - public: - SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it) - {} - - bool more() + if ( type == SMDSEntity_Node ) { - return myIterator->more(); + return myNodeFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::NonNullFilter ); } - - const SMDS_MeshNode* next() - { - return static_cast(myIterator->next()); - } -}; - -SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const -{ - return SMDS_NodeIteratorPtr - (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator())); + int nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type ); + return myCellFactory->GetIterator( new SMDS_MeshElement::EntityFilter( type ), + nbElems); } /////////////////////////////////////////////////////////////////////////////// /// Return an iterator on elements of the current mesh factory /////////////////////////////////////////////////////////////////////////////// -SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const +SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const { - return myElementIDFactory->elementsIterator(); + typedef SMDS_ElemIterator TIterator; + switch ( type ) { + + case SMDSAbs_All: + return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter ); + + case SMDSAbs_Node: + return myNodeFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter ); + + default: + int nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type ); + return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( type ), + nbElems); + } + return SMDS_ElemIteratorPtr(); } /////////////////////////////////////////////////////////////////////////////// ///Return an iterator on edges of the current mesh. /////////////////////////////////////////////////////////////////////////////// -class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator -{ - typedef SMDS_Mesh::SetOfEdges SetOfEdges; - SetOfEdges::Iterator myIterator; - public: - SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s) - {} - - bool more() - { - while(myIterator.More()) - { - if(myIterator.Value()->GetID()!=-1) - return true; - myIterator.Next(); - } - return false; - } - - const SMDS_MeshEdge* next() - { - const SMDS_MeshEdge* current = myIterator.Value(); - myIterator.Next(); - return current; - } -}; SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const { - return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges)); + typedef SMDS_EdgeIterator TIterator; + int nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbEdges(); + return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Edge ), + nbElems); } /////////////////////////////////////////////////////////////////////////////// ///Return an iterator on faces of the current mesh. /////////////////////////////////////////////////////////////////////////////// -class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator -{ - typedef SMDS_Mesh::SetOfFaces SetOfFaces; - SetOfFaces::Iterator myIterator; - public: - SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s) - {} - - bool more() - { - while(myIterator.More()) - { - if(myIterator.Value()->GetID()!=-1) - return true; - myIterator.Next(); - } - return false; - } - - const SMDS_MeshFace* next() - { - const SMDS_MeshFace* current = myIterator.Value(); - myIterator.Next(); - return current; - } -}; SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const { - return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces)); + typedef SMDS_FaceIterator TIterator; + int nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbFaces(); + return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Face ), + nbElems); } /////////////////////////////////////////////////////////////////////////////// ///Return an iterator on volumes of the current mesh. /////////////////////////////////////////////////////////////////////////////// -class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator -{ - typedef SMDS_Mesh::SetOfVolumes SetOfVolumes; - SetOfVolumes::Iterator myIterator; - public: - SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s) - {} - bool more() - { - return myIterator.More() != Standard_False; - } +SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const +{ + typedef SMDS_VolumeIterator TIterator; + int nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbVolumes(); + return + myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Volume ), + nbElems ); +} - const SMDS_MeshVolume* next() - { - const SMDS_MeshVolume* current = myIterator.Value(); - myIterator.Next(); - return current; - } -}; +SMDS_NodeIteratorPtr SMDS_Mesh::shapeNodesIterator(int shapeID, + size_t nbElemsToReturn, + const SMDS_MeshNode* sm1stNode) const +{ + return myNodeFactory->GetShapeIterator< SMDS_NodeIterator >( shapeID, nbElemsToReturn, sm1stNode ); +} -SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const +SMDS_ElemIteratorPtr SMDS_Mesh::shapeElementsIterator(int shapeID, + size_t nbElemsToReturn, + const SMDS_MeshElement* sm1stElem) const { - return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes)); + return myCellFactory->GetShapeIterator< SMDS_ElemIterator >( shapeID, nbElemsToReturn, sm1stElem ); } /////////////////////////////////////////////////////////////////////////////// /// Do intersection of sets (more than 2) /////////////////////////////////////////////////////////////////////////////// -static set * intersectionOfSets( - set vs[], int numberOfSets) +static std::set * +intersectionOfSets( std::set vs[], int numberOfSets ) { - set* rsetA=new set(vs[0]); - set* rsetB; + std::set* rsetA = new std::set(vs[0]); + std::set* rsetB; - for(int i=0; i(); - set_intersection( - rsetA->begin(), rsetA->end(), - vs[i+1].begin(), vs[i+1].end(), - inserter(*rsetB, rsetB->begin())); - delete rsetA; - rsetA=rsetB; - } - return rsetA; + for(int i=0; i(); + set_intersection(rsetA->begin(), rsetA->end(), + vs[i+1].begin(), vs[i+1].end(), + inserter(*rsetB, rsetB->begin())); + delete rsetA; + rsetA=rsetB; + } + return rsetA; } - /////////////////////////////////////////////////////////////////////////////// -/// 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 * getFinitElements(const SMDS_MeshElement * element) +static std::set * getFinitElements(const SMDS_MeshElement * element) { - int numberOfSets=element->NbNodes(); - set *initSet = new set[numberOfSets]; - - SMDS_ElemIteratorPtr itNodes=element->nodesIterator(); - - int i=0; - while(itNodes->more()) - { - const SMDS_MeshNode * n=static_cast(itNodes->next()); - SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); + int numberOfSets=element->NbNodes(); + std::set *initSet = new std::set[numberOfSets]; - //initSet[i]=set(); - while(itFe->more()) - initSet[i].insert(itFe->next()); + SMDS_NodeIteratorPtr itNodes = element->nodeIterator(); - i++; - } - set *retSet=intersectionOfSets(initSet, numberOfSets); - delete [] initSet; - return retSet; + int i = 0; + while ( itNodes->more() ) + { + const SMDS_MeshNode * n = itNodes->next(); + for ( SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); itFe->more(); ) + initSet[i].insert( itFe->next() ); + i++; + } + std::set *retSet = intersectionOfSets( initSet, numberOfSets ); + delete [] initSet; + return retSet; } /////////////////////////////////////////////////////////////////////////////// -/// Return the list of nodes used only by the given elements +/// Return the std::list of nodes used only by the given elements /////////////////////////////////////////////////////////////////////////////// -static set * getExclusiveNodes( - set& elements) +static +std::set *getExclusiveNodes(std::set& elements) { - set * toReturn=new set(); - set::iterator itElements=elements.begin(); + std::set * toReturn = new std::set(); + std::set::iterator itElements = elements.begin(); + + while( itElements != elements.end() ) + { + SMDS_NodeIteratorPtr itNodes = (*itElements)->nodeIterator(); + itElements++; - while(itElements!=elements.end()) - { - SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator(); - itElements++; - - while(itNodes->more()) - { - const SMDS_MeshNode * n=static_cast(itNodes->next()); - SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); - set s; - while(itFe->more()) - s.insert(itFe->next()); - if(s==elements) toReturn->insert(n); - } - } - return toReturn; + while( itNodes->more() ) + { + const SMDS_MeshNode * n = itNodes->next(); + SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); + std::set s; + while ( itFe->more() ) + s.insert( itFe->next() ); + if ( s == elements ) toReturn->insert(n); + } + } + return toReturn; } /////////////////////////////////////////////////////////////////////////////// -///Find the children of an element that are made of given nodes +///Find the children of an element that are made of given nodes ///@param setOfChildren The set in which matching children will be inserted ///@param element The element were to search matching children ///@param nodes The nodes that the children must have to be selected /////////////////////////////////////////////////////////////////////////////// -void SMDS_Mesh::addChildrenWithNodes(set& setOfChildren, - const SMDS_MeshElement * element, set& nodes) -{ - - switch(element->GetType()) - { - case SMDSAbs_Node: - MESSAGE("Internal Error: This should not append"); - break; - case SMDSAbs_Edge: - { - SMDS_ElemIteratorPtr itn=element->nodesIterator(); - while(itn->more()) - { - const SMDS_MeshElement * e=itn->next(); - if(nodes.find(e)!=nodes.end()) - { - setOfChildren.insert(element); - break; - } - } - } break; - case SMDSAbs_Face: - { - SMDS_ElemIteratorPtr itn=element->nodesIterator(); - while(itn->more()) - { - const SMDS_MeshElement * e=itn->next(); - if(nodes.find(e)!=nodes.end()) - { - setOfChildren.insert(element); - break; - } - } - if(hasConstructionEdges()) - { - SMDS_ElemIteratorPtr ite=element->edgesIterator(); - while(ite->more()) - addChildrenWithNodes(setOfChildren, ite->next(), nodes); - } - } break; - case SMDSAbs_Volume: - { - if(hasConstructionFaces()) - { - SMDS_ElemIteratorPtr ite=element->facesIterator(); - while(ite->more()) - addChildrenWithNodes(setOfChildren, ite->next(), nodes); - } - else if(hasConstructionEdges()) - { - SMDS_ElemIteratorPtr ite=element->edgesIterator(); - while(ite->more()) - addChildrenWithNodes(setOfChildren, ite->next(), nodes); - } - } - } +void SMDS_Mesh::addChildrenWithNodes(std::set& setOfChildren, + const SMDS_MeshElement * element, + std::set& nodes) +{ + switch(element->GetType()) + { + case SMDSAbs_Node: + throw SALOME_Exception("Internal Error: This should not happen"); + break; + case SMDSAbs_0DElement: + case SMDSAbs_Ball: + { + } + break; + case SMDSAbs_Edge: + { + SMDS_ElemIteratorPtr itn=element->nodesIterator(); + while(itn->more()) + { + const SMDS_MeshElement * e=itn->next(); + if(nodes.find(e)!=nodes.end()) + { + setOfChildren.insert(element); + break; + } + } + } break; + case SMDSAbs_Face: + { + SMDS_ElemIteratorPtr itn=element->nodesIterator(); + while(itn->more()) + { + const SMDS_MeshElement * e=itn->next(); + if(nodes.find(e)!=nodes.end()) + { + setOfChildren.insert(element); + break; + } + } + } break; + case SMDSAbs_Volume: + case SMDSAbs_NbElementTypes: + case SMDSAbs_All: break; + } } /////////////////////////////////////////////////////////////////////////////// @@ -2130,42 +1804,44 @@ void SMDS_Mesh::addChildrenWithNodes(set& setOfChildren ///@param removenodes if true remaining nodes will be removed /////////////////////////////////////////////////////////////////////////////// void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, - const bool removenodes) + const bool removenodes) { - list removedElems; - list removedNodes; + std::vector removedElems; + std::vector removedNodes; RemoveElement( elem, removedElems, removedNodes, removenodes ); } - + /////////////////////////////////////////////////////////////////////////////// ///@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& removedElems, - list& removedNodes, - bool removenodes) +void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, + std::vector& removedElems, + std::vector& removedNodes, + bool removenodes) { // get finite elements built on elem - set * s1; - if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge || - !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face || - elem->GetType() == SMDSAbs_Volume) + std::set * s1; + if ( (elem->GetType() == SMDSAbs_0DElement) + || (elem->GetType() == SMDSAbs_Ball) + || (elem->GetType() == SMDSAbs_Edge) + || (elem->GetType() == SMDSAbs_Face) + || (elem->GetType() == SMDSAbs_Volume) ) { - s1 = new set(); + s1 = new std::set (); s1->insert(elem); } else s1 = getFinitElements(elem); // get exclusive nodes (which would become free afterwards) - set * s2; + std::set * s2; if (elem->GetType() == SMDSAbs_Node) // a node is removed { // do not remove nodes except elem - s2 = new set(); + s2 = new std::set (); s2->insert(elem); removenodes = true; } @@ -2173,67 +1849,60 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, s2 = getExclusiveNodes(*s1); // form the set of finite and construction elements to remove - set s3; - set::iterator it=s1->begin(); - while(it!=s1->end()) + std::set s3; + std::set::iterator it = s1->begin(); + while (it != s1->end()) { - addChildrenWithNodes(s3, *it ,*s2); + addChildrenWithNodes(s3, *it, *s2); s3.insert(*it); it++; } - if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem); + if (elem->GetType() != SMDSAbs_Node) + s3.insert(elem); // remove finite and construction elements - it=s3.begin(); - while(it!=s3.end()) + for( it = s3.begin();it != s3.end(); ++it ) { // Remove element from of its nodes - SMDS_ElemIteratorPtr itn=(*it)->nodesIterator(); - while(itn->more()) + SMDS_NodeIteratorPtr itn = (*it)->nodeIterator(); + while (itn->more()) { - SMDS_MeshNode * n = static_cast - (const_cast(itn->next())); - n->RemoveInverseElement( (*it) ); + SMDS_MeshNode * n = const_cast (itn->next()); + n->RemoveInverseElement((*it)); } - switch((*it)->GetType()) - { + int vtkid = (*it)->GetVtkID(); + + switch ((*it)->GetType()) { case SMDSAbs_Node: - MESSAGE("Internal Error: This should not happen"); - break; - case SMDSAbs_Edge: - myEdges.Remove(static_cast - (const_cast(*it))); - break; - case SMDSAbs_Face: - myFaces.Remove(static_cast - (const_cast(*it))); - break; - case SMDSAbs_Volume: - myVolumes.Remove(static_cast - (const_cast(*it))); + throw SALOME_Exception(LOCALIZED("Internal Error: This should not happen")); break; + case SMDSAbs_Edge: myInfo.RemoveEdge(*it); break; + case SMDSAbs_Face: myInfo.RemoveFace(*it); break; + case SMDSAbs_Volume: myInfo.RemoveVolume(*it); break; + case SMDSAbs_Ball: myInfo.myNbBalls--; break; + case SMDSAbs_0DElement: myInfo.myNb0DElements--; break; + case SMDSAbs_All: // avoid compilation warning + case SMDSAbs_NbElementTypes: break; + } + removedElems.push_back( *it); + + myCellFactory->Free( static_cast< const SMDS_MeshCell*>( *it )); + + if (vtkid >= 0) + { + this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL); } - //MESSAGE( "SMDS: RM elem " << (*it)->GetID() ); - removedElems.push_back( (*it) ); - myElementIDFactory->ReleaseID((*it)->GetID()); - delete (*it); - it++; } // remove exclusive (free) nodes - if(removenodes) + if (removenodes) { - it=s2->begin(); - while(it!=s2->end()) + for ( it = s2->begin(); it != s2->end(); ++it ) { - //MESSAGE( "SMDS: RM node " << (*it)->GetID() ); - myNodes.Remove(static_cast - (const_cast(*it))); - myNodeIDFactory->ReleaseID((*it)->GetID()); - removedNodes.push_back( (*it) ); - delete *it; - it++; + myInfo.myNbNodes--; + myNodeFactory->Free( (*it) ); + removedNodes.push_back((*it)); } } @@ -2241,122 +1910,106 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, delete s1; } - + /////////////////////////////////////////////////////////////////////////////// ///@param elem The element to delete /////////////////////////////////////////////////////////////////////////////// void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem) { + const int vtkId = elem->GetVtkID(); SMDSAbs_ElementType aType = elem->GetType(); - if (aType == SMDSAbs_Node) { + if ( aType == SMDSAbs_Node ) + { // only free node can be removed by this method - const SMDS_MeshNode* n = static_cast(elem); - SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); - if (!itFe->more()) { // free node - myNodes.Remove(const_cast(n)); - myNodeIDFactory->ReleaseID(elem->GetID()); - delete elem; + const SMDS_MeshNode* n = static_cast( elem ); + if ( n->NbInverseElements() == 0 ) { // free node + myInfo.myNbNodes--; + myNodeFactory->Free( n ); } - } else { - if (hasConstructionEdges() || hasConstructionFaces()) - // this methods is only for meshes without descendants - return; - + else + { + throw SALOME_Exception( LOCALIZED( "RemoveFreeElement: not a free node" )); + } + } + else + { // Remove element from of its nodes - SMDS_ElemIteratorPtr itn = elem->nodesIterator(); + SMDS_NodeIteratorPtr itn = elem->nodeIterator(); while (itn->more()) { - SMDS_MeshNode * n = static_cast - (const_cast(itn->next())); + SMDS_MeshNode * n = const_cast(itn->next()); n->RemoveInverseElement(elem); } // in meshes without descendants elements are always free switch (aType) { - case SMDSAbs_Edge: - myEdges.Remove(static_cast - (const_cast(elem))); - break; - case SMDSAbs_Face: - myFaces.Remove(static_cast - (const_cast(elem))); - break; - case SMDSAbs_Volume: - myVolumes.Remove(static_cast - (const_cast(elem))); - break; - default: - break; + case SMDSAbs_0DElement: myInfo.remove(elem); break; + case SMDSAbs_Edge: myInfo.RemoveEdge(elem); break; + case SMDSAbs_Face: myInfo.RemoveFace(elem); break; + case SMDSAbs_Volume: myInfo.RemoveVolume(elem); break; + case SMDSAbs_Ball: myInfo.remove(elem); break; + default: break; } - myElementIDFactory->ReleaseID(elem->GetID()); - delete elem; + myCellFactory->Free( elem ); + + this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL); } } +//======================================================================= /*! * Checks if the element is present in mesh. - * Useful to determine dead pointers. */ +//======================================================================= + bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const { - // we should not imply on validity of *elem, so iterate on containers - // of all types in the hope of finding somewhere there - SMDS_NodeIteratorPtr itn = nodesIterator(); - while (itn->more()) - if (elem == itn->next()) - return true; - SMDS_EdgeIteratorPtr ite = edgesIterator(); - while (ite->more()) - if (elem == ite->next()) - return true; - SMDS_FaceIteratorPtr itf = facesIterator(); - while (itf->more()) - if (elem == itf->next()) - return true; - SMDS_VolumeIteratorPtr itv = volumesIterator(); - while (itv->more()) - if (elem == itv->next()) - return true; - return false; + if ( !elem || elem->IsNull() ) + return false; + + if ( elem->GetType() == SMDSAbs_Node ) + return ( elem == myNodeFactory->FindElement( elem->GetID() )); + + return ( elem == myCellFactory->FindElement( elem->GetID() )); } //======================================================================= //function : MaxNodeID -//purpose : +//purpose : //======================================================================= int SMDS_Mesh::MaxNodeID() const { - return myNodeIDFactory->GetMaxID(); + return myNodeFactory->GetMaxID(); } //======================================================================= //function : MinNodeID -//purpose : +//purpose : //======================================================================= int SMDS_Mesh::MinNodeID() const { - return myNodeIDFactory->GetMinID(); + return myNodeFactory->GetMinID(); } //======================================================================= //function : MaxElementID -//purpose : +//purpose : //======================================================================= int SMDS_Mesh::MaxElementID() const { - return myElementIDFactory->GetMaxID(); + return myCellFactory->GetMaxID(); } //======================================================================= //function : MinElementID -//purpose : +//purpose : //======================================================================= int SMDS_Mesh::MinElementID() const { - return myElementIDFactory->GetMinID(); + return myCellFactory->GetMinID(); } //======================================================================= @@ -2364,38 +2017,12 @@ int SMDS_Mesh::MinElementID() const //purpose : Renumber all nodes or elements. //======================================================================= -void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID) -{ - if ( deltaID == 0 ) - return; +// void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID) +// { +// if ( deltaID == 0 ) +// return; - SMDS_MeshElementIDFactory * idFactory = - isNodes ? myNodeIDFactory : myElementIDFactory; - - // get existing elements in the order of ID increasing - map elemMap; - SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator(); - while ( idElemIt->more() ) { - SMDS_MeshElement* elem = const_cast(idElemIt->next()); - int id = elem->GetID(); - elemMap.insert(map::value_type(id, elem)); - } - // release their ids - map::iterator elemIt = elemMap.begin(); - for ( ; elemIt != elemMap.end(); elemIt++ ) - { - int id = (*elemIt).first; - idFactory->ReleaseID( id ); - } - // set new IDs - int ID = startID; - elemIt = elemMap.begin(); - for ( ; elemIt != elemMap.end(); elemIt++ ) - { - idFactory->BindID( ID, (*elemIt).second ); - ID += deltaID; - } -} +// } //======================================================================= //function : GetElementType @@ -2404,19 +2031,13 @@ void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int del SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const { - SMDS_MeshElement* elem = 0; + const SMDS_MeshElement* elem = 0; if( iselem ) - elem = myElementIDFactory->MeshElement( id ); + elem = myCellFactory->FindElement( id ); else - elem = myNodeIDFactory->MeshElement( id ); + elem = myNodeFactory->FindElement( id ); - if( !elem ) - { - //throw SALOME_Exception(LOCALIZED ("this element isn't exist")); - return SMDSAbs_All; - } - else - return elem->GetType(); + return elem ? elem->GetType() : SMDSAbs_All; } @@ -2430,158 +2051,265 @@ SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) //******************************************************************** //======================================================================= -//function : AddEdgeWithID -//purpose : +//function : AddEdgeWithID +//purpose : +//======================================================================= +SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) +{ + return SMDS_Mesh::AddEdgeWithID (myNodeFactory->FindNode(n1), + myNodeFactory->FindNode(n2), + myNodeFactory->FindNode(n12), + ID); +} + +//======================================================================= +//function : AddEdge +//purpose : +//======================================================================= +SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n12) +{ + return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myCellFactory->GetFreeID()); +} + +//======================================================================= +//function : AddEdgeWithID +//purpose : +//======================================================================= +SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, + int ID) +{ + if ( !n1 || !n2 || !n12 ) return 0; + + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Quad_Edge, /*nbNodes=*/3, n1, n2, n12 ); + myInfo.myNbQuadEdges++; + return static_cast( cell ); + } + return 0; +} + + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31) +{ + return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31, + myCellFactory->GetFreeID()); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, + int n12,int n23,int n31, int ID) +{ + return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) , + myNodeFactory->FindNode(n2) , + myNodeFactory->FindNode(n3) , + myNodeFactory->FindNode(n12), + myNodeFactory->FindNode(n23), + myNodeFactory->FindNode(n31), + ID); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + int ID) +{ + if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 ) return 0; + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Quad_Triangle, /*nbNodes=*/6, n1, n2, n3, n12, n23, n31 ); + myInfo.myNbQuadTriangles++; + return static_cast( cell ); + } + return 0; +} + + +//======================================================================= +//function : AddFace +//purpose : //======================================================================= -SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * nCenter) { - SMDS_MeshNode* node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1); - SMDS_MeshNode* node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2); - SMDS_MeshNode* node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12); - if(!node1 || !node2 || !node12) return NULL; - return SMDS_Mesh::AddEdgeWithID(node1, node2, node12, ID); + return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,nCenter, + myCellFactory->GetFreeID()); } //======================================================================= -//function : AddEdge -//purpose : +//function : AddFaceWithID +//purpose : //======================================================================= -SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1, - const SMDS_MeshNode* n2, - const SMDS_MeshNode* n12) +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, + int n12,int n23,int n31, int nCenter, int ID) { - return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID()); + return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) , + myNodeFactory->FindNode(n2) , + myNodeFactory->FindNode(n3) , + myNodeFactory->FindNode(n12), + myNodeFactory->FindNode(n23), + myNodeFactory->FindNode(n31), + myNodeFactory->FindNode(nCenter), + ID); } //======================================================================= -//function : AddEdgeWithID -//purpose : +//function : AddFaceWithID +//purpose : //======================================================================= -SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n12, - int ID) -{ - SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12); - if(myElementIDFactory->BindID(ID, edge)) { - SMDS_MeshNode *node1,*node2, *node12; - node1 = const_cast(n1); - node2 = const_cast(n2); - node12 = const_cast(n12); - node1->AddInverseElement(edge); - node2->AddInverseElement(edge); - node12->AddInverseElement(edge); - myEdges.Add(edge); - return edge; - } - else { - delete edge; - return NULL; +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * nCenter, + int ID) +{ + if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 || !nCenter) return 0; + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_BiQuad_Triangle, /*nbNodes=*/7, n1, n2, n3, n12, n23, n31, nCenter ); + myInfo.myNbBiQuadTriangles++; + return static_cast( cell ); } + return 0; } //======================================================================= //function : AddFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31) + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41) { - return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31, - myElementIDFactory->GetFreeID()); + return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41, + myCellFactory->GetFreeID()); } //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= -SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, - int n12,int n23,int n31, int ID) +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int ID) { - SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1); - SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2); - SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3); - SMDS_MeshNode * node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12); - SMDS_MeshNode * node23 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23); - SMDS_MeshNode * node31 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31); - if(!node1 || !node2 || !node3 || !node12 || !node23 || !node31) return NULL; - return SMDS_Mesh::AddFaceWithID(node1, node2, node3, - node12, node23, node31, ID); + return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) , + myNodeFactory->FindNode(n2) , + myNodeFactory->FindNode(n3) , + myNodeFactory->FindNode(n4) , + myNodeFactory->FindNode(n12), + myNodeFactory->FindNode(n23), + myNodeFactory->FindNode(n34), + myNodeFactory->FindNode(n41), + ID); } //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, int ID) { - if(hasConstructionEdges()) { - // creation quadratic edges - not implemented - } - SMDS_QuadraticFaceOfNodes* face = - new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31); - myFaces.Add(face); + if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0; + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - if (!registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Quad_Quadrangle, /*nbNodes=*/8, n1, n2, n3, n4, n12, n23, n34, n41 ); + myInfo.myNbQuadQuadrangles++; + return static_cast( cell ); } - return face; + return 0; } - //======================================================================= //function : AddFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41) + const SMDS_MeshNode * n41, + const SMDS_MeshNode * nCenter) { - return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41, - myElementIDFactory->GetFreeID()); + return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter, + myCellFactory->GetFreeID()); } //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, - int n12,int n23,int n34,int n41, int ID) + int n12,int n23,int n34,int n41, int nCenter, int ID) { - SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1); - SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2); - SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3); - SMDS_MeshNode * node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4); - SMDS_MeshNode * node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12); - SMDS_MeshNode * node23 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23); - SMDS_MeshNode * node34 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34); - SMDS_MeshNode * node41 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41); - if(!node1 || !node2 || !node3 || !node4 || - !node12 || !node23 || !node34 || !node41) return NULL; - return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, - node12, node23, node34, node41, ID); + return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) , + myNodeFactory->FindNode(n2) , + myNodeFactory->FindNode(n3) , + myNodeFactory->FindNode(n4) , + myNodeFactory->FindNode(n12), + myNodeFactory->FindNode(n23), + myNodeFactory->FindNode(n34), + myNodeFactory->FindNode(n41), + myNodeFactory->FindNode(nCenter), + ID); } //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -2589,73 +2317,65 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * nCenter, int ID) { - if(hasConstructionEdges()) { - // creation quadratic edges - not implemented - } - SMDS_QuadraticFaceOfNodes* face = - new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41); - myFaces.Add(face); + if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0; + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - if (!registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_BiQuad_Quadrangle, + /*nbNodes=*/9, n1, n2, n3, n4, n12, n23, n34, n41, nCenter ); + myInfo.myNbBiQuadQuadrangles++; + return static_cast( cell ); } - return face; + return 0; } //======================================================================= //function : AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n31, - const SMDS_MeshNode * n14, + const SMDS_MeshNode * n14, const SMDS_MeshNode * n24, const SMDS_MeshNode * n34) { - int ID = myElementIDFactory->GetFreeID(); - SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23, - n31, n14, n24, n34, ID); - if(v==NULL) myElementIDFactory->ReleaseID(ID); - return v; + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23, + n31, n14, n24, n34, myCellFactory->GetFreeID()); } //======================================================================= //function : AddVolumeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n12,int n23,int n31, int n14,int n24,int n34, int ID) { - SMDS_MeshNode *node1, *node2, *node3, *node4, *node12, *node23; - SMDS_MeshNode *node31, *node14, *node24, *node34; - node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1); - node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2); - node3 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3); - node4 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4); - node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12); - node23 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23); - node31 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31); - node14 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14); - node24 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24); - node34 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34); - if( !node1 || !node2 || !node3 || !node4 || !node12 || !node23 || - !node31 || !node14 || !node24 || !node34 ) return NULL; - return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node12, node23, - node31, node14, node24, node34, ID); -} - + return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) , + myNodeFactory->FindNode(n2) , + myNodeFactory->FindNode(n3) , + myNodeFactory->FindNode(n4) , + myNodeFactory->FindNode(n12), + myNodeFactory->FindNode(n23), + myNodeFactory->FindNode(n31), + myNodeFactory->FindNode(n14), + myNodeFactory->FindNode(n24), + myNodeFactory->FindNode(n34), + ID); +} + //======================================================================= //function : AddVolumeWithID //purpose : 2d order tetrahedron of 10 nodes @@ -2667,84 +2387,72 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n31, - const SMDS_MeshNode * n14, + const SMDS_MeshNode * n14, const SMDS_MeshNode * n24, const SMDS_MeshNode * n34, int ID) { - if(hasConstructionFaces()) { - // creation quadratic faces - not implemented - } - SMDS_QuadraticVolumeOfNodes * volume = - new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); - myVolumes.Add(volume); + if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34) + return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Quad_Tetra, + /*nbNodes=*/10, n1, n2, n3, n4, n12, n23, n31, n14, n24, n34 ); + myInfo.myNbQuadTetras++; + return static_cast( cell ); } - return volume; + return 0; } //======================================================================= //function : AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, const SMDS_MeshNode * n41, - const SMDS_MeshNode * n15, + const SMDS_MeshNode * n15, const SMDS_MeshNode * n25, const SMDS_MeshNode * n35, const SMDS_MeshNode * n45) { - int ID = myElementIDFactory->GetFreeID(); - SMDS_MeshVolume * v = - SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41, - n15, n25, n35, n45, ID); - if(v==NULL) myElementIDFactory->ReleaseID(ID); - return v; + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41, + n15, n25, n35, n45, myCellFactory->GetFreeID()); } //======================================================================= //function : AddVolumeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n12,int n23,int n34,int n41, int n15,int n25,int n35,int n45, int ID) { - SMDS_MeshNode *node1, *node2, *node3, *node4, *node5; - SMDS_MeshNode *node12, *node23, *node34, *node41; - SMDS_MeshNode *node15, *node25, *node35, *node45; - node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1); - node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2); - node3 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3); - node4 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4); - node5 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5); - node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12); - node23 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23); - node34 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34); - node41 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41); - node15 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15); - node25 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25); - node35 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35); - node45 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45); - if( !node1 || !node2 || !node3 || !node4 || !node5 || - !node12 || !node23 || !node34 || !node41 || - !node15 || !node25 || !node35 || !node45 ) return NULL; - return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, - node12, node23, node34, node41, - node15, node25, node35, node45, ID); -} - + return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) , + myNodeFactory->FindNode(n2) , + myNodeFactory->FindNode(n3) , + myNodeFactory->FindNode(n4) , + myNodeFactory->FindNode(n5) , + myNodeFactory->FindNode(n12), + myNodeFactory->FindNode(n23), + myNodeFactory->FindNode(n34), + myNodeFactory->FindNode(n41), + myNodeFactory->FindNode(n15), + myNodeFactory->FindNode(n25), + myNodeFactory->FindNode(n35), + myNodeFactory->FindNode(n45), + ID); +} + //======================================================================= //function : AddVolumeWithID //purpose : 2d order pyramid of 13 nodes @@ -2753,64 +2461,60 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, + const SMDS_MeshNode * n5, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, const SMDS_MeshNode * n41, - const SMDS_MeshNode * n15, + const SMDS_MeshNode * n15, const SMDS_MeshNode * n25, const SMDS_MeshNode * n35, const SMDS_MeshNode * n45, int ID) { - if(hasConstructionFaces()) { - // creation quadratic faces - not implemented - } - SMDS_QuadraticVolumeOfNodes * volume = - new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23, - n34,n41,n15,n25,n35,n45); - myVolumes.Add(volume); + if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 || + !n34 || !n41 || !n15 || !n25 || !n35 || !n45) + return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Quad_Pyramid, + /*nbNodes=*/13, n1, n2, n3, n4, n5, n12, n23, n34, n41, n15, n25, n35, n45); + myInfo.myNbQuadPyramids++; + return static_cast( cell ); } - return volume; + return 0; } //======================================================================= //function : AddVolume -//purpose : +//purpose : 2d order Pentahedron (prism) with 15 nodes //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, + const SMDS_MeshNode * n31, const SMDS_MeshNode * n45, const SMDS_MeshNode * n56, - const SMDS_MeshNode * n64, + const SMDS_MeshNode * n64, const SMDS_MeshNode * n14, const SMDS_MeshNode * n25, const SMDS_MeshNode * n36) { - int ID = myElementIDFactory->GetFreeID(); - SMDS_MeshVolume * v = - SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31, - n45, n56, n64, n14, n25, n36, ID); - if(v==NULL) myElementIDFactory->ReleaseID(ID); - return v; + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31, + n45, n56, n64, n14, n25, n36, myCellFactory->GetFreeID()); } //======================================================================= //function : AddVolumeWithID -//purpose : +//purpose : 2d order Pentahedron (prism) with 15 nodes //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, @@ -2818,106 +2522,194 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n45,int n56,int n64, int n14,int n25,int n36, int ID) { - SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6; - SMDS_MeshNode *node12, *node23, *node31; - SMDS_MeshNode *node45, *node56, *node64; - SMDS_MeshNode *node14, *node25, *node36; - node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1); - node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2); - node3 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3); - node4 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4); - node5 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5); - node6 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6); - node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12); - node23 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23); - node31 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31); - node45 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45); - node56 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56); - node64 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64); - node14 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14); - node25 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25); - node36 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36); - if( !node1 || !node2 || !node3 || !node4 || !node5 || !node6 || - !node12 || !node23 || !node31 || !node45 || !node56 || - !node64 || !node14 || !node25 || !node36 ) return NULL; - return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, - node12, node23, node31, node45, node56, - node64, node14, node25, node36, ID); + return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) , + myNodeFactory->FindNode(n2) , + myNodeFactory->FindNode(n3) , + myNodeFactory->FindNode(n4) , + myNodeFactory->FindNode(n5) , + myNodeFactory->FindNode(n6) , + myNodeFactory->FindNode(n12), + myNodeFactory->FindNode(n23), + myNodeFactory->FindNode(n31), + myNodeFactory->FindNode(n45), + myNodeFactory->FindNode(n56), + myNodeFactory->FindNode(n64), + myNodeFactory->FindNode(n14), + myNodeFactory->FindNode(n25), + myNodeFactory->FindNode(n36), + ID); } - + //======================================================================= //function : AddVolumeWithID -//purpose : 2d order Pentahedron with 15 nodes +//purpose : 2d order Pentahedron (prism) with 15 nodes //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, + const SMDS_MeshNode * n31, const SMDS_MeshNode * n45, const SMDS_MeshNode * n56, - const SMDS_MeshNode * n64, + const SMDS_MeshNode * n64, const SMDS_MeshNode * n14, const SMDS_MeshNode * n25, const SMDS_MeshNode * n36, int ID) { - if(hasConstructionFaces()) { - // creation quadratic faces - not implemented + if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 || + !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36) + return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Quad_Penta, /*nbNodes=*/15, + n1, n2, n3, n4, n5, n6, n12, n23, n31, n45, n56, n64, n14, n25, n36 ); + myInfo.myNbQuadPrisms++; + return static_cast( cell ); } - SMDS_QuadraticVolumeOfNodes * volume = - new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31, - n45,n56,n64,n14,n25,n36); - myVolumes.Add(volume); + return 0; +} + +//======================================================================= +//function : AddVolume +//purpose : 2d order Pentahedron (prism) with 18 nodes +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36, + const SMDS_MeshNode * n1245, + const SMDS_MeshNode * n2356, + const SMDS_MeshNode * n1346) +{ + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31, + n45, n56, n64, n14, n25, n36, n1245, n2356, n1346, + myCellFactory->GetFreeID()); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Pentahedron (prism) with 18 nodes +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, + int n4, int n5, int n6, + int n12,int n23,int n31, + int n45,int n56,int n64, + int n14,int n25,int n36, + int n1245, int n2356, int n1346, int ID) +{ + return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) , + myNodeFactory->FindNode(n2) , + myNodeFactory->FindNode(n3) , + myNodeFactory->FindNode(n4) , + myNodeFactory->FindNode(n5) , + myNodeFactory->FindNode(n6) , + myNodeFactory->FindNode(n12), + myNodeFactory->FindNode(n23), + myNodeFactory->FindNode(n31), + myNodeFactory->FindNode(n45), + myNodeFactory->FindNode(n56), + myNodeFactory->FindNode(n64), + myNodeFactory->FindNode(n14), + myNodeFactory->FindNode(n25), + myNodeFactory->FindNode(n36), + myNodeFactory->FindNode(n1245), + myNodeFactory->FindNode(n2356), + myNodeFactory->FindNode(n1346), + ID); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Pentahedron (prism) with 18 nodes +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36, + const SMDS_MeshNode * n1245, + const SMDS_MeshNode * n2356, + const SMDS_MeshNode * n1346, + int ID) +{ + //MESSAGE("AddVolumeWithID penta18 "<< ID); + if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 || + !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36 || !n1245 || !n2356 || !n1346) + return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_BiQuad_Penta, /*nbNodes=*/18, n1, n2, n3, n4, n5, n6, + n12, n23, n31, n45, n56, n64, n14, n25, n36, n1245, n2356, n1346 ); + myInfo.myNbBiQuadPrisms++; + return static_cast( cell ); } - return volume; + return 0; } //======================================================================= //function : AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, + const SMDS_MeshNode * n8, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n41, const SMDS_MeshNode * n56, const SMDS_MeshNode * n67, const SMDS_MeshNode * n78, - const SMDS_MeshNode * n85, + const SMDS_MeshNode * n85, const SMDS_MeshNode * n15, const SMDS_MeshNode * n26, const SMDS_MeshNode * n37, const SMDS_MeshNode * n48) { - int ID = myElementIDFactory->GetFreeID(); - SMDS_MeshVolume * v = - SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41, - n56, n67, n78, n85, n15, n26, n37, n48, ID); - if(v==NULL) myElementIDFactory->ReleaseID(ID); - return v; + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41, + n56, n67, n78, n85, n15, n26, n37, n48, + myCellFactory->GetFreeID()); } //======================================================================= //function : AddVolumeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, @@ -2925,43 +2717,29 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n56,int n67,int n78,int n85, int n15,int n26,int n37,int n48, int ID) { - SMDS_MeshNode *node1, *node2, *node3, *node4; - SMDS_MeshNode *node5, *node6, *node7, *node8; - SMDS_MeshNode *node12, *node23, *node34, *node41; - SMDS_MeshNode *node56, *node67, *node78, *node85; - SMDS_MeshNode *node15, *node26, *node37, *node48; - node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1); - node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2); - node3 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3); - node4 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4); - node5 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5); - node6 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6); - node7 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7); - node8 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8); - node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12); - node23 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23); - node34 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34); - node41 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41); - node56 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56); - node67 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67); - node78 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78); - node85 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85); - node15 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15); - node26 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26); - node37 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37); - node48 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48); - if( !node1 || !node2 || !node3 || !node4 || - !node5 || !node6 || !node7 || !node8 || - !node12 || !node23 || !node34 || !node41 || - !node56 || !node67 || !node78 || !node85 || - !node15 || !node26 || !node37 || !node48 ) return NULL; - return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, - node5, node6, node7, node8, - node12, node23, node34, node41, - node56, node67, node78, node85, - node15, node26, node37, node48, ID); -} - + return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1), + myNodeFactory->FindNode(n2), + myNodeFactory->FindNode(n3), + myNodeFactory->FindNode(n4), + myNodeFactory->FindNode(n5), + myNodeFactory->FindNode(n6), + myNodeFactory->FindNode(n7), + myNodeFactory->FindNode(n8), + myNodeFactory->FindNode(n12), + myNodeFactory->FindNode(n23), + myNodeFactory->FindNode(n34), + myNodeFactory->FindNode(n41), + myNodeFactory->FindNode(n56), + myNodeFactory->FindNode(n67), + myNodeFactory->FindNode(n78), + myNodeFactory->FindNode(n85), + myNodeFactory->FindNode(n15), + myNodeFactory->FindNode(n26), + myNodeFactory->FindNode(n37), + myNodeFactory->FindNode(n48), + ID); +} + //======================================================================= //function : AddVolumeWithID //purpose : 2d order Hexahedrons with 20 nodes @@ -2970,36 +2748,306 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + int ID) +{ + if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 || + !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48) + return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Quad_Hexa, /*nbNodes=*/20, n1, n2, n3, n4, n5, n6, n7, n8, + n12, n23, n34, n41, n56, n67, n78, n85, n15, n26, n37, n48 ); + myInfo.myNbQuadHexas++; + return static_cast( cell ); + } + return 0; +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + const SMDS_MeshNode * n1234, + const SMDS_MeshNode * n1256, + const SMDS_MeshNode * n2367, + const SMDS_MeshNode * n3478, + const SMDS_MeshNode * n1458, + const SMDS_MeshNode * n5678, + const SMDS_MeshNode * nCenter) +{ + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41, + n56, n67, n78, n85, n15, n26, n37, n48, + n1234, n1256, n2367, n3478, n1458, n5678, nCenter, + myCellFactory->GetFreeID()); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12,int n23,int n34,int n41, + int n56,int n67,int n78,int n85, + int n15,int n26,int n37,int n48, + int n1234,int n1256,int n2367,int n3478, + int n1458,int n5678,int nCenter, int ID) +{ + return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1), + myNodeFactory->FindNode(n2), + myNodeFactory->FindNode(n3), + myNodeFactory->FindNode(n4), + myNodeFactory->FindNode(n5), + myNodeFactory->FindNode(n6), + myNodeFactory->FindNode(n7), + myNodeFactory->FindNode(n8), + myNodeFactory->FindNode(n12), + myNodeFactory->FindNode(n23), + myNodeFactory->FindNode(n34), + myNodeFactory->FindNode(n41), + myNodeFactory->FindNode(n56), + myNodeFactory->FindNode(n67), + myNodeFactory->FindNode(n78), + myNodeFactory->FindNode(n85), + myNodeFactory->FindNode(n15), + myNodeFactory->FindNode(n26), + myNodeFactory->FindNode(n37), + myNodeFactory->FindNode(n48), + myNodeFactory->FindNode(n1234), + myNodeFactory->FindNode(n1256), + myNodeFactory->FindNode(n2367), + myNodeFactory->FindNode(n3478), + myNodeFactory->FindNode(n1458), + myNodeFactory->FindNode(n5678), + myNodeFactory->FindNode(nCenter), + ID); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Hexahedrons with 27 nodes +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, + const SMDS_MeshNode * n8, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n41, const SMDS_MeshNode * n56, const SMDS_MeshNode * n67, const SMDS_MeshNode * n78, - const SMDS_MeshNode * n85, + const SMDS_MeshNode * n85, const SMDS_MeshNode * n15, const SMDS_MeshNode * n26, const SMDS_MeshNode * n37, const SMDS_MeshNode * n48, + const SMDS_MeshNode * n1234, + const SMDS_MeshNode * n1256, + const SMDS_MeshNode * n2367, + const SMDS_MeshNode * n3478, + const SMDS_MeshNode * n1458, + const SMDS_MeshNode * n5678, + const SMDS_MeshNode * nCenter, int ID) { - if(hasConstructionFaces()) { - // creation quadratic faces - not implemented + if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 || + !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 || + !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter ) + return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_TriQuad_Hexa, /*nbNodes=*/27, n1, n2, n3, n4, n5, n6, n7, n8, + n12, n23, n34, n41, n56, n67, n78, n85, n15, n26, n37, n48, + n1234, n1256, n2367, n3478, n1458, n5678, nCenter); + myInfo.myNbTriQuadHexas++; + return static_cast( cell ); + } + return 0; +} + +void SMDS_Mesh::dumpGrid(std::string ficdump) +{ + // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New(); + // aWriter->SetFileName(ficdump.c_str()); + // aWriter->SetInput(myGrid); + // if(myGrid->GetNumberOfCells()) + // { + // aWriter->Write(); + // } + // aWriter->Delete(); + ficdump = ficdump + "_connectivity"; + std::ofstream ficcon(ficdump.c_str(), ios::out); + int nbPoints = myGrid->GetNumberOfPoints(); + ficcon << "-------------------------------- points " << nbPoints << endl; + for (int i=0; iGetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl; + } + int nbCells = myGrid->GetNumberOfCells(); + ficcon << "-------------------------------- cells " << nbCells << endl; + for (int i=0; iGetCell(i)->GetCellType() << " -"; + int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints(); + vtkIdList *listid = myGrid->GetCell(i)->GetPointIds(); + for (int j=0; jGetId(j); + } + ficcon << endl; + } + ficcon << "-------------------------------- connectivity " << nbPoints << endl; + vtkCellLinks *links = myGrid->GetLinks(); + for (int i=0; iGetNcells(i); + vtkIdType *cells = links->GetCells(i); + ficcon << i << " - " << ncells << " -"; + for (int j=0; jmyCompactTime = this->myModifTime; + + bool idsChange = HasNumerationHoles(); + if ( idsChange ) + { + std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin(); + for ( ; holder != myElemHolders.end(); ++holder ) + (*holder)->beforeCompacting(); + } + int oldCellSize = myCellFactory->GetMaxID(); + + // remove "holes" in SMDS numeration + std::vector idNodesOldToNew, idCellsNewToOld, idCellsOldToNew; + myNodeFactory->Compact( idNodesOldToNew ); + myCellFactory->Compact( idCellsNewToOld ); + + // make VTK IDs correspond to SMDS IDs + int newNodeSize = myNodeFactory->NbUsedElements(); + int newCellSize = myCellFactory->NbUsedElements(); + myGrid->compactGrid( idNodesOldToNew, newNodeSize, idCellsNewToOld, newCellSize ); + + if ( idsChange && !myElemHolders.empty() ) + { + // idCellsNewToOld -> idCellsOldToNew + idCellsOldToNew.resize( oldCellSize, oldCellSize ); + for ( size_t iNew = 0; iNew < idCellsNewToOld.size(); ++iNew ) + { + if ( idCellsNewToOld[ iNew ] >= (int) idCellsOldToNew.size() ) + idCellsOldToNew.resize( ( 1 + idCellsNewToOld[ iNew ]) * 1.5, oldCellSize ); + idCellsOldToNew[ idCellsNewToOld[ iNew ]] = iNew; + } } - SMDS_QuadraticVolumeOfNodes * volume = - new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41, - n56,n67,n78,n85,n15,n26,n37,n48); - myVolumes.Add(volume); - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; + std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin(); + for ( ; holder != myElemHolders.end(); ++holder ) + if ( idsChange ) + (*holder)->restoreElements( idNodesOldToNew, idCellsOldToNew ); + else + (*holder)->compact(); + + return; +} + +int SMDS_Mesh::FromVtkToSmds( int vtkid ) const +{ + return myCellFactory->FromVtkToSmds( vtkid ); +} + +double SMDS_Mesh::getMaxDim() +{ + double dmax = 1.e-3; + if ((xmax - xmin) > dmax) dmax = xmax -xmin; + if ((ymax - ymin) > dmax) dmax = ymax -ymin; + if ((zmax - zmin) > dmax) dmax = zmax -zmin; + return dmax; +} + +//! modification that needs compact structure and redraw +void SMDS_Mesh::Modified() +{ + if (this->myModified) + { + myGrid->Modified(); + this->myModifTime++; + myModified = false; } - return volume; } +//! get last modification timeStamp +vtkMTimeType SMDS_Mesh::GetMTime() const +{ + return this->myModifTime; +} + +bool SMDS_Mesh::IsCompacted() +{ + return ( this->myCompactTime == this->myModifTime ); +} + +//! are there holes in elements or nodes numeration +bool SMDS_Mesh::HasNumerationHoles() +{ + return ( myNodeFactory->CompactChangePointers() || + myCellFactory->CompactChangePointers() ); +} + +void SMDS_Mesh::setNbShapes( size_t nbShapes ) +{ + myNodeFactory->SetNbShapes( nbShapes ); +}