Salome HOME
Merge from V6_main 06/03/2013
authorvsr <vsr@opencascade.com>
Wed, 6 Mar 2013 13:57:01 +0000 (13:57 +0000)
committervsr <vsr@opencascade.com>
Wed, 6 Mar 2013 13:57:01 +0000 (13:57 +0000)
38 files changed:
doc/salome/examples/Makefile.am
doc/salome/gui/SMESH/images/convert.png
doc/salome/gui/SMESH/input/adding_quadratic_elements.doc
doc/salome/gui/SMESH/input/additional_hypo.doc
doc/salome/gui/SMESH/input/convert_to_from_quadratic_mesh.doc
idl/SMESH_Filter.idl
idl/SMESH_MeshEditor.idl
src/Controls/SMESH_Controls.cxx
src/Controls/SMESH_ControlsDef.hxx
src/DriverGMF/DriverGMF_Read.cxx
src/DriverGMF/DriverGMF_Write.cxx
src/DriverGMF/DriverGMF_Write.hxx
src/DriverMED/Makefile.am
src/SMDS/SMDS_MeshInfo.hxx
src/SMDS/SMDS_VolumeTool.cxx
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MeshEditor.hxx
src/SMESH/SMESH_MesherHelper.cxx
src/SMESH/SMESH_MesherHelper.hxx
src/SMESH/SMESH_subMesh.cxx
src/SMESH/SMESH_subMesh.hxx
src/SMESHGUI/SMESHGUI_ConvToQuadDlg.cxx
src/SMESHGUI/SMESHGUI_ConvToQuadDlg.h
src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx
src/SMESHGUI/SMESHGUI_ConvToQuadOp.h
src/SMESHGUI/SMESHGUI_FilterDlg.cxx
src/SMESHGUI/SMESH_msg_en.ts
src/SMESH_I/SMESH_2smeshpy.cxx
src/SMESH_I/SMESH_DumpPython.cxx
src/SMESH_I/SMESH_Filter_i.cxx
src/SMESH_I/SMESH_Filter_i.hxx
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.hxx
src/SMESH_I/SMESH_PythonDump.hxx
src/SMESH_SWIG/smeshDC.py
src/StdMeshers/StdMeshers_MEFISTO_2D.cxx
src/StdMeshers/StdMeshers_Prism_3D.cxx
src/StdMeshers/StdMeshers_Projection_2D.cxx

index 6a5904b..f756654 100644 (file)
@@ -174,7 +174,10 @@ pyexamples_SCRIPTS = $(BAD_TESTS) $(GOOD_TESTS)
 
 EXTRA_DIST += $(pyexamples_SCRIPTS) testme.py
 
+THIS_PYTHONPATH = $(KERNEL_ROOT_DIR)/bin/salome:$(KERNEL_ROOT_DIR)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(KERNEL_ROOT_DIR)/lib64/python$(PYTHON_VERSION)/site-packages/salome
+THIS_LD_LIBRARY_PATH = $(KERNEL_ROOT_DIR)/lib/salome
+
 installcheck-local:
        @for f in $(GOOD_TESTS) ; do \
-         env SMESH_ROOT_DIR=$(prefix) python -B $(top_srcdir)/doc/salome/examples/testme.py $(top_srcdir)/doc/salome/examples/$$f || exit 1; \
+         SMESH_ROOT_DIR=$(prefix) PYTHONPATH=$(THIS_PYTHONPATH):${PYTHONPATH} LD_LIBRARY_PATH=$(THIS_LD_LIBRARY_PATH):${LD_LIBRARY_PATH} python -B $(top_srcdir)/doc/salome/examples/testme.py $(top_srcdir)/doc/salome/examples/$$f || exit 1; \
        done
index 2ebbedc..9139f60 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/convert.png and b/doc/salome/gui/SMESH/images/convert.png differ
index 9219486..7f2cf5c 100644 (file)
@@ -4,10 +4,22 @@
 
 \n MESH module allows you to work with <b>Quadratic Elements</b>.
 
-Quadratic Edge is not a straight but a broken line and can be defined
-by three points: first, middle and last. All more complex \b Quadratic
-\b Elements differ from ordinary ones in that they consist of Quadratic
-Edges.
+Quadratic elements are defined by same corner nodes as the
+corresponding linear ones, and in addition they bear \a midside nodes
+located between the corner nodes on element sides.
+
+The quadratic quadrilateral element can bear an additional node at the
+element center, then it is referred as bi-quadratic one (or
+QUAD9). The quadratic hexahedral element can bear 7 additional nodes:
+at the element center and at centers of sides, then it is referred as
+tri-quadratic one (or HEXA27).
+
+There are several ways you can create quadratic elements in your mesh:
+- manually create quadratic elements (the way described below);
+- use \ref quadratic_mesh_anchor "Quadratic Mesh" hypothesis to
+generate quadratic mesh on your geometry;
+- convert an existing linear mesh to a quadratic one 
+(see \ref convert_to_from_quadratic_mesh_page).
 
 <em>To add a quadratic element to your mesh:</em>
 <ol>
index 2fde9c1..98353ed 100644 (file)
@@ -23,6 +23,9 @@ Quadratic Mesh hypothesis allows to build a quadratic mesh (whose
 edges are not straight but curved lines and can be defined by three
 points: first, middle and last instead of an ordinary two).
 
+See \ref adding_quadratic_elements_page
+for more information about quadratic meshes.
+
 \anchor propagation_anchor
 <h2>Propagation of 1D Hypothesis on opposite edges</h2>
 
index 66f8506..15fe1b7 100644 (file)
@@ -2,13 +2,14 @@
 
 \page convert_to_from_quadratic_mesh_page Convert to/from Quadratic Mesh
 
-\n This functionality allows transforming standard meshes (or
-sub-meshes) to quadratic and vice versa. 
-See \ref adding_quadratic_elements_page "Adding quadratic elements" 
-for more information about quadratic meshes.
-Note that conversion of a sub-mesh most probably will
-produce a non-conformal mesh. Elements on the boundary between
-quadratic and linear sub-meshes become (or remain) quadratic.
+\n This functionality allows transforming linear meshes (or
+sub-meshes) to quadratic and vice versa.
+Note that conversion of a sub-mesh most probably will produce a
+non-conformal mesh. Elements on the boundary between quadratic and
+linear sub-meshes become (or remain) quadratic.
+
+See \ref adding_quadratic_elements_page for more information about
+quadratic meshes.
 
 <em>To produce a conversion:</em>
 <ol>
@@ -18,8 +19,10 @@ Viewer.</li>
 Mesh item </b>, or click <em>"Convert to/from quadratic"</em> button in the
 toolbar.
 
+<center>
 \image html image154.png
-<center><em>"Convert to/from quadratic" button</em></center>
+<em>"Convert to/from quadratic" button</em>
+</center>
 
 The following dialog box will appear:
 
@@ -29,18 +32,20 @@ The following dialog box will appear:
 <li>In this dialog box specify:
 
 <ul>
-<li>if it is necessary to convert a standard mesh to quadratic or a quadratic
-mesh to standard. Note that the choice is available only if the selected mesh
-(or sub-mesh) contains both quadratic and linear elements, else the
-direction of conversion is selected automatically.</li>
-
-<li>if it is necessary to place medium nodes of the quadratic mesh on the
+<li>If it is necessary to convert a linear mesh to quadratic or a quadratic
+  mesh to linear. **Convert to bi-quadratic** option means same as
+  **Convert to quadratic** except that QUAD9 elements are created
+  instead of QUAD8, and HEXA27 elements are created instead of
+  HEXA20. Note that the choice is available only if the selected mesh
+  (or sub-mesh) contains both quadratic and linear elements, else the
+  direction of conversion is selected automatically.</li>
+<li>If it is necessary to place medium nodes of the quadratic mesh on the
 geometry (meshed object). This option is relevant for conversion to
 quadratic provided that the mesh is based on a geometry (not imported from file).</li>
 </ul>
 
 \image html image156.gif
-<center>Standard mesh (coarse mesh on a torus)</center>
+<center>Linear mesh (coarse mesh on a torus)</center>
 
 \image html image155.gif
 <center>Quadratic mesh</center>
index 2c701fc..b516d19 100644 (file)
@@ -75,6 +75,7 @@ module SMESH
     FT_LinearOrQuadratic,
     FT_GroupColor,
     FT_ElemGeomType,
+    FT_EntityType,
     FT_CoplanarFaces,
     FT_BallDiameter,
     FT_LessThan,
@@ -423,6 +424,15 @@ module SMESH
   };
 
   /*!
+  * Functor "Element entity type"
+  * Returns is element has indicated entity type
+  */
+  interface ElemEntityType : Predicate{
+    void            SetElementType ( in ElementType  theType );
+    void            SetEntityType( in EntityType theSetEntityType );
+  };
+
+  /*!
   * Functor "Coplanar faces"
   * Returns true if a mesh face is a coplanar neighbour to a given one. It checks
   * if normal of a face has angle with the threshold face less than a tolerance.
@@ -543,7 +553,6 @@ module SMESH
     MultiConnection   CreateMultiConnection();
     MultiConnection2D CreateMultiConnection2D();
     BallDiameter      CreateBallDiameter();
-
     /*!
     *  Create logical functors ( predicates )
     */
@@ -575,6 +584,7 @@ module SMESH
 
     GroupColor        CreateGroupColor();
     ElemGeomType      CreateElemGeomType();
+    ElemEntityType    CreateElemEntityType();
     CoplanarFaces     CreateCoplanarFaces();
 
     /*!
index 3425d89..956e871 100644 (file)
@@ -42,26 +42,26 @@ module SMESH
     * Return data of mesh edition preview which is computed provided
     * that the editor was obtained trough SMESH_Mesh::GetMeshEditPreviewer()
     */
-    MeshPreviewStruct GetPreviewData();
+    MeshPreviewStruct GetPreviewData() raises (SALOME::SALOME_Exception);
 
    /*!
     * If during last operation of MeshEditor some nodes were
     * created this method returns list of their IDs, if new nodes
     * not created - returns empty list
     */
-    long_array GetLastCreatedNodes();
+    long_array GetLastCreatedNodes() raises (SALOME::SALOME_Exception);
 
    /*!
     * If during last operation of MeshEditor some elements were
     * created this method returns list of their IDs, if new elements
     * not created - returns empty list
     */
-    long_array GetLastCreatedElems();
+    long_array GetLastCreatedElems() raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Returns description of an error/warning occured during the last operation
      */
-    ComputeError GetLastError();
+    ComputeError GetLastError() raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Wrap a sequence of ids in a SMESH_IDSource
@@ -75,20 +75,20 @@ module SMESH
      * \param IDsOfElements list of mesh elements identifiers
      * \return \c true if elements are correctly removed or \c false otherwise
      */
-    boolean RemoveElements(in long_array IDsOfElements);
+    boolean RemoveElements(in long_array IDsOfElements) raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Remove mesh nodes specified by their identifiers.
      * \param IDsOfNodes list of mesh nodes identifiers
      * \return \c true if nodes are correctly removed or \c false otherwise
      */
-    boolean RemoveNodes(in long_array IDsOfNodes);
+    boolean RemoveNodes(in long_array IDsOfNodes) raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Remove all orphan nodes.
      * \return number of removed nodes
      */
-    long RemoveOrphanNodes();
+    long RemoveOrphanNodes() raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Add a new node.
@@ -97,19 +97,19 @@ module SMESH
      * \param z Z coordinate of new node
      * \return integer identifier of new node
      */
-    long AddNode(in double x, in double y, in double z);
+    long AddNode(in double x, in double y, in double z) raises (SALOME::SALOME_Exception);
 
     /*!
      *  Create a 0D element on the given node.
      *  \param IdOfNode Node IDs for creation of element.
      */
-    long Add0DElement(in long IDOfNode);
+    long Add0DElement(in long IDOfNode) raises (SALOME::SALOME_Exception);
 
     /*!
      *  Create a ball element on the given node.
      *  \param IdOfNode Node IDs for creation of element.
      */
-    long AddBall(in long IDOfNode, in double diameter);
+    long AddBall(in long IDOfNode, in double diameter) raises (SALOME::SALOME_Exception);
 
     /*!
      *  Create an edge, either linear and quadratic (this is determed
@@ -119,7 +119,7 @@ module SMESH
      *  of MED. This description is located by the following link:
      *   http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
      */
-    long AddEdge(in long_array IDsOfNodes);
+    long AddEdge(in long_array IDsOfNodes) raises (SALOME::SALOME_Exception);
 
     /*!
      *  Create face, either linear and quadratic (this is determed
@@ -129,9 +129,9 @@ module SMESH
      *  of MED. This description is located by the following link:
      *   http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
      */
-    long AddFace(in long_array IDsOfNodes);
+    long AddFace(in long_array IDsOfNodes) raises (SALOME::SALOME_Exception);
 
-    long AddPolygonalFace(in long_array IdsOfNodes);
+    long AddPolygonalFace(in long_array IdsOfNodes) raises (SALOME::SALOME_Exception);
 
     /*!
      *  Create volume, either linear and quadratic (this is determed
@@ -141,7 +141,7 @@ module SMESH
      *  of MED. This description is located by the following link:
      *   http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
      */
-    long AddVolume(in long_array IDsOfNodes);
+    long AddVolume(in long_array IDsOfNodes) raises (SALOME::SALOME_Exception);
 
     /*!
      *  Create volume of many faces, giving nodes for each face.
@@ -150,14 +150,14 @@ module SMESH
      *         gives quantity of nodes in face number i.
      */
     long AddPolyhedralVolume (in long_array IdsOfNodes,
-                              in long_array Quantities);
+                              in long_array Quantities) raises (SALOME::SALOME_Exception);
     /*!
      *  Create volume of many faces, giving IDs of existing faces.
      *  \param IdsOfFaces List of face IDs for volume creation.
      *  \note The created volume will refer only to nodes
      *        of the given faces, not to the faces itself.
      */
-    long AddPolyhedralVolumeByFaces (in long_array IdsOfFaces);
+    long AddPolyhedralVolumeByFaces (in long_array IdsOfFaces) raises (SALOME::SALOME_Exception);
 
     /*!
      * Create 0D elements on all nodes of the given object except those 
@@ -212,15 +212,20 @@ module SMESH
       raises (SALOME::SALOME_Exception);
 
 
-    boolean MoveNode(in long NodeID, in double x, in double y, in double z);
+    boolean MoveNode(in long NodeID, in double x, in double y, in double z)
+      raises (SALOME::SALOME_Exception);
 
-    boolean InverseDiag(in long NodeID1, in long NodeID2);
+    boolean InverseDiag(in long NodeID1, in long NodeID2) 
+      raises (SALOME::SALOME_Exception);
 
-    boolean DeleteDiag(in long NodeID1, in long NodeID2);
+    boolean DeleteDiag(in long NodeID1, in long NodeID2) 
+      raises (SALOME::SALOME_Exception);
 
-    boolean Reorient(in long_array IDsOfElements);
+    boolean Reorient(in long_array IDsOfElements) 
+      raises (SALOME::SALOME_Exception);
 
-    boolean ReorientObject(in SMESH_IDSource theObject);
+    boolean ReorientObject(in SMESH_IDSource theObject) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Reorient faces contained in \a the2Dgroup.
      * \param the2Dgroup - the mesh or its part to reorient
@@ -245,7 +250,7 @@ module SMESH
      */
     boolean TriToQuad (in long_array       IDsOfElements,
                        in NumericalFunctor Criterion,
-                       in double           MaxAngle);
+                       in double           MaxAngle) raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Fuse neighbour triangles into quadrangles.
@@ -254,7 +259,7 @@ module SMESH
      */
     boolean TriToQuadObject (in SMESH_IDSource   theObject,
                              in NumericalFunctor Criterion,
-                             in double           MaxAngle);
+                             in double           MaxAngle) raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Split quadrangles into triangles.
@@ -263,7 +268,7 @@ module SMESH
      * \return TRUE in case of success, FALSE otherwise.
      */
     boolean QuadToTri (in long_array       IDsOfElements,
-                       in NumericalFunctor Criterion);
+                       in NumericalFunctor Criterion) raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Split quadrangles into triangles.
@@ -271,7 +276,7 @@ module SMESH
      * Behaves like the above method, taking list of elements from \a theObject
      */
     boolean QuadToTriObject (in SMESH_IDSource   theObject,
-                             in NumericalFunctor Criterion);
+                             in NumericalFunctor Criterion) raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Split quadrangles into triangles.
@@ -280,7 +285,7 @@ module SMESH
      * \return TRUE in case of success, FALSE otherwise.
      */
     boolean SplitQuad (in long_array IDsOfElements,
-                       in boolean    Diag13);
+                       in boolean    Diag13) raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Split quadrangles into triangles.
@@ -288,7 +293,7 @@ module SMESH
      * Behaves like the above method, taking list of elements from \a theObject
      */
     boolean SplitQuadObject (in SMESH_IDSource theObject,
-                             in boolean        Diag13);
+                             in boolean        Diag13) raises (SALOME::SALOME_Exception);
 
     /*!
      *  Find better splitting of the given quadrangle.
@@ -298,7 +303,7 @@ module SMESH
      *          diagonal is better, 0 if error occurs.
      */
     long BestSplit (in long             IDOfQuad,
-                    in NumericalFunctor Criterion);
+                    in NumericalFunctor Criterion) raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Split volumic elements into tetrahedrons
@@ -318,40 +323,44 @@ module SMESH
                    in long_array    IDsOfFixedNodes,
                    in long          MaxNbOfIterations,
                    in double        MaxAspectRatio,
-                   in Smooth_Method Method);
+                   in Smooth_Method Method) raises (SALOME::SALOME_Exception);
 
     boolean SmoothObject(in SMESH_IDSource  theObject,
                          in long_array      IDsOfFixedNodes,
                          in long            MaxNbOfIterations,
                          in double          MaxAspectRatio,
-                         in Smooth_Method   Method);
+                         in Smooth_Method   Method) raises (SALOME::SALOME_Exception);
 
     boolean SmoothParametric(in long_array    IDsOfElements,
                              in long_array    IDsOfFixedNodes,
                              in long          MaxNbOfIterations,
                              in double        MaxAspectRatio,
-                             in Smooth_Method Method);
+                             in Smooth_Method Method) raises (SALOME::SALOME_Exception);
 
     boolean SmoothParametricObject(in SMESH_IDSource  theObject,
                                    in long_array      IDsOfFixedNodes,
                                    in long            MaxNbOfIterations,
                                    in double          MaxAspectRatio,
-                                   in Smooth_Method   Method);
-
-    void ConvertToQuadratic(in boolean theForce3d);
-
-    boolean ConvertFromQuadratic();
+                                   in Smooth_Method   Method) raises (SALOME::SALOME_Exception);
 
+    void ConvertToQuadratic(in boolean theForce3d) 
+      raises (SALOME::SALOME_Exception);
     void ConvertToQuadraticObject(in boolean        theForce3d, 
                                   in SMESH_IDSource theObject) 
       raises (SALOME::SALOME_Exception);
+    
+    boolean ConvertFromQuadratic() 
+      raises (SALOME::SALOME_Exception);
+    void    ConvertFromQuadraticObject(in SMESH_IDSource theObject)
+      raises (SALOME::SALOME_Exception);
 
-    void ConvertFromQuadraticObject(in SMESH_IDSource theObject)
+    void ConvertToBiQuadratic(in boolean        theForce3d, 
+                              in SMESH_IDSource theObject)
       raises (SALOME::SALOME_Exception);
 
-    void RenumberNodes();
+    void RenumberNodes() raises (SALOME::SALOME_Exception);
 
-    void RenumberElements();
+    void RenumberElements() raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Genarate dim+1 elements by rotation of given elements around axis
@@ -364,7 +373,8 @@ module SMESH
                        in AxisStruct       Axix,
                        in double           AngleInRadians,
                        in long             NbOfSteps,
-                       in double           Tolerance);
+                       in double           Tolerance) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Same as previous but additionally create groups of elements
      *  generated from elements belonging to preexisting groups
@@ -373,7 +383,8 @@ module SMESH
                                          in AxisStruct       Axix,
                                          in double           AngleInRadians,
                                          in long             NbOfSteps,
-                                         in double           Tolerance);
+                                         in double           Tolerance) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Genarate dim+1 elements by rotation of the object around axis
      * \param theObject - object containing elements to ratate
@@ -385,7 +396,8 @@ module SMESH
                              in AxisStruct      Axix,
                              in double          AngleInRadians,
                              in long            NbOfSteps,
-                             in double          Tolerance);
+                             in double          Tolerance) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Same as previous but additionally create groups of elements
      *  generated from elements belonging to preexisting groups
@@ -394,7 +406,8 @@ module SMESH
                                                in AxisStruct      Axix,
                                                in double          AngleInRadians,
                                                in long            NbOfSteps,
-                                               in double          Tolerance);
+                                               in double          Tolerance) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Genarate dim+1 elements by rotation of the object around axis
      * \param theObject - object containing elements to ratate
@@ -406,7 +419,8 @@ module SMESH
                                in AxisStruct      Axix,
                                in double          AngleInRadians,
                                in long            NbOfSteps,
-                               in double          Tolerance);
+                               in double          Tolerance) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Same as previous but additionally create groups of elements
      *  generated from elements belonging to preexisting groups
@@ -415,7 +429,8 @@ module SMESH
                                                  in AxisStruct      Axix,
                                                  in double          AngleInRadians,
                                                  in long            NbOfSteps,
-                                                 in double          Tolerance);
+                                                 in double          Tolerance) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Genarate dim+1 elements by rotation of the object around axis
      * \param theObject - object containing elements to ratate
@@ -427,7 +442,8 @@ module SMESH
                                in AxisStruct      Axix,
                                in double          AngleInRadians,
                                in long            NbOfSteps,
-                               in double          Tolerance);
+                               in double          Tolerance) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Same as previous but additionally create groups of elements
      *  generated from elements belonging to preexisting groups
@@ -436,7 +452,8 @@ module SMESH
                                                  in AxisStruct      Axix,
                                                  in double          AngleInRadians,
                                                  in long            NbOfSteps,
-                                                 in double          Tolerance);
+                                                 in double          Tolerance) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Genarate dim+1 elements by extrusion of elements along vector
      * \param IDsOfElements - elements to sweep
@@ -445,7 +462,8 @@ module SMESH
      */
     void ExtrusionSweep(in long_array      IDsOfElements,
                         in DirStruct       StepVector,
-                        in long            NbOfSteps);
+                        in long            NbOfSteps) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Genarate dim+1 elements by extrusion of elements along vector
      * \param IDsOfElements - elements to sweep
@@ -454,20 +472,23 @@ module SMESH
      */
     void ExtrusionSweep0D(in long_array    IDsOfElements,
                         in DirStruct       StepVector,
-                        in long            NbOfSteps);
+                        in long            NbOfSteps) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Same as previous but additionally create groups of elements
      *  generated from elements belonging to preexisting groups
      */
     ListOfGroups ExtrusionSweepMakeGroups(in long_array      IDsOfElements,
                                           in DirStruct       StepVector,
-                                          in long            NbOfSteps);
+                                          in long            NbOfSteps) 
+      raises (SALOME::SALOME_Exception);
    /*!
      * \brief Same as previous but elements are nodes
      */
     ListOfGroups ExtrusionSweepMakeGroups0D(in long_array      IDsOfElements,
                                           in DirStruct       StepVector,
-                                          in long            NbOfSteps);
+                                          in long            NbOfSteps) 
+      raises (SALOME::SALOME_Exception);
    /*!
     * Generate new elements by extrusion of theElements
     * by StepVector by NbOfSteps
@@ -479,7 +500,8 @@ module SMESH
                            in DirStruct       StepVector,
                            in long            NbOfSteps,
                            in long            ExtrFlags,
-                           in double          SewTolerance);
+                           in double          SewTolerance) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Same as previous but additionally create groups of elements
      *  generated from elements belonging to preexisting groups
@@ -488,35 +510,44 @@ module SMESH
                                              in DirStruct       StepVector,
                                              in long            NbOfSteps,
                                              in long            ExtrFlags,
-                                             in double          SewTolerance);
+                                             in double          SewTolerance) 
+      raises (SALOME::SALOME_Exception);
 
     void ExtrusionSweepObject(in SMESH_IDSource  theObject,
                               in DirStruct       StepVector,
-                              in long            NbOfSteps);
+                              in long            NbOfSteps) 
+      raises (SALOME::SALOME_Exception);
     ListOfGroups ExtrusionSweepObjectMakeGroups(in SMESH_IDSource  theObject,
                                                 in DirStruct       StepVector,
-                                                in long            NbOfSteps);
+                                                in long            NbOfSteps) 
+      raises (SALOME::SALOME_Exception);
 
     void ExtrusionSweepObject0D(in SMESH_IDSource theObject,
                                 in DirStruct      StepVector,
-                                in long           NbOfSteps);
+                                in long           NbOfSteps) 
+      raises (SALOME::SALOME_Exception);
     ListOfGroups ExtrusionSweepObject0DMakeGroups(in SMESH_IDSource theObject,
                                                   in DirStruct      StepVector,
-                                                  in long           NbOfSteps);
+                                                  in long           NbOfSteps) 
+      raises (SALOME::SALOME_Exception);
 
     void ExtrusionSweepObject1D(in SMESH_IDSource theObject,
                                 in DirStruct      StepVector,
-                                in long           NbOfSteps);
+                                in long           NbOfSteps) 
+      raises (SALOME::SALOME_Exception);
     ListOfGroups ExtrusionSweepObject1DMakeGroups(in SMESH_IDSource theObject,
                                                   in DirStruct      StepVector,
-                                                  in long           NbOfSteps);
+                                                  in long           NbOfSteps) 
+      raises (SALOME::SALOME_Exception);
 
     void ExtrusionSweepObject2D(in SMESH_IDSource theObject,
                                 in DirStruct      StepVector,
-                                in long           NbOfSteps);
+                                in long           NbOfSteps) 
+      raises (SALOME::SALOME_Exception);
     ListOfGroups ExtrusionSweepObject2DMakeGroups(in SMESH_IDSource theObject,
                                                   in DirStruct      StepVector,
-                                                  in long           NbOfSteps);
+                                                  in long           NbOfSteps) 
+      raises (SALOME::SALOME_Exception);
 
     enum Extrusion_Error {
       EXTR_OK,
@@ -538,7 +569,8 @@ module SMESH
                                      in PointStruct       RefPoint,
                                      in boolean           MakeGroups,
                                      in ElementType       ElemType,
-                                     out Extrusion_Error  Error);
+                                     out Extrusion_Error  Error) 
+      raises (SALOME::SALOME_Exception);
 
     ListOfGroups ExtrusionAlongPathObjX(in SMESH_IDSource    theObject,
                                         in SMESH_IDSource    Path,
@@ -550,7 +582,8 @@ module SMESH
                                         in PointStruct       RefPoint,
                                         in boolean           MakeGroups,
                                         in ElementType       ElemType,
-                                        out Extrusion_Error  Error);
+                                        out Extrusion_Error  Error) 
+      raises (SALOME::SALOME_Exception);
 
     Extrusion_Error ExtrusionAlongPath(in long_array        IDsOfElements,
                                        in SMESH_Mesh        PathMesh,
@@ -559,7 +592,8 @@ module SMESH
                                        in boolean           HasAngles,
                                        in double_array      Angles,
                                        in boolean           HasRefPoint,
-                                       in PointStruct       RefPoint);
+                                       in PointStruct       RefPoint) 
+      raises (SALOME::SALOME_Exception);
     ListOfGroups ExtrusionAlongPathMakeGroups(in long_array        IDsOfElements,
                                               in SMESH_Mesh        PathMesh,
                                               in GEOM::GEOM_Object PathShape,
@@ -568,7 +602,8 @@ module SMESH
                                               in double_array      Angles,
                                               in boolean           HasRefPoint,
                                               in PointStruct       RefPoint,
-                                              out Extrusion_Error  Error);
+                                              out Extrusion_Error  Error) 
+      raises (SALOME::SALOME_Exception);
 
     Extrusion_Error ExtrusionAlongPathObject(in SMESH_IDSource    theObject,
                                              in SMESH_Mesh        PathMesh,
@@ -577,7 +612,8 @@ module SMESH
                                              in boolean           HasAngles,
                                              in double_array      Angles,
                                              in boolean           HasRefPoint,
-                                             in PointStruct       RefPoint);
+                                             in PointStruct       RefPoint) 
+      raises (SALOME::SALOME_Exception);
     ListOfGroups ExtrusionAlongPathObjectMakeGroups(in SMESH_IDSource    theObject,
                                                     in SMESH_Mesh        PathMesh,
                                                     in GEOM::GEOM_Object PathShape,
@@ -586,7 +622,8 @@ module SMESH
                                                     in double_array      Angles,
                                                     in boolean           HasRefPoint,
                                                     in PointStruct       RefPoint,
-                                                    out Extrusion_Error  Error);
+                                                    out Extrusion_Error  Error) 
+      raises (SALOME::SALOME_Exception);
 
     Extrusion_Error ExtrusionAlongPathObject1D(in SMESH_IDSource    theObject,
                                                in SMESH_Mesh        PathMesh,
@@ -595,7 +632,8 @@ module SMESH
                                                in boolean           HasAngles,
                                                in double_array      Angles,
                                                in boolean           HasRefPoint,
-                                               in PointStruct       RefPoint);
+                                               in PointStruct       RefPoint) 
+      raises (SALOME::SALOME_Exception);
     ListOfGroups ExtrusionAlongPathObject1DMakeGroups(in SMESH_IDSource    theObject,
                                                       in SMESH_Mesh        PathMesh,
                                                       in GEOM::GEOM_Object PathShape,
@@ -604,7 +642,8 @@ module SMESH
                                                       in double_array      Angles,
                                                       in boolean           HasRefPoint,
                                                       in PointStruct       RefPoint,
-                                                      out Extrusion_Error  Error);
+                                                      out Extrusion_Error  Error) 
+      raises (SALOME::SALOME_Exception);
 
     Extrusion_Error ExtrusionAlongPathObject2D(in SMESH_IDSource    theObject,
                                                in SMESH_Mesh        PathMesh,
@@ -613,7 +652,8 @@ module SMESH
                                                in boolean           HasAngles,
                                                in double_array      Angles,
                                                in boolean           HasRefPoint,
-                                               in PointStruct       RefPoint);
+                                               in PointStruct       RefPoint) 
+      raises (SALOME::SALOME_Exception);
     ListOfGroups ExtrusionAlongPathObject2DMakeGroups(in SMESH_IDSource    theObject,
                                                       in SMESH_Mesh        PathMesh,
                                                       in GEOM::GEOM_Object PathShape,
@@ -622,7 +662,8 @@ module SMESH
                                                       in double_array      Angles,
                                                       in boolean           HasRefPoint,
                                                       in PointStruct       RefPoint,
-                                                      out Extrusion_Error  Error);
+                                                      out Extrusion_Error  Error) 
+      raises (SALOME::SALOME_Exception);
 
    /*!
     * Compute rotation angles for ExtrusionAlongPath as linear variation
@@ -641,101 +682,126 @@ module SMESH
     void Mirror (in long_array IDsOfElements,
                  in AxisStruct Mirror,
                  in MirrorType Type,
-                 in boolean    Copy);
+                 in boolean    Copy) 
+      raises (SALOME::SALOME_Exception);
     ListOfGroups MirrorMakeGroups (in long_array IDsOfElements,
                                    in AxisStruct Mirror,
-                                   in MirrorType Type);
+                                   in MirrorType Type) 
+      raises (SALOME::SALOME_Exception);
     SMESH_Mesh MirrorMakeMesh (in long_array IDsOfElements,
                                in AxisStruct Mirror,
                                in MirrorType Type,
                                in boolean    CopyGroups,
-                               in string     MeshName);
+                               in string     MeshName) 
+      raises (SALOME::SALOME_Exception);
 
     void MirrorObject (in SMESH_IDSource theObject,
                        in AxisStruct     Mirror,
                        in MirrorType     Type,
-                       in boolean        Copy);
+                       in boolean        Copy) 
+      raises (SALOME::SALOME_Exception);
     ListOfGroups MirrorObjectMakeGroups (in SMESH_IDSource theObject,
                                          in AxisStruct     Mirror,
-                                         in MirrorType     Type);
+                                         in MirrorType     Type) 
+      raises (SALOME::SALOME_Exception);
     SMESH_Mesh MirrorObjectMakeMesh (in SMESH_IDSource theObject,
                                      in AxisStruct     Mirror,
                                      in MirrorType     Type,
                                      in boolean        CopyGroups,
-                                     in string         MeshName);
+                                     in string         MeshName) 
+      raises (SALOME::SALOME_Exception);
 
     void Translate (in long_array IDsOfElements,
                     in DirStruct  Vector,
-                    in boolean    Copy);
+                    in boolean    Copy) 
+      raises (SALOME::SALOME_Exception);
     ListOfGroups TranslateMakeGroups (in long_array IDsOfElements,
-                                      in DirStruct  Vector);
+                                      in DirStruct  Vector) 
+      raises (SALOME::SALOME_Exception);
     SMESH_Mesh TranslateMakeMesh (in long_array IDsOfElements,
                                   in DirStruct  Vector,
                                   in boolean    CopyGroups,
-                                  in string     MeshName);
+                                  in string     MeshName) 
+      raises (SALOME::SALOME_Exception);
 
     void TranslateObject (in SMESH_IDSource theObject,
                           in DirStruct      Vector,
-                          in boolean        Copy);
+                          in boolean        Copy) 
+      raises (SALOME::SALOME_Exception);
     ListOfGroups TranslateObjectMakeGroups (in SMESH_IDSource theObject,
-                                            in DirStruct      Vector);
+                                            in DirStruct      Vector) 
+      raises (SALOME::SALOME_Exception);
     SMESH_Mesh TranslateObjectMakeMesh (in SMESH_IDSource theObject,
                                         in DirStruct      Vector,
                                         in boolean        CopyGroups,
-                                        in string         MeshName);
+                                        in string         MeshName) 
+      raises (SALOME::SALOME_Exception);
 
     void Scale (in SMESH_IDSource theObject,
                 in PointStruct    thePoint,
                 in double_array   theScaleFact,
-                in boolean        Copy);
+                in boolean        Copy) 
+      raises (SALOME::SALOME_Exception);
     ListOfGroups ScaleMakeGroups (in SMESH_IDSource theObject,
                                   in PointStruct    thePoint,
-                                  in double_array   theScaleFact);
+                                  in double_array   theScaleFact) 
+      raises (SALOME::SALOME_Exception);
     SMESH_Mesh ScaleMakeMesh (in SMESH_IDSource theObject,
                               in PointStruct    thePoint,
                               in double_array   theScaleFact,
                               in boolean        CopyGroups,
-                              in string         MeshName);
+                              in string         MeshName) 
+      raises (SALOME::SALOME_Exception);
 
     void Rotate (in long_array IDsOfElements,
                  in AxisStruct Axis,
                  in double     AngleInRadians,
-                 in boolean    Copy);
+                 in boolean    Copy) 
+      raises (SALOME::SALOME_Exception);
     ListOfGroups RotateMakeGroups (in long_array IDsOfElements,
                                    in AxisStruct Axis,
-                                   in double     AngleInRadians);
+                                   in double     AngleInRadians) 
+      raises (SALOME::SALOME_Exception);
     SMESH_Mesh RotateMakeMesh (in long_array IDsOfElements,
                                in AxisStruct Axis,
                                in double     AngleInRadians,
                                in boolean    CopyGroups,
-                               in string     MeshName);
+                               in string     MeshName) 
+      raises (SALOME::SALOME_Exception);
 
     void RotateObject (in SMESH_IDSource theObject,
                        in AxisStruct     Axis,
                        in double         AngleInRadians,
-                       in boolean        Copy);
+                       in boolean        Copy) 
+      raises (SALOME::SALOME_Exception);
     ListOfGroups RotateObjectMakeGroups (in SMESH_IDSource theObject,
                                          in AxisStruct     Axis,
-                                         in double         AngleInRadians);
+                                         in double         AngleInRadians) 
+      raises (SALOME::SALOME_Exception);
     SMESH_Mesh RotateObjectMakeMesh (in SMESH_IDSource theObject,
                                      in AxisStruct     Axis,
                                      in double         AngleInRadians,
                                      in boolean        CopyGroups,
-                                     in string         MeshName);
+                                     in string         MeshName) 
+      raises (SALOME::SALOME_Exception);
 
     void FindCoincidentNodes (in  double              Tolerance,
-                              out array_of_long_array GroupsOfNodes);
+                              out array_of_long_array GroupsOfNodes) 
+      raises (SALOME::SALOME_Exception);
 
     void FindCoincidentNodesOnPart (in  SMESH_IDSource      SubMeshOrGroup,
                                     in  double              Tolerance,
-                                    out array_of_long_array GroupsOfNodes);
+                                    out array_of_long_array GroupsOfNodes) 
+      raises (SALOME::SALOME_Exception);
 
     void FindCoincidentNodesOnPartBut (in  SMESH_IDSource      SubMeshOrGroup,
                                        in  double              Tolerance,
                                        out array_of_long_array GroupsOfNodes,
-                                       in  ListOfIDSources     ExceptSubMeshOrGroups);
+                                       in  ListOfIDSources     ExceptSubMeshOrGroups) 
+      raises (SALOME::SALOME_Exception);
 
-    void MergeNodes (in array_of_long_array GroupsOfNodes);
+    void MergeNodes (in array_of_long_array GroupsOfNodes) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Find elements built on the same nodes.
@@ -743,36 +809,42 @@ module SMESH
      * \return List of groups of equal elements.
      */
     void FindEqualElements (in  SMESH_IDSource      MeshOrSubMeshOrGroup,
-                            out array_of_long_array GroupsOfElementsID);
+                            out array_of_long_array GroupsOfElementsID) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Merge elements in each given group.
      * \param GroupsOfElementsID Groups of elements for merging.
      */
