-# Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2020 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
from salome.geom import geomBuilder
import SMESH, StdMeshers
-## The base class to define meshing algorithms
-#
-# @note This class should not be used directly, it is supposed to be sub-classed
-# for implementing Python API for specific meshing algorithms
-#
-# For each meshing algorithm, a python class inheriting from class %Mesh_Algorithm
-# should be defined. This descendant class should have two attributes defining the way
-# it is created by class Mesh (see e.g. class @ref StdMeshersBuilder.StdMeshersBuilder_Segment "StdMeshersBuilder_Segment"
-# in StdMeshersBuilder package):
-# - @c meshMethod attribute defines name of method of class smesh.Mesh by calling which the
-# python class of algorithm is created; this method is dynamically added to the smesh.Mesh class
-# in runtime. For example, if in @c class MyPlugin_Algorithm this attribute is defined as
-# @code
-# meshMethod = "MyAlgorithm"
-# @endcode
-# then an instance of @c MyPlugin_Algorithm can be created by the direct invocation of the function
-# of smesh.Mesh class:
-# @code
-# my_algo = mesh.MyAlgorithm()
-# @endcode
-# - @c algoType defines type of algorithm and is used mostly to discriminate
-# algorithms that are created by the same method of class smesh.Mesh. For example, if this attribute
-# is specified in @c MyPlugin_Algorithm class as
-# @code
-# algoType = "MyPLUGIN"
-# @endcode
-# then it's creation code can be:
-# @code
-# my_algo = mesh.MyAlgorithm(algo="MyPLUGIN")
-# @endcode
-# @ingroup l2_algorithms
class Mesh_Algorithm:
+ """
+ The base class to define meshing algorithms
+
+ Note:
+ This class should not be used directly, it is supposed to be sub-classed
+ for implementing Python API for specific meshing algorithms
+
+ For each meshing algorithm, a python class inheriting from class *Mesh_Algorithm*
+ should be defined. This descendant class should have two attributes defining the way
+ it is created by class :class:`~smeshBuilder.Mesh` (see e.g. class :class:`~StdMeshersBuilder.StdMeshersBuilder_Segment`):
+
+ - :code:`meshMethod` attribute defines name of method of class :class:`~smeshBuilder.Mesh` by calling which the
+ python class of algorithm is created; this method is dynamically added to the :class:`~smeshBuilder.Mesh` class
+ in runtime. For example, if in :code:`class MyPlugin_Algorithm` this attribute is defined as::
+
+ meshMethod = "MyAlgorithm"
+
+ then an instance of :code:`MyPlugin_Algorithm` can be created by the direct invocation of the function
+ of :class:`~smeshBuilder.Mesh` class::
+
+ my_algo = mesh.MyAlgorithm()
+
+ - :code:`algoType` defines type of algorithm and is used mostly to discriminate
+ algorithms that are created by the same method of class :class:`~smeshBuilder.Mesh`. For example, if this attribute
+ is specified in :code:`MyPlugin_Algorithm` class as::
+
+ algoType = "MyPLUGIN"
+
+ then it's creation code can be::
+
+ my_algo = mesh.MyAlgorithm(algo="MyPLUGIN")
+ """
+
- ## Private constuctor
def __init__(self):
+ """
+ Private constructor
+ """
self.mesh = None
self.geom = None
self.subm = None
self.algo = None
pass
- ## Finds a hypothesis in the study by its type name and parameters.
- # Finds only the hypotheses created in smeshpyD engine.
- # @return SMESH.SMESH_Hypothesis
def FindHypothesis (self, hypname, args, CompareMethod, smeshpyD):
- study = smeshpyD.GetCurrentStudy()
+ """
+ Finds a hypothesis in the study by its type name and parameters.
+ Finds only the hypotheses created in smeshBuilder engine.
+
+ Returns:
+ :class:`~SMESH.SMESH_Hypothesis`
+ """
+ study = salome.myStudy
if not study: return None
#to do: find component by smeshpyD object, not by its data type
scomp = study.FindComponent(smeshpyD.ComponentDataType())
attr = hypo_so_i.FindAttribute("AttributeIOR")[1]
if attr is not None:
anIOR = attr.Value()
+ if not anIOR: continue # prevent exception in orb.string_to_object()
hypo_o_i = salome.orb.string_to_object(anIOR)
if hypo_o_i is not None:
# Check if this is a hypothesis
pass
return None
- ## Finds the algorithm in the study by its type name.
- # Finds only the algorithms, which have been created in smeshpyD engine.
- # @return SMESH.SMESH_Algo
def FindAlgorithm (self, algoname, smeshpyD):
- study = smeshpyD.GetCurrentStudy()
+ """
+ Finds the algorithm in the study by its type name.
+ Finds only the algorithms, which have been created in smeshBuilder engine.
+
+ Returns:
+ SMESH.SMESH_Algo
+ """
+ study = salome.myStudy
if not study: return None
#to do: find component by smeshpyD object, not by its data type
scomp = study.FindComponent(smeshpyD.ComponentDataType())
attr = algo_so_i.FindAttribute("AttributeIOR")[1]
if attr is not None:
anIOR = attr.Value()
+ if not anIOR: continue # prevent exception in orb.string_to_object()
algo_o_i = salome.orb.string_to_object(anIOR)
if algo_o_i is not None:
# Check if this is an algorithm
pass
return None
- ## If the algorithm is global, returns 0; \n
- # else returns the submesh associated to this algorithm.
def GetSubMesh(self):
+ """
+ If the algorithm is global, returns 0;
+ else returns the :class:`~SMESH.SMESH_subMesh` associated to this algorithm.
+ """
return self.subm
- ## Returns the wrapped mesher.
def GetAlgorithm(self):
+ """
+ Returns the wrapped mesher.
+ """
return self.algo
- ## Gets the list of hypothesis that can be used with this algorithm
def GetCompatibleHypothesis(self):
+ """
+ Gets the list of hypothesis that can be used with this algorithm
+ """
mylist = []
if self.algo:
mylist = self.algo.GetCompatibleHypothesis()
return mylist
- ## Gets the name of the algorithm
def GetName(self):
+ """
+ Gets the name of the algorithm
+ """
from salome.smesh.smeshBuilder import GetName
return GetName(self.algo)
- ## Sets the name to the algorithm
def SetName(self, name):
+ """
+ Sets the name to the algorithm
+ """
self.mesh.smeshpyD.SetName(self.algo, name)
- ## Gets the id of the algorithm
def GetId(self):
+ """
+ Gets the id of the algorithm
+ """
return self.algo.GetId()
- ## Private method.
def Create(self, mesh, geom, hypo, so="libStdMeshersEngine.so"):
+ """
+ Private method.
+ """
if geom is None and mesh.mesh.HasShapeToMesh():
- raise RuntimeError, "Attemp to create " + hypo + " algoritm on None shape"
+ raise RuntimeError("Attempt to create " + hypo + " algorithm on None shape")
algo = self.FindAlgorithm(hypo, mesh.smeshpyD)
if algo is None:
algo = mesh.smeshpyD.CreateHypothesis(hypo, so)
self.Assign(algo, mesh, geom)
return self.algo
- ## Private method
def Assign(self, algo, mesh, geom):
+ """
+ Private method
+ """
from salome.smesh.smeshBuilder import AssureGeomPublished, TreatHypoStatus, GetName
if geom is None and mesh.mesh.HasShapeToMesh():
- raise RuntimeError, "Attemp to create " + algo + " algoritm on None shape"
+ raise RuntimeError("Attempt to create " + algo + " algorithm on None shape")
self.mesh = mesh
if not geom or geom.IsSame( mesh.geom ):
self.geom = mesh.geom
return
def CompareHyp (self, hyp, args):
- print "CompareHyp is not implemented for ", self.__class__.__name__, ":", hyp.GetName()
+ print("CompareHyp is not implemented for ", self.__class__.__name__, ":", hyp.GetName())
return False
def CompareEqualHyp (self, hyp, args):
return True
- ## Private method
def Hypothesis (self, hyp, args=[], so="libStdMeshersEngine.so",
UseExisting=0, CompareMethod="", toAdd=True):
+ """
+ Private method
+ """
from salome.smesh.smeshBuilder import TreatHypoStatus, GetName
hypo = None
if UseExisting:
TreatHypoStatus( status, GetName(hypo), geomName, 0, self.mesh )
return hypo
- ## Returns entry of the shape to mesh in the study
def MainShapeEntry(self):
+ """
+ Returns entry of the shape to mesh in the study
+ """
if not self.mesh or not self.mesh.GetMesh(): return ""
if not self.mesh.GetMesh().HasShapeToMesh(): return ""
shape = self.mesh.GetShape()
return shape.GetStudyEntry()
- ## Defines "ViscousLayers" hypothesis to give parameters of layers of prisms to build
- # near mesh boundary. This hypothesis can be used by several 3D algorithms:
- # NETGEN 3D, MG-Tetra, Hexahedron(i,j,k)
- # @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 faces list of geometrical faces (or their ids).
- # Viscous layers are either generated on these faces or not, depending on
- # the value of \a isFacesToIgnore parameter.
- # @param isFacesToIgnore if \c True, the Viscous layers are not generated on the
- # faces specified by the previous parameter (\a faces).
- # @param extrMethod extrusion method defines how position of nodes are found during
- # prism construction and how creation of distorted and intersecting prisms is
- # prevented. Possible values are:
- # - StdMeshers.SURF_OFFSET_SMOOTH (default) method extrudes nodes along normal
- # to underlying geometrical surface. Smoothing of internal surface of
- # element layers can be used to avoid creation of invalid prisms.
- # - StdMeshers.FACE_OFFSET method extrudes nodes along average normal of
- # surrounding mesh faces till intersection with a neighbor mesh face
- # translated along its own normal by the layers thickness. Thickness
- # of layers can be limited to avoid creation of invalid prisms.
- # - StdMeshers.NODE_OFFSET method extrudes nodes along average normal of
- # surrounding mesh faces by the layers thickness. Thickness of
- # layers can be limited to avoid creation of invalid prisms.
- # @ingroup l3_hypos_additi
def ViscousLayers(self, thickness, numberOfLayers, stretchFactor,
- faces=[], isFacesToIgnore=True, extrMethod=StdMeshers.SURF_OFFSET_SMOOTH ):
+ faces=[], isFacesToIgnore=True,
+ extrMethod=StdMeshers.SURF_OFFSET_SMOOTH, groupName=""):
+ """
+ Defines "ViscousLayers" hypothesis to give parameters of layers of prisms to build
+ near mesh boundary. This hypothesis can be used by several 3D algorithms:
+ NETGEN 3D, MG-Tetra, Hexahedron(i,j,k)
+
+ Parameters:
+ thickness: total thickness of layers of prisms
+ numberOfLayers: number of layers of prisms
+ stretchFactor: factor (>1.0) of growth of layer thickness towards inside of mesh
+ faces: list of geometrical faces (or their ids).
+ Viscous layers are either generated on these faces or not, depending on
+ the value of **isFacesToIgnore** parameter.
+ isFacesToIgnore: if *True*, the Viscous layers are not generated on the
+ faces specified by the previous parameter (**faces**).
+ extrMethod: extrusion method defines how position of new nodes are found during
+ prism construction and how creation of distorted and intersecting prisms is
+ prevented. Possible values are:
+
+ - StdMeshers.SURF_OFFSET_SMOOTH (default) method extrudes nodes along normal
+ to underlying geometrical surface. Smoothing of internal surface of
+ element layers can be used to avoid creation of invalid prisms.
+ - StdMeshers.FACE_OFFSET method extrudes nodes along average normal of
+ surrounding mesh faces till intersection with a neighbor mesh face
+ translated along its own normal by the layers thickness. Thickness
+ of layers can be limited to avoid creation of invalid prisms.
+ - StdMeshers.NODE_OFFSET method extrudes nodes along average normal of
+ surrounding mesh faces by the layers thickness. Thickness of
+ layers can be limited to avoid creation of invalid prisms.
+ groupName: name of a group to contain elements of layers. If not provided,
+ no group is created. The group is created upon mesh generation.
+ It can be retrieved by calling
+ ::
+
+ group = mesh.GetGroupByName( groupName, SMESH.VOLUME )[0]
+
+ Returns:
+ StdMeshers.StdMeshers_ViscousLayers hypothesis
+ """
+
if not isinstance(self.algo, SMESH._objref_SMESH_3D_Algo):
- raise TypeError, "ViscousLayers are supported by 3D algorithms only"
+ raise TypeError("ViscousLayers are supported by 3D algorithms only")
if not "ViscousLayers" in self.GetCompatibleHypothesis():
- raise TypeError, "ViscousLayers are not supported by %s"%self.algo.GetName()
+ raise TypeError("ViscousLayers are not supported by %s"%self.algo.GetName())
+ if faces and isinstance( faces, geomBuilder.GEOM._objref_GEOM_Object ):
+ faces = [ faces ]
if faces and isinstance( faces[0], geomBuilder.GEOM._objref_GEOM_Object ):
- import GEOM
faceIDs = []
- for f in faces:
- if self.mesh.geompyD.ShapeIdToType( f.GetType() ) == "GROUP":
- faceIDs += f.GetSubShapeIndices()
- else:
- faceIDs += [self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f)]
+ for shape in faces:
+ try:
+ ff = self.mesh.geompyD.SubShapeAll( shape, self.mesh.geompyD.ShapeType["FACE"] )
+ for f in ff:
+ faceIDs.append( self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f))
+ except:
+ # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
+ # simplification of access in geomBuilder: omniORB.registerObjref
+ from SHAPERSTUDY_utils import getEngine
+ gen = getEngine()
+ if gen:
+ aShapeOp = gen.GetIShapesOperations()
+ ff = aShapeOp.ExtractSubShapes( shape, self.mesh.geompyD.ShapeType["FACE"], False)
+ for f in ff:
+ faceIDs.append( aShapeOp.GetSubShapeIndex( self.mesh.geom, f ))
faces = faceIDs
hyp = self.Hypothesis("ViscousLayers",
[thickness, numberOfLayers, stretchFactor, faces, isFacesToIgnore],
hyp.SetStretchFactor( stretchFactor )
hyp.SetFaces( faces, isFacesToIgnore )
hyp.SetMethod( extrMethod )
+ hyp.SetGroupName( groupName )
self.mesh.AddHypothesis( hyp, self.geom )
return hyp
- ## Defines "ViscousLayers2D" hypothesis to give parameters of layers of quadrilateral
- # elements to build near mesh boundary. This hypothesis can be used by several 2D algorithms:
- # NETGEN 2D, NETGEN 1D-2D, Quadrangle (mapping), MEFISTO, MG-CADSurf
- # @param thickness total thickness of layers of quadrilaterals
- # @param numberOfLayers number of layers
- # @param stretchFactor factor (>1.0) of growth of layer thickness towards inside of mesh
- # @param edges list of geometrical edges (or their ids).
- # Viscous layers are either generated on these edges or not, depending on
- # the value of \a isEdgesToIgnore parameter.
- # @param isEdgesToIgnore if \c True, the Viscous layers are not generated on the
- # edges specified by the previous parameter (\a edges).
- # @ingroup l3_hypos_additi
def ViscousLayers2D(self, thickness, numberOfLayers, stretchFactor,
- edges=[], isEdgesToIgnore=True ):
+ edges=[], isEdgesToIgnore=True, groupName="" ):
+ """
+ Defines "ViscousLayers2D" hypothesis to give parameters of layers of quadrilateral
+ elements to build near mesh boundary. This hypothesis can be used by several 2D algorithms:
+ NETGEN 2D, NETGEN 1D-2D, Quadrangle (mapping), MEFISTO, MG-CADSurf
+
+ Parameters:
+ thickness: total thickness of layers of quadrilaterals
+ numberOfLayers: number of layers
+ stretchFactor: factor (>1.0) of growth of layer thickness towards inside of mesh
+ edges: list of geometrical edges (or their ids).
+ Viscous layers are either generated on these edges or not, depending on
+ the value of **isEdgesToIgnore** parameter.
+ isEdgesToIgnore: if *True*, the Viscous layers are not generated on the
+ edges specified by the previous parameter (**edges**).
+ groupName: name of a group to contain elements of layers. If not provided,
+ no group is created. The group is created upon mesh generation.
+ It can be retrieved by calling
+ ::
+
+ group = mesh.GetGroupByName( groupName, SMESH.FACE )[0]
+
+ Returns:
+ StdMeshers.StdMeshers_ViscousLayers2D hypothesis
+ """
+
if not isinstance(self.algo, SMESH._objref_SMESH_2D_Algo):
- raise TypeError, "ViscousLayers2D are supported by 2D algorithms only"
+ raise TypeError("ViscousLayers2D are supported by 2D algorithms only")
if not "ViscousLayers2D" in self.GetCompatibleHypothesis():
- raise TypeError, "ViscousLayers2D are not supported by %s"%self.algo.GetName()
+ raise TypeError("ViscousLayers2D are not supported by %s"%self.algo.GetName())
+ if edges and not isinstance( edges, list ) and not isinstance( edges, tuple ):
+ edges = [edges]
if edges and isinstance( edges[0], geomBuilder.GEOM._objref_GEOM_Object ):
- edges = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f) for f in edges ]
+ edgeIDs = []
+ for shape in edges:
+ try:
+ ee = self.mesh.geompyD.SubShapeAll( shape, self.mesh.geompyD.ShapeType["EDGE"])
+ for e in ee:
+ edgeIDs.append( self.mesh.geompyD.GetSubShapeID( self.mesh.geom, e ))
+ except:
+ # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
+ # simplification of access in geomBuilder: omniORB.registerObjref
+ from SHAPERSTUDY_utils import getEngine
+ gen = getEngine()
+ if gen:
+ aShapeOp = gen.GetIShapesOperations()
+ ee = aShapeOp.ExtractSubShapes( shape, self.mesh.geompyD.ShapeType["EDGE"], False)
+ for e in ee:
+ edgeIDs.append( aShapeOp.GetSubShapeIndex( self.mesh.geom, e ))
+ edges = edgeIDs
hyp = self.Hypothesis("ViscousLayers2D",
[thickness, numberOfLayers, stretchFactor, edges, isEdgesToIgnore],
toAdd=False)
hyp.SetNumberLayers(numberOfLayers)
hyp.SetStretchFactor(stretchFactor)
hyp.SetEdges(edges, isEdgesToIgnore)
+ hyp.SetGroupName( groupName )
self.mesh.AddHypothesis( hyp, self.geom )
return hyp
- ## Transform a list of either 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):
- from salome.smesh.smeshBuilder import FirstVertexOnCurve
+ """
+ Transform a list of either edges or tuples (edge, 1st_vertex_of_edge)
+ into a list acceptable to SetReversedEdges() of some 1D hypotheses
+ """
+
resList = []
geompy = self.mesh.geompyD
for i in reverseList:
if isinstance( i, int ):
- s = geompy.SubShapes(self.mesh.geom, [i])[0]
+ s = geompy.GetSubShape(self.mesh.geom, [i])
+
+ #bos #20082 begin:
+ if s is None and type(self.geom) != geomBuilder.GEOM._objref_GEOM_Object:
+ # try to get the SHAPERSTUDY engine directly, as GetGen does not work because of
+ # simplification of access in geomBuilder: omniORB.registerObjref
+ from SHAPERSTUDY_utils import getEngine
+ gen = getEngine()
+ if gen:
+ aShapeOp = gen.GetIShapesOperations()
+ s = aShapeOp.GetSubShape(self.mesh.geom, i)
+ #bos #20082 end
+
if s.GetShapeType() != geomBuilder.GEOM.EDGE:
- raise TypeError, "Not EDGE index given"
+ raise TypeError("Not EDGE index given")
resList.append( i )
elif isinstance( i, geomBuilder.GEOM._objref_GEOM_Object ):
if i.GetShapeType() != geomBuilder.GEOM.EDGE:
- raise TypeError, "Not an EDGE given"
+ 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, geomBuilder.GEOM._objref_GEOM_Object ) or \
not isinstance( v, geomBuilder.GEOM._objref_GEOM_Object ):
- raise TypeError, "A list item must be a tuple (edge, 1st_vertex_of_edge)"
+ raise TypeError("A list item must be a tuple (edge, 1st_vertex_of_edge)")
if v.GetShapeType() == geomBuilder.GEOM.EDGE and \
e.GetShapeType() == geomBuilder.GEOM.VERTEX:
v,e = e,v
if e.GetShapeType() != geomBuilder.GEOM.EDGE or \
v.GetShapeType() != geomBuilder.GEOM.VERTEX:
- raise TypeError, "A list item must be a tuple (edge, 1st_vertex_of_edge)"
- vFirst = FirstVertexOnCurve( self.mesh, e )
+ raise TypeError("A list item must be a tuple (edge, 1st_vertex_of_edge)")
+ vFirst = geompy.GetVertexByIndex( e, 0, False )
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)"
+ raise TypeError("Item must be either an edge or tuple (edge, 1st_vertex_of_edge)")
return resList