Salome HOME
22244: [CEA] Method to compute the normal to a mesh face
[modules/smesh.git] / src / SMESH_SWIG / StdMeshersBuilder.py
index ee05f82efc585e1e6702342549174a57de2e734d..4e5b2d217cf13a4f5c29ad59304fb1cc18930c79 100644 (file)
 # Python API for the standard meshing plug-in module.
 
 from salome.smesh.smesh_algorithm import Mesh_Algorithm
-from salome.smesh.smeshBuilder import AssureGeomPublished, IsEqual, ParseParameters
-from salome.smesh.smeshBuilder import GetName, TreatHypoStatus
-from salome.smesh.smeshBuilder import Mesh
-
 import StdMeshers
 
 #----------------------------
@@ -100,6 +96,7 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm):
     #  @return an instance of StdMeshers_LocalLength hypothesis
     #  @ingroup l3_hypos_1dhyps
     def LocalLength(self, l, UseExisting=0, p=1e-07):
+        from salome.smesh.smeshBuilder import IsEqual
         comFun=lambda hyp, args: IsEqual(hyp.GetLength(), args[0]) and IsEqual(hyp.GetPrecision(), args[1])
         hyp = self.Hypothesis("LocalLength", [l,p], UseExisting=UseExisting, CompareMethod=comFun)
         hyp.SetLength(l)
@@ -171,6 +168,7 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm):
                     if not args[1] or hyp.GetObjectEntry() == args[2]:
                         return True
             else:
+                from salome.smesh.smeshBuilder import IsEqual
                 if hyp.GetReversedEdges() == args[2]:
                     if not args[2] or hyp.GetObjectEntry() == args[3]:
                         if hyp.GetDistrType() == 1:
@@ -178,7 +176,31 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm):
                                 return True
         return False
 
-    ## Defines "Arithmetic1D" hypothesis to cut an edge in several segments with increasing arithmetic length
+    ## Defines "Adaptive" hypothesis to cut an edge into segments keeping segment size
+    #  within the given range and considering (1) deflection of segments from the edge
+    #  and (2) distance from segments to closest edges and faces to have segment length
+    #  not longer than two times shortest distances to edges and faces.
+    #  @param minSize defines the minimal allowed segment length
+    #  @param maxSize defines the maximal allowed segment length
+    #  @param deflection defines the maximal allowed distance from a segment to an edge
+    #  @param UseExisting if ==true - searches for an existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    #  @return an instance of StdMeshers_Adaptive1D hypothesis
+    #  @ingroup l3_hypos_1dhyps
+    def Adaptive(self, minSize, maxSize, deflection, UseExisting=False):
+        from salome.smesh.smeshBuilder import IsEqual
+        compFun = lambda hyp, args: ( IsEqual(hyp.GetMinSize(), args[0]) and \
+                                      IsEqual(hyp.GetMaxSize(), args[1]) and \
+                                      IsEqual(hyp.GetDeflection(), args[2]))
+        hyp = self.Hypothesis("Adaptive1D", [minSize, maxSize, deflection],
+                              UseExisting=UseExisting, CompareMethod=compFun)
+        hyp.SetMinSize(minSize)
+        hyp.SetMaxSize(maxSize)
+        hyp.SetDeflection(deflection)
+        return hyp
+
+    ## Defines "Arithmetic1D" hypothesis to cut an edge in several segments with a length
+    #  that changes in arithmetic progression
     #  @param start defines the length of the first segment
     #  @param end   defines the length of the last  segment
     #  @param reversedEdges is a list of edges to mesh using reversed orientation.
@@ -192,6 +214,7 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm):
             reversedEdges, UseExisting = [], reversedEdges
         reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
         entry = self.MainShapeEntry()
+        from salome.smesh.smeshBuilder import IsEqual
         compFun = lambda hyp, args: ( IsEqual(hyp.GetLength(1), args[0]) and \
                                       IsEqual(hyp.GetLength(0), args[1]) and \
                                       hyp.GetReversedEdges() == args[2]  and \
@@ -204,6 +227,32 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm):
         hyp.SetObjectEntry( entry )
         return hyp
 