-    void MergeElements(in array_of_long_array GroupsOfElementsID);
+    void MergeElements(in array_of_long_array GroupsOfElementsID) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Merge equal elements in the whole mesh.
      */
-    void MergeEqualElements();
+    void MergeEqualElements() 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * If the given ID is a valid node ID (nodeID > 0), just move this node, else
      * move the node closest to the point to point's location and return ID of the node
      */
-    long MoveClosestNodeToPoint(in double x, in double y, in double z, in long nodeID);
+    long MoveClosestNodeToPoint(in double x, in double y, in double z, in long nodeID) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * Return ID of node closest to a given point
      */
-    long FindNodeClosestTo(in double x, in double y, in double z);
+    long FindNodeClosestTo(in double x, in double y, in double z) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * Return elements of given type where the given point is IN or ON.
      *
      * 'ALL' type means elements of any type excluding nodes and 0D elements
      */
-    long_array FindElementsByPoint(in double x, in double y, in double z, in ElementType type);
+    long_array FindElementsByPoint(in double x, in double y, in double z, in ElementType type) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * Searching among the given elements, return elements of given type 
@@ -782,13 +854,15 @@ module SMESH
      */
     long_array FindAmongElementsByPoint(in SMESH_IDSource elements,
                                         in double x, in double y, in double z, 
-                                        in ElementType type);
+                                        in ElementType type) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * 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.
      */
-    short GetPointState(in double x, in double y, in double z);
+    short GetPointState(in double x, in double y, in double z) 
+      raises (SALOME::SALOME_Exception);
 
     enum Sew_Error {
       SEW_OK,
@@ -811,13 +885,15 @@ module SMESH
                               in long SecondNodeID2,
                               in long LastNodeID2,
                               in boolean CreatePolygons,
-                              in boolean CreatePolyedrs);
+                              in boolean CreatePolyedrs) 
+      raises (SALOME::SALOME_Exception);
 
     Sew_Error SewConformFreeBorders (in long FirstNodeID1,
                                      in long SecondNodeID1,
                                      in long LastNodeID1,
                                      in long FirstNodeID2,
-                                     in long SecondNodeID2);
+                                     in long SecondNodeID2) 
+      raises (SALOME::SALOME_Exception);
 
     Sew_Error SewBorderToSide (in long FirstNodeIDOnFreeBorder,
                                in long SecondNodeIDOnFreeBorder,
@@ -825,21 +901,24 @@ module SMESH
                                in long FirstNodeIDOnSide,
                                in long LastNodeIDOnSide,
                                in boolean CreatePolygons,
-                               in boolean CreatePolyedrs);
+                               in boolean CreatePolyedrs) 
+      raises (SALOME::SALOME_Exception);
 
     Sew_Error SewSideElements (in long_array IDsOfSide1Elements,
                                in long_array IDsOfSide2Elements,
                                in long       NodeID1OfSide1ToMerge,
                                in long       NodeID1OfSide2ToMerge,
                                in long       NodeID2OfSide1ToMerge,
-                               in long       NodeID2OfSide2ToMerge);
+                               in long       NodeID2OfSide2ToMerge) 
+      raises (SALOME::SALOME_Exception);
 
    /*!
     * Set new nodes for given element.
     * If number of nodes is not corresponded to type of
     * element - returns false
     */
-    boolean ChangeElemNodes(in long ide, in long_array newIDs);
+    boolean ChangeElemNodes(in long ide, in long_array newIDs) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
@@ -850,7 +929,8 @@ module SMESH
      *        \return TRUE if operation has been completed successfully, FALSE otherwise
      * \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
      */
-    boolean DoubleNodes( in long_array theNodes, in long_array theModifiedElems );
+    boolean DoubleNodes( in long_array theNodes, in long_array theModifiedElems ) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
@@ -860,7 +940,8 @@ module SMESH
      * \return TRUE if operation has been completed successfully, FALSE otherwise
      * \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
      */
-    boolean DoubleNode( in long theNodeId, in long_array theModifiedElems );
+    boolean DoubleNode( in long theNodeId, in long_array theModifiedElems ) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
@@ -871,7 +952,8 @@ module SMESH
      * \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups(), DoubleNodeGroupNew()
      */
     boolean DoubleNodeGroup( in SMESH_GroupBase theNodes,
-                             in SMESH_GroupBase theModifiedElems );
+                             in SMESH_GroupBase theModifiedElems ) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
      * Works as DoubleNodeGroup() described above, but returns a new group with
@@ -882,7 +964,8 @@ module SMESH
      * \sa DoubleNodeGroup()
      */
     SMESH_Group DoubleNodeGroupNew( in SMESH_GroupBase theNodes,
-                                    in SMESH_GroupBase theModifiedElems );
+                                    in SMESH_GroupBase theModifiedElems ) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
@@ -893,7 +976,8 @@ module SMESH
      * \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
      */
     boolean DoubleNodeGroups( in ListOfGroups theNodes,
-                              in ListOfGroups theModifiedElems );
+                              in ListOfGroups theModifiedElems ) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
      * Works as DoubleNodeGroups() described above, but returns a new group with
@@ -904,7 +988,8 @@ module SMESH
      * \sa DoubleNodeGroups()
      */
     SMESH_Group DoubleNodeGroupsNew( in ListOfGroups theNodes,
-                                    in ListOfGroups theModifiedElems );
+                                    in ListOfGroups theModifiedElems ) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
@@ -918,7 +1003,8 @@ module SMESH
      */
     boolean DoubleNodeElem( in long_array theElems,
                             in long_array theNodesNot,
-                            in long_array theAffectedElems );
+                            in long_array theAffectedElems ) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
@@ -933,7 +1019,8 @@ module SMESH
      */
     boolean DoubleNodeElemInRegion( in long_array theElems,
                                     in long_array theNodesNot,
-                                    in GEOM::GEOM_Object theShape );
+                                    in GEOM::GEOM_Object theShape ) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
@@ -947,7 +1034,8 @@ module SMESH
      */
     boolean DoubleNodeElemGroup( in SMESH_GroupBase theElems,
                                  in SMESH_GroupBase theNodesNot,
-                                 in SMESH_GroupBase theAffectedElems );
+                                 in SMESH_GroupBase theAffectedElems ) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
      * Works as DoubleNodeElemGroup() described above, but returns a new group with
@@ -961,7 +1049,8 @@ module SMESH
      */
     SMESH_Group DoubleNodeElemGroupNew( in SMESH_GroupBase theElems,
                                         in SMESH_GroupBase theNodesNot,
-                                        in SMESH_GroupBase theAffectedElems );
+                                        in SMESH_GroupBase theAffectedElems ) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
      * Works as DoubleNodeElemGroup() described above, but returns two new groups:
@@ -979,7 +1068,8 @@ module SMESH
                                           in SMESH_GroupBase theNodesNot,
                                           in SMESH_GroupBase theAffectedElems,
                                           in boolean         theElemGroupNeeded,
-                                          in boolean         theNodeGroupNeeded);
+                                          in boolean         theNodeGroupNeeded) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
@@ -994,7 +1084,8 @@ module SMESH
      */
     boolean DoubleNodeElemGroupInRegion( in SMESH_GroupBase theElems,
                                          in SMESH_GroupBase theNodesNot,
-                                         in GEOM::GEOM_Object theShape );
+                                         in GEOM::GEOM_Object theShape ) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
@@ -1008,7 +1099,8 @@ module SMESH
      */
     boolean DoubleNodeElemGroups( in ListOfGroups theElems,
                                   in ListOfGroups theNodesNot,
-                                  in ListOfGroups theAffectedElems );
+                                  in ListOfGroups theAffectedElems ) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
      * Works as DoubleNodeElemGroups() described above, but returns a new group with
@@ -1022,7 +1114,8 @@ module SMESH
      */
     SMESH_Group DoubleNodeElemGroupsNew( in ListOfGroups theElems,
                                          in ListOfGroups theNodesNot,
-                                         in ListOfGroups theAffectedElems );
+                                         in ListOfGroups theAffectedElems ) 
+      raises (SALOME::SALOME_Exception);
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
      * Works as DoubleNodeElemGroups() described above, but returns two new groups:
@@ -1040,7 +1133,8 @@ module SMESH
                                            in ListOfGroups theNodesNot,
                                            in ListOfGroups theAffectedElems,
                                            in boolean         theElemGroupNeeded,
-                                           in boolean         theNodeGroupNeeded );
+                                           in boolean         theNodeGroupNeeded ) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
@@ -1055,7 +1149,8 @@ module SMESH
      */
     boolean DoubleNodeElemGroupsInRegion( in ListOfGroups theElems,
                                           in ListOfGroups theNodesNot,
-                                          in GEOM::GEOM_Object theShape );
+                                          in GEOM::GEOM_Object theShape )
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Identify the elements that will be affected by node duplication (actual duplication is not performed).
@@ -1070,14 +1165,15 @@ module SMESH
      */
     ListOfGroups AffectedElemGroupsInRegion( in ListOfGroups theElems,
                                              in ListOfGroups theNodesNot,
-                                             in GEOM::GEOM_Object theShape );
+                                             in GEOM::GEOM_Object theShape ) 
+      raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Generates skin mesh (containing 2D cells) from 3D mesh
      * The created 2D mesh elements based on nodes of free faces of boundary volumes
      * \return TRUE if operation has been completed successfully, FALSE otherwise
      */
-    boolean Make2DMeshFrom3D();
+    boolean Make2DMeshFrom3D() raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Creates missing boundary elements
@@ -1101,7 +1197,7 @@ module SMESH
                                 in string         meshName,
                                 in boolean        toCopyElements,
                                 in boolean        toCopyExistingBondary,
-                                out SMESH_Group   group);
+                                out SMESH_Group   group) raises (SALOME::SALOME_Exception);
     /*!
      * \brief Creates missing boundary elements around either the whole mesh or 
      *    groups of 2D elements
@@ -1150,7 +1246,8 @@ module SMESH
      * \param theGroupsOfFaces - list of groups of faces
      * \return TRUE if operation has been completed successfully, FALSE otherwise
      */
-    boolean CreateFlatElementsOnFacesGroups( in ListOfGroups theGroupsOfFaces ); 
+    boolean CreateFlatElementsOnFacesGroups( in ListOfGroups theGroupsOfFaces ) 
+      raises (SALOME::SALOME_Exception); 
 
     /*!
      *  \brief identify all the elements around a geom shape, get the faces delimiting the hole
@@ -1162,7 +1259,8 @@ module SMESH
                         in GEOM::GEOM_Object theShape,
                         in string groupName,
                         in double_array theNodesCoords,
-                        out array_of_long_array GroupsOfNodes) raises (SALOME::SALOME_Exception);
+                        out array_of_long_array GroupsOfNodes) 
+      raises (SALOME::SALOME_Exception);
   };
 };
 
index 239aa41..eb1e5bd 100644 (file)
@@ -210,10 +210,13 @@ using namespace SMESH::Controls;
  *                               FUNCTORS
  */
 
+//================================================================================
 /*
   Class       : NumericalFunctor
   Description : Base class for numerical functors
 */
