+void BLSURFPlugin_Hypothesis::SetEnforceCadEdgesSize( bool toEnforce )
+{
+#if MESHGEMS_VERSION_HEX < 0x020A00
+ // Deprecated since MeshGems 2.10
+ if ( GetEnforceCadEdgesSize() != toEnforce )
+ {
+ SetOptionValue( "enforce_cad_edge_sizes", toEnforce ? "yes" : "no" );
+ NotifySubMeshesHypothesisModification();
+ }
+#else
+ (void)toEnforce; // maybe unused
+#endif
+}
+//=============================================================================
+bool BLSURFPlugin_Hypothesis::GetEnforceCadEdgesSize()
+{
+#if MESHGEMS_VERSION_HEX < 0x020A00
+ // Deprecated since MeshGems 2.10
+ return ToBool( GetOptionValue( "enforce_cad_edge_sizes" ), GET_DEFAULT() );
+#else
+ return false;
+#endif
+}
+//=============================================================================
+
+void BLSURFPlugin_Hypothesis::SetJacobianRectificationRespectGeometry( bool allowRectification )
+{
+ if ( GetJacobianRectificationRespectGeometry() != allowRectification )
+ {
+ SetOptionValue("jacobian_rectification_respect_geometry", allowRectification ? "yes" : "no" );
+ NotifySubMeshesHypothesisModification();
+ }
+}
+//=============================================================================
+bool BLSURFPlugin_Hypothesis::GetJacobianRectificationRespectGeometry()
+{
+ return ToBool( GetOptionValue("jacobian_rectification_respect_geometry", GET_DEFAULT()));
+}
+//=============================================================================
+
+void BLSURFPlugin_Hypothesis::SetJacobianRectification( bool allowRectification )
+{
+ if ( GetJacobianRectification() != allowRectification )
+ {
+ SetOptionValue( "rectify_jacobian", allowRectification ? "yes" : "no" );
+ NotifySubMeshesHypothesisModification();
+ }
+}
+//=============================================================================
+bool BLSURFPlugin_Hypothesis::GetJacobianRectification()
+{
+ return ToBool( GetOptionValue("rectify_jacobian", GET_DEFAULT()));
+}
+//=============================================================================
+
+void BLSURFPlugin_Hypothesis::SetUseDeprecatedPatchMesher( bool /*useDeprecatedPatchMesher*/ )
+{
+ // if ( GetUseDeprecatedPatchMesher() != useDeprecatedPatchMesher )
+ // {
+ // SetOptionValue( "use_deprecated_patch_mesher", useDeprecatedPatchMesher ? "yes" : "no" );
+ // NotifySubMeshesHypothesisModification();
+ // }
+}
+//=============================================================================
+bool BLSURFPlugin_Hypothesis::GetUseDeprecatedPatchMesher()
+{
+ return false;//ToBool( GetOptionValue("use_deprecated_patch_mesher", GET_DEFAULT()));
+}
+//=============================================================================
+
+void BLSURFPlugin_Hypothesis::SetMaxNumberOfPointsPerPatch( int nb )
+{
+#if MESHGEMS_VERSION_HEX < 0x020A00
+ // Deprecated since MeshGems 2.10
+ if ( nb < 0 )
+ throw std::invalid_argument( SMESH_Comment("Invalid number of points: ") << nb );
+
+ if ( GetMaxNumberOfPointsPerPatch() != nb )
+ {
+ SetOptionValue("max_number_of_points_per_patch", SMESH_Comment( nb ));
+ NotifySubMeshesHypothesisModification();
+ }
+#else
+ (void)nb; // maybe unused
+#endif
+}
+//=============================================================================
+int BLSURFPlugin_Hypothesis::GetMaxNumberOfPointsPerPatch()
+{
+#if MESHGEMS_VERSION_HEX < 0x020A00
+ // Deprecated since MeshGems 2.10
+ return ToInt( GetOptionValue("max_number_of_points_per_patch", GET_DEFAULT()));
+#else
+ return 0;
+#endif
+}
+//=============================================================================
+
+void BLSURFPlugin_Hypothesis::SetMaxNumberOfThreads( int nb )
+{
+ if ( nb < 0 )
+ throw std::invalid_argument( SMESH_Comment("Invalid number of threads: ") << nb );
+
+ if ( GetMaxNumberOfThreads() != nb )
+ {
+ SetOptionValue("max_number_of_threads", SMESH_Comment( nb ));
+ NotifySubMeshesHypothesisModification();
+ }
+}
+//=============================================================================
+int BLSURFPlugin_Hypothesis::GetMaxNumberOfThreads()
+{
+ return ToInt( GetOptionValue("max_number_of_threads", GET_DEFAULT()));
+}
+//=============================================================================
+
+void BLSURFPlugin_Hypothesis::SetRespectGeometry( bool toRespect )
+{
+ if ( GetRespectGeometry() != toRespect )
+ {
+ SetOptionValue("respect_geometry", toRespect ? "yes" : "no" );
+ NotifySubMeshesHypothesisModification();
+ }
+}
+//=============================================================================
+bool BLSURFPlugin_Hypothesis::GetRespectGeometry()
+{
+ return ToBool( GetOptionValue( "respect_geometry", GET_DEFAULT()));
+}
+//=============================================================================
+
+void BLSURFPlugin_Hypothesis::SetTinyEdgesAvoidSurfaceIntersections( bool toAvoidIntersection )
+{
+ if ( GetTinyEdgesAvoidSurfaceIntersections() != toAvoidIntersection )
+ {
+ SetOptionValue("tiny_edge_avoid_surface_intersections", toAvoidIntersection ? "yes" : "no" );
+ NotifySubMeshesHypothesisModification();
+ }
+}
+//=============================================================================
+bool BLSURFPlugin_Hypothesis::GetTinyEdgesAvoidSurfaceIntersections()
+{
+ return ToBool( GetOptionValue("tiny_edge_avoid_surface_intersections", GET_DEFAULT()));
+}
+//=============================================================================
+
+void BLSURFPlugin_Hypothesis::SetClosedGeometry( bool isClosed )
+{
+ if ( GetClosedGeometry() != isClosed )
+ {
+ SetPreCADOptionValue("closed_geometry", isClosed ? "yes" : "no" );
+ NotifySubMeshesHypothesisModification();
+ }
+}
+//=============================================================================
+bool BLSURFPlugin_Hypothesis::GetClosedGeometry()
+{
+ return ToBool( GetPreCADOptionValue( "closed_geometry", GET_DEFAULT()));
+}
+//=============================================================================
+
+void BLSURFPlugin_Hypothesis::SetDebug( bool isDebug )
+{
+ if ( GetDebug() != isDebug )
+ {
+ SetPreCADOptionValue("debug", isDebug ? "yes" : "no" );
+ NotifySubMeshesHypothesisModification();
+ }
+}
+//=============================================================================
+bool BLSURFPlugin_Hypothesis::GetDebug()
+{
+ return ToBool( GetPreCADOptionValue("debug", GET_DEFAULT()));
+}
+//=============================================================================
+
+void BLSURFPlugin_Hypothesis::SetPeriodicTolerance( CORBA::Double tol )
+{
+ if ( tol <= 0 )
+ throw std::invalid_argument( SMESH_Comment("Invalid tolerance: ") << tol );
+ if ( GetPeriodicTolerance() != tol )
+ {
+ SetPreCADOptionValue("periodic_tolerance", SMESH_Comment( tol ) );
+ NotifySubMeshesHypothesisModification();
+ }
+}
+//=============================================================================
+double BLSURFPlugin_Hypothesis::GetPeriodicTolerance()
+{
+ return ToDbl( GetPreCADOptionValue( "periodic_tolerance", GET_DEFAULT()));
+}
+//=============================================================================
+
+void BLSURFPlugin_Hypothesis::SetRequiredEntities( const std::string& howToTreat )
+{
+ if ( howToTreat != "respect" && howToTreat != "ignore" && howToTreat != "clear" )
+ throw std::invalid_argument
+ ( SMESH_Comment("required_entities must be in ['respect','ignore','clear'] "));
+
+ if ( GetRequiredEntities() != howToTreat )
+ {
+ SetPreCADOptionValue("required_entities", howToTreat );
+ NotifySubMeshesHypothesisModification();
+ }
+}
+//=============================================================================
+std::string BLSURFPlugin_Hypothesis::GetRequiredEntities()
+{
+ return GetPreCADOptionValue("required_entities", GET_DEFAULT());
+}
+//=============================================================================
+
+void BLSURFPlugin_Hypothesis::SetSewingTolerance( CORBA::Double tol )
+{
+ if ( tol <= 0 )
+ throw std::invalid_argument( SMESH_Comment("Invalid tolerance: ") << tol );
+ if ( GetSewingTolerance() != tol )
+ {
+ SetPreCADOptionValue("sewing_tolerance", SMESH_Comment( tol ) );
+ NotifySubMeshesHypothesisModification();
+ }
+}
+//=============================================================================
+CORBA::Double BLSURFPlugin_Hypothesis::GetSewingTolerance()
+{
+ return ToDbl( GetPreCADOptionValue("sewing_tolerance", GET_DEFAULT()));
+}
+//=============================================================================
+
+void BLSURFPlugin_Hypothesis::SetTags( const std::string& howToTreat )
+{
+ if ( howToTreat != "respect" && howToTreat != "ignore" && howToTreat != "clear" )
+ throw std::invalid_argument
+ ( SMESH_Comment("'tags' must be in ['respect','ignore','clear'] "));
+
+ if ( GetTags() != howToTreat )
+ {
+ SetPreCADOptionValue("tags", howToTreat );
+ NotifySubMeshesHypothesisModification();
+ }
+}
+//=============================================================================
+std::string BLSURFPlugin_Hypothesis::GetTags()
+{
+ return GetPreCADOptionValue("tags", GET_DEFAULT());
+}
+
+//=============================================================================
+void BLSURFPlugin_Hypothesis::SetHyperPatches(const THyperPatchList& hpl, bool notifyMesh)
+{
+ if ( hpl != _hyperPatchList )
+ {
+ // join patches sharing tags
+ _hyperPatchList.clear();
+ for ( size_t i = 0; i < hpl.size(); ++i )
+ {
+ const THyperPatchTags& tags = hpl[i];
+ if ( tags.size() < 2 ) continue;
+
+ std::set<int> iPatches;
+ if ( !_hyperPatchList.empty() )
+ {
+ THyperPatchTags::iterator t = tags.begin();
+ for ( ; t != tags.end(); ++t )
+ {
+ int iPatch = -1;
+ GetHyperPatchTag( *t, this, &iPatch );
+ if ( iPatch >= 0 )
+ iPatches.insert( iPatch );
+ }
+ }
+
+ if ( iPatches.empty() )
+ {
+ _hyperPatchList.push_back( tags );
+ }
+ else
+ {
+ std::set<int>::iterator iPatch = iPatches.begin();
+ THyperPatchTags& mainPatch = _hyperPatchList[ *iPatch ];
+ mainPatch.insert( tags.begin(), tags.end() );
+
+ for ( ++iPatch; iPatch != iPatches.end(); ++iPatch )
+ {
+ mainPatch.insert( _hyperPatchList[ *iPatch ].begin(), _hyperPatchList[ *iPatch ].end() );
+ _hyperPatchList[ *iPatch ].clear();
+ }
+ if ( iPatches.size() > 1 )
+ for ( int j = (int) _hyperPatchList.size()-1; j > 0; --j )
+ if ( _hyperPatchList[j].empty() )
+ _hyperPatchList.erase( _hyperPatchList.begin() + j );
+ }
+ }
+ if ( notifyMesh )
+ NotifySubMeshesHypothesisModification();
+ }
+}
+//=============================================================================
+void BLSURFPlugin_Hypothesis::SetHyperPatches(const THyperPatchEntriesList& hpel)
+{
+ if ( hpel != _hyperPatchEntriesList )
+ {
+ _hyperPatchEntriesList = hpel;
+ _hyperPatchList.clear();
+
+ NotifySubMeshesHypothesisModification();
+ }
+}
+//================================================================================
+/*!
+ * \brief Set _hyperPatchList by _hyperPatchEntriesList
+ */
+//================================================================================
+
+void BLSURFPlugin_Hypothesis::
+SetHyperPatchIDsByEntry( const TopoDS_Shape& mainShape,
+ const std::map< std::string, TopoDS_Shape >& entryToShape)
+{
+ _hyperPatchList.clear();
+ if ( _hyperPatchEntriesList.empty() || mainShape.IsNull() )
+ return;
+
+ _hyperPatchList.resize( _hyperPatchEntriesList.size() );
+
+ TopTools_IndexedMapOfShape shapeMap;
+ TopExp::MapShapes( mainShape, shapeMap );
+
+ for ( size_t i = 0; i < _hyperPatchEntriesList.size(); ++i )
+ {
+ THyperPatchTags & idsList = _hyperPatchList [ i ];
+ const THyperPatchEntries & entryList = _hyperPatchEntriesList[ i ];
+ for ( const std::string & entry : entryList )
+ {
+ auto e2sIt = entryToShape.find( entry );
+ if ( e2sIt != entryToShape.end() )
+ {
+ for ( TopExp_Explorer fExp( e2sIt->second, TopAbs_FACE ); fExp.More(); fExp.Next() )
+ {
+ int id = shapeMap.FindIndex( fExp.Current() );
+ if ( id > 0 )
+ idsList.insert( id );
+ }
+ }
+ }
+ }
+ THyperPatchList hpl;
+ hpl.swap( _hyperPatchList );
+ SetHyperPatches( hpl, /*notifyMesh=*/false );
+}
+
+//=============================================================================
+/*!
+ * \brief Return a tag of a face taking into account the hyper-patches. Optionally
+ * return an index of a patch including the face
+ */
+//================================================================================
+
+int BLSURFPlugin_Hypothesis::GetHyperPatchTag( const int faceTag,
+ const BLSURFPlugin_Hypothesis* hyp,
+ int* iPatch)
+{
+ if ( hyp )
+ {
+ const THyperPatchList& hpl = hyp->_hyperPatchList;
+ for ( size_t i = 0; i < hpl.size(); ++i )
+ if ( hpl[i].count( faceTag ))
+ {
+ if ( iPatch ) *iPatch = (int) i;
+ return *( hpl[i].begin() );
+ }
+ }
+ return faceTag;
+}
+
+//=============================================================================
+void BLSURFPlugin_Hypothesis::SetEnforcedMeshes( std::vector< EnforcedMesh > & enforcedMeshes )
+{
+ if ( _enforcedMeshes != enforcedMeshes )
+ {
+ _enforcedMeshes.swap( enforcedMeshes );
+ NotifySubMeshesHypothesisModification();
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Return elements of 1D enforced mesh. Result can be NULL
+ */
+//================================================================================
+
+SMDS_ElemIteratorPtr
+BLSURFPlugin_Hypothesis::GetEnforcedSegments( const EnforcedMesh& enfMesh,
+ SMESH_Mesh* & mesh ) const
+{
+ SMDS_ElemIteratorPtr it;
+ if (( mesh = SMESH_Hypothesis::GetMeshByPersistentID( enfMesh._meshID )))
+ {
+ mesh->Load();
+ if ( mesh->NbEdges() == 0 )
+ GetGen()->Compute( *mesh, mesh->GetShapeToMesh(), /*flags=*/0 );
+
+ switch( enfMesh._type )
+ {
+ case ENFORCED_MESH:
+ it = mesh->GetMeshDS()->elementsIterator( SMDSAbs_Edge );
+ break;
+
+ case ENFORCED_GROUP:
+ if ( SMESH_Group* grp = mesh->GetGroup( enfMesh._subID ))
+ {
+ if ( grp->GetGroupDS()->GetType() == SMDSAbs_Edge )
+ it = grp->GetGroupDS()->GetElements();
+ }
+ break;
+
+ case ENFORCED_SUBMESH:
+ if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining( enfMesh._subID ))
+ if ( SMESHDS_SubMesh * smDS = sm->GetSubMeshDS() )
+ {
+ it = smDS->GetElements();
+ if ( it->more() && it->next()->GetType() != SMDSAbs_Edge )
+ it = SMDS_ElemIteratorPtr();
+ else
+ it = smDS->GetElements();
+ }
+ break;
+ }
+ }
+ return it;
+}
+
+
+//=============================================================================
+void BLSURFPlugin_Hypothesis::SetPreCADMergeEdges(bool theVal)
+{
+ if (theVal != ToBool( GetPreCADOptionValue("merge_edges", GET_DEFAULT()))) {