+    ## Defines "GeometricProgression" hypothesis to cut an edge in several
+    #  segments with a length that changes in Geometric progression
+    #  @param start defines the length of the first segment
+    #  @param ratio defines the common ratio of the geometric progression
+    #  @param reversedEdges is a list of edges to mesh using reversed orientation.
+    #                       A list item can also be a tuple (edge, 1st_vertex_of_edge)
+    #  @param UseExisting if ==true - searches for an existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    #  @return an instance of StdMeshers_Geometric1D hypothesis
+    #  @ingroup l3_hypos_1dhyps
+    def GeometricProgression(self, start, ratio, reversedEdges=[], UseExisting=0):
+        reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
+        entry = self.MainShapeEntry()
+        from salome.smesh.smeshBuilder import IsEqual
+        compFun = lambda hyp, args: ( IsEqual(hyp.GetLength(1), args[0]) and \
+                                      IsEqual(hyp.GetLength(0), args[1]) and \
+                                      hyp.GetReversedEdges() == args[2]  and \
+                                      (not args[2] or hyp.GetObjectEntry() == args[3]))
+        hyp = self.Hypothesis("GeometricProgression", [start, ratio, reversedEdgeInd, entry],
+                              UseExisting=UseExisting, CompareMethod=compFun)
+        hyp.SetStartLength( start )
+        hyp.SetCommonRatio( ratio )
+        hyp.SetReversedEdges( reversedEdgeInd )
+        hyp.SetObjectEntry( entry )
+        return hyp
+
     ## Defines "FixedPoints1D" hypothesis to cut an edge using parameter
     # on curve from 0 to 1 (additionally it is neecessary to check
     # orientation of edges and create list of reversed edges if it is
@@ -215,7 +264,7 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm):
     #                       A list item can also be a tuple (edge, 1st_vertex_of_edge)
     #  @param UseExisting if ==true - searches for an existing hypothesis created with
     #                     the same parameters, else (default) - creates a new one
-    #  @return an instance of StdMeshers_Arithmetic1D hypothesis
+    #  @return an instance of StdMeshers_FixedPoints1D hypothesis
     #  @ingroup l3_hypos_1dhyps
     def FixedPoints1D(self, points, nbSegs=[1], reversedEdges=[], UseExisting=0):
         if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
@@ -248,6 +297,7 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm):
             reversedEdges, UseExisting = [], reversedEdges
         reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
         entry = self.MainShapeEntry()
+        from salome.smesh.smeshBuilder import IsEqual
         compFun = lambda hyp, args: ( IsEqual(hyp.GetLength(1), args[0]) and \
                                       IsEqual(hyp.GetLength(0), args[1]) and \
                                       hyp.GetReversedEdges() == args[2]  and \
@@ -266,23 +316,36 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm):
     #                     the same parameters, else (default) - create a new one
     #  @ingroup l3_hypos_1dhyps
     def Deflection1D(self, d, UseExisting=0):
+        from salome.smesh.smeshBuilder import IsEqual
         compFun = lambda hyp, args: IsEqual(hyp.GetDeflection(), args[0])
         hyp = self.Hypothesis("Deflection1D", [d], UseExisting=UseExisting, CompareMethod=compFun)
         hyp.SetDeflection(d)
         return hyp
 
-    ## Defines "Propagation" hypothesis that propagates all other hypotheses on all other edges that are at
-    #  the opposite side in case of quadrangular faces
+    ## Defines "Propagation" hypothesis that propagates 1D hypotheses
+    #  from an edge where this hypothesis is assigned to
+    #  on all other edges that are at the opposite side in case of quadrangular faces
+    #  This hypothesis should be assigned to an edge to propagate a hypothesis from.
     #  @ingroup l3_hypos_additi
     def Propagation(self):
         return self.Hypothesis("Propagation", UseExisting=1, CompareMethod=self.CompareEqualHyp)
 
+    ## Defines "Propagation of Node Distribution" hypothesis that propagates
+    #  distribution of nodes from an edge where this hypothesis is assigned to,
+    #  to opposite edges of quadrangular faces, so that number of segments on all these
+    #  edges will be the same, as well as relations between segment lengths. 
+    #  @ingroup l3_hypos_additi
+    def PropagationOfDistribution(self):
+        return self.Hypothesis("PropagOfDistribution", UseExisting=1,
+                               CompareMethod=self.CompareEqualHyp)
+
     ## Defines "AutomaticLength" hypothesis
     #  @param fineness for the fineness [0-1]
     #  @param UseExisting if ==true - searches for an existing hypothesis created with the
     #                     same parameters, else (default) - create a new one
     #  @ingroup l3_hypos_1dhyps
     def AutomaticLength(self, fineness=0, UseExisting=0):
