Salome HOME
22355: EDF SMESH: New 1D hypothesis "Adaptive"
[modules/smesh.git] / src / SMESH_SWIG / StdMeshersBuilder.py
1 # Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
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.
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 StdMeshersBuilder
22 # Python API for the standard meshing plug-in module.
23
24 from salome.smesh.smesh_algorithm import Mesh_Algorithm
25 from salome.smesh.smeshBuilder import AssureGeomPublished, IsEqual, ParseParameters
26 from salome.smesh.smeshBuilder import GetName, TreatHypoStatus
27 from salome.smesh.smeshBuilder import Mesh
28
29 import StdMeshers
30
31 #----------------------------
32 # Mesh algo type identifiers
33 #----------------------------
34
35 ## Algorithm type: Regular 1D algorithm, see StdMeshersBuilder_Segment
36 REGULAR     = "Regular_1D"
37 ## Algorithm type: Python 1D algorithm, see StdMeshersBuilder_Segment_Python
38 PYTHON      = "Python_1D"
39 ## Algorithm type: Composite segment 1D algorithm, see StdMeshersBuilder_CompositeSegment
40 COMPOSITE   = "CompositeSegment_1D"
41 ## Algorithm type: Triangle MEFISTO 2D algorithm, see StdMeshersBuilder_Triangle_MEFISTO
42 MEFISTO     = "MEFISTO_2D"
43 ## Algorithm type: Hexahedron 3D (i-j-k) algorithm, see StdMeshersBuilder_Hexahedron
44 Hexa        = "Hexa_3D"
45 ## Algorithm type: Quadrangle 2D algorithm, see StdMeshersBuilder_Quadrangle
46 QUADRANGLE  = "Quadrangle_2D"
47 ## Algorithm type: Radial Quadrangle 1D-2D algorithm, see StdMeshersBuilder_RadialQuadrangle1D2D
48 RADIAL_QUAD = "RadialQuadrangle_1D2D"
49
50 # import items of enum QuadType
51 for e in StdMeshers.QuadType._items: exec('%s = StdMeshers.%s'%(e,e))
52
53 #----------------------
54 # Algorithms
55 #----------------------
56
57 ## Defines segment 1D algorithm for edges discretization.
58 #
59 #  It can be created by calling smeshBuilder.Mesh.Segment(geom=0)
60 #
61 #  @ingroup l3_algos_basic
62 class StdMeshersBuilder_Segment(Mesh_Algorithm):
63
64     ## name of the dynamic method in smeshBuilder.Mesh class
65     #  @internal
66     meshMethod = "Segment"
67     ## type of algorithm used with helper function in smeshBuilder.Mesh class
68     #  @internal
69     algoType   = REGULAR
70     ## flag pointing either this algorithm should be used by default in dynamic method
71     #  of smeshBuilder.Mesh class
72     #  @internal
73     isDefault  = True
74     ## doc string of the method
75     #  @internal
76     docHelper  = "Creates segment 1D algorithm for edges"
77
78     ## Private constructor.
79     #  @param mesh parent mesh object algorithm is assigned to
80     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
81     #              if it is @c 0 (default), the algorithm is assigned to the main shape
82     def __init__(self, mesh, geom=0):
83         Mesh_Algorithm.__init__(self)
84         self.Create(mesh, geom, self.algoType)
85         pass
86
87     ## Defines "LocalLength" hypothesis to cut an edge in several segments with the same length
88     #  @param l for the length of segments that cut an edge
89     #  @param UseExisting if ==true - searches for an  existing hypothesis created with
90     #                    the same parameters, else (default) - creates a new one
91     #  @param p precision, used for calculation of the number of segments.
92     #           The precision should be a positive, meaningful value within the range [0,1].
93     #           In general, the number of segments is calculated with the formula:
94     #           nb = ceil((edge_length / l) - p)
95     #           Function ceil rounds its argument to the higher integer.
96     #           So, p=0 means rounding of (edge_length / l) to the higher integer,
97     #               p=0.5 means rounding of (edge_length / l) to the nearest integer,
98     #               p=1 means rounding of (edge_length / l) to the lower integer.
99     #           Default value is 1e-07.
100     #  @return an instance of StdMeshers_LocalLength hypothesis
101     #  @ingroup l3_hypos_1dhyps
102     def LocalLength(self, l, UseExisting=0, p=1e-07):
103         comFun=lambda hyp, args: IsEqual(hyp.GetLength(), args[0]) and IsEqual(hyp.GetPrecision(), args[1])
104         hyp = self.Hypothesis("LocalLength", [l,p], UseExisting=UseExisting, CompareMethod=comFun)
105         hyp.SetLength(l)
106         hyp.SetPrecision(p)
107         return hyp
108
109     ## Defines "MaxSize" hypothesis to cut an edge into segments not longer than given value
110     #  @param length is optional maximal allowed length of segment, if it is omitted
111     #                the preestimated length is used that depends on geometry size
112     #  @param UseExisting if ==true - searches for an existing hypothesis created with
113     #                     the same parameters, else (default) - creates a new one
114     #  @return an instance of StdMeshers_MaxLength hypothesis
115     #  @ingroup l3_hypos_1dhyps
116     def MaxSize(self, length=0.0, UseExisting=0):
117         hyp = self.Hypothesis("MaxLength", [length], UseExisting=UseExisting)
118         if length > 0.0:
119             # set given length
120             hyp.SetLength(length)
121         if not UseExisting:
122             # set preestimated length
123             gen = self.mesh.smeshpyD
124             initHyp = gen.GetHypothesisParameterValues("MaxLength", "libStdMeshersEngine.so",
125                                                        self.mesh.GetMesh(), self.mesh.GetShape(),
126                                                        False) # <- byMesh
127             preHyp = initHyp._narrow(StdMeshers.StdMeshers_MaxLength)
128             if preHyp:
129                 hyp.SetPreestimatedLength( preHyp.GetPreestimatedLength() )
130                 pass
131             pass
132         hyp.SetUsePreestimatedLength( length == 0.0 )
133         return hyp
134
135     ## Defines "NumberOfSegments" hypothesis to cut an edge in a fixed number of segments
136     #  @param n for the number of segments that cut an edge
137     #  @param s for the scale factor (optional)
138     #  @param reversedEdges is a list of edges to mesh using reversed orientation.
139     #                       A list item can also be a tuple (edge, 1st_vertex_of_edge)
140     #  @param UseExisting if ==true - searches for an existing hypothesis created with
141     #                     the same parameters, else (default) - create a new one
142     #  @return an instance of StdMeshers_NumberOfSegments hypothesis
143     #  @ingroup l3_hypos_1dhyps
144     def NumberOfSegments(self, n, s=[], reversedEdges=[], UseExisting=0):
145         if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
146             reversedEdges, UseExisting = [], reversedEdges
147         entry = self.MainShapeEntry()
148         reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
149         if s == []:
150             hyp = self.Hypothesis("NumberOfSegments", [n, reversedEdgeInd, entry],
151                                   UseExisting=UseExisting,
152                                   CompareMethod=self._compareNumberOfSegments)
153         else:
154             hyp = self.Hypothesis("NumberOfSegments", [n,s, reversedEdgeInd, entry],
155                                   UseExisting=UseExisting,
156                                   CompareMethod=self._compareNumberOfSegments)
157             hyp.SetDistrType( 1 )
158             hyp.SetScaleFactor(s)
159         hyp.SetNumberOfSegments(n)
160         hyp.SetReversedEdges( reversedEdgeInd )
161         hyp.SetObjectEntry( entry )
162         return hyp
163
164     ## Private method
165     #  
166     #  Checks if the given "NumberOfSegments" hypothesis has the same parameters as the given arguments
167     def _compareNumberOfSegments(self, hyp, args):
168         if hyp.GetNumberOfSegments() == args[0]:
169             if len(args) == 3:
170                 if hyp.GetReversedEdges() == args[1]:
171                     if not args[1] or hyp.GetObjectEntry() == args[2]:
172                         return True
173             else:
174                 if hyp.GetReversedEdges() == args[2]:
175                     if not args[2] or hyp.GetObjectEntry() == args[3]:
176                         if hyp.GetDistrType() == 1:
177                             if IsEqual(hyp.GetScaleFactor(), args[1]):
178                                 return True
179         return False
180
181     ## Defines "Adaptive" hypothesis to cut an edge into segments keeping segment size
182     #  within the given range and considering (1) deflection of segments from the edge
183     #  and (2) distance from segments to closest edges and faces to have segment length
184     #  not longer than two times shortest distances to edges and faces.
185     #  @param minSize defines the minimal allowed segment length
186     #  @param maxSize defines the maximal allowed segment length
187     #  @param deflection defines the maximal allowed distance from a segment to an edge
188     #  @param UseExisting if ==true - searches for an existing hypothesis created with
189     #                     the same parameters, else (default) - creates a new one
190     #  @return an instance of StdMeshers_Adaptive1D hypothesis
191     #  @ingroup l3_hypos_1dhyps
192     def Adaptive(self, minSize, maxSize, deflection, UseExisting=False):
193         compFun = lambda hyp, args: ( IsEqual(hyp.GetMinSize(), args[0]) and \
194                                       IsEqual(hyp.GetMaxSize(), args[1]) and \
195                                       IsEqual(hyp.GetDeflection(), args[2]))
196         hyp = self.Hypothesis("Adaptive1D", [minSize, maxSize, deflection],
197                               UseExisting=UseExisting, CompareMethod=compFun)
198         hyp.SetMinSize(minSize)
199         hyp.SetMaxSize(maxSize)
200         hyp.SetDeflection(deflection)
201         return hyp
202
203     ## Defines "Arithmetic1D" hypothesis to cut an edge in several segments with increasing arithmetic length
204     #  @param start defines the length of the first segment
205     #  @param end   defines the length of the last  segment
206     #  @param reversedEdges is a list of edges to mesh using reversed orientation.
207     #                       A list item can also be a tuple (edge, 1st_vertex_of_edge)
208     #  @param UseExisting if ==true - searches for an existing hypothesis created with
209     #                     the same parameters, else (default) - creates a new one
210     #  @return an instance of StdMeshers_Arithmetic1D hypothesis
211     #  @ingroup l3_hypos_1dhyps
212     def Arithmetic1D(self, start, end, reversedEdges=[], UseExisting=0):
213         if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
214             reversedEdges, UseExisting = [], reversedEdges
215         reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
216         entry = self.MainShapeEntry()
217         compFun = lambda hyp, args: ( IsEqual(hyp.GetLength(1), args[0]) and \
218                                       IsEqual(hyp.GetLength(0), args[1]) and \
219                                       hyp.GetReversedEdges() == args[2]  and \
220                                       (not args[2] or hyp.GetObjectEntry() == args[3]))
221         hyp = self.Hypothesis("Arithmetic1D", [start, end, reversedEdgeInd, entry],
222                               UseExisting=UseExisting, CompareMethod=compFun)
223         hyp.SetStartLength(start)
224         hyp.SetEndLength(end)
225         hyp.SetReversedEdges( reversedEdgeInd )
226         hyp.SetObjectEntry( entry )
227         return hyp
228
229     ## Defines "FixedPoints1D" hypothesis to cut an edge using parameter
230     # on curve from 0 to 1 (additionally it is neecessary to check
231     # orientation of edges and create list of reversed edges if it is
232     # needed) and sets numbers of segments between given points (default
233     # values are equals 1
234     #  @param points defines the list of parameters on curve
235     #  @param nbSegs defines the list of numbers of segments
236     #  @param reversedEdges is a list of edges to mesh using reversed orientation.
237     #                       A list item can also be a tuple (edge, 1st_vertex_of_edge)
238     #  @param UseExisting if ==true - searches for an existing hypothesis created with
239     #                     the same parameters, else (default) - creates a new one
240     #  @return an instance of StdMeshers_Arithmetic1D hypothesis
241     #  @ingroup l3_hypos_1dhyps
242     def FixedPoints1D(self, points, nbSegs=[1], reversedEdges=[], UseExisting=0):
243         if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
244             reversedEdges, UseExisting = [], reversedEdges
245         reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
246         entry = self.MainShapeEntry()
247         compFun = lambda hyp, args: ( hyp.GetPoints() == args[0] and \
248                                       hyp.GetNbSegments() == args[1] and \
249                                       hyp.GetReversedEdges() == args[2] and \
250                                       (not args[2] or hyp.GetObjectEntry() == args[3]))
251         hyp = self.Hypothesis("FixedPoints1D", [points, nbSegs, reversedEdgeInd, entry],
252                               UseExisting=UseExisting, CompareMethod=compFun)
253         hyp.SetPoints(points)
254         hyp.SetNbSegments(nbSegs)
255         hyp.SetReversedEdges(reversedEdgeInd)
256         hyp.SetObjectEntry(entry)
257         return hyp
258
259     ## Defines "StartEndLength" hypothesis to cut an edge in several segments with increasing geometric length
260     #  @param start defines the length of the first segment
261     #  @param end   defines the length of the last  segment
262     #  @param reversedEdges is a list of edges to mesh using reversed orientation.
263     #                       A list item can also be a tuple (edge, 1st_vertex_of_edge)
264     #  @param UseExisting if ==true - searches for an existing hypothesis created with
265     #                     the same parameters, else (default) - creates a new one
266     #  @return an instance of StdMeshers_StartEndLength hypothesis
267     #  @ingroup l3_hypos_1dhyps
268     def StartEndLength(self, start, end, reversedEdges=[], UseExisting=0):
269         if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
270             reversedEdges, UseExisting = [], reversedEdges
271         reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
272         entry = self.MainShapeEntry()
273         compFun = lambda hyp, args: ( IsEqual(hyp.GetLength(1), args[0]) and \
274                                       IsEqual(hyp.GetLength(0), args[1]) and \
275                                       hyp.GetReversedEdges() == args[2]  and \
276                                       (not args[2] or hyp.GetObjectEntry() == args[3]))
277         hyp = self.Hypothesis("StartEndLength", [start, end, reversedEdgeInd, entry],
278                               UseExisting=UseExisting, CompareMethod=compFun)
279         hyp.SetStartLength(start)
280         hyp.SetEndLength(end)
281         hyp.SetReversedEdges( reversedEdgeInd )
282         hyp.SetObjectEntry( entry )
283         return hyp
284
285     ## Defines "Deflection1D" hypothesis
286     #  @param d for the deflection
287     #  @param UseExisting if ==true - searches for an existing hypothesis created with
288     #                     the same parameters, else (default) - create a new one
289     #  @ingroup l3_hypos_1dhyps
290     def Deflection1D(self, d, UseExisting=0):
291         compFun = lambda hyp, args: IsEqual(hyp.GetDeflection(), args[0])
292         hyp = self.Hypothesis("Deflection1D", [d], UseExisting=UseExisting, CompareMethod=compFun)
293         hyp.SetDeflection(d)
294         return hyp
295
296     ## Defines "Propagation" hypothesis that propagates all other hypotheses on all other edges that are at
297     #  the opposite side in case of quadrangular faces
298     #  @ingroup l3_hypos_additi
299     def Propagation(self):
300         return self.Hypothesis("Propagation", UseExisting=1, CompareMethod=self.CompareEqualHyp)
301
302     ## Defines "AutomaticLength" hypothesis
303     #  @param fineness for the fineness [0-1]
304     #  @param UseExisting if ==true - searches for an existing hypothesis created with the
305     #                     same parameters, else (default) - create a new one
306     #  @ingroup l3_hypos_1dhyps
307     def AutomaticLength(self, fineness=0, UseExisting=0):
308         compFun = lambda hyp, args: IsEqual(hyp.GetFineness(), args[0])
309         hyp = self.Hypothesis("AutomaticLength",[fineness],UseExisting=UseExisting,
310                               CompareMethod=compFun)
311         hyp.SetFineness( fineness )
312         return hyp
313
314     ## Defines "SegmentLengthAroundVertex" hypothesis
315     #  @param length for the segment length
316     #  @param vertex for the length localization: the vertex index [0,1] | vertex object.
317     #         Any other integer value means that the hypothesis will be set on the
318     #         whole 1D shape, where Mesh_Segment algorithm is assigned.
319     #  @param UseExisting if ==true - searches for an  existing hypothesis created with
320     #                   the same parameters, else (default) - creates a new one
321     #  @ingroup l3_algos_segmarv
322     def LengthNearVertex(self, length, vertex=0, UseExisting=0):
323         import types
324         store_geom = self.geom
325         if type(vertex) is types.IntType:
326             if vertex == 0 or vertex == 1:
327                 from salome.geom import geomBuilder
328                 vertex = self.mesh.geompyD.ExtractShapes(self.geom, geomBuilder.geomBuilder.ShapeType["VERTEX"],True)[vertex]
329                 self.geom = vertex
330                 pass
331             pass
332         else:
333             self.geom = vertex
334             pass
335         # 0D algorithm
336         if self.geom is None:
337             raise RuntimeError, "Attemp to create SegmentAroundVertex_0D algoritm on None shape"
338         AssureGeomPublished( self.mesh, self.geom )
339         name = GetName(self.geom)
340
341         algo = self.FindAlgorithm("SegmentAroundVertex_0D", self.mesh.smeshpyD)
342         if algo is None:
343             algo = self.mesh.smeshpyD.CreateHypothesis("SegmentAroundVertex_0D", "libStdMeshersEngine.so")
344             pass
345         status = self.mesh.mesh.AddHypothesis(self.geom, algo)
346         TreatHypoStatus(status, "SegmentAroundVertex_0D", name, True)
347         #
348         comFun = lambda hyp, args: IsEqual(hyp.GetLength(), args[0])
349         hyp = self.Hypothesis("SegmentLengthAroundVertex", [length], UseExisting=UseExisting,
350                               CompareMethod=comFun)
351         self.geom = store_geom
352         hyp.SetLength( length )
353         return hyp
354
355     ## Defines "QuadraticMesh" hypothesis, forcing construction of quadratic edges.
356     #  If the 2D mesher sees that all boundary edges are quadratic,
357     #  it generates quadratic faces, else it generates linear faces using
358     #  medium nodes as if they are vertices.
359     #  The 3D mesher generates quadratic volumes only if all boundary faces
360     #  are quadratic, else it fails.
361     #
362     #  @ingroup l3_hypos_additi
363     def QuadraticMesh(self):
364         hyp = self.Hypothesis("QuadraticMesh", UseExisting=1, CompareMethod=self.CompareEqualHyp)
365         return hyp
366
367     pass # end of StdMeshersBuilder_Segment class
368
369 ## Segment 1D algorithm for discretization of a set of adjacent edges as one edge.
370 #
371 #  It is created by calling smeshBuilder.Mesh.Segment(smeshBuilder.COMPOSITE,geom=0)
372 #
373 #  @ingroup l3_algos_basic
374 class StdMeshersBuilder_CompositeSegment(StdMeshersBuilder_Segment):
375
376     ## name of the dynamic method in smeshBuilder.Mesh class
377     #  @internal
378     meshMethod = "Segment"
379     ## type of algorithm used with helper function in smeshBuilder.Mesh class
380     #  @internal
381     algoType   = COMPOSITE
382     ## flag pointing either this algorithm should be used by default in dynamic method
383     #  of smeshBuilder.Mesh class
384     #  @internal
385     isDefault  = False
386     ## doc string of the method
387     #  @internal
388     docHelper  = "Creates segment 1D algorithm for edges"
389
390     ## Private constructor.
391     #  @param mesh parent mesh object algorithm is assigned to
392     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
393     #              if it is @c 0 (default), the algorithm is assigned to the main shape
394     def __init__(self, mesh, geom=0):
395         self.Create(mesh, geom, self.algoType)
396         pass
397
398     pass # end of StdMeshersBuilder_CompositeSegment class
399
400 ## Defines a segment 1D algorithm for discretization of edges with Python function
401 #
402 #  It is created by calling smeshBuilder.Mesh.Segment(smeshBuilder.PYTHON,geom=0)
403 #
404 #  @ingroup l3_algos_basic
405 class StdMeshersBuilder_Segment_Python(Mesh_Algorithm):
406
407     ## name of the dynamic method in smeshBuilder.Mesh class
408     #  @internal
409     meshMethod = "Segment"
410     ## type of algorithm used with helper function in smeshBuilder.Mesh class
411     #  @internal
412     algoType   = PYTHON
413     ## doc string of the method
414     #  @internal
415     docHelper  = "Creates tetrahedron 3D algorithm for solids"
416     ## doc string of the method
417     #  @internal
418     docHelper  = "Creates segment 1D algorithm for edges"
419
420     ## Private constructor.
421     #  @param mesh parent mesh object algorithm is assigned to
422     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
423     #              if it is @c 0 (default), the algorithm is assigned to the main shape
424     def __init__(self, mesh, geom=0):
425         import Python1dPlugin
426         self.Create(mesh, geom, self.algoType, "libPython1dEngine.so")
427         pass
428
429     ## Defines "PythonSplit1D" hypothesis
430     #  @param n for the number of segments that cut an edge
431     #  @param func for the python function that calculates the length of all segments
432     #  @param UseExisting if ==true - searches for the existing hypothesis created with
433     #                     the same parameters, else (default) - creates a new one
434     #  @ingroup l3_hypos_1dhyps
435     def PythonSplit1D(self, n, func, UseExisting=0):
436         compFun = lambda hyp, args: False
437         hyp = self.Hypothesis("PythonSplit1D", [n], "libPython1dEngine.so",
438                               UseExisting=UseExisting, CompareMethod=compFun)
439         hyp.SetNumberOfSegments(n)
440         hyp.SetPythonLog10RatioFunction(func)
441         return hyp
442
443     pass # end of StdMeshersBuilder_Segment_Python class
444
445 ## Triangle MEFISTO 2D algorithm
446 #
447 #  It is created by calling smeshBuilder.Mesh.Triangle(smeshBuilder.MEFISTO,geom=0)
448 #
449 #  @ingroup l3_algos_basic
450 class StdMeshersBuilder_Triangle_MEFISTO(Mesh_Algorithm):
451
452     ## name of the dynamic method in smeshBuilder.Mesh class
453     #  @internal
454     meshMethod = "Triangle"
455     ## type of algorithm used with helper function in smeshBuilder.Mesh class
456     #  @internal
457     algoType   = MEFISTO
458     ## flag pointing either this algorithm should be used by default in dynamic method
459     #  of smeshBuilder.Mesh class
460     #  @internal
461     isDefault  = True
462     ## doc string of the method
463     #  @internal
464     docHelper  = "Creates triangle 2D algorithm for faces"
465
466     ## Private constructor.
467     #  @param mesh parent mesh object algorithm is assigned to
468     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
469     #              if it is @c 0 (default), the algorithm is assigned to the main shape
470     def __init__(self, mesh, geom=0):
471         Mesh_Algorithm.__init__(self)
472         self.Create(mesh, geom, self.algoType)
473         pass
474
475     ## Defines "MaxElementArea" hypothesis basing on the definition of the maximum area of each triangle
476     #  @param area for the maximum area of each triangle
477     #  @param UseExisting if ==true - searches for an  existing hypothesis created with the
478     #                     same parameters, else (default) - creates a new one
479     #
480     #  @ingroup l3_hypos_2dhyps
481     def MaxElementArea(self, area, UseExisting=0):
482         comparator = lambda hyp, args: IsEqual(hyp.GetMaxElementArea(), args[0])
483         hyp = self.Hypothesis("MaxElementArea", [area], UseExisting=UseExisting,
484                               CompareMethod=comparator)
485         hyp.SetMaxElementArea(area)
486         return hyp
487
488     ## Defines "LengthFromEdges" hypothesis to build triangles
489     #  based on the length of the edges taken from the wire
490     #
491     #  @ingroup l3_hypos_2dhyps
492     def LengthFromEdges(self):
493         hyp = self.Hypothesis("LengthFromEdges", UseExisting=1, CompareMethod=self.CompareEqualHyp)
494         return hyp
495
496     pass # end of StdMeshersBuilder_Triangle_MEFISTO class
497
498 ## Defines a quadrangle 2D algorithm
499
500 #  It is created by calling smeshBuilder.Mesh.Quadrangle(geom=0)
501 #
502 #  @ingroup l3_algos_basic
503 class StdMeshersBuilder_Quadrangle(Mesh_Algorithm):
504
505     ## name of the dynamic method in smeshBuilder.Mesh class
506     #  @internal
507     meshMethod = "Quadrangle"
508     ## type of algorithm used with helper function in smeshBuilder.Mesh class
509     #  @internal
510     algoType   = QUADRANGLE
511     ## flag pointing either this algorithm should be used by default in dynamic method
512     #  of smeshBuilder.Mesh class
513     #  @internal
514     isDefault  = True
515     ## doc string of the method
516     #  @internal
517     docHelper  = "Creates quadrangle 2D algorithm for faces"
518     ## hypothesis associated with algorithm
519     #  @internal
520     params     = 0
521
522     ## Private constructor.
523     #  @param mesh parent mesh object algorithm is assigned to
524     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
525     #              if it is @c 0 (default), the algorithm is assigned to the main shape
526     def __init__(self, mesh, geom=0):
527         Mesh_Algorithm.__init__(self)
528         self.Create(mesh, geom, self.algoType)
529         pass
530
531     ## Defines "QuadrangleParameters" hypothesis
532     #  @param quadType defines the algorithm of transition between differently descretized
533     #                  sides of a geometrical face:
534     #  - QUAD_STANDARD - both triangles and quadrangles are possible in the transition
535     #                    area along the finer meshed sides.
536     #  - QUAD_TRIANGLE_PREF - only triangles are built in the transition area along the
537     #                    finer meshed sides.
538     #  - QUAD_QUADRANGLE_PREF - only quadrangles are built in the transition area along
539     #                    the finer meshed sides, iff the total quantity of segments on
540     #                    all four sides of the face is even (divisible by 2).
541     #  - QUAD_QUADRANGLE_PREF_REVERSED - same as QUAD_QUADRANGLE_PREF but the transition
542     #                    area is located along the coarser meshed sides.
543     #  - QUAD_REDUCED - only quadrangles are built and the transition between the sides
544     #                    is made gradually, layer by layer. This type has a limitation on
545     #                    the number of segments: one pair of opposite sides must have the
546     #                    same number of segments, the other pair must have an even difference
547     #                    between the numbers of segments on the sides.
548     #  @param triangleVertex: vertex of a trilateral geometrical face, around which triangles
549     #                  will be created while other elements will be quadrangles.
550     #                  Vertex can be either a GEOM_Object or a vertex ID within the
551     #                  shape to mesh
552     #  @param UseExisting: if ==true - searches for the existing hypothesis created with
553     #                  the same parameters, else (default) - creates a new one
554     #  @ingroup l3_hypos_quad
555     def QuadrangleParameters(self, quadType=StdMeshers.QUAD_STANDARD, triangleVertex=0, UseExisting=0):
556         import GEOM
557         vertexID = triangleVertex
558         if isinstance( triangleVertex, GEOM._objref_GEOM_Object ):
559             vertexID = self.mesh.geompyD.GetSubShapeID( self.mesh.geom, triangleVertex )
560         if not self.params:
561             compFun = lambda hyp,args: \
562                       hyp.GetQuadType() == args[0] and \
563                       ( hyp.GetTriaVertex()==args[1] or ( hyp.GetTriaVertex()<1 and args[1]<1))
564             self.params = self.Hypothesis("QuadrangleParams", [quadType,vertexID],
565                                           UseExisting = UseExisting, CompareMethod=compFun)
566             pass
567         if self.params.GetQuadType() != quadType:
568             self.params.SetQuadType(quadType)
569         if vertexID > 0:
570             self.params.SetTriaVertex( vertexID )
571         return self.params
572
573     ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only
574     #   quadrangles are built in the transition area along the finer meshed sides,
575     #   iff the total quantity of segments on all four sides of the face is even.
576     #  @param reversed if True, transition area is located along the coarser meshed sides.
577     #  @param UseExisting: if ==true - searches for the existing hypothesis created with
578     #                  the same parameters, else (default) - creates a new one
579     #  @ingroup l3_hypos_quad
580     def QuadranglePreference(self, reversed=False, UseExisting=0):
581         if reversed:
582             return self.QuadrangleParameters(QUAD_QUADRANGLE_PREF_REVERSED,UseExisting=UseExisting)
583         return self.QuadrangleParameters(QUAD_QUADRANGLE_PREF,UseExisting=UseExisting)
584
585     ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only
586     #   triangles are built in the transition area along the finer meshed sides.
587     #  @param UseExisting: if ==true - searches for the existing hypothesis created with
588     #                  the same parameters, else (default) - creates a new one
589     #  @ingroup l3_hypos_quad
590     def TrianglePreference(self, UseExisting=0):
591         return self.QuadrangleParameters(QUAD_TRIANGLE_PREF,UseExisting=UseExisting)
592
593     ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only
594     #   quadrangles are built and the transition between the sides is made gradually,
595     #   layer by layer. This type has a limitation on the number of segments: one pair
596     #   of opposite sides must have the same number of segments, the other pair must
597     #   have an even difference between the numbers of segments on the sides.
598     #  @param UseExisting: if ==true - searches for the existing hypothesis created with
599     #                  the same parameters, else (default) - creates a new one
600     #  @ingroup l3_hypos_quad
601     def Reduced(self, UseExisting=0):
602         return self.QuadrangleParameters(QUAD_REDUCED,UseExisting=UseExisting)
603
604     ## Defines "QuadrangleParams" hypothesis with QUAD_STANDARD type of quadrangulation
605     #  @param vertex: vertex of a trilateral geometrical face, around which triangles
606     #                 will be created while other elements will be quadrangles.
607     #                 Vertex can be either a GEOM_Object or a vertex ID within the
608     #                 shape to mesh
609     #  @param UseExisting: if ==true - searches for the existing hypothesis created with
610     #                   the same parameters, else (default) - creates a new one
611     #  @ingroup l3_hypos_quad
612     def TriangleVertex(self, vertex, UseExisting=0):
613         return self.QuadrangleParameters(QUAD_STANDARD,vertex,UseExisting)
614
615     pass # end of StdMeshersBuilder_Quadrangle class
616
617 ## Defines a hexahedron 3D algorithm
618
619 #  It is created by calling smeshBuilder.Mesh.Hexahedron(geom=0)
620 #
621 #  @ingroup l3_algos_basic
622 class StdMeshersBuilder_Hexahedron(Mesh_Algorithm):
623
624     ## name of the dynamic method in smeshBuilder.Mesh class
625     #  @internal
626     meshMethod = "Hexahedron"
627     ## type of algorithm used with helper function in smeshBuilder.Mesh class
628     #  @internal
629     algoType   = Hexa
630     ## flag pointing either this algorithm should be used by default in dynamic method
631     #  of smeshBuilder.Mesh class
632     #  @internal
633     isDefault  = True
634     ## doc string of the method
635     #  @internal
636     docHelper  = "Creates hexahedron 3D algorithm for volumes"
637
638     ## Private constructor.
639     #  @param mesh parent mesh object algorithm is assigned to
640     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
641     #              if it is @c 0 (default), the algorithm is assigned to the main shape
642     def __init__(self, mesh, geom=0):
643         Mesh_Algorithm.__init__(self)
644         self.Create(mesh, geom, Hexa)
645         pass
646
647     pass # end of StdMeshersBuilder_Hexahedron class
648
649 ## Defines a projection 1D algorithm
650 #  
651 #  It is created by calling smeshBuilder.Mesh.Projection1D(geom=0)
652 #
653 #  @ingroup l3_algos_proj
654 class StdMeshersBuilder_Projection1D(Mesh_Algorithm):
655
656     ## name of the dynamic method in smeshBuilder.Mesh class
657     #  @internal
658     meshMethod = "Projection1D"
659     ## type of algorithm used with helper function in smeshBuilder.Mesh class
660     #  @internal
661     algoType   = "Projection_1D"
662     ## flag pointing either this algorithm should be used by default in dynamic method
663     #  of smeshBuilder.Mesh class
664     #  @internal
665     isDefault  = True
666     ## doc string of the method
667     #  @internal
668     docHelper  = "Creates projection 1D algorithm for edges"
669
670     ## Private constructor.
671     #  @param mesh parent mesh object algorithm is assigned to
672     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
673     #              if it is @c 0 (default), the algorithm is assigned to the main shape
674     def __init__(self, mesh, geom=0):
675         Mesh_Algorithm.__init__(self)
676         self.Create(mesh, geom, self.algoType)
677         pass
678
679     ## Defines "Source Edge" hypothesis, specifying a meshed edge, from where
680     #  a mesh pattern is taken, and, optionally, the association of vertices
681     #  between the source edge and a target edge (to which a hypothesis is assigned)
682     #  @param edge from which nodes distribution is taken
683     #  @param mesh from which nodes distribution is taken (optional)
684     #  @param srcV a vertex of \a edge to associate with \a tgtV (optional)
685     #  @param tgtV a vertex of \a the edge to which the algorithm is assigned,
686     #  to associate with \a srcV (optional)
687     #  @param UseExisting if ==true - searches for the existing hypothesis created with
688     #                     the same parameters, else (default) - creates a new one
689     def SourceEdge(self, edge, mesh=None, srcV=None, tgtV=None, UseExisting=0):
690         AssureGeomPublished( self.mesh, edge )
691         AssureGeomPublished( self.mesh, srcV )
692         AssureGeomPublished( self.mesh, tgtV )
693         hyp = self.Hypothesis("ProjectionSource1D", [edge,mesh,srcV,tgtV],
694                               UseExisting=0)
695         # it does not seem to be useful to reuse the existing "SourceEdge" hypothesis
696                               #UseExisting=UseExisting, CompareMethod=self.CompareSourceEdge)
697         hyp.SetSourceEdge( edge )
698         if not mesh is None and isinstance(mesh, Mesh):
699             mesh = mesh.GetMesh()
700         hyp.SetSourceMesh( mesh )
701         hyp.SetVertexAssociation( srcV, tgtV )
702         return hyp
703
704     pass # end of StdMeshersBuilder_Projection1D class
705
706 ## Defines a projection 2D algorithm
707 #  
708 #  It is created by calling smeshBuilder.Mesh.Projection2D(geom=0)
709 #
710 #  @ingroup l3_algos_proj
711 class StdMeshersBuilder_Projection2D(Mesh_Algorithm):
712
713     ## name of the dynamic method in smeshBuilder.Mesh class
714     #  @internal
715     meshMethod = "Projection2D"
716     ## type of algorithm used with helper function in smeshBuilder.Mesh class
717     #  @internal
718     algoType   = "Projection_2D"
719     ## flag pointing either this algorithm should be used by default in dynamic method
720     #  of smeshBuilder.Mesh class
721     #  @internal
722     isDefault  = True
723     ## doc string of the method
724     #  @internal
725     docHelper  = "Creates projection 2D algorithm for faces"
726
727     ## Private constructor.
728     #  @param mesh parent mesh object algorithm is assigned to
729     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
730     #              if it is @c 0 (default), the algorithm is assigned to the main shape
731     def __init__(self, mesh, geom=0):
732         Mesh_Algorithm.__init__(self)
733         self.Create(mesh, geom, self.algoType)
734         pass
735
736     ## Defines "Source Face" hypothesis, specifying a meshed face, from where
737     #  a mesh pattern is taken, and, optionally, the association of vertices
738     #  between the source face and the target face (to which a hypothesis is assigned)
739     #  @param face from which the mesh pattern is taken
740     #  @param mesh from which the mesh pattern is taken (optional)
741     #  @param srcV1 a vertex of \a face to associate with \a tgtV1 (optional)
742     #  @param tgtV1 a vertex of \a the face to which the algorithm is assigned,
743     #               to associate with \a srcV1 (optional)
744     #  @param srcV2 a vertex of \a face to associate with \a tgtV1 (optional)
745     #  @param tgtV2 a vertex of \a the face to which the algorithm is assigned,
746     #               to associate with \a srcV2 (optional)
747     #  @param UseExisting if ==true - forces the search for the existing hypothesis created with
748     #                     the same parameters, else (default) - forces the creation a new one
749     #
750     #  Note: all association vertices must belong to one edge of a face
751     def SourceFace(self, face, mesh=None, srcV1=None, tgtV1=None,
752                    srcV2=None, tgtV2=None, UseExisting=0):
753         from salome.smesh.smeshBuilder import Mesh
754         if isinstance(mesh, Mesh):
755             mesh = mesh.GetMesh()
756         for geom in [ face, srcV1, tgtV1, srcV2, tgtV2 ]:
757             AssureGeomPublished( self.mesh, geom )
758         hyp = self.Hypothesis("ProjectionSource2D", [face,mesh,srcV1,tgtV1,srcV2,tgtV2],
759                               UseExisting=0)
760         # it does not seem to be useful to reuse the existing "SourceFace" hypothesis
761                               #UseExisting=UseExisting, CompareMethod=self.CompareSourceFace)
762         hyp.SetSourceFace( face )
763         hyp.SetSourceMesh( mesh )
764         hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 )
765         return hyp
766
767     pass # end of StdMeshersBuilder_Projection2D class
768
769 ## Defines a projection 1D-2D algorithm
770 #  
771 #  It is created by calling smeshBuilder.Mesh.Projection1D2D(geom=0)
772 #
773 #  @ingroup l3_algos_proj
774 class StdMeshersBuilder_Projection1D2D(StdMeshersBuilder_Projection2D):
775
776     ## name of the dynamic method in smeshBuilder.Mesh class
777     #  @internal
778     meshMethod = "Projection1D2D"
779     ## type of algorithm used with helper function in smeshBuilder.Mesh class
780     #  @internal
781     algoType   = "Projection_1D2D"
782     ## doc string of the method
783     #  @internal
784     docHelper  = "Creates projection 1D-2D algorithm for edges and faces"
785
786     ## Private constructor.
787     #  @param mesh parent mesh object algorithm is assigned to
788     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
789     #              if it is @c 0 (default), the algorithm is assigned to the main shape
790     def __init__(self, mesh, geom=0):
791         StdMeshersBuilder_Projection2D.__init__(self, mesh, geom)
792         pass
793
794     pass # end of StdMeshersBuilder_Projection1D2D class
795
796 ## Defines a projection 3D algorithm
797
798 #  It is created by calling smeshBuilder.Mesh.Projection3D(geom=0)
799 #
800 #  @ingroup l3_algos_proj
801 class StdMeshersBuilder_Projection3D(Mesh_Algorithm):
802
803     ## name of the dynamic method in smeshBuilder.Mesh class
804     #  @internal
805     meshMethod = "Projection3D"
806     ## type of algorithm used with helper function in smeshBuilder.Mesh class
807     #  @internal
808     algoType   = "Projection_3D"
809     ## doc string of the method
810     #  @internal
811     docHelper  = "Creates projection 3D algorithm for volumes"
812
813     ## Private constructor.
814     #  @param mesh parent mesh object algorithm is assigned to
815     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
816     #              if it is @c 0 (default), the algorithm is assigned to the main shape
817     def __init__(self, mesh, geom=0):
818         Mesh_Algorithm.__init__(self)
819         self.Create(mesh, geom, self.algoType)
820         pass
821
822     ## Defines the "Source Shape 3D" hypothesis, specifying a meshed solid, from where
823     #  the mesh pattern is taken, and, optionally, the  association of vertices
824     #  between the source and the target solid  (to which a hipothesis is assigned)
825     #  @param solid from where the mesh pattern is taken
826     #  @param mesh from where the mesh pattern is taken (optional)
827     #  @param srcV1 a vertex of \a solid to associate with \a tgtV1 (optional)
828     #  @param tgtV1 a vertex of \a the solid where the algorithm is assigned,
829     #  to associate with \a srcV1 (optional)
830     #  @param srcV2 a vertex of \a solid to associate with \a tgtV1 (optional)
831     #  @param tgtV2 a vertex of \a the solid to which the algorithm is assigned,
832     #  to associate with \a srcV2 (optional)
833     #  @param UseExisting - if ==true - searches for the existing hypothesis created with
834     #                     the same parameters, else (default) - creates a new one
835     #
836     #  Note: association vertices must belong to one edge of a solid
837     def SourceShape3D(self, solid, mesh=0, srcV1=0, tgtV1=0,
838                       srcV2=0, tgtV2=0, UseExisting=0):
839         for geom in [ solid, srcV1, tgtV1, srcV2, tgtV2 ]:
840             AssureGeomPublished( self.mesh, geom )
841         hyp = self.Hypothesis("ProjectionSource3D",
842                               [solid,mesh,srcV1,tgtV1,srcV2,tgtV2],
843                               UseExisting=0)
844         # seems to be not really useful to reuse existing "SourceShape3D" hypothesis
845                               #UseExisting=UseExisting, CompareMethod=self.CompareSourceShape3D)
846         hyp.SetSource3DShape( solid )
847         if isinstance(mesh, Mesh):
848             mesh = mesh.GetMesh()
849         if mesh:
850             hyp.SetSourceMesh( mesh )
851         if srcV1 and srcV2 and tgtV1 and tgtV2:
852             hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 )
853         #elif srcV1 or srcV2 or tgtV1 or tgtV2:
854         return hyp
855
856     pass # end of StdMeshersBuilder_Projection3D class
857
858 ## Defines a Prism 3D algorithm, which is either "Extrusion 3D" or "Radial Prism"
859 #  depending on geometry
860
861 #  It is created by calling smeshBuilder.Mesh.Prism(geom=0)
862 #
863 #  @ingroup l3_algos_3dextr
864 class StdMeshersBuilder_Prism3D(Mesh_Algorithm):
865
866     ## name of the dynamic method in smeshBuilder.Mesh class
867     #  @internal
868     meshMethod = "Prism"
869     ## type of algorithm used with helper function in smeshBuilder.Mesh class
870     #  @internal
871     algoType   = "Prism_3D"
872     ## doc string of the method
873     #  @internal
874     docHelper  = "Creates prism 3D algorithm for volumes"
875
876     ## Private constructor.
877     #  @param mesh parent mesh object algorithm is assigned to
878     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
879     #              if it is @c 0 (default), the algorithm is assigned to the main shape
880     def __init__(self, mesh, geom=0):
881         Mesh_Algorithm.__init__(self)
882         
883         shape = geom
884         if not shape:
885             shape = mesh.geom
886         from salome.geom import geomBuilder
887         nbSolids = len( geomBuilder.geom.SubShapeAll( shape, geomBuilder.geomBuilder.ShapeType["SOLID"] ))
888         nbShells = len( geomBuilder.geom.SubShapeAll( shape, geomBuilder.geomBuilder.ShapeType["SHELL"] ))
889         if nbSolids == 0 or nbSolids == nbShells:
890             self.Create(mesh, geom, "Prism_3D")
891             pass
892         else:
893             self.algoType = "RadialPrism_3D"
894             self.Create(mesh, geom, "RadialPrism_3D")
895             self.distribHyp = None #self.Hypothesis("LayerDistribution", UseExisting=0)
896             self.nbLayers = None
897             pass
898         pass
899
900     ## Return 3D hypothesis holding the 1D one
901     def Get3DHypothesis(self):
902         if self.algoType != "RadialPrism_3D":
903             print "Prism_3D algorith doesn't support any hyposesis"
904             return None
905         return self.distribHyp
906
907     ## Private method creating a 1D hypothesis and storing it in the LayerDistribution
908     #  hypothesis. Returns the created hypothesis
909     def OwnHypothesis(self, hypType, args=[], so="libStdMeshersEngine.so"):
910         if self.algoType != "RadialPrism_3D":
911             print "Prism_3D algorith doesn't support any hyposesis"
912             return None
913         if not self.nbLayers is None:
914             self.mesh.GetMesh().RemoveHypothesis( self.geom, self.nbLayers )
915             self.mesh.GetMesh().AddHypothesis( self.geom, self.distribHyp )
916         study = self.mesh.smeshpyD.GetCurrentStudy() # prevents publishing own 1D hypothesis
917         self.mesh.smeshpyD.SetCurrentStudy( None )
918         hyp = self.mesh.smeshpyD.CreateHypothesis(hypType, so)
919         self.mesh.smeshpyD.SetCurrentStudy( study ) # enables publishing
920         if not self.distribHyp:
921             self.distribHyp = self.Hypothesis("LayerDistribution", UseExisting=0)
922         self.distribHyp.SetLayerDistribution( hyp )
923         return hyp
924
925     ## Defines "NumberOfLayers" hypothesis, specifying the number of layers of
926     #  prisms to build between the inner and outer shells
927     #  @param n number of layers
928     #  @param UseExisting if ==true - searches for the existing hypothesis created with
929     #                     the same parameters, else (default) - creates a new one
930     def NumberOfLayers(self, n, UseExisting=0):
931         if self.algoType != "RadialPrism_3D":
932             print "Prism_3D algorith doesn't support any hyposesis"
933             return None
934         self.mesh.RemoveHypothesis( self.distribHyp, self.geom )
935         compFun = lambda hyp, args: IsEqual(hyp.GetNumberOfLayers(), args[0])
936         self.nbLayers = self.Hypothesis("NumberOfLayers", [n], UseExisting=UseExisting,
937                                         CompareMethod=compFun)
938         self.nbLayers.SetNumberOfLayers( n )
939         return self.nbLayers
940
941     ## Defines "LocalLength" hypothesis, specifying the segment length
942     #  to build between the inner and the outer shells
943     #  @param l the length of segments
944     #  @param p the precision of rounding
945     def LocalLength(self, l, p=1e-07):
946         if self.algoType != "RadialPrism_3D":
947             print "Prism_3D algorith doesn't support any hyposesis"
948             return None
949         hyp = self.OwnHypothesis("LocalLength", [l,p])
950         hyp.SetLength(l)
951         hyp.SetPrecision(p)
952         return hyp
953
954     ## Defines "NumberOfSegments" hypothesis, specifying the number of layers of
955     #  prisms to build between the inner and the outer shells.
956     #  @param n the number of layers
957     #  @param s the scale factor (optional)
958     def NumberOfSegments(self, n, s=[]):
959         if self.algoType != "RadialPrism_3D":
960             print "Prism_3D algorith doesn't support any hyposesis"
961             return None
962         if s == []:
963             hyp = self.OwnHypothesis("NumberOfSegments", [n])
964         else:
965             hyp = self.OwnHypothesis("NumberOfSegments", [n,s])
966             hyp.SetDistrType( 1 )
967             hyp.SetScaleFactor(s)
968         hyp.SetNumberOfSegments(n)
969         return hyp
970
971     ## Defines "Arithmetic1D" hypothesis, specifying the distribution of segments
972     #  to build between the inner and the outer shells with a length that changes in arithmetic progression
973     #  @param start  the length of the first segment
974     #  @param end    the length of the last  segment
975     def Arithmetic1D(self, start, end ):
976         if self.algoType != "RadialPrism_3D":
977             print "Prism_3D algorith doesn't support any hyposesis"
978             return None
979         hyp = self.OwnHypothesis("Arithmetic1D", [start, end])
980         hyp.SetLength(start, 1)
981         hyp.SetLength(end  , 0)
982         return hyp
983
984     ## Defines "StartEndLength" hypothesis, specifying distribution of segments
985     #  to build between the inner and the outer shells as geometric length increasing
986     #  @param start for the length of the first segment
987     #  @param end   for the length of the last  segment
988     def StartEndLength(self, start, end):
989         if self.algoType != "RadialPrism_3D":
990             print "Prism_3D algorith doesn't support any hyposesis"
991             return None
992         hyp = self.OwnHypothesis("StartEndLength", [start, end])
993         hyp.SetLength(start, 1)
994         hyp.SetLength(end  , 0)
995         return hyp
996
997     ## Defines "AutomaticLength" hypothesis, specifying the number of segments
998     #  to build between the inner and outer shells
999     #  @param fineness defines the quality of the mesh within the range [0-1]
1000     def AutomaticLength(self, fineness=0):
1001         if self.algoType != "RadialPrism_3D":
1002             print "Prism_3D algorith doesn't support any hyposesis"
1003             return None
1004         hyp = self.OwnHypothesis("AutomaticLength")
1005         hyp.SetFineness( fineness )
1006         return hyp
1007
1008     pass # end of StdMeshersBuilder_Prism3D class
1009
1010 ## Defines a Prism 3D algorithm, which is either "Extrusion 3D" or "Radial Prism"
1011 #  depending on geometry
1012
1013 #  It is created by calling smeshBuilder.Mesh.Prism(geom=0)
1014 #
1015 #  @ingroup l3_algos_3dextr
1016 class StdMeshersBuilder_RadialPrism3D(StdMeshersBuilder_Prism3D):
1017
1018     ## name of the dynamic method in smeshBuilder.Mesh class
1019     #  @internal
1020     meshMethod = "Prism"
1021     ## type of algorithm used with helper function in smeshBuilder.Mesh class
1022     #  @internal
1023     algoType   = "RadialPrism_3D"
1024     ## doc string of the method
1025     #  @internal
1026     docHelper  = "Creates prism 3D algorithm for volumes"
1027
1028     ## Private constructor.
1029     #  @param mesh parent mesh object algorithm is assigned to
1030     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
1031     #              if it is @c 0 (default), the algorithm is assigned to the main shape
1032     def __init__(self, mesh, geom=0):
1033         Mesh_Algorithm.__init__(self)
1034         
1035         shape = geom
1036         if not shape:
1037             shape = mesh.geom
1038         self.Create(mesh, geom, "RadialPrism_3D")
1039         self.distribHyp = None
1040         self.nbLayers = None
1041         return
1042
1043 ## Defines a Radial Quadrangle 1D-2D algorithm
1044
1045 #  It is created by calling smeshBuilder.Mesh.Quadrangle(smeshBuilder.RADIAL_QUAD,geom=0)
1046 #
1047 #  @ingroup l2_algos_radialq
1048 class StdMeshersBuilder_RadialQuadrangle1D2D(Mesh_Algorithm):
1049
1050     ## name of the dynamic method in smeshBuilder.Mesh class
1051     #  @internal
1052     meshMethod = "Quadrangle"
1053     ## type of algorithm used with helper function in smeshBuilder.Mesh class
1054     #  @internal
1055     algoType   = RADIAL_QUAD
1056     ## doc string of the method
1057     #  @internal
1058     docHelper  = "Creates quadrangle 1D-2D algorithm for triangular faces"
1059
1060     ## Private constructor.
1061     #  @param mesh parent mesh object algorithm is assigned to
1062     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
1063     #              if it is @c 0 (default), the algorithm is assigned to the main shape
1064     def __init__(self, mesh, geom=0):
1065         Mesh_Algorithm.__init__(self)
1066         self.Create(mesh, geom, self.algoType)
1067
1068         self.distribHyp = None #self.Hypothesis("LayerDistribution2D", UseExisting=0)
1069         self.nbLayers = None
1070         pass
1071
1072     ## Return 2D hypothesis holding the 1D one
1073     def Get2DHypothesis(self):
1074         if not self.distribHyp:
1075             self.distribHyp = self.Hypothesis("LayerDistribution2D", UseExisting=0)
1076         return self.distribHyp
1077
1078     ## Private method creating a 1D hypothesis and storing it in the LayerDistribution
1079     #  hypothesis. Returns the created hypothesis
1080     def OwnHypothesis(self, hypType, args=[], so="libStdMeshersEngine.so"):
1081         if self.nbLayers:
1082             self.mesh.GetMesh().RemoveHypothesis( self.geom, self.nbLayers )
1083         if self.distribHyp is None:
1084             self.distribHyp = self.Hypothesis("LayerDistribution2D", UseExisting=0)
1085         else:
1086             self.mesh.GetMesh().AddHypothesis( self.geom, self.distribHyp )
1087         study = self.mesh.smeshpyD.GetCurrentStudy() # prevents publishing own 1D hypothesis
1088         self.mesh.smeshpyD.SetCurrentStudy( None )
1089         hyp = self.mesh.smeshpyD.CreateHypothesis(hypType, so)
1090         self.mesh.smeshpyD.SetCurrentStudy( study ) # enables publishing
1091         self.distribHyp.SetLayerDistribution( hyp )
1092         return hyp
1093
1094     ## Defines "NumberOfLayers" hypothesis, specifying the number of layers
1095     #  @param n number of layers
1096     #  @param UseExisting if ==true - searches for the existing hypothesis created with
1097     #                     the same parameters, else (default) - creates a new one
1098     def NumberOfLayers(self, n, UseExisting=0):
1099         if self.distribHyp:
1100             self.mesh.GetMesh().RemoveHypothesis( self.geom, self.distribHyp )
1101         compFun = lambda hyp, args: IsEqual(hyp.GetNumberOfLayers(), args[0])
1102         self.nbLayers = self.Hypothesis("NumberOfLayers2D", [n], UseExisting=UseExisting,
1103                                         CompareMethod=compFun)
1104         self.nbLayers.SetNumberOfLayers( n )
1105         return self.nbLayers
1106
1107     ## Defines "LocalLength" hypothesis, specifying the segment length
1108     #  @param l the length of segments
1109     #  @param p the precision of rounding
1110     def LocalLength(self, l, p=1e-07):
1111         hyp = self.OwnHypothesis("LocalLength", [l,p])
1112         hyp.SetLength(l)
1113         hyp.SetPrecision(p)
1114         return hyp
1115
1116     ## Defines "NumberOfSegments" hypothesis, specifying the number of layers
1117     #  @param n the number of layers
1118     #  @param s the scale factor (optional)
1119     def NumberOfSegments(self, n, s=[]):
1120         if s == []:
1121             hyp = self.OwnHypothesis("NumberOfSegments", [n])
1122         else:
1123             hyp = self.OwnHypothesis("NumberOfSegments", [n,s])
1124             hyp.SetDistrType( 1 )
1125             hyp.SetScaleFactor(s)
1126         hyp.SetNumberOfSegments(n)
1127         return hyp
1128
1129     ## Defines "Arithmetic1D" hypothesis, specifying the distribution of segments
1130     #  with a length that changes in arithmetic progression
1131     #  @param start  the length of the first segment
1132     #  @param end    the length of the last  segment
1133     def Arithmetic1D(self, start, end ):
1134         hyp = self.OwnHypothesis("Arithmetic1D", [start, end])
1135         hyp.SetLength(start, 1)
1136         hyp.SetLength(end  , 0)
1137         return hyp
1138
1139     ## Defines "StartEndLength" hypothesis, specifying distribution of segments
1140     #  as geometric length increasing
1141     #  @param start for the length of the first segment
1142     #  @param end   for the length of the last  segment
1143     def StartEndLength(self, start, end):
1144         hyp = self.OwnHypothesis("StartEndLength", [start, end])
1145         hyp.SetLength(start, 1)
1146         hyp.SetLength(end  , 0)
1147         return hyp
1148
1149     ## Defines "AutomaticLength" hypothesis, specifying the number of segments
1150     #  @param fineness defines the quality of the mesh within the range [0-1]
1151     def AutomaticLength(self, fineness=0):
1152         hyp = self.OwnHypothesis("AutomaticLength")
1153         hyp.SetFineness( fineness )
1154         return hyp
1155
1156     pass # end of StdMeshersBuilder_RadialQuadrangle1D2D class
1157
1158 ## Defines a Use Existing Elements 1D algorithm
1159 #
1160 #  It is created by calling smeshBuilder.Mesh.UseExisting1DElements(geom=0)
1161 #
1162 #  @ingroup l3_algos_basic
1163 class StdMeshersBuilder_UseExistingElements_1D(Mesh_Algorithm):
1164
1165     ## name of the dynamic method in smeshBuilder.Mesh class
1166     #  @internal
1167     meshMethod = "UseExisting1DElements"
1168     ## type of algorithm used with helper function in smeshBuilder.Mesh class
1169     #  @internal
1170     algoType   = "Import_1D"
1171     ## flag pointing either this algorithm should be used by default in dynamic method
1172     #  of smeshBuilder.Mesh class
1173     #  @internal
1174     isDefault  = True
1175     ## doc string of the method
1176     #  @internal
1177     docHelper  = "Creates 1D algorithm for edges with reusing of existing mesh elements"
1178
1179     ## Private constructor.
1180     #  @param mesh parent mesh object algorithm is assigned to
1181     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
1182     #              if it is @c 0 (default), the algorithm is assigned to the main shape
1183     def __init__(self, mesh, geom=0):
1184         Mesh_Algorithm.__init__(self)
1185         self.Create(mesh, geom, self.algoType)
1186         pass
1187
1188     ## Defines "Source edges" hypothesis, specifying groups of edges to import
1189     #  @param groups list of groups of edges
1190     #  @param toCopyMesh if True, the whole mesh \a groups belong to is imported
1191     #  @param toCopyGroups if True, all groups of the mesh \a groups belong to are imported
1192     #  @param UseExisting if ==true - searches for the existing hypothesis created with
1193     #                     the same parameters, else (default) - creates a new one
1194     def SourceEdges(self, groups, toCopyMesh=False, toCopyGroups=False, UseExisting=False):
1195         for group in groups:
1196             AssureGeomPublished( self.mesh, group )
1197         compFun = lambda hyp, args: ( hyp.GetSourceEdges() == args[0] and \
1198                                       hyp.GetCopySourceMesh() == args[1], args[2] )
1199         hyp = self.Hypothesis("ImportSource1D", [groups, toCopyMesh, toCopyGroups],
1200                               UseExisting=UseExisting, CompareMethod=compFun)
1201         hyp.SetSourceEdges(groups)
1202         hyp.SetCopySourceMesh(toCopyMesh, toCopyGroups)
1203         return hyp
1204
1205     pass # end of StdMeshersBuilder_UseExistingElements_1D class
1206
1207 ## Defines a Use Existing Elements 1D-2D algorithm
1208 #
1209 #  It is created by calling smeshBuilder.Mesh.UseExisting2DElements(geom=0)
1210 #
1211 #  @ingroup l3_algos_basic
1212 class StdMeshersBuilder_UseExistingElements_1D2D(Mesh_Algorithm):
1213
1214     ## name of the dynamic method in smeshBuilder.Mesh class
1215     #  @internal
1216     meshMethod = "UseExisting2DElements"
1217     ## type of algorithm used with helper function in smeshBuilder.Mesh class
1218     #  @internal
1219     algoType   = "Import_1D2D"
1220     ## flag pointing either this algorithm should be used by default in dynamic method
1221     #  of smeshBuilder.Mesh class
1222     #  @internal
1223     isDefault  = True
1224     ## doc string of the method
1225     #  @internal
1226     docHelper  = "Creates 1D-2D algorithm for edges/faces with reusing of existing mesh elements"
1227
1228     ## Private constructor.
1229     #  @param mesh parent mesh object algorithm is assigned to
1230     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
1231     #              if it is @c 0 (default), the algorithm is assigned to the main shape
1232     def __init__(self, mesh, geom=0):
1233         Mesh_Algorithm.__init__(self)
1234         self.Create(mesh, geom, self.algoType)
1235         pass
1236
1237     ## Defines "Source faces" hypothesis, specifying groups of faces to import
1238     #  @param groups list of groups of faces
1239     #  @param toCopyMesh if True, the whole mesh \a groups belong to is imported
1240     #  @param toCopyGroups if True, all groups of the mesh \a groups belong to are imported
1241     #  @param UseExisting if ==true - searches for the existing hypothesis created with
1242     #                     the same parameters, else (default) - creates a new one
1243     def SourceFaces(self, groups, toCopyMesh=False, toCopyGroups=False, UseExisting=False):
1244         for group in groups:
1245             AssureGeomPublished( self.mesh, group )
1246         compFun = lambda hyp, args: ( hyp.GetSourceFaces() == args[0] and \
1247                                       hyp.GetCopySourceMesh() == args[1], args[2] )
1248         hyp = self.Hypothesis("ImportSource2D", [groups, toCopyMesh, toCopyGroups],
1249                               UseExisting=UseExisting, CompareMethod=compFun)
1250         hyp.SetSourceFaces(groups)
1251         hyp.SetCopySourceMesh(toCopyMesh, toCopyGroups)
1252         return hyp
1253
1254     pass # end of StdMeshersBuilder_UseExistingElements_1D2D class
1255
1256 ## Defines a Body Fitting 3D algorithm
1257 #
1258 #  It is created by calling smeshBuilder.Mesh.BodyFitted(geom=0)
1259 #
1260 #  @ingroup l3_algos_basic
1261 class StdMeshersBuilder_Cartesian_3D(Mesh_Algorithm):
1262
1263     ## name of the dynamic method in smeshBuilder.Mesh class
1264     #  @internal
1265     meshMethod = "BodyFitted"
1266     ## type of algorithm used with helper function in smeshBuilder.Mesh class
1267     #  @internal
1268     algoType   = "Cartesian_3D"
1269     ## flag pointing either this algorithm should be used by default in dynamic method
1270     #  of smeshBuilder.Mesh class
1271     #  @internal
1272     isDefault  = True
1273     ## doc string of the method
1274     #  @internal
1275     docHelper  = "Creates body fitting 3D algorithm for volumes"
1276
1277     ## Private constructor.
1278     #  @param mesh parent mesh object algorithm is assigned to
1279     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
1280     #              if it is @c 0 (default), the algorithm is assigned to the main shape
1281     def __init__(self, mesh, geom=0):
1282         self.Create(mesh, geom, self.algoType)
1283         self.hyp = None
1284         pass
1285
1286     ## Defines "Body Fitting parameters" hypothesis
1287     #  @param xGridDef is definition of the grid along the X asix.
1288     #  It can be in either of two following forms:
1289     #  - Explicit coordinates of nodes, e.g. [-1.5, 0.0, 3.1] or range( -100,200,10)
1290     #  - Functions f(t) defining grid spacing at each point on grid axis. If there are
1291     #    several functions, they must be accompanied by relative coordinates of
1292     #    points dividing the whole shape into ranges where the functions apply; points
1293     #    coodrinates should vary within (0.0, 1.0) range. Parameter \a t of the spacing
1294     #    function f(t) varies from 0.0 to 1.0 witin a shape range. 
1295     #    Examples:
1296     #    - "10.5" - defines a grid with a constant spacing
1297     #    - [["1", "1+10*t", "11"] [0.1, 0.6]] - defines different spacing in 3 ranges.
1298     #  @param yGridDef defines the grid along the Y asix the same way as \a xGridDef does
1299     #  @param zGridDef defines the grid along the Z asix the same way as \a xGridDef does
1300     #  @param sizeThreshold (> 1.0) defines a minimal size of a polyhedron so that
1301     #         a polyhedron of size less than hexSize/sizeThreshold is not created
1302     #  @param UseExisting if ==true - searches for the existing hypothesis created with
1303     #                     the same parameters, else (default) - creates a new one
1304     def SetGrid(self, xGridDef, yGridDef, zGridDef, sizeThreshold=4.0, UseExisting=False):
1305         if not self.hyp:
1306             compFun = lambda hyp, args: False
1307             self.hyp = self.Hypothesis("CartesianParameters3D",
1308                                        [xGridDef, yGridDef, zGridDef, sizeThreshold],
1309                                        UseExisting=UseExisting, CompareMethod=compFun)
1310         if not self.mesh.IsUsedHypothesis( self.hyp, self.geom ):
1311             self.mesh.AddHypothesis( self.hyp, self.geom )
1312
1313         for axis, gridDef in enumerate( [xGridDef, yGridDef, zGridDef]):
1314             if not gridDef: raise ValueError, "Empty grid definition"
1315             if isinstance( gridDef, str ):
1316                 self.hyp.SetGridSpacing( [gridDef], [], axis )
1317             elif isinstance( gridDef[0], str ):
1318                 self.hyp.SetGridSpacing( gridDef, [], axis )
1319             elif isinstance( gridDef[0], int ) or \
1320                  isinstance( gridDef[0], float ):
1321                 self.hyp.SetGrid(gridDef, axis )
1322             else:
1323                 self.hyp.SetGridSpacing( gridDef[0], gridDef[1], axis )
1324         self.hyp.SetSizeThreshold( sizeThreshold )
1325         return self.hyp
1326
1327     pass # end of StdMeshersBuilder_Cartesian_3D class
1328
1329 ## Defines a stub 1D algorithm, which enables "manual" creation of nodes and
1330 #  segments usable by 2D algoritms
1331 #
1332 #  It is created by calling smeshBuilder.Mesh.UseExistingSegments(geom=0)
1333 #
1334 #  @ingroup l3_algos_basic
1335 class StdMeshersBuilder_UseExisting_1D(Mesh_Algorithm):
1336
1337     ## name of the dynamic method in smeshBuilder.Mesh class
1338     #  @internal
1339     meshMethod = "UseExistingSegments"
1340     ## type of algorithm used with helper function in smeshBuilder.Mesh class
1341     #  @internal
1342     algoType   = "UseExisting_1D"
1343     ## doc string of the method
1344     #  @internal
1345     docHelper  = "Creates 1D algorithm for edges with reusing of existing mesh elements"
1346
1347     ## Private constructor.
1348     #  @param mesh parent mesh object algorithm is assigned to
1349     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
1350     #              if it is @c 0 (default), the algorithm is assigned to the main shape
1351     def __init__(self, mesh, geom=0):
1352         self.Create(mesh, geom, self.algoType)
1353         pass
1354
1355     pass # end of StdMeshersBuilder_UseExisting_1D class
1356
1357 ## Defines a stub 2D algorithm, which enables "manual" creation of nodes and
1358 #  faces usable by 3D algoritms
1359 #
1360 #  It is created by calling smeshBuilder.Mesh.UseExistingFaces(geom=0)
1361 #
1362 #  @ingroup l3_algos_basic
1363 class StdMeshersBuilder_UseExisting_2D(Mesh_Algorithm):
1364
1365     ## name of the dynamic method in smeshBuilder.Mesh class
1366     #  @internal
1367     meshMethod = "UseExistingFaces"
1368     ## type of algorithm used with helper function in smeshBuilder.Mesh class
1369     #  @internal
1370     algoType   = "UseExisting_2D"
1371     ## doc string of the method
1372     #  @internal
1373     docHelper  = "Creates 2D algorithm for faces with reusing of existing mesh elements"
1374
1375     ## Private constructor.
1376     #  @param mesh parent mesh object algorithm is assigned to
1377     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
1378     #              if it is @c 0 (default), the algorithm is assigned to the main shape
1379     def __init__(self, mesh, geom=0):
1380         self.Create(mesh, geom, self.algoType)
1381         pass
1382
1383     pass # end of StdMeshersBuilder_UseExisting_2D class