X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_Mesh.cxx;h=692940c5434090b97fec73f139c4533d16796d60;hp=a7e10a243f7bf6b3ed4d16d41ae87df2c1c08ba1;hb=97787812e26d555a6141ece38c9f13167410f425;hpb=bd8f1aee7c78f7d2eb82bd4fec5e08c9e3d280ce diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index a7e10a243..692940c54 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2014 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 @@ -6,7 +6,7 @@ // 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. +// 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 @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -65,10 +66,15 @@ #include #include -#include "Utils_ExceptHandlers.hxx" +#include "SMESH_TryCatch.hxx" // include after OCCT headers! +#include "Utils_ExceptHandlers.hxx" +#ifndef WIN32 #include #include +#else +#include +#endif using namespace std; @@ -136,16 +142,28 @@ SMESH_Mesh::SMESH_Mesh(): namespace { +#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 } //============================================================================= /*! - * + * */ //============================================================================= @@ -188,9 +206,15 @@ SMESH_Mesh::~SMESH_Mesh() _myDocument->RemoveMesh( _id ); _myDocument = 0; - if ( _myMeshDS ) + 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 + } } //================================================================================ @@ -363,13 +387,10 @@ void SMESH_Mesh::Clear() { 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 ); - } + 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; @@ -592,19 +613,9 @@ SMESH_Hypothesis::Hypothesis_Status 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 ); @@ -682,8 +693,7 @@ SMESH_Hypothesis::Hypothesis_Status SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId]; if(MYDEBUG) { - int hypType = anHyp->GetType(); - SCRUTE(hypType); + SCRUTE(anHyp->GetType()); } // shape @@ -813,7 +823,8 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape & aSubS int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, const SMESH_HypoFilter& aFilter, list & aHypList, - const bool andAncestors) const + const bool andAncestors, + list< TopoDS_Shape > * assignedTo/*=0*/) const { set hypTypes; // to exclude same type hypos from the result list int nbHyps = 0; @@ -842,6 +853,7 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, nbHyps++; if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() ) mainHypFound = true; + if ( assignedTo ) assignedTo->push_back( aSubShape ); } } @@ -868,12 +880,29 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & 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; +} + //============================================================================= /*! * @@ -918,10 +947,9 @@ SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) 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 ) @@ -1240,6 +1268,19 @@ bool SMESH_Mesh::HasDuplicatedGroupNamesMED() //================================================================================ /*! * \brief Export the mesh to a med file + * \param [in] file - name of the MED file + * \param [in] theMeshName - name of this mesh + * \param [in] theAutoGroups - boolean parameter for creating/not creating + * the groups Group_On_All_Nodes, Group_On_All_Faces, ... ; + * the typical use is auto_groups=false. + * \param [in] theVersion - defines the version of format of MED file, that will be created + * \param [in] meshPart - mesh data to export + * \param [in] theAutoDimension - if \c true, a space dimension of a MED mesh can be either + * - 1D if all mesh nodes lie on OX coordinate axis, or + * - 2D if all mesh nodes lie on XOY coordinate plane, or + * - 3D in the rest cases. + * If \a theAutoDimension is \c false, the space dimension is always 3. + * \return int - mesh index in the file */ //================================================================================ @@ -1247,19 +1288,21 @@ void SMESH_Mesh::ExportMED(const char * file, 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 ( _id ); + myWriter.SetMeshId ( _id ); else { - myWriter.SetMeshId ( -1 ); - myWriter.SetMeshName( theMeshName ); + myWriter.SetMeshId ( -1 ); + myWriter.SetMeshName ( theMeshName ); } if ( theAutoGroups ) { @@ -1296,8 +1339,16 @@ void SMESH_Mesh::ExportMED(const char * file, } // 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) @@ -1306,7 +1357,7 @@ void SMESH_Mesh::ExportSAUV(const char *file, std::string medfilename(file); medfilename += ".med"; std::string cmd; -#ifdef WNT +#ifdef WIN32 cmd = "%PYTHONBIN% "; #else cmd = "python "; @@ -1316,7 +1367,7 @@ void SMESH_Mesh::ExportSAUV(const char *file, cmd += "\""; system(cmd.c_str()); ExportMED(medfilename.c_str(), theMeshName, theAutoGroups, 1); -#ifdef WNT +#ifdef WIN32 cmd = "%PYTHONBIN% "; #else cmd = "python "; @@ -1325,7 +1376,7 @@ void SMESH_Mesh::ExportSAUV(const char *file, 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 "; @@ -1442,6 +1493,80 @@ void SMESH_Mesh::ExportGMF(const char * file, 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& 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: "<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 @@ -1502,6 +1627,18 @@ int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) const throw(SALOME_Excep 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