1 // Copyright (C) 2004-2021 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()),
81 const char* boolOptionNames[] = { "no_initial_central_point", // no
82 "force_max_size", // no
83 "apply_gradation_on_skin_vertex_sizes", // yes
84 "optimise_worst_elements", // no
85 "force_output_quadratic_mesh", // no
86 "rectify_jacobian", // yes
87 "jacobian_rectification_respect_input_surface_mesh", // yes
90 const char* intOptionNames[] = { "max_number_of_errors_printed", // 1
91 "max_number_of_threads", // 4
94 const char* doubleOptionNames[] = { "target_quality", // 0
98 const char* charOptionNames[] = { "pthreads_mode", // ""
99 "boundary_regeneration", // standard
100 "split_overconstrained_tetrahedra", // no
105 while (boolOptionNames[i][0])
107 _boolOptions.insert( boolOptionNames[i] );
108 _option2value[boolOptionNames[i++]].clear();
111 while (intOptionNames[i][0])
112 _option2value[intOptionNames[i++]].clear();
115 while (doubleOptionNames[i][0]) {
116 _doubleOptions.insert(doubleOptionNames[i]);
117 _option2value[doubleOptionNames[i++]].clear();
120 while (charOptionNames[i][0]) {
121 _charOptions.insert(charOptionNames[i]);
122 _option2value[charOptionNames[i++]].clear();
125 // default values to be used while MG meshing
127 _defaultOptionValues["no_initial_central_point" ] = "no";
128 _defaultOptionValues["force_max_size" ] = "no";
129 _defaultOptionValues["apply_gradation_on_skin_vertex_sizes" ] = "yes";
130 _defaultOptionValues["optimise_worst_elements" ] = "no";
131 _defaultOptionValues["force_output_quadratic_mesh" ] = "no";
132 _defaultOptionValues["rectify_jacobian" ] = "yes";
133 _defaultOptionValues["jacobian_rectification_respect_input_surface_mesh"] = "yes";
134 _defaultOptionValues["max_number_of_errors_printed" ] = "1";
135 _defaultOptionValues["max_number_of_threads" ] = "4";
136 _defaultOptionValues["target_quality" ] = "";//NoValue();
137 _defaultOptionValues["sliver_angle" ] = "5";
138 _defaultOptionValues["pthreads_mode" ] = "";//NoValue();
139 _defaultOptionValues["boundary_regeneration" ] = "standard";
140 _defaultOptionValues["split_overconstrained_tetrahedra" ] = "no";
143 // check validity of option names of _defaultOptionValues
144 TOptionValues::iterator n2v = _defaultOptionValues.begin();
145 for ( ; n2v != _defaultOptionValues.end(); ++n2v )
146 ASSERT( _option2value.count( n2v->first ));
147 ASSERT( _option2value.size() == _defaultOptionValues.size() );
151 //=======================================================================
152 //function : SetToMeshHoles
153 //=======================================================================
155 void GHS3DPlugin_Hypothesis::SetToMeshHoles(bool toMesh)
157 if ( myToMeshHoles != toMesh ) {
158 myToMeshHoles = toMesh;
159 NotifySubMeshesHypothesisModification();
163 //=======================================================================
164 //function : GetToMeshHoles
165 //=======================================================================
167 bool GHS3DPlugin_Hypothesis::GetToMeshHoles(bool checkFreeOption) const
169 if ( checkFreeOption )
171 std::string optionName = "components";
172 TOptionValues::const_iterator op_val = _customOption2value.find(optionName);
173 if ( op_val != _customOption2value.end())
175 if ( op_val->second.find("all"))
177 if ( op_val->second.find("outside_components"))
181 return myToMeshHoles;
184 //=======================================================================
185 //function : SetToMakeGroupsOfDomains
186 //=======================================================================
188 void GHS3DPlugin_Hypothesis::SetToMakeGroupsOfDomains(bool toMakeGroups)
190 if ( myToMakeGroupsOfDomains != toMakeGroups ) {
191 myToMakeGroupsOfDomains = toMakeGroups;
192 NotifySubMeshesHypothesisModification();
196 //=======================================================================
197 //function : GetToMakeGroupsOfDomains
198 //=======================================================================
200 bool GHS3DPlugin_Hypothesis::GetToMakeGroupsOfDomains() const
202 return myToMakeGroupsOfDomains;
205 //=======================================================================
206 //function : GetToMakeGroupsOfDomains
207 //=======================================================================
209 bool GHS3DPlugin_Hypothesis::GetToMakeGroupsOfDomains(const GHS3DPlugin_Hypothesis* hyp)
212 if ( hyp ) res = /*hyp->GetToMeshHoles(true) &&*/ hyp->GetToMakeGroupsOfDomains();
213 else res = /*DefaultMeshHoles() &&*/ DefaultToMakeGroupsOfDomains();
217 //=======================================================================
218 //function : SetMaximumMemory
219 //=======================================================================
221 void GHS3DPlugin_Hypothesis::SetMaximumMemory(float MB)
223 if ( myMaximumMemory != MB ) {
224 myMaximumMemory = MB;
225 NotifySubMeshesHypothesisModification();
229 //=======================================================================
230 //function : GetMaximumMemory
231 // * automatic memory adjustment mode. Default is zero
232 //=======================================================================
234 float GHS3DPlugin_Hypothesis::GetMaximumMemory() const
236 return myMaximumMemory;
239 //=======================================================================
240 //function : SetInitialMemory
241 //=======================================================================
243 void GHS3DPlugin_Hypothesis::SetInitialMemory(float MB)
245 if ( myInitialMemory != MB ) {
246 myInitialMemory = MB;
247 NotifySubMeshesHypothesisModification();
251 //=======================================================================
252 //function : GetInitialMemory
253 //=======================================================================
255 float GHS3DPlugin_Hypothesis::GetInitialMemory() const
257 return myInitialMemory;
260 //=======================================================================
261 //function : SetOptimizationLevel
262 //=======================================================================
264 void GHS3DPlugin_Hypothesis::SetOptimizationLevel(OptimizationLevel level)
266 if ( myOptimizationLevel != level ) {
267 myOptimizationLevel = level;
268 NotifySubMeshesHypothesisModification();
272 //=======================================================================
273 //function : GetOptimizationLevel
274 //=======================================================================
276 GHS3DPlugin_Hypothesis::OptimizationLevel GHS3DPlugin_Hypothesis::GetOptimizationLevel() const
278 return (OptimizationLevel) myOptimizationLevel;
281 //=======================================================================
282 //function : SetWorkingDirectory
283 //=======================================================================
285 void GHS3DPlugin_Hypothesis::SetWorkingDirectory(const std::string& path)
287 if ( myWorkingDirectory != path ) {
288 myWorkingDirectory = path;
289 NotifySubMeshesHypothesisModification();
293 //=======================================================================
294 //function : GetWorkingDirectory
295 //=======================================================================
297 std::string GHS3DPlugin_Hypothesis::GetWorkingDirectory() const
299 return myWorkingDirectory;
302 //=======================================================================
303 //function : SetKeepFiles
304 //=======================================================================
306 void GHS3DPlugin_Hypothesis::SetKeepFiles(bool toKeep)
308 if ( myKeepFiles != toKeep ) {
309 myKeepFiles = toKeep;
310 NotifySubMeshesHypothesisModification();
314 //=======================================================================
315 //function : GetKeepFiles
316 //=======================================================================
318 bool GHS3DPlugin_Hypothesis::GetKeepFiles() const
323 //=======================================================================
324 //function : SetVerboseLevel
325 //=======================================================================
327 void GHS3DPlugin_Hypothesis::SetVerboseLevel(short level)
329 if ( myVerboseLevel != level ) {
330 myVerboseLevel = level;
331 NotifySubMeshesHypothesisModification();
335 //=======================================================================
336 //function : GetVerboseLevel
337 //=======================================================================
339 short GHS3DPlugin_Hypothesis::GetVerboseLevel() const
341 return myVerboseLevel;
344 //=======================================================================
345 //function : SetToCreateNewNodes
346 //=======================================================================
348 void GHS3DPlugin_Hypothesis::SetToCreateNewNodes(bool toCreate)
350 if ( myToCreateNewNodes != toCreate ) {
351 myToCreateNewNodes = toCreate;
352 NotifySubMeshesHypothesisModification();
356 //=======================================================================
357 //function : GetToCreateNewNodes
358 //=======================================================================
360 bool GHS3DPlugin_Hypothesis::GetToCreateNewNodes() const
362 return myToCreateNewNodes;
365 //=======================================================================
366 //function : SetToUseBoundaryRecoveryVersion
367 //=======================================================================
369 void GHS3DPlugin_Hypothesis::SetToUseBoundaryRecoveryVersion(bool toUse)
371 if ( myToUseBoundaryRecoveryVersion != toUse ) {
372 myToUseBoundaryRecoveryVersion = toUse;
373 NotifySubMeshesHypothesisModification();
377 //=======================================================================
378 //function : GetToUseBoundaryRecoveryVersion
379 //=======================================================================
381 bool GHS3DPlugin_Hypothesis::GetToUseBoundaryRecoveryVersion() const
383 return myToUseBoundaryRecoveryVersion;
386 //=======================================================================
387 //function : SetFEMCorrection
388 //=======================================================================
390 void GHS3DPlugin_Hypothesis::SetFEMCorrection(bool toUseFem)
392 if ( myToUseFemCorrection != toUseFem ) {
393 myToUseFemCorrection = toUseFem;
394 NotifySubMeshesHypothesisModification();
398 //=======================================================================
399 //function : GetFEMCorrection
400 //=======================================================================
402 bool GHS3DPlugin_Hypothesis::GetFEMCorrection() const
404 return myToUseFemCorrection;
407 //=======================================================================
408 //function : SetToRemoveCentralPoint
409 //=======================================================================
411 void GHS3DPlugin_Hypothesis::SetToRemoveCentralPoint(bool toRemove)
413 SetOptionValue( "no_initial_central_point", toRemove ? "yes" : "no" );
414 myToRemoveCentralPoint = toRemove;
417 //=======================================================================
418 //function : GetToRemoveCentralPoint
419 //=======================================================================
421 bool GHS3DPlugin_Hypothesis::GetToRemoveCentralPoint() const
423 return myToRemoveCentralPoint;
426 //=======================================================================
427 //function : SetAdvancedOption
428 //=======================================================================
430 void GHS3DPlugin_Hypothesis::SetAdvancedOption(const std::string& option)
432 size_t wsPos = option.find(' ');
433 if ( wsPos == string::npos )
435 SetOptionValue( option, "" );
439 std::string opt( option, 0, wsPos );
440 std::string val( option, wsPos + 1 );
441 SetOptionValue( opt, val );
445 //=======================================================================
446 //function : GetAdvancedOption
447 //=======================================================================
449 std::string GHS3DPlugin_Hypothesis::GetAdvancedOption() const
453 TOptionValues::const_iterator o2v = _option2value.begin();
454 for ( ; o2v != _option2value.end(); ++o2v )
455 if ( !o2v->second.empty() )
459 txt << o2v->first << " " << o2v->second;
461 for ( o2v = _customOption2value.begin(); o2v != _customOption2value.end(); ++o2v )
465 txt << o2v->first << " " << o2v->second;
470 //=======================================================================
471 //function : SetGradation
472 //=======================================================================
474 void GHS3DPlugin_Hypothesis::SetGradation(double gradation)
476 if ( myGradation != gradation ) {
477 myGradation = gradation;
478 NotifySubMeshesHypothesisModification();
482 //=======================================================================
483 //function : GetGradation
484 //=======================================================================
486 double GHS3DPlugin_Hypothesis::GetGradation() const
491 //=============================================================================
492 void GHS3DPlugin_Hypothesis::SetMinSize(double theMinSize)
494 if ( theMinSize != myMinSize )
496 myMinSize = theMinSize;
497 NotifySubMeshesHypothesisModification();
501 //=============================================================================
502 void GHS3DPlugin_Hypothesis::SetMaxSize(double theMaxSize)
504 if ( theMaxSize != myMaxSize )
506 myMaxSize = theMaxSize;
507 NotifySubMeshesHypothesisModification();
511 //=============================================================================
512 void GHS3DPlugin_Hypothesis::SetUseVolumeProximity( bool toUse )
514 if ( myUseVolumeProximity != toUse )
516 myUseVolumeProximity = toUse;
517 NotifySubMeshesHypothesisModification();
521 //=============================================================================
522 void GHS3DPlugin_Hypothesis::SetNbVolumeProximityLayers( int nbLayers )
524 if ( myNbVolumeProximityLayers != nbLayers )
526 myNbVolumeProximityLayers = nbLayers;
527 NotifySubMeshesHypothesisModification();
531 //=======================================================================
532 //function : SetStandardOutputLog
533 //=======================================================================
535 void GHS3DPlugin_Hypothesis::SetStandardOutputLog(bool logInStandardOutput)
537 if ( myLogInStandardOutput != logInStandardOutput ) {
538 myLogInStandardOutput = logInStandardOutput;
539 NotifySubMeshesHypothesisModification();
543 //=======================================================================
544 //function : GetStandardOutputLog
545 //=======================================================================
547 bool GHS3DPlugin_Hypothesis::GetStandardOutputLog() const
549 return myLogInStandardOutput;
552 //=======================================================================
553 //function : SetRemoveLogOnSuccess
554 //=======================================================================
556 void GHS3DPlugin_Hypothesis::SetRemoveLogOnSuccess(bool removeLogOnSuccess)
558 if ( myRemoveLogOnSuccess != removeLogOnSuccess ) {
559 myRemoveLogOnSuccess = removeLogOnSuccess;
560 NotifySubMeshesHypothesisModification();
564 //=======================================================================
565 //function : GetRemoveLogOnSuccess
566 //=======================================================================
568 bool GHS3DPlugin_Hypothesis::GetRemoveLogOnSuccess() const
570 return myRemoveLogOnSuccess;
573 //=======================================================================
574 //function : SetEnforcedVertex
575 //=======================================================================
577 bool GHS3DPlugin_Hypothesis::SetEnforcedVertex(std::string theName,
578 std::string theEntry,
579 std::string theGroupName,
581 double x, double y, double z,
584 MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedVertex(\""<< theName << "\", \""<< theEntry << "\", \"" << theGroupName << "\", "
585 << size << ", " << x << ", " << y << ", " << z << ", "<< isCompound << ")");
587 bool toNotify = false;
588 bool toCreate = true;
590 TGHS3DEnforcedVertex *oldEnVertex;
591 TGHS3DEnforcedVertex *newEnfVertex = new TGHS3DEnforcedVertex();
592 newEnfVertex->name = theName;
593 newEnfVertex->geomEntry = theEntry;
594 newEnfVertex->coords.clear();
596 newEnfVertex->coords.push_back(x);
597 newEnfVertex->coords.push_back(y);
598 newEnfVertex->coords.push_back(z);
600 newEnfVertex->groupName = theGroupName;
601 newEnfVertex->size = size;
602 newEnfVertex->isCompound = isCompound;
605 // update _enfVertexList
606 TGHS3DEnforcedVertexList::iterator it = _enfVertexList.find(newEnfVertex);
607 if (it != _enfVertexList.end()) {
610 MESSAGE("Enforced Vertex was found => Update");
611 if (oldEnVertex->name != theName) {
612 MESSAGE("Update name from \"" << oldEnVertex->name << "\" to \"" << theName << "\"");
613 oldEnVertex->name = theName;
616 if (oldEnVertex->groupName != theGroupName) {
617 MESSAGE("Update group name from \"" << oldEnVertex->groupName << "\" to \"" << theGroupName << "\"");
618 oldEnVertex->groupName = theGroupName;
621 if (oldEnVertex->size != size) {
622 MESSAGE("Update size from \"" << oldEnVertex->size << "\" to \"" << size << "\"");
623 oldEnVertex->size = size;
627 // update map coords / enf vertex if needed
628 if (oldEnVertex->coords.size()) {
629 _coordsEnfVertexMap[oldEnVertex->coords] = oldEnVertex;
630 _enfVertexCoordsSizeList[oldEnVertex->coords] = size;
633 // update map geom entry / enf vertex if needed
634 if (oldEnVertex->geomEntry != "") {
635 _geomEntryEnfVertexMap[oldEnVertex->geomEntry] = oldEnVertex;
636 _enfVertexEntrySizeList[oldEnVertex->geomEntry] = size;
641 // //////// CREATE ////////////
644 MESSAGE("Creating new enforced vertex");
645 _enfVertexList.insert(newEnfVertex);
646 if (theEntry == "") {
647 _coordsEnfVertexMap[newEnfVertex->coords] = newEnfVertex;
648 _enfVertexCoordsSizeList[newEnfVertex->coords] = size;
651 _geomEntryEnfVertexMap[newEnfVertex->geomEntry] = newEnfVertex;
652 _enfVertexEntrySizeList[newEnfVertex->geomEntry] = size;
657 NotifySubMeshesHypothesisModification();
659 MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedVertex END");
664 //=======================================================================
665 //function : SetEnforcedMesh
666 //=======================================================================
667 bool GHS3DPlugin_Hypothesis::SetEnforcedMesh(SMESH_Mesh& theMesh, SMESH::ElementType elementType, std::string name, std::string entry, std::string groupName)
669 TIDSortedElemSet theElemSet;
670 SMDS_ElemIteratorPtr eIt = theMesh.GetMeshDS()->elementsIterator(SMDSAbs_ElementType(elementType));
671 while ( eIt->more() )
672 theElemSet.insert( eIt->next() );
673 MESSAGE("Add "<<theElemSet.size()<<" types["<<elementType<<"] from source mesh");
674 bool added = SetEnforcedElements( theElemSet, elementType, groupName);
676 TGHS3DEnforcedMesh* newEnfMesh = new TGHS3DEnforcedMesh();
677 newEnfMesh->persistID = theMesh.GetMeshDS()->GetPersistentId();
678 newEnfMesh->name = name;
679 newEnfMesh->entry = entry;
680 newEnfMesh->elementType = elementType;
681 newEnfMesh->groupName = groupName;
683 TGHS3DEnforcedMeshList::iterator it = _enfMeshList.find(newEnfMesh);
684 if (it == _enfMeshList.end()) {
685 _entryEnfMeshMap[entry].insert(newEnfMesh);
686 _enfMeshList.insert(newEnfMesh);
695 //=======================================================================
696 //function : SetEnforcedGroup
697 //=======================================================================
698 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)
700 MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedGroup");
701 TIDSortedElemSet theElemSet;
702 if ( theIDs->length() == 0 ){MESSAGE("The source group is empty");}
703 for ( CORBA::ULong i = 0; i < theIDs->length(); i++) {
704 SMESH::smIdType ind = theIDs[i];
705 if (elementType == SMESH::NODE)
707 const SMDS_MeshNode * node = theMeshDS->FindNode(ind);
709 theElemSet.insert( node );
713 const SMDS_MeshElement * elem = theMeshDS->FindElement(ind);
715 theElemSet.insert( elem );
719 // SMDS_ElemIteratorPtr it = theGroup->GetGroupDS()->GetElements();
720 // while ( it->more() )
721 // theElemSet.insert( it->next() );
723 MESSAGE("Add "<<theElemSet.size()<<" types["<<elementType<<"] from source group ");
724 bool added = SetEnforcedElements( theElemSet, elementType, groupName);
726 TGHS3DEnforcedMesh* newEnfMesh = new TGHS3DEnforcedMesh();
727 newEnfMesh->name = name;
728 newEnfMesh->entry = entry;
729 newEnfMesh->elementType = elementType;
730 newEnfMesh->groupName = groupName;
732 TGHS3DEnforcedMeshList::iterator it = _enfMeshList.find(newEnfMesh);
733 if (it == _enfMeshList.end()) {
734 _entryEnfMeshMap[entry].insert(newEnfMesh);
735 _enfMeshList.insert(newEnfMesh);
741 //=======================================================================
742 //function : SetEnforcedElements
743 //=======================================================================
744 bool GHS3DPlugin_Hypothesis::SetEnforcedElements(TIDSortedElemSet theElemSet, SMESH::ElementType elementType, std::string groupName)
746 MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedElements");
747 TIDSortedElemSet::const_iterator it = theElemSet.begin();
748 const SMDS_MeshElement* elem;
749 const SMDS_MeshNode* node;
751 pair<TIDSortedNodeGroupMap::iterator,bool> nodeRet;
752 pair<TIDSortedElemGroupMap::iterator,bool> elemRet;
754 for (;it != theElemSet.end();++it)
757 switch (elementType) {
759 node = dynamic_cast<const SMDS_MeshNode*>(elem);
761 nodeRet = _enfNodes.insert(make_pair(node,groupName));
762 added = added && nodeRet.second;
763 string msg = added ? "yes":"no";
764 MESSAGE( "Node (" <<node->X()<<","<<node->Y()<<","<<node->Z()<< ") with ID " << node->GetID() <<" added ? " << msg);
767 SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
768 for (;nodeIt->more();) {
769 node = dynamic_cast<const SMDS_MeshNode*>(nodeIt->next());
770 nodeRet = _enfNodes.insert(make_pair(node,groupName));
771 added = added && nodeRet.second;
776 if (elem->GetType() == SMDSAbs_Edge) {
777 elemRet = _enfEdges.insert(make_pair(elem,groupName));
778 added = added && elemRet.second;
780 else if (elem->GetType() > SMDSAbs_Edge) {
781 // SMDS_ElemIteratorPtr it = elem->edgesIterator();
782 // for (;it->more();) {
783 // const SMDS_MeshElement* anEdge = it->next();
784 // elemRet = _enfEdges.insert(make_pair(anEdge,groupName));
785 // added = added && elemRet.second;
790 if (elem->GetType() == SMDSAbs_Face)
792 if (elem->NbCornerNodes() == 3) {
793 elemRet = _enfTriangles.insert(make_pair(elem,groupName));
794 added = added && elemRet.second;
797 else if (elem->GetType() > SMDSAbs_Face) { // Group of faces
798 // SMDS_ElemIteratorPtr it = elem->facesIterator();
799 // for (;it->more();) {
800 // const SMDS_MeshElement* aFace = it->next();
801 // if (aFace->NbCornerNodes() == 3) {
802 // elemRet = _enfTriangles.insert(make_pair(aFace,groupName));
803 // added = added && elemRet.second;
813 NotifySubMeshesHypothesisModification();
818 //=======================================================================
819 //function : GetEnforcedVertex
820 //=======================================================================
822 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex* GHS3DPlugin_Hypothesis::GetEnforcedVertex(double x, double y, double z)
824 std::vector<double> coord(3);
828 if (_coordsEnfVertexMap.count(coord)>0)
829 return _coordsEnfVertexMap[coord];
830 std::ostringstream msg ;
831 msg << "No enforced vertex at " << x << ", " << y << ", " << z;
832 throw std::invalid_argument(msg.str());
835 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex* GHS3DPlugin_Hypothesis::GetEnforcedVertex(const std::string theEntry)
837 if (_geomEntryEnfVertexMap.count(theEntry)>0)
838 return _geomEntryEnfVertexMap[theEntry];
840 std::ostringstream msg ;
841 msg << "No enforced vertex with entry " << theEntry;
842 throw std::invalid_argument(msg.str());
845 //=======================================================================
846 //function : RemoveEnforcedVertex
847 //=======================================================================
849 bool GHS3DPlugin_Hypothesis::RemoveEnforcedVertex(double x, double y, double z, const std::string theEntry)
851 bool toNotify = false;
852 std::ostringstream msg;
853 TGHS3DEnforcedVertex *oldEnfVertex;
854 std::vector<double> coords(3);
859 // check that enf vertex with given enf vertex entry exists
860 TGeomEntryGHS3DEnforcedVertexMap::iterator it_enfVertexEntry = _geomEntryEnfVertexMap.find(theEntry);
861 if (it_enfVertexEntry != _geomEntryEnfVertexMap.end()) {
863 MESSAGE("Found enforced vertex with geom entry " << theEntry);
864 oldEnfVertex = it_enfVertexEntry->second;
865 _geomEntryEnfVertexMap.erase(it_enfVertexEntry);
868 MESSAGE("Enforced vertex with geom entry " << theEntry << " not found");
869 // check that enf vertex with given coords exists
870 TCoordsGHS3DEnforcedVertexMap::iterator it_coords_enf = _coordsEnfVertexMap.find(coords);
871 if (it_coords_enf != _coordsEnfVertexMap.end()) {
873 MESSAGE("Found enforced vertex with coords " << x << ", " << y << ", " << z);
874 oldEnfVertex = it_coords_enf->second;
875 _coordsEnfVertexMap.erase(it_coords_enf);
876 _enfVertexCoordsSizeList.erase(_enfVertexCoordsSizeList.find(coords));
879 MESSAGE("Enforced vertex with coords " << x << ", " << y << ", " << z << " not found");
880 throw std::invalid_argument(msg.str());
884 MESSAGE("Remove enf vertex from _enfVertexList");
886 // update _enfVertexList
887 TGHS3DEnforcedVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
888 if (it != _enfVertexList.end()) {
889 if ((*it)->groupName != "")
890 _groupsToRemove.insert((*it)->groupName);
891 _enfVertexList.erase(it);
897 NotifySubMeshesHypothesisModification();
902 //=======================================================================
903 //function : ClearEnforcedVertices
904 //=======================================================================
905 void GHS3DPlugin_Hypothesis::ClearEnforcedVertices()
907 TGHS3DEnforcedVertexList::const_iterator it = _enfVertexList.begin();
908 for(;it != _enfVertexList.end();++it) {
909 if ((*it)->groupName != "")
910 _groupsToRemove.insert((*it)->groupName);
912 _enfVertexList.clear();
913 _coordsEnfVertexMap.clear();
914 _geomEntryEnfVertexMap.clear();
915 _enfVertexCoordsSizeList.clear();
916 _enfVertexEntrySizeList.clear();
917 NotifySubMeshesHypothesisModification();
920 //=======================================================================
921 //function : ClearEnforcedMeshes
922 //=======================================================================
923 void GHS3DPlugin_Hypothesis::ClearEnforcedMeshes()
925 TGHS3DEnforcedMeshList::const_iterator it = _enfMeshList.begin();
926 for(;it != _enfMeshList.end();++it) {
927 if ((*it)->groupName != "")
928 _groupsToRemove.insert((*it)->groupName);
932 _enfTriangles.clear();
933 _nodeIDToSizeMap.clear();
934 _enfMeshList.clear();
935 _entryEnfMeshMap.clear();
936 NotifySubMeshesHypothesisModification();
939 //================================================================================
941 * \brief At mesh loading, restore enforced elements by just loaded enforced meshes
943 //================================================================================
945 void GHS3DPlugin_Hypothesis::RestoreEnfElemsByMeshes()
947 TGHS3DEnforcedMeshList::const_iterator it = _enfMeshList.begin();
948 for(;it != _enfMeshList.end();++it) {
949 TGHS3DEnforcedMesh* enfMesh = *it;
950 if ( SMESH_Mesh* mesh = GetMeshByPersistentID( enfMesh->persistID ))
951 SetEnforcedMesh( *mesh,
952 enfMesh->elementType,
955 enfMesh->groupName );
956 enfMesh->persistID = -1; // not to restore again
960 //=======================================================================
961 //function : SetGroupsToRemove
962 //=======================================================================
964 void GHS3DPlugin_Hypothesis::ClearGroupsToRemove()
966 _groupsToRemove.clear();
970 //=======================================================================
971 //function : DefaultMeshHoles
972 //=======================================================================
974 bool GHS3DPlugin_Hypothesis::DefaultMeshHoles()
976 return false; // PAL19680
979 //=======================================================================
980 //function : DefaultToMakeGroupsOfDomains
981 //=======================================================================
983 bool GHS3DPlugin_Hypothesis::DefaultToMakeGroupsOfDomains()
985 return false; // issue 0022172
988 //=======================================================================
989 //function : DefaultMaximumMemory
990 //=======================================================================
994 #elif !defined(__APPLE__)
995 #include <sys/sysinfo.h>
998 float GHS3DPlugin_Hypothesis::DefaultMaximumMemory()
1001 // See http://msdn.microsoft.com/en-us/library/aa366589.aspx
1002 MEMORYSTATUSEX statex;
1003 statex.dwLength = sizeof (statex);
1004 long err = GlobalMemoryStatusEx (&statex);
1006 double totMB = double( statex.ullAvailPhys ) / 1024. / 1024.;
1007 return float( 0.7 * totMB );
1009 #elif !defined(__APPLE__)
1011 long err = sysinfo( &si );
1013 double ramMB = double( si.totalram * si.mem_unit / 1024 / 1024 );
1014 return float( 0.7 * ramMB );
1020 //=======================================================================
1021 //function : DefaultInitialMemory
1022 //=======================================================================
1024 float GHS3DPlugin_Hypothesis::DefaultInitialMemory()
1026 return DefaultMaximumMemory();
1029 //=======================================================================
1030 //function : DefaultOptimizationLevel
1031 //=======================================================================
1033 short GHS3DPlugin_Hypothesis::DefaultOptimizationLevel()
1038 //=======================================================================
1039 //function : DefaultWorkingDirectory
1040 //=======================================================================
1042 std::string GHS3DPlugin_Hypothesis::DefaultWorkingDirectory()
1044 TCollection_AsciiString aTmpDir;
1046 char *Tmp_dir = getenv("SALOME_TMP_DIR");
1047 if(Tmp_dir != NULL) {
1052 aTmpDir = TCollection_AsciiString("C:\\");
1054 aTmpDir = TCollection_AsciiString("/tmp/");
1057 return aTmpDir.ToCString();
1060 //=======================================================================
1061 //function : DefaultKeepFiles
1062 //=======================================================================
1064 bool GHS3DPlugin_Hypothesis::DefaultKeepFiles()
1069 //=======================================================================
1070 //function : DefaultRemoveLogOnSuccess
1071 //=======================================================================
1073 bool GHS3DPlugin_Hypothesis::DefaultRemoveLogOnSuccess()
1079 //=======================================================================
1080 //function : DefaultVerboseLevel
1081 //=======================================================================
1083 short GHS3DPlugin_Hypothesis::DefaultVerboseLevel()
1088 //=======================================================================
1089 //function : DefaultToCreateNewNodes
1090 //=======================================================================
1092 bool GHS3DPlugin_Hypothesis::DefaultToCreateNewNodes()
1097 //=======================================================================
1098 //function : DefaultToUseBoundaryRecoveryVersion
1099 //=======================================================================
1101 bool GHS3DPlugin_Hypothesis::DefaultToUseBoundaryRecoveryVersion()
1106 //=======================================================================
1107 //function : DefaultToUseFEMCorrection
1108 //=======================================================================
1110 bool GHS3DPlugin_Hypothesis::DefaultToUseFEMCorrection()
1115 //=======================================================================
1116 //function : DefaultToRemoveCentralPoint
1117 //=======================================================================
1119 bool GHS3DPlugin_Hypothesis::DefaultToRemoveCentralPoint()
1124 //=======================================================================
1125 //function : DefaultStandardOutputLog
1126 //=======================================================================
1128 bool GHS3DPlugin_Hypothesis::DefaultStandardOutputLog()
1133 // //=======================================================================
1134 // //function : DefaultID2SizeMap
1135 // //=======================================================================
1137 // GHS3DPlugin_Hypothesis::TID2SizeMap GHS3DPlugin_Hypothesis::DefaultID2SizeMap()
1139 // return GHS3DPlugin_Hypothesis::TID2SizeMap();
1143 //=======================================================================
1145 //=======================================================================
1147 std::ostream & GHS3DPlugin_Hypothesis::SaveTo(std::ostream & save)
1149 save << (int) myToMeshHoles << " ";
1150 save << myMaximumMemory << " ";
1151 save << myInitialMemory << " ";
1152 save << myOptimizationLevel << " ";
1153 save << myWorkingDirectory << " ";
1154 save << (int)myKeepFiles << " ";
1155 save << myVerboseLevel << " ";
1156 save << (int)myToCreateNewNodes << " ";
1157 save << (int)myToUseBoundaryRecoveryVersion << " ";
1158 save << (int)myToUseFemCorrection << " ";
1159 save << (int)myToRemoveCentralPoint << " ";
1160 save << myGradation << " ";
1161 save << myToMakeGroupsOfDomains << " ";
1162 // if (!myTextOption.empty()) {
1163 // save << "__OPTIONS_BEGIN__ ";
1164 // save << myTextOption << " ";
1165 // save << "__OPTIONS_END__ ";
1169 TGHS3DEnforcedVertexList::iterator it = _enfVertexList.begin();
1170 if (it != _enfVertexList.end()) {
1171 save << " " << "__ENFORCED_VERTICES_BEGIN__ ";
1172 for ( ; it != _enfVertexList.end(); ++it ) {
1173 TGHS3DEnforcedVertex *enfVertex = (*it);
1174 save << " " << "__BEGIN_VERTEX__";
1175 if (!enfVertex->name.empty()) {
1176 save << " " << "__BEGIN_NAME__";
1177 save << " " << enfVertex->name;
1178 save << " " << "__END_NAME__";
1180 if (!enfVertex->geomEntry.empty()) {
1181 save << " " << "__BEGIN_ENTRY__";
1182 save << " " << enfVertex->geomEntry;
1183 save << " " << enfVertex->isCompound;
1184 save << " " << "__END_ENTRY__";
1186 if (!enfVertex->groupName.empty()) {
1187 save << " " << "__BEGIN_GROUP__";
1188 save << " " << enfVertex->groupName;
1189 save << " " << "__END_GROUP__";
1191 if (enfVertex->coords.size()) {
1192 save << " " << "__BEGIN_COORDS__";
1193 for ( size_t i = 0; i < enfVertex->coords.size(); i++ )
1194 save << " " << enfVertex->coords[i];
1195 save << " " << "__END_COORDS__";
1197 save << " " << "__BEGIN_SIZE__";
1198 save << " " << enfVertex->size;
1199 save << " " << "__END_SIZE__";
1200 save << " " << "__END_VERTEX__";
1202 save << " " << "__ENFORCED_VERTICES_END__ ";
1205 TGHS3DEnforcedMeshList::iterator it_mesh = _enfMeshList.begin();
1206 if (it_mesh != _enfMeshList.end()) {
1207 save << " " << "__ENFORCED_MESHES_BEGIN__ ";
1208 for ( ; it_mesh != _enfMeshList.end(); ++it_mesh ) {
1209 TGHS3DEnforcedMesh *enfMesh = (*it_mesh);
1210 save << " " << "__BEGIN_ENF_MESH__";
1212 save << " " << "__BEGIN_NAME__";
1213 save << " " << enfMesh->name;
1214 save << " " << "__END_NAME__";
1216 save << " " << "__BEGIN_ENTRY__";
1217 save << " " << enfMesh->entry;
1218 save << " " << "__END_ENTRY__";
1220 save << " " << "__BEGIN_ELEM_TYPE__";
1221 save << " " << (int)enfMesh->elementType;
1222 save << " " << "__END_ELEM_TYPE__";
1224 if (!enfMesh->groupName.empty()) {
1225 save << " " << "__BEGIN_GROUP__";
1226 save << " " << enfMesh->groupName;
1227 save << " " << "__END_GROUP__";
1229 save << " " << "__PERSIST_ID__";
1230 save << " " << enfMesh->persistID;
1231 save << " " << "__END_ENF_MESH__";
1232 std::cout << "Saving of enforced mesh " << enfMesh->name.c_str() << " done" << std::endl;
1234 save << " " << "__ENFORCED_MESHES_END__ ";
1237 // New options in 2.9.6 (issue #17784)
1239 save << " " << myUseVolumeProximity;
1240 save << " " << myNbVolumeProximityLayers;
1241 save << " " << myMinSize;
1242 save << " " << myMaxSize;
1243 save << " " << myMinSizeDefault;
1244 save << " " << myMaxSizeDefault;
1246 save << " " << _option2value.size();
1247 TOptionValues::iterator o2v = _option2value.begin();
1248 for ( ; o2v != _option2value.end(); ++o2v )
1249 save << " -" << o2v->first << " -" << o2v->second;
1251 save << " " << _customOption2value.size();
1252 for ( o2v = _customOption2value.begin(); o2v != _customOption2value.end(); ++o2v )
1253 save << " -" << o2v->first << " -" << o2v->second;
1258 //=======================================================================
1259 //function : LoadFrom
1260 //=======================================================================
1262 std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load)
1268 isOK = static_cast<bool>(load >> i);
1272 load.clear(ios::badbit | load.rdstate());
1274 isOK = static_cast<bool>(load >> d);
1276 myMaximumMemory = float( d );
1278 load.clear(ios::badbit | load.rdstate());
1280 isOK = static_cast<bool>(load >> d);
1282 myInitialMemory = float( d );
1284 load.clear(ios::badbit | load.rdstate());
1286 isOK = static_cast<bool>(load >> i);
1288 myOptimizationLevel = (short int) i;
1290 load.clear(ios::badbit | load.rdstate());
1292 isOK = static_cast<bool>(load >> myWorkingDirectory);
1294 if ( myWorkingDirectory == "0") { // myWorkingDirectory was empty
1295 myKeepFiles = false;
1296 myWorkingDirectory.clear();
1298 else if ( myWorkingDirectory == "1" ) {
1300 myWorkingDirectory.clear();
1304 load.clear(ios::badbit | load.rdstate());
1306 if ( !myWorkingDirectory.empty() ) {
1307 isOK = static_cast<bool>(load >> i);
1311 load.clear(ios::badbit | load.rdstate());
1314 isOK = static_cast<bool>(load >> i);
1316 myVerboseLevel = (short) i;
1318 load.clear(ios::badbit | load.rdstate());
1320 isOK = static_cast<bool>(load >> i);
1322 myToCreateNewNodes = (bool) i;
1324 load.clear(ios::badbit | load.rdstate());
1326 isOK = static_cast<bool>(load >> i);
1328 myToUseBoundaryRecoveryVersion = (bool) i;
1330 load.clear(ios::badbit | load.rdstate());
1332 isOK = static_cast<bool>(load >> i);
1334 myToUseFemCorrection = (bool) i;
1336 load.clear(ios::badbit | load.rdstate());
1338 isOK = static_cast<bool>(load >> i);
1340 myToRemoveCentralPoint = (bool) i;
1342 load.clear(ios::badbit | load.rdstate());
1344 isOK = static_cast<bool>(load >> d);
1348 load.clear(ios::badbit | load.rdstate());
1350 std::string separator;
1351 bool hasOptions = false;
1352 bool hasEnforcedVertices = false;
1353 bool hasEnforcedMeshes = false;
1354 isOK = static_cast<bool>(load >> separator);
1356 if ( isOK && ( separator == "0" || separator == "1" ))
1358 myToMakeGroupsOfDomains = ( separator == "1" );
1359 isOK = static_cast<bool>(load >> separator);
1363 if (separator == "__OPTIONS_BEGIN__")
1365 else if (separator == "__ENFORCED_VERTICES_BEGIN__")
1366 hasEnforcedVertices = true;
1367 else if (separator == "__ENFORCED_MESHES_BEGIN__")
1368 hasEnforcedMeshes = true;
1374 isOK = static_cast<bool>(load >> txt);
1376 if (txt == "__OPTIONS_END__") {
1377 // if (!myTextOption.empty()) {
1378 // // Remove last space
1379 // myTextOption.erase(myTextOption.end()-1);
1384 // myTextOption += txt;
1385 // myTextOption += " ";
1391 isOK = static_cast<bool>(load >> separator);
1392 if (isOK && separator == "__ENFORCED_VERTICES_BEGIN__")
1393 hasEnforcedVertices = true;
1394 if (isOK && separator == "__ENFORCED_MESHES_BEGIN__")
1395 hasEnforcedMeshes = true;
1398 if (hasEnforcedVertices) {
1399 std::string txt, name, entry, groupName;
1400 double size, coords[3];
1402 bool hasCoords = false;
1403 isOK = static_cast<bool>(load >> txt); // __BEGIN_VERTEX__
1405 if (txt == "__ENFORCED_VERTICES_END__") {
1410 TGHS3DEnforcedVertex *enfVertex = new TGHS3DEnforcedVertex();
1412 isOK = static_cast<bool>(load >> txt);
1413 if (txt == "__END_VERTEX__") {
1414 enfVertex->name = name;
1415 enfVertex->geomEntry = entry;
1416 enfVertex->isCompound = isCompound;
1417 enfVertex->groupName = groupName;
1418 enfVertex->coords.clear();
1420 enfVertex->coords.assign(coords,coords+3);
1422 _enfVertexList.insert(enfVertex);
1424 if (enfVertex->coords.size())
1425 _coordsEnfVertexMap[enfVertex->coords] = enfVertex;
1426 if (!enfVertex->geomEntry.empty())
1427 _geomEntryEnfVertexMap[enfVertex->geomEntry] = enfVertex;
1436 if (txt == "__BEGIN_NAME__") { // __BEGIN_NAME__
1437 while (isOK && (txt != "__END_NAME__")) {
1438 isOK = static_cast<bool>(load >> txt);
1439 if (txt != "__END_NAME__") {
1445 MESSAGE("name: " <<name);
1448 if (txt == "__BEGIN_ENTRY__") { // __BEGIN_ENTRY__
1449 isOK = static_cast<bool>(load >> entry);
1450 isOK = static_cast<bool>(load >> isCompound);
1451 isOK = static_cast<bool>(load >> txt); // __END_ENTRY__
1452 if (txt != "__END_ENTRY__")
1453 throw std::exception();
1454 MESSAGE("entry: " << entry);
1457 if (txt == "__BEGIN_GROUP__") { // __BEGIN_GROUP__
1458 while (isOK && (txt != "__END_GROUP__")) {
1459 isOK = static_cast<bool>(load >> txt);
1460 if (txt != "__END_GROUP__") {
1461 if (!groupName.empty())
1466 MESSAGE("groupName: " << groupName);
1469 if (txt == "__BEGIN_COORDS__") { // __BEGIN_COORDS__
1471 isOK = static_cast<bool>(load >> coords[0] >> coords[1] >> coords[2]);
1472 isOK = static_cast<bool>(load >> txt); // __END_COORDS__
1473 if (txt != "__END_COORDS__")
1474 throw std::exception();
1475 MESSAGE("coords: " << coords[0] <<","<< coords[1] <<","<< coords[2]);
1478 if (txt == "__BEGIN_SIZE__") { // __BEGIN_ENTRY__
1479 isOK = static_cast<bool>(load >> size);
1480 isOK = static_cast<bool>(load >> txt); // __END_ENTRY__
1481 if (txt != "__END_SIZE__") {
1482 throw std::exception();
1484 MESSAGE("size: " << size);
1487 isOK = static_cast<bool>(load >> txt); // __BEGIN_VERTEX__
1491 if (hasEnforcedVertices) {
1492 isOK = static_cast<bool>(load >> separator);
1493 if (isOK && separator == "__ENFORCED_MESHES_BEGIN__")
1494 hasEnforcedMeshes = true;
1497 if (hasEnforcedMeshes) {
1498 std::string txt, name, entry, groupName;
1499 int elementType = -1, persistID = -1;
1500 isOK = static_cast<bool>(load >> txt); // __BEGIN_ENF_MESH__
1503 if (txt == "__ENFORCED_MESHES_END__")
1506 TGHS3DEnforcedMesh *enfMesh = new TGHS3DEnforcedMesh();
1508 isOK = static_cast<bool>(load >> txt);
1509 if (txt == "__END_ENF_MESH__") {
1510 enfMesh->name = name;
1511 enfMesh->entry = entry;
1512 enfMesh->elementType = (SMESH::ElementType)elementType;
1513 enfMesh->groupName = groupName;
1514 enfMesh->persistID = persistID;
1516 _enfMeshList.insert(enfMesh);
1517 //std::cout << "Restoring of enforced mesh " <<name << " done" << std::endl;
1527 if (txt == "__BEGIN_NAME__") { // __BEGIN_NAME__
1528 while (isOK && (txt != "__END_NAME__")) {
1529 isOK = static_cast<bool>(load >> txt);
1530 if (txt != "__END_NAME__") {
1536 MESSAGE("name: " <<name);
1539 if (txt == "__BEGIN_ENTRY__") { // __BEGIN_ENTRY__
1540 isOK = static_cast<bool>(load >> entry);
1541 isOK = static_cast<bool>(load >> txt); // __END_ENTRY__
1542 if (txt != "__END_ENTRY__")
1543 throw std::exception();
1544 MESSAGE("entry: " << entry);
1547 if (txt == "__BEGIN_ELEM_TYPE__") { // __BEGIN_ELEM_TYPE__
1548 isOK = static_cast<bool>(load >> elementType);
1549 isOK = static_cast<bool>(load >> txt); // __END_ELEM_TYPE__
1550 if (txt != "__END_ELEM_TYPE__")
1551 throw std::exception();
1552 MESSAGE("elementType: " << elementType);
1555 if (txt == "__BEGIN_GROUP__") { // __BEGIN_GROUP__
1556 while (isOK && (txt != "__END_GROUP__")) {
1557 isOK = static_cast<bool>(load >> txt);
1558 if (txt != "__END_GROUP__") {
1559 if (!groupName.empty())
1564 MESSAGE("groupName: " << groupName);
1567 if (txt == "__PERSIST_ID__") {
1568 isOK = static_cast<bool>(load >> persistID);
1569 MESSAGE("persistID: " << persistID);
1571 //std::cout << "isOK: " << isOK << std::endl;
1574 isOK = static_cast<bool>(load >> txt); // __BEGIN_ENF_MESH__
1578 // New options in 2.9.6 (issue #17784)
1580 if ( ! hasOptions && ! hasEnforcedVertices && ! hasEnforcedMeshes )
1581 myUseVolumeProximity = ( separator == "1" );
1582 else if ( static_cast<bool>( load >> i ))
1583 myUseVolumeProximity = (bool) i;
1585 if ( static_cast<bool>( load >> myNbVolumeProximityLayers ))
1589 load >> myMinSizeDefault;
1590 load >> myMaxSizeDefault;
1592 std::string option, value;
1593 if ( static_cast<bool>( load >> i ) && i >= 0 )
1595 for ( int nbRead = 0; nbRead < i; ++nbRead )
1597 load >> option >> value;
1598 _option2value[ std::string( option, 1 )] = std::string( value, 1 );
1601 if ( static_cast<bool>( load >> i ) && i >= 0 )
1603 for ( int nbRead = 0; nbRead < i; ++nbRead )
1605 load >> option >> value;
1606 _customOption2value[ std::string( option, 1 )] = std::string( value, 1 );
1614 //=======================================================================
1615 //function : SetParametersByMesh
1616 //=======================================================================
1618 bool GHS3DPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* ,const TopoDS_Shape&)
1624 //================================================================================
1626 * \brief Sets myToMakeGroupsOfDomains depending on whether theMesh is on shape or not
1628 //================================================================================
1630 bool GHS3DPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& dflts,
1631 const SMESH_Mesh* /*theMesh*/)
1633 myToMakeGroupsOfDomains = ( !dflts._shape || dflts._shape->IsNull() );
1635 double diagonal = dflts._elemLength * _gen->GetBoundaryBoxSegmentation();
1636 myMinSizeDefault = 1e-3 * diagonal;
1637 myMaxSizeDefault = diagonal / 5.;
1642 //================================================================================
1644 * \brief Return command to run MG-Tetra mesher excluding file prefix (-f)
1646 //================================================================================
1648 std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* hyp,
1649 const bool hasShapeToMesh,
1650 const bool forExecutable)
1652 std::string cmd = GetExeName();
1653 // check if any option is overridden by hyp->myTextOption
1654 bool max_memory = hyp ? !hyp->HasOptionDefined("max_memory") : true;
1655 bool auto_memory = hyp ? !hyp->HasOptionDefined("automatic_memory") : true;
1656 bool comp = hyp ? !hyp->HasOptionDefined("components") : true;
1657 bool optim_level = hyp ? !hyp->HasOptionDefined("optimisation_level") : true;
1658 bool no_int_points = hyp ? !hyp->HasOptionDefined("no_internal_points") : true;
1659 bool C = hyp ? !hyp->HasOptionDefined("-C") : true;
1660 bool verbose = hyp ? !hyp->HasOptionDefined("verbose") : true;
1661 bool gra = hyp ? !hyp->HasOptionDefined("-Dcpropa") : true;
1662 bool rem = hyp ? !hyp->HasOptionDefined("no_initial_central_point") : true;
1663 //bool fem = hyp ? !hyp->HasOptionDefined("-FEM") : true;
1665 // if use boundary recovery version, few options are allowed
1666 bool useBndRecovery = !C;
1667 if ( !useBndRecovery && hyp )
1668 useBndRecovery = hyp->myToUseBoundaryRecoveryVersion;
1670 // MG-Tetra needs to know amount of memory it may use (MB).
1671 // Default memory is defined at MG-Tetra installation but it may be not enough,
1672 // so allow to use about all available memory
1674 float aMaximumMemory = hyp ? hyp->myMaximumMemory : -1;
1675 cmd += " --max_memory ";
1676 if ( aMaximumMemory < 0 ) cmd += SMESH_Comment( int( DefaultMaximumMemory() ));
1677 else cmd += SMESH_Comment( int( aMaximumMemory ));
1679 if ( auto_memory && !useBndRecovery ) {
1680 float aInitialMemory = hyp ? hyp->myInitialMemory : -1;
1681 cmd += " --automatic_memory ";
1682 if ( aInitialMemory > 0 ) cmd += SMESH_Comment( int( aInitialMemory ));
1685 // component to mesh
1686 if ( comp && !useBndRecovery ) {
1687 // We always run MG-Tetra with "to mesh holes'==TRUE (see PAL19680)
1688 if ( hasShapeToMesh )
1689 cmd += " --components all";
1691 bool aToMeshHoles = hyp ? hyp->myToMeshHoles : DefaultMeshHoles();
1692 if ( aToMeshHoles ) cmd += " --components all";
1693 else cmd += " --components outside_components";
1696 const bool toCreateNewNodes = ( no_int_points && ( !hyp || hyp->myToCreateNewNodes ));
1698 // optimization level
1699 if ( !toCreateNewNodes ) {
1700 cmd += " --optimisation_level none"; // issue 22608
1702 else if ( optim_level && hyp && !useBndRecovery ) {
1703 if ( hyp->myOptimizationLevel >= 0 && hyp->myOptimizationLevel < 5 ) {
1704 const char* level[] = { "none" , "light" , "standard" , "standard+" , "strong" };
1705 cmd += " --optimisation_level ";
1706 cmd += level[ hyp->myOptimizationLevel ];
1710 // to create internal nodes
1711 if ( no_int_points && !toCreateNewNodes ) {
1712 if ( forExecutable )
1713 cmd += " --no_internal_points";
1715 cmd += " --internalpoints no";
1719 if ( verbose && hyp ) {
1720 cmd += " --verbose " + SMESH_Comment( hyp->myVerboseLevel );
1723 // boundary recovery version
1724 // if ( useBndRecovery ) {
1728 // to use FEM correction
1729 // if ( fem && hyp && hyp->myToUseFemCorrection) {
1733 // to remove initial central point.
1734 if ( rem && hyp && hyp->myToRemoveCentralPoint ) {
1735 if ( forExecutable )
1736 cmd += " --no_initial_central_point";
1738 cmd += " --centralpoint no";
1742 // if ( hyp && !hyp->myTextOption.empty() ) {
1743 // cmd += " " + hyp->myTextOption;
1749 if ( hyp->GetMinSize() > 0 )
1750 cmd += " --min_size " + SMESH_Comment( hyp->GetMinSize() );
1751 if ( hyp->GetMaxSize() > 0 )
1752 cmd += " --max_size " + SMESH_Comment( hyp->GetMaxSize() );
1755 // to define volumic gradation.
1758 cmd += " --gradation " + SMESH_Comment( hyp->myGradation );
1764 if ( hyp->GetUseVolumeProximity() )
1766 cmd += " --volume_proximity_layers " + SMESH_Comment( hyp->GetNbVolumeProximityLayers() );
1769 std::string option, value;
1771 const TOptionValues* options[] = { & hyp->_option2value, & hyp->_customOption2value };
1772 for ( int iOp = 0; iOp < 2; ++iOp )
1774 TOptionValues::const_iterator o2v = options[iOp]->begin();
1775 for ( ; o2v != options[iOp]->end(); ++o2v )
1777 option = o2v->first;
1778 value = hyp->GetOptionValue( option, &isDefault );
1782 if ( value.empty() )//value == NoValue() )
1784 if ( hyp->_defaultOptionValues.count( option ))
1785 continue; // non-custom option with no value
1788 if ( strncmp( "no", option.c_str(), 2 ) == 0 ) // options w/o values: --no_*
1790 if ( !value.empty() && ToBool( value ) == false )
1794 if ( option[0] != '-' )
1798 cmd += option + " " + value;
1810 //================================================================================
1812 * \brief Return a unique file name
1814 //================================================================================
1816 std::string GHS3DPlugin_Hypothesis::GetFileName(const GHS3DPlugin_Hypothesis* hyp)
1818 std::string aTmpDir = hyp ? hyp->GetWorkingDirectory() : DefaultWorkingDirectory();
1819 if ( !SMESH_File( aTmpDir ).exists() )
1820 aTmpDir = Kernel_Utils::GetTmpDirByPath( aTmpDir );
1822 const char lastChar = *aTmpDir.rbegin();
1824 if(lastChar != '\\') aTmpDir+='\\';
1826 if(lastChar != '/') aTmpDir+='/';
1829 TCollection_AsciiString aGenericName = (char*)aTmpDir.c_str();
1830 aGenericName += "GHS3D_";
1831 aGenericName += getpid();
1832 aGenericName += "_";
1833 aGenericName += Abs((Standard_Integer)(long) aGenericName.ToCString());
1835 return aGenericName.ToCString();
1838 //================================================================================
1840 * Return the name of executable
1842 //================================================================================
1844 std::string GHS3DPlugin_Hypothesis::GetExeName()
1846 return "mg-tetra.exe";
1849 //================================================================================
1851 * \brief Return the enforced vertices
1853 //================================================================================
1855 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexList GHS3DPlugin_Hypothesis::GetEnforcedVertices(const GHS3DPlugin_Hypothesis* hyp)
1857 return hyp ? hyp->_GetEnforcedVertices(): TGHS3DEnforcedVertexList();
1860 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues GHS3DPlugin_Hypothesis::GetEnforcedVerticesCoordsSize (const GHS3DPlugin_Hypothesis* hyp)
1862 return hyp ? hyp->_GetEnforcedVerticesCoordsSize(): TGHS3DEnforcedVertexCoordsValues();
1865 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexEntryValues GHS3DPlugin_Hypothesis::GetEnforcedVerticesEntrySize (const GHS3DPlugin_Hypothesis* hyp)
1867 return hyp ? hyp->_GetEnforcedVerticesEntrySize(): TGHS3DEnforcedVertexEntryValues();
1870 GHS3DPlugin_Hypothesis::TCoordsGHS3DEnforcedVertexMap GHS3DPlugin_Hypothesis::GetEnforcedVerticesByCoords (const GHS3DPlugin_Hypothesis* hyp)
1872 return hyp ? hyp->_GetEnforcedVerticesByCoords(): TCoordsGHS3DEnforcedVertexMap();
1875 GHS3DPlugin_Hypothesis::TGeomEntryGHS3DEnforcedVertexMap GHS3DPlugin_Hypothesis::GetEnforcedVerticesByEntry (const GHS3DPlugin_Hypothesis* hyp)
1877 return hyp ? hyp->_GetEnforcedVerticesByEntry(): TGeomEntryGHS3DEnforcedVertexMap();
1880 GHS3DPlugin_Hypothesis::TIDSortedNodeGroupMap GHS3DPlugin_Hypothesis::GetEnforcedNodes(const GHS3DPlugin_Hypothesis* hyp)
1882 return hyp ? hyp->_GetEnforcedNodes():TIDSortedNodeGroupMap();
1885 GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap GHS3DPlugin_Hypothesis::GetEnforcedEdges(const GHS3DPlugin_Hypothesis* hyp)
1887 return hyp ? hyp->_GetEnforcedEdges():TIDSortedElemGroupMap();
1890 GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap GHS3DPlugin_Hypothesis::GetEnforcedTriangles(const GHS3DPlugin_Hypothesis* hyp)
1892 return hyp ? hyp->_GetEnforcedTriangles():TIDSortedElemGroupMap();
1895 GHS3DPlugin_Hypothesis::TID2SizeMap GHS3DPlugin_Hypothesis::GetNodeIDToSizeMap(const GHS3DPlugin_Hypothesis* hyp)
1897 return hyp ? hyp->_GetNodeIDToSizeMap(): TID2SizeMap();
1900 GHS3DPlugin_Hypothesis::TSetStrings GHS3DPlugin_Hypothesis::GetGroupsToRemove(const GHS3DPlugin_Hypothesis* hyp)
1902 return hyp ? hyp->_GetGroupsToRemove(): TSetStrings();
1906 //=============================================================================
1907 void GHS3DPlugin_Hypothesis::SetOptionValue(const std::string& optionName,
1908 const std::string& optionValue)
1910 TOptionValues::iterator op_val = _option2value.find(optionName);
1911 if (op_val == _option2value.end())
1913 op_val = _customOption2value.find( optionName );
1914 if ( op_val != _customOption2value.end() && op_val->second != optionValue )
1915 NotifySubMeshesHypothesisModification();
1916 _customOption2value[ optionName ] = optionValue;
1920 if (op_val->second != optionValue)
1922 const char* ptr = optionValue.c_str();
1923 // strip white spaces
1924 while (ptr[0] == ' ')
1926 size_t i = strlen(ptr);
1927 while (i != 0 && ptr[i - 1] == ' ')
1931 std::string typeName;
1934 } else if (_charOptions.count(optionName)) {
1935 // do not check strings
1936 } else if (_doubleOptions.count(optionName)) {
1937 // check if value is double
1938 ToDbl(ptr, &typeOk);
1940 } else if (_boolOptions.count(optionName)) {
1941 // check if value is bool
1942 ToBool(ptr, &typeOk);
1945 // check if value is int
1946 ToInt(ptr, &typeOk);
1947 typeName = "integer";
1949 if ( typeOk ) // check some specific values ?
1954 std::string msg = "Advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName;
1955 throw std::invalid_argument(msg);
1957 std::string value( ptr, i );
1958 if ( _defaultOptionValues[ optionName ] == value )
1961 op_val->second = value;
1963 NotifySubMeshesHypothesisModification();
1967 //=============================================================================
1968 //! Return option value. If isDefault provided, it can be a default value,
1969 // then *isDefault == true. If isDefault is not provided, the value will be
1970 // empty if it equals a default one.
1971 std::string GHS3DPlugin_Hypothesis::GetOptionValue(const std::string& optionName,
1972 bool* isDefault) const
1974 TOptionValues::const_iterator op_val = _option2value.find(optionName);
1975 if (op_val == _option2value.end())
1977 op_val = _customOption2value.find(optionName);
1978 if (op_val == _customOption2value.end())
1980 std::string msg = "Unknown MG-Tetra option: <" + optionName + ">";
1981 throw std::invalid_argument(msg);
1984 std::string val = op_val->second;
1985 if ( isDefault ) *isDefault = ( val.empty() );
1987 if ( val.empty() && isDefault )
1989 op_val = _defaultOptionValues.find( optionName );
1990 if (op_val != _defaultOptionValues.end())
1991 val = op_val->second;
1997 //=============================================================================
1998 bool GHS3DPlugin_Hypothesis::HasOptionDefined( const std::string& optionName ) const
2000 bool isDefault = false;
2003 GetOptionValue( optionName, &isDefault );
2005 catch ( std::invalid_argument& )
2012 //=============================================================================
2013 void GHS3DPlugin_Hypothesis::ClearOption(const std::string& optionName)
2015 TOptionValues::iterator op_val = _customOption2value.find(optionName);
2016 if (op_val != _customOption2value.end())
2017 _customOption2value.erase(op_val);
2019 op_val = _option2value.find(optionName);
2020 if (op_val != _option2value.end())
2021 op_val->second.clear();
2025 //=============================================================================
2026 GHS3DPlugin_Hypothesis::TOptionValues GHS3DPlugin_Hypothesis::GetOptionValues() const
2029 TOptionValues::const_iterator op_val = _option2value.begin();
2030 for ( ; op_val != _option2value.end(); ++op_val )
2031 vals.insert( make_pair( op_val->first, GetOptionValue( op_val->first, GET_DEFAULT() )));
2036 //================================================================================
2038 * \brief Converts a string to a bool
2040 //================================================================================
2042 bool GHS3DPlugin_Hypothesis::ToBool(const std::string& str, bool* isOk )
2044 std::string s = str;
2045 if ( isOk ) *isOk = true;
2047 for ( size_t i = 0; i <= s.size(); ++i )
2048 s[i] = (char) tolower( s[i] );
2050 if ( s == "1" || s == "true" || s == "active" || s == "yes" )
2053 if ( s == "0" || s == "false" || s == "inactive" || s == "no" )
2059 std::string msg = "Not a Boolean value:'" + str + "'";
2060 throw std::invalid_argument(msg);
2065 //================================================================================
2067 * \brief Converts a string to a real value
2069 //================================================================================
2071 double GHS3DPlugin_Hypothesis::ToDbl(const std::string& str, bool* isOk )
2073 if ( str.empty() ) throw std::invalid_argument("Empty value provided");
2076 double val = strtod(&str[0], &endPtr);
2077 bool ok = (&str[0] != endPtr);
2079 if ( isOk ) *isOk = ok;
2083 std::string msg = "Not a real value:'" + str + "'";
2084 throw std::invalid_argument(msg);
2089 //================================================================================
2091 * \brief Converts a string to a integer value
2093 //================================================================================
2095 int GHS3DPlugin_Hypothesis::ToInt(const std::string& str, bool* isOk )
2097 if ( str.empty() ) throw std::invalid_argument("Empty value provided");
2100 int val = (int)strtol( &str[0], &endPtr, 10);
2101 bool ok = (&str[0] != endPtr);
2103 if ( isOk ) *isOk = ok;
2107 std::string msg = "Not an integer value:'" + str + "'";
2108 throw std::invalid_argument(msg);