+//================================================================================
+
 NumericalFunctor::NumericalFunctor():
   myMesh(NULL)
 {
@@ -321,6 +324,7 @@ double NumericalFunctor::Round( const double & aVal )
  *  \param minmax - boundaries of diapason of values to divide into intervals
  */
 //================================================================================
+
 void NumericalFunctor::GetHistogram(int                  nbIntervals,
                                     std::vector<int>&    nbEvents,
                                     std::vector<double>& funValues,
@@ -403,9 +407,11 @@ void NumericalFunctor::GetHistogram(int                  nbIntervals,
 }
 
 //=======================================================================
-//function : GetValue
-//purpose  : 
-//=======================================================================
+/*
+  Class       : Volume
+  Description : Functor calculating volume of a 3D element
+*/
+//================================================================================
 
 double Volume::GetValue( long theElementId )
 {
@@ -417,21 +423,11 @@ double Volume::GetValue( long theElementId )
   return 0;
 }
 
-//=======================================================================
-//function : GetBadRate
-//purpose  : meaningless as it is not quality control functor
-//=======================================================================
-
 double Volume::GetBadRate( double Value, int /*nbNodes*/ ) const
 {
   return Value;
 }
 
-//=======================================================================
-//function : GetType
-//purpose  : 
-//=======================================================================
-
 SMDSAbs_ElementType Volume::GetType() const
 {
   return SMDSAbs_Volume;
@@ -442,6 +438,8 @@ SMDSAbs_ElementType Volume::GetType() const
   Class       : MaxElementLength2D
   Description : Functor calculating maximum length of 2D element
 */
+//================================================================================
+
 double MaxElementLength2D::GetValue( const TSequenceOfXYZ& P )
 {
   if(P.size() == 0)
@@ -508,6 +506,7 @@ SMDSAbs_ElementType MaxElementLength2D::GetType() const
   Class       : MaxElementLength3D
   Description : Functor calculating maximum length of 3D element
 */
+//================================================================================
 
 double MaxElementLength3D::GetValue( long theElementId )
 {
@@ -683,6 +682,7 @@ SMDSAbs_ElementType MaxElementLength3D::GetType() const
   Class       : MinimumAngle
   Description : Functor for calculation of minimum angle
 */
+//================================================================================
 
 double MinimumAngle::GetValue( const TSequenceOfXYZ& P )
 {
@@ -715,10 +715,13 @@ SMDSAbs_ElementType MinimumAngle::GetType() const
 }
 
 
+//================================================================================
 /*
   Class       : AspectRatio
   Description : Functor for calculating aspect ratio
 */
+//================================================================================
+
 double AspectRatio::GetValue( long theId )
 {
   double aVal = 0;
@@ -899,10 +902,13 @@ SMDSAbs_ElementType AspectRatio::GetType() const
 }
 
 
+//================================================================================
 /*
   Class       : AspectRatio3D
   Description : Functor for calculating aspect ratio
 */
+//================================================================================
+
 namespace{
 
   inline double getHalfPerimeter(double theTria[3]){
@@ -1269,10 +1275,13 @@ SMDSAbs_ElementType AspectRatio3D::GetType() const
 }
 
 
+//================================================================================
 /*
   Class       : Warping
   Description : Functor for calculating warping
 */
+//================================================================================
+
 double Warping::GetValue( const TSequenceOfXYZ& P )
 {
   if ( P.size() != 4 )
@@ -1326,10 +1335,13 @@ SMDSAbs_ElementType Warping::GetType() const
 }
 
 
+//================================================================================
 /*
   Class       : Taper
   Description : Functor for calculating taper
 */
+//================================================================================
+
 double Taper::GetValue( const TSequenceOfXYZ& P )
 {
   if ( P.size() != 4 )
@@ -1366,11 +1378,13 @@ SMDSAbs_ElementType Taper::GetType() const
   return SMDSAbs_Face;
 }
 
-
+//================================================================================
 /*
   Class       : Skew
   Description : Functor for calculating skew in degrees
 */
+//================================================================================
+
 static inline double skewAngle( const gp_XYZ& p1, const gp_XYZ& p2, const gp_XYZ& p3 )
 {
   gp_XYZ p12 = ( p2 + p1 ) / 2.;
@@ -1430,10 +1444,13 @@ SMDSAbs_ElementType Skew::GetType() const
 }
 
 
+//================================================================================
 /*
   Class       : Area
   Description : Functor for calculating area
 */
+//================================================================================
+
 double Area::GetValue( const TSequenceOfXYZ& P )
 {
   double val = 0.0;
@@ -1463,11 +1480,13 @@ SMDSAbs_ElementType Area::GetType() const
   return SMDSAbs_Face;
 }
 
-
+//================================================================================
 /*
   Class       : Length
   Description : Functor for calculating length of edge
 */
+//================================================================================
+
 double Length::GetValue( const TSequenceOfXYZ& P )
 {
   switch ( P.size() ) {
@@ -1488,10 +1507,12 @@ SMDSAbs_ElementType Length::GetType() const
   return SMDSAbs_Edge;
 }
 
+//================================================================================
 /*
   Class       : Length2D
   Description : Functor for calculating length of edge
 */
+//================================================================================
 
 double Length2D::GetValue( long theElementId)
 {
@@ -1799,10 +1820,13 @@ void Length2D::GetValues(TValues& theValues){
   }
 }
 
+//================================================================================
 /*
   Class       : MultiConnection
   Description : Functor for calculating number of faces conneted to the edge
 */
+//================================================================================
+
 double MultiConnection::GetValue( const TSequenceOfXYZ& P )
 {
   return 0;
@@ -1823,10 +1847,13 @@ SMDSAbs_ElementType MultiConnection::GetType() const
   return SMDSAbs_Edge;
 }
 
+//================================================================================
 /*
   Class       : MultiConnection2D
   Description : Functor for calculating number of faces conneted to the edge
 */
+//================================================================================
+
 double MultiConnection2D::GetValue( const TSequenceOfXYZ& P )
 {
   return 0;
@@ -1970,10 +1997,13 @@ void MultiConnection2D::GetValues(MValues& theValues){
 
 }
 
+//================================================================================
 /*
   Class       : BallDiameter
   Description : Functor returning diameter of a ball element
 */
+//================================================================================
+
 double BallDiameter::GetValue( long theId )
 {
   double diameter = 0;
@@ -2002,10 +2032,12 @@ SMDSAbs_ElementType BallDiameter::GetType() const
                             PREDICATES
 */
 
+//================================================================================
 /*
   Class       : BadOrientedVolume
   Description : Predicate bad oriented volumes
 */
+//================================================================================
 
 BadOrientedVolume::BadOrientedVolume()
 {
@@ -2052,9 +2084,11 @@ bool BareBorderVolume::IsSatisfy(long theElementId )
   return false;
 }
 
+//================================================================================
 /*
   Class       : BareBorderFace
 */
+//================================================================================
 
 bool BareBorderFace::IsSatisfy(long theElementId )
 {
@@ -2092,9 +2126,11 @@ bool BareBorderFace::IsSatisfy(long theElementId )
   return ok;
 }
 
+//================================================================================
 /*
   Class       : OverConstrainedVolume
 */
+//================================================================================
 
 bool OverConstrainedVolume::IsSatisfy(long theElementId )
 {
@@ -2112,9 +2148,11 @@ bool OverConstrainedVolume::IsSatisfy(long theElementId )
   return false;
 }
 
+//================================================================================
 /*
   Class       : OverConstrainedFace
 */
+//================================================================================
 
 bool OverConstrainedFace::IsSatisfy(long theElementId )
 {
@@ -2145,10 +2183,12 @@ bool OverConstrainedFace::IsSatisfy(long theElementId )
   return false;
 }
 
+//================================================================================
 /*
   Class       : CoincidentNodes
   Description : Predicate of Coincident nodes
 */
+//================================================================================
 
 CoincidentNodes::CoincidentNodes()
 {
@@ -2190,11 +2230,13 @@ void CoincidentNodes::SetMesh( const SMDS_Mesh* theMesh )
   }
 }
 
+//================================================================================
 /*
   Class       : CoincidentElements
   Description : Predicate of Coincident Elements
   Note        : This class is suitable only for visualization of Coincident Elements
 */
+//================================================================================
 
 CoincidentElements::CoincidentElements()
 {
@@ -2245,10 +2287,12 @@ SMDSAbs_ElementType CoincidentElements3D::GetType() const
 }
 
 
+//================================================================================
 /*
   Class       : FreeBorders
   Description : Predicate for free borders
 */
+//================================================================================
 
 FreeBorders::FreeBorders()
 {
@@ -2271,10 +2315,13 @@ SMDSAbs_ElementType FreeBorders::GetType() const
 }
 
 
+//================================================================================
 /*
   Class       : FreeEdges
   Description : Predicate for free Edges
 */
+//================================================================================
+
 FreeEdges::FreeEdges()
 {
   myMesh = 0;
@@ -2406,11 +2453,12 @@ void FreeEdges::GetBoreders(TBorders& theBorders)
   }
 }
 
-
+//================================================================================
 /*
   Class       : FreeNodes
   Description : Predicate for free nodes
 */
+//================================================================================
 
 FreeNodes::FreeNodes()
 {
@@ -2437,10 +2485,12 @@ SMDSAbs_ElementType FreeNodes::GetType() const
 }
 
 
+//================================================================================
 /*
   Class       : FreeFaces
   Description : Predicate for free faces
 */
+//================================================================================
 
 FreeFaces::FreeFaces()
 {
@@ -2493,10 +2543,12 @@ SMDSAbs_ElementType FreeFaces::GetType() const
   return SMDSAbs_Face;
 }
 
+//================================================================================
 /*
   Class       : LinearOrQuadratic
   Description : Predicate to verify whether a mesh element is linear
 */
+//================================================================================
 
 LinearOrQuadratic::LinearOrQuadratic()
 {
@@ -2527,10 +2579,12 @@ SMDSAbs_ElementType LinearOrQuadratic::GetType() const
   return myType;
 }
 
+//================================================================================
 /*
   Class       : GroupColor
   Description : Functor for check color of group to whic mesh element belongs to
 */
+//================================================================================
 
 GroupColor::GroupColor()
 {
@@ -2619,6 +2673,7 @@ void GroupColor::SetColorStr( const TCollection_AsciiString& theStr )
 // Purpose : Get range as a string.
 //           Example: "1,2,3,50-60,63,67,70-"
 //=======================================================================
+
 void GroupColor::GetColorStr( TCollection_AsciiString& theResStr ) const
 {
   theResStr.Clear();
@@ -2627,10 +2682,12 @@ void GroupColor::GetColorStr( TCollection_AsciiString& theResStr ) const
   theResStr += TCollection_AsciiString( ";" ) + TCollection_AsciiString( myColor.Blue() );
 }
 
+//================================================================================
 /*
   Class       : ElemGeomType
   Description : Predicate to check element geometry type
 */
+//================================================================================
 
 ElemGeomType::ElemGeomType()
 {
@@ -2678,6 +2735,54 @@ SMDSAbs_GeometryType ElemGeomType::GetGeomType() const
 }
 
 //================================================================================
+/*
+  Class       : ElemEntityType
+  Description : Predicate to check element entity type
+*/
+//================================================================================
+
+ElemEntityType::ElemEntityType():
+  myMesh( 0 ),
+  myType( SMDSAbs_All ),
+  myEntityType( SMDSEntity_0D )
+{
+}
+
+void ElemEntityType::SetMesh( const SMDS_Mesh* theMesh )
+{
+  myMesh = theMesh;
+}
+
+bool ElemEntityType::IsSatisfy( long theId )
+{
+  if ( !myMesh ) return false;
+  const SMDS_MeshElement* anElem = myMesh->FindElement( theId );
+  return ( anElem &&
+           myEntityType == anElem->GetEntityType() &&
+           ( myType == SMDSAbs_Edge || myType == SMDSAbs_Face || myType ==  SMDSAbs_Volume ));
+}
+
+void ElemEntityType::SetType( SMDSAbs_ElementType theType )
+{
+  myType = theType;
+}
+
+SMDSAbs_ElementType ElemEntityType::GetType() const
+{
+  return myType;
+}
+
+void ElemEntityType::SetElemEntityType( SMDSAbs_EntityType theEntityType )
+{
+  myEntityType = theEntityType;
+}
+
+SMDSAbs_EntityType ElemEntityType::GetElemEntityType() const
+{
+  return myEntityType;
+}
+
+//================================================================================
 /*!
  * \brief Class CoplanarFaces
  */
index 9b9c265..972cb04 100644 (file)
@@ -245,7 +245,6 @@ namespace SMESH{
       virtual SMDSAbs_ElementType GetType() const;
     };
 
-
     /*
       Class       : Skew
       Description : Functor for calculating skew in degrees
@@ -430,6 +429,28 @@ namespace SMESH{
     };
 
     /*
+      Class       : ElemEntityType
+      Description : Functor for calculating entity type
+    */
+    class SMESHCONTROLS_EXPORT ElemEntityType: public virtual Predicate{
+      public:
+      ElemEntityType();
+      virtual void         SetMesh( const SMDS_Mesh* theMesh );
+      virtual bool         IsSatisfy( long theElementId );
+      void                 SetType( SMDSAbs_ElementType theType );
+      virtual              SMDSAbs_ElementType GetType() const;
+      void                 SetElemEntityType( SMDSAbs_EntityType theEntityType );
+      SMDSAbs_EntityType   GetElemEntityType() const;
+
+    private:
+      const SMDS_Mesh*     myMesh;
+      SMDSAbs_ElementType  myType;
+      SMDSAbs_EntityType   myEntityType;
+    };
+    typedef boost::shared_ptr<ElemEntityType> ElemEntityTypePtr;
+
+
+    /*
       BareBorderVolume
     */
     class SMESHCONTROLS_EXPORT BareBorderVolume: public Predicate
index e3fc5d7..0d70c8d 100644 (file)
@@ -29,6 +29,7 @@
 #include "SMESHDS_Group.hxx"
 #include "SMESHDS_Mesh.hxx"
 #include "SMESH_Comment.hxx"
+#include "SMESH_TypeDefs.hxx"
 
 #include <Basics_Utils.hxx>
 
@@ -69,9 +70,11 @@ Driver_Mesh::Status DriverGMF_Read::Perform()
   if ( !meshID )
   {
     if ( DriverGMF::isExtensionCorrect( myFile ))
-      return addMessage( SMESH_Comment("Can't open for reading ") << myFile, /*fatal=*/true );
+      return addMessage( SMESH_Comment("Can't open for reading ") << myFile,
+                         /*fatal=*/true );
     else
-      return addMessage( SMESH_Comment("Not '.mesh' or '.meshb' extension of file ") << myFile, /*fatal=*/true );
+      return addMessage( SMESH_Comment("Not '.mesh' or '.meshb' extension of file ") << myFile,
+                         /*fatal=*/true );
   }
   DriverGMF::MeshCloser aMeshCloser( meshID ); // An object closing GMF mesh at destruction
 
@@ -109,34 +112,33 @@ Driver_Mesh::Status DriverGMF_Read::Perform()
 
   int iN[28]; // 28 - nb nodes in HEX27 (+ 1 for safety :)
 
-  /* Read extra vertices for quadratic edges */
-  std::vector<int> quadNodesAtEdges;
-  int nbQuadEdges = 0;
-  if ( (nbQuadEdges = GmfStatKwd(meshID, GmfExtraVerticesAtEdges)) )
-  {
-    quadNodesAtEdges.reserve( nbQuadEdges );
-    GmfGotoKwd(meshID, GmfExtraVerticesAtEdges);
-    for ( int i = 1; i <= nbQuadEdges; ++i )
-    {
-      GmfGetLin(meshID, GmfExtraVerticesAtEdges, &iN[0], &iN[1], &iN[2]);
-      quadNodesAtEdges.push_back(iN[2]);
-    }
-  }
-
   /* Read edges */
   const int edgeIDShift = myMesh->GetMeshInfo().NbElements();
   if ( int nbEdges = GmfStatKwd(meshID, GmfEdges))
   {
-    const bool readQuadNodes = ( nbQuadEdges == nbEdges );
+    // read extra vertices for quadratic edges
+    std::vector<int> quadNodesAtEdges( nbEdges + 1, -1 );
+    if ( int nbQuadEdges = GmfStatKwd(meshID, GmfExtraVerticesAtEdges))
+    {
+      GmfGotoKwd(meshID, GmfExtraVerticesAtEdges);
+      for ( int i = 1; i <= nbQuadEdges; ++i )
+      {
+        GmfGetLin(meshID, GmfExtraVerticesAtEdges, &iN[0], &iN[1], &iN[2]);
+        if ( iN[1] >= 1 )
+          quadNodesAtEdges[ iN[0] ] = iN[2];
+      }
+    }
+    // create edges
     GmfGotoKwd(meshID, GmfEdges);
     for ( int i = 1; i <= nbEdges; ++i )
     {
       GmfGetLin(meshID, GmfEdges, &iN[0], &iN[1], &ref);
-      if ( readQuadNodes )
+      const int midN = quadNodesAtEdges[ i ];
+      if ( midN > 0 )
       {
-        const int midN = quadNodesAtEdges[i-1];
         if ( !myMesh->AddEdgeWithID( iN[0], iN[1], midN, edgeIDShift + i ))
-          status = storeBadNodeIds( "GmfEdges + GmfExtraVerticesAtEdges",i, 3, iN[0],iN[1],midN);
+          status = storeBadNodeIds( "GmfEdges + GmfExtraVerticesAtEdges",i,
+                                    3, iN[0], iN[1], midN);
       }
       else
       {
@@ -145,47 +147,40 @@ Driver_Mesh::Status DriverGMF_Read::Perform()
       }
     }
   }
-  // the vector of extra vertices at edges won't be used anymore so it is cleared
-  quadNodesAtEdges.clear();
-
-  /* Read extra vertices for quadratic triangles */
-  std::vector< std::vector<int> > quadNodesAtTriangles;
-  int nbQuadTria = 0;
-  if ( (nbQuadTria = GmfStatKwd(meshID, GmfExtraVerticesAtTriangles)) )
-  {
-    GmfGotoKwd(meshID, GmfExtraVerticesAtTriangles);
-    quadNodesAtTriangles.reserve( nbQuadTria );
-    std::vector<int> nodes(4);
-    for ( int i = 1; i <= nbQuadTria; ++i )
-    {
-      GmfGetLin(meshID, GmfExtraVerticesAtTriangles,
-                &iN[0], &iN[1], &iN[2], &iN[3], &iN[4],
-                &iN[5]); // iN[5] - preview TRIA7
-      nodes.clear();
-      nodes.push_back(iN[2]);
-      nodes.push_back(iN[3]);
-      nodes.push_back(iN[4]);
-      nodes.push_back(iN[5]);
-      nodes.resize( iN[1] );
-
-      quadNodesAtTriangles.push_back(nodes);
-    }
-  }
 
   /* Read triangles */
   const int triaIDShift = myMesh->GetMeshInfo().NbElements();
   if ( int nbTria = GmfStatKwd(meshID, GmfTriangles))
   {
-    const bool readQuadNodes = (nbQuadTria == nbTria);
+    // read extra vertices for quadratic triangles
+    std::vector< std::vector<int> > quadNodesAtTriangles( nbTria + 1 );
+    if ( int nbQuadTria = GmfStatKwd(meshID, GmfExtraVerticesAtTriangles ))
+    {
+      GmfGotoKwd( meshID, GmfExtraVerticesAtTriangles );
+      for ( int i = 1; i <= nbQuadTria; ++i )
+      {
+        GmfGetLin(meshID, GmfExtraVerticesAtTriangles,
+                  &iN[0], &iN[1], &iN[2], &iN[3], &iN[4],
+                  &iN[5]); // iN[5] - preview TRIA7
+        if ( iN[0] <= nbTria )
+        {
+          std::vector<int>& nodes = quadNodesAtTriangles[ iN[0] ];
+          nodes.insert( nodes.end(), & iN[2], & iN[5+1] );
+          nodes.resize( iN[1] );
+        }
+      }
+    }
+    // create triangles
     GmfGotoKwd(meshID, GmfTriangles);
     for ( int i = 1; i <= nbTria; ++i )
     {
       GmfGetLin(meshID, GmfTriangles, &iN[0], &iN[1], &iN[2], &ref);
-      if ( readQuadNodes )
+      std::vector<int>& midN = quadNodesAtTriangles[ i ];
+      if ( midN.size() >= 3 )
       {
-        const std::vector<int>& midN = quadNodesAtTriangles[ i-1 ];
-        if ( !myMesh->AddFaceWithID( iN[0],iN[1],iN[2], midN[0],midN[1],midN[2],  triaIDShift + i ))
-          status = storeBadNodeIds( "GmfTriangles + GmfExtraVerticesAtTriangles",i, 6, 
+        if ( !myMesh->AddFaceWithID( iN[0],iN[1],iN[2], midN[0],midN[1],midN[2],
+                                     triaIDShift + i ))
+          status = storeBadNodeIds( "GmfTriangles + GmfExtraVerticesAtTriangles",i, 6,
                                     iN[0],iN[1],iN[2], midN[0],midN[1],midN[2] );
       }
       else
@@ -193,127 +188,108 @@ Driver_Mesh::Status DriverGMF_Read::Perform()
         if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], triaIDShift + i ))
           status = storeBadNodeIds( "GmfTriangles",i, 3, iN[0], iN[1], iN[2] );
       }
+      if ( !midN.empty() ) SMESHUtils::FreeVector( midN );
     }
   }
-  // the vector of extra vertices at triangles won't be used anymore so it is cleared
-  quadNodesAtTriangles.clear();
 
-  /* Read extra vertices for quadratic quadrangles */
-  std::vector< std::vector<int> > quadNodesAtQuadrilaterals;
-  int nbQuadQuad = 0;
-  if ( (nbQuadQuad = GmfStatKwd(meshID, GmfExtraVerticesAtQuadrilaterals)) )
-  {
-    GmfGotoKwd(meshID, GmfExtraVerticesAtQuadrilaterals);
-    quadNodesAtQuadrilaterals.reserve( nbQuadQuad );
-    std::vector<int> nodes( 5 );
-    for ( int i = 1; i <= nbQuadQuad; ++i )
-    {
-      GmfGetLin(meshID, GmfExtraVerticesAtQuadrilaterals,
-                &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &iN[6]);
-      nodes.clear();
-      nodes.push_back(iN[2]);
-      nodes.push_back(iN[3]);
-      nodes.push_back(iN[4]);
-      nodes.push_back(iN[5]);
-      nodes.push_back(iN[6]);
-      nodes.resize( iN[1] );
-
-      quadNodesAtQuadrilaterals.push_back(nodes);
-    }
-  }
-
- /* Read quadrangles */
+  /* Read quadrangles */
   const int quadIDShift = myMesh->GetMeshInfo().NbElements();
   if ( int nbQuad = GmfStatKwd(meshID, GmfQuadrilaterals))
   {
-    const bool readQuadNodes = (nbQuadQuad == nbQuad);
+    // read extra vertices for quadratic quadrangles
+    std::vector< std::vector<int> > quadNodesAtQuadrilaterals( nbQuad + 1 );
+    if ( int nbQuadQuad = GmfStatKwd( meshID, GmfExtraVerticesAtQuadrilaterals ))
+    {
+      GmfGotoKwd(meshID, GmfExtraVerticesAtQuadrilaterals);
+      for ( int i = 1; i <= nbQuadQuad; ++i )
+      {
+        GmfGetLin(meshID, GmfExtraVerticesAtQuadrilaterals,
+                  &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &iN[6]);
+        if ( iN[0] <= nbQuad )
+        {
+          std::vector<int>& nodes = quadNodesAtQuadrilaterals[ iN[0] ];
+          nodes.insert( nodes.end(), & iN[2], & iN[6+1] );
+          nodes.resize( iN[1] );
+        }
+      }
+    }
+    // create quadrangles
     GmfGotoKwd(meshID, GmfQuadrilaterals);
     for ( int i = 1; i <= nbQuad; ++i )
     {
       GmfGetLin(meshID, GmfQuadrilaterals, &iN[0], &iN[1], &iN[2], &iN[3], &ref);
-      if ( readQuadNodes )
+      std::vector<int>& midN = quadNodesAtQuadrilaterals[ i ];
+      if ( midN.size() == 8-4 ) // QUAD8
       {
-        const std::vector<int>& midN = quadNodesAtQuadrilaterals[ i-1 ];
-        if ( midN.size() == 4 )
-        {
-          if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], iN[3],
-                                       midN[0], midN[1], midN[2], midN[3],
-                                       quadIDShift + i ))
-            status = storeBadNodeIds( "GmfQuadrilaterals + GmfExtraVerticesAtQuadrilaterals",i, 8,
-                                      iN[0], iN[1],iN[2], iN[3],
-                                      midN[0], midN[1], midN[2], midN[3]);
-        }
-        else
-        {
-          if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], iN[3],
-                                       midN[0], midN[1], midN[2], midN[3], midN[4],
-                                       quadIDShift + i ))
-            status = storeBadNodeIds( "GmfQuadrilaterals + GmfExtraVerticesAtQuadrilaterals",i, 9,
-                                      iN[0], iN[1],iN[2], iN[3],
-                                      midN[0], midN[1], midN[2], midN[3], midN[4]);
-        }
+        if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], iN[3],
+                                     midN[0], midN[1], midN[2], midN[3],
+                                     quadIDShift + i ))
+          status = storeBadNodeIds( "GmfQuadrilaterals + GmfExtraVerticesAtQuadrilaterals",i, 8,
+                                    iN[0], iN[1],iN[2], iN[3],
+                                    midN[0], midN[1], midN[2], midN[3]);
       }
-      else
+      else if ( midN.size() > 8-4 ) // QUAD9
+      {
+        if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], iN[3],
+                                     midN[0], midN[1], midN[2], midN[3], midN[4],
+                                     quadIDShift + i ))
+          status = storeBadNodeIds( "GmfQuadrilaterals + GmfExtraVerticesAtQuadrilaterals",i, 9,
+                                    iN[0], iN[1],iN[2], iN[3],
+                                    midN[0], midN[1], midN[2], midN[3], midN[4]);
+      }
+      else // QUAD4
       {
         if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], iN[3], quadIDShift + i ))
           status = storeBadNodeIds( "GmfQuadrilaterals",i, 4, iN[0], iN[1],iN[2], iN[3] );
       }
+      if ( !midN.empty() ) SMESHUtils::FreeVector( midN );
     }
   }
-  // the vector of extra vertices at quadrilaterals won't be used anymore so it is cleared
-  quadNodesAtQuadrilaterals.clear();
 
-  /* Read extra vertices for quadratic tetrahedra */
-  std::vector< std::vector<int> > quadNodesAtTetrahedra;
-  int nbQuadTetra = 0;
-  if ( (nbQuadTetra = GmfStatKwd(meshID, GmfExtraVerticesAtTetrahedra)) )
-  {
-    GmfGotoKwd(meshID, GmfExtraVerticesAtTetrahedra);
-    quadNodesAtTetrahedra.reserve( nbQuadTetra );
-    std::vector<int> nodes( 6 );
-    for ( int i = 1; i <= nbQuadTetra; ++i )
-    {
-      GmfGetLin(meshID, GmfExtraVerticesAtTetrahedra,
-                &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &iN[6], &iN[7]);
-      nodes.clear();
-      nodes.push_back(iN[2]);
-      nodes.push_back(iN[3]);
-      nodes.push_back(iN[4]);
-      nodes.push_back(iN[5]);
-      nodes.push_back(iN[6]);
-      nodes.push_back(iN[7]);
-      nodes.resize( iN[1] );
-
-      quadNodesAtTetrahedra.push_back(nodes);
-    }
-  }
   /* Read terahedra */
   const int tetIDShift = myMesh->GetMeshInfo().NbElements();
-  if ( int nbTet = GmfStatKwd(meshID, GmfTetrahedra))
+  if ( int nbTet = GmfStatKwd( meshID, GmfTetrahedra ))
   {
-    const bool readQuadNodes = (nbQuadTetra == nbTet);
+    // read extra vertices for quadratic tetrahedra
+    std::vector< std::vector<int> > quadNodesAtTetrahedra( nbTet + 1 );
+    if ( int nbQuadTetra = GmfStatKwd( meshID, GmfExtraVerticesAtTetrahedra ))
+    {
+      GmfGotoKwd(meshID, GmfExtraVerticesAtTetrahedra);
+      for ( int i = 1; i <= nbQuadTetra; ++i )
+      {
+        GmfGetLin(meshID, GmfExtraVerticesAtTetrahedra,
+                  &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &iN[6], &iN[7]);
+        if ( iN[0] <= nbTet )
+        {
+          std::vector<int>& nodes = quadNodesAtTetrahedra[ iN[0] ];
+          nodes.insert( nodes.end(), & iN[2], & iN[7+1] );
+          nodes.resize( iN[1] );
+        }
+      }
+    }
+    // create tetrahedra
     GmfGotoKwd(meshID, GmfTetrahedra);
     for ( int i = 1; i <= nbTet; ++i )
     {
       GmfGetLin(meshID, GmfTetrahedra, &iN[0], &iN[1], &iN[2], &iN[3], &ref);
-      if ( readQuadNodes )
+      std::vector<int>& midN = quadNodesAtTetrahedra[ i ];  
+      if ( midN.size() >= 10-4 ) // TETRA10
       {
-        const std::vector<int>& midN = quadNodesAtTetrahedra[ i-1 ];  
         if ( !myMesh->AddVolumeWithID( iN[0], iN[2], iN[1], iN[3], 
-                                       midN[2], midN[1], midN[0], midN[3], midN[5], midN[4], tetIDShift + i ))
-          status = storeBadNodeIds( "GmfTetrahedra + GmfExtraVerticesAtTetrahedra",i, 10, iN[0], iN[2], iN[1], iN[3], 
-                                                                midN[2], midN[1], midN[0], midN[3], midN[5], midN[4] );
+                                       midN[2], midN[1], midN[0], midN[3], midN[5], midN[4],
+                                       tetIDShift + i ))
+          status = storeBadNodeIds( "GmfTetrahedra + GmfExtraVerticesAtTetrahedra",i, 10,
+                                    iN[0], iN[2], iN[1], iN[3], 
+                                    midN[2], midN[1], midN[0], midN[3], midN[5], midN[4] );
       }
-      else
+      else // TETRA4
       {
-        if ( !myMesh->AddVolumeWithID( iN[0], iN[2], iN[1], iN[3], tetIDShift + i ) )
+        if ( !myMesh->AddVolumeWithID( iN[0], iN[2], iN[1], iN[3], tetIDShift + i ))
           status = storeBadNodeIds( "GmfTetrahedra" ,i, 4, iN[0], iN[2], iN[1], iN[3] );
       }
+      if ( !midN.empty() ) SMESHUtils::FreeVector( midN );
     }
   }
-  // the vector of extra vertices at tetrahedra won't be used anymore so it is cleared
-  quadNodesAtTetrahedra.clear();
 
   /* Read pyramids */
   const int pyrIDShift = myMesh->GetMeshInfo().NbElements();
@@ -328,92 +304,58 @@ Driver_Mesh::Status DriverGMF_Read::Perform()
     }
   }
 
-  /* Read extra vertices for quadratic hexahedra */
-  std::vector< std::vector<int> > quadNodesAtHexahedra;
-  int nbQuadHexa = 0;
-  if ( (nbQuadHexa = GmfStatKwd(meshID, GmfExtraVerticesAtHexahedra)) )
-  {
-    GmfGotoKwd(meshID, GmfExtraVerticesAtHexahedra);
-    quadNodesAtHexahedra.reserve( nbQuadHexa );
-    std::vector<int> nodes( 19 );
-    for ( int i = 1; i <= nbQuadHexa; ++i )
-    {
-      GmfGetLin(meshID, GmfExtraVerticesAtHexahedra, &iN[0], &iN[1],    // Hexa Id, Nb of extra vertices
-                                                     &iN[2], &iN[3], &iN[4], &iN[5],
-                                                     &iN[6], &iN[7], &iN[8], &iN[9],
-                                                     &iN[10], &iN[11], &iN[12], &iN[13], // HEXA20
-                                                     &iN[14], 
-                                                     &iN[15], &iN[16], &iN[17], &iN[18], 
-                                                     &iN[19],
-                                                     &iN[20]);                          // HEXA27
-      nodes.clear();
-      nodes.push_back(iN[2]);
-      nodes.push_back(iN[3]);
-      nodes.push_back(iN[4]);
-      nodes.push_back(iN[5]);
-      nodes.push_back(iN[6]);
-      nodes.push_back(iN[7]);
-      nodes.push_back(iN[8]);
-      nodes.push_back(iN[9]);
-      nodes.push_back(iN[10]);
-      nodes.push_back(iN[11]);
-      nodes.push_back(iN[12]);
-      nodes.push_back(iN[13]);     
-      nodes.push_back(iN[14]);
-      nodes.push_back(iN[15]);
-      nodes.push_back(iN[16]);
-      nodes.push_back(iN[17]);
-      nodes.push_back(iN[18]);
-      nodes.push_back(iN[19]);
-      nodes.push_back(iN[20]);
-      nodes.resize( iN[1] );
-
-      quadNodesAtHexahedra.push_back(nodes);
-    }
-  }
-  
   /* Read hexahedra */
   const int hexIDShift = myMesh->GetMeshInfo().NbElements();
   if ( int nbHex = GmfStatKwd(meshID, GmfHexahedra))
   {
-    const bool readQuadNodes = (nbQuadHexa == nbHex);
+    // read extra vertices for quadratic hexahedra
+    std::vector< std::vector<int> > quadNodesAtHexahedra( nbHex + 1 );
+    if ( int nbQuadHexa = GmfStatKwd( meshID, GmfExtraVerticesAtHexahedra ))
+    {
+      GmfGotoKwd(meshID, GmfExtraVerticesAtHexahedra);
+      for ( int i = 1; i <= nbQuadHexa; ++i )
+      {
+        GmfGetLin(meshID, GmfExtraVerticesAtHexahedra, &iN[0], &iN[1], // Hexa Id, Nb extra vertices
+                  &iN[2], &iN[3], &iN[4], &iN[5],
+                  &iN[6], &iN[7], &iN[8], &iN[9],
+                  &iN[10], &iN[11], &iN[12], &iN[13], // HEXA20
+                  &iN[14],
+                  &iN[15], &iN[16], &iN[17], &iN[18], 
+                  &iN[19],
+                  &iN[20]);                          // HEXA27
+        if ( iN[0] <= nbHex )
+        {
+          std::vector<int>& nodes = quadNodesAtHexahedra[ iN[0] ];
+          nodes.insert( nodes.end(), & iN[2], & iN[20+1] );
+          nodes.resize( iN[1] );
+        }
+      }
+    }
+    // create hexhedra
     GmfGotoKwd(meshID, GmfHexahedra);
     for ( int i = 1; i <= nbHex; ++i )
     {
       GmfGetLin(meshID, GmfHexahedra, &iN[0], &iN[1], &iN[2], &iN[3],
-                                      &iN[4], &iN[5], &iN[6], &iN[7],&ref);
-      if ( readQuadNodes )
+                &iN[4], &iN[5], &iN[6], &iN[7], &ref);
+      std::vector<int>& midN = quadNodesAtHexahedra[ i ];
+      if ( midN.size() == 20-8 ) // HEXA20
       {
-        const std::vector<int>& midN = quadNodesAtHexahedra[ i-1 ];  
-        if ( midN.size() == 12 )  // HEXA20
-        {
-          if ( !myMesh->AddVolumeWithID( iN[0], iN[3], iN[2], iN[1],
-                                         iN[4], iN[7], iN[6], iN[5],
-                                         midN[3], midN[2], midN[1], midN[0],
-                                         midN[7], midN[6], midN[5], midN[4],
-                                         midN[8], midN[11], midN[10], midN[9],
-                                         tetIDShift + i ))
-            status = storeBadNodeIds( "GmfHexahedra + GmfExtraVerticesAtHexahedra",i, 20, 
-                                       iN[0], iN[3], iN[2], iN[1],
+        if ( !myMesh->AddVolumeWithID( iN[0], iN[3], iN[2], iN[1],
                                        iN[4], iN[7], iN[6], iN[5],
                                        midN[3], midN[2], midN[1], midN[0],
                                        midN[7], midN[6], midN[5], midN[4],
-                                       midN[8], midN[11], midN[10], midN[9]);
-        }
-        else                      // HEXA27
-        {
-           if ( !myMesh->AddVolumeWithID( iN[0], iN[3], iN[2], iN[1],
-                                          iN[4], iN[7], iN[6], iN[5],
-                                          midN[3], midN[2], midN[1], midN[0],
-                                          midN[7], midN[6], midN[5], midN[4],
-                                          midN[8], midN[11], midN[10], midN[9],
-                                          midN[12],
-                                          midN[16], midN[15], midN[14], midN[13],
-                                          midN[17],
-                                          midN[18],                                                        
-                                          tetIDShift + i ))
-            status = storeBadNodeIds( "GmfHexahedra + GmfExtraVerticesAtHexahedra",i, 27, 
-                                       iN[0], iN[3], iN[2], iN[1],
+                                       midN[8], midN[11], midN[10], midN[9],
+                                       hexIDShift + i ))
+          status = storeBadNodeIds( "GmfHexahedra + GmfExtraVerticesAtHexahedra",i, 20, 
+                                    iN[0], iN[3], iN[2], iN[1],
+                                    iN[4], iN[7], iN[6], iN[5],
+                                    midN[3], midN[2], midN[1], midN[0],
+                                    midN[7], midN[6], midN[5], midN[4],
+                                    midN[8], midN[11], midN[10], midN[9]);
+      }
+      else if ( midN.size() >= 27-8 ) // HEXA27
+      {
+        if ( !myMesh->AddVolumeWithID( iN[0], iN[3], iN[2], iN[1],
                                        iN[4], iN[7], iN[6], iN[5],
                                        midN[3], midN[2], midN[1], midN[0],
                                        midN[7], midN[6], midN[5], midN[4],
@@ -421,20 +363,29 @@ Driver_Mesh::Status DriverGMF_Read::Perform()
                                        midN[12],
                                        midN[16], midN[15], midN[14], midN[13],
                                        midN[17],
-                                       midN[18]);
-        }
+                                       midN[18],
+                                       hexIDShift + i ))
+          status = storeBadNodeIds( "GmfHexahedra + GmfExtraVerticesAtHexahedra",i, 27, 
+                                    iN[0], iN[3], iN[2], iN[1],
+                                    iN[4], iN[7], iN[6], iN[5],
+                                    midN[3], midN[2], midN[1], midN[0],
+                                    midN[7], midN[6], midN[5], midN[4],
+                                    midN[8], midN[11], midN[10], midN[9],
+                                    midN[12],
+                                    midN[16], midN[15], midN[14], midN[13],
+                                    midN[17],
+                                    midN[18]);
       }
-      else
+      else // HEXA8
       {
         if ( !myMesh->AddVolumeWithID( iN[0], iN[3], iN[2], iN[1],
                                        iN[4], iN[7], iN[6], iN[5], hexIDShift + i ) )
           status = storeBadNodeIds( "GmfHexahedra" ,i, 8, iN[0], iN[3], iN[2], iN[1],
-                                                          iN[4], iN[7], iN[6], iN[5] );
+                                    iN[4], iN[7], iN[6], iN[5] );
       }
+      if ( !midN.empty() ) SMESHUtils::FreeVector( midN );
     }
   }
-  // the vector of extra vertices at tetrahedra won't be used anymore so it is cleared
-  quadNodesAtHexahedra.clear();
 
   /* Read prism */
   const int prismIDShift = myMesh->GetMeshInfo().NbElements();
@@ -443,8 +394,7 @@ Driver_Mesh::Status DriverGMF_Read::Perform()
     GmfGotoKwd(meshID, GmfPrisms);
     for ( int i = 1; i <= nbPrism; ++i )
     {
-      GmfGetLin(meshID, GmfPrisms,
-                &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &ref);
+      GmfGetLin(meshID, GmfPrisms, &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &ref);
       if ( !myMesh->AddVolumeWithID( iN[0], iN[2], iN[1], iN[3], iN[5], iN[4], prismIDShift + i))
         status = storeBadNodeIds( "GmfPrisms",i,
                                   6, iN[0], iN[1],iN[2], iN[3], iN[4], iN[5] );
index 432551e..0a3c5ca 100644 (file)
@@ -40,37 +40,42 @@ extern "C"
 #include <vector>
 
 #define BEGIN_ELEM_WRITE( SMDSEntity, GmfKwd, elem )                    \
-  elemIt = myMesh->elementEntityIterator( SMDSEntity );                 \
+  elemIt = elementIterator( SMDSEntity );                               \
   if ( elemIt->more() )                                                 \
   {                                                                     \
-  GmfSetKwd(meshID, GmfKwd, myMesh->GetMeshInfo().NbEntities( SMDSEntity )); \
+  GmfSetKwd(meshID, GmfKwd, myMesh->GetMeshInfo().NbElements( SMDSEntity )); \
   for ( int gmfID = 1; elemIt->more(); ++gmfID )                        \
   {                                                                     \
   const SMDS_MeshElement* elem = elemIt->next();                        \
   GmfSetLin(meshID, GmfKwd,
 
-#define BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity, GmfKwd, elem, nbVertices ) \
-  elemIt = myMesh->elementEntityIterator( SMDSEntity );                 \
+#define BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom, LinType, GmfKwd, elem )   \
+  elemIt = elementIterator( SMDSGeom );                                 \
   if ( elemIt->more() )                                                 \
   {                                                                     \
-  GmfSetKwd(meshID, GmfKwd, myMesh->GetMeshInfo().NbEntities( SMDSEntity )); \
+  int totalNbElems  = myMesh->GetMeshInfo().NbElements( SMDSGeom );     \
+  int nbLinearElems = myMesh->GetMeshInfo().NbElements( LinType );      \
+  if ( totalNbElems - nbLinearElems > 0 )                               \
+  {                                                                     \
+  GmfSetKwd(meshID, GmfKwd, totalNbElems - nbLinearElems);              \
   for ( int gmfID = 1; elemIt->more(); ++gmfID )                        \
   {                                                                     \
   const SMDS_MeshElement* elem = elemIt->next();                        \
-  GmfSetLin(meshID, GmfKwd, gmfID, nbVertices,
+  if ( elem->IsQuadratic() ) {                                          \
+  GmfSetLin(meshID, GmfKwd, gmfID, elem->NbNodes() - elem->NbCornerNodes(),
 
 #define END_ELEM_WRITE( elem )                  \
   elem->getshapeId() );                         \
-  }}                                            \
+  }}
 
 #define END_ELEM_WRITE_ADD_TO_MAP( elem, e2id )         \
   elem->getshapeId() );                                 \
   e2id.insert( e2id.end(), make_pair( elem, gmfID ));   \
-  }}                                                    \
+  }}
 
 #define END_EXTRA_VERTICES_WRITE()           \
   );                                         \
-  }}                                         \
+  }}}}
 
 
 DriverGMF_Write::DriverGMF_Write():
@@ -126,107 +131,73 @@ Driver_Mesh::Status DriverGMF_Write::Perform()
 
   // edges
   TElem2IDMap edge2IDMap;
