-// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2013 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
#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"
#include <BRepBndLib.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <Bnd_Box.hxx>
+#include <TColStd_MapOfInteger.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopoDS_Iterator.hxx>
-#include "Utils_ExceptHandlers.hxx"
+#include "SMESH_TryCatch.hxx" // include after OCCT headers!
+#include "Utils_ExceptHandlers.hxx"
+#ifndef WIN32
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
+#else
+#include <pthread.h>
+#endif
using namespace std;
_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;
- _callUp = 0;
+ _callUp = NULL;
_myMeshDS->ShapeToMesh( PseudoShape() );
}
SMESH_Mesh::SMESH_Mesh():
_id(-1),
_studyId(-1),
- _idDoc(-1),
_groupId( 0 ),
_nbSubShapes( 0 ),
_isShapeToMesh( false ),
namespace
{
- void deleteMeshDS(SMESHDS_Mesh* meshDS)
+#ifndef WIN32
+ void deleteMeshDS(SMESHDS_Mesh* meshDS)
{
//cout << "deleteMeshDS( " << meshDS << endl;
delete meshDS;
}
+#else
+ static void* deleteMeshDS(void* meshDS)
+ {
+ //cout << "deleteMeshDS( " << meshDS << endl;
+ SMESHDS_Mesh* m = (SMESHDS_Mesh*)meshDS;
+ if(m) {
+ delete m;
+ }
+ return 0;
+ }
+#endif
}
//=============================================================================
_myDocument->RemoveMesh( _id );
_myDocument = 0;
- if ( _myMeshDS )
- // delete _myMeshDS, in a thread in order not to block closing a study with large meshes
+ if ( _myMeshDS ) {
+ // delete _myMeshDS, in a thread in order not to block closing a study with large meshes
+#ifndef WIN32
boost::thread aThread(boost::bind( & deleteMeshDS, _myMeshDS ));
+#else
+ pthread_t thread;
+ int result=pthread_create(&thread, NULL, deleteMeshDS, (void*)_myMeshDS);
+#endif
+ }
}
//================================================================================
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() ) )
+ {
+ sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
+ sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
+ sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ sm->ComputeSubMeshStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ }
}
_isModified = false;
}
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();
+}
+
//=============================================================================
/*!
*
if ( !subMesh || !subMesh->GetId())
return SMESH_Hypothesis::HYP_BAD_SUBSHAPE;
- StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
- if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
- {
- if(MYDEBUG) MESSAGE("Hypothesis ID does not give an hypothesis");
- if(MYDEBUG) {
- SCRUTE(_studyId);
- SCRUTE(anHypId);
- }
+ SMESH_Hypothesis *anHyp = GetHypothesis( anHypId );
+ if ( !anHyp )
throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
- }
-
- SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
- MESSAGE( "SMESH_Mesh::AddHypothesis " << anHyp->GetName() );
bool isGlobalHyp = IsMainShape( aSubShape );
}
HasModificationsToDiscard(); // to reset _isModified flag if a mesh becomes empty
- GetMeshDS()->Modified();
-
if(MYDEBUG) subMesh->DumpAlgoState(true);
if(MYDEBUG) SCRUTE(ret);
return ret;
SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
if(MYDEBUG) {
- int hypType = anHyp->GetType();
- SCRUTE(hypType);
+ SCRUTE(anHyp->GetType());
}
// shape
HasModificationsToDiscard(); // to reset _isModified flag if mesh become empty
- GetMeshDS()->Modified();
-
if(MYDEBUG) subMesh->DumpAlgoState(true);
if(MYDEBUG) SCRUTE(ret);
return ret;
int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape,
const SMESH_HypoFilter& aFilter,
list <const SMESHDS_Hypothesis * >& aHypList,
- const bool andAncestors) const
+ const bool andAncestors,
+ list< TopoDS_Shape > * assignedTo/*=0*/) const
{
set<string> hypTypes; // to exclude same type hypos from the result list
int nbHyps = 0;
nbHyps++;
if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
mainHypFound = true;
+ if ( assignedTo ) assignedTo->push_back( aSubShape );
}
}
nbHyps++;
if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
mainHypFound = true;
+ if ( assignedTo ) assignedTo->push_back( curSh );
}
}
}
return nbHyps;
}
+//================================================================================
+/*!
+ * \brief Return a hypothesis by its ID
+ */
+//================================================================================
+
+SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const int anHypId) const
+{
+ StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
+ if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
+ return NULL;
+
+ SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
+ return anHyp;
+}
+
//=============================================================================
/*!
*
if ( it.More() )
{
index = _myMeshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() );
- if ( index > _nbSubShapes ) _nbSubShapes = index; // not to create sm for this group again
-
// fill map of Ancestors
- fillAncestorsMap(aSubShape);
+ while ( _nbSubShapes < index )
+ fillAncestorsMap( _myMeshDS->IndexToShape( ++_nbSubShapes ));
}
}
// if ( !index )
const char* theMeshName,
bool theAutoGroups,
int theVersion,
- const SMESHDS_Mesh* meshPart)
+ const SMESHDS_Mesh* meshPart,
+ bool theAutoDimension)
throw(SALOME_Exception)
{
- Unexpect aCatch(SalomeException);
+ SMESH_TRY;
DriverMED_W_SMESHDS_Mesh myWriter;
- myWriter.SetFile ( file, MED::EVersion(theVersion) );
- myWriter.SetMesh ( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS );
+ myWriter.SetFile ( file, MED::EVersion(theVersion) );
+ myWriter.SetMesh ( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS );
+ myWriter.SetAutoDimension( theAutoDimension );
if ( !theMeshName )
- myWriter.SetMeshId ( _idDoc );
+ myWriter.SetMeshId ( _id );
else {
- myWriter.SetMeshId ( -1 );
- myWriter.SetMeshName( theMeshName );
+ myWriter.SetMeshId ( -1 );
+ myWriter.SetMeshName ( theMeshName );
}
if ( theAutoGroups ) {
}
// Perform export
myWriter.Perform();
+
+ SMESH_CATCH( SMESH::throwSalomeEx );
}
+//================================================================================
+/*!
+ * \brief Export the mesh to a SAUV file
+ */
+//================================================================================
+
void SMESH_Mesh::ExportSAUV(const char *file,
const char* theMeshName,
bool theAutoGroups)
std::string medfilename(file);
medfilename += ".med";
std::string cmd;
-#ifdef WNT
+#ifdef WIN32
cmd = "%PYTHONBIN% ";
#else
cmd = "python ";
cmd += "\"";
system(cmd.c_str());
ExportMED(medfilename.c_str(), theMeshName, theAutoGroups, 1);
-#ifdef WNT
+#ifdef WIN32
cmd = "%PYTHONBIN% ";
#else
cmd = "python ";
cmd += "from medutilities import convert ; convert(r'" + medfilename + "', 'MED', 'GIBI', 1, r'" + file + "')";
cmd += "\"";
system(cmd.c_str());
-#ifdef WNT
+#ifdef WIN32
cmd = "%PYTHONBIN% ";
#else
cmd = "python ";
DriverDAT_W_SMDS_Mesh myWriter;
myWriter.SetFile( file );
myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS );
- myWriter.SetMeshId(_idDoc);
+ myWriter.SetMeshId(_id);
myWriter.Perform();
}
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 )
myWriter.SetFile( file );
myWriter.SetIsAscii( isascii );
myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS);
- myWriter.SetMeshId(_idDoc);
+ myWriter.SetMeshId(_id);
myWriter.Perform();
}
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<SMESHDS_Mesh*>( meshDS ));
+ myWriter.SetExportRequiredGroups( withRequiredGroups );
+
+ myWriter.Perform();
+}
+
+//================================================================================
+/*!
+ * \brief Return a ratio of "compute cost" of computed sub-meshes to the whole
+ * "compute cost".
+ */
+//================================================================================
+
+double SMESH_Mesh::GetComputeProgress() const
+{
+ double totalCost = 1e-100, computedCost = 0;
+ const SMESH_subMesh* curSM = _gen->GetCurrentSubMesh();
+
+ // get progress of a current algo
+ TColStd_MapOfInteger currentSubIds;
+ if ( curSM )
+ if ( SMESH_Algo* algo = curSM->GetAlgo() )
+ {
+ int algoNotDoneCost = 0, algoDoneCost = 0;
+ const std::vector<SMESH_subMesh*>& smToCompute = algo->SubMeshesToCompute();
+ for ( size_t i = 0; i < smToCompute.size(); ++i )
+ {
+ if ( smToCompute[i]->IsEmpty() )
+ algoNotDoneCost += smToCompute[i]->GetComputeCost();
+ else
+ algoDoneCost += smToCompute[i]->GetComputeCost();
+ currentSubIds.Add( smToCompute[i]->GetId() );
+ }
+ double rate = 0;
+ try
+ {
+ OCC_CATCH_SIGNALS;
+ rate = algo->GetProgress();
+ }
+ catch (...) {
+#ifdef _DEBUG_
+ cerr << "Exception in " << algo->GetName() << "::GetProgress()" << endl;
+#endif
+ }
+ if ( 0. < rate && rate < 1.001 )
+ {
+ computedCost += rate * ( algoDoneCost + algoNotDoneCost );
+ }
+ else
+ {
+ rate = algo->GetProgressByTic();
+ computedCost += algoDoneCost + rate * algoNotDoneCost;
+ }
+ // cout << "rate: "<<rate << " algoNotDoneCost: " << algoNotDoneCost << endl;
+ }
+
+ // get cost of already treated sub-meshes
+ if ( SMESH_subMesh* mainSM = GetSubMeshContaining( 1 ))
+ {
+ SMESH_subMeshIteratorPtr smIt = mainSM->getDependsOnIterator(/*includeSelf=*/true);
+ while ( smIt->more() )
+ {
+ const SMESH_subMesh* sm = smIt->next();
+ const int smCost = sm->GetComputeCost();
+ totalCost += smCost;
+ if ( !currentSubIds.Contains( sm->GetId() ) )
+ {
+ if (( !sm->IsEmpty() ) ||
+ ( sm->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE &&
+ !sm->DependsOn( curSM ) ))
+ computedCost += smCost;
+ }
+ }
+ }
+ // cout << "Total: " << totalCost
+ // << " computed: " << computedCost << " progress: " << computedCost / totalCost
+ // << " nbElems: " << GetMeshDS()->GetMeshInfo().NbElements() << endl;
+ return computedCost / totalCost;
+}
+
//================================================================================
/*!
* \brief Return number of nodes in the mesh
return _myMeshDS->GetMeshInfo().NbTriangles(order);
}
+//================================================================================
+/*!
+ * \brief Return number of biquadratic triangles in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbBiQuadTriangles() const throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ return _myMeshDS->GetMeshInfo().NbBiQuadTriangles();
+}
+
//================================================================================
/*!
* \brief Return the number nodes faces 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
{
// 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())
{
(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 )) {
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 ));