1 // Copyright (C) 2004-2023 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 //=============================================================================
21 // File : GHS3DPlugin_Hypothesis.cxx
22 // Created : Wed Apr 2 12:36:29 2008
23 // Author : Edward AGAPOV (eap)
24 //=============================================================================
26 #include "GHS3DPlugin_Hypothesis.hxx"
28 #include <Basics_DirUtils.hxx>
29 #include <SMESHDS_Mesh.hxx>
30 #include <SMESH_File.hxx>
32 #include <TCollection_AsciiString.hxx>
36 #define getpid _getpid
43 struct GET_DEFAULT // struct used to get default value from GetOptionValue()
46 operator bool* () { return &isDefault; }
50 //=======================================================================
51 //function : GHS3DPlugin_Hypothesis
52 //=======================================================================
54 GHS3DPlugin_Hypothesis::GHS3DPlugin_Hypothesis(int hypId, SMESH_Gen * gen)
55 : SMESH_Hypothesis(hypId, gen),
56 myToMeshHoles(DefaultMeshHoles()),
57 myToMakeGroupsOfDomains(DefaultToMakeGroupsOfDomains()),
60 myOptimizationLevel(DefaultOptimizationLevel()),
61 myKeepFiles(DefaultKeepFiles()),
62 myWorkingDirectory(DefaultWorkingDirectory()),
63 myVerboseLevel(DefaultVerboseLevel()),
64 myToCreateNewNodes(DefaultToCreateNewNodes()),
65 myToUseBoundaryRecoveryVersion(DefaultToUseBoundaryRecoveryVersion()),
66 myToUseFemCorrection(DefaultToUseFEMCorrection()),
67 myToRemoveCentralPoint(DefaultToRemoveCentralPoint()),
68 myLogInStandardOutput(DefaultStandardOutputLog()),
69 myRemoveLogOnSuccess( DefaultRemoveLogOnSuccess() ),
70 myGradation(DefaultGradation()),
71 myUseVolumeProximity(DefaultUseVolumeProximity()),
72 myNbVolumeProximityLayers(DefaultNbVolumeProximityLayers()),
73 myAlgorithm(DefaultAlgorithm()),
74 myNumOfThreads(DefaultNumOfThreads()),
75 myUseNumOfThreads(DefaultUseNumOfThreads()),
76 myPthreadModeMG(DefaultMyPthreadMode()),
77 myPthreadModeMGHPC(DefaultMyPthreadModeHPC()),
86 const char* boolOptionNames[] = { "no_initial_central_point", // no
87 "force_max_size", // no
88 "apply_gradation_on_skin_vertex_sizes", // yes
89 "optimise_worst_elements", // no
90 "force_output_quadratic_mesh", // no
91 "rectify_jacobian", // yes
92 "jacobian_rectification_respect_input_surface_mesh", // yes
95 const char* intOptionNames[] = { "max_number_of_errors_printed", // 1
98 const char* doubleOptionNames[] = { "target_quality", // 0
102 const char* charOptionNames[] = { "boundary_regeneration", // standard
103 "split_overconstrained_tetrahedra", // no
108 while (boolOptionNames[i][0])
110 _boolOptions.insert( boolOptionNames[i] );
111 _option2value[boolOptionNames[i++]].clear();
114 while (intOptionNames[i][0])
115 _option2value[intOptionNames[i++]].clear();
118 while (doubleOptionNames[i][0]) {
119 _doubleOptions.insert(doubleOptionNames[i]);
120 _option2value[doubleOptionNames[i++]].clear();
123 while (charOptionNames[i][0]) {
124 _charOptions.insert(charOptionNames[i]);
125 _option2value[charOptionNames[i++]].clear();
128 // default values to be used while MG meshing
130 _defaultOptionValues["no_initial_central_point" ] = "no";
131 _defaultOptionValues["force_max_size" ] = "no";
132 _defaultOptionValues["apply_gradation_on_skin_vertex_sizes" ] = "yes";
133 _defaultOptionValues["optimise_worst_elements" ] = "no";
134 _defaultOptionValues["force_output_quadratic_mesh" ] = "no";
135 _defaultOptionValues["rectify_jacobian" ] = "yes";
136 _defaultOptionValues["jacobian_rectification_respect_input_surface_mesh"] = "yes";
137 _defaultOptionValues["max_number_of_errors_printed" ] = "1";
138 _defaultOptionValues["target_quality" ] = "";//NoValue();
139 _defaultOptionValues["sliver_angle" ] = "5";
140 _defaultOptionValues["boundary_regeneration" ] = "standard";
141 _defaultOptionValues["split_overconstrained_tetrahedra" ] = "no";
144 // check validity of option names of _defaultOptionValues
145 TOptionValues::iterator n2v = _defaultOptionValues.begin();
146 for ( ; n2v != _defaultOptionValues.end(); ++n2v )
147 ASSERT( _option2value.count( n2v->first ));
148 ASSERT( _option2value.size() == _defaultOptionValues.size() );
152 //=======================================================================
153 //function : SetToMeshHoles
154 //=======================================================================
156 void GHS3DPlugin_Hypothesis::SetToMeshHoles(bool toMesh)
158 if ( myToMeshHoles != toMesh ) {
159 myToMeshHoles = toMesh;
160 NotifySubMeshesHypothesisModification();
164 //=======================================================================
165 //function : GetToMeshHoles
166 //=======================================================================
168 bool GHS3DPlugin_Hypothesis::GetToMeshHoles(bool checkFreeOption) const
170 if ( checkFreeOption )
172 std::string optionName = "components";
173 TOptionValues::const_iterator op_val = _customOption2value.find(optionName);
174 if ( op_val != _customOption2value.end())
176 if ( op_val->second.find("all"))
178 if ( op_val->second.find("outside_components"))
182 return myToMeshHoles;
185 //=======================================================================
186 //function : SetToMakeGroupsOfDomains
187 //=======================================================================
189 void GHS3DPlugin_Hypothesis::SetToMakeGroupsOfDomains(bool toMakeGroups)
191 if ( myToMakeGroupsOfDomains != toMakeGroups ) {
192 myToMakeGroupsOfDomains = toMakeGroups;
193 NotifySubMeshesHypothesisModification();
197 //=======================================================================
198 //function : GetToMakeGroupsOfDomains
199 //=======================================================================
201 bool GHS3DPlugin_Hypothesis::GetToMakeGroupsOfDomains() const
203 return myToMakeGroupsOfDomains;
206 //=======================================================================
207 //function : GetToMakeGroupsOfDomains
208 //=======================================================================
210 bool GHS3DPlugin_Hypothesis::GetToMakeGroupsOfDomains(const GHS3DPlugin_Hypothesis* hyp)
213 if ( hyp ) res = /*hyp->GetToMeshHoles(true) &&*/ hyp->GetToMakeGroupsOfDomains();
214 else res = /*DefaultMeshHoles() &&*/ DefaultToMakeGroupsOfDomains();
218 //=======================================================================
219 //function : SetMaximumMemory
220 //=======================================================================
222 void GHS3DPlugin_Hypothesis::SetMaximumMemory(float MB)
224 if ( myMaximumMemory != MB ) {
225 myMaximumMemory = MB;
226 NotifySubMeshesHypothesisModification();
230 //=======================================================================
231 //function : GetMaximumMemory
232 // * automatic memory adjustment mode. Default is zero
233 //=======================================================================
235 float GHS3DPlugin_Hypothesis::GetMaximumMemory() const
237 return myMaximumMemory;
240 //=======================================================================
241 //function : SetInitialMemory
242 //=======================================================================
244 void GHS3DPlugin_Hypothesis::SetInitialMemory(float MB)
246 if ( myInitialMemory != MB ) {
247 myInitialMemory = MB;
248 NotifySubMeshesHypothesisModification();
252 //=======================================================================
253 //function : GetInitialMemory
254 //=======================================================================
256 float GHS3DPlugin_Hypothesis::GetInitialMemory() const
258 return myInitialMemory;
261 //=======================================================================
262 //function : SetOptimizationLevel
263 //=======================================================================
265 void GHS3DPlugin_Hypothesis::SetOptimizationLevel(OptimizationLevel level)
267 if ( myOptimizationLevel != level ) {
268 myOptimizationLevel = level;
269 NotifySubMeshesHypothesisModification();
273 //=======================================================================
274 //function : GetOptimizationLevel
275 //=======================================================================
277 GHS3DPlugin_Hypothesis::OptimizationLevel GHS3DPlugin_Hypothesis::GetOptimizationLevel() const
279 return (OptimizationLevel) myOptimizationLevel;
282 //=======================================================================
283 //function : SetWorkingDirectory
284 //=======================================================================
286 void GHS3DPlugin_Hypothesis::SetWorkingDirectory(const std::string& path)
288 if ( myWorkingDirectory != path ) {
289 myWorkingDirectory = path;
290 NotifySubMeshesHypothesisModification();
294 //=======================================================================
295 //function : GetWorkingDirectory
296 //=======================================================================
298 std::string GHS3DPlugin_Hypothesis::GetWorkingDirectory() const
300 return myWorkingDirectory;
303 //=======================================================================
304 //function : SetKeepFiles
305 //=======================================================================
307 void GHS3DPlugin_Hypothesis::SetKeepFiles(bool toKeep)
309 if ( myKeepFiles != toKeep ) {
310 myKeepFiles = toKeep;
311 NotifySubMeshesHypothesisModification();
315 //=======================================================================
316 //function : GetKeepFiles
317 //=======================================================================
319 bool GHS3DPlugin_Hypothesis::GetKeepFiles() const
324 //=======================================================================
325 //function : SetVerboseLevel
326 //=======================================================================
328 void GHS3DPlugin_Hypothesis::SetVerboseLevel(short level)
330 if ( myVerboseLevel != level ) {
331 myVerboseLevel = level;
332 NotifySubMeshesHypothesisModification();
336 //=======================================================================
337 //function : GetVerboseLevel
338 //=======================================================================
340 short GHS3DPlugin_Hypothesis::GetVerboseLevel() const
342 return myVerboseLevel;
345 //=======================================================================
346 //function : SetToCreateNewNodes
347 //=======================================================================
349 void GHS3DPlugin_Hypothesis::SetToCreateNewNodes(bool toCreate)
351 if ( myToCreateNewNodes != toCreate ) {
352 myToCreateNewNodes = toCreate;
353 NotifySubMeshesHypothesisModification();
357 //=======================================================================
358 //function : SetAlgorithm
359 //=======================================================================
360 void GHS3DPlugin_Hypothesis::SetAlgorithm(ImplementedAlgorithms algoId)
362 if ( myAlgorithm != algoId ) {
363 myAlgorithm = algoId;
364 NotifySubMeshesHypothesisModification();
368 //=======================================================================
369 //function : short GetAlgorithm() const;
371 //=======================================================================
372 GHS3DPlugin_Hypothesis::ImplementedAlgorithms GHS3DPlugin_Hypothesis::GetAlgorithm() const
374 return (ImplementedAlgorithms) myAlgorithm;
377 //=======================================================================
378 //function : SetPthreadMode
379 //=======================================================================
380 void GHS3DPlugin_Hypothesis::SetPthreadMode(PThreadMode pThreadsMode )
382 if ( myPthreadModeMG != pThreadsMode ) {
383 myPthreadModeMG = pThreadsMode;
384 NotifySubMeshesHypothesisModification();
388 //=======================================================================
389 //function : short GetPthreadMode() const;
391 //=======================================================================
392 GHS3DPlugin_Hypothesis::PThreadMode GHS3DPlugin_Hypothesis::GetPthreadMode() const
394 return (PThreadMode)myPthreadModeMG;
397 //=======================================================================
398 //function : SetParallelMode
399 //=======================================================================
400 void GHS3DPlugin_Hypothesis::SetParallelMode(ParallelMode parallelMode )
402 if ( myPthreadModeMGHPC != parallelMode ) {
403 myPthreadModeMGHPC = parallelMode;
404 NotifySubMeshesHypothesisModification();
408 //=======================================================================
409 //function : short GetParallelMode() const;
411 //=======================================================================
412 GHS3DPlugin_Hypothesis::ParallelMode GHS3DPlugin_Hypothesis::GetParallelMode() const
414 return (ParallelMode)myPthreadModeMGHPC;
417 //=======================================================================
418 //function : SetUseNumOfThreads
419 //=======================================================================
420 void GHS3DPlugin_Hypothesis::SetUseNumOfThreads(bool setUseOfThreads)
422 if ( myUseNumOfThreads != setUseOfThreads ) {
423 myUseNumOfThreads = setUseOfThreads;
424 NotifySubMeshesHypothesisModification();
428 //=======================================================================
429 //function : bool GetUseNumOfThreads() const;
431 //=======================================================================
432 bool GHS3DPlugin_Hypothesis::GetUseNumOfThreads() const
434 return myUseNumOfThreads;
437 //=======================================================================
438 //function : SetNumOfThreads
439 //=======================================================================
440 void GHS3DPlugin_Hypothesis::SetNumOfThreads(short numOfThreads)
442 if ( myNumOfThreads != numOfThreads ) {
443 myNumOfThreads = numOfThreads;
444 NotifySubMeshesHypothesisModification();
448 //=======================================================================
449 //function : short GetUseNumOfThreads() const;
451 //=======================================================================
452 short GHS3DPlugin_Hypothesis::GetNumOfThreads() const
454 return myNumOfThreads;
457 //=======================================================================
458 //function : GetToCreateNewNodes
459 //=======================================================================
460 bool GHS3DPlugin_Hypothesis::GetToCreateNewNodes() const
462 return myToCreateNewNodes;
465 //=======================================================================
466 //function : SetToUseBoundaryRecoveryVersion
467 //=======================================================================
469 void GHS3DPlugin_Hypothesis::SetToUseBoundaryRecoveryVersion(bool toUse)
471 if ( myToUseBoundaryRecoveryVersion != toUse ) {
472 myToUseBoundaryRecoveryVersion = toUse;
473 NotifySubMeshesHypothesisModification();
477 //=======================================================================
478 //function : GetToUseBoundaryRecoveryVersion
479 //=======================================================================
481 bool GHS3DPlugin_Hypothesis::GetToUseBoundaryRecoveryVersion() const
483 return myToUseBoundaryRecoveryVersion;
486 //=======================================================================
487 //function : SetFEMCorrection
488 //=======================================================================
490 void GHS3DPlugin_Hypothesis::SetFEMCorrection(bool toUseFem)
492 if ( myToUseFemCorrection != toUseFem ) {
493 myToUseFemCorrection = toUseFem;
494 NotifySubMeshesHypothesisModification();
498 //=======================================================================
499 //function : GetFEMCorrection
500 //=======================================================================
502 bool GHS3DPlugin_Hypothesis::GetFEMCorrection() const
504 return myToUseFemCorrection;
507 //=======================================================================
508 //function : SetToRemoveCentralPoint
509 //=======================================================================
511 void GHS3DPlugin_Hypothesis::SetToRemoveCentralPoint(bool toRemove)
513 SetOptionValue( "no_initial_central_point", toRemove ? "yes" : "no" );
514 myToRemoveCentralPoint = toRemove;
517 //=======================================================================
518 //function : GetToRemoveCentralPoint
519 //=======================================================================
521 bool GHS3DPlugin_Hypothesis::GetToRemoveCentralPoint() const
523 return myToRemoveCentralPoint;
526 //=======================================================================
527 //function : SetAdvancedOption
528 //=======================================================================
530 void GHS3DPlugin_Hypothesis::SetAdvancedOption(const std::string& option)
532 size_t wsPos = option.find(' ');
533 if ( wsPos == string::npos )
535 SetOptionValue( option, "" );
539 std::string opt( option, 0, wsPos );
540 std::string val( option, wsPos + 1 );
541 SetOptionValue( opt, val );
545 //=======================================================================
546 //function : GetAdvancedOption
547 //=======================================================================
549 std::string GHS3DPlugin_Hypothesis::GetAdvancedOption() const
553 TOptionValues::const_iterator o2v = _option2value.begin();
554 for ( ; o2v != _option2value.end(); ++o2v )
555 if ( !o2v->second.empty() )
559 txt << o2v->first << " " << o2v->second;
561 for ( o2v = _customOption2value.begin(); o2v != _customOption2value.end(); ++o2v )
565 txt << o2v->first << " " << o2v->second;
570 //=======================================================================
571 //function : SetGradation
572 //=======================================================================
574 void GHS3DPlugin_Hypothesis::SetGradation(double gradation)
576 if ( myGradation != gradation ) {
577 myGradation = gradation;
578 NotifySubMeshesHypothesisModification();
582 //=======================================================================
583 //function : GetGradation
584 //=======================================================================
586 double GHS3DPlugin_Hypothesis::GetGradation() const
591 //=============================================================================
592 void GHS3DPlugin_Hypothesis::SetMinSize(double theMinSize)
594 if ( theMinSize != myMinSize )
596 myMinSize = theMinSize;
597 NotifySubMeshesHypothesisModification();
601 //=============================================================================
602 void GHS3DPlugin_Hypothesis::SetMaxSize(double theMaxSize)
604 if ( theMaxSize != myMaxSize )
606 myMaxSize = theMaxSize;
607 NotifySubMeshesHypothesisModification();
611 //=============================================================================
612 void GHS3DPlugin_Hypothesis::SetUseVolumeProximity( bool toUse )
614 if ( myUseVolumeProximity != toUse )
616 myUseVolumeProximity = toUse;
617 NotifySubMeshesHypothesisModification();
621 //=============================================================================
622 void GHS3DPlugin_Hypothesis::SetNbVolumeProximityLayers( int nbLayers )
624 if ( myNbVolumeProximityLayers != nbLayers )
626 myNbVolumeProximityLayers = nbLayers;
627 NotifySubMeshesHypothesisModification();
631 //=======================================================================
632 //function : SetStandardOutputLog
633 //=======================================================================
635 void GHS3DPlugin_Hypothesis::SetStandardOutputLog(bool logInStandardOutput)
637 if ( myLogInStandardOutput != logInStandardOutput ) {
638 myLogInStandardOutput = logInStandardOutput;
639 NotifySubMeshesHypothesisModification();
643 //=======================================================================
644 //function : GetStandardOutputLog
645 //=======================================================================
647 bool GHS3DPlugin_Hypothesis::GetStandardOutputLog() const
649 return myLogInStandardOutput;
652 //=======================================================================
653 //function : SetRemoveLogOnSuccess
654 //=======================================================================
656 void GHS3DPlugin_Hypothesis::SetRemoveLogOnSuccess(bool removeLogOnSuccess)
658 if ( myRemoveLogOnSuccess != removeLogOnSuccess ) {
659 myRemoveLogOnSuccess = removeLogOnSuccess;
660 NotifySubMeshesHypothesisModification();
664 //=======================================================================
665 //function : GetRemoveLogOnSuccess
666 //=======================================================================
668 bool GHS3DPlugin_Hypothesis::GetRemoveLogOnSuccess() const
670 return myRemoveLogOnSuccess;
673 //=======================================================================
674 //function : SetEnforcedVertex
675 //=======================================================================
677 bool GHS3DPlugin_Hypothesis::SetEnforcedVertex(std::string theName,
678 std::string theEntry,
679 std::string theGroupName,
681 double x, double y, double z,
684 MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedVertex(\""<< theName << "\", \""<< theEntry << "\", \"" << theGroupName << "\", "
685 << size << ", " << x << ", " << y << ", " << z << ", "<< isCompound << ")");
687 bool toNotify = false;
688 bool toCreate = true;
690 TGHS3DEnforcedVertex *oldEnVertex;
691 TGHS3DEnforcedVertex *newEnfVertex = new TGHS3DEnforcedVertex();
692 newEnfVertex->name = theName;
693 newEnfVertex->geomEntry = theEntry;
694 newEnfVertex->coords.clear();
696 newEnfVertex->coords.push_back(x);
697 newEnfVertex->coords.push_back(y);
698 newEnfVertex->coords.push_back(z);
700 newEnfVertex->groupName = theGroupName;
701 newEnfVertex->size = size;
702 newEnfVertex->isCompound = isCompound;
705 // update _enfVertexList
706 TGHS3DEnforcedVertexList::iterator it = _enfVertexList.find(newEnfVertex);
707 if (it != _enfVertexList.end()) {
710 MESSAGE("Enforced Vertex was found => Update");
711 if (oldEnVertex->name != theName) {
712 MESSAGE("Update name from \"" << oldEnVertex->name << "\" to \"" << theName << "\"");
713 oldEnVertex->name = theName;
716 if (oldEnVertex->groupName != theGroupName) {
717 MESSAGE("Update group name from \"" << oldEnVertex->groupName << "\" to \"" << theGroupName << "\"");
718 oldEnVertex->groupName = theGroupName;
721 if (oldEnVertex->size != size) {
722 MESSAGE("Update size from \"" << oldEnVertex->size << "\" to \"" << size << "\"");
723 oldEnVertex->size = size;
727 // update map coords / enf vertex if needed
728 if (oldEnVertex->coords.size()) {
729 _coordsEnfVertexMap[oldEnVertex->coords] = oldEnVertex;
730 _enfVertexCoordsSizeList[oldEnVertex->coords] = size;
733 // update map geom entry / enf vertex if needed
734 if (oldEnVertex->geomEntry != "") {
735 _geomEntryEnfVertexMap[oldEnVertex->geomEntry] = oldEnVertex;
736 _enfVertexEntrySizeList[oldEnVertex->geomEntry] = size;
741 // //////// CREATE ////////////
744 MESSAGE("Creating new enforced vertex");
745 _enfVertexList.insert(newEnfVertex);
746 if (theEntry == "") {
747 _coordsEnfVertexMap[newEnfVertex->coords] = newEnfVertex;
748 _enfVertexCoordsSizeList[newEnfVertex->coords] = size;
751 _geomEntryEnfVertexMap[newEnfVertex->geomEntry] = newEnfVertex;
752 _enfVertexEntrySizeList[newEnfVertex->geomEntry] = size;
757 NotifySubMeshesHypothesisModification();
759 MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedVertex END");
764 //=======================================================================
765 //function : SetEnforcedMesh
766 //=======================================================================
767 bool GHS3DPlugin_Hypothesis::SetEnforcedMesh(SMESH_Mesh& theMesh, SMESH::ElementType elementType, std::string name, std::string entry, std::string groupName)
769 TIDSortedElemSet theElemSet;
770 SMDS_ElemIteratorPtr eIt = theMesh.GetMeshDS()->elementsIterator(SMDSAbs_ElementType(elementType));
771 while ( eIt->more() )
772 theElemSet.insert( eIt->next() );
773 MESSAGE("Add "<<theElemSet.size()<<" types["<<elementType<<"] from source mesh");
774 bool added = SetEnforcedElements( theElemSet, elementType, groupName);
776 TGHS3DEnforcedMesh* newEnfMesh = new TGHS3DEnforcedMesh();
777 newEnfMesh->persistID = theMesh.GetMeshDS()->GetPersistentId();
778 newEnfMesh->name = name;
779 newEnfMesh->entry = entry;
780 newEnfMesh->elementType = elementType;
781 newEnfMesh->groupName = groupName;
783 TGHS3DEnforcedMeshList::iterator it = _enfMeshList.find(newEnfMesh);
784 if (it == _enfMeshList.end()) {
785 _entryEnfMeshMap[entry].insert(newEnfMesh);
786 _enfMeshList.insert(newEnfMesh);
795 //=======================================================================
796 //function : SetEnforcedGroup
797 //=======================================================================
798 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)
800 MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedGroup");
801 TIDSortedElemSet theElemSet;
802 if ( theIDs->length() == 0 ){MESSAGE("The source group is empty");}
803 for ( CORBA::ULong i = 0; i < theIDs->length(); i++) {
804 SMESH::smIdType ind = theIDs[i];
805 if (elementType == SMESH::NODE)
807 const SMDS_MeshNode * node = theMeshDS->FindNode(ind);
809 theElemSet.insert( node );
813 const SMDS_MeshElement * elem = theMeshDS->FindElement(ind);
815 theElemSet.insert( elem );
819 // SMDS_ElemIteratorPtr it = theGroup->GetGroupDS()->GetElements();
820 // while ( it->more() )
821 // theElemSet.insert( it->next() );
823 MESSAGE("Add "<<theElemSet.size()<<" types["<<elementType<<"] from source group ");
824 bool added = SetEnforcedElements( theElemSet, elementType, groupName);
826 TGHS3DEnforcedMesh* newEnfMesh = new TGHS3DEnforcedMesh();
827 newEnfMesh->name = name;
828 newEnfMesh->entry = entry;
829 newEnfMesh->elementType = elementType;
830 newEnfMesh->groupName = groupName;
832 TGHS3DEnforcedMeshList::iterator it = _enfMeshList.find(newEnfMesh);
833 if (it == _enfMeshList.end()) {
834 _entryEnfMeshMap[entry].insert(newEnfMesh);
835 _enfMeshList.insert(newEnfMesh);
841 //=======================================================================
842 //function : SetEnforcedElements
843 //=======================================================================
844 bool GHS3DPlugin_Hypothesis::SetEnforcedElements(TIDSortedElemSet theElemSet, SMESH::ElementType elementType, std::string groupName)
846 MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedElements");
847 TIDSortedElemSet::const_iterator it = theElemSet.begin();
848 const SMDS_MeshElement* elem;
849 const SMDS_MeshNode* node;
851 pair<TIDSortedNodeGroupMap::iterator,bool> nodeRet;
852 pair<TIDSortedElemGroupMap::iterator,bool> elemRet;
854 for (;it != theElemSet.end();++it)
857 switch (elementType) {
859 node = dynamic_cast<const SMDS_MeshNode*>(elem);
861 nodeRet = _enfNodes.insert(make_pair(node,groupName));
862 added = added && nodeRet.second;
863 string msg = added ? "yes":"no";
864 MESSAGE( "Node (" <<node->X()<<","<<node->Y()<<","<<node->Z()<< ") with ID " << node->GetID() <<" added ? " << msg);
867 SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
868 for (;nodeIt->more();) {
869 node = dynamic_cast<const SMDS_MeshNode*>(nodeIt->next());
870 nodeRet = _enfNodes.insert(make_pair(node,groupName));
871 added = added && nodeRet.second;
876 if (elem->GetType() == SMDSAbs_Edge) {
877 elemRet = _enfEdges.insert(make_pair(elem,groupName));
878 added = added && elemRet.second;
880 else if (elem->GetType() > SMDSAbs_Edge) {
881 // SMDS_ElemIteratorPtr it = elem->edgesIterator();
882 // for (;it->more();) {
883 // const SMDS_MeshElement* anEdge = it->next();
884 // elemRet = _enfEdges.insert(make_pair(anEdge,groupName));
885 // added = added && elemRet.second;
890 if (elem->GetType() == SMDSAbs_Face)
892 if (elem->NbCornerNodes() == 3) {
893 elemRet = _enfTriangles.insert(make_pair(elem,groupName));
894 added = added && elemRet.second;
897 else if (elem->GetType() > SMDSAbs_Face) { // Group of faces
898 // SMDS_ElemIteratorPtr it = elem->facesIterator();
899 // for (;it->more();) {
900 // const SMDS_MeshElement* aFace = it->next();
901 // if (aFace->NbCornerNodes() == 3) {
902 // elemRet = _enfTriangles.insert(make_pair(aFace,groupName));
903 // added = added && elemRet.second;
913 NotifySubMeshesHypothesisModification();
918 //=======================================================================
919 //function : GetEnforcedVertex
920 //=======================================================================
922 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex* GHS3DPlugin_Hypothesis::GetEnforcedVertex(double x, double y, double z)
924 std::vector<double> coord(3);
928 if (_coordsEnfVertexMap.count(coord)>0)
929 return _coordsEnfVertexMap[coord];
930 std::ostringstream msg ;
931 msg << "No enforced vertex at " << x << ", " << y << ", " << z;
932 throw std::invalid_argument(msg.str());
935 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex* GHS3DPlugin_Hypothesis::GetEnforcedVertex(const std::string theEntry)
937 if (_geomEntryEnfVertexMap.count(theEntry)>0)
938 return _geomEntryEnfVertexMap[theEntry];
940 std::ostringstream msg ;
941 msg << "No enforced vertex with entry " << theEntry;
942 throw std::invalid_argument(msg.str());
945 //=======================================================================
946 //function : RemoveEnforcedVertex
947 //=======================================================================
949 bool GHS3DPlugin_Hypothesis::RemoveEnforcedVertex(double x, double y, double z, const std::string theEntry)
951 bool toNotify = false;
952 std::ostringstream msg;
953 TGHS3DEnforcedVertex *oldEnfVertex;
954 std::vector<double> coords(3);
959 // check that enf vertex with given enf vertex entry exists
960 TGeomEntryGHS3DEnforcedVertexMap::iterator it_enfVertexEntry = _geomEntryEnfVertexMap.find(theEntry);
961 if (it_enfVertexEntry != _geomEntryEnfVertexMap.end()) {
963 MESSAGE("Found enforced vertex with geom entry " << theEntry);
964 oldEnfVertex = it_enfVertexEntry->second;
965 _geomEntryEnfVertexMap.erase(it_enfVertexEntry);
968 MESSAGE("Enforced vertex with geom entry " << theEntry << " not found");
969 // check that enf vertex with given coords exists
970 TCoordsGHS3DEnforcedVertexMap::iterator it_coords_enf = _coordsEnfVertexMap.find(coords);
971 if (it_coords_enf != _coordsEnfVertexMap.end()) {
973 MESSAGE("Found enforced vertex with coords " << x << ", " << y << ", " << z);
974 oldEnfVertex = it_coords_enf->second;
975 _coordsEnfVertexMap.erase(it_coords_enf);
976 _enfVertexCoordsSizeList.erase(_enfVertexCoordsSizeList.find(coords));
979 MESSAGE("Enforced vertex with coords " << x << ", " << y << ", " << z << " not found");
980 throw std::invalid_argument(msg.str());
984 MESSAGE("Remove enf vertex from _enfVertexList");
986 // update _enfVertexList
987 TGHS3DEnforcedVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
988 if (it != _enfVertexList.end()) {
989 if ((*it)->groupName != "")
990 _groupsToRemove.insert((*it)->groupName);
991 _enfVertexList.erase(it);
997 NotifySubMeshesHypothesisModification();
1002 //=======================================================================
1003 //function : ClearEnforcedVertices
1004 //=======================================================================
1005 void GHS3DPlugin_Hypothesis::ClearEnforcedVertices()
1007 TGHS3DEnforcedVertexList::const_iterator it = _enfVertexList.begin();
1008 for(;it != _enfVertexList.end();++it) {
1009 if ((*it)->groupName != "")
1010 _groupsToRemove.insert((*it)->groupName);
1012 _enfVertexList.clear();
1013 _coordsEnfVertexMap.clear();
1014 _geomEntryEnfVertexMap.clear();
1015 _enfVertexCoordsSizeList.clear();
1016 _enfVertexEntrySizeList.clear();
1017 NotifySubMeshesHypothesisModification();
1020 //=======================================================================
1021 //function : ClearEnforcedMeshes
1022 //=======================================================================
1023 void GHS3DPlugin_Hypothesis::ClearEnforcedMeshes()
1025 TGHS3DEnforcedMeshList::const_iterator it = _enfMeshList.begin();
1026 for(;it != _enfMeshList.end();++it) {
1027 if ((*it)->groupName != "")
1028 _groupsToRemove.insert((*it)->groupName);
1032 _enfTriangles.clear();
1033 _nodeIDToSizeMap.clear();
1034 _enfMeshList.clear();
1035 _entryEnfMeshMap.clear();
1036 NotifySubMeshesHypothesisModification();
1039 //================================================================================
1041 * \brief At mesh loading, restore enforced elements by just loaded enforced meshes
1043 //================================================================================
1045 void GHS3DPlugin_Hypothesis::RestoreEnfElemsByMeshes()
1047 TGHS3DEnforcedMeshList::const_iterator it = _enfMeshList.begin();
1048 for(;it != _enfMeshList.end();++it) {
1049 TGHS3DEnforcedMesh* enfMesh = *it;
1050 if ( SMESH_Mesh* mesh = GetMeshByPersistentID( enfMesh->persistID ))
1051 SetEnforcedMesh( *mesh,
1052 enfMesh->elementType,
1055 enfMesh->groupName );
1056 enfMesh->persistID = -1; // not to restore again
1060 //=======================================================================
1061 //function : SetGroupsToRemove
1062 //=======================================================================
1064 void GHS3DPlugin_Hypothesis::ClearGroupsToRemove()
1066 _groupsToRemove.clear();
1070 //=======================================================================
1071 //function : DefaultMeshHoles
1072 //=======================================================================
1074 bool GHS3DPlugin_Hypothesis::DefaultMeshHoles()
1076 return false; // PAL19680
1079 //=======================================================================
1080 //function : DefaultToMakeGroupsOfDomains
1081 //=======================================================================
1083 bool GHS3DPlugin_Hypothesis::DefaultToMakeGroupsOfDomains()
1085 return false; // issue 0022172
1088 //=======================================================================
1089 //function : DefaultMaximumMemory
1090 //=======================================================================
1093 #include <windows.h>
1094 #elif !defined(__APPLE__)
1095 #include <sys/sysinfo.h>
1098 float GHS3DPlugin_Hypothesis::DefaultMaximumMemory()
1101 // See http://msdn.microsoft.com/en-us/library/aa366589.aspx
1102 MEMORYSTATUSEX statex;
1103 statex.dwLength = sizeof (statex);
1104 long err = GlobalMemoryStatusEx (&statex);
1106 double totMB = double( statex.ullAvailPhys ) / 1024. / 1024.;
1107 return float( 0.7 * totMB );
1109 #elif !defined(__APPLE__)
1111 long err = sysinfo( &si );
1113 double ramMB = double( si.totalram * si.mem_unit / 1024 / 1024 );
1114 return float( 0.7 * ramMB );
1120 //=======================================================================
1121 //function : DefaultInitialMemory
1122 //=======================================================================
1124 float GHS3DPlugin_Hypothesis::DefaultInitialMemory()
1126 return DefaultMaximumMemory();
1129 //=======================================================================
1130 //function : DefaultOptimizationLevel
1131 //=======================================================================
1133 short GHS3DPlugin_Hypothesis::DefaultOptimizationLevel()
1138 //=======================================================================
1139 //function : DefaultWorkingDirectory
1140 //=======================================================================
1142 std::string GHS3DPlugin_Hypothesis::DefaultWorkingDirectory()
1144 TCollection_AsciiString aTmpDir;
1146 char *Tmp_dir = getenv("SALOME_TMP_DIR");
1147 if(Tmp_dir != NULL) {
1152 aTmpDir = TCollection_AsciiString("C:\\");
1154 aTmpDir = TCollection_AsciiString("/tmp/");
1157 return aTmpDir.ToCString();
1160 //=======================================================================
1161 //function : DefaultKeepFiles
1162 //=======================================================================
1164 bool GHS3DPlugin_Hypothesis::DefaultKeepFiles()
1169 //=======================================================================
1170 //function : DefaultRemoveLogOnSuccess
1171 //=======================================================================
1173 bool GHS3DPlugin_Hypothesis::DefaultRemoveLogOnSuccess()
1179 //=======================================================================
1180 //function : DefaultVerboseLevel
1181 //=======================================================================
1183 short GHS3DPlugin_Hypothesis::DefaultVerboseLevel()
1188 //=======================================================================
1189 //function : DefaultToCreateNewNodes
1190 //=======================================================================
1192 bool GHS3DPlugin_Hypothesis::DefaultToCreateNewNodes()
1197 //=======================================================================
1198 //function : DefaultToUseBoundaryRecoveryVersion
1199 //=======================================================================
1201 bool GHS3DPlugin_Hypothesis::DefaultToUseBoundaryRecoveryVersion()
1206 //=======================================================================
1207 //function : DefaultToUseFEMCorrection
1208 //=======================================================================
1210 bool GHS3DPlugin_Hypothesis::DefaultToUseFEMCorrection()
1215 //=======================================================================
1216 //function : DefaultToRemoveCentralPoint
1217 //=======================================================================
1219 bool GHS3DPlugin_Hypothesis::DefaultToRemoveCentralPoint()
1224 //=======================================================================
1225 //function : DefaultStandardOutputLog
1226 //=======================================================================
1228 bool GHS3DPlugin_Hypothesis::DefaultStandardOutputLog()
1233 // //=======================================================================
1234 // //function : DefaultID2SizeMap
1235 // //=======================================================================
1237 // GHS3DPlugin_Hypothesis::TID2SizeMap GHS3DPlugin_Hypothesis::DefaultID2SizeMap()
1239 // return GHS3DPlugin_Hypothesis::TID2SizeMap();
1243 //=======================================================================
1245 //=======================================================================
1247 std::ostream & GHS3DPlugin_Hypothesis::SaveTo(std::ostream & save)
1249 save << (int) myToMeshHoles << " ";
1250 save << myMaximumMemory << " ";
1251 save << myInitialMemory << " ";
1252 save << myOptimizationLevel << " ";
1253 save << myWorkingDirectory << " ";
1254 save << (int)myKeepFiles << " ";
1255 save << myVerboseLevel << " ";
1256 save << (int)myToCreateNewNodes << " ";
1257 save << (int)myToUseBoundaryRecoveryVersion << " ";
1258 save << (int)myToUseFemCorrection << " ";
1259 save << (int)myToRemoveCentralPoint << " ";
1260 save << myGradation << " ";
1261 save << myToMakeGroupsOfDomains << " ";
1262 // if (!myTextOption.empty()) {
1263 // save << "__OPTIONS_BEGIN__ ";
1264 // save << myTextOption << " ";
1265 // save << "__OPTIONS_END__ ";
1269 TGHS3DEnforcedVertexList::iterator it = _enfVertexList.begin();
1270 if (it != _enfVertexList.end()) {
1271 save << " " << "__ENFORCED_VERTICES_BEGIN__ ";
1272 for ( ; it != _enfVertexList.end(); ++it ) {
1273 TGHS3DEnforcedVertex *enfVertex = (*it);
1274 save << " " << "__BEGIN_VERTEX__";
1275 if (!enfVertex->name.empty()) {
1276 save << " " << "__BEGIN_NAME__";
1277 save << " " << enfVertex->name;
1278 save << " " << "__END_NAME__";
1280 if (!enfVertex->geomEntry.empty()) {
1281 save << " " << "__BEGIN_ENTRY__";
1282 save << " " << enfVertex->geomEntry;
1283 save << " " << enfVertex->isCompound;
1284 save << " " << "__END_ENTRY__";
1286 if (!enfVertex->groupName.empty()) {
1287 save << " " << "__BEGIN_GROUP__";
1288 save << " " << enfVertex->groupName;
1289 save << " " << "__END_GROUP__";
1291 if (enfVertex->coords.size()) {
1292 save << " " << "__BEGIN_COORDS__";
1293 for ( size_t i = 0; i < enfVertex->coords.size(); i++ )
1294 save << " " << enfVertex->coords[i];
1295 save << " " << "__END_COORDS__";
1297 save << " " << "__BEGIN_SIZE__";
1298 save << " " << enfVertex->size;
1299 save << " " << "__END_SIZE__";
1300 save << " " << "__END_VERTEX__";
1302 save << " " << "__ENFORCED_VERTICES_END__ ";
1305 TGHS3DEnforcedMeshList::iterator it_mesh = _enfMeshList.begin();
1306 if (it_mesh != _enfMeshList.end()) {
1307 save << " " << "__ENFORCED_MESHES_BEGIN__ ";
1308 for ( ; it_mesh != _enfMeshList.end(); ++it_mesh ) {
1309 TGHS3DEnforcedMesh *enfMesh = (*it_mesh);
1310 save << " " << "__BEGIN_ENF_MESH__";
1312 save << " " << "__BEGIN_NAME__";
1313 save << " " << enfMesh->name;
1314 save << " " << "__END_NAME__";
1316 save << " " << "__BEGIN_ENTRY__";
1317 save << " " << enfMesh->entry;
1318 save << " " << "__END_ENTRY__";
1320 save << " " << "__BEGIN_ELEM_TYPE__";
1321 save << " " << (int)enfMesh->elementType;
1322 save << " " << "__END_ELEM_TYPE__";
1324 if (!enfMesh->groupName.empty()) {
1325 save << " " << "__BEGIN_GROUP__";
1326 save << " " << enfMesh->groupName;
1327 save << " " << "__END_GROUP__";
1329 save << " " << "__PERSIST_ID__";
1330 save << " " << enfMesh->persistID;
1331 save << " " << "__END_ENF_MESH__";
1332 std::cout << "Saving of enforced mesh " << enfMesh->name.c_str() << " done" << std::endl;
1334 save << " " << "__ENFORCED_MESHES_END__ ";
1337 // New options in 2.9.6 (issue #17784)
1339 save << " " << myUseVolumeProximity;
1340 save << " " << myNbVolumeProximityLayers;
1341 save << " " << myMinSize;
1342 save << " " << myMaxSize;
1343 save << " " << myMinSizeDefault;
1344 save << " " << myMaxSizeDefault;
1346 save << " " << _option2value.size();
1347 TOptionValues::iterator o2v = _option2value.begin();
1348 for ( ; o2v != _option2value.end(); ++o2v )
1349 save << " -" << o2v->first << " -" << o2v->second;
1351 save << " " << _customOption2value.size();
1352 for ( o2v = _customOption2value.begin(); o2v != _customOption2value.end(); ++o2v )
1353 save << " -" << o2v->first << " -" << o2v->second;
1355 // New options (issue #32737)
1356 save << " " << myAlgorithm;
1357 save << " " << myUseNumOfThreads;
1358 save << " " << myNumOfThreads;
1359 save << " " << myPthreadModeMG;
1360 save << " " << myPthreadModeMGHPC;
1365 //=======================================================================
1366 //function : LoadFrom
1367 //=======================================================================
1369 std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load)
1375 isOK = static_cast<bool>(load >> i);
1379 load.clear(ios::badbit | load.rdstate());
1381 isOK = static_cast<bool>(load >> d);
1383 myMaximumMemory = float( d );
1385 load.clear(ios::badbit | load.rdstate());
1387 isOK = static_cast<bool>(load >> d);
1389 myInitialMemory = float( d );
1391 load.clear(ios::badbit | load.rdstate());
1393 isOK = static_cast<bool>(load >> i);
1395 myOptimizationLevel = (short int) i;
1397 load.clear(ios::badbit | load.rdstate());
1399 isOK = static_cast<bool>(load >> myWorkingDirectory);
1401 if ( myWorkingDirectory == "0") { // myWorkingDirectory was empty
1402 myKeepFiles = false;
1403 myWorkingDirectory.clear();
1405 else if ( myWorkingDirectory == "1" ) {
1407 myWorkingDirectory.clear();
1411 load.clear(ios::badbit | load.rdstate());
1413 if ( !myWorkingDirectory.empty() ) {
1414 isOK = static_cast<bool>(load >> i);
1418 load.clear(ios::badbit | load.rdstate());
1421 isOK = static_cast<bool>(load >> i);
1423 myVerboseLevel = (short) i;
1425 load.clear(ios::badbit | load.rdstate());
1427 isOK = static_cast<bool>(load >> i);
1429 myToCreateNewNodes = (bool) i;
1431 load.clear(ios::badbit | load.rdstate());
1433 isOK = static_cast<bool>(load >> i);
1435 myToUseBoundaryRecoveryVersion = (bool) i;
1437 load.clear(ios::badbit | load.rdstate());
1439 isOK = static_cast<bool>(load >> i);
1441 myToUseFemCorrection = (bool) i;
1443 load.clear(ios::badbit | load.rdstate());
1445 isOK = static_cast<bool>(load >> i);
1447 myToRemoveCentralPoint = (bool) i;
1449 load.clear(ios::badbit | load.rdstate());
1451 isOK = static_cast<bool>(load >> d);
1455 load.clear(ios::badbit | load.rdstate());
1457 std::string separator;
1458 bool hasOptions = false;
1459 bool hasEnforcedVertices = false;
1460 bool hasEnforcedMeshes = false;
1461 isOK = static_cast<bool>(load >> separator);
1463 if ( isOK && ( separator == "0" || separator == "1" ))
1465 myToMakeGroupsOfDomains = ( separator == "1" );
1466 isOK = static_cast<bool>(load >> separator);
1470 if (separator == "__OPTIONS_BEGIN__")
1472 else if (separator == "__ENFORCED_VERTICES_BEGIN__")
1473 hasEnforcedVertices = true;
1474 else if (separator == "__ENFORCED_MESHES_BEGIN__")
1475 hasEnforcedMeshes = true;
1481 isOK = static_cast<bool>(load >> txt);
1483 if (txt == "__OPTIONS_END__") {
1484 // if (!myTextOption.empty()) {
1485 // // Remove last space
1486 // myTextOption.erase(myTextOption.end()-1);
1491 // myTextOption += txt;
1492 // myTextOption += " ";
1498 isOK = static_cast<bool>(load >> separator);
1499 if (isOK && separator == "__ENFORCED_VERTICES_BEGIN__")
1500 hasEnforcedVertices = true;
1501 if (isOK && separator == "__ENFORCED_MESHES_BEGIN__")
1502 hasEnforcedMeshes = true;
1505 if (hasEnforcedVertices) {
1506 std::string txt, name, entry, groupName;
1507 double size, coords[3];
1509 bool hasCoords = false;
1510 isOK = static_cast<bool>(load >> txt); // __BEGIN_VERTEX__
1512 if (txt == "__ENFORCED_VERTICES_END__") {
1517 TGHS3DEnforcedVertex *enfVertex = new TGHS3DEnforcedVertex();
1519 isOK = static_cast<bool>(load >> txt);
1520 if (txt == "__END_VERTEX__") {
1521 enfVertex->name = name;
1522 enfVertex->geomEntry = entry;
1523 enfVertex->isCompound = isCompound;
1524 enfVertex->groupName = groupName;
1525 enfVertex->coords.clear();
1527 enfVertex->coords.assign(coords,coords+3);
1529 _enfVertexList.insert(enfVertex);
1531 if (enfVertex->coords.size())
1532 _coordsEnfVertexMap[enfVertex->coords] = enfVertex;
1533 if (!enfVertex->geomEntry.empty())
1534 _geomEntryEnfVertexMap[enfVertex->geomEntry] = enfVertex;
1543 if (txt == "__BEGIN_NAME__") { // __BEGIN_NAME__
1544 while (isOK && (txt != "__END_NAME__")) {
1545 isOK = static_cast<bool>(load >> txt);
1546 if (txt != "__END_NAME__") {
1552 MESSAGE("name: " <<name);
1555 if (txt == "__BEGIN_ENTRY__") { // __BEGIN_ENTRY__
1556 isOK = static_cast<bool>(load >> entry);
1557 isOK = static_cast<bool>(load >> isCompound);
1558 isOK = static_cast<bool>(load >> txt); // __END_ENTRY__
1559 if (txt != "__END_ENTRY__")
1560 throw std::exception();
1561 MESSAGE("entry: " << entry);
1564 if (txt == "__BEGIN_GROUP__") { // __BEGIN_GROUP__
1565 while (isOK && (txt != "__END_GROUP__")) {
1566 isOK = static_cast<bool>(load >> txt);
1567 if (txt != "__END_GROUP__") {
1568 if (!groupName.empty())
1573 MESSAGE("groupName: " << groupName);
1576 if (txt == "__BEGIN_COORDS__") { // __BEGIN_COORDS__
1578 isOK = static_cast<bool>(load >> coords[0] >> coords[1] >> coords[2]);
1579 isOK = static_cast<bool>(load >> txt); // __END_COORDS__
1580 if (txt != "__END_COORDS__")
1581 throw std::exception();
1582 MESSAGE("coords: " << coords[0] <<","<< coords[1] <<","<< coords[2]);
1585 if (txt == "__BEGIN_SIZE__") { // __BEGIN_ENTRY__
1586 isOK = static_cast<bool>(load >> size);
1587 isOK = static_cast<bool>(load >> txt); // __END_ENTRY__
1588 if (txt != "__END_SIZE__") {
1589 throw std::exception();
1591 MESSAGE("size: " << size);
1594 isOK = static_cast<bool>(load >> txt); // __BEGIN_VERTEX__
1598 if (hasEnforcedVertices) {
1599 isOK = static_cast<bool>(load >> separator);
1600 if (isOK && separator == "__ENFORCED_MESHES_BEGIN__")
1601 hasEnforcedMeshes = true;
1604 if (hasEnforcedMeshes) {
1605 std::string txt, name, entry, groupName;
1606 int elementType = -1, persistID = -1;
1607 isOK = static_cast<bool>(load >> txt); // __BEGIN_ENF_MESH__
1610 if (txt == "__ENFORCED_MESHES_END__")
1613 TGHS3DEnforcedMesh *enfMesh = new TGHS3DEnforcedMesh();
1615 isOK = static_cast<bool>(load >> txt);
1616 if (txt == "__END_ENF_MESH__") {
1617 enfMesh->name = name;
1618 enfMesh->entry = entry;
1619 enfMesh->elementType = (SMESH::ElementType)elementType;
1620 enfMesh->groupName = groupName;
1621 enfMesh->persistID = persistID;
1623 _enfMeshList.insert(enfMesh);
1624 //std::cout << "Restoring of enforced mesh " <<name << " done" << std::endl;
1634 if (txt == "__BEGIN_NAME__") { // __BEGIN_NAME__
1635 while (isOK && (txt != "__END_NAME__")) {
1636 isOK = static_cast<bool>(load >> txt);
1637 if (txt != "__END_NAME__") {
1643 MESSAGE("name: " <<name);
1646 if (txt == "__BEGIN_ENTRY__") { // __BEGIN_ENTRY__
1647 isOK = static_cast<bool>(load >> entry);
1648 isOK = static_cast<bool>(load >> txt); // __END_ENTRY__
1649 if (txt != "__END_ENTRY__")
1650 throw std::exception();
1651 MESSAGE("entry: " << entry);
1654 if (txt == "__BEGIN_ELEM_TYPE__") { // __BEGIN_ELEM_TYPE__
1655 isOK = static_cast<bool>(load >> elementType);
1656 isOK = static_cast<bool>(load >> txt); // __END_ELEM_TYPE__
1657 if (txt != "__END_ELEM_TYPE__")
1658 throw std::exception();
1659 MESSAGE("elementType: " << elementType);
1662 if (txt == "__BEGIN_GROUP__") { // __BEGIN_GROUP__
1663 while (isOK && (txt != "__END_GROUP__")) {
1664 isOK = static_cast<bool>(load >> txt);
1665 if (txt != "__END_GROUP__") {
1666 if (!groupName.empty())
1671 MESSAGE("groupName: " << groupName);
1674 if (txt == "__PERSIST_ID__") {
1675 isOK = static_cast<bool>(load >> persistID);
1676 MESSAGE("persistID: " << persistID);
1678 //std::cout << "isOK: " << isOK << std::endl;
1681 isOK = static_cast<bool>(load >> txt); // __BEGIN_ENF_MESH__
1685 // New options in 2.9.6 (issue #17784)
1687 if ( ! hasOptions && ! hasEnforcedVertices && ! hasEnforcedMeshes )
1688 myUseVolumeProximity = ( separator == "1" );
1689 else if ( static_cast<bool>( load >> i ))
1690 myUseVolumeProximity = (bool) i;
1692 if ( static_cast<bool>( load >> myNbVolumeProximityLayers ))
1696 load >> myMinSizeDefault;
1697 load >> myMaxSizeDefault;
1699 std::string option, value;
1700 if ( static_cast<bool>( load >> i ) && i >= 0 )
1702 for ( int nbRead = 0; nbRead < i; ++nbRead )
1704 load >> option >> value;
1705 _option2value[ std::string( option, 1 )] = std::string( value, 1 );
1708 if ( static_cast<bool>( load >> i ) && i >= 0 )
1710 for ( int nbRead = 0; nbRead < i; ++nbRead )
1712 load >> option >> value;
1713 _customOption2value[ std::string( option, 1 )] = std::string( value, 1 );
1718 isOK = static_cast<bool>(load >> i);
1720 myAlgorithm = (short) i;
1722 load.clear(ios::badbit | load.rdstate());
1724 isOK = static_cast<bool>(load >> i);
1726 myUseNumOfThreads = (short) i;
1728 load.clear(ios::badbit | load.rdstate());
1730 isOK = static_cast<bool>(load >> i);
1732 myNumOfThreads = (short) i;
1734 load.clear(ios::badbit | load.rdstate());
1736 isOK = static_cast<bool>(load >> i);
1738 myPthreadModeMG = (short) i;
1740 load.clear(ios::badbit | load.rdstate());
1742 isOK = static_cast<bool>(load >> i);
1744 myPthreadModeMGHPC = (short) i;
1746 load.clear(ios::badbit | load.rdstate());
1751 //=======================================================================
1752 //function : SetParametersByMesh
1753 //=======================================================================
1755 bool GHS3DPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* ,const TopoDS_Shape&)
1761 //================================================================================
1763 * \brief Sets myToMakeGroupsOfDomains depending on whether theMesh is on shape or not
1765 //================================================================================
1767 bool GHS3DPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& dflts,
1768 const SMESH_Mesh* /*theMesh*/)
1770 myToMakeGroupsOfDomains = ( !dflts._shape || dflts._shape->IsNull() );
1772 double diagonal = dflts._elemLength * _gen->GetBoundaryBoxSegmentation();
1773 myMinSizeDefault = 1e-3 * diagonal;
1774 myMaxSizeDefault = diagonal / 5.;
1779 void GHS3DPlugin_Hypothesis::SetAdvancedOptionsInCommandLine( std::string & cmd ) const
1781 std::string option, value;
1783 const TOptionValues* options[] = { & this->_option2value, & this->_customOption2value };
1784 for ( int iOp = 0; iOp < 2; ++iOp )
1786 TOptionValues::const_iterator o2v = options[iOp]->begin();
1787 for ( ; o2v != options[iOp]->end(); ++o2v )
1789 option = o2v->first;
1790 value = this->GetOptionValue( option, &isDefault );
1795 if ( value.empty() )//value == NoValue() )
1797 if ( this->_defaultOptionValues.count( option ))
1798 continue; // non-custom option with no value
1802 if ( strncmp( "no", option.c_str(), 2 ) == 0 ) // options w/o values: --no_*
1804 if ( !value.empty() && ToBool( value ) == false )
1809 if ( option[0] != '-' )
1813 cmd += option + " " + value;
1818 //================================================================================
1820 * \brief Return command to run MG-Tetra mesher excluding file prefix (-f)
1822 //================================================================================
1823 std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* hyp,
1824 const bool hasShapeToMesh,
1825 const bool forExecutable)
1827 GHS3DPlugin_Hypothesis::ImplementedAlgorithms algoId = hyp ? (ImplementedAlgorithms) hyp->myAlgorithm : MGTetra;
1828 std::string cmd = GetExeName( algoId );
1830 // check if any option is overridden by hyp->myTextOption
1831 bool max_memory = hyp ? !hyp->HasOptionDefined("max_memory") : true;
1832 bool auto_memory = hyp ? !hyp->HasOptionDefined("automatic_memory") : true;
1833 bool comp = hyp ? !hyp->HasOptionDefined("components") : true;
1834 bool optim_level = hyp ? !hyp->HasOptionDefined("optimisation_level") : true;
1835 bool no_int_points = hyp ? !hyp->HasOptionDefined("no_internal_points") : true;
1836 bool C = hyp ? !hyp->HasOptionDefined("-C") : true;
1837 bool verbose = hyp ? !hyp->HasOptionDefined("verbose") : true;
1838 bool gra = hyp ? !hyp->HasOptionDefined("-Dcpropa") : true;
1839 bool rem = hyp ? !hyp->HasOptionDefined("no_initial_central_point") : true;
1840 //bool fem = hyp ? !hyp->HasOptionDefined("-FEM") : true;
1842 // if use boundary recovery version, few options are allowed
1843 bool useBndRecovery = !C;
1844 if ( !useBndRecovery && hyp )
1845 useBndRecovery = hyp->myToUseBoundaryRecoveryVersion;
1847 // MG-Tetra needs to know amount of memory it may use (MB).
1848 // Default memory is defined at MG-Tetra installation but it may be not enough, // so allow to use about all available memory
1849 if ( algoId == MGTetra && max_memory ) {
1850 float aMaximumMemory = hyp ? hyp->myMaximumMemory : -1;
1851 cmd += " --max_memory ";
1852 if ( aMaximumMemory < 0 ) cmd += SMESH_Comment( int( DefaultMaximumMemory() ));
1853 else cmd += SMESH_Comment( int( aMaximumMemory ));
1855 if ( algoId == MGTetra && ( auto_memory && !useBndRecovery ) ) {
1856 float aInitialMemory = hyp ? hyp->myInitialMemory : -1;
1857 cmd += " --automatic_memory ";
1858 if ( aInitialMemory > 0 ) cmd += SMESH_Comment( int( aInitialMemory ));
1862 // component to mesh
1863 if ( comp && !useBndRecovery ) {
1864 // We always run MG-Tetra with "to mesh holes'==TRUE (see PAL19680)
1865 if ( hasShapeToMesh )
1866 cmd += " --components all";
1868 bool aToMeshHoles = hyp ? hyp->myToMeshHoles : DefaultMeshHoles();
1869 if ( aToMeshHoles ) cmd += " --components all";
1870 else cmd += " --components outside_components";
1873 const bool toCreateNewNodes = ( no_int_points && ( !hyp || hyp->myToCreateNewNodes ));
1875 // optimization level
1876 if ( !toCreateNewNodes ) {
1877 cmd += " --optimisation_level none"; // issue 22608
1879 else if ( optim_level && hyp && !useBndRecovery ) {
1880 const char* level[] = { "none" , "light" , "standard" , "standard+" , "strong" };
1881 const short myOpt = hyp->myOptimizationLevel;
1883 if ( myOpt >= 0 && myOpt < 5 && ( algoId == MGTetra || ( algoId == MGTetraHPC && myOpt != 3 ) ) ) {
1884 cmd += " --optimisation_level ";
1885 cmd += level[ myOpt ];
1889 // to create internal nodes
1890 if ( no_int_points && !toCreateNewNodes ) {
1891 if ( forExecutable )
1892 cmd += " --no_internal_points";
1894 cmd += " --internalpoints no";
1901 cmd += " --verbose " + SMESH_Comment( hyp->myVerboseLevel );
1904 // to remove initial central point.
1905 if ( rem && hyp->myToRemoveCentralPoint ) {
1906 if ( forExecutable )
1907 cmd += " --no_initial_central_point";
1909 cmd += " --centralpoint no";
1912 if ( hyp->GetMinSize() > 0 )
1913 cmd += " --min_size " + SMESH_Comment( hyp->GetMinSize() );
1915 if ( hyp->GetMaxSize() > 0 )
1916 cmd += " --max_size " + SMESH_Comment( hyp->GetMaxSize() );
1918 // to define volumic gradation.
1920 cmd += " --gradation " + SMESH_Comment( hyp->myGradation );
1922 if ( hyp->GetUseNumOfThreads() )
1924 cmd += " --max_number_of_threads " + SMESH_Comment( hyp->GetNumOfThreads() );
1925 const char* pthreadMode[] = { "none" , "aggressive" , "safe" };
1926 const char* parallelMode[] = { "none", "reproducible_given_max_number_of_threads", "reproducible", "aggressive" };
1928 if ( algoId == MGTetra && hyp->myPthreadModeMG >= 1 && hyp->myPthreadModeMG < 3 ) {
1929 cmd += " --pthreads_mode ";
1930 cmd += pthreadMode[ hyp->myPthreadModeMG ];
1932 else if ( algoId == MGTetraHPC && hyp->myPthreadModeMGHPC >= 1 && hyp->myPthreadModeMGHPC < 4 )
1934 cmd += " --parallel_strategy ";
1935 cmd += parallelMode[ hyp->myPthreadModeMGHPC ];
1940 if ( hyp->GetUseVolumeProximity() )
1942 cmd += " --volume_proximity_layers " + SMESH_Comment( hyp->GetNbVolumeProximityLayers() );
1945 hyp->SetAdvancedOptionsInCommandLine( cmd );
1954 //================================================================================
1956 * \brief Return a unique file name for MGTetra
1958 //================================================================================
1960 std::string GHS3DPlugin_Hypothesis::GetFileName(const GHS3DPlugin_Hypothesis* hyp)
1962 std::string aTmpDir = hyp ? hyp->GetWorkingDirectory() : DefaultWorkingDirectory();
1963 if ( !SMESH_File( aTmpDir ).exists() )
1964 aTmpDir = Kernel_Utils::GetTmpDirByPath( aTmpDir );
1966 const char lastChar = *aTmpDir.rbegin();
1968 if(lastChar != '\\') aTmpDir+='\\';
1970 if(lastChar != '/') aTmpDir+='/';
1973 TCollection_AsciiString aGenericName = (char*)aTmpDir.c_str();
1974 aGenericName += "GHS3D_";
1975 aGenericName += getpid();
1976 aGenericName += "_";
1977 aGenericName += Abs((Standard_Integer)(long) aGenericName.ToCString());
1979 return aGenericName.ToCString();
1982 //================================================================================
1984 * \brief Return a unique file name when running MGTetra HPC
1986 //================================================================================
1988 std::string GHS3DPlugin_Hypothesis::GetFileNameHPC(const GHS3DPlugin_Hypothesis* hyp)
1990 std::string aTmpDir = hyp ? hyp->GetWorkingDirectory() : DefaultWorkingDirectory();
1991 if ( !SMESH_File( aTmpDir ).exists() )
1992 aTmpDir = Kernel_Utils::GetTmpDirByPath( aTmpDir );
1994 const char lastChar = *aTmpDir.rbegin();
1996 if(lastChar != '\\') aTmpDir+='\\';
1998 if(lastChar != '/') aTmpDir+='/';
2001 TCollection_AsciiString aGenericName = (char*)aTmpDir.c_str();
2002 aGenericName += "MGTETRAHPC_";
2003 aGenericName += getpid();
2004 aGenericName += "_";
2005 aGenericName += Abs((Standard_Integer)(long) aGenericName.ToCString());
2007 return aGenericName.ToCString();
2010 //================================================================================
2012 * Return the name of executable
2014 //================================================================================
2016 std::string GHS3DPlugin_Hypothesis::GetExeName( ImplementedAlgorithms algoId )
2021 return "mg-tetra.exe";
2023 return "mg-tetra_hpc.exe";
2025 throw( "Undefined algorithm id: ");
2029 //================================================================================
2031 * \brief Return the enforced vertices
2033 //================================================================================
2035 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexList GHS3DPlugin_Hypothesis::GetEnforcedVertices(const GHS3DPlugin_Hypothesis* hyp)
2037 return hyp ? hyp->_GetEnforcedVertices(): TGHS3DEnforcedVertexList();
2040 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues GHS3DPlugin_Hypothesis::GetEnforcedVerticesCoordsSize (const GHS3DPlugin_Hypothesis* hyp)
2042 return hyp ? hyp->_GetEnforcedVerticesCoordsSize(): TGHS3DEnforcedVertexCoordsValues();
2045 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexEntryValues GHS3DPlugin_Hypothesis::GetEnforcedVerticesEntrySize (const GHS3DPlugin_Hypothesis* hyp)
2047 return hyp ? hyp->_GetEnforcedVerticesEntrySize(): TGHS3DEnforcedVertexEntryValues();
2050 GHS3DPlugin_Hypothesis::TCoordsGHS3DEnforcedVertexMap GHS3DPlugin_Hypothesis::GetEnforcedVerticesByCoords (const GHS3DPlugin_Hypothesis* hyp)
2052 return hyp ? hyp->_GetEnforcedVerticesByCoords(): TCoordsGHS3DEnforcedVertexMap();
2055 GHS3DPlugin_Hypothesis::TGeomEntryGHS3DEnforcedVertexMap GHS3DPlugin_Hypothesis::GetEnforcedVerticesByEntry (const GHS3DPlugin_Hypothesis* hyp)
2057 return hyp ? hyp->_GetEnforcedVerticesByEntry(): TGeomEntryGHS3DEnforcedVertexMap();
2060 GHS3DPlugin_Hypothesis::TIDSortedNodeGroupMap GHS3DPlugin_Hypothesis::GetEnforcedNodes(const GHS3DPlugin_Hypothesis* hyp)
2062 return hyp ? hyp->_GetEnforcedNodes():TIDSortedNodeGroupMap();
2065 GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap GHS3DPlugin_Hypothesis::GetEnforcedEdges(const GHS3DPlugin_Hypothesis* hyp)
2067 return hyp ? hyp->_GetEnforcedEdges():TIDSortedElemGroupMap();
2070 GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap GHS3DPlugin_Hypothesis::GetEnforcedTriangles(const GHS3DPlugin_Hypothesis* hyp)
2072 return hyp ? hyp->_GetEnforcedTriangles():TIDSortedElemGroupMap();
2075 GHS3DPlugin_Hypothesis::TID2SizeMap GHS3DPlugin_Hypothesis::GetNodeIDToSizeMap(const GHS3DPlugin_Hypothesis* hyp)
2077 return hyp ? hyp->_GetNodeIDToSizeMap(): TID2SizeMap();
2080 GHS3DPlugin_Hypothesis::TSetStrings GHS3DPlugin_Hypothesis::GetGroupsToRemove(const GHS3DPlugin_Hypothesis* hyp)
2082 return hyp ? hyp->_GetGroupsToRemove(): TSetStrings();
2086 //=============================================================================
2087 void GHS3DPlugin_Hypothesis::SetOptionValue(const std::string& optionName,
2088 const std::string& optionValue)
2090 TOptionValues::iterator op_val = _option2value.find(optionName);
2091 if (op_val == _option2value.end())
2093 op_val = _customOption2value.find( optionName );
2094 if ( op_val != _customOption2value.end() && op_val->second != optionValue )
2095 NotifySubMeshesHypothesisModification();
2096 _customOption2value[ optionName ] = optionValue;
2100 if (op_val->second != optionValue)
2102 const char* ptr = optionValue.c_str();
2103 // strip white spaces
2104 while (ptr[0] == ' ')
2106 size_t i = strlen(ptr);
2107 while (i != 0 && ptr[i - 1] == ' ')
2111 std::string typeName;
2114 } else if (_charOptions.count(optionName)) {
2115 // do not check strings
2116 } else if (_doubleOptions.count(optionName)) {
2117 // check if value is double
2118 ToDbl(ptr, &typeOk);
2120 } else if (_boolOptions.count(optionName)) {
2121 // check if value is bool
2122 ToBool(ptr, &typeOk);
2125 // check if value is int
2126 ToInt(ptr, &typeOk);
2127 typeName = "integer";
2129 if ( typeOk ) // check some specific values ?
2134 std::string msg = "Advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName;
2135 throw std::invalid_argument(msg);
2137 std::string value( ptr, i );
2138 if ( _defaultOptionValues[ optionName ] == value )
2141 op_val->second = value;
2143 NotifySubMeshesHypothesisModification();
2147 //=============================================================================
2148 //! Return option value. If isDefault provided, it can be a default value,
2149 // then *isDefault == true. If isDefault is not provided, the value will be
2150 // empty if it equals a default one.
2151 std::string GHS3DPlugin_Hypothesis::GetOptionValue(const std::string& optionName,
2152 bool* isDefault) const
2154 TOptionValues::const_iterator op_val = _option2value.find(optionName);
2155 if (op_val == _option2value.end())
2157 op_val = _customOption2value.find(optionName);
2158 if (op_val == _customOption2value.end())
2160 std::string msg = "Unknown MG-Tetra option: <" + optionName + ">";
2161 throw std::invalid_argument(msg);
2164 std::string val = op_val->second;
2165 if ( isDefault ) *isDefault = ( val.empty() );
2167 if ( val.empty() && isDefault )
2169 op_val = _defaultOptionValues.find( optionName );
2170 if (op_val != _defaultOptionValues.end())
2171 val = op_val->second;
2177 //=============================================================================
2178 bool GHS3DPlugin_Hypothesis::HasOptionDefined( const std::string& optionName ) const
2180 bool isDefault = false;
2183 GetOptionValue( optionName, &isDefault );
2185 catch ( std::invalid_argument& )
2192 //=============================================================================
2193 void GHS3DPlugin_Hypothesis::ClearOption(const std::string& optionName)
2195 TOptionValues::iterator op_val = _customOption2value.find(optionName);
2196 if (op_val != _customOption2value.end())
2197 _customOption2value.erase(op_val);
2199 op_val = _option2value.find(optionName);
2200 if (op_val != _option2value.end())
2201 op_val->second.clear();
2205 //=============================================================================
2206 GHS3DPlugin_Hypothesis::TOptionValues GHS3DPlugin_Hypothesis::GetOptionValues() const
2209 TOptionValues::const_iterator op_val = _option2value.begin();
2210 for ( ; op_val != _option2value.end(); ++op_val )
2211 vals.insert( make_pair( op_val->first, GetOptionValue( op_val->first, GET_DEFAULT() )));
2216 //================================================================================
2218 * \brief Converts a string to a bool
2220 //================================================================================
2222 bool GHS3DPlugin_Hypothesis::ToBool(const std::string& str, bool* isOk )
2224 std::string s = str;
2225 if ( isOk ) *isOk = true;
2227 for ( size_t i = 0; i <= s.size(); ++i )
2228 s[i] = (char) tolower( s[i] );
2230 if ( s == "1" || s == "true" || s == "active" || s == "yes" )
2233 if ( s == "0" || s == "false" || s == "inactive" || s == "no" )
2239 std::string msg = "Not a Boolean value:'" + str + "'";
2240 throw std::invalid_argument(msg);
2245 //================================================================================
2247 * \brief Converts a string to a real value
2249 //================================================================================
2251 double GHS3DPlugin_Hypothesis::ToDbl(const std::string& str, bool* isOk )
2253 if ( str.empty() ) throw std::invalid_argument("Empty value provided");
2256 double val = strtod(&str[0], &endPtr);
2257 bool ok = (&str[0] != endPtr);
2259 if ( isOk ) *isOk = ok;
2263 std::string msg = "Not a real value:'" + str + "'";
2264 throw std::invalid_argument(msg);
2269 //================================================================================
2271 * \brief Converts a string to a integer value
2273 //================================================================================
2275 int GHS3DPlugin_Hypothesis::ToInt(const std::string& str, bool* isOk )
2277 if ( str.empty() ) throw std::invalid_argument("Empty value provided");
2280 int val = (int)strtol( &str[0], &endPtr, 10);
2281 bool ok = (&str[0] != endPtr);
2283 if ( isOk ) *isOk = ok;
2287 std::string msg = "Not an integer value:'" + str + "'";
2288 throw std::invalid_argument(msg);