+        from salome.smesh.smeshBuilder import IsEqual
         compFun = lambda hyp, args: IsEqual(hyp.GetFineness(), args[0])
         hyp = self.Hypothesis("AutomaticLength",[fineness],UseExisting=UseExisting,
                               CompareMethod=compFun)
@@ -313,6 +376,7 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm):
         # 0D algorithm
         if self.geom is None:
             raise RuntimeError, "Attemp to create SegmentAroundVertex_0D algoritm on None shape"
+        from salome.smesh.smeshBuilder import AssureGeomPublished, GetName, TreatHypoStatus
         AssureGeomPublished( self.mesh, self.geom )
         name = GetName(self.geom)
 
@@ -323,6 +387,7 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm):
         status = self.mesh.mesh.AddHypothesis(self.geom, algo)
         TreatHypoStatus(status, "SegmentAroundVertex_0D", name, True)
         #
+        from salome.smesh.smeshBuilder import IsEqual
         comFun = lambda hyp, args: IsEqual(hyp.GetLength(), args[0])
         hyp = self.Hypothesis("SegmentLengthAroundVertex", [length], UseExisting=UseExisting,
                               CompareMethod=comFun)
@@ -457,6 +522,7 @@ class StdMeshersBuilder_Triangle_MEFISTO(Mesh_Algorithm):
     #
     #  @ingroup l3_hypos_2dhyps
     def MaxElementArea(self, area, UseExisting=0):
+        from salome.smesh.smeshBuilder import IsEqual
         comparator = lambda hyp, args: IsEqual(hyp.GetMaxElementArea(), args[0])
         hyp = self.Hypothesis("MaxElementArea", [area], UseExisting=UseExisting,
                               CompareMethod=comparator)
@@ -524,28 +590,56 @@ class StdMeshersBuilder_Quadrangle(Mesh_Algorithm):
     #                    same number of segments, the other pair must have an even difference
     #                    between the numbers of segments on the sides.
     #  @param triangleVertex: vertex of a trilateral geometrical face, around which triangles
-    #                  will be created while other elements will be quadrangles.
-    #                  Vertex can be either a GEOM_Object or a vertex ID within the
-    #                  shape to mesh
-    #  @param UseExisting: if ==true - searches for the existing hypothesis created with
-    #                  the same parameters, else (default) - creates a new one
+    #                    will be created while other elements will be quadrangles.
+    #                    Vertex can be either a GEOM_Object or a vertex ID within the
+    #                    shape to mesh
+    #  @param enfVertices: list of shapes defining positions where nodes (enforced nodes)
+    #                    must be created by the mesher. Shapes can be of any type,
+    #                    vertices of given shapes define positions of enforced nodes.
+    #                    Only vertices successfully projected to the face are used.
+    #  @param enfPoint: list of points giving positions of enforced nodes.
+    #                    Point can be defined either as SMESH.PointStruct's
+    #                    ([SMESH.PointStruct(x1,y1,z1), SMESH.PointStruct(x2,y2,z2),...])
+    #                    or triples of values ([[x1,y1,z1], [x2,y2,z2], ...]).
+    #                    In the case if the defined QuadrangleParameters() refer to a sole face,
+    #                    all given points must lie on this face, else the mesher fails.
+    #  @param UseExisting: if \c True - searches for the existing hypothesis created with
+    #                    the same parameters, else (default) - creates a new one
     #  @ingroup l3_hypos_quad
-    def QuadrangleParameters(self, quadType=StdMeshers.QUAD_STANDARD, triangleVertex=0, UseExisting=0):
-        import GEOM
+    def QuadrangleParameters(self, quadType=StdMeshers.QUAD_STANDARD, triangleVertex=0,
+                             enfVertices=[],enfPoints=[],UseExisting=0):
+        import GEOM, SMESH
         vertexID = triangleVertex
         if isinstance( triangleVertex, GEOM._objref_GEOM_Object ):
             vertexID = self.mesh.geompyD.GetSubShapeID( self.mesh.geom, triangleVertex )
