+ * \brief Return true if all sub-meshes are computed OK - to update an icon
+ */
+//=============================================================================
+
+bool SMESH_Mesh::IsComputedOK()
+{
+ if ( NbNodes() == 0 )
+ return false;
+
+ // if ( !HasShapeToMesh() )
+ // return true;
+
+ if ( SMESH_subMesh* mainSM = GetSubMeshContaining( 1 ))
+ {
+ SMESH_subMeshIteratorPtr smIt = mainSM->getDependsOnIterator(/*includeSelf=*/true);
+ while ( smIt->more() )
+ {
+ const SMESH_subMesh* sm = smIt->next();
+ if ( !sm->IsAlwaysComputed() )
+ switch ( sm->GetComputeState() )
+ {
+ case SMESH_subMesh::NOT_READY:
+ case SMESH_subMesh::COMPUTE_OK:
+ continue; // ok
+ case SMESH_subMesh::FAILED_TO_COMPUTE:
+ case SMESH_subMesh::READY_TO_COMPUTE:
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief Check if any groups of the same type have equal names
+ */
+//================================================================================
+
+bool SMESH_Mesh::HasDuplicatedGroupNamesMED()
+{
+ // Corrected for Mantis issue 0020028
+ std::map< SMDSAbs_ElementType, std::set< std::string > > aGroupNames;
+ for ( std::map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
+ {
+ SMESH_Group* aGroup = it->second;
+ SMDSAbs_ElementType aType = aGroup->GetGroupDS()->GetType();
+ std::string aGroupName = aGroup->GetName();
+ aGroupName.resize( MAX_MED_GROUP_NAME_LENGTH );
+ if ( !aGroupNames[aType].insert(aGroupName).second )
+ return true;
+ }
+
+ return false;
+}
+
+//================================================================================
+/*!
+ * \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] theMinor - define the minor version (y, where version is x.y.z) of MED file format.
+ * The theMinor must be between 0 and the current minor version of MED file library.
+ * If theMinor is equal to -1, the minor version is not changed (default).
+ * The major version (x, where version is x.y.z) cannot be changed.
+ * \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.
+ * \param [in] theAddODOnVertices - to create 0D elements on all vertices
+ * \param [in] theAllElemsToGroup - to make every element to belong to any group (PAL23413)
+ * \param [in] ZTolerance - tolerance in Z direction. If Z coordinate of a node is close to zero
+ * within a given tolerance, the coordinate is set to zero.
+ * If \a ZTolerance is negative, the node coordinates are kept as is.
+ * \return int - mesh index in the file
+ */
+//================================================================================
+
+void SMESH_Mesh::ExportMED(const char * file,
+ const char* theMeshName,
+ bool theAutoGroups,
+ int theVersion,
+ const SMESHDS_Mesh* meshPart,
+ bool theAutoDimension,
+ bool theAddODOnVertices,
+ double theZTolerance,
+ bool theAllElemsToGroup)
+throw(SALOME_Exception)
+{
+ MESSAGE("MED_VERSION:"<< theVersion);
+ SMESH_TRY;
+
+ DriverMED_W_SMESHDS_Mesh myWriter;
+ myWriter.SetFile ( file , theVersion);
+ myWriter.SetMesh ( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS );
+ myWriter.SetAutoDimension( theAutoDimension );
+ myWriter.AddODOnVertices ( theAddODOnVertices );
+ myWriter.SetZTolerance ( theZTolerance );
+ if ( !theMeshName )
+ myWriter.SetMeshId ( _id );
+ else {
+ myWriter.SetMeshId ( -1 );
+ myWriter.SetMeshName ( theMeshName );
+ }
+
+ if ( theAutoGroups ) {
+ myWriter.AddGroupOfNodes();
+ myWriter.AddGroupOfEdges();
+ myWriter.AddGroupOfFaces();
+ myWriter.AddGroupOfVolumes();
+ myWriter.AddGroupOf0DElems();
+ myWriter.AddGroupOfBalls();
+ }
+ if ( theAllElemsToGroup )
+ myWriter.AddAllToGroup();
+
+ // Pass groups to writer. Provide unique group names.
+ //set<string> aGroupNames; // Corrected for Mantis issue 0020028
+ if ( !meshPart )
+ {
+ std::map< SMDSAbs_ElementType, std::set<std::string> > aGroupNames;
+ char aString [256];
+ int maxNbIter = 10000; // to guarantee cycle finish
+ for ( std::map<int, SMESH_Group*>::iterator it = _mapGroup.begin();
+ it != _mapGroup.end();
+ it++ ) {
+ SMESH_Group* aGroup = it->second;
+ SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
+ if ( aGroupDS ) {
+ SMDSAbs_ElementType aType = aGroupDS->GetType();
+ std::string aGroupName0 = aGroup->GetName();
+ aGroupName0.resize(MAX_MED_GROUP_NAME_LENGTH);
+ std::string aGroupName = aGroupName0;
+ for (int i = 1; !aGroupNames[aType].insert(aGroupName).second && i < maxNbIter; i++) {
+ sprintf(&aString[0], "GR_%d_%s", i, aGroupName0.c_str());
+ aGroupName = aString;
+ aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH);
+ }
+ aGroupDS->SetStoreName( aGroupName.c_str() );
+ myWriter.AddGroup( aGroupDS );
+ }
+ }
+ }
+ // 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)
+ throw(SALOME_Exception)
+{
+ std::string medfilename(file);
+ medfilename += ".med";
+ std::string cmd;
+#ifdef WIN32
+ cmd = "%PYTHONBIN% ";
+#else
+ cmd = "python3 ";
+#endif
+ cmd += "-c \"";
+ cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')";
+ cmd += "\"";
+ system(cmd.c_str());
+ ExportMED(medfilename.c_str(), theMeshName, theAutoGroups, /*minor=*/-1,
+ /*meshPart=*/NULL, /*theAutoDimension=*/false, /*theAddODOnVertices=*/false,
+ /*zTol=*/-1, /*theAllElemsToGroup=*/true ); // theAllElemsToGroup is for PAL0023413
+#ifdef WIN32
+ cmd = "%PYTHONBIN% ";
+#else
+ cmd = "python3 ";
+#endif
+ cmd += "-c \"";
+ cmd += "from medutilities import convert ; convert(r'" + medfilename + "', 'MED', 'GIBI', 1, r'" + file + "')";
+ cmd += "\"";
+ system(cmd.c_str());
+#ifdef WIN32
+ cmd = "%PYTHONBIN% ";
+#else
+ cmd = "python3 ";
+#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
+ */
+//================================================================================
+
+void SMESH_Mesh::ExportDAT(const char * file,
+ const SMESHDS_Mesh* meshPart) throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ DriverDAT_W_SMDS_Mesh myWriter;
+ myWriter.SetFile( file );
+ myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS );
+ myWriter.SetMeshId(_id);
+ myWriter.Perform();
+}
+
+//================================================================================
+/*!
+ * \brief Export the mesh to an UNV file
+ */
+//================================================================================
+
+void SMESH_Mesh::ExportUNV(const char * file,
+ const SMESHDS_Mesh* meshPart) throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ DriverUNV_W_SMDS_Mesh myWriter;
+ myWriter.SetFile( file );
+ myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS );
+ myWriter.SetMeshId(_id);
+ // myWriter.SetGroups(_mapGroup);
+
+ // pass group names to SMESHDS
+ if ( !meshPart )
+ {
+ std::map<int, SMESH_Group*>::iterator it = _mapGroup.begin();
+ for ( ; it != _mapGroup.end(); it++ ) {
+ SMESH_Group* aGroup = it->second;
+ SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
+ if ( aGroupDS ) {
+ std::string aGroupName = aGroup->GetName();
+ aGroupDS->SetStoreName( aGroupName.c_str() );
+ myWriter.AddGroup( aGroupDS );
+ }
+ }
+ }
+ myWriter.Perform();
+}
+
+//================================================================================
+/*!
+ * \brief Export the mesh to an STL file
+ */
+//================================================================================
+
+void SMESH_Mesh::ExportSTL(const char * file,
+ const bool isascii,
+ const char * name,
+ const SMESHDS_Mesh* meshPart) throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ DriverSTL_W_SMDS_Mesh myWriter;
+ myWriter.SetFile( file );
+ myWriter.SetIsAscii( isascii );
+ myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS);
+ myWriter.SetMeshId(_id);
+ if ( name ) myWriter.SetName( name );
+ myWriter.Perform();
+}
+
+//================================================================================
+/*!
+ * \brief Export the mesh to the CGNS file
+ */
+//================================================================================
+
+void SMESH_Mesh::ExportCGNS(const char * file,
+ const SMESHDS_Mesh* meshDS,
+ const char * meshName,
+ const bool groupElemsByType)
+{
+ int res = Driver_Mesh::DRS_FAIL;
+
+ // pass group names to SMESHDS
+ std::map<int, SMESH_Group*>::iterator it = _mapGroup.begin();
+ for ( ; it != _mapGroup.end(); it++ ) {
+ SMESH_Group* group = it->second;
+ SMESHDS_GroupBase* groupDS = group->GetGroupDS();
+ if ( groupDS ) {
+ std::string groupName = group->GetName();
+ groupDS->SetStoreName( groupName.c_str() );
+ }
+ }
+#ifdef WITH_CGNS
+
+ DriverCGNS_Write myWriter;
+ myWriter.SetFile( file );
+ myWriter.SetMesh( const_cast<SMESHDS_Mesh*>( meshDS ));
+ myWriter.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId());
+ if ( meshName && meshName[0] )
+ myWriter.SetMeshName( meshName );
+ myWriter.SetElementsByType( groupElemsByType );
+ res = myWriter.Perform();
+ if ( res != Driver_Mesh::DRS_OK )
+ {
+ SMESH_ComputeErrorPtr err = myWriter.GetError();
+ if ( err && !err->IsOK() && !err->myComment.empty() )
+ throw SALOME_Exception(("Export failed: " + err->myComment ).c_str() );
+ }
+
+#endif
+ if ( res != Driver_Mesh::DRS_OK )
+ 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() || smToCompute.size() == 1 )
+ 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_
+ std::cerr << "Exception in " << algo->GetName() << "::GetProgress()" << std::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
+ */
+//================================================================================
+
+int SMESH_Mesh::NbNodes() const throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ return _myMeshDS->NbNodes();
+}
+
+//================================================================================
+/*!
+ * \brief Return number of edges of given order in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::Nb0DElements() const throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ return _myMeshDS->GetMeshInfo().Nb0DElements();
+}
+
+//================================================================================
+/*!
+ * \brief Return number of edges of given order in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ return _myMeshDS->GetMeshInfo().NbEdges(order);
+}
+
+//================================================================================
+/*!
+ * \brief Return number of faces of given order in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ return _myMeshDS->GetMeshInfo().NbFaces(order);
+}
+
+//================================================================================
+/*!
+ * \brief Return the number of faces in the mesh