1 // Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SMESH SMESHGUI : support of import / export with meshio library
24 // File : SMESHGUI_Meshio.h
25 // Author : Konstantin Leontev, Open CASCADE S.A.S.
27 #include "SMESHGUI_Meshio.h"
28 #include "SMESH_Meshio.h"
32 #include "SMESHGUI_FieldSelectorWdg.h"
34 // SALOME GUI includes
35 #include <SUIT_Desktop.h>
36 #include <SUIT_FileDlg.h>
37 #include <SUIT_MessageBox.h>
39 // SALOME KERNEL includes
40 #include <utilities.h>
43 #include <QStringList>
49 SMESHGUI_Meshio::SMESHGUI_Meshio()
56 SMESHGUI_Meshio::~SMESHGUI_Meshio()
61 Check and warn about exporting many shapes
63 bool SMESHGUI_Meshio::CheckMeshCount(const meshList& aMeshList)
65 if (aMeshList.size() == 1)
69 else if (!aMeshList.size())
71 // We shouldn't get here, but...
72 MESSAGE("Error: empty mesh list. Export canceled.");
76 const bool isOk = SUIT_MessageBox::warning(
78 QObject::tr("SMESH_WARNING"),
79 QObject::tr("SMESH_EXPORT_MESHIO_ONLY_MESH"),
80 SUIT_MessageBox::Yes |
82 SUIT_MessageBox::No) == SUIT_MessageBox::Yes;
88 Import mesh through an intermediate MED file
90 SMESH::mesh_array_var SMESHGUI_Meshio::ImportMesh(
91 SMESH::SMESH_Gen_ptr theComponentMesh, const QString& filename, QStringList& errors)
93 SMESH::DriverMED_ReadStatus res;
94 SMESH::mesh_array_var aMeshes = theComponentMesh->CreateMeshesFromMESHIO(filename.toUtf8().constData(), res);
95 if (res != SMESH::DRS_OK)
97 errors.append(QString("%1 :\n\t%2").arg(filename).arg(
98 QObject::tr(QString("SMESH_DRS_%1").arg(res).toLatin1().data())));
105 Returns a filter for Import File dialog
107 const QStringList& SMESHGUI_Meshio::GetImportFileFilter()
109 auto addAllFiles = []() -> QStringList
111 QStringList filter = GetExportFileFilter();
113 // Remove SVG because it works only for export
114 const int svgIndex = filter.indexOf(QRegExp("^SVG.+"));
117 filter.removeAt(svgIndex);
120 filter << QObject::tr("ALL_FILES_FILTER") + " (*)";
125 static const QStringList filter = addAllFiles();
130 Returns a filter for Export File dialog
132 const QStringList& SMESHGUI_Meshio::GetExportFileFilter()
134 static const QStringList filter = {
139 "DOLFIN XML (*.xml)",
141 "Exodus (*.e *.exo)",
146 //"Gmsh 4.1 (*.msh)",
148 "Kratos/MDPA (*.mdpa)",
149 "MED/Salome (*.med)",
150 "Medit (*.mesh *.meshb)",
151 "Nastran (*.bdf *.fem *.nas)",
152 "Netgen(*.vol *.vol.gz)",
155 "PERMAS (*.post *.post.gz *.dato *.dato.gz)",
159 "SVG, 2D output only (*.svg)",
161 "TetGen (*.node *.ele)",
166 "XDMF (*.xdmf *.xmf)"
173 Export mesh through an intermediate MED file
175 void SMESHGUI_Meshio::ExportMesh(const meshList& aMeshList, const QString& targetFileName, const QString& selectedFilter)
177 // Helper for indexed naming of the target files.
178 // We need to save into separated files because meshio doesn't
179 // support reading more than one mesh from a MED file.
180 // Look at src/meshio/med/_med.py in meshio git repo for a reference.
181 auto indexedFileName = [](const QString& targetFileName, const int index) -> QString
183 QString indexedFileName = targetFileName;
185 const int lastIndex = indexedFileName.lastIndexOf(".");
186 indexedFileName.insert(lastIndex, "_" + QString::number(index));
188 return indexedFileName;
191 // Trim an extension from the filter like in example: 'VTK (.vtk)' => 'VTK'
192 auto getFilterWithoutExt = [](const QString& selectedFilter) -> QString
194 // Find the start index for an extension in the filter string
195 const int index = selectedFilter.indexOf('(');
198 const QString filterWithoutExt = selectedFilter.left(index);
199 return filterWithoutExt.trimmed();
202 return selectedFilter;
205 // Iterate all the meshes from a list
206 auto aMeshIter = aMeshList.begin();
207 for(int aMeshIndex = 0; aMeshIter != aMeshList.end(); aMeshIter++, aMeshIndex++)
209 SMESH::SMESH_IDSource_var aMeshOrGroup = (*aMeshIter).first;
210 SMESH::SMESH_Mesh_var aMeshItem = aMeshOrGroup->GetMesh();
212 // Exprort this part.
213 aMeshItem->ExportPartToMESHIO(
214 aMeshOrGroup, // mesh part
215 (aMeshIndex ? indexedFileName(targetFileName, aMeshIndex) : targetFileName).toUtf8().data(),
216 getFilterWithoutExt(selectedFilter).toLatin1().data()
222 Opens file dialog and returns a choosen target name
224 QString SMESHGUI_Meshio::GetFileName(QString& selectedFilter, const bool isOpen/* = false*/)
226 // Get a target directory name
227 QString anInitialPath = SUIT_FileDlg::getLastVisitedPath();
228 if (anInitialPath.isEmpty())
229 anInitialPath = QDir::currentPath();
231 // Return a target file name
232 return SUIT_FileDlg::getFileName(
235 GetExportFileFilter(),
237 QObject::tr("SMESH_EXPORT_MESH"),
243 Returns true if meshio package is installed
245 bool SMESHGUI_Meshio::IsMeshioInstalled()
247 const bool isInstalled = SMESH_Meshio::IsMeshioInstalled();
250 SUIT_MessageBox::warning(
252 QObject::tr("SMESH_WARNING"),
253 QObject::tr("SMESH_MESHIO_NOT_INSTALLED")