-  BEGIN_ELEM_WRITE( SMDSEntity_Edge, GmfEdges, edge )
+  BEGIN_ELEM_WRITE( SMDSGeom_EDGE, GmfEdges, edge )
     node2IdMap[ edge->GetNode( 0 )],
     node2IdMap[ edge->GetNode( 1 )],
     END_ELEM_WRITE_ADD_TO_MAP( edge, edge2IDMap );
 
-  // quadratic edges
-  BEGIN_ELEM_WRITE( SMDSEntity_Quad_Edge, GmfEdges, edge )
-    node2IdMap[ edge->GetNode( 0 )],
-    node2IdMap[ edge->GetNode( 1 )],
-    END_ELEM_WRITE( edge );
-
-  BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity_Quad_Edge, GmfExtraVerticesAtEdges, edge, 1 )
+  // nodes of quadratic edges
+  BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_EDGE, SMDSEntity_Edge,
+                              GmfExtraVerticesAtEdges, edge )
     node2IdMap[ edge->GetNode( 2 )]
     END_EXTRA_VERTICES_WRITE();
 
   // triangles
   TElem2IDMap tria2IDMap;
-  BEGIN_ELEM_WRITE( SMDSEntity_Triangle, GmfTriangles, tria )
+  BEGIN_ELEM_WRITE( SMDSGeom_TRIANGLE, GmfTriangles, tria )
     node2IdMap[ tria->GetNode( 0 )],
     node2IdMap[ tria->GetNode( 1 )],
     node2IdMap[ tria->GetNode( 2 )],
     END_ELEM_WRITE_ADD_TO_MAP( tria, tria2IDMap );
 
-  // quadratic triangles
-  BEGIN_ELEM_WRITE( SMDSEntity_Quad_Triangle, GmfTriangles, tria )
-    node2IdMap[ tria->GetNode( 0 )],
-    node2IdMap[ tria->GetNode( 1 )],
-    node2IdMap[ tria->GetNode( 2 )],
-    END_ELEM_WRITE( tria );
-
-  BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity_Quad_Triangle, GmfExtraVerticesAtTriangles, tria, 3 )
+  // nodes of quadratic triangles
+  BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_TRIANGLE, SMDSEntity_Triangle,
+                              GmfExtraVerticesAtTriangles, tria )
     node2IdMap[ tria->GetNode( 3 )],
     node2IdMap[ tria->GetNode( 4 )],
     node2IdMap[ tria->GetNode( 5 )]
+    //node2IdMap[ tria->GetNodeWrap( 6 )] // for TRIA7
     END_EXTRA_VERTICES_WRITE();
 
   // quadrangles
   TElem2IDMap quad2IDMap;
-  BEGIN_ELEM_WRITE( SMDSEntity_Quadrangle, GmfQuadrilaterals, quad )
+  BEGIN_ELEM_WRITE( SMDSGeom_QUADRANGLE, GmfQuadrilaterals, quad )
     node2IdMap[ quad->GetNode( 0 )],
     node2IdMap[ quad->GetNode( 1 )],
     node2IdMap[ quad->GetNode( 2 )],
     node2IdMap[ quad->GetNode( 3 )],
     END_ELEM_WRITE_ADD_TO_MAP( quad, quad2IDMap );
 
-  // quadratic quadrangles
-  BEGIN_ELEM_WRITE( SMDSEntity_Quad_Quadrangle, GmfQuadrilaterals, quad )
-    node2IdMap[ quad->GetNode( 0 )],
-    node2IdMap[ quad->GetNode( 1 )],
-    node2IdMap[ quad->GetNode( 2 )],
-    node2IdMap[ quad->GetNode( 3 )],
-    END_ELEM_WRITE( quad );
-
-  BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity_Quad_Quadrangle, GmfExtraVerticesAtQuadrilaterals, quad, 4 )
-    node2IdMap[ quad->GetNode( 4 )],
-    node2IdMap[ quad->GetNode( 5 )],
-    node2IdMap[ quad->GetNode( 6 )],
-    node2IdMap[ quad->GetNode( 7 )]
-    END_EXTRA_VERTICES_WRITE();
-
-  // bi-quadratic quadrangles
-  BEGIN_ELEM_WRITE( SMDSEntity_BiQuad_Quadrangle, GmfQuadrilaterals, quad )
-    node2IdMap[ quad->GetNode( 0 )],
-    node2IdMap[ quad->GetNode( 1 )],
-    node2IdMap[ quad->GetNode( 2 )],
-    node2IdMap[ quad->GetNode( 3 )],
-    END_ELEM_WRITE( quad );
-
-  BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity_BiQuad_Quadrangle, GmfExtraVerticesAtQuadrilaterals, quad, 5 )
+  // nodes of quadratic quadrangles
+  BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_QUADRANGLE, SMDSEntity_Quadrangle,
+                              GmfExtraVerticesAtQuadrilaterals, quad )
     node2IdMap[ quad->GetNode( 4 )],
     node2IdMap[ quad->GetNode( 5 )],
     node2IdMap[ quad->GetNode( 6 )],
     node2IdMap[ quad->GetNode( 7 )],
-    node2IdMap[ quad->GetNode( 8 )]
+    node2IdMap[ quad->GetNodeWrap( 8 )] // for QUAD9
     END_EXTRA_VERTICES_WRITE();
 
   // terahedra
-  BEGIN_ELEM_WRITE( SMDSEntity_Tetra, GmfTetrahedra, tetra )
+  BEGIN_ELEM_WRITE( SMDSGeom_TETRA, GmfTetrahedra, tetra )
     node2IdMap[ tetra->GetNode( 0 )],
     node2IdMap[ tetra->GetNode( 2 )],
     node2IdMap[ tetra->GetNode( 1 )],
     node2IdMap[ tetra->GetNode( 3 )],
     END_ELEM_WRITE( tetra );
 
-  // quadratic terahedra
-  BEGIN_ELEM_WRITE( SMDSEntity_Quad_Tetra, GmfTetrahedra, tetra )
-    node2IdMap[ tetra->GetNode( 0 )],
-    node2IdMap[ tetra->GetNode( 2 )],
-    node2IdMap[ tetra->GetNode( 1 )],
-    node2IdMap[ tetra->GetNode( 3 )],
-    END_ELEM_WRITE( tetra );
-    
-  BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity_Quad_Tetra, GmfExtraVerticesAtTetrahedra, tetra, 6 )
+  // nodes of quadratic terahedra
+  BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_TETRA, SMDSEntity_Tetra,
+                              GmfExtraVerticesAtTetrahedra, tetra )
     node2IdMap[ tetra->GetNode( 6 )],
     node2IdMap[ tetra->GetNode( 5 )],
     node2IdMap[ tetra->GetNode( 4 )],
     node2IdMap[ tetra->GetNode( 7 )],
     node2IdMap[ tetra->GetNode( 9 )],
     node2IdMap[ tetra->GetNode( 8 )]
+    //node2IdMap[ tetra->GetNodeWrap( 10 )], // for TETRA11
     END_EXTRA_VERTICES_WRITE();
-    
+
   // pyramids
   BEGIN_ELEM_WRITE( SMDSEntity_Pyramid, GmfPyramids, pyra )
     node2IdMap[ pyra->GetNode( 0 )],
@@ -237,7 +208,7 @@ Driver_Mesh::Status DriverGMF_Write::Perform()
     END_ELEM_WRITE( pyra );
 
   // hexahedra
-  BEGIN_ELEM_WRITE( SMDSEntity_Hexa, GmfHexahedra, hexa )
+  BEGIN_ELEM_WRITE( SMDSGeom_HEXA, GmfHexahedra, hexa )
     node2IdMap[ hexa->GetNode( 0 )],
     node2IdMap[ hexa->GetNode( 3 )],
     node2IdMap[ hexa->GetNode( 2 )],
@@ -248,65 +219,28 @@ Driver_Mesh::Status DriverGMF_Write::Perform()
     node2IdMap[ hexa->GetNode( 5 )],
     END_ELEM_WRITE( hexa );
 
-  // quadratic hexahedra
-  BEGIN_ELEM_WRITE( SMDSEntity_Quad_Hexa, GmfHexahedra, hexa )
-    node2IdMap[ hexa->GetNode( 0 )],
-    node2IdMap[ hexa->GetNode( 3 )],
-    node2IdMap[ hexa->GetNode( 2 )],
-    node2IdMap[ hexa->GetNode( 1 )],
-    node2IdMap[ hexa->GetNode( 4 )],
-    node2IdMap[ hexa->GetNode( 7 )],
-    node2IdMap[ hexa->GetNode( 6 )],
-    node2IdMap[ hexa->GetNode( 5 )],
-    END_ELEM_WRITE( hexa );
-    
-  BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity_Quad_Hexa, GmfExtraVerticesAtHexahedra, hexa, 12 )
-    node2IdMap[ hexa->GetNode( 11 )],
+  // nodes of quadratic hexahedra
+  BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_HEXA, SMDSEntity_Hexa,
+                              GmfExtraVerticesAtHexahedra, hexa )
+    node2IdMap[ hexa->GetNode( 11 )], // HEXA20
     node2IdMap[ hexa->GetNode( 10 )],
-    node2IdMap[ hexa->GetNode( 9 )],
-    node2IdMap[ hexa->GetNode( 8 )],
+    node2IdMap[ hexa->GetNode(  9 )],
+    node2IdMap[ hexa->GetNode(  8 )],
     node2IdMap[ hexa->GetNode( 15 )],
     node2IdMap[ hexa->GetNode( 14 )],
     node2IdMap[ hexa->GetNode( 13 )],
     node2IdMap[ hexa->GetNode( 12 )],
     node2IdMap[ hexa->GetNode( 16 )],
     node2IdMap[ hexa->GetNode( 19 )],
-    node2IdMap[ hexa->GetNode( 18 )],
-    node2IdMap[ hexa->GetNode( 17 )]
-    END_EXTRA_VERTICES_WRITE();
-    
-  // tri-quadratic hexahedra
-  BEGIN_ELEM_WRITE( SMDSEntity_TriQuad_Hexa, GmfHexahedra, hexa )
-    node2IdMap[ hexa->GetNode( 0 )],
-    node2IdMap[ hexa->GetNode( 3 )],
-    node2IdMap[ hexa->GetNode( 2 )],
-    node2IdMap[ hexa->GetNode( 1 )],
-    node2IdMap[ hexa->GetNode( 4 )],
-    node2IdMap[ hexa->GetNode( 7 )],
-    node2IdMap[ hexa->GetNode( 6 )],
-    node2IdMap[ hexa->GetNode( 5 )],
-    END_ELEM_WRITE( hexa );
-    
-  BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity_TriQuad_Hexa, GmfExtraVerticesAtHexahedra, hexa, 19 )
-    node2IdMap[ hexa->GetNode( 11 )],
-    node2IdMap[ hexa->GetNode( 10 )],
-    node2IdMap[ hexa->GetNode( 9 )],
-    node2IdMap[ hexa->GetNode( 8 )],
-    node2IdMap[ hexa->GetNode( 15 )],
-    node2IdMap[ hexa->GetNode( 14 )],
-    node2IdMap[ hexa->GetNode( 13 )],
-    node2IdMap[ hexa->GetNode( 12 )],
-    node2IdMap[ hexa->GetNode( 16 )],
-    node2IdMap[ hexa->GetNode( 19 )],
-    node2IdMap[ hexa->GetNode( 18 )],
-    node2IdMap[ hexa->GetNode( 17 )],
-    node2IdMap[ hexa->GetNode( 20 )],
-    node2IdMap[ hexa->GetNode( 24 )],
-    node2IdMap[ hexa->GetNode( 23 )],
-    node2IdMap[ hexa->GetNode( 22 )],
-    node2IdMap[ hexa->GetNode( 21 )],
-    node2IdMap[ hexa->GetNode( 25 )],
-    node2IdMap[ hexa->GetNode( 26 )]
+    node2IdMap[ hexa->GetNodeWrap( 18 )], // + HEXA27
+    node2IdMap[ hexa->GetNodeWrap( 17 )],
+    node2IdMap[ hexa->GetNodeWrap( 20 )],
+    node2IdMap[ hexa->GetNodeWrap( 24 )],
+    node2IdMap[ hexa->GetNodeWrap( 23 )],
+    node2IdMap[ hexa->GetNodeWrap( 22 )],
+    node2IdMap[ hexa->GetNodeWrap( 21 )],
+    node2IdMap[ hexa->GetNodeWrap( 25 )],
+    node2IdMap[ hexa->GetNodeWrap( 26 )]
     END_EXTRA_VERTICES_WRITE();
 
   // prism
@@ -405,3 +339,22 @@ Driver_Mesh::Status DriverGMF_Write::Perform()
 
   return DRS_OK;
 }
+
+//================================================================================
+/*!
+ * \brief Returns an iterator on elements of a certain type
+ */
+//================================================================================
+
+SMDS_ElemIteratorPtr DriverGMF_Write::elementIterator(SMDSAbs_ElementType type)
+{
+  return myMesh->elementsIterator(type);
+}
+SMDS_ElemIteratorPtr DriverGMF_Write::elementIterator(SMDSAbs_EntityType type) 
+{
+  return myMesh->elementEntityIterator(type);
+}
+SMDS_ElemIteratorPtr DriverGMF_Write::elementIterator(SMDSAbs_GeometryType type)
+{
+  return myMesh->elementGeomIterator(type);
+}
index 0e8ee4f..b66b3d9 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "Driver_SMESHDS_Mesh.h"
 #include "SMDSAbs_ElementType.hxx"
+#include "SMDS_ElemIterator.hxx"
 
 /*!
  * \brief Driver Writing a mesh into a GMF file.
@@ -51,6 +52,10 @@ public:
 
  private:
 
+  SMDS_ElemIteratorPtr elementIterator(SMDSAbs_ElementType  type); 
+  SMDS_ElemIteratorPtr elementIterator(SMDSAbs_EntityType   type);  
+  SMDS_ElemIteratorPtr elementIterator(SMDSAbs_GeometryType type);
+
   bool _exportRequiredGroups;
 };
 
index db0fa90..2e858e4 100644 (file)
@@ -21,7 +21,7 @@
 #  Author : Marc Tajchman (CEA)
 #  Modified by : Alexander BORODIN (OCN) - autotools usage
 #  Module : SMESH
-
+#
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 # header files 
index 026590a..07c7dc9 100644 (file)
@@ -39,8 +39,12 @@ public:
   inline SMDS_MeshInfo& operator=(const SMDS_MeshInfo& other);
   inline void Clear();
 
-  inline int NbElements(SMDSAbs_ElementType type=SMDSAbs_All) const;
+  inline int NbElements(SMDSAbs_ElementType  type=SMDSAbs_All) const;
+  inline int NbElements(SMDSAbs_EntityType   type) const { return NbEntities(type); }
+  inline int NbElements(SMDSAbs_GeometryType type) const { return NbElementsOfGeom(type); }
+
   inline int NbEntities(SMDSAbs_EntityType  type) const;
+  inline int NbElementsOfGeom(SMDSAbs_GeometryType geom) const;
 
   int NbNodes()      const { return myNbNodes; }
   int Nb0DElements() const { return myNb0DElements; }
@@ -230,47 +234,47 @@ inline void // RemoveVolume
 SMDS_MeshInfo::RemoveVolume(const SMDS_MeshElement* el)
 { if ( el->IsPoly() ) --myNbPolyhedrons; else remove( el ); }
 
-inline int // NbEdges
+inline int  // NbEdges
 SMDS_MeshInfo::NbEdges      (SMDSAbs_ElementOrder order) const
 { return order == ORDER_ANY ? myNbEdges+myNbQuadEdges : order == ORDER_LINEAR ? myNbEdges : myNbQuadEdges; }
 
-inline int // NbFaces
+inline int  // NbFaces
 SMDS_MeshInfo::NbFaces      (SMDSAbs_ElementOrder order) const
 { return NbTriangles(order)+NbQuadrangles(order)+(order == ORDER_QUADRATIC ? 0 : myNbPolygons); }
 
-inline int // NbTriangles
+inline int  // NbTriangles
 SMDS_MeshInfo::NbTriangles  (SMDSAbs_ElementOrder order) const
 { return order == ORDER_ANY ? myNbTriangles+myNbQuadTriangles : order == ORDER_LINEAR ? myNbTriangles : myNbQuadTriangles; }
 
-inline int // NbQuadrangles
+inline int  // NbQuadrangles
 SMDS_MeshInfo::NbQuadrangles(SMDSAbs_ElementOrder order) const
 { return order == ORDER_ANY ? myNbQuadrangles+myNbQuadQuadrangles+myNbBiQuadQuadrangles : order == ORDER_LINEAR ? myNbQuadrangles : myNbQuadQuadrangles+myNbBiQuadQuadrangles; }
 
-inline int // NbVolumes
+inline int  // NbVolumes
 SMDS_MeshInfo::NbVolumes (SMDSAbs_ElementOrder order) const
 { return NbTetras(order) + NbHexas(order) + NbPyramids(order) + NbPrisms(order) + NbHexPrisms(order) + (order == ORDER_QUADRATIC ? 0 : myNbPolyhedrons); }
 
-inline int // NbTetras
+inline int  // NbTetras
 SMDS_MeshInfo::NbTetras  (SMDSAbs_ElementOrder order) const
 { return order == ORDER_ANY ? myNbTetras+myNbQuadTetras : order == ORDER_LINEAR ? myNbTetras : myNbQuadTetras; }
 
-inline int // NbHexas
+inline int  // NbHexas
 SMDS_MeshInfo::NbHexas   (SMDSAbs_ElementOrder order) const
 { return order == ORDER_ANY ? myNbHexas+myNbQuadHexas+myNbTriQuadHexas : order == ORDER_LINEAR ? myNbHexas : myNbQuadHexas+myNbTriQuadHexas; }
 
-inline int // NbPyramids
+inline int  // NbPyramids
 SMDS_MeshInfo::NbPyramids(SMDSAbs_ElementOrder order) const
 { return order == ORDER_ANY ? myNbPyramids+myNbQuadPyramids : order == ORDER_LINEAR ? myNbPyramids : myNbQuadPyramids; }
 
-inline int // NbPrisms
+inline int  // NbPrisms
 SMDS_MeshInfo::NbPrisms  (SMDSAbs_ElementOrder order) const
 { return order == ORDER_ANY ? myNbPrisms+myNbQuadPrisms : order == ORDER_LINEAR ? myNbPrisms : myNbQuadPrisms; }
 
-inline int // NbHexPrisms
+inline int  // NbHexPrisms
 SMDS_MeshInfo::NbHexPrisms  (SMDSAbs_ElementOrder order) const
 { return order == ORDER_ANY ? myNbHexPrism : order == ORDER_LINEAR ? myNbHexPrism : 0; }
 
-inline int // NbElements
+inline int  // NbElements
 SMDS_MeshInfo::NbElements(SMDSAbs_ElementType type) const
 { 
   int nb = 0;
@@ -305,7 +309,7 @@ SMDS_MeshInfo::NbElements(SMDSAbs_ElementType type) const
   return nb;
 }
 
-int // NbEntities
+inline int  // NbEntities
 SMDS_MeshInfo::NbEntities(SMDSAbs_EntityType type) const
 {
   switch (type) {
@@ -338,7 +342,44 @@ SMDS_MeshInfo::NbEntities(SMDSAbs_EntityType type) const
   return 0;
 }
 
-void // set
+inline int  // NbElementsOfGeom
+SMDS_MeshInfo::NbElementsOfGeom(SMDSAbs_GeometryType geom) const
+{
+  switch ( geom ) {
+    // 0D:
+  case SMDSGeom_POINT:           return myNb0DElements;
+    // 1D:
+  case SMDSGeom_EDGE:            return (myNbEdges +
+                                         myNbQuadEdges);
+    // 2D:
+  case SMDSGeom_TRIANGLE:        return (myNbTriangles +
+                                         myNbQuadTriangles);
+  case SMDSGeom_QUADRANGLE:      return (myNbQuadrangles +
+                                         myNbQuadQuadrangles +
+                                         myNbBiQuadQuadrangles );
+  case SMDSGeom_POLYGON:         return myNbPolygons;
+    // 3D:
+  case SMDSGeom_TETRA:           return (myNbTetras +
+                                         myNbQuadTetras);
+  case SMDSGeom_PYRAMID:         return (myNbPyramids +
+                                         myNbQuadPyramids);
+  case SMDSGeom_HEXA:            return (myNbHexas +
+                                         myNbQuadHexas +
+                                         myNbTriQuadHexas);
+  case SMDSGeom_PENTA:           return (myNbPrisms +
+                                         myNbQuadPrisms);
+  case SMDSGeom_HEXAGONAL_PRISM: return myNbHexPrism;
+  case SMDSGeom_POLYHEDRA:       return myNbPolyhedrons;
+    // Discrete:
+  case SMDSGeom_BALL:            return myNbBalls;
+    //
+  case SMDSGeom_NONE:
+  default:;
+  }
+  return 0;
+}
+
+inline void // setNb
 SMDS_MeshInfo::setNb(const SMDSAbs_EntityType geomType, const int nb)
 {
   switch (geomType) {
index 2c7c401..a2a8d2b 100644 (file)
@@ -292,27 +292,27 @@ static int QuadPenta_RE [5][9] = { // REVERSED -> EXTERNAL
 static int QuadPenta_nbN [] = { 6, 6, 8, 8, 8 };
 
 /*
-//                 13
-//         N5+-----+-----+N6
-//          /|          /|
-//       12+ |       14+ |
-//        /  |        /  |
-//     N4+-----+-----+N7 |           QUADRATIC
-//       |   | 15    |   |           HEXAHEDRON
-//       |   |       |   |
-//       | 17+       |   +18
-//       |   |       |   |
-//       |   |       |   |
-//       |   |       |   |
-//     16+   |       +19 |
-//       |   |       |   |
-//       |   |     9 |   |
-//       | N1+-----+-|---+N2
-//       |  /        |  /
-//       | +8        | +10
-//       |/          |/
-//     N0+-----+-----+N3
-//             11
+//                 13                                                         
+//         N5+-----+-----+N6                          +-----+-----+
+//          /|          /|                           /|          /| 
+//       12+ |       14+ |                          + |   +25   + |    
+//        /  |        /  |                         /  |        /  |    
+//     N4+-----+-----+N7 |       QUADRATIC        +-----+-----+   |  Central nodes
+//       |   | 15    |   |       HEXAHEDRON       |   |       |   |  of tri-quadratic
+//       |   |       |   |                        |   |       |   |  HEXAHEDRON
+//       | 17+       |   +18                      |   +   22+ |   +  
+//       |   |       |   |                        |21 |       |   | 
+//       |   |       |   |                        | + | 26+   | + |    
+//       |   |       |   |                        |   |       |23 |    
+//     16+   |       +19 |                        +   | +24   +   |    
+//       |   |       |   |                        |   |       |   |    
+//       |   |     9 |   |                        |   |       |   |    
+//       | N1+-----+-|---+N2                      |   +-----+-|---+    
+//       |  /        |  /                         |  /        |  /  
+//       | +8        | +10                        | +   20+   | +      
+//       |/          |/                           |/          |/       
+//     N0+-----+-----+N3                          +-----+-----+    
+//             11                              
 */
 static int QuadHexa_F [6][9] = {  // FORWARD
   { 0, 8, 1, 9, 2, 10,3, 11,0 },   // all face normals are external,
index e875610..a6a4d9b 100644 (file)
@@ -9587,14 +9587,26 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh *   theSm,
   {
     nbElem++;
     const SMDS_MeshElement* elem = ElemItr->next();
-    if( !elem || elem->IsQuadratic() ) continue;
+    if( !elem ) continue;
 
+    const SMDSAbs_EntityType aGeomType = elem->GetEntityType();
+    if ( elem->IsQuadratic() )
+    {
+      bool alreadyOK;
+      switch ( aGeomType ) {
+      case SMDSEntity_Quad_Quadrangle:
+      case SMDSEntity_Quad_Hexa:         alreadyOK = !theHelper.GetIsBiQuadratic(); break;
+      case SMDSEntity_BiQuad_Quadrangle:
+      case SMDSEntity_TriQuad_Hexa:      alreadyOK = theHelper.GetIsBiQuadratic(); break;
+      default:                           alreadyOK = true;
+      }
+      if ( alreadyOK ) continue;
+    }
     // get elem data needed to re-create it
     //
-    const int id                        = elem->GetID();
-    const int nbNodes                   = elem->NbNodes();
-    const SMDSAbs_ElementType aType     = elem->GetType();
-    const SMDSAbs_EntityType  aGeomType = elem->GetEntityType();
+    const int id                     = elem->GetID();
+    const int nbNodes                = elem->NbCornerNodes();
+    const SMDSAbs_ElementType aType  = elem->GetType();
     nodes.assign(elem->begin_nodes(), elem->end_nodes());
     if ( aGeomType == SMDSEntity_Polyhedra )
       nbNodeInFaces = static_cast<const SMDS_VtkVolume* >( elem )->GetQuantities();
@@ -9643,6 +9655,8 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh *   theSm,
           NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], id, theForce3d);
           break;
         case SMDSEntity_Hexa:
+        case SMDSEntity_Quad_Hexa:
+        case SMDSEntity_TriQuad_Hexa:
           NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3],
                                         nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d);
           break;
@@ -9661,18 +9675,20 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh *   theSm,
   }
   return nbElem;
 }
-
 //=======================================================================
 //function : ConvertToQuadratic
 //purpose  :
 //=======================================================================
 
-void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
+void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theToBiQuad)
 {
   SMESHDS_Mesh* meshDS = GetMeshDS();
 
   SMESH_MesherHelper aHelper(*myMesh);
+
   aHelper.SetIsQuadratic( true );
+  aHelper.SetIsBiQuadratic( theToBiQuad );
+  aHelper.SetElementsOnShape(true);
 
   int nbCheckedElems = 0;
   if ( myMesh->HasShapeToMesh() )
@@ -9714,10 +9730,14 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
     while(aFaceItr->more())
     {
       const SMDS_MeshFace* face = aFaceItr->next();
-      if(!face || face->IsQuadratic() ) continue;
+      if ( !face ) continue;
+      
+      const SMDSAbs_EntityType type = face->GetEntityType();
+      if (( theToBiQuad  && type == SMDSEntity_BiQuad_Quadrangle ) ||
+          ( !theToBiQuad && type == SMDSEntity_Quad_Quadrangle ))
+        continue;
 
       const int id = face->GetID();
-      const SMDSAbs_EntityType type = face->GetEntityType();
       vector<const SMDS_MeshNode *> nodes ( face->begin_nodes(), face->end_nodes());
 
       meshDS->RemoveFreeElement(face, smDS, /*fromGroups=*/false);
@@ -9743,8 +9763,12 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
       const SMDS_MeshVolume* volume = aVolumeItr->next();
       if(!volume || volume->IsQuadratic() ) continue;
 
-      const int id = volume->GetID();
       const SMDSAbs_EntityType type = volume->GetEntityType();
+      if (( theToBiQuad  && type == SMDSEntity_TriQuad_Hexa ) ||
+          ( !theToBiQuad && type == SMDSEntity_Quad_Hexa ))
+        continue;
+
+      const int id = volume->GetID();
       vector<const SMDS_MeshNode *> nodes (volume->begin_nodes(), volume->end_nodes());
       if ( type == SMDSEntity_Polyhedra )
         nbNodeInFaces = static_cast<const SMDS_VtkVolume* >(volume)->GetQuantities();
@@ -9760,6 +9784,8 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
         NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d );
         break;
       case SMDSEntity_Hexa:
+      case SMDSEntity_Quad_Hexa:
+      case SMDSEntity_TriQuad_Hexa:
         NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3],
                                       nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d);
         break;
