X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FSMESH%2FSMESH_Mesh.cxx;h=ecc9e60613231240439cde53590f232ade7213e5;hb=20c126bc220757c06b5576f71ed6f34ae85e3e40;hp=9416618c5c433325ec980dc4d6b39a5bdc6bd2df;hpb=fe663d61f64f1e7116438902e18e8779240967e3;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 9416618c5..ecc9e6061 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -20,12 +20,12 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_Mesh.cxx // Author : Paul RASCLE, EDF // Module : SMESH // #include "SMESH_Mesh.hxx" +#include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_Gen.hxx" #include "SMESH_Hypothesis.hxx" @@ -40,14 +40,15 @@ #include "utilities.h" -#include "DriverMED_W_SMESHDS_Mesh.h" #include "DriverDAT_W_SMDS_Mesh.h" -#include "DriverUNV_W_SMDS_Mesh.h" -#include "DriverSTL_W_SMDS_Mesh.h" - +#include "DriverGMF_Read.hxx" +#include "DriverGMF_Write.hxx" #include "DriverMED_R_SMESHDS_Mesh.h" -#include "DriverUNV_R_SMDS_Mesh.h" +#include "DriverMED_W_SMESHDS_Mesh.h" #include "DriverSTL_R_SMDS_Mesh.h" +#include "DriverSTL_W_SMDS_Mesh.h" +#include "DriverUNV_R_SMDS_Mesh.h" +#include "DriverUNV_W_SMDS_Mesh.h" #ifdef WITH_CGNS #include "DriverCGNS_Read.hxx" #include "DriverCGNS_Write.hxx" @@ -102,13 +103,12 @@ SMESH_Mesh::SMESH_Mesh(int theLocalId, _studyId = theStudyId; _gen = theGen; _myDocument = theDocument; - _idDoc = theDocument->NewMesh(theIsEmbeddedMode); - _myMeshDS = theDocument->GetMesh(_idDoc); + _myMeshDS = theDocument->NewMesh(theIsEmbeddedMode,theLocalId); _isShapeToMesh = false; _isAutoColor = false; _isModified = false; _shapeDiagonal = 0.0; - _rmGroupCallUp = 0; + _callUp = NULL; _myMeshDS->ShapeToMesh( PseudoShape() ); } @@ -121,7 +121,6 @@ SMESH_Mesh::SMESH_Mesh(int theLocalId, SMESH_Mesh::SMESH_Mesh(): _id(-1), _studyId(-1), - _idDoc(-1), _groupId( 0 ), _nbSubShapes( 0 ), _isShapeToMesh( false ), @@ -131,7 +130,7 @@ SMESH_Mesh::SMESH_Mesh(): _isAutoColor( false ), _isModified( false ), _shapeDiagonal( 0.0 ), - _rmGroupCallUp( 0 ) + _callUp( 0 ) { } @@ -170,11 +169,14 @@ SMESH_Mesh::~SMESH_Mesh() // delete sub-meshes map ::iterator sm = _mapSubMesh.begin(); for ( ; sm != _mapSubMesh.end(); ++sm ) + { delete sm->second; + sm->second = 0; + } _mapSubMesh.clear(); - if ( _rmGroupCallUp) delete _rmGroupCallUp; - _rmGroupCallUp = 0; + if ( _callUp) delete _callUp; + _callUp = 0; // remove self from studyContext if ( _gen ) @@ -184,12 +186,24 @@ SMESH_Mesh::~SMESH_Mesh() } if ( _myDocument ) _myDocument->RemoveMesh( _id ); + _myDocument = 0; if ( _myMeshDS ) // delete _myMeshDS, in a thread in order not to block closing a study with large meshes boost::thread aThread(boost::bind( & deleteMeshDS, _myMeshDS )); } +//================================================================================ +/*! + * \brief Return true if a mesh with given id exists + */ +//================================================================================ + +bool SMESH_Mesh::MeshExists( int meshId ) const +{ + return _myDocument ? _myDocument->GetMesh( meshId ) : false; +} + //============================================================================= /*! * \brief Set geometry to be meshed @@ -311,6 +325,18 @@ double SMESH_Mesh::GetShapeDiagonalSize() const return _shapeDiagonal; } +//================================================================================ +/*! + * \brief Load mesh from study file + */ +//================================================================================ + +void SMESH_Mesh::Load() +{ + if (_callUp) + _callUp->Load(); +} + //======================================================================= /*! * \brief Remove all nodes and elements @@ -319,16 +345,32 @@ double SMESH_Mesh::GetShapeDiagonalSize() const void SMESH_Mesh::Clear() { - // clear mesh data - _myMeshDS->ClearMesh(); + if ( HasShapeToMesh() ) // remove all nodes and elements + { + // clear mesh data + _myMeshDS->ClearMesh(); - // update compute state of submeshes - if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) ) + // update compute state of submeshes + if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) ) + { + sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); + sm->ComputeSubMeshStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); + sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); // for event listeners (issue 0020918) + sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN ); + } + } + else // remove only nodes/elements computed by algorithms { - sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); - sm->ComputeSubMeshStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); - sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); // for event listeners (issue 0020918) - sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN ); + if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) ) + { + SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true, + /*complexShapeFirst=*/true); + while ( smIt->more() ) + { + sm = smIt->next(); + sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); + } + } } _isModified = false; } @@ -511,6 +553,28 @@ int SMESH_Mesh::CGNSToMesh(const char* theFileName, return res; } +//================================================================================ +/*! + * \brief Fill its data by reading a GMF file + */ +//================================================================================ + +SMESH_ComputeErrorPtr SMESH_Mesh::GMFToMesh(const char* theFileName, + bool theMakeRequiredGroups) +{ + DriverGMF_Read myReader; + myReader.SetMesh(_myMeshDS); + myReader.SetFile(theFileName); + myReader.SetMakeRequiredGroups( theMakeRequiredGroups ); + myReader.Perform(); + //theMeshName = myReader.GetMeshName(); + + // create groups + SynchronizeGroups(); + + return myReader.GetError(); +} + //============================================================================= /*! * @@ -594,8 +658,6 @@ SMESH_Hypothesis::Hypothesis_Status } HasModificationsToDiscard(); // to reset _isModified flag if a mesh becomes empty - GetMeshDS()->Modified(); - if(MYDEBUG) subMesh->DumpAlgoState(true); if(MYDEBUG) SCRUTE(ret); return ret; @@ -669,8 +731,6 @@ SMESH_Hypothesis::Hypothesis_Status HasModificationsToDiscard(); // to reset _isModified flag if mesh become empty - GetMeshDS()->Modified(); - if(MYDEBUG) subMesh->DumpAlgoState(true); if(MYDEBUG) SCRUTE(ret); return ret; @@ -876,7 +936,6 @@ SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) { aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape); _mapSubMesh[index] = aSubMesh; - ClearMeshOrder(); } return aSubMesh; } @@ -941,17 +1000,27 @@ SMESH_Mesh::GetGroupSubMeshesContaining(const TopoDS_Shape & aSubShape) const for ( i_sm = _mapSubMesh.rbegin(); i_sm != _mapSubMesh.rend(); ++i_sm) { SMESHDS_SubMesh * ds = i_sm->second->GetSubMeshDS(); if ( ds && ds->IsComplexSubmesh() ) { - TopExp_Explorer exp( i_sm->second->GetSubShape(), aSubShape.ShapeType() ); - for ( ; exp.More(); exp.Next() ) { - if ( aSubShape.IsSame( exp.Current() )) { - found.push_back( i_sm->second ); - break; - } + if ( SMESH_MesherHelper::IsSubShape( aSubShape, i_sm->second->GetSubShape() )) + { + found.push_back( i_sm->second ); + //break; } } else { - break; + break; // the rest sub-meshes are not those of groups } } + + if ( found.empty() ) // maybe the main shape is a COMPOUND (issue 0021530) + { + if ( SMESH_subMesh * mainSM = GetSubMeshContaining(1)) + if ( mainSM->GetSubShape().ShapeType() == TopAbs_COMPOUND ) + { + TopoDS_Iterator it( mainSM->GetSubShape() ); + if ( it.Value().ShapeType() == aSubShape.ShapeType() && + SMESH_MesherHelper::IsSubShape( aSubShape, mainSM->GetSubShape() )) + found.push_back( mainSM ); + } + } return found; } //======================================================================= @@ -1028,6 +1097,9 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h if ( !GetMeshDS()->IsUsedHypothesis( hyp )) return; + if (_callUp) + _callUp->HypothesisModified(); + const SMESH_Algo *foundAlgo = 0; SMESH_HypoFilter algoKind, compatibleHypoKind; list usedHyps; @@ -1184,7 +1256,7 @@ void SMESH_Mesh::ExportMED(const char * file, myWriter.SetFile ( file, MED::EVersion(theVersion) ); myWriter.SetMesh ( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS ); if ( !theMeshName ) - myWriter.SetMeshId ( _idDoc ); + myWriter.SetMeshId ( _id ); else { myWriter.SetMeshId ( -1 ); myWriter.SetMeshName( theMeshName ); @@ -1277,7 +1349,7 @@ void SMESH_Mesh::ExportDAT(const char * file, DriverDAT_W_SMDS_Mesh myWriter; myWriter.SetFile( file ); myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS ); - myWriter.SetMeshId(_idDoc); + myWriter.SetMeshId(_id); myWriter.Perform(); } @@ -1294,7 +1366,7 @@ void SMESH_Mesh::ExportUNV(const char * file, DriverUNV_W_SMDS_Mesh myWriter; myWriter.SetFile( file ); myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS ); - myWriter.SetMeshId(_idDoc); + myWriter.SetMeshId(_id); // myWriter.SetGroups(_mapGroup); if ( !meshPart ) @@ -1327,7 +1399,7 @@ void SMESH_Mesh::ExportSTL(const char * file, myWriter.SetFile( file ); myWriter.SetIsAscii( isascii ); myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS); - myWriter.SetMeshId(_idDoc); + myWriter.SetMeshId(_id); myWriter.Perform(); } @@ -1352,6 +1424,24 @@ void SMESH_Mesh::ExportCGNS(const char * file, throw SALOME_Exception("Export failed"); } +//================================================================================ +/*! + * \brief Export the mesh to a GMF file + */ +//================================================================================ + +void SMESH_Mesh::ExportGMF(const char * file, + const SMESHDS_Mesh* meshDS, + bool withRequiredGroups) +{ + DriverGMF_Write myWriter; + myWriter.SetFile( file ); + myWriter.SetMesh( const_cast( meshDS )); + myWriter.SetExportRequiredGroups( withRequiredGroups ); + + myWriter.Perform(); +} + //================================================================================ /*! * \brief Return number of nodes in the mesh @@ -1544,6 +1634,18 @@ int SMESH_Mesh::NbPolyhedrons() const throw(SALOME_Exception) return _myMeshDS->GetMeshInfo().NbPolyhedrons(); } +//================================================================================ +/*! + * \brief Return number of ball elements in the mesh + */ +//================================================================================ + +int SMESH_Mesh::NbBalls() const throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + return _myMeshDS->GetMeshInfo().NbBalls(); +} + //================================================================================ /*! * \brief Return number of submeshes in the mesh @@ -1600,6 +1702,35 @@ SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType, return aGroup; } +//================================================================================ +/*! + * \brief Creates a group based on an existing SMESHDS group. Group ID should be unique + */ +//================================================================================ + +SMESH_Group* SMESH_Mesh::AddGroup (SMESHDS_GroupBase* groupDS) throw(SALOME_Exception) +{ + if ( !groupDS ) + throw SALOME_Exception(LOCALIZED ("SMESH_Mesh::AddGroup(): NULL SMESHDS_GroupBase")); + + map ::iterator i_g = _mapGroup.find( groupDS->GetID() ); + if ( i_g != _mapGroup.end() && i_g->second ) + { + if ( i_g->second->GetGroupDS() == groupDS ) + return i_g->second; + else + throw SALOME_Exception(LOCALIZED ("SMESH_Mesh::AddGroup() wrong ID of SMESHDS_GroupBase")); + } + SMESH_Group* aGroup = new SMESH_Group (groupDS); + _mapGroup[ groupDS->GetID() ] = aGroup; + GetMeshDS()->AddGroup( aGroup->GetGroupDS() ); + + _groupId = 1 + _mapGroup.rbegin()->first; + + return aGroup; +} + + //================================================================================ /*! * \brief Creates SMESH_Groups for not wrapped SMESHDS_Groups @@ -1669,15 +1800,15 @@ list SMESH_Mesh::GetGroupIds() const //================================================================================ /*! - * \brief Set a caller of RemoveGroup() at level of CORBA API implementation. + * \brief Set a caller of methods at level of CORBA API implementation. * The set upCaller will be deleted by SMESH_Mesh */ //================================================================================ -void SMESH_Mesh::SetRemoveGroupCallUp( TRmGroupCallUp* upCaller ) +void SMESH_Mesh::SetCallUp( TCallUp* upCaller ) { - if ( _rmGroupCallUp ) delete _rmGroupCallUp; - _rmGroupCallUp = upCaller; + if ( _callUp ) delete _callUp; + _callUp = upCaller; } //============================================================================= @@ -1693,8 +1824,8 @@ bool SMESH_Mesh::RemoveGroup (const int theGroupID) GetMeshDS()->RemoveGroup( _mapGroup[theGroupID]->GetGroupDS() ); delete _mapGroup[theGroupID]; _mapGroup.erase (theGroupID); - if (_rmGroupCallUp) - _rmGroupCallUp->RemoveGroup( theGroupID ); + if (_callUp) + _callUp->RemoveGroup( theGroupID ); return true; } @@ -1883,7 +2014,9 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape) { // a geom group is added. Insert it into lists of ancestors before // the first ancestor more complex than group members - int memberType = TopoDS_Iterator( theShape ).Value().ShapeType(); + TopoDS_Iterator subIt( theShape ); + if ( !subIt.More() ) return; + int memberType = subIt.Value().ShapeType(); for ( desType = TopAbs_VERTEX; desType >= memberType; desType-- ) for (TopExp_Explorer des( theShape, TopAbs_ShapeEnum( desType )); des.More(); des.Next()) { @@ -1904,6 +2037,13 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape) (TopAbs_ShapeEnum) ancType, _mapAncestors ); } + // visit COMPOUNDs inside a COMPOUND that are not reachable by TopExp_Explorer + if ( theShape.ShapeType() == TopAbs_COMPOUND ) + { + for ( TopoDS_Iterator sIt(theShape); sIt.More(); sIt.Next() ) + if ( sIt.Value().ShapeType() == TopAbs_COMPOUND ) + fillAncestorsMap( sIt.Value() ); + } } //============================================================================= @@ -1926,9 +2066,9 @@ bool SMESH_Mesh::SortByMeshOrder(list& theListToSort) const typedef list::iterator TPosInList; map< int, TPosInList > sortedPos; TPosInList smBeg = theListToSort.begin(), smEnd = theListToSort.end(); - TListOfListOfInt::const_iterator listIddIt = _mySubMeshOrder.begin(); - for( ; listIddIt != _mySubMeshOrder.end(); listIddIt++) { - const TListOfInt& listOfId = *listIddIt; + TListOfListOfInt::const_iterator listIdsIt = _mySubMeshOrder.begin(); + for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++) { + const TListOfInt& listOfId = *listIdsIt; TListOfInt::const_iterator idIt = listOfId.begin(); for ( ; idIt != listOfId.end(); idIt++ ) { if ( SMESH_subMesh * sm = GetSubMeshContaining( *idIt )) { @@ -1955,6 +2095,30 @@ bool SMESH_Mesh::SortByMeshOrder(list& theListToSort) const return res; } +//================================================================================ +/*! + * \brief Return true if given order of sub-meshes is OK + */ +//================================================================================ + +bool SMESH_Mesh::IsOrderOK( const SMESH_subMesh* smBefore, + const SMESH_subMesh* smAfter ) const +{ + TListOfListOfInt::const_iterator listIdsIt = _mySubMeshOrder.begin(); + TListOfInt::const_iterator idBef, idAft; + for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++) + { + const TListOfInt& listOfId = *listIdsIt; + idBef = std::find( listOfId.begin(), listOfId.end(), smBefore->GetId() ); + if ( idBef != listOfId.end() ) + idAft = std::find( listOfId.begin(), listOfId.end(), smAfter->GetId() ); + if ( idAft != listOfId.end () ) + return ( std::distance( listOfId.begin(), idBef ) < + std::distance( listOfId.begin(), idAft ) ); + } + return true; // no order imposed to given submeshes +} + //============================================================================= /*! * \brief sort submeshes according to stored mesh order @@ -1963,8 +2127,8 @@ bool SMESH_Mesh::SortByMeshOrder(list& theListToSort) const */ //============================================================================= -list SMESH_Mesh::getAncestorsSubMeshes - (const TopoDS_Shape& theSubShape) const +list +SMESH_Mesh::getAncestorsSubMeshes (const TopoDS_Shape& theSubShape) const { list listOfSubMesh; TopTools_ListIteratorOfListOfShape it( GetAncestors( theSubShape ));