mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-12-27 09:50:34 +05:00
e85c9d5b6b
Added using MESHIO_VERSION env variable to detect meshio version. Exodus format removed from a file filter on Windows.
373 lines
9.4 KiB
C++
373 lines
9.4 KiB
C++
// Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE
|
|
//
|
|
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
|
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
|
//
|
|
// 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, 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
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this library; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
//
|
|
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
|
//
|
|
|
|
// SMESH SMESH_I : support of import / export with meshio library
|
|
// File : SMESH_Meshio.h
|
|
// Author : Konstantin Leontev, Open CASCADE S.A.S.
|
|
//
|
|
|
|
#include "SMESH_Meshio.h"
|
|
|
|
// SALOME KERNEL includes
|
|
#include <SALOMEDS_Tool.hxx>
|
|
#include <Basics_DirUtils.hxx>
|
|
#include <SALOME_Exception.hh>
|
|
#include <utilities.h>
|
|
|
|
// Qt
|
|
#include <QFileInfo>
|
|
|
|
#include <fstream>
|
|
|
|
|
|
/*!
|
|
Constructor
|
|
*/
|
|
SMESH_Meshio::SMESH_Meshio()
|
|
{
|
|
CreateErrorFileName();
|
|
}
|
|
|
|
/*!
|
|
Constructor
|
|
*/
|
|
SMESH_Meshio::SMESH_Meshio(const QString& selectedFilter)
|
|
: SMESH_Meshio()
|
|
{
|
|
mySelectedFilter = selectedFilter;
|
|
}
|
|
|
|
/*!
|
|
Destructor
|
|
*/
|
|
SMESH_Meshio::~SMESH_Meshio()
|
|
{
|
|
RemoveTempFile();
|
|
RemoveErrorFile();
|
|
}
|
|
|
|
/*!
|
|
Convert file with meshio convert command
|
|
*/
|
|
void SMESH_Meshio::Convert(const QString& sourceFileName, const QString& targetFileName) const
|
|
{
|
|
// Execute meshio convert command
|
|
const QString convert = IsModernMeshioVersion() ? "meshio convert " : "meshio-convert ";
|
|
const QString optArgs = GetConvertOptArgs();
|
|
|
|
const std::string cmd =
|
|
(convert + optArgs + " " + sourceFileName + " " + targetFileName + " 2> " + myErrorFileName).toStdString();
|
|
MESSAGE("Call system(\"" << cmd << "\") ...");
|
|
|
|
const int status = system(cmd.c_str());
|
|
MESSAGE("status: " << status);
|
|
|
|
// Check results
|
|
if (status != 0 || !Kernel_Utils::IsExists(targetFileName.toStdString()))
|
|
{
|
|
// Get all the output from an error file
|
|
const std::string meshioErrors = ReadErrorsFromFile();
|
|
MESSAGE("meshioErrors: \n" << meshioErrors);
|
|
|
|
SALOME::ExceptionStruct es;
|
|
es.type = SALOME::ExceptionType::BAD_PARAM;
|
|
es.lineNumber = -1;
|
|
es.text = CORBA::string_dup(
|
|
("MESHIO\nFailed system(\"" + cmd + "\").\n\n" + meshioErrors + "\nOperation canceled.").c_str());
|
|
|
|
throw SALOME::SALOME_Exception(es);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
Returns a name for a file in default temp directory
|
|
based on a target basename.
|
|
*/
|
|
QString SMESH_Meshio::CreateTempFileName(const QString& targetFileName)
|
|
{
|
|
// Make a name for a temp file
|
|
const QFileInfo fileInfo(targetFileName);
|
|
const QString targetBaseName = fileInfo.baseName();
|
|
const QString dirName(SALOMEDS_Tool::GetTmpDir().c_str());
|
|
myTempFileName = dirName + targetBaseName + ".med";
|
|
|
|
MESSAGE("targetFileName: " << targetFileName.toStdString());
|
|
MESSAGE("myTempFileName: " << myTempFileName.toStdString());
|
|
|
|
return myTempFileName;
|
|
}
|
|
|
|
/*!
|
|
Removes the temporary file if we have any
|
|
*/
|
|
void SMESH_Meshio::RemoveTempFile()
|
|
{
|
|
if (!myTempFileName.isEmpty())
|
|
{
|
|
std::remove(myTempFileName.toStdString().c_str());
|
|
MESSAGE("Temp file " << myTempFileName.toStdString() << " was removed");
|
|
}
|
|
}
|
|
|
|
/*!
|
|
Returns meshio version string that has valid integer at least in the first position.
|
|
*/
|
|
QString SMESH_Meshio::GetMeshioVersion()
|
|
{
|
|
auto IsVersionStringValid = [](const QString& version) -> bool
|
|
{
|
|
if (version.isEmpty())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Check if we have an integer at least at the first position
|
|
const QStringList curVersionNums = version.split('.');
|
|
|
|
bool ok;
|
|
const int firstNum = curVersionNums[0].toInt(&ok);
|
|
if (!ok)
|
|
{
|
|
ERROR_MESSAGE("meshio version value is not valid!");
|
|
return false;
|
|
}
|
|
|
|
MESSAGE("meshio version first number: " << firstNum);
|
|
return true;
|
|
};
|
|
|
|
auto GetMeshioVersionFromEnv = []() -> QString
|
|
{
|
|
const char *envVar = std::getenv("MESHIO_VERSION");
|
|
if (envVar && (envVar[0] != '\0'))
|
|
{
|
|
MESSAGE("MESHIO_VERSION: " << envVar);
|
|
return envVar;
|
|
}
|
|
|
|
MESSAGE("MESHIO_VERSION is not set!");
|
|
return {};
|
|
};
|
|
|
|
auto GetMeshioVersionHelper = [&]() -> QString
|
|
{
|
|
// Check if we can get a version from environment
|
|
const QString meshioVersionEnv = GetMeshioVersionFromEnv();
|
|
if (IsVersionStringValid(meshioVersionEnv))
|
|
{
|
|
return meshioVersionEnv;
|
|
}
|
|
|
|
// Try to gess a version by installed Python version
|
|
const QString meshioVersionByPython = IsModernPythonVersion() ? "5" : "4";
|
|
MESSAGE("meshio version was defined by Python version: " << meshioVersionByPython.toStdString());
|
|
|
|
return meshioVersionByPython;
|
|
};
|
|
|
|
static const QString meshioVersion = GetMeshioVersionHelper();
|
|
return meshioVersion;
|
|
};
|
|
|
|
/*!
|
|
Returns true if we're going to use meshio version of 5.0 or greater.
|
|
*/
|
|
bool SMESH_Meshio::IsModernMeshioVersion()
|
|
{
|
|
// It's a version when meshio commands were changed from using
|
|
// many executables for each operation to one for everything (meshio 5.0).
|
|
// For example, from
|
|
// meshio-convert input.msh output.vtk
|
|
// to
|
|
// meshio convert input.msh output.vtk
|
|
|
|
auto IsModernVersion = [&]() -> bool
|
|
{
|
|
const QString curVersion = GetMeshioVersion();
|
|
|
|
const int minReqVersion = 5;
|
|
const QStringList curVersionNums = curVersion.split('.');
|
|
if (minReqVersion > curVersionNums[0].toInt())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
static const bool isModern = IsModernVersion();
|
|
return isModern;
|
|
}
|
|
|
|
/*!
|
|
Returns true if meshio is installed
|
|
*/
|
|
bool SMESH_Meshio::IsMeshioInstalled()
|
|
{
|
|
auto IsAllowedFromEnvironment = []() -> bool
|
|
{
|
|
const QString curVersion = GetMeshioVersion();
|
|
|
|
// Check if we explicitly set off using of meshio from environment
|
|
const QStringList curVersionNums = curVersion.split('.');
|
|
const int firstNum = curVersionNums[0].toInt();
|
|
if (firstNum <= 0)
|
|
{
|
|
MESSAGE("meshio was set as not installed from an environment");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
auto IsAbleToCallMeshio = []() -> bool
|
|
{
|
|
// Try to call meshio to check if it's present
|
|
const std::string cmd =
|
|
SMESH_Meshio::IsModernMeshioVersion() ? "meshio --version" : "meshio-info --version";
|
|
|
|
const int status = system(cmd.c_str());
|
|
MESSAGE("status: " << status);
|
|
|
|
return status == 0;
|
|
};
|
|
|
|
static const bool isInstalled = IsAllowedFromEnvironment() && IsAbleToCallMeshio();
|
|
return isInstalled;
|
|
}
|
|
|
|
/*!
|
|
Returns true if current Python equal or newer than required version for
|
|
meshio release from 5.0 and greater.
|
|
*/
|
|
bool SMESH_Meshio::IsModernPythonVersion()
|
|
{
|
|
// It's a version when meshio commands were changed from using
|
|
// many executables for each operation to one for everything (meshio 5.0).
|
|
// For example, from
|
|
// meshio-convert input.msh output.vtk
|
|
// to
|
|
// meshio convert input.msh output.vtk
|
|
|
|
const std::vector<int> minReqVersionNums = { 3, 7 };
|
|
|
|
auto GetCurrentVersion = []() -> QString
|
|
{
|
|
const char *envVar = std::getenv("PYTHON_VERSION");
|
|
if (envVar && (envVar[0] != '\0'))
|
|
{
|
|
return envVar;
|
|
}
|
|
|
|
return {};
|
|
};
|
|
|
|
auto IsModernVersion = [&]() -> bool
|
|
{
|
|
const QString curVersion = GetCurrentVersion();
|
|
MESSAGE("Current Python version: " << curVersion.toStdString())
|
|
if (curVersion.length() < 3)
|
|
return false;
|
|
|
|
int index = 0;
|
|
const QStringList curVersionNums = curVersion.split('.');
|
|
for (const int minVersion : minReqVersionNums)
|
|
{
|
|
if (minVersion > curVersionNums[index].toInt())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
++index;
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
static const bool isModern = IsModernVersion();
|
|
return isModern;
|
|
}
|
|
|
|
/*!
|
|
Creates a temp file for error output from meshio command.
|
|
*/
|
|
void SMESH_Meshio::CreateErrorFileName()
|
|
{
|
|
// Make a name for a temp file
|
|
const QString fileName = "meshio_errors.txt";
|
|
const QString dirName(SALOMEDS_Tool::GetTmpDir().c_str());
|
|
myErrorFileName = dirName + fileName;
|
|
|
|
MESSAGE("myErrorFileName: " << myErrorFileName.toStdString());
|
|
}
|
|
|
|
/*!
|
|
Removes the temporary error output file if we have any
|
|
*/
|
|
void SMESH_Meshio::RemoveErrorFile()
|
|
{
|
|
if (!myErrorFileName.isEmpty())
|
|
{
|
|
std::remove(myErrorFileName.toStdString().c_str());
|
|
MESSAGE("Temp file " << myErrorFileName.toStdString() << " was removed");
|
|
}
|
|
}
|
|
|
|
/*!
|
|
Read all errors output from a temp file
|
|
*/
|
|
std::string SMESH_Meshio::ReadErrorsFromFile() const
|
|
{
|
|
if (myErrorFileName.isEmpty())
|
|
return {};
|
|
|
|
std::ifstream fileStream(myErrorFileName.toStdString());
|
|
if(fileStream)
|
|
{
|
|
std::ostringstream ss;
|
|
ss << fileStream.rdbuf();
|
|
|
|
return ss.str();
|
|
}
|
|
|
|
return {};
|
|
}
|
|
|
|
/*!
|
|
Get optional arguments for meshio convert command
|
|
*/
|
|
QString SMESH_Meshio::GetConvertOptArgs() const
|
|
{
|
|
if (mySelectedFilter.isEmpty())
|
|
return mySelectedFilter;
|
|
|
|
// Check what kind of option we must provide
|
|
if (mySelectedFilter.startsWith("ANSYS"))
|
|
return "-o ansys";
|
|
else if (mySelectedFilter.startsWith("Gmsh 2"))
|
|
return "-o gmsh22";
|
|
else if (mySelectedFilter.startsWith("Gmsh 4"))
|
|
return "-o gmsh";
|
|
|
|
return {};
|
|
}
|