@@ -9795,7 +9821,8 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
 //================================================================================
 
 void SMESH_MeshEditor::ConvertToQuadratic(const bool        theForce3d,
-                                          TIDSortedElemSet& theElements)
+                                          TIDSortedElemSet& theElements,
+                                          const bool        theToBiQuad)
 {
   if ( theElements.empty() ) return;
 
@@ -9822,8 +9849,19 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool        theForce3d,
       const SMDS_MeshElement* e = invIt->next();
       if ( e->IsQuadratic() )
       {
-        quadAdjacentElems[ e->GetType() ].insert( e );
-        continue;
+        bool alreadyOK;
+        switch ( e->GetEntityType() ) {
+        case SMDSEntity_Quad_Quadrangle:
+        case SMDSEntity_Quad_Hexa:         alreadyOK = !theToBiQuad; break;
+        case SMDSEntity_BiQuad_Quadrangle:
+        case SMDSEntity_TriQuad_Hexa:      alreadyOK = theToBiQuad; break;
+        default:                           alreadyOK = true;
+        }
+        if ( alreadyOK )
+        {
+          quadAdjacentElems[ e->GetType() ].insert( e );
+          continue;
+        }
       }
       if ( e->GetType() >= elemType )
       {
@@ -9845,6 +9883,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool        theForce3d,
 
   SMESH_MesherHelper helper(*myMesh);
   helper.SetIsQuadratic( true );
+  helper.SetIsBiQuadratic( theToBiQuad );
 
   // add links of quadratic adjacent elements to the helper
 
@@ -9867,18 +9906,32 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool        theForce3d,
       helper.AddTLinks( static_cast< const SMDS_MeshVolume*> (*eIt) );
     }
 
-  // make quadratic elements instead of linear ones
+  // make quadratic (or bi-tri-quadratic) elements instead of linear ones
 
-  SMESHDS_Mesh* meshDS = GetMeshDS();
+  SMESHDS_Mesh*  meshDS = GetMeshDS();
   SMESHDS_SubMesh* smDS = 0;
   for ( eIt = theElements.begin(); eIt != theElements.end(); ++eIt )
   {
     const SMDS_MeshElement* elem = *eIt;
-    if( elem->IsQuadratic() || elem->NbNodes() < 2 || elem->IsPoly() )
+    if( elem->NbNodes() < 2 || elem->IsPoly() )
       continue;
 
-    const int id                   = elem->GetID();
+    if ( elem->IsQuadratic() )
+    {
+      bool alreadyOK;
+      switch ( elem->GetEntityType() ) {
+      case SMDSEntity_Quad_Quadrangle:
+      case SMDSEntity_Quad_Hexa:         alreadyOK = !theToBiQuad; break;
+      case SMDSEntity_BiQuad_Quadrangle:
+      case SMDSEntity_TriQuad_Hexa:      alreadyOK = theToBiQuad; break;
+      default:                           alreadyOK = true;
+      }
+      if ( alreadyOK ) continue;
+    }
+
     const SMDSAbs_ElementType type = elem->GetType();
+    const int                   id = elem->GetID();
+    const int              nbNodes = elem->NbCornerNodes();
     vector<const SMDS_MeshNode *> nodes ( elem->begin_nodes(), elem->end_nodes());
 
     if ( !smDS || !smDS->Contains( elem ))
@@ -9886,7 +9939,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool        theForce3d,
     meshDS->RemoveFreeElement(elem, smDS, /*fromGroups=*/false);
 
     SMDS_MeshElement * newElem = 0;
-    switch( nodes.size() )
+    switch( nbNodes )
     {
     case 4: // cases for most frequently used element types go first (for optimization)
       if ( type == SMDSAbs_Volume )
index ce52a9c..746f50d 100644 (file)
@@ -117,7 +117,6 @@ public:
   const SMESH_SequenceOfElemPtr& GetLastCreatedNodes() const { return myLastCreatedNodes; }
   const SMESH_SequenceOfElemPtr& GetLastCreatedElems() const { return myLastCreatedElems; }
   void                           CrearLastCreated();
-
   SMESH_ComputeErrorPtr &        GetError() { return myError; }
 
   /*!
@@ -492,15 +491,15 @@ public:
   // insert theNodesToInsert into all volumes, containing link
   // theBetweenNode1 - theBetweenNode2, between theBetweenNode1 and theBetweenNode2.
 
-  void ConvertToQuadratic(const bool theForce3d);
-  void ConvertToQuadratic(const bool theForce3d, TIDSortedElemSet& theElements);
-  // Converts all mesh to quadratic one, deletes old elements, replacing 
-  // them with quadratic ones with the same id.
+  void ConvertToQuadratic(const bool theForce3d, const bool theToBiQuad);
+  void ConvertToQuadratic(const bool theForce3d,
+                          TIDSortedElemSet& theElements, const bool theToBiQuad);
+  // Converts all mesh to quadratic or bi-quadratic one, deletes old elements, 
+  // replacing them with quadratic or bi-quadratic ones with the same id.
   // If theForce3d = 1; this results in the medium node lying at the 
-  // middle of the line segments connecting start and end node of a mesh 
-  // element
+  // middle of the line segments connecting start and end node of a mesh element.
   // If theForce3d = 0; this results in the medium node lying at the 
-  // geometrical edge from which the mesh element is built
+  // geometrical edge from which the mesh element is built.
 
   bool ConvertFromQuadratic();
   void ConvertFromQuadratic(TIDSortedElemSet& theElements);
@@ -625,7 +624,6 @@ public:
                        bool                    toAddExistingBondary = false,
                        bool                    aroundElements = false);
 
-
  private:
 
   /*!
index 4f732ef..e1f9709 100644 (file)
@@ -81,7 +81,11 @@ namespace {
 //================================================================================
 
 SMESH_MesherHelper::SMESH_MesherHelper(SMESH_Mesh& theMesh)
-  : myParIndex(0), myMesh(&theMesh), myShapeID(0), myCreateQuadratic(false),
+  : myParIndex(0),
+    myMesh(&theMesh),
+    myShapeID(0),
+    myCreateQuadratic(false),
+    myCreateBiQuadratic(false),
     myFixNodeParameters(false)
 {
   myPar1[0] = myPar2[0] = myPar1[1] = myPar2[1] = 0;
@@ -934,11 +938,18 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
 //function : GetMediumPos
 //purpose  : Return index and type of the shape  (EDGE or FACE only) to
 //          set a medium node on
+//param    : useCurSubShape - if true, returns the shape set via SetSubShape()
+//           if any
 //=======================================================================
 
-std::pair<int, TopAbs_ShapeEnum> SMESH_MesherHelper::GetMediumPos(const SMDS_MeshNode* n1,
-                                                                  const SMDS_MeshNode* n2)
+std::pair<int, TopAbs_ShapeEnum>
+SMESH_MesherHelper::GetMediumPos(const SMDS_MeshNode* n1,
+                                 const SMDS_MeshNode* n2,
+                                 const bool           useCurSubShape)
 {
+  if ( useCurSubShape && !myShape.IsNull() )
+    return std::make_pair( myShapeID, myShape.ShapeType() );
+
   TopAbs_ShapeEnum shapeType = TopAbs_SHAPE;
   int              shapeID = -1;
   TopoDS_Shape     shape;
@@ -1010,8 +1021,156 @@ std::pair<int, TopAbs_ShapeEnum> SMESH_MesherHelper::GetMediumPos(const SMDS_Mes
 }
 
 //=======================================================================
+//function : GetCentralNode
+//purpose  : Return existing or create a new central node for a quardilateral
+//           quadratic face given its 8 nodes.
+//@param   : force3d - true means node creation in between the given nodes,
+//             else node position is found on a geometrical face if any.
+//=======================================================================
+
+const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1,
+                                                        const SMDS_MeshNode* n2,
+                                                        const SMDS_MeshNode* n3,
+                                                        const SMDS_MeshNode* n4,
+                                                        const SMDS_MeshNode* n12,
+                                                        const SMDS_MeshNode* n23,
+                                                        const SMDS_MeshNode* n34,
+                                                        const SMDS_MeshNode* n41,
+                                                        bool                 force3d)
+{
+  SMDS_MeshNode *centralNode = 0; // central node to return
+
+  // Find an existing central node
+
+  TBiQuad keyOfMap(n1,n2,n3,n4);
+  std::map<TBiQuad, SMDS_MeshNode* >::iterator itMapCentralNode;
+  itMapCentralNode = myMapWithCentralNode.find( keyOfMap );
+  if ( itMapCentralNode != myMapWithCentralNode.end() ) 
+  {
+    return (*itMapCentralNode).second;
+  }
+
+  // Get type of shape for the new central node
+
+  TopAbs_ShapeEnum shapeType = TopAbs_SHAPE;
+  int              shapeID = -1;
+  int              faceID = -1;
+  TopoDS_Shape     shape;
+  TopTools_ListIteratorOfListOfShape it;
+
+  std::map< int, int > faceId2nbNodes;
+  std::map< int, int > ::iterator itMapWithIdFace;
+  
+  SMESHDS_Mesh* meshDS = GetMeshDS();
+  
+  // check if a face lie on a FACE, i.e. its all corner nodes lie either on the FACE or
+  // on sub-shapes of the FACE
+  if ( GetMesh()->HasShapeToMesh() )
+  {
+    const SMDS_MeshNode* nodes[] = { n1, n2, n3, n4 };
+    for(int i = 0; i < 4; i++)
+    {
+      shape = GetSubShapeByNode( nodes[i], meshDS );
+      if ( shape.IsNull() ) break;
+      if ( shape.ShapeType() == TopAbs_SOLID )
+      {
+        shapeID   = nodes[i]->getshapeId();
+        shapeType = TopAbs_SOLID;
+        break;
+      }
+      if ( shape.ShapeType() == TopAbs_FACE )
+      {
+        faceID          = nodes[i]->getshapeId();
+        itMapWithIdFace = faceId2nbNodes.insert( std::make_pair( faceID, 0 ) ).first;
+        itMapWithIdFace->second++;
+      }
+      else
+      {
+        PShapeIteratorPtr it = GetAncestors(shape, *GetMesh(), TopAbs_FACE );
+        while ( const TopoDS_Shape* face = it->next() )
+        {
+          faceID = meshDS->ShapeToIndex( *face );
+          itMapWithIdFace = faceId2nbNodes.insert( std::make_pair( faceID, 0 ) ).first;
+          itMapWithIdFace->second++;
+        }
+      }
+    }
+  }
+  if ( shapeID < 1 && !faceId2nbNodes.empty() ) // SOLID not found
+  {
+    // find ID of the FACE the four corner nodes belong to
+    itMapWithIdFace = faceId2nbNodes.begin();
+    for ( ; itMapWithIdFace != faceId2nbNodes.end(); ++itMapWithIdFace)
+    {
+      if ( itMapWithIdFace->second == 4 ) 
+      {
+        shapeType = TopAbs_FACE;
+        faceID = (*itMapWithIdFace).first;
+        break;
+      }
+    }
+  }
+
+  TopoDS_Face F;
+  if ( shapeType == TopAbs_FACE )
+  {
+    F = TopoDS::Face( meshDS->IndexToShape( faceID ));
+  }
+
+  // Create a node
+
+  gp_XY  uvAvg;
+  gp_Pnt P;
+  if ( !F.IsNull() )
+  {
+    if ( !force3d )
+    {
+      uvAvg = calcTFI (0.5, 0.5,
+                       GetNodeUV(F,n1,n3),  GetNodeUV(F,n2,n4),
+                       GetNodeUV(F,n3,n1),  GetNodeUV(F,n4,n2), 
+                       GetNodeUV(F,n12,n3), GetNodeUV(F,n23,n4),
+                       GetNodeUV(F,n34,n2), GetNodeUV(F,n41,n2));
+      TopLoc_Location loc;
+      Handle( Geom_Surface ) S = BRep_Tool::Surface( F, loc );
+      P = S->Value( uvAvg.X(), uvAvg.Y() ).Transformed( loc );
+      centralNode = meshDS->AddNode( P.X(), P.Y(), P.Z() );
+      if ( mySetElemOnShape )
+        meshDS->SetNodeOnFace( centralNode, faceID, uvAvg.X(), uvAvg.Y() );
+      myMapWithCentralNode.insert( std::make_pair( keyOfMap, centralNode ) );
+      return centralNode;
+    }
+  }
+
+  P = ( SMESH_TNodeXYZ( n1 ) +
+        SMESH_TNodeXYZ( n2 ) +
+        SMESH_TNodeXYZ( n3 ) +
+        SMESH_TNodeXYZ( n4 ) ) / 4;
+  centralNode = meshDS->AddNode( P.X(), P.Y(), P.Z() );
+
+  if ( mySetElemOnShape )
+  {
+    if ( !F.IsNull() )
+    {
+      uvAvg = (GetNodeUV(F,n1,n3) +
+               GetNodeUV(F,n2,n4) +
+               GetNodeUV(F,n3,n1) +
+               GetNodeUV(F,n4,n2)) / 4;
+      CheckNodeUV( F, centralNode, uvAvg, 2*BRep_Tool::Tolerance( F ), /*force=*/true);
+      meshDS->SetNodeOnFace( centralNode, faceID, uvAvg.X(), uvAvg.Y() );
+    }
+    else if ( shapeID > 0 )
+      meshDS->SetNodeInVolume( centralNode, shapeID );
+    else if ( myShapeID > 0 )
+      meshDS->SetMeshElementOnShape( centralNode, myShapeID );
+  }
+
+  myMapWithCentralNode.insert( std::make_pair( keyOfMap, centralNode ) );
+  return centralNode;
+}
+
+//=======================================================================
 //function : GetMediumNode
-//purpose  : Return existing or create new medium nodes between given ones
+//purpose  : Return existing or create a new medium node between given ones
 //=======================================================================
 
 const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
@@ -1041,7 +1200,7 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
   TopoDS_Face F; gp_XY  uv[2];
   bool uvOK[2] = { false, false };
 
-  pair<int, TopAbs_ShapeEnum> pos = GetMediumPos( n1, n2 );
+  pair<int, TopAbs_ShapeEnum> pos = GetMediumPos( n1, n2, mySetElemOnShape );
 
   // get positions of the given nodes on shapes
   if ( pos.second == TopAbs_FACE )
@@ -1088,7 +1247,8 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
         gp_XY UV = GetMiddleUV( S, uv[0], uv[1] );
         gp_Pnt P = S->Value( UV.X(), UV.Y() ).Transformed(loc);
         n12 = meshDS->AddNode(P.X(), P.Y(), P.Z());
-        meshDS->SetNodeOnFace(n12, faceID, UV.X(), UV.Y());
+        if ( mySetElemOnShape )
+          meshDS->SetNodeOnFace(n12, faceID, UV.X(), UV.Y());
         myTLinkNodeMap.insert(make_pair(link,n12));
         return n12;
       }
@@ -1112,7 +1272,8 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
 
         gp_Pnt P = C->Value( U );
         n12 = meshDS->AddNode(P.X(), P.Y(), P.Z());
-        meshDS->SetNodeOnEdge(n12, edgeID, U);
+        if ( mySetElemOnShape )
+          meshDS->SetNodeOnEdge(n12, edgeID, U);
         myTLinkNodeMap.insert(make_pair(link,n12));
         return n12;
       }
@@ -1125,21 +1286,24 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
   double z = ( n1->Z() + n2->Z() )/2.;
   n12 = meshDS->AddNode(x,y,z);
 
-  if ( !F.IsNull() )
-  {
-    gp_XY UV = ( uv[0] + uv[1] ) / 2.;
-    CheckNodeUV( F, n12, UV, 2*BRep_Tool::Tolerance( F ), /*force=*/true);
-    meshDS->SetNodeOnFace(n12, faceID, UV.X(), UV.Y() );
-  }
-  else if ( !E.IsNull() )
-  {
-    double U = ( u[0] + u[1] ) / 2.;
-    CheckNodeU( E, n12, U, 2*BRep_Tool::Tolerance( E ), /*force=*/true);
-    meshDS->SetNodeOnEdge(n12, edgeID, U);
-  }
-  else if ( myShapeID > 0 )
+  if ( mySetElemOnShape )
   {
-    meshDS->SetNodeInVolume(n12, myShapeID);
+    if ( !F.IsNull() )
+    {
+      gp_XY UV = ( uv[0] + uv[1] ) / 2.;
+      CheckNodeUV( F, n12, UV, 2*BRep_Tool::Tolerance( F ), /*force=*/true);
+      meshDS->SetNodeOnFace(n12, faceID, UV.X(), UV.Y() );
+    }
+    else if ( !E.IsNull() )
+    {
+      double U = ( u[0] + u[1] ) / 2.;
+      CheckNodeU( E, n12, U, 2*BRep_Tool::Tolerance( E ), /*force=*/true);
+      meshDS->SetNodeOnEdge(n12, edgeID, U);
+    }
+    else if ( myShapeID > 0 )
+    {
+      meshDS->SetMeshElementOnShape(n12, myShapeID);
+    }
   }
 
   myTLinkNodeMap.insert( make_pair( link, n12 ));
@@ -1211,7 +1375,8 @@ const SMDS_MeshNode* SMESH_MesherHelper::getMediumNodeOnComposedWire(const SMDS_
     GetMeshDS()->MoveNode( n12, p.X(), p.Y(), p.Z() );
   }
 
-  GetMeshDS()->SetNodeOnEdge(n12, edges[iOkEdge], u);
+  if ( mySetElemOnShape )
+    GetMeshDS()->SetNodeOnEdge(n12, edges[iOkEdge], u);
 
   myTLinkNodeMap.insert( make_pair( SMESH_TLink(n1,n2), n12 ));
 
@@ -1319,7 +1484,7 @@ SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
 
 //=======================================================================
 //function : AddFace
-//purpose  : Creates quadratic or linear quadrangle
+//purpose  : Creates bi-quadratic, quadratic or linear quadrangle
 //=======================================================================
 
 SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
@@ -1362,11 +1527,21 @@ SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
     const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
     const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
     const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);
-
-    if(id)
-      elem = meshDS->AddFaceWithID(n1, n2, n3, n4, n12, n23, n34, n41, id);
+    if(myCreateBiQuadratic)
+    {
+     const SMDS_MeshNode* nCenter = GetCentralNode(n1, n2, n3, n4, n12, n23, n34, n41, force3d);
+     if(id)
+       elem = meshDS->AddFaceWithID(n1, n2, n3, n4, n12, n23, n34, n41, nCenter, id);
+     else
+       elem = meshDS->AddFace(n1, n2, n3, n4, n12, n23, n34, n41, nCenter);
+    }
     else
-      elem = meshDS->AddFace(n1, n2, n3, n4, n12, n23, n34, n41);
+    {
+      if(id)
+        elem = meshDS->AddFaceWithID(n1, n2, n3, n4, n12, n23, n34, n41, id);
+      else
+        elem = meshDS->AddFace(n1, n2, n3, n4, n12, n23, n34, n41);
+    }
   }
   if ( mySetElemOnShape && myShapeID > 0 )
     meshDS->SetMeshElementOnShape( elem, myShapeID );
@@ -1550,7 +1725,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
 
 //=======================================================================
 //function : AddVolume
-//purpose  : Creates quadratic or linear hexahedron
+//purpose  : Creates bi-quadratic, quadratic or linear hexahedron
 //=======================================================================
 
 SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
@@ -1587,15 +1762,75 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
     const SMDS_MeshNode* n26 = GetMediumNode(n2,n6,force3d);
     const SMDS_MeshNode* n37 = GetMediumNode(n3,n7,force3d);
     const SMDS_MeshNode* n48 = GetMediumNode(n4,n8,force3d);
-
-    if(id)
-      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8,
-                                     n12, n23, n34, n41, n56, n67,
-                                     n78, n85, n15, n26, n37, n48, id);
+    if(myCreateBiQuadratic)
+    {
+      const SMDS_MeshNode* n1234 = GetCentralNode(n1,n2,n3,n4,n12,n23,n34,n41,force3d);
+      const SMDS_MeshNode* n1256 = GetCentralNode(n1,n2,n5,n6,n12,n26,n56,n15,force3d);
+      const SMDS_MeshNode* n2367 = GetCentralNode(n2,n3,n6,n7,n23,n37,n67,n26,force3d);
+      const SMDS_MeshNode* n3478 = GetCentralNode(n3,n4,n7,n8,n34,n48,n78,n37,force3d);
+      const SMDS_MeshNode* n1458 = GetCentralNode(n1,n4,n5,n8,n41,n48,n15,n85,force3d);
+      const SMDS_MeshNode* n5678 = GetCentralNode(n5,n6,n7,n8,n56,n67,n78,n85,force3d);
+
+      vector<gp_XYZ> pointsOnShapes( SMESH_Block::ID_Shell );
+
+      pointsOnShapes[ SMESH_Block::ID_V000 ] = SMESH_TNodeXYZ( n4 );
+      pointsOnShapes[ SMESH_Block::ID_V100 ] = SMESH_TNodeXYZ( n8 );
+      pointsOnShapes[ SMESH_Block::ID_V010 ] = SMESH_TNodeXYZ( n3 );
+      pointsOnShapes[ SMESH_Block::ID_V110 ] = SMESH_TNodeXYZ( n7 );
+      pointsOnShapes[ SMESH_Block::ID_V001 ] = SMESH_TNodeXYZ( n1 );
+      pointsOnShapes[ SMESH_Block::ID_V101 ] = SMESH_TNodeXYZ( n5 );
+      pointsOnShapes[ SMESH_Block::ID_V011 ] = SMESH_TNodeXYZ( n2 );
+      pointsOnShapes[ SMESH_Block::ID_V111 ] = SMESH_TNodeXYZ( n6 );
+
+      pointsOnShapes[ SMESH_Block::ID_Ex00 ] = SMESH_TNodeXYZ( n48 );
+      pointsOnShapes[ SMESH_Block::ID_Ex10 ] = SMESH_TNodeXYZ( n37 );
+      pointsOnShapes[ SMESH_Block::ID_E0y0 ] = SMESH_TNodeXYZ( n15 );
+      pointsOnShapes[ SMESH_Block::ID_E1y0 ] = SMESH_TNodeXYZ( n26 );
+      pointsOnShapes[ SMESH_Block::ID_Ex01 ] = SMESH_TNodeXYZ( n34 );
+      pointsOnShapes[ SMESH_Block::ID_Ex11 ] = SMESH_TNodeXYZ( n78 );
+      pointsOnShapes[ SMESH_Block::ID_E0y1 ] = SMESH_TNodeXYZ( n12 );
+      pointsOnShapes[ SMESH_Block::ID_E1y1 ] = SMESH_TNodeXYZ( n56 );
+      pointsOnShapes[ SMESH_Block::ID_E00z ] = SMESH_TNodeXYZ( n41 );    
+      pointsOnShapes[ SMESH_Block::ID_E10z ] = SMESH_TNodeXYZ( n85 );    
+      pointsOnShapes[ SMESH_Block::ID_E01z ] = SMESH_TNodeXYZ( n23 );    
+      pointsOnShapes[ SMESH_Block::ID_E11z ] = SMESH_TNodeXYZ( n67 );
+
+      pointsOnShapes[ SMESH_Block::ID_Fxy0 ] = SMESH_TNodeXYZ( n3478 );
+      pointsOnShapes[ SMESH_Block::ID_Fxy1 ] = SMESH_TNodeXYZ( n1256 );
+      pointsOnShapes[ SMESH_Block::ID_Fx0z ] = SMESH_TNodeXYZ( n1458 );   
+      pointsOnShapes[ SMESH_Block::ID_Fx1z ] = SMESH_TNodeXYZ( n2367 );   
+      pointsOnShapes[ SMESH_Block::ID_F0yz ] = SMESH_TNodeXYZ( n1234 );    
+      pointsOnShapes[ SMESH_Block::ID_F1yz ] = SMESH_TNodeXYZ( n5678 );
+
+      gp_XYZ centerCube(0.5, 0.5, 0.5);
+      gp_XYZ nCenterElem;
+      SMESH_Block::ShellPoint( centerCube, pointsOnShapes, nCenterElem );
+      const SMDS_MeshNode* nCenter =
+        meshDS->AddNode( nCenterElem.X(), nCenterElem.Y(), nCenterElem.Z() );
+      meshDS->SetNodeInVolume( nCenter, myShapeID );
+
+     if(id)
+        elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8,
+                                      n12, n23, n34, n41, n56, n67,
+                                      n78, n85, n15, n26, n37, n48,
+                                      n1234, n1256, n2367, n3478, n1458, n5678, nCenter, id);
+      else
+        elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8,
+                                n12, n23, n34, n41, n56, n67,
+                                n78, n85, n15, n26, n37, n48,
+                                n1234, n1256, n2367, n3478, n1458, n5678, nCenter);
+    }
     else
-      elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8,
-                               n12, n23, n34, n41, n56, n67,
-                               n78, n85, n15, n26, n37, n48);
+    {
+      if(id)
+        elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8,
+                                      n12, n23, n34, n41, n56, n67,
+                                      n78, n85, n15, n26, n37, n48, id);
+      else
+        elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8,
+                                n12, n23, n34, n41, n56, n67,
+                                n78, n85, n15, n26, n37, n48);
+    }
   }
   if ( mySetElemOnShape && myShapeID > 0 )
     meshDS->SetMeshElementOnShape( elem, myShapeID );
@@ -1720,10 +1955,11 @@ bool SMESH_MesherHelper::IsSameElemGeometry(const SMESHDS_SubMesh* smDS,
   if ( !smDS ) return nullSubMeshRes;
 
   SMDS_ElemIteratorPtr elemIt = smDS->GetElements();
-  while ( elemIt->more() )
-    if ( elemIt->next()->GetGeomType() != shape )
+  while ( elemIt->more() ) {
+    const SMDS_MeshElement* e = elemIt->next();
+    if ( e->GetGeomType() != shape )
       return false;
-
+  }
   return true;
 }
 
@@ -1898,7 +2134,8 @@ namespace
   //================================================================================
 
   bool isCornerOfStructure( const SMDS_MeshNode*   n,
-                            const SMESHDS_SubMesh* faceSM )
+                            const SMESHDS_SubMesh* faceSM,
+                            SMESH_MesherHelper&    faceAnalyser )
   {
     int nbFacesInSM = 0;
     if ( n ) {
@@ -1906,7 +2143,14 @@ namespace
       while ( fIt->more() )
         nbFacesInSM += faceSM->Contains( fIt->next() );
     }
-    return ( nbFacesInSM == 1 );
+    if ( nbFacesInSM == 1 )
+      return true;
+
+    if ( nbFacesInSM == 2 && n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX )
+    {
+      return faceAnalyser.IsRealSeam( n->getshapeId() );
+    }
+    return false;
   }
 }
 
@@ -1925,13 +2169,15 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM )
   list< int > nbEdgesInWires;
   int nbWires = SMESH_Block::GetOrderedEdges( TopoDS::Face( faceSM->GetSubShape() ),
                                               edges, nbEdgesInWires );
-  if ( nbWires != 1 )
+  if ( nbWires != 1 || nbEdgesInWires.front() != 4 )
     return false;
 
   // algo: find corners of a structure and then analyze nb of faces and
   // length of structure sides
 
   SMESHDS_Mesh* meshDS = faceSM->GetFather()->GetMeshDS();
+  SMESH_MesherHelper faceAnalyser( *faceSM->GetFather() );
+  faceAnalyser.SetSubShape( faceSM->GetSubShape() );
 
   // rotate edges to get the first node being at corner
   // (in principle it's not necessary but so far none SALOME algo can make
@@ -1940,7 +2186,8 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM )
   int nbRemainEdges = nbEdgesInWires.front();
   do {
     TopoDS_Vertex V = IthVertex( 0, edges.front() );
-    isCorner = isCornerOfStructure( SMESH_Algo::VertexNode( V, meshDS ), fSM);
+    isCorner = isCornerOfStructure( SMESH_Algo::VertexNode( V, meshDS ),
+                                    fSM, faceAnalyser);
     if ( !isCorner ) {
       edges.splice( edges.end(), edges, edges.begin() );
       --nbRemainEdges;
@@ -1963,16 +2210,13 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM )
 
     list< const SMDS_MeshNode* > edgeNodes;
     map< double, const SMDS_MeshNode* >::iterator u2n = u2Nodes.begin();
-    if ( !nodes.empty() && nodes.back() == u2n->second )
-      ++u2n;
-    map< double, const SMDS_MeshNode* >::iterator u2nEnd = --u2Nodes.end();
-    if ( nodes.empty() || nodes.back() != u2nEnd->second )
-      ++u2nEnd;
-    for ( ; u2n != u2nEnd; ++u2n )
+    for ( ; u2n != u2Nodes.end(); ++u2n )
       edgeNodes.push_back( u2n->second );
-
     if ( edge->Orientation() == TopAbs_REVERSED )
       edgeNodes.reverse();
+
+    if ( !nodes.empty() && nodes.back() == edgeNodes.front() )
+      edgeNodes.pop_front();
     nodes.splice( nodes.end(), edgeNodes, edgeNodes.begin(), edgeNodes.end() );
   }
 
