X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH_SWIG%2FsmeshDC.py;h=59fa4f88ef530a9e48d8b996a11d298050dced63;hb=493747e8ea338a2d88204a5f12ba924d72ecbb5b;hp=eb1f505730d0266d52b35b0f50034319b5d8629c;hpb=e30e3628ce1c7687b6e462e793c9e402684811e1;p=modules%2Fsmesh.git diff --git a/src/SMESH_SWIG/smeshDC.py b/src/SMESH_SWIG/smeshDC.py index eb1f50573..59fa4f88e 100644 --- a/src/SMESH_SWIG/smeshDC.py +++ b/src/SMESH_SWIG/smeshDC.py @@ -1,21 +1,20 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2011 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 -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # # File : smesh.py # Author : Francis KLOSS, OCC @@ -189,10 +188,10 @@ None_Optimization, Light_Optimization, Medium_Optimization, Strong_Optimization None_Optimization, Light_Optimization, Standard_Optimization, StandardPlus_Optimization, Strong_Optimization = 0,1,2,3,4 # Topology treatment way of BLSURF -FromCAD, PreProcess, PreProcessPlus = 0,1,2 +FromCAD, PreProcess, PreProcessPlus, PreCAD = 0,1,2,3 # Element size flag of BLSURF -DefaultSize, DefaultGeom, Custom = 0,0,1 +DefaultSize, DefaultGeom, BLSURF_Custom, SizeMap = 0,0,1,2 PrecisionConfusion = 1e-07 @@ -491,12 +490,56 @@ def CheckPlugin(plugin): return False return True +## Private method. Add geom (sub-shape of the main shape) into the study if not yet there +def AssureGeomPublished(mesh, geom, name=''): + if not isinstance( geom, geompyDC.GEOM._objref_GEOM_Object ): + return + if not geom.IsSame( mesh.geom ) and not geom.GetStudyEntry(): + ## set the study + studyID = mesh.smeshpyD.GetCurrentStudy()._get_StudyId() + if studyID != mesh.geompyD.myStudyId: + mesh.geompyD.init_geom( mesh.smeshpyD.GetCurrentStudy()) + ## get a name + if not name and geom.GetShapeType() != geompyDC.GEOM.COMPOUND: + # for all groups SubShapeName() returns "Compound_-1" + name = mesh.geompyD.SubShapeName(geom, mesh.geom) + if not name: + name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000) + ## publish + mesh.geompyD.addToStudyInFather( mesh.geom, geom, name ) + return + +## Return the first vertex of a geomertical edge by ignoring orienation +def FirstVertexOnCurve(edge): + from geompy import SubShapeAll, ShapeType, KindOfShape, PointCoordinates + vv = SubShapeAll( edge, ShapeType["VERTEX"]) + if not vv: + raise TypeError, "Given object has no vertices" + if len( vv ) == 1: return vv[0] + info = KindOfShape(edge) + xyz = info[1:4] # coords of the first vertex + xyz1 = PointCoordinates( vv[0] ) + xyz2 = 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] + # end of l1_auxiliary ## @} # All methods of this class are accessible directly from the smesh.py package. class smeshDC(SMESH._objref_SMESH_Gen): + ## Dump component to the Python script + # This method overrides IDL function to allow default values for the parameters. + def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True): + return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile) + ## Sets the current study and Geometry component # @ingroup l1_auxiliary def init_smesh(self,theStudy,geompyD): @@ -569,7 +612,7 @@ class smeshDC(SMESH._objref_SMESH_Gen): # @return SMESH.AxisStruct # @ingroup l1_auxiliary def GetAxisStruct(self,theObj): - edges = self.geompyD.ExtractShapes( theObj, geompyDC.ShapeType["EDGE"] ) + edges = self.geompyD.SubShapeAll( theObj, geompyDC.ShapeType["EDGE"] ) if len(edges) > 1: vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geompyDC.ShapeType["VERTEX"] ) vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geompyDC.ShapeType["VERTEX"] ) @@ -654,6 +697,17 @@ class smeshDC(SMESH._objref_SMESH_Gen): aMeshes.append(aMesh) return aMeshes, aStatus + ## Creates a Mesh object(s) importing data from the given SAUV file + # @return a list of Mesh class instances + # @ingroup l2_impexp + def CreateMeshesFromSAUV( self,theFileName ): + aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName) + aMeshes = [] + for iMesh in range(len(aSmeshMeshes)) : + aMesh = Mesh(self, self.geompyD, aSmeshMeshes[iMesh]) + aMeshes.append(aMesh) + return aMeshes, aStatus + ## Creates a Mesh object importing data from the given STL file # @return an instance of Mesh class # @ingroup l2_impexp @@ -662,6 +716,17 @@ class smeshDC(SMESH._objref_SMESH_Gen): aMesh = Mesh(self, self.geompyD, aSmeshMesh) return aMesh + ## Creates Mesh objects importing data from the given CGNS file + # @return an instance of Mesh class + # @ingroup l2_impexp + def CreateMeshesFromCGNS( self, theFileName ): + aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName) + aMeshes = [] + for iMesh in range(len(aSmeshMeshes)) : + aMesh = Mesh(self, self.geompyD, aSmeshMeshes[iMesh]) + aMeshes.append(aMesh) + return aMeshes, aStatus + ## Concatenate the given meshes into one mesh. # @return an instance of Mesh class # @param meshes the meshes to combine into one mesh @@ -741,6 +806,7 @@ class smeshDC(SMESH._objref_SMESH_Gen): UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision) ## Creates a criterion by the given parameters + # \n Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below) # @param elementType the type of elements(NODE, EDGE, FACE, VOLUME) # @param CritType the type of criterion (FT_Taper, FT_Area, FT_RangeOfIds, FT_LyingOnGeom etc.) # @param Compare belongs to {FT_LessThan, FT_MoreThan, FT_EqualTo} @@ -751,6 +817,8 @@ class smeshDC(SMESH._objref_SMESH_Gen): # @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface, # FT_LyingOnGeom, FT_CoplanarFaces criteria # @return SMESH.Filter.Criterion + # + # Example of Criteria usage # @ingroup l1_controls def GetCriterion(self,elementType, CritType, @@ -759,6 +827,8 @@ class smeshDC(SMESH._objref_SMESH_Gen): UnaryOp=FT_Undefined, BinaryOp=FT_Undefined, Tolerance=1e-07): + if not CritType in SMESH.FunctorType._items: + raise TypeError, "CritType should be of SMESH.FunctorType" aCriterion = self.GetEmptyCriterion() aCriterion.TypeOfElement = elementType aCriterion.Type = self.EnumToLong(CritType) @@ -774,7 +844,7 @@ class smeshDC(SMESH._objref_SMESH_Gen): aCriterion.Compare = self.EnumToLong(FT_LessThan) elif Compare == ">": aCriterion.Compare = self.EnumToLong(FT_MoreThan) - else: + elif Compare != FT_Undefined: aCriterion.Compare = self.EnumToLong(FT_EqualTo) aTreshold = Compare @@ -787,6 +857,10 @@ class smeshDC(SMESH._objref_SMESH_Gen): else: print "Error: The treshold should be a shape." return None + if isinstance(UnaryOp,float): + aCriterion.Tolerance = UnaryOp + UnaryOp = FT_Undefined + pass elif CritType == FT_RangeOfIds: # Checks the treshold if isinstance(aTreshold, str): @@ -810,6 +884,7 @@ class smeshDC(SMESH._objref_SMESH_Gen): # Checks the treshold try: aCriterion.Threshold = self.EnumToLong(aTreshold) + assert( aTreshold in SMESH.GeometryType._items ) except: if isinstance(aTreshold, int): aCriterion.Threshold = aTreshold @@ -867,6 +942,8 @@ class smeshDC(SMESH._objref_SMESH_Gen): # @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface, # FT_LyingOnGeom, FT_CoplanarFaces criteria # @return SMESH_Filter + # + # Example of Filters usage # @ingroup l1_controls def GetFilter(self,elementType, CritType=FT_Undefined, @@ -880,7 +957,20 @@ class smeshDC(SMESH._objref_SMESH_Gen): aCriteria = [] aCriteria.append(aCriterion) aFilter.SetCriteria(aCriteria) - aFilterMgr.Destroy() + aFilterMgr.UnRegister() + return aFilter + + ## Creates a filter from criteria + # @param criteria a list of criteria + # @return SMESH_Filter + # + # Example of Filters usage + # @ingroup l1_controls + def GetFilterFromCriteria(self,criteria): + aFilterMgr = self.CreateFilterManager() + aFilter = aFilterMgr.CreateFilter() + aFilter.SetCriteria(criteria) + aFilterMgr.UnRegister() return aFilter ## Creates a numerical functor by its type @@ -927,14 +1017,14 @@ class smeshDC(SMESH._objref_SMESH_Gen): def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"): return SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName ) - ## Gets the mesh stattistic - # @return dictionary type element - count of elements + ## Gets the mesh statistic + # @return dictionary "element type" - "count of elements" # @ingroup l1_meshinfo def GetMeshInfo(self, obj): if isinstance( obj, Mesh ): obj = obj.GetMesh() d = {} - if hasattr(obj, "_narrow") and obj._narrow(SMESH.SMESH_IDSource): + if hasattr(obj, "GetMeshInfo"): values = obj.GetMeshInfo() for i in range(SMESH.Entity_Last._v): if i < len(values): d[SMESH.EntityType._item(i)]=values[i] @@ -1005,7 +1095,7 @@ class smeshDC(SMESH._objref_SMESH_Gen): pass aMeasurements = self.CreateMeasurements() result = aMeasurements.MinDistance(src1, src2) - aMeasurements.Destroy() + aMeasurements.UnRegister() return result ## Get bounding box of the specified object(s) @@ -1042,7 +1132,7 @@ class smeshDC(SMESH._objref_SMESH_Gen): pass aMeasurements = self.CreateMeasurements() result = aMeasurements.BoundingBox(srclist) - aMeasurements.Destroy() + aMeasurements.UnRegister() return result import omniORB @@ -1081,7 +1171,16 @@ class Mesh: if obj != 0: if isinstance(obj, geompyDC.GEOM._objref_GEOM_Object): self.geom = obj + # publish geom of mesh (issue 0021122) + if not self.geom.GetStudyEntry(): + studyID = smeshpyD.GetCurrentStudy()._get_StudyId() + if studyID != geompyD.myStudyId: + geompyD.init_geom( smeshpyD.GetCurrentStudy()) + pass + geo_name = "%s_%s"%(self.geom.GetShapeType(), id(self.geom)%100) + geompyD.addToStudy( self.geom, geo_name ) self.mesh = self.smeshpyD.CreateMesh(self.geom) + elif isinstance(obj, SMESH._objref_SMESH_Mesh): self.SetMesh(obj) else: @@ -1124,12 +1223,13 @@ class Mesh: ## Gets the subMesh object associated to a \a theSubObject geometrical object. # The subMesh object gives access to the IDs of nodes and elements. - # @param theSubObject a geometrical object (shape) - # @param theName a name for the submesh + # @param geom a geometrical object (shape) + # @param name a name for the submesh # @return an object of type SMESH_SubMesh, representing a part of mesh, which lies on the given shape # @ingroup l2_submeshes - def GetSubMesh(self, theSubObject, theName): - submesh = self.mesh.GetSubMesh(theSubObject, theName) + def GetSubMesh(self, geom, name): + AssureGeomPublished( self, geom, name ) + submesh = self.mesh.GetSubMesh( geom, name ) return submesh ## Returns the shape associated to the mesh @@ -1324,6 +1424,15 @@ class Mesh: def Projection1D(self, geom=0): return Mesh_Projection1D(self, geom) + ## Creates a projection 1D-2D algorithm for faces. + # If the optional \a geom parameter is not set, this algorithm is global. + # Otherwise, this algorithm defines a submesh based on \a geom subshape. + # @param geom If defined, the subshape to be meshed + # @return an instance of Mesh_Projection2D algorithm + # @ingroup l3_algos_proj + def Projection1D2D(self, geom=0): + return Mesh_Projection2D(self, geom, "Projection_1D2D") + ## Creates a projection 2D algorithm for faces. # If the optional \a geom parameter is not set, this algorithm is global. # Otherwise, this algorithm defines a submesh based on \a geom subshape. @@ -1331,7 +1440,7 @@ class Mesh: # @return an instance of Mesh_Projection2D algorithm # @ingroup l3_algos_proj def Projection2D(self, geom=0): - return Mesh_Projection2D(self, geom) + return Mesh_Projection2D(self, geom, "Projection_2D") ## Creates a projection 3D algorithm for solids. # If the optional \a geom parameter is not set, this algorithm is global. @@ -1352,12 +1461,27 @@ class Mesh: shape = geom if shape==0: shape = self.geom - nbSolids = len( self.geompyD.ExtractShapes( shape, geompyDC.ShapeType["SOLID"] )) - nbShells = len( self.geompyD.ExtractShapes( shape, geompyDC.ShapeType["SHELL"] )) + nbSolids = len( self.geompyD.SubShapeAll( shape, geompyDC.ShapeType["SOLID"] )) + nbShells = len( self.geompyD.SubShapeAll( shape, geompyDC.ShapeType["SHELL"] )) if nbSolids == 0 or nbSolids == nbShells: return Mesh_Prism3D(self, geom) return Mesh_RadialPrism3D(self, geom) + ## Creates a "Body Fitted" 3D algorithm for solids, which generates + # 3D structured Cartesian mesh in the internal part of a solid shape + # and polyhedral volumes near the shape boundary. + # If the optional \a geom parameter is not set, this algorithm is global. + # Otherwise, this algorithm defines a submesh based on \a geom subshape. + # The algorithm does not support submeshes. + # Generally usage of this algorithm as a local one is useless since + # it does not discretize 1D and 2D subshapes in a usual way acceptable + # for other algorithms. + # @param geom If defined, the subshape to be meshed + # @return an instance of Mesh_Cartesian_3D algorithm + # @ingroup l3_algos_basic + def BodyFitted(self, geom=0): + return Mesh_Cartesian_3D(self, geom) + ## Evaluates size of prospective mesh on a shape # @return a list where i-th element is a number of elements of i-th SMESH.EntityType # To know predicted number of e.g. edges, inquire it this way @@ -1532,7 +1656,7 @@ class Mesh: salome.sg.updateObjBrowser(1) ## Computes a tetrahedral mesh using AutomaticLength + MEFISTO + NETGEN - # @param fineness [0,-1] defines mesh fineness + # @param fineness [0.0,1.0] defines mesh fineness # @return True or False # @ingroup l3_algos_basic def AutomaticTetrahedralization(self, fineness=0): @@ -1549,7 +1673,7 @@ class Mesh: return self.Compute() ## Computes an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron - # @param fineness [0,-1] defines mesh fineness + # @param fineness [0.0, 1.0] defines mesh fineness # @return True or False # @ingroup l3_algos_basic def AutomaticHexahedralization(self, fineness=0): @@ -1588,6 +1712,23 @@ class Mesh: TreatHypoStatus( status, hyp_name, geom_name, isAlgo ) return status + ## Return True if an algorithm of hypothesis is assigned to a given shape + # @param hyp a hypothesis to check + # @param geom a subhape of mesh geometry + # @return True of False + # @ingroup l2_hypotheses + def IsUsedHypothesis(self, hyp, geom): + if not hyp or not geom: + return False + if isinstance( hyp, Mesh_Algorithm ): + hyp = hyp.GetAlgorithm() + pass + hyps = self.GetHypothesisList(geom) + for h in hyps: + if h.GetId() == hyp.GetId(): + return True + return False + ## Unassigns a hypothesis # @param hyp a hypothesis to unassign # @param geom a subshape of mesh geometry @@ -1619,24 +1760,13 @@ class Mesh: pass pass - ## Creates a mesh group based on the geometric object \a grp - # and gives a \a name, \n if this parameter is not defined - # the name is the same as the geometric group name \n - # Note: Works like GroupOnGeom(). - # @param grp a geometric group, a vertex, an edge, a face or a solid - # @param name the name of the mesh group - # @return SMESH_GroupOnGeom - # @ingroup l2_grps_create - def Group(self, grp, name=""): - return self.GroupOnGeom(grp, name) - ## Deprecated, used only for compatibility! Please, use ExportToMEDX() method instead. # Exports the mesh in a file in MED format and chooses the \a version of MED format ## allowing to overwrite the file if it exists or add the exported data to its contents # @param f the file name # @param version values are SMESH.MED_V2_1, SMESH.MED_V2_2 # @param opt boolean parameter for creating/not creating - # the groups Group_On_All_Nodes, Group_On_All_Faces, ... + # the groups Group_On_All_Nodes, Group_On_All_Faces, ... # @param overwrite boolean parameter for overwriting/not overwriting the file # @ingroup l2_impexp def ExportToMED(self, f, version, opt=0, overwrite=1): @@ -1650,29 +1780,75 @@ class Mesh: # the typical use is auto_groups=false. # @param version MED format version(MED_V2_1 or MED_V2_2) # @param overwrite boolean parameter for overwriting/not overwriting the file + # @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh # @ingroup l2_impexp - def ExportMED(self, f, auto_groups=0, version=MED_V2_2, overwrite=1): - self.mesh.ExportToMEDX(f, auto_groups, version, overwrite) + def ExportMED(self, f, auto_groups=0, version=MED_V2_2, overwrite=1, meshPart=None): + if meshPart: + if isinstance( meshPart, list ): + meshPart = self.GetIDSource( meshPart, SMESH.ALL ) + self.mesh.ExportPartToMED( meshPart, f, auto_groups, version, overwrite ) + else: + self.mesh.ExportToMEDX(f, auto_groups, version, overwrite) + + ## Exports the mesh in a file in SAUV format + # @param f is the file name + # @param auto_groups boolean parameter for creating/not creating + # the groups Group_On_All_Nodes, Group_On_All_Faces, ... ; + # the typical use is auto_groups=false. + # @ingroup l2_impexp + def ExportSAUV(self, f, auto_groups=0): + self.mesh.ExportSAUV(f, auto_groups) ## Exports the mesh in a file in DAT format # @param f the file name + # @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh # @ingroup l2_impexp - def ExportDAT(self, f): - self.mesh.ExportDAT(f) + def ExportDAT(self, f, meshPart=None): + if meshPart: + if isinstance( meshPart, list ): + meshPart = self.GetIDSource( meshPart, SMESH.ALL ) + self.mesh.ExportPartToDAT( meshPart, f ) + else: + self.mesh.ExportDAT(f) ## Exports the mesh in a file in UNV format # @param f the file name + # @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh # @ingroup l2_impexp - def ExportUNV(self, f): - self.mesh.ExportUNV(f) + def ExportUNV(self, f, meshPart=None): + if meshPart: + if isinstance( meshPart, list ): + meshPart = self.GetIDSource( meshPart, SMESH.ALL ) + self.mesh.ExportPartToUNV( meshPart, f ) + else: + self.mesh.ExportUNV(f) ## Export the mesh in a file in STL format # @param f the file name # @param ascii defines the file encoding + # @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh # @ingroup l2_impexp - def ExportSTL(self, f, ascii=1): - self.mesh.ExportSTL(f, ascii) + def ExportSTL(self, f, ascii=1, meshPart=None): + if meshPart: + if isinstance( meshPart, list ): + meshPart = self.GetIDSource( meshPart, SMESH.ALL ) + self.mesh.ExportPartToSTL( meshPart, f, ascii ) + else: + self.mesh.ExportSTL(f, ascii) + ## Exports the mesh in a file in CGNS format + # @param f is the file name + # @param overwrite boolean parameter for overwriting/not overwriting the file + # @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh + # @ingroup l2_impexp + def ExportCGNS(self, f, overwrite=1, meshPart=None): + if isinstance( meshPart, list ): + meshPart = self.GetIDSource( meshPart, SMESH.ALL ) + if isinstance( meshPart, Mesh ): + meshPart = meshPart.mesh + elif not meshPart: + meshPart = self.mesh + self.mesh.ExportCGNS(meshPart, f, overwrite) # Operations with groups: # ---------------------- @@ -1685,6 +1861,17 @@ class Mesh: def CreateEmptyGroup(self, elementType, name): return self.mesh.CreateGroup(elementType, name) + ## Creates a mesh group based on the geometric object \a grp + # and gives a \a name, \n if this parameter is not defined + # the name is the same as the geometric group name \n + # Note: Works like GroupOnGeom(). + # @param grp a geometric group, a vertex, an edge, a face or a solid + # @param name the name of the mesh group + # @return SMESH_GroupOnGeom + # @ingroup l2_grps_create + def Group(self, grp, name=""): + return self.GroupOnGeom(grp, name) + ## Creates a mesh group based on the geometrical object \a grp # and gives a \a name, \n if this parameter is not defined # the name is the same as the geometrical group name @@ -1695,58 +1882,44 @@ class Mesh: # @return SMESH_GroupOnGeom # @ingroup l2_grps_create def GroupOnGeom(self, grp, name="", typ=None): + AssureGeomPublished( self, grp, name ) if name == "": name = grp.GetName() - - if typ == None: - tgeo = str(grp.GetShapeType()) - if tgeo == "VERTEX": - typ = NODE - elif tgeo == "EDGE": - typ = EDGE - elif tgeo == "FACE": - typ = FACE - elif tgeo == "SOLID": - typ = VOLUME - elif tgeo == "SHELL": - typ = VOLUME - elif tgeo == "COMPOUND": - try: # it raises on a compound of compounds - if len( self.geompyD.GetObjectIDs( grp )) == 0: - print "Mesh.Group: empty geometric group", GetName( grp ) - return 0 - pass - except: - pass - if grp.GetType() == 37: # GEOMImpl_Types.hxx: #define GEOM_GROUP 37 - # group - tgeo = self.geompyD.GetType(grp) - if tgeo == geompyDC.ShapeType["VERTEX"]: - typ = NODE - elif tgeo == geompyDC.ShapeType["EDGE"]: - typ = EDGE - elif tgeo == geompyDC.ShapeType["FACE"]: - typ = FACE - elif tgeo == geompyDC.ShapeType["SOLID"]: - typ = VOLUME - pass - pass - else: - # just a compound - for elemType, shapeType in [[VOLUME,"SOLID"],[FACE,"FACE"], - [EDGE,"EDGE"],[NODE,"VERTEX"]]: - if self.geompyD.SubShapeAll(grp,geompyDC.ShapeType[shapeType]): - typ = elemType - break - pass - pass - pass - pass - if typ == None: - print "Mesh.Group: bad first argument: expected a group, a vertex, an edge, a face or a solid" - return 0 + if not typ: + typ = self._groupTypeFromShape( grp ) + return self.mesh.CreateGroupFromGEOM(typ, name, grp) + + ## Pivate method to get a type of group on geometry + def _groupTypeFromShape( self, shape ): + tgeo = str(shape.GetShapeType()) + if tgeo == "VERTEX": + typ = NODE + elif tgeo == "EDGE": + typ = EDGE + elif tgeo == "FACE" or tgeo == "SHELL": + typ = FACE + elif tgeo == "SOLID" or tgeo == "COMPSOLID": + typ = VOLUME + elif tgeo == "COMPOUND": + sub = self.geompyD.SubShapeAll( shape, geompyDC.ShapeType["SHAPE"]) + if not sub: + raise ValueError,"_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape) + return self._groupTypeFromShape( sub[0] ) else: - return self.mesh.CreateGroupFromGEOM(typ, name, grp) + raise ValueError, \ + "_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape) + return typ + + ## Creates a mesh group with given \a name based on the \a filter which + ## is a special type of group dynamically updating it's contents during + ## mesh modification + # @param typ the type of elements in the group + # @param name the name of the mesh group + # @param filter the filter defining group contents + # @return SMESH_GroupOnFilter + # @ingroup l2_grps_create + def GroupOnFilter(self, typ, name, filter): + return self.mesh.CreateGroupFromFilter(typ, name, filter) ## Creates a mesh group by the given ids of elements # @param groupName the name of the mesh group @@ -1794,7 +1967,7 @@ class Mesh: aCriteria.append(Criterion) aFilter.SetCriteria(aCriteria) group = self.MakeGroupByFilter(groupName, aFilter) - aFilterMgr.Destroy() + aFilterMgr.UnRegister() return group ## Creates a mesh group by the given criteria (list of criteria) @@ -1807,7 +1980,7 @@ class Mesh: aFilter = aFilterMgr.CreateFilter() aFilter.SetCriteria(theCriteria) group = self.MakeGroupByFilter(groupName, aFilter) - aFilterMgr.Destroy() + aFilterMgr.UnRegister() return group ## Creates a mesh group by the given filter @@ -1838,7 +2011,7 @@ class Mesh: aPredicate = aFilterMgr.CreateFreeEdges() aPredicate.SetMesh(self.mesh) aBorders = aPredicate.GetBorders() - aFilterMgr.Destroy() + aFilterMgr.UnRegister() return aBorders ## Removes a group @@ -1921,10 +2094,10 @@ class Mesh: def CutListOfGroups(self, main_groups, tool_groups, name): return self.mesh.CutListOfGroups(main_groups, tool_groups, name) - ## Produces a group of elements with specified element type using list of existing groups + ## Produces a group of elements of specified type using list of existing groups # A new group is created. System - # 1) extract all nodes on which groups elements are built - # 2) combine all elements of specified dimension laying on these nodes + # 1) extracts all nodes on which groups elements are built + # 2) combines all elements of specified dimension laying on these nodes # @return an instance of SMESH_Group # @ingroup l2_grps_operon def CreateDimGroup(self, groups, elem_type, name): @@ -2402,7 +2575,7 @@ class Mesh: aMeasurements = self.smeshpyD.CreateMeasurements() aMeasure = aMeasurements.MinDistance(id1, id2) - aMeasurements.Destroy() + aMeasurements.UnRegister() return aMeasure ## Get bounding box of the specified object(s) @@ -2420,7 +2593,7 @@ class Mesh: return result ## Get measure structure specifying bounding box data of the specified object(s) - # @param objects single source object or list of source objects or list of nodes/elements IDs + # @param IDs single source object or list of source objects or list of nodes/elements IDs # @param isElem if @a objects is a list of IDs, @c True value in this parameters specifies that @a objects are elements, # @c False specifies that @a objects are nodes # @return Measure structure @@ -2451,7 +2624,7 @@ class Mesh: pass aMeasurements = self.smeshpyD.CreateMeasurements() aMeasure = aMeasurements.BoundingBox(srclist) - aMeasurements.Destroy() + aMeasurements.UnRegister() return aMeasure # Mesh edition (SMESH_MeshEditor functionality): @@ -2679,10 +2852,14 @@ class Mesh: # @param z the Z coordinate of a point # @param elementType type of elements to find (SMESH.ALL type # means elements of any type excluding nodes and 0D elements) + # @param meshPart a part of mesh (group, sub-mesh) to search within # @return list of IDs of found elements # @ingroup l2_modif_throughp - def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL): - return self.editor.FindElementsByPoint(x, y, z, elementType) + def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None): + if meshPart: + return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType ); + else: + return self.editor.FindElementsByPoint(x, y, z, elementType) # Return point state in a closed 2D mesh in terms of TopAbs_State enumeration. # TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails. @@ -3046,19 +3223,26 @@ class Mesh: ## Converts the mesh to quadratic, deletes old elements, replacing # them with quadratic with the same id. # @param theForce3d new node creation method: - # 0 - the medium node lies at the geometrical edge from which the mesh element is built + # 0 - the medium node lies at the geometrical entity from which the mesh element is built # 1 - the medium node lies at the middle of the line segments connecting start and end node of a mesh element + # @param theSubMesh a group or a sub-mesh to convert; WARNING: in this case the mesh can become not conformal # @ingroup l2_modif_tofromqu - def ConvertToQuadratic(self, theForce3d): - self.editor.ConvertToQuadratic(theForce3d) + def ConvertToQuadratic(self, theForce3d, theSubMesh=None): + if theSubMesh: + self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh) + else: + self.editor.ConvertToQuadratic(theForce3d) ## Converts the mesh from quadratic to ordinary, # deletes old quadratic elements, \n replacing # them with ordinary mesh elements with the same id. - # @return TRUE in case of success, FALSE otherwise. + # @param theSubMesh a group or a sub-mesh to convert; WARNING: in this case the mesh can become not conformal # @ingroup l2_modif_tofromqu - def ConvertFromQuadratic(self): - return self.editor.ConvertFromQuadratic() + def ConvertFromQuadratic(self, theSubMesh=None): + if theSubMesh: + self.editor.ConvertFromQuadraticObject(theSubMesh) + else: + return self.editor.ConvertFromQuadratic() ## Creates 2D mesh as skin on boundary faces of a 3D mesh # @return TRUE if operation has been completed successfully, FALSE otherwise @@ -3069,15 +3253,18 @@ class Mesh: ## Creates missing boundary elements # @param elements - elements whose boundary is to be checked: # mesh, group, sub-mesh or list of elements + # if elements is mesh, it must be the mesh whose MakeBoundaryMesh() is called # @param dimension - defines type of boundary elements to create: # SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D + # SMESH.BND_1DFROM3D creates mesh edges on all borders of free facets of 3D cells # @param groupName - a name of group to store created boundary elements in, # "" means not to create the group # @param meshName - a name of new mesh to store created boundary elements in, # "" means not to create the new mesh - # @param toCopyElements - if true, the checked elements will be copied into the new mesh + # @param toCopyElements - if true, the checked elements will be copied into + # the new mesh else only boundary elements will be copied into the new mesh # @param toCopyExistingBondary - if true, not only new but also pre-existing - # boundary elements will be copied into the new mesh + # boundary elements will be copied into the new mesh # @return tuple (mesh, group) where bondary elements were added to # @ingroup l2_modif_edit def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="", @@ -3093,6 +3280,29 @@ class Mesh: if mesh: mesh = self.smeshpyD.Mesh(mesh) return mesh, group + ## + # @brief Creates missing boundary elements around either the whole mesh or + # groups of 2D elements + # @param dimension - defines type of boundary elements to create + # @param groupName - a name of group to store all boundary elements in, + # "" means not to create the group + # @param meshName - a name of a new mesh, which is a copy of the initial + # mesh + created boundary elements; "" means not to create the new mesh + # @param toCopyAll - if true, the whole initial mesh will be copied into + # the new mesh else only boundary elements will be copied into the new mesh + # @param groups - groups of 2D elements to make boundary around + # @retval tuple( long, mesh, groups ) + # long - number of added boundary elements + # mesh - the mesh where elements were added to + # group - the group of boundary elements or None + # + def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="", + toCopyAll=False, groups=[]): + nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName, + toCopyAll,groups) + if mesh: mesh = self.smeshpyD.Mesh(mesh) + return nb, mesh, group + ## Renumber mesh nodes # @ingroup l2_modif_renumber def RenumberNodes(self): @@ -3248,7 +3458,7 @@ class Mesh: ## Generates new elements by extrusion of the elements with given ids # @param IDsOfElements the list of elements ids for extrusion - # @param StepVector vector or DirStruct, defining the direction and value of extrusion + # @param StepVector vector or DirStruct, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||) # @param NbOfSteps the number of steps # @param MakeGroups forces the generation of new groups from existing ones # @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise @@ -3291,7 +3501,7 @@ class Mesh: ## Generates new elements by extrusion of the elements which belong to the object # @param theObject the object which elements should be processed. # It can be a mesh, a sub mesh or a group. - # @param StepVector vector, defining the direction and value of extrusion + # @param StepVector vector, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||) # @param NbOfSteps the number of steps # @param MakeGroups forces the generation of new groups from existing ones # @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise @@ -3313,7 +3523,7 @@ class Mesh: ## Generates new elements by extrusion of the elements which belong to the object # @param theObject object which elements should be processed. # It can be a mesh, a sub mesh or a group. - # @param StepVector vector, defining the direction and value of extrusion + # @param StepVector vector, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||) # @param NbOfSteps the number of steps # @param MakeGroups to generate new groups from existing ones # @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise @@ -3335,7 +3545,7 @@ class Mesh: ## Generates new elements by extrusion of the elements which belong to the object # @param theObject object which elements should be processed. # It can be a mesh, a sub mesh or a group. - # @param StepVector vector, defining the direction and value of extrusion + # @param StepVector vector, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||) # @param NbOfSteps the number of steps # @param MakeGroups forces the generation of new groups from existing ones # @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise @@ -4029,6 +4239,7 @@ class Mesh: # This method provided for convenience works as DoubleNodes() described above. # @param theNodes list of groups of nodes to be doubled # @param theModifiedElems list of groups of elements to be updated. + # @param theMakeGroup forces the generation of a group containing new nodes. # @return TRUE if operation has been completed successfully, FALSE otherwise # @ingroup l2_modif_edit def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False): @@ -4123,6 +4334,16 @@ class Mesh: def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems ): return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems ) + ## Double nodes on some external faces and create flat elements. + # Flat elements are mainly used by some types of mechanic calculations. + # + # Each group of the list must be constituted of faces. + # Triangles are transformed in prisms, and quadrangles in hexahedrons. + # @param theGroupsOfFaces - list of groups of faces + # @return TRUE if operation has been completed successfully, FALSE otherwise + def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ): + return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces ) + def _valueFromFunctor(self, funcType, elemId): fn = self.smeshpyD.GetFunctor(funcType) fn.SetMesh(self.mesh) @@ -4344,25 +4565,22 @@ class Mesh_Algorithm: if geom is None: raise RuntimeError, "Attemp to create " + algo + " algoritm on None shape" self.mesh = mesh - piece = mesh.geom name = "" if not geom: - self.geom = piece + self.geom = mesh.geom else: self.geom = geom + AssureGeomPublished( mesh, geom ) try: name = GetName(geom) pass except: - name = mesh.geompyD.SubShapeName(geom, piece) - if not name: - name = "%s_%s"%(geom.GetShapeType(), id(geom%1000)) pass self.subm = mesh.mesh.GetSubMesh(geom, algo.GetName()) - self.algo = algo status = mesh.mesh.AddHypothesis(self.geom, self.algo) TreatHypoStatus( status, algo.GetName(), name, True ) + return def CompareHyp (self, hyp, args): print "CompareHyp is not implemented for ", self.__class__.__name__, ":", hyp.GetName() @@ -4383,13 +4601,19 @@ class Mesh_Algorithm: hypo = self.mesh.smeshpyD.CreateHypothesis(hyp, so) a = "" s = "=" - i = 0 - n = len(args) - while i 10: + argStr = argStr[:7]+"..." + if argStr[0] == '[': argStr += ']' + a = a + s + argStr s = "," - i = i + 1 pass + if len(a) > 50: + a = a[:47]+"..." self.mesh.smeshpyD.SetName(hypo, hyp + a) pass geomName="" @@ -4417,7 +4641,7 @@ class Mesh_Algorithm: # @param thickness total thickness of layers of prisms # @param numberOfLayers number of layers of prisms # @param stretchFactor factor (>1.0) of growth of layer thickness towards inside of mesh - # @param ignoreFaces geometrical face (or their ids) not to generate layers on + # @param ignoreFaces list of geometrical faces (or their ids) not to generate layers on # @ingroup l3_hypos_additi def ViscousLayers(self, thickness, numberOfLayers, stretchFactor, ignoreFaces=[]): if not isinstance(self.algo, SMESH._objref_SMESH_3D_Algo): @@ -4434,6 +4658,42 @@ class Mesh_Algorithm: hyp.SetIgnoreFaces(ignoreFaces) return hyp + ## Transform a list of ether edges or tuples (edge 1st_vertex_of_edge) + # into a list acceptable to SetReversedEdges() of some 1D hypotheses + # @ingroup l3_hypos_1dhyps + def ReversedEdgeIndices(self, reverseList): + resList = [] + geompy = self.mesh.geompyD + for i in reverseList: + if isinstance( i, int ): + s = geompy.SubShapes(self.mesh.geom, [i])[0] + if s.GetShapeType() != geompyDC.GEOM.EDGE: + raise TypeError, "Not EDGE index given" + resList.append( i ) + elif isinstance( i, geompyDC.GEOM._objref_GEOM_Object ): + if i.GetShapeType() != geompyDC.GEOM.EDGE: + raise TypeError, "Not an EDGE given" + resList.append( geompy.GetSubShapeID(self.mesh.geom, i )) + elif len( i ) > 1: + e = i[0] + v = i[1] + if not isinstance( e, geompyDC.GEOM._objref_GEOM_Object ) or \ + not isinstance( v, geompyDC.GEOM._objref_GEOM_Object ): + raise TypeError, "A list item must be a tuple (edge 1st_vertex_of_edge)" + if v.GetShapeType() == geompyDC.GEOM.EDGE and \ + e.GetShapeType() == geompyDC.GEOM.VERTEX: + v,e = e,v + if e.GetShapeType() != geompyDC.GEOM.EDGE or \ + v.GetShapeType() != geompyDC.GEOM.VERTEX: + raise TypeError, "A list item must be a tuple (edge 1st_vertex_of_edge)" + vFirst = FirstVertexOnCurve( e ) + tol = geompy.Tolerance( vFirst )[-1] + if geompy.MinDistance( v, vFirst ) > 1.5*tol: + resList.append( geompy.GetSubShapeID(self.mesh.geom, e )) + else: + raise TypeError, "Item must be either an edge or tuple (edge 1st_vertex_of_edge)" + return resList + # Public class: Mesh_Segment # -------------------------- @@ -4506,7 +4766,8 @@ class Mesh_Segment(Mesh_Algorithm): ## Defines "NumberOfSegments" hypothesis to cut an edge in a fixed number of segments # @param n for the number of segments that cut an edge # @param s for the scale factor (optional) - # @param reversedEdges is a list of edges to mesh using reversed orientation + # @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) - create a new one # @return an instance of StdMeshers_NumberOfSegments hypothesis @@ -4515,20 +4776,19 @@ class Mesh_Segment(Mesh_Algorithm): if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges reversedEdges, UseExisting = [], reversedEdges entry = self.MainShapeEntry() - if reversedEdges and isinstance(reversedEdges[0],geompyDC.GEOM._objref_GEOM_Object): - reversedEdges = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, e) for e in reversedEdges ] + reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges) if s == []: - hyp = self.Hypothesis("NumberOfSegments", [n, reversedEdges, entry], + hyp = self.Hypothesis("NumberOfSegments", [n, reversedEdgeInd, entry], UseExisting=UseExisting, CompareMethod=self.CompareNumberOfSegments) else: - hyp = self.Hypothesis("NumberOfSegments", [n,s, reversedEdges, entry], + hyp = self.Hypothesis("NumberOfSegments", [n,s, reversedEdgeInd, entry], UseExisting=UseExisting, CompareMethod=self.CompareNumberOfSegments) hyp.SetDistrType( 1 ) hyp.SetScaleFactor(s) hyp.SetNumberOfSegments(n) - hyp.SetReversedEdges( reversedEdges ) + hyp.SetReversedEdges( reversedEdgeInd ) hyp.SetObjectEntry( entry ) return hyp @@ -4551,7 +4811,8 @@ class Mesh_Segment(Mesh_Algorithm): ## Defines "Arithmetic1D" hypothesis to cut an edge in several segments with increasing arithmetic length # @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 + # @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_Arithmetic1D hypothesis @@ -4559,15 +4820,14 @@ class Mesh_Segment(Mesh_Algorithm): def Arithmetic1D(self, start, end, reversedEdges=[], UseExisting=0): if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges reversedEdges, UseExisting = [], reversedEdges - if reversedEdges and isinstance(reversedEdges[0],geompyDC.GEOM._objref_GEOM_Object): - reversedEdges = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, e) for e in reversedEdges ] + reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges) entry = self.MainShapeEntry() - hyp = self.Hypothesis("Arithmetic1D", [start, end, reversedEdges, entry], + hyp = self.Hypothesis("Arithmetic1D", [start, end, reversedEdgeInd, entry], UseExisting=UseExisting, CompareMethod=self.CompareArithmetic1D) hyp.SetStartLength(start) hyp.SetEndLength(end) - hyp.SetReversedEdges( reversedEdges ) + hyp.SetReversedEdges( reversedEdgeInd ) hyp.SetObjectEntry( entry ) return hyp @@ -4589,7 +4849,8 @@ class Mesh_Segment(Mesh_Algorithm): # values are equals 1 # @param points defines the list of parameters on curve # @param nbSegs defines the list of numbers of segments - # @param reversedEdges is a list of edges to mesh using reversed orientation + # @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_Arithmetic1D hypothesis @@ -4597,15 +4858,14 @@ class Mesh_Segment(Mesh_Algorithm): def FixedPoints1D(self, points, nbSegs=[1], reversedEdges=[], UseExisting=0): if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges reversedEdges, UseExisting = [], reversedEdges - if reversedEdges and isinstance(reversedEdges[0],geompyDC.GEOM._objref_GEOM_Object): - reversedEdges = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, e) for e in reversedEdges ] + reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges) entry = self.MainShapeEntry() - hyp = self.Hypothesis("FixedPoints1D", [points, nbSegs, reversedEdges, entry], + hyp = self.Hypothesis("FixedPoints1D", [points, nbSegs, reversedEdgeInd, entry], UseExisting=UseExisting, CompareMethod=self.CompareFixedPoints1D) hyp.SetPoints(points) hyp.SetNbSegments(nbSegs) - hyp.SetReversedEdges(reversedEdges) + hyp.SetReversedEdges(reversedEdgeInd) hyp.SetObjectEntry(entry) return hyp @@ -4625,7 +4885,8 @@ class Mesh_Segment(Mesh_Algorithm): ## Defines "StartEndLength" hypothesis to cut an edge in several segments with increasing geometric length # @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 + # @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_StartEndLength hypothesis @@ -4633,15 +4894,14 @@ class Mesh_Segment(Mesh_Algorithm): def StartEndLength(self, start, end, reversedEdges=[], UseExisting=0): if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges reversedEdges, UseExisting = [], reversedEdges - if reversedEdges and isinstance(reversedEdges[0],geompyDC.GEOM._objref_GEOM_Object): - reversedEdges = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, e) for e in reversedEdges ] + reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges) entry = self.MainShapeEntry() - hyp = self.Hypothesis("StartEndLength", [start, end, reversedEdges, entry], + hyp = self.Hypothesis("StartEndLength", [start, end, reversedEdgeInd, entry], UseExisting=UseExisting, CompareMethod=self.CompareStartEndLength) hyp.SetStartLength(start) hyp.SetEndLength(end) - hyp.SetReversedEdges( reversedEdges ) + hyp.SetReversedEdges( reversedEdgeInd ) hyp.SetObjectEntry( entry ) return hyp @@ -4713,14 +4973,9 @@ class Mesh_Segment(Mesh_Algorithm): ### 0D algorithm if self.geom is None: raise RuntimeError, "Attemp to create SegmentAroundVertex_0D algoritm on None shape" - try: - name = GetName(self.geom) - pass - except: - piece = self.mesh.geom - name = self.mesh.geompyD.SubShapeName(self.geom, piece) - self.mesh.geompyD.addToStudyInFather(piece, self.geom, name) - pass + AssureGeomPublished( self.mesh, self.geom ) + name = GetName(self.geom) + algo = self.FindAlgorithm("SegmentAroundVertex_0D", self.mesh.smeshpyD) if algo is None: algo = self.mesh.smeshpyD.CreateHypothesis("SegmentAroundVertex_0D", "libStdMeshersEngine.so") @@ -4816,7 +5071,6 @@ class Mesh_Triangle(Mesh_Algorithm): def __init__(self, mesh, algoType, geom=0): Mesh_Algorithm.__init__(self) - self.algoType = algoType if algoType == MEFISTO: self.Create(mesh, geom, "MEFISTO_2D") pass @@ -4833,6 +5087,8 @@ class Mesh_Triangle(Mesh_Algorithm): self.Create(mesh, geom, "NETGEN_2D_ONLY", "libNETGENEngine.so") pass + self.algoType = algoType + ## Defines "MaxElementArea" hypothesis basing on the definition of the maximum area of each triangle # @param area for the maximum area of each triangle # @param UseExisting if ==true - searches for an existing hypothesis created with the @@ -4868,98 +5124,332 @@ class Mesh_Triangle(Mesh_Algorithm): return hyp ## Sets a way to define size of mesh elements to generate. - # @param thePhysicalMesh is: DefaultSize or Custom. + # @param thePhysicalMesh is: DefaultSize, BLSURF_Custom or SizeMap. # @ingroup l3_hypos_blsurf def SetPhysicalMesh(self, thePhysicalMesh=DefaultSize): - # Parameter of BLSURF algo - self.Parameters().SetPhysicalMesh(thePhysicalMesh) + if self.Parameters(): + # Parameter of BLSURF algo + self.params.SetPhysicalMesh(thePhysicalMesh) ## Sets size of mesh elements to generate. # @ingroup l3_hypos_blsurf def SetPhySize(self, theVal): - # Parameter of BLSURF algo - self.SetPhysicalMesh(1) #Custom - else why to set the size? - self.Parameters().SetPhySize(theVal) + if self.Parameters(): + # Parameter of BLSURF algo + self.params.SetPhySize(theVal) ## Sets lower boundary of mesh element size (PhySize). # @ingroup l3_hypos_blsurf def SetPhyMin(self, theVal=-1): - # Parameter of BLSURF algo - self.Parameters().SetPhyMin(theVal) + if self.Parameters(): + # Parameter of BLSURF algo + self.params.SetPhyMin(theVal) ## Sets upper boundary of mesh element size (PhySize). # @ingroup l3_hypos_blsurf def SetPhyMax(self, theVal=-1): - # Parameter of BLSURF algo - self.Parameters().SetPhyMax(theVal) + if self.Parameters(): + # Parameter of BLSURF algo + self.params.SetPhyMax(theVal) ## Sets a way to define maximum angular deflection of mesh from CAD model. # @param theGeometricMesh is: 0 (None) or 1 (Custom) # @ingroup l3_hypos_blsurf def SetGeometricMesh(self, theGeometricMesh=0): - # Parameter of BLSURF algo - if self.Parameters().GetPhysicalMesh() == 0: theGeometricMesh = 1 - self.params.SetGeometricMesh(theGeometricMesh) + if self.Parameters(): + # Parameter of BLSURF algo + if self.params.GetPhysicalMesh() == 0: theGeometricMesh = 1 + self.params.SetGeometricMesh(theGeometricMesh) ## Sets angular deflection (in degrees) of a mesh face from CAD surface. # @ingroup l3_hypos_blsurf def SetAngleMeshS(self, theVal=_angleMeshS): - # Parameter of BLSURF algo - if self.Parameters().GetGeometricMesh() == 0: theVal = self._angleMeshS - self.params.SetAngleMeshS(theVal) + if self.Parameters(): + # Parameter of BLSURF algo + if self.params.GetGeometricMesh() == 0: theVal = self._angleMeshS + self.params.SetAngleMeshS(theVal) ## Sets angular deflection (in degrees) of a mesh edge from CAD curve. # @ingroup l3_hypos_blsurf def SetAngleMeshC(self, theVal=_angleMeshS): - # Parameter of BLSURF algo - if self.Parameters().GetGeometricMesh() == 0: theVal = self._angleMeshS - self.params.SetAngleMeshC(theVal) + if self.Parameters(): + # Parameter of BLSURF algo + if self.params.GetGeometricMesh() == 0: theVal = self._angleMeshS + self.params.SetAngleMeshC(theVal) ## Sets lower boundary of mesh element size computed to respect angular deflection. # @ingroup l3_hypos_blsurf def SetGeoMin(self, theVal=-1): - # Parameter of BLSURF algo - self.Parameters().SetGeoMin(theVal) + if self.Parameters(): + # Parameter of BLSURF algo + self.params.SetGeoMin(theVal) ## Sets upper boundary of mesh element size computed to respect angular deflection. # @ingroup l3_hypos_blsurf def SetGeoMax(self, theVal=-1): - # Parameter of BLSURF algo - self.Parameters().SetGeoMax(theVal) + if self.Parameters(): + # Parameter of BLSURF algo + self.params.SetGeoMax(theVal) ## Sets maximal allowed ratio between the lengths of two adjacent edges. # @ingroup l3_hypos_blsurf def SetGradation(self, theVal=_gradation): - # Parameter of BLSURF algo - if self.Parameters().GetGeometricMesh() == 0: theVal = self._gradation - self.params.SetGradation(theVal) + if self.Parameters(): + # Parameter of BLSURF algo + if self.params.GetGeometricMesh() == 0: theVal = self._gradation + self.params.SetGradation(theVal) ## Sets topology usage way. # @param way defines how mesh conformity is assured + #
  • PreProcess or PreProcessPlus - by pre-processing a CAD model
  • + #
  • PreCAD - by pre-processing with PreCAD a CAD model
  • # @ingroup l3_hypos_blsurf def SetTopology(self, way): - # Parameter of BLSURF algo - self.Parameters().SetTopology(way) + if self.Parameters(): + # Parameter of BLSURF algo + self.params.SetTopology(way) ## To respect geometrical edges or not. # @ingroup l3_hypos_blsurf def SetDecimesh(self, toIgnoreEdges=False): - # Parameter of BLSURF algo - self.Parameters().SetDecimesh(toIgnoreEdges) + if self.Parameters(): + # Parameter of BLSURF algo + self.params.SetDecimesh(toIgnoreEdges) ## Sets verbosity level in the range 0 to 100. # @ingroup l3_hypos_blsurf def SetVerbosity(self, level): - # Parameter of BLSURF algo - self.Parameters().SetVerbosity(level) + if self.Parameters(): + # Parameter of BLSURF algo + self.params.SetVerbosity(level) + + ## To optimize merges edges. + # @ingroup l3_hypos_blsurf + def SetPreCADMergeEdges(self, toMergeEdges=False): + if self.Parameters(): + # Parameter of BLSURF algo + self.params.SetPreCADMergeEdges(toMergeEdges) + + ## To remove nano edges. + # @ingroup l3_hypos_blsurf + def SetPreCADRemoveNanoEdges(self, toRemoveNanoEdges=False): + if self.Parameters(): + # Parameter of BLSURF algo + self.params.SetPreCADRemoveNanoEdges(toRemoveNanoEdges) + + ## To compute topology from scratch + # @ingroup l3_hypos_blsurf + def SetPreCADDiscardInput(self, toDiscardInput=False): + if self.Parameters(): + # Parameter of BLSURF algo + self.params.SetPreCADDiscardInput(toDiscardInput) + + ## Sets the length below which an edge is considered as nano + # for the topology processing. + # @ingroup l3_hypos_blsurf + def SetPreCADEpsNano(self, epsNano): + if self.Parameters(): + # Parameter of BLSURF algo + self.params.SetPreCADEpsNano(epsNano) ## Sets advanced option value. # @ingroup l3_hypos_blsurf def SetOptionValue(self, optionName, level): - # Parameter of BLSURF algo - self.Parameters().SetOptionValue(optionName,level) + if self.Parameters(): + # Parameter of BLSURF algo + self.params.SetOptionValue(optionName,level) + + ## Sets advanced PreCAD option value. + # Keyword arguments: + # optionName: name of the option + # optionValue: value of the option + # @ingroup l3_hypos_blsurf + def SetPreCADOptionValue(self, optionName, optionValue): + if self.Parameters(): + # Parameter of BLSURF algo + self.params.SetPreCADOptionValue(optionName,optionValue) + + ## Sets GMF file for export at computation + # @ingroup l3_hypos_blsurf + def SetGMFFile(self, fileName): + if self.Parameters(): + # Parameter of BLSURF algo + self.params.SetGMFFile(fileName) + + ## Enforced vertices (BLSURF) + + ## To get all the enforced vertices + # @ingroup l3_hypos_blsurf + def GetAllEnforcedVertices(self): + if self.Parameters(): + # Parameter of BLSURF algo + return self.params.GetAllEnforcedVertices() + + ## To get all the enforced vertices sorted by face (or group, compound) + # @ingroup l3_hypos_blsurf + def GetAllEnforcedVerticesByFace(self): + if self.Parameters(): + # Parameter of BLSURF algo + return self.params.GetAllEnforcedVerticesByFace() + + ## To get all the enforced vertices sorted by coords of input vertices + # @ingroup l3_hypos_blsurf + def GetAllEnforcedVerticesByCoords(self): + if self.Parameters(): + # Parameter of BLSURF algo + return self.params.GetAllEnforcedVerticesByCoords() + + ## To get all the coords of input vertices sorted by face (or group, compound) + # @ingroup l3_hypos_blsurf + def GetAllCoordsByFace(self): + if self.Parameters(): + # Parameter of BLSURF algo + return self.params.GetAllCoordsByFace() + + ## To get all the enforced vertices on a face (or group, compound) + # @param theFace : GEOM face (or group, compound) on which to define an enforced vertex + # @ingroup l3_hypos_blsurf + def GetEnforcedVertices(self, theFace): + if self.Parameters(): + # Parameter of BLSURF algo + AssureGeomPublished( self.mesh, theFace ) + return self.params.GetEnforcedVertices(theFace) + + ## To clear all the enforced vertices + # @ingroup l3_hypos_blsurf + def ClearAllEnforcedVertices(self): + if self.Parameters(): + # Parameter of BLSURF algo + return self.params.ClearAllEnforcedVertices() + + ## To set an enforced vertex on a face (or group, compound) given the coordinates of a point. If the point is not on the face, it will projected on it. If there is no projection, no enforced vertex is created. + # @param theFace : GEOM face (or group, compound) on which to define an enforced vertex + # @param x : x coordinate + # @param y : y coordinate + # @param z : z coordinate + # @param vertexName : name of the enforced vertex + # @param groupName : name of the group + # @ingroup l3_hypos_blsurf + def SetEnforcedVertex(self, theFace, x, y, z, vertexName = "", groupName = ""): + if self.Parameters(): + # Parameter of BLSURF algo + AssureGeomPublished( self.mesh, theFace ) + if vertexName == "": + if groupName == "": + return self.params.SetEnforcedVertex(theFace, x, y, z) + else: + return self.params.SetEnforcedVertexWithGroup(theFace, x, y, z, groupName) + else: + if groupName == "": + return self.params.SetEnforcedVertexNamed(theFace, x, y, z, vertexName) + else: + return self.params.SetEnforcedVertexNamedWithGroup(theFace, x, y, z, vertexName, groupName) + + ## To set an enforced vertex on a face (or group, compound) given a GEOM vertex, group or compound. + # @param theFace : GEOM face (or group, compound) on which to define an enforced vertex + # @param theVertex : GEOM vertex (or group, compound) to be projected on theFace. + # @param groupName : name of the group + # @ingroup l3_hypos_blsurf + def SetEnforcedVertexGeom(self, theFace, theVertex, groupName = ""): + if self.Parameters(): + # Parameter of BLSURF algo + AssureGeomPublished( self.mesh, theFace ) + AssureGeomPublished( self.mesh, theVertex ) + if groupName == "": + return self.params.SetEnforcedVertexGeom(theFace, theVertex) + else: + return self.params.SetEnforcedVertexGeomWithGroup(theFace, theVertex,groupName) + + ## To remove an enforced vertex on a given GEOM face (or group, compound) given the coordinates. + # @param theFace : GEOM face (or group, compound) on which to remove the enforced vertex + # @param x : x coordinate + # @param y : y coordinate + # @param z : z coordinate + # @ingroup l3_hypos_blsurf + def UnsetEnforcedVertex(self, theFace, x, y, z): + if self.Parameters(): + # Parameter of BLSURF algo + AssureGeomPublished( self.mesh, theFace ) + return self.params.UnsetEnforcedVertex(theFace, x, y, z) + + ## To remove an enforced vertex on a given GEOM face (or group, compound) given a GEOM vertex, group or compound. + # @param theFace : GEOM face (or group, compound) on which to remove the enforced vertex + # @param theVertex : GEOM vertex (or group, compound) to remove. + # @ingroup l3_hypos_blsurf + def UnsetEnforcedVertexGeom(self, theFace, theVertex): + if self.Parameters(): + # Parameter of BLSURF algo + AssureGeomPublished( self.mesh, theFace ) + AssureGeomPublished( self.mesh, theVertex ) + return self.params.UnsetEnforcedVertexGeom(theFace, theVertex) + + ## To remove all enforced vertices on a given face. + # @param theFace : face (or group/compound of faces) on which to remove all enforced vertices + # @ingroup l3_hypos_blsurf + def UnsetEnforcedVertices(self, theFace): + if self.Parameters(): + # Parameter of BLSURF algo + AssureGeomPublished( self.mesh, theFace ) + return self.params.UnsetEnforcedVertices(theFace) + + ## Attractors (BLSURF) + + ## Sets an attractor on the chosen face. The mesh size will decrease exponentially with the distance from theAttractor, following the rule h(d) = theEndSize - (theEndSize - theStartSize) * exp [ - ( d / theInfluenceDistance ) ^ 2 ] + # @param theFace : face on which the attractor will be defined + # @param theAttractor : geometrical object from which the mesh size "h" decreases exponentially + # @param theStartSize : mesh size on theAttractor + # @param theEndSize : maximum size that will be reached on theFace + # @param theInfluenceDistance : influence of the attractor ( the size grow slower on theFace if it's high) + # @param theConstantSizeDistance : distance until which the mesh size will be kept constant on theFace + # @ingroup l3_hypos_blsurf + def SetAttractorGeom(self, theFace, theAttractor, theStartSize, theEndSize, theInfluenceDistance, theConstantSizeDistance): + if self.Parameters(): + # Parameter of BLSURF algo + AssureGeomPublished( self.mesh, theFace ) + AssureGeomPublished( self.mesh, theAttractor ) + self.params.SetAttractorGeom(theFace, theAttractor, theStartSize, theEndSize, theInfluenceDistance, theConstantSizeDistance) + + ## Unsets an attractor on the chosen face. + # @param theFace : face on which the attractor has to be removed + # @ingroup l3_hypos_blsurf + def UnsetAttractorGeom(self, theFace): + if self.Parameters(): + # Parameter of BLSURF algo + AssureGeomPublished( self.mesh, theFace ) + self.params.SetAttractorGeom(theFace) + + ## Size maps (BLSURF) + + ## To set a size map on a face, edge or vertex (or group, compound) given Python function. + # If theObject is a face, the function can be: def f(u,v): return u+v + # If theObject is an edge, the function can be: def f(t): return t/2 + # If theObject is a vertex, the function can be: def f(): return 10 + # @param theObject : GEOM face, edge or vertex (or group, compound) on which to define a size map + # @param theSizeMap : Size map defined as a string + # @ingroup l3_hypos_blsurf + def SetSizeMap(self, theObject, theSizeMap): + if self.Parameters(): + # Parameter of BLSURF algo + AssureGeomPublished( self.mesh, theObject ) + return self.params.SetSizeMap(theObject, theSizeMap) + + ## To remove a size map defined on a face, edge or vertex (or group, compound) + # @param theObject : GEOM face, edge or vertex (or group, compound) on which to define a size map + # @ingroup l3_hypos_blsurf + def UnsetSizeMap(self, theObject): + if self.Parameters(): + # Parameter of BLSURF algo + AssureGeomPublished( self.mesh, theObject ) + return self.params.UnsetSizeMap(theObject) + + ## To remove all the size maps + # @ingroup l3_hypos_blsurf + def ClearSizeMaps(self): + if self.Parameters(): + # Parameter of BLSURF algo + return self.params.ClearSizeMaps() + ## Sets QuadAllowed flag. # Only for algoType == NETGEN(NETGEN_1D2D) || NETGEN_2D || BLSURF @@ -5260,7 +5750,7 @@ class Mesh_Tetrahedron(Mesh_Algorithm): self.params = self.Hypothesis("NETGEN_Parameters", [], "libNETGENEngine.so", UseExisting=0) - if self.algoType == NETGEN: + elif self.algoType == NETGEN: self.params = self.Hypothesis("NETGEN_Parameters_3D", [], "libNETGENEngine.so", UseExisting=0) @@ -5272,7 +5762,7 @@ class Mesh_Tetrahedron(Mesh_Algorithm): self.params = self.Hypothesis("GHS3DPRL_Parameters", [], "libGHS3DPRLEngine.so", UseExisting=0) else: - print "Algo supports no multi-parameter hypothesis" + print "Warning: %s supports no multi-parameter hypothesis"%self.algo.GetName() return self.params @@ -5357,7 +5847,8 @@ class Mesh_Tetrahedron(Mesh_Algorithm): # @ingroup l3_hypos_ghs3dh def SetToMeshHoles(self, toMesh): # Parameter of GHS3D - self.Parameters().SetToMeshHoles(toMesh) + if self.Parameters(): + self.params.SetToMeshHoles(toMesh) ## Set Optimization level: # None_Optimization, Light_Optimization, Standard_Optimization, StandardPlus_Optimization, @@ -5366,32 +5857,37 @@ class Mesh_Tetrahedron(Mesh_Algorithm): # @ingroup l3_hypos_ghs3dh def SetOptimizationLevel(self, level): # Parameter of GHS3D - self.Parameters().SetOptimizationLevel(level) + if self.Parameters(): + self.params.SetOptimizationLevel(level) ## Maximal size of memory to be used by the algorithm (in Megabytes). # @ingroup l3_hypos_ghs3dh def SetMaximumMemory(self, MB): # Advanced parameter of GHS3D - self.Parameters().SetMaximumMemory(MB) + if self.Parameters(): + self.params.SetMaximumMemory(MB) ## Initial size of memory to be used by the algorithm (in Megabytes) in # automatic memory adjustment mode. # @ingroup l3_hypos_ghs3dh def SetInitialMemory(self, MB): # Advanced parameter of GHS3D - self.Parameters().SetInitialMemory(MB) + if self.Parameters(): + self.params.SetInitialMemory(MB) ## Path to working directory. # @ingroup l3_hypos_ghs3dh def SetWorkingDirectory(self, path): # Advanced parameter of GHS3D - self.Parameters().SetWorkingDirectory(path) + if self.Parameters(): + self.params.SetWorkingDirectory(path) ## To keep working files or remove them. Log file remains in case of errors anyway. # @ingroup l3_hypos_ghs3dh def SetKeepFiles(self, toKeep): # Advanced parameter of GHS3D and GHS3DPRL - self.Parameters().SetKeepFiles(toKeep) + if self.Parameters(): + self.params.SetKeepFiles(toKeep) ## To set verbose level [0-10].