From b8fc64c6d71bf196b76b855ca89dd86267bd7478 Mon Sep 17 00:00:00 2001 From: vsr Date: Mon, 8 Oct 2012 13:15:52 +0000 Subject: [PATCH] Merge from V6_main (04/10/2012) --- doc/salome/gui/NETGENPLUGIN/Makefile.am | 17 +- doc/salome/gui/NETGENPLUGIN/doxyfile_py.in | 26 +- .../NETGENPLUGIN/input/netgen_2d_3d_hypo.doc | 27 +- .../input/netgenplugin_python_interface.doc | 6 +- src/GUI/NETGENPluginGUI_HypothesisCreator.cxx | 10 +- src/GUI/NETGENPluginGUI_SimpleCreator.cxx | 2 +- src/NETGENPlugin/NETGENPluginDC.py | 303 +++++++++++++----- .../NETGENPlugin_Hypothesis_2D.cxx | 94 +++--- .../NETGENPlugin_Hypothesis_2D.hxx | 14 +- src/NETGENPlugin/NETGENPlugin_Mesher.cxx | 77 ++++- src/NETGENPlugin/NETGENPlugin_NETGEN_2D.hxx | 5 +- src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.cxx | 11 +- src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.hxx | 11 +- .../NETGENPlugin_NETGEN_2D_ONLY.cxx | 25 +- .../NETGENPlugin_NETGEN_2D_ONLY.hxx | 4 +- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 27 +- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx | 2 +- 17 files changed, 437 insertions(+), 224 deletions(-) diff --git a/doc/salome/gui/NETGENPLUGIN/Makefile.am b/doc/salome/gui/NETGENPLUGIN/Makefile.am index c075ffe..2b360e8 100755 --- a/doc/salome/gui/NETGENPLUGIN/Makefile.am +++ b/doc/salome/gui/NETGENPLUGIN/Makefile.am @@ -29,16 +29,15 @@ EXTRA_DIST += images input static/footer.html static/doxygen.css guidocdir = $(docdir)/gui/NETGENPLUGIN guidoc_DATA = images/head.png +DOC_PYTHONPATH=$(prefix)/bin/salome:$(SMESH_ROOT_DIR)/bin/salome:$(SMESH_ROOT_DIR)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(MED_ROOT_DIR)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(GEOM_ROOT_DIR)/bin/salome:$(GEOM_ROOT_DIR)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(KERNEL_ROOT_DIR)/bin/salome:$(KERNEL_ROOT_DIR)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(OMNIORB_ROOT)/lib/python$(PYTHON_VERSION)/site-packages:$(OMNIORB_ROOT)/lib64/python$(PYTHON_VERSION)/site-packages +DOC_SMESH_MeshersList=NETGENPlugin -usr_docs: doxyfile - echo "===========================================" ; \ - echo "Generating Python interface documentation"; \ - echo "===========================================" ; \ - $(DOXYGEN) doxyfile_py \ - echo "===========================================" ; \ - echo "Generating GUI documentation" ; \ - echo "===========================================" ; \ - $(DOXYGEN) doxyfile ; +smesh.py: $(top_srcdir)/src/NETGENPlugin/NETGENPluginDC.py + @PYTHONPATH=$(DOC_PYTHONPATH):${PYTHONPATH} SMESH_MeshersList=$(DOC_SMESH_MeshersList) $(PYTHON) $(SMESH_ROOT_DIR)/bin/salome/collect_mesh_methods.py -d -o $@ NETGENPlugin + +usr_docs: doxyfile_py doxyfile smesh.py + @$(DOXYGEN) doxyfile_py ; \ + $(DOXYGEN) doxyfile docs: usr_docs diff --git a/doc/salome/gui/NETGENPLUGIN/doxyfile_py.in b/doc/salome/gui/NETGENPLUGIN/doxyfile_py.in index 58fba65..4863fbd 100755 --- a/doc/salome/gui/NETGENPLUGIN/doxyfile_py.in +++ b/doc/salome/gui/NETGENPLUGIN/doxyfile_py.in @@ -99,7 +99,9 @@ EXAMPLE_RECURSIVE = NO #--------------------------------------------------------------------------- #Input related options #--------------------------------------------------------------------------- -INPUT = @top_srcdir@/src/NETGENPlugin/NETGENPluginDC.py +INPUT = @top_srcdir@/src/NETGENPlugin/NETGENPluginDC.py \ + smesh.py \ + @SMESH_ROOT_DIR@/bin/salome/smesh_algorithm.py FILE_PATTERNS = IMAGE_PATH = @srcdir@/images RECURSIVE = NO @@ -132,24 +134,24 @@ GENERATE_RTF = NO #--------------------------------------------------------------------------- CLASS_DIAGRAMS = NO HIDE_UNDOC_RELATIONS = NO -HAVE_DOT = NO -CLASS_GRAPH = NO +HAVE_DOT = YES +CLASS_GRAPH = YES COLLABORATION_GRAPH = NO GROUP_GRAPHS = NO UML_LOOK = NO -TEMPLATE_RELATIONS = NO -INCLUDE_GRAPH = NO -INCLUDED_BY_GRAPH = NO +TEMPLATE_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES CALL_GRAPH = NO -GRAPHICAL_HIERARCHY = NO -DIRECTORY_GRAPH = NO -DOT_IMAGE_FORMAT = jpg +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png DOT_FONTNAME = Arial DOT_PATH = DOTFILE_DIRS = MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1200 -MAX_DOT_GRAPH_DEPTH = 0 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = NO @@ -159,4 +161,4 @@ DOT_CLEANUP = YES #External reference options #--------------------------------------------------------------------------- GENERATE_TAGFILE = netgenpluginpy_doc.tag -SEARCHENGINE = YES \ No newline at end of file +SEARCHENGINE = YES diff --git a/doc/salome/gui/NETGENPLUGIN/input/netgen_2d_3d_hypo.doc b/doc/salome/gui/NETGENPLUGIN/input/netgen_2d_3d_hypo.doc index 7a75cdd..87e31cb 100644 --- a/doc/salome/gui/NETGENPLUGIN/input/netgen_2d_3d_hypo.doc +++ b/doc/salome/gui/NETGENPLUGIN/input/netgen_2d_3d_hypo.doc @@ -24,8 +24,7 @@ algorithms - Min Size - minimum linear dimensions for mesh cells. It is ignored if it is more than Max Size. - Second Order - if this box is checked in, the algorithm will -create second order nodes on the mesh, which actually will become -\ref adding_quadratic_elements_page "Quadratic". +create second order nodes on the mesh, which will then become quadratic. - Fineness - ranging from Very Coarse to Very Fine allows to set the level of meshing detalization using the three parameters below. You can select Custom to define them manually. @@ -59,17 +58,18 @@ parameters allow defining the size of elements for each dimension. \b 1D group allows defining the size of 1D elements in either of two ways: -- Number of Segments has the same sense as \ref -number_of_segments_anchor "Number of segments" hypothesis with -equidistant distribution. -- Local Length has the same sense as \ref -average_length_anchor "Local Length" hypothesis. +- Number of Segments allows specifying number of segments, that +will split each edge, with equidistant distribution. +- Local Length can be applied for meshing of edges +composing geometrical object. Definition of this hypothesis +consists of setting required \b length of segments. \b 2D group allows defining the size of 2D elements -- Length from edges if checked in, acts like \ref -length_from_edges_anchor "Length from Edges" hypothesis, else -- Max. Element Area defines the maximum element area like \ref -max_element_area_anchor "Max Element Area" hypothesis. +- Length from edges if checked in, hypothesis forces building of +2D mesh segments having a length calculated as an average edge length +for a given wire, else +- Max. Element Area specifies expected maximum element area for +each 2d element. - Allow Quadrangles - allows to use quadrangle elements in a triangle 2D mesh. This checkbox is not present in Netgen 3D simple parameters because currently building a tetrahedral mesh with quadrangle faces is @@ -78,9 +78,8 @@ not possible. \b 3D groups allows defining the size of 3D elements. - Length from faces if checked in, the area of sides of volumic elements will be equal to an average area of 2D elements, else -- Max. Element Volume defines the maximum element volume like -\ref max_element_volume_hypo_page "Max Element Volume" -hypothesis. +- Max. Element Volume specifies expected maximum element volume +of each 3d element. \note Netgen algorithm does not strictly follow the input parameters. The actual mesh can be more or less dense than diff --git a/doc/salome/gui/NETGENPLUGIN/input/netgenplugin_python_interface.doc b/doc/salome/gui/NETGENPLUGIN/input/netgenplugin_python_interface.doc index 87905e7..f5f6ecd 100644 --- a/doc/salome/gui/NETGENPLUGIN/input/netgenplugin_python_interface.doc +++ b/doc/salome/gui/NETGENPLUGIN/input/netgenplugin_python_interface.doc @@ -2,9 +2,11 @@ \page netgenplugin_python_interface_page Python Interface -Python package \ref NETGENPluginDC "NETGENPlugin" defines several classes, destined for creation of the 2D and 3D meshes. +Python package NETGENPluginDC defines several classes, destined for +creation of the 2D and 3D meshes. -Documentation for NETGENPlugin package is available in linear form grouped by classes, declared in the NETGENPluginDC.py file. +NETGEN meshing plugin dynamically adds several methods to the +smesh.Mesh class to create meshing algorithms. Below you can see an example of usage of the NETGENPlugin package for mesh generation: diff --git a/src/GUI/NETGENPluginGUI_HypothesisCreator.cxx b/src/GUI/NETGENPluginGUI_HypothesisCreator.cxx index 58f599f..31b3f7e 100644 --- a/src/GUI/NETGENPluginGUI_HypothesisCreator.cxx +++ b/src/GUI/NETGENPluginGUI_HypothesisCreator.cxx @@ -389,13 +389,13 @@ bool NETGENPluginGUI_HypothesisCreator::readParamsFromHypo( NetgenHypothesisData h_data.myMinSize = h->GetMinSize(); h_data.myMinSizeVar = getVariableName("SetMinSize"); - if ( myIs2D ) + //if ( myIs2D ) { - NETGENPlugin::NETGENPlugin_Hypothesis_2D_var h_2d = - NETGENPlugin::NETGENPlugin_Hypothesis_2D::_narrow( initParamsHypothesis() ); + NETGENPlugin::NETGENPlugin_Hypothesis_var h = + NETGENPlugin::NETGENPlugin_Hypothesis::_narrow( initParamsHypothesis() ); - if ( !h_2d->_is_nil() ) - h_data.myAllowQuadrangles = h_2d->GetQuadAllowed(); + if ( !h->_is_nil() ) + h_data.myAllowQuadrangles = h->GetQuadAllowed(); } NETGENPluginGUI_HypothesisCreator* that = (NETGENPluginGUI_HypothesisCreator*)this; diff --git a/src/GUI/NETGENPluginGUI_SimpleCreator.cxx b/src/GUI/NETGENPluginGUI_SimpleCreator.cxx index 12fa4b8..ab9ef3d 100644 --- a/src/GUI/NETGENPluginGUI_SimpleCreator.cxx +++ b/src/GUI/NETGENPluginGUI_SimpleCreator.cxx @@ -253,7 +253,7 @@ void NETGENPluginGUI_SimpleCreator::retrieveParams() const // set values of hypothesis - SMESH::ListOfParameters_var aParameters = h->GetLastParameters(); + //SMESH::ListOfParameters_var aParameters = h->GetLastParameters(); // 1D int nbSeg = isCreation() ? dfltNbSeg : (int) h->GetNumberOfSegments(); diff --git a/src/NETGENPlugin/NETGENPluginDC.py b/src/NETGENPlugin/NETGENPluginDC.py index 9568df6..e4eab1f 100644 --- a/src/NETGENPlugin/NETGENPluginDC.py +++ b/src/NETGENPlugin/NETGENPluginDC.py @@ -17,7 +17,12 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -from smesh import Mesh_Algorithm, AssureGeomPublished, ParseParameters, IsEqual +## +# @package NETGENPluginDC +# Python API for the NETGEN meshing plug-in module. + +from smesh_algorithm import Mesh_Algorithm +from smesh import AssureGeomPublished, ParseParameters, IsEqual # import NETGENPlugin module if possible noNETGENPlugin = 0 @@ -27,71 +32,117 @@ except ImportError: noNETGENPlugin = 1 pass -# Types of algorithms +#---------------------------- +# Mesh algo type identifiers +#---------------------------- + +## Algorithm type: Netgen tetrahedron 3D algorithm, see NETGEN_3D_Algorithm NETGEN_3D = "NETGEN_3D" +## Algorithm type: Netgen tetrahedron 1D-2D-3D algorithm, see NETGEN_1D2D3D_Algorithm NETGEN_1D2D3D = "NETGEN_2D3D" +## Algorithm type: Netgen triangle 1D-2D algorithm, see NETGEN_1D2D_Algorithm NETGEN_1D2D = "NETGEN_2D" +## Algorithm type: Netgen triangle 2D algorithm, see NETGEN_2D_Only_Algorithm NETGEN_2D = "NETGEN_2D_ONLY" +## Algorithm type: Synonim of NETGEN_1D2D3D, see NETGEN_1D2D3D_Algorithm NETGEN_FULL = NETGEN_1D2D3D +## Algorithm type: Synonim of NETGEN_3D, see NETGEN_3D_Algorithm NETGEN = NETGEN_3D +## Algorithm type: Synonim of NETGEN_1D2D3D, see NETGEN_1D2D3D_Algorithm FULL_NETGEN = NETGEN_FULL +#---------------------------- +# Hypothesis type enumeration +#---------------------------- + +## Hypothesis type enumeration: complex hypothesis +# (full set of parameters can be specified), +# see NETGEN_Algorithm.Parameters() SOLE = 0 +## Hypothesis type enumeration: simple hypothesis +# (only major parameters are specified), +# see NETGEN_Algorithm.Parameters() SIMPLE = 1 +#---------------------- # Fineness enumeration +#---------------------- + +## Fineness enumeration: very coarse quality of mesh, +# see NETGEN_Algorithm.SetFineness() VeryCoarse = 0 +## Fineness enumeration: coarse quality of mesh, +# see NETGEN_Algorithm.SetFineness() Coarse = 1 +## Fineness enumeration: moderate quality of mesh, +# see NETGEN_Algorithm.SetFineness() Moderate = 2 +## Fineness enumeration: fine quality of mesh, +# see NETGEN_Algorithm.SetFineness() Fine = 3 +## Fineness enumeration: very fine quality of mesh, +# see NETGEN_Algorithm.SetFineness() VeryFine = 4 +## Fineness enumeration: custom quality of mesh specified by other parameters), +# see NETGEN_Algorithm.SetFineness() Custom = 5 +#---------------------- +# Algorithms +#---------------------- + ## Base of all NETGEN algorithms. # +# This class provides common methods for all algorithms implemented by NETGEN plugin. +# @note This class must not be instantiated directly. class NETGEN_Algorithm(Mesh_Algorithm): + ## Private constructor + # @param mesh parent mesh object algorithm is assigned to + # @param geom geometry (shape/sub-shape) algorithm is assigned to; + # if it is @c 0 (default), the algorithm is assigned to the main shape def __init__(self, mesh, geom=0): Mesh_Algorithm.__init__(self) if noNETGENPlugin: print "Warning: NETGENPlugin module unavailable" self.Create(mesh, geom, self.algoType, "libNETGENEngine.so") self.params = None + pass - ## Sets MaxSize - # + ## Sets @c MaxSize parameter + # @param theSize new value of the @c MaxSize parameter def SetMaxSize(self, theSize): - if self.Parameters(): - self.params.SetMaxSize(theSize) + if self.Parameters(): self.params.SetMaxSize(theSize) + pass - ## Sets MinSize - # + ## Sets @c MinSize parameter + # @param theSize new value of the @c MinSize parameter def SetMinSize(self, theSize): - if self.Parameters(): - self.params.SetMinSize(theSize) - + if self.Parameters(): self.params.SetMinSize(theSize) + pass - ## Sets Optimize flag - # + ## Sets @c Optimize flag + # @param theVal new value of the @c Optimize parameter def SetOptimize(self, theVal): - if self.Parameters(): - self.params.SetOptimize(theVal) + if self.Parameters(): self.params.SetOptimize(theVal) + pass - ## Sets Fineness - # @param theFineness is: - # VeryCoarse, Coarse, Moderate, Fine, VeryFine or Custom - # + ## Sets @c Fineness parameter + # @param theFineness new value of the @c Fineness parameter; it can be: + # @ref VeryCoarse, @ref Coarse, @ref Moderate, @ref Fine, @ref VeryFine or @ref Custom def SetFineness(self, theFineness): - if self.Parameters(): - self.params.SetFineness(theFineness) + if self.Parameters(): self.params.SetFineness(theFineness) + pass - ## Sets GrowthRate - # + ## Sets @c GrowthRate parameter + # @param theRate new value of the @c GrowthRate parameter def SetGrowthRate(self, theRate): - if self.Parameters(): - self.params.SetGrowthRate(theRate) + if self.Parameters(): self.params.SetGrowthRate(theRate) + pass - ## Defines hypothesis having several parameters - # + ## Creates meshing hypothesis according to the chosen algorithm type + # and initializes it with default parameters + # @param which hypothesis type; can be either @ref SOLE (default) or @ref SIMPLE + # @return hypothesis object def Parameters(self, which=SOLE): if self.algoType == NETGEN_1D2D: if which == SIMPLE: @@ -116,111 +167,161 @@ class NETGEN_Algorithm(Mesh_Algorithm): return self.params + pass # end of NETGEN_Algorithm class -## Defines a tetrahedron 1D-2D-3D algorithm -# It is created by calling Mesh.Triangle( NETGEN_1D2D3D, geom=0 ) +## Tetrahedron 1D-2D-3D algorithm. # +# It can be created by calling smesh.Mesh.Tetrahedron( smesh.NETGEN_1D2D3D, geom=0 ). +# This algorithm generates all 1D (edges), 2D (faces) and 3D (volumes) elements +# for given geometrical shape. class NETGEN_1D2D3D_Algorithm(NETGEN_Algorithm): + ## name of the dynamic method in smesh.Mesh class + # @internal meshMethod = "Tetrahedron" + ## type of algorithm used with helper function in smesh.Mesh class + # @internal algoType = NETGEN_1D2D3D + ## doc string of the method + # @internal + docHelper = "Creates tetrahedron 3D algorithm for solids" ## Private constructor. + # @param mesh parent mesh object algorithm is assigned to + # @param geom geometry (shape/sub-shape) algorithm is assigned to; + # if it is @c 0 (default), the algorithm is assigned to the main shape def __init__(self, mesh, geom=0): NETGEN_Algorithm.__init__(self, mesh, geom) + pass - ## Sets SecondOrder flag - # + ## Sets @c SecondOrder flag + # @param theVal new value of the @c SecondOrder parameter def SetSecondOrder(self, theVal): - if self.Parameters(): - self.params.SetSecondOrder(theVal) + if self.Parameters(): self.params.SetSecondOrder(theVal) + pass - ## Sets NbSegPerEdge - # + ## Sets @c NbSegPerEdge parameter + # @param theVal new value of the @c NbSegPerEdge parameter def SetNbSegPerEdge(self, theVal): - if self.Parameters(): - self.params.SetNbSegPerEdge(theVal) + if self.Parameters(): self.params.SetNbSegPerEdge(theVal) + pass - ## Sets NbSegPerRadius - # + ## Sets @c NbSegPerRadius parameter + # @param theVal new value of the @c NbSegPerRadius parameter def SetNbSegPerRadius(self, theVal): - if self.Parameters(): - self.params.SetNbSegPerRadius(theVal) + if self.Parameters(): self.params.SetNbSegPerRadius(theVal) + pass - ## Sets QuadAllowed flag. + ## Sets @c QuadAllowed flag + # @param toAllow new value of the @c QuadAllowed parameter (@c True by default) def SetQuadAllowed(self, toAllow=True): - if self.Parameters(): - self.params.SetQuadAllowed(toAllow) - + if self.Parameters(): self.params.SetQuadAllowed(toAllow) + pass ## Sets number of segments overriding the value set by SetLocalLength() - # + # @param theVal new value of number of segments parameter def SetNumberOfSegments(self, theVal): self.Parameters(SIMPLE).SetNumberOfSegments(theVal) + pass ## Sets number of segments overriding the value set by SetNumberOfSegments() - # + # @param theVal new value of local length parameter def SetLocalLength(self, theVal): self.Parameters(SIMPLE).SetLocalLength(theVal) + pass - ## Defines "MaxElementArea" parameter of NETGEN_SimpleParameters_3D hypothesis. + ## Defines @c MaxElementArea parameter of @c NETGEN_SimpleParameters_3D hypothesis. # Overrides value set by LengthFromEdges() + # @param area new value of @c MaxElementArea parameter def MaxElementArea(self, area): self.Parameters(SIMPLE).SetMaxElementArea(area) + pass - ## Defines "LengthFromEdges" parameter of NETGEN_SimpleParameters_3D hypothesis + ## Defines @c LengthFromEdges parameter of @c NETGEN_SimpleParameters_3D hypothesis. # Overrides value set by MaxElementArea() def LengthFromEdges(self): self.Parameters(SIMPLE).LengthFromEdges() + pass - ## Defines "LengthFromFaces" parameter of NETGEN_SimpleParameters_3D hypothesis + ## Defines @c LengthFromFaces parameter of @c NETGEN_SimpleParameters_3D hypothesis. # Overrides value set by MaxElementVolume() def LengthFromFaces(self): self.Parameters(SIMPLE).LengthFromFaces() + pass - ## Defines "MaxElementVolume" parameter of NETGEN_SimpleParameters_3D hypothesis + ## Defines @c MaxElementVolume parameter of @c NETGEN_SimpleParameters_3D hypothesis. # Overrides value set by LengthFromFaces() + # @param vol new value of @c MaxElementVolume parameter def MaxElementVolume(self, vol): self.Parameters(SIMPLE).SetMaxElementVolume(vol) + pass + + pass # end of NETGEN_1D2D3D_Algorithm class ## Triangle NETGEN 1D-2D algorithm. -# It is created by calling Mesh.Triangle( NETGEN_1D2D, geom=0 ) # +# It can be created by calling smesh.Mesh.Triangle( smesh.NETGEN_1D2D, geom=0 ) +# +# This algorithm generates 1D (edges) and 2D (faces) elements +# for given geometrical shape. class NETGEN_1D2D_Algorithm(NETGEN_1D2D3D_Algorithm): + ## name of the dynamic method in smesh.Mesh class + # @internal meshMethod = "Triangle" + ## type of algorithm used with helper function in smesh.Mesh class + # @internal algoType = NETGEN_1D2D + ## doc string of the method + # @internal + docHelper = "Creates triangle 2D algorithm for faces" ## Private constructor. + # @param mesh parent mesh object algorithm is assigned to + # @param geom geometry (shape/sub-shape) algorithm is assigned to; + # if it is @c 0 (default), the algorithm is assigned to the main shape def __init__(self, mesh, geom=0): NETGEN_1D2D3D_Algorithm.__init__(self, mesh, geom) + pass + pass # end of NETGEN_1D2D_Algorithm class ## Triangle NETGEN 2D algorithm -# It is created by calling Mesh.Triangle( NETGEN_2D, geom=0 ) # +# It can be created by calling smesh.Mesh.Triangle( smesh.NETGEN_2D, geom=0 ) +# +# This algorithm generates only 2D (faces) elements for given geometrical shape +# and, in contrast to NETGEN_1D2D_Algorithm class, should be used in conjunction +# with other 1D meshing algorithm. class NETGEN_2D_Only_Algorithm(NETGEN_Algorithm): + ## name of the dynamic method in smesh.Mesh class + # @internal meshMethod = "Triangle" + ## type of algorithm used with helper function in smesh.Mesh class + # @internal algoType = NETGEN_2D + ## doc string of the method + # @internal + docHelper = "Creates triangle 2D algorithm for faces" ## Private constructor. + # @param mesh parent mesh object algorithm is assigned to + # @param geom geometry (shape/sub-shape) algorithm is assigned to; + # if it is @c 0 (default), the algorithm is assigned to the main shape def __init__(self, mesh, geom=0): NETGEN_Algorithm.__init__(self, mesh, geom) + pass - ## Sets QuadAllowed flag. - def SetQuadAllowed(self, toAllow=True): - if self.Parameters(): - self.params.SetQuadAllowed(toAllow) - - ## 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 + ## Defines @c MaxElementArea parameter of hypothesis basing on the definition of the + # maximum area of each triangle + # @param area maximum area value of each triangle + # @param UseExisting if \c True - searches for an existing hypothesis created with the # same parameters, else (default) - creates a new one - # + # @return hypothesis object def MaxElementArea(self, area, UseExisting=0): compFun = lambda hyp, args: IsEqual(hyp.GetMaxElementArea(), args[0]) hyp = self.Hypothesis("MaxElementArea", [area], UseExisting=UseExisting, @@ -228,14 +329,16 @@ class NETGEN_2D_Only_Algorithm(NETGEN_Algorithm): hyp.SetMaxElementArea(area) return hyp - ## Defines "LengthFromEdges" hypothesis to build triangles + ## Defines @c LengthFromEdges hypothesis to build triangles # based on the length of the edges taken from the wire - # + # @return hypothesis object def LengthFromEdges(self): hyp = self.Hypothesis("LengthFromEdges", UseExisting=1, CompareMethod=self.CompareEqualHyp) return hyp - ## Sets QuadAllowed flag. + ## Sets @c QuadAllowed flag. + # @param toAllow new value of the @c QuadAllowed parameter (@c True by default) + # @return hypothesis object def SetQuadAllowed(self, toAllow=True): if not self.params: # use simple hyps @@ -260,23 +363,45 @@ class NETGEN_2D_Only_Algorithm(NETGEN_Algorithm): self.Parameters().SetQuadAllowed( toAllow ) return self.params -## Defines a tetrahedron 3D algorithm -# It is created by calling Mesh.Tetrahedron() + pass # end of NETGEN_2D_Only_Algorithm class + + +## Tetrahedron 3D algorithm # +# It can be created by calling smesh.Mesh.Tetrahedron() or smesh.Mesh.Tetrahedron( smesh.NETGEN, geom=0 ) +# +# This algorithm generates only 3D (volumes) elements for given geometrical shape +# and, in contrast to NETGEN_1D2D3D_Algorithm class, should be used in conjunction +# with other 1D and 2D meshing algorithms. class NETGEN_3D_Algorithm(NETGEN_Algorithm): + ## name of the dynamic method in smesh.Mesh class + # @internal meshMethod = "Tetrahedron" + ## type of algorithm used with helper function in smesh.Mesh class + # @internal algoType = NETGEN + ## flag pointing either this algorithm should be used by default in dynamic method + # of smesh.Mesh class + # @internal isDefault = True + ## doc string of the method + # @internal + docHelper = "Creates tetrahedron 3D algorithm for solids" ## Private constructor. + # @param mesh parent mesh object algorithm is assigned to + # @param geom geometry (shape/sub-shape) algorithm is assigned to; + # if it is @c 0 (default), the algorithm is assigned to the main shape def __init__(self, mesh, geom=0): NETGEN_Algorithm.__init__(self, mesh, geom) + pass - ## Defines "MaxElementVolume" hypothesis to give the maximun volume of each tetrahedron - # @param vol for the maximum volume of each tetrahedron - # @param UseExisting if ==true - searches for the existing hypothesis created with + ## Defines @c MaxElementVolume hypothesis to specify the maximum volume value of each tetrahedron + # @param vol maximum volume value of each tetrahedron + # @param UseExisting if \c True - searches for the existing hypothesis created with # the same parameters, else (default) - creates a new one + # @return hypothesis object def MaxElementVolume(self, vol, UseExisting=0): compFun = lambda hyp, args: IsEqual(hyp.GetMaxElementVolume(), args[0]) hyp = self.Hypothesis("MaxElementVolume", [vol], UseExisting=UseExisting, @@ -284,23 +409,57 @@ class NETGEN_3D_Algorithm(NETGEN_Algorithm): hyp.SetMaxElementVolume(vol) return hyp + pass # end of NETGEN_3D_Algorithm class + -# Class just to create NETGEN_1D2D by calling Mesh.Triangle(NETGEN) +## Triangle (helper) 1D-2D algorithm +# +# This is the helper class that is used just to allow creating of create NETGEN_1D2D algorithm +# by calling smesh.Mesh.Triangle( smesh.NETGEN, geom=0 ); this is required for backward compatibility +# with old Python scripts. +# +# @note This class (and corresponding smesh.Mesh function) is obsolete; +# use smesh.Mesh.Triangle( smesh.NETGEN_1D2D, geom=0 ) instead. class NETGEN_1D2D_Algorithm_2(NETGEN_1D2D_Algorithm): + ## name of the dynamic method in smesh.Mesh class + # @internal algoType = NETGEN ## Private constructor. + # @param mesh parent mesh object algorithm is assigned to + # @param geom geometry (shape/sub-shape) algorithm is assigned to; + # if it is @c 0 (default), the algorithm is assigned to the main shape def __init__(self, mesh, geom=0): self.algoType = NETGEN_1D2D NETGEN_1D2D_Algorithm.__init__(self,mesh, geom) + pass + + pass # end of NETGEN_1D2D_Algorithm_2 class -# Class just to create NETGEN_1D2D3D by calling Mesh.Netgen() +## Tetrahedron (helper) 1D-2D-3D algorithm. +# +# This is the helper class that is used just to allow creating of create NETGEN_1D2D3D +# by calling smesh.Mesh.Netgen(); this is required for backward compatibility with old Python scripts. +# +# @note This class (and corresponding smesh.Mesh function) is obsolete; +# use smesh.Mesh.Tetrahedron( smesh.NETGEN_1D2D3D, geom=0 ) instead. class NETGEN_1D2D3D_Algorithm_2(NETGEN_1D2D3D_Algorithm): + ## name of the dynamic method in smesh.Mesh class + # @internal meshMethod = "Netgen" + ## doc string of the method + # @internal + docHelper = "Deprecated, used only for compatibility! See Tetrahedron() method." ## Private constructor. + # @param mesh parent mesh object algorithm is assigned to + # @param geom geometry (shape/sub-shape) algorithm is assigned to; + # if it is @c 0 (default), the algorithm is assigned to the main shape def __init__(self, mesh, geom=0): NETGEN_1D2D3D_Algorithm.__init__(self,mesh, geom) + pass + + pass # end of NETGEN_1D2D3D_Algorithm_2 class diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D.cxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D.cxx index 0a488ad..588d03f 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D.cxx @@ -39,8 +39,8 @@ using namespace std; //============================================================================= NETGENPlugin_Hypothesis_2D::NETGENPlugin_Hypothesis_2D (int hypId, int studyId, SMESH_Gen * gen) - : NETGENPlugin_Hypothesis(hypId, studyId, gen), - _quadAllowed (GetDefaultQuadAllowed()) + : NETGENPlugin_Hypothesis(hypId, studyId, gen)/*, + _quadAllowed (GetDefaultQuadAllowed())*/ { _name = "NETGEN_Parameters_2D"; _param_algo_dim = 2; @@ -51,56 +51,56 @@ NETGENPlugin_Hypothesis_2D::NETGENPlugin_Hypothesis_2D (int hypId, int studyId, * */ //============================================================================= -void NETGENPlugin_Hypothesis_2D::SetQuadAllowed(bool theVal) -{ - if (theVal != _quadAllowed) - { - _quadAllowed = theVal; - NotifySubMeshesHypothesisModification(); - } -} +// void NETGENPlugin_Hypothesis_2D::SetQuadAllowed(bool theVal) +// { +// if (theVal != _quadAllowed) +// { +// _quadAllowed = theVal; +// NotifySubMeshesHypothesisModification(); +// } +// } -//============================================================================= -/*! - * - */ -//============================================================================= -bool NETGENPlugin_Hypothesis_2D::GetDefaultQuadAllowed() -{ - return false; -} +// //============================================================================= +// /*! +// * +// */ +// //============================================================================= +// bool NETGENPlugin_Hypothesis_2D::GetDefaultQuadAllowed() +// { +// return false; +// } -//============================================================================= -/*! - * - */ -//============================================================================= -ostream & NETGENPlugin_Hypothesis_2D::SaveTo(ostream & save) -{ - NETGENPlugin_Hypothesis::SaveTo(save); +// //============================================================================= +// /*! +// * +// */ +// //============================================================================= +// ostream & NETGENPlugin_Hypothesis_2D::SaveTo(ostream & save) +// { +// NETGENPlugin_Hypothesis::SaveTo(save); - save << " " << (int)_quadAllowed; +// save << " " << (int)_quadAllowed; - return save; -} +// return save; +// } -//============================================================================= -/*! - * - */ -//============================================================================= -istream & NETGENPlugin_Hypothesis_2D::LoadFrom(istream & load) -{ - NETGENPlugin_Hypothesis::LoadFrom(load); +// //============================================================================= +// /*! +// * +// */ +// //============================================================================= +// istream & NETGENPlugin_Hypothesis_2D::LoadFrom(istream & load) +// { +// NETGENPlugin_Hypothesis::LoadFrom(load); - bool isOK = true; - int is; +// bool isOK = true; +// int is; - isOK = (load >> is); - if (isOK) - _quadAllowed = (bool) is; - else - load.clear(ios::badbit | load.rdstate()); +// isOK = (load >> is); +// if (isOK) +// _quadAllowed = (bool) is; +// else +// load.clear(ios::badbit | load.rdstate()); - return load; -} +// return load; +// } diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D.hxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D.hxx index babfc87..77382b0 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D.hxx @@ -45,16 +45,16 @@ public: NETGENPlugin_Hypothesis_2D(int hypId, int studyId, SMESH_Gen * gen); - void SetQuadAllowed(bool theVal); - bool GetQuadAllowed() const { return _quadAllowed; } - static bool GetDefaultQuadAllowed(); + // void SetQuadAllowed(bool theVal); + // bool GetQuadAllowed() const { return _quadAllowed; } + // static bool GetDefaultQuadAllowed(); // Persistence - virtual ostream & SaveTo(ostream & save); - virtual istream & LoadFrom(istream & load); + // virtual ostream & SaveTo(ostream & save); + // virtual istream & LoadFrom(istream & load); -private: - bool _quadAllowed; +// private: +// bool _quadAllowed; }; #endif diff --git a/src/NETGENPlugin/NETGENPlugin_Mesher.cxx b/src/NETGENPlugin/NETGENPlugin_Mesher.cxx index 9249d95..16da863 100644 --- a/src/NETGENPlugin/NETGENPlugin_Mesher.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Mesher.cxx @@ -2340,7 +2340,9 @@ bool NETGENPlugin_Mesher::Evaluate(MapShapeNbElems& aResMap) // Prepare OCC geometry // ------------------------- netgen::OCCGeometry occgeo; - PrepareOCCgeometry( occgeo, _shape, *_mesh ); + list< SMESH_subMesh* > meshedSM[3]; // for 0-2 dimensions + NETGENPlugin_Internals internals( *_mesh, _shape, _isVolume ); + PrepareOCCgeometry( occgeo, _shape, *_mesh, meshedSM, &internals ); bool tooManyElems = false; const int hugeNb = std::numeric_limits::max() / 100; @@ -2349,26 +2351,31 @@ bool NETGENPlugin_Mesher::Evaluate(MapShapeNbElems& aResMap) // evaluate 1D // ---------------- // pass 1D simple parameters to NETGEN - if ( _simpleHyp ) { - if ( int nbSeg = _simpleHyp->GetNumberOfSegments() ) { + if ( _simpleHyp ) + { + // not to RestrictLocalH() according to curvature during MESHCONST_ANALYSE + mparams.uselocalh = false; + mparams.grading = 0.8; // not limitited size growth + + if ( _simpleHyp->GetNumberOfSegments() ) // nb of segments - mparams.segmentsperedge = nbSeg + 0.1; mparams.maxh = occgeo.boundingbox.Diam(); - mparams.minh = GetDefaultMinSize( _shape, mparams.maxh ); - mparams.grading = 0.01; - } - else { + else // segment length - mparams.segmentsperedge = 1; mparams.maxh = _simpleHyp->GetLocalLength(); - } } + + if ( mparams.maxh == 0.0 ) + mparams.maxh = occgeo.boundingbox.Diam(); + if ( _simpleHyp || ( mparams.minh == 0.0 && _fineness != NETGENPlugin_Hypothesis::UserDefined)) + mparams.minh = GetDefaultMinSize( _shape, mparams.maxh ); + // let netgen create ngMesh and calculate element size on not meshed shapes NETGENPlugin_NetgenLibWrapper ngLib; netgen::Mesh *ngMesh = NULL; char *optstr = 0; int startWith = netgen::MESHCONST_ANALYSE; - int endWith = netgen::MESHCONST_MESHEDGES; + int endWith = netgen::MESHCONST_ANALYSE; int err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr); #ifdef WITH_SMESH_CANCEL_COMPUTE if(netgen::multithread.terminate) @@ -2380,7 +2387,53 @@ bool NETGENPlugin_Mesher::Evaluate(MapShapeNbElems& aResMap) sm->GetComputeError().reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED )); return false; } - + if ( _simpleHyp ) + { + // Pass 1D simple parameters to NETGEN + // -------------------------------- + int nbSeg = _simpleHyp->GetNumberOfSegments(); + double segSize = _simpleHyp->GetLocalLength(); + for ( int iE = 1; iE <= occgeo.emap.Extent(); ++iE ) + { + const TopoDS_Edge& e = TopoDS::Edge( occgeo.emap(iE)); + if ( nbSeg ) + segSize = SMESH_Algo::EdgeLength( e ) / ( nbSeg - 0.4 ); + setLocalSize( e, segSize, *ngMesh ); + } + } + else // if ( ! _simpleHyp ) + { + // Local size on vertices and edges + // -------------------------------- + for(std::map::const_iterator it=EdgeId2LocalSize.begin(); it!=EdgeId2LocalSize.end(); it++) + { + int key = (*it).first; + double hi = (*it).second; + const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key); + const TopoDS_Edge& e = TopoDS::Edge(shape); + setLocalSize( e, hi, *ngMesh ); + } + for(std::map::const_iterator it=VertexId2LocalSize.begin(); it!=VertexId2LocalSize.end(); it++) + { + int key = (*it).first; + double hi = (*it).second; + const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key); + const TopoDS_Vertex& v = TopoDS::Vertex(shape); + gp_Pnt p = BRep_Tool::Pnt(v); + NETGENPlugin_Mesher::RestrictLocalSize( *ngMesh, p.XYZ(), hi ); + } + for(map::const_iterator it=FaceId2LocalSize.begin(); + it!=FaceId2LocalSize.end(); it++) + { + int key = (*it).first; + double val = (*it).second; + const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key); + int faceNgID = occgeo.fmap.FindIndex(shape); + occgeo.SetFaceMaxH(faceNgID, val); + for ( TopExp_Explorer edgeExp( shape, TopAbs_EDGE ); edgeExp.More(); edgeExp.Next() ) + setLocalSize( TopoDS::Edge( edgeExp.Current() ), val, *ngMesh ); + } + } // calculate total nb of segments and length of edges double fullLen = 0.0; int fullNbSeg = 0; diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D.hxx index cfb723d..70009f3 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D.hxx @@ -25,7 +25,6 @@ // Author : Michael Sazonov (OCN) // Date : 20/03/2006 // Project : SALOME -// $Header$ //============================================================================= // #ifndef _NETGENPlugin_NETGEN_2D_HXX_ @@ -33,13 +32,11 @@ #include "NETGENPlugin_Defs.hxx" -#include "SMESH_2D_Algo.hxx" +#include "SMESH_Algo.hxx" #include "SMESH_Mesh.hxx" #include "StdMeshers_MaxElementVolume.hxx" #include "Utils_SALOME_Exception.hxx" -//class NETGENPlugin_Hypothesis_2D; - class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_2D: public SMESH_2D_Algo { public: diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.cxx index 5959507..9dc9650 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.cxx @@ -25,7 +25,6 @@ // Author : Michael Sazonov (OCN) // Date : 20/03/2006 // Project : SALOME -// $Header$ //============================================================================= // #include "NETGENPlugin_NETGEN_2D3D.hxx" @@ -125,7 +124,7 @@ bool NETGENPlugin_NETGEN_2D3D::CheckHypothesis //============================================================================= /*! - *Here we are going to use the NETGEN mesher + * Here we are going to use the NETGEN mesher */ //============================================================================= @@ -135,15 +134,19 @@ bool NETGENPlugin_NETGEN_2D3D::Compute(SMESH_Mesh& aMesh, #ifdef WITH_SMESH_CANCEL_COMPUTE netgen::multithread.terminate = 0; #endif -// SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); NETGENPlugin_Mesher mesher(&aMesh, aShape, true); -// NETGENPlugin_Mesher mesher(meshDS, aShape, true); mesher.SetParameters(dynamic_cast(_hypothesis)); mesher.SetParameters(dynamic_cast(_hypothesis)); return mesher.Compute(); } +//============================================================================= +/*! + * + */ +//============================================================================= + #ifdef WITH_SMESH_CANCEL_COMPUTE void NETGENPlugin_NETGEN_2D3D::CancelCompute() { diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.hxx index 7775f8c..677519a 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.hxx @@ -25,7 +25,6 @@ // Author : Michael Sazonov (OCN) // Date : 20/03/2006 // Project : SALOME -// $Header$ //============================================================================= // #ifndef _NETGENPlugin_NETGEN_2D3D_HXX_ @@ -33,12 +32,10 @@ #include "NETGENPlugin_Defs.hxx" -#include "SMESH_3D_Algo.hxx" -#include "SMESH_Mesh.hxx" -#include "StdMeshers_MaxElementVolume.hxx" -#include "Utils_SALOME_Exception.hxx" - -//class NETGENPlugin_Hypothesis; +#include +#include +#include +#include class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_2D3D: public SMESH_3D_Algo { diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx index acb11d6..fbf6829 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx @@ -26,23 +26,24 @@ #include "NETGENPlugin_Mesher.hxx" #include "NETGENPlugin_Hypothesis_2D.hxx" -#include "SMDS_MeshElement.hxx" -#include "SMDS_MeshNode.hxx" -#include "SMESHDS_Mesh.hxx" -#include "SMESH_Comment.hxx" -#include "SMESH_Gen.hxx" -#include "SMESH_Mesh.hxx" -#include "SMESH_MesherHelper.hxx" -#include "StdMeshers_FaceSide.hxx" -#include "StdMeshers_MaxElementArea.hxx" -#include "StdMeshers_LengthFromEdges.hxx" -#include "StdMeshers_QuadranglePreference.hxx" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include -#include "utilities.h" +#include #include #include diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx index 5e476b2..f4ff38f 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx @@ -24,8 +24,8 @@ #ifndef _NETGENPlugin_NETGEN_2D_ONLY_HXX_ #define _NETGENPlugin_NETGEN_2D_ONLY_HXX_ -#include "SMESH_2D_Algo.hxx" -#include "SMESH_Mesh.hxx" +#include +#include class StdMeshers_MaxElementArea; class StdMeshers_LengthFromEdges; diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index e923afb..474d242 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -32,18 +32,19 @@ #include "NETGENPlugin_Hypothesis.hxx" -#include "SMDS_MeshElement.hxx" -#include "SMDS_MeshNode.hxx" -#include "SMESHDS_Mesh.hxx" -#include "SMESH_Comment.hxx" -#include "SMESH_ControlsDef.hxx" -#include "SMESH_Gen.hxx" -#include "SMESH_Mesh.hxx" -#include "SMESH_MesherHelper.hxx" -#include "SMESH_MeshEditor.hxx" -#include "StdMeshers_QuadToTriaAdaptor.hxx" -#include "StdMeshers_MaxElementVolume.hxx" -#include "StdMeshers_ViscousLayers.hxx" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -56,7 +57,7 @@ #include #include -#include "utilities.h" +#include #include #include diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx index 44f3941..ec43d6e 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx @@ -34,7 +34,7 @@ #include "NETGENPlugin_Defs.hxx" #include "NETGENPlugin_Mesher.hxx" -#include "SMESH_3D_Algo.hxx" +#include "SMESH_Algo.hxx" #include "Utils_SALOME_Exception.hxx" class StdMeshers_ViscousLayers; -- 2.30.2