1 // Copyright (C) 2007-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
21 // File : BLSURFPlugin_Hypothesis.cxx
22 // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) & Lioka RAZAFINDRAZAKA (CEA)
23 // & Aurelien ALLEAUME (DISTENE)
24 // Size maps development: Nicolas GEIMER (OCC) & Gilles DAVID (EURIWARE)
27 #include "BLSURFPlugin_Hypothesis.hxx"
28 #include "BLSURFPlugin_Attractor.hxx"
30 #include <SMESHDS_Group.hxx>
31 #include <SMESHDS_Mesh.hxx>
32 #include <SMESH_BoostTxtArchive.hxx>
33 #include <SMESH_Gen_i.hxx>
34 #include <SMESH_Group.hxx>
35 #include <SMESH_TryCatch.hxx>
37 #include <Basics_Utils.hxx>
38 #include <utilities.h>
41 #include <ShapeAnalysis.hxx>
44 #include CORBA_CLIENT_HEADER(SALOMEDS)
45 #include CORBA_CLIENT_HEADER(GEOM_Gen)
47 #include <meshgems/meshgems.h>
48 #define MESHGEMS_VERSION_HEX (MESHGEMS_VERSION_MAJOR << 16 | MESHGEMS_VERSION_MINOR << 8 | MESHGEMS_VERSION_PATCH)
50 #include <boost/archive/text_oarchive.hpp>
51 #include <boost/serialization/set.hpp>
52 #include <boost/serialization/vector.hpp>
53 #include <boost/serialization/string.hpp>
57 struct GET_DEFAULT // struct used to get default value from GetOptionValue()
60 operator bool* () { return &isDefault; }
64 //=============================================================================
65 BLSURFPlugin_Hypothesis::BLSURFPlugin_Hypothesis(int hypId, SMESH_Gen * gen, bool hasgeom) :
66 SMESH_Hypothesis(hypId, gen),
67 _physicalMesh(GetDefaultPhysicalMesh()),
68 _geometricMesh(GetDefaultGeometricMesh()),
69 _phySize(GetDefaultPhySize()),
70 _phySizeRel(GetDefaultPhySizeRel()),
71 _minSize(GetDefaultMinSize()),
72 _maxSize(GetDefaultMaxSize()),
73 _minSizeRel(GetDefaultMinSizeRel()),
74 _maxSizeRel(GetDefaultMaxSizeRel()),
75 _useGradation(GetDefaultUseGradation()),
76 _gradation(GetDefaultGradation()),
77 _useVolumeGradation(GetDefaultUseVolumeGradation()),
78 _volumeGradation(GetDefaultVolumeGradation()),
79 _elementType(GetDefaultElementType()),
80 _angleMesh(GetDefaultAngleMesh()),
81 _chordalError(GetDefaultChordalError()),
82 _anisotropic(GetDefaultAnisotropic()),
83 _anisotropicRatio(GetDefaultAnisotropicRatio()),
84 _removeTinyEdges(GetDefaultRemoveTinyEdges()),
85 _tinyEdgeLength(GetDefaultTinyEdgeLength()),
86 _optimiseTinyEdges(GetDefaultOptimiseTinyEdges()),
87 _tinyEdgeOptimisationLength(GetDefaultTinyEdgeOptimisationLength()),
88 _correctSurfaceIntersec(GetDefaultCorrectSurfaceIntersection()),
89 _corrSurfaceIntersCost(GetDefaultCorrectSurfaceIntersectionMaxCost()),
90 _badElementRemoval(GetDefaultBadElementRemoval()),
91 _badElementAspectRatio(GetDefaultBadElementAspectRatio()),
92 _optimizeMesh(GetDefaultOptimizeMesh()),
93 _quadraticMesh(GetDefaultQuadraticMesh()),
94 _verb(GetDefaultVerbosity()),
95 _topology(GetDefaultTopology()),
96 _useSurfaceProximity(GetDefaultUseSurfaceProximity()),
97 _nbSurfaceProximityLayers(GetDefaultNbSurfaceProximityLayers()),
98 _surfaceProximityRatio(GetDefaultSurfaceProximityRatio()),
99 _useVolumeProximity(GetDefaultUseVolumeProximity()),
100 _nbVolumeProximityLayers(GetDefaultNbVolumeProximityLayers()),
101 _volumeProximityRatio(GetDefaultVolumeProximityRatio()),
102 _preCADMergeEdges(GetDefaultPreCADMergeEdges()),
103 _preCADRemoveDuplicateCADFaces(GetDefaultPreCADRemoveDuplicateCADFaces()),
104 _preCADProcess3DTopology(GetDefaultPreCADProcess3DTopology()),
105 _preCADDiscardInput(GetDefaultPreCADDiscardInput()),
106 _sizeMap(GetDefaultSizeMap()),
107 _attractors(GetDefaultSizeMap()),
108 _classAttractors(GetDefaultAttractorMap()),
109 _faceEntryEnfVertexListMap(GetDefaultFaceEntryEnfVertexListMap()),
110 _enfVertexList(GetDefaultEnfVertexList()),
111 _faceEntryCoordsListMap(GetDefaultFaceEntryCoordsListMap()),
112 _coordsEnfVertexMap(GetDefaultCoordsEnfVertexMap()),
113 _faceEntryEnfVertexEntryListMap(GetDefaultFaceEntryEnfVertexEntryListMap()),
114 _enfVertexEntryEnfVertexMap(GetDefaultEnfVertexEntryEnfVertexMap()),
115 _groupNameNodeIDMap(GetDefaultGroupNameNodeIDMap()),
116 _enforcedInternalVerticesAllFaces(GetDefaultInternalEnforcedVertex()),
117 _preCadFacesPeriodicityVector(GetDefaultPreCadFacesPeriodicityVector()),
118 _preCadEdgesPeriodicityVector(GetDefaultPreCadEdgesPeriodicityVector()),
119 _GMFFileName(GetDefaultGMFFile())
121 _name = GetHypType(hasgeom);
124 // Advanced options with their defaults according to MG User Manual
126 const char* boolOptionNames[] = {
127 #if MESHGEMS_VERSION_HEX < 0x020A00
128 "enforce_cad_edge_sizes", // default = 0 // Deprecated since MeshGems 2.10
130 "jacobian_rectification_respect_geometry", // default = 1
131 "rectify_jacobian", // default = 1
132 "respect_geometry", // default = 1
133 "tiny_edge_avoid_surface_intersections", // default = 1
134 "debug", // default = 0
135 "allow_patch_independent", // false
139 const char* intOptionNames[] = {
140 #if MESHGEMS_VERSION_HEX < 0x020A00
141 "max_number_of_points_per_patch", // default = 100000 // Deprecated since MeshGems 2.10
143 "max_number_of_threads", // default = 4
146 const char* doubleOptionNames[] = { // "surface_intersections_processing_max_cost",// default = 15
147 // "periodic_tolerance", // default = diag/100
148 // "volume_gradation",
149 // "tiny_edge_optimisation_length", // default = diag * 1e-6
152 const char* charOptionNames[] = { // "required_entities", // default = "respect"
153 // "tags", // default = "respect"
157 // PreCAD advanced options
158 const char* preCADboolOptionNames[] = { "closed_geometry", // default = 0
159 "discard_input_topology", // default = 0
160 "merge_edges", // default = = 1
161 "remove_duplicate_cad_faces", // default = 1
162 // "create_tag_on_collision", // default = 1
163 "process_3d_topology", // default = 1
164 // "remove_tiny_edges", // default = 0
165 // remove_tiny_uv_edges option is not documented
166 // but it is useful that the user can change it to disable all preprocessing options
167 "remove_tiny_uv_edges", // default = 1
168 "compute_ridges", // true
171 const char* preCADintOptionNames[] = { // "manifold_geometry", // default = 0
174 const char* preCADdoubleOptionNames[] = { "periodic_tolerance", // default = diag * 1e-5
175 "sewing_tolerance", // default = diag * 5e-4
176 // "tiny_edge_length", // default = diag * 1e-5
179 const char* preCADcharOptionNames[] = { "required_entities", // default = "respect"
180 "tags", // default = "respect"
185 while (boolOptionNames[i][0])
187 _boolOptions.insert( boolOptionNames[i] );
188 _option2value[boolOptionNames[i++]].clear();
191 while (preCADboolOptionNames[i][0] && hasgeom)
193 _boolOptions.insert( preCADboolOptionNames[i] );
194 _preCADoption2value[preCADboolOptionNames[i++]].clear();
197 while (intOptionNames[i][0])
198 _option2value[intOptionNames[i++]].clear();
201 while (preCADintOptionNames[i][0] && hasgeom)
202 _preCADoption2value[preCADintOptionNames[i++]].clear();
205 while (doubleOptionNames[i][0]) {
206 _doubleOptions.insert(doubleOptionNames[i]);
207 _option2value[doubleOptionNames[i++]].clear();
210 while (preCADdoubleOptionNames[i][0] && hasgeom) {
211 _preCADdoubleOptions.insert(preCADdoubleOptionNames[i]);
212 _preCADoption2value[preCADdoubleOptionNames[i++]].clear();
215 while (charOptionNames[i][0]) {
216 _charOptions.insert(charOptionNames[i]);
217 _option2value[charOptionNames[i++]].clear();
220 while (preCADcharOptionNames[i][0] && hasgeom) {
221 _preCADcharOptions.insert(preCADcharOptionNames[i]);
222 _preCADoption2value[preCADcharOptionNames[i++]].clear();
225 // default values to be used while MG meshing
227 #if MESHGEMS_VERSION_HEX < 0x020A00
228 _defaultOptionValues["enforce_cad_edge_sizes" ] = "no"; // Deprecated since MeshGems 2.10
230 _defaultOptionValues["jacobian_rectification_respect_geometry"] = "yes";
231 #if MESHGEMS_VERSION_HEX < 0x020A00
232 _defaultOptionValues["max_number_of_points_per_patch" ] = "0"; // Deprecated since MeshGems 2.10
234 _defaultOptionValues["max_number_of_threads" ] = "4";
235 _defaultOptionValues["rectify_jacobian" ] = "yes";
236 _defaultOptionValues["respect_geometry" ] = "yes";
237 _defaultOptionValues["tiny_edge_avoid_surface_intersections" ] = "yes";
238 //_defaultOptionValues["use_deprecated_patch_mesher" ] = "no";
239 _defaultOptionValues["debug" ] = "no";
240 _defaultOptionValues["allow_patch_independent" ] = "no";
243 _defaultOptionValues["closed_geometry" ] = "no";
244 _defaultOptionValues["discard_input_topology" ] = "no";
245 _defaultOptionValues["merge_edges" ] = "no";
246 _defaultOptionValues["periodic_tolerance" ] = "1e-5*D";
247 _defaultOptionValues["process_3d_topology" ] = "no";
248 _defaultOptionValues["remove_duplicate_cad_faces" ] = "no";
249 _defaultOptionValues["remove_tiny_uv_edges" ] = "no";
250 _defaultOptionValues["required_entities" ] = "respect";
251 _defaultOptionValues["sewing_tolerance" ] = "5e-4*D";
252 _defaultOptionValues["tags" ] = "respect";
253 _defaultOptionValues["compute_ridges" ] = "yes";
256 if ( MESHGEMS_VERSION_HEX < 0x020906 )
258 std::string missingOption = "allow_patch_independent";
259 _defaultOptionValues.erase( missingOption );
260 _boolOptions.erase( missingOption );
261 _option2value.erase( missingOption );
265 // check validity of option names of _defaultOptionValues
266 TOptionValues::iterator n2v = _defaultOptionValues.begin();
267 for ( ; n2v != _defaultOptionValues.end(); ++n2v )
268 ASSERT( _option2value.count( n2v->first ) || _preCADoption2value.count( n2v->first ));
269 ASSERT( _option2value.size() + _preCADoption2value.size() == _defaultOptionValues.size() );
274 TopoDS_Shape BLSURFPlugin_Hypothesis::entryToShape(std::string entry)
276 GEOM::GEOM_Object_var aGeomObj;
278 TopoDS_Shape S = TopoDS_Shape();
279 SALOMEDS::SObject_var aSObj = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectID( entry.c_str() );
280 if (!aSObj->_is_nil() ) {
281 CORBA::Object_var obj = aSObj->GetObject();
282 aGeomObj = GEOM::GEOM_Object::_narrow(obj);
285 if ( !aGeomObj->_is_nil() )
286 S = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( aGeomObj.in() );
290 //=============================================================================
291 std::string BLSURFPlugin_Hypothesis::GetMeshGemsVersion()
293 return MESHGEMS_VERSION_LONG;
296 //=============================================================================
297 void BLSURFPlugin_Hypothesis::SetPhysicalMesh(PhysicalMesh thePhysicalMesh)
299 if (thePhysicalMesh != _physicalMesh) {
300 _physicalMesh = thePhysicalMesh;
301 NotifySubMeshesHypothesisModification();
305 //=============================================================================
306 void BLSURFPlugin_Hypothesis::SetGeometricMesh(GeometricMesh theGeometricMesh)
308 if (theGeometricMesh != _geometricMesh) {
309 _geometricMesh = theGeometricMesh;
310 // switch (_geometricMesh) {
313 // _angleMesh = GetDefaultAngleMesh();
314 // _gradation = GetDefaultGradation();
317 NotifySubMeshesHypothesisModification();
321 //=============================================================================
322 void BLSURFPlugin_Hypothesis::SetPhySize(double theVal, bool isRelative)
324 if ((theVal != _phySize) || (isRelative != _phySizeRel)) {
325 _phySizeRel = isRelative;
327 _phySize = GetMaxSize();
331 NotifySubMeshesHypothesisModification();
335 //=============================================================================
336 void BLSURFPlugin_Hypothesis::SetMinSize(double theMinSize, bool isRelative)
338 if ((theMinSize != _minSize) || (isRelative != _minSizeRel)) {
339 _minSizeRel = isRelative;
340 _minSize = theMinSize;
341 NotifySubMeshesHypothesisModification();
345 //=============================================================================
346 void BLSURFPlugin_Hypothesis::SetMaxSize(double theMaxSize, bool isRelative)
348 if ((theMaxSize != _maxSize) || (isRelative != _maxSizeRel)) {
349 _maxSizeRel = isRelative;
350 _maxSize = theMaxSize;
351 NotifySubMeshesHypothesisModification();
355 //=============================================================================
356 void BLSURFPlugin_Hypothesis::SetUseGradation(bool theVal)
358 if (theVal != _useGradation) {
359 _useGradation = theVal;
360 NotifySubMeshesHypothesisModification();
364 //=============================================================================
365 void BLSURFPlugin_Hypothesis::SetGradation(double theVal)
367 _useGradation = ( theVal > 0 );
368 if (theVal != _gradation) {
370 NotifySubMeshesHypothesisModification();
374 //=============================================================================
375 void BLSURFPlugin_Hypothesis::SetUseVolumeGradation(bool theVal)
377 if (theVal != _useVolumeGradation) {
378 _useVolumeGradation = theVal;
379 NotifySubMeshesHypothesisModification();
383 //=============================================================================
384 void BLSURFPlugin_Hypothesis::SetVolumeGradation(double theVal)
386 _useVolumeGradation = ( theVal > 0 );
387 if (theVal != _volumeGradation) {
388 _volumeGradation = theVal;
389 NotifySubMeshesHypothesisModification();
393 //=============================================================================
394 void BLSURFPlugin_Hypothesis::SetElementType(ElementType theElementType)
396 if (theElementType != _elementType) {
397 _elementType = theElementType;
398 NotifySubMeshesHypothesisModification();
402 //=============================================================================
403 void BLSURFPlugin_Hypothesis::SetAngleMesh(double theVal)
405 if (theVal != _angleMesh) {
407 NotifySubMeshesHypothesisModification();
411 //=============================================================================
412 void BLSURFPlugin_Hypothesis::SetChordalError(double theDistance)
414 if (theDistance != _chordalError) {
415 _chordalError = theDistance;
416 NotifySubMeshesHypothesisModification();
420 //=============================================================================
421 void BLSURFPlugin_Hypothesis::SetAnisotropic(bool theVal)
423 if (theVal != _anisotropic) {
424 _anisotropic = theVal;
425 NotifySubMeshesHypothesisModification();
429 //=============================================================================
430 void BLSURFPlugin_Hypothesis::SetAnisotropicRatio(double theVal)
432 if (theVal != _anisotropicRatio) {
433 _anisotropicRatio = theVal;
434 NotifySubMeshesHypothesisModification();
438 //=============================================================================
439 void BLSURFPlugin_Hypothesis::SetRemoveTinyEdges(bool theVal)
441 if (theVal != _removeTinyEdges) {
442 _removeTinyEdges = theVal;
443 NotifySubMeshesHypothesisModification();
447 //=============================================================================
448 void BLSURFPlugin_Hypothesis::SetTinyEdgeLength(double theVal)
450 if (theVal != _tinyEdgeLength) {
451 _tinyEdgeLength = theVal;
452 NotifySubMeshesHypothesisModification();
456 //=============================================================================
457 void BLSURFPlugin_Hypothesis::SetOptimiseTinyEdges(bool theVal)
459 if (theVal != _optimiseTinyEdges) {
460 _optimiseTinyEdges = theVal;
461 NotifySubMeshesHypothesisModification();
465 //=============================================================================
466 void BLSURFPlugin_Hypothesis::SetTinyEdgeOptimisationLength(double theVal)
468 if (theVal != _tinyEdgeOptimisationLength) {
469 _tinyEdgeOptimisationLength = theVal;
470 NotifySubMeshesHypothesisModification();
474 //=============================================================================
475 void BLSURFPlugin_Hypothesis::SetCorrectSurfaceIntersection(bool theVal)
477 if (theVal != _correctSurfaceIntersec) {
478 _correctSurfaceIntersec = theVal;
479 NotifySubMeshesHypothesisModification();
483 //=============================================================================
484 void BLSURFPlugin_Hypothesis::SetCorrectSurfaceIntersectionMaxCost(double theVal)
486 if (theVal != _corrSurfaceIntersCost) {
487 _corrSurfaceIntersCost = theVal;
488 NotifySubMeshesHypothesisModification();
492 //=============================================================================
493 void BLSURFPlugin_Hypothesis::SetBadElementRemoval(bool theVal)
495 if (theVal != _badElementRemoval) {
496 _badElementRemoval = theVal;
497 NotifySubMeshesHypothesisModification();
501 //=============================================================================
502 void BLSURFPlugin_Hypothesis::SetBadElementAspectRatio(double theVal)
504 if (theVal != _badElementAspectRatio) {
505 _badElementAspectRatio = theVal;
506 NotifySubMeshesHypothesisModification();
510 //=============================================================================
511 void BLSURFPlugin_Hypothesis::SetOptimizeMesh(bool theVal)
513 if (theVal != _optimizeMesh) {
514 _optimizeMesh = theVal;
515 NotifySubMeshesHypothesisModification();
519 //=============================================================================
520 void BLSURFPlugin_Hypothesis::SetQuadraticMesh(bool theVal)
522 if (theVal != _quadraticMesh) {
523 _quadraticMesh = theVal;
524 NotifySubMeshesHypothesisModification();
528 //=============================================================================
529 void BLSURFPlugin_Hypothesis::SetTopology(Topology theTopology)
531 if (theTopology != _topology) {
532 _topology = theTopology;
533 NotifySubMeshesHypothesisModification();
537 //=============================================================================
538 void BLSURFPlugin_Hypothesis::SetUseSurfaceProximity( bool toUse )
540 if ( _useSurfaceProximity != toUse )
542 _useSurfaceProximity = toUse;
543 NotifySubMeshesHypothesisModification();
547 //=============================================================================
548 void BLSURFPlugin_Hypothesis::SetNbSurfaceProximityLayers( int nbLayers )
550 if ( _nbSurfaceProximityLayers != nbLayers )
552 _nbSurfaceProximityLayers = nbLayers;
553 NotifySubMeshesHypothesisModification();
557 //=============================================================================
558 void BLSURFPlugin_Hypothesis::SetSurfaceProximityRatio( double ratio )
560 if ( _surfaceProximityRatio != ratio )
562 _surfaceProximityRatio = ratio;
563 NotifySubMeshesHypothesisModification();
567 //=============================================================================
568 void BLSURFPlugin_Hypothesis::SetUseVolumeProximity( bool toUse )
570 if ( _useVolumeProximity != toUse )
572 _useVolumeProximity = toUse;
573 NotifySubMeshesHypothesisModification();
577 //=============================================================================
578 void BLSURFPlugin_Hypothesis::SetNbVolumeProximityLayers( int nbLayers )
580 if ( _nbVolumeProximityLayers != nbLayers )
582 _nbVolumeProximityLayers = nbLayers;
583 NotifySubMeshesHypothesisModification();
587 //=============================================================================
588 void BLSURFPlugin_Hypothesis::SetVolumeProximityRatio( double ratio )
590 if ( _volumeProximityRatio != ratio )
592 _volumeProximityRatio = ratio;
593 NotifySubMeshesHypothesisModification();
597 //=============================================================================
598 void BLSURFPlugin_Hypothesis::SetVerbosity(int theVal) {
599 if (theVal != _verb) {
601 NotifySubMeshesHypothesisModification();
605 //=============================================================================
606 void BLSURFPlugin_Hypothesis::SetEnforceCadEdgesSize( bool toEnforce )
608 #if MESHGEMS_VERSION_HEX < 0x020A00
609 // Deprecated since MeshGems 2.10
610 if ( GetEnforceCadEdgesSize() != toEnforce )
612 SetOptionValue( "enforce_cad_edge_sizes", toEnforce ? "yes" : "no" );
613 NotifySubMeshesHypothesisModification();
616 (void)toEnforce; // maybe unused
619 //=============================================================================
620 bool BLSURFPlugin_Hypothesis::GetEnforceCadEdgesSize()
622 #if MESHGEMS_VERSION_HEX < 0x020A00
623 // Deprecated since MeshGems 2.10
624 return ToBool( GetOptionValue( "enforce_cad_edge_sizes" ), GET_DEFAULT() );
629 //=============================================================================
631 void BLSURFPlugin_Hypothesis::SetJacobianRectificationRespectGeometry( bool allowRectification )
633 if ( GetJacobianRectificationRespectGeometry() != allowRectification )
635 SetOptionValue("jacobian_rectification_respect_geometry", allowRectification ? "yes" : "no" );
636 NotifySubMeshesHypothesisModification();
639 //=============================================================================
640 bool BLSURFPlugin_Hypothesis::GetJacobianRectificationRespectGeometry()
642 return ToBool( GetOptionValue("jacobian_rectification_respect_geometry", GET_DEFAULT()));
644 //=============================================================================
646 void BLSURFPlugin_Hypothesis::SetJacobianRectification( bool allowRectification )
648 if ( GetJacobianRectification() != allowRectification )
650 SetOptionValue( "rectify_jacobian", allowRectification ? "yes" : "no" );
651 NotifySubMeshesHypothesisModification();
654 //=============================================================================
655 bool BLSURFPlugin_Hypothesis::GetJacobianRectification()
657 return ToBool( GetOptionValue("rectify_jacobian", GET_DEFAULT()));
659 //=============================================================================
661 void BLSURFPlugin_Hypothesis::SetUseDeprecatedPatchMesher( bool /*useDeprecatedPatchMesher*/ )
663 // if ( GetUseDeprecatedPatchMesher() != useDeprecatedPatchMesher )
665 // SetOptionValue( "use_deprecated_patch_mesher", useDeprecatedPatchMesher ? "yes" : "no" );
666 // NotifySubMeshesHypothesisModification();
669 //=============================================================================
670 bool BLSURFPlugin_Hypothesis::GetUseDeprecatedPatchMesher()
672 return false;//ToBool( GetOptionValue("use_deprecated_patch_mesher", GET_DEFAULT()));
674 //=============================================================================
676 void BLSURFPlugin_Hypothesis::SetMaxNumberOfPointsPerPatch( int nb )
678 #if MESHGEMS_VERSION_HEX < 0x020A00
679 // Deprecated since MeshGems 2.10
681 throw std::invalid_argument( SMESH_Comment("Invalid number of points: ") << nb );
683 if ( GetMaxNumberOfPointsPerPatch() != nb )
685 SetOptionValue("max_number_of_points_per_patch", SMESH_Comment( nb ));
686 NotifySubMeshesHypothesisModification();
689 (void)nb; // maybe unused
692 //=============================================================================
693 int BLSURFPlugin_Hypothesis::GetMaxNumberOfPointsPerPatch()
695 #if MESHGEMS_VERSION_HEX < 0x020A00
696 // Deprecated since MeshGems 2.10
697 return ToInt( GetOptionValue("max_number_of_points_per_patch", GET_DEFAULT()));
702 //=============================================================================
704 void BLSURFPlugin_Hypothesis::SetMaxNumberOfThreads( int nb )
707 throw std::invalid_argument( SMESH_Comment("Invalid number of threads: ") << nb );
709 if ( GetMaxNumberOfThreads() != nb )
711 SetOptionValue("max_number_of_threads", SMESH_Comment( nb ));
712 NotifySubMeshesHypothesisModification();
715 //=============================================================================
716 int BLSURFPlugin_Hypothesis::GetMaxNumberOfThreads()
718 return ToInt( GetOptionValue("max_number_of_threads", GET_DEFAULT()));
720 //=============================================================================
722 void BLSURFPlugin_Hypothesis::SetRespectGeometry( bool toRespect )
724 if ( GetRespectGeometry() != toRespect )
726 SetOptionValue("respect_geometry", toRespect ? "yes" : "no" );
727 NotifySubMeshesHypothesisModification();
730 //=============================================================================
731 bool BLSURFPlugin_Hypothesis::GetRespectGeometry()
733 return ToBool( GetOptionValue( "respect_geometry", GET_DEFAULT()));
735 //=============================================================================
737 void BLSURFPlugin_Hypothesis::SetTinyEdgesAvoidSurfaceIntersections( bool toAvoidIntersection )
739 if ( GetTinyEdgesAvoidSurfaceIntersections() != toAvoidIntersection )
741 SetOptionValue("tiny_edge_avoid_surface_intersections", toAvoidIntersection ? "yes" : "no" );
742 NotifySubMeshesHypothesisModification();
745 //=============================================================================
746 bool BLSURFPlugin_Hypothesis::GetTinyEdgesAvoidSurfaceIntersections()
748 return ToBool( GetOptionValue("tiny_edge_avoid_surface_intersections", GET_DEFAULT()));
750 //=============================================================================
752 void BLSURFPlugin_Hypothesis::SetClosedGeometry( bool isClosed )
754 if ( GetClosedGeometry() != isClosed )
756 SetPreCADOptionValue("closed_geometry", isClosed ? "yes" : "no" );
757 NotifySubMeshesHypothesisModification();
760 //=============================================================================
761 bool BLSURFPlugin_Hypothesis::GetClosedGeometry()
763 return ToBool( GetPreCADOptionValue( "closed_geometry", GET_DEFAULT()));
765 //=============================================================================
767 void BLSURFPlugin_Hypothesis::SetDebug( bool isDebug )
769 if ( GetDebug() != isDebug )
771 SetPreCADOptionValue("debug", isDebug ? "yes" : "no" );
772 NotifySubMeshesHypothesisModification();
775 //=============================================================================
776 bool BLSURFPlugin_Hypothesis::GetDebug()
778 return ToBool( GetPreCADOptionValue("debug", GET_DEFAULT()));
780 //=============================================================================
782 void BLSURFPlugin_Hypothesis::SetPeriodicTolerance( CORBA::Double tol )
785 throw std::invalid_argument( SMESH_Comment("Invalid tolerance: ") << tol );
786 if ( GetPeriodicTolerance() != tol )
788 SetPreCADOptionValue("periodic_tolerance", SMESH_Comment( tol ) );
789 NotifySubMeshesHypothesisModification();
792 //=============================================================================
793 double BLSURFPlugin_Hypothesis::GetPeriodicTolerance()
795 return ToDbl( GetPreCADOptionValue( "periodic_tolerance", GET_DEFAULT()));
797 //=============================================================================
799 void BLSURFPlugin_Hypothesis::SetRequiredEntities( const std::string& howToTreat )
801 if ( howToTreat != "respect" && howToTreat != "ignore" && howToTreat != "clear" )
802 throw std::invalid_argument
803 ( SMESH_Comment("required_entities must be in ['respect','ignore','clear'] "));
805 if ( GetRequiredEntities() != howToTreat )
807 SetPreCADOptionValue("required_entities", howToTreat );
808 NotifySubMeshesHypothesisModification();
811 //=============================================================================
812 std::string BLSURFPlugin_Hypothesis::GetRequiredEntities()
814 return GetPreCADOptionValue("required_entities", GET_DEFAULT());
816 //=============================================================================
818 void BLSURFPlugin_Hypothesis::SetSewingTolerance( CORBA::Double tol )
821 throw std::invalid_argument( SMESH_Comment("Invalid tolerance: ") << tol );
822 if ( GetSewingTolerance() != tol )
824 SetPreCADOptionValue("sewing_tolerance", SMESH_Comment( tol ) );
825 NotifySubMeshesHypothesisModification();
828 //=============================================================================
829 CORBA::Double BLSURFPlugin_Hypothesis::GetSewingTolerance()
831 return ToDbl( GetPreCADOptionValue("sewing_tolerance", GET_DEFAULT()));
833 //=============================================================================
835 void BLSURFPlugin_Hypothesis::SetTags( const std::string& howToTreat )
837 if ( howToTreat != "respect" && howToTreat != "ignore" && howToTreat != "clear" )
838 throw std::invalid_argument
839 ( SMESH_Comment("'tags' must be in ['respect','ignore','clear'] "));
841 if ( GetTags() != howToTreat )
843 SetPreCADOptionValue("tags", howToTreat );
844 NotifySubMeshesHypothesisModification();
847 //=============================================================================
848 std::string BLSURFPlugin_Hypothesis::GetTags()
850 return GetPreCADOptionValue("tags", GET_DEFAULT());
853 //=============================================================================
854 void BLSURFPlugin_Hypothesis::SetHyperPatches(const THyperPatchList& hpl, bool notifyMesh)
856 if ( hpl != _hyperPatchList )
858 // join patches sharing tags
859 _hyperPatchList.clear();
860 for ( size_t i = 0; i < hpl.size(); ++i )
862 const THyperPatchTags& tags = hpl[i];
863 if ( tags.size() < 2 ) continue;
865 std::set<int> iPatches;
866 if ( !_hyperPatchList.empty() )
868 THyperPatchTags::iterator t = tags.begin();
869 for ( ; t != tags.end(); ++t )
872 GetHyperPatchTag( *t, this, &iPatch );
874 iPatches.insert( iPatch );
878 if ( iPatches.empty() )
880 _hyperPatchList.push_back( tags );
884 std::set<int>::iterator iPatch = iPatches.begin();
885 THyperPatchTags& mainPatch = _hyperPatchList[ *iPatch ];
886 mainPatch.insert( tags.begin(), tags.end() );
888 for ( ++iPatch; iPatch != iPatches.end(); ++iPatch )
890 mainPatch.insert( _hyperPatchList[ *iPatch ].begin(), _hyperPatchList[ *iPatch ].end() );
891 _hyperPatchList[ *iPatch ].clear();
893 if ( iPatches.size() > 1 )
894 for ( int j = (int) _hyperPatchList.size()-1; j > 0; --j )
895 if ( _hyperPatchList[j].empty() )
896 _hyperPatchList.erase( _hyperPatchList.begin() + j );
900 NotifySubMeshesHypothesisModification();
903 //=============================================================================
904 void BLSURFPlugin_Hypothesis::SetHyperPatches(const THyperPatchEntriesList& hpel)
906 if ( hpel != _hyperPatchEntriesList )
908 _hyperPatchEntriesList = hpel;
909 _hyperPatchList.clear();
911 NotifySubMeshesHypothesisModification();
914 //================================================================================
916 * \brief Set _hyperPatchList by _hyperPatchEntriesList
918 //================================================================================
920 void BLSURFPlugin_Hypothesis::
921 SetHyperPatchIDsByEntry( const TopoDS_Shape& mainShape,
922 const std::map< std::string, TopoDS_Shape >& entryToShape)
924 _hyperPatchList.clear();
925 if ( _hyperPatchEntriesList.empty() || mainShape.IsNull() )
928 _hyperPatchList.resize( _hyperPatchEntriesList.size() );
930 TopTools_IndexedMapOfShape shapeMap;
931 TopExp::MapShapes( mainShape, shapeMap );
933 for ( size_t i = 0; i < _hyperPatchEntriesList.size(); ++i )
935 THyperPatchTags & idsList = _hyperPatchList [ i ];
936 const THyperPatchEntries & entryList = _hyperPatchEntriesList[ i ];
937 for ( const std::string & entry : entryList )
939 auto e2sIt = entryToShape.find( entry );
940 if ( e2sIt != entryToShape.end() )
942 for ( TopExp_Explorer fExp( e2sIt->second, TopAbs_FACE ); fExp.More(); fExp.Next() )
944 int id = shapeMap.FindIndex( fExp.Current() );
946 idsList.insert( id );
952 hpl.swap( _hyperPatchList );
953 SetHyperPatches( hpl, /*notifyMesh=*/false );
956 //=============================================================================
958 * \brief Return a tag of a face taking into account the hyper-patches. Optionally
959 * return an index of a patch including the face
961 //================================================================================
963 int BLSURFPlugin_Hypothesis::GetHyperPatchTag( const int faceTag,
964 const BLSURFPlugin_Hypothesis* hyp,
969 const THyperPatchList& hpl = hyp->_hyperPatchList;
970 for ( size_t i = 0; i < hpl.size(); ++i )
971 if ( hpl[i].count( faceTag ))
973 if ( iPatch ) *iPatch = (int) i;
974 return *( hpl[i].begin() );
980 //=============================================================================
981 void BLSURFPlugin_Hypothesis::SetEnforcedMeshes( std::vector< EnforcedMesh > & enforcedMeshes )
983 if ( _enforcedMeshes != enforcedMeshes )
985 _enforcedMeshes.swap( enforcedMeshes );
986 NotifySubMeshesHypothesisModification();
990 //================================================================================
992 * \brief Return elements of 1D enforced mesh. Result can be NULL
994 //================================================================================
997 BLSURFPlugin_Hypothesis::GetEnforcedSegments( const EnforcedMesh& enfMesh,
998 SMESH_Mesh* & mesh ) const
1000 SMDS_ElemIteratorPtr it;
1001 if (( mesh = SMESH_Hypothesis::GetMeshByPersistentID( enfMesh._meshID )))
1004 if ( mesh->NbEdges() == 0 )
1005 GetGen()->Compute( *mesh, mesh->GetShapeToMesh(), /*flags=*/0 );
1007 switch( enfMesh._type )
1010 it = mesh->GetMeshDS()->elementsIterator( SMDSAbs_Edge );
1013 case ENFORCED_GROUP:
1014 if ( SMESH_Group* grp = mesh->GetGroup( enfMesh._subID ))
1016 if ( grp->GetGroupDS()->GetType() == SMDSAbs_Edge )
1017 it = grp->GetGroupDS()->GetElements();
1021 case ENFORCED_SUBMESH:
1022 if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining( enfMesh._subID ))
1023 if ( SMESHDS_SubMesh * smDS = sm->GetSubMeshDS() )
1025 it = smDS->GetElements();
1026 if ( it->more() && it->next()->GetType() != SMDSAbs_Edge )
1027 it = SMDS_ElemIteratorPtr();
1029 it = smDS->GetElements();
1038 //=============================================================================
1039 void BLSURFPlugin_Hypothesis::SetPreCADMergeEdges(bool theVal)
1041 if (theVal != ToBool( GetPreCADOptionValue("merge_edges", GET_DEFAULT()))) {
1042 _preCADMergeEdges = theVal;
1043 SetPreCADOptionValue("merge_edges", theVal ? "yes" : "no" );
1044 NotifySubMeshesHypothesisModification();
1048 //=============================================================================
1049 void BLSURFPlugin_Hypothesis::SetPreCADRemoveDuplicateCADFaces(bool theVal)
1051 if (theVal != ToBool( GetPreCADOptionValue("remove_duplicate_cad_faces", GET_DEFAULT()))) {
1052 _preCADRemoveDuplicateCADFaces = theVal;
1053 SetPreCADOptionValue("remove_duplicate_cad_faces", theVal ? "yes" : "no" );
1054 NotifySubMeshesHypothesisModification();
1058 //=============================================================================
1059 void BLSURFPlugin_Hypothesis::SetPreCADProcess3DTopology(bool theVal)
1061 if (theVal != ToBool( GetPreCADOptionValue("process_3d_topology", GET_DEFAULT()))) {
1062 _preCADProcess3DTopology = theVal;
1063 SetPreCADOptionValue("process_3d_topology", theVal ? "yes" : "no" );
1064 NotifySubMeshesHypothesisModification();
1068 //=============================================================================
1069 void BLSURFPlugin_Hypothesis::SetPreCADDiscardInput(bool theVal)
1071 if (theVal != ToBool( GetPreCADOptionValue("discard_input_topology", GET_DEFAULT()))) {
1072 _preCADDiscardInput = theVal;
1073 SetPreCADOptionValue("discard_input_topology", theVal ? "yes" : "no" );
1074 NotifySubMeshesHypothesisModification();
1078 //=============================================================================
1079 // Return true if any PreCAD option is activated
1080 bool BLSURFPlugin_Hypothesis::HasPreCADOptions(const BLSURFPlugin_Hypothesis* hyp)
1082 if ( !hyp || hyp->_name == GetHypType(/*hasgeom=*/false))
1086 bool orDefault, isOk;
1087 return ( ToBool( hyp->GetPreCADOptionValue("closed_geometry" , &orDefault )) ||
1088 ToBool( hyp->GetPreCADOptionValue("discard_input_topology" , &orDefault )) ||
1089 ToBool( hyp->GetPreCADOptionValue("merge_edges" , &orDefault )) ||
1090 ToBool( hyp->GetPreCADOptionValue("remove_duplicate_cad_faces", &orDefault )) ||
1091 ToBool( hyp->GetPreCADOptionValue("process_3d_topology" , &orDefault )) ||
1092 ToBool( hyp->GetPreCADOption ("manifold_geometry") , &isOk ) ||
1093 hyp->GetPreCADOptionValue("sewing_tolerance", &orDefault ) != "5e-4*D" ||
1094 !hyp->_preCadFacesPeriodicityVector.empty() ||
1095 !hyp->_preCadEdgesPeriodicityVector.empty() ||
1096 !hyp->_facesPeriodicityVector.empty() ||
1097 !hyp->_edgesPeriodicityVector.empty() ||
1098 !hyp->_verticesPeriodicityVector.empty() ||
1099 !hyp->GetHyperPatches().empty() ||
1100 hyp->GetTopology() != FromCAD );
1103 //=============================================================================
1104 // void BLSURFPlugin_Hypothesis::SetGMFFile(const std::string& theFileName, bool isBinary)
1105 void BLSURFPlugin_Hypothesis::SetGMFFile(const std::string& theFileName)
1107 _GMFFileName = theFileName;
1108 // _GMFFileMode = isBinary;
1109 NotifySubMeshesHypothesisModification();
1112 //=============================================================================
1113 void BLSURFPlugin_Hypothesis::SetOptionValue(const std::string& optionName, const std::string& optionValue)
1115 TOptionValues::iterator op_val = _option2value.find(optionName);
1116 if (op_val == _option2value.end())
1118 op_val = _preCADoption2value.find(optionName);
1119 if (op_val == _preCADoption2value.end())
1121 std::string msg = "Unknown MG-CADSurf option: '" + optionName + "'. Try SetAdvancedOption()";
1122 throw std::invalid_argument(msg);
1125 if (op_val->second != optionValue)
1127 const char* ptr = optionValue.c_str();
1128 // strip white spaces
1129 while (ptr[0] == ' ')
1131 size_t i = strlen(ptr);
1132 while (i != 0 && ptr[i - 1] == ' ')
1136 std::string typeName;
1139 } else if (_charOptions.count(optionName)) {
1140 // do not check strings
1141 } else if (_doubleOptions.count(optionName)) {
1142 // check if value is double
1143 ToDbl(ptr, &typeOk);
1145 } else if (_boolOptions.count(optionName)) {
1146 // check if value is bool
1147 ToBool(ptr, &typeOk);
1150 // check if value is int
1151 ToInt(ptr, &typeOk);
1152 typeName = "integer";
1155 std::string msg = "Advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName;
1156 throw std::invalid_argument(msg);
1158 std::string value( ptr, i );
1159 if ( _defaultOptionValues[ optionName ] == value )
1162 op_val->second = value;
1164 NotifySubMeshesHypothesisModification();
1168 //=============================================================================
1169 void BLSURFPlugin_Hypothesis::SetPreCADOptionValue(const std::string& optionName, const std::string& optionValue)
1171 TOptionValues::iterator op_val = _preCADoption2value.find(optionName);
1172 if (op_val == _preCADoption2value.end()) {
1173 op_val = _option2value.find(optionName);
1174 if (op_val == _option2value.end()) {
1175 std::string msg = "Unknown MG-PreCAD option: '" + optionName + "'. Try SetAdvancedOption()";
1176 throw std::invalid_argument(msg);
1179 if (op_val->second != optionValue)
1181 const char* ptr = optionValue.c_str();
1182 // strip white spaces
1183 while (ptr[0] == ' ')
1185 size_t i = strlen(ptr);
1186 while (i != 0 && ptr[i - 1] == ' ')
1190 std::string typeName;
1193 } else if (_preCADcharOptions.find(optionName) != _preCADcharOptions.end()) {
1194 // do not check strings
1195 } else if (_preCADdoubleOptions.find(optionName) != _preCADdoubleOptions.end()) {
1196 // check if value is double
1198 strtod(ptr, &endPtr);
1199 typeOk = (ptr != endPtr);
1201 } else if (_boolOptions.count(optionName)) {
1202 // check if value is bool
1203 ToBool(ptr, &typeOk);
1206 // check if value is int
1208 strtol(ptr, &endPtr, 10);
1209 typeOk = (ptr != endPtr);
1210 typeName = "integer";
1213 std::string msg = "PreCAD advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName;
1214 throw std::invalid_argument(msg);
1216 std::string value( ptr, i );
1217 if ( _defaultOptionValues[ optionName ] == value )
1220 op_val->second = value;
1222 NotifySubMeshesHypothesisModification();
1226 //=============================================================================
1227 std::string BLSURFPlugin_Hypothesis::GetOptionValue(const std::string& optionName,
1228 bool* isDefault) const
1230 TOptionValues::const_iterator op_val = _option2value.find(optionName);
1231 if (op_val == _option2value.end())
1233 op_val = _preCADoption2value.find(optionName);
1234 if (op_val == _preCADoption2value.end())
1236 op_val = _customOption2value.find(optionName);
1237 if (op_val == _customOption2value.end())
1239 std::string msg = "Unknown MG-CADSurf option: <" + optionName + ">";
1240 throw std::invalid_argument(msg);
1244 std::string val = op_val->second;
1245 if ( isDefault ) *isDefault = ( val.empty() );
1247 if ( val.empty() && isDefault )
1249 op_val = _defaultOptionValues.find( optionName );
1250 if (op_val != _defaultOptionValues.end())
1251 val = op_val->second;
1256 //=============================================================================
1257 std::string BLSURFPlugin_Hypothesis::GetPreCADOptionValue(const std::string& optionName,
1258 bool* isDefault) const
1260 TOptionValues::const_iterator op_val = _preCADoption2value.find(optionName);
1261 if (op_val == _preCADoption2value.end())
1263 op_val = _option2value.find(optionName);
1264 if (op_val == _option2value.end())
1266 op_val = _customOption2value.find(optionName);
1267 if (op_val == _customOption2value.end())
1269 std::string msg = "Unknown MG-CADSurf option: <" + optionName + ">";
1270 throw std::invalid_argument(msg);
1274 std::string val = op_val->second;
1275 if ( isDefault ) *isDefault = ( val.empty() );
1277 if ( val.empty() && isDefault )
1279 op_val = _defaultOptionValues.find( optionName );
1280 if (op_val != _defaultOptionValues.end())
1281 val = op_val->second;
1286 //=============================================================================
1287 void BLSURFPlugin_Hypothesis::ClearOption(const std::string& optionName)
1289 TOptionValues::iterator op_val = _customOption2value.find(optionName);
1290 if (op_val != _customOption2value.end())
1291 _customOption2value.erase(op_val);
1293 op_val = _option2value.find(optionName);
1294 if (op_val != _option2value.end())
1295 op_val->second.clear();
1297 op_val = _preCADoption2value.find(optionName);
1298 if (op_val != _preCADoption2value.end())
1299 op_val->second.clear();
1304 //=============================================================================
1305 void BLSURFPlugin_Hypothesis::ClearPreCADOption(const std::string& optionName)
1307 TOptionValues::iterator op_val = _preCADoption2value.find(optionName);
1308 if (op_val != _preCADoption2value.end())
1309 op_val->second.clear();
1312 //=============================================================================
1313 void BLSURFPlugin_Hypothesis::AddOption(const std::string& optionName, const std::string& optionValue)
1316 TOptionValues::iterator op_val = _option2value.find(optionName);
1317 if (op_val != _option2value.end())
1319 if (op_val->second != optionValue)
1320 op_val->second = optionValue;
1326 op_val = _preCADoption2value.find(optionName);
1327 if (op_val != _preCADoption2value.end())
1329 if (op_val->second != optionValue)
1330 op_val->second = optionValue;
1334 else if ( optionValue.empty() )
1336 _customOption2value.erase( optionName );
1340 op_val = _customOption2value.find(optionName);
1341 if (op_val == _customOption2value.end())
1342 _customOption2value[optionName] = optionValue;
1343 else if (op_val->second != optionValue)
1344 op_val->second = optionValue;
1350 NotifySubMeshesHypothesisModification();
1353 //=============================================================================
1354 void BLSURFPlugin_Hypothesis::AddPreCADOption(const std::string& optionName, const std::string& optionValue)
1356 AddOption( optionName, optionValue );
1359 //=============================================================================
1360 std::string BLSURFPlugin_Hypothesis::GetOption(const std::string& optionName) const
1362 TOptionValues::const_iterator op_val = _customOption2value.find(optionName);
1363 if (op_val != _customOption2value.end())
1364 return op_val->second;
1369 //=============================================================================
1370 std::string BLSURFPlugin_Hypothesis::GetPreCADOption(const std::string& optionName) const
1372 TOptionValues::const_iterator op_val = _customOption2value.find(optionName);
1373 if (op_val != _customOption2value.end())
1374 return op_val->second;
1379 //=============================================================================
1380 BLSURFPlugin_Hypothesis::TOptionValues BLSURFPlugin_Hypothesis::GetOptionValues() const
1383 TOptionValues::const_iterator op_val = _option2value.begin();
1384 for ( ; op_val != _option2value.end(); ++op_val )
1385 vals.insert( make_pair( op_val->first, GetOptionValue( op_val->first, GET_DEFAULT() )));
1390 //=============================================================================
1391 BLSURFPlugin_Hypothesis::TOptionValues BLSURFPlugin_Hypothesis::GetPreCADOptionValues() const
1394 TOptionValues::const_iterator op_val = _preCADoption2value.begin();
1395 for ( ; op_val != _preCADoption2value.end(); ++op_val )
1396 vals.insert( make_pair( op_val->first, GetPreCADOptionValue( op_val->first, GET_DEFAULT() )));
1401 //=======================================================================
1402 //function : SetSizeMapEntry
1403 //=======================================================================
1404 void BLSURFPlugin_Hypothesis::SetSizeMapEntry(const std::string& entry, const std::string& sizeMap) {
1405 if (_sizeMap[entry].compare(sizeMap) != 0) {
1406 SetPhysicalMesh(PhysicalLocalSize);
1407 _sizeMap[entry] = sizeMap;
1408 NotifySubMeshesHypothesisModification();
1412 //=======================================================================
1413 //function : GetSizeMapEntry
1414 //=======================================================================
1415 std::string BLSURFPlugin_Hypothesis::GetSizeMapEntry(const std::string& entry) {
1416 TSizeMap::iterator it = _sizeMap.find(entry);
1417 if (it != _sizeMap.end())
1420 return "No_Such_Entry";
1424 * \brief Return the size maps
1426 BLSURFPlugin_Hypothesis::TSizeMap BLSURFPlugin_Hypothesis::GetSizeMapEntries(const BLSURFPlugin_Hypothesis* hyp) {
1427 return hyp ? hyp->_GetSizeMapEntries() : GetDefaultSizeMap();
1430 //=======================================================================
1431 //function : SetAttractorEntry
1432 //=======================================================================
1433 void BLSURFPlugin_Hypothesis::SetAttractorEntry(const std::string& entry, const std::string& attractor) {
1434 if (_attractors[entry].compare(attractor) != 0) {
1435 SetPhysicalMesh(PhysicalLocalSize);
1436 _attractors[entry] = attractor;
1437 NotifySubMeshesHypothesisModification();
1441 //=======================================================================
1442 //function : GetAttractorEntry
1443 //=======================================================================
1444 std::string BLSURFPlugin_Hypothesis::GetAttractorEntry(const std::string& entry) {
1445 TSizeMap::iterator it = _attractors.find(entry);
1446 if (it != _attractors.end())
1449 return "No_Such_Entry";
1453 * \brief Return the attractors
1455 BLSURFPlugin_Hypothesis::TSizeMap BLSURFPlugin_Hypothesis::GetAttractorEntries(const BLSURFPlugin_Hypothesis* hyp) {
1456 return hyp ? hyp->_GetAttractorEntries() : GetDefaultSizeMap();
1459 //=======================================================================
1460 //function : SetClassAttractorEntry
1461 //=======================================================================
1462 void BLSURFPlugin_Hypothesis::SetClassAttractorEntry(const std::string& entry, const std::string& attEntry, double StartSize, double EndSize, double ActionRadius, double ConstantRadius)
1464 SetPhysicalMesh(PhysicalLocalSize);
1466 // The new attractor can't be defined on the same face as another sizemap
1467 TSizeMap::iterator it = _sizeMap.find( entry );
1468 if ( it != _sizeMap.end() ) {
1470 NotifySubMeshesHypothesisModification();
1473 TSizeMap::iterator itAt = _attractors.find( entry );
1474 if ( itAt != _attractors.end() ) {
1475 _attractors.erase(itAt);
1476 NotifySubMeshesHypothesisModification();
1480 const TopoDS_Shape AttractorShape = BLSURFPlugin_Hypothesis::entryToShape(attEntry);
1481 const TopoDS_Face FaceShape = TopoDS::Face(BLSURFPlugin_Hypothesis::entryToShape(entry));
1482 TAttractorMap::iterator attIt = _classAttractors.find(entry);
1483 for ( ; attIt != _classAttractors.end(); ++attIt )
1484 if ( attIt->first == entry &&
1485 attIt->second->GetAttractorEntry() == attEntry )
1487 bool attExists = (attIt != _classAttractors.end());
1489 BLSURFPlugin_Attractor* myAttractor;
1491 myAttractor = new BLSURFPlugin_Attractor(FaceShape, AttractorShape, attEntry);//, 0.1 );
1492 _classAttractors.insert( make_pair( entry, myAttractor ));
1495 myAttractor = attIt->second;
1497 // if (!myAttractor->IsMapBuilt())
1498 // myAttractor->BuildMap();
1499 myAttractor->SetParameters(StartSize, EndSize, ActionRadius, ConstantRadius);
1501 NotifySubMeshesHypothesisModification();
1504 //=======================================================================
1505 //function : SetConstantSizeOnAdjacentFaces
1506 //=======================================================================
1507 // TODO uncomment and test (include the needed .hxx)
1508 // SetConstantSizeOnAdjacentFaces(myShape, att_entry, startSize, endSize = user_size, const_dist ) {
1509 // TopTools_IndexedMapOfShapListOdShape anEdge2FaceMap;
1510 // TopExp::MapShapesAnAncestors(myShape,TopAbs_EDGE, TopAbs_FACE, anEdge2FaceMap);
1511 // TopTools_IndexedMapOfShapListOdShape::iterator it;
1512 // for (it = anEdge2FaceMap.begin();it != anEdge2FaceMap.end();it++){
1513 // SetClassAttractorEntry((*it).first, att_entry, startSize, endSize, 0, const_dist)
1521 //=======================================================================
1522 //function : GetClassAttractorEntry
1523 //=======================================================================
1524 // BLSURFPlugin_Attractor& BLSURFPlugin_Hypothesis::GetClassAttractorEntry(const std::string& entry)
1526 // TAttractorMap::iterator it = _classAttractors.find( entry );
1527 // if ( it != _classAttractors.end() )
1528 // return it->second;
1530 // return "No_Such_Entry";
1534 * \brief Return the map of attractor instances
1536 BLSURFPlugin_Hypothesis::TAttractorMap BLSURFPlugin_Hypothesis::GetClassAttractorEntries(const BLSURFPlugin_Hypothesis* hyp)
1538 return hyp ? hyp->_GetClassAttractorEntries():GetDefaultAttractorMap();
1541 //=======================================================================
1542 //function : ClearEntry
1543 //=======================================================================
1544 void BLSURFPlugin_Hypothesis::ClearEntry(const std::string& entry,
1545 const char * attEntry/*=0*/)
1547 TSizeMap::iterator it = _sizeMap.find( entry );
1549 if ( it != _sizeMap.end() ) {
1551 NotifySubMeshesHypothesisModification();
1554 TSizeMap::iterator itAt = _attractors.find( entry );
1555 if ( itAt != _attractors.end() ) {
1556 _attractors.erase(itAt);
1557 NotifySubMeshesHypothesisModification();
1560 TAttractorMap::iterator it_clAt = _classAttractors.find( entry );
1561 if ( it_clAt != _classAttractors.end() ) {
1563 if ( !attEntry || it_clAt->second->GetAttractorEntry() == attEntry )
1564 _classAttractors.erase( it_clAt++ );
1568 while ( it_clAt != _classAttractors.end() );
1569 NotifySubMeshesHypothesisModification();
1572 std::cout<<"No_Such_Entry"<<std::endl;
1577 //=======================================================================
1578 //function : ClearSizeMaps
1579 //=======================================================================
1580 void BLSURFPlugin_Hypothesis::ClearSizeMaps() {
1582 _attractors.clear();
1583 _classAttractors.clear();
1586 // Enable internal enforced vertices on specific face if requested by user
1588 ////=======================================================================
1589 ////function : SetInternalEnforcedVertex
1590 ////=======================================================================
1591 //void BLSURFPlugin_Hypothesis::SetInternalEnforcedVertex(TEntry theFaceEntry,
1592 // bool toEnforceInternalVertices,
1593 // TEnfGroupName theGroupName) {
1595 // << toEnforceInternalVertices << ", " << theGroupName << ")");
1597 // TFaceEntryInternalVerticesList::iterator it = _faceEntryInternalVerticesList.find(theFaceEntry);
1598 // if (it != _faceEntryInternalVerticesList.end()) {
1599 // if (!toEnforceInternalVertices) {
1600 // _faceEntryInternalVerticesList.erase(it);
1604 // if (toEnforceInternalVertices) {
1605 // _faceEntryInternalVerticesList.insert(theFaceEntry);
1610 // // Take care of groups
1614 //=======================================================================
1615 //function : SetEnforcedVertex
1616 //=======================================================================
1617 bool BLSURFPlugin_Hypothesis::SetEnforcedVertex(TEntry theFaceEntry,
1618 TEnfName theVertexName,
1619 TEntry theVertexEntry,
1620 TEnfGroupName theGroupName,
1621 double x, double y, double z)
1623 SetPhysicalMesh(PhysicalLocalSize);
1625 bool toNotify = false;
1626 bool toCreate = true;
1628 TEnfVertex *oldEnVertex;
1629 TEnfVertex *newEnfVertex = new TEnfVertex();
1630 newEnfVertex->name = theVertexName;
1631 newEnfVertex->geomEntry = theVertexEntry;
1632 newEnfVertex->coords.clear();
1633 if (theVertexEntry == "") {
1634 newEnfVertex->coords.push_back(x);
1635 newEnfVertex->coords.push_back(y);
1636 newEnfVertex->coords.push_back(z);
1638 newEnfVertex->grpName = theGroupName;
1639 newEnfVertex->faceEntries.clear();
1640 newEnfVertex->faceEntries.insert(theFaceEntry);
1643 // update _enfVertexList
1644 TEnfVertexList::iterator it = _enfVertexList.find(newEnfVertex);
1645 if (it != _enfVertexList.end()) {
1647 oldEnVertex = (*it);
1648 if (oldEnVertex->name != theVertexName) {
1649 oldEnVertex->name = theVertexName;
1652 if (oldEnVertex->grpName != theGroupName) {
1653 oldEnVertex->grpName = theGroupName;
1656 TEntryList::iterator it_faceEntries = oldEnVertex->faceEntries.find(theFaceEntry);
1657 if (it_faceEntries == oldEnVertex->faceEntries.end()) {
1658 oldEnVertex->faceEntries.insert(theFaceEntry);
1659 _faceEntryEnfVertexListMap[theFaceEntry].insert(oldEnVertex);
1663 // update map coords / enf vertex if needed
1664 if (oldEnVertex->coords.size()) {
1665 _coordsEnfVertexMap[oldEnVertex->coords] = oldEnVertex;
1666 _faceEntryCoordsListMap[theFaceEntry].insert(oldEnVertex->coords);
1669 // update map geom entry / enf vertex if needed
1670 if (oldEnVertex->geomEntry != "") {
1671 _enfVertexEntryEnfVertexMap[oldEnVertex->geomEntry] = oldEnVertex;
1672 _faceEntryEnfVertexEntryListMap[theFaceEntry].insert(oldEnVertex->geomEntry);
1677 // //////// CREATE ////////////
1680 AddEnforcedVertex( theFaceEntry, newEnfVertex );
1683 delete newEnfVertex;
1687 NotifySubMeshesHypothesisModification();
1692 //=======================================================================
1693 //function : AddEnforcedVertex
1694 //=======================================================================
1696 void BLSURFPlugin_Hypothesis::AddEnforcedVertex( const TEntry& faceEntry,
1697 TEnfVertex * newEnfVertex )
1701 _faceEntryEnfVertexListMap[faceEntry].insert(newEnfVertex);
1702 _enfVertexList.insert(newEnfVertex);
1703 if ( newEnfVertex->geomEntry.empty() ) {
1704 _faceEntryCoordsListMap[faceEntry].insert(newEnfVertex->coords);
1705 _coordsEnfVertexMap[newEnfVertex->coords] = newEnfVertex;
1708 _faceEntryEnfVertexEntryListMap[faceEntry].insert(newEnfVertex->geomEntry);
1709 _enfVertexEntryEnfVertexMap[newEnfVertex->geomEntry] = newEnfVertex;
1714 //=======================================================================
1715 //function : GetEnforcedVertices
1716 //=======================================================================
1718 BLSURFPlugin_Hypothesis::TEnfVertexList BLSURFPlugin_Hypothesis::GetEnfVertexList(const TEntry& theFaceEntry)
1720 if (_faceEntryEnfVertexListMap.count(theFaceEntry) > 0)
1721 return _faceEntryEnfVertexListMap[theFaceEntry];
1723 return GetDefaultEnfVertexList();
1725 std::ostringstream msg;
1726 msg << "No enforced vertex for face entry " << theFaceEntry;
1727 throw std::invalid_argument(msg.str());
1730 //=======================================================================
1731 //function : GetEnfVertexCoordsList
1732 //=======================================================================
1734 BLSURFPlugin_Hypothesis::TEnfVertexCoordsList BLSURFPlugin_Hypothesis::GetEnfVertexCoordsList(const TEntry& theFaceEntry)
1736 if (_faceEntryCoordsListMap.count(theFaceEntry) > 0)
1737 return _faceEntryCoordsListMap[theFaceEntry];
1739 std::ostringstream msg;
1740 msg << "No enforced vertex coords for face entry " << theFaceEntry;
1741 throw std::invalid_argument(msg.str());
1744 //=======================================================================
1745 //function : GetEnfVertexEntryList
1746 //=======================================================================
1748 BLSURFPlugin_Hypothesis::TEntryList BLSURFPlugin_Hypothesis::GetEnfVertexEntryList(const TEntry& theFaceEntry)
1750 if (_faceEntryEnfVertexEntryListMap.count(theFaceEntry) > 0)
1751 return _faceEntryEnfVertexEntryListMap[theFaceEntry];
1753 std::ostringstream msg;
1754 msg << "No enforced vertex entry for face entry " << theFaceEntry;
1755 throw std::invalid_argument(msg.str());
1758 //=======================================================================
1759 //function : GetEnfVertex(TEnfVertexCoords coords)
1760 //=======================================================================
1762 BLSURFPlugin_Hypothesis::TEnfVertex* BLSURFPlugin_Hypothesis::GetEnfVertex(TEnfVertexCoords coords)
1764 if (_coordsEnfVertexMap.count(coords) > 0)
1765 return _coordsEnfVertexMap[coords];
1767 std::ostringstream msg;
1768 msg << "No enforced vertex with coords (" << coords[0] << ", " << coords[1] << ", " << coords[2] << ")";
1769 throw std::invalid_argument(msg.str());
1772 //=======================================================================
1773 //function : GetEnfVertex(const TEntry& theEnfVertexEntry)
1774 //=======================================================================
1776 BLSURFPlugin_Hypothesis::TEnfVertex* BLSURFPlugin_Hypothesis::GetEnfVertex(const TEntry& theEnfVertexEntry)
1778 if (_enfVertexEntryEnfVertexMap.count(theEnfVertexEntry) > 0)
1779 return _enfVertexEntryEnfVertexMap[theEnfVertexEntry];
1781 std::ostringstream msg;
1782 msg << "No enforced vertex with entry " << theEnfVertexEntry;
1783 throw std::invalid_argument(msg.str());
1786 //Enable internal enforced vertices on specific face if requested by user
1787 ////=======================================================================
1788 ////function : GetInternalEnforcedVertex
1789 ////=======================================================================
1791 //bool BLSURFPlugin_Hypothesis::GetInternalEnforcedVertex(const TEntry& theFaceEntry)
1793 // if (_faceEntryInternalVerticesList.count(theFaceEntry) > 0)
1798 //=======================================================================
1799 //function : ClearEnforcedVertex
1800 //=======================================================================
1802 bool BLSURFPlugin_Hypothesis::ClearEnforcedVertex(const TEntry& theFaceEntry,
1803 double x, double y, double z,
1804 const TEntry& theVertexEntry)
1806 bool toNotify = false;
1807 std::ostringstream msg;
1808 TEnfVertex *oldEnfVertex;
1809 TEnfVertexCoords coords;
1811 coords.push_back(x);
1812 coords.push_back(y);
1813 coords.push_back(z);
1815 // check that enf vertex with given enf vertex entry exists
1816 TEnfVertexEntryEnfVertexMap::iterator it_enfVertexEntry = _enfVertexEntryEnfVertexMap.find(theVertexEntry);
1817 if (it_enfVertexEntry != _enfVertexEntryEnfVertexMap.end()) {
1819 oldEnfVertex = it_enfVertexEntry->second;
1821 _enfVertexEntryEnfVertexMap.erase(it_enfVertexEntry);
1823 TEntryList& enfVertexEntryList = _faceEntryEnfVertexEntryListMap[theFaceEntry];
1824 enfVertexEntryList.erase(theVertexEntry);
1825 if (enfVertexEntryList.size() == 0)
1826 _faceEntryEnfVertexEntryListMap.erase(theFaceEntry);
1827 // TFaceEntryEnfVertexEntryListMap::iterator it_entry_entry = _faceEntryEnfVertexEntryListMap.find(theFaceEntry);
1828 // TEntryList::iterator it_entryList = it_entry_entry->second.find(theVertexEntry);
1829 // it_entry_entry->second.erase(it_entryList);
1830 // if (it_entry_entry->second.size() == 0)
1831 // _faceEntryEnfVertexEntryListMap.erase(it_entry_entry);
1834 MESSAGE("Enforced vertex with geom entry " << theVertexEntry << " not found");
1835 msg << "No enforced vertex with geom entry " << theVertexEntry;
1836 // check that enf vertex with given coords exists
1837 TCoordsEnfVertexMap::iterator it_coords_enf = _coordsEnfVertexMap.find(coords);
1838 if (it_coords_enf != _coordsEnfVertexMap.end()) {
1840 oldEnfVertex = it_coords_enf->second;
1842 _coordsEnfVertexMap.erase(it_coords_enf);
1844 TEnfVertexCoordsList& enfVertexCoordsList = _faceEntryCoordsListMap[theFaceEntry];
1845 enfVertexCoordsList.erase(coords);
1846 if (enfVertexCoordsList.size() == 0)
1847 _faceEntryCoordsListMap.erase(theFaceEntry);
1848 // TFaceEntryCoordsListMap::iterator it_entry_coords = _faceEntryCoordsListMap.find(theFaceEntry);
1849 // TEnfVertexCoordsList::iterator it_coordsList = it_entry_coords->second.find(coords);
1850 // it_entry_coords->second.erase(it_coordsList);
1851 // if (it_entry_coords->second.size() == 0)
1852 // _faceEntryCoordsListMap.erase(it_entry_coords);
1855 MESSAGE("Enforced vertex with coords " << x << ", " << y << ", " << z << " not found");
1857 msg << "No enforced vertex at " << x << ", " << y << ", " << z;
1858 throw std::invalid_argument(msg.str());
1862 // update _enfVertexList
1863 TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
1864 if (it != _enfVertexList.end()) {
1865 (*it)->faceEntries.erase(theFaceEntry);
1866 if ((*it)->faceEntries.size() == 0){
1867 _enfVertexList.erase(it);
1872 // update _faceEntryEnfVertexListMap
1873 TEnfVertexList& currentEnfVertexList = _faceEntryEnfVertexListMap[theFaceEntry];
1874 currentEnfVertexList.erase(oldEnfVertex);
1876 if (currentEnfVertexList.size() == 0) {
1877 _faceEntryEnfVertexListMap.erase(theFaceEntry);
1881 NotifySubMeshesHypothesisModification();
1886 //=======================================================================
1887 //function : ClearEnforcedVertices
1888 //=======================================================================
1890 bool BLSURFPlugin_Hypothesis::ClearEnforcedVertices(const TEntry& theFaceEntry)
1892 bool toNotify = false;
1893 TEnfVertex *oldEnfVertex;
1895 TFaceEntryCoordsListMap::iterator it_entry_coords = _faceEntryCoordsListMap.find(theFaceEntry);
1896 if (it_entry_coords != _faceEntryCoordsListMap.end()) {
1898 TEnfVertexCoordsList coordsList = it_entry_coords->second;
1899 TEnfVertexCoordsList::iterator it_coordsList = coordsList.begin();
1900 for (; it_coordsList != coordsList.end(); ++it_coordsList) {
1901 TEnfVertexCoords coords = (*it_coordsList);
1902 oldEnfVertex = _coordsEnfVertexMap[coords];
1903 _coordsEnfVertexMap.erase(coords);
1904 // update _enfVertexList
1905 TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
1906 if (it != _enfVertexList.end()) {
1907 (*it)->faceEntries.erase(theFaceEntry);
1908 if ((*it)->faceEntries.size() == 0){
1909 _enfVertexList.erase(it);
1914 _faceEntryCoordsListMap.erase(it_entry_coords);
1915 _faceEntryEnfVertexListMap.erase(theFaceEntry);
1918 TFaceEntryEnfVertexEntryListMap::iterator it_entry_entry = _faceEntryEnfVertexEntryListMap.find(theFaceEntry);
1919 if (it_entry_entry != _faceEntryEnfVertexEntryListMap.end()) {
1921 TEntryList enfVertexEntryList = it_entry_entry->second;
1922 TEntryList::iterator it_enfVertexEntryList = enfVertexEntryList.begin();
1923 for (; it_enfVertexEntryList != enfVertexEntryList.end(); ++it_enfVertexEntryList) {
1924 TEntry enfVertexEntry = (*it_enfVertexEntryList);
1925 oldEnfVertex = _enfVertexEntryEnfVertexMap[enfVertexEntry];
1926 _enfVertexEntryEnfVertexMap.erase(enfVertexEntry);
1927 // update _enfVertexList
1928 TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
1929 if (it != _enfVertexList.end()) {
1930 (*it)->faceEntries.erase(theFaceEntry);
1931 if ((*it)->faceEntries.size() == 0){
1932 _enfVertexList.erase(it);
1937 _faceEntryEnfVertexEntryListMap.erase(it_entry_entry);
1938 _faceEntryEnfVertexListMap.erase(theFaceEntry);
1942 NotifySubMeshesHypothesisModification();
1945 // std::ostringstream msg;
1946 // msg << "No enforced vertex for " << theFaceEntry;
1947 // throw std::invalid_argument(msg.str());
1950 //=======================================================================
1951 //function : ClearAllEnforcedVertices
1952 //=======================================================================
1953 void BLSURFPlugin_Hypothesis::ClearAllEnforcedVertices()
1955 _faceEntryEnfVertexListMap.clear();
1956 _faceEntryCoordsListMap.clear();
1957 _coordsEnfVertexMap.clear();
1958 _faceEntryEnfVertexEntryListMap.clear();
1959 _enfVertexEntryEnfVertexMap.clear();
1961 TEnfVertexList::iterator it_enfVertex = _enfVertexList.begin();
1962 for ( ; it_enfVertex != _enfVertexList.end(); ++it_enfVertex )
1963 delete *it_enfVertex;
1964 _enfVertexList.clear();
1966 // Enable internal enforced vertices on specific face if requested by user
1967 // _faceEntryInternalVerticesList.clear();
1968 NotifySubMeshesHypothesisModification();
1972 //================================================================================
1974 * \brief Return the enforced vertices
1976 //================================================================================
1979 BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexListMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByFace(
1980 const BLSURFPlugin_Hypothesis* hyp)
1982 return hyp ? hyp->_GetAllEnforcedVerticesByFace() : GetDefaultFaceEntryEnfVertexListMap();
1985 //Enable internal enforced vertices on specific face if requested by user
1986 //BLSURFPlugin_Hypothesis::TFaceEntryInternalVerticesList BLSURFPlugin_Hypothesis::GetAllInternalEnforcedVerticesByFace(
1987 // const BLSURFPlugin_Hypothesis* hyp) {
1988 // return hyp ? hyp->_GetAllInternalEnforcedVerticesByFace() : GetDefaultFaceEntryInternalVerticesMap();
1991 bool BLSURFPlugin_Hypothesis::GetInternalEnforcedVertexAllFaces(const BLSURFPlugin_Hypothesis* hyp)
1993 return hyp ? hyp->_GetInternalEnforcedVertexAllFaces() : GetDefaultInternalEnforcedVertex();
1996 BLSURFPlugin_Hypothesis::TEnfGroupName BLSURFPlugin_Hypothesis::GetInternalEnforcedVertexAllFacesGroup(const BLSURFPlugin_Hypothesis* hyp)
1998 return hyp ? hyp->_GetInternalEnforcedVertexAllFacesGroup() : BLSURFPlugin_Hypothesis::TEnfGroupName();
2001 BLSURFPlugin_Hypothesis::TEnfVertexList BLSURFPlugin_Hypothesis::GetAllEnforcedVertices(
2002 const BLSURFPlugin_Hypothesis* hyp)
2004 return hyp ? hyp->_GetAllEnforcedVertices() : GetDefaultEnfVertexList();
2007 BLSURFPlugin_Hypothesis::TFaceEntryCoordsListMap BLSURFPlugin_Hypothesis::GetAllCoordsByFace(
2008 const BLSURFPlugin_Hypothesis* hyp)
2010 return hyp ? hyp->_GetAllCoordsByFace() : GetDefaultFaceEntryCoordsListMap();
2013 BLSURFPlugin_Hypothesis::TCoordsEnfVertexMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByCoords(
2014 const BLSURFPlugin_Hypothesis* hyp)
2016 return hyp ? hyp->_GetAllEnforcedVerticesByCoords() : GetDefaultCoordsEnfVertexMap();
2019 BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexEntryListMap BLSURFPlugin_Hypothesis::GetAllEnfVertexEntriesByFace(
2020 const BLSURFPlugin_Hypothesis* hyp)
2022 return hyp ? hyp->_GetAllEnfVertexEntriesByFace() : GetDefaultFaceEntryEnfVertexEntryListMap();
2025 BLSURFPlugin_Hypothesis::TEnfVertexEntryEnfVertexMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByEnfVertexEntry(
2026 const BLSURFPlugin_Hypothesis* hyp)
2028 return hyp ? hyp->_GetAllEnforcedVerticesByEnfVertexEntry() : GetDefaultEnfVertexEntryEnfVertexMap();
2031 std::set<smIdType> BLSURFPlugin_Hypothesis::GetEnfVertexNodeIDs(TEnfGroupName theGroupName)
2033 TGroupNameNodeIDMap::const_iterator it = _groupNameNodeIDMap.find(theGroupName);
2034 if (it != _groupNameNodeIDMap.end()) {
2037 std::ostringstream msg;
2038 msg << "No group " << theGroupName;
2039 throw std::invalid_argument(msg.str());
2042 void BLSURFPlugin_Hypothesis::AddEnfVertexNodeID(TEnfGroupName theGroupName,smIdType theNodeID)
2044 _groupNameNodeIDMap[theGroupName].insert(theNodeID);
2047 void BLSURFPlugin_Hypothesis::RemoveEnfVertexNodeID(TEnfGroupName theGroupName,smIdType theNodeID)
2049 TGroupNameNodeIDMap::iterator it = _groupNameNodeIDMap.find(theGroupName);
2050 if (it != _groupNameNodeIDMap.end()) {
2051 std::set<smIdType>::iterator IDit = it->second.find(theNodeID);
2052 if (IDit != it->second.end())
2053 it->second.erase(IDit);
2054 std::ostringstream msg;
2055 msg << "No node IDs " << theNodeID << " for group " << theGroupName;
2056 throw std::invalid_argument(msg.str());
2058 std::ostringstream msg;
2059 msg << "No group " << theGroupName;
2060 throw std::invalid_argument(msg.str());
2064 //=============================================================================
2065 void BLSURFPlugin_Hypothesis::SetInternalEnforcedVertexAllFaces(bool toEnforceInternalVertices)
2067 if (toEnforceInternalVertices != _enforcedInternalVerticesAllFaces) {
2068 _enforcedInternalVerticesAllFaces = toEnforceInternalVertices;
2069 if (toEnforceInternalVertices)
2070 SetPhysicalMesh(PhysicalLocalSize);
2071 NotifySubMeshesHypothesisModification();
2076 //=============================================================================
2077 void BLSURFPlugin_Hypothesis::SetInternalEnforcedVertexAllFacesGroup(BLSURFPlugin_Hypothesis::TEnfGroupName theGroupName)
2079 if (std::string(theGroupName) != std::string(_enforcedInternalVerticesAllFacesGroup)) {
2080 _enforcedInternalVerticesAllFacesGroup = theGroupName;
2081 NotifySubMeshesHypothesisModification();
2085 //=============================================================================
2086 BLSURFPlugin_Hypothesis::TPreCadPeriodicityVector BLSURFPlugin_Hypothesis::GetPreCadFacesPeriodicityVector(
2087 const BLSURFPlugin_Hypothesis* hyp)
2089 return hyp ? hyp->_GetPreCadFacesPeriodicityVector() : GetDefaultPreCadFacesPeriodicityVector();
2092 //=============================================================================
2093 BLSURFPlugin_Hypothesis::TPreCadPeriodicityVector BLSURFPlugin_Hypothesis::GetPreCadEdgesPeriodicityVector(
2094 const BLSURFPlugin_Hypothesis* hyp)
2096 return hyp ? hyp->_GetPreCadEdgesPeriodicityVector() : GetDefaultPreCadEdgesPeriodicityVector();
2099 //=============================================================================
2100 BLSURFPlugin_Hypothesis::TFacesPeriodicityVector BLSURFPlugin_Hypothesis::GetFacesPeriodicityVector(
2101 const BLSURFPlugin_Hypothesis* hyp)
2103 return hyp ? hyp->_GetFacesPeriodicityVector() : GetDefaultFacesPeriodicityVector();
2106 //=============================================================================
2107 BLSURFPlugin_Hypothesis::TEdgesPeriodicityVector BLSURFPlugin_Hypothesis::GetEdgesPeriodicityVector(
2108 const BLSURFPlugin_Hypothesis* hyp)
2110 return hyp ? hyp->_GetEdgesPeriodicityVector() : GetDefaultEdgesPeriodicityVector();
2113 //=============================================================================
2114 BLSURFPlugin_Hypothesis::TVerticesPeriodicityVector BLSURFPlugin_Hypothesis::GetVerticesPeriodicityVector(
2115 const BLSURFPlugin_Hypothesis* hyp)
2117 return hyp ? hyp->_GetVerticesPeriodicityVector() : GetDefaultVerticesPeriodicityVector();
2120 //=======================================================================
2121 //function : ClearAllEnforcedVertices
2122 //=======================================================================
2123 void BLSURFPlugin_Hypothesis::ClearPreCadPeriodicityVectors()
2125 _preCadFacesPeriodicityVector.clear();
2126 _preCadEdgesPeriodicityVector.clear();
2127 NotifySubMeshesHypothesisModification();
2130 //=======================================================================
2131 //function : AddPreCadFacesPeriodicity
2132 //=======================================================================
2133 void BLSURFPlugin_Hypothesis::AddPreCadFacesPeriodicity(TEntry theFace1Entry, TEntry theFace2Entry,
2134 std::vector<std::string> &theSourceVerticesEntries, std::vector<std::string> &theTargetVerticesEntries)
2137 TPreCadPeriodicity preCadFacesPeriodicity;
2138 preCadFacesPeriodicity.shape1Entry = theFace1Entry;
2139 preCadFacesPeriodicity.shape2Entry = theFace2Entry;
2140 preCadFacesPeriodicity.theSourceVerticesEntries = theSourceVerticesEntries;
2141 preCadFacesPeriodicity.theTargetVerticesEntries = theTargetVerticesEntries;
2143 _preCadFacesPeriodicityVector.push_back(preCadFacesPeriodicity);
2145 NotifySubMeshesHypothesisModification();
2148 //=======================================================================
2149 //function : AddPreCadEdgesPeriodicity
2150 //=======================================================================
2151 void BLSURFPlugin_Hypothesis::AddPreCadEdgesPeriodicity(TEntry theEdge1Entry, TEntry theEdge2Entry,
2152 std::vector<std::string> &theSourceVerticesEntries, std::vector<std::string> &theTargetVerticesEntries)
2154 TPreCadPeriodicity preCadEdgesPeriodicity;
2155 preCadEdgesPeriodicity.shape1Entry = theEdge1Entry;
2156 preCadEdgesPeriodicity.shape2Entry = theEdge2Entry;
2157 preCadEdgesPeriodicity.theSourceVerticesEntries = theSourceVerticesEntries;
2158 preCadEdgesPeriodicity.theTargetVerticesEntries = theTargetVerticesEntries;
2160 _preCadEdgesPeriodicityVector.push_back(preCadEdgesPeriodicity);
2162 NotifySubMeshesHypothesisModification();
2165 //=============================================================================
2166 std::ostream & BLSURFPlugin_Hypothesis::SaveTo(std::ostream & save)
2168 // We must keep at least the same number of arguments when increasing the SALOME version
2169 // When MG-CADSurf becomes CADMESH, some parameters were fused into a single one. Thus the same
2170 // parameter can be written several times to keep the old global number of parameters.
2172 // Treat old options which are now in the advanced options
2173 TOptionValues::iterator op_val;
2175 int _preCADRemoveNanoEdges = -1;
2176 double _preCADEpsNano = -1.0;
2177 op_val = _option2value.find("respect_geometry");
2178 if (op_val != _option2value.end()) {
2179 std::string value = op_val->second;
2181 _decimesh = value.compare("1") == 0 ? 1 : 0;
2183 op_val = _preCADoption2value.find("remove_tiny_edges");
2184 if (op_val != _preCADoption2value.end()) {
2185 std::string value = op_val->second;
2187 _preCADRemoveNanoEdges = value.compare("1") == 0 ? 1 : 0;
2189 op_val = _preCADoption2value.find("tiny_edge_length");
2190 if (op_val != _preCADoption2value.end()) {
2191 std::string value = op_val->second;
2193 _preCADEpsNano = strtod(value.c_str(), NULL);
2196 save << " " << (int) _topology << " " << (int) _physicalMesh << " " << (int) _geometricMesh << " " << _phySize << " "
2197 << _angleMesh << " " << _gradation << " " << (int) _elementType << " " << _decimesh;
2198 save << " " << _minSize << " " << _maxSize << " " << _angleMesh << " " << _minSize << " " << _maxSize << " " << _verb;
2199 save << " " << (int) _preCADMergeEdges << " " << _preCADRemoveNanoEdges << " " << (int) _preCADDiscardInput << " " << _preCADEpsNano ;
2200 save << " " << (int) _enforcedInternalVerticesAllFaces;
2201 save << " " << (int) _phySizeRel << " " << (int) _minSizeRel << " " << (int) _maxSizeRel << " " << _chordalError ;
2202 save << " " << (int) _anisotropic << " " << _anisotropicRatio << " " << (int) _removeTinyEdges << " " << _tinyEdgeLength ;
2203 save << " " << (int) _badElementRemoval << " " << _badElementAspectRatio << " " << (int) _optimizeMesh << " " << (int) _quadraticMesh ;
2204 save << " " << (int) _preCADProcess3DTopology << " " << (int) _preCADRemoveDuplicateCADFaces;
2205 save << " " << (int)_optimiseTinyEdges << " " << _tinyEdgeOptimisationLength;
2206 save << " " << (int)_correctSurfaceIntersec << " " << _corrSurfaceIntersCost;
2207 save << " " << (int)_useGradation << " " << (int)_useVolumeGradation << " " << _volumeGradation;
2209 op_val = _option2value.begin();
2210 if (op_val != _option2value.end()) {
2211 save << " " << "__OPTIONS_BEGIN__";
2212 for (; op_val != _option2value.end(); ++op_val) {
2213 if (!op_val->second.empty())
2214 save << " " << op_val->first << " " << op_val->second << "%#"; // "%#" is a mark of value end
2216 save << " " << "__OPTIONS_END__";
2219 op_val = _customOption2value.begin();
2220 if (op_val != _customOption2value.end()) {
2221 save << " " << "__CUSTOM_OPTIONS_BEGIN__";
2222 for (; op_val != _customOption2value.end(); ++op_val) {
2223 if (!op_val->second.empty())
2224 save << " " << op_val->first << " " << op_val->second << "%#"; // "%#" is a mark of value end
2226 save << " " << "__CUSTOM_OPTIONS_END__";
2229 op_val = _preCADoption2value.begin();
2230 if (op_val != _preCADoption2value.end()) {
2231 save << " " << "__PRECAD_OPTIONS_BEGIN__";
2232 for (; op_val != _preCADoption2value.end(); ++op_val) {
2233 if (!op_val->second.empty())
2234 save << " " << op_val->first << " " << op_val->second << "%#"; // "%#" is a mark of value end
2236 save << " " << "__PRECAD_OPTIONS_END__";
2239 TSizeMap::iterator it_sm = _sizeMap.begin();
2240 if (it_sm != _sizeMap.end()) {
2241 save << " " << "__SIZEMAP_BEGIN__";
2242 for (; it_sm != _sizeMap.end(); ++it_sm) {
2243 save << " " << it_sm->first << " " << it_sm->second << "%#"; // "%#" is a mark of value end
2245 save << " " << "__SIZEMAP_END__";
2248 TSizeMap::iterator it_at = _attractors.begin();
2249 if (it_at != _attractors.end()) {
2250 save << " " << "__ATTRACTORS_BEGIN__";
2251 for (; it_at != _attractors.end(); ++it_at) {
2252 save << " " << it_at->first << " " << it_at->second << "%#"; // "%#" is a mark of value end
2254 save << " " << "__ATTRACTORS_END__";
2257 TAttractorMap::iterator it_At = _classAttractors.begin();
2258 if (it_At != _classAttractors.end()) {
2259 std::ostringstream test;
2260 save << " " << "__NEW_ATTRACTORS_BEGIN__";
2261 test << " " << "__NEW_ATTRACTORS_BEGIN__";
2262 for (; it_At != _classAttractors.end(); ++it_At) {
2263 std::vector<double> attParams;
2264 attParams = it_At->second->GetParameters();
2265 // double step = it_At->second->GetStep();
2266 save << " " << it_At->first;
2267 save << " " << it_At->second->GetAttractorEntry();
2268 save << " " << attParams[0] << " " << attParams[1] << " " << attParams[2] << " " << attParams[3];
2269 // save << " " << step;
2270 test << " " << it_At->first;
2271 test << " " << it_At->second->GetAttractorEntry();
2272 test << " " << attParams[0] << " " << attParams[1] << " " << attParams[2] << " " << attParams[3];
2273 // test << " " << step;
2275 save << " " << "__NEW_ATTRACTORS_END__";
2276 test << " " << "__NEW_ATTRACTORS_END__";
2279 TEnfVertexList::const_iterator it_enf = _enfVertexList.begin();
2280 if (it_enf != _enfVertexList.end()) {
2281 save << " " << "__ENFORCED_VERTICES_BEGIN__";
2282 for (; it_enf != _enfVertexList.end(); ++it_enf) {
2283 TEnfVertex *enfVertex = (*it_enf);
2284 save << " " << "__BEGIN_VERTEX__";
2285 if (!enfVertex->name.empty()) {
2286 save << " " << "__BEGIN_NAME__";
2287 save << " " << enfVertex->name;
2288 save << " " << "__END_NAME__";
2290 if (!enfVertex->geomEntry.empty()) {
2291 save << " " << "__BEGIN_ENTRY__";
2292 save << " " << enfVertex->geomEntry;
2293 save << " " << "__END_ENTRY__";
2295 if (!enfVertex->grpName.empty()) {
2296 save << " " << "__BEGIN_GROUP__";
2297 save << " " << enfVertex->grpName;
2298 save << " " << "__END_GROUP__";
2300 if (enfVertex->coords.size()) {
2301 save << " " << "__BEGIN_COORDS__";
2302 for ( size_t i = 0; i < enfVertex->coords.size(); i++ )
2303 save << " " << enfVertex->coords[i];
2304 save << " " << "__END_COORDS__";
2306 TEntryList::const_iterator faceEntriesIt = enfVertex->faceEntries.begin();
2307 bool hasFaces = false;
2308 if (faceEntriesIt != enfVertex->faceEntries.end()) {
2310 save << " " << "__BEGIN_FACELIST__";
2312 for (; faceEntriesIt != enfVertex->faceEntries.end(); ++faceEntriesIt)
2313 if ( faceEntriesIt->empty() )
2314 save << " _no_face_";
2316 save << " " << (*faceEntriesIt);
2318 save << " " << "__END_FACELIST__";
2319 save << " " << "__END_VERTEX__";
2321 save << " " << "__ENFORCED_VERTICES_END__";
2326 SavePreCADPeriodicity(save, "FACES");
2327 SavePreCADPeriodicity(save, "EDGES");
2329 SaveFacesPeriodicity(save);
2330 SaveEdgesPeriodicity(save);
2331 SaveVerticesPeriodicity(save);
2334 save << " " << _hyperPatchList.size() << " ";
2335 for ( size_t i = 0; i < _hyperPatchList.size(); ++i )
2337 THyperPatchTags& patch = _hyperPatchList[i];
2338 save << patch.size() << " ";
2339 THyperPatchTags::iterator tag = patch.begin();
2340 for ( ; tag != patch.end(); ++tag )
2341 save << *tag << " ";
2344 // New options in 2.9.6 (issue #17784)
2345 save << " " << _useSurfaceProximity;
2346 save << " " << _nbSurfaceProximityLayers;
2347 save << " " << _surfaceProximityRatio;
2348 save << " " << _useVolumeProximity;
2349 save << " " << _nbVolumeProximityLayers;
2350 save << " " << _volumeProximityRatio;
2352 // hyper-patches as entries
2353 std::ostringstream hpStream;
2354 boost::archive::text_oarchive( hpStream ) << _hyperPatchEntriesList;
2355 std::string hpString = hpStream.str();
2356 SMESHDS_Hypothesis::SaveStringToStream( save, hpString );
2359 std::ostringstream enfMStream;
2360 boost::archive::text_oarchive( enfMStream ) << _enforcedMeshes;
2361 std::string enfMString = enfMStream.str();
2362 SMESHDS_Hypothesis::SaveStringToStream( save, enfMString );
2367 void BLSURFPlugin_Hypothesis::SaveFacesPeriodicity(std::ostream & save)
2369 TFacesPeriodicityVector::const_iterator it_faces_periodicity = _facesPeriodicityVector.begin();
2370 if (it_faces_periodicity != _facesPeriodicityVector.end()) {
2371 save << " " << "__FACES_PERIODICITY_BEGIN__";
2372 for (; it_faces_periodicity != _facesPeriodicityVector.end(); ++it_faces_periodicity) {
2373 TFacesPeriodicity periodicity_i = (*it_faces_periodicity);
2374 save << " " << "__BEGIN_PERIODICITY_DESCRIPTION__";
2375 save << " " << "__BEGIN_ENTRY1__";
2376 save << " " << periodicity_i.first;
2377 save << " " << "__END_ENTRY1__";
2378 save << " " << "__BEGIN_ENTRY2__";
2379 save << " " << periodicity_i.second;
2380 save << " " << "__END_ENTRY2__";
2381 save << " " << "__END_PERIODICITY_DESCRIPTION__";
2383 save << " " << "__FACES_PERIODICITY_END__";
2387 void BLSURFPlugin_Hypothesis::SaveEdgesPeriodicity(std::ostream & save)
2389 TEdgesPeriodicityVector::const_iterator it_edges_periodicity = _edgesPeriodicityVector.begin();
2390 if (it_edges_periodicity != _edgesPeriodicityVector.end()) {
2391 save << " " << "__EDGES_PERIODICITY_BEGIN__";
2392 for (; it_edges_periodicity != _edgesPeriodicityVector.end(); ++it_edges_periodicity) {
2393 TEdgePeriodicity periodicity_i = (*it_edges_periodicity);
2394 save << " " << "__BEGIN_PERIODICITY_DESCRIPTION__";
2395 if (! periodicity_i.theFace1Entry.empty()){
2396 save << " " << "__BEGIN_FACE1__";
2397 save << " " << periodicity_i.theFace1Entry;
2398 save << " " << "__END_FACE1__";
2400 save << " " << "__BEGIN_EDGE1__";
2401 save << " " << periodicity_i.theEdge1Entry;
2402 save << " " << "__END_EDGE1__";
2403 if (! periodicity_i.theFace2Entry.empty()){
2404 save << " " << "__BEGIN_FACE2__";
2405 save << " " << periodicity_i.theFace2Entry;
2406 save << " " << "__END_FACE2__";
2408 save << " " << "__BEGIN_EDGE2__";
2409 save << " " << periodicity_i.theEdge2Entry;
2410 save << " " << "__END_EDGE2__";
2411 save << " " << "__BEGIN_EDGE_ORIENTATION__";
2412 save << " " << periodicity_i.edge_orientation;
2413 save << " " << "__END_EDGE_ORIENTATION__";
2414 save << " " << "__END_PERIODICITY_DESCRIPTION__";
2416 save << " " << "__EDGES_PERIODICITY_END__";
2420 void BLSURFPlugin_Hypothesis::SaveVerticesPeriodicity(std::ostream & save)
2422 TVerticesPeriodicityVector::const_iterator it_vertices_periodicity = _verticesPeriodicityVector.begin();
2423 if (it_vertices_periodicity != _verticesPeriodicityVector.end()) {
2424 save << " " << "__VERTICES_PERIODICITY_BEGIN__";
2425 for (; it_vertices_periodicity != _verticesPeriodicityVector.end(); ++it_vertices_periodicity) {
2426 TVertexPeriodicity periodicity_i = (*it_vertices_periodicity);
2427 save << " " << "__BEGIN_PERIODICITY_DESCRIPTION__";
2428 save << " " << "__BEGIN_EDGE1__";
2429 save << " " << periodicity_i.theEdge1Entry;
2430 save << " " << "__END_EDGE1__";
2431 save << " " << "__BEGIN_VERTEX1__";
2432 save << " " << periodicity_i.theVertex1Entry;
2433 save << " " << "__END_VERTEX1__";
2434 save << " " << "__BEGIN_EDGE2__";
2435 save << " " << periodicity_i.theEdge2Entry;
2436 save << " " << "__END_EDGE2__";
2437 save << " " << "__BEGIN_VERTEX2__";
2438 save << " " << periodicity_i.theVertex2Entry;
2439 save << " " << "__END_VERTEX2__";
2440 save << " " << "__END_PERIODICITY_DESCRIPTION__";
2442 save << " " << "__VERTICES_PERIODICITY_END__";
2446 void BLSURFPlugin_Hypothesis::SavePreCADPeriodicity(std::ostream & save, const char* shapeType)
2448 TPreCadPeriodicityVector precad_periodicity;
2449 if ( shapeType && strcmp( shapeType, "FACES" ) == 0 )
2450 precad_periodicity = _preCadFacesPeriodicityVector;
2452 precad_periodicity = _preCadEdgesPeriodicityVector;
2453 TPreCadPeriodicityVector::const_iterator it_precad_periodicity = precad_periodicity.begin();
2454 if (it_precad_periodicity != precad_periodicity.end()) {
2455 save << " " << "__PRECAD_" << shapeType << "_PERIODICITY_BEGIN__";
2456 for (; it_precad_periodicity != precad_periodicity.end(); ++it_precad_periodicity) {
2457 TPreCadPeriodicity periodicity_i = (*it_precad_periodicity);
2458 save << " " << "__BEGIN_PERIODICITY_DESCRIPTION__";
2459 if (!periodicity_i.shape1Entry.empty()) {
2460 save << " " << "__BEGIN_ENTRY1__";
2461 save << " " << periodicity_i.shape1Entry;
2462 save << " " << "__END_ENTRY1__";
2464 if (!periodicity_i.shape2Entry.empty()) {
2465 save << " " << "__BEGIN_ENTRY2__";
2466 save << " " << periodicity_i.shape2Entry;
2467 save << " " << "__END_ENTRY2__";
2470 std::vector<std::string>::const_iterator sourceVerticesEntriesIt = periodicity_i.theSourceVerticesEntries.begin();
2471 bool hasSourceVertices = false;
2472 if (sourceVerticesEntriesIt != periodicity_i.theSourceVerticesEntries.end()) {
2473 hasSourceVertices = true;
2474 save << " " << "__BEGIN_SOURCE_VERTICES_LIST__";
2476 for (; sourceVerticesEntriesIt != periodicity_i.theSourceVerticesEntries.end(); ++sourceVerticesEntriesIt)
2477 save << " " << (*sourceVerticesEntriesIt);
2478 if (hasSourceVertices)
2479 save << " " << "__END_SOURCE_VERTICES_LIST__";
2481 std::vector<std::string>::const_iterator targetVerticesEntriesIt = periodicity_i.theTargetVerticesEntries.begin();
2482 bool hasTargetVertices = false;
2483 if (targetVerticesEntriesIt != periodicity_i.theTargetVerticesEntries.end()) {
2484 hasTargetVertices = true;
2485 save << " " << "__BEGIN_TARGET_VERTICES_LIST__";
2487 for (; targetVerticesEntriesIt != periodicity_i.theTargetVerticesEntries.end(); ++targetVerticesEntriesIt)
2488 save << " " << (*targetVerticesEntriesIt);
2489 if (hasTargetVertices)
2490 save << " " << "__END_TARGET_VERTICES_LIST__";
2492 save << " " << "__END_PERIODICITY_DESCRIPTION__";
2494 save << " " << "__PRECAD_" << shapeType << "_PERIODICITY_END__";
2499 //=============================================================================
2500 std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load)
2505 std::string option_or_sm;
2507 isOK = static_cast<bool>(load >> i);
2509 _topology = (Topology) i;
2511 load.clear(std::ios::badbit | load.rdstate());
2513 isOK = static_cast<bool>(load >> i);
2515 _physicalMesh = (PhysicalMesh) i;
2517 load.clear(std::ios::badbit | load.rdstate());
2519 isOK = static_cast<bool>(load >> i);
2521 _geometricMesh = (GeometricMesh) i;
2523 load.clear(std::ios::badbit | load.rdstate());
2525 isOK = static_cast<bool>(load >> val);
2529 load.clear(std::ios::badbit | load.rdstate());
2531 isOK = static_cast<bool>(load >> val);
2535 load.clear(std::ios::badbit | load.rdstate());
2537 isOK = static_cast<bool>(load >> val);
2541 load.clear(std::ios::badbit | load.rdstate());
2543 isOK = static_cast<bool>(load >> i);
2545 _elementType = (ElementType) i;
2547 load.clear(std::ios::badbit | load.rdstate());
2549 isOK = static_cast<bool>(load >> i);
2551 if ( i != -1) { // if value is -1, then this is no longer a standard option
2552 std::string & value = _option2value["respect_geometry"];
2553 bool _decimesh = (bool) i;
2554 value = _decimesh ? "1" : "0";
2558 load.clear(std::ios::badbit | load.rdstate());
2560 isOK = static_cast<bool>(load >> val);
2564 load.clear(std::ios::badbit | load.rdstate());
2566 isOK = static_cast<bool>(load >> val);
2570 load.clear(std::ios::badbit | load.rdstate());
2572 isOK = static_cast<bool>(load >> val);
2574 // former parameter: get min value
2575 _angleMesh = std::min(val,_angleMesh);
2577 load.clear(std::ios::badbit | load.rdstate());
2579 isOK = static_cast<bool>(load >> val);
2581 // former parameter: get min value
2582 _minSize = std::min(val,_minSize);
2584 load.clear(std::ios::badbit | load.rdstate());
2586 isOK = static_cast<bool>(load >> val);
2588 // former parameter: get max value
2589 _maxSize = std::max(val,_maxSize);
2591 load.clear(std::ios::badbit | load.rdstate());
2593 isOK = static_cast<bool>(load >> i);
2597 load.clear(std::ios::badbit | load.rdstate());
2599 isOK = static_cast<bool>(load >> i);
2601 _preCADMergeEdges = (bool) i;
2603 load.clear(std::ios::badbit | load.rdstate());
2605 isOK = static_cast<bool>(load >> i);
2607 if ( i != -1) { // if value is -1, then this is no longer a standard option
2608 std::string & value = _preCADoption2value["remove_tiny_edges"];
2609 bool _preCADRemoveNanoEdges = (bool) i;
2610 value = _preCADRemoveNanoEdges ? "1" : "0";
2614 load.clear(std::ios::badbit | load.rdstate());
2616 isOK = static_cast<bool>(load >> i);
2618 _preCADDiscardInput = (bool) i;
2620 load.clear(std::ios::badbit | load.rdstate());
2622 isOK = static_cast<bool>(load >> val);
2623 if (isOK) { // _preCADEpsNano
2624 if ( (i + 1.0) < 1e-6 ) { // if value is -1, then this is no longer a standard option: get optional value "tiny_edge_length" instead
2625 std::string & value = _preCADoption2value["tiny_edge_length"];
2626 std::ostringstream oss;
2632 load.clear(std::ios::badbit | load.rdstate());
2634 isOK = static_cast<bool>(load >> i);
2636 _enforcedInternalVerticesAllFaces = (bool) i;
2638 load.clear(std::ios::badbit | load.rdstate());
2640 // New options with MeshGems-CADSurf
2642 bool hasCADSurfOptions = false;
2643 bool hasOptions = false;
2644 bool hasCustomOptions = false;
2645 bool hasPreCADOptions = false;
2646 bool hasSizeMap = false;
2647 bool hasAttractor = false;
2648 bool hasNewAttractor = false;
2649 bool hasEnforcedVertex = false;
2650 bool hasPreCADFacesPeriodicity = false;
2651 bool hasPreCADEdgesPeriodicity = false;
2652 bool hasFacesPeriodicity = false;
2653 bool hasEdgesPeriodicity = false;
2654 bool hasVerticesPeriodicity = false;
2656 isOK = static_cast<bool>(load >> option_or_sm);
2658 if (( option_or_sm == "1" ) || ( option_or_sm == "0" )) {
2659 i = atoi(option_or_sm.c_str());
2660 hasCADSurfOptions = true;
2661 _phySizeRel = (bool) i;
2663 else if (option_or_sm == "__OPTIONS_BEGIN__")
2665 else if (option_or_sm == "__CUSTOM_OPTIONS_BEGIN__")
2666 hasCustomOptions = true;
2667 else if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__")
2668 hasPreCADOptions = true;
2669 else if (option_or_sm == "__SIZEMAP_BEGIN__")
2671 else if (option_or_sm == "__ATTRACTORS_BEGIN__")
2672 hasAttractor = true;
2673 else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2674 hasNewAttractor = true;
2675 else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2676 hasEnforcedVertex = true;
2677 else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2678 hasPreCADFacesPeriodicity = true;
2679 else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2680 hasPreCADEdgesPeriodicity = true;
2681 else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2682 hasFacesPeriodicity = true;
2683 else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2684 hasEdgesPeriodicity = true;
2685 else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2686 hasVerticesPeriodicity = true;
2689 if (isOK && hasCADSurfOptions) {
2690 isOK = static_cast<bool>(load >> i);
2692 _minSizeRel = (bool) i;
2694 load.clear(std::ios::badbit | load.rdstate());
2696 isOK = static_cast<bool>(load >> i);
2698 _maxSizeRel = (bool) i;
2700 load.clear(std::ios::badbit | load.rdstate());
2702 isOK = static_cast<bool>(load >> val);
2704 _chordalError = val;
2706 load.clear(std::ios::badbit | load.rdstate());
2708 isOK = static_cast<bool>(load >> i);
2710 _anisotropic = (bool) i;
2712 load.clear(std::ios::badbit | load.rdstate());
2714 isOK = static_cast<bool>(load >> val);
2716 _anisotropicRatio = val;
2718 load.clear(std::ios::badbit | load.rdstate());
2720 isOK = static_cast<bool>(load >> i);
2722 _removeTinyEdges = (bool) i;
2724 load.clear(std::ios::badbit | load.rdstate());
2726 isOK = static_cast<bool>(load >> val);
2728 _tinyEdgeLength = val;
2730 load.clear(std::ios::badbit | load.rdstate());
2732 isOK = static_cast<bool>(load >> i);
2734 _badElementRemoval = (bool) i;
2736 load.clear(std::ios::badbit | load.rdstate());
2738 isOK = static_cast<bool>(load >> val);
2740 _badElementAspectRatio = val;
2742 load.clear(std::ios::badbit | load.rdstate());
2744 isOK = static_cast<bool>(load >> i);
2746 _optimizeMesh = (bool) i;
2748 load.clear(std::ios::badbit | load.rdstate());
2750 isOK = static_cast<bool>(load >> i);
2752 _quadraticMesh = (bool) i;
2754 load.clear(std::ios::badbit | load.rdstate());
2756 isOK = static_cast<bool>(load >> i);
2758 _preCADProcess3DTopology = (bool) i;
2760 load.clear(std::ios::badbit | load.rdstate());
2762 if (( load >> std::ws).peek() != '_' )
2764 isOK = static_cast<bool>(load >> i);
2766 _preCADRemoveDuplicateCADFaces = (bool) i;
2768 load.clear(std::ios::badbit | load.rdstate());
2770 isOK = static_cast<bool>(load >> i);
2772 _optimiseTinyEdges = (bool) i;
2774 load.clear(std::ios::badbit | load.rdstate());
2776 isOK = static_cast<bool>(load >> val);
2778 _tinyEdgeOptimisationLength = val;
2780 load.clear(std::ios::badbit | load.rdstate());
2782 isOK = static_cast<bool>(load >> i);
2784 _correctSurfaceIntersec = (bool) i;
2786 load.clear(std::ios::badbit | load.rdstate());
2788 isOK = static_cast<bool>(load >> val);
2790 _corrSurfaceIntersCost = val;
2792 load.clear(std::ios::badbit | load.rdstate());
2794 isOK = static_cast<bool>(load >> i);
2796 _useGradation = (bool) i;
2798 load.clear(std::ios::badbit | load.rdstate());
2800 isOK = static_cast<bool>(load >> i);
2802 _useVolumeGradation = (bool) i;
2804 load.clear(std::ios::badbit | load.rdstate());
2806 isOK = static_cast<bool>(load >> val);
2808 _volumeGradation = val;
2810 load.clear(std::ios::badbit | load.rdstate());
2815 if (hasCADSurfOptions) {
2816 isOK = static_cast<bool>(load >> option_or_sm);
2818 if (option_or_sm == "__OPTIONS_BEGIN__")
2820 else if (option_or_sm == "__CUSTOM_OPTIONS_BEGIN__")
2821 hasCustomOptions = true;
2822 else if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__")
2823 hasPreCADOptions = true;
2824 else if (option_or_sm == "__SIZEMAP_BEGIN__")
2826 else if (option_or_sm == "__ATTRACTORS_BEGIN__")
2827 hasAttractor = true;
2828 else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2829 hasNewAttractor = true;
2830 else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2831 hasEnforcedVertex = true;
2832 else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2833 hasPreCADFacesPeriodicity = true;
2834 else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2835 hasPreCADEdgesPeriodicity = true;
2836 else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2837 hasFacesPeriodicity = true;
2838 else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2839 hasEdgesPeriodicity = true;
2840 else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2841 hasVerticesPeriodicity = true;
2845 std::string optName, optValue;
2846 while (isOK && hasOptions) {
2847 isOK = static_cast<bool>(load >> optName);
2849 if (optName == "__OPTIONS_END__")
2851 isOK = static_cast<bool>(load >> optValue);
2853 // read the value of the advanced option
2854 // unless this option is no more used
2856 #if MESHGEMS_VERSION_HEX >= 0x020A00
2857 && optName != "enforce_cad_edge_sizes" && optName != "max_number_of_points_per_patch"
2860 std::string & value = _option2value[optName];
2862 int len = (int) value.size();
2863 // continue reading until "%#" encountered
2864 while (value[len - 1] != '#' || value[len - 2] != '%') {
2865 isOK = static_cast<bool>(load >> optValue);
2869 len = (int) value.size();
2874 if ( value[ len - 1] == '#' )
2875 value.resize(len - 2); //cut off "%#"
2880 isOK = static_cast<bool>(load >> option_or_sm);
2882 if (option_or_sm == "__CUSTOM_OPTIONS_BEGIN__")
2883 hasCustomOptions = true;
2884 else if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__")
2885 hasPreCADOptions = true;
2886 else if (option_or_sm == "__SIZEMAP_BEGIN__")
2888 else if (option_or_sm == "__ATTRACTORS_BEGIN__")
2889 hasAttractor = true;
2890 else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2891 hasNewAttractor = true;
2892 else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2893 hasEnforcedVertex = true;
2894 else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2895 hasPreCADFacesPeriodicity = true;
2896 else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2897 hasPreCADEdgesPeriodicity = true;
2898 else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2899 hasFacesPeriodicity = true;
2900 else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2901 hasEdgesPeriodicity = true;
2902 else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2903 hasVerticesPeriodicity = true;
2907 while (isOK && hasCustomOptions) {
2908 isOK = static_cast<bool>(load >> optName);
2910 if (optName == "__CUSTOM_OPTIONS_END__")
2912 isOK = static_cast<bool>(load >> optValue);
2915 std::string& value = optValue;
2916 int len = (int) value.size();
2917 // continue reading until "%#" encountered
2918 while (value[len - 1] != '#' || value[len - 2] != '%') {
2919 isOK = static_cast<bool>(load >> optValue);
2923 len = (int) value.size();
2928 if ( value[ len - 1] == '#' )
2929 value.resize(len - 2); //cut off "%#"
2930 _customOption2value[optName] = value;
2934 if (hasCustomOptions) {
2935 isOK = static_cast<bool>(load >> option_or_sm);
2937 if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__")
2938 hasPreCADOptions = true;
2939 else if (option_or_sm == "__SIZEMAP_BEGIN__")
2941 else if (option_or_sm == "__ATTRACTORS_BEGIN__")
2942 hasAttractor = true;
2943 else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2944 hasNewAttractor = true;
2945 else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2946 hasEnforcedVertex = true;
2947 else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2948 hasPreCADFacesPeriodicity = true;
2949 else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2950 hasPreCADEdgesPeriodicity = true;
2951 else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2952 hasFacesPeriodicity = true;
2953 else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2954 hasEdgesPeriodicity = true;
2955 else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2956 hasVerticesPeriodicity = true;
2960 while (isOK && hasPreCADOptions) {
2961 isOK = static_cast<bool>(load >> optName);
2963 if (optName == "__PRECAD_OPTIONS_END__")
2965 isOK = static_cast<bool>(load >> optValue);
2968 std::string & value = _preCADoption2value[optName];
2970 int len = (int) value.size();
2971 // continue reading until "%#" encountered
2972 while (value[len - 1] != '#' || value[len - 2] != '%') {
2973 isOK = static_cast<bool>(load >> optValue);
2977 len = (int) value.size();
2982 if ( value[ len - 1] == '#' )
2983 value.resize(len - 2); //cut off "%#"
2987 if (hasPreCADOptions) {
2988 isOK = static_cast<bool>(load >> option_or_sm);
2990 if (option_or_sm == "__SIZEMAP_BEGIN__")
2992 else if (option_or_sm == "__ATTRACTORS_BEGIN__")
2993 hasAttractor = true;
2994 else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2995 hasNewAttractor = true;
2996 else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2997 hasEnforcedVertex = true;
2998 else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2999 hasPreCADFacesPeriodicity = true;
3000 else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
3001 hasPreCADEdgesPeriodicity = true;
3002 else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
3003 hasFacesPeriodicity = true;
3004 else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
3005 hasEdgesPeriodicity = true;
3006 else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3007 hasVerticesPeriodicity = true;
3011 std::string smEntry, smValue;
3012 while (isOK && hasSizeMap) {
3013 isOK = static_cast<bool>(load >> smEntry);
3015 if (smEntry == "__SIZEMAP_END__")
3017 isOK = static_cast<bool>(load >> smValue);
3020 std::string & value2 = _sizeMap[smEntry];
3022 int len2 = (int) value2.size();
3023 // continue reading until "%#" encountered
3024 while (value2[len2 - 1] != '#' || value2[len2 - 2] != '%') {
3025 isOK = static_cast<bool>(load >> smValue);
3029 len2 = (int) value2.size();
3034 value2.resize(len2 - 2); //cut off "%#"
3039 isOK = static_cast<bool>(load >> option_or_sm);
3041 if (option_or_sm == "__ATTRACTORS_BEGIN__")
3042 hasAttractor = true;
3043 else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
3044 hasNewAttractor = true;
3045 else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
3046 hasEnforcedVertex = true;
3047 else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
3048 hasPreCADFacesPeriodicity = true;
3049 else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
3050 hasPreCADEdgesPeriodicity = true;
3051 else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
3052 hasFacesPeriodicity = true;
3053 else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
3054 hasEdgesPeriodicity = true;
3055 else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3056 hasVerticesPeriodicity = true;
3060 std::string atEntry, atValue;
3061 while (isOK && hasAttractor) {
3062 isOK = static_cast<bool>(load >> atEntry);
3064 if (atEntry == "__ATTRACTORS_END__")
3066 isOK = static_cast<bool>(load >> atValue);
3069 std::string & value3 = _attractors[atEntry];
3071 int len3 = (int) value3.size();
3072 // continue reading until "%#" encountered
3073 while (value3[len3 - 1] != '#' || value3[len3 - 2] != '%') {
3074 isOK = static_cast<bool>(load >> atValue);
3078 len3 = (int) value3.size();
3083 value3.resize(len3 - 2); //cut off "%#"
3088 isOK = static_cast<bool>(load >> option_or_sm);
3090 if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
3091 hasNewAttractor = true;
3092 else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
3093 hasEnforcedVertex = true;
3094 else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
3095 hasPreCADFacesPeriodicity = true;
3096 else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
3097 hasPreCADEdgesPeriodicity = true;
3098 else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
3099 hasFacesPeriodicity = true;
3100 else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
3101 hasEdgesPeriodicity = true;
3102 else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3103 hasVerticesPeriodicity = true;
3107 std::string newAtFaceEntry, atTestString;
3108 std::string newAtShapeEntry;
3109 double attParams[4];
3111 while (isOK && hasNewAttractor) {
3112 //std::cout<<"Load new attractor"<<std::endl;
3113 isOK = static_cast<bool>(load >> newAtFaceEntry);
3115 if (newAtFaceEntry == "__NEW_ATTRACTORS_END__")
3117 isOK = static_cast<bool>(load >> newAtShapeEntry);
3120 isOK = static_cast<bool>(load >> attParams[0]>>attParams[1]>>attParams[2]>>attParams[3]); //>>step);
3123 const TopoDS_Shape attractorShape = BLSURFPlugin_Hypothesis::entryToShape(newAtShapeEntry);
3124 const TopoDS_Face faceShape = TopoDS::Face(BLSURFPlugin_Hypothesis::entryToShape(newAtFaceEntry));
3125 BLSURFPlugin_Attractor* attractor = new BLSURFPlugin_Attractor(faceShape, attractorShape, newAtShapeEntry);//, step);
3126 attractor->SetParameters(attParams[0], attParams[1], attParams[2], attParams[3]);
3127 //attractor->BuildMap();
3128 _classAttractors.insert( make_pair( newAtFaceEntry, attractor ));
3133 if (hasNewAttractor) {
3134 isOK = static_cast<bool>(load >> option_or_sm);
3136 if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
3137 hasEnforcedVertex = true;
3138 else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
3139 hasPreCADFacesPeriodicity = true;
3140 else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
3141 hasPreCADEdgesPeriodicity = true;
3142 else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
3143 hasFacesPeriodicity = true;
3144 else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
3145 hasEdgesPeriodicity = true;
3146 else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3147 hasVerticesPeriodicity = true;
3153 // Here is a example of the saved stream:
3154 // __ENFORCED_VERTICES_BEGIN__
3155 // __BEGIN_VERTEX__ => no name, no entry
3156 // __BEGIN_GROUP__ mon groupe __END_GROUP__
3157 // __BEGIN_COORDS__ 10 10 10 __END_COORDS__
3158 // __BEGIN_FACELIST__ 0:1:1:1:1 __END_FACELIST__
3160 // __BEGIN_VERTEX__ => no coords
3161 // __BEGIN_NAME__ mes points __END_NAME__
3162 // __BEGIN_ENTRY__ 0:1:1:4 __END_ENTRY__
3163 // __BEGIN_GROUP__ mon groupe __END_GROUP__
3164 // __BEGIN_FACELIST__ 0:1:1:1:3 __END_FACELIST__
3166 // __ENFORCED_VERTICES_END__
3169 std::string enfSeparator;
3170 std::string enfName;
3171 std::string enfGeomEntry;
3172 std::string enfGroup;
3173 TEntryList enfFaceEntryList;
3174 double enfCoords[3];
3175 bool hasCoords = false;
3177 _faceEntryEnfVertexListMap.clear();
3178 _enfVertexList.clear();
3179 _faceEntryCoordsListMap.clear();
3180 _coordsEnfVertexMap.clear();
3181 _faceEntryEnfVertexEntryListMap.clear();
3182 _enfVertexEntryEnfVertexMap.clear();
3185 while (isOK && hasEnforcedVertex)
3187 isOK = static_cast<bool>(load >> enfSeparator); // __BEGIN_VERTEX__
3188 TEnfVertex *enfVertex = new TEnfVertex();
3189 if (enfSeparator == "__ENFORCED_VERTICES_END__")
3190 break; // __ENFORCED_VERTICES_END__
3191 if (enfSeparator != "__BEGIN_VERTEX__")
3192 throw std::exception();
3195 isOK = static_cast<bool>(load >> enfSeparator);
3196 if (enfSeparator == "__END_VERTEX__") {
3198 enfVertex->name = enfName;
3199 enfVertex->geomEntry = enfGeomEntry;
3200 enfVertex->grpName = enfGroup;
3201 enfVertex->coords.clear();
3203 enfVertex->coords.assign(enfCoords,enfCoords+3);
3204 enfVertex->faceEntries = enfFaceEntryList;
3206 _enfVertexList.insert(enfVertex);
3208 if (enfVertex->coords.size()) {
3209 _coordsEnfVertexMap[enfVertex->coords] = enfVertex;
3210 for (TEntryList::const_iterator it = enfVertex->faceEntries.begin() ; it != enfVertex->faceEntries.end(); ++it) {
3211 _faceEntryCoordsListMap[(*it)].insert(enfVertex->coords);
3212 _faceEntryEnfVertexListMap[(*it)].insert(enfVertex);
3215 if (!enfVertex->geomEntry.empty()) {
3216 _enfVertexEntryEnfVertexMap[enfVertex->geomEntry] = enfVertex;
3217 for (TEntryList::const_iterator it = enfVertex->faceEntries.begin() ; it != enfVertex->faceEntries.end(); ++it) {
3218 _faceEntryEnfVertexEntryListMap[(*it)].insert(enfVertex->geomEntry);
3219 _faceEntryEnfVertexListMap[(*it)].insert(enfVertex);
3224 enfGeomEntry.clear();
3226 enfFaceEntryList.clear();
3228 break; // __END_VERTEX__
3231 if (enfSeparator == "__BEGIN_NAME__") { // __BEGIN_NAME__
3232 while (isOK && (enfSeparator != "__END_NAME__")) {
3233 isOK = static_cast<bool>(load >> enfSeparator);
3234 if (enfSeparator != "__END_NAME__") {
3235 if (!enfName.empty())
3237 enfName += enfSeparator;
3242 if (enfSeparator == "__BEGIN_ENTRY__") { // __BEGIN_ENTRY__
3243 isOK = static_cast<bool>(load >> enfGeomEntry);
3244 isOK = static_cast<bool>(load >> enfSeparator); // __END_ENTRY__
3245 if (enfSeparator != "__END_ENTRY__")
3246 throw std::exception();
3249 if (enfSeparator == "__BEGIN_GROUP__") { // __BEGIN_GROUP__
3250 while (isOK && (enfSeparator != "__END_GROUP__")) {
3251 isOK = static_cast<bool>(load >> enfSeparator);
3252 if (enfSeparator != "__END_GROUP__") {
3253 if (!enfGroup.empty())
3255 enfGroup += enfSeparator;
3260 if (enfSeparator == "__BEGIN_COORDS__") { // __BEGIN_COORDS__
3262 isOK = static_cast<bool>(load >> enfCoords[0] >> enfCoords[1] >> enfCoords[2]);
3263 isOK = static_cast<bool>(load >> enfSeparator); // __END_COORDS__
3264 if (enfSeparator != "__END_COORDS__")
3265 throw std::exception();
3268 if (enfSeparator == "__BEGIN_FACELIST__") { // __BEGIN_FACELIST__
3269 while (isOK && (enfSeparator != "__END_FACELIST__")) {
3270 isOK = static_cast<bool>(load >> enfSeparator);
3271 if (enfSeparator != "__END_FACELIST__") {
3272 enfFaceEntryList.insert(enfSeparator);
3279 if ( hasEnforcedVertex ) {
3280 isOK = static_cast<bool>(load >> option_or_sm);
3282 if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
3283 hasPreCADFacesPeriodicity = true;
3284 else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
3285 hasPreCADEdgesPeriodicity = true;
3286 else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
3287 hasFacesPeriodicity = true;
3288 else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
3289 hasEdgesPeriodicity = true;
3290 else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3291 hasVerticesPeriodicity = true;
3297 if (hasPreCADFacesPeriodicity)
3299 LoadPreCADPeriodicity(load, "FACES");
3301 isOK = static_cast<bool>(load >> option_or_sm);
3303 if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
3304 hasPreCADEdgesPeriodicity = true;
3305 else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
3306 hasFacesPeriodicity = true;
3307 else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
3308 hasEdgesPeriodicity = true;
3309 else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3310 hasVerticesPeriodicity = true;
3314 if (hasPreCADEdgesPeriodicity)
3316 LoadPreCADPeriodicity(load, "EDGES");
3318 isOK = static_cast<bool>(load >> option_or_sm);
3320 if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
3321 hasFacesPeriodicity = true;
3322 else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
3323 hasEdgesPeriodicity = true;
3324 else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3325 hasVerticesPeriodicity = true;
3329 if (hasFacesPeriodicity)
3331 LoadFacesPeriodicity(load);
3333 isOK = static_cast<bool>(load >> option_or_sm);
3335 if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
3336 hasEdgesPeriodicity = true;
3337 else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3338 hasVerticesPeriodicity = true;
3342 if (hasEdgesPeriodicity)
3344 LoadEdgesPeriodicity(load);
3346 isOK = static_cast<bool>(load >> option_or_sm);
3348 if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3349 hasVerticesPeriodicity = true;
3352 if (hasVerticesPeriodicity)
3353 LoadVerticesPeriodicity(load);
3356 if ( !option_or_sm.empty() && option_or_sm[0] == '_' )
3357 isOK = static_cast<bool>(load >> option_or_sm);
3358 if ( isOK && !option_or_sm.empty() )
3360 int nbPatches = atoi( option_or_sm.c_str() );
3361 if ( nbPatches >= 0 )
3363 _hyperPatchList.resize( nbPatches );
3364 for ( int iP = 0; iP < nbPatches && isOK; ++iP )
3366 isOK = static_cast<bool>(load >> i) && i >= 2;
3369 for ( int iT = 0; iT < nbTags; ++iT )
3371 if (( isOK = static_cast<bool>(load >> i)))
3372 _hyperPatchList[ iP ].insert( i );
3377 if ( !isOK ) // remove invalid patches
3379 for ( i = nbPatches - 1; i >= 0; i-- )
3380 if ( _hyperPatchList[i].size() < 2 )
3381 _hyperPatchList.resize( i );
3386 // New options in 2.9.6 (issue #17784)
3387 if ( static_cast<bool>( load >> _useSurfaceProximity ))
3389 load >> _nbSurfaceProximityLayers;
3390 load >> _surfaceProximityRatio;
3391 load >> _useVolumeProximity;
3392 load >> _nbVolumeProximityLayers;
3393 isOK = static_cast<bool>( load >> _volumeProximityRatio );
3396 // hyper-patches as entries (issue bos #20543)
3398 if ( SMESHDS_Hypothesis::LoadStringFromStream( load, buffer ))
3401 SMESHUtils::BoostTxtArchive( buffer ) >> _hyperPatchEntriesList;
3402 SMESH_CATCH( SMESH::printErrorInDebugMode );
3405 // Enforced meshes (issue bos $16292)
3407 if ( SMESHDS_Hypothesis::LoadStringFromStream( load, buffer ))
3410 SMESHUtils::BoostTxtArchive( buffer ) >> _enforcedMeshes;
3411 SMESH_CATCH( SMESH::printErrorInDebugMode );
3418 namespace serialization {
3420 //=======================================================================
3421 //function : serialize
3422 //purpose : serialize EnforcedMesh
3423 //=======================================================================
3425 template<class Archive>
3426 void serialize(Archive & ar, BLSURFPlugin_Hypothesis::EnforcedMesh & enfM,
3427 const unsigned int /*version*/)
3432 ar & enfM._groupName;
3435 } // namespace serialization
3436 } // namespace boost
3439 void BLSURFPlugin_Hypothesis::LoadFacesPeriodicity(std::istream & load)
3443 std::string periodicitySeparator;
3447 _facesPeriodicityVector.clear();
3450 isOK = static_cast<bool>(load >> periodicitySeparator); // __BEGIN_PERIODICITY_DESCRIPTION__
3451 TFacesPeriodicity *periodicity_i = new TFacesPeriodicity();
3452 if (periodicitySeparator == "__FACES_PERIODICITY_END__")
3453 break; // __FACES_PERIODICITY_END__
3454 if (periodicitySeparator != "__BEGIN_PERIODICITY_DESCRIPTION__"){
3455 throw std::exception();
3459 isOK = static_cast<bool>(load >> periodicitySeparator);
3460 if (periodicitySeparator == "__END_PERIODICITY_DESCRIPTION__") {
3462 periodicity_i->first = shape1Entry;
3463 periodicity_i->second = shape2Entry;
3465 _facesPeriodicityVector.push_back(*periodicity_i);
3467 break; // __END_PERIODICITY_DESCRIPTION__
3470 if (periodicitySeparator == "__BEGIN_ENTRY1__") { // __BEGIN_ENTRY1__
3471 isOK = static_cast<bool>(load >> shape1Entry);
3472 isOK = static_cast<bool>(load >> periodicitySeparator); // __END_ENTRY1__
3473 if (periodicitySeparator != "__END_ENTRY1__")
3474 throw std::exception();
3477 if (periodicitySeparator == "__BEGIN_ENTRY2__") { // __BEGIN_ENTRY2__
3478 isOK = static_cast<bool>(load >> shape2Entry);
3479 isOK = static_cast<bool>(load >> periodicitySeparator); // __END_ENTRY2__
3480 if (periodicitySeparator != "__END_ENTRY2__")
3481 throw std::exception();
3488 void BLSURFPlugin_Hypothesis::LoadEdgesPeriodicity(std::istream & load)
3492 std::string periodicitySeparator;
3493 TEntry theFace1Entry;
3494 TEntry theEdge1Entry;
3495 TEntry theFace2Entry;
3496 TEntry theEdge2Entry;
3497 int edge_orientation = 0;
3499 _edgesPeriodicityVector.clear();
3502 isOK = static_cast<bool>(load >> periodicitySeparator); // __BEGIN_PERIODICITY_DESCRIPTION__
3503 TEdgePeriodicity *periodicity_i = new TEdgePeriodicity();
3504 if (periodicitySeparator == "__EDGES_PERIODICITY_END__")
3505 break; // __EDGES_PERIODICITY_END__
3506 if (periodicitySeparator != "__BEGIN_PERIODICITY_DESCRIPTION__"){
3507 throw std::exception();
3511 isOK = static_cast<bool>(load >> periodicitySeparator);
3512 if (periodicitySeparator == "__END_PERIODICITY_DESCRIPTION__") {
3514 periodicity_i->theFace1Entry = theFace1Entry;
3515 periodicity_i->theEdge1Entry = theEdge1Entry;
3516 periodicity_i->theFace2Entry = theFace2Entry;
3517 periodicity_i->theEdge2Entry = theEdge2Entry;
3518 periodicity_i->edge_orientation = edge_orientation;
3520 _edgesPeriodicityVector.push_back(*periodicity_i);
3522 break; // __END_PERIODICITY_DESCRIPTION__
3525 if (periodicitySeparator == "__BEGIN_FACE1__") { // __BEGIN_FACE1__
3526 isOK = static_cast<bool>(load >> theFace1Entry);
3527 isOK = static_cast<bool>(load >> periodicitySeparator); // __END_FACE1__
3528 if (periodicitySeparator != "__END_FACE1__"){
3529 throw std::exception();
3533 if (periodicitySeparator == "__BEGIN_EDGE1__") { // __BEGIN_EDGE1__
3534 isOK = static_cast<bool>(load >> theEdge1Entry);
3535 isOK = static_cast<bool>(load >> periodicitySeparator); // __END_EDGE1__
3536 if (periodicitySeparator != "__END_EDGE1__")
3537 throw std::exception();
3540 if (periodicitySeparator == "__BEGIN_FACE2__") { // __BEGIN_FACE2__
3541 isOK = static_cast<bool>(load >> theFace2Entry);
3542 isOK = static_cast<bool>(load >> periodicitySeparator); // __END_FACE2__
3543 if (periodicitySeparator != "__END_FACE2__")
3544 throw std::exception();
3547 if (periodicitySeparator == "__BEGIN_EDGE2__") { // __BEGIN_EDGE2__
3548 isOK = static_cast<bool>(load >> theEdge2Entry);
3549 isOK = static_cast<bool>(load >> periodicitySeparator); // __END_EDGE2__
3550 if (periodicitySeparator != "__END_EDGE2__")
3551 throw std::exception();
3554 if (periodicitySeparator == "__BEGIN_EDGE_ORIENTATION__") { // __BEGIN_EDGE_ORIENTATION__
3555 isOK = static_cast<bool>(load >> edge_orientation);
3556 isOK = static_cast<bool>(load >> periodicitySeparator); // __END_EDGE_ORIENTATION__
3557 if (periodicitySeparator != "__END_EDGE_ORIENTATION__")
3558 throw std::exception();
3564 void BLSURFPlugin_Hypothesis::LoadVerticesPeriodicity(std::istream & load)
3568 std::string periodicitySeparator;
3569 TEntry theEdge1Entry;
3570 TEntry theVertex1Entry;
3571 TEntry theEdge2Entry;
3572 TEntry theVertex2Entry;
3574 _verticesPeriodicityVector.clear();
3577 isOK = static_cast<bool>(load >> periodicitySeparator); // __BEGIN_PERIODICITY_DESCRIPTION__
3578 TVertexPeriodicity *periodicity_i = new TVertexPeriodicity();
3579 if (periodicitySeparator == "__VERTICES_PERIODICITY_END__")
3580 break; // __VERTICES_PERIODICITY_END__
3581 if (periodicitySeparator != "__BEGIN_PERIODICITY_DESCRIPTION__"){
3582 throw std::exception();
3586 isOK = static_cast<bool>(load >> periodicitySeparator);
3587 if (periodicitySeparator == "__END_PERIODICITY_DESCRIPTION__") {
3589 periodicity_i->theEdge1Entry = theEdge1Entry;
3590 periodicity_i->theVertex1Entry = theVertex1Entry;
3591 periodicity_i->theEdge2Entry = theEdge2Entry;
3592 periodicity_i->theVertex2Entry = theVertex2Entry;
3594 _verticesPeriodicityVector.push_back(*periodicity_i);
3596 break; // __END_PERIODICITY_DESCRIPTION__
3599 if (periodicitySeparator == "__BEGIN_EDGE1__") { // __BEGIN_EDGE1__
3600 isOK = static_cast<bool>(load >> theEdge1Entry);
3601 isOK = static_cast<bool>(load >> periodicitySeparator); // __END_EDGE1__
3602 if (periodicitySeparator != "__END_EDGE1__")
3603 throw std::exception();
3606 if (periodicitySeparator == "__BEGIN_VERTEX1__") { // __BEGIN_VERTEX1__
3607 isOK = static_cast<bool>(load >> theVertex1Entry);
3608 isOK = static_cast<bool>(load >> periodicitySeparator); // __END_VERTEX1__
3609 if (periodicitySeparator != "__END_VERTEX1__")
3610 throw std::exception();
3613 if (periodicitySeparator == "__BEGIN_EDGE2__") { // __BEGIN_EDGE2__
3614 isOK = static_cast<bool>(load >> theEdge2Entry);
3615 isOK = static_cast<bool>(load >> periodicitySeparator); // __END_EDGE2__
3616 if (periodicitySeparator != "__END_EDGE2__")
3617 throw std::exception();
3620 if (periodicitySeparator == "__BEGIN_VERTEX2__") { // __BEGIN_VERTEX2__
3621 isOK = static_cast<bool>(load >> theVertex2Entry);
3622 isOK = static_cast<bool>(load >> periodicitySeparator); // __END_VERTEX2__
3623 if (periodicitySeparator != "__END_VERTEX2__")
3624 throw std::exception();
3630 void BLSURFPlugin_Hypothesis::LoadPreCADPeriodicity(std::istream & load, const char* shapeType)
3634 std::string periodicitySeparator;
3637 std::vector<std::string> theSourceVerticesEntries;
3638 std::vector<std::string> theTargetVerticesEntries;
3640 bool hasSourceVertices = false;
3641 bool hasTargetVertices = false;
3643 if ( shapeType && strcmp( shapeType, "FACES") == 0 )
3644 _preCadFacesPeriodicityVector.clear();
3646 _preCadEdgesPeriodicityVector.clear();
3650 isOK = static_cast<bool>(load >> periodicitySeparator); // __BEGIN_PERIODICITY_DESCRIPTION__
3651 TPreCadPeriodicity *periodicity_i = new TPreCadPeriodicity();
3652 std::string endSeparator = "__PRECAD_" + std::string(shapeType) + "_PERIODICITY_END__";
3653 if (periodicitySeparator == endSeparator)
3654 break; // __PRECAD_FACES_PERIODICITY_END__
3655 if (periodicitySeparator != "__BEGIN_PERIODICITY_DESCRIPTION__"){
3656 throw std::exception();
3660 isOK = static_cast<bool>(load >> periodicitySeparator);
3661 if (periodicitySeparator == "__END_PERIODICITY_DESCRIPTION__") {
3663 periodicity_i->shape1Entry = shape1Entry;
3664 periodicity_i->shape2Entry = shape2Entry;
3666 if (hasSourceVertices)
3667 periodicity_i->theSourceVerticesEntries = theSourceVerticesEntries;
3668 if (hasTargetVertices)
3669 periodicity_i->theTargetVerticesEntries = theTargetVerticesEntries;
3671 if ( shapeType && strcmp( shapeType, "FACES" ) == 0 )
3672 _preCadFacesPeriodicityVector.push_back(*periodicity_i);
3674 _preCadEdgesPeriodicityVector.push_back(*periodicity_i);
3676 theSourceVerticesEntries.clear();
3677 theTargetVerticesEntries.clear();
3678 hasSourceVertices = false;
3679 hasTargetVertices = false;
3680 break; // __END_PERIODICITY_DESCRIPTION__
3683 if (periodicitySeparator == "__BEGIN_ENTRY1__") { // __BEGIN_ENTRY1__
3684 isOK = static_cast<bool>(load >> shape1Entry);
3685 isOK = static_cast<bool>(load >> periodicitySeparator); // __END_ENTRY1__
3686 if (periodicitySeparator != "__END_ENTRY1__")
3687 throw std::exception();
3690 if (periodicitySeparator == "__BEGIN_ENTRY2__") { // __BEGIN_ENTRY2__
3691 isOK = static_cast<bool>(load >> shape2Entry);
3692 isOK = static_cast<bool>(load >> periodicitySeparator); // __END_ENTRY2__
3693 if (periodicitySeparator != "__END_ENTRY2__")
3694 throw std::exception();
3697 if (periodicitySeparator == "__BEGIN_SOURCE_VERTICES_LIST__") { // __BEGIN_SOURCE_VERTICES_LIST__
3698 hasSourceVertices = true;
3699 while (isOK && (periodicitySeparator != "__END_SOURCE_VERTICES_LIST__")) {
3700 isOK = static_cast<bool>(load >> periodicitySeparator);
3701 if (periodicitySeparator != "__END_SOURCE_VERTICES_LIST__") {
3702 theSourceVerticesEntries.push_back(periodicitySeparator);
3707 if (periodicitySeparator == "__BEGIN_TARGET_VERTICES_LIST__") { // __BEGIN_TARGET_VERTICES_LIST__
3708 hasTargetVertices = true;
3709 while (isOK && (periodicitySeparator != "__END_TARGET_VERTICES_LIST__")) {
3710 isOK = static_cast<bool>(load >> periodicitySeparator);
3711 if (periodicitySeparator != "__END_TARGET_VERTICES_LIST__") {
3712 theTargetVerticesEntries.push_back(periodicitySeparator);
3720 //=============================================================================
3721 std::ostream & operator <<(std::ostream & save, BLSURFPlugin_Hypothesis & hyp) {
3722 return hyp.SaveTo(save);
3725 //=============================================================================
3726 std::istream & operator >>(std::istream & load, BLSURFPlugin_Hypothesis & hyp) {
3727 return hyp.LoadFrom(load);
3730 //================================================================================
3732 * \brief Does nothing
3734 //================================================================================
3736 bool BLSURFPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* /*theMesh*/, const TopoDS_Shape& /*theShape*/)
3741 //================================================================================
3743 * \brief Returns default global constant physical size given a default value of element length ratio
3745 //================================================================================
3747 double BLSURFPlugin_Hypothesis::GetDefaultPhySize(double diagonal, double bbSegmentation)
3749 if (bbSegmentation != 0 && diagonal != 0)
3750 return diagonal / bbSegmentation ;
3754 //================================================================================
3756 * \brief Returns default min size given a default value of element length ratio
3758 //================================================================================
3760 double BLSURFPlugin_Hypothesis::GetDefaultMinSize(double diagonal)
3763 return diagonal / 1000.0 ;
3764 return undefinedDouble();
3767 //================================================================================
3769 * \brief Returns default max size given a default value of element length ratio
3771 //================================================================================
3773 double BLSURFPlugin_Hypothesis::GetDefaultMaxSize(double diagonal)
3776 return diagonal / 5.0 ;
3777 return undefinedDouble();
3780 //================================================================================
3782 * \brief Returns default chordal error given a default value of element length ratio
3784 //================================================================================
3786 double BLSURFPlugin_Hypothesis::GetDefaultChordalError(double diagonal)
3790 return undefinedDouble();
3793 //================================================================================
3795 * \brief Returns default tiny edge length given a default value of element length ratio
3797 //================================================================================
3799 double BLSURFPlugin_Hypothesis::GetDefaultTinyEdgeLength(double diagonal)
3802 return diagonal * 1e-6 ;
3803 return undefinedDouble();
3806 //================================================================================
3808 * \brief Returns default tiny edge optimisation length given a default value of element length ratio
3810 //================================================================================
3812 double BLSURFPlugin_Hypothesis::GetDefaultTinyEdgeOptimisationLength(double diagonal)
3815 return diagonal * 1e-6 ;
3816 return undefinedDouble();
3819 //=============================================================================
3821 * \brief Initialize my parameter values by default parameters.
3822 * \retval bool - true if parameter values have been successfully defined
3824 //=============================================================================
3826 bool BLSURFPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& dflts,
3827 const SMESH_Mesh* /*theMesh*/)
3829 _phySize = GetDefaultPhySize(dflts._diagonal, _gen->GetBoundaryBoxSegmentation());
3830 _minSize = GetDefaultMinSize(dflts._diagonal);
3831 _maxSize = GetDefaultMaxSize(dflts._diagonal);
3832 _chordalError = 0.5 * _phySize; //GetDefaultChordalError(diagonal); IMP 0023307
3834 if ( dflts._way == SMESH_Hypothesis::BY_AVERAGE_LENGTH )
3836 _phySize = dflts._elemLength;
3837 _minSize = dflts._elemLength / 100.;
3838 _maxSize = dflts._elemLength * 2.;
3839 _chordalError = dflts._elemLength / 2.;
3840 _elementType = dflts._quadDominated ? QuadrangleDominant : Triangles;
3841 _physicalMesh = PhysicalLocalSize; // to activate _enforcedInternalVerticesAllFaces
3842 _enforcedInternalVerticesAllFaces = true;
3846 _tinyEdgeLength = GetDefaultTinyEdgeLength(dflts._diagonal);
3847 _tinyEdgeOptimisationLength = GetDefaultTinyEdgeOptimisationLength(dflts._diagonal);
3853 //================================================================================
3855 * \brief Converts a string to a bool
3857 //================================================================================
3859 bool BLSURFPlugin_Hypothesis::ToBool(const std::string& str, bool* isOk )
3861 std::string s = str;
3862 if ( isOk ) *isOk = true;
3864 for ( size_t i = 0; i <= s.size(); ++i )
3865 s[i] = (char) tolower( s[i] );
3867 if ( s == "1" || s == "true" || s == "active" || s == "yes" )
3870 if ( s == "0" || s == "false" || s == "inactive" || s == "no" )
3876 std::string msg = "Not a Boolean value:'" + str + "'";
3877 throw std::invalid_argument(msg);
3882 //================================================================================
3884 * \brief Converts a string to a real value
3886 //================================================================================
3888 double BLSURFPlugin_Hypothesis::ToDbl(const std::string& str, bool* isOk )
3890 if ( str.empty() ) throw std::invalid_argument("Empty value provided");
3892 // Forces "C" locale to be set as LC_NUMERIC
3893 Kernel_Utils::Localizer loc;
3896 double val = strtod(&str[0], &endPtr);
3897 bool ok = (&str[0] != endPtr);
3899 if ( isOk ) *isOk = ok;
3903 std::string msg = "Not a real value:'" + str + "'";
3904 throw std::invalid_argument(msg);
3909 //================================================================================
3911 * \brief Converts a string to a integer value
3913 //================================================================================
3915 int BLSURFPlugin_Hypothesis::ToInt(const std::string& str, bool* isOk )
3917 if ( str.empty() ) throw std::invalid_argument("Empty value provided");
3920 int val = (int)strtol( &str[0], &endPtr, 10);
3921 bool ok = (&str[0] != endPtr);
3923 if ( isOk ) *isOk = ok;
3927 std::string msg = "Not an integer value:'" + str + "'";
3928 throw std::invalid_argument(msg);