From d8fb185943ac37f7fe54f54f34b42b6a456afc3f Mon Sep 17 00:00:00 2001 From: azakir Date: Thu, 10 Dec 2020 16:15:09 +0100 Subject: [PATCH] mesh adaptation with mg-adapt --- src/SMESHGUI/CMakeLists.txt | 8 + src/SMESHGUI/MG_ADAPT.cxx | 1297 ++++++++++++++++++++ src/SMESHGUI/MG_ADAPT.hxx | 330 ++++++ src/SMESHGUI/MG_ADAPTGUI.cxx | 1367 ++++++++++++++++++++++ src/SMESHGUI/MG_ADAPTGUI.hxx | 312 +++++ src/SMESHGUI/SMESHGUI_MG_ADAPTDRIVER.cxx | 771 ++++++++++++ src/SMESHGUI/SMESHGUI_MG_ADAPTDRIVER.h | 227 ++++ 7 files changed, 4312 insertions(+) create mode 100644 src/SMESHGUI/MG_ADAPT.cxx create mode 100644 src/SMESHGUI/MG_ADAPT.hxx create mode 100644 src/SMESHGUI/MG_ADAPTGUI.cxx create mode 100644 src/SMESHGUI/MG_ADAPTGUI.hxx create mode 100644 src/SMESHGUI/SMESHGUI_MG_ADAPTDRIVER.cxx create mode 100644 src/SMESHGUI/SMESHGUI_MG_ADAPTDRIVER.h diff --git a/src/SMESHGUI/CMakeLists.txt b/src/SMESHGUI/CMakeLists.txt index 642d767df..df5580f27 100644 --- a/src/SMESHGUI/CMakeLists.txt +++ b/src/SMESHGUI/CMakeLists.txt @@ -46,6 +46,7 @@ INCLUDE_DIRECTORIES( ${PROJECT_BINARY_DIR} ${PROJECT_BINARY_DIR}/idl ${PROJECT_BINARY_DIR}/src/ADAPTGUI + ${MEDCOUPLING_INCLUDE_DIRS} ) # additional preprocessor / compiler flags @@ -78,6 +79,7 @@ SET(_link_LIBRARIES ADAPTGUI ADAPTImpl ADAPTEngine + ${MEDCoupling_medloader} ) # --- headers --- @@ -151,6 +153,8 @@ SET(_moc_HEADERS SMESHGUI_IdPreview.h SMESHGUI_PreVisualObj.h SMESHGUI_AdaptDlg.h + SMESHGUI_MG_ADAPTDRIVER.h + MG_ADAPTGUI.hxx # to replace in ../ADAPTGUI/ ) # header files / no moc processing @@ -173,6 +177,7 @@ SET(_other_HEADERS SMESHGUI_FileValidator.h SMESHGUI_SelectionProxy.h SMESH_SMESHGUI.hxx + MG_ADAPT.hxx # to replace in ../ADAPT/ ) # header files / to install @@ -267,6 +272,9 @@ SET(_other_SOURCES SMESHGUI_PreVisualObj.cxx SMESHGUI_IdPreview.cxx SMESHGUI_AdaptDlg.cxx + SMESHGUI_MG_ADAPTDRIVER.cxx + MG_ADAPTGUI.cxx # to replace in ../ADAPTGUI/ + MG_ADAPT.cxx # to replace in ../ADAPT/ ) # sources / to compile diff --git a/src/SMESHGUI/MG_ADAPT.cxx b/src/SMESHGUI/MG_ADAPT.cxx new file mode 100644 index 000000000..305990c33 --- /dev/null +++ b/src/SMESHGUI/MG_ADAPT.cxx @@ -0,0 +1,1297 @@ +// Copyright (C) 2007-2020 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 +// +// 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 +// file : MG_ADAPT.cxx + +#include "MG_ADAPT.hxx" + +#include "MeshFormatReader.hxx" +#include "MeshFormatWriter.hxx" +#include "MEDFileMesh.hxx" +#include "MCAuto.hxx" +#include "MEDFileData.hxx" +#include "MEDFileField.hxx" +#include "MEDCouplingFieldDouble.hxx" + +#include +#include +#include +#include +#include +#include + +namespace +{ +struct GET_DEFAULT // struct used to get default value from GetOptionValue() +{ + bool isDefault; + operator bool* () { + return &isDefault; + } +}; +} + +//---------------------------------------------------------------------------------------- +MgAdapt::MgAdapt() +{ + data = new MgAdaptHypothesisData(); + data->myInMeshName = ""; + data->fromMedFile = defaultFromMedFile(); + data->myFileInDir = defaultWorkingDirectory(); + data->myMeshFileIn = ""; + data->myFileOutDir = defaultWorkingDirectory(); + data->myOutMeshName = ""; + data->myMeshFileOut = ""; + data->myMeshOutMed = defaultMeshOutMed(); + data->myPublish = defaultPublish(); + data->myUseLocalMap = defaultUseLocalMap(); + data->myUseBackgroundMap = defaultUseBackgroundMap(); + data->myFileSizeMapDir = defaultWorkingDirectory(); + data->myMeshFileBackground = ""; + data->myUseConstantValue = defaultUseConstantValue(); + data->myConstantValue = 0.0; + data->myFieldName = ""; + data->myUseNoTimeStep = defaultUseNoTimeStep(); + data->myUseLastTimeStep = defaultUseLastTimeStep(); + data->myUseChosenTimeStep = defaultUseChosenTimeStep(); + data->myTimeStep = -2; + data->myRank = -2; + data->myWorkingDir = defaultWorkingDirectory(); + data->myLogFile = defaultLogFile(); + data->myVerboseLevel = defaultVerboseLevel(); + data->myPrintLogInFile = defaultPrintLogInFile(); + data->myKeepFiles = defaultKeepFiles(); + data->myRemoveLogOnSuccess = defaultRemoveLogOnSuccess(); + + buildModel(); + setAll(); +} +MgAdapt::MgAdapt(MgAdaptHypothesisData* myData) +{ + data = new MgAdaptHypothesisData(); + setData(myData); + buildModel(); +} + +MgAdapt::MgAdapt( const MgAdapt& copy) +{ + + data = new MgAdaptHypothesisData(); + MgAdaptHypothesisData *copyData = copy.getData(); + copyMgAdaptHypothesisData(copyData); + setAll(); + + this->_option2value = copy._option2value; + this->_customOption2value = copy._customOption2value; + this->_defaultOptionValues = copy._defaultOptionValues; + this->_doubleOptions = copy._doubleOptions; + this->_charOptions = copy._charOptions; + this->_boolOptions = copy._boolOptions; + +} + + + +//----------------------------------------------------------------------------------------- +MgAdapt::~MgAdapt() +{ + + delete data; + +} +void MgAdapt::buildModel() +{ + + const char* boolOptionNames[] = { "compute_ridges", // yes + "" // mark of end + }; + // const char* intOptionNames[] = { "max_number_of_errors_printed", // 1 + // "max_number_of_threads", // 4 + // "" // mark of end + // }; + const char* doubleOptionNames[] = { "max_memory", // 0 + "" // mark of end + }; + const char* charOptionNames[] = { "components", // "yes" + "adaptation", // both + "" // mark of end + }; + + int i = 0; + while (boolOptionNames[i][0]) + { + _boolOptions.insert( boolOptionNames[i] ); + _option2value[boolOptionNames[i++]].clear(); + } + // i = 0; + // while (intOptionNames[i][0]) + // _option2value[intOptionNames[i++]].clear(); + + i = 0; + while (doubleOptionNames[i][0]) { + _doubleOptions.insert(doubleOptionNames[i]); + _option2value[doubleOptionNames[i++]].clear(); + } + i = 0; + while (charOptionNames[i][0]) { + _charOptions.insert(charOptionNames[i]); + _option2value[charOptionNames[i++]].clear(); + } + + // default values to be used while MG-Adapt + + _defaultOptionValues["adaptation" ] = "both"; + _defaultOptionValues["components" ] = "outside components"; + _defaultOptionValues["compute_ridges" ] = "yes"; + _defaultOptionValues["max_memory" ] = ToComment(defaultMaximumMemory()); +} + +//============================================================================= +TOptionValues MgAdapt::getOptionValues() const +{ + TOptionValues vals; + TOptionValues::const_iterator op_val = _option2value.begin(); + for ( ; op_val != _option2value.end(); ++op_val ) + vals.insert( make_pair( op_val->first, getOptionValue( op_val->first, GET_DEFAULT() ))); + + return vals; +} + +std::vector MgAdapt::getOptionValuesStrVec() const +{ + std::vector vals; + TOptionValues::const_iterator op_val = _option2value.begin(); + for ( ; op_val != _option2value.end(); ++op_val ) + vals.push_back(op_val->first+":"+getOptionValue( op_val->first, GET_DEFAULT() )); + + return vals; +} + +std::vector MgAdapt::getCustomOptionValuesStrVec() const +{ + std::vector vals; + TOptionValues::const_iterator op_val; + for ( op_val = _customOption2value.begin(); op_val != _customOption2value.end(); ++op_val ) + { + vals.push_back(op_val->first+":"+getOptionValue( op_val->first, GET_DEFAULT() )); + } + return vals; +} +const TOptionValues& MgAdapt::getCustomOptionValues() const +{ + return _customOption2value; +} +void MgAdapt::setData(MgAdaptHypothesisData* myData) +{ + copyMgAdaptHypothesisData(myData); + setAll(); +} +MgAdaptHypothesisData* MgAdapt::getData() const +{ + return data; +} +void MgAdapt::setMedFileIn(std::string fileName) +{ + medFileIn = fileName; +} + +std::string MgAdapt::getMedFileIn() +{ + return medFileIn; +} + +void MgAdapt::setMedFileOut(std::string fileOut) +{ + medFileOut = fileOut; +} + +std::string MgAdapt::getMedFileOut() +{ + return medFileOut; +} +void MgAdapt::setMeshOutMed(bool mybool) +{ + meshOutMed = mybool; +} +bool MgAdapt::getMeshOutMed() +{ + return meshOutMed; +} +void MgAdapt::setPublish(bool mybool) +{ + publish = mybool; +} +bool MgAdapt::getPublish() +{ + return publish; +} +void MgAdapt::setFieldName(std::string myFieldName) +{ + fieldName = myFieldName; +} +std::string MgAdapt::getFieldName() +{ + return fieldName; +} +void MgAdapt::setTimeStep(int time) +{ + timeStep = time; +} +int MgAdapt::getTimeStep() const +{ + return timeStep; +} + +void MgAdapt::setRankTimeStep(int time, int myRank) +{ + timeStep = time; + rank = myRank; +} + +int MgAdapt::getRank() +{ + return rank; +} +void MgAdapt::setUseLocalMap(bool myLocal) +{ + useLocalMap = myLocal; + +} +bool MgAdapt::getUseLocalMap() +{ + return useLocalMap; +} + +void MgAdapt::setUseBackgroundMap(bool bckg) +{ + useBackgroundMap = bckg; + +} +bool MgAdapt::getUseBackgroundMap() +{ + return useBackgroundMap; +} + +void MgAdapt::setUseConstantValue(bool cnst) +{ + useConstantValue = cnst; + +} +bool MgAdapt::getUseConstantValue() +{ + return useConstantValue; +} +void MgAdapt::setLogFile(std::string myLogFile) +{ + logFile = myLogFile; +} +std::string MgAdapt::getLogFile() +{ + return logFile; +} +void MgAdapt::setVerbosityLevel(int verboLevel) +{ + verbosityLevel = verboLevel; +} +int MgAdapt::getVerbosityLevel() +{ + return verbosityLevel; +} +void MgAdapt::setRemoveOnSuccess(bool rmons) +{ + removeOnSuccess = rmons; +} +bool MgAdapt::getRemoveOnSuccess() +{ + return removeOnSuccess; +} +void MgAdapt::setSizeMapFile(std::string mapFile) +{ + sizeMapFile = mapFile; +} +std::string MgAdapt::getSizeMapFile() +{ + return sizeMapFile; +} + +void MgAdapt::setMeshName(std::string name) +{ + meshName = name; +} +std::string MgAdapt::getMeshName() +{ + return meshName; +} +void MgAdapt::setMeshNameOut(std::string name) +{ + meshNameOut = name; +} +std::string MgAdapt::getMeshNameOut() +{ + return meshNameOut; +} +void MgAdapt::setFromMedFile(bool mybool) +{ + fromMedFile = mybool; +} +bool MgAdapt::isFromMedFile() +{ + return fromMedFile; +} +void MgAdapt::setConstantValue(double cnst) +{ + constantValue = cnst; +} +bool MgAdapt::getConstantValue() +{ + return constantValue; +} + +void MgAdapt::setWorkingDir(std::string dir) +{ + workingDir = dir; +} +std::string MgAdapt::getWorkingDir() const +{ + return workingDir; +} +void MgAdapt::setKeepWorkingFiles(bool mybool) +{ + toKeepWorkingFiles = mybool; +} +bool MgAdapt::getKeepWorkingFiles() +{ + return toKeepWorkingFiles; +} +void MgAdapt::setPrintLogInFile(bool print) +{ + printLogInFile = print; +} +bool MgAdapt::getPrintLogInFile() +{ + return printLogInFile; +} + +bool MgAdapt::setAll() +{ + + setFromMedFile(data->fromMedFile); + std::string file; + checkDirPath(data->myFileInDir); + file = data->myFileInDir+data->myMeshFileIn; + setMedFileIn(file); + setMeshName(data->myInMeshName); + setMeshNameOut(data->myOutMeshName); + checkDirPath(data->myFileOutDir); + std::string out = data->myFileOutDir+data->myMeshFileOut; + setMedFileOut(out); + setPublish(data->myPublish); + setMeshOutMed(data->myMeshOutMed); + setUseLocalMap(data->myUseLocalMap); + setUseBackgroundMap(data->myUseBackgroundMap); + setUseConstantValue(data->myUseConstantValue); + + std::string mapfile; + if (useBackgroundMap) + { + + checkDirPath(data->myFileSizeMapDir); + mapfile = data->myFileSizeMapDir+data->myMeshFileBackground; + setFieldName(data->myFieldName); + } + else if (useConstantValue) + { + setConstantValue(data->myConstantValue); + } + else + { + mapfile =""; + setConstantValue(0.0); + setFieldName(data->myFieldName); + + } + + setSizeMapFile(mapfile); + int rank; + int tmst; + if (data->myUseNoTimeStep) + { + rank = MED_NO_IT; + tmst = MED_NO_DT ; + } + else if (data->myUseLastTimeStep) + { + std::string fieldFile = useBackgroundMap ? sizeMapFile : medFileIn; + getTimeStepInfos(fieldFile, tmst, rank); + } + else + { + rank = data->myRank; + tmst = data->myTimeStep; + } + setRankTimeStep(tmst, rank); + + /* Advanced options */ + setWorkingDir(data->myWorkingDir); + checkDirPath(data->myWorkingDir); + setLogFile(data->myWorkingDir+defaultLogFile()); + setVerbosityLevel(data->myVerboseLevel); + setRemoveOnSuccess(data->myRemoveLogOnSuccess); + setPrintLogInFile(data->myPrintLogInFile); + setKeepWorkingFiles(data->myKeepFiles); + + return true; +} + +void MgAdapt::checkDirPath(std::string& dirPath) +{ + const char lastChar = *dirPath.rbegin(); +#ifdef WIN32 + if(lastChar != '\\') dirPath+='\\'; +#else + if(lastChar != '/') dirPath+='/'; +#endif +} +//============================================================================= +void MgAdapt::setOptionValue(const std::string& optionName, + const std::string& optionValue) +throw (std::invalid_argument) +{ + TOptionValues::iterator op_val = _option2value.find(optionName); + if (op_val == _option2value.end()) + { + op_val = _customOption2value.find( optionName ); + _customOption2value[ optionName ] = optionValue; + return; + } + + if (op_val->second != optionValue) + { + const char* ptr = optionValue.c_str(); + // strip white spaces + while (ptr[0] == ' ') + ptr++; + int i = strlen(ptr); + while (i != 0 && ptr[i - 1] == ' ') + i--; + // check value type + bool typeOk = true; + std::string typeName; + if (i == 0) { + // empty string + } else if (_charOptions.count(optionName)) { + // do not check strings + } else if (_doubleOptions.count(optionName)) { + // check if value is double + toDbl(ptr, &typeOk); + typeName = "real"; + } else if (_boolOptions.count(optionName)) { + // check if value is bool + toBool(ptr, &typeOk); + typeName = "bool"; + } else { + // check if value is int + toInt(ptr, &typeOk); + typeName = "integer"; + } + if ( typeOk ) // check some specific values ? + { + } + if ( !typeOk ) + { + std::string msg = "Advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName; + throw std::invalid_argument(msg); + } + std::string value( ptr, i ); + if ( _defaultOptionValues[ optionName ] == value ) + value.clear(); + + + op_val->second = value; + + } +} +//============================================================================= +//! Return option value. If isDefault provided, it can be a default value, +// then *isDefault == true. If isDefault is not provided, the value will be +// empty if it equals a default one. +std::string MgAdapt::getOptionValue(const std::string& optionName, bool* isDefault) const +throw (std::invalid_argument) +{ + TOptionValues::const_iterator op_val = _option2value.find(optionName); + if (op_val == _option2value.end()) + { + op_val = _customOption2value.find(optionName); + if (op_val == _customOption2value.end()) + { + std::string msg = "Unknown MG-Adapt option: <" + optionName + ">"; + throw std::invalid_argument(msg); + } + } + std::string val = op_val->second; + if ( isDefault ) *isDefault = ( val.empty() ); + + if ( val.empty() && isDefault ) + { + op_val = _defaultOptionValues.find( optionName ); + if (op_val != _defaultOptionValues.end()) + val = op_val->second; + } + return val; +} +//================================================================================ +/*! + * \brief Converts a string to a real value + */ +//================================================================================ + +double MgAdapt::toDbl(const std::string& str, bool* isOk ) +throw (std::invalid_argument) +{ + if ( str.empty() ) throw std::invalid_argument("Empty value provided"); + + char * endPtr; + double val = strtod(&str[0], &endPtr); + bool ok = (&str[0] != endPtr); + + if ( isOk ) *isOk = ok; + + if ( !ok ) + { + std::string msg = "Not a real value:'" + str + "'"; + throw std::invalid_argument(msg); + } + return val; +} +//================================================================================ +/*! + * \brief Converts a string to a bool + */ +//================================================================================ + +bool MgAdapt::toBool(const std::string& str, bool* isOk ) +throw (std::invalid_argument) +{ + std::string s = str; + if ( isOk ) *isOk = true; + + for ( size_t i = 0; i <= s.size(); ++i ) + s[i] = tolower( s[i] ); + + if ( s == "1" || s == "true" || s == "active" || s == "yes" ) + return true; + + if ( s == "0" || s == "false" || s == "inactive" || s == "no" ) + return false; + + if ( isOk ) + *isOk = false; + else { + std::string msg = "Not a Boolean value:'" + str + "'"; + throw std::invalid_argument(msg); + } + return false; +} +//================================================================================ +/*! + * \brief Converts a string to a integer value + */ +//================================================================================ + +int MgAdapt::toInt(const std::string& str, bool* isOk ) +throw (std::invalid_argument) +{ + if ( str.empty() ) throw std::invalid_argument("Empty value provided"); + + char * endPtr; + int val = (int)strtol( &str[0], &endPtr, 10); + bool ok = (&str[0] != endPtr); + + if ( isOk ) *isOk = ok; + + if ( !ok ) + { + std::string msg = "Not an integer value:'" + str + "'"; + throw std::invalid_argument(msg); + } + return val; +} +//============================================================================= +bool MgAdapt::hasOptionDefined( const std::string& optionName ) const +{ + bool isDefault = false; + try + { + getOptionValue( optionName, &isDefault ); + } + catch ( std::invalid_argument ) + { + return false; + } + return !isDefault; +} +//================================================================================ +/*! + * \brief Return command to run MG-Tetra mesher excluding file prefix (-f) + */ +//================================================================================ + +std::string MgAdapt::getCommandToRun(MgAdapt* hyp) +{ + return hyp ? hyp->getCommandToRun() : ToComment("error with hypothesis!"); +} + + + +int MgAdapt::compute(std::string& errStr) +{ + std::string cmd= getCommandToRun(); + int err = 0; + execCmd( cmd.c_str(), err ); // run + + if ( err ) + { + errStr = ToComment("system(mg-adapt.exe ...) command failed with error: ") + << strerror( errno ); + } + else + { + convertMeshFile(meshFormatOutputMesh, solFormatOutput); + } + return err; +} + +void MgAdapt::execCmd( const char* cmd, int& err) +{ + err = 1; + std::array buffer; + std:: ofstream logStream; + logStream.open(logFile); + std::unique_ptr pipe(popen(cmd, "r"), pclose ); + if(!pipe) + { + throw std::runtime_error("popen() failed!"); + } + while(fgets(buffer.data(), buffer.size(), pipe.get()) !=nullptr ) + { + logStream<begin(); + for ( ; o2v != options[iOp]->end(); ++o2v ) + { + option = o2v->first; + value = getOptionValue( option, &isDefault ); + + if ( isDefault ) + continue; + if ( value.empty() )//value == NoValue() ) + { + if ( _defaultOptionValues.count( option )) + continue; // non-custom option with no value + //value.clear(); + } + if ( strncmp( "no", option.c_str(), 2 ) == 0 ) // options w/o values: --no_* + { + if ( !value.empty() && toBool( value ) == false ) + continue; + value.clear(); + } + if ( option[0] != '-' ) + cmd += " --"; + else + cmd += " "; + cmd += option + " " + value; + } + } + //~} +//~cmd+= " >" +#ifdef WIN32 + cmd += " < NUL"; +#endif + + return cmd; +} + + +bool MgAdapt::isFileExist(std::string& fName) const +{ + + if ( fName.empty() ) + return false; + + boost::system::error_code err; + bool res = boost::filesystem::exists( fName, err ); + + return err ? false : res; +} +//======================================================================= +//function : defaultMaximumMemory +//======================================================================= + +#if defined(WIN32) +#include +#elif !defined(__APPLE__) +#include +#endif + +double MgAdapt::defaultMaximumMemory() +{ +#if defined(WIN32) + // See http://msdn.microsoft.com/en-us/library/aa366589.aspx + MEMORYSTATUSEX statex; + statex.dwLength = sizeof (statex); + long err = GlobalMemoryStatusEx (&statex); + if (err != 0) { + double totMB = (double)statex.ullAvailPhys / 1024. / 1024.; + return (double)( 0.7 * totMB ); + } +#elif !defined(__APPLE__) + struct sysinfo si; + long err = sysinfo( &si ); + if ( err == 0 ) { + long ramMB = si.totalram * si.mem_unit / 1024 / 1024; + return ( 0.7 * ramMB ); + } +#endif + return 1024; +} + + +//======================================================================= +//function : defaultWorkingDirectory +//======================================================================= + +std::string MgAdapt::defaultWorkingDirectory() +{ + TCollection_AsciiString aTmpDir; + + char *Tmp_dir = getenv("SALOME_TMP_DIR"); + if(Tmp_dir != NULL) { + aTmpDir = Tmp_dir; + } + else { +#ifdef WIN32 + aTmpDir = TCollection_AsciiString("C:\\"); +#else + aTmpDir = TCollection_AsciiString("/tmp/"); +#endif + } + return aTmpDir.ToCString(); +} +//================================================================================ +/*! + * \brief Return a unique file name + */ +//================================================================================ + +std::string MgAdapt::getFileName() const +{ + std::string aTmpDir = workingDir; + const char lastChar = *aTmpDir.rbegin(); +#ifdef WIN32 + if(lastChar != '\\') aTmpDir+='\\'; +#else + if(lastChar != '/') aTmpDir+='/'; +#endif + + TCollection_AsciiString aGenericName = (char*)aTmpDir.c_str(); + aGenericName += "MgAdapt_"; + aGenericName += getpid(); + aGenericName += "_"; + aGenericName += Abs((Standard_Integer)(long) aGenericName.ToCString()); + + return aGenericName.ToCString(); +} +//======================================================================= +//function : defaultLogFile +//======================================================================= + +std::string MgAdapt::defaultLogFile() +{ + std::string alogFile("MG_ADAPT.log"); + return alogFile; +} +//======================================================================= +//function : defaultUseConstantValue +//======================================================================= + +bool MgAdapt::defaultUseConstantValue() +{ + return false; +} +//======================================================================= +//function : defaultUseNoTimeStep +//======================================================================= + +bool MgAdapt::defaultUseNoTimeStep() +{ + return true; +} +//======================================================================= +//function : defaultRemoveLogOnSuccess +//======================================================================= + +bool MgAdapt::defaultRemoveLogOnSuccess() +{ + return true; +} +//======================================================================= +//function : defaultPrintLogInFile +//======================================================================= + +bool MgAdapt::defaultPrintLogInFile() +{ + return false; +} +//======================================================================= +//function : defaultUseChosenTimeStep +//======================================================================= + +bool MgAdapt::defaultUseChosenTimeStep() +{ + return false; +} +//======================================================================= +//function : UseLastTimeStep +//======================================================================= + +bool MgAdapt::defaultUseLastTimeStep() +{ + return false; +} +//======================================================================= +//function : defaultUseBackgroundMap +//======================================================================= + +bool MgAdapt::defaultUseBackgroundMap() +{ + return false; +} +//======================================================================= +//function : defaultKeepFiles +//======================================================================= + +bool MgAdapt::defaultKeepFiles() +{ + return false; +} +//======================================================================= +//function : defaultUseLocalMap +//======================================================================= + +bool MgAdapt::defaultUseLocalMap() +{ + return true; +} +//======================================================================= +//function : defaultPublish +//======================================================================= + +bool MgAdapt::defaultPublish() +{ + return false; +} +//======================================================================= +//function : defaultMeshOutMed +//======================================================================= + +bool MgAdapt::defaultMeshOutMed() +{ + return true; +} +//======================================================================= +//function : defaultFromMedFile +//======================================================================= + +bool MgAdapt::defaultFromMedFile() +{ + return true; +} +//======================================================================= +//function : defaultVerboseLevel +//======================================================================= + +int MgAdapt::defaultVerboseLevel() +{ + return 3; +} +std::string MgAdapt::getExeName() +{ + return "mg-adapt.exe"; +} +void MgAdapt::copyMgAdaptHypothesisData( MgAdaptHypothesisData* from) +{ + + data->myFileInDir = from->myFileInDir; + data->myMeshFileIn = from->myMeshFileIn; + data->myMeshFileBackground = from->myMeshFileBackground; + data->myOutMeshName = from->myOutMeshName; + data->myMeshFileOut = from->myMeshFileOut; + data->myFileOutDir = from->myFileOutDir; + data->myFileSizeMapDir = from->myFileSizeMapDir; + data->myFieldName = from->myFieldName; + data->fromMedFile = from->fromMedFile; + data->myPublish = from->myPublish; + data->myMeshOutMed = from->myMeshOutMed; + data->myUseLocalMap = from->myUseLocalMap; + data->myUseBackgroundMap = from->myUseBackgroundMap; + data->myUseConstantValue = from->myUseConstantValue; + data->myConstantValue = from->myConstantValue; + data->myTimeStep = from->myTimeStep; + data->myRank = from->myRank; + data->myUseNoTimeStep = from->myUseNoTimeStep; + data->myUseLastTimeStep = from->myUseLastTimeStep; + data->myUseChosenTimeStep = from->myUseChosenTimeStep; + data->myWorkingDir = from->myWorkingDir; + data->myLogFile = from->myLogFile; + data->myPrintLogInFile = from->myPrintLogInFile; + data->myKeepFiles = from->myKeepFiles; + data->myRemoveLogOnSuccess = from->myRemoveLogOnSuccess; + data->myVerboseLevel = from->myVerboseLevel; + +} + + +void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& solFormatFieldFileName, std::string& meshFormatsizeMapFile) +{ + + std::vector fieldFileNames; + MeshFormatWriter writer; + MEDCoupling::MCAuto mfd = MEDCoupling::MEDFileData::New(medFileIn); + MEDCoupling::MEDFileMeshes* meshes = mfd->getMeshes(); + MEDCoupling::MEDFileMesh* fileMesh = meshes->getMeshAtPos(0); // ok only one mesh in file! + storeGroupsAndFams(fileMesh); + + MEDCoupling::MCAuto fields = MEDCoupling::MEDFileFields::New(); + solFormatFieldFileName = getFileName(); + solFormatFieldFileName+=".sol"; + fieldFileNames.push_back(solFormatFieldFileName); + + if (useBackgroundMap) + { + + meshFormatsizeMapFile = getFileName(); + meshFormatsizeMapFile += ".mesh"; + MEDCoupling::MCAuto tmpMfd = MEDCoupling::MEDFileData::New(sizeMapFile); + MEDCoupling::MEDFileFields* tmpFields = tmpMfd->getFields(); + MEDCoupling::MEDFileAnyTypeFieldMultiTS* fts = tmpFields->getFieldWithName(fieldName); + MEDCoupling::MCAuto fts1 = dynamic_cast(fts); + MEDCoupling::MCAuto f = fts1->getTimeStep(timeStep, rank); + MEDCoupling::MCAuto tmFts = MEDCoupling::MEDFileFieldMultiTS::New(); + tmFts->pushBackTimeStep(f); + + MEDCoupling::MCAuto tmp_fields = MEDCoupling::MEDFileFields::New(); + tmp_fields->pushField(tmFts); + + + tmpMfd->setFields( tmp_fields ); + MeshFormatWriter tmpWriter; + tmpWriter.setMeshFileName(meshFormatsizeMapFile); + tmpWriter.setFieldFileNames( fieldFileNames); + tmpWriter.setMEDFileDS(tmpMfd); + tmpWriter.write(); + + + } + else if(useLocalMap) + { + + MEDCoupling::MCAuto fts = dynamic_cast( mfd->getFields()->getFieldWithName(fieldName) ); + MEDCoupling::MCAuto f = fts->getTimeStep(timeStep, rank); + MEDCoupling::MCAuto tmFts = MEDCoupling::MEDFileFieldMultiTS::New(); + tmFts->pushBackTimeStep(f); + + fields->pushField(tmFts); + + writer.setFieldFileNames( fieldFileNames); + } + + else + { + MEDCoupling::MEDCouplingMesh* mesh = fileMesh->getMeshAtLevel(1); // nodes mesh + MEDCoupling::MEDCouplingFieldDouble* fieldOnNodes=MEDCoupling::MEDCouplingFieldDouble::New(MEDCoupling::ON_NODES,MEDCoupling::NO_TIME); + fieldOnNodes->setName("MyScalarFieldOnNodeNoTime"); + fieldOnNodes->setMesh(mesh); + mesh->decrRef(); // no more need of mesh because mesh has been attached to fieldOnNodes + MEDCoupling::DataArrayDouble *array=MEDCoupling::DataArrayDouble::New(); + array->alloc(fieldOnNodes->getMesh()->getNumberOfNodes(),1);//Implicitly fieldOnNodes will be a 1 component field. + array->fillWithValue(constantValue); + fieldOnNodes->setArray(array); + array->decrRef(); + // fieldOnNodes is now usable + // ... + // fieldOnNodes is no more useful h + + } + + mfd->setFields( fields ); + meshFormatMeshFileName = getFileName(); + meshFormatMeshFileName+=".mesh"; + writer.setMeshFileName(meshFormatMeshFileName); + writer.setMEDFileDS( mfd); + writer.write(); + +} + +void MgAdapt::convertMeshFile(std::string& meshFormatIn, std::vector< std::string>& solFieldFileNames) const +{ + MeshFormatReader reader(meshFormatIn, solFieldFileNames); + + MEDCoupling::MCAuto mfd = reader.loadInMedFileDS(); + // write MED + MEDCoupling::MEDFileMeshes* meshes = mfd->getMeshes(); + MEDCoupling::MEDFileMesh* fileMesh = meshes->getMeshAtPos(0); // ok only one mesh in file! + fileMesh->setName(meshNameOut); + restoreGroupsAndFams(fileMesh); + mfd->write(medFileOut, 2); +} + + +void MgAdapt::storeGroupsAndFams(MEDCoupling::MEDFileMesh* fileMesh) +{ + storefams(fileMesh); + storeGroups(fileMesh); +} + +void MgAdapt::restoreGroupsAndFams(MEDCoupling::MEDFileMesh* fileMesh) const +{ + restorefams(fileMesh); + restoreGroups(fileMesh); +} +void MgAdapt::storeGroups(MEDCoupling::MEDFileMesh* fileMesh) +{ + std::map > grpFams = fileMesh->getGroupInfo(); + std::map >::iterator g2ff = grpFams.begin(); + + for ( ; g2ff != grpFams.end(); ++g2ff ) + { + std::string groupName = g2ff->first; + std::vector famNames = g2ff->second; + + if ( famNames.empty() ) continue; + std::size_t k = 0; + std::vector< mcIdType> famListId; + for ( size_t i = 0; i < famNames.size(); ++i ) + { + famListId.push_back( fileMesh->getFamilyId( famNames[i].c_str() ) ); + } + group grp(groupName, famListId, famNames); + groupVec.push_back(grp); + } +} + +void MgAdapt::storefams(MEDCoupling::MEDFileMesh* fileMesh) +{ + std::map grpFams = fileMesh->getFamilyInfo(); + std::map::iterator f = grpFams.begin(); + + for ( ; f != grpFams.end(); ++f ) + { + if(!f->second) continue; // FAMILLE_ZERO + family fs(f->first, f->second); + famVec.push_back(fs); + } + +} + +void MgAdapt::restorefams(MEDCoupling::MEDFileMesh* fileMesh) const +{ + std::vector::const_iterator fIt = famVec.begin(); + + for (; fIt!=famVec.end(); ++fIt) + { + std::string givenFamNameFromMeshGemConverter = fileMesh->getFamilyNameGivenId( fIt->_famId ); + fileMesh->changeFamilyName(givenFamNameFromMeshGemConverter, fIt->_famName); + } +} + +void MgAdapt::restoreGroups(MEDCoupling::MEDFileMesh* fileMesh) const +{ + std::map > info; + std::vector ::const_iterator grpFams = groupVec.begin(); + + for (; grpFams!=groupVec.end(); ++grpFams) + { + info.insert(std::pair > (grpFams->_name, grpFams->_famNames) ); + } + + fileMesh->setGroupInfo(info); +} +// ======================================================================= +med_idt MgAdapt::openMedFile(const std::string aFile) +// ======================================================================= +// renvoie le medId associe au fichier Med apres ouverture +{ + med_idt medIdt = MEDfileOpen(aFile.c_str(),MED_ACC_RDONLY); + if (medIdt <0) + { + //~addMessage( ToComment(" error: Can't open ") << aFile, /*fatal=*/true ); + ; + } + return medIdt; +} + +MgAdapt::Status MgAdapt::addMessage(const std::string& msg, + const bool isFatal/*=false*/) +{ + if ( isFatal ) + _myErrorMessages.clear(); // warnings are useless if a fatal error encounters + + _myErrorMessages.push_back( msg ); + + //~MESSAGE(msg); +#ifdef _DEBUG_ + std::cout << msg << std::endl; +#endif + return ( _myStatus = isFatal ? MgAdapt::DRS_FAIL : MgAdapt::DRS_WARN_SKIP_ELEM ); +} + + + + +// ======================================================================= +void MgAdapt::getTimeStepInfos(std::string aFile, int& numdt, int& numit) +// ======================================================================= +{ +// Il faut voir si plusieurs maillages + + + med_err erreur = 0 ; + med_idt medIdt ; + + + // Ouverture du fichier + //~SCRUTE(aFile.toStdString()); + medIdt = openMedFile(aFile); + if ( medIdt < 0 ) return ; + // Lecture du nombre de champs + med_int ncha = MEDnField(medIdt) ; + if (ncha < 1 ) + { + //~addMessage( ToComment(" error: there is no field in ") << aFile, /*fatal=*/true ); + return; + } + // Lecture des caracteristiques du champs + + // Lecture du type du champ, des noms des composantes et du nom de l'unite + char nomcha [MED_NAME_SIZE+1]; + strcpy(nomcha, fieldName.c_str()); +// Lecture du nombre de composantes + med_int ncomp = MEDfieldnComponentByName(medIdt, nomcha); + char meshname[MED_NAME_SIZE+1]; + char * comp = (char*) malloc(ncomp*MED_SNAME_SIZE+1); + char * unit = (char*) malloc(ncomp*MED_SNAME_SIZE+1); + char dtunit[MED_SNAME_SIZE+1]; + med_bool local; + med_field_type typcha; + med_int nbofcstp; + erreur = MEDfieldInfoByName (medIdt, nomcha, meshname,&local,&typcha,comp,unit,dtunit, &nbofcstp); + free(comp); + free(unit); + if ( erreur < 0 ) + { + //~addMessage( ToComment(" error: error while reading field ") << nomcha << " in file " << aFile , /*fatal=*/true ); + return; + } + + med_float dt; + int tmp_numdt, tmp_numit; + + med_int step = data->myUseLastTimeStep ? nbofcstp : data->myTimeStep+1; + //~myPrint("step ", step); + erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, step, &tmp_numdt, &tmp_numit, &dt ); + if ( erreur < 0 ) + { + + //~addMessage( ToComment(" error: error while reading field last time step ") << nomcha << " in file " << aFile , /*fatal=*/true ); + return; + } + + numdt = tmp_numdt; + numit = tmp_numit; + + + // Fermeture du fichier + if ( medIdt > 0 ) MEDfileClose(medIdt); + + +} + + + diff --git a/src/SMESHGUI/MG_ADAPT.hxx b/src/SMESHGUI/MG_ADAPT.hxx new file mode 100644 index 000000000..f81dd03c5 --- /dev/null +++ b/src/SMESHGUI/MG_ADAPT.hxx @@ -0,0 +1,330 @@ +// Copyright (C) 2011-2020 CEA/DEN, EDF R&D +// +// 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 +// + +// +// File : MG_ADAPT.hxx +// +#ifndef MG_ADAPT_HXX +#define MG_ADAPT_HXX +#include +# include +#include +#include +#include +#include + +#include "MCAuto.hxx" +#include "MCType.hxx" +#include "MEDFileMesh.hxx" + +#include +// SMESH includes + +//~#include + + +class MgAdapt; + +typedef std::map< std::string, std::string > TOptionValues; +typedef std::set< std::string > TOptionNames; + +struct MgAdaptHypothesisData +{ + std::string myFileInDir, myMeshFileIn, myInMeshName, myMeshFileBackground, myOutMeshName, + myMeshFileOut, myFileOutDir, myFileSizeMapDir, myFieldName; + bool fromMedFile; + bool myPublish, myMeshOutMed; + bool myUseLocalMap, myUseBackgroundMap, myUseConstantValue; + double myConstantValue; + int myRank, myTimeStep; + bool myUseNoTimeStep, myUseLastTimeStep, myUseChosenTimeStep; + std::string myWorkingDir, myLogFile; + bool myPrintLogInFile, myKeepFiles, myRemoveLogOnSuccess; + int myVerboseLevel; + +}; + + + +/*! + * \brief Class to generate string from any type + */ +class ToComment : public std::string +{ + std::ostringstream _s ; + +public : + + ToComment():std::string("") {} + + ToComment(const ToComment& c):std::string() { + _s << c.c_str() ; + this->std::string::operator=( _s.str() ); + } + + ToComment & operator=(const ToComment& c) { + _s << c.c_str() ; + this->std::string::operator=( _s.str() ); + return *this; + } + + template + ToComment( const T &anything ) { + _s << anything ; + this->std::string::operator=( _s.str() ); + } + + template + ToComment & operator<<( const T &anything ) { + _s << anything ; + this->std::string::operator=( _s.str() ); + return *this ; + } + + operator char*() const { + return (char*)c_str(); + } + + std::ostream& Stream() { + return _s; + } +}; + + +class MgAdapt +{ + enum YesNo {YES, NO}; +public: + + MgAdapt(); + MgAdapt(MgAdaptHypothesisData*); + MgAdapt(const MgAdapt&); + ~MgAdapt(); + void buildModel(); + void setData( MgAdaptHypothesisData*); + + void setMedFileIn(std::string); + std::string getMedFileIn(); + + void setMedFileOut(std::string); + std::string getMedFileOut(); + + void setMeshName(std::string); + std::string getMeshName(); + + void setMeshNameOut(std::string); + std::string getMeshNameOut(); + + void setMeshOutMed(bool); + bool getMeshOutMed(); + + void setPublish(bool); + bool getPublish(); + + void setFieldName(std::string); + std::string getFieldName(); + + void setTimeStep(int); + int getTimeStep() const; + + void setRankTimeStep(int, int ); + int getRank(); + + void setLogFile(std::string); + std::string getLogFile(); + + void setVerbosityLevel(int); + int getVerbosityLevel(); + + void setRemoveOnSuccess(bool); + bool getRemoveOnSuccess(); + + MgAdaptHypothesisData* getData() const; + + void setUseLocalMap(bool); + bool getUseLocalMap(); + + void setUseBackgroundMap(bool); + bool getUseBackgroundMap(); + + void setUseConstantValue(bool); + bool getUseConstantValue(); + + void setConstantValue(double); + bool getConstantValue(); + + void setSizeMapFile(std::string); + std::string getSizeMapFile(); + + void setFromMedFile(bool); + bool isFromMedFile(); + + void setKeepWorkingFiles(bool); + bool getKeepWorkingFiles(); + + void setPrintLogInFile(bool); + bool getPrintLogInFile(); + + void setWorkingDir(std::string); + std::string getWorkingDir() const; + + + bool setAll(); + static std::string getCommandToRun(MgAdapt* ); + std::string getCommandToRun() ; + int compute(std::string& errStr); + std::string getFileName() const; + static std::string getExeName(); + void copyMgAdaptHypothesisData( MgAdaptHypothesisData* ) ; + + void checkDirPath(std::string& ); + + + + bool hasOptionDefined( const std::string& optionName ) const; + void setOptionValue(const std::string& optionName, + const std::string& optionValue) throw (std::invalid_argument); + std::string getOptionValue(const std::string& optionName, + bool* isDefault=0) const throw (std::invalid_argument); + std::vector getCustomOptionValuesStrVec() const; + std::vector getOptionValuesStrVec() const; + + + TOptionValues getOptionValues() const; + const TOptionValues& getCustomOptionValues() const ; + static double toDbl(const std::string&, bool* isOk = 0) throw (std::invalid_argument); + static bool toBool(const std::string&, bool* isOk = 0) throw (std::invalid_argument); + static int toInt(const std::string&, bool* isOk = 0 ) throw (std::invalid_argument); + + + /* default values */ + static std::string defaultWorkingDirectory(); + static std::string defaultLogFile(); + static bool defaultKeepFiles(); + static bool defaultRemoveLogOnSuccess(); + static int defaultVerboseLevel(); + static bool defaultPrintLogInFile(); + static bool defaultFromMedFile(); + static bool defaultMeshOutMed(); + static bool defaultPublish(); + static bool defaultUseLocalMap(); + static bool defaultUseBackgroundMap(); + static bool defaultUseConstantValue(); + static bool defaultUseNoTimeStep(); + static bool defaultUseLastTimeStep(); + static bool defaultUseChosenTimeStep(); + static double defaultMaximumMemory(); + + + + + enum Status { + DRS_OK, + DRS_EMPTY, // a file contains no mesh with the given name + DRS_WARN_RENUMBER, // a file has overlapped ranges of element numbers, + // so the numbers from the file are ignored + DRS_WARN_SKIP_ELEM, // some elements were skipped due to incorrect file data + DRS_WARN_DESCENDING, // some elements were skipped due to descending connectivity + DRS_FAIL, // general failure (exception etc.) + DRS_NO_TIME_STEP // general failure (exception etc.) + }; + + struct group { + + std::string _name; + std::vector _famListId; + std::vector _famNames; + group(std::string name, std::vector famListId, std::vector famNames):_name(name) + { + std::vector::iterator it = famListId.begin(); + for (; it!=famListId.end(); ++it) + _famListId.push_back(*it); + + std::vector::iterator itt = famNames.begin(); + for (; itt!=famNames.end(); ++itt) + _famNames.push_back(*itt); + } + }; + + struct family { + std::string _famName; + mcIdType _famId; + family(std::string famName, MEDCoupling::mcIdType famId):_famName(famName), _famId(famId) {} + }; + + +private : + bool fromMedFile; + + std::string medFileIn; + std::string medFileOut; + std::string meshName; + std::string meshNameOut; + bool publish, meshOutMed; + bool useLocalMap, useBackgroundMap, useConstantValue; + std::string sizeMapFile; + std::string fieldName; + double constantValue; + int rank, timeStep; + + /* advanced options */ + + + std::string logFile; + std::string workingDir; + int verbosityLevel; + bool removeOnSuccess; + bool toKeepWorkingFiles; + bool printLogInFile; + + /* Model DATA */ + MgAdaptHypothesisData* data; + + /* */ + + TOptionValues _option2value, _customOption2value; // user defined values + TOptionValues _defaultOptionValues; // default values + TOptionNames _doubleOptions, _charOptions, _boolOptions; // to find a type of option + + std::vector _myErrorMessages; + Status _myStatus; + std::string meshFormatOutputMesh; + std::vector< std::string> solFormatOutput; + std::vector groupVec; + std::vector famVec; + + /* convert MED-->.mesh format */ + void convertMedFile(std::string& meshIn,std::string& solFileIn, std::string& sizeMapIn) ; + void storeGroups(MEDCoupling::MEDFileMesh* fileMesh); + void restoreGroups(MEDCoupling::MEDFileMesh* fileMesh) const; + void storefams(MEDCoupling::MEDFileMesh* fileMesh); + void restorefams(MEDCoupling::MEDFileMesh* fileMesh) const; + void storeGroupsAndFams(MEDCoupling::MEDFileMesh* fileMesh); + void restoreGroupsAndFams(MEDCoupling::MEDFileMesh* fileMesh) const; + void convertMeshFile(std::string& meshFormatIn, std::vector< std::string>& solFieldFileNames) const ; + void getTimeStepInfos(std::string aFile, int& numdt, int& numit); + Status addMessage(const std::string& msg, const bool isFatal = false); + med_idt openMedFile(const std::string aFile) ; + bool isFileExist(std::string& fName) const; + void execCmd( const char* cmd, int& err); +}; + + + +#endif // MG_ADAPT_HXX diff --git a/src/SMESHGUI/MG_ADAPTGUI.cxx b/src/SMESHGUI/MG_ADAPTGUI.cxx new file mode 100644 index 000000000..628912e46 --- /dev/null +++ b/src/SMESHGUI/MG_ADAPTGUI.cxx @@ -0,0 +1,1367 @@ +// Copyright (C) 2007-2020 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 +// +// 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 +// +// file : MG_ADAPTGUI.cxx + +#include "MG_ADAPTGUI.hxx" + +#include "SUIT_Desktop.h" +#include "SUIT_Application.h" +#include "SUIT_Session.h" + +#include "SalomeApp_Application.h" +#include "SalomeApp_Module.h" +#include "SalomeApp_Study.h" +#include "SMESH_Actor.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +// SALOME KERNEL includes +#include +#include +#include +#include +#include "SalomeApp_Tools.h" +#include +#include +#include + +#include + + +const int SPACING = 6; // layout spacing +const int MARGIN = 9; // layout margin + +//================================================================================= +// function : SMESHGUI_MgAdaptDlg() +// purpose : +//================================================================================= +SMESHGUI_MgAdaptDlg::SMESHGUI_MgAdaptDlg( SalomeApp_Module* theModule, MgAdapt* myModel, QWidget* parent, bool isCreation ) + : mySMESHGUI( theModule ), QDialog(parent) +{ + model = new MgAdapt(*myModel); + myData = model->getData(); + buildDlg(); + if (!isCreation) readParamsFromHypo(); +} + +void SMESHGUI_MgAdaptDlg::buildDlg() +{ + setModal( false ); + setAttribute( Qt::WA_DeleteOnClose, true ); + setWindowTitle( tr( "ADAPT_PREF_MG_ADAPT" ) ); + setSizeGripEnabled( true ); + + + myTabWidget = new QTabWidget( this ); + + // Arguments + + myArgs = new SMESHGUI_MgAdaptArguments( myTabWidget ); + std::vector str = model->getOptionValuesStrVec(); + std::vector str2 = model->getCustomOptionValuesStrVec(); + str.insert( str.end(), str2.begin(), str2.end() ); + + myAdvOpt = new MgAdaptAdvWidget(myTabWidget, &str); + int argsTab = myTabWidget->addTab( myArgs, tr( "Args" ) ); + int advTab = myTabWidget->addTab( myAdvOpt, tr( "ADVOP" ) ); + + myAdvOpt->workingDirectoryLabel ->setText (tr( "WORKING_DIR" )); + myAdvOpt->workingDirectoryPushButton ->setText (tr( "SELECT_DIR" )); + myAdvOpt->keepWorkingFilesCheck ->setText (tr( "KEEP_WORKING_FILES" )); + myAdvOpt->verboseLevelLabel ->setText (tr( "VERBOSE_LEVEL" )); + myAdvOpt->removeLogOnSuccessCheck ->setText (tr( "REMOVE_LOG_ON_SUCCESS" )); + myAdvOpt->logInFileCheck ->setText (tr( "LOG_IN_FILE" )); + myAdvOpt->logGroupBox ->setTitle(tr( "LOG_GROUP_TITLE" )); + + // buttons + QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this ); + okBtn->setAutoDefault( true ); + okBtn->setDefault( true ); + okBtn->setFocus(); + QPushButton* buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), this); + buttonApply->setAutoDefault(true); + QPushButton* buttonApplyAndClose = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), this); + buttonApplyAndClose->setAutoDefault(true); + QPushButton* cancelBtn = new QPushButton( tr( "SMESH_BUT_CANCEL" ), this ); + cancelBtn->setAutoDefault( true ); + QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this ); + helpBtn->setAutoDefault( true ); + + QHBoxLayout* btnLayout = new QHBoxLayout; + btnLayout->setSpacing( SPACING ); + btnLayout->setMargin( 0 ); + btnLayout->addWidget( buttonApplyAndClose ); + btnLayout->addStretch( 10 ); + btnLayout->addWidget( buttonApply ); + btnLayout->addStretch( 10 ); + btnLayout->addWidget( okBtn ); + btnLayout->addStretch( 10 ); + btnLayout->addWidget( cancelBtn ); + btnLayout->addStretch( 10 ); + btnLayout->addWidget( helpBtn ); + okBtn->hide(); // tab 1 + + QVBoxLayout* l = new QVBoxLayout ( this ); + l->setMargin( MARGIN ); + l->setSpacing( SPACING ); + l->addWidget( myTabWidget ); + l->addStretch(); + l->addLayout( btnLayout ); + + + connect( okBtn, SIGNAL( clicked() ), this, SLOT( clickOnOk() ) ); + connect( helpBtn, SIGNAL( clicked() ), this, SLOT( clickOnHelp() ) ); + connect(cancelBtn, SIGNAL(clicked()), this, SLOT(reject())); + connect(buttonApply, SIGNAL(clicked()), this,SLOT(clickOnApply())); + connect(buttonApplyAndClose, SIGNAL(clicked()), this,SLOT(clickOnOk())); +} + + +//================================================================================= +// function : ~SMESHGUI_MgAdaptDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +SMESHGUI_MgAdaptDlg::~SMESHGUI_MgAdaptDlg() +{ + delete model; +} + +void SMESHGUI_MgAdaptDlg::setModel(MgAdapt* mg) +{ + model = mg; +} +MgAdapt* SMESHGUI_MgAdaptDlg::getModel() const +{ + return model; +} +/*! + \brief Perform clean-up actions on the dialog box closing. +*/ +bool SMESHGUI_MgAdaptDlg::clickOnApply() +{ + readParamsFromWidgets(); + return true; +} +void SMESHGUI_MgAdaptDlg::clickOnOk() +{ + clickOnApply(); + reject(); +} +void SMESHGUI_MgAdaptDlg::reject() +{ + QDialog::reject(); +} +bool SMESHGUI_MgAdaptDlg::readParamsFromHypo( ) const +{ + bool ret = true; + myArgs->aMedfile->setChecked(myData->fromMedFile) ; + if (myData->fromMedFile) + { + + *(myArgs->myFileInDir) = QString(myData->myFileInDir.c_str()) ; + myArgs->selectMedFileLineEdit->setText(myData->myMeshFileIn.c_str()) ; + // myData->myInMeshName = // TODO + + } + else + { + myArgs->aBrowserObject->setText(myData->myInMeshName.c_str()); + //~ myArgs->myFileInDir =""; // TODO + //~ myArgs->selectMedFileLineEdit->setText(); // TODO + } + myArgs->meshNameLineEdit->setText(myData->myOutMeshName.c_str()); + myArgs->medFileCheckBox->setChecked(myData->myMeshOutMed); + + if(myData->myMeshOutMed) + { + *(myArgs->myFileOutDir) = QString(myData->myFileOutDir.c_str()); + myArgs->selectOutMedFileLineEdit->setText(myData->myMeshFileOut.c_str()); + + } + else + { + *(myArgs->myFileOutDir) = QString(""); //TODO + } + + myArgs->publishOut->setChecked(myData->myPublish); + + myArgs->localButton->setChecked(myData->myUseLocalMap); + myArgs->backgroundButton->setChecked(myData->myUseBackgroundMap); + myArgs->constantButton->setChecked(myData->myUseConstantValue); + + if (myData->myUseConstantValue) + { + myArgs->dvalue->setValue(myData->myConstantValue); + } + else + { + myArgs->dvalue->setValue(0.0); + } + + if (myData->myUseBackgroundMap) + { + + *(myArgs->myFileSizeMapDir) = QString(myData->myFileSizeMapDir.c_str()) ; + myArgs->selectMedFileBackgroundLineEdit->setText(myData->myMeshFileBackground.c_str()); + } + else + { + *(myArgs->myFileSizeMapDir) = QString("") ; //TODO + myArgs->selectMedFileBackgroundLineEdit->setText(""); //TODO + } + + myArgs->fieldNameCmb->setCurrentText(myData->myFieldName.c_str()); + myArgs->noTimeStep->setChecked(myData->myUseNoTimeStep); + myArgs->lastTimeStep->setChecked( myData->myUseLastTimeStep); + myArgs->chosenTimeStep->setChecked(myData->myUseChosenTimeStep); + if (myData->myUseChosenTimeStep) + { + myArgs->rankSpinBox->setValue(myData->myRank); + myArgs->timeStep->setValue(myData->myTimeStep); + } + + myAdvOpt->workingDirectoryLineEdit->setText(myData->myWorkingDir.c_str()); + myAdvOpt->logInFileCheck->setChecked(myData->myPrintLogInFile); + + myAdvOpt->verboseLevelSpin->setValue(myData->myVerboseLevel); + myAdvOpt->removeLogOnSuccessCheck->setChecked(myData->myRemoveLogOnSuccess); + myAdvOpt->keepWorkingFilesCheck->setChecked(myData->myKeepFiles); + + return ret; + +} + + +bool SMESHGUI_MgAdaptDlg::readParamsFromWidgets() +{ + bool ret = true; + MgAdaptHypothesisData* aData = new MgAdaptHypothesisData(); + aData->fromMedFile = myArgs->aMedfile->isChecked(); + if (aData->fromMedFile) + { + + aData->myFileInDir = myArgs->myFileInDir->toStdString(); + aData->myMeshFileIn = myArgs->selectMedFileLineEdit->text().toStdString(); + // aData->myInMeshName = // TODO + } + else // TODO browser + { + aData->myInMeshName = myArgs->aBrowserObject->text().toStdString(); + aData->myFileInDir = myAdvOpt->workingDirectoryLineEdit->text().toStdString(); + + TCollection_AsciiString aGenericName = (char*)aData->myFileInDir.c_str(); + TCollection_AsciiString aGenericName2 = "MgAdapt_"; + aGenericName2 += getpid(); + aGenericName2 += "_"; + aGenericName2 += Abs((Standard_Integer)(long) aGenericName.ToCString()); + aGenericName2 += ".med"; + aGenericName+=aGenericName2; + emit myArgs->toExportMED(aGenericName.ToCString()); + aData->myMeshFileIn = aGenericName2.ToCString(); + } + aData->myOutMeshName = myArgs->meshNameLineEdit->text().toStdString(); + aData->myMeshOutMed = myArgs->medFileCheckBox->isChecked(); + if(aData->myMeshOutMed) + { + aData->myFileOutDir = myArgs->myFileOutDir->toStdString(); + aData->myMeshFileOut = myArgs->selectOutMedFileLineEdit->text().toStdString(); + + } + else + { + aData->myMeshFileOut = ""; + } + + aData->myPublish = myArgs->publishOut->isChecked(); + + + aData->myUseLocalMap = myArgs->localButton->isChecked(); + aData->myUseBackgroundMap = myArgs->backgroundButton->isChecked(); + aData->myUseConstantValue = myArgs->constantButton->isChecked(); + if (aData->myUseConstantValue) + { + aData->myConstantValue = myArgs->dvalue->value(); + } + else + { + aData->myConstantValue = 0.0; + } + if (aData->myUseBackgroundMap) + { + aData->myFileSizeMapDir = myArgs->myFileSizeMapDir->toStdString(); + aData->myMeshFileBackground = myArgs->selectMedFileBackgroundLineEdit->text().toStdString(); + } + else + { + aData->myMeshFileBackground = ""; + } + + aData->myFieldName = myArgs->fieldNameCmb->currentText().toStdString(); + aData->myUseNoTimeStep = myArgs->noTimeStep->isChecked(); + aData->myUseLastTimeStep = myArgs->lastTimeStep->isChecked(); + aData->myUseChosenTimeStep = myArgs->chosenTimeStep->isChecked(); + if (aData->myUseChosenTimeStep) + { + aData->myRank = myArgs->rankSpinBox->value(); + aData->myTimeStep = myArgs->timeStep->value(); + + } + + + aData->myWorkingDir = myAdvOpt->workingDirectoryLineEdit->text().toStdString(); + aData->myPrintLogInFile = myAdvOpt->logInFileCheck->isChecked(); + aData->myVerboseLevel = myAdvOpt->verboseLevelSpin->value(); + aData->myRemoveLogOnSuccess = myAdvOpt->removeLogOnSuccessCheck->isChecked(); + aData->myKeepFiles = myAdvOpt->keepWorkingFilesCheck->isChecked(); + model->setData(aData); + QString msg; + checkParams(msg); + delete aData; + return ret; +} +bool SMESHGUI_MgAdaptDlg::storeParamsToHypo( const MgAdaptHypothesisData& ) const +{ + +} +/*! + \brief Show help page +*/ +void SMESHGUI_MgAdaptDlg::clickOnHelp() +{ + // QString aHelpFile; + // if ( myTabWidget->currentIndex() == MinDistance ) { + // aHelpFile = "measurements.html#min-distance-anchor"; + // } else if ( myTabWidget->currentIndex() == BoundingBox ) { + // aHelpFile = "measurements.html#bounding-box-anchor"; + // } else if ( myTabWidget->currentWidget() == myAngle ) { + // aHelpFile = "measurements.html#angle-anchor"; + // } else { + // aHelpFile = "measurements.html#basic-properties-anchor"; + // } + + // SMESH::ShowHelpFile( aHelpFile ); +} +bool SMESHGUI_MgAdaptDlg::checkParams(QString& msg) +{ + if ( !QFileInfo( myAdvOpt->workingDirectoryLineEdit->text().trimmed() ).isWritable() ) { + SUIT_MessageBox::warning( this, + tr( "SMESH_WRN_WARNING" ), + tr( "GHS3D_PERMISSION_DENIED" ) ); + return false; + } + + + myAdvOpt->myOptionTable->setFocus(); + QApplication::instance()->processEvents(); + + QString name, value; + bool isDefault, ok = true; + int iRow = 0, nbRows = myAdvOpt->myOptionTable->topLevelItemCount(); + for ( ; iRow < nbRows; ++iRow ) + { + QTreeWidgetItem* row = myAdvOpt->myOptionTable->topLevelItem( iRow ); + myAdvOpt->GetOptionAndValue( row, name, value, isDefault ); + + if ( name.simplified().isEmpty() ) + continue; // invalid custom option + + if ( isDefault ) // not selected option + value.clear(); + + try { + model->setOptionValue( name.toLatin1().constData(), value.toLatin1().constData() ); + } + catch ( const SALOME::SALOME_Exception& ex ) + { + msg = ex.details.text.in(); + ok = false; + break; + } + } + + + return ok; +} + +//================================================================================= +// function : SMESHGUI_MgAdaptArguments() +// purpose : +//================================================================================= +SMESHGUI_MgAdaptArguments::SMESHGUI_MgAdaptArguments( QWidget* parent ) + :QWidget(parent) +{ + + + myFileInDir = new QString(""); + myFileOutDir = new QString(""); + myFileSizeMapDir = new QString(""); + if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() ) + { + *myFileInDir = QDir::currentPath(); + *myFileOutDir = QDir::currentPath(); + *myFileSizeMapDir = QDir::currentPath(); + } + else + { + *myFileInDir = SUIT_FileDlg::getLastVisitedPath(); + *myFileOutDir = SUIT_FileDlg::getLastVisitedPath(); + *myFileSizeMapDir = SUIT_FileDlg::getLastVisitedPath(); + } + + + // Mesh in + aMeshIn = new QGroupBox( tr( "MeshIn" ), this ); + aMedfile = new QRadioButton( tr( "MEDFile" ), aMeshIn ); + aBrowser = new QRadioButton( tr( "Browser" ), aMeshIn ); + aBrowserObject = new QLineEdit( aMeshIn ); + selectMedFilebutton = new QPushButton("", aMeshIn); + selectMedFileLineEdit = new QLineEdit( aMeshIn ); + + meshIn = new QGridLayout( aMeshIn ); + + meshIn->setMargin( MARGIN ); + meshIn->setSpacing( SPACING ); + meshIn->addWidget( aMedfile, 0, 0, 1,1 ); + meshIn->addWidget( aBrowser, 0, 1,1,1); + meshIn->addWidget( aBrowserObject, 0, 2, 1, 1 ); + meshIn->addWidget( selectMedFilebutton, 1, 0,1, 1); + meshIn->addWidget( selectMedFileLineEdit, 1, 1, 1, 1 ); + hspacer = new QSpacerItem(188, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + + meshInGroup = new QButtonGroup( this ); + meshInGroup->addButton( aMedfile, 0 ); + meshInGroup->addButton( aBrowser, 1 ); + + //Mesh out + + aMeshOut = new QGroupBox( tr( "MeshOut" ), this ); + meshName = new QLabel(tr("MeshName"), aMeshOut); + secondHspacer = new QSpacerItem(100, 30); + meshNameLineEdit = new QLineEdit(aMeshOut) ; + medFileCheckBox = new QCheckBox(tr("MEDFile"), aMeshOut); + selectOutMedFilebutton = new QPushButton("", aMeshOut); + thirdHspacer = new QSpacerItem(188, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + selectOutMedFileLineEdit = new QLineEdit(aMeshOut) ; + publishOut = new QCheckBox(tr("Publish_MG_ADAPT"), aMeshOut); + + meshOut = new QGridLayout( aMeshOut ); + + meshOut->setMargin( MARGIN ); + meshOut->setSpacing( SPACING ); + meshOut->addWidget( meshName, 0, 0, 1,1 ); + meshOut->addItem( secondHspacer, 0, 1, 1, 1 ); + meshOut->addWidget( meshNameLineEdit, 0, 2,1,1); + meshOut->addWidget( medFileCheckBox, 1, 0,1,1 ); + meshOut->addWidget( selectOutMedFilebutton, 1, 1,1,1 ); + meshOut->addWidget( selectOutMedFileLineEdit, 1, 2,1,1); + meshOut->addWidget( publishOut, 2, 0,1,1 ); + + //size map definition + + sizeMapDefinition = new QGroupBox(tr("SIZE_MAP_DEF"), this); + localButton = new QRadioButton(tr("LOCAL_MG_ADAPT"), sizeMapDefinition); + backgroundButton = new QRadioButton(tr("BACKGRND_MG_ADAPT"), sizeMapDefinition); + constantButton = new QRadioButton(tr("CNST_MG_ADAPT"), sizeMapDefinition); + medFileBackground = new QLabel(tr("MED_FILE_BCKG"), sizeMapDefinition); + selectMedFileBackgroundbutton = new QPushButton(tr(""), sizeMapDefinition); + selectMedFileBackgroundLineEdit = new QLineEdit(sizeMapDefinition); + valueLabel = new QLabel(tr("VALUE_MG_ADAPT"), sizeMapDefinition); + dvalue = new QDoubleSpinBox(sizeMapDefinition); + sizeMapDefGroup = new QButtonGroup( this ); + sizeMapDefGroup->addButton( localButton, 0 ); + sizeMapDefGroup->addButton( backgroundButton, 1 ); + sizeMapDefGroup->addButton( constantButton, 2 ); + + sizeMapDefGroupLayout = new QGridLayout(sizeMapDefinition); + sizeMapDefGroupLayout->addWidget(localButton, 0,0); + sizeMapDefGroupLayout->addWidget(backgroundButton, 0,1); + sizeMapDefGroupLayout->addWidget(constantButton, 0,2); + sizeMapDefGroupLayout->addWidget(medFileBackground, 1,0); + sizeMapDefGroupLayout->addWidget(selectMedFileBackgroundbutton, 1,1); + sizeMapDefGroupLayout->addWidget(selectMedFileBackgroundLineEdit, 1,2); + sizeMapDefGroupLayout->addWidget(valueLabel, 2,0); + sizeMapDefGroupLayout->addWidget(dvalue, 2,1); + + // size Map field + sizeMapField = new QGroupBox(tr("SIZE_MAP_FIELD"), this); + fieldName = new QLabel(tr("MG_ADAPT_FIELD_NAME"), sizeMapField); + fieldNameCmb = new QComboBox(sizeMapField); + noTimeStep = new QRadioButton(tr("MG_ADAPT_NO_T_ST"), sizeMapField); + lastTimeStep = new QRadioButton(tr("MG_ADAPT_L_ST"), sizeMapField); + chosenTimeStep = new QRadioButton(tr("MG_ADAPT_CH_ST"), sizeMapField); + timeStepLabel = new QLabel(tr("MG_ADAPT_TSTP"), sizeMapField); + timeStep = new QSpinBox(sizeMapField); + //~timeStep->setMinimum(-1); + rankLabel = new QLabel(tr("MG_ADAPT_RANK"), sizeMapField); + rankSpinBox = new QSpinBox(sizeMapField); + rankSpinBox->setMinimum(-1); + + timeStepGroup = new QButtonGroup(this); + timeStepGroup->addButton(noTimeStep, 0); + timeStepGroup->addButton(lastTimeStep, 1); + timeStepGroup->addButton(chosenTimeStep, 2); + + sizeMapFieldGroupLayout = new QGridLayout(sizeMapField); + + sizeMapFieldGroupLayout->addWidget(fieldName, 0,0); + sizeMapFieldGroupLayout->addWidget(fieldNameCmb, 0,1); + sizeMapFieldGroupLayout->addWidget(noTimeStep, 1,0); + sizeMapFieldGroupLayout->addWidget(lastTimeStep, 1,1); + sizeMapFieldGroupLayout->addWidget(chosenTimeStep, 1,2); + sizeMapFieldGroupLayout->addWidget(timeStepLabel, 2,0); + sizeMapFieldGroupLayout->addWidget(timeStep, 2,1); + sizeMapFieldGroupLayout->addWidget(rankLabel, 2,2); + sizeMapFieldGroupLayout->addWidget(rankSpinBox, 2,3); + + + QGridLayout* argumentsLayout = new QGridLayout( this ); + argumentsLayout->setMargin( MARGIN ); + argumentsLayout->setSpacing( SPACING ); + + argumentsLayout->addWidget( aMeshIn, 0, 0, 1, 3 ); + argumentsLayout->addWidget( aMeshOut, 1, 0, 1, 3 ); + argumentsLayout->addWidget( sizeMapDefinition, 2, 0, 1, 3 ); + argumentsLayout->addWidget( sizeMapField, 3, 0, 1, 3 ); + argumentsLayout->setColumnStretch( 1, 5 ); + argumentsLayout->setRowStretch( 4, 5 ); + + // Initial state + setMode( Mesh, Local); + medFileCheckBox->setChecked(true); + + // Connections + connect( meshInGroup, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged( int ) ) ); + connect( sizeMapDefGroup, SIGNAL( buttonClicked( int ) ), this, SLOT( sizeMapDefChanged( int ) ) ); + connect( selectMedFilebutton, SIGNAL( pressed( ) ), this, SLOT( onSelectMedFilebuttonClicked( ) ) ); + connect(medFileCheckBox, SIGNAL (stateChanged(int)), this, SLOT(onMedFileCheckBox(int) ) ); + connect(publishOut, SIGNAL (stateChanged(int)), this, SLOT(onPublishOut(int) ) ); + connect(selectOutMedFilebutton, SIGNAL( pressed()), this, SLOT(onSelectOutMedFilebutton())); + connect(selectMedFileBackgroundbutton, SIGNAL(pressed()), this, SLOT(onSelectMedFileBackgroundbutton()) ); + connect( timeStepGroup, SIGNAL( buttonClicked( int ) ), this, SLOT( timeStepGroupChanged( int ) ) ); + emit updateSelection(); +} + +//================================================================================= +// function : ~SMESHGUI_MgAdaptArguments() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +SMESHGUI_MgAdaptArguments::~SMESHGUI_MgAdaptArguments() +{ +} + +void SMESHGUI_MgAdaptArguments::onNoTimeStep(bool disableOther) +{ + noTimeStep->setChecked(true); + + rankLabel->setVisible(0); + rankSpinBox->setVisible(0); + rankSpinBox->setValue(-2); + + timeStepLabel->setVisible(0); + timeStep->setVisible(0); + timeStep->setValue(-2); + + lastTimeStep->setDisabled(disableOther); + chosenTimeStep->setDisabled(disableOther); + + +} +void SMESHGUI_MgAdaptArguments::onLastTimeStep(bool disableOther) +{ + lastTimeStep->setChecked(true); + + rankLabel->setVisible(0); + rankSpinBox->setVisible(0); + rankSpinBox->setValue(-1); + + timeStepLabel->setVisible(0); + timeStep->setVisible(0); + timeStep->setValue(-1); + noTimeStep->setDisabled(disableOther); +} + +void SMESHGUI_MgAdaptArguments::onChosenTimeStep(bool disableOther, int max) +{ + chosenTimeStep->setChecked(true); + + rankLabel->setVisible(1); + rankSpinBox->setVisible(1); + rankSpinBox->setValue(0); + + timeStepLabel->setVisible(1); + timeStep->setVisible(1); + timeStep->setValue(0); + if (max) timeStep->setMaximum(max); + +} + +void SMESHGUI_MgAdaptArguments::onSelectOutMedFilebutton() +{ + + QString filtre = QString("Med") ; + filtre += QString(" files (*.") + QString("med") + QString(");;"); + QString fileName = QFileDialog::getSaveFileName(this, tr("SAVE_MED"), + QString(""), filtre); + QFileInfo myFileInfo(fileName); + selectOutMedFileLineEdit->setText(myFileInfo.fileName()); + *myFileOutDir = myFileInfo.path(); + +} +void SMESHGUI_MgAdaptArguments::onSelectMedFileBackgroundbutton() +{ + QString fileName0 = selectMedFileBackgroundbutton->text().trimmed(); + + QString fileName = getMedFileName(false); + if (fileName != QString::null) + { + myFieldList = GetListeChamps(fileName); + if (myFieldList.empty()) + { + fileName = fileName0; + fieldNameCmb->clear(); + } + else + { + // fill field name Combobox + fieldNameCmb->clear(); + std::map::const_iterator it; + for ( it=myFieldList.begin() ; it != myFieldList.end(); it++) + { + fieldNameCmb->insertItem(0,QString(it->first)); + int typeStepInField = it->second > 2 ? 2 : it->second ; + timeStepGroupChanged(typeStepInField, true, it->second-1); + } + + } + + } + else + { + fileName = fileName0; + fieldNameCmb->clear(); + } + + QFileInfo myFileInfo(fileName); + *myFileSizeMapDir = myFileInfo.path(); + selectMedFileBackgroundLineEdit->setText(myFileInfo.fileName()); + +} +void SMESHGUI_MgAdaptArguments::onMedFileCheckBox(int state) +{ + if (state == Qt::Checked) + { + selectOutMedFilebutton->show(); + selectOutMedFileLineEdit->show(); + selectOutMedFilebutton->setEnabled(true); + selectOutMedFileLineEdit->setEnabled(true); + } + else + { + selectOutMedFilebutton->setEnabled(false); + selectOutMedFileLineEdit->setEnabled(false); + publishOut->setChecked(true); + } +} +void SMESHGUI_MgAdaptArguments::onPublishOut(int state) +{ + if (state == Qt::Unchecked) + { + medFileCheckBox->setChecked(true); + } +} + +void SMESHGUI_MgAdaptArguments::onSelectMedFilebuttonClicked() +{ + // bool keep = false; + QString fileName0 = selectMedFileLineEdit->text().trimmed(); + + QString fileName = getMedFileName(false); + if(fileName != QString::null) + { + QString aMeshName = lireNomMaillage(fileName.trimmed()); + if (aMeshName == QString::null ) + { + QMessageBox::critical( 0, QObject::tr("MG_ADAPT_ERROR"), + QObject::tr("MG_ADAPT_MED_FILE_2") ); + fileName = fileName0; + } + else + { + meshNameLineEdit->setText(aMeshName); + } + + } + else + { + return; + } + + + QFileInfo myFileInfo(fileName); + *myFileInDir = myFileInfo.path(); + *myFileOutDir = myFileInfo.path(); + selectMedFileLineEdit->setText(myFileInfo.fileName()); + selectOutMedFileLineEdit->setText(myFileInfo.fileName()); + onLocalSelected(myFileInfo.filePath()); + +} + +void SMESHGUI_MgAdaptArguments::onLocalSelected(QString filePath) +{ + myFieldList = GetListeChamps(filePath, false); + if (myFieldList.empty()) + { + if (localButton->isChecked()) + { + fieldNameCmb->clear(); + } + + } + else + { + // fill field name Combobox + fieldNameCmb->clear(); + std::map::const_iterator it; + for ( it=myFieldList.begin() ; it != myFieldList.end(); it++) + { + fieldNameCmb->insertItem(0,QString(it->first)); + int typeStepInField = it->second > 2 ? 2 : it->second ; + timeStepGroupChanged(typeStepInField, true, it->second-1); + } + + } +} +// ======================================================================= +// Gestion les boutons qui permettent de +// 1) retourne le nom d'un fichier par une fenetre de dialogue si aucun +// objet est selectionne dans l arbre d etude +// 2) retourne le nom du fichier asocie a l objet +// selectionne dans l arbre d etude +// ======================================================================= +QString SMESHGUI_MgAdaptArguments::getMedFileName(bool avertir) +{ + + QString aFile = QString::null; + QString filtre = QString("Med") ; + filtre += QString(" files (*.") + QString("med") + QString(");;"); + aFile = SUIT_FileDlg::getOpenFileName(0, QObject::tr("MG_ADAPT_SELECT_FILE_0"), QString(""), filtre ); + + return aFile; + +} +void SMESHGUI_MgAdaptArguments::setMode(const Mode theMode, const SIZEMAP theSizeMap ) +{ + QRadioButton* aButton = qobject_cast( meshInGroup->button( theMode ) ); + QRadioButton* bButton = qobject_cast( sizeMapDefGroup->button( theSizeMap ) ); + if ( aButton ) { + aButton->setChecked( true ); + modeChanged( theMode ); + } + if ( bButton ) { + bButton->setChecked( true ); + sizeMapDefChanged( theSizeMap ); + } +} + +void SMESHGUI_MgAdaptArguments::modeChanged( int theMode ) +{ + clear(); + if(theMode == Mesh) + { + aBrowserObject->hide(); + selectMedFileLineEdit->show(); + selectMedFilebutton->show(); + localButton->setEnabled(true); + } + else + { + selectMedFileLineEdit->hide(); + selectMedFilebutton->hide(); + localButton->setEnabled(false); + aBrowserObject->show(); + sizeMapDefChanged(Background); + emit updateSelection(); + } + + + +} + +void SMESHGUI_MgAdaptArguments::sizeMapDefChanged( int theSizeMap ) +{ + fieldNameCmb->clear(); + if(theSizeMap == Local) + { + localButton->setEnabled(true); + localButton->setChecked(true); + medFileBackground->hide(); + selectMedFileBackgroundbutton->hide(); + selectMedFileBackgroundLineEdit->hide(); + selectMedFileBackgroundLineEdit->clear(); + valueLabel->hide(); + dvalue->hide(); + + sizeMapField->setEnabled(true); + if (!selectMedFileLineEdit->text().isEmpty()) + { + QFileInfo myFileInfo(QDir(*myFileInDir), selectMedFileLineEdit->text()); + onLocalSelected(myFileInfo.filePath()); + } + } + else if (theSizeMap == Background) + { + medFileBackground->show(); + backgroundButton->setChecked(true); + selectMedFileBackgroundbutton->show(); + selectMedFileBackgroundLineEdit->show(); + valueLabel->hide(); + dvalue->hide(); + sizeMapField->setEnabled(true); + + } + else + { + medFileBackground->hide(); + constantButton->setChecked(true); + selectMedFileBackgroundbutton->hide(); + selectMedFileBackgroundLineEdit->clear(); + selectMedFileBackgroundLineEdit->hide(); + valueLabel->show(); + dvalue->show(); + sizeMapField->setEnabled(false); + + } + + +} +void SMESHGUI_MgAdaptArguments::timeStepGroupChanged(int timeStepType, bool disableOther, int max) +{ + switch (timeStepType) + { + case 0 : + onNoTimeStep(disableOther); + break; + case 1 : + onLastTimeStep(disableOther); + break; + case 2 : + onChosenTimeStep(disableOther, max); + default: + break; + } +} + +void SMESHGUI_MgAdaptArguments::clear() +{ + selectMedFileLineEdit->clear(); + aBrowserObject->clear(); + + meshNameLineEdit->clear(); + selectOutMedFileLineEdit->clear(); +} + +QWidget* ItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &o, const QModelIndex &index) const +{ + bool editable = index.data( EDITABLE_ROLE ).toInt(); + return editable ? QItemDelegate::createEditor( parent, o, index ) : 0; +} + +////////////////////////////////////////// +// MgAdaptAdvWidget +////////////////////////////////////////// + +MgAdaptAdvWidget::MgAdaptAdvWidget( QWidget* parent, std::vector * options, Qt::WindowFlags f ) + : QWidget( parent, f ), myOptions(options) +{ + setupWidget(); + myOptionTable->header()->setSectionResizeMode( QHeaderView::ResizeToContents ); + myOptionTable->setItemDelegate( new ItemDelegate( myOptionTable ) ); + + for ( int i = 0, nb = myOptions->size(); i < nb; ++i ) + { + AddOption( (*myOptions)[i].c_str() ); + } + + connect( myOptionTable, SIGNAL( itemChanged(QTreeWidgetItem *, int)), SLOT( itemChanged(QTreeWidgetItem *, int ))); + connect( addBtn, SIGNAL( clicked() ), this, SLOT( onAddOption() ) ); +} + +MgAdaptAdvWidget::~MgAdaptAdvWidget() +{ +} + +void MgAdaptAdvWidget::AddOption( const char* option, bool isCustom ) +{ + QTreeWidget * table = myOptionTable; + //table->setExpanded( true ); + + QTreeWidgetItem * row = new QTreeWidgetItem( table ); + row->setData( NAME_COL, EDITABLE_ROLE, int( isCustom && !option )); + row->setFlags( row->flags() | Qt::ItemIsEditable ); + + QString name, value; + bool isDefault = false; + if ( option ) + { + QStringList name_value_type = QString(option).split( ":", QString::KeepEmptyParts ); + if ( name_value_type.size() > 0 ) + name = name_value_type[0]; + if ( name_value_type.size() > 1 ) + value = name_value_type[1]; + if ( name_value_type.size() > 2 ) + isDefault = !name_value_type[2].toInt(); + + } + row->setText( 0, tr( name.toLatin1().constData() )); + row->setText( 1, tr( value.toLatin1().constData() )); + row->setCheckState( 0, isDefault ? Qt::Unchecked : Qt::Checked); + row->setData( NAME_COL, PARAM_NAME, name ); + + if ( isCustom ) + { + myOptionTable->scrollToItem( row ); + myOptionTable->setCurrentItem( row ); + myOptionTable->editItem( row, NAME_COL ); + } +} +void MgAdaptAdvWidget::onAddOption() +{ + AddOption( NULL, true ); +} +void MgAdaptAdvWidget::GetOptionAndValue( QTreeWidgetItem * tblRow, + QString& option, + QString& value, + bool& isDefault) +{ + option = tblRow->data( NAME_COL, PARAM_NAME ).toString(); + value = tblRow->text( VALUE_COL ); + isDefault = ! tblRow->checkState( NAME_COL ); + +} + + +void MgAdaptAdvWidget::itemChanged(QTreeWidgetItem * tblRow, int column) +{ + if ( tblRow ) + { + myOptionTable->blockSignals( true ); + + tblRow->setData( VALUE_COL, EDITABLE_ROLE, int( tblRow->checkState( NAME_COL ))); + + int c = tblRow->checkState( NAME_COL ) ? 0 : 150; + tblRow->setForeground( VALUE_COL, QBrush( QColor( c, c, c ))); + + if ( column == NAME_COL && tblRow->data( NAME_COL, EDITABLE_ROLE ).toInt() ) // custom table + { + tblRow->setData( NAME_COL, PARAM_NAME, tblRow->text( NAME_COL )); + } + + myOptionTable->blockSignals( false ); + } +} +void MgAdaptAdvWidget::setupWidget() +{ + if (this->objectName().isEmpty()) + this->setObjectName(QString(tr("MG-ADAPT-ADV"))); + this->resize(337, 369); + gridLayout_4 = new QGridLayout(this); + gridLayout_4->setObjectName(QString("gridLayout_4")); + myOptionTable = new MgAdaptAdvWidgetTreeWidget(this); + QFont font; + font.setBold(false); + font.setWeight(50); + QTreeWidgetItem *__qtreewidgetitem = new QTreeWidgetItem(); + __qtreewidgetitem->setFont(1, font); + __qtreewidgetitem->setFont(0, font); + __qtreewidgetitem->setText(1, tr("OPTION_VALUE_COLUMN")); + __qtreewidgetitem->setText(0, tr("OPTION_NAME_COLUMN")); + myOptionTable->setHeaderItem(__qtreewidgetitem); + myOptionTable->setObjectName(QString("myOptionTable")); + myOptionTable->setEditTriggers(QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed); + myOptionTable->setTabKeyNavigation(true); + + gridLayout_4->addWidget(myOptionTable, 0, 0, 1, 2); + + addBtn = new QPushButton(this); + addBtn->setObjectName(QString("addBtn")); + + gridLayout_4->addWidget(addBtn, 1, 0, 1, 1); + + horizontalSpacer = new QSpacerItem(188, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + + gridLayout_4->addItem(horizontalSpacer, 1, 1, 1, 1); + + logGroupBox = new QGroupBox(this); + logGroupBox->setObjectName(QString("logGroupBox")); + gridLayout_2 = new QGridLayout(logGroupBox); + gridLayout_2->setObjectName(QString("gridLayout_2")); + gridLayout = new QGridLayout(); + gridLayout->setObjectName(QString("gridLayout")); + workingDirectoryLabel = new QLabel(logGroupBox); + workingDirectoryLabel->setObjectName(QString("workingDirectoryLabel")); + + gridLayout->addWidget(workingDirectoryLabel, 0, 0, 1, 1); + + workingDirectoryLineEdit = new QLineEdit(logGroupBox); + workingDirectoryLineEdit->setObjectName(QString("workingDirectoryLineEdit")); + + gridLayout->addWidget(workingDirectoryLineEdit, 0, 1, 1, 1); + + workingDirectoryPushButton = new QPushButton(logGroupBox); + workingDirectoryPushButton->setObjectName(QString("workingDirectoryPushButton")); + + gridLayout->addWidget(workingDirectoryPushButton, 0, 2, 1, 1); + + verboseLevelLabel = new QLabel(logGroupBox); + verboseLevelLabel->setObjectName(QString("verboseLevelLabel")); + + gridLayout->addWidget(verboseLevelLabel, 1, 0, 1, 1); + + verboseLevelSpin = new QSpinBox(logGroupBox); + verboseLevelSpin->setObjectName(QString("verboseLevelSpin")); + + gridLayout->addWidget(verboseLevelSpin, 1, 1, 1, 1); + + + gridLayout_2->addLayout(gridLayout, 0, 0, 1, 1); + + horizontalLayout = new QHBoxLayout(); + horizontalLayout->setObjectName(QString("horizontalLayout")); + logInFileCheck = new QCheckBox(logGroupBox); + logInFileCheck->setObjectName(QString("logInFileCheck")); + logInFileCheck->setChecked(true); + + horizontalLayout->addWidget(logInFileCheck); + + removeLogOnSuccessCheck = new QCheckBox(logGroupBox); + removeLogOnSuccessCheck->setObjectName(QString("removeLogOnSuccessCheck")); + removeLogOnSuccessCheck->setChecked(true); + + horizontalLayout->addWidget(removeLogOnSuccessCheck); + + + gridLayout_2->addLayout(horizontalLayout, 1, 0, 1, 1); + + keepWorkingFilesCheck = new QCheckBox(logGroupBox); + keepWorkingFilesCheck->setObjectName(QString("keepWorkingFilesCheck")); + keepWorkingFilesCheck->setAutoExclusive(false); + + gridLayout_2->addWidget(keepWorkingFilesCheck, 2, 0, 1, 1); + + + gridLayout_4->addWidget(logGroupBox, 3, 0, 1, 2); + + + // retranslateUi(this); + + // QMetaObject::connectSlotsByName(this); + +} + +namespace +{ +bool isEditable( const QModelIndex& index ) +{ + return index.isValid() && + index.flags() & Qt::ItemIsEditable && + index.flags() & Qt::ItemIsEnabled && + ( !index.data( Qt::UserRole + 1 ).isValid() || index.data( Qt::UserRole + 1 ).toInt() != 0 ); +} +} + +MgAdaptAdvWidgetTreeWidget::MgAdaptAdvWidgetTreeWidget( QWidget* parent ) + : QTreeWidget( parent ) +{ +} + +QModelIndex MgAdaptAdvWidgetTreeWidget::moveCursor( CursorAction action, Qt::KeyboardModifiers modifiers ) +{ + QModelIndex current = currentIndex(); + int column = current.column(); + if ( action == MoveNext ) { + if ( column < columnCount()-1 ) { + QModelIndex next = current.sibling( current.row(), column+1 ); + if ( isEditable( next ) ) + return next; + } + else { + QModelIndex next = current.sibling( current.row()+1, 0 ); + if ( isEditable( next ) ) + return next; + } + } + else if ( action == MovePrevious ) { + if ( column == 0 ) { + QModelIndex next = current.sibling( current.row()-1, columnCount()-1 ); + if ( isEditable( next ) ) + return next; + } + else { + QModelIndex next = current.sibling( current.row(), column-1 ); + if ( isEditable( next ) ) + return next; + } + } + return QTreeWidget::moveCursor( action, modifiers ); +} + +void MgAdaptAdvWidgetTreeWidget::keyPressEvent( QKeyEvent* e ) +{ + switch ( e->key() ) { + case Qt::Key_F2: + { + QModelIndex index = currentIndex(); + if ( !isEditable( index ) ) { + for ( int i = 0; i < columnCount(); i++ ) { + QModelIndex sibling = index.sibling( index.row(), i ); + if ( isEditable( sibling ) ) { + if ( !edit( sibling, EditKeyPressed, e ) ) + e->ignore(); + } + } + } + } + break; + default: + break; + } + QTreeWidget::keyPressEvent( e ); +} + + +// ======================================================================= +// renvoie le medId associe au fichier Med apres ouverture +// ======================================================================= +med_idt OuvrirFichier(QString aFile) +{ + med_idt medIdt = MEDfileOpen(aFile.toStdString().c_str(),MED_ACC_RDONLY); + if (medIdt <0) + { + QMessageBox::critical( 0, QObject::tr("MG_ADAPT_ERROR"), + QObject::tr("MG_ADAPT_MED_FILE_1") ); + } + return medIdt; +} + +// ====================================================== +// ======================================================== +QString lireNomMaillage(QString aFile) +{ + QString nomMaillage = QString::null ; + int erreur = 0 ; + med_idt medIdt ; + + // Ouverture du fichier + medIdt = OuvrirFichier(aFile); + if ( medIdt < 0 ) + { + erreur = 1 ; + return nomMaillage; + } + med_int numberOfMeshes = MEDnMesh(medIdt) ; + if (numberOfMeshes == 0 ) + { + QMessageBox::critical( 0, QObject::tr("MG_ADAPT_ERROR"), + QObject::tr("MG_ADAPT_MED_FILE_2") ); + erreur = 2 ; + return nomMaillage; + } + if (numberOfMeshes > 1 ) + { + QMessageBox::critical( 0, QObject::tr("MG_ADAPT_ERROR"), + QObject::tr("MG_ADAPT_MED_FILE_3") ); + erreur = 3 ; + return nomMaillage; + } + + nomMaillage = lireNomMaillage2(medIdt,1); + // Fermeture du fichier + if ( medIdt > 0 ) MEDfileClose(medIdt); + + return nomMaillage; +} + +// ======================================================================= +// ======================================================================= +QString lireNomMaillage2(med_idt medIdt,int meshId) +{ + QString NomMaillage=QString::null; + char meshname[MED_NAME_SIZE+1]; + med_int spacedim,meshdim; + med_mesh_type meshtype; + char descriptionription[MED_COMMENT_SIZE+1]; + char dtunit[MED_SNAME_SIZE+1]; + med_sorting_type sortingtype; + med_int nstep; + med_axis_type axistype; + int naxis = MEDmeshnAxis(medIdt,1); + char *axisname=new char[naxis*MED_SNAME_SIZE+1]; + char *axisunit=new char[naxis*MED_SNAME_SIZE+1]; + med_err aRet = MEDmeshInfo(medIdt, + meshId, + meshname, + &spacedim, + &meshdim, + &meshtype, + descriptionription, + dtunit, + &sortingtype, + &nstep, + &axistype, + axisname, + axisunit); + + if ( aRet < 0 ) { + QMessageBox::critical( 0, QObject::tr("MG_ADAPT_ERROR"), \ + QObject::tr("MG_ADAPT_MED_FILE_4") ); + } + else { + NomMaillage=QString(meshname); + } + + delete[] axisname ; + delete[] axisunit ; + + return NomMaillage; +} + + + +// ======================================================================= +std::map GetListeChamps(QString aFile, bool errorMessage) +// ======================================================================= +{ +// Il faut voir si plusieurs maillages + + MESSAGE("GetListeChamps"); + std::map ListeChamp ; + + med_err erreur = 0 ; + med_idt medIdt ; + + while ( erreur == 0 ) + { + // Ouverture du fichier + SCRUTE(aFile.toStdString()); + medIdt = OuvrirFichier(aFile); + if ( medIdt < 0 ) + { + erreur = 1 ; + break ; + } + // Lecture du nombre de champs + med_int ncha = MEDnField(medIdt) ; + if (ncha < 1 ) + { + if(errorMessage) + { + QMessageBox::critical( 0, QObject::tr("_ERROR"), + QObject::tr("HOM_MED_FILE_5") ); + } + erreur = 2 ; + break ; + } + // Lecture des caracteristiques des champs + for (int i=0; i< ncha; i++) + { +// Lecture du nombre de composantes + med_int ncomp = MEDfieldnComponent(medIdt,i+1); +// Lecture du type du champ, des noms des composantes et du nom de l'unite + char nomcha [MED_NAME_SIZE+1]; + char meshname[MED_NAME_SIZE+1]; + char * comp = (char*) malloc(ncomp*MED_SNAME_SIZE+1); + char * unit = (char*) malloc(ncomp*MED_SNAME_SIZE+1); + char dtunit[MED_SNAME_SIZE+1]; + med_bool local; + med_field_type typcha; + med_int nbofcstp; + erreur = MEDfieldInfo(medIdt,i+1,nomcha,meshname,&local,&typcha,comp,unit,dtunit,&nbofcstp) ; + free(comp); + free(unit); + if ( erreur < 0 ) + { + if(errorMessage) + { + QMessageBox::critical( 0, QObject::tr("MG_ADAPT_ERROR"), + QObject::tr("MG_ADAPT_MED_FILE_6") ); + } + break ; + } + + ListeChamp.insert(std::pair (QString(nomcha), nbofcstp)); + + } + break ; + } + // Fermeture du fichier + if ( medIdt > 0 ) MEDfileClose(medIdt); + + return ListeChamp; +} + + + + diff --git a/src/SMESHGUI/MG_ADAPTGUI.hxx b/src/SMESHGUI/MG_ADAPTGUI.hxx new file mode 100644 index 000000000..db4012425 --- /dev/null +++ b/src/SMESHGUI/MG_ADAPTGUI.hxx @@ -0,0 +1,312 @@ +// Copyright (C) 2011-2020 CEA/DEN, EDF R&D +// +// 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 SMESHGUI : GUI for the adaptation in the SMESH component +// File : MG_ADAPTGUI.hxx +// +#ifndef MG_ADAPTGUI_HXX +#define MG_ADAPTGUI_HXX + +#include +// SMESH includes + +// Qt includes +#include +#include +#include + +#include "LightApp_DataOwner.h" +#include "SalomeApp_Application.h" +#include +#include +#include "SalomeApp_Module.h" +#include "SalomeApp_Study.h" +#include +#include + + +// model + + +#include "MG_ADAPT.hxx" + +class SUIT_ViewWindow; +class SUIT_Desktop; +class SUIT_Study; +class SUIT_ResourceMgr; + +class CAM_Module; + +class SALOMEDSClient_Study; +class SALOMEDSClient_SObject; + +class SalomeApp_Study; +class SalomeApp_Module; +class LightApp_SelectionMgr; + + +class QButtonGroup; +class QLineEdit; +class QGroupBox; +class QRadioButton; +class QLabel; +class QCheckBox; +class QGridLayout; +class QTabWidget; +class QDoubleSpinBox; +class QSpinBox; +class QTreeWidget; +class QTreeWidgetItem; +class QSpacerItem; +class QHBoxLayout; +class QItemDelegate; +class QComboBox; + +// IDL includes +#include + +class SVTK_ViewWindow; +class SVTK_Selector; +class SMESHGUI_MgAdaptDlg; +class SMESHGUI_MgAdaptArguments; +class SMESHGUI_SpinBox; +class MgAdaptAdvWidgetTreeWidget; +class MgAdaptAdvWidget; +class MgAdapt; +class QHeaderView; +class QFileDialog; + + +std::map GetListeChamps(QString aFile, bool errorMessage = true); +QString lireNomMaillage(QString aFile); +QString lireNomMaillage2(med_idt medIdt,int meshId); +med_idt OuvrirFichier(QString aFile); + +//================================================================================= +// class : SMESHGUI_MgAdaptDlg +// purpose : +//================================================================================= +class SMESHGUI_MgAdaptDlg : public QDialog +{ + Q_OBJECT; +public: + //! Property type + enum Mode { Arguments, AdvancedOptions}; + SMESHGUI_MgAdaptDlg( SalomeApp_Module*, MgAdapt*, QWidget* parent= 0,bool isCreation = true ); + ~SMESHGUI_MgAdaptDlg(); + + void buildDlg(); + void reject(); + bool checkParams(QString& msg) ; + void setModel(MgAdapt*); + MgAdapt* getModel() const; + +public slots: + +protected slots: + + virtual bool clickOnApply(); +private slots: + virtual void clickOnHelp(); + virtual void clickOnOk(); +protected : + + SMESHGUI_MgAdaptArguments* myArgs; + MgAdaptAdvWidget* myAdvOpt; + bool readParamsFromHypo( ) const ; + bool readParamsFromWidgets( ) ; + bool storeParamsToHypo( const MgAdaptHypothesisData& ) const; + +private: + + + SalomeApp_Module* mySMESHGUI; /* Current SMESHGUI object */ + QTabWidget* myTabWidget; + + + MgAdaptHypothesisData* myData; + MgAdapt* model; + +}; + +class SMESHGUI_MgAdaptArguments : public QWidget +{ + Q_OBJECT; +public: + //! Property type + enum Mode { Mesh, Browser}; + enum SIZEMAP { Local, Background, Constant}; + SMESHGUI_MgAdaptArguments( QWidget* parent); + ~SMESHGUI_MgAdaptArguments(); + void setMode( const Mode, const SIZEMAP ); + + QString* myFileInDir; + QString* myFileOutDir; + QString* myFileSizeMapDir; + QGroupBox* aMeshIn ; + QRadioButton* aMedfile; + QRadioButton* aBrowser ; + QLineEdit* aBrowserObject; + QPushButton* selectMedFilebutton ; + QSpacerItem* hspacer; + QLineEdit* selectMedFileLineEdit ; + QButtonGroup* meshInGroup ; + QGridLayout* meshIn ; + + QGroupBox* aMeshOut ; + QLabel* meshName; + QLineEdit* meshNameLineEdit; + QSpacerItem* secondHspacer; + QCheckBox* medFileCheckBox; + QPushButton* selectOutMedFilebutton; + QLineEdit* selectOutMedFileLineEdit; + QSpacerItem* thirdHspacer; + QCheckBox* publishOut; + QGridLayout* meshOut ; + + QGroupBox* sizeMapDefinition ; + QRadioButton* localButton; + QRadioButton* backgroundButton ; + QRadioButton* constantButton ; + QLabel* medFileBackground; + QPushButton* selectMedFileBackgroundbutton; + QLineEdit* selectMedFileBackgroundLineEdit; + QLabel* valueLabel; + QDoubleSpinBox* dvalue; + QButtonGroup* sizeMapDefGroup ; + QGridLayout* sizeMapDefGroupLayout; + + + QGroupBox* sizeMapField; + QLabel* fieldName; + QComboBox* fieldNameCmb; + QRadioButton* noTimeStep; + QRadioButton* lastTimeStep ; + QRadioButton* chosenTimeStep; + QLabel* timeStepLabel; + QSpinBox* timeStep; + QLabel* rankLabel; + QSpinBox* rankSpinBox; + QButtonGroup* timeStepGroup; + QGridLayout* sizeMapFieldGroupLayout; + +signals: + void updateSelection(); + void toExportMED(const char *); +public slots: + +protected slots: + +private slots: + void modeChanged( int); + void sizeMapDefChanged(int); + void timeStepGroupChanged(int timeStepType, bool disableOther = false, int max = 0); + void onSelectMedFilebuttonClicked(); + void clear(); + void onMedFileCheckBox(int); + void onPublishOut(int); + void onSelectOutMedFilebutton(); + void onSelectMedFileBackgroundbutton(); + void onLocalSelected(QString); + void onNoTimeStep(bool disableOther = false); + void onLastTimeStep(bool disableOther = false); + void onChosenTimeStep(bool disableOther = false, int max = 0); + +private: + + QString getMedFileName(bool avertir); + LightApp_SelectionMgr* selMgr ; + + std::map myFieldList; + + +}; +enum { + OPTION_ID_COLUMN = 0, + OPTION_TYPE_COLUMN, + OPTION_NAME_COLUMN = 0, + OPTION_VALUE_COLUMN, + NB_COLUMNS, +}; + +////////////////////////////////////////// +// MgAdaptAdvWidget +////////////////////////////////////////// +class MgAdaptAdvWidget : public QWidget +{ + Q_OBJECT + +public: + MgAdaptAdvWidget( QWidget* = 0, std::vector * = nullptr, Qt::WindowFlags = 0 ); + ~MgAdaptAdvWidget(); + std::vector < std::string > * myOptions; + QGridLayout *gridLayout_4; + MgAdaptAdvWidgetTreeWidget *myOptionTable; + QPushButton *addBtn; + QSpacerItem *horizontalSpacer; + QGroupBox *logGroupBox; + QGridLayout *gridLayout_2; + QGridLayout *gridLayout; + QLabel *workingDirectoryLabel; + QLineEdit *workingDirectoryLineEdit; + QPushButton *workingDirectoryPushButton; + QLabel *verboseLevelLabel; + QSpinBox *verboseLevelSpin; + QHBoxLayout *horizontalLayout; + QCheckBox *logInFileCheck; + QCheckBox *removeLogOnSuccessCheck; + QCheckBox *keepWorkingFilesCheck; + + void AddOption( const char* name_value_type, bool isCustom = false ); + void GetOptionAndValue( QTreeWidgetItem * tblRow, QString& option, QString& value, bool& dflt ); + void setupWidget(); +public slots: + + void onAddOption(); + void itemChanged(QTreeWidgetItem * tblRow, int column); + +}; + +enum { EDITABLE_ROLE = Qt::UserRole + 1, PARAM_NAME, + NAME_COL = 0, VALUE_COL + }; + + + +class ItemDelegate: public QItemDelegate +{ +public: + + ItemDelegate(QObject* parent=0): QItemDelegate(parent) {} + QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &o, const QModelIndex &index) const; +}; + +class MgAdaptAdvWidgetTreeWidget : public QTreeWidget +{ + Q_OBJECT +public: + MgAdaptAdvWidgetTreeWidget( QWidget* ); + +protected: + QModelIndex moveCursor( CursorAction, Qt::KeyboardModifiers ); + void keyPressEvent( QKeyEvent* ); +}; + + +#endif // MG_ADAPTGUI_HXX diff --git a/src/SMESHGUI/SMESHGUI_MG_ADAPTDRIVER.cxx b/src/SMESHGUI/SMESHGUI_MG_ADAPTDRIVER.cxx new file mode 100644 index 000000000..1e732a8a0 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MG_ADAPTDRIVER.cxx @@ -0,0 +1,771 @@ +// Copyright (C) 2007-2020 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 +// +// 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 +// +// File : SMESHGUI_MG_ADAPTDRIVER.cxx + +#include "SMESHGUI_MG_ADAPTDRIVER.h" + +#include "SUIT_Desktop.h" +#include "SUIT_Application.h" +#include "SUIT_Session.h" + +#include "SalomeApp_Application.h" +#include "SalomeApp_Module.h" +#include "SalomeApp_Study.h" + +#include "SMESH_Comment.hxx" +#include "SMESH_Actor.h" +#include "SMESHGUI.h" +#include "SMESHGUI_FilterDlg.h" +#include "SMESHGUI_Selection.h" +#include +#include "SMESHGUI_IdValidator.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_MeshEditPreview.h" +#include "SMESHGUI_VTKUtils.h" +#include +#include +#include +#include +#include +#include "SMESHGUI_SpinBox.h" + +#include +#include +#include +#include +#include +#include +#include "SMESHGUI_MeshUtils.h" + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +// SALOME KERNEL includes +#include +#include +#include +#include +#include "SalomeApp_Tools.h" +#include +#include +#include + +#include + +const int SPACING = 6; // layout spacing +const int MARGIN = 9; // layout margin + +SALOME_ListIO mySelected; + + +//================================================================ +// Function : firstIObject +// Purpose : Return the first selected object in the selected object list +//================================================================ +Handle(SALOME_InteractiveObject) firstIObject() +{ + const SALOME_ListIO& aList = selectedIO(); + return aList.Extent() > 0 ? aList.First() : Handle(SALOME_InteractiveObject)(); +} +//================================================================ +// Function : selectedIO +// Return the list of selected SALOME_InteractiveObject's +//================================================================ +const SALOME_ListIO& selectedIO() +{ + SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* > ( SUIT_Session::session()->activeApplication() ); + LightApp_SelectionMgr* aSelectionMgr = app->selectionMgr(); + if( aSelectionMgr ) + { + aSelectionMgr->selectedObjects( mySelected ); + for (SALOME_ListIteratorOfListIO it (mySelected); it.More(); it.Next()) + SCRUTE(it.Value()->getEntry()); + }; + return mySelected; +} +//================================================================ +// Function : getStudy +// Returne un pointeur sur l'etude active +//================================================================ +_PTR(Study) getStudy() +{ + static _PTR(Study) _study; + if(!_study) + _study = SalomeApp_Application::getStudy(); + return _study; +} + +bool createAndPublishMed(QString fileName) +{ + + SMESH::DriverMED_ReadStatus res; + SMESH::mesh_array_var aMeshes = new SMESH::mesh_array; + // SMESHGUI aGui; + + aMeshes = SMESHGUI::GetSMESHGen()->CreateMeshesFromMED( fileName.toUtf8().constData(), res ); + _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshes[0] ); + _PTR(Study) aStudy = SMESH::getStudy(); + QStringList anEntryList; + // bool isEmpty; + if ( aMeshSO ) { + _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder(); + _PTR(AttributePixMap) aPixmap = aBuilder->FindOrCreateAttribute( aMeshSO, "AttributePixMap" ); + aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" ); + anEntryList.append( aMeshSO->GetID().c_str() ); + } + else { + // isEmpty = true; + return false; + } + SMESHGUI::GetSMESHGUI()->updateObjBrowser(); + + // browse to the published meshes + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + anApp->browseObjects( anEntryList ); + return true; +} +bool createMgAdaptObject(MgAdapt *myMgAdapt ) +{ + // SMESH::SMESH_Mesh_var newMesh = SMESHGUI::GetSMESHGen()->CreateEmptyMesh(); + + // _PTR(SObject) aHypothesis; + _PTR(Study) aStudy = SMESH::getStudy(); + QStringList anEntryList; + _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder(); + _PTR(SComponent) mgadapt = aStudy->FindComponent("MG-ADAPT"); + _PTR(GenericAttribute) ga; + if (!aBuilder->FindAttribute(mgadapt, ga, "AttributeName") ) + { + mgadapt = aBuilder->NewComponent("MG-ADAPT"); + _PTR(AttributeName) Name = aBuilder->FindOrCreateAttribute(mgadapt, "AttributeName"); + Name->SetValue("MG-ADAPT"); + _PTR(AttributePixMap) myPixmap = aBuilder->FindOrCreateAttribute( mgadapt, "AttributePixMap" ); + myPixmap->SetPixMap( "ICON_MG_ADAPT" ); + anEntryList.append( mgadapt->GetID().c_str() ); + } + + _PTR(SObject) obj = aBuilder->NewObject(mgadapt); + _PTR(AttributeName) myName = aBuilder->FindOrCreateAttribute(obj, "AttributeName"); + myName->SetValue("hypo"); + _PTR(AttributePixMap) aPixmap = aBuilder->FindOrCreateAttribute( obj, "AttributePixMap" ); + aPixmap->SetPixMap( "ICON_SMESH_TREE_HYPO" ); + anEntryList.append( obj->GetID().c_str() ); + + SMESHGUI::GetSMESHGUI()->updateObjBrowser(); + + // // browse to the published meshes + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + anApp->browseObjects( anEntryList ); + return true; +} + + +// MG ADAPT UTILS +//================================================================ +// Function : IObjectCount +// Return the number of selected objects +//================================================================ +int IObjectCount() +{ + SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() ); + LightApp_SelectionMgr* aSelectionMgr = app->selectionMgr(); + if( aSelectionMgr ) + { + aSelectionMgr->selectedObjects( mySelected ); + SCRUTE(mySelected.Extent()); + return mySelected.Extent(); + } + return 0; +} + + +SMESHGUI_MG_AdaptComputeDlg_QThread::SMESHGUI_MG_AdaptComputeDlg_QThread(MgAdapt* aModel) +{ + model = aModel; + myResult = -1; +} + +void SMESHGUI_MG_AdaptComputeDlg_QThread::run() +{ + + int err; + std::string errStr; + errStr = model->compute(errStr); + std::string msg = err == 0 ? " ok" : std::string("Not ok \n")+ errStr; + exec(); +} + +int SMESHGUI_MG_AdaptComputeDlg_QThread::result() +{ + return myResult; +} + +void SMESHGUI_MG_AdaptComputeDlg_QThread::cancel() +{ + //~model->cancel(); +} + +SMESHGUI_MG_ADAPTDRIVER::SMESHGUI_MG_ADAPTDRIVER( SMESHGUI* theModule, MgAdapt* myModel, bool isCreation ) + : mySMESHGUI( theModule ), + myFilterDlg(0), + myIsApplyAndClose( false ), + SMESHGUI_MgAdaptDlg((SalomeApp_Module*)theModule, myModel, SMESHGUI::desktop(), isCreation) +{ + + resMgr = resourceMgr(); + + selMgr = selectionMgr(); + + // connections + connect(myArgs, SIGNAL(updateSelection()), this, SLOT(updateSelection())); + connect(myArgs, SIGNAL(toExportMED(const char*)), this, SLOT(exportMED(const char*))); +} + +SUIT_ResourceMgr* SMESHGUI_MG_ADAPTDRIVER::resourceMgr() +{ + return dynamic_cast( SUIT_Session::session()->resourceMgr() ); +} + +LightApp_SelectionMgr* SMESHGUI_MG_ADAPTDRIVER::selectionMgr() +{ + SalomeApp_Application* anApp = dynamic_cast( SUIT_Session::session()->activeApplication() ); + if( anApp ) + return dynamic_cast( anApp->selectionMgr() ); + else + return 0; +} + +void SMESHGUI_MG_ADAPTDRIVER::updateSelection() +{ + disconnect( selMgr, 0, this, 0 ); + selMgr->clearFilters(); + + SMESH::SetPointRepresentation( true ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( ActorSelection ); + if (myArgs->aBrowser->isChecked()) + { + connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() )); + selectionChanged(); + } + +} +void SMESHGUI_MG_ADAPTDRIVER::selectionChanged() +{ + //~ get selected mesh + SALOME_ListIO aList; + selMgr->selectedObjects(aList); + QString aString = ""; + int nbSel = aList.Extent(); + if (nbSel != 1) + return; + + Handle(SALOME_InteractiveObject) IO = aList.First(); + SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO(IO); + if ( !mesh->_is_nil() ) + { + myMesh = mesh; + + mySelectedObject = SMESH::IObjectToInterface( IO ); + if ( mySelectedObject->_is_nil() ) + return; + + } + else + return; + + SMESH::GetNameOfSelectedIObjects( selMgr, aString ); + if ( aString.isEmpty() ) aString = " "; + else aString = aString.trimmed(); + + + bool ok = !aString.isEmpty(); + if ( !mesh->_is_nil() ) + { + myArgs->aBrowserObject->setText( aString ); + myArgs->meshNameLineEdit->setText( aString ); + myArgs->selectOutMedFileLineEdit->setText(aString+QString(".med")); + } + +} +void SMESHGUI_MG_ADAPTDRIVER::exportMED(const char* tmp_file) +{ + bool toOverwrite = true; + bool toFindOutDim = true; + myMesh->ExportMED(tmp_file, false, -1, toOverwrite, toFindOutDim); +} +void SMESHGUI_MG_ADAPTDRIVER::setMyMesh(SMESH::SMESH_Mesh_var mesh) +{ + myMesh = mesh; +} +SMESH::SMESH_Mesh_var SMESHGUI_MG_ADAPTDRIVER::getMyMesh() +{ + return myMesh; +} + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void SMESHGUI_MG_ADAPTDRIVER::clickOnOk() +{ + setIsApplyAndClose( true ); + clickOnApply(); + reject(); +} +bool SMESHGUI_MG_ADAPTDRIVER::clickOnApply() +{ + + if ( SMESHGUI::isStudyLocked() ) + return false; + if( !isValid() ) + return false; + + SMESHGUI_MgAdaptDlg::clickOnApply(); + + bool ok = execute(); + //~SMESHGUI_MG_AdaptComputeDlg_QThread atest(getModel()); + //~atest.start(); + //~atest.quit(); + if (getModel()->getPublish()) this->createMeshInObjectBrowser(); + + return ok; +} + +bool SMESHGUI_MG_ADAPTDRIVER::execute() +{ + + int err; + std::string errStr; + try + { + err = getModel()->compute(errStr); + std::string msg = err == 0 ? " ok" : std::string("Not ok \n")+errStr ; + } + catch (const std::exception& e) + { + std::cerr<clear(); + myNbOkElements = 0; + + buttonOk->setEnabled(false); + buttonApply->setEnabled(false); + + //~myActor = 0; + myMesh = SMESH::SMESH_Mesh::_nil(); + + myIdSourceCheck->setChecked(true); + + onConstructor( 0 ); + } + +} + +//======================================================================= +//function : onConstructor +//purpose : switch operation mode +//======================================================================= + +void SMESHGUI_MG_ADAPTDRIVER::onConstructor( int withGeom ) +{ + + myGeomLabel ->setVisible( withGeom ); + myGeomNameEdit ->setVisible( withGeom ); + myReuseHypCheck ->setVisible( withGeom ); + myCopyElementsCheck->setVisible( withGeom ); + myFilterBtn ->setVisible( !withGeom ); + myIdSourceCheck ->setVisible( !withGeom ); + + if ( !withGeom ) + myMeshNameEdit->setText( SMESH::UniqueMeshName("Mesh")); + +} + + +//~void SMESHGUI_MG_ADAPTDRIVER::onSelectIdSource( bool ) +//~{} + + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void SMESHGUI_MG_ADAPTDRIVER::enterEvent (QEvent*) +{ + + // if ( !ConstructorsBox->isEnabled() ) { + // SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ); + // if ( aViewWindow && !mySelector ) { + // mySelector = aViewWindow->GetSelector(); + // } + // activateThisDialog(); + // } + +} + +//================================================================================= +// function : keyPressEvent() +// purpose : +//================================================================================= +void SMESHGUI_MG_ADAPTDRIVER::keyPressEvent( QKeyEvent* e ) +{ + + QDialog::keyPressEvent( e ); + if ( e->isAccepted() ) + return; + + if ( e->key() == Qt::Key_F1 ) { + e->accept(); + clickOnHelp(); + } + +} + +//================================================================================= +// function : clickOnHelp() +// purpose : +//================================================================================= +void SMESHGUI_MG_ADAPTDRIVER::clickOnHelp() +{ + + LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); + if (app) + app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); + else { + QString platform; +#ifdef WIN32 + platform = "winapplication"; +#else + platform = "application"; +#endif + SUIT_MessageBox::warning(this, tr("WRN_WARNING"), + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); + } + +} + +//======================================================================= +//function : getErrorMsg +//purpose : Return an error message and entries of invalid smesh object +//======================================================================= + +QString SMESHGUI_MG_ADAPTDRIVER::getErrorMsg( SMESH::string_array_var theInvalidEntries, + QStringList & theEntriesToBrowse ) +{ + + if ( theInvalidEntries->length() == 0 ) + return tr("OPERATION_FAILED"); + + // theInvalidEntries - SObject's that hold geometry objects whose + // counterparts are not found in the newGeometry, followed by SObject's + // holding mesh sub-objects that are invalid because they depend on a not found + // preceding sub-shape + + QString msg = tr("SUBSHAPES_NOT_FOUND_MSG") + "\n"; + + QString objString; + for ( CORBA::ULong i = 0; i < theInvalidEntries->length(); ++i ) + { + _PTR(SObject) so = SMESH::getStudy()->FindObjectID( theInvalidEntries[i].in() ); + + int objType = SMESHGUI_Selection::type( theInvalidEntries[i].in() ); + if ( objType < 0 ) // geom object + { + objString += "\n"; + if ( so ) + objString += so->GetName().c_str(); + else + objString += theInvalidEntries[i].in(); // it's something like "FACE #2" + } + else // smesh object + { + theEntriesToBrowse.push_back( theInvalidEntries[i].in() ); + + objString += "\n "; + switch ( objType ) { + case SMESH::MESH: + objString += tr("SMESH_MESH"); + break; + case SMESH::HYPOTHESIS: + objString += tr("SMESH_HYPOTHESIS"); + break; + case SMESH::ALGORITHM: + objString += tr("SMESH_ALGORITHM"); + break; + case SMESH::SUBMESH_VERTEX: + case SMESH::SUBMESH_EDGE: + case SMESH::SUBMESH_FACE: + case SMESH::SUBMESH_SOLID: + case SMESH::SUBMESH_COMPOUND: + case SMESH::SUBMESH: + objString += tr("SMESH_SUBMESH"); + break; + case SMESH::GROUP: + objString += tr("SMESH_GROUP"); + break; + default: + ; + } + objString += " \""; + if ( so ) + objString += so->GetName().c_str(); + objString += "\" ("; + objString += theInvalidEntries[i].in(); + objString += ")"; + } + } + if ( !objString.isEmpty() ) + msg += objString; + + return msg; +} + +//================================================================================= +// function : isValid +// purpose : +//================================================================================= + +bool SMESHGUI_MG_ADAPTDRIVER::isValid() +{ + bool ok = true; + return ok; +} + +bool SMESHGUI_MG_ADAPTDRIVER::createMeshInObjectBrowser() +{ + QString filename(getModel()->getMedFileOut().c_str()); + QStringList errors; + QStringList anEntryList; + bool isEmpty = false; + bool ok = false; + SMESH::SMESH_Gen_var SMESH_Gen_ptr = SMESHGUI::GetSMESHGen(); + if (!SMESH_Gen_ptr) { + std::cerr << "Could not retrieve SMESH_Gen_ptr" << std::endl; + throw SALOME_Exception(LOCALIZED("Could not retrieve SMESH::GetSMESHGen()")); + } + SMESH::mesh_array_var aMeshes = new SMESH::mesh_array; + aMeshes->length( 1 ); // one mesh only + SMESH::DriverMED_ReadStatus res; + aMeshes = SMESH_Gen_ptr->CreateMeshesFromMED( filename.toUtf8().constData(), res ); + if ( res != SMESH::DRS_OK ) { + errors.append( QString( "%1 :\n\t%2" ).arg( filename ).arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) ); + } + _PTR(Study) aStudy = SMESH::getStudy(); + for ( int i = 0, iEnd = aMeshes->length(); i < iEnd; i++ ) + { + _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshes[i] ); + if ( aMeshSO ) { + _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder(); + _PTR(AttributePixMap) aPixmap = aBuilder->FindOrCreateAttribute( aMeshSO, "AttributePixMap" ); + aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" ); // put REFINED mesh ico + anEntryList.append( aMeshSO->GetID().c_str() ); + } + else { + isEmpty = true; + } + } + // update Object browser + SMESHGUI::GetSMESHGUI()->updateObjBrowser(); + // browse to the published meshes + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + anApp->browseObjects( anEntryList ); + + // show Error message box if there were errors + if ( errors.count() > 0 ) { + SUIT_MessageBox::critical( SMESHGUI::desktop(), + QObject::tr( "SMESH_ERROR" ), + QObject::tr( "SMESH_IMPORT_ERRORS" ) + "\n" + errors.join( "\n" ) ); + } + + // show warning message box, if some imported mesh is empty + if ( isEmpty ) { + SUIT_MessageBox::warning( SMESHGUI::desktop(), + QObject::tr( "SMESH_WRN_WARNING" ), + QObject::tr( "SMESH_DRS_SOME_EMPTY" ) ); + } + return true; +} + +//================================================================ +// function : setIsApplyAndClose +// Purpose : Set value of the flag indicating that the dialog is +// accepted by Apply & Close button +//================================================================ +void SMESHGUI_MG_ADAPTDRIVER::setIsApplyAndClose( const bool theFlag ) +{ + myIsApplyAndClose = theFlag; +}//================================================================ +// function : isApplyAndClose +// Purpose : Get value of the flag indicating that the dialog is +// accepted by Apply & Close button +//================================================================ +bool SMESHGUI_MG_ADAPTDRIVER::isApplyAndClose() const +{ + return myIsApplyAndClose; +} + +//================================================================================= +// function : DeactivateActiveDialog() +// purpose : +//================================================================================= +void SMESHGUI_MG_ADAPTDRIVER::deactivateActiveDialog() +{ + + if (ConstructorsBox->isEnabled()) { + ConstructorsBox->setEnabled(false); + GroupArguments->setEnabled(false); + GroupButtons->setEnabled(false); + mySMESHGUI->ResetState(); + mySMESHGUI->SetActiveDialogBox(0); + if ( selMgr ) + selMgr->removeFilter( myIdSourceFilter ); + } +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void SMESHGUI_MG_ADAPTDRIVER::activateThisDialog() +{ + + /* Emit a signal to deactivate the active dialog */ + // mySMESHGUI->EmitSignalDeactivateDialog(); + // ConstructorsBox->setEnabled(true); + // GroupArguments->setEnabled(true); + // GroupButtons->setEnabled(true); + + // mySMESHGUI->SetActiveDialogBox((QDialog*)this); + + // onSelectIdSource( myIdSourceCheck->isChecked() ); + + // SelectionIntoArgument(); +} + +//================================================================================= +// function : setFilters() +// purpose : SLOT. Called when "Filter" button pressed. +//================================================================================= +void SMESHGUI_MG_ADAPTDRIVER::setFilters() +{ + if(myMesh->_is_nil()) { + SUIT_MessageBox::critical(this, + tr("SMESH_ERROR"), + tr("NO_MESH_SELECTED")); + return; + } + if ( !myFilterDlg ) + myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL ); + + QList types; + if ( myMesh->NbEdges() ) types << SMESH::EDGE; + if ( myMesh->NbFaces() ) types << SMESH::FACE; + if ( myMesh->NbVolumes() ) types << SMESH::VOLUME; + if ( myMesh->NbBalls() ) types << SMESH::BALL; + if ( myMesh->Nb0DElements()) types << SMESH::ELEM0D; + if ( types.count() > 1 ) types << SMESH::ALL; + + myFilterDlg->Init( types ); + myFilterDlg->SetSelection(); + myFilterDlg->SetMesh( myMesh ); + myFilterDlg->SetSourceWg( myLineEditElements ); + + myFilterDlg->show(); +} + +//================================================================================= +// function : onOpenView() +// purpose : +//================================================================================= +void SMESHGUI_MG_ADAPTDRIVER::onOpenView() +{ + if ( mySelector ) { + SMESH::SetPointRepresentation(false); + } + else { + mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector(); + activateThisDialog(); + } +} + +//================================================================================= +// function : onCloseView() +// purpose : +//================================================================================= +void SMESHGUI_MG_ADAPTDRIVER::onCloseView() +{ + deactivateActiveDialog(); + mySelector = 0; +} diff --git a/src/SMESHGUI/SMESHGUI_MG_ADAPTDRIVER.h b/src/SMESHGUI/SMESHGUI_MG_ADAPTDRIVER.h new file mode 100644 index 000000000..7f2e3ee6f --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MG_ADAPTDRIVER.h @@ -0,0 +1,227 @@ +// Copyright (C) 2011-2020 CEA/DEN, EDF R&D +// +// 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 SMESHGUI : GUI for the adaptation in the SMESH component +// File : SMESHGUI_MG_ADAPTDRIVER.h +// +#ifndef SMESHGUI_MG_ADAPTDRIVER_H +#define SMESHGUI_MG_ADAPTDRIVER_H + +#include +// SMESH includes +#include "SMESH_SMESHGUI.hxx" + +// Qt includes +#include +#include +#include + +#include + +#include "LightApp_DataOwner.h" +#include "SalomeApp_Application.h" +#include +#include +#include "SalomeApp_Module.h" +#include "SalomeApp_Study.h" +#include +#include +// model +//~#include "MG_ADAPT.h" +#include "MG_ADAPTGUI.hxx" +#include "MG_ADAPT.hxx" + + +class SUIT_ViewWindow; +class SUIT_Desktop; +class SUIT_Study; +class SUIT_ResourceMgr; + +class CAM_Module; + +class SALOMEDSClient_Study; +class SALOMEDSClient_SObject; + +class SalomeApp_Study; +class SalomeApp_Module; +class LightApp_SelectionMgr; +class SUIT_SelectionFilter; + + +class QButtonGroup; +class QLineEdit; +class QGroupBox; +class QRadioButton; +class QLabel; +class QCheckBox; +class QGridLayout; +class QTabWidget; +class QDoubleSpinBox; +class QSpinBox; +class QTreeWidget; +class QTreeWidgetItem; +class QSpacerItem; +class QHBoxLayout; +class QItemDelegate; +class QComboBox; +class QObject; + + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_Gen) +class SMESHGUI; +class SMESHGUI_MgAdaptDlg; +class SMESHGUI_IdValidator; +class SMESHGUI_FilterDlg; +class MgAdapt; +class QHeaderView; +class QFileDialog; + + +int IObjectCount(); +const SALOME_ListIO& selectedIO(); +_PTR(Study) getStudy(); +Handle(SALOME_InteractiveObject) firstIObject(); +bool createAndPublishMed(QString fileName); +bool createMgAdaptObject(MgAdapt* myMgAdapt = 0); + +class SMESHGUI_EXPORT SMESHGUI_MG_AdaptComputeDlg_QThread : public QThread +{ + Q_OBJECT + +public: + SMESHGUI_MG_AdaptComputeDlg_QThread(MgAdapt* model); + int result(); + void cancel(); +protected: + void run(); + +private: + + MgAdapt* model; + int myResult; +}; + +class SMESHGUI_MG_ADAPTDRIVER : public SMESHGUI_MgAdaptDlg +{ + Q_OBJECT; + +public : + SMESHGUI_MG_ADAPTDRIVER( SMESHGUI*, MgAdapt*, bool isCreation = true ); + void setMyMesh(SMESH::SMESH_Mesh_var); + SMESH::SMESH_Mesh_var getMyMesh() ; + +private : + + SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ + LightApp_SelectionMgr* selMgr ; + SUIT_ResourceMgr* resMgr; + SUIT_ResourceMgr* resourceMgr(); + LightApp_SelectionMgr* selectionMgr(); + SMESH::SMESH_Mesh_var myMesh ; + + + + void Init( bool = true ); + void enterEvent( QEvent* ); /* mouse enter the QWidget */ + void keyPressEvent( QKeyEvent* ); + QString getErrorMsg( SMESH::string_array_var invalidEntries, + QStringList & entriesToBrowse ); + + bool isValid(); + bool createMeshInObjectBrowser(); + void setIsApplyAndClose( const bool theFlag ); + bool isApplyAndClose() const; + bool execute(); + SMESHGUI_IdValidator* myIdValidator; + int myNbOkElements; /* to check when elements are defined */ + + SVTK_Selector* mySelector; + + bool myBusy; + GEOM::GEOM_Object_var myNewGeometry; + //~SMESH_Actor* myActor; // + SUIT_SelectionFilter* myIdSourceFilter; + + SMESH::SMESH_IDSource_var mySelectedObject; + + QTabWidget* myTabWidget; + QButtonGroup* GroupConstructors; + + QGroupBox* ConstructorsBox; + QGroupBox* GroupArguments; + QGroupBox* GroupButtons; + + QPushButton* buttonOk; + QPushButton* buttonCancel; + QPushButton* buttonApply; + QPushButton* buttonHelp; + + QLabel* myTextLabelElements; + QLabel* myGeomLabel; + QLineEdit* myLineEditElements; + QLineEdit* myMeshNameEdit; + QLineEdit* myGeomNameEdit; + QCheckBox* myIdSourceCheck; + QCheckBox* myCopyGroupsCheck; + QCheckBox* myReuseHypCheck; + QCheckBox* myCopyElementsCheck; + QCheckBox* myKeepIdsCheck; + + QPushButton* myFilterBtn; + SMESHGUI_FilterDlg* myFilterDlg; + + QString myHelpFileName; + + bool myIsApplyAndClose; + + QString inputMeshName; + QString outputMeshName; +private slots: + void selectionChanged(); + void updateSelection(); + +protected slots : + +private slots: + + void exportMED(const char* ); + + virtual bool clickOnApply(); + virtual void clickOnOk(); + virtual void clickOnHelp(); + //~void SelectionIntoArgument(); + void deactivateActiveDialog(); + void activateThisDialog(); + void onConstructor( int ); + //~void onTextChange( const QString& ); + //~void onSelectIdSource( bool ); + void setFilters(); + void onOpenView(); + void onCloseView(); + + +}; + + + + +#endif // SMESHGUI_MG_ADAPTDRIVER_H -- 2.30.2