+        if isinstance( enfVertices, int ) and not enfPoints and not UseExisting:
+            # a call of old syntax, before inserting enfVertices and enfPoints before UseExisting
+            UseExisting, enfVertices = enfVertices, []
+        pStructs, xyz = [], []
+        for p in enfPoints:
+            if isinstance( p, SMESH.PointStruct ):
+                xyz.append(( p.x, p.y, p.z ))
+                pStructs.append( p )
+            else:
+                xyz.append(( p[0], p[1], p[2] ))
+                pStructs.append( SMESH.PointStruct( p[0], p[1], p[2] ))
         if not self.params:
             compFun = lambda hyp,args: \
                       hyp.GetQuadType() == args[0] and \
-                      ( hyp.GetTriaVertex()==args[1] or ( hyp.GetTriaVertex()<1 and args[1]<1))
-            self.params = self.Hypothesis("QuadrangleParams", [quadType,vertexID],
+                      (hyp.GetTriaVertex()==args[1] or ( hyp.GetTriaVertex()<1 and args[1]<1)) and \
+                      ((hyp.GetEnforcedNodes()) == (args[2],args[3])) # True w/o enfVertices only
+            entries = [ shape.GetStudyEntry() for shape in enfVertices ]
+            self.params = self.Hypothesis("QuadrangleParams", [quadType,vertexID,entries,xyz],
                                           UseExisting = UseExisting, CompareMethod=compFun)
             pass
         if self.params.GetQuadType() != quadType:
             self.params.SetQuadType(quadType)
         if vertexID > 0:
             self.params.SetTriaVertex( vertexID )
+        from salome.smesh.smeshBuilder import AssureGeomPublished
+        for v in enfVertices:
+            AssureGeomPublished( self.mesh, v )
+        self.params.SetEnforcedNodes( enfVertices, pStructs )
         return self.params
 
     ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only
@@ -665,6 +759,7 @@ class StdMeshersBuilder_Projection1D(Mesh_Algorithm):
     #  @param UseExisting if ==true - searches for the existing hypothesis created with
     #                     the same parameters, else (default) - creates a new one
     def SourceEdge(self, edge, mesh=None, srcV=None, tgtV=None, UseExisting=0):
+        from salome.smesh.smeshBuilder import AssureGeomPublished, Mesh
         AssureGeomPublished( self.mesh, edge )
         AssureGeomPublished( self.mesh, srcV )
         AssureGeomPublished( self.mesh, tgtV )
@@ -732,6 +827,7 @@ class StdMeshersBuilder_Projection2D(Mesh_Algorithm):
         if isinstance(mesh, Mesh):
             mesh = mesh.GetMesh()
         for geom in [ face, srcV1, tgtV1, srcV2, tgtV2 ]:
+            from salome.smesh.smeshBuilder import AssureGeomPublished
             AssureGeomPublished( self.mesh, geom )
         hyp = self.Hypothesis("ProjectionSource2D", [face,mesh,srcV1,tgtV1,srcV2,tgtV2],
                               UseExisting=0)
@@ -815,6 +911,7 @@ class StdMeshersBuilder_Projection3D(Mesh_Algorithm):
     def SourceShape3D(self, solid, mesh=0, srcV1=0, tgtV1=0,
                       srcV2=0, tgtV2=0, UseExisting=0):
         for geom in [ solid, srcV1, tgtV1, srcV2, tgtV2 ]:
+            from salome.smesh.smeshBuilder import AssureGeomPublished
             AssureGeomPublished( self.mesh, geom )
         hyp = self.Hypothesis("ProjectionSource3D",
                               [solid,mesh,srcV1,tgtV1,srcV2,tgtV2],
@@ -822,6 +919,7 @@ class StdMeshersBuilder_Projection3D(Mesh_Algorithm):
         # seems to be not really useful to reuse existing "SourceShape3D" hypothesis
                               #UseExisting=UseExisting, CompareMethod=self.CompareSourceShape3D)
         hyp.SetSource3DShape( solid )
+        from salome.smesh.smeshBuilder import Mesh
         if isinstance(mesh, Mesh):
             mesh = mesh.GetMesh()
         if mesh:
@@ -910,6 +1008,7 @@ class StdMeshersBuilder_Prism3D(Mesh_Algorithm):
             print "Prism_3D algorith doesn't support any hyposesis"
             return None
         self.mesh.RemoveHypothesis( self.distribHyp, self.geom )
+        from salome.smesh.smeshBuilder import IsEqual
         compFun = lambda hyp, args: IsEqual(hyp.GetNumberOfLayers(), args[0])
         self.nbLayers = self.Hypothesis("NumberOfLayers", [n], UseExisting=UseExisting,
                                         CompareMethod=compFun)
@@ -947,7 +1046,8 @@ class StdMeshersBuilder_Prism3D(Mesh_Algorithm):
         return hyp
 
     ## Defines "Arithmetic1D" hypothesis, specifying the distribution of segments
-    #  to build between the inner and the outer shells with a length that changes in arithmetic progression
+    #  to build between the inner and the outer shells with a length that changes
+    #  in arithmetic progression
     #  @param start  the length of the first segment
     #  @param end    the length of the last  segment
     def Arithmetic1D(self, start, end ):
@@ -959,6 +1059,20 @@ class StdMeshersBuilder_Prism3D(Mesh_Algorithm):
         hyp.SetLength(end  , 0)
         return hyp
 
+    ## Defines "GeometricProgression" hypothesis, specifying the distribution of segments
+    #  to build between the inner and the outer shells with a length that changes
+    #  in Geometric progression
+    #  @param start  the length of the first segment
+    #  @param ratio  the common ratio of the geometric progression
+    def GeometricProgression(self, start, ratio ):
+        if self.algoType != "RadialPrism_3D":
+            print "Prism_3D algorith doesn't support any hyposesis"
+            return None
+        hyp = self.OwnHypothesis("GeometricProgression", [start, ratio])
+        hyp.SetStartLength( start )
+        hyp.SetCommonRatio( ratio )
+        return hyp
+
     ## Defines "StartEndLength" hypothesis, specifying distribution of segments
     #  to build between the inner and the outer shells as geometric length increasing
     #  @param start for the length of the first segment
@@ -1076,6 +1190,7 @@ class StdMeshersBuilder_RadialQuadrangle1D2D(Mesh_Algorithm):
     def NumberOfLayers(self, n, UseExisting=0):
         if self.distribHyp:
             self.mesh.GetMesh().RemoveHypothesis( self.geom, self.distribHyp )
+        from salome.smesh.smeshBuilder import IsEqual
         compFun = lambda hyp, args: IsEqual(hyp.GetNumberOfLayers(), args[0])
         self.nbLayers = self.Hypothesis("NumberOfLayers2D", [n], UseExisting=UseExisting,
                                         CompareMethod=compFun)
@@ -1114,6 +1229,16 @@ class StdMeshersBuilder_RadialQuadrangle1D2D(Mesh_Algorithm):
         hyp.SetLength(end  , 0)
         return hyp
 
+    ## Defines "GeometricProgression" hypothesis, specifying the distribution of segments
+    #  with a length that changes in Geometric progression
+    #  @param start  the length of the first segment
+    #  @param ratio  the common ratio of the geometric progression
+    def GeometricProgression(self, start, ratio ):
+        hyp = self.OwnHypothesis("GeometricProgression", [start, ratio])
+        hyp.SetStartLength( start )
+        hyp.SetCommonRatio( ratio )
+        return hyp
+
     ## Defines "StartEndLength" hypothesis, specifying distribution of segments
     #  as geometric length increasing
     #  @param start for the length of the first segment
@@ -1171,6 +1296,7 @@ class StdMeshersBuilder_UseExistingElements_1D(Mesh_Algorithm):
     #                     the same parameters, else (default) - creates a new one
     def SourceEdges(self, groups, toCopyMesh=False, toCopyGroups=False, UseExisting=False):
         for group in groups:
+            from salome.smesh.smeshBuilder import AssureGeomPublished
             AssureGeomPublished( self.mesh, group )
         compFun = lambda hyp, args: ( hyp.GetSourceEdges() == args[0] and \
                                       hyp.GetCopySourceMesh() == args[1], args[2] )
@@ -1220,6 +1346,7 @@ class StdMeshersBuilder_UseExistingElements_1D2D(Mesh_Algorithm):
     #                     the same parameters, else (default) - creates a new one
     def SourceFaces(self, groups, toCopyMesh=False, toCopyGroups=False, UseExisting=False):
         for group in groups:
+            from salome.smesh.smeshBuilder import AssureGeomPublished
             AssureGeomPublished( self.mesh, group )
         compFun = lambda hyp, args: ( hyp.GetSourceFaces() == args[0] and \
                                       hyp.GetCopySourceMesh() == args[1], args[2] )