smesh/src/SMESH_SWIG/smesh_algorithm.py
2012-10-08 11:56:59 +00:00

323 lines
14 KiB
Python

# Copyright (C) 2007-2012 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 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
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
## @package smesh_algorithm
# Python API for base Mesh_Algorithm class.
# This package is a part of SALOME %Mesh module Python API
import salome
import geompyDC
import SMESH
## 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 StdMeshersDC.StdMeshersDC_Segment "StdMeshersDC_Segment"
# in StdMeshersDC 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 invokation 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:
## Private constuctor
def __init__(self):
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()
#to do: find component by smeshpyD object, not by its data type
scomp = study.FindComponent(smeshpyD.ComponentDataType())
if scomp is not None:
res,hypRoot = scomp.FindSubObject(SMESH.Tag_HypothesisRoot)
# Check if the root label of the hypotheses exists
if res and hypRoot is not None:
iter = study.NewChildIterator(hypRoot)
# Check all published hypotheses
while iter.More():
hypo_so_i = iter.Value()
attr = hypo_so_i.FindAttribute("AttributeIOR")[1]
if attr is not None:
anIOR = attr.Value()
hypo_o_i = salome.orb.string_to_object(anIOR)
if hypo_o_i is not None:
# Check if this is a hypothesis
hypo_i = hypo_o_i._narrow(SMESH.SMESH_Hypothesis)
if hypo_i is not None:
# Check if the hypothesis belongs to current engine
if smeshpyD.GetObjectId(hypo_i) > 0:
# Check if this is the required hypothesis
if hypo_i.GetName() == hypname:
# Check arguments
if CompareMethod(hypo_i, args):
# found!!!
return hypo_i
pass
pass
pass
pass
pass
iter.Next()
pass
pass
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()
if not study: return None
#to do: find component by smeshpyD object, not by its data type
scomp = study.FindComponent(smeshpyD.ComponentDataType())
if scomp is not None:
res,hypRoot = scomp.FindSubObject(SMESH.Tag_AlgorithmsRoot)
# Check if the root label of the algorithms exists
if res and hypRoot is not None:
iter = study.NewChildIterator(hypRoot)
# Check all published algorithms
while iter.More():
algo_so_i = iter.Value()
attr = algo_so_i.FindAttribute("AttributeIOR")[1]
if attr is not None:
anIOR = attr.Value()
algo_o_i = salome.orb.string_to_object(anIOR)
if algo_o_i is not None:
# Check if this is an algorithm
algo_i = algo_o_i._narrow(SMESH.SMESH_Algo)
if algo_i is not None:
# Checks if the algorithm belongs to the current engine
if smeshpyD.GetObjectId(algo_i) > 0:
# Check if this is the required algorithm
if algo_i.GetName() == algoname:
# found!!!
return algo_i
pass
pass
pass
pass
iter.Next()
pass
pass
pass
return None
## If the algorithm is global, returns 0; \n
# else returns the submesh associated to this algorithm.
def GetSubMesh(self):
return self.subm
## Returns the wrapped mesher.
def GetAlgorithm(self):
return self.algo
## Gets the list of hypothesis that can be used with this algorithm
def GetCompatibleHypothesis(self):
mylist = []
if self.algo:
mylist = self.algo.GetCompatibleHypothesis()
return mylist
## Gets the name of the algorithm
def GetName(self):
from smesh import GetName
return GetName(self.algo)
## Sets the name to the algorithm
def SetName(self, name):
self.mesh.smeshpyD.SetName(self.algo, name)
## Gets the id of the algorithm
def GetId(self):
return self.algo.GetId()
## Private method.
def Create(self, mesh, geom, hypo, so="libStdMeshersEngine.so"):
if geom is None:
raise RuntimeError, "Attemp to create " + hypo + " algoritm on None shape"
algo = self.FindAlgorithm(hypo, mesh.smeshpyD)
if algo is None:
algo = mesh.smeshpyD.CreateHypothesis(hypo, so)
pass
self.Assign(algo, mesh, geom)
return self.algo
## Private method
def Assign(self, algo, mesh, geom):
from smesh import AssureGeomPublished, TreatHypoStatus, GetName
if geom is None:
raise RuntimeError, "Attemp to create " + algo + " algoritm on None shape"
self.mesh = mesh
name = ""
if not geom:
self.geom = mesh.geom
else:
self.geom = geom
AssureGeomPublished( mesh, geom )
try:
name = GetName(geom)
pass
except:
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()
return False
def CompareEqualHyp (self, hyp, args):
return True
## Private method
def Hypothesis (self, hyp, args=[], so="libStdMeshersEngine.so",
UseExisting=0, CompareMethod=""):
from smesh import TreatHypoStatus, GetName
hypo = None
if UseExisting:
if CompareMethod == "": CompareMethod = self.CompareHyp
hypo = self.FindHypothesis(hyp, args, CompareMethod, self.mesh.smeshpyD)
pass
if hypo is None:
hypo = self.mesh.smeshpyD.CreateHypothesis(hyp, so)
a = ""
s = "="
for arg in args:
argStr = str(arg)
if isinstance( arg, geompyDC.GEOM._objref_GEOM_Object ):
argStr = arg.GetStudyEntry()
if not argStr: argStr = "GEOM_Obj_%s", arg.GetEntry()
if len( argStr ) > 10:
argStr = argStr[:7]+"..."
if argStr[0] == '[': argStr += ']'
a = a + s + argStr
s = ","
pass
if len(a) > 50:
a = a[:47]+"..."
self.mesh.smeshpyD.SetName(hypo, hyp + a)
pass
geomName=""
if self.geom:
geomName = GetName(self.geom)
status = self.mesh.mesh.AddHypothesis(self.geom, hypo)
TreatHypoStatus( status, GetName(hypo), geomName, 0 )
return hypo
## Returns entry of the shape to mesh in the study
def MainShapeEntry(self):
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, GHS3D, 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 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):
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()
if ignoreFaces and isinstance( ignoreFaces[0], geompyDC.GEOM._objref_GEOM_Object ):
ignoreFaces = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f) for f in ignoreFaces ]
hyp = self.Hypothesis("ViscousLayers",
[thickness, numberOfLayers, stretchFactor, ignoreFaces])
hyp.SetTotalThickness(thickness)
hyp.SetNumberLayers(numberOfLayers)
hyp.SetStretchFactor(stretchFactor)
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):
from smesh import FirstVertexOnCurve
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