X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGHS3DPlugin%2FGHS3DPlugin_Hypothesis.cxx;h=45d4d9249765195029c218c9412739ed9c27ef8e;hb=ac2d9a39f715f3cdfd4d1678df1ed65e3f42ea59;hp=1c1c6b970a38295093315f8551091a50f353be8a;hpb=744c914fb53e3676e3ec45080046ef1274f43522;p=plugins%2Fghs3dplugin.git diff --git a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx index 1c1c6b9..45d4d92 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx +++ b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx @@ -1,9 +1,9 @@ -// Copyright (C) 2004-2013 CEA/DEN, EDF R&D +// Copyright (C) 2004-2023 CEA, EDF // // 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. +// 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 @@ -24,52 +24,129 @@ //============================================================================= // #include "GHS3DPlugin_Hypothesis.hxx" -#include -#include -#include + +#include +#include +#include #include -#ifdef WNT +#ifdef WIN32 #include #define getpid _getpid #endif +using namespace std; + +namespace +{ + struct GET_DEFAULT // struct used to get default value from GetOptionValue() + { + bool isDefault; + operator bool* () { return &isDefault; } + }; +} + //======================================================================= //function : GHS3DPlugin_Hypothesis //======================================================================= -GHS3DPlugin_Hypothesis::GHS3DPlugin_Hypothesis(int hypId, int studyId, SMESH_Gen * gen) - : SMESH_Hypothesis(hypId, studyId, gen), - myToMeshHoles(DefaultMeshHoles()), - myToMakeGroupsOfDomains(DefaultToMakeGroupsOfDomains()), - myMaximumMemory(-1), - myInitialMemory(-1), - myOptimizationLevel(DefaultOptimizationLevel()), - myWorkingDirectory(DefaultWorkingDirectory()), - myKeepFiles(DefaultKeepFiles()), - myVerboseLevel(DefaultVerboseLevel()), - myToCreateNewNodes(DefaultToCreateNewNodes()), - myToUseBoundaryRecoveryVersion(DefaultToUseBoundaryRecoveryVersion()), - myToUseFemCorrection(DefaultToUseFEMCorrection()), - myToRemoveCentralPoint(DefaultToRemoveCentralPoint()), - myGradation(DefaultGradation()), - myLogInStandardOutput(DefaultStandardOutputLog()), - _enfVertexList(DefaultGHS3DEnforcedVertexList()), - _enfVertexCoordsSizeList(DefaultGHS3DEnforcedVertexCoordsValues()), - _enfVertexEntrySizeList(DefaultGHS3DEnforcedVertexEntryValues()), - _coordsEnfVertexMap(DefaultCoordsGHS3DEnforcedVertexMap()), - _geomEntryEnfVertexMap(DefaultGeomEntryGHS3DEnforcedVertexMap()), - _enfMeshList(DefaultGHS3DEnforcedMeshList()), - _entryEnfMeshMap(DefaultEntryGHS3DEnforcedMeshListMap()), - _enfNodes(TIDSortedNodeGroupMap()), - _enfEdges(TIDSortedElemGroupMap()), - _enfTriangles(TIDSortedElemGroupMap()), - _nodeIDToSizeMap(DefaultID2SizeMap()), - _groupsToRemove(DefaultGroupsToRemove()) -{ - _name = "GHS3D_Parameters"; +GHS3DPlugin_Hypothesis::GHS3DPlugin_Hypothesis(int hypId, SMESH_Gen * gen) + : SMESH_Hypothesis(hypId, gen), + myToMeshHoles(DefaultMeshHoles()), + myToMakeGroupsOfDomains(DefaultToMakeGroupsOfDomains()), + myMaximumMemory(-1), + myInitialMemory(-1), + myOptimizationLevel(DefaultOptimizationLevel()), + myKeepFiles(DefaultKeepFiles()), + myWorkingDirectory(DefaultWorkingDirectory()), + myVerboseLevel(DefaultVerboseLevel()), + myToCreateNewNodes(DefaultToCreateNewNodes()), + myToUseBoundaryRecoveryVersion(DefaultToUseBoundaryRecoveryVersion()), + myToUseFemCorrection(DefaultToUseFEMCorrection()), + myToRemoveCentralPoint(DefaultToRemoveCentralPoint()), + myLogInStandardOutput(DefaultStandardOutputLog()), + myRemoveLogOnSuccess( DefaultRemoveLogOnSuccess() ), + myGradation(DefaultGradation()), + myUseVolumeProximity(DefaultUseVolumeProximity()), + myNbVolumeProximityLayers(DefaultNbVolumeProximityLayers()), + myAlgorithm(DefaultAlgorithm()), + myNumOfThreads(DefaultNumOfThreads()), + myUseNumOfThreads(DefaultUseNumOfThreads()), + myPthreadModeMG(DefaultMyPthreadMode()), + myPthreadModeMGHPC(DefaultMyPthreadModeHPC()), + myMinSize(0), + myMinSizeDefault(0), + myMaxSize(0), + myMaxSizeDefault(0) +{ + _name = GetHypType(); _param_algo_dim = 3; + + const char* boolOptionNames[] = { "no_initial_central_point", // no + "force_max_size", // no + "apply_gradation_on_skin_vertex_sizes", // yes + "optimise_worst_elements", // no + "force_output_quadratic_mesh", // no + "rectify_jacobian", // yes + "jacobian_rectification_respect_input_surface_mesh", // yes + "" // mark of end + }; + const char* intOptionNames[] = { "max_number_of_errors_printed", // 1 + "" // mark of end + }; + const char* doubleOptionNames[] = { "target_quality", // 0 + "sliver_angle", // 5 + "" // mark of end + }; + const char* charOptionNames[] = { "boundary_regeneration", // standard + "split_overconstrained_tetrahedra", // no + "" // 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 meshing + + _defaultOptionValues["no_initial_central_point" ] = "no"; + _defaultOptionValues["force_max_size" ] = "no"; + _defaultOptionValues["apply_gradation_on_skin_vertex_sizes" ] = "yes"; + _defaultOptionValues["optimise_worst_elements" ] = "no"; + _defaultOptionValues["force_output_quadratic_mesh" ] = "no"; + _defaultOptionValues["rectify_jacobian" ] = "yes"; + _defaultOptionValues["jacobian_rectification_respect_input_surface_mesh"] = "yes"; + _defaultOptionValues["max_number_of_errors_printed" ] = "1"; + _defaultOptionValues["target_quality" ] = "";//NoValue(); + _defaultOptionValues["sliver_angle" ] = "5"; + _defaultOptionValues["boundary_regeneration" ] = "standard"; + _defaultOptionValues["split_overconstrained_tetrahedra" ] = "no"; + +#ifdef _DEBUG_ + // check validity of option names of _defaultOptionValues + TOptionValues::iterator n2v = _defaultOptionValues.begin(); + for ( ; n2v != _defaultOptionValues.end(); ++n2v ) + ASSERT( _option2value.count( n2v->first )); + ASSERT( _option2value.size() == _defaultOptionValues.size() ); +#endif } //======================================================================= @@ -90,11 +167,17 @@ void GHS3DPlugin_Hypothesis::SetToMeshHoles(bool toMesh) bool GHS3DPlugin_Hypothesis::GetToMeshHoles(bool checkFreeOption) const { - if (checkFreeOption && !myTextOption.empty()) { - if ( myTextOption.find("-c 0")) - return true; - if ( myTextOption.find("-c 1")) - return false; + if ( checkFreeOption ) + { + std::string optionName = "components"; + TOptionValues::const_iterator op_val = _customOption2value.find(optionName); + if ( op_val != _customOption2value.end()) + { + if ( op_val->second.find("all")) + return true; + if ( op_val->second.find("outside_components")) + return false; + } } return myToMeshHoles; } @@ -136,7 +219,7 @@ bool GHS3DPlugin_Hypothesis::GetToMakeGroupsOfDomains(const GHS3DPlugin_Hypothes //function : SetMaximumMemory //======================================================================= -void GHS3DPlugin_Hypothesis::SetMaximumMemory(int MB) +void GHS3DPlugin_Hypothesis::SetMaximumMemory(float MB) { if ( myMaximumMemory != MB ) { myMaximumMemory = MB; @@ -149,7 +232,7 @@ void GHS3DPlugin_Hypothesis::SetMaximumMemory(int MB) // * automatic memory adjustment mode. Default is zero //======================================================================= -int GHS3DPlugin_Hypothesis::GetMaximumMemory() const +float GHS3DPlugin_Hypothesis::GetMaximumMemory() const { return myMaximumMemory; } @@ -158,7 +241,7 @@ int GHS3DPlugin_Hypothesis::GetMaximumMemory() const //function : SetInitialMemory //======================================================================= -void GHS3DPlugin_Hypothesis::SetInitialMemory(int MB) +void GHS3DPlugin_Hypothesis::SetInitialMemory(float MB) { if ( myInitialMemory != MB ) { myInitialMemory = MB; @@ -170,7 +253,7 @@ void GHS3DPlugin_Hypothesis::SetInitialMemory(int MB) //function : GetInitialMemory //======================================================================= -int GHS3DPlugin_Hypothesis::GetInitialMemory() const +float GHS3DPlugin_Hypothesis::GetInitialMemory() const { return myInitialMemory; } @@ -272,9 +355,108 @@ void GHS3DPlugin_Hypothesis::SetToCreateNewNodes(bool toCreate) } //======================================================================= -//function : GetToCreateNewNodes +//function : SetAlgorithm +//======================================================================= +void GHS3DPlugin_Hypothesis::SetAlgorithm(ImplementedAlgorithms algoId) +{ + if ( myAlgorithm != algoId ) { + myAlgorithm = algoId; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : short GetAlgorithm() const; + +//======================================================================= +GHS3DPlugin_Hypothesis::ImplementedAlgorithms GHS3DPlugin_Hypothesis::GetAlgorithm() const +{ + return (ImplementedAlgorithms) myAlgorithm; +} + +//======================================================================= +//function : SetPthreadMode +//======================================================================= +void GHS3DPlugin_Hypothesis::SetPthreadMode(PThreadMode pThreadsMode ) +{ + if ( myPthreadModeMG != pThreadsMode ) { + myPthreadModeMG = pThreadsMode; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : short GetPthreadMode() const; + +//======================================================================= +GHS3DPlugin_Hypothesis::PThreadMode GHS3DPlugin_Hypothesis::GetPthreadMode() const +{ + return (PThreadMode)myPthreadModeMG; +} + //======================================================================= +//function : SetParallelMode +//======================================================================= +void GHS3DPlugin_Hypothesis::SetParallelMode(ParallelMode parallelMode ) +{ + if ( myPthreadModeMGHPC != parallelMode ) { + myPthreadModeMGHPC = parallelMode; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : short GetParallelMode() const; + +//======================================================================= +GHS3DPlugin_Hypothesis::ParallelMode GHS3DPlugin_Hypothesis::GetParallelMode() const +{ + return (ParallelMode)myPthreadModeMGHPC; +} +//======================================================================= +//function : SetUseNumOfThreads +//======================================================================= +void GHS3DPlugin_Hypothesis::SetUseNumOfThreads(bool setUseOfThreads) +{ + if ( myUseNumOfThreads != setUseOfThreads ) { + myUseNumOfThreads = setUseOfThreads; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : bool GetUseNumOfThreads() const; + +//======================================================================= +bool GHS3DPlugin_Hypothesis::GetUseNumOfThreads() const +{ + return myUseNumOfThreads; +} + +//======================================================================= +//function : SetNumOfThreads +//======================================================================= +void GHS3DPlugin_Hypothesis::SetNumOfThreads(short numOfThreads) +{ + if ( myNumOfThreads != numOfThreads ) { + myNumOfThreads = numOfThreads; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : short GetUseNumOfThreads() const; + +//======================================================================= +short GHS3DPlugin_Hypothesis::GetNumOfThreads() const +{ + return myNumOfThreads; +} + +//======================================================================= +//function : GetToCreateNewNodes +//======================================================================= bool GHS3DPlugin_Hypothesis::GetToCreateNewNodes() const { return myToCreateNewNodes; @@ -328,10 +510,8 @@ bool GHS3DPlugin_Hypothesis::GetFEMCorrection() const void GHS3DPlugin_Hypothesis::SetToRemoveCentralPoint(bool toRemove) { - if ( myToRemoveCentralPoint != toRemove ) { - myToRemoveCentralPoint = toRemove; - NotifySubMeshesHypothesisModification(); - } + SetOptionValue( "no_initial_central_point", toRemove ? "yes" : "no" ); + myToRemoveCentralPoint = toRemove; } //======================================================================= @@ -344,24 +524,47 @@ bool GHS3DPlugin_Hypothesis::GetToRemoveCentralPoint() const } //======================================================================= -//function : SetTextOption +//function : SetAdvancedOption //======================================================================= -void GHS3DPlugin_Hypothesis::SetTextOption(const std::string& option) +void GHS3DPlugin_Hypothesis::SetAdvancedOption(const std::string& option) { - if ( myTextOption != option ) { - myTextOption = option; - NotifySubMeshesHypothesisModification(); + size_t wsPos = option.find(' '); + if ( wsPos == string::npos ) + { + SetOptionValue( option, "" ); + } + else + { + std::string opt( option, 0, wsPos ); + std::string val( option, wsPos + 1 ); + SetOptionValue( opt, val ); } } //======================================================================= -//function : GetTextOption +//function : GetAdvancedOption //======================================================================= -std::string GHS3DPlugin_Hypothesis::GetTextOption() const +std::string GHS3DPlugin_Hypothesis::GetAdvancedOption() const { - return myTextOption; + SMESH_Comment txt; + + TOptionValues::const_iterator o2v = _option2value.begin(); + for ( ; o2v != _option2value.end(); ++o2v ) + if ( !o2v->second.empty() ) + { + if ( !txt.empty() ) + txt << " "; + txt << o2v->first << " " << o2v->second; + } + for ( o2v = _customOption2value.begin(); o2v != _customOption2value.end(); ++o2v ) + { + if ( !txt.empty() ) + txt << " "; + txt << o2v->first << " " << o2v->second; + } + return txt; } //======================================================================= @@ -385,6 +588,46 @@ double GHS3DPlugin_Hypothesis::GetGradation() const return myGradation; } +//============================================================================= +void GHS3DPlugin_Hypothesis::SetMinSize(double theMinSize) +{ + if ( theMinSize != myMinSize ) + { + myMinSize = theMinSize; + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +void GHS3DPlugin_Hypothesis::SetMaxSize(double theMaxSize) +{ + if ( theMaxSize != myMaxSize ) + { + myMaxSize = theMaxSize; + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +void GHS3DPlugin_Hypothesis::SetUseVolumeProximity( bool toUse ) +{ + if ( myUseVolumeProximity != toUse ) + { + myUseVolumeProximity = toUse; + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +void GHS3DPlugin_Hypothesis::SetNbVolumeProximityLayers( int nbLayers ) +{ + if ( myNbVolumeProximityLayers != nbLayers ) + { + myNbVolumeProximityLayers = nbLayers; + NotifySubMeshesHypothesisModification(); + } +} + //======================================================================= //function : SetStandardOutputLog //======================================================================= @@ -431,8 +674,12 @@ bool GHS3DPlugin_Hypothesis::GetRemoveLogOnSuccess() const //function : SetEnforcedVertex //======================================================================= -bool GHS3DPlugin_Hypothesis::SetEnforcedVertex(std::string theName, std::string theEntry, std::string theGroupName, - double size, double x, double y, double z, bool isCompound) +bool GHS3DPlugin_Hypothesis::SetEnforcedVertex(std::string theName, + std::string theEntry, + std::string theGroupName, + double size, + double x, double y, double z, + bool isCompound) { MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedVertex(\""<< theName << "\", \""<< theEntry << "\", \"" << theGroupName << "\", " << size << ", " << x << ", " << y << ", " << z << ", "<< isCompound << ")"); @@ -548,13 +795,13 @@ bool GHS3DPlugin_Hypothesis::SetEnforcedMesh(SMESH_Mesh& theMesh, SMESH::Element //======================================================================= //function : SetEnforcedGroup //======================================================================= -bool GHS3DPlugin_Hypothesis::SetEnforcedGroup(const SMESHDS_Mesh* theMeshDS, SMESH::long_array_var theIDs, SMESH::ElementType elementType, std::string name, std::string entry, std::string groupName) +bool GHS3DPlugin_Hypothesis::SetEnforcedGroup(const SMESHDS_Mesh* theMeshDS, SMESH::smIdType_array_var theIDs, SMESH::ElementType elementType, std::string name, std::string entry, std::string groupName) { MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedGroup"); TIDSortedElemSet theElemSet; if ( theIDs->length() == 0 ){MESSAGE("The source group is empty");} - for (int i=0; i < theIDs->length(); i++) { - CORBA::Long ind = theIDs[i]; + for ( CORBA::ULong i = 0; i < theIDs->length(); i++) { + SMESH::smIdType ind = theIDs[i]; if (elementType == SMESH::NODE) { const SMDS_MeshNode * node = theMeshDS->FindNode(ind); @@ -623,7 +870,6 @@ bool GHS3DPlugin_Hypothesis::SetEnforcedElements(TIDSortedElemSet theElemSet, SM nodeRet = _enfNodes.insert(make_pair(node,groupName)); added = added && nodeRet.second; } -// added = true;s } break; case SMESH::EDGE: @@ -632,12 +878,12 @@ bool GHS3DPlugin_Hypothesis::SetEnforcedElements(TIDSortedElemSet theElemSet, SM added = added && elemRet.second; } else if (elem->GetType() > SMDSAbs_Edge) { - SMDS_ElemIteratorPtr it = elem->edgesIterator(); - for (;it->more();) { - const SMDS_MeshElement* anEdge = it->next(); - elemRet = _enfEdges.insert(make_pair(anEdge,groupName)); - added = added && elemRet.second; - } + // SMDS_ElemIteratorPtr it = elem->edgesIterator(); + // for (;it->more();) { + // const SMDS_MeshElement* anEdge = it->next(); + // elemRet = _enfEdges.insert(make_pair(anEdge,groupName)); + // added = added && elemRet.second; + // } } break; case SMESH::FACE: @@ -649,14 +895,14 @@ bool GHS3DPlugin_Hypothesis::SetEnforcedElements(TIDSortedElemSet theElemSet, SM } } else if (elem->GetType() > SMDSAbs_Face) { // Group of faces - SMDS_ElemIteratorPtr it = elem->facesIterator(); - for (;it->more();) { - const SMDS_MeshElement* aFace = it->next(); - if (aFace->NbCornerNodes() == 3) { - elemRet = _enfTriangles.insert(make_pair(aFace,groupName)); - added = added && elemRet.second; - } - } + // SMDS_ElemIteratorPtr it = elem->facesIterator(); + // for (;it->more();) { + // const SMDS_MeshElement* aFace = it->next(); + // if (aFace->NbCornerNodes() == 3) { + // elemRet = _enfTriangles.insert(make_pair(aFace,groupName)); + // added = added && elemRet.second; + // } + // } } break; default: @@ -674,7 +920,6 @@ bool GHS3DPlugin_Hypothesis::SetEnforcedElements(TIDSortedElemSet theElemSet, SM //======================================================================= GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex* GHS3DPlugin_Hypothesis::GetEnforcedVertex(double x, double y, double z) - throw (std::invalid_argument) { std::vector coord(3); coord[0] = x; @@ -688,7 +933,6 @@ GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex* GHS3DPlugin_Hypothesis::GetEnforce } GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex* GHS3DPlugin_Hypothesis::GetEnforcedVertex(const std::string theEntry) - throw (std::invalid_argument) { if (_geomEntryEnfVertexMap.count(theEntry)>0) return _geomEntryEnfVertexMap[theEntry]; @@ -703,7 +947,6 @@ GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex* GHS3DPlugin_Hypothesis::GetEnforce //======================================================================= bool GHS3DPlugin_Hypothesis::RemoveEnforcedVertex(double x, double y, double z, const std::string theEntry) - throw (std::invalid_argument) { bool toNotify = false; std::ostringstream msg; @@ -839,39 +1082,36 @@ bool GHS3DPlugin_Hypothesis::DefaultMeshHoles() bool GHS3DPlugin_Hypothesis::DefaultToMakeGroupsOfDomains() { - return true; // issue 0022172 + return false; // issue 0022172 } //======================================================================= //function : DefaultMaximumMemory //======================================================================= -#ifndef WIN32 -#include -#else +#if defined(WIN32) #include +#elif !defined(__APPLE__) +#include #endif -int GHS3DPlugin_Hypothesis::DefaultMaximumMemory() +float GHS3DPlugin_Hypothesis::DefaultMaximumMemory() { -#ifndef WIN32 - struct sysinfo si; - int err = sysinfo( &si ); - if ( err == 0 ) { - int ramMB = si.totalram * si.mem_unit / 1024 / 1024; - return (int) ( 0.7 * ramMB ); - } -#else +#if defined(WIN32) // See http://msdn.microsoft.com/en-us/library/aa366589.aspx MEMORYSTATUSEX statex; statex.dwLength = sizeof (statex); - int err = GlobalMemoryStatusEx (&statex); + long err = GlobalMemoryStatusEx (&statex); if (err != 0) { - int totMB = - statex.ullTotalPhys / 1024 / 1024 + - statex.ullTotalPageFile / 1024 / 1024 + - statex.ullTotalVirtual / 1024 / 1024; - return (int) ( 0.7 * totMB ); + double totMB = double( statex.ullAvailPhys ) / 1024. / 1024.; + return float( 0.7 * totMB ); + } +#elif !defined(__APPLE__) + struct sysinfo si; + long err = sysinfo( &si ); + if ( err == 0 ) { + double ramMB = double( si.totalram * si.mem_unit / 1024 / 1024 ); + return float( 0.7 * ramMB ); } #endif return 1024; @@ -881,7 +1121,7 @@ int GHS3DPlugin_Hypothesis::DefaultMaximumMemory() //function : DefaultInitialMemory //======================================================================= -int GHS3DPlugin_Hypothesis::DefaultInitialMemory() +float GHS3DPlugin_Hypothesis::DefaultInitialMemory() { return DefaultMaximumMemory(); } @@ -890,7 +1130,7 @@ int GHS3DPlugin_Hypothesis::DefaultInitialMemory() //function : DefaultOptimizationLevel //======================================================================= -short GHS3DPlugin_Hypothesis::DefaultOptimizationLevel() +short GHS3DPlugin_Hypothesis::DefaultOptimizationLevel() { return Medium; } @@ -981,15 +1221,6 @@ bool GHS3DPlugin_Hypothesis::DefaultToRemoveCentralPoint() return false; } -//======================================================================= -//function : DefaultGradation -//======================================================================= - -double GHS3DPlugin_Hypothesis::DefaultGradation() -{ - return 1.05; -} - //======================================================================= //function : DefaultStandardOutputLog //======================================================================= @@ -1028,11 +1259,11 @@ std::ostream & GHS3DPlugin_Hypothesis::SaveTo(std::ostream & save) save << (int)myToRemoveCentralPoint << " "; save << myGradation << " "; save << myToMakeGroupsOfDomains << " "; - if (!myTextOption.empty()) { - save << "__OPTIONS_BEGIN__ "; - save << myTextOption << " "; - save << "__OPTIONS_END__ "; - } + // if (!myTextOption.empty()) { + // save << "__OPTIONS_BEGIN__ "; + // save << myTextOption << " "; + // save << "__OPTIONS_END__ "; + // } TGHS3DEnforcedVertexList::iterator it = _enfVertexList.begin(); @@ -1059,7 +1290,7 @@ std::ostream & GHS3DPlugin_Hypothesis::SaveTo(std::ostream & save) } if (enfVertex->coords.size()) { save << " " << "__BEGIN_COORDS__"; - for (int i=0;icoords.size();i++) + for ( size_t i = 0; i < enfVertex->coords.size(); i++ ) save << " " << enfVertex->coords[i]; save << " " << "__END_COORDS__"; } @@ -1102,6 +1333,32 @@ std::ostream & GHS3DPlugin_Hypothesis::SaveTo(std::ostream & save) } save << " " << "__ENFORCED_MESHES_END__ "; } + + // New options in 2.9.6 (issue #17784) + + save << " " << myUseVolumeProximity; + save << " " << myNbVolumeProximityLayers; + save << " " << myMinSize; + save << " " << myMaxSize; + save << " " << myMinSizeDefault; + save << " " << myMaxSizeDefault; + + save << " " << _option2value.size(); + TOptionValues::iterator o2v = _option2value.begin(); + for ( ; o2v != _option2value.end(); ++o2v ) + save << " -" << o2v->first << " -" << o2v->second; + + save << " " << _customOption2value.size(); + for ( o2v = _customOption2value.begin(); o2v != _customOption2value.end(); ++o2v ) + save << " -" << o2v->first << " -" << o2v->second; + + // New options (issue #32737) + save << " " << myAlgorithm; + save << " " << myUseNumOfThreads; + save << " " << myNumOfThreads; + save << " " << myPthreadModeMG; + save << " " << myPthreadModeMGHPC; + return save; } @@ -1115,31 +1372,31 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) int i; double d; - isOK = (load >> i); + isOK = static_cast(load >> i); if (isOK) myToMeshHoles = i; else load.clear(ios::badbit | load.rdstate()); - isOK = (load >> i); + isOK = static_cast(load >> d); if (isOK) - myMaximumMemory = i; + myMaximumMemory = float( d ); else load.clear(ios::badbit | load.rdstate()); - isOK = (load >> i); + isOK = static_cast(load >> d); if (isOK) - myInitialMemory = i; + myInitialMemory = float( d ); else load.clear(ios::badbit | load.rdstate()); - isOK = (load >> i); + isOK = static_cast(load >> i); if (isOK) - myOptimizationLevel = i; + myOptimizationLevel = (short int) i; else load.clear(ios::badbit | load.rdstate()); - isOK = (load >> myWorkingDirectory); + isOK = static_cast(load >> myWorkingDirectory); if (isOK) { if ( myWorkingDirectory == "0") { // myWorkingDirectory was empty myKeepFiles = false; @@ -1154,44 +1411,44 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) load.clear(ios::badbit | load.rdstate()); if ( !myWorkingDirectory.empty() ) { - isOK = (load >> i); + isOK = static_cast(load >> i); if (isOK) myKeepFiles = i; else load.clear(ios::badbit | load.rdstate()); } - isOK = (load >> i); + isOK = static_cast(load >> i); if (isOK) myVerboseLevel = (short) i; else load.clear(ios::badbit | load.rdstate()); - isOK = (load >> i); + isOK = static_cast(load >> i); if (isOK) myToCreateNewNodes = (bool) i; else load.clear(ios::badbit | load.rdstate()); - isOK = (load >> i); + isOK = static_cast(load >> i); if (isOK) myToUseBoundaryRecoveryVersion = (bool) i; else load.clear(ios::badbit | load.rdstate()); - isOK = (load >> i); + isOK = static_cast(load >> i); if (isOK) myToUseFemCorrection = (bool) i; else load.clear(ios::badbit | load.rdstate()); - isOK = (load >> i); + isOK = static_cast(load >> i); if (isOK) myToRemoveCentralPoint = (bool) i; else load.clear(ios::badbit | load.rdstate()); - isOK = (load >> d); + isOK = static_cast(load >> d); if (isOK) myGradation = d; else @@ -1201,12 +1458,12 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) bool hasOptions = false; bool hasEnforcedVertices = false; bool hasEnforcedMeshes = false; - isOK = (load >> separator); + isOK = static_cast(load >> separator); if ( isOK && ( separator == "0" || separator == "1" )) { myToMakeGroupsOfDomains = ( separator == "1" ); - isOK = (load >> separator); + isOK = static_cast(load >> separator); } if (isOK) { @@ -1221,24 +1478,24 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) if (hasOptions) { std::string txt; while (isOK) { - isOK = (load >> txt); + isOK = static_cast(load >> txt); if (isOK) { if (txt == "__OPTIONS_END__") { - if (!myTextOption.empty()) { - // Remove last space - myTextOption.erase(myTextOption.end()-1); - } + // if (!myTextOption.empty()) { + // // Remove last space + // myTextOption.erase(myTextOption.end()-1); + // } isOK = false; break; } - myTextOption += txt; - myTextOption += " "; + // myTextOption += txt; + // myTextOption += " "; } } } if (hasOptions) { - isOK = (load >> separator); + isOK = static_cast(load >> separator); if (isOK && separator == "__ENFORCED_VERTICES_BEGIN__") hasEnforcedVertices = true; if (isOK && separator == "__ENFORCED_MESHES_BEGIN__") @@ -1250,14 +1507,16 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) double size, coords[3]; bool isCompound; bool hasCoords = false; - isOK = (load >> txt); // __BEGIN_VERTEX__ + isOK = static_cast(load >> txt); // __BEGIN_VERTEX__ while (isOK) { - if (txt == "__ENFORCED_VERTICES_END__") - isOK = false; - + if (txt == "__ENFORCED_VERTICES_END__") { + //isOK = false; + break; + } + TGHS3DEnforcedVertex *enfVertex = new TGHS3DEnforcedVertex(); while (isOK) { - isOK = (load >> txt); + isOK = static_cast(load >> txt); if (txt == "__END_VERTEX__") { enfVertex->name = name; enfVertex->geomEntry = entry; @@ -1283,7 +1542,7 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) if (txt == "__BEGIN_NAME__") { // __BEGIN_NAME__ while (isOK && (txt != "__END_NAME__")) { - isOK = (load >> txt); + isOK = static_cast(load >> txt); if (txt != "__END_NAME__") { if (!name.empty()) name += " "; @@ -1294,9 +1553,9 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) } if (txt == "__BEGIN_ENTRY__") { // __BEGIN_ENTRY__ - isOK = (load >> entry); - isOK = (load >> isCompound); - isOK = (load >> txt); // __END_ENTRY__ + isOK = static_cast(load >> entry); + isOK = static_cast(load >> isCompound); + isOK = static_cast(load >> txt); // __END_ENTRY__ if (txt != "__END_ENTRY__") throw std::exception(); MESSAGE("entry: " << entry); @@ -1304,7 +1563,7 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) if (txt == "__BEGIN_GROUP__") { // __BEGIN_GROUP__ while (isOK && (txt != "__END_GROUP__")) { - isOK = (load >> txt); + isOK = static_cast(load >> txt); if (txt != "__END_GROUP__") { if (!groupName.empty()) groupName += " "; @@ -1316,28 +1575,28 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) if (txt == "__BEGIN_COORDS__") { // __BEGIN_COORDS__ hasCoords = true; - isOK = (load >> coords[0] >> coords[1] >> coords[2]); - isOK = (load >> txt); // __END_COORDS__ + isOK = static_cast(load >> coords[0] >> coords[1] >> coords[2]); + isOK = static_cast(load >> txt); // __END_COORDS__ if (txt != "__END_COORDS__") throw std::exception(); MESSAGE("coords: " << coords[0] <<","<< coords[1] <<","<< coords[2]); } if (txt == "__BEGIN_SIZE__") { // __BEGIN_ENTRY__ - isOK = (load >> size); - isOK = (load >> txt); // __END_ENTRY__ + isOK = static_cast(load >> size); + isOK = static_cast(load >> txt); // __END_ENTRY__ if (txt != "__END_SIZE__") { throw std::exception(); } MESSAGE("size: " << size); } } - isOK = (load >> txt); // __BEGIN_VERTEX__ + isOK = static_cast(load >> txt); // __BEGIN_VERTEX__ } } if (hasEnforcedVertices) { - isOK = (load >> separator); + isOK = static_cast(load >> separator); if (isOK && separator == "__ENFORCED_MESHES_BEGIN__") hasEnforcedMeshes = true; } @@ -1345,7 +1604,7 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) if (hasEnforcedMeshes) { std::string txt, name, entry, groupName; int elementType = -1, persistID = -1; - isOK = (load >> txt); // __BEGIN_ENF_MESH__ + isOK = static_cast(load >> txt); // __BEGIN_ENF_MESH__ while (isOK) { // if (isOK) { if (txt == "__ENFORCED_MESHES_END__") @@ -1353,7 +1612,7 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) TGHS3DEnforcedMesh *enfMesh = new TGHS3DEnforcedMesh(); while (isOK) { - isOK = (load >> txt); + isOK = static_cast(load >> txt); if (txt == "__END_ENF_MESH__") { enfMesh->name = name; enfMesh->entry = entry; @@ -1362,7 +1621,7 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) enfMesh->persistID = persistID; _enfMeshList.insert(enfMesh); - std::cout << "Restoring of enforced mesh " <> txt); + isOK = static_cast(load >> txt); if (txt != "__END_NAME__") { if (!name.empty()) name += " "; @@ -1385,16 +1644,16 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) } if (txt == "__BEGIN_ENTRY__") { // __BEGIN_ENTRY__ - isOK = (load >> entry); - isOK = (load >> txt); // __END_ENTRY__ + isOK = static_cast(load >> entry); + isOK = static_cast(load >> txt); // __END_ENTRY__ if (txt != "__END_ENTRY__") throw std::exception(); MESSAGE("entry: " << entry); } if (txt == "__BEGIN_ELEM_TYPE__") { // __BEGIN_ELEM_TYPE__ - isOK = (load >> elementType); - isOK = (load >> txt); // __END_ELEM_TYPE__ + isOK = static_cast(load >> elementType); + isOK = static_cast(load >> txt); // __END_ELEM_TYPE__ if (txt != "__END_ELEM_TYPE__") throw std::exception(); MESSAGE("elementType: " << elementType); @@ -1402,7 +1661,7 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) if (txt == "__BEGIN_GROUP__") { // __BEGIN_GROUP__ while (isOK && (txt != "__END_GROUP__")) { - isOK = (load >> txt); + isOK = static_cast(load >> txt); if (txt != "__END_GROUP__") { if (!groupName.empty()) groupName += " "; @@ -1413,16 +1672,79 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) } // if if (txt == "__PERSIST_ID__") { - isOK = (load >> persistID); + isOK = static_cast(load >> persistID); MESSAGE("persistID: " << persistID); } - std::cout << "isOK: " << isOK << std::endl; + //std::cout << "isOK: " << isOK << std::endl; } // while // } // if - isOK = (load >> txt); // __BEGIN_ENF_MESH__ + isOK = static_cast(load >> txt); // __BEGIN_ENF_MESH__ } // while } // if + // New options in 2.9.6 (issue #17784) + + if ( ! hasOptions && ! hasEnforcedVertices && ! hasEnforcedMeshes ) + myUseVolumeProximity = ( separator == "1" ); + else if ( static_cast( load >> i )) + myUseVolumeProximity = (bool) i; + + if ( static_cast( load >> myNbVolumeProximityLayers )) + { + load >> myMinSize; + load >> myMaxSize; + load >> myMinSizeDefault; + load >> myMaxSizeDefault; + + std::string option, value; + if ( static_cast( load >> i ) && i >= 0 ) + { + for ( int nbRead = 0; nbRead < i; ++nbRead ) + { + load >> option >> value; + _option2value[ std::string( option, 1 )] = std::string( value, 1 ); + } + } + if ( static_cast( load >> i ) && i >= 0 ) + { + for ( int nbRead = 0; nbRead < i; ++nbRead ) + { + load >> option >> value; + _customOption2value[ std::string( option, 1 )] = std::string( value, 1 ); + } + } + } + + isOK = static_cast(load >> i); + if (isOK) + myAlgorithm = (short) i; + else + load.clear(ios::badbit | load.rdstate()); + + isOK = static_cast(load >> i); + if (isOK) + myUseNumOfThreads = (short) i; + else + load.clear(ios::badbit | load.rdstate()); + + isOK = static_cast(load >> i); + if (isOK) + myNumOfThreads = (short) i; + else + load.clear(ios::badbit | load.rdstate()); + + isOK = static_cast(load >> i); + if (isOK) + myPthreadModeMG = (short) i; + else + load.clear(ios::badbit | load.rdstate()); + + isOK = static_cast(load >> i); + if (isOK) + myPthreadModeMGHPC = (short) i; + else + load.clear(ios::badbit | load.rdstate()); + return load; } @@ -1446,134 +1768,201 @@ bool GHS3DPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* /*theMesh*/) { myToMakeGroupsOfDomains = ( !dflts._shape || dflts._shape->IsNull() ); + + double diagonal = dflts._elemLength * _gen->GetBoundaryBoxSegmentation(); + myMinSizeDefault = 1e-3 * diagonal; + myMaxSizeDefault = diagonal / 5.; + return true; } +void GHS3DPlugin_Hypothesis::SetAdvancedOptionsInCommandLine( std::string & cmd ) const +{ + std::string option, value; + bool isDefault; + const TOptionValues* options[] = { & this->_option2value, & this->_customOption2value }; + for ( int iOp = 0; iOp < 2; ++iOp ) + { + TOptionValues::const_iterator o2v = options[iOp]->begin(); + for ( ; o2v != options[iOp]->end(); ++o2v ) + { + option = o2v->first; + value = this->GetOptionValue( option, &isDefault ); + + if ( isDefault ) + continue; + + if ( value.empty() )//value == NoValue() ) + { + if ( this->_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; + } + } +} + //================================================================================ /*! - * \brief Return command to run ghs3d mesher excluding file prefix (-f) + * \brief Return command to run MG-Tetra mesher excluding file prefix (-f) */ //================================================================================ - std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* hyp, - const bool hasShapeToMesh) + const bool hasShapeToMesh, + const bool forExecutable) { - TCollection_AsciiString cmd = GetExeName().c_str(); + GHS3DPlugin_Hypothesis::ImplementedAlgorithms algoId = hyp ? (ImplementedAlgorithms) hyp->myAlgorithm : MGTetra; + std::string cmd = GetExeName( algoId ); + // check if any option is overridden by hyp->myTextOption - bool m = hyp ? ( hyp->myTextOption.find("-m") == std::string::npos ) : true; - bool M = hyp ? ( hyp->myTextOption.find("-M") == std::string::npos ) : true; - bool c = hyp ? ( hyp->myTextOption.find("-c") == std::string::npos ) : true; - bool o = hyp ? ( hyp->myTextOption.find("-o") == std::string::npos ) : true; - bool p0 = hyp ? ( hyp->myTextOption.find("-p0") == std::string::npos ) : true; - bool C = hyp ? ( hyp->myTextOption.find("-C") == std::string::npos ) : true; - bool v = hyp ? ( hyp->myTextOption.find("-v") == std::string::npos ) : true; - bool fem = hyp ? ( hyp->myTextOption.find("-FEM")== std::string::npos ) : true; - bool rem = hyp ? ( hyp->myTextOption.find("-no_initial_central_point")== std::string::npos ) : true; - bool gra = hyp ? ( hyp->myTextOption.find("-Dcpropa")== std::string::npos ) : true; + bool max_memory = hyp ? !hyp->HasOptionDefined("max_memory") : true; + bool auto_memory = hyp ? !hyp->HasOptionDefined("automatic_memory") : true; + bool comp = hyp ? !hyp->HasOptionDefined("components") : true; + bool optim_level = hyp ? !hyp->HasOptionDefined("optimisation_level") : true; + bool no_int_points = hyp ? !hyp->HasOptionDefined("no_internal_points") : true; + bool C = hyp ? !hyp->HasOptionDefined("-C") : true; + bool verbose = hyp ? !hyp->HasOptionDefined("verbose") : true; + bool gra = hyp ? !hyp->HasOptionDefined("-Dcpropa") : true; + bool rem = hyp ? !hyp->HasOptionDefined("no_initial_central_point") : true; + //bool fem = hyp ? !hyp->HasOptionDefined("-FEM") : true; // if use boundary recovery version, few options are allowed bool useBndRecovery = !C; if ( !useBndRecovery && hyp ) useBndRecovery = hyp->myToUseBoundaryRecoveryVersion; - // ghs3d needs to know amount of memory it may use (MB). - // Default memory is defined at ghs3d installation but it may be not enough, - // so allow to use about all available memory - if ( m ) { - int aMaximumMemory = hyp ? hyp->myMaximumMemory : -1; - cmd += " -m "; - if ( aMaximumMemory < 0 ) - cmd += DefaultMaximumMemory(); - else - cmd += aMaximumMemory; + // MG-Tetra needs to know amount of memory it may use (MB). + // Default memory is defined at MG-Tetra installation but it may be not enough, // so allow to use about all available memory + if ( algoId == MGTetra && max_memory ) { + float aMaximumMemory = hyp ? hyp->myMaximumMemory : -1; + cmd += " --max_memory "; + if ( aMaximumMemory < 0 ) cmd += SMESH_Comment( int( DefaultMaximumMemory() )); + else cmd += SMESH_Comment( int( aMaximumMemory )); } - if ( M && !useBndRecovery ) { - int aInitialMemory = hyp ? hyp->myInitialMemory : -1; - cmd += " -M "; - if ( aInitialMemory > 0 ) - cmd += aInitialMemory; - else - cmd += "100"; + if ( algoId == MGTetra && ( auto_memory && !useBndRecovery ) ) { + float aInitialMemory = hyp ? hyp->myInitialMemory : -1; + cmd += " --automatic_memory "; + if ( aInitialMemory > 0 ) cmd += SMESH_Comment( int( aInitialMemory )); + else cmd += "100"; } + // component to mesh - // 0 , all components to be meshed - // 1 , only the main ( outermost ) component to be meshed - if ( c && !useBndRecovery ) { - // We always run GHS3D with "to mesh holes'==TRUE (see PAL19680) + if ( comp && !useBndRecovery ) { + // We always run MG-Tetra with "to mesh holes'==TRUE (see PAL19680) if ( hasShapeToMesh ) - cmd += " -c 0"; + cmd += " --components all"; else { bool aToMeshHoles = hyp ? hyp->myToMeshHoles : DefaultMeshHoles(); - if ( aToMeshHoles ) - cmd += " -c 0"; - else - cmd += " -c 1"; + if ( aToMeshHoles ) cmd += " --components all"; + else cmd += " --components outside_components"; } } + const bool toCreateNewNodes = ( no_int_points && ( !hyp || hyp->myToCreateNewNodes )); // optimization level - if ( o && hyp && !useBndRecovery ) { - if ( hyp->myOptimizationLevel >= 0 && hyp->myOptimizationLevel < 5 ) { - const char* level[] = { "none" , "light" , "standard" , "standard+" , "strong" }; - cmd += " -o "; - cmd += level[ hyp->myOptimizationLevel ]; - } + if ( !toCreateNewNodes ) { + cmd += " --optimisation_level none"; // issue 22608 + } + else if ( optim_level && hyp && !useBndRecovery ) { + const char* level[] = { "none" , "light" , "standard" , "standard+" , "strong" }; + const short myOpt = hyp->myOptimizationLevel; + + if ( myOpt >= 0 && myOpt < 5 && ( algoId == MGTetra || ( algoId == MGTetraHPC && myOpt != 3 ) ) ) { + cmd += " --optimisation_level "; + cmd += level[ myOpt ]; + } } // to create internal nodes - if ( p0 && hyp && !hyp->myToCreateNewNodes ) { - cmd += " -p0"; + if ( no_int_points && !toCreateNewNodes ) { + if ( forExecutable ) + cmd += " --no_internal_points"; + else + cmd += " --internalpoints no"; } - // verbose mode - if ( v && hyp ) { - cmd += " -v "; - cmd += hyp->myVerboseLevel; - } + if ( hyp ) + { + // verbose mode + if ( verbose ) { + cmd += " --verbose " + SMESH_Comment( hyp->myVerboseLevel ); + } - // boundary recovery version - if ( useBndRecovery ) { - cmd += " -C"; - } + // to remove initial central point. + if ( rem && hyp->myToRemoveCentralPoint ) { + if ( forExecutable ) + cmd += " --no_initial_central_point"; + else + cmd += " --centralpoint no"; + } - // to use FEM correction - if ( fem && hyp && hyp->myToUseFemCorrection) { - cmd += " -FEM"; - } + if ( hyp->GetMinSize() > 0 ) + cmd += " --min_size " + SMESH_Comment( hyp->GetMinSize() ); - // to remove initial central point. - if ( rem && hyp && hyp->myToRemoveCentralPoint) { - cmd += " -no_initial_central_point"; - } + if ( hyp->GetMaxSize() > 0 ) + cmd += " --max_size " + SMESH_Comment( hyp->GetMaxSize() ); - // options as text - if ( hyp && !hyp->myTextOption.empty() ) { - cmd += " "; - cmd += (char*) hyp->myTextOption.c_str(); - } + // to define volumic gradation. + if ( gra ) + cmd += " --gradation " + SMESH_Comment( hyp->myGradation ); + + if ( hyp->GetUseNumOfThreads() ) + { + cmd += " --max_number_of_threads " + SMESH_Comment( hyp->GetNumOfThreads() ); + const char* pthreadMode[] = { "none" , "aggressive" , "safe" }; + const char* parallelMode[] = { "none", "reproducible_given_max_number_of_threads", "reproducible", "aggressive" }; + + if ( algoId == MGTetra && hyp->myPthreadModeMG >= 1 && hyp->myPthreadModeMG < 3 ) { + cmd += " --pthreads_mode "; + cmd += pthreadMode[ hyp->myPthreadModeMG ]; + } + else if ( algoId == MGTetraHPC && hyp->myPthreadModeMGHPC >= 1 && hyp->myPthreadModeMGHPC < 4 ) + { + cmd += " --parallel_strategy "; + cmd += parallelMode[ hyp->myPthreadModeMGHPC ]; + } + } - // to define volumic gradation. - if ( gra && hyp) { - cmd += " -Dcpropa="; - cmd += hyp->myGradation; + // proximity + if ( hyp->GetUseVolumeProximity() ) + { + cmd += " --volume_proximity_layers " + SMESH_Comment( hyp->GetNbVolumeProximityLayers() ); + } + + hyp->SetAdvancedOptionsInCommandLine( cmd ); } -#ifdef WNT +#ifdef WIN32 cmd += " < NUL"; #endif - - return cmd.ToCString(); + return cmd; } //================================================================================ /*! - * \brief Return a unique file name + * \brief Return a unique file name for MGTetra */ //================================================================================ std::string GHS3DPlugin_Hypothesis::GetFileName(const GHS3DPlugin_Hypothesis* hyp) { std::string aTmpDir = hyp ? hyp->GetWorkingDirectory() : DefaultWorkingDirectory(); + if ( !SMESH_File( aTmpDir ).exists() ) + aTmpDir = Kernel_Utils::GetTmpDirByPath( aTmpDir ); + const char lastChar = *aTmpDir.rbegin(); #ifdef WIN32 if(lastChar != '\\') aTmpDir+='\\'; @@ -1590,15 +1979,51 @@ std::string GHS3DPlugin_Hypothesis::GetFileName(const GHS3DPlugin_Hypothesis* hy return aGenericName.ToCString(); } +//================================================================================ +/*! + * \brief Return a unique file name when running MGTetra HPC + */ +//================================================================================ + +std::string GHS3DPlugin_Hypothesis::GetFileNameHPC(const GHS3DPlugin_Hypothesis* hyp) +{ + std::string aTmpDir = hyp ? hyp->GetWorkingDirectory() : DefaultWorkingDirectory(); + if ( !SMESH_File( aTmpDir ).exists() ) + aTmpDir = Kernel_Utils::GetTmpDirByPath( aTmpDir ); + + const char lastChar = *aTmpDir.rbegin(); +#ifdef WIN32 + if(lastChar != '\\') aTmpDir+='\\'; +#else + if(lastChar != '/') aTmpDir+='/'; +#endif + + TCollection_AsciiString aGenericName = (char*)aTmpDir.c_str(); + aGenericName += "MGTETRAHPC_"; + aGenericName += getpid(); + aGenericName += "_"; + aGenericName += Abs((Standard_Integer)(long) aGenericName.ToCString()); + + return aGenericName.ToCString(); +} + //================================================================================ /* * Return the name of executable */ //================================================================================ -std::string GHS3DPlugin_Hypothesis::GetExeName() +std::string GHS3DPlugin_Hypothesis::GetExeName( ImplementedAlgorithms algoId ) { - return "mg-tetra.exe"; + switch ( algoId ) + { + case MGTetra: + return "mg-tetra.exe"; + case MGTetraHPC: + return "mg-tetra_hpc.exe"; + default: + throw( "Undefined algorithm id: "); + } } //================================================================================ @@ -1609,50 +2034,259 @@ std::string GHS3DPlugin_Hypothesis::GetExeName() GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexList GHS3DPlugin_Hypothesis::GetEnforcedVertices(const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedVertices():DefaultGHS3DEnforcedVertexList(); + return hyp ? hyp->_GetEnforcedVertices(): TGHS3DEnforcedVertexList(); } GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues GHS3DPlugin_Hypothesis::GetEnforcedVerticesCoordsSize (const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedVerticesCoordsSize(): DefaultGHS3DEnforcedVertexCoordsValues(); + return hyp ? hyp->_GetEnforcedVerticesCoordsSize(): TGHS3DEnforcedVertexCoordsValues(); } GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexEntryValues GHS3DPlugin_Hypothesis::GetEnforcedVerticesEntrySize (const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedVerticesEntrySize(): DefaultGHS3DEnforcedVertexEntryValues(); + return hyp ? hyp->_GetEnforcedVerticesEntrySize(): TGHS3DEnforcedVertexEntryValues(); } GHS3DPlugin_Hypothesis::TCoordsGHS3DEnforcedVertexMap GHS3DPlugin_Hypothesis::GetEnforcedVerticesByCoords (const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedVerticesByCoords(): DefaultCoordsGHS3DEnforcedVertexMap(); + return hyp ? hyp->_GetEnforcedVerticesByCoords(): TCoordsGHS3DEnforcedVertexMap(); } GHS3DPlugin_Hypothesis::TGeomEntryGHS3DEnforcedVertexMap GHS3DPlugin_Hypothesis::GetEnforcedVerticesByEntry (const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedVerticesByEntry(): DefaultGeomEntryGHS3DEnforcedVertexMap(); + return hyp ? hyp->_GetEnforcedVerticesByEntry(): TGeomEntryGHS3DEnforcedVertexMap(); } GHS3DPlugin_Hypothesis::TIDSortedNodeGroupMap GHS3DPlugin_Hypothesis::GetEnforcedNodes(const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedNodes():DefaultIDSortedNodeGroupMap(); + return hyp ? hyp->_GetEnforcedNodes():TIDSortedNodeGroupMap(); } GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap GHS3DPlugin_Hypothesis::GetEnforcedEdges(const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedEdges():DefaultIDSortedElemGroupMap(); + return hyp ? hyp->_GetEnforcedEdges():TIDSortedElemGroupMap(); } GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap GHS3DPlugin_Hypothesis::GetEnforcedTriangles(const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedTriangles():DefaultIDSortedElemGroupMap(); + return hyp ? hyp->_GetEnforcedTriangles():TIDSortedElemGroupMap(); } GHS3DPlugin_Hypothesis::TID2SizeMap GHS3DPlugin_Hypothesis::GetNodeIDToSizeMap(const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetNodeIDToSizeMap(): DefaultID2SizeMap(); + return hyp ? hyp->_GetNodeIDToSizeMap(): TID2SizeMap(); } GHS3DPlugin_Hypothesis::TSetStrings GHS3DPlugin_Hypothesis::GetGroupsToRemove(const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetGroupsToRemove(): DefaultGroupsToRemove(); + return hyp ? hyp->_GetGroupsToRemove(): TSetStrings(); +} + + +//============================================================================= +void GHS3DPlugin_Hypothesis::SetOptionValue(const std::string& optionName, + const std::string& optionValue) +{ + TOptionValues::iterator op_val = _option2value.find(optionName); + if (op_val == _option2value.end()) + { + op_val = _customOption2value.find( optionName ); + if ( op_val != _customOption2value.end() && op_val->second != optionValue ) + NotifySubMeshesHypothesisModification(); + _customOption2value[ optionName ] = optionValue; + return; + } + + if (op_val->second != optionValue) + { + const char* ptr = optionValue.c_str(); + // strip white spaces + while (ptr[0] == ' ') + ptr++; + size_t 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; + + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +//! 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 GHS3DPlugin_Hypothesis::GetOptionValue(const std::string& optionName, + bool* isDefault) const +{ + 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-Tetra 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; +} + + +//============================================================================= +bool GHS3DPlugin_Hypothesis::HasOptionDefined( const std::string& optionName ) const +{ + bool isDefault = false; + try + { + GetOptionValue( optionName, &isDefault ); + } + catch ( std::invalid_argument& ) + { + return false; + } + return !isDefault; +} + +//============================================================================= +void GHS3DPlugin_Hypothesis::ClearOption(const std::string& optionName) +{ + TOptionValues::iterator op_val = _customOption2value.find(optionName); + if (op_val != _customOption2value.end()) + _customOption2value.erase(op_val); + else { + op_val = _option2value.find(optionName); + if (op_val != _option2value.end()) + op_val->second.clear(); + } +} + +//============================================================================= +GHS3DPlugin_Hypothesis::TOptionValues GHS3DPlugin_Hypothesis::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; +} + +//================================================================================ +/*! + * \brief Converts a string to a bool + */ +//================================================================================ + +bool GHS3DPlugin_Hypothesis::ToBool(const std::string& str, bool* isOk ) +{ + std::string s = str; + if ( isOk ) *isOk = true; + + for ( size_t i = 0; i <= s.size(); ++i ) + s[i] = (char) 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 real value + */ +//================================================================================ + +double GHS3DPlugin_Hypothesis::ToDbl(const std::string& str, bool* isOk ) +{ + 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 integer value + */ +//================================================================================ + +int GHS3DPlugin_Hypothesis::ToInt(const std::string& str, bool* isOk ) +{ + 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; +} +