@@ -1983,7 +2227,7 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM )
   for ( ; n != nodes.end(); ++n )
   {
     ++nbEdges;
-    if ( isCornerOfStructure( *n, fSM )) {
+    if ( isCornerOfStructure( *n, fSM, faceAnalyser )) {
       nbEdgesInSide.push_back( nbEdges );
       nbEdges = 0;
     }
@@ -2488,7 +2732,7 @@ namespace { // Structures used by FixQuadraticElements()
   enum { ERR_OK, ERR_TRI, ERR_PRISM, ERR_UNKNOWN }; // errors of QFace::GetLinkChain()
   // --------------------------------------------------------------------
   /*!
-   * \brief Face shared by two volumes and bound by QLinks
+   * \brief Quadratic face shared by two volumes and bound by QLinks
    */
   struct QFace: public TIDSortedNodeSet
   {
@@ -3857,11 +4101,13 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
   // 3. Compute displacement of medium nodes
   // ---------------------------------------
 
-  // two loops on QFaces: the first is to treat boundary links, the second is for internal ones
+  // two loops on QFaces: the first is to treat boundary links, the second is for internal ones.
   TopLoc_Location loc;
-  // not treat boundary of volumic submesh
+  bool checkUV;
+  // not to treat boundary of volumic sub-mesh.
   int isInside = ( elemType == SMDSAbs_Volume && volumeOnly ) ? 1 : 0;
-  for ( ; isInside < 2; ++isInside ) {
+  for ( ; isInside < 2; ++isInside )
+  {
     MSG( "--------------- LOOP (inside=" << isInside << ") ------------------");
     SMDS_TypeOfPosition pos = isInside ? SMDS_TOP_3DSPACE : SMDS_TOP_FACE;
     SMDS_TypeOfPosition bndPos = isInside ? SMDS_TOP_FACE : SMDS_TOP_EDGE;
@@ -3936,7 +4182,6 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
           gp_Vec move1 = chain.back ()->_nodeMove;
 
           TopoDS_Face face;
-          bool checkUV = true;
           if ( !isInside )
           {
             // compute node displacement of end links of chain in parametric space of face
@@ -4049,10 +4294,131 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
   // 4. Move nodes
   // -------------
 
+  TIDSortedElemSet biQuadQuas, triQuadHexa;
+  const SMDS_MeshElement *biQuadQua, *triQuadHex;
+  const bool toFixCentralNodes = ( myMesh->NbBiQuadQuadrangles() +
+                                   myMesh->NbTriQuadraticHexas() );
+
   for ( pLink = links.begin(); pLink != links.end(); ++pLink ) {
-    if ( pLink->IsMoved() ) {
+    if ( pLink->IsMoved() )
+    {
       gp_Pnt p = pLink->MiddlePnt() + pLink->Move();
       GetMeshDS()->MoveNode( pLink->_mediumNode, p.X(), p.Y(), p.Z());
+
+      // collect bi-quadratic elements
+      if ( toFixCentralNodes )
+      {
+        biQuadQua = triQuadHex = 0;
+        SMDS_ElemIteratorPtr eIt = pLink->_mediumNode->GetInverseElementIterator();
+        while ( eIt->more() )
+        {
+          const SMDS_MeshElement* e = eIt->next();
+          SMDSAbs_EntityType   type = e->GetEntityType();
+          if ( type == SMDSEntity_BiQuad_Quadrangle )
+            biQuadQuas.insert( e );
+          else if ( type == SMDSEntity_TriQuad_Hexa )
+            triQuadHexa.insert( e );
+        }
+      }
+    }
+  }
+
+  // Fix positions of central nodes of bi-tri-quadratic elements
+
+  // treat bi-quad quadrangles
+  {
+    vector< const SMDS_MeshNode* > nodes( 9 );
+    gp_XY uv[ 9 ];
+    //TIDSortedNodeSet checkedNodes;
+    TIDSortedElemSet::iterator quadIt = biQuadQuas.begin();
+    for ( ; quadIt != biQuadQuas.end(); ++quadIt )
+    {
+      const SMDS_MeshElement* quad = *quadIt;
+      // nodes
+      nodes.clear();
+      nodes.assign( quad->begin_nodes(), quad->end_nodes() );
+      // FACE
+      TopoDS_Shape S = GetSubShapeByNode( nodes.back(), GetMeshDS() );
+      if ( S.IsNull() || S.ShapeType() != TopAbs_FACE ) continue;
+      const TopoDS_Face& F = TopoDS::Face( S );
+      Handle( Geom_Surface ) surf = BRep_Tool::Surface( F, loc );
+      const double tol = BRep_Tool::Tolerance( F );
+      // UV
+      for ( int i = 0; i < 8; ++i )
+      {
+        uv[ i ] = GetNodeUV( F, nodes[i], nodes[8], &checkUV );
+        // as this method is used after mesh generation, UV of nodes is not
+        // updated according to bending links, so we update 
+        if ( i > 3 && nodes[i]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
+          CheckNodeUV( F, nodes[i], uv[ i ], 2*tol, /*force=*/true );
+      }
+      // move central node
+      gp_XY uvCent = calcTFI (0.5, 0.5, uv[0],uv[1],uv[2],uv[3],uv[4],uv[5],uv[6],uv[7] );
+      gp_Pnt p = surf->Value( uvCent.X(), uvCent.Y() ).Transformed( loc );
+      GetMeshDS()->MoveNode( nodes[8], p.X(), p.Y(), p.Z());
+    }
+  }
+
+  // treat tri-quadratic hexahedra
+  {
+    SMDS_VolumeTool volExp;
+    TIDSortedElemSet::iterator hexIt = triQuadHexa.begin();
+    for ( ; hexIt != triQuadHexa.end(); ++hexIt )
+    {
+      volExp.Set( *hexIt, /*ignoreCentralNodes=*/false );
+
+      // fix nodes central in sides
+      for ( int iQuad = 0; iQuad < volExp.NbFaces(); ++iQuad )
+      {
+        const SMDS_MeshNode** quadNodes = volExp.GetFaceNodes( iQuad );
+        if ( quadNodes[8]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_3DSPACE )
+        {
+          gp_XYZ p = calcTFI( 0.5, 0.5,
+                              SMESH_TNodeXYZ( quadNodes[0] ), SMESH_TNodeXYZ( quadNodes[2] ),
+                              SMESH_TNodeXYZ( quadNodes[4] ), SMESH_TNodeXYZ( quadNodes[6] ),
+                              SMESH_TNodeXYZ( quadNodes[1] ), SMESH_TNodeXYZ( quadNodes[3] ),
+                              SMESH_TNodeXYZ( quadNodes[5] ), SMESH_TNodeXYZ( quadNodes[7] ));
+          GetMeshDS()->MoveNode( quadNodes[8], p.X(), p.Y(), p.Z());
+        }
+      }
+
+      // fix the volume central node
+      vector<gp_XYZ> pointsOnShapes( SMESH_Block::ID_Shell );
+      const SMDS_MeshNode** hexNodes = volExp.GetNodes();
+
+      pointsOnShapes[ SMESH_Block::ID_V000 ] = SMESH_TNodeXYZ( hexNodes[ 0 ] );
+      pointsOnShapes[ SMESH_Block::ID_V100 ] = SMESH_TNodeXYZ( hexNodes[ 3 ] );
+      pointsOnShapes[ SMESH_Block::ID_V010 ] = SMESH_TNodeXYZ( hexNodes[ 1 ] );
+      pointsOnShapes[ SMESH_Block::ID_V110 ] = SMESH_TNodeXYZ( hexNodes[ 2 ] );
+      pointsOnShapes[ SMESH_Block::ID_V001 ] = SMESH_TNodeXYZ( hexNodes[ 4 ] );
+      pointsOnShapes[ SMESH_Block::ID_V101 ] = SMESH_TNodeXYZ( hexNodes[ 7 ] );
+      pointsOnShapes[ SMESH_Block::ID_V011 ] = SMESH_TNodeXYZ( hexNodes[ 5 ] );
+      pointsOnShapes[ SMESH_Block::ID_V111 ] = SMESH_TNodeXYZ( hexNodes[ 6 ] );
+
+      pointsOnShapes[ SMESH_Block::ID_Ex00 ] = SMESH_TNodeXYZ( hexNodes[ 11 ] );
+      pointsOnShapes[ SMESH_Block::ID_Ex10 ] = SMESH_TNodeXYZ( hexNodes[  9 ] );
+      pointsOnShapes[ SMESH_Block::ID_E0y0 ] = SMESH_TNodeXYZ( hexNodes[  8 ] );
+      pointsOnShapes[ SMESH_Block::ID_E1y0 ] = SMESH_TNodeXYZ( hexNodes[ 10 ] );
+      pointsOnShapes[ SMESH_Block::ID_Ex01 ] = SMESH_TNodeXYZ( hexNodes[ 15 ] );
+      pointsOnShapes[ SMESH_Block::ID_Ex11 ] = SMESH_TNodeXYZ( hexNodes[ 13 ] );
+      pointsOnShapes[ SMESH_Block::ID_E0y1 ] = SMESH_TNodeXYZ( hexNodes[ 12 ] );
+      pointsOnShapes[ SMESH_Block::ID_E1y1 ] = SMESH_TNodeXYZ( hexNodes[ 14 ] );
+      pointsOnShapes[ SMESH_Block::ID_E00z ] = SMESH_TNodeXYZ( hexNodes[ 16 ] );    
+      pointsOnShapes[ SMESH_Block::ID_E10z ] = SMESH_TNodeXYZ( hexNodes[ 19 ] );    
+      pointsOnShapes[ SMESH_Block::ID_E01z ] = SMESH_TNodeXYZ( hexNodes[ 17 ] );    
+      pointsOnShapes[ SMESH_Block::ID_E11z ] = SMESH_TNodeXYZ( hexNodes[ 18 ] );
+
+      pointsOnShapes[ SMESH_Block::ID_Fxy0 ] = SMESH_TNodeXYZ( hexNodes[ 20 ] );
+      pointsOnShapes[ SMESH_Block::ID_Fxy1 ] = SMESH_TNodeXYZ( hexNodes[ 25 ] );
+      pointsOnShapes[ SMESH_Block::ID_Fx0z ] = SMESH_TNodeXYZ( hexNodes[ 21 ] );   
+      pointsOnShapes[ SMESH_Block::ID_Fx1z ] = SMESH_TNodeXYZ( hexNodes[ 23 ] );   
+      pointsOnShapes[ SMESH_Block::ID_F0yz ] = SMESH_TNodeXYZ( hexNodes[ 24 ] );    
+      pointsOnShapes[ SMESH_Block::ID_F1yz ] = SMESH_TNodeXYZ( hexNodes[ 22 ] );
+
+      gp_XYZ nCenterParams(0.5, 0.5, 0.5), nCenterCoords;
+      SMESH_Block::ShellPoint( nCenterParams, pointsOnShapes, nCenterCoords );
+      GetMeshDS()->MoveNode( hexNodes[26],
+                             nCenterCoords.X(), nCenterCoords.Y(), nCenterCoords.Z());
     }
   }
 
index cf515df..ee3e62b 100644 (file)
@@ -72,7 +72,7 @@ typedef gp_XY (*xyFunPtr)(const gp_XY& uv1, const gp_XY& uv2);
 
 class SMESH_EXPORT SMESH_MesherHelper
 {
-public:
+ public:
   // ---------- PUBLIC UTILITIES ----------
   
   /*!
@@ -147,6 +147,36 @@ public:
   }
 
   /*!
+   * \brief Return UV of a point inside a quadrilateral FACE by it's
+   *        normalized parameters within a unit quadrangle and the
+   *        corresponding projections on sub-shapes of the real-world FACE.
+   *        The used calculation method is called Trans-Finite Interpolation (TFI).
+   *  \param x,y - normalized parameters that should be in range [0,1]
+   *  \param a0,a1,a2,a3 - UV of VERTEXes of the FACE == projections on VERTEXes
+   *  \param p0,p1,p2,p3 - UV of the point projections on EDGEs of the FACE
+   *  \return gp_XY - UV of the point on the FACE
+   *
+   * Order of those UV in the FACE is as follows.
+   *   a4   p3    a3
+   *    o---x-----o
+   *    |   :     |
+   *    |   :UV   |
+   * p4 x...O.....x p2
+   *    |   :     |
+   *    o---x-----o
+   *   a1   p1    a2
+   */
+  inline static gp_XY calcTFI(double x, double y,
+                              const gp_XY a0,const gp_XY a1,const gp_XY a2,const gp_XY a3,
+                              const gp_XY p0,const gp_XY p1,const gp_XY p2,const gp_XY p3);
+
+  /*!
+   * \brief Same as "gp_XY calcTFI(...)" but in 3D
+   */
+  inline static gp_XYZ calcTFI(double x, double y,
+                               const gp_XYZ a0,const gp_XYZ a1,const gp_XYZ a2,const gp_XYZ a3,
+                               const gp_XYZ p0,const gp_XYZ p1,const gp_XYZ p2,const gp_XYZ p3);
+  /*!
    * \brief Count nb of sub-shapes
     * \param shape - the shape
     * \param type - the type of sub-shapes to count
@@ -214,8 +244,19 @@ public:
   /*!
    * \brief Set order of elements to create without calling IsQuadraticSubMesh()
    */
+
+  /*!
+   * \brief Set myCreateQuadratic flag
+   */
   void SetIsQuadratic(const bool theBuildQuadratic)
   { myCreateQuadratic = theBuildQuadratic; }
+
+  /*!
+   * \brief Set myCreateBiQuadratic flag
+   */
+  void SetIsBiQuadratic(const bool theBuildBiQuadratic)
+  { myCreateBiQuadratic = theBuildBiQuadratic; }
+  
   /*!
    * \brief Return myCreateQuadratic flag
    */
@@ -227,6 +268,11 @@ public:
   bool IsReversedSubMesh (const TopoDS_Face& theFace);
 
   /*!
+   * \brief Return myCreateBiQuadratic flag
+   */
+  bool GetIsBiQuadratic() const { return myCreateBiQuadratic; }
+
+  /*!
    * \brief Move medium nodes of faces and volumes to fix distorted elements
    * \param error - container of fixed distorted elements
    * \param volumeOnly - fix nodes on geom faces or not if the shape is solid
@@ -276,7 +322,7 @@ public:
                          const int id=0, 
                          const bool force3d = false);
   /*!
-   * Creates quadratic or linear quadrangle
+   * Creates bi-quadratic, quadratic or linear quadrangle
    */
   SMDS_MeshFace* AddFace(const SMDS_MeshNode* n1,
                          const SMDS_MeshNode* n2,
@@ -284,7 +330,6 @@ public:
                          const SMDS_MeshNode* n4,
                          const int id = 0,
                          const bool force3d = false);
-
   /*!
    * Creates polygon, with additional nodes in quadratic mesh
    */
@@ -322,7 +367,7 @@ public:
                              const int id = 0, 
                              const bool force3d = true);
   /*!
-   * Creates quadratic or linear hexahedron
+   * Creates bi-quadratic, quadratic or linear hexahedron
    */
   SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
                              const SMDS_MeshNode* n2,
@@ -526,10 +571,26 @@ public:
                                      const SMDS_MeshNode* n2,
                                      const bool force3d);
   /*!
+   * \brief Return existing or create a new central node for a quardilateral
+   *       quadratic face given its 8 nodes.
+   *  \param force3d - true means node creation in between the given nodes,
+   *                   else node position is found on a geometrical face if any.
+   */
+  const SMDS_MeshNode* GetCentralNode(const SMDS_MeshNode* n1,
+                                      const SMDS_MeshNode* n2,
+                                      const SMDS_MeshNode* n3,
+                                      const SMDS_MeshNode* n4,
+                                      const SMDS_MeshNode* n12,
+                                      const SMDS_MeshNode* n23,
+                                      const SMDS_MeshNode* n34,
+                                      const SMDS_MeshNode* n41,
+                                      bool                 force3d);
+  /*!
    * \brief Return index and type of the shape (EDGE or FACE only) to set a medium node on
    */
   std::pair<int, TopAbs_ShapeEnum> GetMediumPos(const SMDS_MeshNode* n1,
-                                                const SMDS_MeshNode* n2);
+                                                const SMDS_MeshNode* n2,
+                                                const bool           useCurSubShape=false);
   /*!
    * \brief Add a link in my data structure
    */
@@ -561,13 +622,13 @@ public:
   
   virtual ~SMESH_MesherHelper();
 
-protected:
+ protected:
 
   /*!
    * \brief Select UV on either of 2 pcurves of a seam edge, closest to the given UV
-    * \param uv1 - UV on the seam
-    * \param uv2 - UV within a face
-    * \retval gp_Pnt2d - selected UV
+    \param uv1 - UV on the seam
+    \param uv2 - UV within a face
+    \retval gp_Pnt2d - selected UV
    */
   gp_Pnt2d GetUVOnSeam( const gp_Pnt2d& uv1, const gp_Pnt2d& uv2 ) const;
 
@@ -577,10 +638,31 @@ protected:
  private:
 
   // Forbiden copy constructor
-  SMESH_MesherHelper (const SMESH_MesherHelper& theOther) {};
-
-  // special map for using during creation of quadratic elements
-  TLinkNodeMap    myTLinkNodeMap;
+  SMESH_MesherHelper (const SMESH_MesherHelper& theOther);
+
+  // key of a map of bi-quadratic face to it's central node
+  struct TBiQuad: public std::pair<int, std::pair<int, int> >
+  {
+    TBiQuad(const SMDS_MeshNode* n1,
+            const SMDS_MeshNode* n2, 
+            const SMDS_MeshNode* n3,
+            const SMDS_MeshNode* n4)
+    {
+      TIDSortedNodeSet s;
+      s.insert(n1);
+      s.insert(n2);
+      s.insert(n3);
+      s.insert(n4);
+      TIDSortedNodeSet::iterator n = s.begin();
+      first = (*n++)->GetID();
+      second.first = (*n++)->GetID();
+      second.second = (*n++)->GetID();
+    }
+  };
+
+  // maps used during creation of quadratic elements
+  TLinkNodeMap                        myTLinkNodeMap;       // medium nodes on links
+  std::map< TBiQuad, SMDS_MeshNode* > myMapWithCentralNode; // central nodes of faces
 
   std::set< int > myDegenShapeIds;
   std::set< int > mySeamShapeIds;
@@ -597,14 +679,35 @@ protected:
   int             myShapeID;
 
   bool            myCreateQuadratic;
+  bool            myCreateBiQuadratic;
   bool            mySetElemOnShape;
   bool            myFixNodeParameters;
 
   std::map< int,bool > myNodePosShapesValidity;
   bool toCheckPosOnShape(int shapeID ) const;
   void setPosOnShapeValidity(int shapeID, bool ok ) const;
-
 };
 
+//=======================================================================
+inline gp_XY
+SMESH_MesherHelper::calcTFI(double x, double y,
+                            const gp_XY a0,const gp_XY a1,const gp_XY a2,const gp_XY a3,
+                            const gp_XY p0,const gp_XY p1,const gp_XY p2,const gp_XY p3)
+{
+  return
+    ((1 - y) * p0 + x * p1 + y * p2 + (1 - x) * p3 ) -
+    ((1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3);
+}
+//=======================================================================
+inline gp_XYZ
+SMESH_MesherHelper::calcTFI(double x, double y,
+                            const gp_XYZ a0,const gp_XYZ a1,const gp_XYZ a2,const gp_XYZ a3,
+                            const gp_XYZ p0,const gp_XYZ p1,const gp_XYZ p2,const gp_XYZ p3)
+{
+  return
+    ((1 - y) * p0 + x * p1 + y * p2 + (1 - x) * p3 ) -
+    ((1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3);
+}
+//=======================================================================
 
 #endif
index d015be1..08b033d 100644 (file)
@@ -647,7 +647,7 @@ SMESH_Hypothesis::Hypothesis_Status
 
   int oldAlgoState = _algoState;
   bool modifiedHyp = (event == MODIF_HYP);  // if set to true, force event MODIF_ALGO_STATE
-  bool needFullClean = false, subMeshesSupported = false;
+  SMESH_Algo* algoRequiringCleaning = 0;
 
   bool isApplicableHyp = IsApplicableHypotesis( anHyp );
 
@@ -671,7 +671,8 @@ SMESH_Hypothesis::Hypothesis_Status
       filter.Or( SMESH_HypoFilter::HasType( algo->GetType()+1 ));
       filter.Or( SMESH_HypoFilter::HasType( algo->GetType()+2 ));
       if ( SMESH_Algo * curAlgo = (SMESH_Algo*)_father->GetHypothesis(_subShape, filter, true ))
-        needFullClean = ( !curAlgo->NeedDiscreteBoundary() );
+        if ( !curAlgo->NeedDiscreteBoundary() )
+          algoRequiringCleaning = curAlgo;
     }
   }
 
@@ -702,13 +703,7 @@ SMESH_Hypothesis::Hypothesis_Status
     {
       algo = dynamic_cast<SMESH_Algo*> (anHyp);
       if (!algo->NeedDiscreteBoundary())
-      {
-        // clean all mesh in the tree of the current submesh;
-        // we must perform it now because later
-        // we will have no information about the type of the removed algo
-        needFullClean = true;
-        subMeshesSupported = algo->SupportSubmeshes();
-      }
+        algoRequiringCleaning = algo;
     }
   }
 
@@ -990,10 +985,7 @@ SMESH_Hypothesis::Hypothesis_Status
       // CLEAN was not called at event REMOVE_ALGO because the algo is not applicable to SOLID.
       algo = dynamic_cast<SMESH_Algo*> (anHyp);
       if (!algo->NeedDiscreteBoundary())
-      {
-        needFullClean = true;
-        subMeshesSupported = algo->SupportSubmeshes();
-      }
+        algoRequiringCleaning = algo;
       algo = GetAlgo();
       if (algo == NULL)  // no more applying algo on father
       {
@@ -1069,10 +1061,10 @@ SMESH_Hypothesis::Hypothesis_Status
     }
   }
 
-  if ( needFullClean ) {
+  if ( algoRequiringCleaning ) {
     // added or removed algo is all-dimensional
     ComputeStateEngine( CLEAN );
-    cleanDependsOn( subMeshesSupported );
+    cleanDependsOn( algoRequiringCleaning );
     ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
   }
 
@@ -1174,45 +1166,67 @@ SMESH_Hypothesis::Hypothesis_Status
 //================================================================================
 /*!
  * \brief Remove elements from sub-meshes.
- *  \param keepSupportedsubMeshes - if true, the sub-meshes computed using more 
- *         local algorithms are not cleaned
+ *  \param algoRequiringCleaning - an all-dimensional algorithm whose presence
+ *         causes the cleaning.
  */
 //================================================================================
 
-void SMESH_subMesh::cleanDependsOn( bool keepSupportedsubMeshes )
+void SMESH_subMesh::cleanDependsOn( SMESH_Algo* algoRequiringCleaning/*=0*/ )
 {
-  if ( _father->NbNodes() == 0 ) return;
-
   SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,
                                                        /*complexShapeFirst=*/true);
-  if ( !keepSupportedsubMeshes )
+  if ( _father->NbNodes() == 0 )
+  {
+    while ( smIt->more() )
+      smIt->next()->ComputeStateEngine(CHECK_COMPUTE_STATE);
+  }
+  else if ( !algoRequiringCleaning || !algoRequiringCleaning->SupportSubmeshes() )
   {
     while ( smIt->more() )
       smIt->next()->ComputeStateEngine(CLEAN);
   }
-  else
+  else if ( algoRequiringCleaning && algoRequiringCleaning->SupportSubmeshes() )
   {
+    SMESHDS_Mesh* meshDS = _father->GetMeshDS();
+
     // find sub-meshes to keep elements on
     set< SMESH_subMesh* > smToKeep;
-    SMESHDS_Mesh* meshDS = _father->GetMeshDS();
+    TopAbs_ShapeEnum prevShapeType = TopAbs_SHAPE;
+    bool toKeepPrevShapeType = false;
     while ( smIt->more() )
     {
       SMESH_subMesh* sm = smIt->next();
-      if ( sm->IsEmpty() ) continue;
-
-      // look for an algo assigned to sm
-      bool algoFound = false;
-      const list<const SMESHDS_Hypothesis*>& hyps = meshDS->GetHypothesis( sm->_subShape );
-      list<const SMESHDS_Hypothesis*>::const_iterator h = hyps.begin();
-      for ( ; ( !algoFound && h != hyps.end() ); ++h )
-        algoFound = ((*h)->GetType() != SMESHDS_Hypothesis::PARAM_ALGO );
-
-      // remember all sub-meshes of sm
-      if ( algoFound )
+      sm->ComputeStateEngine(CHECK_COMPUTE_STATE);
+      if ( !sm->IsEmpty() )
       {
-        SMESH_subMeshIteratorPtr smIt2 = getDependsOnIterator(false,true);
-        while ( smIt2->more() )
-          smToKeep.insert( smIt2->next() );
+        const bool sameShapeType = ( prevShapeType == sm->GetSubShape().ShapeType() );
+        bool keepSubMeshes = ( sameShapeType && toKeepPrevShapeType );
+        if ( !sameShapeType )
+        {
+          // check if the algo allows presence of global algos of dimension the algo
+          // can generate it-self
+          int  shapeDim = SMESH_Gen::GetShapeDim( sm->GetSubShape() );
+          keepSubMeshes = algoRequiringCleaning->NeedLowerHyps( shapeDim );
+          prevShapeType = sm->GetSubShape().ShapeType();
+          toKeepPrevShapeType = keepSubMeshes;
+        }
+        if ( !keepSubMeshes )
+        {
+          // look for an algo assigned to sm
+          bool algoFound = false;
+          const list<const SMESHDS_Hypothesis*>& hyps = meshDS->GetHypothesis( sm->_subShape );
+          list<const SMESHDS_Hypothesis*>::const_iterator h = hyps.begin();
+          for ( ; ( !algoFound && h != hyps.end() ); ++h )
+            algoFound = ((*h)->GetType() != SMESHDS_Hypothesis::PARAM_ALGO );
+          keepSubMeshes = algoFound;
+        }
+        // remember all sub-meshes of sm
+        if ( keepSubMeshes )
+        {
+          SMESH_subMeshIteratorPtr smIt2 = getDependsOnIterator(false,true);
+          while ( smIt2->more() )
+            smToKeep.insert( smIt2->next() );
+        }
       }
     }
     // remove elements
@@ -1374,7 +1388,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
     case MODIF_ALGO_STATE:
       algo = GetAlgo();
       if (algo && !algo->NeedDiscreteBoundary())
-        cleanDependsOn( algo->SupportSubmeshes() ); // clean sub-meshes with event CLEAN
+        cleanDependsOn( algo ); // clean sub-meshes with event CLEAN
       if ( _algoState == HYP_OK )
         _computeState = READY_TO_COMPUTE;
       break;
@@ -1420,7 +1434,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
       if (algo)
       {
         if (!algo->NeedDiscreteBoundary())
-          cleanDependsOn( algo->SupportSubmeshes() ); // clean sub-meshes with event CLEAN
+          cleanDependsOn( algo ); // clean sub-meshes with event CLEAN
         if ( _algoState == HYP_OK )
           _computeState = READY_TO_COMPUTE;
       }
@@ -1646,7 +1660,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
       ComputeStateEngine( CLEAN );
       algo = GetAlgo();
       if (algo && !algo->NeedDiscreteBoundary())
-        cleanDependsOn( algo->SupportSubmeshes() ); // clean sub-meshes with event CLEAN
+        cleanDependsOn( algo ); // clean sub-meshes with event CLEAN
       break;
     case COMPUTE:               // nothing to do
       break;
@@ -1701,7 +1715,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
         ComputeStateEngine( CLEAN );
       algo = GetAlgo();
       if (algo && !algo->NeedDiscreteBoundary())
-        cleanDependsOn( algo->SupportSubmeshes() ); // clean sub-meshes with event CLEAN
+        cleanDependsOn( algo ); // clean sub-meshes with event CLEAN
       if (_algoState == HYP_OK)
         _computeState = READY_TO_COMPUTE;
       else
index a1b3a85..669ef71 100644 (file)
@@ -273,7 +273,7 @@ protected:
   void updateDependantsState(const compute_event theEvent);
   void updateSubMeshState(const compute_state theState);
   void cleanDependants();
-  void cleanDependsOn( bool keepSupportedsubMeshes = false );
+  void cleanDependsOn( SMESH_Algo* algoRequiringCleaning=0 );
   void setAlgoState(algo_state state);
 
   /*!
index b42d728..57b69e7 100644 (file)
@@ -27,6 +27,8 @@
 //
 #include "SMESHGUI_ConvToQuadDlg.h"
 
+#include "SMESHGUI_ConvToQuadOp.h"
+
 // Qt includes
 #include <QGroupBox>
 #include <QCheckBox>
@@ -62,14 +64,17 @@ SMESHGUI_ConvToQuadDlg::SMESHGUI_ConvToQuadDlg()
   aBGLayout->setMargin(MARGIN);
   aBGLayout->setSpacing(SPACING);
   
-  myRB1 = new QRadioButton( tr( "RADIOBTN_1" ), myBGBox );
-  myRB2 = new QRadioButton( tr( "RADIOBTN_2" ), myBGBox );
-
-  aBGLayout->addWidget(myRB1);
-  aBGLayout->addWidget(myRB2);
-  myBG->addButton(myRB1, 0);
-  myBG->addButton(myRB2, 1);
-  myRB1->setChecked( true );
+  myRB2Lin = new QRadioButton( tr( "RADIOBTN_1" ), myBGBox );
+  myRB2Quad = new QRadioButton( tr( "RADIOBTN_2" ), myBGBox );
+  myRB2BiQua = new QRadioButton( tr( "RADIOBTN_3" ), myBGBox );
+
+  aBGLayout->addWidget(myRB2Lin);
+  aBGLayout->addWidget(myRB2Quad);
+  aBGLayout->addWidget(myRB2BiQua);
+  myBG->addButton(myRB2Lin, 0);
+  myBG->addButton(myRB2Quad, 1);
+  myBG->addButton(myRB2BiQua, 2);
+  myRB2Lin->setChecked( true );
 
   myWarning = new QLabel(QString("<b>%1</b>").arg(tr("NON_CONFORM_WARNING")), mainFrame());
 
@@ -92,6 +97,11 @@ SMESHGUI_ConvToQuadDlg::~SMESHGUI_ConvToQuadDlg()
 {
 }
 
+bool SMESHGUI_ConvToQuadDlg::IsBiQuadratic() const
+{
+  return myRB2BiQua->isChecked();
+}
+
 bool SMESHGUI_ConvToQuadDlg::IsMediumNdsOnGeom() const
 {
   return !myMedNdsOnGeom->isChecked();
@@ -133,27 +143,32 @@ bool SMESHGUI_ConvToQuadDlg::isWarningShown()
 void SMESHGUI_ConvToQuadDlg::SetEnabledControls( const bool theCheck )
 {
   //myBGBox->setEnabled( theCheck );
-  myRB1->setEnabled( theCheck );
-  myRB2->setEnabled( theCheck );
+  myRB2Lin->setEnabled( theCheck );
+  myRB2Quad->setEnabled( theCheck );
+  myRB2BiQua->setEnabled( theCheck );
   myMedNdsOnGeom->setEnabled( theCheck );
   //setButtonEnabled( theCheck, QtxDialog::OK | QtxDialog::Apply );
 }
 
 void SMESHGUI_ConvToQuadDlg::SetEnabledRB( const int idx, const bool theCheck ) 
 {
-  if(idx)
+  myRB2Lin  ->setEnabled( idx & SMESHGUI_ConvToQuadOp::Linear );
+  myRB2Quad ->setEnabled( idx & SMESHGUI_ConvToQuadOp::Quadratic );
+  myRB2BiQua->setEnabled( idx & SMESHGUI_ConvToQuadOp::BiQuadratic );
+
+  if ( idx & SMESHGUI_ConvToQuadOp::Linear )
   {
-    myRB2->setEnabled( theCheck );
-    myRB1->setEnabled( !theCheck );
-    myRB1->setChecked( true );
+    myRB2Lin->setChecked( true );
+    myRB2Quad->setChecked( false );
   }
   else
   {
-    myRB1->setEnabled( theCheck );
-    myRB2->setEnabled( !theCheck );
-    myRB2->setChecked( true );
+    myRB2Lin->setChecked( false );
+    myRB2Quad->setChecked( true );
   }
-  emit onClicked( myBG->checkedId() );
-}
+  myRB2BiQua->setChecked( false );
 
+  myMedNdsOnGeom->setEnabled( theCheck );
 
+  emit onClicked( myBG->checkedId() );
+}
index 660dbc7..cc4a26c 100644 (file)
@@ -56,6 +56,7 @@ public:
   int           CurrentRB(); //returns the ID of the selected toggle button
   void          ShowWarning(bool);
   bool          isWarningShown();
+  bool          IsBiQuadratic() const;
 
 signals:
   void          onClicked( int );
@@ -64,8 +65,9 @@ private:
   QCheckBox*    myMedNdsOnGeom;
   QGroupBox*    myBGBox;
   QButtonGroup* myBG;
-  QRadioButton* myRB1;
-  QRadioButton* myRB2;
+  QRadioButton* myRB2Lin;
+  QRadioButton* myRB2Quad;
+  QRadioButton* myRB2BiQua;
   QLabel* myWarning;
 };
 
index ff21b39..42dad57 100644 (file)
@@ -142,19 +142,10 @@ void SMESHGUI_ConvToQuadOp::selectionDone()
       myDlg->setButtonEnabled( false, QtxDialog::OK | QtxDialog::Apply );
       return;
     }
-    MeshType meshType = ConsistMesh( idSource );
-    if( meshType == SMESHGUI_ConvToQuadOp::Quadratic )
-    {
-      myDlg->SetEnabledRB( 0, false );
-    }
-    else if( meshType == SMESHGUI_ConvToQuadOp::Linear )
-    {
-      myDlg->SetEnabledRB( 1, false );
-    }
-    else 
-    {
-      myDlg->SetEnabledControls( true );
-    }
+    SMESH::SMESH_Mesh_var      mesh = idSource->GetMesh();
+    bool                    hasGeom = mesh->HasShapeToMesh();
+    MeshDestinationType meshTgtType = DestinationMesh( idSource );
+    myDlg->SetEnabledRB( meshTgtType, hasGeom && ( meshTgtType & ( BiQuadratic | Quadratic )));
 
     // show warning on non-conformal result mesh
     if ( ! idSource->_is_nil() )
@@ -166,8 +157,9 @@ void SMESHGUI_ConvToQuadOp::selectionDone()
       {
         SMESH::SMESH_Mesh_var mesh = idSource->GetMesh();
         idSource = SMESH::SMESH_IDSource::_narrow( mesh );
-        MeshType fullMeshType = ConsistMesh( idSource );
-        toShow = ( fullMeshType != Comp );
+        bool isMixOrder;
+        DestinationMesh( idSource, &isMixOrder );
+        toShow = !isMixOrder;
       }
       myDlg->ShowWarning( toShow );
     }
@@ -241,17 +233,20 @@ bool SMESHGUI_ConvToQuadOp::onApply()
     SMESH::SMESH_MeshEditor_var aEditor = mesh->GetMeshEditor();
     aResult = true; 
     SMESH::SMESH_Mesh_var sourceMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( pObj );  
-    if( !myDlg->CurrentRB() )
+    if( myDlg->CurrentRB()==1 || myDlg->CurrentRB()==2)
     {
       bool force3d = true;
       if( myDlg->IsEnabledCheck() )
         force3d = myDlg->IsMediumNdsOnGeom();
-
-      if ( sourceMesh->_is_nil() )
-        aEditor->ConvertToQuadraticObject( force3d, idSource );
-      else
-        aEditor->ConvertToQuadratic( force3d );
-
+      bool theToBiQuad = myDlg->IsBiQuadratic();
+      if ( sourceMesh->_is_nil() ) {
+        if ( theToBiQuad ) aEditor->ConvertToBiQuadratic    ( force3d, idSource );
+        else               aEditor->ConvertToQuadraticObject( force3d, idSource );
+      }
+      else {
+        if ( theToBiQuad ) aEditor->ConvertToBiQuadratic( force3d, sourceMesh );
+        else               aEditor->ConvertToQuadratic  ( force3d );
+      }
       if ( !force3d )
       {
         SMESH::ComputeError_var error = aEditor->GetLastError();
@@ -259,7 +254,7 @@ bool SMESHGUI_ConvToQuadOp::onApply()
         {
           if ( myBadElemsPreview ) delete myBadElemsPreview; // viewWindow may change
           myBadElemsPreview = new SMESHGUI_MeshEditPreview( viewWindow() );
-          
+
           double aPointSize = SMESH::GetFloat("SMESH:node_size",3);
           double aLineWidth = SMESH::GetFloat("SMESH:element_width",1);
           vtkProperty* prop = vtkProperty::New();
@@ -325,12 +320,23 @@ void SMESHGUI_ConvToQuadOp::onWarningWinFinished()
 
 //================================================================================
 /*! ConsistMesh
- *  Determines, what elements this mesh contains. 
+ *  Determines, what elements this mesh does not contain.
  */
 //================================================================================
-SMESHGUI_ConvToQuadOp::MeshType SMESHGUI_ConvToQuadOp::ConsistMesh( const SMESH::SMESH_IDSource_var& idSource) const
+
+SMESHGUI_ConvToQuadOp::MeshDestinationType
+SMESHGUI_ConvToQuadOp::DestinationMesh( const SMESH::SMESH_IDSource_var& idSource,
+                                        bool*                            isMixOrder) const
 {
   SMESH::long_array_var nbElemOfType = idSource->GetMeshInfo();
+
+  bool hasBiQuad     = ( nbElemOfType[SMDSEntity_BiQuad_Quadrangle ] ||
+                         nbElemOfType[SMDSEntity_TriQuad_Hexa      ] );
+  bool hasLinStruct  = ( nbElemOfType[SMDSEntity_Quadrangle ] ||
+                         nbElemOfType[SMDSEntity_Hexa       ] );
+  bool hasQuadStruct = ( nbElemOfType[SMDSEntity_Quad_Quadrangle ] ||
+                         nbElemOfType[SMDSEntity_Quad_Hexa       ] );
+
   bool hasQuad = ( nbElemOfType[SMDSEntity_Quad_Edge      ] ||
                    nbElemOfType[SMDSEntity_Quad_Triangle  ] ||
                    nbElemOfType[SMDSEntity_Quad_Quadrangle] ||
@@ -347,9 +353,25 @@ SMESHGUI_ConvToQuadOp::MeshType SMESHGUI_ConvToQuadOp::ConsistMesh( const SMESH:
                    nbElemOfType[SMDSEntity_Pyramid   ] ||
                    nbElemOfType[SMDSEntity_Penta     ] );
 
-  if ( hasQuad && hasLin )
-    return Comp;
-  return hasQuad ? Quadratic : Linear;
+  int tgtType = 0;
+  if ( hasBiQuad )
+    tgtType |= ( Quadratic | Linear );
+  if ( hasLinStruct )
+    tgtType |= ( BiQuadratic | Quadratic );
+  if ( hasQuadStruct )
+    tgtType |= ( BiQuadratic | Linear );
+  if ( hasQuad )
+    tgtType |= Linear;
+  if ( hasLin )
+    tgtType |= Quadratic;
+
+  if ( tgtType == 0 )
+    tgtType = Quadratic;
+
+  if ( isMixOrder )
+    *isMixOrder = ( hasLin && ( hasQuad || hasBiQuad ));
+
+  return MeshDestinationType( tgtType );
 }
 
 void SMESHGUI_ConvToQuadOp::ConnectRadioButtons( int id )
@@ -364,7 +386,7 @@ void SMESHGUI_ConvToQuadOp::ConnectRadioButtons( int id )
 
   bool hasGeom = mesh->HasShapeToMesh();
 
-  if( id || !hasGeom )
+  if( id==0 || !hasGeom )
     myDlg->SetEnabledCheck( false );
   else
     myDlg->SetEnabledCheck( true );
index ba30b15..8573bf4 100644 (file)
@@ -44,7 +44,7 @@ class SMESHGUI_EXPORT SMESHGUI_ConvToQuadOp : public SMESHGUI_SelectionOp
   Q_OBJECT
 
 public:      
-  enum MeshType{ Comp = 0, Linear, Quadratic };
+  enum MeshDestinationType { Linear = 1, Quadratic = 2, BiQuadratic = 4 };
 
 public:
   SMESHGUI_ConvToQuadOp();
@@ -56,7 +56,8 @@ protected:
   virtual void                   startOperation();
   virtual void                   selectionDone();
   virtual SUIT_SelectionFilter*  createFilter( const int ) const;
-  MeshType                       ConsistMesh( const SMESH::SMESH_IDSource_var& ) const;
+  MeshDestinationType            DestinationMesh( const SMESH::SMESH_IDSource_var& ,
+                                                  bool* isMixOrder = 0) const;
 
 protected slots:
   virtual bool                   onApply();
index f109701..1ea95a4 100755 (executable)
@@ -1137,6 +1137,7 @@ bool SMESHGUI_FilterTable::IsValid (const bool theMess, const int theEntityType)
              aCriterion == SMESH::FT_BelongToCylinder ||
              aCriterion == SMESH::FT_BelongToGenSurface ||
              aCriterion == SMESH::FT_ElemGeomType ||
+             aCriterion == SMESH::FT_EntityType ||
              aCriterion == SMESH::FT_CoplanarFaces ||
              aCriterion == SMESH::FT_LyingOnGeom)
     {
@@ -1253,6 +1254,8 @@ void SMESHGUI_FilterTable::GetCriterion (const int                 theRow,
   }
   else if ( aCriterionType == SMESH::FT_ElemGeomType )
     theCriterion.Threshold = (double)((ComboItem*)aTable->item(theRow, 2))->value();
+  else if ( aCriterionType == SMESH::FT_EntityType )
+    theCriterion.Threshold = (double)((ComboItem*)aTable->item(theRow, 2))->value();
   else if ( aCriterionType == SMESH::FT_CoplanarFaces )
     theCriterion.ThresholdID = aTable->text(theRow, 2).toLatin1().constData();
   else if ( aCriterionType != SMESH::FT_RangeOfIds &&
@@ -1329,6 +1332,11 @@ void SMESHGUI_FilterTable::SetCriterion (const int                       theRow,
     ComboItem* typeBox = (ComboItem*)aTable->item(theRow, 2);
     typeBox->setValue( (int)(theCriterion.Threshold + 0.5) );
   }
+  else if (theCriterion.Type == SMESH::FT_EntityType )
+  {
+    ComboItem* typeBox = (ComboItem*)aTable->item(theRow, 2);
+    typeBox->setValue( (int)(theCriterion.Threshold + 0.5) );
+  }
   else if (theCriterion.Type == SMESH::FT_CoplanarFaces )
   {
     aTable->item( theRow, 2 )->setText( QString( theCriterion.ThresholdID ) );
@@ -1652,9 +1660,39 @@ static QList<int> geomTypes( const int theType )
 }
 
 //=======================================================================
+// name    : entityTypes
+// Purpose : returns available entity types of elements
+//=======================================================================
+
+static QList<int> entityTypes( const int theType )
+{
+  QList<int> typeIds;
+
+  if ( theType == SMESH::EDGE )
+  {
+    typeIds.append( SMDSEntity_Edge );
+    typeIds.append( SMDSEntity_Quad_Edge );
+  }
+  if ( theType == SMESH::FACE )
+  {
+    typeIds.append( SMDSEntity_Quadrangle );
+    typeIds.append( SMDSEntity_Quad_Quadrangle );
+    typeIds.append( SMDSEntity_BiQuad_Quadrangle );
+  }
+  if ( theType == SMESH::VOLUME )
+  {
+    typeIds.append( SMDSEntity_Hexa );
+    typeIds.append( SMDSEntity_Quad_Hexa );
+    typeIds.append( SMDSEntity_TriQuad_Hexa );
+  }
+  return typeIds;
+}
+
+//=======================================================================
 // name    : SMESHGUI_FilterTable::onCriterionChanged()
 // Purpose : Provides reaction on change of criterion
 //=======================================================================
+
 void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, const int entityType)
 {
   int aType = entityType == -1 ? GetType() : entityType;
@@ -1689,8 +1727,8 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
     aCriterionType == SMESH::FT_Length2D ||
     aCriterionType == SMESH::FT_MaxElementLength2D ||
     aCriterionType == SMESH::FT_MaxElementLength3D ||
-    aCriterionType == SMESH::FT_Volume3D;
-
+    aCriterionType == SMESH::FT_Volume3D ||
+    aCriterionType == SMESH::FT_EntityType;
   int aPrecision = 0;
   if ( anIsDoubleCriterion ) {
     const char* aPrecisionType = getPrecision( aCriterionType );
@@ -1710,6 +1748,7 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
 
   if ( (aCriterionType != SMESH::FT_GroupColor && clrBtn) ||
        (aCriterionType != SMESH::FT_ElemGeomType && isComboItem) ||
+       (aCriterionType != SMESH::FT_EntityType && isComboItem) ||
        (aCriterionType != SMESH::FT_MultiConnection && isIntSpinItem) ||
        (!anIsDoubleCriterion && isDoubleSpinItem) ||
        anIsPrecisionChanged )
@@ -1722,6 +1761,7 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
   }
   if ( (aCriterionType == SMESH::FT_GroupColor && !clrBtn) ||
        (aCriterionType == SMESH::FT_ElemGeomType && !isComboItem) ||
+       (aCriterionType == SMESH::FT_EntityType && !isComboItem) ||
        (aCriterionType == SMESH::FT_MultiConnection && !isIntSpinItem) ||
        (anIsDoubleCriterion && !isDoubleSpinItem) ||
        anIsPrecisionChanged )
@@ -1742,6 +1782,18 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
       ComboItem* typeBox = new ComboItem( typeNames );
       aTable->setItem( row, 2, typeBox );
     }
+    else if ( aCriterionType == SMESH::FT_EntityType ) {
+      QList<int> typeIds = entityTypes( aType );
+      QMap<int, QString> typeNames;
+      QList<int>::const_iterator anIter = typeIds.begin();
+      for ( int i = 0; anIter != typeIds.end(); ++anIter, ++i)
+      {
+        QString typeKey = QString( "ENTITY_TYPE_%1" ).arg( *anIter );
+        typeNames[ *anIter ] = tr( typeKey.toLatin1().data() );
+      }
+      ComboItem* typeBox = new ComboItem( typeNames );
+      aTable->setItem( row, 2, typeBox );
+    }
     else if ( aCriterionType == SMESH::FT_MultiConnection ) {
       IntSpinItem* intSpin = new IntSpinItem( 0 );
       aTable->setItem( row, 2, intSpin );
@@ -1771,7 +1823,8 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
       aCriterionType == SMESH::FT_LinearOrQuadratic ||
       aCriterionType == SMESH::FT_GroupColor ||
       aCriterionType == SMESH::FT_ElemGeomType ||
-      aCriterionType == SMESH::FT_CoplanarFaces
+      aCriterionType == SMESH::FT_CoplanarFaces ||
+      aCriterionType == SMESH::FT_EntityType 
       )
   {
     bool isSignalsBlocked = aTable->signalsBlocked();
@@ -1783,6 +1836,7 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
     aTable->item(row, 2)->setText( QString("") );
     aTable->setEditable(aCriterionType == SMESH::FT_GroupColor ||
                         aCriterionType == SMESH::FT_ElemGeomType ||
+                        aCriterionType == SMESH::FT_EntityType || 
                         aCriterionType == SMESH::FT_CoplanarFaces, row, 2);
     aTable->blockSignals( isSignalsBlocked );
   }
@@ -1802,7 +1856,8 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
       aTable->setEditable(true, row, 2);
   }
   else if (aCriterionType == SMESH::FT_GroupColor ||
-           aCriterionType == SMESH::FT_ElemGeomType)
+           aCriterionType == SMESH::FT_ElemGeomType ||
+           aCriterionType == SMESH::FT_EntityType)
   {
     if (!aTable->isEditable(row, 2))
       aTable->setEditable(true, row, 2);
@@ -2034,6 +2089,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
       aCriteria[ SMESH::FT_GroupColor         ] = tr("GROUP_COLOR");
       aCriteria[ SMESH::FT_ElemGeomType       ] = tr("GEOM_TYPE");
       aCriteria[ SMESH::FT_EqualEdges         ] = tr("EQUAL_EDGE");
+      aCriteria[ SMESH::FT_EntityType         ] = tr("ENTITY_TYPE");
     }
     return aCriteria;
   }
@@ -2066,6 +2122,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
       aCriteria[ SMESH::FT_ElemGeomType       ] = tr("GEOM_TYPE");
       aCriteria[ SMESH::FT_CoplanarFaces      ] = tr("COPLANAR_FACES");
       aCriteria[ SMESH::FT_EqualFaces         ] = tr("EQUAL_FACE");
+      aCriteria[ SMESH::FT_EntityType         ] = tr("ENTITY_TYPE");
     }
     return aCriteria;
   }
@@ -2087,6 +2144,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
       aCriteria[ SMESH::FT_GroupColor           ] = tr("GROUP_COLOR");
       aCriteria[ SMESH::FT_ElemGeomType         ] = tr("GEOM_TYPE");
       aCriteria[ SMESH::FT_EqualVolumes         ] = tr("EQUAL_VOLUME");
+      aCriteria[ SMESH::FT_EntityType           ] = tr("ENTITY_TYPE");
     }
     return aCriteria;
   }
