X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH_SWIG%2FsmeshBuilder.py;h=8fd7b6166febc11fef4e5f938ad5ca0b99b54e6d;hb=b8ddb1330cad42ad5381912dd267d1e39182daae;hp=20b7bc0389f1193f49de9895aaa7a0911ddc6c8c;hpb=64680c27c16f878decc136ec6c38dc9a72f12f3b;p=modules%2Fsmesh.git diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py old mode 100755 new mode 100644 index 20b7bc038..8fd7b6166 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -318,27 +318,13 @@ def AssureGeomPublished(mesh, geom, name=''): mesh.geompyD.addToStudyInFather( mesh.geom, geom, name ) return -def FirstVertexOnCurve(mesh, edge): - """ - Returns: - the first vertex of a geometrical edge by ignoring orientation - """ - vv = mesh.geompyD.SubShapeAll( edge, geomBuilder.geomBuilder.ShapeType["VERTEX"]) - if not vv: - raise TypeError("Given object has no vertices") - if len( vv ) == 1: return vv[0] - v0 = mesh.geompyD.MakeVertexOnCurve(edge,0.) - xyz = mesh.geompyD.PointCoordinates( v0 ) # coords of the first vertex - xyz1 = mesh.geompyD.PointCoordinates( vv[0] ) - xyz2 = mesh.geompyD.PointCoordinates( vv[1] ) - dist1, dist2 = 0,0 - for i in range(3): - dist1 += abs( xyz[i] - xyz1[i] ) - dist2 += abs( xyz[i] - xyz2[i] ) - if dist1 < dist2: - return vv[0] - else: - return vv[1] +# def FirstVertexOnCurve(mesh, edge): +# """ +# Returns: +# the first vertex of a geometrical edge by ignoring orientation +# """ +# return mesh.geompyD.GetVertexByIndex( edge, 0, False ) + smeshInst = None """ @@ -475,6 +461,24 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): obj,name = name,obj return Mesh(self, self.geompyD, obj, name) + def RemoveMesh( self, mesh ): + """ + Delete a mesh + """ + if isinstance( mesh, Mesh ): + mesh = mesh.GetMesh() + pass + if not isinstance( mesh, SMESH._objref_SMESH_Mesh ): + raise TypeError("%s is not a mesh" % mesh ) + so = salome.ObjectToSObject( mesh ) + if so: + sb = salome.myStudy.NewBuilder() + sb.RemoveObjectWithChildren( so ) + else: + mesh.UnRegister() + pass + return + def EnumToLong(self,theItem): """ Return a long value from enumeration @@ -513,8 +517,8 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): Returns: :class:`SMESH.PointStruct` """ - - [x, y, z] = self.geompyD.PointCoordinates(theVertex) + geompyD = theVertex.GetGen() + [x, y, z] = geompyD.PointCoordinates(theVertex) return PointStruct(x,y,z) def GetDirStruct(self,theVector): @@ -527,13 +531,13 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): Returns: :class:`SMESH.DirStruct` """ - - vertices = self.geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] ) + geompyD = theVector.GetGen() + vertices = geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] ) if(len(vertices) != 2): print("Error: vector object is incorrect.") return None - p1 = self.geompyD.PointCoordinates(vertices[0]) - p2 = self.geompyD.PointCoordinates(vertices[1]) + p1 = geompyD.PointCoordinates(vertices[0]) + p2 = geompyD.PointCoordinates(vertices[1]) pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2]) dirst = DirStruct(pnt) return dirst @@ -563,28 +567,29 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): :class:`SMESH.AxisStruct` """ import GEOM - edges = self.geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] ) + geompyD = theObj.GetGen() + edges = geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] ) axis = None if len(edges) > 1: - vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] ) - vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] ) - vertex1 = self.geompyD.PointCoordinates(vertex1) - vertex2 = self.geompyD.PointCoordinates(vertex2) - vertex3 = self.geompyD.PointCoordinates(vertex3) - vertex4 = self.geompyD.PointCoordinates(vertex4) + vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] ) + vertex3, vertex4 = geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] ) + vertex1 = geompyD.PointCoordinates(vertex1) + vertex2 = geompyD.PointCoordinates(vertex2) + vertex3 = geompyD.PointCoordinates(vertex3) + vertex4 = geompyD.PointCoordinates(vertex4) v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]] v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]] normal = [ v1[1]*v2[2]-v2[1]*v1[2], v1[2]*v2[0]-v2[2]*v1[0], v1[0]*v2[1]-v2[0]*v1[1] ] axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2]) axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE elif len(edges) == 1: - vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] ) - p1 = self.geompyD.PointCoordinates( vertex1 ) - p2 = self.geompyD.PointCoordinates( vertex2 ) + vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] ) + p1 = geompyD.PointCoordinates( vertex1 ) + p2 = geompyD.PointCoordinates( vertex2 ) axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2]) axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS elif theObj.GetShapeType() == GEOM.VERTEX: - x,y,z = self.geompyD.PointCoordinates( theObj ) + x,y,z = geompyD.PointCoordinates( theObj ) axis = AxisStruct( x,y,z, 1,0,0,) axis._mirrorType = SMESH.SMESH_MeshEditor.POINT return axis @@ -745,33 +750,38 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): mergeTolerance: tolerance for merging nodes allGroups: forces creation of groups corresponding to every input mesh name: name of a new mesh - meshToAppendTo a mesh to append all given meshes + meshToAppendTo: a mesh to append all given meshes Returns: an instance of class :class:`Mesh` + + See also: + :meth:`Mesh.Append` """ if not meshes: return None - for i,m in enumerate(meshes): - if isinstance(m, Mesh): + if not isinstance( meshes, list ): + meshes = [ meshes ] + for i,m in enumerate( meshes ): + if isinstance( m, Mesh ): meshes[i] = m.GetMesh() - mergeTolerance,Parameters,hasVars = ParseParameters(mergeTolerance) + mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance ) if hasattr(meshes[0], "SetParameters"): - meshes[0].SetParameters(Parameters) + meshes[0].SetParameters( Parameters ) else: - meshes[0].GetMesh().SetParameters(Parameters) + meshes[0].GetMesh().SetParameters( Parameters ) if isinstance( meshToAppendTo, Mesh ): meshToAppendTo = meshToAppendTo.GetMesh() if allGroups: aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups( self,meshes,uniteIdenticalGroups,mergeNodesAndElements, - mergeTolerance,meshToAppendTo) + mergeTolerance,meshToAppendTo ) else: aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate( self,meshes,uniteIdenticalGroups,mergeNodesAndElements, - mergeTolerance,meshToAppendTo) + mergeTolerance,meshToAppendTo ) - aMesh = Mesh(self, self.geompyD, aSmeshMesh, name=name) + aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name ) return aMesh def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False): @@ -807,7 +817,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): Parameters: sourceMesh: the mesh to copy definition of. - newGeom: the new geomtry. + newGeom: the new geometry. meshName: an optional name of the new mesh. If omitted, the mesh name is kept. toCopyGroups: to create groups in the new mesh. toReuseHypotheses: to reuse hypotheses of the *sourceMesh*. @@ -818,7 +828,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): *invalidEntries* are study entries of objects whose counterparts are not found in the *newGeom*, followed by entries of mesh sub-objects that are invalid because they depend on a not found - preceeding sub-shape + preceding sub-shape """ if isinstance( sourceMesh, Mesh ): sourceMesh = sourceMesh.GetMesh() @@ -949,7 +959,8 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): name = aCriterion.ThresholdStr if not name: name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000) - aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name ) + geompyD = aThreshold.GetGen() + aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name ) # or a name of GEOM object elif isinstance( aThreshold, str ): aCriterion.ThresholdStr = aThreshold @@ -1000,7 +1011,8 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): name = aThreshold.GetName() if not name: name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000) - aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name ) + geompyD = aThreshold.GetGen() + aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name ) elif isinstance(aThreshold, int): # node id aCriterion.Threshold = aThreshold elif isinstance(aThreshold, list): # 3 point coordinates @@ -1188,6 +1200,8 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): functor = aFilterMgr.CreateLength() elif theCriterion == FT_Length2D: functor = aFilterMgr.CreateLength2D() + elif theCriterion == FT_Length3D: + functor = aFilterMgr.CreateLength3D() elif theCriterion == FT_Deflection2D: functor = aFilterMgr.CreateDeflection2D() elif theCriterion == FT_NodeConnectivityNumber: @@ -1228,8 +1242,6 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): def GetMeshInfo(self, obj): """ Get the mesh statistic. - Use :meth:`smeshBuilder.EnumToLong` to get an integer from - an item of :class:`SMESH.EntityType`. Returns: dictionary { :class:`SMESH.EntityType` - "count of elements" } @@ -1610,14 +1622,15 @@ class Mesh(metaclass = MeshMeta): Parameters: theMesh: a :class:`SMESH.SMESH_Mesh` object """ - - # do not call Register() as this prevents mesh servant deletion at closing study #if self.mesh: self.mesh.UnRegister() self.mesh = theMesh if self.mesh: #self.mesh.Register() self.geom = self.mesh.GetShapeToMesh() + if self.geom: + self.geompyD = self.geom.GetGen() + pass pass def GetMesh(self): @@ -2049,7 +2062,14 @@ class Mesh(metaclass = MeshMeta): def SetMeshOrder(self, submeshes): """ - Set order in which concurrent sub-meshes should be meshed + Set priority of sub-meshes. It works in two ways: + + * For sub-meshes with assigned algorithms of same dimension generating mesh of + *several dimensions*, it sets the order in which the sub-meshes are computed. + * For the rest sub-meshes, it sets the order in which the sub-meshes are checked + when looking for meshing parameters to apply to a sub-shape. To impose the + order in which sub-meshes with uni-dimensional algorithms are computed, + call **submesh.Compute()** in a desired order. Parameters: submeshes: list of lists of :class:`sub-meshes ` @@ -2501,6 +2521,25 @@ class Mesh(metaclass = MeshMeta): minor = -1 # invoke engine's function self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension) + return + + + def Append(self, meshes, uniteIdenticalGroups = True, + mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False): + """ + Append given meshes into this mesh. + All groups of input meshes will be created in this mesh. + + Parameters: + meshes: :class:`meshes, sub-meshes, groups or filters ` to append + uniteIdenticalGroups: if True, groups with same names are united, else they are renamed + mergeNodesAndElements: if True, equal nodes and elements are merged + mergeTolerance: tolerance for merging nodes + allGroups: forces creation of groups corresponding to every input mesh + """ + self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups, + mergeNodesAndElements, mergeTolerance, allGroups, + meshToAppendTo = self.GetMesh() ) # Operations with groups: # ---------------------- @@ -2731,6 +2770,10 @@ class Mesh(metaclass = MeshMeta): Parameters: group (SMESH.SMESH_GroupBase): group to remove + + Note: + This operation can create gaps in numeration of nodes or elements. + Call :meth:`RenumberElements` to remove the gaps. """ self.mesh.RemoveGroupWithContents(group) @@ -3065,8 +3108,6 @@ class Mesh(metaclass = MeshMeta): def GetMeshInfo(self, obj = None): """ Get the mesh statistic. - Use :meth:`smeshBuilder.EnumToLong` to get an integer from - an item of :class:`SMESH.EntityType`. Returns: dictionary { :class:`SMESH.EntityType` - "count of elements" } @@ -3931,6 +3972,10 @@ class Mesh(metaclass = MeshMeta): Returns: True or False + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ return self.editor.RemoveElements(IDsOfElements) @@ -3944,6 +3989,10 @@ class Mesh(metaclass = MeshMeta): Returns: True or False + + Note: + This operation can create gaps in numeration of nodes. + Call :meth:`RenumberElements` to remove the gaps. """ return self.editor.RemoveNodes(IDsOfNodes) @@ -3954,6 +4003,10 @@ class Mesh(metaclass = MeshMeta): Returns: number of the removed nodes + + Note: + This operation can create gaps in numeration of nodes. + Call :meth:`RenumberElements` to remove the gaps. """ return self.editor.RemoveOrphanNodes() @@ -4362,7 +4415,8 @@ class Mesh(metaclass = MeshMeta): Returns: A list of edge groups and a list of corresponding node groups, - where the group is a list of IDs of edges or elements. + where the group is a list of IDs of edges or elements, like follows + [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]]. If a group is closed, the first and last nodes of the group are same. """ if isinstance( edges, Mesh ): @@ -4428,6 +4482,10 @@ class Mesh(metaclass = MeshMeta): Returns: False if proper faces were not found + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ return self.editor.DeleteDiag(NodeID1, NodeID2) @@ -4467,8 +4525,8 @@ class Mesh(metaclass = MeshMeta): Reorient faces contained in *the2DObject*. Parameters: - the2DObject: is a :class:`mesh, sub-mesh, group or filter ` or list of IDs of 2D elements - theDirection: is a desired direction of normal of *theFace*. + the2DObject: a :class:`mesh, sub-mesh, group or filter ` or list of IDs of 2D elements + theDirection: a desired direction of normal of *theFace*. It can be either a GEOM vector or a list of coordinates [x,y,z]. theFaceOrPoint: defines a face of *the2DObject* whose normal will be compared with theDirection. It can be either ID of face or a point @@ -4558,6 +4616,10 @@ class Mesh(metaclass = MeshMeta): Returns: True in case of success, False otherwise. + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle) @@ -4582,6 +4644,10 @@ class Mesh(metaclass = MeshMeta): Returns: True in case of success, False otherwise. + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle) @@ -4605,6 +4671,10 @@ class Mesh(metaclass = MeshMeta): Returns: True in case of success, False otherwise. + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ if IDsOfElements == []: IDsOfElements = self.GetElementsId() @@ -4628,6 +4698,10 @@ class Mesh(metaclass = MeshMeta): Returns: True in case of success, False otherwise. + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ if ( isinstance( theObject, Mesh )): theObject = theObject.GetMesh() @@ -4645,6 +4719,10 @@ class Mesh(metaclass = MeshMeta): theElements: the faces to be splitted. This can be either :class:`mesh, sub-mesh, group, filter ` or a list of face IDs. By default all quadrangles are split + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ unRegister = genObjUnRegister() if isinstance( theElements, Mesh ): @@ -4666,6 +4744,10 @@ class Mesh(metaclass = MeshMeta): Returns: True in case of success, False otherwise. + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ if IDsOfElements == []: IDsOfElements = self.GetElementsId() @@ -4682,6 +4764,10 @@ class Mesh(metaclass = MeshMeta): Returns: True in case of success, False otherwise. + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ if ( isinstance( theObject, Mesh )): theObject = theObject.GetMesh() @@ -4702,6 +4788,10 @@ class Mesh(metaclass = MeshMeta): * 1 if 1-3 diagonal is better, * 2 if 2-4 diagonal is better, * 0 if error occurs. + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion)) @@ -4714,6 +4804,10 @@ class Mesh(metaclass = MeshMeta): method: flags passing splitting method: smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet. smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc. + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ unRegister = genObjUnRegister() if isinstance( elems, Mesh ): @@ -4738,6 +4832,10 @@ class Mesh(metaclass = MeshMeta): Parameters: elems: elements to split\: :class:`mesh, sub-mesh, group, filter ` or element IDs; if None (default), all bi-quadratic elements will be split + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ unRegister = genObjUnRegister() if elems and isinstance( elems, list ) and isinstance( elems[0], int ): @@ -4769,6 +4867,10 @@ class Mesh(metaclass = MeshMeta): allDomains: if :code:`False`, only hexahedra adjacent to one closest to *startHexPoint* are split, else *startHexPoint* is used to find the facet to split in all domains present in *elems*. + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ # IDSource unRegister = genObjUnRegister() @@ -4798,6 +4900,10 @@ class Mesh(metaclass = MeshMeta): def SplitQuadsNearTriangularFacets(self): """ Split quadrangle faces near triangular facets of volumes + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ faces_array = self.GetElementsByType(SMESH.FACE) for face_id in faces_array: @@ -4842,6 +4948,10 @@ class Mesh(metaclass = MeshMeta): Returns: True in case of success, False otherwise. + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ # Pattern: # 5.---------.6 @@ -4906,6 +5016,10 @@ class Mesh(metaclass = MeshMeta): Returns: True in case of success, False otherwise. + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ # Pattern: 5.---------.6 # /|# /| @@ -5063,6 +5177,10 @@ class Mesh(metaclass = MeshMeta): Warning: If *theSubMesh* is provided, the mesh can become non-conformal + + Note: + This operation can create gaps in numeration of nodes or elements. + Call :meth:`RenumberElements` to remove the gaps. """ if isinstance( theSubMesh, Mesh ): @@ -5090,6 +5208,10 @@ class Mesh(metaclass = MeshMeta): Warning: If *theSubMesh* is provided, the mesh can become non-conformal + + Note: + This operation can create gaps in numeration of nodes or elements. + Call :meth:`RenumberElements` to remove the gaps. """ if theSubMesh: @@ -5340,7 +5462,8 @@ class Mesh(metaclass = MeshMeta): NbOfSteps, Tolerance, MakeGroups, TotalAngle) def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False, - scaleFactors=[], linearVariation=False, basePoint=[] ): + scaleFactors=[], linearVariation=False, basePoint=[], + angles=[], anglesVariation=False): """ Generate new elements by extrusion of the given elements and nodes @@ -5354,15 +5477,19 @@ class Mesh(metaclass = MeshMeta): NbOfSteps: the number of steps MakeGroups: forces the generation of new groups from existing ones scaleFactors: optional scale factors to apply during extrusion - linearVariation: if *True*, scaleFactors are spread over all *scaleFactors*, - else scaleFactors[i] is applied to nodes at the i-th extrusion step - basePoint: optional scaling center; if not provided, a gravity center of + linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*, + else *scaleFactors* [i] is applied to nodes at the i-th extrusion step + basePoint: optional scaling and rotation center; if not provided, a gravity center of nodes and elements being extruded is used as the scaling center. It can be either - a list of tree components of the point or - a node ID or - a GEOM point + angles: list of angles in radians. Nodes at each extrusion step are rotated + around *basePoint*, additionally to previous steps. + anglesVariation: forces the computation of rotation angles as linear + variation of the given *angles* along path steps Returns: the list of created :class:`groups ` if *MakeGroups* == True, empty list otherwise @@ -5387,13 +5514,17 @@ class Mesh(metaclass = MeshMeta): basePoint = self.geompyD.PointCoordinates( basePoint ) NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps) - Parameters = StepVector.PS.parameters + var_separator + Parameters + scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors) + angles,angleParameters,hasVars = ParseAngles(angles) + Parameters = StepVector.PS.parameters + var_separator + \ + Parameters + var_separator + \ + scaleParameters + var_separator + angleParameters self.mesh.SetParameters(Parameters) return self.editor.ExtrusionSweepObjects( nodes, edges, faces, - StepVector, NbOfSteps, + StepVector, NbOfSteps, MakeGroups, scaleFactors, linearVariation, basePoint, - MakeGroups) + angles, anglesVariation ) def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False): @@ -5454,6 +5585,8 @@ class Mesh(metaclass = MeshMeta): if isinstance( Elements, list ): if not Elements: raise RuntimeError("Elements empty!") + if isinstance( Elements[0], Mesh ): + Elements = [ Elements[0].GetMesh() ] if isinstance( Elements[0], int ): Elements = self.GetIDSource( Elements, SMESH.ALL ) unRegister.set( Elements ) @@ -5555,9 +5688,10 @@ class Mesh(metaclass = MeshMeta): return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps, ExtrFlags, SewTolerance, MakeGroups) - def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None, + def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None, NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False, - HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False): + HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False, + ScaleFactors=[], ScalesVariation=False): """ Generate new elements by extrusion of the given elements and nodes along the path. The path of extrusion must be a meshed edge. @@ -5566,20 +5700,22 @@ class Mesh(metaclass = MeshMeta): Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters ` Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters ` Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters ` - PathMesh: 1D mesh or 1D sub-mesh, along which proceeds the extrusion - PathShape: shape (edge) defines the sub-mesh of PathMesh if PathMesh - contains not only path segments, else it can be None + PathObject: :class:`mesh, sub-mesh, group or filter ` containing edges along which proceeds the extrusion + PathShape: optional shape (edge or wire) which defines the sub-mesh of the mesh defined by *PathObject* if the mesh contains not only path segments, else it can be None NodeStart: the first or the last node on the path. Defines the direction of extrusion - HasAngles: allows the shape to be rotated around the path - to get the resulting mesh in a helical fashion - Angles: list of angles + HasAngles: not used obsolete + Angles: list of angles in radians. Nodes at each extrusion step are rotated + around *basePoint*, additionally to previous steps. LinearVariation: forces the computation of rotation angles as linear variation of the given Angles along path steps HasRefPoint: allows using the reference point - RefPoint: the reference point around which the shape is rotated (the mass center of the - shape by default). The User can specify any point as the Reference Point. + RefPoint: optional scaling and rotation center (mass center of the extruded + elements by default). The User can specify any point as the Reference Point. *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct` MakeGroups: forces the generation of new groups from existing ones + ScaleFactors: optional scale factors to apply during extrusion + ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*, + else *scaleFactors* [i] is applied to nodes at the i-th extrusion step Returns: list of created :class:`groups ` and @@ -5597,15 +5733,18 @@ class Mesh(metaclass = MeshMeta): if isinstance( RefPoint, list ): if not RefPoint: RefPoint = [0,0,0] RefPoint = SMESH.PointStruct( *RefPoint ) - if isinstance( PathMesh, Mesh ): - PathMesh = PathMesh.GetMesh() + if isinstance( PathObject, Mesh ): + PathObject = PathObject.GetMesh() Angles,AnglesParameters,hasVars = ParseAngles(Angles) - Parameters = AnglesParameters + var_separator + RefPoint.parameters + ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors) + Parameters = AnglesParameters + var_separator + \ + RefPoint.parameters + var_separator + ScalesParameters self.mesh.SetParameters(Parameters) return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces, - PathMesh, PathShape, NodeStart, + PathObject, PathShape, NodeStart, HasAngles, Angles, LinearVariation, - HasRefPoint, RefPoint, MakeGroups) + HasRefPoint, RefPoint, MakeGroups, + ScaleFactors, ScalesVariation) def ExtrusionAlongPathX(self, Base, Path, NodeStart, HasAngles=False, Angles=[], LinearVariation=False, @@ -5619,9 +5758,9 @@ class Mesh(metaclass = MeshMeta): Base: :class:`mesh, sub-mesh, group, filter `, or list of ids of elements for extrusion Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion NodeStart: the start node from Path. Defines the direction of extrusion - HasAngles: allows the shape to be rotated around the path - to get the resulting mesh in a helical fashion - Angles: list of angles in radians + HasAngles: not used obsolete + Angles: list of angles in radians. Nodes at each extrusion step are rotated + around *basePoint*, additionally to previous steps. LinearVariation: forces the computation of rotation angles as linear variation of the given Angles along path steps HasRefPoint: allows using the reference point @@ -5662,9 +5801,9 @@ class Mesh(metaclass = MeshMeta): PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion PathShape: shape (edge) defines the sub-mesh for the path NodeStart: the first or the last node on the edge. Defines the direction of extrusion - HasAngles: allows the shape to be rotated around the path - to get the resulting mesh in a helical fashion - Angles: list of angles in radians + HasAngles: not used obsolete + Angles: list of angles in radians. Nodes at each extrusion step are rotated + around *basePoint*, additionally to previous steps. HasRefPoint: allows using the reference point RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default). The User can specify any point as the Reference Point. @@ -5703,9 +5842,9 @@ class Mesh(metaclass = MeshMeta): PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds PathShape: shape (edge) defines the sub-mesh for the path NodeStart: the first or the last node on the edge. Defines the direction of extrusion - HasAngles: allows the shape to be rotated around the path - to get the resulting mesh in a helical fashion - Angles: list of angles + HasAngles: not used obsolete + Angles: list of angles in radians. Nodes at each extrusion step are rotated + around *basePoint*, additionally to previous steps. HasRefPoint: allows using the reference point RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default). The User can specify any point as the Reference Point. @@ -5741,9 +5880,9 @@ class Mesh(metaclass = MeshMeta): PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds PathShape: shape (edge) defines the sub-mesh for the path NodeStart: the first or the last node on the edge. Defines the direction of extrusion - HasAngles: allows the shape to be rotated around the path - to get the resulting mesh in a helical fashion - Angles: list of angles + HasAngles: not used obsolete + Angles: list of angles in radians. Nodes at each extrusion step are rotated + around *basePoint*, additionally to previous steps. HasRefPoint: allows using the reference point RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default). The User can specify any point as the Reference Point. @@ -5779,9 +5918,9 @@ class Mesh(metaclass = MeshMeta): PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds PathShape: shape (edge) defines the sub-mesh for the path NodeStart: the first or the last node on the edge. Defines the direction of extrusion - HasAngles: allows the shape to be rotated around the path - to get the resulting mesh in a helical fashion - Angles: list of angles + HasAngles: not used obsolete + Angles: list of angles in radians. Nodes at each extrusion step are rotated + around *basePoint*, additionally to previous steps. HasRefPoint: allows using the reference point RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default). The User can specify any point as the Reference Point. @@ -6259,7 +6398,7 @@ class Mesh(metaclass = MeshMeta): SubMeshOrGroup = [ obj.GetMesh() ] break if isinstance( obj, int ): - SubMeshOrGroup = self.GetIDSource( SubMeshOrGroup, SMESH.NODE ) + SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )] unRegister.set( SubMeshOrGroup ) break @@ -6285,6 +6424,10 @@ class Mesh(metaclass = MeshMeta): then the first node in the group is kept. AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming invalid + + Note: + This operation can create gaps in numeration of nodes or elements. + Call :meth:`RenumberElements` to remove the gaps. """ self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles ) @@ -6334,6 +6477,10 @@ class Mesh(metaclass = MeshMeta): ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs. If *ElementsToKeep* does not include an element to keep for some group to merge, then the first element in the group is kept. + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ unRegister = genObjUnRegister() @@ -6349,6 +6496,10 @@ class Mesh(metaclass = MeshMeta): def MergeEqualElements(self): """ Leave one element and remove all other elements built on the same nodes. + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ self.editor.MergeEqualElements() @@ -6381,7 +6532,7 @@ class Mesh(metaclass = MeshMeta): holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes) if not isinstance( holeNodes, SMESH.FreeBorder ): raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes) - self.editor.FillHole( holeNodes, groupName ) + return self.editor.FillHole( holeNodes, groupName ) def FindCoincidentFreeBorders (self, tolerance=0.): """ @@ -6418,6 +6569,10 @@ class Mesh(metaclass = MeshMeta): Returns: a number of successfully sewed groups + + Note: + This operation can create gaps in numeration of nodes or elements. + Call :meth:`RenumberElements` to remove the gaps. """ if freeBorders and isinstance( freeBorders, list ): @@ -6449,6 +6604,10 @@ class Mesh(metaclass = MeshMeta): Returns: :class:`error code ` + + Note: + This operation can create gaps in numeration of nodes or elements. + Call :meth:`RenumberElements` to remove the gaps. """ return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1, @@ -6462,6 +6621,10 @@ class Mesh(metaclass = MeshMeta): Returns: :class:`error code ` + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1, @@ -6474,6 +6637,10 @@ class Mesh(metaclass = MeshMeta): Returns: :class:`error code ` + + Note: + This operation can create gaps in numeration of elements. + Call :meth:`RenumberElements` to remove the gaps. """ return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder, @@ -6492,6 +6659,10 @@ class Mesh(metaclass = MeshMeta): Returns: :class:`error code ` + + Note: + This operation can create gaps in numeration of nodes. + Call :meth:`RenumberElements` to remove the gaps. """ return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements, @@ -6500,7 +6671,7 @@ class Mesh(metaclass = MeshMeta): def ChangeElemNodes(self, ide, newIDs): """ - Set new nodes for the given element. + Set new nodes for the given element. Number of nodes should be kept. Parameters: ide: the element ID @@ -6861,7 +7032,7 @@ class Mesh(metaclass = MeshMeta): def MakeSlot(self, segmentGroup, width ): """ Create a slot of given width around given 1D elements lying on a triangle mesh. - The slot is consrtucted by cutting faces by cylindrical surfaces made + The slot is constructed by cutting faces by cylindrical surfaces made around each segment. Segments are expected to be created by MakePolyLine(). Returns: @@ -6910,52 +7081,90 @@ class Mesh(metaclass = MeshMeta): def GetLength(self, elemId=None): """ - Get length of 1D element or sum of lengths of all 1D mesh elements + Get length of given 1D elements or of all 1D mesh elements Parameters: - elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated) + elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter `. By default sum length of all 1D elements will be calculated. Returns: - element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise + Sum of lengths of given elements """ length = 0 if elemId == None: length = self.smeshpyD.GetLength(self) + elif isinstance(elemId, SMESH._objref_SMESH_IDSource): + length = self.smeshpyD.GetLength(elemId) + elif elemId == []: + length = 0 + elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource): + for obj in elemId: + length += self.smeshpyD.GetLength(obj) + elif isinstance(elemId, list) and isinstance(elemId[0], int): + unRegister = genObjUnRegister() + obj = self.GetIDSource( elemId ) + unRegister.set( obj ) + length = self.smeshpyD.GetLength( obj ) else: length = self.FunctorValue(SMESH.FT_Length, elemId) return length def GetArea(self, elemId=None): """ - Get area of 2D element or sum of areas of all 2D mesh elements - elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated) + Get area of given 2D elements or of all 2D mesh elements + + Parameters: + elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter `. By default sum area of all 2D elements will be calculated. Returns: - element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise + Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise """ area = 0 if elemId == None: area = self.smeshpyD.GetArea(self) + elif isinstance(elemId, SMESH._objref_SMESH_IDSource): + area = self.smeshpyD.GetArea(elemId) + elif elemId == []: + area = 0 + elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource): + for obj in elemId: + area += self.smeshpyD.GetArea(obj) + elif isinstance(elemId, list) and isinstance(elemId[0], int): + unRegister = genObjUnRegister() + obj = self.GetIDSource( elemId ) + unRegister.set( obj ) + area = self.smeshpyD.GetArea( obj ) else: area = self.FunctorValue(SMESH.FT_Area, elemId) return area def GetVolume(self, elemId=None): """ - Get volume of 3D element or sum of volumes of all 3D mesh elements + Get volume of given 3D elements or of all 3D mesh elements Parameters: - elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated) + elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter `. By default sum volume of all 3D elements will be calculated. Returns: - element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise + Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise """ volume = 0 if elemId == None: - volume = self.smeshpyD.GetVolume(self) + volume= self.smeshpyD.GetVolume(self) + elif isinstance(elemId, SMESH._objref_SMESH_IDSource): + volume= self.smeshpyD.GetVolume(elemId) + elif elemId == []: + volume = 0 + elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource): + for obj in elemId: + volume+= self.smeshpyD.GetVolume(obj) + elif isinstance(elemId, list) and isinstance(elemId[0], int): + unRegister = genObjUnRegister() + obj = self.GetIDSource( elemId ) + unRegister.set( obj ) + volume= self.smeshpyD.GetVolume( obj ) else: volume = self.FunctorValue(SMESH.FT_Volume3D, elemId) return volume