X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMDS%2FSMDS_Mesh.cxx;h=43a48eb37f23095e4f666dd64df2ed7c84a93487;hp=9ba95601271f0c9545a1bf170ee1eefdf1719c24;hb=eb177ba64551d4218329339113f3e1782ceb6029;hpb=4791f5b30ea7a9c1247aa551750dc71cb83b99aa diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index 9ba956012..43a48eb37 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -1,1493 +1,2991 @@ -// SMESH SMDS : implementaion of Salome mesh data structure +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// 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 // -// File : SMDS_Mesh.cxx -// Author : Jean-Michel BOULCOURT -// Module : SMESH - -using namespace std; -#include "SMDS_Mesh.ixx" -#include "SMDS_MapIteratorOfExtendedOrientedMap.hxx" -#include "SMDS_ListOfMeshElement.hxx" -#include "SMDS_ListIteratorOfListOfMeshElement.hxx" -#include "SMDS_MeshNode.hxx" -#include "SMDS_MeshEdge.hxx" -#include "SMDS_MeshFace.hxx" -#include "SMDS_MeshTriangle.hxx" -#include "SMDS_MeshQuadrangle.hxx" -#include "SMDS_MeshVolume.hxx" -#include "SMDS_MeshTetrahedron.hxx" -#include "SMDS_MeshPyramid.hxx" -#include "SMDS_MeshPrism.hxx" -#include "SMDS_MeshHexahedron.hxx" -#include "SMDS_ListOfMesh.hxx" -#include "SMDS_ListIteratorOfListOfMesh.hxx" - -#include -#include +// SMESH SMDS : implementation of Salome mesh data structure +// +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + +#include "SMDS_Mesh.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 +#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, suppres 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" ); + } -#include "utilities.h" + // 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; -//======================================================================= -//function : SMDS_Mesh -//purpose : creation of a new mesh object -//======================================================================= + if ( doNotRaise ) + return 0; -SMDS_Mesh::SMDS_Mesh(const Standard_Integer nbnodes, - const Standard_Integer nbedges, - const Standard_Integer nbfaces, - const Standard_Integer nbvolumes) - :myNodes(nbnodes),myEdges(nbedges),myFaces(nbfaces),myVolumes(nbvolumes), - myNodeIDFactory(new SMDS_MeshNodeIDFactory()), - myElementIDFactory(new SMDS_MeshElementIDFactory()),myHasInverse(Standard_False) -{ + 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(): + 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(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Create a new child 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): + myNodeFactory( new SMDS_NodeFactory( this )), + myCellFactory( new SMDS_ElementFactory( this )), + myParent(parent) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a submesh and add it to the current mesh +/////////////////////////////////////////////////////////////////////////////// + +SMDS_Mesh *SMDS_Mesh::AddSubMesh() +{ + SMDS_Mesh *submesh = new SMDS_Mesh(this); + myChildren.insert(myChildren.end(), submesh); + return submesh; } -//======================================================================= -//function : SMDS_Mesh -//purpose : -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +///create a MeshNode and add it to the current Mesh +///An ID is automatically assigned to the node. +///@return : The created node +/////////////////////////////////////////////////////////////////////////////// -SMDS_Mesh::SMDS_Mesh(const Handle(SMDS_Mesh)& parent, - const Standard_Integer nbnodes) - :myNodes(nbnodes),myParent(parent),myNodeIDFactory(parent->myNodeIDFactory), - myElementIDFactory(parent->myElementIDFactory), - myHasInverse(Standard_False) +SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z) { + return SMDS_Mesh::AddNodeWithID( x,y,z, myNodeFactory->GetFreeID() ); } -//======================================================================= -//function : AddSubMesh -//purpose : create an submesh -//======================================================================= - -Handle(SMDS_Mesh) SMDS_Mesh::AddSubMesh() +/////////////////////////////////////////////////////////////////////////////// +///create a MeshNode and add it to the current Mesh +///@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 ) { - Handle(SMDS_Mesh) submesh = new SMDS_Mesh(this); - if (!submesh.IsNull()) { - myChildren.Append(submesh); + // find the MeshNode corresponding to ID + SMDS_MeshNode *node = myNodeFactory->NewNode( ID ); + if ( node ) + { + node->init( x, y, z ); + myInfo.myNbNodes++; + myModified = true; + this->adjustBoundingBox(x, y, z); } - - return submesh; + 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); +} -//======================================================================= -//function : AddNode -//purpose : create a MeshNode and returns an 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() ); +} -Standard_Integer SMDS_Mesh::AddNode(const Standard_Real x, - const Standard_Real y, - const Standard_Real z) +/////////////////////////////////////////////////////////////////////////////// +/// 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) { - Standard_Integer ID = myNodeIDFactory->GetFreeID(); + if (!n) return 0; - Handle(SMDS_MeshElement) node = new SMDS_MeshNode(ID,x,y,z); - AddNode(node); + if (Nb0DElements() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); - return ID; -} + if ( SMDS_MeshCell * cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_0D, /*nbNodes=*/1, n ); + myInfo.myNb0DElements++; + return static_cast< SMDS_Mesh0DElement*> ( cell ); + } -//======================================================================= -//function : AddNode -//purpose : create a MeshNode. Returns False if the ID already exists -//======================================================================= + return 0; +} -Standard_Boolean SMDS_Mesh::AddNodeWithID(const Standard_Real x, - const Standard_Real y, - const Standard_Real z, - const Standard_Integer ID) +/////////////////////////////////////////////////////////////////////////////// +/// 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 ) { - - // find the MeshNode corresponding to ID - Handle(SMDS_MeshElement) node; - node = GetNode(ID); - - if (node.IsNull()) { - node = new SMDS_MeshNode(ID,x,y,z); - AddNode(node); - return Standard_True; - } else - return Standard_False; - + const SMDS_MeshNode * node = myNodeFactory->FindNode( idnode ); + if (!node) return NULL; + return SMDS_Mesh::AddBallWithID( node, diameter, ID ); } -//======================================================================= -//function : AddNode -//purpose : add an existing node in the mesh (useful for submesh) -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +/// 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()); +} -Standard_Boolean SMDS_Mesh::AddNode(const Standard_Integer ID) +/////////////////////////////////////////////////////////////////////////////// +/// 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) { - // find the MeshNode corresponding to ID - Handle(SMDS_MeshElement) node; + if (!n) return 0; - node = GetNode(ID); + if (NbBalls() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); - if (!node.IsNull()) { - myNodes.Add(node); - return Standard_True;; - } else - return Standard_False; + SMDS_BallElement* ball = static_cast< SMDS_BallElement*>( myCellFactory->NewElement( ID )); + if ( ball ) + { + ball->init( n, diameter ); + myInfo.myNbBalls++; + } + return ball; } -//======================================================================= -//function : AddNode -//purpose : -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +/// create a MeshEdge and add it to the current Mesh +/// @return : The created MeshEdge +/////////////////////////////////////////////////////////////////////////////// -Standard_Boolean SMDS_Mesh::AddNode(const Handle(SMDS_MeshElement)& node) +SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) { - - if (!node.IsNull()) { - myNodes.Add(node); - if (!myParent.IsNull()) { - myParent->AddNode(node); - } - return Standard_True; - } else - return Standard_False; + 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); } +/////////////////////////////////////////////////////////////////////////////// +/// create a MeshEdge and add it to the current Mesh +/// @return : The created MeshEdge +/////////////////////////////////////////////////////////////////////////////// -//======================================================================= -//function : AddEdge -//purpose : -//======================================================================= - -Standard_Integer SMDS_Mesh::AddEdge(const Standard_Integer idnode1, - const Standard_Integer idnode2) +SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2) { - Standard_Integer ID = myElementIDFactory->GetFreeID(); - - if (AddEdgeWithID(idnode1,idnode2,ID)) - return ID; - else - return 0; - + return SMDS_Mesh::AddEdgeWithID(node1, node2, myCellFactory->GetFreeID()); } -//======================================================================= -//function : AddEdge -//purpose : -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +/// Create a new edge and at it to the mesh +/// @param idnode1 ID of the first node +/// @param idnode2 ID of the second node +/// @param ID ID of the edge to create +/// @return The created edge or NULL if an element with this ID already exists or +/// if input nodes are not found. +/////////////////////////////////////////////////////////////////////////////// -Standard_Boolean SMDS_Mesh::AddEdgeWithID(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer ID) +SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + int ID) { - Handle(SMDS_MeshElement) edge,elem; - Standard_Boolean successAdd = Standard_False; + if ( !n1 || !n2 ) return 0; - // find the MeshNode corresponding to idnode1 - if (AddNode(idnode1)) { - // find the MeshNode corresponding to idnode2 - if (AddNode(idnode2)) { - elem = CreateEdge(ID,idnode1,idnode2); - edge = FindEdge(elem); - if (edge.IsNull()) { - edge = elem; - myEdges.Add(edge); - } - successAdd = myElementIDFactory->BindID(ID,edge); - } + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Edge, /*nbNodes=*/2, n1, n2 ); + myInfo.myNbEdges++; + return static_cast( cell ); } - - return successAdd; - + return 0; } -//======================================================================= -//function : AddFace -//purpose : -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +/// Add a triangle defined by its nodes. An ID is automatically affected to the +/// Created face +/////////////////////////////////////////////////////////////////////////////// -Standard_Integer SMDS_Mesh::AddFace(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3) +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3) { - Standard_Integer ID = myElementIDFactory->GetFreeID(); - - if (AddFaceWithID(idnode1,idnode2,idnode3,ID)) - return ID; - else - return 0; - + return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myCellFactory->GetFreeID()); } -//======================================================================= -//function : AddFace -//purpose : -//======================================================================= - -Standard_Boolean SMDS_Mesh::AddFaceWithID(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer ID) -{ - Handle(SMDS_MeshElement) face,elem; - Standard_Boolean successAdd = Standard_False; - - // find the MeshNode corresponding to idnode1 - if (AddNode(idnode1)) { - // find the MeshNode corresponding to idnode2 - if (AddNode(idnode2)) { - // find the MeshNode corresponding to idnode3 - if (AddNode(idnode3)) { - elem = CreateFace(ID,idnode1,idnode2,idnode3); - face = FindFace(elem); - if (face.IsNull()) { - face = elem; - myFaces.Add(face); - } - successAdd = myElementIDFactory->BindID(ID,face); - } - } - } +/////////////////////////////////////////////////////////////////////////////// +/// Add a triangle defined by its nodes IDs +/////////////////////////////////////////////////////////////////////////////// - return successAdd; - -} - - -//======================================================================= -//function : AddFace -//purpose : -//======================================================================= - -Standard_Integer SMDS_Mesh::AddFace(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4) +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID) { - Standard_Integer ID = myElementIDFactory->GetFreeID(); - - if (AddFaceWithID(idnode1,idnode2,idnode3,idnode4,ID)) - return ID; - else - return 0; - + 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); } +/////////////////////////////////////////////////////////////////////////////// +/// Add a triangle defined by its nodes +/////////////////////////////////////////////////////////////////////////////// -//======================================================================= -//function : AddFace -//purpose : -//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + int ID) +{ + if ( !n1 || !n2 || !n3 ) return 0; + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); -Standard_Boolean SMDS_Mesh::AddFaceWithID(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4, - const Standard_Integer ID) -{ - Handle(SMDS_MeshElement) face,elem; - Standard_Boolean successAdd = Standard_False; - - // find the MeshNode corresponding to idnode1 - if (AddNode(idnode1)) { - // find the MeshNode corresponding to idnode2 - if (AddNode(idnode2)) { - // find the MeshNode corresponding to idnode3 - if (AddNode(idnode3)) { - // find the MeshNode corresponding to idnode4 - if (AddNode(idnode4)) { - elem = CreateFace(ID,idnode1,idnode2,idnode3,idnode4); - face = FindFace(elem); - if (face.IsNull()) { - face = elem; - myFaces.Add(face); - } - successAdd = myElementIDFactory->BindID(ID,face); - } - } - } + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Triangle, /*nbNodes=*/3, n1, n2, n3 ); + myInfo.myNbTriangles++; + return static_cast( cell ); } - - return successAdd; - + return 0; } +/////////////////////////////////////////////////////////////////////////////// +/// Add a quadrangle defined by its nodes. An ID is automatically affected to the +/// created face +/////////////////////////////////////////////////////////////////////////////// - -//======================================================================= -//function : AddVolume -//purpose : Tetrahedra -//======================================================================= - -Standard_Integer SMDS_Mesh::AddVolume(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4) +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4) { - Standard_Integer ID = myElementIDFactory->GetFreeID(); - - if (AddVolumeWithID(idnode1,idnode2,idnode3,idnode4,ID)) - return ID; - else - return 0; - + return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myCellFactory->GetFreeID()); } -//======================================================================= -//function : AddVolume -//purpose : Tetrahedra -//======================================================================= - -Standard_Boolean SMDS_Mesh::AddVolumeWithID(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4, - const Standard_Integer ID) -{ - Handle(SMDS_MeshElement) volume,elem; - Standard_Boolean successAdd = Standard_False; - - // find the MeshNode corresponding to idnode1 - if (AddNode(idnode1)) { - // find the MeshNode corresponding to idnode2 - if (AddNode(idnode2)) { - // find the MeshNode corresponding to idnode3 - if (AddNode(idnode3)) { - // find the MeshNode corresponding to idnode4 - if (AddNode(idnode4)) { - elem = CreateVolume(ID,idnode1,idnode2,idnode3,idnode4); - volume = FindVolume(elem); - if (volume.IsNull()) { - volume = elem; - myVolumes.Add(volume); - } - successAdd = myElementIDFactory->BindID(ID,volume); - } - } - } - } - - return successAdd; +/////////////////////////////////////////////////////////////////////////////// +/// Add a quadrangle defined by its nodes IDs +/////////////////////////////////////////////////////////////////////////////// +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int 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); } -//======================================================================= -//function : AddVolume -//purpose : Pyramid -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +/// Add a quadrangle defined by its nodes +/////////////////////////////////////////////////////////////////////////////// -Standard_Integer SMDS_Mesh::AddVolume(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4, - const Standard_Integer idnode5) +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID) { - Standard_Integer ID = myElementIDFactory->GetFreeID(); - - if (AddVolumeWithID(idnode1,idnode2,idnode3,idnode4,idnode5,ID)) - return ID; - else - return 0; + if ( !n1 || !n2 || !n3 || !n4 ) return 0; + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); -} - -//======================================================================= -//function : AddVolume -//purpose : Pyramid -//======================================================================= - -Standard_Boolean SMDS_Mesh::AddVolumeWithID(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4, - const Standard_Integer idnode5, - const Standard_Integer ID) -{ - Handle(SMDS_MeshElement) volume,elem; - Standard_Boolean successAdd = Standard_False; - - // find the MeshNode corresponding to idnode1 - if (AddNode(idnode1)) { - // find the MeshNode corresponding to idnode2 - if (AddNode(idnode2)) { - // find the MeshNode corresponding to idnode3 - if (AddNode(idnode3)) { - // find the MeshNode corresponding to idnode4 - if (AddNode(idnode4)) { - // find the MeshNode corresponding to idnode5 - if (AddNode(idnode5)) { - elem = CreateVolume(ID,idnode1,idnode2,idnode3,idnode4,idnode5); - volume = FindVolume(elem); - if (volume.IsNull()) { - volume = elem; - myVolumes.Add(volume); - } - successAdd = myElementIDFactory->BindID(ID,volume); - } - } - } - } + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Quadrangle, /*nbNodes=*/4, n1, n2, n3, n4 ); + myInfo.myNbQuadrangles++; + return static_cast( cell ); } - - return successAdd; - + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// +///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) +{ + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, myCellFactory->GetFreeID() ); +} + +/////////////////////////////////////////////////////////////////////////////// +///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) +{ + 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. +///@param ID The ID of the new volume +///@return The created tetrahedron +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID) +{ + if ( !n1 || !n2 || !n3 || !n4 ) return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Tetra, /*nbNodes=*/4, n1, n2, n3, n4 ); + myInfo.myNbTetras++; + return static_cast( cell ); + } + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// +///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 +/////////////////////////////////////////////////////////////////////////////// + +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) +{ + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, myCellFactory->GetFreeID() ); +} + +/////////////////////////////////////////////////////////////////////////////// +///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) +{ + 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 +///@param ID The ID of the new volume +///@return The created pyramid +/////////////////////////////////////////////////////////////////////////////// + +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, + int ID) +{ + if ( !n1 || !n2 || !n3 || !n4 || !n5 ) return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + + 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 0; +} + +/////////////////////////////////////////////////////////////////////////////// +///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 +/////////////////////////////////////////////////////////////////////////////// + +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) +{ + 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. +///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) +{ + 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. +///@param ID The ID of the new volume +///@return The created prism +/////////////////////////////////////////////////////////////////////////////// + +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, + int ID) +{ + if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 ) return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + + 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 0; +} + +/////////////////////////////////////////////////////////////////////////////// +///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 * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, + const SMDS_MeshNode * n12) +{ + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, + n7, n8, n9, n10, n11, n12, + myCellFactory->GetFreeID() ); +} + +/////////////////////////////////////////////////////////////////////////////// +///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. +/////////////////////////////////////////////////////////////////////////////// + +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, node9, node10, node11, node12, + ID); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new hexagonal prism and add it to the mesh. +///@param ID The ID of the new volume +///@return The created prism +/////////////////////////////////////////////////////////////////////////////// + +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 * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, + const SMDS_MeshNode * n12, + int ID) +{ + 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 ( 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 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 +/////////////////////////////////////////////////////////////////////////////// + +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) +{ + int ID = myCellFactory->GetFreeID(); + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, 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. +///@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. +/////////////////////////////////////////////////////////////////////////////// + +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 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::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) +{ + 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; } -//======================================================================= -//function : AddVolume -//purpose : Prism -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +/// Add a polygon defined by its nodes IDs +/////////////////////////////////////////////////////////////////////////////// -Standard_Integer SMDS_Mesh::AddVolume(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4, - const Standard_Integer idnode5, - const Standard_Integer idnode6) +SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const std::vector & nodes_ids, + const int ID) { - Standard_Integer ID = myElementIDFactory->GetFreeID(); - - if (AddVolumeWithID(idnode1,idnode2,idnode3,idnode4, - idnode5,idnode6,ID)) - return ID; - else - return 0; - -} - -//======================================================================= -//function : AddVolume -//purpose : Prism -//======================================================================= - -Standard_Boolean SMDS_Mesh::AddVolumeWithID(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4, - const Standard_Integer idnode5, - const Standard_Integer idnode6, - const Standard_Integer ID) -{ - Handle(SMDS_MeshElement) volume,elem; - Standard_Boolean successAdd = Standard_False; - - // find the MeshNode corresponding to idnode1 - if (AddNode(idnode1)) { - // find the MeshNode corresponding to idnode2 - if (AddNode(idnode2)) { - // find the MeshNode corresponding to idnode3 - if (AddNode(idnode3)) { - // find the MeshNode corresponding to idnode4 - if (AddNode(idnode4)) { - // find the MeshNode corresponding to idnode5 - if (AddNode(idnode5)) { - // find the MeshNode corresponding to idnode6 - if (AddNode(idnode6)) { - elem = CreateVolume(ID,idnode1,idnode2,idnode3,idnode4,idnode5,idnode6); - volume = FindVolume(elem); - if (volume.IsNull()) { - volume = elem; - myVolumes.Add(volume); - } - successAdd = myElementIDFactory->BindID(ID,volume); - } - } - } - } - } + 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 successAdd; - + return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID); } -//======================================================================= -//function : AddVolume -//purpose : Hexahedra -//======================================================================= - -Standard_Integer SMDS_Mesh::AddVolume(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4, - const Standard_Integer idnode5, - const Standard_Integer idnode6, - const Standard_Integer idnode7, - const Standard_Integer idnode8) -{ - Standard_Integer ID = myElementIDFactory->GetFreeID(); - - if (AddVolumeWithID(idnode1,idnode2,idnode3,idnode4, - idnode5,idnode6,idnode7,idnode8,ID)) - return ID; - else - return 0; +/////////////////////////////////////////////////////////////////////////////// +/// Add a polygon defined by its nodes +/////////////////////////////////////////////////////////////////////////////// -} +SMDS_MeshFace* +SMDS_Mesh::AddPolygonalFaceWithID (const std::vector & nodes, + const int ID) +{ + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); -//======================================================================= -//function : AddVolume -//purpose : Hexahedra -//======================================================================= - -Standard_Boolean SMDS_Mesh::AddVolumeWithID(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4, - const Standard_Integer idnode5, - const Standard_Integer idnode6, - const Standard_Integer idnode7, - const Standard_Integer idnode8, - const Standard_Integer ID) -{ - Handle(SMDS_MeshElement) volume,elem; - Standard_Boolean successAdd = Standard_False; - - // find the MeshNode corresponding to idnode1 - if (AddNode(idnode1)) { - // find the MeshNode corresponding to idnode2 - if (AddNode(idnode2)) { - // find the MeshNode corresponding to idnode3 - if (AddNode(idnode3)) { - // find the MeshNode corresponding to idnode4 - if (AddNode(idnode4)) { - // find the MeshNode corresponding to idnode5 - if (AddNode(idnode5)) { - // find the MeshNode corresponding to idnode6 - if (AddNode(idnode6)) { - // find the MeshNode corresponding to idnode7 - if (AddNode(idnode7)) { - // find the MeshNode corresponding to idnode8 - if (AddNode(idnode8)) { - elem = CreateVolume(ID,idnode1,idnode2,idnode3,idnode4,idnode5, - idnode6,idnode7,idnode8); - volume = FindVolume(elem); - if (volume.IsNull()) { - volume = elem; - myVolumes.Add(volume); - } - successAdd = myElementIDFactory->BindID(ID,volume); - } - } - } - } - } - } - } + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Polygon, nodes ); + myInfo.myNbPolygons++; + return static_cast( cell ); } - - return successAdd; - + return 0; } +/////////////////////////////////////////////////////////////////////////////// +/// Add a polygon defined by its nodes. +/// An ID is automatically affected to the created face. +/////////////////////////////////////////////////////////////////////////////// -//======================================================================= -//function : GetNode -//purpose : returns the MeshNode corresponding to the ID -//======================================================================= - -Handle(SMDS_MeshElement) SMDS_Mesh::GetNode(const Standard_Integer idnode) const +SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const std::vector & nodes) { + return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myCellFactory->GetFreeID()); +} - Handle(SMDS_MeshElement) node; +/////////////////////////////////////////////////////////////////////////////// +/// Add a quadratic polygon defined by its nodes IDs +/////////////////////////////////////////////////////////////////////////////// - Handle(SMDS_MeshElement) elem = FindNode(idnode); - if (!elem.IsNull()) { // found one correspondance - node = elem; - } else { - if (!myParent.IsNull()) - node = myParent->GetNode(idnode); +SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector & nodes_ids, + const int ID) +{ + 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 node; + return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID); } -//======================================================================= -//function : FindNode -//purpose : -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +/// Add a quadratic polygon defined by its nodes +/////////////////////////////////////////////////////////////////////////////// -Handle(SMDS_MeshElement) SMDS_Mesh::FindNode(const Standard_Integer ID) const +SMDS_MeshFace* +SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector & nodes, + const int ID) { - Handle(SMDS_MeshElement) elem; - if (myNodes.ContainsID(ID)) - elem = myNodes.FindID(ID); - return elem; + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + cell->init( SMDSEntity_Quad_Polygon, nodes ); + myInfo.myNbQuadPolygons++; + return static_cast( cell ); + } + return 0; } -//======================================================================= -//function : FindNode -//purpose : -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +/// Add a quadratic polygon defined by its nodes. +/// An ID is automatically affected to the created face. +/////////////////////////////////////////////////////////////////////////////// -Handle(SMDS_MeshElement) SMDS_Mesh::FindNode(const Handle(SMDS_MeshElement)& node) const +SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const std::vector & nodes) { - Handle(SMDS_MeshElement) elem; - if (myNodes.Contains(node)) - elem = myNodes.Find(node); - - return elem; + return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, myCellFactory->GetFreeID()); } -//======================================================================= -//function : CreateEdge -//purpose : -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +/// 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. +/////////////////////////////////////////////////////////////////////////////// -Handle(SMDS_MeshElement) SMDS_Mesh::CreateEdge(const Standard_Integer ID, - const Standard_Integer idnode1, - const Standard_Integer idnode2) const +SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector & nodes_ids, + const std::vector & quantities, + const int ID) { - Handle(SMDS_MeshEdge) edge = new SMDS_MeshEdge(ID,idnode1,idnode2); - return edge; + 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 SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); +} + +/////////////////////////////////////////////////////////////////////////////// +/// 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 (const std::vector& nodes, + const std::vector & quantities, + const int ID) +{ + if ( nodes.empty() || quantities.empty() ) + return NULL; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + + if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + { + SMDS_MeshVolume* volume = static_cast( cell ); + volume->init( nodes, quantities ); + myInfo.myNbPolyhedrons++; + return volume; + } + return 0; } +/////////////////////////////////////////////////////////////////////////////// +/// Create a new polyhedral volume and add it to the mesh. +/// @return The created volume +/////////////////////////////////////////////////////////////////////////////// -//======================================================================= -//function : CreateFace -//purpose : -//======================================================================= - -Handle(SMDS_MeshElement) SMDS_Mesh::CreateFace(const Standard_Integer ID, - const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3) const +SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume +(const std::vector & nodes, + const std::vector & quantities) { - Handle(SMDS_MeshFace) face = new SMDS_MeshTriangle(ID,idnode1,idnode2,idnode3); - return face; + int ID = myCellFactory->GetFreeID(); + return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); } +SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector& vtkNodeIds) +{ + SMDS_MeshCell* cell = myCellFactory->NewCell( myCellFactory->GetFreeID() ); + SMDS_MeshVolume * vol = static_cast( cell ); + vol->init( vtkNodeIds ); + myInfo.add( cell ); + return vol; +} -//======================================================================= -//function : CreateFace -//purpose : -//======================================================================= - -Handle(SMDS_MeshElement) SMDS_Mesh::CreateFace(const Standard_Integer ID, - const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4) const +SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIds(const std::vector& vtkNodeIds) { - Handle(SMDS_MeshFace) face = new SMDS_MeshQuadrangle(ID,idnode1,idnode2,idnode3,idnode4); - return face; + SMDS_MeshCell* cell = myCellFactory->NewCell( myCellFactory->GetFreeID() ); + SMDS_MeshFace * f = static_cast( cell ); + f->init( vtkNodeIds ); + myInfo.add( cell ); + return f; } //======================================================================= -//function : CreateVolume +//function : MoveNode //purpose : //======================================================================= -Handle(SMDS_MeshElement) SMDS_Mesh::CreateVolume(const Standard_Integer ID, - const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4) const +void SMDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z) { - Handle(SMDS_MeshVolume) volume = new SMDS_MeshTetrahedron(ID,idnode1,idnode2,idnode3,idnode4); - return volume; + SMDS_MeshNode * node=const_cast(n); + node->setXYZ(x,y,z); } -//======================================================================= -//function : CreateVolume -//purpose : -//======================================================================= - -Handle(SMDS_MeshElement) SMDS_Mesh::CreateVolume(const Standard_Integer ID, - const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4, - const Standard_Integer idnode5) const +/////////////////////////////////////////////////////////////////////////////// +/// Return the node whose SMDS ID is 'ID'. +/////////////////////////////////////////////////////////////////////////////// +const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const { - Handle(SMDS_MeshVolume) volume = new SMDS_MeshPyramid(ID,idnode1,idnode2,idnode3,idnode4,idnode5); - return volume; + return myNodeFactory->FindNode( ID ); } -//======================================================================= -//function : CreateVolume -//purpose : -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +/// Return the node whose VTK ID is 'vtkId'. +/////////////////////////////////////////////////////////////////////////////// +const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const +{ + return myNodeFactory->FindNode( vtkId + 1 ); +} -Handle(SMDS_MeshElement) SMDS_Mesh::CreateVolume(const Standard_Integer ID, - const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4, - const Standard_Integer idnode5, - const Standard_Integer idnode6) const +const SMDS_MeshElement * SMDS_Mesh::FindElementVtk(int IDelem) const { - Handle(SMDS_MeshVolume) volume = new SMDS_MeshPrism(ID,idnode1,idnode2,idnode3,idnode4,idnode5,idnode6); - return volume; + return myCellFactory->FindElement( FromVtkToSmds( IDelem )); } -//======================================================================= -//function : CreateVolume -//purpose : -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +/// Remove a node and all the elements which own this node +/////////////////////////////////////////////////////////////////////////////// -Handle(SMDS_MeshElement) SMDS_Mesh::CreateVolume(const Standard_Integer ID, - const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4, - const Standard_Integer idnode5, - const Standard_Integer idnode6, - const Standard_Integer idnode7, - const Standard_Integer idnode8) const +void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node) { - Handle(SMDS_MeshVolume) volume = new SMDS_MeshHexahedron(ID,idnode1,idnode2,idnode3,idnode4, - idnode5,idnode6,idnode7,idnode8); - return volume; + RemoveElement(node, true); } //======================================================================= -//function : Contains -//purpose : +//function : RemoveFromParent +//purpose : //======================================================================= -Standard_Boolean SMDS_Mesh::Contains(const Handle(SMDS_MeshElement)& elem) const +bool SMDS_Mesh::RemoveFromParent() { - Standard_Boolean isinmesh = Standard_False; - if (myNodes.Contains(elem)) - isinmesh = Standard_True; - else if (myEdges.Contains(elem)) - isinmesh = Standard_True; - else if (myFaces.Contains(elem)) - isinmesh = Standard_True; - else if (myVolumes.Contains(elem)) - isinmesh = Standard_True; - - return isinmesh; + if (myParent==NULL) return false; + else return (myParent->RemoveSubMesh(this)); } //======================================================================= -//function : FindEdge -//purpose : +//function : RemoveSubMesh +//purpose : //======================================================================= -Handle(SMDS_MeshElement) SMDS_Mesh::FindEdge(const Handle(SMDS_MeshElement)& edge) const +bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh) { - Handle(SMDS_MeshElement) elem; - if (myEdges.Contains(edge)) - elem = myEdges.Find(edge); + bool found = false; - return elem; + 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 : FindFace -//purpose : +//function : ChangeElementNodes +//purpose : //======================================================================= -Handle(SMDS_MeshElement) SMDS_Mesh::FindFace(const Handle(SMDS_MeshElement)& face) const +bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element, + const SMDS_MeshNode * nodes[], + const int nbnodes) { - Handle(SMDS_MeshElement) elem; - if (myFaces.Contains(face)) - elem = myFaces.Find(face); + // keep current nodes of element + std::set oldNodes( element->begin_nodes(), element->end_nodes() ); - return elem; -} + // change nodes + bool Ok = false; + if ( SMDS_MeshCell* cell = dynamic_cast((SMDS_MeshElement*) element)) + Ok = cell->ChangeNodes(nodes, nbnodes); + if ( Ok ) + setMyModified(); -//======================================================================= -//function : FindVolume -//purpose : -//======================================================================= + if ( Ok && GetGrid()->HasLinks() ) // update InverseElements + { + std::set::iterator it; -Handle(SMDS_MeshElement) SMDS_Mesh::FindVolume(const Handle(SMDS_MeshElement)& volume) const -{ - Handle(SMDS_MeshElement) elem; - if (myVolumes.Contains(volume)) - elem = myVolumes.Find(volume); + // AddInverseElement to new nodes + for ( int i = 0; i < nbnodes; i++ ) { + it = oldNodes.find( nodes[i] ); + if ( it == oldNodes.end() ) + // new node + const_cast( nodes[i] )->AddInverseElement( element ); + else + // remove from oldNodes a node that remains in elem + oldNodes.erase( it ); + } + // RemoveInverseElement from the nodes removed from elem + for ( it = oldNodes.begin(); it != oldNodes.end(); it++ ) + { + SMDS_MeshNode * n = const_cast( *it ); + n->RemoveInverseElement( element ); + } + } - return elem; + return Ok; } - -//======================================================================= -//function : FreeNode -//purpose : -//======================================================================= - -void SMDS_Mesh::FreeNode(const Handle(SMDS_MeshElement)& node) +const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node) { - myNodes.Remove(node); - - SMDS_ListIteratorOfListOfMesh itmsh(myChildren); - for (;itmsh.More(); itmsh.Next()) { - const Handle(SMDS_Mesh)& submesh = itmsh.Value(); - submesh->RemoveNode(node->GetID()); + 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); } + } + return toReturn; } +const SMDS_BallElement* SMDS_Mesh::FindBall(const SMDS_MeshNode * node) +{ + 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; +} - -//======================================================================= -//function : RemoveNode -//purpose : -//======================================================================= - -void SMDS_Mesh::RemoveNode(const Standard_Integer IDnode) +const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2) { - // find the MeshNode corresponding to IDnode - Handle(SMDS_MeshElement) node = FindNode(IDnode); - if (RemoveNode(node)) { - if (myParent.IsNull()) { // if no parent we can release the ID - myNodeIDFactory->ReleaseID(IDnode); + if ( !node1 ) return 0; + const SMDS_MeshEdge * toReturn=NULL; + SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge); + while(it1->more()) { + const SMDS_MeshElement * e = it1->next(); + if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) { + toReturn = static_cast( e ); + break; + } + } + return toReturn; +} + +const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3) +{ + if ( !node1 ) return 0; + SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge); + while(it1->more()) { + 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 0; } //======================================================================= -//function : RemoveNode -//purpose : -//======================================================================= - -Standard_Boolean SMDS_Mesh::RemoveNode(const Handle(SMDS_MeshElement)& node) -{ - Standard_Boolean successRemove = Standard_False; - - if (!node.IsNull()) { - if (myHasInverse && myNodes.Contains(node)) { - SMDS_MapOfMeshOrientedElement map(1); - BuildMapNodeAncestors(node,map); - RemoveAncestors(node,map); +//function : FindFace +//purpose : +//======================================================================= + +const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3) +{ + if ( !node1 ) return 0; + SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face); + while(it1->more()) { + 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); } - - FreeNode(node); - successRemove = Standard_True; } - - return successRemove; + return 0; } //======================================================================= -//function : RemoveEdge -//purpose : +//function : FindFace +//purpose : +//======================================================================= + +const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3, + const SMDS_MeshNode *node4) +{ + if ( !node1 ) return 0; + SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face); + while(it1->more()) { + 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); + } + } + return 0; +} + //======================================================================= +//function : FindFace +//purpose :quadratic triangle +//======================================================================= + +const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3, + const SMDS_MeshNode *node4, + const SMDS_MeshNode *node5, + const SMDS_MeshNode *node6) +{ + if ( !node1 ) return 0; + SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face); + while(it1->more()) { + 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); + } + } + return 0; +} -void SMDS_Mesh::RemoveEdge(const Standard_Integer idnode1, const Standard_Integer idnode2) -{ - Handle(SMDS_MeshElement) edge = FindEdge(idnode1,idnode2); - RemoveEdge(edge); + +//======================================================================= +//function : FindFace +//purpose : quadratic quadrangle +//======================================================================= + +const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3, + const SMDS_MeshNode *node4, + const SMDS_MeshNode *node5, + const SMDS_MeshNode *node6, + const SMDS_MeshNode *node7, + const SMDS_MeshNode *node8) +{ + if ( !node1 ) return 0; + SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face); + while(it1->more()) { + 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); + } + } + return 0; } + //======================================================================= -//function : RemoveEdge -//purpose : +//function : FindElement +//purpose : //======================================================================= -void SMDS_Mesh::RemoveEdge(const Handle(SMDS_MeshElement)& edge) +const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const { + return myCellFactory->FindElement( IDelem ); +} - if (!edge.IsNull()) { - myEdges.Remove(edge); +//======================================================================= +//function : FindFace +//purpose : find polygon +//======================================================================= + + +const SMDS_MeshFace* SMDS_Mesh::FindFace (const std::vector& nodes) +{ + return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face ); +} + + +//================================================================================ +/*! + * \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 + */ +//================================================================================ + +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; + } + } + } + return NULL; +} + +//================================================================================ +/*! + * \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 + */ +//================================================================================ + +int SMDS_Mesh::GetElementsByNodes(const std::vector& nodes, + std::vector& foundElems, + const SMDSAbs_ElementType type) +{ + // 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 ); + } - myElementIDFactory->ReleaseID(edge->GetID()); + 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 : RemoveFace -//purpose : -//======================================================================= - -void SMDS_Mesh::RemoveFace(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3) +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of nodes +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbNodes() const { - Handle(SMDS_MeshElement) face = FindFace(idnode1,idnode2,idnode3); - RemoveFace(face); + return myInfo.NbNodes(); } -//======================================================================= -//function : RemoveFace -//purpose : -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of elements +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbElements() const +{ + return myInfo.NbElements(); +} +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of 0D elements +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::Nb0DElements() const +{ + return myInfo.Nb0DElements(); +} -void SMDS_Mesh::RemoveFace(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4) +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of 0D elements +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbBalls() const { - Handle(SMDS_MeshElement) face = FindFace(idnode1,idnode2,idnode3,idnode4); - RemoveFace(face); + return myInfo.NbBalls(); } +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of edges (including construction edges) +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbEdges() const +{ + return myInfo.NbEdges(); +} -//======================================================================= -//function : RemoveFace -//purpose : -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of faces (including construction faces) +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbFaces() const +{ + return myInfo.NbFaces(); +} -void SMDS_Mesh::RemoveFace(const Handle(SMDS_MeshElement)& face) +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of volumes +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbVolumes() const { - if (!face.IsNull()) { - myFaces.Remove(face); - myElementIDFactory->ReleaseID(face->GetID()); - } + return myInfo.NbVolumes(); } -//======================================================================= -//function : RemoveVolume -//purpose : -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of child mesh of this mesh. +/// Note that the tree structure of SMDS_Mesh is unused in SMESH +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbSubMesh() const +{ + return myChildren.size(); +} -void SMDS_Mesh::RemoveVolume(const Handle(SMDS_MeshElement)& volume) +/////////////////////////////////////////////////////////////////////////////// +/// Destroy the mesh and all its elements +/// All pointer on elements owned by this mesh become illegals. +/////////////////////////////////////////////////////////////////////////////// +SMDS_Mesh::~SMDS_Mesh() { - if (myVolumes.Contains(volume)) { - myVolumes.Remove(volume); - myElementIDFactory->ReleaseID(volume->GetID()); + std::list::iterator itc=myChildren.begin(); + while(itc!=myChildren.end()) + { + delete *itc; + itc++; } + + delete myNodeFactory; + delete myCellFactory; + + myGrid->Delete(); } -//======================================================================= -//function : RemoveElement -//purpose : -//======================================================================= +//================================================================================ +/*! + * \brief Clear all data + */ +//================================================================================ -void SMDS_Mesh::RemoveElement(const Standard_Integer IDelem,const Standard_Boolean removenodes) +void SMDS_Mesh::Clear() { - Handle(SMDS_MeshElement) elem = myElementIDFactory->MeshElement(IDelem); - RemoveElement(elem,removenodes); + std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin(); + for ( ; holder != myElemHolders.end(); ++holder ) + (*holder)->clear(); + + myNodeFactory->Clear(); + myCellFactory->Clear(); + + std::list::iterator itc=myChildren.begin(); + while(itc!=myChildren.end()) + (*itc)->Clear(); + myModified = false; + myModifTime++; + xmin = 0; xmax = 0; + ymin = 0; ymax = 0; + zmin = 0; zmax = 0; - + myInfo.Clear(); + + 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(); } -//======================================================================= -//function : RemoveElement -//purpose : -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +/// Return an iterator on nodes of the current mesh factory +/////////////////////////////////////////////////////////////////////////////// -void SMDS_Mesh::RemoveElement(const Handle(SMDS_MeshElement)& elem,const Standard_Boolean removenodes) -{ - if ( elem->IsKind(STANDARD_TYPE(SMDS_MeshEdge)) ) { - RemoveEdge(elem); - } else if ( elem->IsKind(STANDARD_TYPE(SMDS_MeshNode))) { - RemoveNode(elem); - return; - } else if ( elem->IsKind(STANDARD_TYPE(SMDS_MeshFace))) { - RemoveFace(elem); - } else if ( elem->IsKind(STANDARD_TYPE(SMDS_MeshVolume))) { - RemoveVolume(elem); - } else { - MESSAGE( "remove function : unknown type" ); - return; - } +SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const +{ + return myNodeFactory->GetIterator< SMDS_NodeIterator >( new SMDS_MeshElement::NonNullFilter ); +} - Standard_Integer nbcnx = elem->NbNodes(); - Standard_Integer i; - for (i=1; i <= nbcnx; ++i) { - RemoveInverseElement(GetNode(i,elem),elem); - - } +SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) const +{ + return myCellFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::GeomFilter( type ), + myInfo.NbElements( type )); +} - if (removenodes) { - for (i=1; i <= nbcnx; ++i) { - if (GetNode(i,elem)->InverseElements().IsEmpty()) - FreeNode(GetNode(i,elem)); - } +SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const +{ + if ( type == SMDSEntity_Node ) + { + return myNodeFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::NonNullFilter ); } - + return myCellFactory->GetIterator( new SMDS_MeshElement::EntityFilter( type ), + myInfo.NbElements( type )); } - -//======================================================================= -//function : RemoveFromParent -//purpose : -//======================================================================= -Standard_Boolean SMDS_Mesh::RemoveFromParent() +/////////////////////////////////////////////////////////////////////////////// +/// Return an iterator on elements of the current mesh factory +/////////////////////////////////////////////////////////////////////////////// +SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const { - if (myParent.IsNull()) - return Standard_False; + typedef SMDS_ElemIterator TIterator; + switch ( type ) { + + case SMDSAbs_All: + return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter ); - return (myParent->RemoveSubMesh(this)); + case SMDSAbs_Node: + return myNodeFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter ); + default: + return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( type ), + myInfo.NbElements( type )); + } + return SMDS_ElemIteratorPtr(); } -//======================================================================= -//function : RemoveSubMesh -//purpose : -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +///Return an iterator on edges of the current mesh. +/////////////////////////////////////////////////////////////////////////////// -Standard_Boolean SMDS_Mesh::RemoveSubMesh(const Handle(SMDS_Mesh)& aMesh) +SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const { - Standard_Boolean found = Standard_False; + typedef SMDS_EdgeIterator TIterator; + return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Edge ), + myInfo.NbEdges()); +} - SMDS_ListIteratorOfListOfMesh itmsh(myChildren); - for (;itmsh.More() && !found; itmsh.Next()) { - Handle(SMDS_Mesh) submesh; - submesh = itmsh.Value(); - if (submesh == aMesh) { - found = Standard_True; - myChildren.Remove(itmsh); - } - } +/////////////////////////////////////////////////////////////////////////////// +///Return an iterator on faces of the current mesh. +/////////////////////////////////////////////////////////////////////////////// - return found; +SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const +{ + typedef SMDS_FaceIterator TIterator; + return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Face ), + myInfo.NbFaces()); } -//======================================================================= -//function : RemoveInverseElement -//purpose : -//======================================================================= +/////////////////////////////////////////////////////////////////////////////// +///Return an iterator on volumes of the current mesh. +/////////////////////////////////////////////////////////////////////////////// -void SMDS_Mesh::RemoveInverseElement(const Handle(SMDS_MeshElement)& elem, - const Handle(SMDS_MeshElement)& parent) const +SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const { - if (!myHasInverse) - return; - - Handle(SMDS_MeshNode)& node = *((Handle(SMDS_MeshNode)*)&elem); - node->RemoveInverseElement(parent); + typedef SMDS_VolumeIterator TIterator; + return + myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Volume ), + myInfo.NbVolumes()); } - -//======================================================================= -//function : RemoveAncestors -//purpose : -//======================================================================= -void SMDS_Mesh::RemoveAncestors(const Handle(SMDS_MeshElement)& elem, - const SMDS_MapOfMeshOrientedElement& map) +SMDS_NodeIteratorPtr SMDS_Mesh::shapeNodesIterator(int shapeID, size_t nbElemsToReturn) const { + return myNodeFactory->GetShapeIterator< SMDS_NodeIterator >( shapeID, nbElemsToReturn ); +} - if (!myHasInverse) - return; - - SMDS_MapIteratorOfExtendedOrientedMap itAnc(map); +SMDS_ElemIteratorPtr SMDS_Mesh::shapeElementsIterator(int shapeID, size_t nbElemsToReturn) const +{ + return myCellFactory->GetShapeIterator< SMDS_ElemIterator >( shapeID, nbElemsToReturn ); +} - for (;itAnc.More();itAnc.Next()) { - const Handle(SMDS_MeshElement)& ME = itAnc.Key(); - Standard_Integer nbcnx = ME->NbNodes(); +/////////////////////////////////////////////////////////////////////////////// +/// Do intersection of sets (more than 2) +/////////////////////////////////////////////////////////////////////////////// +static std::set * +intersectionOfSets( std::set vs[], int numberOfSets ) +{ + std::set* rsetA = new std::set(vs[0]); + std::set* rsetB; - for (Standard_Integer i=1; i <= nbcnx; ++i) { - RemoveInverseElement(GetNode(i,ME),ME); + 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 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 std::set * getFinitElements(const SMDS_MeshElement * element) +{ + int numberOfSets=element->NbNodes(); + std::set *initSet = new std::set[numberOfSets]; + + SMDS_NodeIteratorPtr itNodes = element->nodeIterator(); + + 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 std::list of nodes used only by the given elements +/////////////////////////////////////////////////////////////////////////////// +static +std::set *getExclusiveNodes(std::set& elements) +{ + std::set * toReturn = new std::set(); + std::set::iterator itElements = elements.begin(); + + while( itElements != elements.end() ) + { + SMDS_NodeIteratorPtr itNodes = (*itElements)->nodeIterator(); + itElements++; + + 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); } } - - SMDS_MapIteratorOfExtendedOrientedMap itAnc2(map); - - for (;itAnc2.More();itAnc2.Next()) { - const Handle(SMDS_MeshElement)& ME = itAnc2.Key(); - RemoveElement(ME); + return toReturn; +} + +/////////////////////////////////////////////////////////////////////////////// +///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(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; } } -//======================================================================= -//function : BuildMapNodeAncestors -//purpose : -//======================================================================= - -void SMDS_Mesh::BuildMapNodeAncestors(const Handle(SMDS_MeshElement)& ME, - SMDS_MapOfMeshOrientedElement& map) const -{ - - if (!myHasInverse) - return; +/////////////////////////////////////////////////////////////////////////////// +///@param elem The element to delete +///@param removenodes if true remaining nodes will be removed +/////////////////////////////////////////////////////////////////////////////// +void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, + const bool removenodes) +{ + std::vector removedElems; + std::vector removedNodes; + RemoveElement( elem, removedElems, removedNodes, removenodes ); +} + +/////////////////////////////////////////////////////////////////////////////// +///@param elem The element to delete +///@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, + std::vector& removedElems, + std::vector& removedNodes, + bool removenodes) +{ + // get finite elements built on elem + 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 std::set (); + s1->insert(elem); + } + else + s1 = getFinitElements(elem); + + // get exclusive nodes (which would become free afterwards) + std::set * s2; + if (elem->GetType() == SMDSAbs_Node) // a node is removed + { + // do not remove nodes except elem + s2 = new std::set (); + s2->insert(elem); + removenodes = true; + } + else + s2 = getExclusiveNodes(*s1); + + // form the set of finite and construction elements to remove + std::set s3; + std::set::iterator it = s1->begin(); + while (it != s1->end()) + { + addChildrenWithNodes(s3, *it, *s2); + s3.insert(*it); + it++; + } + if (elem->GetType() != SMDSAbs_Node) + s3.insert(elem); + + // remove finite and construction elements + for( it = s3.begin();it != s3.end(); ++it ) + { + // Remove element from of its nodes + SMDS_NodeIteratorPtr itn = (*it)->nodeIterator(); + while (itn->more()) + { + SMDS_MeshNode * n = const_cast (itn->next()); + n->RemoveInverseElement((*it)); + } - Standard_Integer nbcnx = ME->NbNodes(); + int vtkid = (*it)->GetVtkID(); + + switch ((*it)->GetType()) { + case SMDSAbs_Node: + 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; + } - for (Standard_Integer i=1; i <= nbcnx; ++i) { - const SMDS_ListOfMeshElement& lstInvElements = GetNode(i,ME)->InverseElements(); + myCellFactory->Free( static_cast< const SMDS_MeshCell*>( *it )); - SMDS_ListIteratorOfListOfMeshElement it(lstInvElements); - for (;it.More();it.Next()) { - const Handle(SMDS_MeshElement)& meParent = it.Value(); - if (Contains(meParent)) - map.Add(meParent); + if (vtkid >= 0) + { + this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL); } + } + // remove exclusive (free) nodes + if (removenodes) + { + for ( it = s2->begin(); it != s2->end(); ++it ) + { + myInfo.myNbNodes--; + myNodeFactory->Free( (*it) ); + removedNodes.push_back((*it)); + } } + delete s2; + delete s1; } -//======================================================================= -//function : BuildMapEdgeAncestors -//purpose : -//======================================================================= - -void SMDS_Mesh::BuildMapEdgeAncestors(const Handle(SMDS_MeshElement)& ME, - SMDS_MapOfMeshOrientedElement& map) const +/////////////////////////////////////////////////////////////////////////////// +///@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 ) + { + // only free node can be removed by this method + const SMDS_MeshNode* n = static_cast( elem ); + if ( n->NbInverseElements() == 0 ) { // free node + myInfo.myNbNodes--; + myNodeFactory->Free( n ); + } + else + { + throw SALOME_Exception( LOCALIZED( "RemoveFreeElement: not a free node" )); + } + } + else + { + // Remove element from of its nodes + SMDS_NodeIteratorPtr itn = elem->nodeIterator(); + while (itn->more()) { + SMDS_MeshNode * n = const_cast(itn->next()); + n->RemoveInverseElement(elem); + } - if (!myHasInverse) - return; - - Standard_Integer nbcnx = ME->NbNodes(); - - for (Standard_Integer i=1; i <= nbcnx; ++i) { - const SMDS_ListOfMeshElement& lstInvElements = GetNode(i,ME)->InverseElements(); - - SMDS_ListIteratorOfListOfMeshElement it(lstInvElements); - for (;it.More();it.Next()) { - const Handle(SMDS_MeshElement)& meParent = it.Value(); - if ( !meParent->IsKind(STANDARD_TYPE(SMDS_MeshEdge)) && Contains(meParent)) - map.Add(meParent); + // in meshes without descendants elements are always free + switch (aType) { + 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; } + myCellFactory->Free( elem ); + this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL); } - } - //======================================================================= -//function : BuildMapFaceAncestors -//purpose : +/*! + * Checks if the element is present in mesh. + */ //======================================================================= -void SMDS_Mesh::BuildMapFaceAncestors(const Handle(SMDS_MeshElement)& ME, - SMDS_MapOfMeshOrientedElement& map) const +bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const { + if ( !elem || elem->IsNull() ) + return false; - if (!myHasInverse) - return; - - Standard_Integer nbcnx = ME->NbNodes(); - - for (Standard_Integer i=1; i <= nbcnx; ++i) { - const SMDS_ListOfMeshElement& lstInvElements = GetNode(i,ME)->InverseElements(); - - SMDS_ListIteratorOfListOfMeshElement it(lstInvElements); - for (;it.More();it.Next()) { - const Handle(SMDS_MeshElement)& meParent = it.Value(); - if ( !meParent->IsKind(STANDARD_TYPE(SMDS_MeshEdge)) - && ( !meParent->IsKind(STANDARD_TYPE(SMDS_MeshFace))) && Contains(meParent) ) - map.Add(meParent); - } - - } + if ( elem->GetType() == SMDSAbs_Node ) + return ( elem == myNodeFactory->FindElement( elem->GetID() )); + return ( elem == myCellFactory->FindElement( elem->GetID() )); } - //======================================================================= -//function : FindEdge -//purpose : +//function : MaxNodeID +//purpose : //======================================================================= -Handle(SMDS_MeshElement) SMDS_Mesh::FindEdge(const Standard_Integer idnode1, - const Standard_Integer idnode2 ) const +int SMDS_Mesh::MaxNodeID() const { - Handle(SMDS_MeshEdge) edge = new SMDS_MeshEdge(0,idnode1,idnode2); - return FindEdge(edge); + return myNodeFactory->GetMaxID(); } //======================================================================= -//function : FindFace -//purpose : +//function : MinNodeID +//purpose : //======================================================================= -Handle(SMDS_MeshElement) SMDS_Mesh::FindFace(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3 ) const +int SMDS_Mesh::MinNodeID() const { - Handle(SMDS_MeshFace) face = new SMDS_MeshTriangle(0,idnode1,idnode2,idnode3); - return FindFace(face); + return myNodeFactory->GetMinID(); } //======================================================================= -//function : FindFace -//purpose : +//function : MaxElementID +//purpose : //======================================================================= -Handle(SMDS_MeshElement) SMDS_Mesh::FindFace(const Standard_Integer idnode1, - const Standard_Integer idnode2, - const Standard_Integer idnode3, - const Standard_Integer idnode4 ) const +int SMDS_Mesh::MaxElementID() const { - Handle(SMDS_MeshFace) face = new SMDS_MeshQuadrangle(0,idnode1,idnode2,idnode3,idnode4); - return FindFace(face); + return myCellFactory->GetMaxID(); } //======================================================================= -//function : FindElement -//purpose : +//function : MinElementID +//purpose : //======================================================================= -Handle(SMDS_MeshElement) SMDS_Mesh::FindElement(const Standard_Integer IDelem) const +int SMDS_Mesh::MinElementID() const { - return myElementIDFactory->MeshElement(IDelem); + return myCellFactory->GetMinID(); } //======================================================================= -//function : GetNode -//purpose : +//function : Renumber +//purpose : Renumber all nodes or elements. //======================================================================= -Handle(SMDS_MeshNode) SMDS_Mesh::GetNode(const Standard_Integer rank, - const Handle(SMDS_MeshElement)& ME) const - -{ - const Standard_Integer idnode = ME->GetConnection(rank); // take care, no control of bounds - - Handle(SMDS_MeshElement) elem = FindNode(idnode); - Handle(SMDS_MeshNode)& node = *((Handle(SMDS_MeshNode)*)&elem); - return node; - -} +// void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID) +// { +// if ( deltaID == 0 ) +// return; +// } //======================================================================= -//function : DumpNodes -//purpose : +//function : GetElementType +//purpose : Return type of element or node with id //======================================================================= -void SMDS_Mesh::DumpNodes() const +SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const { - MESSAGE( "dump nodes of mesh : " ); - - SMDS_MapIteratorOfExtendedOrientedMap itnode(myNodes); - - for (;itnode.More();itnode.Next()) { - const Handle(SMDS_MeshElement)& node = itnode.Key(); - MESSAGE( node); - - } + const SMDS_MeshElement* elem = 0; + if( iselem ) + elem = myCellFactory->FindElement( id ); + else + elem = myNodeFactory->FindElement( id ); + return elem ? elem->GetType() : SMDSAbs_All; } +//******************************************************************** +//******************************************************************** +//******** ********* +//***** Methods for addition of quadratic elements ****** +//******** ********* +//******************************************************************** +//******************************************************************** + //======================================================================= -//function : DumpEdges -//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); +} -void SMDS_Mesh::DumpEdges() const +//======================================================================= +//function : AddEdge +//purpose : +//======================================================================= +SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n12) { - MESSAGE( "dump edges of mesh : " ); + return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myCellFactory->GetFreeID()); +} - SMDS_MapIteratorOfExtendedOrientedMap itedge(myEdges); +//======================================================================= +//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; - for (;itedge.More();itedge.Next()) { - const Handle(SMDS_MeshElement)& edge = itedge.Key(); - MESSAGE( edge); + 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 : DumpFaces -//purpose : +//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()); +} -void SMDS_Mesh::DumpFaces() const +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, + int n12,int n23,int n31, int ID) { - MESSAGE( "dump faces of mesh : " ); + return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) , + myNodeFactory->FindNode(n2) , + myNodeFactory->FindNode(n3) , + myNodeFactory->FindNode(n12), + myNodeFactory->FindNode(n23), + myNodeFactory->FindNode(n31), + ID); +} - SMDS_MapIteratorOfExtendedOrientedMap itface(myFaces); +//======================================================================= +//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(); - for (;itface.More();itface.Next()) { - const Handle(SMDS_MeshElement)& face = itface.Key(); - MESSAGE( face); + 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 : DumpVolumes -//purpose : +//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, + const SMDS_MeshNode * nCenter) +{ + return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,nCenter, + myCellFactory->GetFreeID()); +} -void SMDS_Mesh::DumpVolumes() const +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, + int n12,int n23,int n31, int nCenter, int ID) { - MESSAGE( "dump volumes of mesh : " ); + 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); +} - SMDS_MapIteratorOfExtendedOrientedMap itvol(myVolumes); +//======================================================================= +//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, + const SMDS_MeshNode * nCenter, + int ID) +{ + if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 || !nCenter) return 0; + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - for (;itvol.More();itvol.Next()) { - const Handle(SMDS_MeshElement)& volume = itvol.Key(); - MESSAGE( volume); + 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 : DebugStats -//purpose : +//function : AddFace +//purpose : //======================================================================= - -void SMDS_Mesh::DebugStats() const +SMDS_MeshFace* SMDS_Mesh::AddFace(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 * n34, + const SMDS_MeshNode * n41) { - //VRV: T2.4 impossible to use Logger server - MESSAGE( "Debug stats of mesh : " ); - - MESSAGE( "===== NODES =====" ); - myNodes.Statistics(cout); - - MESSAGE( "===== EDGES =====" ); - myEdges.Statistics(cout); - - MESSAGE( "===== FACES =====" ); - myFaces.Statistics(cout); + return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41, + myCellFactory->GetFreeID()); +} - MESSAGE( "===== VOLUMES =====" ); - myVolumes.Statistics(cout); - //VRV: T2.4 impossible to use Logger server +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int 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); +} - MESSAGE( "End Debug stats of mesh " ); +//======================================================================= +//function : AddFaceWithID +//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 * n34, + const SMDS_MeshNode * n41, + int ID) +{ + if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0; + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - //#ifdef DEB - SMDS_MapIteratorOfExtendedOrientedMap itnode(myNodes); - Standard_Integer sizeofnodes = 0; - Standard_Integer sizeoffaces = 0; + 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 0; +} +//======================================================================= +//function : AddFace +//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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * nCenter) +{ + return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter, + myCellFactory->GetFreeID()); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int nCenter, int 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 : +//======================================================================= +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 * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * nCenter, + int ID) +{ + if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0; + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + + 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 0; +} - for (;itnode.More();itnode.Next()) { - const Handle(SMDS_MeshElement)& node = itnode.Key(); - - Standard_Transient *p = node->This(); - sizeofnodes += sizeof( *((SMDS_MeshNode *)p) ); - SMDS_ListIteratorOfListOfMeshElement it(node->InverseElements()); - for (;it.More();it.Next()) { - const Handle(SMDS_MeshElement)& me = it.Value(); - sizeofnodes += sizeof(me); - } - +//======================================================================= +//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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34) +{ + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23, + n31, n14, n24, n34, myCellFactory->GetFreeID()); +} + +//======================================================================= +//function : AddVolumeWithID +//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) +{ + 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 +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(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 * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34, + int ID) +{ + if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34) + return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + + 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 0; +} - SMDS_MapIteratorOfExtendedOrientedMap itface(myFaces); - for (;itface.More();itface.Next()) { - const Handle(SMDS_MeshElement)& face = itface.Key(); - - Standard_Transient *p = face->This(); - sizeoffaces += sizeof( *((SMDS_MeshFace *)p) ); - +//======================================================================= +//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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45) +{ + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41, + n15, n25, n35, n45, myCellFactory->GetFreeID()); +} + +//======================================================================= +//function : AddVolumeWithID +//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) +{ + 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 +//======================================================================= +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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45, + int ID) +{ + if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 || + !n34 || !n41 || !n15 || !n25 || !n35 || !n45) + return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + + 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 ); } - MESSAGE( "total size of node elements = " << sizeofnodes );; - MESSAGE( "total size of face elements = " << sizeoffaces );; + return 0; +} - //#endif +//======================================================================= +//function : AddVolume +//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 * 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) +{ + return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31, + n45, n56, n64, n14, n25, n36, myCellFactory->GetFreeID()); +} + +//======================================================================= +//function : AddVolumeWithID +//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, + int n12,int n23,int n31, + int n45,int n56,int n64, + int n14,int n25,int n36, 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), + ID); +} + +//======================================================================= +//function : AddVolumeWithID +//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 * 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, + int ID) +{ + 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 ); + } + return 0; } //======================================================================= -//function : RebuildAllInverseConnections -//purpose : -//======================================================================= - -void SMDS_Mesh::RebuildAllInverseConnections() -{ - if (!myParent.IsNull()) - myParent->RebuildAllInverseConnections(); - - else { - // Clear all inverseconnections from nodes - SMDS_MapIteratorOfExtendedOrientedMap itnode(myNodes); - - for (;itnode.More();itnode.Next()) { - const Handle(SMDS_MeshElement)& elem = itnode.Key(); - elem->ClearInverseElements(); - } - - - RebuildInverseConnections(); +//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 ( 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 0; +} - SMDS_ListIteratorOfListOfMesh itmsh(myChildren); - for (;itmsh.More(); itmsh.Next()) { - Handle(SMDS_Mesh) submesh; - submesh = itmsh.Value(); - - submesh->RebuildInverseConnections(); - } +//======================================================================= +//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) +{ + 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 : +//======================================================================= +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 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 +//======================================================================= +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 * 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 : RebuildInverseConnections -//purpose : -//======================================================================= - -void SMDS_Mesh::RebuildInverseConnections() -{ - // rebuld inverse connections to volumes - SMDS_MapIteratorOfExtendedOrientedMap itvol(myVolumes); - - for (;itvol.More();itvol.Next()) { - const Handle(SMDS_MeshElement)& vol = itvol.Key(); - - Standard_Integer nbcnx = vol->NbNodes(); - for (Standard_Integer inode=1; inode<=nbcnx; ++inode) { - Standard_Integer idnode = vol->GetConnection(inode); - Handle(SMDS_MeshElement) node = FindNode(idnode); - if (!node.IsNull()) - node->AddInverseElement(vol); +//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 * 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, + int ID) +{ + 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; - Standard_Integer nbcnx = face->NbNodes(); - for (Standard_Integer inode=1; inode<=nbcnx; ++inode) { - Standard_Integer idnode = face->GetConnection(inode); - Handle(SMDS_MeshElement) node = FindNode(idnode); - if (!node.IsNull()) - node->AddInverseElement(face); + bool idsChange = ( myNodeFactory->CompactChangePointers() || + myCellFactory->CompactChangePointers() ); + 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; } - } - // rebuld inverse connections to edges - SMDS_MapIteratorOfExtendedOrientedMap itedge(myEdges); + std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin(); + for ( ; holder != myElemHolders.end(); ++holder ) + if ( idsChange ) + (*holder)->restoreElements( idNodesOldToNew, idCellsOldToNew ); + else + (*holder)->compact(); - for (;itedge.More();itedge.Next()) { - const Handle(SMDS_MeshElement)& edge = itedge.Key(); + return; +} - Standard_Integer nbcnx = edge->NbNodes(); - for (Standard_Integer inode=1; inode<=nbcnx; ++inode) { - Standard_Integer idnode = edge->GetConnection(inode); - Handle(SMDS_MeshElement) node = FindNode(idnode); - if (!node.IsNull()) - node->AddInverseElement(edge); - } - - } +int SMDS_Mesh::FromVtkToSmds( int vtkid ) const +{ + return myCellFactory->FromVtkToSmds( vtkid ); +} - myHasInverse = Standard_True; +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) + { + this->myModifTime++; + myModified = false; + } +} -//======================================================================= -//function : SubMeshIterator -//purpose : returns the ith SubMesh -//======================================================================= +//! get last modification timeStamp +vtkMTimeType SMDS_Mesh::GetMTime() const +{ + return this->myModifTime; +} -void SMDS_Mesh::SubMeshIterator(SMDS_ListIteratorOfListOfMesh& itmsh) const +bool SMDS_Mesh::IsCompacted() { - itmsh.Initialize(myChildren); + return ( this->myCompactTime == this->myModifTime ); } +void SMDS_Mesh::setNbShapes( size_t nbShapes ) +{ + myNodeFactory->SetNbShapes( nbShapes ); +}