index 5e82b9b..ebd89c1 100644 (file)
@@ -4634,13 +4634,17 @@ Do you want to restore original submesh priority?</translation>
     </message>
     <message>
         <source>RADIOBTN_1</source>
-        <translation>Convert to quadratic</translation>
+        <translation>Convert to linear</translation>
     </message>
     <message>
         <source>RADIOBTN_2</source>
-        <translation>Convert from quadratic</translation>
+        <translation>Convert to quadratic</translation>
     </message>
-    <message>
+      <message>
+        <source>RADIOBTN_3</source>
+        <translation>Convert to bi-quadratic</translation>
+      </message>
+      <message>
         <source>NON_CONFORM_WARNING</source>
         <translation>Warning: mesh can become non-conformal</translation>
     </message>
@@ -5196,6 +5200,10 @@ Please check input data and try again</translation>
         <source>COPLANAR_FACES</source>
         <translation>Coplanar faces</translation>
     </message>
+  <message>
+    <source>NUMBEROFNODESINELEMENT</source>
+    <translation>Number Of Nodes In Element</translation>
+  </message>
     <message>
         <source>COPY_FROM</source>
         <translation>Copy from...</translation>
@@ -5217,10 +5225,6 @@ Please check input data and try again</translation>
         <translation>Edges</translation>
     </message>
     <message>
-        <source>ENTITY_TYPE</source>
-        <translation>Entity type</translation>
-    </message>
-    <message>
         <source>EQUAL_TO</source>
         <translation>Equal to</translation>
     </message>
@@ -5368,6 +5372,98 @@ Please enter correct value and try again</translation>
         <translation>Elements</translation>
     </message>
     <message>
+        <source>ENTITY_TYPE</source>
+        <translation>Entity type</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_0</source>
+        <translation>POINT1</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_2</source>
+        <translation>SEG2</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_3</source>
+        <translation>SEG3</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_4</source>
+        <translation>TRIA3</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_5</source>
+        <translation>TRIA6</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_6</source>
+        <translation>QUAD4</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_7</source>
+        <translation>QUAD8</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_8</source>
+        <translation>QUAD9</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_9</source>
+        <translation>TETRA4</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_10</source>
+        <translation>TETRA10</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_11</source>
+        <translation>PYRA5</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_12</source>
+        <translation>PYRA13</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_13</source>
+        <translation>PENTA6</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_14</source>
+        <translation>PENTA15</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_15</source>
+        <translation>HEXA8</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_16</source>
+        <translation>HEXA20</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_17</source>
+        <translation>HEXA27</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_18</source>
+        <translation>OCTA12</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_19</source>
+        <translation>POLYGONE</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_20</source>
+        <translation>POLYEDRE</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_21</source>
+        <translation>NONE</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_22</source>
+        <translation>BALL</translation>
+    </message>
+    <message>
         <source>GEOM_TYPE</source>
         <translation>Geometry type</translation>
     </message>
index 57a0768..5b10f99 100644 (file)
@@ -256,6 +256,8 @@ namespace {
     //   - FT_EqualVolumes          = 17
     // v 6.6.0: FT_Undefined == 44, new items:
     //   - FT_BallDiameter          = 37
+    // v 6.7.1: FT_Undefined == 45, new items:
+    //   - FT_EntityType            = 36
     //
     // It's necessary to continue recording this history and to fill
     // undef2newItems (see below) accordingly.
@@ -275,6 +277,8 @@ namespace {
         undef2newItems[ 43 ].assign( items, items+4 ); }
       { int items[] = { 37 };
         undef2newItems[ 44 ].assign( items, items+1 ); }
+      { int items[] = { 36 };
+        undef2newItems[ 45 ].assign( items, items+1 ); }
     }
 
     int iType     = Type.IntegerValue();
@@ -660,7 +664,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
     // 1    2       3         4            5           6       7        8         9             10
     // in order to avoid the problem of type mismatch of long and FunctorType
     const TCollection_AsciiString
-      SMESH("SMESH."), dfltFunctor = "SMESH.FT_Undefined", dftlTol = "1e-07", dftlPreci = "-1";
+      SMESH("SMESH."), dfltFunctor("SMESH.FT_Undefined"), dftlTol("1e-07"), dftlPreci("-1");
     TCollection_AsciiString
       Type          = aCommand->GetArg(1),  // long
       Compare       = aCommand->GetArg(2),  // long
@@ -686,17 +690,34 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
     aCommand->SetArg( 2, Type );
     aCommand->SetArg( 3, Compare );
 
-    if ( Type == "SMESH.FT_ElemGeomType" && Threshold.IsIntegerValue() )
+    if ( Threshold.IsIntegerValue() )
     {
-      // set SMESH.GeometryType instead of a numerical Threshold
-      const char* types[SMESH::Geom_BALL+1] = {
-        "Geom_POINT", "Geom_EDGE", "Geom_TRIANGLE", "Geom_QUADRANGLE", "Geom_POLYGON",
-        "Geom_TETRA", "Geom_PYRAMID", "Geom_HEXA", "Geom_PENTA", "Geom_HEXAGONAL_PRISM",
-        "Geom_POLYHEDRA", "Geom_BALL"
-      };
       int iGeom = Threshold.IntegerValue();
-      if ( -1 < iGeom && iGeom < SMESH::Geom_POLYHEDRA+1 )
-        Threshold = SMESH + types[ iGeom ];
+      if ( Type == "SMESH.FT_ElemGeomType" )
+      {
+        // set SMESH.GeometryType instead of a numerical Threshold
+        const char* types[SMESH::Geom_BALL+1] = {
+          "Geom_POINT", "Geom_EDGE", "Geom_TRIANGLE", "Geom_QUADRANGLE", "Geom_POLYGON",
+          "Geom_TETRA", "Geom_PYRAMID", "Geom_HEXA", "Geom_PENTA", "Geom_HEXAGONAL_PRISM",
+          "Geom_POLYHEDRA", "Geom_BALL" };
+        if ( -1 < iGeom && iGeom < SMESH::Geom_POLYHEDRA+1 )
+          Threshold = SMESH + types[ iGeom ];
+      }
+      if (Type == "SMESH.FT_EntityType")
+      {
+        // set SMESH.EntityType instead of a numerical Threshold
+        const char* types[SMESH::Entity_Ball+1] = {
+          "Entity_Node", "Entity_0D", "Entity_Edge", "Entity_Quad_Edge",
+          "Entity_Triangle", "Entity_Quad_Triangle",
+          "Entity_Quadrangle", "Entity_Quad_Quadrangle", "Entity_BiQuad_Quadrangle",
+          "Entity_Polygon", "Entity_Quad_Polygon", "Entity_Tetra", "Entity_Quad_Tetra",
+          "Entity_Pyramid", "Entity_Quad_Pyramid",
+          "Entity_Hexa", "Entity_Quad_Hexa", "Entity_TriQuad_Hexa",
+          "Entity_Penta", "Entity_Quad_Penta", "Entity_Hexagonal_Prism",
+          "Entity_Polyhedra", "Entity_Quad_Polyhedra", "Entity_Ball" };
+        if ( -1 < iGeom && iGeom < SMESH::Entity_Quad_Polyhedra+1 )
+          Threshold = SMESH + types[ iGeom ];
+      }
     }
     if ( ThresholdID.Length() != 2 && ThresholdStr.Length() != 2) // not '' or ""
       aCommand->SetArg( 4, ThresholdID.SubString( 2, ThresholdID.Length()-1 )); // shape entry
@@ -773,6 +794,14 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
       Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue(ind+1));
       myMeshes.insert( make_pair( mesh->GetID(), mesh ));
     }
+    if ( method == "CreateMeshesFromGMF" )
+    {
+      // CreateMeshesFromGMF( theFileName, theMakeRequiredGroups ) ->
+      // CreateMeshesFromGMF( theFileName )
+      _AString file = theCommand->GetArg(1);
+      theCommand->RemoveArgs();
+      theCommand->SetArg( 1, file );
+    }
   }
 
   // CreateHypothesis()
@@ -1571,7 +1600,7 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
          method == "ExportToMEDX" ) { // ExportToMEDX() --> ExportMED()
       theCommand->SetMethod( "ExportMED" );
     }
-    else if ( method == "ExportCGNS" || method == "ExportGMF" )
+    else if ( method == "ExportCGNS" )
     { // ExportCGNS(part, ...) -> ExportCGNS(..., part)
       _pyID partID = theCommand->GetArg( 1 );
       int nbArgs = theCommand->GetNbArgs();
@@ -1579,6 +1608,14 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
         theCommand->SetArg( i-1, theCommand->GetArg( i ));
       theCommand->SetArg( nbArgs, partID );
     }
+    else if ( method == "ExportGMF" )
+    { // ExportGMF(part,file,bool) -> ExportCGNS(file, part)
+      _pyID partID  = theCommand->GetArg( 1 );
+      _AString file = theCommand->GetArg( 2 );
+      theCommand->RemoveArgs();
+      theCommand->SetArg( 1, file );
+      theCommand->SetArg( 2, partID );
+    }
     else if ( theCommand->MethodStartsFrom( "ExportPartTo" ))
     { // ExportPartTo*(part, ...) -> Export*(..., part)
       //
@@ -2035,6 +2072,13 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
     if (( isPyMeshMethod = ( newMethod.Length() > 0 )))
       theCommand->SetMethod( newMethod );
   }
+  // ConvertToBiQuadratic(...) -> ConvertToQuadratic(...,True)
+  if ( !isPyMeshMethod && (method == "ConvertToBiQuadratic" || method == "ConvertToBiQuadraticObject") )
+  {
+    isPyMeshMethod = true;
+    theCommand->SetMethod( method.SubString( 1, 9) + method.SubString( 12, method.Length()));
+    theCommand->SetArg( theCommand->GetNbArgs() + 1, "True" );
+  }
 
   if ( !isPyMeshMethod )
   {
@@ -3593,7 +3637,7 @@ void _pyCommand::SetArg( int index, const TCollection_AsciiString& theArg)
 
 void _pyCommand::RemoveArgs()
 {
-  if ( int pos = myString.Location( '(', 1, Length() ))
+  if ( int pos = myString.Location( '(', Max( 1, GetBegPos( METHOD_IND )), Length() ))
     myString.Trunc( pos );
   myString += ")";
   myArgs.Clear();
index b609c57..34c1c32 100644 (file)
@@ -196,6 +196,40 @@ namespace SMESH
     }
     return *this;
   }
+  TPythonDump&
+  TPythonDump::
+  operator<<(const SMESH::EntityType& theArg)
+  {
+    myStream<<"SMESH.";
+    switch(theArg){
+    case Entity_0D:                myStream<<"Entity_0D";                break;
+    case Entity_Edge:              myStream<<"Entity_Edge";              break;
+    case Entity_Quad_Edge:         myStream<<"Entity_Quad_Edge";         break;
+    case Entity_Triangle:          myStream<<"Entity_Triangle";          break;
+    case Entity_Quad_Triangle:     myStream<<"Entity_Quad_Triangle";     break;
+    case Entity_Quadrangle:        myStream<<"Entity_Quadrangle";        break;
+    case Entity_Quad_Quadrangle:   myStream<<"Entity_Quad_Quadrangle";   break;
+    case Entity_BiQuad_Quadrangle: myStream<<"Entity_BiQuad_Quadrangle"; break;
+    case Entity_Polygon:           myStream<<"Entity_Polygon";           break;
+    case Entity_Quad_Polygon:      myStream<<"Entity_Quad_Polygon";      break;
+    case Entity_Tetra:             myStream<<"Entity_Tetra";             break;
+    case Entity_Quad_Tetra:        myStream<<"Entity_Quad_Tetra";        break;
+    case Entity_Pyramid:           myStream<<"Entity_Pyramid";           break;
+    case Entity_Quad_Pyramid:      myStream<<"Entity_Quad_Pyramid";      break;
+    case Entity_Hexa:              myStream<<"Entity_Hexa";              break;
+    case Entity_Quad_Hexa:         myStream<<"Entity_Quad_Hexa";         break;
+    case Entity_TriQuad_Hexa:      myStream<<"Entity_TriQuad_Hexa";      break;
+    case Entity_Penta:             myStream<<"Entity_Penta";             break;
+    case Entity_Quad_Penta:        myStream<<"Entity_Quad_Penta";        break;
+    case Entity_Hexagonal_Prism:   myStream<<"Entity_Hexagonal_Prism";   break;
+    case Entity_Polyhedra:         myStream<<"Entity_Polyhedra";         break;
+    case Entity_Quad_Polyhedra:    myStream<<"Entity_Quad_Polyhedra";    break;
+    case Entity_Ball:              myStream<<"Entity_Ball";              break;
+    case Entity_Last:              myStream<<"Entity_Last";              break;
+    default:    myStream<<"__UNKNOWN__EntityType: " << theArg;
+    }
+    return *this;
+  }
 
   template<class TArray>
   void DumpArray(const TArray& theArray, TPythonDump & theStream)
index f7040c5..ac52733 100644 (file)
@@ -702,7 +702,6 @@ FunctorType Taper_i::GetFunctorType()
   return SMESH::FT_Taper;
 }
 
-
 /*
   Class       : Skew_i
   Description : Functor for calculating skew in degrees
@@ -1638,6 +1637,37 @@ FunctorType ElemGeomType_i::GetFunctorType()
 }
 
 /*
+  Class       : ElemEntityType_i
+  Description : Predicate check is element has indicated entity type
+*/
+ElemEntityType_i::ElemEntityType_i()
+{
+  myElemEntityTypePtr.reset(new Controls::ElemEntityType());
+  myFunctorPtr = myPredicatePtr = myElemEntityTypePtr;
+}
+
+void ElemEntityType_i::SetElementType(ElementType theType)
+{
+  myElemEntityTypePtr->SetType(SMDSAbs_ElementType(theType));
+  TPythonDump()<<this<<".SetElementType("<<theType<<")";
+}
+
+void ElemEntityType_i::SetEntityType(EntityType theEntityType)
+{
+  myElemEntityTypePtr->SetElemEntityType(SMDSAbs_EntityType (theEntityType));
+  TPythonDump()<<this<<".SetEntityType("<<theEntityType<<")";
+}
+EntityType ElemEntityType_i::GetEntityType() const
+{
+ return (EntityType) myElemEntityTypePtr->GetElemEntityType();
+}
+
+FunctorType ElemEntityType_i::GetFunctorType()
+{
+  return SMESH::FT_EntityType;
+}
+
+/*
   Class       : CoplanarFaces_i
   Description : Returns true if a mesh face is a coplanar neighbour to a given one
 */
@@ -2312,6 +2342,14 @@ ElemGeomType_ptr FilterManager_i::CreateElemGeomType()
   return anObj._retn();
 }
 
+ElemEntityType_ptr FilterManager_i::CreateElemEntityType()
+{
+  SMESH::ElemEntityType_i* aServant = new SMESH::ElemEntityType_i();
+  SMESH::ElemEntityType_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateElemEntityType()";
+  return anObj._retn();
+}
+
 Filter_ptr FilterManager_i::CreateFilter()
 {
   SMESH::Filter_i* aServant = new SMESH::Filter_i();
@@ -2802,6 +2840,18 @@ static inline bool getCriteria( Predicate_i*                thePred,
       theCriteria[ i ].Threshold     = (double)aPred->GetGeometryType();
       return true;
     }
+  case FT_EntityType:
+    {
+      CORBA::ULong i = theCriteria->length();
+      theCriteria->length( i + 1 );
+
+      theCriteria[ i ] = createCriterion();
+
+      ElemEntityType_i* aPred = dynamic_cast<ElemEntityType_i*>( thePred );
+      theCriteria[ i ].Type          = aFType;
+      theCriteria[ i ].Threshold     = (double)aPred->GetEntityType();
+      return true;
+    }
 
   case FT_Undefined:
     return false;
@@ -3043,6 +3093,14 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
           aPredicate = tmpPred;
           break;
         }
+      case SMESH::FT_EntityType:
+        {
+          SMESH::ElemEntityType_ptr tmpPred = aFilterMgr->CreateElemEntityType();
+          tmpPred->SetElementType( aTypeOfElem );
+          tmpPred->SetEntityType( EntityType( (int (aThreshold + 0.5))));
+          aPredicate = tmpPred;
+          break;
+        }
       case SMESH::FT_CoplanarFaces:
         {
           SMESH::CoplanarFaces_ptr tmpPred = aFilterMgr->CreateCoplanarFaces();
@@ -3289,6 +3347,7 @@ static inline LDOMString toString( CORBA::Long theType )
     case FT_GroupColor      : return "Color of Group";
     case FT_LinearOrQuadratic : return "Linear or Quadratic";
     case FT_ElemGeomType    : return "Element geomtry type";
+    case FT_EntityType      : return "Entity type";
     case FT_Undefined       : return "";
     default                 : return "";
   }
