1 # Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 Python API for the standard meshing plug-in module.
24 LIBRARY = "libStdMeshersEngine.so"
26 from salome.smesh.smesh_algorithm import Mesh_Algorithm
29 #----------------------------
30 # Mesh algo type identifiers
31 #----------------------------
33 REGULAR = "Regular_1D"
35 Algorithm type: Regular 1D algorithm, see :class:`~StdMeshersBuilder.StdMeshersBuilder_Segment`
40 Algorithm type: Python 1D algorithm, see :class:`~StdMeshersBuilder.StdMeshersBuilder_Segment_Python`
43 COMPOSITE = "CompositeSegment_1D"
45 Algorithm type: Composite segment 1D algorithm, see :class:`~StdMeshersBuilder.StdMeshersBuilder_CompositeSegment`
50 Algorithm type: Hexahedron 3D (i-j-k) algorithm, see :class:`~StdMeshersBuilder.StdMeshersBuilder_Hexahedron`
53 QUADRANGLE = "Quadrangle_2D"
55 Algorithm type: Quadrangle 2D algorithm, see :class:`~StdMeshersBuilder.StdMeshersBuilder_Quadrangle`
58 RADIAL_QUAD = "RadialQuadrangle_1D2D"
60 Algorithm type: Radial Quadrangle 1D-2D algorithm, see :class:`~StdMeshersBuilder.StdMeshersBuilder_RadialQuadrangle1D2D`
63 QUAD_MA_PROJ = "QuadFromMedialAxis_1D2D"
65 Algorithm type: Quadrangle (Medial Axis Projection) 1D-2D algorithm, see :class:`~StdMeshersBuilder.StdMeshersBuilder_QuadMA_1D2D`
68 POLYGON = "PolygonPerFace_2D"
70 Algorithm type: Polygon Per Face 2D algorithm, see :class:`~StdMeshersBuilder.StdMeshersBuilder_PolygonPerFace`
73 POLYHEDRON = "PolyhedronPerSolid_3D"
75 Algorithm type: Polyhedron Per Solid 3D algorithm, see :class:`~StdMeshersBuilder.StdMeshersBuilder_PolyhedronPerSolid`
78 # import items of enums
79 for e in StdMeshers.QuadType._items: exec('%s = StdMeshers.%s'%(e,e))
80 for e in StdMeshers.VLExtrusionMethod._items: exec('%s = StdMeshers.%s'%(e,e))
82 #----------------------
84 #----------------------
86 class StdMeshersBuilder_Segment(Mesh_Algorithm):
88 Defines segment 1D algorithm for edges discretization.
90 It can be created by calling smeshBuilder.Mesh.Segment(geom=0)
94 meshMethod = "Segment"
96 name of the dynamic method in smeshBuilder.Mesh class
101 type of algorithm used with helper function in smeshBuilder.Mesh class
106 flag pointing whether this algorithm should be used by default in dynamic method
107 of smeshBuilder.Mesh class
110 docHelper = "Create segment 1D algorithm for edges"
112 doc string of the method
115 def __init__(self, mesh, geom=0):
119 mesh: parent mesh object algorithm is assigned to
120 geom: geometry (shape/sub-shape) algorithm is assigned to;
121 if it is :code:`0` (default), the algorithm is assigned to the main shape
123 Mesh_Algorithm.__init__(self)
124 self.Create(mesh, geom, self.algoType)
127 def LocalLength(self, l, UseExisting=0, p=1e-07):
129 Defines "LocalLength" hypothesis to cut an edge in several segments with the same length
132 l : for the length of segments that cut an edge
133 UseExisting : if == true - searches for an existing hypothesis created with
134 the same parameters, else (default) - Create a new one
135 p : precision, used for calculation of the number of segments.
136 The precision should be a positive, meaningful value within the range [0,1].
137 In general, the number of segments is calculated with the formula:
138 nb = ceil((edge_length / l) - p)
139 Function ceil rounds its argument to the higher integer.
140 So, p=0 means rounding of (edge_length / l) to the higher integer,
141 p=0.5 means rounding of (edge_length / l) to the nearest integer,
142 p=1 means rounding of (edge_length / l) to the lower integer.
143 Default value is 1e-07.
146 an instance of StdMeshers_LocalLength hypothesis
149 from salome.smesh.smeshBuilder import IsEqual
150 comFun=lambda hyp, args: IsEqual(hyp.GetLength(), args[0]) and IsEqual(hyp.GetPrecision(), args[1])
151 hyp = self.Hypothesis("LocalLength", [l,p], UseExisting=UseExisting, CompareMethod=comFun)
156 def MaxSize(self, length=0.0, UseExisting=0):
158 Defines "MaxSize" hypothesis to cut an edge into segments not longer than given value
161 length : is optional maximal allowed length of segment, if it is omitted
162 the preestimated length is used that depends on geometry size
163 UseExisting : if ==true - searches for an existing hypothesis created with
164 the same parameters, else (default) - Create a new one
167 an instance of StdMeshers_MaxLength hypothesis
171 hyp = self.Hypothesis("MaxLength", [length], UseExisting=UseExisting)
172 if isinstance(length,str) or length > 0:
174 hyp.SetLength(length)
176 # set preestimated length
178 gen = self.mesh.smeshpyD
179 initHyp = gen.GetHypothesisParameterValues("MaxLength", "libStdMeshersEngine.so",
180 self.mesh.GetMesh(), self.mesh.GetShape(),
181 SMESH.HypInitParams( 1, 1.0, False ))
182 preHyp = initHyp._narrow(StdMeshers.StdMeshers_MaxLength)
184 hyp.SetPreestimatedLength( preHyp.GetPreestimatedLength() )
187 hyp.SetUsePreestimatedLength( length == 0.0 )
190 def NumberOfSegments(self, n, s=[], reversedEdges=[], UseExisting=0):
192 Defines "NumberOfSegments" hypothesis to cut an edge in a fixed number of segments
195 n: for the number of segments that cut an edge
196 s: for the scale factor (optional)
197 reversedEdges: is a list of edges to mesh using reversed orientation.
198 A list item can also be a tuple (edge, 1st_vertex_of_edge)
199 UseExisting: if ==true - searches for an existing hypothesis created with
200 the same parameters, else (default) - create a new one
203 an instance of StdMeshers_NumberOfSegments hypothesis
207 if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
208 reversedEdges, UseExisting = [], reversedEdges
209 entry = self.MainShapeEntry()
210 reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
212 hyp = self.Hypothesis("NumberOfSegments", [n, reversedEdgeInd, entry],
213 UseExisting=UseExisting,
214 CompareMethod=self._compareNumberOfSegments)
216 hyp = self.Hypothesis("NumberOfSegments", [n,s, reversedEdgeInd, entry],
217 UseExisting=UseExisting,
218 CompareMethod=self._compareNumberOfSegments)
219 hyp.SetScaleFactor(s)
220 hyp.SetNumberOfSegments(n)
221 hyp.SetReversedEdges( reversedEdgeInd )
222 hyp.SetObjectEntry( entry )
225 def _compareNumberOfSegments(self, hyp, args):
228 Checks if the given "NumberOfSegments" hypothesis has the same parameters as the given arguments
230 if hyp.GetNumberOfSegments() == args[0]:
232 if hyp.GetReversedEdges() == args[1]:
233 if not args[1] or hyp.GetObjectEntry() == args[2]:
236 from salome.smesh.smeshBuilder import IsEqual
237 if hyp.GetReversedEdges() == args[2]:
238 if not args[2] or hyp.GetObjectEntry() == args[3]:
239 if hyp.GetDistrType() == 1:
240 if IsEqual(hyp.GetScaleFactor(), args[1]):
244 def Adaptive(self, minSize, maxSize, deflection, UseExisting=False):
246 Defines "Adaptive" hypothesis to cut an edge into segments keeping segment size
247 within the given range and considering (1) deflection of segments from the edge
248 and (2) distance from segments to closest edges and faces to have segment length
249 not longer than two times shortest distances to edges and faces.
252 minSize: defines the minimal allowed segment length
253 maxSize: defines the maximal allowed segment length
254 deflection: defines the maximal allowed distance from a segment to an edge
255 UseExisting: if ==true - searches for an existing hypothesis created with
256 the same parameters, else (default) - Create a new one
259 an instance of StdMeshers_Adaptive1D hypothesis
262 from salome.smesh.smeshBuilder import IsEqual
263 compFun = lambda hyp, args: ( IsEqual(hyp.GetMinSize(), args[0]) and \
264 IsEqual(hyp.GetMaxSize(), args[1]) and \
265 IsEqual(hyp.GetDeflection(), args[2]))
266 hyp = self.Hypothesis("Adaptive1D", [minSize, maxSize, deflection],
267 UseExisting=UseExisting, CompareMethod=compFun)
268 hyp.SetMinSize(minSize)
269 hyp.SetMaxSize(maxSize)
270 hyp.SetDeflection(deflection)
273 def Arithmetic1D(self, start, end, reversedEdges=[], UseExisting=0):
275 Defines "Arithmetic1D" hypothesis to cut an edge in several segments with a length
276 that changes in arithmetic progression
279 start: defines the length of the first segment
280 end: defines the length of the last segment
281 reversedEdges: is a list of edges to mesh using reversed orientation.
282 A list item can also be a tuple (edge, 1st_vertex_of_edge)
283 UseExisting: if ==true - searches for an existing hypothesis created with
284 the same parameters, else (default) - Create a new one
287 an instance of StdMeshers_Arithmetic1D hypothesis
290 if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
291 reversedEdges, UseExisting = [], reversedEdges
292 reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
293 entry = self.MainShapeEntry()
294 from salome.smesh.smeshBuilder import IsEqual
295 compFun = lambda hyp, args: ( IsEqual(hyp.GetLength(1), args[0]) and \
296 IsEqual(hyp.GetLength(0), args[1]) and \
297 hyp.GetReversedEdges() == args[2] and \
298 (not args[2] or hyp.GetObjectEntry() == args[3]))
299 hyp = self.Hypothesis("Arithmetic1D", [start, end, reversedEdgeInd, entry],
300 UseExisting=UseExisting, CompareMethod=compFun)
301 hyp.SetStartLength(start)
302 hyp.SetEndLength(end)
303 hyp.SetReversedEdges( reversedEdgeInd )
304 hyp.SetObjectEntry( entry )
307 def GeometricProgression(self, start, ratio, reversedEdges=[], UseExisting=0):
309 Defines "GeometricProgression" hypothesis to cut an edge in several
310 segments with a length that changes in Geometric progression
313 start: defines the length of the first segment
314 ratio: defines the common ratio of the geometric progression
315 reversedEdges: is a list of edges to mesh using reversed orientation.
316 A list item can also be a tuple (edge, 1st_vertex_of_edge)
317 UseExisting: if ==true - searches for an existing hypothesis created with
318 the same parameters, else (default) - Create a new one
321 an instance of StdMeshers_Geometric1D hypothesis
324 reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
325 entry = self.MainShapeEntry()
326 from salome.smesh.smeshBuilder import IsEqual
327 compFun = lambda hyp, args: ( IsEqual(hyp.GetLength(1), args[0]) and \
328 IsEqual(hyp.GetLength(0), args[1]) and \
329 hyp.GetReversedEdges() == args[2] and \
330 (not args[2] or hyp.GetObjectEntry() == args[3]))
331 hyp = self.Hypothesis("GeometricProgression", [start, ratio, reversedEdgeInd, entry],
332 UseExisting=UseExisting, CompareMethod=compFun)
333 hyp.SetStartLength( start )
334 hyp.SetCommonRatio( ratio )
335 hyp.SetReversedEdges( reversedEdgeInd )
336 hyp.SetObjectEntry( entry )
339 def FixedPoints1D(self, points, nbSegs=[1], reversedEdges=[], UseExisting=0):
341 Defines "FixedPoints1D" hypothesis to cut an edge using parameter
342 on curve from 0 to 1 (additionally it is neecessary to check
343 orientation of edges and create list of reversed edges if it is
344 needed) and sets numbers of segments between given points (default
348 points: defines the list of parameters on curve
349 nbSegs: defines the list of numbers of segments
350 reversedEdges: is a list of edges to mesh using reversed orientation.
351 A list item can also be a tuple (edge, 1st_vertex_of_edge)
352 UseExisting: if ==true - searches for an existing hypothesis created with
353 the same parameters, else (default) - Create a new one
356 an instance of StdMeshers_FixedPoints1D hypothesis
359 if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
360 reversedEdges, UseExisting = [], reversedEdges
361 reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
362 entry = self.MainShapeEntry()
363 compFun = lambda hyp, args: ( hyp.GetPoints() == args[0] and \
364 hyp.GetNbSegments() == args[1] and \
365 hyp.GetReversedEdges() == args[2] and \
366 (not args[2] or hyp.GetObjectEntry() == args[3]))
367 hyp = self.Hypothesis("FixedPoints1D", [points, nbSegs, reversedEdgeInd, entry],
368 UseExisting=UseExisting, CompareMethod=compFun)
369 hyp.SetPoints(points)
370 hyp.SetNbSegments(nbSegs)
371 hyp.SetReversedEdges(reversedEdgeInd)
372 hyp.SetObjectEntry(entry)
375 def StartEndLength(self, start, end, reversedEdges=[], UseExisting=0):
377 Defines "StartEndLength" hypothesis to cut an edge in several segments with increasing geometric length
380 start: defines the length of the first segment
381 end: defines the length of the last segment
382 reversedEdges: is a list of edges to mesh using reversed orientation.
383 A list item can also be a tuple (edge, 1st_vertex_of_edge)
384 UseExisting: if ==true - searches for an existing hypothesis created with
385 the same parameters, else (default) - Create a new one
388 an instance of StdMeshers_StartEndLength hypothesis
391 if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
392 reversedEdges, UseExisting = [], reversedEdges
393 reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
394 entry = self.MainShapeEntry()
395 from salome.smesh.smeshBuilder import IsEqual
396 compFun = lambda hyp, args: ( IsEqual(hyp.GetLength(1), args[0]) and \
397 IsEqual(hyp.GetLength(0), args[1]) and \
398 hyp.GetReversedEdges() == args[2] and \
399 (not args[2] or hyp.GetObjectEntry() == args[3]))
400 hyp = self.Hypothesis("StartEndLength", [start, end, reversedEdgeInd, entry],
401 UseExisting=UseExisting, CompareMethod=compFun)
402 hyp.SetStartLength(start)
403 hyp.SetEndLength(end)
404 hyp.SetReversedEdges( reversedEdgeInd )
405 hyp.SetObjectEntry( entry )
408 def Deflection1D(self, d, UseExisting=0):
410 Defines "Deflection1D" hypothesis
413 d: for the deflection
414 UseExisting: if ==true - searches for an existing hypothesis created with
415 the same parameters, else (default) - create a new one
418 from salome.smesh.smeshBuilder import IsEqual
419 compFun = lambda hyp, args: IsEqual(hyp.GetDeflection(), args[0])
420 hyp = self.Hypothesis("Deflection1D", [d], UseExisting=UseExisting, CompareMethod=compFun)
424 def Propagation(self):
426 Defines "Propagation" hypothesis that propagates 1D hypotheses
427 from an edge where this hypothesis is assigned to
428 on all other edges that are at the opposite side in case of quadrangular faces
429 This hypothesis should be assigned to an edge to propagate a hypothesis from.
432 return self.Hypothesis("Propagation", UseExisting=1, CompareMethod=self.CompareEqualHyp)
434 def PropagationOfDistribution(self):
436 Defines "Propagation of Node Distribution" hypothesis that propagates
437 distribution of nodes from an edge where this hypothesis is assigned to,
438 to opposite edges of quadrangular faces, so that number of segments on all these
439 edges will be the same, as well as relations between segment lengths.
442 return self.Hypothesis("PropagOfDistribution", UseExisting=1,
443 CompareMethod=self.CompareEqualHyp)
445 def AutomaticLength(self, fineness=0, UseExisting=0):
447 Defines "AutomaticLength" hypothesis
450 fineness: for the fineness [0-1]
451 UseExisting: if ==true - searches for an existing hypothesis created with the
452 same parameters, else (default) - create a new one
455 from salome.smesh.smeshBuilder import IsEqual
456 compFun = lambda hyp, args: IsEqual(hyp.GetFineness(), args[0])
457 hyp = self.Hypothesis("AutomaticLength",[fineness],UseExisting=UseExisting,
458 CompareMethod=compFun)
459 hyp.SetFineness( fineness )
462 def LengthNearVertex(self, length, vertex=-1, UseExisting=0):
464 Defines "SegmentLengthAroundVertex" hypothesis
467 length: for the segment length
468 vertex: for the length localization: the vertex index [0,1] | vertex object.
469 Any other integer value means that the hypothesis will be set on the
470 whole 1D shape, where Mesh_Segment algorithm is assigned.
471 UseExisting: if ==true - searches for an existing hypothesis created with
472 the same parameters, else (default) - Create a new one
476 store_geom = self.geom
477 if isinstance(vertex, int):
478 if vertex == 0 or vertex == 1:
479 from salome.geom import geomBuilder
480 vertex = self.mesh.geompyD.ExtractShapes(self.geom, geomBuilder.geomBuilder.ShapeType["VERTEX"],True)[vertex]
488 if self.geom is None:
489 self.geom = store_geom
490 raise RuntimeError("Attempt to create SegmentAroundVertex_0D algorithm on None shape")
491 from salome.smesh.smeshBuilder import AssureGeomPublished, GetName, TreatHypoStatus
492 AssureGeomPublished( self.mesh, self.geom )
493 name = GetName(self.geom)
495 algo = self.FindAlgorithm("SegmentAroundVertex_0D", self.mesh.smeshpyD)
497 algo = self.mesh.smeshpyD.CreateHypothesis("SegmentAroundVertex_0D", "libStdMeshersEngine.so")
499 status = self.mesh.mesh.AddHypothesis(self.geom, algo)
500 TreatHypoStatus(status, "SegmentAroundVertex_0D", name, True, self.mesh)
502 from salome.smesh.smeshBuilder import IsEqual
503 comFun = lambda hyp, args: IsEqual(hyp.GetLength(), args[0])
504 hyp = self.Hypothesis("SegmentLengthAroundVertex", [length], UseExisting=UseExisting,
505 CompareMethod=comFun)
506 self.geom = store_geom
507 hyp.SetLength( length )
510 def QuadraticMesh(self):
512 Defines "QuadraticMesh" hypothesis, forcing construction of quadratic edges.
513 If the 2D mesher sees that all boundary edges are quadratic,
514 it generates quadratic faces, else it generates linear faces using
515 medium nodes as if they are vertices.
516 The 3D mesher generates quadratic volumes only if all boundary faces
517 are quadratic, else it fails.
520 hyp = self.Hypothesis("QuadraticMesh", UseExisting=1, CompareMethod=self.CompareEqualHyp)
523 pass # end of StdMeshersBuilder_Segment class
525 class StdMeshersBuilder_CompositeSegment(StdMeshersBuilder_Segment):
527 Segment 1D algorithm for discretization of a set of adjacent edges as one edge.
529 It is created by calling smeshBuilder.Mesh.Segment(smeshBuilder.COMPOSITE,geom=0)
533 meshMethod = "Segment"
535 name of the dynamic method in smeshBuilder.Mesh class
540 type of algorithm used with helper function in smeshBuilder.Mesh class
545 flag pointing whether this algorithm should be used by default in dynamic method
546 of smeshBuilder.Mesh class
549 docHelper = "Create segment 1D algorithm for edges"
551 doc string of the method
554 def __init__(self, mesh, geom=0):
559 mesh: parent mesh object algorithm is assigned to
560 geom: geometry (shape/sub-shape) algorithm is assigned to;
561 if it is :code:`0` (default), the algorithm is assigned to the main shape
563 self.Create(mesh, geom, self.algoType)
566 pass # end of StdMeshersBuilder_CompositeSegment class
568 class StdMeshersBuilder_Segment_Python(Mesh_Algorithm):
570 Defines a segment 1D algorithm for discretization of edges with Python function.
571 It is created by calling smeshBuilder.Mesh.Segment(smeshBuilder.PYTHON,geom=0)
575 meshMethod = "Segment"
577 name of the dynamic method in smeshBuilder.Mesh class
581 type of algorithm used with helper function in smeshBuilder.Mesh class
583 docHelper = "Create segment 1D algorithm for edges"
585 doc string of the method
588 def __init__(self, mesh, geom=0):
593 mesh: parent mesh object algorithm is assigned to
594 geom: geometry (shape/sub-shape) algorithm is assigned to;
595 if it is :code:`0` (default), the algorithm is assigned to the main shape
597 import Python1dPlugin
598 self.Create(mesh, geom, self.algoType, "libPython1dEngine.so")
601 def PythonSplit1D(self, n, func, UseExisting=0):
603 Defines "PythonSplit1D" hypothesis
606 n: for the number of segments that cut an edge
607 func: for the python function that calculates the length of all segments
608 UseExisting: if ==true - searches for the existing hypothesis created with
609 the same parameters, else (default) - Create a new one
612 compFun = lambda hyp, args: False
613 hyp = self.Hypothesis("PythonSplit1D", [n], "libPython1dEngine.so",
614 UseExisting=UseExisting, CompareMethod=compFun)
615 hyp.SetNumberOfSegments(n)
616 hyp.SetPythonLog10RatioFunction(func)
619 pass # end of StdMeshersBuilder_Segment_Python class
621 class StdMeshersBuilder_Quadrangle(Mesh_Algorithm):
623 Defines a quadrangle 2D algorithm.
624 It is created by calling smeshBuilder.Mesh.Quadrangle(geom=0)
628 meshMethod = "Quadrangle"
630 name of the dynamic method in smeshBuilder.Mesh class
632 algoType = QUADRANGLE
634 type of algorithm used with helper function in smeshBuilder.Mesh class
638 flag pointing whether this algorithm should be used by default in dynamic method
639 of smeshBuilder.Mesh class
641 docHelper = "Create quadrangle 2D algorithm for faces"
643 doc string of the method
647 hypothesis associated with algorithm
650 def __init__(self, mesh, geom=0):
655 mesh: parent mesh object algorithm is assigned to
656 geom: geometry (shape/sub-shape) algorithm is assigned to;
657 if it is :code:`0` (default), the algorithm is assigned to the main shape
659 Mesh_Algorithm.__init__(self)
660 self.Create(mesh, geom, self.algoType)
663 def QuadrangleParameters(self, quadType=StdMeshers.QUAD_STANDARD, triangleVertex=0,
664 enfVertices=[],enfPoints=[],corners=[],UseExisting=0):
666 Defines "QuadrangleParameters" hypothesis
667 quadType defines the algorithm of transition between differently descretized
668 sides of a geometrical face:
670 - QUAD_STANDARD - both triangles and quadrangles are possible in the transition
671 area along the finer meshed sides.
672 - QUAD_TRIANGLE_PREF - only triangles are built in the transition area along the
674 - QUAD_QUADRANGLE_PREF - only quadrangles are built in the transition area along
675 the finer meshed sides, iff the total quantity of segments on
676 all four sides of the face is even (divisible by 2).
677 - QUAD_QUADRANGLE_PREF_REVERSED - same as QUAD_QUADRANGLE_PREF but the transition
678 area is located along the coarser meshed sides.
679 - QUAD_REDUCED - only quadrangles are built and the transition between the sides
680 is made gradually, layer by layer. This type has a limitation on
681 the number of segments: one pair of opposite sides must have the
682 same number of segments, the other pair must have an even difference
683 between the numbers of segments on the sides.
686 triangleVertex: vertex of a trilateral geometrical face, around which triangles
687 will be created while other elements will be quadrangles.
688 Vertex can be either a GEOM_Object or a vertex ID within the
690 enfVertices: list of shapes defining positions where nodes (enforced nodes)
691 must be created by the mesher. Shapes can be of any type,
692 vertices of given shapes define positions of enforced nodes.
693 Only vertices successfully projected to the face are used.
694 enfPoints: list of points giving positions of enforced nodes.
695 Point can be defined either as SMESH.PointStruct's
696 ([SMESH.PointStruct(x1,y1,z1), SMESH.PointStruct(x2,y2,z2),...])
697 or triples of values ([[x1,y1,z1], [x2,y2,z2], ...]).
698 In the case if the defined QuadrangleParameters() refer to a sole face,
699 all given points must lie on this face, else the mesher fails.
700 corners: list of vertices that should be used as quadrangle corners.
701 The parameter can be useful for faces with more than four vertices,
702 since in some cases Quadrangle Mapping algorithm chooses corner vertices
703 differently than it is desired.
704 A hypothesis can be global and define corners for all CAD faces that
705 require it, but be sure that each specified vertex is a corner in all
706 faces the hypothesis will be applied to.
707 UseExisting: if *True* - searches for the existing hypothesis created with
708 the same parameters, else (default) - Create a new one
713 vertexID = triangleVertex
714 if isinstance( triangleVertex, GEOM._objref_GEOM_Object ):
715 vertexID = self.mesh.geompyD.GetSubShapeID( self.mesh.geom, triangleVertex )
716 if isinstance( enfVertices, int ) and not enfPoints and not UseExisting:
717 # a call of old syntax, before inserting enfVertices and enfPoints before UseExisting
718 UseExisting, enfVertices = enfVertices, []
720 pStructs, xyz = [], []
722 if isinstance( p, SMESH.PointStruct ):
723 xyz.append(( p.x, p.y, p.z ))
726 xyz.append(( p[0], p[1], p[2] ))
727 pStructs.append( SMESH.PointStruct( p[0], p[1], p[2] ))
729 compFun = lambda hyp,args: \
730 hyp.GetQuadType() == args[0] and \
731 (hyp.GetTriaVertex()==args[1] or ( hyp.GetTriaVertex()<1 and args[1]<1)) and \
732 ((hyp.GetEnforcedNodes()) == (args[2],args[3])) # True w/o enfVertices only
733 entries = [ shape.GetStudyEntry() for shape in enfVertices ]
734 self.params = self.Hypothesis("QuadrangleParams", [quadType,vertexID,entries,xyz],
735 UseExisting = UseExisting, CompareMethod=compFun)
738 if corners and isinstance( corners[0], GEOM._objref_GEOM_Object ):
739 corners = [ self.mesh.geompyD.GetSubShapeID( self.mesh.geom, v ) for v in corners ]
741 #If quadType is None - will used default parameter ( StdMeshers.QUAD_STANDARD )
742 if quadType and self.params.GetQuadType() != quadType:
743 self.params.SetQuadType(quadType)
744 #If triangleVertex is None - will used default parameter ( -1 ):
745 if triangleVertex and vertexID > 0:
746 self.params.SetTriaVertex( vertexID )
747 from salome.smesh.smeshBuilder import AssureGeomPublished
748 for v in enfVertices:
749 AssureGeomPublished( self.mesh, v )
750 self.params.SetEnforcedNodes( enfVertices, pStructs )
751 self.params.SetCorners( corners )
754 def QuadranglePreference(self, reversed=False, UseExisting=0):
756 Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only
757 quadrangles are built in the transition area along the finer meshed sides,
758 if the total quantity of segments on all four sides of the face is even.
761 reversed: if True, transition area is located along the coarser meshed sides.
762 UseExisting: if ==true - searches for the existing hypothesis created with
763 the same parameters, else (default) - Create a new one
767 return self.QuadrangleParameters(QUAD_QUADRANGLE_PREF_REVERSED,UseExisting=UseExisting)
768 return self.QuadrangleParameters(QUAD_QUADRANGLE_PREF,UseExisting=UseExisting)
770 def TrianglePreference(self, UseExisting=0):
772 Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only
773 triangles are built in the transition area along the finer meshed sides.
776 UseExisting: if ==true - searches for the existing hypothesis created with
777 the same parameters, else (default) - Create a new one
780 return self.QuadrangleParameters(QUAD_TRIANGLE_PREF,UseExisting=UseExisting)
782 def Reduced(self, UseExisting=0):
784 Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only
785 quadrangles are built and the transition between the sides is made gradually,
786 layer by layer. This type has a limitation on the number of segments: one pair
787 of opposite sides must have the same number of segments, the other pair must
788 have an even difference between the numbers of segments on the sides.
791 UseExisting: if ==true - searches for the existing hypothesis created with
792 the same parameters, else (default) - Create a new one
795 return self.QuadrangleParameters(QUAD_REDUCED,UseExisting=UseExisting)
797 def TriangleVertex(self, vertex, UseExisting=0):
799 Defines "QuadrangleParams" hypothesis with QUAD_STANDARD type of quadrangulation
802 vertex: vertex of a trilateral geometrical face, around which triangles
803 will be created while other elements will be quadrangles.
804 Vertex can be either a GEOM_Object or a vertex ID within the
806 UseExisting: if ==true - searches for the existing hypothesis created with
807 the same parameters, else (default) - Create a new one
810 return self.QuadrangleParameters(QUAD_STANDARD,vertex,UseExisting)
812 pass # end of StdMeshersBuilder_Quadrangle class
814 class StdMeshersBuilder_Hexahedron(Mesh_Algorithm):
816 Defines a hexahedron 3D algorithm.
817 It is created by calling smeshBuilder.Mesh.Hexahedron(geom=0)
821 meshMethod = "Hexahedron"
823 name of the dynamic method in smeshBuilder.Mesh class
827 type of algorithm used with helper function in smeshBuilder.Mesh class
831 flag pointing whether this algorithm should be used by default in dynamic method
832 of smeshBuilder.Mesh class
834 docHelper = "Create hexahedron 3D algorithm for volumes"
836 doc string of the method
839 def __init__(self, mesh, geom=0):
844 mesh: parent mesh object algorithm is assigned to
845 geom: geometry (shape/sub-shape) algorithm is assigned to;
846 if it is :code:`0` (default), the algorithm is assigned to the main shape
848 Mesh_Algorithm.__init__(self)
849 self.Create(mesh, geom, Hexa)
850 self.renumHypothesis = 0
853 def Renumber(self, blockCSList=[] ):
854 if isinstance( blockCSList, StdMeshers.BlockCS ):
855 blockCSList = [blockCSList]
856 if not self.renumHypothesis:
857 self.renumHypothesis = self.Hypothesis("BlockRenumber", blockCSList, UseExisting=0)
858 self.renumHypothesis.SetBlocksOrientation( blockCSList )
859 return self.renumHypothesis
861 pass # end of StdMeshersBuilder_Hexahedron class
863 class StdMeshersBuilder_Projection1D(Mesh_Algorithm):
865 Defines a projection 1D algorithm.
866 It is created by calling smeshBuilder.Mesh.Projection1D(geom=0)
870 meshMethod = "Projection1D"
872 name of the dynamic method in smeshBuilder.Mesh class
874 algoType = "Projection_1D"
876 type of algorithm used with helper function in smeshBuilder.Mesh class
880 flag pointing whether this algorithm should be used by default in dynamic method
881 of smeshBuilder.Mesh class
883 docHelper = "Create projection 1D algorithm for edges"
885 doc string of the method
887 def __init__(self, mesh, geom=0):
892 mesh: parent mesh object algorithm is assigned to
893 geom: geometry (shape/sub-shape) algorithm is assigned to;
894 if it is :code:`0` (default), the algorithm is assigned to the main shape
896 Mesh_Algorithm.__init__(self)
897 self.Create(mesh, geom, self.algoType)
900 def SourceEdge(self, edge, mesh=None, srcV=None, tgtV=None, UseExisting=0):
902 Defines "Source Edge" hypothesis, specifying a meshed edge, from where
903 a mesh pattern is taken, and, optionally, the association of vertices
904 between the source edge and a target edge (to which a hypothesis is assigned)
907 edge: from which nodes distribution is taken
908 mesh: from which nodes distribution is taken (optional)
909 srcV: a vertex of *edge* to associate with *tgtV* (optional)
910 tgtV: a vertex of *the edge* to which the algorithm is assigned, to associate with *srcV* (optional)
911 UseExisting: if ==true - searches for the existing hypothesis created with
912 the same parameters, else (default) - Create a new one
914 from salome.smesh.smeshBuilder import AssureGeomPublished, Mesh
915 AssureGeomPublished( self.mesh, edge )
916 AssureGeomPublished( self.mesh, srcV )
917 AssureGeomPublished( self.mesh, tgtV )
918 hyp = self.Hypothesis("ProjectionSource1D", [edge,mesh,srcV,tgtV],
920 # it does not seem to be useful to reuse the existing "SourceEdge" hypothesis
921 #UseExisting=UseExisting, CompareMethod=self.CompareSourceEdge)
922 hyp.SetSourceEdge( edge )
923 if not mesh is None and isinstance(mesh, Mesh):
924 mesh = mesh.GetMesh()
925 hyp.SetSourceMesh( mesh )
926 hyp.SetVertexAssociation( srcV, tgtV )
929 pass # end of StdMeshersBuilder_Projection1D class
931 class StdMeshersBuilder_Projection2D(Mesh_Algorithm):
933 Defines a projection 2D algorithm.
934 It is created by calling smeshBuilder.Mesh.Projection2D(geom=0)
938 meshMethod = "Projection2D"
940 name of the dynamic method in smeshBuilder.Mesh class
942 algoType = "Projection_2D"
944 type of algorithm used with helper function in smeshBuilder.Mesh class
948 flag pointing whether this algorithm should be used by default in dynamic method
949 of smeshBuilder.Mesh class
951 docHelper = "Create projection 2D algorithm for faces"
953 doc string of the method
956 def __init__(self, mesh, geom=0):
961 mesh: parent mesh object algorithm is assigned to
962 geom: geometry (shape/sub-shape) algorithm is assigned to;
963 if it is :code:`0` (default), the algorithm is assigned to the main shape
965 Mesh_Algorithm.__init__(self)
966 self.Create(mesh, geom, self.algoType)
970 def SourceFace(self, face, mesh=None, srcV1=None, tgtV1=None,
971 srcV2=None, tgtV2=None, UseExisting=0):
973 Defines "Source Face" hypothesis, specifying a meshed face, from where
974 a mesh pattern is taken, and, optionally, the association of vertices
975 between the source face and the target face (to which a hypothesis is assigned)
978 face: from which the mesh pattern is taken
979 mesh: from which the mesh pattern is taken (optional)
980 srcV1: a vertex of *face* to associate with *tgtV1* (optional)
981 tgtV1: a vertex of *the face* to which the algorithm is assigned, to associate with *srcV1* (optional)
982 srcV2: a vertex of *face* to associate with *tgtV1* (optional)
983 tgtV2: a vertex of *the face* to which the algorithm is assigned, to associate with *srcV2* (optional)
984 UseExisting: if ==true - forces the search for the existing hypothesis created with
985 he same parameters, else (default) - forces the creation a new one
988 all association vertices must belong to one edge of a face
990 from salome.smesh.smeshBuilder import Mesh
991 if isinstance(mesh, Mesh):
992 mesh = mesh.GetMesh()
993 for geom in [ face, srcV1, tgtV1, srcV2, tgtV2 ]:
994 from salome.smesh.smeshBuilder import AssureGeomPublished
995 AssureGeomPublished( self.mesh, geom )
996 hyp = self.Hypothesis("ProjectionSource2D", [face,mesh,srcV1,tgtV1,srcV2,tgtV2],
997 UseExisting=0, toAdd=False)
998 # it does not seem to be useful to reuse the existing "SourceFace" hypothesis
999 #UseExisting=UseExisting, CompareMethod=self.CompareSourceFace)
1000 hyp.SetSourceFace( face )
1001 hyp.SetSourceMesh( mesh )
1002 hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 )
1003 self.mesh.AddHypothesis(hyp, self.geom)
1006 pass # end of StdMeshersBuilder_Projection2D class
1008 class StdMeshersBuilder_Projection1D2D(StdMeshersBuilder_Projection2D):
1010 Defines a projection 1D-2D algorithm.
1011 It is created by calling smeshBuilder.Mesh.Projection1D2D(geom=0)
1015 meshMethod = "Projection1D2D"
1017 name of the dynamic method in smeshBuilder.Mesh class
1019 algoType = "Projection_1D2D"
1021 type of algorithm used with helper function in smeshBuilder.Mesh class
1023 docHelper = "Create projection 1D-2D algorithm for faces"
1025 doc string of the method
1028 def __init__(self, mesh, geom=0):
1030 Private constructor.
1033 mesh: parent mesh object algorithm is assigned to
1034 geom: geometry (shape/sub-shape) algorithm is assigned to;
1035 if it is :code:`0` (default), the algorithm is assigned to the main shape
1037 StdMeshersBuilder_Projection2D.__init__(self, mesh, geom)
1040 pass # end of StdMeshersBuilder_Projection1D2D class
1042 class StdMeshersBuilder_Projection3D(Mesh_Algorithm):
1044 Defines a projection 3D algorithm.
1045 It is created by calling smeshBuilder.Mesh.Projection3D(geom=0)
1049 meshMethod = "Projection3D"
1051 name of the dynamic method in smeshBuilder.Mesh class
1053 algoType = "Projection_3D"
1055 type of algorithm used with helper function in smeshBuilder.Mesh class
1057 docHelper = "Create projection 3D algorithm for volumes"
1059 doc string of the method
1062 def __init__(self, mesh, geom=0):
1064 Private constructor.
1067 mesh: parent mesh object algorithm is assigned to
1068 geom" geometry (shape/sub-shape) algorithm is assigned to;
1069 if it is :code:`0` (default), the algorithm is assigned to the main shape
1071 Mesh_Algorithm.__init__(self)
1072 self.Create(mesh, geom, self.algoType)
1075 def SourceShape3D(self, solid, mesh=0, srcV1=0, tgtV1=0,
1076 srcV2=0, tgtV2=0, UseExisting=0):
1078 Defines the "Source Shape 3D" hypothesis, specifying a meshed solid, from where
1079 the mesh pattern is taken, and, optionally, the association of vertices
1080 between the source and the target solid (to which a hipothesis is assigned)
1083 solid: from where the mesh pattern is taken
1084 mesh: from where the mesh pattern is taken (optional)
1085 srcV1: a vertex of *solid* to associate with *tgtV1* (optional)
1086 tgtV1: a vertex of *the solid* where the algorithm is assigned, to associate with *srcV1* (optional)
1087 srcV2: a vertex of *solid* to associate with *tgtV1* (optional)
1088 tgtV2: a vertex of *the solid* to which the algorithm is assigned,to associate with *srcV2* (optional)
1089 UseExisting: if ==true - searches for the existing hypothesis created with
1090 the same parameters, else (default) - Create a new one
1093 association vertices must belong to one edge of a solid
1095 for geom in [ solid, srcV1, tgtV1, srcV2, tgtV2 ]:
1096 from salome.smesh.smeshBuilder import AssureGeomPublished
1097 AssureGeomPublished( self.mesh, geom )
1098 hyp = self.Hypothesis("ProjectionSource3D",
1099 [solid,mesh,srcV1,tgtV1,srcV2,tgtV2],
1101 # seems to be not really useful to reuse existing "SourceShape3D" hypothesis
1102 #UseExisting=UseExisting, CompareMethod=self.CompareSourceShape3D)
1103 hyp.SetSource3DShape( solid )
1104 from salome.smesh.smeshBuilder import Mesh
1105 if isinstance(mesh, Mesh):
1106 mesh = mesh.GetMesh()
1108 hyp.SetSourceMesh( mesh )
1109 if srcV1 and srcV2 and tgtV1 and tgtV2:
1110 hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 )
1111 #elif srcV1 or srcV2 or tgtV1 or tgtV2:
1114 pass # end of StdMeshersBuilder_Projection3D class
1116 class StdMeshersBuilder_Prism3D(Mesh_Algorithm):
1118 Defines a Prism 3D algorithm, which is either "Extrusion 3D" or "Radial Prism" depending on geometry.
1119 It is created by calling smeshBuilder.Mesh.Prism(geom=0)
1123 meshMethod = "Prism"
1125 name of the dynamic method in smeshBuilder.Mesh class
1127 algoType = "Prism_3D"
1129 type of algorithm used with helper function in smeshBuilder.Mesh class
1131 docHelper = "Create prism 3D algorithm for volumes"
1133 doc string of the method
1137 flag pointing whether this algorithm should be used by default in dynamic method
1138 of smeshBuilder.Mesh class
1141 def __init__(self, mesh, geom=0):
1143 Private constructor.
1146 mesh: parent mesh object algorithm is assigned to
1147 geom: geometry (shape/sub-shape) algorithm is assigned to;
1148 if it is :code:`0` (default), the algorithm is assigned to the main shape
1150 Mesh_Algorithm.__init__(self)
1155 isRadial = mesh.smeshpyD.IsApplicable("RadialPrism_3D", LIBRARY, shape, False )
1157 self.Create(mesh, geom, "Prism_3D")
1160 self.algoType = "RadialPrism_3D"
1161 self.Create(mesh, geom, "RadialPrism_3D")
1162 self.distribHyp = None #self.Hypothesis("LayerDistribution", UseExisting=0)
1163 self.nbLayers = None
1167 def Get3DHypothesis(self):
1170 3D hypothesis holding the 1D one
1172 if self.algoType != "RadialPrism_3D":
1173 print("Prism_3D algorithm doesn't support any hypothesis")
1175 return self.distribHyp
1177 def OwnHypothesis(self, hypType, args=[], so="libStdMeshersEngine.so"):
1179 Private method creating a 1D hypothesis and storing it in the LayerDistribution
1183 the created hypothesis
1185 if self.algoType != "RadialPrism_3D":
1186 print("Prism_3D algorithm doesn't support any hypothesis")
1188 if not self.nbLayers is None:
1189 self.mesh.GetMesh().RemoveHypothesis( self.geom, self.nbLayers )
1190 self.mesh.GetMesh().AddHypothesis( self.geom, self.distribHyp )
1191 self.mesh.smeshpyD.SetEnablePublish( False ) # prevents publishing own 1D hypothesis
1192 hyp = self.mesh.smeshpyD.CreateHypothesis(hypType, so)
1193 self.mesh.smeshpyD.SetEnablePublish( True ) # enables publishing
1194 if not self.distribHyp:
1195 self.distribHyp = self.Hypothesis("LayerDistribution", UseExisting=0)
1196 self.distribHyp.SetLayerDistribution( hyp )
1199 def NumberOfLayers(self, n, UseExisting=0):
1201 Defines "NumberOfLayers" hypothesis, specifying the number of layers of
1202 prisms to build between the inner and outer shells
1206 UseExisting: if ==true - searches for the existing hypothesis created with
1207 the same parameters, else (default) - Create a new one
1209 if self.algoType != "RadialPrism_3D":
1210 print("Prism_3D algorithm doesn't support any hypothesis")
1212 self.mesh.RemoveHypothesis( self.distribHyp, self.geom )
1213 from salome.smesh.smeshBuilder import IsEqual
1214 compFun = lambda hyp, args: IsEqual(hyp.GetNumberOfLayers(), args[0])
1215 self.nbLayers = self.Hypothesis("NumberOfLayers", [n], UseExisting=UseExisting,
1216 CompareMethod=compFun)
1217 self.nbLayers.SetNumberOfLayers( n )
1218 return self.nbLayers
1220 def LocalLength(self, l, p=1e-07):
1222 Defines "LocalLength" hypothesis, specifying the segment length
1223 to build between the inner and the outer shells
1226 l: the length of segments
1227 p: the precision of rounding
1229 if self.algoType != "RadialPrism_3D":
1230 print("Prism_3D algorithm doesn't support any hypothesis")
1232 hyp = self.OwnHypothesis("LocalLength", [l,p])
1237 def NumberOfSegments(self, n, s=[]):
1239 Defines "NumberOfSegments" hypothesis, specifying the number of layers of
1240 prisms to build between the inner and the outer shells.
1243 n: the number of layers
1244 s: the scale factor (optional)
1246 if self.algoType != "RadialPrism_3D":
1247 print("Prism_3D algorithm doesn't support any hypothesis")
1250 hyp = self.OwnHypothesis("NumberOfSegments", [n])
1252 hyp = self.OwnHypothesis("NumberOfSegments", [n,s])
1253 hyp.SetScaleFactor(s)
1254 hyp.SetNumberOfSegments(n)
1257 def Arithmetic1D(self, start, end ):
1259 Defines "Arithmetic1D" hypothesis, specifying the distribution of segments
1260 to build between the inner and the outer shells with a length that changes
1261 in arithmetic progression
1264 start: the length of the first segment
1265 end: the length of the last segment
1267 if self.algoType != "RadialPrism_3D":
1268 print("Prism_3D algorithm doesn't support any hypothesis")
1270 hyp = self.OwnHypothesis("Arithmetic1D", [start, end])
1271 hyp.SetLength(start, 1)
1272 hyp.SetLength(end , 0)
1275 def GeometricProgression(self, start, ratio ):
1277 Defines "GeometricProgression" hypothesis, specifying the distribution of segments
1278 to build between the inner and the outer shells with a length that changes
1279 in Geometric progression
1282 start: the length of the first segment
1283 ratio: the common ratio of the geometric progression
1285 if self.algoType != "RadialPrism_3D":
1286 print("Prism_3D algorithm doesn't support any hypothesis")
1288 hyp = self.OwnHypothesis("GeometricProgression", [start, ratio])
1289 hyp.SetStartLength( start )
1290 hyp.SetCommonRatio( ratio )
1293 def StartEndLength(self, start, end):
1295 Defines "StartEndLength" hypothesis, specifying distribution of segments
1296 to build between the inner and the outer shells as geometric length increasing
1299 start: for the length of the first segment
1300 end: for the length of the last segment
1302 if self.algoType != "RadialPrism_3D":
1303 print("Prism_3D algorithm doesn't support any hypothesis")
1305 hyp = self.OwnHypothesis("StartEndLength", [start, end])
1306 hyp.SetLength(start, 1)
1307 hyp.SetLength(end , 0)
1310 def AutomaticLength(self, fineness=0):
1312 Defines "AutomaticLength" hypothesis, specifying the number of segments
1313 to build between the inner and outer shells
1316 fineness: defines the quality of the mesh within the range [0-1]
1318 if self.algoType != "RadialPrism_3D":
1319 print("Prism_3D algorithm doesn't support any hypothesis")
1321 hyp = self.OwnHypothesis("AutomaticLength")
1322 hyp.SetFineness( fineness )
1325 pass # end of StdMeshersBuilder_Prism3D class
1327 class StdMeshersBuilder_RadialPrism3D(StdMeshersBuilder_Prism3D):
1329 Defines Radial Prism 3D algorithm.
1330 It is created by calling smeshBuilder.Mesh.Prism(geom=0).
1331 See :class:`StdMeshersBuilder_Prism3D` for methods defining distribution of mesh layers
1332 build between the inner and outer shells.
1335 meshMethod = "Prism"
1337 name of the dynamic method in smeshBuilder.Mesh class
1339 algoType = "RadialPrism_3D"
1341 type of algorithm used with helper function in smeshBuilder.Mesh class
1343 docHelper = "Create Raial Prism 3D algorithm for volumes"
1345 doc string of the method
1348 def __init__(self, mesh, geom=0):
1350 Private constructor.
1353 mesh: parent mesh object algorithm is assigned to
1354 geom: geometry (shape/sub-shape) algorithm is assigned to;
1355 if it is :code:`0` (default), the algorithm is assigned to the main shape
1357 Mesh_Algorithm.__init__(self)
1362 self.Create(mesh, geom, "RadialPrism_3D")
1363 self.distribHyp = None
1364 self.nbLayers = None
1367 class StdMeshersBuilder_RadialAlgorithm(Mesh_Algorithm):
1369 Base class for algorithms supporting radial distribution hypotheses
1373 Mesh_Algorithm.__init__(self)
1375 self.distribHyp = None #self.Hypothesis("LayerDistribution2D", UseExisting=0)
1376 self.nbLayers = None
1379 def Get2DHypothesis(self):
1382 2D hypothesis holding the 1D one
1384 if not self.distribHyp:
1385 self.distribHyp = self.Hypothesis("LayerDistribution2D", UseExisting=0)
1386 return self.distribHyp
1388 def OwnHypothesis(self, hypType, args=[], so="libStdMeshersEngine.so"):
1390 Private method creating a 1D hypothesis and storing it in the LayerDistribution
1394 the created hypothesis
1397 self.mesh.GetMesh().RemoveHypothesis( self.geom, self.nbLayers )
1398 if self.distribHyp is None:
1399 self.distribHyp = self.Hypothesis("LayerDistribution2D", UseExisting=0)
1401 self.mesh.GetMesh().AddHypothesis( self.geom, self.distribHyp )
1402 self.mesh.smeshpyD.SetEnablePublish( False )
1403 hyp = self.mesh.smeshpyD.CreateHypothesis(hypType, so)
1404 self.mesh.smeshpyD.SetEnablePublish( True )
1405 self.distribHyp.SetLayerDistribution( hyp )
1408 def NumberOfLayers(self, n, UseExisting=0):
1410 Defines "NumberOfLayers" hypothesis, specifying the number of layers
1414 UseExisting: if ==true - searches for the existing hypothesis created with
1415 the same parameters, else (default) - Create a new one
1418 self.mesh.GetMesh().RemoveHypothesis( self.geom, self.distribHyp )
1419 from salome.smesh.smeshBuilder import IsEqual
1420 compFun = lambda hyp, args: IsEqual(hyp.GetNumberOfLayers(), args[0])
1421 self.nbLayers = self.Hypothesis("NumberOfLayers2D", [n], UseExisting=UseExisting,
1422 CompareMethod=compFun)
1423 self.nbLayers.SetNumberOfLayers( n )
1424 return self.nbLayers
1426 def LocalLength(self, l, p=1e-07):
1428 Defines "LocalLength" hypothesis, specifying the segment length
1431 l: the length of segments
1432 p: the precision of rounding
1434 hyp = self.OwnHypothesis("LocalLength", [l,p])
1439 def NumberOfSegments(self, n, s=[]):
1441 Defines "NumberOfSegments" hypothesis, specifying the number of layers
1444 n: the number of layers
1445 s: the scale factor (optional)
1448 hyp = self.OwnHypothesis("NumberOfSegments", [n])
1450 hyp = self.OwnHypothesis("NumberOfSegments", [n,s])
1451 hyp.SetDistrType( 1 )
1452 hyp.SetScaleFactor(s)
1453 hyp.SetNumberOfSegments(n)
1456 def Arithmetic1D(self, start, end ):
1458 Defines "Arithmetic1D" hypothesis, specifying the distribution of segments
1459 with a length that changes in arithmetic progression
1462 start: the length of the first segment
1463 end: the length of the last segment
1465 hyp = self.OwnHypothesis("Arithmetic1D", [start, end])
1466 hyp.SetLength(start, 1)
1467 hyp.SetLength(end , 0)
1470 def GeometricProgression(self, start, ratio ):
1472 Defines "GeometricProgression" hypothesis, specifying the distribution of segments
1473 with a length that changes in Geometric progression
1476 start: the length of the first segment
1477 ratio: the common ratio of the geometric progression
1479 hyp = self.OwnHypothesis("GeometricProgression", [start, ratio])
1480 hyp.SetStartLength( start )
1481 hyp.SetCommonRatio( ratio )
1484 def StartEndLength(self, start, end):
1486 Defines "StartEndLength" hypothesis, specifying distribution of segments
1487 as geometric length increasing
1490 start: for the length of the first segment
1491 end: for the length of the last segment
1493 hyp = self.OwnHypothesis("StartEndLength", [start, end])
1494 hyp.SetLength(start, 1)
1495 hyp.SetLength(end , 0)
1498 def AutomaticLength(self, fineness=0):
1500 Defines "AutomaticLength" hypothesis, specifying the number of segments
1503 fineness: defines the quality of the mesh within the range [0-1]
1505 hyp = self.OwnHypothesis("AutomaticLength")
1506 hyp.SetFineness( fineness )
1509 pass # end of StdMeshersBuilder_RadialQuadrangle1D2D class
1511 class StdMeshersBuilder_RadialQuadrangle1D2D(StdMeshersBuilder_RadialAlgorithm):
1513 Defines a Radial Quadrangle 1D-2D algorithm.
1514 It is created by calling smeshBuilder.Mesh.Quadrangle(smeshBuilder.RADIAL_QUAD,geom=0)
1517 meshMethod = "Quadrangle"
1519 name of the dynamic method in smeshBuilder.Mesh class
1521 algoType = RADIAL_QUAD
1523 type of algorithm used with helper function in smeshBuilder.Mesh class
1525 docHelper = "Create quadrangle 1D-2D algorithm for faces having a shape of disk or a disk segment"
1527 doc string of the method
1530 def __init__(self, mesh, geom=0):
1532 Private constructor.
1535 mesh: parent mesh object algorithm is assigned to
1536 geom: geometry (shape/sub-shape) algorithm is assigned to;
1537 if it is :code:`0` (default), the algorithm is assigned to the main shape
1539 StdMeshersBuilder_RadialAlgorithm.__init__(self)
1540 self.Create(mesh, geom, self.algoType)
1542 self.distribHyp = None #self.Hypothesis("LayerDistribution2D", UseExisting=0)
1543 self.nbLayers = None
1547 class StdMeshersBuilder_QuadMA_1D2D(StdMeshersBuilder_RadialAlgorithm):
1549 Defines a Quadrangle (Medial Axis Projection) 1D-2D algorithm .
1550 It is created by calling smeshBuilder.Mesh.Quadrangle(smeshBuilder.QUAD_MA_PROJ,geom=0)
1553 meshMethod = "Quadrangle"
1555 name of the dynamic method in smeshBuilder.Mesh class
1557 algoType = QUAD_MA_PROJ
1559 type of algorithm used with helper function in smeshBuilder.Mesh class
1561 docHelper = "Create quadrangle 1D-2D algorithm for faces"
1563 doc string of the method
1566 def __init__(self, mesh, geom=0):
1568 Private constructor.
1571 mesh: parent mesh object algorithm is assigned to
1572 geom: geometry (shape/sub-shape) algorithm is assigned to;
1573 if it is :code:`0` (default), the algorithm is assigned to the main shape
1575 StdMeshersBuilder_RadialAlgorithm.__init__(self)
1576 self.Create(mesh, geom, self.algoType)
1581 class StdMeshersBuilder_PolygonPerFace(Mesh_Algorithm):
1582 """ Defines a Polygon Per Face 2D algorithm.
1583 It is created by calling smeshBuilder.Mesh.Polygon(geom=0)
1586 meshMethod = "Polygon"
1588 name of the dynamic method in smeshBuilder.Mesh class
1592 type of algorithm used with helper function in smeshBuilder.Mesh class
1596 flag pointing whether this algorithm should be used by default in dynamic method
1597 of smeshBuilder.Mesh class
1599 docHelper = "Create polygon 2D algorithm for faces"
1601 doc string of the method
1604 def __init__(self, mesh, geom=0):
1606 Private constructor.
1609 mesh: parent mesh object algorithm is assigned to
1610 geom: geometry (shape/sub-shape) algorithm is assigned to;
1611 if it is :code:`0` (default), the algorithm is assigned to the main shape
1613 Mesh_Algorithm.__init__(self)
1614 self.Create(mesh, geom, self.algoType)
1619 class StdMeshersBuilder_PolyhedronPerSolid(Mesh_Algorithm):
1620 """ Defines a Polyhedron Per Solid 3D algorithm.
1621 It is created by calling smeshBuilder.Mesh.Polyhedron(geom=0)
1624 meshMethod = "Polyhedron"
1626 name of the dynamic method in smeshBuilder.Mesh class
1628 algoType = POLYHEDRON
1630 type of algorithm used with helper function in smeshBuilder.Mesh class
1634 flag pointing whether this algorithm should be used by default in dynamic method
1635 of smeshBuilder.Mesh class
1637 docHelper = "Create polyhedron 3D algorithm for solids"
1639 doc string of the method
1642 def __init__(self, mesh, geom=0):
1644 Private constructor.
1647 mesh: parent mesh object algorithm is assigned to
1648 geom: geometry (shape/sub-shape) algorithm is assigned to;
1649 if it is :code:`0` (default), the algorithm is assigned to the main shape
1651 Mesh_Algorithm.__init__(self)
1652 self.Create(mesh, geom, self.algoType)
1657 class StdMeshersBuilder_UseExistingElements_1D(Mesh_Algorithm):
1658 """ Defines a Use Existing Elements 1D algorithm.
1660 It is created by calling smeshBuilder.Mesh.UseExisting1DElements(geom=0)
1664 meshMethod = "UseExisting1DElements"
1666 name of the dynamic method in smeshBuilder.Mesh class
1668 algoType = "Import_1D"
1670 type of algorithm used with helper function in smeshBuilder.Mesh class
1674 flag pointing whether this algorithm should be used by default in dynamic method
1675 of smeshBuilder.Mesh class
1677 docHelper = "Create 1D algorithm for edges with reusing of existing mesh elements"
1679 doc string of the method
1682 def __init__(self, mesh, geom=0):
1684 Private constructor.
1687 mesh: parent mesh object algorithm is assigned to
1688 geom: geometry (shape/sub-shape) algorithm is assigned to;
1689 if it is :code:`0` (default), the algorithm is assigned to the main shape
1691 Mesh_Algorithm.__init__(self)
1692 self.Create(mesh, geom, self.algoType)
1695 def SourceEdges(self, groups, toCopyMesh=False, toCopyGroups=False, UseExisting=False):
1697 Defines "Source edges" hypothesis, specifying groups of edges to import
1700 groups: list of groups of edges
1701 toCopyMesh: if True, the whole mesh *groups* belong to is imported
1702 toCopyGroups: if True, all groups of the mesh *groups* belong to are imported
1703 UseExisting: if ==true - searches for the existing hypothesis created with
1704 the same parameters, else (default) - Create a new one
1706 for group in groups:
1707 from salome.smesh.smeshBuilder import AssureGeomPublished
1708 AssureGeomPublished( self.mesh, group )
1709 compFun = lambda hyp, args: ( hyp.GetSourceEdges() == args[0] and \
1710 hyp.GetCopySourceMesh() == args[1], args[2] )
1711 hyp = self.Hypothesis("ImportSource1D", [groups, toCopyMesh, toCopyGroups],
1712 UseExisting=UseExisting, CompareMethod=compFun)
1713 hyp.SetSourceEdges(groups)
1714 hyp.SetCopySourceMesh(toCopyMesh, toCopyGroups)
1717 pass # end of StdMeshersBuilder_UseExistingElements_1D class
1719 class StdMeshersBuilder_UseExistingElements_1D2D(Mesh_Algorithm):
1720 """ Defines a Use Existing Elements 1D-2D algorithm.
1722 It is created by calling smeshBuilder.Mesh.UseExisting2DElements(geom=0)
1726 meshMethod = "UseExisting2DElements"
1728 name of the dynamic method in smeshBuilder.Mesh class
1730 algoType = "Import_1D2D"
1732 type of algorithm used with helper function in smeshBuilder.Mesh class
1736 flag pointing whether this algorithm should be used by default in dynamic method
1737 of smeshBuilder.Mesh class
1739 docHelper = "Create 1D-2D algorithm for faces with reusing of existing mesh elements"
1741 doc string of the method
1744 def __init__(self, mesh, geom=0):
1746 Private constructor.
1749 mesh: parent mesh object algorithm is assigned to
1750 geom: geometry (shape/sub-shape) algorithm is assigned to;
1751 if it is :code:`0` (default), the algorithm is assigned to the main shape
1753 Mesh_Algorithm.__init__(self)
1754 self.Create(mesh, geom, self.algoType)
1757 def SourceFaces(self, groups, toCopyMesh=False, toCopyGroups=False, UseExisting=False):
1759 Defines "Source faces" hypothesis, specifying groups of faces to import
1762 groups: list of groups of faces
1763 toCopyMesh: if True, the whole mesh *groups* belong to is imported
1764 toCopyGroups: if True, all groups of the mesh *groups* belong to are imported
1765 UseExisting: if ==true - searches for the existing hypothesis created with
1766 the same parameters, else (default) - Create a new one
1769 compFun = lambda hyp, args: ( hyp.GetSourceFaces() == args[0] and \
1770 hyp.GetCopySourceMesh() == args[1], args[2] )
1771 hyp = self.Hypothesis("ImportSource2D", [groups, toCopyMesh, toCopyGroups],
1772 UseExisting=UseExisting, CompareMethod=compFun, toAdd=False)
1773 if groups and isinstance( groups, SMESH._objref_SMESH_GroupBase ):
1775 hyp.SetSourceFaces(groups)
1776 hyp.SetCopySourceMesh(toCopyMesh, toCopyGroups)
1777 self.mesh.AddHypothesis(hyp, self.geom)
1780 pass # end of StdMeshersBuilder_UseExistingElements_1D2D class
1782 class StdMeshersBuilder_Cartesian_3D(Mesh_Algorithm):
1783 """ Defines a Body Fitting 3D algorithm.
1785 It is created by calling smeshBuilder.Mesh.BodyFitted(geom=0)
1789 meshMethod = "BodyFitted"
1791 name of the dynamic method in smeshBuilder.Mesh class
1793 algoType = "Cartesian_3D"
1795 type of algorithm used with helper function in smeshBuilder.Mesh class
1799 flag pointing whether this algorithm should be used by default in dynamic method
1800 of smeshBuilder.Mesh class
1802 docHelper = "Create Body Fitting 3D algorithm for volumes"
1804 doc string of the method
1807 def __init__(self, mesh, geom=0):
1809 Private constructor.
1812 mesh: parent mesh object algorithm is assigned to
1813 geom: geometry (shape/sub-shape) algorithm is assigned to;
1814 if it is :code:`0` (default), the algorithm is assigned to the main shape
1816 self.Create(mesh, geom, self.algoType)
1820 def SetGrid(self, xGridDef, yGridDef, zGridDef, sizeThreshold=4.0, implEdges=False):
1822 Defines "Body Fitting parameters" hypothesis
1825 xGridDef: is definition of the grid along the X asix.
1826 It can be in either of two following forms:
1828 - Explicit coordinates of nodes, e.g. [-1.5, 0.0, 3.1] or range( -100,200,10)
1829 - Functions f(t) defining grid spacing at each point on grid axis. If there are
1830 several functions, they must be accompanied by relative coordinates of
1831 points dividing the whole shape into ranges where the functions apply; points
1832 coordinates should vary within (0.0, 1.0) range. Parameter *t* of the spacing
1833 function f(t) varies from 0.0 to 1.0 within a shape range.
1835 The actual grid spacing can slightly differ from the defined one. This is done for the
1836 best fitting of polyhedrons and for a better mesh quality on the interval boundaries.
1837 For example, if a constant **Spacing** is defined along an axis, the actual grid will
1838 fill the shape's dimension L along this axis with round number of equal cells:
1839 Spacing_actual = L / round( L / Spacing_defined ).
1842 "10.5" - defines a grid with a constant spacing
1843 [["1", "1+10*t", "11"] [0.1, 0.6]] - defines different spacing in 3 ranges.
1846 yGridDef: defines the grid along the Y asix the same way as *xGridDef* does.
1847 zGridDef: defines the grid along the Z asix the same way as *xGridDef* does.
1848 sizeThreshold: (> 1.0) defines a minimal size of a polyhedron so that
1849 a polyhedron of size less than hexSize/sizeThreshold is not created.
1850 implEdges: enables implementation of geometrical edges into the mesh.
1853 compFun = lambda hyp, args: False
1854 self.hyp = self.Hypothesis("CartesianParameters3D",
1855 [xGridDef, yGridDef, zGridDef, sizeThreshold],
1856 UseExisting=False, CompareMethod=compFun)
1857 if not self.mesh.IsUsedHypothesis( self.hyp, self.geom ):
1858 self.mesh.AddHypothesis( self.hyp, self.geom )
1860 for axis, gridDef in enumerate( [xGridDef, yGridDef, zGridDef] ):
1861 if not gridDef: raise ValueError("Empty grid definition")
1862 if isinstance( gridDef, str ):
1863 self.hyp.SetGridSpacing( [gridDef], [], axis )
1864 elif isinstance( gridDef[0], str ):
1865 self.hyp.SetGridSpacing( gridDef, [], axis )
1866 elif isinstance( gridDef[0], int ) or \
1867 isinstance( gridDef[0], float ):
1868 self.hyp.SetGrid(gridDef, axis )
1870 self.hyp.SetGridSpacing( gridDef[0], gridDef[1], axis )
1871 self.hyp.SetSizeThreshold( sizeThreshold )
1872 self.hyp.SetToAddEdges( implEdges )
1875 def SetAxesDirs( self, xAxis, yAxis, zAxis ):
1877 Defines custom directions of axes of the grid
1880 xAxis: either SMESH.DirStruct or a vector, or 3 vector components
1881 yAxis: either SMESH.DirStruct or a vector, or 3 vector components
1882 zAxis: either SMESH.DirStruct or a vector, or 3 vector components
1885 if hasattr( xAxis, "__getitem__" ):
1886 xAxis = self.mesh.smeshpyD.MakeDirStruct( xAxis[0],xAxis[1],xAxis[2] )
1887 elif isinstance( xAxis, GEOM._objref_GEOM_Object ):
1888 xAxis = self.mesh.smeshpyD.GetDirStruct( xAxis )
1889 if hasattr( yAxis, "__getitem__" ):
1890 yAxis = self.mesh.smeshpyD.MakeDirStruct( yAxis[0],yAxis[1],yAxis[2] )
1891 elif isinstance( yAxis, GEOM._objref_GEOM_Object ):
1892 yAxis = self.mesh.smeshpyD.GetDirStruct( yAxis )
1893 if hasattr( zAxis, "__getitem__" ):
1894 zAxis = self.mesh.smeshpyD.MakeDirStruct( zAxis[0],zAxis[1],zAxis[2] )
1895 elif isinstance( zAxis, GEOM._objref_GEOM_Object ):
1896 zAxis = self.mesh.smeshpyD.GetDirStruct( zAxis )
1898 self.hyp = self.Hypothesis("CartesianParameters3D")
1899 if not self.mesh.IsUsedHypothesis( self.hyp, self.geom ):
1900 self.mesh.AddHypothesis( self.hyp, self.geom )
1901 self.hyp.SetAxesDirs( xAxis, yAxis, zAxis )
1904 def SetOptimalAxesDirs(self, isOrthogonal=True):
1906 Automatically defines directions of axes of the grid at which
1907 a number of generated hexahedra is maximal
1910 isOrthogonal: defines whether the axes mush be orthogonal
1913 self.hyp = self.Hypothesis("CartesianParameters3D")
1914 if not self.mesh.IsUsedHypothesis( self.hyp, self.geom ):
1915 self.mesh.AddHypothesis( self.hyp, self.geom )
1916 x,y,z = self.hyp.ComputeOptimalAxesDirs( self.geom, isOrthogonal )
1917 self.hyp.SetAxesDirs( x,y,z )
1920 def SetFixedPoint( self, p, toUnset=False ):
1922 Sets/unsets a fixed point. The algorithm makes a plane of the grid pass
1923 through the fixed point in each direction at which the grid is defined
1927 p: coordinates of the fixed point. Either SMESH.PointStruct or
1928 a vertex or 3 components of coordinates.
1929 toUnset: defines whether the fixed point is defined or removed.
1933 if not self.hyp: return
1934 p = SMESH.PointStruct(0,0,0)
1935 elif hasattr( p, "__getitem__" ):
1936 p = SMESH.PointStruct( p[0],p[1],p[2] )
1937 elif isinstance( p, GEOM._objref_GEOM_Object ):
1938 p = self.mesh.smeshpyD.GetPointStruct( p )
1940 self.hyp = self.Hypothesis("CartesianParameters3D")
1941 if not self.mesh.IsUsedHypothesis( self.hyp, self.geom ):
1942 self.mesh.AddHypothesis( self.hyp, self.geom )
1943 self.hyp.SetFixedPoint( p, toUnset )
1947 pass # end of StdMeshersBuilder_Cartesian_3D class
1949 class StdMeshersBuilder_UseExisting_1D(Mesh_Algorithm):
1950 """ Defines a stub 1D algorithm, which enables "manual" creation of nodes and
1951 segments usable by 2D algorithms.
1953 It is created by calling smeshBuilder.Mesh.UseExistingSegments(geom=0)
1957 meshMethod = "UseExistingSegments"
1959 name of the dynamic method in smeshBuilder.Mesh class
1961 algoType = "UseExisting_1D"
1963 type of algorithm used with helper function in smeshBuilder.Mesh class
1965 docHelper = "Create 1D algorithm allowing batch meshing of edges"
1967 doc string of the method
1970 def __init__(self, mesh, geom=0):
1972 Private constructor.
1975 mesh: parent mesh object algorithm is assigned to
1976 geom: geometry (shape/sub-shape) algorithm is assigned to;
1977 if it is :code:`0` (default), the algorithm is assigned to the main shape
1979 self.Create(mesh, geom, self.algoType)
1982 pass # end of StdMeshersBuilder_UseExisting_1D class
1984 class StdMeshersBuilder_UseExisting_2D(Mesh_Algorithm):
1985 """ Defines a stub 2D algorithm, which enables "manual" creation of nodes and
1986 faces usable by 3D algorithms.
1988 It is created by calling smeshBuilder.Mesh.UseExistingFaces(geom=0)
1992 meshMethod = "UseExistingFaces"
1994 name of the dynamic method in smeshBuilder.Mesh class
1996 algoType = "UseExisting_2D"
1998 type of algorithm used with helper function in smeshBuilder.Mesh class
2000 docHelper = "Create 2D algorithm allowing batch meshing of faces"
2002 doc string of the method
2005 def __init__(self, mesh, geom=0):
2007 Private constructor.
2010 mesh: parent mesh object algorithm is assigned to
2011 geom: geometry (shape/sub-shape) algorithm is assigned to;
2012 if it is :code:`0` (default), the algorithm is assigned to the main shape
2014 self.Create(mesh, geom, self.algoType)
2017 pass # end of StdMeshersBuilder_UseExisting_2D class