Salome HOME
updated copyright message
[plugins/blsurfplugin.git] / src / BLSURFPlugin / BLSURFPluginBuilder.py
1 # Copyright (C) 2007-2023  CEA, EDF
2 #
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.
7 #
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.
12 #
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
16 #
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 #
19
20 ##
21 # @package BLSURFPluginBuilder
22 # Python API for the MG-CADSurf meshing plug-in module.
23
24 from salome.smesh.smesh_algorithm import Mesh_Algorithm
25 import GEOM
26
27 LIBRARY = "libBLSURFEngine.so"
28
29 # ElementType enum
30 Triangles, QuadrangleDominant, Quadrangles = 0, 1, 2
31
32 # Topology treatment way of MG-CADSurf
33 FromCAD, PreProcess, PreProcessPlus, PreCAD = 0,1,2,3
34
35 # Element size flag of MG-CADSurf
36 DefaultSize, DefaultGeom, MG_CADSURF_GlobalSize, MG_CADSURF_LocalSize = 0,0,1,2
37 # Retrocompatibility
38 MG_CADSURF_Custom, SizeMap = MG_CADSURF_GlobalSize, MG_CADSURF_LocalSize
39 BLSURF_Custom, BLSURF_GlobalSize, BLSURF_LocalSize = MG_CADSURF_Custom, MG_CADSURF_GlobalSize, MG_CADSURF_LocalSize
40
41 # import BLSURFPlugin module if possible
42 noBLSURFPlugin = 0
43 try:
44   import BLSURFPlugin
45   from BLSURFPlugin import MG_EnforcedMesh1D
46
47 except ImportError:
48   noBLSURFPlugin = 1
49   pass
50
51 #----------------------------
52 # Mesh algo type identifiers
53 #----------------------------
54
55 ## Algorithm type: MG-CADSurf triangle algorithm, see BLSURF_Algorithm
56 MG_CADSurf = "MG-CADSurf"
57 BLSURF = MG_CADSurf
58
59 #----------------------
60 # Algorithms
61 #----------------------
62
63 ## MG-CADSurf 2D algorithm.
64 #
65 #  It can be created by calling smeshBuilder.Mesh.Triangle(smeshBuilder.MG-CADSurf,geom=0)
66 #
67 class BLSURF_Algorithm(Mesh_Algorithm):
68
69   ## name of the dynamic method in smeshBuilder.Mesh class
70   #  @internal
71   meshMethod = "Triangle"
72   ## type of algorithm used with helper function in smeshBuilder.Mesh class
73   #  @internal
74   algoType   = MG_CADSurf
75   ## doc string of the method
76   #  @internal
77   docHelper  = "Creates triangle algorithm for faces"
78
79   _anisotropic_ratio = 0
80   _bad_surface_element_aspect_ratio = 1000
81   _geometric_approximation = 22
82   _gradation  = 1.3
83   _volume_gradation  = 2
84   _metric = "isotropic"
85   _remove_tiny_edges = 0
86
87   ## Private constructor.
88   #  @param mesh parent mesh object algorithm is assigned to
89   #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
90   #              if it is @c 0 (default), the algorithm is assigned to the main shape
91   def __init__(self, mesh, geom=0):
92     Mesh_Algorithm.__init__(self)
93     if noBLSURFPlugin:
94       print("Warning: BLSURFPlugin module unavailable")
95     if mesh.GetMesh().HasShapeToMesh():
96       self.Create(mesh, geom, self.algoType, LIBRARY)
97     else:
98       self.Create(mesh, geom, self.algoType+"_NOGEOM", LIBRARY)
99       mesh.smeshpyD.SetName( self.algo, self.algoType )
100     self.params=None
101     self.geompyD = mesh.geompyD
102     #self.SetPhysicalMesh() - PAL19680
103     pass
104
105   ## Sets a way to define size of mesh elements to generate.
106   #  @param thePhysicalMesh is: DefaultSize, MG_CADSURF_Custom or SizeMap.
107   def SetPhysicalMesh(self, thePhysicalMesh=DefaultSize):
108     physical_size_mode = thePhysicalMesh
109     if self.Parameters().GetGeometricMesh() == DefaultGeom:
110       if physical_size_mode == DefaultSize:
111         physical_size_mode = MG_CADSURF_GlobalSize
112     self.Parameters().SetPhysicalMesh(physical_size_mode)
113     pass
114
115   ## Sets a way to define maximum angular deflection of mesh from CAD model.
116   #  @param theGeometricMesh is: DefaultGeom (0)) or MG_CADSURF_GlobalSize (1))
117   def SetGeometricMesh(self, theGeometricMesh=DefaultGeom):
118     geometric_size_mode = theGeometricMesh
119     if self.Parameters().GetPhysicalMesh() == DefaultSize:
120       if geometric_size_mode == DefaultGeom:
121         geometric_size_mode = MG_CADSURF_GlobalSize
122     self.Parameters().SetGeometricMesh(geometric_size_mode)
123     pass
124
125   ## Sets size of mesh elements to generate.
126   #  @param theVal : constant global size when using a global physical size.
127   #  @param isRelative : if True, the value is relative to the length of the diagonal of the bounding box
128   def SetPhySize(self, theVal, isRelative = False):
129     if self.Parameters().GetPhysicalMesh() == DefaultSize:
130       self.SetPhysicalMesh(MG_CADSURF_GlobalSize)
131     if isRelative:
132       self.Parameters().SetPhySizeRel(theVal)
133     else:
134       self.Parameters().SetPhySize(theVal)
135     pass
136
137   ## Sets lower boundary of mesh element size.
138   #  @param theVal : global minimal cell size desired.
139   #  @param isRelative : if True, the value is relative to the length of the diagonal of the bounding box
140   def SetMinSize(self, theVal=-1, isRelative = False):
141     if isRelative:
142       self.Parameters().SetMinSizeRel(theVal)
143     else:
144       self.Parameters().SetMinSize(theVal)
145     pass
146
147   ## Sets upper boundary of mesh element size.
148   #  @param theVal : global maximal cell size desired.
149   #  @param isRelative : if True, the value is relative to the length of the diagonal of the bounding box
150   def SetMaxSize(self, theVal=-1, isRelative = False):
151     if isRelative:
152       self.Parameters().SetMaxSizeRel(theVal)
153     else:
154       self.Parameters().SetMaxSize(theVal)
155     pass
156
157   ## Sets angular deflection (in degrees) from CAD surface.
158   #  @param theVal value of angular deflection
159   def SetAngleMesh(self, theVal=_geometric_approximation):
160     if self.Parameters().GetGeometricMesh() == DefaultGeom:
161       self.SetGeometricMesh(MG_CADSURF_GlobalSize)
162     self.Parameters().SetAngleMesh(theVal)
163     pass
164
165   ## Sets the maximum desired distance between a triangle and its supporting CAD surface
166   #  @param distance the distance between a triangle and a surface
167   def SetChordalError(self, distance):
168     self.Parameters().SetChordalError(distance)
169     pass
170
171   ## Sets maximal allowed ratio between the lengths of two adjacent edges.
172   #  @param toUseGradation to use gradation
173   #  @param theVal value of maximal length ratio
174   def SetGradation(self, toUseGradation=True, theVal=_gradation):
175     if isinstance( toUseGradation, float ): ## backward compatibility
176       toUseGradation, theVal = True, toUseGradation
177     if self.Parameters().GetGeometricMesh() == 0: theVal = self._gradation
178     self.Parameters().SetUseGradation(toUseGradation)
179     self.Parameters().SetGradation(theVal)
180     pass
181
182   ## Sets maximal allowed ratio between the lengths of two adjacent edges in 3D mesh.
183   #  @param toUseGradation to use gradation
184   #  @param theVal value of maximal length ratio
185   def SetVolumeGradation(self, toUseGradation=True, theVal=_gradation):
186     if self.Parameters().GetGeometricMesh() == 0: theVal = self._volume_gradation
187     self.Parameters().SetUseVolumeGradation(toUseGradation)
188     self.Parameters().SetVolumeGradation(theVal)
189     pass
190
191   ## Sets topology usage way.
192   # @param way defines how mesh conformity is assured <ul>
193   # <li>FromCAD - mesh conformity is assured by conformity of a shape</li>
194   # <li>PreProcess or PreProcessPlus - by pre-processing a CAD model (OBSOLETE: FromCAD will be used)</li>
195   # <li>PreCAD - by pre-processing with PreCAD a CAD model</li></ul>
196   def SetTopology(self, way):
197     if way != PreCAD and way != FromCAD:
198       print("Warning: topology mode %d is no longer supported. Mode FromCAD is used."%way)
199       way = FromCAD
200     self.Parameters().SetTopology(way)
201     pass
202
203   ## Activate/deactivate surface proximity computation
204   # @param toUse boolean flag
205   #
206   def SetSurfaceProximity(self, toUse ):
207     self.Parameters().SetSurfaceProximity(toUse)
208     return
209
210   ## Set number of surface element layers to be generated due to surface proximity
211   # @param nbLayers number of layers
212   #
213   def SetNbSurfaceProximityLayers(self, nbLayers ):
214     self.Parameters().SetNbSurfaceProximityLayers( nbLayers )
215     return
216
217   ## Set coefficient by which size of element refined due to surface proximity is increased
218   # @param ratio proximity coefficient
219   #
220   def SetSurfaceProximityRatio(self, ratio ):
221     self.Parameters().SetSurfaceProximityRatio(ratio)
222     return
223   
224   ## Activate/deactivate volume proximity computation
225   # @param toUse boolean flag
226   #
227   def SetVolumeProximity(self, toUse ):
228     self.Parameters().SetVolumeProximity(toUse)
229     return
230   
231   ## Set number of surface element layers to be generated due to volume proximity
232   # @param nbLayers number of layers
233   #
234   def SetNbVolumeProximityLayers(self, nbLayers ):
235     self.Parameters().SetNbVolumeProximityLayers(nbLayers)
236     return
237
238   ## Set coefficient by which size of element refined due to volume proximity is increased
239   # @param ratio proximity coefficient
240   #
241   def SetVolumeProximityRatio(self, ratio ):
242     self.Parameters().SetVolumeProximityRatio(ratio)
243     return
244
245
246   ## Sets verbosity level in the range 0 to 10.
247   #  @param level verbosity level
248   def SetVerbosity(self, level):
249     self.Parameters().SetVerbosity(level)
250     pass
251
252   ## Set enforce_cad_edge_sizes parameter
253   #  
254   #  Relaxes the given sizemap constraint around CAD edges to allow a better
255   #  element quality and a better geometric approximation. It is only useful in 
256   #  combination with the gradation option.
257   #  
258   def SetEnforceCadEdgesSize( self, toEnforce ):
259     if not version_less(self.Parameters().GetMeshGemsVersion(), '2.10'):
260       print("Warning: method SetEnforceCadEdgesSize() is deprecated")
261     self.Parameters().SetEnforceCadEdgesSize( toEnforce )
262
263   ## Set jacobian_rectification_respect_geometry parameter
264   #  
265   #  While making the mesh quadratic, allows to lose the CAD-mesh associativity in order
266   #  to correct elements with nagative Jacobian
267   #  
268   def SetJacobianRectificationRespectGeometry( self, allowRectification ):
269     self.Parameters().SetJacobianRectificationRespectGeometry( allowRectification )
270     
271   ## Set rectify_jacobian parameter
272   #  
273   #  While making the mesh quadratic, allow to fix nagative Jacobian surface elements
274   #  
275   def SetJacobianRectification( self, allowRectification ):
276     self.Parameters().SetJacobianRectification( allowRectification )
277
278   ## Set use_deprecated_patch_mesher parameter (compatibility with older versions of Meshgems)
279   #  
280   # the use_deprecated_patch_mesher parameter allows to keep the same behaviour than
281   # in salome < 8.3 (meshgems 2.1.11 instead of meshgems >= 2.4.5)
282   #  
283   def SetUseDeprecatedPatchMesher( self, useDeprecatedPatchMesher ):
284     self.Parameters().SetUseDeprecatedPatchMesher( useDeprecatedPatchMesher )
285
286   ## Set respect_geometry parameter
287   #  
288   #  This patch independent option can be deactivated to allow MeshGems-CADSurf
289   #  to lower the geometry accuracy in its patch independent process.
290   #  
291   def SetRespectGeometry( self, toRespect ):
292     self.Parameters().SetRespectGeometry( toRespect )
293
294   ## Set max_number_of_points_per_patch parameter
295   #  
296   #  This parameter controls the maximum amount of points MeshGems-CADSurf is allowed
297   #  to generate on a single CAD patch. For an automatic gestion of the memory, one
298   #  can set this parameter to 0
299   #  
300   def SetMaxNumberOfPointsPerPatch( self, nb ):
301     if not version_less(self.Parameters().GetMeshGemsVersion(), '2.10'):
302       print("Warning: method SetMaxNumberOfPointsPerPatch() is deprecated")
303     self.Parameters().SetMaxNumberOfPointsPerPatch( nb )
304
305   ## Set max_number_of_threads parameter
306   #
307   #  Set the maximum of threads to use for multithreading mesh computation
308   #
309   def SetMaxNumberOfThreads( self, nb ):
310     self.Parameters().SetMaxNumberOfThreads( nb )
311
312   ## Set respect_geometry parameter
313   #  
314   #  This patch independent option can be deactivated to allow MeshGems-CADSurf
315   #  to lower the geometry accuracy in its patch independent process.
316   #  
317   def SetRespectGeometry( self, toRespect ):
318     self.Parameters().SetRespectGeometry( toRespect )
319
320   ## Set tiny_edges_avoid_surface_intersections parameter
321   #  
322   #  This option defines the priority between the tiny feature
323   #  suppression and the surface intersection prevention. 
324   #  
325   def SetTinyEdgesAvoidSurfaceIntersections( self, toAvoidIntersection ):
326     self.Parameters().SetTinyEdgesAvoidSurfaceIntersections( toAvoidIntersection )
327
328   ## Set closed_geometry parameter parameter
329   #  
330   #  Describes whether the geometry is expected to be closed or not. 
331   #  When activated, this option helps MeshGems-PreCAD to treat the dirtiest geometries.
332   #  
333   def SetClosedGeometry( self, isClosed ):
334     self.Parameters().SetClosedGeometry( isClosed )
335
336   ## Set debug parameter
337   #  
338   #  Make MeshGems-CADSurf will be very verbose and will output some intermediate
339   #  files in the working directory. This option is mainly meant for Distene support issues.
340   #  
341   def SetDebug( self, isDebug ):
342     self.Parameters().SetDebug( isDebug )
343
344   ## Set periodic_tolerance parameter
345   #  
346   #  This parameter defines the maximum size difference between two periodic edges
347   #  and also the maximum distance error between two periodic entities.
348   #  
349   def SetPeriodicTolerance( self, tol ):
350     self.Parameters().SetPeriodicTolerance( tol )
351
352   ## Set required_entities parameter
353   #  
354   #  The required entities control the correction operations. 
355   #  Accepted values for this parameter are :
356   #  - "respect" : MeshGems-CADSurf is not allowed to alter any required entity, 
357   #                even for correction purposes,
358   #  - "ignore" : MeshGems-CADSurf will ignore the required entities in its processing,
359   #  - "clear" : MeshGems-CADSurf will clear any required status for the entities. 
360   #              There will not be any entity marked as required in the generated mesh.
361   #  
362   def SetRequiredEntities( self, howToTreat ):
363     self.Parameters().SetRequiredEntities( howToTreat )
364
365   ## Set sewing_tolerance parameter
366   #  
367   #  This parameter is the tolerance of the assembly.
368   #  
369   def SetSewingTolerance( self, tol ):
370     self.Parameters().SetSewingTolerance( tol )
371
372   ## Set tags parameter
373   #  
374   #  The tag (attribute) system controls the optimisation process. 
375   #  Accepted values for this parameter are :
376   #  - "respect"  : the CAD tags will be preserved and unaltered by the optimisation operations,
377   #  - "ignore" : the CAD tags will be ignored by the optimisation operations 
378   #               but they will still be present in the output mesh,
379   #  - "clear" : MeshGems-CADSurf will clear any tag on any entity and optimise accordingly. 
380   #              There will not be any tag in the generated mesh.
381   #  
382   def SetTags( self, howToTreat ):
383     self.Parameters().SetTags( howToTreat )
384
385   ## Activate/deactivate fully patch independent meshing
386   #   @param isIndependent boolean flag
387   #
388   # This feature can only be used if the @a tags parameter is set to "respect".
389   # By default this option deactivated.
390   #
391   def SetPatchIndependent( self, isIndependent ):
392     self.SetOptionValue( "allow_patch_independent", "yes" if isIndependent else "no" )
393
394   ## Set to preserve lines defined by a sharp angle in the input discrete geometry
395   #   @param toCompute boolean flag
396   #
397   # If this option is deactivated, MeshGems-CADSurf will not try to preserve lines
398   # defined by a sharp angle in the input discrete geometry. Only input ridges, free
399   # edges, non manifold edges and separation betwen zones with different attributes
400   # will be respected (if tags is set to respect).
401   # By default this option activated.
402   #
403   def SetComputeRidges( self, toCompute ):
404     self.SetOptionValue( "compute_ridges", "yes" if toCompute else "no" )
405
406
407   ## Activate removal of the tiny edges from the generated
408   # mesh when it improves the local mesh quality, without taking into account the
409   # tags (attributes) specifications.
410   #  @param toOptimise "to optimize" flag value
411   #  @param length minimal length under which an edge is considered to be a tiny
412   def SetOptimiseTinyEdges(self, toOptimise, length=-1):
413     self.Parameters().SetOptimiseTinyEdges( toOptimise )
414     if toOptimise:
415       self.Parameters().SetTinyEdgeOptimisationLength( length )
416
417   ## Activate correction of all surface intersections
418   #  @param toCorrect "to correct" flag value
419   #  @param maxCost  the time the user is ready to spend in the intersection prevention process
420   #         For example, maxCost = 3 means that MeshGems-CADSurf will not spend more time
421   #         in the intersection removal process than 3 times the time required to mesh
422   #         without processing the intersections.
423   def SetCorrectSurfaceIntersection(self, toCorrect, maxCost ):
424     self.Parameters().SetCorrectSurfaceIntersection( toCorrect )
425     if toCorrect:
426       self.Parameters().SetCorrectSurfaceIntersectionMaxCost( maxCost )
427
428   ## To optimize merges edges.
429   #  @param toMergeEdges "merge edges" flag value
430   def SetPreCADMergeEdges(self, toMergeEdges=False):
431     self.Parameters().SetPreCADMergeEdges(toMergeEdges)
432     pass
433
434   ## To remove duplicate CAD Faces
435   #  @param toRemoveDuplicateCADFaces "remove_duplicate_cad_faces" flag value
436   def SetPreCADRemoveDuplicateCADFaces(self, toRemoveDuplicateCADFaces=False):
437     self.Parameters().SetPreCADRemoveDuplicateCADFaces(toRemoveDuplicateCADFaces)
438     pass
439
440   ## To process 3D topology.
441   #  @param toProcess "PreCAD process 3D" flag value
442   def SetPreCADProcess3DTopology(self, toProcess=False):
443     self.Parameters().SetPreCADProcess3DTopology(toProcess)
444     pass
445
446   ## To remove nano edges.
447   #  @param toRemoveNanoEdges "remove nano edges" flag value
448   def SetPreCADRemoveNanoEdges(self, toRemoveNanoEdges=False):
449     if toRemoveNanoEdges:
450       self.SetPreCADOptionValue("remove_tiny_edges","1")
451     else:
452       self.SetPreCADOptionValue("remove_tiny_edges","0")
453     pass
454
455   ## To compute topology from scratch
456   #  @param toDiscardInput "discard input" flag value
457   def SetPreCADDiscardInput(self, toDiscardInput=False):
458     self.Parameters().SetPreCADDiscardInput(toDiscardInput)
459     pass
460
461   ## Sets the length below which an edge is considered as nano
462   #  for the topology processing.
463   #  @param epsNano nano edge length threshold value
464   def SetPreCADEpsNano(self, epsNano):
465     self.SetPreCADOptionValue("tiny_edge_length","%f"%epsNano)
466     pass
467
468   ## Sets advanced option value.
469   #  @param optionName advanced option name
470   #  @param level advanced option value
471   def SetOptionValue(self, optionName, level):
472     self.Parameters().SetOptionValue(optionName,level)
473     pass
474
475   ## Sets advanced PreCAD option value.
476   #  @param optionName name of the option
477   #  @param optionValue value of the option
478   def SetPreCADOptionValue(self, optionName, optionValue):
479     self.Parameters().SetPreCADOptionValue(optionName,optionValue)
480     pass
481   
482   ## Adds custom advanced option values
483   #  @param optionsAndValues options and values in a form "option_1 v1 option_2 v2'"
484   def SetAdvancedOption(self, optionsAndValues):
485     self.Parameters().SetAdvancedOption(optionsAndValues)
486     pass
487
488   ## Adds custom advanced option value.
489   #  @param optionName custom advanced option name
490   #  @param level custom advanced option value
491   def AddOption(self, optionName, level):
492     self.Parameters().AddOption(optionName,level)
493     pass
494
495   ## Adds custom advanced PreCAD option value.
496   #  @param optionName custom name of the option
497   #  @param optionValue value of the option
498   def AddPreCADOption(self, optionName, optionValue):
499     self.Parameters().AddPreCADOption(optionName,optionValue)
500     pass
501
502   ## Sets GMF file for export at computation
503   #  @param fileName GMF file name
504   def SetGMFFile(self, fileName):
505     self.Parameters().SetGMFFile(fileName)
506     pass
507
508   #-----------------------------------------
509   # Enforced vertices (BLSURF)
510   #-----------------------------------------
511
512   ## To get all the enforced vertices
513   def GetAllEnforcedVertices(self):
514     return self.Parameters().GetAllEnforcedVertices()
515
516   ## To get all the enforced vertices sorted by face (or group, compound)
517   def GetAllEnforcedVerticesByFace(self):
518     return self.Parameters().GetAllEnforcedVerticesByFace()
519
520   ## To get all the enforced vertices sorted by coords of input vertices
521   def GetAllEnforcedVerticesByCoords(self):
522     return self.Parameters().GetAllEnforcedVerticesByCoords()
523
524   ## To get all the coords of input vertices sorted by face (or group, compound)
525   def GetAllCoordsByFace(self):
526     return self.Parameters().GetAllCoordsByFace()
527
528   ## To get all the enforced vertices on a face (or group, compound)
529   #  @param theFace : GEOM face (or group, compound) on which to define an enforced vertex
530   def GetEnforcedVertices(self, theFace):
531     from salome.smesh.smeshBuilder import AssureGeomPublished
532     AssureGeomPublished( self.mesh, theFace )
533     return self.Parameters().GetEnforcedVertices(theFace)
534
535   ## To clear all the enforced vertices
536   def ClearAllEnforcedVertices(self):
537     return self.Parameters().ClearAllEnforcedVertices()
538
539   ## To set an enforced vertex on a face (or group, compound) given the coordinates of a point. If the point is not on the face, it will projected on it. If there is no projection, no enforced vertex is created.
540   #  @param theFace      : GEOM face (or group, compound) on which to define an enforced vertex
541   #  @param x            : x coordinate
542   #  @param y            : y coordinate
543   #  @param z            : z coordinate
544   #  @param vertexName   : name of the enforced vertex
545   #  @param groupName    : name of the group
546   def SetEnforcedVertex(self, theFace, x, y, z, vertexName = "", groupName = ""):
547     from salome.smesh.smeshBuilder import AssureGeomPublished
548     AssureGeomPublished( self.mesh, theFace )
549     if vertexName == "":
550       if groupName == "":
551         return self.Parameters().SetEnforcedVertex(theFace, x, y, z)
552       else:
553         return self.Parameters().SetEnforcedVertexWithGroup(theFace, x, y, z, groupName)
554       pass
555     else:
556       if groupName == "":
557         return self.Parameters().SetEnforcedVertexNamed(theFace, x, y, z, vertexName)
558       else:
559         return self.Parameters().SetEnforcedVertexNamedWithGroup(theFace, x, y, z, vertexName, groupName)
560       pass
561     pass
562
563   ## To set an enforced vertex on a face (or group, compound) given a GEOM vertex, group or compound.
564   #  @param theFace      : GEOM face (or group, compound) on which to define an enforced vertex
565   #  @param theVertex    : GEOM vertex (or group, compound) to be projected on theFace.
566   #  @param groupName    : name of the group
567   def SetEnforcedVertexGeom(self, theFace, theVertex, groupName = ""):
568     from salome.smesh.smeshBuilder import AssureGeomPublished
569     AssureGeomPublished( self.mesh, theFace )
570     AssureGeomPublished( self.mesh, theVertex )
571     if groupName == "":
572       return self.Parameters().SetEnforcedVertexGeom(theFace, theVertex)
573     else:
574       return self.Parameters().SetEnforcedVertexGeomWithGroup(theFace, theVertex,groupName)
575     pass
576
577   ## Set an enforced vertex on a face given the coordinates of a point.
578   #  The face if found by the application.
579   #  @param x            : x coordinate
580   #  @param y            : y coordinate
581   #  @param z            : z coordinate
582   #  @param vertexName   : name of the enforced vertex
583   #  @param groupName    : name of the group
584   def AddEnforcedVertex(self, x, y, z, vertexName = "", groupName = ""):
585     from salome.smesh.smeshBuilder import AssureGeomPublished
586     if vertexName == "":
587       if groupName == "":
588         return self.Parameters().AddEnforcedVertex(x, y, z)
589       else:
590         return self.Parameters().AddEnforcedVertexWithGroup(x, y, z, groupName)
591       pass
592     else:
593       if groupName == "":
594         return self.Parameters().AddEnforcedVertexNamed(x, y, z, vertexName)
595       else:
596         return self.Parameters().AddEnforcedVertexNamedWithGroup( x, y, z, vertexName, groupName)
597       pass
598     pass
599
600   ## To set an enforced vertex on a face given a GEOM vertex, group or compound.
601   #  The face if found by the application.
602   #  @param theVertex    : GEOM vertex (or group, compound).
603   #  @param groupName    : name of the group
604   def AddEnforcedVertexGeom(self, theVertex, groupName = ""):
605     from salome.smesh.smeshBuilder import AssureGeomPublished
606     AssureGeomPublished( self.mesh, theVertex )
607     if groupName == "":
608       return self.Parameters().AddEnforcedVertexGeom(theVertex)
609     else:
610       return self.Parameters().AddEnforcedVertexGeomWithGroup(theVertex,groupName)
611     pass
612
613   ## To remove an enforced vertex on a given GEOM face (or group, compound) given the coordinates.
614   #  @param theFace      : GEOM face (or group, compound) on which to remove the enforced vertex
615   #  @param x            : x coordinate
616   #  @param y            : y coordinate
617   #  @param z            : z coordinate
618   def UnsetEnforcedVertex(self, theFace, x, y, z):
619     from salome.smesh.smeshBuilder import AssureGeomPublished
620     AssureGeomPublished( self.mesh, theFace )
621     return self.Parameters().UnsetEnforcedVertex(theFace, x, y, z)
622
623   ## To remove an enforced vertex on a given GEOM face (or group, compound) given a GEOM vertex, group or compound.
624   #  @param theFace      : GEOM face (or group, compound) on which to remove the enforced vertex
625   #  @param theVertex    : GEOM vertex (or group, compound) to remove.
626   def UnsetEnforcedVertexGeom(self, theFace, theVertex):
627     from salome.smesh.smeshBuilder import AssureGeomPublished
628     AssureGeomPublished( self.mesh, theFace )
629     AssureGeomPublished( self.mesh, theVertex )
630     return self.Parameters().UnsetEnforcedVertexGeom(theFace, theVertex)
631
632   ## To remove all enforced vertices on a given face.
633   #  @param theFace      : face (or group/compound of faces) on which to remove all enforced vertices
634   def UnsetEnforcedVertices(self, theFace):
635     from salome.smesh.smeshBuilder import AssureGeomPublished
636     AssureGeomPublished( self.mesh, theFace )
637     return self.Parameters().UnsetEnforcedVertices(theFace)
638
639   ## To tell BLSURF to add a node on internal vertices
640   #  @param toEnforceInternalVertices : boolean; if True the internal vertices are added as enforced vertices
641   def SetInternalEnforcedVertexAllFaces(self, toEnforceInternalVertices):
642     return self.Parameters().SetInternalEnforcedVertexAllFaces(toEnforceInternalVertices)
643
644   ## To know if BLSURF will add a node on internal vertices
645   def GetInternalEnforcedVertexAllFaces(self):
646     return self.Parameters().GetInternalEnforcedVertexAllFaces()
647
648   ## To define a group for the nodes of internal vertices
649   #  @param groupName : string; name of the group
650   def SetInternalEnforcedVertexAllFacesGroup(self, groupName):
651     return self.Parameters().SetInternalEnforcedVertexAllFacesGroup(groupName)
652
653   ## To get the group name of the nodes of internal vertices
654   def GetInternalEnforcedVertexAllFacesGroup(self):
655     return self.Parameters().GetInternalEnforcedVertexAllFacesGroup()
656
657   #-----------------------------------------
658   #  Enforced mesh
659   #-----------------------------------------
660
661   ## Set enforced 1D meshes
662   #  @param enfMeshes : list of smeshBuilder.MG_EnforcedMesh1D structures
663   #
664   #  Example: cadsurf.SetEnforcedMeshes([ smeshBuilder.MG_EnforcedMesh1D( mesh1D, "Group 1D")]
665   def SetEnforcedMeshes( self, enfMeshes ):
666     from salome.smesh.smeshBuilder import Mesh
667     for em in enfMeshes:
668       if isinstance( em.mesh, Mesh ):
669         em.mesh = em.mesh.GetMesh()
670     return self.Parameters().SetEnforcedMeshes( enfMeshes )
671
672   #-----------------------------------------
673   #  Attractors
674   #-----------------------------------------
675
676   ## Sets an attractor on the chosen face. The mesh size will decrease exponentially with the distance from theAttractor, following the rule h(d) = theEndSize - (theEndSize - theStartSize) * exp [ - ( d / theInfluenceDistance ) ^ 2 ]
677   #  @param theFace      : face on which the attractor will be defined
678   #  @param theAttractor : geometrical object from which the mesh size "h" decreases exponentially
679   #  @param theStartSize : mesh size on theAttractor
680   #  @param theEndSize   : maximum size that will be reached on theFace
681   #  @param theInfluenceDistance : influence of the attractor ( the size grow slower on theFace if it's high)
682   #  @param theConstantSizeDistance : distance until which the mesh size will be kept constant on theFace
683   def SetAttractorGeom(self, theFace, theAttractor, theStartSize, theEndSize, theInfluenceDistance, theConstantSizeDistance):
684     from salome.smesh.smeshBuilder import AssureGeomPublished
685     AssureGeomPublished( self.mesh, theFace )
686     AssureGeomPublished( self.mesh, theAttractor )
687     self.Parameters().SetAttractorGeom(theFace, theAttractor, theStartSize, theEndSize, theInfluenceDistance, theConstantSizeDistance)
688     pass
689
690   ## Unsets an attractor on the chosen face.
691   #  @param theFace      : face on which the attractor has to be removed
692   def UnsetAttractorGeom(self, theFace):
693     from salome.smesh.smeshBuilder import AssureGeomPublished
694     AssureGeomPublished( self.mesh, theFace )
695     self.Parameters().SetAttractorGeom(theFace)
696     pass
697
698   #-----------------------------------------
699   # Size maps (BLSURF)
700   #-----------------------------------------
701
702   ## To set a size map on a face, edge or vertex (or group, compound) given Python function.
703   #  If theObject is a face, the function can be: def f(u,v): return u+v
704   #  If theObject is an edge, the function can be: def f(t): return t/2
705   #  If theObject is a vertex, the function can be: def f(): return 10
706   #  @param theObject   : GEOM face, edge or vertex (or group, compound) on which to define a size map
707   #  @param theSizeMap  : Size map defined as a string
708   def SetSizeMap(self, theObject, theSizeMap):
709     from salome.smesh.smeshBuilder import AssureGeomPublished
710     AssureGeomPublished( self.mesh, theObject )
711     self.Parameters().SetSizeMap(theObject, theSizeMap)
712     pass
713
714   ## To set a constant size map on a face, edge or vertex (or group, compound).
715   #  @param theObject   : GEOM face, edge or vertex (or group, compound) on which to define a size map
716   #  @param theSizeMap  : Size map defined as a double
717   def SetConstantSizeMap(self, theObject, theSizeMap):
718     from salome.smesh.smeshBuilder import AssureGeomPublished
719     AssureGeomPublished( self.mesh, theObject )
720     self.Parameters().SetConstantSizeMap(theObject, theSizeMap)
721
722   ## To remove a size map defined on a face, edge or vertex (or group, compound)
723   #  @param theObject   : GEOM face, edge or vertex (or group, compound) on which to define a size map
724   def UnsetSizeMap(self, theObject):
725     from salome.smesh.smeshBuilder import AssureGeomPublished
726     AssureGeomPublished( self.mesh, theObject )
727     self.Parameters().UnsetSizeMap(theObject)
728     pass
729
730   ## To remove all the size maps
731   def ClearSizeMaps(self):
732     self.Parameters().ClearSizeMaps()
733     pass
734
735   ## Sets QuadAllowed flag (DEPRECATED: use SetElementType)
736   #  @param toAllow "allow quadrangles" flag value
737   # TODO: to remove in Salome 9
738   def SetQuadAllowed(self, toAllow=True):
739     self.Parameters().SetQuadAllowed(toAllow)
740     pass
741
742   ## Sets elements type
743   #  @param theElementType: 0 (Triangles), 1 (QuadrangleDominant), 2 (Quadrangles)
744   def SetElementType(self, theElementType=Triangles):
745     self.Parameters().SetElementType(theElementType)
746     pass
747
748   ## Defines hypothesis having several parameters
749   #  @return hypothesis object
750   def Parameters(self):
751     if not self.params:
752       hypType = "MG-CADSurf Parameters"
753       hasGeom = self.mesh.GetMesh().HasShapeToMesh()
754       if hasGeom:
755         self.params = self.Hypothesis(hypType, [], LIBRARY, UseExisting=0)
756       else:
757         self.params = self.Hypothesis(hypType + "_NOGEOM", [], LIBRARY, UseExisting=0)
758         self.mesh.smeshpyD.SetName( self.params, hypType )
759       pass
760     return self.params
761
762   #-----------------------------------------
763   # Periodicity (BLSURF with PreCAD)
764   #-----------------------------------------
765   
766   ## Defines periodicity between two groups of faces, using PreCAD
767   #  @param theFace1 : GEOM face (or group, compound) to associate with theFace2
768   #  @param theFace2 : GEOM face (or group, compound) associated with theFace1
769   #  @param theSourceVertices (optionnal): list of GEOM vertices on theFace1 defining the transformation from theFace1 to theFace2.
770   #    If None, PreCAD tries to find a simple translation. Else, need at least 3 not aligned vertices.
771   #  @param theTargetVertices (optionnal): list of GEOM vertices on theFace2 defining the transformation from theFace1 to theFace2.
772   #    If None, PreCAD tries to find a simple translation. Else, need at least 3 not aligned vertices.
773   def AddPreCadFacesPeriodicity(self, theFace1, theFace2, theSourceVertices=[], theTargetVertices=[]):
774     """calls preCad function:
775     status_t cad_add_face_multiple_periodicity_with_transformation_function(cad t *cad,
776           integer *fid1, integer size1, integer *fid2, integer size2,
777           periodicity_transformation_t transf, void *user data);
778     """
779     if theSourceVertices and theTargetVertices:
780       self.Parameters().AddPreCadFacesPeriodicityWithVertices(theFace1, theFace2, theSourceVertices, theTargetVertices)
781     else:
782       self.Parameters().AddPreCadFacesPeriodicity(theFace1, theFace2)
783     pass
784
785   ## Defines periodicity between two groups of edges, using PreCAD
786   #  @param theEdge1 : GEOM edge (or group, compound) to associate with theEdge2
787   #  @param theEdge2 : GEOM edge (or group, compound) associated with theEdge1
788   #  @param theSourceVertices (optionnal): list of GEOM vertices on theEdge1 defining the transformation from theEdge1 to theEdge2.
789   #    If None, PreCAD tries to find a simple translation. Else, need at least 3 not aligned vertices.
790   #  @param  theTargetVertices (optionnal): list of GEOM vertices on theEdge2 defining the transformation from theEdge1 to theEdge2.
791   #    If None, PreCAD tries to find a simple translation. Else, need at least 3 not aligned vertices.
792   def AddPreCadEdgesPeriodicity(self, theEdge1, theEdge2, theSourceVertices=[], theTargetVertices=[]):
793     """calls preCad function:
794     status_t cad_add_edge_multiple_periodicity_with_transformation_function(cad t *cad,
795           integer *eid1, integer size1, integer *eid2, integer size2,
796           periodicity_transformation_t transf, void *user data);
797     """
798     if theSourceVertices and theTargetVertices:
799         self.Parameters().AddPreCadEdgesPeriodicityWithVertices(theEdge1, theEdge2, theSourceVertices, theTargetVertices)
800     else:
801         self.Parameters().AddPreCadEdgesPeriodicity(theEdge1, theEdge2)
802     pass
803
804   #-----------------------------------------
805   # Hyper-Patches
806   #-----------------------------------------
807   
808   ## Defines hyper-patches. A hyper-patch is a set of adjacent faces meshed as a whole,
809   #  ignoring edges between them
810   #  @param hyperPatchList : list of hyper-patches. A hyper-patch is defined as a list of
811   #         faces or groups of faces. A face can be identified either as a GEOM object or
812   #         a face ID (returned e.g. by geompy.GetSubShapeID( mainShape, subShape )).
813   #         
814   #  Example: cadsurf.SetHyperPatches([[ Face_1, Group_2 ],[ 13, 23 ]])
815   def SetHyperPatches(self, hyperPatchList):
816     hpl = []
817     for patch in hyperPatchList:
818       ids = []
819       for face in patch:
820         if isinstance( face, int ):
821           ids.append( face )
822         elif isinstance( face, GEOM._objref_GEOM_Object):
823           faces = self.mesh.geompyD.SubShapeAll( face, self.mesh.geompyD.ShapeType["FACE"] )
824           for f in faces:
825             ids.append( self.mesh.geompyD.GetSubShapeID( self.mesh.geom, f ))
826         else:
827           raise TypeError("Face of hyper-patch should be either ID or GEOM_Object, not %s" % type(face))
828         pass
829       hpl.append( ids )
830       pass
831     self.Parameters().SetHyperPatches( hpl )
832     return
833
834   pass # end of BLSURF_Algorithm class
835
836 def version_less(version: str, ref_version: str):
837   from re import split
838   return [int(i) for i in split('[.-]', version)] < [int(i) for i in re.split('[.-]', ref_version)]