@@ -3341,6 +3400,7 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
   else if ( theStr.equals( "Color of Group"               ) ) return FT_GroupColor;
   else if ( theStr.equals( "Linear or Quadratic"          ) ) return FT_LinearOrQuadratic;
   else if ( theStr.equals( "Element geomtry type"         ) ) return FT_ElemGeomType;
+  else if ( theStr.equals( "Entity type"                  ) ) return FT_EntityType;
   else if ( theStr.equals( ""                             ) ) return FT_Undefined;
   else  return FT_Undefined;
 }
@@ -3903,6 +3963,7 @@ static const char** getFunctNames()
     "FT_LinearOrQuadratic",
     "FT_GroupColor",
     "FT_ElemGeomType",
+    "FT_EntityType", 
     "FT_CoplanarFaces",
     "FT_BallDiameter",
     "FT_LessThan",
@@ -3911,7 +3972,7 @@ static const char** getFunctNames()
     "FT_LogicalNOT",
     "FT_LogicalAND",
     "FT_LogicalOR",
-    "FT_Undefined" };
+    "FT_Undefined"};
   return functName;
 }
 
index d874819..2186b42 100644 (file)
@@ -329,7 +329,6 @@ namespace SMESH
     Controls::Length2DPtr          myLength2DPtr;
   };
   
-  
   /*
     Class       : MultiConnection_i
     Description : Functor for calculating number of faces conneted to the edge
@@ -450,7 +449,7 @@ namespace SMESH
     OverConstrainedFace_i();
     FunctorType                     GetFunctorType();
   };
-  
+
   /*
     Class       : BelongToGeom_i
     Description : Predicate for selection on geometrical support
@@ -763,6 +762,25 @@ namespace SMESH
   private:
     Controls::ElemGeomTypePtr myElemGeomTypePtr;
   };
+
+  /*
+    Class       : ElemEntityType_i
+    Description : Functor for check element entity type
+  */
+  class SMESH_I_EXPORT ElemEntityType_i: public virtual POA_SMESH::ElemEntityType,
+                                         public virtual Predicate_i
+  {
+  public:
+    ElemEntityType_i();
+    FunctorType             GetFunctorType();
+
+    void                    SetElementType ( ElementType  theType );
+    void                    SetEntityType( EntityType theEntityType );
+    EntityType              GetEntityType() const;
+
+  private:
+    Controls::ElemEntityTypePtr myElemEntityTypePtr;
+  };
   
   /*
     Class       : CoplanarFaces_i
@@ -1095,6 +1113,7 @@ namespace SMESH
     LinearOrQuadratic_ptr     CreateLinearOrQuadratic();
     GroupColor_ptr            CreateGroupColor();
     ElemGeomType_ptr          CreateElemGeomType();
+    ElemEntityType_ptr        CreateElemEntityType();
     CoplanarFaces_ptr         CreateCoplanarFaces();
 
     LessThan_ptr              CreateLessThan();
index 87e8861..d88c814 100644 (file)
@@ -460,6 +460,23 @@ void SMESH_MeshEditor_i::initData(bool deleteSearchers)
   getEditor().GetError().reset();
   getEditor().CrearLastCreated();
 }
+
+//================================================================================
+/*!
+ * \brief Increment mesh modif time and optionally record that the performed
+ *        modification may influence futher mesh re-compute.
+ *  \param [in] isReComputeSafe - true if the modification does not infulence
+ *              futher mesh re-compute
+ */
+//================================================================================
+
+void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
+{
+  myMesh->GetMeshDS()->Modified();
+  if ( !isReComputeSafe )
+    myMesh->SetIsModified( true );
+}
+
 //================================================================================
 /*!
  * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
@@ -500,22 +517,14 @@ TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewEle
 
 //================================================================================
 /*!
- * \brief Now does nothing
- */
-//================================================================================
-
-// void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& )
-// {
-// }
-
-//================================================================================
-/*!
  * Return data of mesh edition preview
  */
 //================================================================================
 
 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
-{
+  throw (SALOME::SALOME_Exception)
+{ 
+  SMESH_TRY;
   const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
 
   if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
@@ -593,6 +602,8 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
   }
 
   return myPreviewData._retn();
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -603,13 +614,19 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
 //================================================================================
 
 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
+
   const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
   myLastCreatedNodes->length( aSeq.Length() );
   for (int i = 1; i <= aSeq.Length(); i++)
     myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
+
   return myLastCreatedNodes._retn();
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -620,13 +637,19 @@ SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
 //================================================================================
 
 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
+
   const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
   myLastCreatedElems->length( aSeq.Length() );
   for ( int i = 1; i <= aSeq.Length(); i++ )
     myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
+
   return myLastCreatedElems._retn();
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -636,7 +659,9 @@ SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
 //=======================================================================
 
 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   SMESH::ComputeError_var errOut = new SMESH::ComputeError;
   SMESH_ComputeErrorPtr&  errIn  = getEditor().GetError();
   if ( errIn && !errIn->IsOK() )
@@ -652,7 +677,10 @@ SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
     errOut->subShapeID = -1;
     errOut->hasBadMesh = false;
   }
+
   return errOut._retn();
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -718,7 +746,9 @@ void SMESH_MeshEditor_i::deleteAuxIDSources()
 
 CORBA::Boolean
 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   list< int > IdList;
@@ -731,10 +761,12 @@ SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
 
   // Remove Elements
   bool ret = getEditor().Remove( IdList, false );
-  myMesh->GetMeshDS()->Modified();
-  if ( IDsOfElements.length() )
-    myMesh->SetIsModified( true ); // issue 0020693
+
+  declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
   return ret;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -744,7 +776,9 @@ SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
 //=============================================================================
 
 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   list< int > IdList;
@@ -755,10 +789,12 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNo
   TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
 
   bool ret = getEditor().Remove( IdList, true );
-  myMesh->GetMeshDS()->Modified();
-  if ( IDsOfNodes.length() )
-    myMesh->SetIsModified( true ); // issue 0020693
+
+  declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
   return ret;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -768,10 +804,11 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNo
 //=============================================================================
 
 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
-
   // Update Python script
   TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
 
@@ -787,12 +824,13 @@ CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
 
   int nbNodesBefore = myMesh->NbNodes();
   getEditor().Remove( IdList, true );
-  myMesh->GetMeshDS()->Modified();
-  if ( IdList.size() )
-    myMesh->SetIsModified( true );
   int nbNodesAfter = myMesh->NbNodes();
 
+  declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
   return nbNodesBefore - nbNodesAfter;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -801,9 +839,10 @@ CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
  */
 //=============================================================================
 
-CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
-                                        CORBA::Double y, CORBA::Double z)
+CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
@@ -812,9 +851,11 @@ CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
   TPythonDump() << "nodeID = " << this << ".AddNode( "
                 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
 
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true ); // issue 0020693
+  declareMeshModified( /*isReComputeSafe=*/false );
   return N->GetID();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -824,7 +865,9 @@ CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
 //=============================================================================
 
 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
@@ -833,12 +876,11 @@ CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
   // Update Python script
   TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
 
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true ); // issue 0020693
+  declareMeshModified( /*isReComputeSafe=*/false );
 
-  if (elem)
-    return elem->GetID();
+  return elem ? elem->GetID() : 0;
 
+  SMESH_CATCH( SMESH::throwCorbaException );
   return 0;
 }
 
@@ -851,13 +893,12 @@ CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
   throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   if ( diameter < std::numeric_limits<double>::min() )
     THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
 
-  SMESH_TRY;
-
   const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
   SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
 
@@ -865,14 +906,10 @@ CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diam
   TPythonDump() << "ballElem = "
                 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
 
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true ); // issue 0020693
-
-  if (elem)
-    return elem->GetID();
+  declareMeshModified( /*isReComputeSafe=*/false );
+  return elem ? elem->GetID() : 0;
 
   SMESH_CATCH( SMESH::throwCorbaException );
-
   return 0;
 }
 
@@ -884,7 +921,9 @@ CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diam
 //=============================================================================
 
 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   int NbNodes = IDsOfNodes.length();
@@ -912,10 +951,10 @@ CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
                   <<n1<<", "<<n2<<", "<<n12<<" ])";
   }
 
-  myMesh->GetMeshDS()->Modified();
-  if(elem)
-    return myMesh->SetIsModified( true ), elem->GetID();
+  declareMeshModified( /*isReComputeSafe=*/false );
+  return elem ? elem->GetID() : 0;
 
+  SMESH_CATCH( SMESH::throwCorbaException );
   return 0;
 }
 
@@ -926,7 +965,9 @@ CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
 //=============================================================================
 
 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   int NbNodes = IDsOfNodes.length();
@@ -965,10 +1006,11 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
   // Update Python script
   TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
 
-  myMesh->GetMeshDS()->Modified();
-  if(elem)
-    return myMesh->SetIsModified( true ), elem->GetID();
+  declareMeshModified( /*isReComputeSafe=*/false );
 
+  return elem ? elem->GetID() : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
   return 0;
 }
 
@@ -978,7 +1020,9 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
  */
 //=============================================================================
 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   int NbNodes = IDsOfNodes.length();
@@ -991,8 +1035,11 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsO
   // Update Python script
   TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
 
-  myMesh->GetMeshDS()->Modified();
-  return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
+  declareMeshModified( /*isReComputeSafe=*/false );
+  return elem ? elem->GetID() : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -1003,7 +1050,9 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsO
 //=============================================================================
 
 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   int NbNodes = IDsOfNodes.length();
@@ -1044,10 +1093,10 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
   // Update Python script
   TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
 
-  myMesh->GetMeshDS()->Modified();
-  if(elem)
-    return myMesh->SetIsModified( true ), elem->GetID();
+  declareMeshModified( /*isReComputeSafe=*/false );
+  return elem ? elem->GetID() : 0;
 
+  SMESH_CATCH( SMESH::throwCorbaException );
   return 0;
 }
 
@@ -1058,7 +1107,9 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
 //=============================================================================
 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
                                                      const SMESH::long_array & Quantities)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   int NbNodes = IDsOfNodes.length();
@@ -1080,9 +1131,12 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & I
   // Update Python script
   TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
                 << IDsOfNodes << ", " << Quantities << " )";
-  myMesh->GetMeshDS()->Modified();
 
-  return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
+  declareMeshModified( /*isReComputeSafe=*/false );
+  return elem ? elem->GetID() : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -1092,7 +1146,9 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & I
 //=============================================================================
 
 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   int NbFaces = IdsOfFaces.length();
@@ -1114,9 +1170,12 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_ar
   // Update Python script
   TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
                 << IdsOfFaces << " )";
-  myMesh->GetMeshDS()->Modified();
 
-  return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
+  declareMeshModified( /*isReComputeSafe=*/false );
+  return elem ? elem->GetID() : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -1136,13 +1195,12 @@ SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObje
                                                const char*               theGroupName)
   throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   SMESH::SMESH_IDSource_var result;
   TPythonDump pyDump;
 
-  SMESH_TRY;
-
   TIDSortedElemSet elements, elems0D;
   if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
     getEditor().Create0DElementsOnAllNodes( elements, elems0D );
@@ -1189,9 +1247,10 @@ SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObje
   pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
          << theObject << ", '" << theGroupName << "' )";
 
-  SMESH_CATCH( SMESH::throwCorbaException );
-
   return result._retn();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -1206,7 +1265,7 @@ SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObje
 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
+  SMESH_TRY;
 
   SMESHDS_Mesh * mesh = getMeshDS();
   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
@@ -1223,6 +1282,8 @@ void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexI
   mesh->SetNodeOnVertex( node, VertexID );
 
   myMesh->SetIsModified( true );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=============================================================================
@@ -1239,7 +1300,7 @@ void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
                                        CORBA::Double paramOnEdge)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
+  SMESH_TRY;
 
   SMESHDS_Mesh * mesh = getMeshDS();
   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
@@ -1261,6 +1322,8 @@ void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
   mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
 
   myMesh->SetIsModified( true );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=============================================================================
@@ -1278,8 +1341,7 @@ void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
                                        CORBA::Double u, CORBA::Double v)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
-
+  SMESH_TRY;
   SMESHDS_Mesh * mesh = getMeshDS();
   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
   if ( !node )
@@ -1311,6 +1373,8 @@ void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
 
   mesh->SetNodeOnFace( node, FaceID, u, v );
   myMesh->SetIsModified( true );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=============================================================================
@@ -1325,8 +1389,7 @@ void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
-
+  SMESH_TRY;
   SMESHDS_Mesh * mesh = getMeshDS();
   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
   if ( !node )
@@ -1342,7 +1405,7 @@ void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID
 
   mesh->SetNodeInVolume( node, SolidID );
 
-  // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=============================================================================
@@ -1358,8 +1421,7 @@ void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
                                                CORBA::Long ShapeID)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
-
+  SMESH_TRY;
   SMESHDS_Mesh * mesh = getMeshDS();
   SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
   if ( !elem )
@@ -1378,6 +1440,8 @@ void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
   mesh->SetMeshElementOnShape( elem, ShapeID );
 
   myMesh->SetIsModified( true );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=============================================================================
@@ -1388,7 +1452,9 @@ void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
 
 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
                                                CORBA::Long NodeID2)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
@@ -1400,11 +1466,13 @@ CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
   TPythonDump() << "isDone = " << this << ".InverseDiag( "
                 << NodeID1 << ", " << NodeID2 << " )";
 
-
   int ret =  getEditor().InverseDiag ( n1, n2 );
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true );
+
+  declareMeshModified( /*isReComputeSafe=*/false );
   return ret;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -1415,7 +1483,9 @@ CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
 
 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
                                               CORBA::Long NodeID2)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
@@ -1430,12 +1500,12 @@ CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
 
   bool stat = getEditor().DeleteDiag ( n1, n2 );
 
-  myMesh->GetMeshDS()->Modified();
-  if ( stat )
-    myMesh->SetIsModified( true ); // issue 0020693
-
+  declareMeshModified( /*isReComputeSafe=*/!stat );
 
   return stat;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -1445,7 +1515,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
 //=============================================================================
 
 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   for (int i = 0; i < IDsOfElements.length(); i++)
@@ -1458,13 +1530,12 @@ CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfEleme
   // Update Python script
   TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
 
-  myMesh->GetMeshDS()->Modified();
-  if ( IDsOfElements.length() )
-    myMesh->SetIsModified( true ); // issue 0020693
-
+  declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
   return true;
-}
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
 
 //=============================================================================
 /*!
@@ -1473,7 +1544,9 @@ CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfEleme
 //=============================================================================
 
 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   TPythonDump aTPythonDump; // suppress dump in Reorient()
@@ -1484,7 +1557,11 @@ CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theO
   // Update Python script
   aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
 
+  declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
   return isDone;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -1504,8 +1581,7 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
                                            const SMESH::PointStruct& thePoint)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
-
+  SMESH_TRY;
   initData(/*deleteSearchers=*/false);
 
   TIDSortedElemSet elements;
@@ -1561,8 +1637,7 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
   int nbReori = getEditor().Reorient2D( elements, dirVec, face );
 
   if ( nbReori ) {
-    myMesh->SetIsModified( true );
-    myMesh->GetMeshDS()->Modified();
+    declareMeshModified( /*isReComputeSafe=*/false );
   }
   TPythonDump() << this << ".Reorient2D( "
                 << the2Dgroup << ", "
@@ -1571,6 +1646,9 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
                 << thePoint << " )";
 
   return nbReori;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -1578,10 +1656,13 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
  *
  */
 //=============================================================================
+
 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfElements,
                                               SMESH::NumericalFunctor_ptr Criterion,
                                               CORBA::Double               MaxAngle)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   SMESHDS_Mesh* aMesh = getMeshDS();
@@ -1602,24 +1683,26 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfE
 
 
   bool stat = getEditor().TriToQuad( faces, aCrit, MaxAngle );
-  myMesh->GetMeshDS()->Modified();
-  if ( stat )
-    myMesh->SetIsModified( true ); // issue 0020693
-
 
+  declareMeshModified( /*isReComputeSafe=*/!stat );
   return stat;
-}
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
 
 //=============================================================================
 /*!
  *
  */
 //=============================================================================
+
 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr   theObject,
                                                     SMESH::NumericalFunctor_ptr Criterion,
                                                     CORBA::Double               MaxAngle)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   TPythonDump aTPythonDump;  // suppress dump in TriToQuad()
@@ -1634,17 +1717,22 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr
                << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
 
   return isDone;
-}
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
 
 //=============================================================================
 /*!
  *
  */
 //=============================================================================
+
 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array &   IDsOfElements,
                                               SMESH::NumericalFunctor_ptr Criterion)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   SMESHDS_Mesh* aMesh = getMeshDS();
@@ -1664,12 +1752,12 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array &   IDsOfE
   TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
 
   CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
-  myMesh->GetMeshDS()->Modified();
-  if ( stat )
-    myMesh->SetIsModified( true ); // issue 0020693
-
 
+  declareMeshModified( /*isReComputeSafe=*/false );
   return stat;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 
@@ -1680,7 +1768,9 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array &   IDsOfE
 //=============================================================================
 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr   theObject,
                                                     SMESH::NumericalFunctor_ptr Criterion)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   TPythonDump aTPythonDump;  // suppress dump in QuadToTri()
@@ -1694,7 +1784,11 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr
   // Update Python script
   aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
 
+  declareMeshModified( /*isReComputeSafe=*/false );
   return isDone;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 
@@ -1705,7 +1799,9 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr
 //=============================================================================
 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
                                               CORBA::Boolean            Diag13)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   SMESHDS_Mesh* aMesh = getMeshDS();
@@ -1717,13 +1813,12 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfEle
                 << IDsOfElements << ", " << Diag13 << " )";
 
   CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
-  myMesh->GetMeshDS()->Modified();
-  if ( stat )
-    myMesh->SetIsModified( true ); // issue 0020693
-
-
 
+  declareMeshModified( /*isReComputeSafe=*/ !stat );
   return stat;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 
@@ -1734,7 +1829,9 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfEle
 //=============================================================================
 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
                                                     CORBA::Boolean            Diag13)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   TPythonDump aTPythonDump;  // suppress dump in SplitQuad()
@@ -1746,7 +1843,11 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr th
   aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
                << theObject << ", " << Diag13 << " )";
 
+  declareMeshModified( /*isReComputeSafe=*/!isDone );
   return isDone;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 
@@ -1755,9 +1856,12 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr th
  *  BestSplit
  */
 //=============================================================================
+
 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long                 IDOfQuad,
                                            SMESH::NumericalFunctor_ptr Criterion)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
@@ -1771,9 +1875,12 @@ CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long                 IDOfQuad,
     else
       aCrit.reset(new SMESH::Controls::AspectRatio());
 
-    return getEditor().BestSplit(quad, aCrit);
+    int id = getEditor().BestSplit(quad, aCrit);
+    declareMeshModified( /*isReComputeSafe=*/ id < 1 );
   }
-  return -1;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -1786,8 +1893,7 @@ void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
                                                 CORBA::Short              methodFlags)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
-
+  SMESH_TRY;
   initData();
 
   SMESH::long_array_var anElementsId = elems->GetIDs();
@@ -1795,14 +1901,12 @@ void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
   arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume );
 
   getEditor().SplitVolumesIntoTetra( elemSet, int( methodFlags ));
-  myMesh->GetMeshDS()->Modified();
-
-
-//   if ( myLastCreatedElems.length() ) - it does not influence Compute()
-//     myMesh->SetIsModified( true ); // issue 0020693
+  declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
 
   TPythonDump() << this << ".SplitVolumesIntoTetra( "
                 << elems << ", " << methodFlags << " )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=======================================================================
@@ -1816,6 +1920,7 @@ SMESH_MeshEditor_i::Smooth(const SMESH::long_array &              IDsOfElements,
                            CORBA::Long                            MaxNbOfIterations,
                            CORBA::Double                          MaxAspectRatio,
                            SMESH::SMESH_MeshEditor::Smooth_Method Method)
+  throw (SALOME::SALOME_Exception)
 {
   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
                  MaxAspectRatio, Method, false );
@@ -1833,6 +1938,7 @@ SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array &              IDsO
                                      CORBA::Long                            MaxNbOfIterations,
                                      CORBA::Double                          MaxAspectRatio,
                                      SMESH::SMESH_MeshEditor::Smooth_Method Method)
+  throw (SALOME::SALOME_Exception)
 {
   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
                  MaxAspectRatio, Method, true );
@@ -1850,6 +1956,7 @@ SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr              theObjec
                                  CORBA::Long                            MaxNbOfIterations,
                                  CORBA::Double                          MaxAspectRatio,
                                  SMESH::SMESH_MeshEditor::Smooth_Method Method)
+  throw (SALOME::SALOME_Exception)
 {
   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
                        MaxAspectRatio, Method, false);
@@ -1867,6 +1974,7 @@ SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr
                                            CORBA::Long                            MaxNbOfIterations,
                                            CORBA::Double                          MaxAspectRatio,
                                            SMESH::SMESH_MeshEditor::Smooth_Method Method)
+  throw (SALOME::SALOME_Exception)
 {
   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
                        MaxAspectRatio, Method, true);
@@ -1886,7 +1994,9 @@ SMESH_MeshEditor_i::smooth(const SMESH::long_array &              IDsOfElements,
                            CORBA::Double                          MaxAspectRatio,
                            SMESH::SMESH_MeshEditor::Smooth_Method Method,
                            bool                                   IsParametric)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   SMESHDS_Mesh* aMesh = getMeshDS();
@@ -1908,9 +2018,7 @@ SMESH_MeshEditor_i::smooth(const SMESH::long_array &              IDsOfElements,
   getEditor().Smooth(elements, fixedNodes, method,
                   MaxNbOfIterations, MaxAspectRatio, IsParametric );
 
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true ); // issue 0020693
-
+  declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
 
   // Update Python script
   TPythonDump() << "isDone = " << this << "."
@@ -1922,6 +2030,9 @@ SMESH_MeshEditor_i::smooth(const SMESH::long_array &              IDsOfElements,
                      "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
 
   return true;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 
@@ -1938,7 +2049,9 @@ SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr              theObjec
                                  CORBA::Double                          MaxAspectRatio,
                                  SMESH::SMESH_MeshEditor::Smooth_Method Method,
                                  bool                                   IsParametric)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   TPythonDump aTPythonDump;  // suppress dump in smooth()
@@ -1957,6 +2070,9 @@ SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr              theObjec
                     "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
 
   return isDone;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 
@@ -1967,13 +2083,16 @@ SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr              theObjec
 //=============================================================================
 
 void SMESH_MeshEditor_i::RenumberNodes()
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   // Update Python script
   TPythonDump() << this << ".RenumberNodes()";
 
   getMeshDS()->Renumber( true );
-}
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+}
 
 //=============================================================================
 /*!
@@ -1982,11 +2101,15 @@ void SMESH_MeshEditor_i::RenumberNodes()
 //=============================================================================
 
 void SMESH_MeshEditor_i::RenumberElements()
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   // Update Python script
   TPythonDump() << this << ".RenumberElements()";
 
   getMeshDS()->Renumber( false );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=======================================================================
@@ -1996,11 +2119,16 @@ void SMESH_MeshEditor_i::RenumberElements()
 //=======================================================================
 
 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   if ( !groupIDs )
     return 0;
   myMesh_i->CreateGroupServants();
   return myMesh_i->GetGroups( *groupIDs );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -2016,7 +2144,9 @@ SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
                                   CORBA::Double             theTolerance,
                                   const bool                theMakeGroups,
                                   const SMDSAbs_ElementType theElementType)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   TIDSortedElemSet inElements, copyElements;
@@ -2038,11 +2168,13 @@ SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
   ::SMESH_MeshEditor::PGroupIDs groupIds =
       getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
                                  theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
-  myMesh->GetMeshDS()->Modified();
 
-  //  myMesh->SetIsModified( true ); -- it does not influence Compute()
+  declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
 
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -2055,6 +2187,7 @@ void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElement
                                        CORBA::Double             theAngleInRadians,
                                        CORBA::Long               theNbOfSteps,
                                        CORBA::Double             theTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   if ( !myIsPreviewMode ) {
     TPythonDump() << this << ".RotationSweep( "
@@ -2083,6 +2216,7 @@ SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfEle
                                             CORBA::Double            theAngleInRadians,
                                             CORBA::Long              theNbOfSteps,
                                             CORBA::Double            theTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
@@ -2093,7 +2227,7 @@ SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfEle
                                                theTolerance,
                                                true);
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".RotationSweepMakeGroups( "
                 << theIDsOfElements        << ", "
                 << theAxis                   << ", "
@@ -2114,6 +2248,7 @@ void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject
                                              CORBA::Double             theAngleInRadians,
                                              CORBA::Long               theNbOfSteps,
                                              CORBA::Double             theTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   if ( !myIsPreviewMode ) {
     TPythonDump() << this << ".RotationSweepObject( "
@@ -2142,6 +2277,7 @@ void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObje
                                                CORBA::Double             theAngleInRadians,
                                                CORBA::Long               theNbOfSteps,
                                                CORBA::Double             theTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   if ( !myIsPreviewMode ) {
     TPythonDump() << this << ".RotationSweepObject1D( "
@@ -2171,6 +2307,7 @@ void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObje
                                                CORBA::Double             theAngleInRadians,
                                                CORBA::Long               theNbOfSteps,
                                                CORBA::Double             theTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   if ( !myIsPreviewMode ) {
     TPythonDump() << this << ".RotationSweepObject2D( "
@@ -2201,6 +2338,7 @@ SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theO
                                                   CORBA::Double             theAngleInRadians,
                                                   CORBA::Long               theNbOfSteps,
                                                   CORBA::Double             theTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
@@ -2212,7 +2350,7 @@ SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theO
                                                theTolerance,
                                                true);
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".RotationSweepObjectMakeGroups( "
                 << theObject << ", "
                 << theAxis << ", "
@@ -2234,6 +2372,7 @@ SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr th
                                                     CORBA::Double             theAngleInRadians,
                                                     CORBA::Long               theNbOfSteps,
                                                     CORBA::Double             theTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
@@ -2246,7 +2385,7 @@ SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr th
                                                true,
                                                SMDSAbs_Edge);
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
                 << theObject                 << ", "
                 << theAxis                   << ", "
@@ -2268,6 +2407,7 @@ SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr th
                                                     CORBA::Double             theAngleInRadians,
                                                     CORBA::Long               theNbOfSteps,
                                                     CORBA::Double             theTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
@@ -2280,7 +2420,7 @@ SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr th
                                                true,
                                                SMDSAbs_Face);
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
                 << theObject                 << ", "
                 << theAxis                   << ", "
@@ -2303,45 +2443,40 @@ SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
                                    CORBA::Long               theNbOfSteps,
                                    bool                      theMakeGroups,
                                    const SMDSAbs_ElementType theElementType)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
-  try {
-#ifdef NO_CAS_CATCH
-    OCC_CATCH_SIGNALS;
-#endif
-    TIDSortedElemSet elements, copyElements;
-    arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
+  TIDSortedElemSet elements, copyElements;
+  arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
 
-    const SMESH::PointStruct * P = &theStepVector.PS;
-    gp_Vec stepVec( P->x, P->y, P->z );
+  const SMESH::PointStruct * P = &theStepVector.PS;
+  gp_Vec stepVec( P->x, P->y, P->z );
 
-    TIDSortedElemSet* workElements = & elements;
+  TIDSortedElemSet* workElements = & elements;
 
-    SMDSAbs_ElementType aType = SMDSAbs_Face;
-    if (theElementType == SMDSAbs_Node)
-    {
-      aType = SMDSAbs_Edge;
-    }
-    if ( myIsPreviewMode ) {
-      SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
-      getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
-      workElements = & copyElements;
-      theMakeGroups = false;
-    }
+  SMDSAbs_ElementType aType = SMDSAbs_Face;
+  if (theElementType == SMDSAbs_Node)
+  {
+    aType = SMDSAbs_Edge;
+  }
+  if ( myIsPreviewMode ) {
+    SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
+    getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
+    workElements = & copyElements;
+    theMakeGroups = false;
+  }
 
-    TElemOfElemListMap aHystory;
-    ::SMESH_MeshEditor::PGroupIDs groupIds = 
-        getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
+  TElemOfElemListMap aHystory;
+  ::SMESH_MeshEditor::PGroupIDs groupIds = 
+      getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
 
-    myMesh->GetMeshDS()->Modified();
+  declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
 
-    return theMakeGroups ? getGroups(groupIds.get()) : 0;
+  return theMakeGroups ? getGroups(groupIds.get()) : 0;
 
-  } catch(Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
-  }
+  SMESH_CATCH( SMESH::throwCorbaException );
   return 0;
 }
 
@@ -2353,6 +2488,7 @@ SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
                                         const SMESH::DirStruct &  theStepVector,
                                         CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
   if (!myIsPreviewMode) {
@@ -2369,6 +2505,7 @@ void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElemen
 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
                                           const SMESH::DirStruct &  theStepVector,
                                           CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
   if (!myIsPreviewMode) {
@@ -2385,6 +2522,7 @@ void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElem
 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
                                               const SMESH::DirStruct &  theStepVector,
                                               CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
@@ -2402,6 +2540,7 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObjec
 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
                                                 const SMESH::DirStruct &  theStepVector,
                                                 CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
@@ -2419,6 +2558,7 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObj
 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
                                                 const SMESH::DirStruct &  theStepVector,
                                                 CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
@@ -2436,6 +2576,7 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObj
 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
                                                 const SMESH::DirStruct &  theStepVector,
                                                 CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
@@ -2454,13 +2595,14 @@ SMESH::ListOfGroups*
 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
                                              const SMESH::DirStruct&  theStepVector,
                                              CORBA::Long              theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
   SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
 
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
                 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
   }
@@ -2476,13 +2618,14 @@ SMESH::ListOfGroups*
 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
                                                const SMESH::DirStruct&  theStepVector,
                                                CORBA::Long              theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
   SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
 
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
                 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
   }
@@ -2498,6 +2641,7 @@ SMESH::ListOfGroups*
 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
                                                    const SMESH::DirStruct&   theStepVector,
                                                    CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
@@ -2505,7 +2649,7 @@ SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr the
   SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
 
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
                 << ", " << theStepVector << ", " << theNbOfSteps << " )";
   }
@@ -2521,6 +2665,7 @@ SMESH::ListOfGroups*
 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
                                                      const SMESH::DirStruct&   theStepVector,
                                                      CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
@@ -2528,7 +2673,7 @@ SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr t
   SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
                                                  theNbOfSteps, true, SMDSAbs_Node);
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
                 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
   }
@@ -2544,6 +2689,7 @@ SMESH::ListOfGroups*
 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
                                                      const SMESH::DirStruct&   theStepVector,
                                                      CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()