-// 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
// 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"
#include "DriverMED_R_SMESHDS_Mesh.h"
#include "DriverUNV_R_SMDS_Mesh.h"
#include "DriverSTL_R_SMDS_Mesh.h"
+#ifdef WITH_CGNS
+#include "DriverCGNS_Read.hxx"
+#include "DriverCGNS_Write.hxx"
+#endif
#undef _Precision_HeaderFile
#include <BRepBndLib.hxx>
#include "Utils_ExceptHandlers.hxx"
+#include <boost/thread/thread.hpp>
+#include <boost/bind.hpp>
+
using namespace std;
// maximum stored group name length in MED file
_isAutoColor = false;
_isModified = false;
_shapeDiagonal = 0.0;
- _rmGroupCallUp = 0;
+ _callUp = 0;
_myMeshDS->ShapeToMesh( PseudoShape() );
}
//================================================================================
SMESH_Mesh::SMESH_Mesh():
- _groupId( 0 ), _nbSubShapes( 0 )
+ _id(-1),
+ _studyId(-1),
+ _idDoc(-1),
+ _groupId( 0 ),
+ _nbSubShapes( 0 ),
+ _isShapeToMesh( false ),
+ _myDocument( 0 ),
+ _myMeshDS( 0 ),
+ _gen( 0 ),
+ _isAutoColor( false ),
+ _isModified( false ),
+ _shapeDiagonal( 0.0 ),
+ _callUp( 0 )
{
- _myMeshDS = 0;
- _isShapeToMesh = false;
- _isAutoColor = false;
- _isModified = false;
- _shapeDiagonal = 0.0;
- _rmGroupCallUp = 0;
+}
+
+namespace
+{
+ void deleteMeshDS(SMESHDS_Mesh* meshDS)
+ {
+ //cout << "deleteMeshDS( " << meshDS << endl;
+ delete meshDS;
+ }
}
//=============================================================================
}
_mapGroup.clear();
- if ( _rmGroupCallUp) delete _rmGroupCallUp;
- _rmGroupCallUp = 0;
+ // delete sub-meshes
+ map <int, SMESH_subMesh*>::iterator sm = _mapSubMesh.begin();
+ for ( ; sm != _mapSubMesh.end(); ++sm )
+ {
+ delete sm->second;
+ sm->second = 0;
+ }
+ _mapSubMesh.clear();
+
+ if ( _callUp) delete _callUp;
+ _callUp = 0;
+
+ // remove self from studyContext
+ if ( _gen )
+ {
+ StudyContextStruct * studyContext = _gen->GetStudyContext( _studyId );
+ studyContext->mapMesh.erase( _id );
+ }
+ 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;
}
//=============================================================================
return _shapeDiagonal;
}
+//================================================================================
+/*!
+ * \brief Load mesh from study file
+ */
+//================================================================================
+
+void SMESH_Mesh::Load()
+{
+ if (_callUp)
+ _callUp->Load();
+}
+
//=======================================================================
/*!
* \brief Remove all nodes and elements
return 1;
}
+//================================================================================
+/*!
+ * \brief Reads the given mesh from the CGNS file
+ * \param theFileName - name of the file
+ * \retval int - Driver_Mesh::Status
+ */
+//================================================================================
+
+int SMESH_Mesh::CGNSToMesh(const char* theFileName,
+ const int theMeshIndex,
+ std::string& theMeshName)
+{
+ int res = Driver_Mesh::DRS_FAIL;
+#ifdef WITH_CGNS
+
+ DriverCGNS_Read myReader;
+ myReader.SetMesh(_myMeshDS);
+ myReader.SetFile(theFileName);
+ myReader.SetMeshId(theMeshIndex);
+ res = myReader.Perform();
+ theMeshName = myReader.GetMeshName();
+
+ // create groups
+ SynchronizeGroups();
+
+#endif
+ return res;
+}
+
//=============================================================================
/*!
*
SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
- // subShapes
+ // sub-shapes
if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is added on father
{
subMesh->CheckConcurentHypothesis( anHyp->GetType() ) != SMESH_Hypothesis::HYP_OK)
ret = SMESH_Hypothesis::HYP_CONCURENT;
- // subShapes
+ // sub-shapes
if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is removed from father
{
{
aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
_mapSubMesh[index] = aSubMesh;
- ClearMeshOrder();
}
return aSubMesh;
}
}
//================================================================================
/*!
- * \brief Return submeshes of groups containing the given subshape
+ * \brief Return submeshes of groups containing the given sub-shape
*/
//================================================================================
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;
}
//=======================================================================
{
Unexpect aCatch(SalomeException);
+ if ( !GetMeshDS()->IsUsedHypothesis( hyp ))
+ return;
+
+ if (_callUp)
+ _callUp->HypothesisModified();
+
const SMESH_Algo *foundAlgo = 0;
SMESH_HypoFilter algoKind, compatibleHypoKind;
list <const SMESHDS_Hypothesis * > usedHyps;
return true;
}
- if ( !hasComputed )
+ if ( NbNodes() < 1 )
const_cast<SMESH_Mesh*>(this)->_isModified = false;
return false;
myWriter.Perform();
}
+void SMESH_Mesh::ExportSAUV(const char *file,
+ const char* theMeshName,
+ bool theAutoGroups)
+ throw(SALOME_Exception)
+{
+ std::string medfilename(file);
+ medfilename += ".med";
+ std::string cmd;
+#ifdef WNT
+ cmd = "%PYTHONBIN% ";
+#else
+ cmd = "python ";
+#endif
+ cmd += "-c \"";
+ cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')";
+ cmd += "\"";
+ system(cmd.c_str());
+ ExportMED(medfilename.c_str(), theMeshName, theAutoGroups, 1);
+#ifdef WNT
+ cmd = "%PYTHONBIN% ";
+#else
+ cmd = "python ";
+#endif
+ cmd += "-c \"";
+ cmd += "from medutilities import convert ; convert(r'" + medfilename + "', 'MED', 'GIBI', 1, r'" + file + "')";
+ cmd += "\"";
+ system(cmd.c_str());
+#ifdef WNT
+ cmd = "%PYTHONBIN% ";
+#else
+ cmd = "python ";
+#endif
+ cmd += "-c \"";
+ cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')";
+ cmd += "\"";
+ system(cmd.c_str());
+}
+
//================================================================================
/*!
* \brief Export the mesh to a DAT file
myWriter.Perform();
}
+//================================================================================
+/*!
+ * \brief Export the mesh to the CGNS file
+ */
+//================================================================================
+
+void SMESH_Mesh::ExportCGNS(const char * file,
+ const SMESHDS_Mesh* meshDS)
+{
+ int res = Driver_Mesh::DRS_FAIL;
+#ifdef WITH_CGNS
+ DriverCGNS_Write myWriter;
+ myWriter.SetFile( file );
+ myWriter.SetMesh( const_cast<SMESHDS_Mesh*>( meshDS ));
+ myWriter.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId());
+ res = myWriter.Perform();
+#endif
+ if ( res != Driver_Mesh::DRS_OK )
+ throw SALOME_Exception("Export failed");
+}
+
//================================================================================
/*!
* \brief Return number of nodes in the mesh
return _myMeshDS->GetMeshInfo().NbQuadrangles(order);
}
+//================================================================================
+/*!
+ * \brief Return number of biquadratic quadrangles in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbBiQuadQuadrangles() const throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ return _myMeshDS->GetMeshInfo().NbBiQuadQuadrangles();
+}
+
//================================================================================
/*!
* \brief Return the number of polygonal faces in the mesh
return _myMeshDS->GetMeshInfo().NbHexas(order);
}
+//================================================================================
+/*!
+ * \brief Return number of triquadratic hexahedrons in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbTriQuadraticHexas() const throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ return _myMeshDS->GetMeshInfo().NbTriQuadHexas();
+}
+
//================================================================================
/*!
* \brief Return number of pyramids of given order in the mesh
return _myMeshDS->GetMeshInfo().NbPrisms(order);
}
+//================================================================================
+/*!
+ * \brief Return number of hexagonal prisms in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbHexagonalPrisms() const throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ return _myMeshDS->GetMeshInfo().NbHexPrisms();
+}
+
//================================================================================
/*!
* \brief Return number of polyhedrons in the mesh
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
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 <int, SMESH_Group*>::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
+ * \retval bool - true if new SMESH_Groups have been created
+ *
+ */
+//================================================================================
+
+bool SMESH_Mesh::SynchronizeGroups()
+{
+ int nbGroups = _mapGroup.size();
+ const set<SMESHDS_GroupBase*>& groups = _myMeshDS->GetGroups();
+ set<SMESHDS_GroupBase*>::const_iterator gIt = groups.begin();
+ for ( ; gIt != groups.end(); ++gIt )
+ {
+ SMESHDS_GroupBase* groupDS = (SMESHDS_GroupBase*) *gIt;
+ _groupId = groupDS->GetID();
+ if ( !_mapGroup.count( _groupId ))
+ _mapGroup[_groupId] = new SMESH_Group( groupDS );
+ }
+ if ( !_mapGroup.empty() )
+ _groupId = _mapGroup.rbegin()->first + 1;
+
+ return nbGroups < _mapGroup.size();
+}
+
//================================================================================
/*!
* \brief Return iterator on all existing groups
//================================================================================
/*!
- * \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;
}
//=============================================================================
GetMeshDS()->RemoveGroup( _mapGroup[theGroupID]->GetGroupDS() );
delete _mapGroup[theGroupID];
_mapGroup.erase (theGroupID);
- if (_rmGroupCallUp)
- _rmGroupCallUp->RemoveGroup( theGroupID );
+ if (_callUp)
+ _callUp->RemoveGroup( theGroupID );
return true;
}
while ( anItr->more() )
aNewGrpDS->Add( (anItr->next())->GetID() );
+ // set color
+ aNewGrpDS->SetColor( anOldGrpDS->GetColor() );
+
// remove old group
delete anOldGrp;
(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() );
+ }
}
//=============================================================================
typedef list<SMESH_subMesh*>::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 )) {
list<SMESH_subMesh*>::iterator onlyBIt = onlyOrderedList.begin();
list<SMESH_subMesh*>::iterator onlyEIt = onlyOrderedList.end();
- // iterates on ordered submeshes and insert them in detected positions
+ // iterate on ordered submeshes and insert them in detected positions
map< int, TPosInList >::iterator i_pos = sortedPos.begin();
for ( ; onlyBIt != onlyEIt; ++onlyBIt, ++i_pos )
*(i_pos->second) = *onlyBIt;
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
*/
//=============================================================================
-list<SMESH_subMesh*> SMESH_Mesh::getAncestorsSubMeshes
- (const TopoDS_Shape& theSubShape) const
+list<SMESH_subMesh*>
+SMESH_Mesh::getAncestorsSubMeshes (const TopoDS_Shape& theSubShape) const
{
list<SMESH_subMesh*> listOfSubMesh;
TopTools_ListIteratorOfListOfShape it( GetAncestors( theSubShape ));