1 # Copyright (C) 2007-2011 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.
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 from smesh import Mesh_Algorithm, AssureGeomPublished, IsEqual, ParseParameters
22 from smeshDC import Mesh
27 REGULAR = "Regular_1D"
29 COMPOSITE = "CompositeSegment_1D"
30 MEFISTO = "MEFISTO_2D"
32 QUADRANGLE = "Quadrangle_2D"
33 RADIAL_QUAD = "RadialQuadrangle_1D2D"
36 # import items of enum QuadType
37 for e in StdMeshers.QuadType._items: exec('%s = StdMeshers.%s'%(e,e))
40 # Public class: Mesh_Segment
41 # --------------------------
43 ## Class to define a REGULAR 1D algorithm for discretization. It is created by
44 # calling Mesh.Segment(geom=0)
46 # @ingroup l3_algos_basic
47 class Mesh_Segment(Mesh_Algorithm):
49 meshMethod = "Segment"
53 ## Private constructor.
54 def __init__(self, mesh, geom=0):
55 Mesh_Algorithm.__init__(self)
56 self.Create(mesh, geom, self.algoType)
58 ## Defines "LocalLength" hypothesis to cut an edge in several segments with the same length
59 # @param l for the length of segments that cut an edge
60 # @param UseExisting if ==true - searches for an existing hypothesis created with
61 # the same parameters, else (default) - creates a new one
62 # @param p precision, used for calculation of the number of segments.
63 # The precision should be a positive, meaningful value within the range [0,1].
64 # In general, the number of segments is calculated with the formula:
65 # nb = ceil((edge_length / l) - p)
66 # Function ceil rounds its argument to the higher integer.
67 # So, p=0 means rounding of (edge_length / l) to the higher integer,
68 # p=0.5 means rounding of (edge_length / l) to the nearest integer,
69 # p=1 means rounding of (edge_length / l) to the lower integer.
70 # Default value is 1e-07.
71 # @return an instance of StdMeshers_LocalLength hypothesis
72 # @ingroup l3_hypos_1dhyps
73 def LocalLength(self, l, UseExisting=0, p=1e-07):
74 comFun=lambda hyp, args: IsEqual(hyp.GetLength(), args[0]) and IsEqual(hyp.GetPrecision(), args[1])
75 hyp = self.Hypothesis("LocalLength", [l,p], UseExisting=UseExisting, CompareMethod=comFun)
80 ## Defines "MaxSize" hypothesis to cut an edge into segments not longer than given value
81 # @param length is optional maximal allowed length of segment, if it is omitted
82 # the preestimated length is used that depends on geometry size
83 # @param UseExisting if ==true - searches for an existing hypothesis created with
84 # the same parameters, else (default) - creates a new one
85 # @return an instance of StdMeshers_MaxLength hypothesis
86 # @ingroup l3_hypos_1dhyps
87 def MaxSize(self, length=0.0, UseExisting=0):
88 hyp = self.Hypothesis("MaxLength", [length], UseExisting=UseExisting)
93 # set preestimated length
94 gen = self.mesh.smeshpyD
95 initHyp = gen.GetHypothesisParameterValues("MaxLength", "libStdMeshersEngine.so",
96 self.mesh.GetMesh(), self.mesh.GetShape(),
98 preHyp = initHyp._narrow(StdMeshers.StdMeshers_MaxLength)
100 hyp.SetPreestimatedLength( preHyp.GetPreestimatedLength() )
103 hyp.SetUsePreestimatedLength( length == 0.0 )
106 ## Defines "NumberOfSegments" hypothesis to cut an edge in a fixed number of segments
107 # @param n for the number of segments that cut an edge
108 # @param s for the scale factor (optional)
109 # @param reversedEdges is a list of edges to mesh using reversed orientation.
110 # A list item can also be a tuple (edge 1st_vertex_of_edge)
111 # @param UseExisting if ==true - searches for an existing hypothesis created with
112 # the same parameters, else (default) - create a new one
113 # @return an instance of StdMeshers_NumberOfSegments hypothesis
114 # @ingroup l3_hypos_1dhyps
115 def NumberOfSegments(self, n, s=[], reversedEdges=[], UseExisting=0):
116 if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
117 reversedEdges, UseExisting = [], reversedEdges
118 entry = self.MainShapeEntry()
119 reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
121 hyp = self.Hypothesis("NumberOfSegments", [n, reversedEdgeInd, entry],
122 UseExisting=UseExisting,
123 CompareMethod=self._compareNumberOfSegments)
125 hyp = self.Hypothesis("NumberOfSegments", [n,s, reversedEdgeInd, entry],
126 UseExisting=UseExisting,
127 CompareMethod=self._compareNumberOfSegments)
128 hyp.SetDistrType( 1 )
129 hyp.SetScaleFactor(s)
130 hyp.SetNumberOfSegments(n)
131 hyp.SetReversedEdges( reversedEdgeInd )
132 hyp.SetObjectEntry( entry )
136 ## Checks if the given "NumberOfSegments" hypothesis has the same parameters as the given arguments
137 def _compareNumberOfSegments(self, hyp, args):
138 if hyp.GetNumberOfSegments() == args[0]:
140 if hyp.GetReversedEdges() == args[1]:
141 if not args[1] or hyp.GetObjectEntry() == args[2]:
144 if hyp.GetReversedEdges() == args[2]:
145 if not args[2] or hyp.GetObjectEntry() == args[3]:
146 if hyp.GetDistrType() == 1:
147 if IsEqual(hyp.GetScaleFactor(), args[1]):
151 ## Defines "Arithmetic1D" hypothesis to cut an edge in several segments with increasing arithmetic length
152 # @param start defines the length of the first segment
153 # @param end defines the length of the last segment
154 # @param reversedEdges is a list of edges to mesh using reversed orientation.
155 # A list item can also be a tuple (edge 1st_vertex_of_edge)
156 # @param UseExisting if ==true - searches for an existing hypothesis created with
157 # the same parameters, else (default) - creates a new one
158 # @return an instance of StdMeshers_Arithmetic1D hypothesis
159 # @ingroup l3_hypos_1dhyps
160 def Arithmetic1D(self, start, end, reversedEdges=[], UseExisting=0):
161 if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
162 reversedEdges, UseExisting = [], reversedEdges
163 reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
164 entry = self.MainShapeEntry()
165 compFun = lambda hyp, args: ( IsEqual(hyp.GetLength(1), args[0]) and \
166 IsEqual(hyp.GetLength(0), args[1]) and \
167 hyp.GetReversedEdges() == args[2] and \
168 (not args[2] or hyp.GetObjectEntry() == args[3]))
169 hyp = self.Hypothesis("Arithmetic1D", [start, end, reversedEdgeInd, entry],
170 UseExisting=UseExisting, CompareMethod=compFun)
171 hyp.SetStartLength(start)
172 hyp.SetEndLength(end)
173 hyp.SetReversedEdges( reversedEdgeInd )
174 hyp.SetObjectEntry( entry )
177 ## Defines "FixedPoints1D" hypothesis to cut an edge using parameter
178 # on curve from 0 to 1 (additionally it is neecessary to check
179 # orientation of edges and create list of reversed edges if it is
180 # needed) and sets numbers of segments between given points (default
181 # values are equals 1
182 # @param points defines the list of parameters on curve
183 # @param nbSegs defines the list of numbers of segments
184 # @param reversedEdges is a list of edges to mesh using reversed orientation.
185 # A list item can also be a tuple (edge 1st_vertex_of_edge)
186 # @param UseExisting if ==true - searches for an existing hypothesis created with
187 # the same parameters, else (default) - creates a new one
188 # @return an instance of StdMeshers_Arithmetic1D hypothesis
189 # @ingroup l3_hypos_1dhyps
190 def FixedPoints1D(self, points, nbSegs=[1], reversedEdges=[], UseExisting=0):
191 if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
192 reversedEdges, UseExisting = [], reversedEdges
193 reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
194 entry = self.MainShapeEntry()
195 compFun = lambda hyp, args: ( hyp.GetPoints() == args[0] and \
196 hyp.GetNbSegments() == args[1] and \
197 hyp.GetReversedEdges() == args[2] and \
198 (not args[2] or hyp.GetObjectEntry() == args[3]))
199 hyp = self.Hypothesis("FixedPoints1D", [points, nbSegs, reversedEdgeInd, entry],
200 UseExisting=UseExisting, CompareMethod=compFun)
201 hyp.SetPoints(points)
202 hyp.SetNbSegments(nbSegs)
203 hyp.SetReversedEdges(reversedEdgeInd)
204 hyp.SetObjectEntry(entry)
207 ## Defines "StartEndLength" hypothesis to cut an edge in several segments with increasing geometric length
208 # @param start defines the length of the first segment
209 # @param end defines the length of the last segment
210 # @param reversedEdges is a list of edges to mesh using reversed orientation.
211 # A list item can also be a tuple (edge 1st_vertex_of_edge)
212 # @param UseExisting if ==true - searches for an existing hypothesis created with
213 # the same parameters, else (default) - creates a new one
214 # @return an instance of StdMeshers_StartEndLength hypothesis
215 # @ingroup l3_hypos_1dhyps
216 def StartEndLength(self, start, end, reversedEdges=[], UseExisting=0):
217 if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
218 reversedEdges, UseExisting = [], reversedEdges
219 reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
220 entry = self.MainShapeEntry()
221 compFun = lambda hyp, args: ( IsEqual(hyp.GetLength(1), args[0]) and \
222 IsEqual(hyp.GetLength(0), args[1]) and \
223 hyp.GetReversedEdges() == args[2] and \
224 (not args[2] or hyp.GetObjectEntry() == args[3]))
225 hyp = self.Hypothesis("StartEndLength", [start, end, reversedEdgeInd, entry],
226 UseExisting=UseExisting, CompareMethod=compFun)
227 hyp.SetStartLength(start)
228 hyp.SetEndLength(end)
229 hyp.SetReversedEdges( reversedEdgeInd )
230 hyp.SetObjectEntry( entry )
233 ## Defines "Deflection1D" hypothesis
234 # @param d for the deflection
235 # @param UseExisting if ==true - searches for an existing hypothesis created with
236 # the same parameters, else (default) - create a new one
237 # @ingroup l3_hypos_1dhyps
238 def Deflection1D(self, d, UseExisting=0):
239 compFun = lambda hyp, args: IsEqual(hyp.GetDeflection(), args[0])
240 hyp = self.Hypothesis("Deflection1D", [d], UseExisting=UseExisting, CompareMethod=compFun)
244 ## Defines "Propagation" hypothesis that propagates all other hypotheses on all other edges that are at
245 # the opposite side in case of quadrangular faces
246 # @ingroup l3_hypos_additi
247 def Propagation(self):
248 return self.Hypothesis("Propagation", UseExisting=1, CompareMethod=self.CompareEqualHyp)
250 ## Defines "AutomaticLength" hypothesis
251 # @param fineness for the fineness [0-1]
252 # @param UseExisting if ==true - searches for an existing hypothesis created with the
253 # same parameters, else (default) - create a new one
254 # @ingroup l3_hypos_1dhyps
255 def AutomaticLength(self, fineness=0, UseExisting=0):
256 compFun = lambda hyp, args: IsEqual(hyp.GetFineness(), args[0])
257 hyp = self.Hypothesis("AutomaticLength",[fineness],UseExisting=UseExisting,
258 CompareMethod=compFun)
259 hyp.SetFineness( fineness )
262 ## Defines "SegmentLengthAroundVertex" hypothesis
263 # @param length for the segment length
264 # @param vertex for the length localization: the vertex index [0,1] | vertex object.
265 # Any other integer value means that the hypothesis will be set on the
266 # whole 1D shape, where Mesh_Segment algorithm is assigned.
267 # @param UseExisting if ==true - searches for an existing hypothesis created with
268 # the same parameters, else (default) - creates a new one
269 # @ingroup l3_algos_segmarv
270 def LengthNearVertex(self, length, vertex=0, UseExisting=0):
272 store_geom = self.geom
273 if type(vertex) is types.IntType:
274 if vertex == 0 or vertex == 1:
275 vertex = self.mesh.geompyD.ExtractShapes(self.geom, geompyDC.ShapeType["VERTEX"],True)[vertex]
283 if self.geom is None:
284 raise RuntimeError, "Attemp to create SegmentAroundVertex_0D algoritm on None shape"
285 AssureGeomPublished( self.mesh, self.geom )
286 name = GetName(self.geom)
288 algo = self.FindAlgorithm("SegmentAroundVertex_0D", self.mesh.smeshpyD)
290 algo = self.mesh.smeshpyD.CreateHypothesis("SegmentAroundVertex_0D", "libStdMeshersEngine.so")
292 status = self.mesh.mesh.AddHypothesis(self.geom, algo)
293 TreatHypoStatus(status, "SegmentAroundVertex_0D", name, True)
295 comFun = lambda hyp, args: IsEqual(hyp.GetLength(), args[0])
296 hyp = self.Hypothesis("SegmentLengthAroundVertex", [length], UseExisting=UseExisting,
297 CompareMethod=comFun)
298 self.geom = store_geom
299 hyp.SetLength( length )
302 ## Defines "QuadraticMesh" hypothesis, forcing construction of quadratic edges.
303 # If the 2D mesher sees that all boundary edges are quadratic,
304 # it generates quadratic faces, else it generates linear faces using
305 # medium nodes as if they are vertices.
306 # The 3D mesher generates quadratic volumes only if all boundary faces
307 # are quadratic, else it fails.
309 # @ingroup l3_hypos_additi
310 def QuadraticMesh(self):
311 hyp = self.Hypothesis("QuadraticMesh", UseExisting=1, CompareMethod=self.CompareEqualHyp)
314 # Public class: Mesh_CompositeSegment
315 # --------------------------
317 ## A regular 1D algorithm for discretization of a set of adjacent edges as one.
318 # It is created by calling Mesh.Segment(COMPOSITE,geom=0)
320 # @ingroup l3_algos_basic
321 class Mesh_CompositeSegment(Mesh_Segment):
323 meshMethod = "Segment"
327 ## Private constructor.
328 def __init__(self, mesh, geom=0):
329 self.Create(mesh, geom, self.algoType)
332 # Public class: Mesh_Segment_Python
333 # ---------------------------------
335 ## Defines a segment 1D algorithm for discretization with python function
336 # It is created by calling Mesh.Segment(PYTHON,geom=0)
338 # @ingroup l3_algos_basic
339 class Mesh_Segment_Python(Mesh_Algorithm):
341 meshMethod = "Segment"
344 ## Private constructor.
345 def __init__(self, mesh, geom=0):
346 import Python1dPlugin
347 self.Create(mesh, geom, self.algoType, "libPython1dEngine.so")
349 ## Defines "PythonSplit1D" hypothesis
350 # @param n for the number of segments that cut an edge
351 # @param func for the python function that calculates the length of all segments
352 # @param UseExisting if ==true - searches for the existing hypothesis created with
353 # the same parameters, else (default) - creates a new one
354 # @ingroup l3_hypos_1dhyps
355 def PythonSplit1D(self, n, func, UseExisting=0):
356 compFun = lambda hyp, args: False
357 hyp = self.Hypothesis("PythonSplit1D", [n], "libPython1dEngine.so",
358 UseExisting=UseExisting, CompareMethod=compFun)
359 hyp.SetNumberOfSegments(n)
360 hyp.SetPythonLog10RatioFunction(func)
363 # Public class: Mesh_Triangle_MEFISTO
364 # -----------------------------------
366 ## Triangle MEFISTO 2D algorithm
367 # It is created by calling Mesh.Triangle(MEFISTO,geom=0)
369 # @ingroup l3_algos_basic
370 class Mesh_Triangle_MEFISTO(Mesh_Algorithm):
372 meshMethod = "Triangle"
376 ## Private constructor.
377 def __init__(self, mesh, geom=0):
378 Mesh_Algorithm.__init__(self)
379 self.Create(mesh, geom, self.algoType)
381 ## Defines "MaxElementArea" hypothesis basing on the definition of the maximum area of each triangle
382 # @param area for the maximum area of each triangle
383 # @param UseExisting if ==true - searches for an existing hypothesis created with the
384 # same parameters, else (default) - creates a new one
386 # @ingroup l3_hypos_2dhyps
387 def MaxElementArea(self, area, UseExisting=0):
388 comparator = lambda hyp, args: IsEqual(hyp.GetMaxElementArea(), args[0])
389 hyp = self.Hypothesis("MaxElementArea", [area], UseExisting=UseExisting,
390 CompareMethod=comparator)
391 hyp.SetMaxElementArea(area)
394 ## Defines "LengthFromEdges" hypothesis to build triangles
395 # based on the length of the edges taken from the wire
397 # @ingroup l3_hypos_2dhyps
398 def LengthFromEdges(self):
399 hyp = self.Hypothesis("LengthFromEdges", UseExisting=1, CompareMethod=self.CompareEqualHyp)
402 # Public class: Mesh_Quadrangle
403 # -----------------------------
405 ## Defines a quadrangle 2D algorithm
406 # It is created by calling Mesh.Quadrangle(geom=0)
408 # @ingroup l3_algos_basic
409 class Mesh_Quadrangle(Mesh_Algorithm):
411 meshMethod = "Quadrangle"
412 algoType = QUADRANGLE
417 ## Private constructor.
418 def __init__(self, mesh, geom=0):
419 Mesh_Algorithm.__init__(self)
420 self.Create(mesh, geom, self.algoType)
423 ## Defines "QuadrangleParameters" hypothesis
424 # @param quadType defines the algorithm of transition between differently descretized
425 # sides of a geometrical face:
426 # - QUAD_STANDARD - both triangles and quadrangles are possible in the transition
427 # area along the finer meshed sides.
428 # - QUAD_TRIANGLE_PREF - only triangles are built in the transition area along the
429 # finer meshed sides.
430 # - QUAD_QUADRANGLE_PREF - only quadrangles are built in the transition area along
431 # the finer meshed sides, iff the total quantity of segments on
432 # all four sides of the face is even (divisible by 2).
433 # - QUAD_QUADRANGLE_PREF_REVERSED - same as QUAD_QUADRANGLE_PREF but the transition
434 # area is located along the coarser meshed sides.
435 # - QUAD_REDUCED - only quadrangles are built and the transition between the sides
436 # is made gradually, layer by layer. This type has a limitation on
437 # the number of segments: one pair of opposite sides must have the
438 # same number of segments, the other pair must have an even difference
439 # between the numbers of segments on the sides.
440 # @param triangleVertex: vertex of a trilateral geometrical face, around which triangles
441 # will be created while other elements will be quadrangles.
442 # Vertex can be either a GEOM_Object or a vertex ID within the
444 # @param UseExisting: if ==true - searches for the existing hypothesis created with
445 # the same parameters, else (default) - creates a new one
446 # @ingroup l3_hypos_quad
447 def QuadrangleParameters(self, quadType=StdMeshers.QUAD_STANDARD, triangleVertex=0, UseExisting=0):
449 vertexID = triangleVertex
450 if isinstance( triangleVertex, GEOM._objref_GEOM_Object ):
451 vertexID = self.mesh.geompyD.GetSubShapeID( self.mesh.geom, triangleVertex )
453 compFun = lambda hyp,args: \
454 hyp.GetQuadType() == args[0] and \
455 ( hyp.GetTriaVertex()==args[1] or ( hyp.GetTriaVertex()<1 and args[1]<1))
456 self.params = self.Hypothesis("QuadrangleParams", [quadType,vertexID],
457 UseExisting = UseExisting, CompareMethod=compFun)
459 if self.params.GetQuadType() != quadType:
460 self.params.SetQuadType(quadType)
462 self.params.SetTriaVertex( vertexID )
465 ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only
466 # quadrangles are built in the transition area along the finer meshed sides,
467 # iff the total quantity of segments on all four sides of the face is even.
468 # @param reversed if True, transition area is located along the coarser meshed sides.
469 # @param UseExisting: if ==true - searches for the existing hypothesis created with
470 # the same parameters, else (default) - creates a new one
471 # @ingroup l3_hypos_quad
472 def QuadranglePreference(self, reversed=False, UseExisting=0):
474 return self.QuadrangleParameters(QUAD_QUADRANGLE_PREF_REVERSED,UseExisting=UseExisting)
475 return self.QuadrangleParameters(QUAD_QUADRANGLE_PREF,UseExisting=UseExisting)
477 ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only
478 # triangles are built in the transition area along the finer meshed sides.
479 # @param UseExisting: if ==true - searches for the existing hypothesis created with
480 # the same parameters, else (default) - creates a new one
481 # @ingroup l3_hypos_quad
482 def TrianglePreference(self, UseExisting=0):
483 return self.QuadrangleParameters(QUAD_TRIANGLE_PREF,UseExisting=UseExisting)
485 ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only
486 # quadrangles are built and the transition between the sides is made gradually,
487 # layer by layer. This type has a limitation on the number of segments: one pair
488 # of opposite sides must have the same number of segments, the other pair must
489 # have an even difference between the numbers of segments on the sides.
490 # @param UseExisting: if ==true - searches for the existing hypothesis created with
491 # the same parameters, else (default) - creates a new one
492 # @ingroup l3_hypos_quad
493 def Reduced(self, UseExisting=0):
494 return self.QuadrangleParameters(QUAD_REDUCED,UseExisting=UseExisting)
496 ## Defines "QuadrangleParams" hypothesis with QUAD_STANDARD type of quadrangulation
497 # @param vertex: vertex of a trilateral geometrical face, around which triangles
498 # will be created while other elements will be quadrangles.
499 # Vertex can be either a GEOM_Object or a vertex ID within the
501 # @param UseExisting: if ==true - searches for the existing hypothesis created with
502 # the same parameters, else (default) - creates a new one
503 # @ingroup l3_hypos_quad
504 def TriangleVertex(self, vertex, UseExisting=0):
505 return self.QuadrangleParameters(QUAD_STANDARD,vertex,UseExisting)
508 # Public class: Mesh_Hexahedron
509 # ------------------------------
511 ## Defines a hexahedron 3D algorithm
512 # It is created by calling Mesh.Hexahedron(geom=0)
514 # @ingroup l3_algos_basic
515 class Mesh_Hexahedron(Mesh_Algorithm):
517 meshMethod = "Hexahedron"
521 ## Private constructor.
522 def __init__(self, mesh, geom=0):
523 Mesh_Algorithm.__init__(self)
524 self.Create(mesh, geom, Hexa)
527 # Public class: Mesh_Projection1D
528 # -------------------------------
530 ## Defines a projection 1D algorithm
531 # It is created by calling Mesh.Projection1D(geom=0)
532 # @ingroup l3_algos_proj
534 class Mesh_Projection1D(Mesh_Algorithm):
536 meshMethod = "Projection1D"
537 algoType = "Projection_1D"
540 ## Private constructor.
541 def __init__(self, mesh, geom=0):
542 Mesh_Algorithm.__init__(self)
543 self.Create(mesh, geom, self.algoType)
545 ## Defines "Source Edge" hypothesis, specifying a meshed edge, from where
546 # a mesh pattern is taken, and, optionally, the association of vertices
547 # between the source edge and a target edge (to which a hypothesis is assigned)
548 # @param edge from which nodes distribution is taken
549 # @param mesh from which nodes distribution is taken (optional)
550 # @param srcV a vertex of \a edge to associate with \a tgtV (optional)
551 # @param tgtV a vertex of \a the edge to which the algorithm is assigned,
552 # to associate with \a srcV (optional)
553 # @param UseExisting if ==true - searches for the existing hypothesis created with
554 # the same parameters, else (default) - creates a new one
555 def SourceEdge(self, edge, mesh=None, srcV=None, tgtV=None, UseExisting=0):
556 AssureGeomPublished( self.mesh, edge )
557 AssureGeomPublished( self.mesh, srcV )
558 AssureGeomPublished( self.mesh, tgtV )
559 hyp = self.Hypothesis("ProjectionSource1D", [edge,mesh,srcV,tgtV],
561 # it does not seem to be useful to reuse the existing "SourceEdge" hypothesis
562 #UseExisting=UseExisting, CompareMethod=self.CompareSourceEdge)
563 hyp.SetSourceEdge( edge )
564 if not mesh is None and isinstance(mesh, Mesh):
565 mesh = mesh.GetMesh()
566 hyp.SetSourceMesh( mesh )
567 hyp.SetVertexAssociation( srcV, tgtV )
571 # Public class: Mesh_Projection2D
572 # ------------------------------
574 ## Defines a projection 2D algorithm
575 # It is created by calling Mesh.Projection2D(geom=0)
576 # @ingroup l3_algos_proj
578 class Mesh_Projection2D(Mesh_Algorithm):
580 meshMethod = "Projection2D"
581 algoType = "Projection_2D"
584 ## Private constructor.
585 def __init__(self, mesh, geom=0):
586 Mesh_Algorithm.__init__(self)
587 self.Create(mesh, geom, self.algoType)
589 ## Defines "Source Face" hypothesis, specifying a meshed face, from where
590 # a mesh pattern is taken, and, optionally, the association of vertices
591 # between the source face and the target face (to which a hypothesis is assigned)
592 # @param face from which the mesh pattern is taken
593 # @param mesh from which the mesh pattern is taken (optional)
594 # @param srcV1 a vertex of \a face to associate with \a tgtV1 (optional)
595 # @param tgtV1 a vertex of \a the face to which the algorithm is assigned,
596 # to associate with \a srcV1 (optional)
597 # @param srcV2 a vertex of \a face to associate with \a tgtV1 (optional)
598 # @param tgtV2 a vertex of \a the face to which the algorithm is assigned,
599 # to associate with \a srcV2 (optional)
600 # @param UseExisting if ==true - forces the search for the existing hypothesis created with
601 # the same parameters, else (default) - forces the creation a new one
603 # Note: all association vertices must belong to one edge of a face
604 def SourceFace(self, face, mesh=None, srcV1=None, tgtV1=None,
605 srcV2=None, tgtV2=None, UseExisting=0):
606 from smeshDC import Mesh
607 if isinstance(mesh, Mesh):
608 mesh = mesh.GetMesh()
609 for geom in [ face, srcV1, tgtV1, srcV2, tgtV2 ]:
610 AssureGeomPublished( self.mesh, geom )
611 hyp = self.Hypothesis("ProjectionSource2D", [face,mesh,srcV1,tgtV1,srcV2,tgtV2],
613 # it does not seem to be useful to reuse the existing "SourceFace" hypothesis
614 #UseExisting=UseExisting, CompareMethod=self.CompareSourceFace)
615 hyp.SetSourceFace( face )
616 hyp.SetSourceMesh( mesh )
617 hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 )
620 # Public class: Mesh_Projection1D2D
621 # ---------------------------------
623 ## Defines a projection 1D-2D algorithm
624 # It is created by calling Mesh.Projection1D2D(geom=0)
626 # @ingroup l3_algos_proj
628 class Mesh_Projection1D2D(Mesh_Projection2D):
630 meshMethod = "Projection1D2D"
631 algoType = "Projection_1D2D"
633 ## Private constructor.
634 def __init__(self, mesh, geom=0):
635 Mesh_Projection2D.__init__(self, mesh, geom)
637 # Public class: Mesh_Projection3D
638 # ------------------------------
640 ## Defines a projection 3D algorithm
641 # It is created by calling Mesh.Projection3D(COMPOSITE)
643 # @ingroup l3_algos_proj
645 class Mesh_Projection3D(Mesh_Algorithm):
647 meshMethod = "Projection3D"
648 algoType = "Projection_3D"
650 ## Private constructor.
651 def __init__(self, mesh, geom=0):
652 Mesh_Algorithm.__init__(self)
653 self.Create(mesh, geom, self.algoType)
655 ## Defines the "Source Shape 3D" hypothesis, specifying a meshed solid, from where
656 # the mesh pattern is taken, and, optionally, the association of vertices
657 # between the source and the target solid (to which a hipothesis is assigned)
658 # @param solid from where the mesh pattern is taken
659 # @param mesh from where the mesh pattern is taken (optional)
660 # @param srcV1 a vertex of \a solid to associate with \a tgtV1 (optional)
661 # @param tgtV1 a vertex of \a the solid where the algorithm is assigned,
662 # to associate with \a srcV1 (optional)
663 # @param srcV2 a vertex of \a solid to associate with \a tgtV1 (optional)
664 # @param tgtV2 a vertex of \a the solid to which the algorithm is assigned,
665 # to associate with \a srcV2 (optional)
666 # @param UseExisting - if ==true - searches for the existing hypothesis created with
667 # the same parameters, else (default) - creates a new one
669 # Note: association vertices must belong to one edge of a solid
670 def SourceShape3D(self, solid, mesh=0, srcV1=0, tgtV1=0,
671 srcV2=0, tgtV2=0, UseExisting=0):
672 for geom in [ solid, srcV1, tgtV1, srcV2, tgtV2 ]:
673 AssureGeomPublished( self.mesh, geom )
674 hyp = self.Hypothesis("ProjectionSource3D",
675 [solid,mesh,srcV1,tgtV1,srcV2,tgtV2],
677 # seems to be not really useful to reuse existing "SourceShape3D" hypothesis
678 #UseExisting=UseExisting, CompareMethod=self.CompareSourceShape3D)
679 hyp.SetSource3DShape( solid )
680 if isinstance(mesh, Mesh):
681 mesh = mesh.GetMesh()
683 hyp.SetSourceMesh( mesh )
684 if srcV1 and srcV2 and tgtV1 and tgtV2:
685 hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 )
686 #elif srcV1 or srcV2 or tgtV1 or tgtV2:
689 # Public class: Mesh_Prism
690 # ------------------------
692 ## Defines a Prism 3D algorithm, which is either "Extrusion 3D" or "Radial Prism"
693 # depending on geometry
694 # It is created by calling Mesh.Prism(geom=0)
696 # @ingroup l3_algos_3dextr
698 class Mesh_Prism3D(Mesh_Algorithm):
701 algoType = "Prism_3D"
703 ## Private constructor.
704 def __init__(self, mesh, geom=0):
705 Mesh_Algorithm.__init__(self)
710 from geompy import SubShapeAll, ShapeType
711 nbSolids = len( SubShapeAll( shape, ShapeType["SOLID"] ))
712 nbShells = len( SubShapeAll( shape, ShapeType["SHELL"] ))
713 if nbSolids == 0 or nbSolids == nbShells:
714 self.Create(mesh, geom, "Prism_3D")
716 self.algoType = "RadialPrism_3D"
717 self.Create(mesh, geom, "RadialPrism_3D")
718 self.distribHyp = self.Hypothesis("LayerDistribution", UseExisting=0)
721 ## Return 3D hypothesis holding the 1D one
722 def Get3DHypothesis(self):
723 if self.algoType != "RadialPrism_3D":
724 print "Prism_3D algorith doesn't support any hyposesis"
726 return self.distribHyp
728 ## Private method creating a 1D hypothesis and storing it in the LayerDistribution
729 # hypothesis. Returns the created hypothesis
730 def OwnHypothesis(self, hypType, args=[], so="libStdMeshersEngine.so"):
731 if self.algoType != "RadialPrism_3D":
732 print "Prism_3D algorith doesn't support any hyposesis"
734 if not self.nbLayers is None:
735 self.mesh.GetMesh().RemoveHypothesis( self.geom, self.nbLayers )
736 self.mesh.GetMesh().AddHypothesis( self.geom, self.distribHyp )
737 study = self.mesh.smeshpyD.GetCurrentStudy() # prevents publishing own 1D hypothesis
738 self.mesh.smeshpyD.SetCurrentStudy( None )
739 hyp = self.mesh.smeshpyD.CreateHypothesis(hypType, so)
740 self.mesh.smeshpyD.SetCurrentStudy( study ) # enables publishing
741 self.distribHyp.SetLayerDistribution( hyp )
744 ## Defines "NumberOfLayers" hypothesis, specifying the number of layers of
745 # prisms to build between the inner and outer shells
746 # @param n number of layers
747 # @param UseExisting if ==true - searches for the existing hypothesis created with
748 # the same parameters, else (default) - creates a new one
749 def NumberOfLayers(self, n, UseExisting=0):
750 if self.algoType != "RadialPrism_3D":
751 print "Prism_3D algorith doesn't support any hyposesis"
753 self.mesh.RemoveHypothesis( self.distribHyp, self.geom )
754 compFun = lambda hyp, args: IsEqual(hyp.GetNumberOfLayers(), args[0])
755 self.nbLayers = self.Hypothesis("NumberOfLayers", [n], UseExisting=UseExisting,
756 CompareMethod=compFun)
757 self.nbLayers.SetNumberOfLayers( n )
760 ## Defines "LocalLength" hypothesis, specifying the segment length
761 # to build between the inner and the outer shells
762 # @param l the length of segments
763 # @param p the precision of rounding
764 def LocalLength(self, l, p=1e-07):
765 if self.algoType != "RadialPrism_3D":
766 print "Prism_3D algorith doesn't support any hyposesis"
768 hyp = self.OwnHypothesis("LocalLength", [l,p])
773 ## Defines "NumberOfSegments" hypothesis, specifying the number of layers of
774 # prisms to build between the inner and the outer shells.
775 # @param n the number of layers
776 # @param s the scale factor (optional)
777 def NumberOfSegments(self, n, s=[]):
778 if self.algoType != "RadialPrism_3D":
779 print "Prism_3D algorith doesn't support any hyposesis"
782 hyp = self.OwnHypothesis("NumberOfSegments", [n])
784 hyp = self.OwnHypothesis("NumberOfSegments", [n,s])
785 hyp.SetDistrType( 1 )
786 hyp.SetScaleFactor(s)
787 hyp.SetNumberOfSegments(n)
790 ## Defines "Arithmetic1D" hypothesis, specifying the distribution of segments
791 # to build between the inner and the outer shells with a length that changes in arithmetic progression
792 # @param start the length of the first segment
793 # @param end the length of the last segment
794 def Arithmetic1D(self, start, end ):
795 if self.algoType != "RadialPrism_3D":
796 print "Prism_3D algorith doesn't support any hyposesis"
798 hyp = self.OwnHypothesis("Arithmetic1D", [start, end])
799 hyp.SetLength(start, 1)
800 hyp.SetLength(end , 0)
803 ## Defines "StartEndLength" hypothesis, specifying distribution of segments
804 # to build between the inner and the outer shells as geometric length increasing
805 # @param start for the length of the first segment
806 # @param end for the length of the last segment
807 def StartEndLength(self, start, end):
808 if self.algoType != "RadialPrism_3D":
809 print "Prism_3D algorith doesn't support any hyposesis"
811 hyp = self.OwnHypothesis("StartEndLength", [start, end])
812 hyp.SetLength(start, 1)
813 hyp.SetLength(end , 0)
816 ## Defines "AutomaticLength" hypothesis, specifying the number of segments
817 # to build between the inner and outer shells
818 # @param fineness defines the quality of the mesh within the range [0-1]
819 def AutomaticLength(self, fineness=0):
820 if self.algoType != "RadialPrism_3D":
821 print "Prism_3D algorith doesn't support any hyposesis"
823 hyp = self.OwnHypothesis("AutomaticLength")
824 hyp.SetFineness( fineness )
828 # Public class: Mesh_RadialQuadrangle1D2D
829 # -------------------------------
831 ## Defines a Radial Quadrangle 1D2D algorithm
832 # It is created by calling Mesh.Quadrangle(RADIAL_QUAD,geom=0)
834 # @ingroup l2_algos_radialq
835 class Mesh_RadialQuadrangle1D2D(Mesh_Algorithm):
837 meshMethod = "Quadrangle"
838 algoType = RADIAL_QUAD
840 ## Private constructor.
841 def __init__(self, mesh, geom=0):
842 Mesh_Algorithm.__init__(self)
843 self.Create(mesh, geom, self.algoType)
845 self.distribHyp = None #self.Hypothesis("LayerDistribution2D", UseExisting=0)
848 ## Return 2D hypothesis holding the 1D one
849 def Get2DHypothesis(self):
850 if not self.distribHyp:
851 self.distribHyp = self.Hypothesis("LayerDistribution2D", UseExisting=0)
852 return self.distribHyp
854 ## Private method creating a 1D hypothesis and storing it in the LayerDistribution
855 # hypothesis. Returns the created hypothesis
856 def OwnHypothesis(self, hypType, args=[], so="libStdMeshersEngine.so"):
858 self.mesh.GetMesh().RemoveHypothesis( self.geom, self.nbLayers )
859 if self.distribHyp is None:
860 self.distribHyp = self.Hypothesis("LayerDistribution2D", UseExisting=0)
862 self.mesh.GetMesh().AddHypothesis( self.geom, self.distribHyp )
863 study = self.mesh.smeshpyD.GetCurrentStudy() # prevents publishing own 1D hypothesis
864 self.mesh.smeshpyD.SetCurrentStudy( None )
865 hyp = self.mesh.smeshpyD.CreateHypothesis(hypType, so)
866 self.mesh.smeshpyD.SetCurrentStudy( study ) # enables publishing
867 self.distribHyp.SetLayerDistribution( hyp )
870 ## Defines "NumberOfLayers" hypothesis, specifying the number of layers
871 # @param n number of layers
872 # @param UseExisting if ==true - searches for the existing hypothesis created with
873 # the same parameters, else (default) - creates a new one
874 def NumberOfLayers(self, n, UseExisting=0):
876 self.mesh.GetMesh().RemoveHypothesis( self.geom, self.distribHyp )
877 compFun = lambda hyp, args: IsEqual(hyp.GetNumberOfLayers(), args[0])
878 self.nbLayers = self.Hypothesis("NumberOfLayers2D", [n], UseExisting=UseExisting,
879 CompareMethod=compFun)
880 self.nbLayers.SetNumberOfLayers( n )
883 ## Defines "LocalLength" hypothesis, specifying the segment length
884 # @param l the length of segments
885 # @param p the precision of rounding
886 def LocalLength(self, l, p=1e-07):
887 hyp = self.OwnHypothesis("LocalLength", [l,p])
892 ## Defines "NumberOfSegments" hypothesis, specifying the number of layers
893 # @param n the number of layers
894 # @param s the scale factor (optional)
895 def NumberOfSegments(self, n, s=[]):
897 hyp = self.OwnHypothesis("NumberOfSegments", [n])
899 hyp = self.OwnHypothesis("NumberOfSegments", [n,s])
900 hyp.SetDistrType( 1 )
901 hyp.SetScaleFactor(s)
902 hyp.SetNumberOfSegments(n)
905 ## Defines "Arithmetic1D" hypothesis, specifying the distribution of segments
906 # with a length that changes in arithmetic progression
907 # @param start the length of the first segment
908 # @param end the length of the last segment
909 def Arithmetic1D(self, start, end ):
910 hyp = self.OwnHypothesis("Arithmetic1D", [start, end])
911 hyp.SetLength(start, 1)
912 hyp.SetLength(end , 0)
915 ## Defines "StartEndLength" hypothesis, specifying distribution of segments
916 # as geometric length increasing
917 # @param start for the length of the first segment
918 # @param end for the length of the last segment
919 def StartEndLength(self, start, end):
920 hyp = self.OwnHypothesis("StartEndLength", [start, end])
921 hyp.SetLength(start, 1)
922 hyp.SetLength(end , 0)
925 ## Defines "AutomaticLength" hypothesis, specifying the number of segments
926 # @param fineness defines the quality of the mesh within the range [0-1]
927 def AutomaticLength(self, fineness=0):
928 hyp = self.OwnHypothesis("AutomaticLength")
929 hyp.SetFineness( fineness )
933 # Public class: Mesh_UseExistingElements
934 # --------------------------------------
935 ## Defines a Radial Quadrangle 1D2D algorithm
936 # It is created by calling Mesh.UseExisting1DElements(geom=0)
938 # @ingroup l3_algos_basic
939 class Mesh_UseExistingElements_1D(Mesh_Algorithm):
941 meshMethod = "UseExisting1DElements"
942 algoType = "Import_1D"
945 def __init__(self, mesh, geom=0):
946 Mesh_Algorithm.__init__(self)
947 self.Create(mesh, geom, self.algoType)
950 ## Defines "Source edges" hypothesis, specifying groups of edges to import
951 # @param groups list of groups of edges
952 # @param toCopyMesh if True, the whole mesh \a groups belong to is imported
953 # @param toCopyGroups if True, all groups of the mesh \a groups belong to are imported
954 # @param UseExisting if ==true - searches for the existing hypothesis created with
955 # the same parameters, else (default) - creates a new one
956 def SourceEdges(self, groups, toCopyMesh=False, toCopyGroups=False, UseExisting=False):
958 AssureGeomPublished( self.mesh, group )
959 compFun = lambda hyp, args: ( hyp.GetSourceEdges() == args[0] and \
960 hyp.GetCopySourceMesh() == args[1], args[2] )
961 hyp = self.Hypothesis("ImportSource1D", [groups, toCopyMesh, toCopyGroups],
962 UseExisting=UseExisting, CompareMethod=compFun)
963 hyp.SetSourceEdges(groups)
964 hyp.SetCopySourceMesh(toCopyMesh, toCopyGroups)
967 # Public class: Mesh_UseExistingElements
968 # --------------------------------------
969 ## Defines a Radial Quadrangle 1D2D algorithm
970 # It is created by calling Mesh.UseExisting2DElements(geom=0)
972 # @ingroup l3_algos_basic
973 class Mesh_UseExistingElements_1D2D(Mesh_Algorithm):
975 meshMethod = "UseExisting2DElements"
976 algoType = "Import_1D2D"
979 def __init__(self, mesh, geom=0):
980 Mesh_Algorithm.__init__(self)
981 self.Create(mesh, geom, self.algoType)
984 ## Defines "Source faces" hypothesis, specifying groups of faces to import
985 # @param groups list of groups of faces
986 # @param toCopyMesh if True, the whole mesh \a groups belong to is imported
987 # @param toCopyGroups if True, all groups of the mesh \a groups belong to are imported
988 # @param UseExisting if ==true - searches for the existing hypothesis created with
989 # the same parameters, else (default) - creates a new one
990 def SourceFaces(self, groups, toCopyMesh=False, toCopyGroups=False, UseExisting=False):
992 AssureGeomPublished( self.mesh, group )
993 compFun = lambda hyp, args: ( hyp.GetSourceFaces() == args[0] and \
994 hyp.GetCopySourceMesh() == args[1], args[2] )
995 hyp = self.Hypothesis("ImportSource2D", [groups, toCopyMesh, toCopyGroups],
996 UseExisting=UseExisting, CompareMethod=compFun)
997 hyp.SetSourceFaces(groups)
998 hyp.SetCopySourceMesh(toCopyMesh, toCopyGroups)
1002 # Public class: Mesh_Cartesian_3D
1003 # --------------------------------------
1004 ## Defines a Body Fitting 3D algorithm
1005 # It is created by calling Mesh.BodyFitted(geom=0)
1007 # @ingroup l3_algos_basic
1008 class Mesh_Cartesian_3D(Mesh_Algorithm):
1010 meshMethod = "BodyFitted"
1011 algoType = "Cartesian_3D"
1014 def __init__(self, mesh, geom=0):
1015 self.Create(mesh, geom, self.algoType)
1019 ## Defines "Body Fitting parameters" hypothesis
1020 # @param xGridDef is definition of the grid along the X asix.
1021 # It can be in either of two following forms:
1022 # - Explicit coordinates of nodes, e.g. [-1.5, 0.0, 3.1] or range( -100,200,10)
1023 # - Functions f(t) defining grid spacing at each point on grid axis. If there are
1024 # several functions, they must be accompanied by relative coordinates of
1025 # points dividing the whole shape into ranges where the functions apply; points
1026 # coodrinates should vary within (0.0, 1.0) range. Parameter \a t of the spacing
1027 # function f(t) varies from 0.0 to 1.0 witin a shape range.
1029 # - "10.5" - defines a grid with a constant spacing
1030 # - [["1", "1+10*t", "11"] [0.1, 0.6]] - defines different spacing in 3 ranges.
1031 # @param yGridDef defines the grid along the Y asix the same way as \a xGridDef does
1032 # @param zGridDef defines the grid along the Z asix the same way as \a xGridDef does
1033 # @param sizeThreshold (> 1.0) defines a minimal size of a polyhedron so that
1034 # a polyhedron of size less than hexSize/sizeThreshold is not created
1035 # @param UseExisting if ==true - searches for the existing hypothesis created with
1036 # the same parameters, else (default) - creates a new one
1037 def SetGrid(self, xGridDef, yGridDef, zGridDef, sizeThreshold=4.0, UseExisting=False):
1039 compFun = lambda hyp, args: False
1040 self.hyp = self.Hypothesis("CartesianParameters3D",
1041 [xGridDef, yGridDef, zGridDef, sizeThreshold],
1042 UseExisting=UseExisting, CompareMethod=compFun)
1043 if not self.mesh.IsUsedHypothesis( self.hyp, self.geom ):
1044 self.mesh.AddHypothesis( self.hyp, self.geom )
1046 for axis, gridDef in enumerate( [xGridDef, yGridDef, zGridDef]):
1047 if not gridDef: raise ValueError, "Empty grid definition"
1048 if isinstance( gridDef, str ):
1049 self.hyp.SetGridSpacing( [gridDef], [], axis )
1050 elif isinstance( gridDef[0], str ):
1051 self.hyp.SetGridSpacing( gridDef, [], axis )
1052 elif isinstance( gridDef[0], int ) or \
1053 isinstance( gridDef[0], float ):
1054 self.hyp.SetGrid(gridDef, axis )
1056 self.hyp.SetGridSpacing( gridDef[0], gridDef[1], axis )
1057 self.hyp.SetSizeThreshold( sizeThreshold )
1060 # Public class: Mesh_UseExisting_1D
1061 # ---------------------------------
1062 ## Defines a stub 1D algorithm, which enables "manual" creation of nodes and
1063 # segments usable by 2D algoritms
1064 # It is created by calling Mesh.UseExistingSegments(geom=0)
1066 # @ingroup l3_algos_basic
1068 class Mesh_UseExisting_1D(Mesh_Algorithm):
1070 meshMethod = "UseExistingSegments"
1071 algoType = "UseExisting_1D"
1073 def __init__(self, mesh, geom=0):
1074 self.Create(mesh, geom, self.algoType)
1077 # Public class: Mesh_UseExisting
1078 # -------------------------------
1079 ## Defines a stub 2D algorithm, which enables "manual" creation of nodes and
1080 # faces usable by 3D algoritms
1081 # It is created by calling Mesh.UseExistingFaces(geom=0)
1083 # @ingroup l3_algos_basic
1085 class Mesh_UseExisting_2D(Mesh_Algorithm):
1087 meshMethod = "UseExistingFaces"
1088 algoType = "UseExisting_2D"
1090 def __init__(self, mesh, geom=0):
1091 self.Create(mesh, geom, self.algoType)