diff --git a/doc/gui/images/reload_mesh_modif_mesh.png b/doc/gui/images/reload_mesh_modif_mesh.png new file mode 100644 index 000000000..ad3a68717 Binary files /dev/null and b/doc/gui/images/reload_mesh_modif_mesh.png differ diff --git a/doc/gui/images/reload_mesh_modif_mesh_props.png b/doc/gui/images/reload_mesh_modif_mesh_props.png new file mode 100644 index 000000000..7ff677cd0 Binary files /dev/null and b/doc/gui/images/reload_mesh_modif_mesh_props.png differ diff --git a/doc/gui/images/reload_mesh_orig_mesh.png b/doc/gui/images/reload_mesh_orig_mesh.png new file mode 100644 index 000000000..3398a90f3 Binary files /dev/null and b/doc/gui/images/reload_mesh_orig_mesh.png differ diff --git a/doc/gui/images/reload_mesh_result.png b/doc/gui/images/reload_mesh_result.png new file mode 100644 index 000000000..902c9e28a Binary files /dev/null and b/doc/gui/images/reload_mesh_result.png differ diff --git a/doc/gui/input/reload_mesh_from_file.rst b/doc/gui/input/reload_mesh_from_file.rst new file mode 100644 index 000000000..470961879 --- /dev/null +++ b/doc/gui/input/reload_mesh_from_file.rst @@ -0,0 +1,41 @@ +.. _reload_mesh_from_file_page: + +******************* +Reload mesh from file +******************* + +This operation allows reload original imported mesh, which was modified by different dedicated tools + +*Reload mesh from file:* + + +#. Select a mesh(es) (and display it in the 3D Viewer if you are going to pick elements by mouse). +#. From popup menu click on the *Reload from file* item + +Each selected mesh will be updated to orignal state with saving display properties + +.. image:: ../images/reload_mesh_orig_mesh.png + :align: center + +.. centered:: + Original mesh + +| + +.. image:: ../images/reload_mesh_modif_mesh.png + :align: center + +.. centered:: + Same mesh after apply "Merge Nodes" + +.. image:: ../images/reload_mesh_modif_mesh_props.png + :align: center + +.. centered:: + Set display properties + +.. image:: ../images/reload_mesh_result.png + :align: center + +.. centered:: + Result after reload mesh diff --git a/idl/SMESH_Gen.idl b/idl/SMESH_Gen.idl index f3bf7f454..aaaf38007 100644 --- a/idl/SMESH_Gen.idl +++ b/idl/SMESH_Gen.idl @@ -258,6 +258,9 @@ module SMESH SMESH_Mesh CreateEmptyMesh() raises ( SALOME::SALOME_Exception ); + SMESH_Mesh ReloadMeshFromFile(in SMESH_Mesh sourceMesh) + raises(SALOME::SALOME_Exception); + /*! * Create Mesh object importing data from given UNV file * (UNV supported version is I-DEAS 10) @@ -302,6 +305,7 @@ module SMESH out SMESH::DriverMED_ReadStatus theStatus) raises (SALOME::SALOME_Exception); + /*! * Create a dual mesh of a Tetrahedron mesh * \param mesh - TetraHedron mesh to create dual from diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 29487f6e0..612a8c54e 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -122,6 +122,9 @@ #include "SMESH_version.h" +#include "SMESHDS_Mesh.hxx" +#include "SMESH_Mesh.hxx" + #include "SMESH_Actor.h" #include "SMESH_ActorUtils.h" #include "SMESH_Client.hxx" @@ -221,6 +224,8 @@ namespace void ExportMeshToFile(int theCommandID); + void ReloadMeshFromFile(int theCommandID); + void SetDisplayMode(int theCommandID, VTK::MarkerMap& theMarkerMap); void SetDisplayEntity(int theCommandID); @@ -1076,6 +1081,84 @@ namespace } } + //================================================================================ + /*! + * \brief Reload selected mesh from file a file + */ + //================================================================================ + void ReloadMeshFromFile(int theCommandID) + { + LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if (aSel) + aSel->selectedObjects(selected); + + QList< QPair< SMESH::SMESH_IDSource_var, QString > > aMeshList; + QList< QPair< SMESH::SMESH_IDSource_var, QString > >::iterator aMeshIter; + SALOME_ListIteratorOfListIO It(selected); + + // Iterate by all selected + for (; It.More(); It.Next()) + { + Handle(SALOME_InteractiveObject) anIObject = It.Value(); + SMESH::SMESH_IDSource_var aMeshItem = + SMESH::IObjectToInterface(anIObject); + + if (aMeshItem->_is_nil()) { + SUIT_MessageBox::warning(SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_BAD_MESH_SELECTION")); + continue; + } + + SMESH::SMESH_Mesh_var aMeshByIO = SMESH::GetMeshByIO(anIObject); + SMESH::SelectionProxy aMesh = SMESH::SelectionProxy(aMeshItem); + SMESH::MedInfo anInfo = aMesh.medFileInfo(); + if (!anInfo.isValid()) + continue; + + SMESH::ListOfGroups aGroups = *aMeshByIO->GetGroups(); + for (int i = 0; i < aGroups.length(); ++i) + { + auto X = aGroups[i]; + _PTR(SObject) aGroupSObject = SMESH::FindSObject(X); + SMESH_Actor* anActor = SMESH::FindActorByEntry(aGroupSObject->GetID().c_str()); + SMESH::smIdType_array aMeshInfo = *X->GetMeshInfo(); + + if (anActor) + { + vtkTypeBool isVisib = anActor->GetVisibility(); + SMESH::UpdateView(!isVisib ? SMESH::eDisplay : SMESH::eErase, aGroupSObject->GetID().c_str()); + } + else + SMESH::UpdateView(SMESH::eErase, aGroupSObject->GetID().c_str()); + } + + SMESH::mesh_array_var aMeshes = new SMESH::mesh_array; + { + // re-import mesh + SMESH::SMESH_Mesh_var aReloadedMesh = SMESHGUI::GetSMESHGen()->ReloadMeshFromFile(aMeshByIO); + + QStringList anEntryList; + + _PTR(SObject) aMeshSO = SMESH::FindSObject(aReloadedMesh); + if (aMeshSO) { + anEntryList.append(aMeshSO->GetID().c_str()); + } + SMESHGUI::GetSMESHGUI()->updateObjBrowser(); + if (LightApp_Application* anApp = + dynamic_cast(SUIT_Session::session()->activeApplication())) + anApp->browseObjects(anEntryList); + } + + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(aMeshItem); + QString aMeshName = anIObject->getName(); + aMeshList.append(QPair< SMESH::SMESH_IDSource_var, QString >(aMeshItem, aMeshName)); + + } + SMESH::UpdateView(); + } + inline void InverseEntityMode(unsigned int& theOutputMode, unsigned int theMode) { @@ -2688,7 +2771,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) ::ImportMeshesFromFile(GetSMESHGen(),theCommandID); break; } - + case SMESHOp::OpReloadFromFile: + { + if (isStudyLocked()) break; + ::ReloadMeshFromFile(theCommandID); + break; + } case SMESHOp::OpFileInformation: { SALOME_ListIO selected; @@ -3481,7 +3569,6 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) } break; } - case SMESHOp::OpFindElementByPoint: { startOperation( theCommandID ); @@ -4317,6 +4404,7 @@ void SMESHGUI::initialize( CAM_Application* app ) //createSMESHAction( SMESHOp::OpStdInfo, "STD_INFO", "ICON_STD_INFO" ); //createSMESHAction( SMESHOp::OpWhatIs, "WHAT_IS", "ICON_WHAT_IS" ); // VSR: issue #0021242 (eliminate "Mesh Element Information" command) createSMESHAction( SMESHOp::OpFindElementByPoint, "FIND_ELEM", "ICON_FIND_ELEM" ); + createSMESHAction( SMESHOp::OpReloadFromFile, "RELOAD_FROM_FILE"); //update createSMESHAction( SMESHOp::OpFreeNode, "FREE_NODE", "ICON_FREE_NODE", 0, true ); createSMESHAction( SMESHOp::OpEqualNode, "EQUAL_NODE", "ICON_EQUAL_NODE", 0, true ); @@ -4929,6 +5017,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createPopupItem( SMESHOp::OpFileInformation, OB, mesh, "&& selcount=1 && isImported" ); createPopupItem( SMESHOp::OpMeshInformation, OB, mesh_part ); createPopupItem( SMESHOp::OpFindElementByPoint,OB, mesh_group, "&& selcount=1 && " + hasElems ); + createPopupItem( SMESHOp::OpReloadFromFile, OB, mesh, "&& isImported"); createPopupItem( SMESHOp::OpOverallMeshQuality,OB, mesh_part ); popupMgr()->insert( separator(), -1, 0 ); createPopupItem( SMESHOp::OpCreateGroup, OB, mesh, "&& selcount=1" ); diff --git a/src/SMESHGUI/SMESHGUI_Operations.h b/src/SMESHGUI/SMESHGUI_Operations.h index 9b9ee1425..58689219d 100644 --- a/src/SMESHGUI/SMESHGUI_Operations.h +++ b/src/SMESHGUI/SMESHGUI_Operations.h @@ -94,6 +94,7 @@ namespace SMESHOp { OpWhatIs = 2101, // MENU MESH - MESH ELEMENT INFORMATION OpStdInfo = 2102, // MENU MESH - MESH STANDARD INFORMATION OpFindElementByPoint = 2103, // MENU MESH - FIND ELEMENT BY POINT + OpReloadFromFile = 2104, // MENU MESH - RELOAD MESH FROM FILE OpUpdate = 2200, // POPUP MENU - UPDATE // Controls -----------------------//-------------------------------- OpFreeNode = 3000, // MENU CONTROLS - FREE NODES diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index 318a047da..6e15a27f6 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -272,6 +272,10 @@ MEN_ADV_INFO Mesh Information + + MEN_RELOAD_FROM_FILE + Reload from file + MEN_ALL All @@ -3332,6 +3336,10 @@ Use Display Entity menu command to show them. STB_ADV_INFO Show base information about the mesh object + + STB_RELOAD_FROM_FILE + Reload original mesh from file + STB_ALL All @@ -4072,6 +4080,10 @@ Use Display Entity menu command to show them. TOP_ADV_INFO Mesh Information + + TOP_RELOAD_FROM_FILE + Reload from file + TOP_ALL All diff --git a/src/SMESHGUI/SMESH_msg_fr.ts b/src/SMESHGUI/SMESH_msg_fr.ts index 4b2af068f..06ec53e42 100644 --- a/src/SMESHGUI/SMESH_msg_fr.ts +++ b/src/SMESHGUI/SMESH_msg_fr.ts @@ -268,6 +268,10 @@ MEN_ADV_INFO Informations sur le maillage + + MEN_RELOAD_FROM_FILE + Reload from file + MEN_ALL Tous @@ -3331,6 +3335,10 @@ Utilisez le menu "Visualiser une entité" pour les afficher. STB_ALL Tous + + STB_RELOAD_FROM_FILE + Reload original mesh from file + STB_AREA Aire @@ -4067,6 +4075,10 @@ Utilisez le menu "Visualiser une entité" pour les afficher. TOP_ADV_INFO Informations sur le maillage + + TOP_RELOAD_FROM_FILE + Reload from file + TOP_ALL Tous diff --git a/src/SMESHGUI/SMESH_msg_ja.ts b/src/SMESHGUI/SMESH_msg_ja.ts index d7706f285..e5f0d3411 100644 --- a/src/SMESHGUI/SMESH_msg_ja.ts +++ b/src/SMESHGUI/SMESH_msg_ja.ts @@ -251,6 +251,10 @@ MEN_ADV_INFO メッシュに関する情報 + + MEN_RELOAD_FROM_FILE + Reload from file + MEN_ALL すべて @@ -2979,6 +2983,10 @@ pip install meshio[all] STB_ADV_INFO メッシュ上の基本的な情報を得る + + STB_RELOAD_FROM_FILE + Reload original mesh from file + STB_ALL すべて @@ -3663,6 +3671,10 @@ pip install meshio[all] TOP_ADV_INFO メッシュに関する情報 + + TOP_RELOAD_FROM_FILE + Reload from file + TOP_ALL すべて diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index 1e73de97a..3883d30b3 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -1013,6 +1013,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) { // there are methods to convert: // CreateMesh( shape ) + // ReloadMesh( shape ) // Concatenate( [mesh1, ...], ... ) // CreateHypothesis( theHypType, theLibName ) // Compute( mesh, geom ) @@ -1067,6 +1068,13 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) Handle(_pyMesh) mesh = new _pyMesh( theCommand, entries.front() ); AddObject( mesh ); } + if (method == "ReloadMeshFromFile") + { + std::cout << "WhatIS" << std::endl; + Handle(_pyMesh) mesh = new _pyMesh(theCommand, theCommand->GetResultValue()); + AddObject(mesh); + return; + } // CreateHypothesis() if ( method == "CreateHypothesis" ) diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 942aacd57..967f6ae5d 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -153,6 +153,7 @@ #include #include #include +#include #include #include @@ -1330,6 +1331,61 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateEmptyMesh() return mesh._retn(); } +SMESH::SMESH_Mesh_ptr SMESH_Gen_i::ReloadMeshFromFile(SMESH::SMESH_Mesh_ptr theMesh) +{ + SMESH::mesh_array_var aMeshes = new SMESH::mesh_array; + + SMESH::MedFileInfo* aMedInfo = theMesh->GetMEDFileInfo(); + + // Get file path and re-import mesh + QString aPath = QString(aMedInfo->fileName); + QStringList aSplit = aPath.split('.'); + QStringList anEntryList; + + auto aStudy = getStudyServant(); + + SMESH::SMESH_Mesh_ptr aNewMesh; + + SMESH_Mesh* aMesh = reinterpret_cast (theMesh->GetMeshPtr()); + aMesh->GetMeshDS()->ClearMesh(); + + if (aSplit.last() == "cgns") + { + SMESH::DriverMED_ReadStatus res; + aMeshes = ReloadMeshesFromCGNS(aPath.toUtf8().constData(), theMesh, res); + + aNewMesh = aMeshes[0]; + + } + else if (aSplit.last().contains("stl", Qt::CaseSensitivity::CaseInsensitive)) + { + aNewMesh = ReloadMeshesFromSTL(aPath.toUtf8().constData(), theMesh); + } + else if (aSplit.last().contains("unv", Qt::CaseSensitivity::CaseInsensitive)) + { + aNewMesh = ReloadMeshesFromUNV(aPath.toUtf8().constData(), theMesh); + } + else if (aSplit.last().contains("mesh", Qt::CaseSensitivity::CaseInsensitive)) + { + SMESH::ComputeError_var res; + aNewMesh = ReloadMeshesFromGMF(aPath.toUtf8().constData(), theMesh, true, res.out()); + } + else if (aSplit.last().contains("med", Qt::CaseSensitivity::CaseInsensitive)) + { + SMESH::DriverMED_ReadStatus res; + aMeshes = ReloadMeshesFromMED(aPath.toUtf8().constData(), theMesh, res); + + aNewMesh = aMeshes[0]; + } + else + { + // MeshIO + } + + theMesh = SMESH::SMESH_Mesh::_duplicate(aNewMesh); + return theMesh; +} + namespace { //================================================================================ @@ -1428,6 +1484,36 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName return aMesh._retn(); } +SMESH::SMESH_Mesh_ptr SMESH_Gen_i::ReloadMeshesFromUNV(const char* theFileName, SMESH::SMESH_Mesh_ptr sourceMesh) +{ + Unexpect aCatch(SALOME_SalomeException); + + checkFileReadable(theFileName); + + string aFileName; + // publish mesh in the study + if (CanPublishInStudy(sourceMesh)) { + SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder(); + aStudyBuilder->NewCommand(); // There is a transaction + SALOMEDS::SObject_wrap aSO = PublishMesh(sourceMesh, aFileName.c_str()); + aStudyBuilder->CommitCommand(); + if (!aSO->_is_nil()) { + // Update Python script + TPythonDump(this) << aSO << " = " << this << ".ReloadMeshesFromUNV(r'" << theFileName << "')"; + } + } + + SMESH_Mesh_i* aServant = dynamic_cast(GetServant(sourceMesh).in()); + ASSERT(aServant); + aServant->ImportUNVFile(theFileName); + + // Dump creation of groups + SMESH::ListOfGroups_var groups = aServant->GetGroups(); + + aServant->GetImpl().GetMeshDS()->Modified(); + return sourceMesh; +} + //============================================================================= /*! * SMESH_Gen_i::CreateMeshFromMED @@ -1511,6 +1597,92 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* return aResult._retn(); } +SMESH::mesh_array* SMESH_Gen_i::ReloadMeshesFromMED(const char* theFileName, SMESH::SMESH_Mesh_ptr sourceMesh, SMESH::DriverMED_ReadStatus& theStatus) +{ + SMESH::ListOfGroups anOldGroups = *sourceMesh->GetGroups(); + checkFileReadable(theFileName); + +#ifdef WIN32 + char bname[_MAX_FNAME]; + _splitpath(theFileName, NULL, NULL, bname, NULL); + string aFileName = bname; +#else + string aFileName = basename(const_cast(theFileName)); +#endif + // Retrieve mesh names from the file + DriverMED_R_SMESHDS_Mesh myReader; + myReader.SetFile(theFileName); + myReader.SetMeshId(-1); + Driver_Mesh::Status aStatus; + list aNames = myReader.GetMeshNames(aStatus); + SMESH::mesh_array_var aResult = new SMESH::mesh_array(); + theStatus = (SMESH::DriverMED_ReadStatus)aStatus; + + { // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups() + + // Python Dump + TPythonDump aPythonDump(this); + aPythonDump << "(["; + + if (theStatus == SMESH::DRS_OK) + { + SALOMEDS::StudyBuilder_var aStudyBuilder; + aStudyBuilder = getStudyServant()->NewBuilder(); + aStudyBuilder->NewCommand(); // There is a transaction + + aResult->length(aNames.size()); + int i = 0; + + // Iterate through all meshes and create mesh objects + for (const std::string& meshName : aNames) + { + // Python Dump + if (i > 0) aPythonDump << ", "; + + // publish mesh in the study + SALOMEDS::SObject_wrap aSO; + if (CanPublishInStudy(sourceMesh)) + aSO = PublishMesh(sourceMesh, meshName.c_str()); + + // Python Dump + if (!aSO->_is_nil()) { + aPythonDump << aSO; + } + else { + aPythonDump << "mesh_" << i; + } + + // Read mesh data (groups are published automatically by ImportMEDFile()) + SMESH_Mesh_i* meshServant = dynamic_cast(GetServant(sourceMesh).in()); + ASSERT(meshServant); + SMESH::DriverMED_ReadStatus status1 = + meshServant->ImportMEDFile(theFileName, meshName.c_str()); + if (status1 > theStatus) + theStatus = status1; + + for (unsigned int i = 0; i < anOldGroups.length(); ++i) + { + //auto X = anOldGroups[i]; + sourceMesh->RemoveGroup(anOldGroups[i]); + } + aResult[i++] = SMESH::SMESH_Mesh::_duplicate(sourceMesh); + + meshServant->GetImpl().GetMeshDS()->Modified(); + } + if (!aStudyBuilder->_is_nil()) + aStudyBuilder->CommitCommand(); + } + + // Update Python script + aPythonDump << "], status) = " << this << ".ReloadMeshesFromMED( r'" << theFileName << "' )"; + } + // Dump creation of groups + for (CORBA::ULong i = 0; i < aResult->length(); ++i) + SMESH::ListOfGroups_var groups = aResult[i]->GetGroups(); + + return aResult._retn(); +} + //============================================================================= /*! * SMESH_Gen_i::CreateMeshFromSTL @@ -1554,6 +1726,37 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName return aMesh._retn(); } +SMESH::SMESH_Mesh_ptr SMESH_Gen_i::ReloadMeshesFromSTL(const char* theFileName, SMESH::SMESH_Mesh_ptr sourceMesh) +{ + Unexpect aCatch(SALOME_SalomeException); + checkFileReadable(theFileName); + +#ifdef WIN32 + char bname[_MAX_FNAME]; + _splitpath(theFileName, NULL, NULL, bname, NULL); + string aFileName = bname; +#else + string aFileName = basename(const_cast(theFileName)); +#endif + // publish mesh in the study + if (CanPublishInStudy(sourceMesh)) { + SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder(); + aStudyBuilder->NewCommand(); // There is a transaction + SALOMEDS::SObject_wrap aSO = PublishInStudy(SALOMEDS::SObject::_nil(), sourceMesh, aFileName.c_str()); + aStudyBuilder->CommitCommand(); + if (!aSO->_is_nil()) { + // Update Python script + TPythonDump(this) << aSO << " = " << this << ".ReloadMeshFromSTL(r'" << theFileName << "')"; + } + } + + SMESH_Mesh_i* aServant = dynamic_cast(GetServant(sourceMesh).in()); + ASSERT(aServant); + aServant->ImportSTLFile(theFileName); + aServant->GetImpl().GetMeshDS()->Modified(); + return sourceMesh; +} + //================================================================================ /*! * \brief Create meshes and import data from the CGSN file @@ -1639,6 +1842,85 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char* return aResult._retn(); } +SMESH::mesh_array* SMESH_Gen_i::ReloadMeshesFromCGNS(const char* theFileName, + SMESH::SMESH_Mesh_ptr sourceMesh, + SMESH::DriverMED_ReadStatus& theStatus) +{ + Unexpect aCatch(SALOME_SalomeException); + checkFileReadable(theFileName); + + SMESH::mesh_array_var aResult = new SMESH::mesh_array(); + +#ifdef WITH_CGNS + // Retrieve nb meshes from the file + DriverCGNS_Read myReader; + myReader.SetFile(theFileName); + Driver_Mesh::Status aStatus; + int nbMeshes = myReader.GetNbMeshes(aStatus); + theStatus = (SMESH::DriverMED_ReadStatus)aStatus; + + aResult->length(nbMeshes); + + { // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups() + + // Python Dump + TPythonDump aPythonDump(this); + aPythonDump << "(["; + + if (theStatus == SMESH::DRS_OK) + { + SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder(); + aStudyBuilder->NewCommand(); // There is a transaction + + int i = 0; + + // Iterate through all meshes and create mesh objects + for (; i < nbMeshes; ++i) + { + // Python Dump + if (i > 0) aPythonDump << ", "; + + // create mesh + aResult[i] = SMESH::SMESH_Mesh::_duplicate(sourceMesh); + + // Read mesh data (groups are published automatically by ImportMEDFile()) + SMESH_Mesh_i* meshServant = dynamic_cast(GetServant(sourceMesh).in()); + ASSERT(meshServant); + string meshName; + SMESH::DriverMED_ReadStatus status1 = + meshServant->ImportCGNSFile(theFileName, i, meshName); + if (status1 > theStatus) + theStatus = status1; + + meshServant->GetImpl().GetMeshDS()->Modified(); + // publish mesh in the study + SALOMEDS::SObject_wrap aSO; + if (CanPublishInStudy(sourceMesh)) + aSO = PublishMesh(sourceMesh, meshName.c_str()); + + // Python Dump + if (!aSO->_is_nil()) { + aPythonDump << aSO; + } + else { + aPythonDump << "mesh_" << i; + } + } + aStudyBuilder->CommitCommand(); + } + + aPythonDump << "], status) = " << this << ".ReloadMeshesFromCGNS(r'" << theFileName << "')"; + } + // Dump creation of groups + for (CORBA::ULong i = 0; i < aResult->length(); ++i) + SMESH::ListOfGroups_var groups = aResult[i]->GetGroups(); +#else + THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR); +#endif + + return aResult._retn(); +} + //================================================================================ /*! * \brief Create a mesh and import data from a GMF file @@ -1682,6 +1964,38 @@ SMESH_Gen_i::CreateMeshesFromGMF( const char* theFileName, return aMesh._retn(); } +SMESH::SMESH_Mesh_ptr SMESH_Gen_i::ReloadMeshesFromGMF(const char* theFileName, SMESH::SMESH_Mesh_ptr sourceMesh, CORBA::Boolean theMakeRequiredGroups, SMESH::ComputeError_out theError) +{ + Unexpect aCatch(SALOME_SalomeException); + checkFileReadable(theFileName); + +#ifdef WIN32 + char bname[_MAX_FNAME]; + _splitpath(theFileName, NULL, NULL, bname, NULL); + string aFileName = bname; +#else + string aFileName = basename(const_cast(theFileName)); +#endif + // publish mesh in the study + if (CanPublishInStudy(sourceMesh)) { + SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder(); + aStudyBuilder->NewCommand(); // There is a transaction + SALOMEDS::SObject_wrap aSO = PublishInStudy(SALOMEDS::SObject::_nil(), sourceMesh, aFileName.c_str()); + aStudyBuilder->CommitCommand(); + if (!aSO->_is_nil()) { + // Update Python script + TPythonDump(this) << "(" << aSO << ", error) = " << this << ".ReloadMeshesFromGMF(r'" + << theFileName << "', " + << theMakeRequiredGroups << " )"; + } + } + SMESH_Mesh_i* aServant = dynamic_cast(GetServant(sourceMesh).in()); + ASSERT(aServant); + theError = aServant->ImportGMFFile(theFileName, theMakeRequiredGroups); + aServant->GetImpl().GetMeshDS()->Modified(); + return sourceMesh; +} + //================================================================================ /*! * \brief Create a mesh and import data from any file supported by meshio library @@ -1768,6 +2082,82 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMESHIO(const char* theFileName, return aResult._retn(); } +SMESH::mesh_array* SMESH_Gen_i::ReloadMeshesFromMESHIO(const char* theFileName, SMESH::SMESH_Mesh_ptr sourceMesh, SMESH::DriverMED_ReadStatus& theStatus) +{ + Unexpect aCatch(SALOME_SalomeException); + checkFileReadable(theFileName); + + MESSAGE("Import part with meshio through an intermediate MED file"); + + // Create an object that holds a temp file name and + // removes the file when goes out of scope. + SMESH_Meshio meshio; + const QString tempFileName = meshio.CreateTempFileName(theFileName); + + // Convert temp file into a target one with meshio command + meshio.Convert(theFileName, tempFileName); + + // We don't need a python dump from SMESH_Gen_i::CreateMeshesFromMED(), so + // we can't use this method as is here. The followed code is an edited part of + // copy pasted CreateMeshesFromMED(). + + // Retrieve mesh names from the file + DriverMED_R_SMESHDS_Mesh myReader; + myReader.SetFile(tempFileName.toStdString()); + myReader.SetMeshId(-1); + Driver_Mesh::Status aStatus; + list aNames = myReader.GetMeshNames(aStatus); + SMESH::mesh_array_var aResult = new SMESH::mesh_array(); + theStatus = (SMESH::DriverMED_ReadStatus)aStatus; + + if (theStatus == SMESH::DRS_OK) + { + SALOMEDS::StudyBuilder_var aStudyBuilder; + aStudyBuilder = getStudyServant()->NewBuilder(); + aStudyBuilder->NewCommand(); // There is a transaction + + aResult->length(aNames.size()); + std::vector sobjects; + int i = 0; + + // Iterate through all meshes and create mesh objects + for (const std::string& meshName : aNames) + { + // publish mesh in the study + SALOMEDS::SObject_wrap aSO; + if (CanPublishInStudy(sourceMesh)) + aSO = PublishMesh(sourceMesh, meshName.c_str()); + + // Save SO to use in a python dump + sobjects.emplace_back(aSO); + + // Read mesh data (groups are published automatically by ImportMEDFile()) + SMESH_Mesh_i* meshServant = dynamic_cast(GetServant(sourceMesh).in()); + ASSERT(meshServant); + SMESH::DriverMED_ReadStatus status1 = + meshServant->ImportMEDFile(tempFileName.toUtf8().data(), meshName.c_str()); + if (status1 > theStatus) + theStatus = status1; + + aResult[i++] = SMESH::SMESH_Mesh::_duplicate(sourceMesh); + meshServant->GetImpl().GetMeshDS()->Modified(); + } + + if (!aStudyBuilder->_is_nil()) + aStudyBuilder->CommitCommand(); + + // Python dump + const std::string functionName = std::string(".ReloadMeshesFromMESHIO(r'") + theFileName + "')"; + functionToPythonDump(this, functionName, sobjects); + } + + // Dump creation of groups + for (CORBA::ULong i = 0; i < aResult->length(); ++i) + SMESH::ListOfGroups_var groups = aResult[i]->GetGroups(); + + return aResult._retn(); +} + //============================================================================= /*! * SMESH_Gen_i::IsReadyToCompute diff --git a/src/SMESH_I/SMESH_Gen_i.hxx b/src/SMESH_I/SMESH_Gen_i.hxx index 3236fb1b6..f7ac965ec 100644 --- a/src/SMESH_I/SMESH_Gen_i.hxx +++ b/src/SMESH_I/SMESH_Gen_i.hxx @@ -237,29 +237,54 @@ public: // Create empty mesh SMESH::SMESH_Mesh_ptr CreateEmptyMesh(); + SMESH::SMESH_Mesh_ptr ReloadMeshFromFile(SMESH::SMESH_Mesh_ptr theMesh); + // Create a mesh and import data from an UNV file SMESH::SMESH_Mesh_ptr CreateMeshesFromUNV( const char* theFileName ); + SMESH::SMESH_Mesh_ptr ReloadMeshesFromUNV(const char* theFileName, + SMESH::SMESH_Mesh_ptr sourceMesh); + // Create mesh(es) and import data from MED file SMESH::mesh_array* CreateMeshesFromMED( const char* theFileName, SMESH::DriverMED_ReadStatus& theStatus ); + SMESH::mesh_array* ReloadMeshesFromMED(const char* theFileName, + SMESH::SMESH_Mesh_ptr sourceMesh, + SMESH::DriverMED_ReadStatus& theStatus); + // Create a mesh and import data from a STL file SMESH::SMESH_Mesh_ptr CreateMeshesFromSTL( const char* theFileName ); + SMESH::SMESH_Mesh_ptr ReloadMeshesFromSTL(const char* theFileName, + SMESH::SMESH_Mesh_ptr sourceMesh); + // Create mesh(es) and import data from CGNS file SMESH::mesh_array* CreateMeshesFromCGNS( const char* theFileName, SMESH::DriverMED_ReadStatus& theStatus ); + SMESH::mesh_array* ReloadMeshesFromCGNS(const char* theFileName, + SMESH::SMESH_Mesh_ptr sourceMesh, + SMESH::DriverMED_ReadStatus& theStatus); + // Create a mesh and import data from a GMF file SMESH::SMESH_Mesh_ptr CreateMeshesFromGMF( const char* theFileName, CORBA::Boolean theMakeRequiredGroups, SMESH::ComputeError_out theError); + SMESH::SMESH_Mesh_ptr ReloadMeshesFromGMF(const char* theFileName, + SMESH::SMESH_Mesh_ptr sourceMesh, + CORBA::Boolean theMakeRequiredGroups, + SMESH::ComputeError_out theError); + // Create a mesh and import data from any file supported by meshio library SMESH::mesh_array* CreateMeshesFromMESHIO(const char* theFileName, SMESH::DriverMED_ReadStatus& theStatus); + SMESH::mesh_array* ReloadMeshesFromMESHIO(const char* theFileName, + SMESH::SMESH_Mesh_ptr sourceMesh, + SMESH::DriverMED_ReadStatus& theStatus); + // Create dual mesh of a tetrahedron mesh SMESH::SMESH_Mesh_ptr CreateDualMesh(SMESH::SMESH_IDSource_ptr meshPart, const char* meshName, diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index 607314411..5d3c4bb06 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -675,6 +675,14 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): global notebook notebook = salome_notebook.NoteBook( theIsEnablePublish ) + def ReloadMeshFromFile(self, theMesh): + """ + Desc for method, + """ + + aSmeshMesh = SMESH._objref_SMESH_Gen.ReloadMeshFromFile(self, theMesh) + aMesh = Mesh(self, self.geompyD, aSmeshMesh) + return aMesh def CreateMeshesFromUNV( self,theFileName ): """