]> SALOME platform Git repositories - modules/smesh.git/commitdiff
Salome HOME
0023064: [CEA 1471] Create and support quadratic polygons in SMESH
authoreap <eap@opencascade.com>
Wed, 24 Jun 2015 09:17:07 +0000 (12:17 +0300)
committereap <eap@opencascade.com>
Wed, 24 Jun 2015 09:17:07 +0000 (12:17 +0300)
64 files changed:
doc/salome/gui/SMESH/images/image152.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/input/about_meshes.doc
doc/salome/gui/SMESH/input/adding_nodes_and_elements.doc
doc/salome/gui/SMESH/input/adding_quadratic_elements.doc
doc/salome/gui/SMESH/input/quad_from_ma_algo.doc
idl/SMESH_Mesh.idl
idl/SMESH_MeshEditor.idl
resources/CMakeLists.txt
resources/mesh_quad_polygon.png [new file with mode: 0644]
src/Controls/SMESH_Controls.cxx
src/Controls/SMESH_ControlsDef.hxx
src/DriverCGNS/DriverCGNS_Write.cxx
src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx
src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx
src/MEDWrapper/Base/MED_Common.hxx
src/MEDWrapper/Base/MED_Utilities.cxx
src/MEDWrapper/V2_2/MED_V2_2_Wrapper.cxx
src/OBJECT/SMESH_Actor.cxx
src/OBJECT/SMESH_ExtractGeometry.cxx
src/OBJECT/SMESH_Object.cxx
src/OBJECT/SMESH_SVTKActor.cxx
src/SMDS/SMDS_Mesh.cxx
src/SMDS/SMDS_Mesh.hxx
src/SMDS/SMDS_MeshCell.cxx
src/SMDS/SMDS_MeshCell.hxx
src/SMDS/SMDS_MeshInfo.hxx
src/SMDS/SMDS_VolumeTool.cxx
src/SMDS/SMDS_VtkCellIterator.cxx
src/SMDS/SMDS_VtkFace.cxx
src/SMDS/SMDS_VtkFace.hxx
src/SMESH/SMESH_Mesh.cxx
src/SMESH/SMESH_Mesh.hxx
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MeshEditor.hxx
src/SMESH/SMESH_MesherHelper.cxx
src/SMESHClient/SMESH_Client.cxx
src/SMESHDS/SMESHDS_Command.cxx
src/SMESHDS/SMESHDS_Command.hxx
src/SMESHDS/SMESHDS_CommandType.hxx
src/SMESHDS/SMESHDS_Mesh.cxx
src/SMESHDS/SMESHDS_Mesh.hxx
src/SMESHDS/SMESHDS_Script.cxx
src/SMESHDS/SMESHDS_Script.hxx
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx
src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx
src/SMESHGUI/SMESHGUI_DisplayEntitiesDlg.h
src/SMESHGUI/SMESHGUI_FilterDlg.cxx
src/SMESHGUI/SMESHGUI_MeshInfo.cxx
src/SMESHGUI/SMESHGUI_Operations.h
src/SMESHGUI/SMESH_images.ts
src/SMESHGUI/SMESH_msg_en.ts
src/SMESHUtils/SMESH_MAT2d.cxx
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.hxx
src/SMESH_I/SMESH_Mesh_i.cxx
src/SMESH_I/SMESH_Mesh_i.hxx
src/SMESH_SWIG/smeshBuilder.py
src/StdMeshers/StdMeshers_Import_1D.cxx
src/StdMeshers/StdMeshers_Import_1D2D.cxx
src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx
src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx
src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.h

old mode 100755 (executable)
new mode 100644 (file)
index 604a150..d30ae67
Binary files a/doc/salome/gui/SMESH/images/image152.png and b/doc/salome/gui/SMESH/images/image152.png differ
index 14b7a54413234968436d9dc87fb7a4693727c8ca..a67f47d00622fe3d08a5dfda9c9f7c7f66f6ecea 100644 (file)
@@ -97,10 +97,14 @@ generated on (if any). The node generated on the geometrical edge or
 surface in addition stores its position in parametric space of the
 associated geometrical entity.
 
+Mesh entities are identified by integer IDs starting from 1.
+Nodes and elements are countered separately, i.e. there can be a node
+and element with the same ID.
+
 SALOME supports elements of second order, without a central node
-(quadratic triangle, quadrangle, tetrahedron, hexahedron, pentahedron
-and pyramid) and with central nodes (bi-quadratic triangle and
-quadrangle and tri-quadratic hexahedron).<br>
+(quadratic triangle, quadrangle, polygon, tetrahedron, hexahedron,
+pentahedron and pyramid) and with central nodes (bi-quadratic triangle
+and quadrangle and tri-quadratic hexahedron).<br>
 Quadratic mesh can be obtained in two ways:
 - Using a global \ref quadratic_mesh_anchor "Quadratic Mesh"
 hypothesis. (Elements with the central node are not generated in this way).
index e46385b2d204371c8a43f853f0b9d2900dbe3f67..1aa0661ab863cad9d8f4f0c62dc9350153427fb4 100644 (file)
@@ -32,7 +32,7 @@ nodal connectivity of elements in the documentation on MED library or
   <li>From the \b Modification menu choose the \b Add item, the
     following associated sub-menu will appear:</li>
 
-  \image html image146.png
+  \image html image152.png
 
 From this sub-menu select the type of element which you would like to add to your mesh.
 
@@ -47,10 +47,13 @@ existing groups of the corresponding type becomes available. By
 default, no group is selected. In this case, when the user presses
 <b>Apply</b> or <b>Apply & Close</b> button, the warning message box
 informs the user about the necessity to input new group name. The
-combo box lists both \ref standalone_group "standalone groups"
-and \ref group_on_geom "groups on geometry". If the user chooses a
-group on geometry, he is warned and proposed to
-\ref convert_to_standalone "convert this group to standalone".
+combo box lists groups of all the 
+\ref grouping_elements_page "three types": both 
+\ref standalone_group "standalone groups",
+\ref group_on_filter "groups on filter", and 
+\ref group_on_geom "groups on geometry". If the user chooses a
+group on geometry or on filter, he is warned and proposed to
+convert this group to standalone.
 If the user rejects conversion operation, it is cancelled and
 a new node/element is not created!
 
index 6a9527b5d04ac4326f901108010db5c04035004b..2fd906bafbde6abd91d248ca97f7e08ce7be0a9f 100644 (file)
@@ -36,7 +36,7 @@ one of the following:
 
 \image html image152.png
 
-\note All dialogs for quadratic element adding to the mesh
+\note All dialogs for adding quadratic element to the mesh
 provide the possibility to automatically add an element
 to the specified group or to create the group anew using
 <b>Add to group</b> box, that allows choosing an existing group for
@@ -47,23 +47,29 @@ existing groups of the corresponding type becomes available. By
 default, no group is selected. In this case, when the user presses
 <b>Apply</b> or <b>Apply & Close</b> button, the warning message box
 informs the user about the necessity to input a new group name. The
-combo box lists both \ref standalone_group "standalone groups"
-and \ref group_on_geom "groups on geometry". If the user chooses a
-group on geometry, he is warned and proposed to
-\ref convert_to_standalone "convert this group to standalone".
+combo box lists groups of all the 
+\ref grouping_elements_page "three types": both 
+\ref standalone_group "standalone groups",
+\ref group_on_filter "groups on filter", and 
+\ref group_on_geom "groups on geometry". If the user chooses a
+group on geometry or on filter, he is warned and proposed to
+convert this group to standalone.
 If the user rejects conversion operation, it is cancelled and
 a new quadratic element is not created.
 
 
-To create any <b>Quadratic Element</b> specify the nodes which will form your
-element by selecting them in the 3D viewer with pressed Shift
-button. Their numbers will appear in the dialog box as <b>Corner Nodes</b>
-(alternatively you can just input numbers in this field without
-selection). The edges formed by the corner nodes will appear in the
-table. To define the middle nodes for each edge, double-click on the
-respective field and input the number of the node (or pick the node in
-the viewer). For bi-quadratic and tri-quadratic elements, your also
-need to specify central nodes.
+To create any <b>Quadratic Element</b> specify the nodes which will
+form your element by selecting them in the 3D viewer with pressed
+Shift button and click \a Selection button to the right of 
+<b>Corner Nodes</b> label. Their numbers will appear in the dialog box
+as <b>Corner Nodes</b> (alternatively you can just input numbers in
+this field without selection; note that to use this way the mesh
+should be selected before invoking this operation). The edges formed
+by the corner nodes will appear in the table. To define the middle
+nodes for each edge, double-click on the respective field and input
+the number of the node (or pick the node in the viewer). For
+bi-quadratic and tri-quadratic elements, your also need to specify
+central nodes.
 As soon as all needed nodes are specified, a preview of a new
 quadratic element will be displayed in the 3D viewer. Then
 you will be able to click \b Apply or <b>Apply and Close</b> button to
index 976783d40d419e0ed54b91b78b9017dab38a0ea7..80c3f59aaf4fd6eb256865742c0d7d660d1379e3 100644 (file)
@@ -13,7 +13,7 @@ The algorithm assures good shape of quadrangles by constructing Medial
 Axis between sinuous borders of the face and using it to
 discretize the borders.
 
-\image html quad_from_ma_medial_axis.png "Media Axis between two blue sinuous borders"
+\image html quad_from_ma_medial_axis.png "Medial Axis between two blue sinuous borders"
 
 The Medial Axis is used in two ways:
 <ol>
index bb193bcc15e2a26f3eea69c7811851f8417953e3..0805ce2359ca7ecc20624b5ee4b63818459745a4 100644 (file)
@@ -66,6 +66,7 @@ module SMESH
       ADD_QUADEDGE,
       ADD_QUADTRIANGLE,
       ADD_QUADQUADRANGLE,
+      ADD_QUADPOLYGON,
       ADD_QUADTETRAHEDRON,
       ADD_QUADPYRAMID,
       ADD_QUADPENTAHEDRON,
@@ -89,18 +90,18 @@ module SMESH
 
   struct PointStruct { double x;
                        double y;
-                       double z; } ;
+                       double z; };
 
   typedef sequence<PointStruct> nodes_array;
 
-  struct DirStruct   { PointStruct PS ; } ;          // analog to OCCT gp_Vec
+  struct DirStruct   { PointStruct PS; };          // analog to OCCT gp_Vec
 
   struct AxisStruct  { double x;
                        double y;
                        double z;
                        double vx;
                        double vy;
-                       double vz; } ;
+                       double vz; };
   /*!
    * Node location on a shape
    */
@@ -132,7 +133,7 @@ module SMESH
     BALL,
     NB_ELEMENT_TYPES
   };
-  typedef sequence<ElementType> array_of_ElementType ;
+  typedef sequence<ElementType> array_of_ElementType;
 
   /*!
    * Enumeration for element geometry type, like SMDSAbs_GeometryType in SMDSAbs_ElementType.hxx
@@ -775,7 +776,7 @@ module SMESH
     long NbBiQuadQuadrangles()
       raises (SALOME::SALOME_Exception);
 
-    long NbPolygons()
+    long NbPolygons(in ElementOrder order)
       raises (SALOME::SALOME_Exception);
 
     long NbVolumes()
index cc6dc0874ad21c60651b543a717594d087340f4b..3cdbea8bff358e41799280eb1420223d24b39a5d 100644 (file)
@@ -143,6 +143,13 @@ module SMESH
 
     long AddPolygonalFace(in long_array IdsOfNodes) raises (SALOME::SALOME_Exception);
 
+    /*!
+     * Create a quadratic polygonal face
+     *  \param IdsOfNodes - nodes of the polygon; corner nodes follow first
+     *  \return long - ID of a new polygon
+     */
+    long AddQuadPolygonalFace(in long_array IdsOfNodes) raises (SALOME::SALOME_Exception);
+
     /*!
      *  Create volume, either linear and quadratic (this is determed
      *  by number of given nodes).
index 24a83d09a7ca19a0ce5717cc605f44f804cfbb08..c50ed7efd5ec210dda5aa60aa738dc071f51e6dc 100755 (executable)
@@ -170,6 +170,7 @@ SET(SMESH_RESOURCES_FILES
   mesh_quad_edge.png
   mesh_quad_triangle.png
   mesh_quad_quadrangle.png
+  mesh_quad_polygon.png
   mesh_quad_tetrahedron.png
   mesh_quad_pyramid.png
   mesh_quad_pentahedron.png
diff --git a/resources/mesh_quad_polygon.png b/resources/mesh_quad_polygon.png
new file mode 100644 (file)
index 0000000..e9dfa35
Binary files /dev/null and b/resources/mesh_quad_polygon.png differ
index 0b53dd266e85c0ea00ca3ebac208948d822a6660..c70528f279b3217a6b56f15a13edecac5c20f051 100644 (file)
@@ -68,7 +68,6 @@
 
 #include <set>
 #include <limits>
-#include <TopTools_MapOfShape.hxx>
 
 /*
                             AUXILIARY METHODS
@@ -159,29 +158,6 @@ namespace {
     }
     int aResult = std::max ( aResult0, aResult1 );
 
-//     TColStd_MapOfInteger aMap;
-
-//     SMDS_ElemIteratorPtr anIter = anEdge->nodesIterator();
-//     if ( anIter != 0 ) {
-//       while( anIter->more() ) {
-//      const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next();
-//      if ( aNode == 0 )
-//        return 0;
-//      SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator();
-//      while( anElemIter->more() ) {
-//        const SMDS_MeshElement* anElem = anElemIter->next();
-//        if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) {
-//          int anId = anElem->GetID();
-
-//          if ( anIter->more() )              // i.e. first node
-//            aMap.Add( anId );
-//          else if ( aMap.Contains( anId ) )
-//            aResult++;
-//        }
-//      }
-//       }
-//     }
-
     return aResult;
   }
 
@@ -233,7 +209,7 @@ void NumericalFunctor::SetMesh( const SMDS_Mesh* theMesh )
   myMesh = theMesh;
 }
 
-bool NumericalFunctor::GetPoints(const int theId,
+bool NumericalFunctor::GetPoints(const int       theId,
                                  TSequenceOfXYZ& theRes ) const
 {
   theRes.clear();
@@ -257,6 +233,7 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem,
     return false;
 
   theRes.reserve( anElem->NbNodes() );
+  theRes.setElement( anElem );
 
   // Get nodes of the element
   SMDS_ElemIteratorPtr anIter;
@@ -273,7 +250,6 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem,
       break;
     default:
       anIter = anElem->nodesIterator();
-      //return false;
     }
   }
   else {
@@ -281,9 +257,13 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem,
   }
 
   if ( anIter ) {
+    double xyz[3];
     while( anIter->more() ) {
       if ( const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>( anIter->next() ))
-        theRes.push_back( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) );
+      {
+        aNode->GetXYZ( xyz );
+        theRes.push_back( gp_XYZ( xyz[0], xyz[1], xyz[2] ));
+      }
     }
   }
 
@@ -348,7 +328,7 @@ void NumericalFunctor::GetHistogram(int                  nbIntervals,
   std::multiset< double > values;
   if ( elements.empty() )
   {
-    SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator(GetType());
+    SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator( GetType() );
     while ( elemIt->more() )
       values.insert( GetValue( elemIt->next()->GetID() ));
   }
@@ -481,6 +461,27 @@ double MaxElementLength2D::GetValue( const TSequenceOfXYZ& P )
     double D2 = getDistance(P( 3 ),P( 7 ));
     aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2));
   }
+  // Diagonals are undefined for concave polygons
+  // else if ( P.getElementEntity() == SMDSEntity_Quad_Polygon && P.size() > 2 ) // quad polygon
+  // {
+  //   // sides
+  //   aVal = getDistance( P( 1 ), P( P.size() )) + getDistance( P( P.size() ), P( P.size()-1 ));
+  //   for ( size_t i = 1; i < P.size()-1; i += 2 )
+  //   {
+  //     double L = getDistance( P( i ), P( i+1 )) + getDistance( P( i+1 ), P( i+2 ));
+  //     aVal = Max( aVal, L );
+  //   }
+  //   // diagonals
+  //   for ( int i = P.size()-5; i > 0; i -= 2 )
+  //     for ( int j = i + 4; j < P.size() + i - 2; i += 2 )
+  //     {
+  //       double D = getDistance( P( i ), P( j ));
+  //       aVal = Max( aVal, D );
+  //     }
+  // }
+  // { // polygons
+    
+  // }
 
   if( myPrecision >= 0 )
   {
@@ -699,8 +700,9 @@ double MinimumAngle::GetValue( const TSequenceOfXYZ& P )
   aMin = getAngle(P( P.size() ), P( 1 ), P( 2 ));
   aMin = Min(aMin,getAngle(P( P.size()-1 ), P( P.size() ), P( 1 )));
 
-  for (int i=2; i<P.size();i++){
-      double A0 = getAngle( P( i-1 ), P( i ), P( i+1 ) );
+  for ( int i = 2; i < P.size(); i++ )
+  {
+    double A0 = getAngle( P( i-1 ), P( i ), P( i+1 ) );
     aMin = Min(aMin,A0);
   }
 
@@ -1467,11 +1469,14 @@ SMDSAbs_ElementType Skew::GetType() const
 double Area::GetValue( const TSequenceOfXYZ& P )
 {
   double val = 0.0;
-  if ( P.size() > 2 ) {
+  if ( P.size() > 2 )
+  {
     gp_Vec aVec1( P(2) - P(1) );
     gp_Vec aVec2( P(3) - P(1) );
     gp_Vec SumVec = aVec1 ^ aVec2;
-    for (int i=4; i<=P.size(); i++) {
+
+    for (int i=4; i<=P.size(); i++)
+    {
       gp_Vec aVec1( P(i-1) - P(1) );
       gp_Vec aVec2( P(i) - P(1) );
       gp_Vec tmp = aVec1 ^ aVec2;
@@ -1523,7 +1528,7 @@ SMDSAbs_ElementType Length::GetType() const
 //================================================================================
 /*
   Class       : Length2D
-  Description : Functor for calculating length of edge
+  Description : Functor for calculating minimal length of edge
 */
 //================================================================================
 
@@ -1531,63 +1536,59 @@ double Length2D::GetValue( long theElementId )
 {
   TSequenceOfXYZ P;
 
-  //cout<<"Length2D::GetValue"<<endl;
-  if (GetPoints(theElementId,P)){
-    //for(int jj=1; jj<=P.size(); jj++)
-    //  cout<<"jj="<<jj<<" P("<<P(jj).X()<<","<<P(jj).Y()<<","<<P(jj).Z()<<")"<<endl;
-
-    double  aVal;// = GetValue( P );
-    const SMDS_MeshElement* aElem = myMesh->FindElement( theElementId );
-    SMDSAbs_ElementType aType = aElem->GetType();
-
+  if ( GetPoints( theElementId, P ))
+  {
+    double aVal = 0;
     int len = P.size();
+    SMDSAbs_EntityType aType = P.getElementEntity();
 
-    switch (aType){
-    case SMDSAbs_All:
-    case SMDSAbs_Node:
-    case SMDSAbs_Edge:
-      if (len == 2){
+    switch (aType) {
+    case SMDSEntity_Edge:
+      if (len == 2)
         aVal = getDistance( P( 1 ), P( 2 ) );
-        break;
-      }
-      else if (len == 3){ // quadratic edge
+      break;
+    case SMDSEntity_Quad_Edge:
+      if (len == 3) // quadratic edge
         aVal = getDistance(P( 1 ),P( 3 )) + getDistance(P( 3 ),P( 2 ));
-        break;
-      }
-    case SMDSAbs_Face:
+      break;
+    case SMDSEntity_Triangle:
       if (len == 3){ // triangles
         double L1 = getDistance(P( 1 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 1 ));
         aVal = Min(L1,Min(L2,L3));
-        break;
       }
-      else if (len == 4){ // quadrangles
+      break;
+    case SMDSEntity_Quadrangle:
+      if (len == 4){ // quadrangles
         double L1 = getDistance(P( 1 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 4 ));
         double L4 = getDistance(P( 4 ),P( 1 ));
         aVal = Min(Min(L1,L2),Min(L3,L4));
-        break;
       }
-      if (len == 6){ // quadratic triangles
+      break;
+    case SMDSEntity_Quad_Triangle:
+    case SMDSEntity_BiQuad_Triangle:
+      if (len >= 6){ // quadratic triangles
         double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 ));
         double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
         double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 ));
         aVal = Min(L1,Min(L2,L3));
-        //cout<<"L1="<<L1<<" L2="<<L2<<"L3="<<L3<<" aVal="<<aVal<<endl;
-        break;
       }
-      else if (len == 8){ // quadratic quadrangles
+      break;
+    case SMDSEntity_Quad_Quadrangle:
+    case SMDSEntity_BiQuad_Quadrangle:
+      if (len >= 8){ // quadratic quadrangles
         double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 ));
         double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
         double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 ));
         double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 ));
         aVal = Min(Min(L1,L2),Min(L3,L4));
-        break;
       }
-    case SMDSAbs_Volume:
-      if (len == 4){ // tetraidrs
+      break;
+    case SMDSEntity_Tetra:
+      if (len == 4){ // tetrahedra
         double L1 = getDistance(P( 1 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 1 ));
@@ -1595,9 +1596,10 @@ double Length2D::GetValue( long theElementId )
         double L5 = getDistance(P( 2 ),P( 4 ));
         double L6 = getDistance(P( 3 ),P( 4 ));
         aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
-        break;
       }
-      else if (len == 5){ // piramids
+      break;
+    case SMDSEntity_Pyramid:
+      if (len == 5){ // piramids
         double L1 = getDistance(P( 1 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 4 ));
@@ -1609,9 +1611,10 @@ double Length2D::GetValue( long theElementId )
 
         aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
         aVal = Min(aVal,Min(L7,L8));
-        break;
       }
-      else if (len == 6){ // pentaidres
+      break;
+    case SMDSEntity_Penta:
+      if (len == 6) { // pentaidres
         double L1 = getDistance(P( 1 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 1 ));
@@ -1624,9 +1627,10 @@ double Length2D::GetValue( long theElementId )
 
         aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
         aVal = Min(aVal,Min(Min(L7,L8),L9));
-        break;
       }
-      else if (len == 8){ // hexaider
+      break;
+    case SMDSEntity_Hexa:
+      if (len == 8){ // hexahedron
         double L1 = getDistance(P( 1 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 4 ));
@@ -1643,10 +1647,9 @@ double Length2D::GetValue( long theElementId )
         aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
         aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10)));
         aVal = Min(aVal,Min(L11,L12));
-        break;
-
       }
-
+      break;
+    case SMDSEntity_Quad_Tetra:
       if (len == 10){ // quadratic tetraidrs
         double L1 = getDistance(P( 1 ),P( 5 )) + getDistance(P( 5 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 6 )) + getDistance(P( 6 ),P( 3 ));
@@ -1655,9 +1658,10 @@ double Length2D::GetValue( long theElementId )
         double L5 = getDistance(P( 2 ),P( 9 )) + getDistance(P( 9 ),P( 4 ));
         double L6 = getDistance(P( 3 ),P( 10 )) + getDistance(P( 10 ),P( 4 ));
         aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
-        break;
       }
-      else if (len == 13){ // quadratic piramids
+      break;
+    case SMDSEntity_Quad_Pyramid:
+      if (len == 13){ // quadratic piramids
         double L1 = getDistance(P( 1 ),P( 6 )) + getDistance(P( 6 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 4 ));
@@ -1668,9 +1672,10 @@ double Length2D::GetValue( long theElementId )
         double L8 = getDistance(P( 4 ),P( 13 )) + getDistance(P( 13 ),P( 5 ));
         aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
         aVal = Min(aVal,Min(L7,L8));
-        break;
       }
-      else if (len == 15){ // quadratic pentaidres
+      break;
+    case SMDSEntity_Quad_Penta:
+      if (len == 15){ // quadratic pentaidres
         double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 ));
@@ -1682,9 +1687,11 @@ double Length2D::GetValue( long theElementId )
         double L9 = getDistance(P( 3 ),P( 15 )) + getDistance(P( 15 ),P( 6 ));
         aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
         aVal = Min(aVal,Min(Min(L7,L8),L9));
-        break;
       }
-      else if (len == 20){ // quadratic hexaider
+      break;
+    case SMDSEntity_Quad_Hexa:
+    case SMDSEntity_TriQuad_Hexa:
+      if (len >= 20) { // quadratic hexaider
         double L1 = getDistance(P( 1 ),P( 9 )) + getDistance(P( 9 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 10 )) + getDistance(P( 10 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 11 )) + getDistance(P( 11 ),P( 4 ));
@@ -1700,11 +1707,55 @@ double Length2D::GetValue( long theElementId )
         aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
         aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10)));
         aVal = Min(aVal,Min(L11,L12));
-        break;
-
       }
-
-    default: aVal=-1;
+      break;
+    case SMDSEntity_Polygon:
+      if ( len > 1 ) {
+        aVal = getDistance( P(1), P( P.size() ));
+        for ( size_t i = 1; i < P.size(); ++i )
+          aVal = Min( aVal, getDistance( P( i ), P( i+1 )));
+      }
+      break;
+    case SMDSEntity_Quad_Polygon:
+      if ( len > 2 ) {
+        aVal = getDistance( P(1), P( P.size() )) + getDistance( P(P.size()), P( P.size()-1 ));
+        for ( size_t i = 1; i < P.size()-1; i += 2 )
+          aVal = Min( aVal, getDistance( P( i ), P( i+1 )) + getDistance( P( i+1 ), P( i+2 )));
+      }
+      break;
+    case SMDSEntity_Hexagonal_Prism:
+      if (len == 12) { // hexagonal prism
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 4 ));
+        double L4 = getDistance(P( 4 ),P( 5 ));
+        double L5 = getDistance(P( 5 ),P( 6 ));
+        double L6 = getDistance(P( 6 ),P( 1 ));
+
+        double L7 = getDistance(P( 7 ), P( 8 ));
+        double L8 = getDistance(P( 8 ), P( 9 ));
+        double L9 = getDistance(P( 9 ), P( 10 ));
+        double L10= getDistance(P( 10 ),P( 11 ));
+        double L11= getDistance(P( 11 ),P( 12 ));
+        double L12= getDistance(P( 12 ),P( 7 ));
+
+        double L13 = getDistance(P( 1 ),P( 7 ));
+        double L14 = getDistance(P( 2 ),P( 8 ));
+        double L15 = getDistance(P( 3 ),P( 9 ));
+        double L16 = getDistance(P( 4 ),P( 10 ));
+        double L17 = getDistance(P( 5 ),P( 11 ));
+        double L18 = getDistance(P( 6 ),P( 12 ));
+        aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
+        aVal = Min(aVal, Min(Min(Min(L7,L8),Min(L9,L10)),Min(L11,L12)));
+        aVal = Min(aVal, Min(Min(Min(L13,L14),Min(L15,L16)),Min(L17,L18)));
+      }
+      break;
+    case SMDSEntity_Polyhedra:
+    {
+    }
+    break;
+    default:
+      return 0;
     }
 
     if (aVal < 0 ) {
@@ -1743,14 +1794,16 @@ Length2D::Value::Value(double theLength,long thePntId1, long thePntId2):
   }
 }
 
-bool Length2D::Value::operator<(const Length2D::Value& x) const{
+bool Length2D::Value::operator<(const Length2D::Value& x) const
+{
   if(myPntId[0] < x.myPntId[0]) return true;
   if(myPntId[0] == x.myPntId[0])
     if(myPntId[1] < x.myPntId[1]) return true;
   return false;
 }
 
-void Length2D::GetValues(TValues& theValues){
+void Length2D::GetValues(TValues& theValues)
+{
   TValues aValues;
   SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
   for(; anIter->more(); ){
@@ -1947,14 +2000,16 @@ MultiConnection2D::Value::Value(long thePntId1, long thePntId2)
   }
 }
 
-bool MultiConnection2D::Value::operator<(const MultiConnection2D::Value& x) const{
+bool MultiConnection2D::Value::operator<(const MultiConnection2D::Value& x) const
+{
   if(myPntId[0] < x.myPntId[0]) return true;
   if(myPntId[0] == x.myPntId[0])
     if(myPntId[1] < x.myPntId[1]) return true;
   return false;
 }
 
-void MultiConnection2D::GetValues(MValues& theValues){
+void MultiConnection2D::GetValues(MValues& theValues)
+{
   if ( !myMesh ) return;
   SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
   for(; anIter->more(); ){
@@ -2526,7 +2581,7 @@ bool FreeFaces::IsSatisfy( long theId )
 
   int nbNode = aFace->NbNodes();
 
-  // collect volumes check that number of volumss with count equal nbNode not less than 2
+  // collect volumes to check that number of volumes with count equal nbNode not less than 2
   typedef map< SMDS_MeshElement*, int > TMapOfVolume; // map of volume counters
   typedef map< SMDS_MeshElement*, int >::iterator TItrMapOfVolume; // iterator
   TMapOfVolume mapOfVol;
@@ -2624,12 +2679,11 @@ static bool isEqual( const Quantity_Color& theColor1,
 {
   // tolerance to compare colors
   const double tol = 5*1e-3;
-  return ( fabs( theColor1.Red() - theColor2.Red() ) < tol &&
+  return ( fabs( theColor1.Red()   - theColor2.Red() )   < tol &&
            fabs( theColor1.Green() - theColor2.Green() ) < tol &&
-           fabs( theColor1.Blue() - theColor2.Blue() ) < tol );
+           fabs( theColor1.Blue()  - theColor2.Blue() )  < tol );
 }
 
-
 void GroupColor::SetMesh( const SMDS_Mesh* theMesh )
 {
   myIDs.clear();
@@ -4634,20 +4688,20 @@ bool LyingOnGeom::Contains( const SMESHDS_Mesh*     theMeshDS,
   return false;
 }
 
-TSequenceOfXYZ::TSequenceOfXYZ()
+TSequenceOfXYZ::TSequenceOfXYZ(): myElem(0)
 {}
 
-TSequenceOfXYZ::TSequenceOfXYZ(size_type n) : myArray(n)
+TSequenceOfXYZ::TSequenceOfXYZ(size_type n) : myArray(n), myElem(0)
 {}
 
-TSequenceOfXYZ::TSequenceOfXYZ(size_type n, const gp_XYZ& t) : myArray(n,t)
+TSequenceOfXYZ::TSequenceOfXYZ(size_type n, const gp_XYZ& t) : myArray(n,t), myElem(0)
 {}
 
-TSequenceOfXYZ::TSequenceOfXYZ(const TSequenceOfXYZ& theSequenceOfXYZ) : myArray(theSequenceOfXYZ.myArray)
+TSequenceOfXYZ::TSequenceOfXYZ(const TSequenceOfXYZ& theSequenceOfXYZ) : myArray(theSequenceOfXYZ.myArray), myElem(theSequenceOfXYZ.myElem)
 {}
 
 template <class InputIterator>
-TSequenceOfXYZ::TSequenceOfXYZ(InputIterator theBegin, InputIterator theEnd): myArray(theBegin,theEnd)
+TSequenceOfXYZ::TSequenceOfXYZ(InputIterator theBegin, InputIterator theEnd): myArray(theBegin,theEnd), myElem(0)
 {}
 
 TSequenceOfXYZ::~TSequenceOfXYZ()
@@ -4656,6 +4710,7 @@ TSequenceOfXYZ::~TSequenceOfXYZ()
 TSequenceOfXYZ& TSequenceOfXYZ::operator=(const TSequenceOfXYZ& theSequenceOfXYZ)
 {
   myArray = theSequenceOfXYZ.myArray;
+  myElem  = theSequenceOfXYZ.myElem;
   return *this;
 }
 
@@ -4689,6 +4744,11 @@ TSequenceOfXYZ::size_type TSequenceOfXYZ::size() const
   return myArray.size();
 }
 
+SMDSAbs_EntityType TSequenceOfXYZ::getElementEntity() const
+{
+  return myElem ? myElem->GetEntityType() : SMDSEntity_Last;
+}
+
 TMeshModifTracer::TMeshModifTracer():
   myMeshModifTime(0), myMesh(0)
 {
index 41448b1f68710b2e6ed36aaf6bd35633cf88b706..8a2ff7e245becdcf4147fa98c3ce0dc4c98cb65f 100644 (file)
@@ -67,7 +67,7 @@ namespace SMESH{
     public:
       TSequenceOfXYZ();
 
-      TSequenceOfXYZ(size_type n);
+      explicit TSequenceOfXYZ(size_type n);
 
       TSequenceOfXYZ(size_type n, const gp_XYZ& t);
 
@@ -92,8 +92,16 @@ namespace SMESH{
 
       size_type size() const;
 
+
+      void setElement(const SMDS_MeshElement* e) { myElem = e; }
+
+      const SMDS_MeshElement* getElement() const { return myElem; }
+
+      SMDSAbs_EntityType getElementEntity() const;
+
     private:
-      std::vector<gp_XYZ> myArray;
+      std::vector<gp_XYZ>     myArray;
+      const SMDS_MeshElement* myElem;
     };
 
     /*!
index a0834759c97ae129d2fd738a2e230ca46446b710..f83fe915e283cb75693c039c6f63f3717a4f8488 100644 (file)
@@ -147,6 +147,7 @@ namespace
       }
       {
         cgTypes[SMDSEntity_Polygon]         = CGNS_ENUMV( NGON_n );
+        cgTypes[SMDSEntity_Quad_Polygon]    = CGNS_ENUMV( NGON_n );
         cgTypes[SMDSEntity_Polyhedra]       = CGNS_ENUMV( NFACE_n );
         cgTypes[SMDSEntity_Hexagonal_Prism] = CGNS_ENUMV( NFACE_n );
       }
@@ -370,6 +371,21 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
       }
       while ( elem && elem->GetEntityType() == elemType );
 
+    else if ( elemType == SMDSEntity_Quad_Polygon ) // QUADRATIC POLYGONS
+      do // write as linear NGON_n
+      {
+        elemData.push_back( elem->NbNodes() );
+        interlace = & SMDS_MeshCell::interlacedSmdsOrder( SMDSEntity_Quad_Polygon,
+                                                          elem->NbNodes() )[0];
+        for ( int i = 0, nb = elem->NbNodes(); i < nb; ++i )
+          elemData.push_back( cgnsID( elem->GetNode( interlace[i] ), n2cgID ));
+        if ( elem->GetID() != cgID )
+          elem2cgID.insert( elem2cgID.end(), make_pair( elem, cgID ));
+        ++cgID;
+        elem = elemIt->more() ? elemIt->next() : 0;
+      }
+      while ( elem && elem->GetEntityType() == elemType );
+
     else if ( elemType == SMDSEntity_Polyhedra ||
               elemType == SMDSEntity_Hexagonal_Prism) // POLYHEDRA
     {
index 61b6fec1c7e5c9b56ca7f1fa25960acc14fdda25..ba851616c2851908b1dc7c075d991668fad55a39 100644 (file)
 //  Module : SMESH
 
 #include "DriverMED_R_SMESHDS_Mesh.h"
-#include "SMESHDS_Mesh.hxx"
-#include "utilities.h"
 
 #include "DriverMED_Family.h"
-
 #include "SMESHDS_Group.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESH_Comment.hxx"
 
-#include "MED_Factory.hxx"
 #include "MED_CoordUtils.hxx"
+#include "MED_Factory.hxx"
 #include "MED_Utilities.hxx"
 
 #include <NCollection_Map.hxx>
 
-#include <stdlib.h>
+#include "utilities.h"
+
+//#include <stdlib.h>
 
 #ifdef _DEBUG_
 static int MYDEBUG = 1;
@@ -62,579 +63,836 @@ namespace DriverMED
                        const TID2FamilyMap&  myFamilies);
   /*!
    * \brief Ensure aFamily has a required ID
-    * \param aFamily - a family to check
-    * \param anID - an ID aFamily should have
-    * \param myFamilies - a map of the family ID to the Family
-    * \retval bool  - true if successful
+   * \param aFamily - a family to check
+   * \param anID - an ID aFamily should have
+   * \param myFamilies - a map of the family ID to the Family
+   * \retval bool  - true if successful
    */
   bool checkFamilyID(DriverMED_FamilyPtr & aFamily,
                      int                   anID,
                      const TID2FamilyMap&  myFamilies);
-}
 
-void
-DriverMED_R_SMESHDS_Mesh
-::SetMeshName(string theMeshName)
-{
-  myMeshName = theMeshName;
+
+  const SMDS_MeshNode* FindNode(const SMDS_Mesh* theMesh, TInt theId)
+  {
+    const SMDS_MeshNode* aNode = theMesh->FindNode(theId);
+    if(aNode) return aNode;
+    EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
+  }
+
 }
 
-static const SMDS_MeshNode* 
-FindNode(const SMDS_Mesh* theMesh, TInt theId)
+//================================================================================
+/*!
+ * \brief Stores a mesh name
+ */
+//================================================================================
+
+void DriverMED_R_SMESHDS_Mesh::SetMeshName(string theMeshName)
 {
-  const SMDS_MeshNode* aNode = theMesh->FindNode(theId);
-  if(aNode) return aNode;
-  EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
+  myMeshName = theMeshName;
 }
 
+//================================================================================
+/*!
+ * \brief Reads a med file
+ */
+//================================================================================
 
-Driver_Mesh::Status 
-DriverMED_R_SMESHDS_Mesh
-::Perform()
+Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform()
 {
+  using namespace DriverMED;
+
   Status aResult = DRS_FAIL;
   bool isDescConn = false; // Mantis issue 0020483
 #ifndef _DEXCEPT_
-  try{
+  try {
 #endif
     myFamilies.clear();
     if(MYDEBUG) MESSAGE("Perform - myFile : "<<myFile);
     PWrapper aMed = CrWrapper(myFile,true);
 
     aResult = DRS_EMPTY;
-    if(TInt aNbMeshes = aMed->GetNbMeshes()){
-      for(int iMesh = 0; iMesh < aNbMeshes; iMesh++){
-        // Reading the MED mesh
-        //---------------------
-        PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
+    TInt aNbMeshes = aMed->GetNbMeshes();
+    for (int iMesh = 0; iMesh < aNbMeshes; iMesh++)
+    {
+      // Reading the MED mesh
+      //---------------------
+      PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
 
-        string aMeshName;
-        if (myMeshId != -1) {
-          ostringstream aMeshNameStr;
-          aMeshNameStr<<myMeshId;
-          aMeshName = aMeshNameStr.str();
-        } else {
-          aMeshName = myMeshName;
-        }
-        if(MYDEBUG) MESSAGE("Perform - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
-        if(aMeshName != aMeshInfo->GetName()) continue;
-        aResult = DRS_OK;
-
-        // Reading MED families to the temporary structure
-        //------------------------------------------------
-        TErr anErr;
-        TInt aNbFams = aMed->GetNbFamilies(aMeshInfo);
-        if(MYDEBUG) MESSAGE("Read " << aNbFams << " families");
-        for (TInt iFam = 0; iFam < aNbFams; iFam++) {
-          PFamilyInfo aFamilyInfo = aMed->GetPFamilyInfo(aMeshInfo,iFam+1,&anErr);
-          if(anErr >= 0){
-            TInt aFamId = aFamilyInfo->GetId();
-            if(MYDEBUG) MESSAGE("Family " << aFamId << " :");
-            
-            DriverMED_FamilyPtr aFamily (new DriverMED_Family);
-            
-            TInt aNbGrp = aFamilyInfo->GetNbGroup();
-            if(MYDEBUG) MESSAGE("belong to " << aNbGrp << " groups");
-            bool isAttrOk = false;
-            if(aFamilyInfo->GetNbAttr() == aNbGrp)
-              isAttrOk = true;
-            for (TInt iGr = 0; iGr < aNbGrp; iGr++) {
-              string aGroupName = aFamilyInfo->GetGroupName(iGr);
-              if(isAttrOk){
-                TInt anAttrVal = aFamilyInfo->GetAttrVal(iGr);
-                aFamily->SetGroupAttributVal(anAttrVal);
-              }
-              
-              if(MYDEBUG) MESSAGE(aGroupName);
-              aFamily->AddGroupName(aGroupName);
-              
+      string aMeshName;
+      if (myMeshId != -1) aMeshName = SMESH_Comment( myMeshId );
+      else                aMeshName = myMeshName;
+
+      if(MYDEBUG) MESSAGE("Perform - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
+      if ( aMeshName != aMeshInfo->GetName() ) continue;
+      aResult = DRS_OK;
+
+      // Reading MED families to the temporary structure
+      //------------------------------------------------
+      TErr anErr;
+      TInt aNbFams = aMed->GetNbFamilies(aMeshInfo);
+      if(MYDEBUG) MESSAGE("Read " << aNbFams << " families");
+      for (TInt iFam = 0; iFam < aNbFams; iFam++)
+      {
+        PFamilyInfo aFamilyInfo = aMed->GetPFamilyInfo(aMeshInfo,iFam+1,&anErr);
+        if(anErr >= 0){
+          TInt aFamId = aFamilyInfo->GetId();
+          if(MYDEBUG) MESSAGE("Family " << aFamId << " :");
+
+          DriverMED_FamilyPtr aFamily (new DriverMED_Family);
+
+          TInt aNbGrp = aFamilyInfo->GetNbGroup();
+          if(MYDEBUG) MESSAGE("belong to " << aNbGrp << " groups");
+          bool isAttrOk = false;
+          if(aFamilyInfo->GetNbAttr() == aNbGrp)
+            isAttrOk = true;
+          for (TInt iGr = 0; iGr < aNbGrp; iGr++)
+          {
+            string aGroupName = aFamilyInfo->GetGroupName(iGr);
+            if ( isAttrOk ) {
+              TInt anAttrVal = aFamilyInfo->GetAttrVal(iGr);
+              aFamily->SetGroupAttributVal(anAttrVal);
             }
-            aFamily->SetId( aFamId );
-            myFamilies[aFamId] = aFamily;
+            if(MYDEBUG) MESSAGE(aGroupName);
+            aFamily->AddGroupName(aGroupName);
           }
+          aFamily->SetId( aFamId );
+          myFamilies[aFamId] = aFamily;
         }
+      }
 
-        if (aMeshInfo->GetType() == MED::eSTRUCTURE){
-          /*bool aRes = */DriverMED::buildMeshGrille(aMed,aMeshInfo,myMesh,myFamilies);
-          continue;
-        }
+      if (aMeshInfo->GetType() == MED::eSTRUCTURE)
+      {
+        /*bool aRes = */DriverMED::buildMeshGrille(aMed,aMeshInfo,myMesh,myFamilies);
+        continue;
+      }
 
-        // Reading MED nodes to the corresponding SMDS structure
-        //------------------------------------------------------
-        PNodeInfo aNodeInfo = aMed->GetPNodeInfo(aMeshInfo);
-        if (!aNodeInfo) {
-          aResult = DRS_FAIL;
-          continue;
+      // Reading MED nodes to the corresponding SMDS structure
+      //------------------------------------------------------
+      PNodeInfo aNodeInfo = aMed->GetPNodeInfo(aMeshInfo);
+      if (!aNodeInfo) {
+        aResult = DRS_FAIL;
+        continue;
+      }
+      aMeshInfo->myDim=aMeshInfo->mySpaceDim;// ignore meshdim in MEDFile because it can be false
+      PCoordHelper aCoordHelper = GetCoordHelper(aNodeInfo);
+
+      EBooleen anIsNodeNum = aNodeInfo->IsElemNum();
+      TInt aNbElems = aNodeInfo->GetNbElem();
+      if(MYDEBUG) MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbElems<<"; anIsNodeNum = "<<anIsNodeNum);
+      DriverMED_FamilyPtr aFamily;
+      for ( TInt iElem = 0; iElem < aNbElems; iElem++ )
+      {
+        TCCoordSlice aCoordSlice = aNodeInfo->GetCoordSlice(iElem);
+        double aCoords[3] = {0.0, 0.0, 0.0};
+        for(TInt iDim = 0; iDim < 3; iDim++)
+          aCoords[iDim] = aCoordHelper->GetCoord(aCoordSlice,iDim);
+        const SMDS_MeshNode* aNode;
+        if ( anIsNodeNum ) {
+          aNode = myMesh->AddNodeWithID
+            (aCoords[0],aCoords[1],aCoords[2],aNodeInfo->GetElemNum(iElem));
+        }
+        else {
+          aNode = myMesh->AddNodeWithID
+            (aCoords[0],aCoords[1],aCoords[2], iElem+1);
         }
-        aMeshInfo->myDim=aMeshInfo->mySpaceDim;// ignore meshdim in MEDFile because it can be false
-        PCoordHelper aCoordHelper = GetCoordHelper(aNodeInfo);
-
-        EBooleen anIsNodeNum = aNodeInfo->IsElemNum();
-        TInt aNbElems = aNodeInfo->GetNbElem();
-        if(MYDEBUG) MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbElems<<"; anIsNodeNum = "<<anIsNodeNum);
-        DriverMED_FamilyPtr aFamily;
-        for(TInt iElem = 0; iElem < aNbElems; iElem++){
-          TCCoordSlice aCoordSlice = aNodeInfo->GetCoordSlice(iElem);
-          double aCoords[3] = {0.0, 0.0, 0.0};
-          for(TInt iDim = 0; iDim < 3; iDim++)
-            aCoords[iDim] = aCoordHelper->GetCoord(aCoordSlice,iDim);
-          const SMDS_MeshNode* aNode;
-          if(anIsNodeNum) {
-            aNode = myMesh->AddNodeWithID
-              (aCoords[0],aCoords[1],aCoords[2],aNodeInfo->GetElemNum(iElem));
-          } else {
-            aNode = myMesh->AddNodeWithID
-              (aCoords[0],aCoords[1],aCoords[2], iElem+1);
-          }
 
-          // Save reference to this node from its family
-          TInt aFamNum = aNodeInfo->GetFamNum(iElem);
-          if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies ))
-          {
-            aFamily->AddElement(aNode);
-            aFamily->SetType(SMDSAbs_Node);
-          }
+        // Save reference to this node from its family
+        TInt aFamNum = aNodeInfo->GetFamNum(iElem);
+        if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies ))
+        {
+          aFamily->AddElement(aNode);
+          aFamily->SetType(SMDSAbs_Node);
         }
+      }
 
-        // Are there any MED cells in descending connectivity
-        // Mantis issue 0020483
-        //---------------------------------------------------
-        NCollection_Map<EEntiteMaillage> aDescendingEntitiesMap;
-        if (!isDescConn) {
-          MED::TEntityInfo aEntityInfoDesc = aMed->GetEntityInfo(aMeshInfo, eDESC);
-          MED::TEntityInfo::iterator anEntityIterDesc = aEntityInfoDesc.begin();
-          //for (; anEntityIterDesc != aEntityInfoDesc.end() && !isDescConn; anEntityIterDesc++) {
-          for (; anEntityIterDesc != aEntityInfoDesc.end(); anEntityIterDesc++) {
-            const EEntiteMaillage& anEntity = anEntityIterDesc->first;
-            aDescendingEntitiesMap.Add(anEntity);
-            //if (anEntity != eNOEUD) isDescConn = true;
-          }
+      // Are there any MED cells in descending connectivity
+      // Mantis issue 0020483
+      //---------------------------------------------------
+      NCollection_Map<EEntiteMaillage> aDescendingEntitiesMap;
+      if (!isDescConn) {
+        MED::TEntityInfo aEntityInfoDesc = aMed->GetEntityInfo(aMeshInfo, eDESC);
+        MED::TEntityInfo::iterator anEntityIterDesc = aEntityInfoDesc.begin();
+        //for (; anEntityIterDesc != aEntityInfoDesc.end() && !isDescConn; anEntityIterDesc++) {
+        for (; anEntityIterDesc != aEntityInfoDesc.end(); anEntityIterDesc++) {
+          const EEntiteMaillage& anEntity = anEntityIterDesc->first;
+          aDescendingEntitiesMap.Add(anEntity);
+          //if (anEntity != eNOEUD) isDescConn = true;
         }
+      }
 
-        // Reading pre information about all MED cells
-        //--------------------------------------------
-        typedef MED::TVector<int> TNodeIds;
-        bool takeNumbers = true;  // initially we trust the numbers from file
-        MED::TEntityInfo aEntityInfo = aMed->GetEntityInfo(aMeshInfo, eNOD);
-        MED::TEntityInfo::iterator anEntityIter = aEntityInfo.begin();
-        for (; anEntityIter != aEntityInfo.end(); anEntityIter++) {
-          const EEntiteMaillage& anEntity = anEntityIter->first;
-          aDescendingEntitiesMap.Remove(anEntity); // Mantis issue 0020483
-          if (anEntity == eNOEUD) continue;
-          // Reading MED cells to the corresponding SMDS structure
-          //------------------------------------------------------
-          const MED::TGeom2Size& aGeom2Size = anEntityIter->second;
-          MED::TGeom2Size::const_iterator aGeom2SizeIter = aGeom2Size.begin();
-          for(; aGeom2SizeIter != aGeom2Size.end(); aGeom2SizeIter++){
-            const EGeometrieElement& aGeom = aGeom2SizeIter->first;
-
-            if ( anEntity == eSTRUCT_ELEMENT ) // MED_BALL (issue 0021459)
-            {
-              PBallInfo aBallInfo = aMed->GetPBallInfo(aMeshInfo);
-              TInt      aNbBalls  = aBallInfo->GetNbElem();
+      // Reading pre information about all MED cells
+      //--------------------------------------------
+      typedef MED::TVector<int> TNodeIds;
+      bool takeNumbers = true;  // initially we trust the numbers from file
+      MED::TEntityInfo aEntityInfo = aMed->GetEntityInfo(aMeshInfo, eNOD);
+      MED::TEntityInfo::iterator anEntityIter = aEntityInfo.begin();
+
+      for (; anEntityIter != aEntityInfo.end(); anEntityIter++)
+      {
+        const EEntiteMaillage& anEntity = anEntityIter->first;
+        aDescendingEntitiesMap.Remove(anEntity); // Mantis issue 0020483
+        if (anEntity == eNOEUD) continue;
+
+        // Reading MED cells to the corresponding SMDS structure
+        //------------------------------------------------------
+        const MED::TGeom2Size& aGeom2Size = anEntityIter->second;
+        MED::TGeom2Size::const_iterator aGeom2SizeIter = aGeom2Size.begin();
+        for ( ; aGeom2SizeIter != aGeom2Size.end(); aGeom2SizeIter++)
+        {
+          const EGeometrieElement& aGeom = aGeom2SizeIter->first;
+
+          if ( anEntity == eSTRUCT_ELEMENT ) // MED_BALL (issue 0021459)
+          {
+            PBallInfo aBallInfo = aMed->GetPBallInfo(aMeshInfo);
+            TInt      aNbBalls  = aBallInfo->GetNbElem();
 
-              EBooleen anIsElemNum = takeNumbers ? aBallInfo->IsElemNum() : eFAUX;
-              if ( anIsElemNum && aBallInfo->myElemNum->empty() )
-                anIsElemNum = eFAUX;
+            EBooleen anIsElemNum = takeNumbers ? aBallInfo->IsElemNum() : eFAUX;
+            if ( anIsElemNum && aBallInfo->myElemNum->empty() )
+              anIsElemNum = eFAUX;
 
-              // get supporting nodes
-              TNodeIds aNodeIds;
+            // get supporting nodes
+            TNodeIds aNodeIds;
 #ifdef _EDF_NODE_IDS_
-              if(anIsNodeNum) {
-                aNodeIds.resize( aNbBalls );
-                for(TInt iBall = 0; iBall < aNbBalls && anIsNodeNum; iBall++)
-                {
-                  aNodeIds[iBall] = aNodeInfo->GetElemNum( (*aBallInfo->myConn)[ iBall ]-1 );
-                  anIsNodeNum = myMesh->FindNode( aNodeIds[iBall] ) ? eVRAI : eFAUX;
-                }
+            if(anIsNodeNum) {
+              aNodeIds.resize( aNbBalls );
+              for(TInt iBall = 0; iBall < aNbBalls && anIsNodeNum; iBall++)
+              {
+                aNodeIds[iBall] = aNodeInfo->GetElemNum( (*aBallInfo->myConn)[ iBall ]-1 );
+                anIsNodeNum = myMesh->FindNode( aNodeIds[iBall] ) ? eVRAI : eFAUX;
               }
+            }
 #endif
-              if ( !anIsNodeNum )
-                aNodeIds.swap( *(aBallInfo->myConn ));
-
-              // allocate array of diameters
-              vtkIdType maxID = myMesh->MaxElementID() + aNbBalls;
-              if ( anIsElemNum && !aBallInfo->myElemNum->empty() )
-                maxID = *std::max_element( aBallInfo->myElemNum->begin(),
-                                           aBallInfo->myElemNum->end() );
-              myMesh->getGrid()->AllocateDiameters( maxID ); // performance optimization
-
-              // create balls
-              SMDS_MeshElement* anElement;
-              DriverMED_FamilyPtr aFamily;
-              for ( TInt iBall = 0; iBall < aNbBalls; iBall++)
+            if ( !anIsNodeNum )
+              aNodeIds.swap( *(aBallInfo->myConn ));
+
+            // allocate array of diameters
+            vtkIdType maxID = myMesh->MaxElementID() + aNbBalls;
+            if ( anIsElemNum && !aBallInfo->myElemNum->empty() )
+              maxID = *std::max_element( aBallInfo->myElemNum->begin(),
+                                         aBallInfo->myElemNum->end() );
+            myMesh->getGrid()->AllocateDiameters( maxID ); // performance optimization
+
+            // create balls
+            SMDS_MeshElement* anElement;
+            DriverMED_FamilyPtr aFamily;
+            for ( TInt iBall = 0; iBall < aNbBalls; iBall++)
+            {
+              anElement = 0;
+              if ( anIsElemNum ) {
+                if (!(anElement = myMesh->AddBallWithID( aNodeIds[iBall],
+                                                         aBallInfo->myDiameters[iBall],
+                                                         aBallInfo->GetElemNum(iBall))))
+                  anIsElemNum = eFAUX;
+              }
+              if ( !anElement )
+                myMesh->AddBall( myMesh->FindNode( aNodeIds[iBall]),
+                                 aBallInfo->myDiameters[iBall] );
+
+              // Save reference to this element from its family
+              TInt aFamNum = aBallInfo->GetFamNum(iBall);
+              if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies ))
               {
-                anElement = 0;
+                aFamily->AddElement(anElement);
+                aFamily->SetType( SMDSAbs_Ball );
+              }
+            }
+
+            if ( !anIsElemNum &&
+                 ( takeNumbers && aBallInfo->IsElemNum() && !aBallInfo->myElemNum->empty() ))
+              if ( aResult < DRS_WARN_RENUMBER )
+                aResult = DRS_WARN_RENUMBER;
+
+            continue;
+          } // MED_BALL
+
+          switch(aGeom) {
+          // case ePOINT1: ## PAL16410
+          //     break;
+          case ePOLYGONE:
+          case ePOLYGON2:
+          {
+            PPolygoneInfo aPolygoneInfo = aMed->GetPPolygoneInfo(aMeshInfo,anEntity,aGeom);
+            EBooleen anIsElemNum = takeNumbers ? aPolygoneInfo->IsElemNum() : eFAUX;
+
+            typedef SMDS_MeshFace* (SMESHDS_Mesh::* FAddPolyWithID)
+              (const std::vector<int> & nodes_ids, const int ID);
+            typedef SMDS_MeshFace* (SMESHDS_Mesh::* FAddPolygon)
+              (const std::vector<const SMDS_MeshNode*> & nodes);
+
+            FAddPolyWithID addPolyWithID = & SMESHDS_Mesh::AddPolygonalFaceWithID;
+            FAddPolygon       addPolygon = & SMESHDS_Mesh::AddPolygonalFace;
+            if ( aGeom == ePOLYGON2 ) {
+              addPolyWithID = & SMESHDS_Mesh::AddQuadPolygonalFaceWithID;
+              addPolygon    = & SMESHDS_Mesh::AddQuadPolygonalFace;
+            }
+            TNodeIds aNodeIds;
+            vector<const SMDS_MeshNode*> aNodes;
+            const TInt aNbElem = aPolygoneInfo->GetNbElem();
+            for ( TInt iElem = 0; iElem < aNbElem; iElem++ )
+            {
+              MED::TCConnSlice aConnSlice = aPolygoneInfo->GetConnSlice(iElem);
+              TInt aNbConn = aPolygoneInfo->GetNbConn(iElem);
+              aNodeIds.resize( aNbConn );
+#ifdef _EDF_NODE_IDS_
+              if(anIsNodeNum)
+                for(TInt iConn = 0; iConn < aNbConn; iConn++)
+                  aNodeIds[iConn] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
+              else
+                for(TInt iConn = 0; iConn < aNbConn; iConn++)
+                  aNodeIds[iConn] = aConnSlice[iConn];
+#else
+              for(TInt iConn = 0; iConn < aNbConn; iConn++)
+                aNodeIds[iConn] = aConnSlice[iConn];
+#endif
+              bool isRenum = false;
+              SMDS_MeshElement* anElement = NULL;
+              TInt aFamNum = aPolygoneInfo->GetFamNum(iElem);
+#ifndef _DEXCEPT_
+              try {
+#endif
                 if ( anIsElemNum ) {
-                  if (!(anElement = myMesh->AddBallWithID( aNodeIds[iBall],
-                                                           aBallInfo->myDiameters[iBall],
-                                                           aBallInfo->GetElemNum(iBall))))
-                    anIsElemNum = eFAUX;
+                  TInt anElemId = aPolygoneInfo->GetElemNum( iElem );
+                  anElement = (myMesh->*addPolyWithID)( aNodeIds, anElemId );
+                }
+                if ( !anElement ) {
+                  aNodes.resize( aNbConn );
+                  for ( TInt iConn = 0; iConn < aNbConn; iConn++ )
+                    aNodes[iConn] = FindNode( myMesh, aNodeIds[iConn] );
+                  anElement = (myMesh->*addPolygon)( aNodes );
+                  isRenum = anIsElemNum;
+                }
+#ifndef _DEXCEPT_
+              } catch(const std::exception& exc) {
+                aResult = DRS_FAIL;
+              } catch (...) {
+                aResult = DRS_FAIL;
+              }
+#endif
+              if ( !anElement ) {
+                aResult = DRS_WARN_SKIP_ELEM;
+              }
+              else {
+                if ( isRenum ) {
+                  anIsElemNum = eFAUX;
+                  takeNumbers = false;
+                  if(aResult < DRS_WARN_RENUMBER)
+                    aResult = DRS_WARN_RENUMBER;
                 }
-                if ( !anElement )
-                  myMesh->AddBall( myMesh->FindNode( aNodeIds[iBall]),
-                                   aBallInfo->myDiameters[iBall] );
-
-                // Save reference to this element from its family
-                TInt aFamNum = aBallInfo->GetFamNum(iBall);
                 if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies ))
                 {
+                  // Save reference to this element from its family
                   aFamily->AddElement(anElement);
-                  aFamily->SetType( SMDSAbs_Ball );
+                  aFamily->SetType(anElement->GetType());
                 }
               }
+            }
+            break;
+          }
+          case ePOLYEDRE: {
+            PPolyedreInfo aPolyedreInfo = aMed->GetPPolyedreInfo(aMeshInfo,anEntity,aGeom);
+            EBooleen anIsElemNum = takeNumbers ? aPolyedreInfo->IsElemNum() : eFAUX;
 
-              if ( !anIsElemNum &&
-                   ( takeNumbers && aBallInfo->IsElemNum() && !aBallInfo->myElemNum->empty() ))
-                if ( aResult < DRS_WARN_RENUMBER )
-                  aResult = DRS_WARN_RENUMBER;
-
-              continue;
-            } // MED_BALL
-
-            switch(aGeom) {
-//          case ePOINT1: ## PAL16410
-//            break;
-            case ePOLYGONE: {
-              PPolygoneInfo aPolygoneInfo = aMed->GetPPolygoneInfo(aMeshInfo,anEntity,aGeom);
-              EBooleen anIsElemNum = takeNumbers ? aPolygoneInfo->IsElemNum() : eFAUX;
-              
-              TInt aNbElem = aPolygoneInfo->GetNbElem();
-              for(TInt iElem = 0; iElem < aNbElem; iElem++){
-                MED::TCConnSlice aConnSlice = aPolygoneInfo->GetConnSlice(iElem);
-                TInt aNbConn = aPolygoneInfo->GetNbConn(iElem);
-                TNodeIds aNodeIds(aNbConn);
+            TInt aNbElem = aPolyedreInfo->GetNbElem();
+            for(TInt iElem = 0; iElem < aNbElem; iElem++){
+              MED::TCConnSliceArr aConnSliceArr = aPolyedreInfo->GetConnSliceArr(iElem);
+              TInt aNbFaces = aConnSliceArr.size();
+              typedef MED::TVector<int> TQuantities;
+              TQuantities aQuantities(aNbFaces);
+              TInt aNbNodes = aPolyedreInfo->GetNbNodes(iElem);
+              TNodeIds aNodeIds(aNbNodes);
+              for(TInt iFace = 0, iNode = 0; iFace < aNbFaces; iFace++){
+                MED::TCConnSlice aConnSlice = aConnSliceArr[iFace];
+                TInt aNbConn = aConnSlice.size();
+                aQuantities[iFace] = aNbConn;
 #ifdef _EDF_NODE_IDS_
                 if(anIsNodeNum)
                   for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                    aNodeIds[iConn] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
+                  {
+                    aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
+                    iNode++;
+                  }
                 else
                   for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                    aNodeIds[iConn] = aConnSlice[iConn];
+                  {
+                    aNodeIds[iNode++] = aConnSlice[iConn];
+                  }
 #else
                 for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                  aNodeIds[iConn] = aConnSlice[iConn];
-#endif
-                bool isRenum = false;
-                SMDS_MeshElement* anElement = NULL;
-                TInt aFamNum = aPolygoneInfo->GetFamNum(iElem);
+                {
+                  aNodeIds[iNode++] = aConnSlice[iConn];
+                }
+#endif          
+              }
 
+              bool isRenum = false;
+              SMDS_MeshElement* anElement = NULL;
+              TInt aFamNum = aPolyedreInfo->GetFamNum(iElem);
+                
 #ifndef _DEXCEPT_
-                try{
+              try{
 #endif
-                  if(anIsElemNum){
-                    TInt anElemId = aPolygoneInfo->GetElemNum(iElem);
-                    anElement = myMesh->AddPolygonalFaceWithID(aNodeIds,anElemId);
-                  }
-                  if(!anElement){
-                    vector<const SMDS_MeshNode*> aNodes(aNbConn);
-                    for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                      aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]);
-                    anElement = myMesh->AddPolygonalFace(aNodes);
-                    isRenum = anIsElemNum;
-                  }
-#ifndef _DEXCEPT_
-                }catch(const std::exception& exc){
-                  aResult = DRS_FAIL;
-                }catch (...){
-                  aResult = DRS_FAIL;
+                if(anIsElemNum){
+                  TInt anElemId = aPolyedreInfo->GetElemNum(iElem);
+                  anElement = myMesh->AddPolyhedralVolumeWithID(aNodeIds,aQuantities,anElemId);
                 }
-#endif
                 if(!anElement){
-                  aResult = DRS_WARN_SKIP_ELEM;
-                }else{
-                  if(isRenum){
-                    anIsElemNum = eFAUX;
-                    takeNumbers = false;
-                    if(aResult < DRS_WARN_RENUMBER)
-                      aResult = DRS_WARN_RENUMBER;
-                  }
-                  if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies ))
-                  {
-                    // Save reference to this element from its family
-                    aFamily->AddElement(anElement);
-                    aFamily->SetType(anElement->GetType());
-                  }
+                  vector<const SMDS_MeshNode*> aNodes(aNbNodes);
+                  for(TInt iConn = 0; iConn < aNbNodes; iConn++)
+                    aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]);
+                  anElement = myMesh->AddPolyhedralVolume(aNodes,aQuantities);
+                  isRenum = anIsElemNum;
                 }
+#ifndef _DEXCEPT_
+              }catch(const std::exception& exc){
+                aResult = DRS_FAIL;
+              }catch(...){
+                aResult = DRS_FAIL;
               }
-              break;
-            }
-            case ePOLYEDRE: {
-              PPolyedreInfo aPolyedreInfo = aMed->GetPPolyedreInfo(aMeshInfo,anEntity,aGeom);
-              EBooleen anIsElemNum = takeNumbers ? aPolyedreInfo->IsElemNum() : eFAUX;
-
-              TInt aNbElem = aPolyedreInfo->GetNbElem();
-              for(TInt iElem = 0; iElem < aNbElem; iElem++){
-                MED::TCConnSliceArr aConnSliceArr = aPolyedreInfo->GetConnSliceArr(iElem);
-                TInt aNbFaces = aConnSliceArr.size();
-                typedef MED::TVector<int> TQuantities;
-                TQuantities aQuantities(aNbFaces);
-                TInt aNbNodes = aPolyedreInfo->GetNbNodes(iElem);
-                TNodeIds aNodeIds(aNbNodes);
-                for(TInt iFace = 0, iNode = 0; iFace < aNbFaces; iFace++){
-                  MED::TCConnSlice aConnSlice = aConnSliceArr[iFace];
-                  TInt aNbConn = aConnSlice.size();
-                  aQuantities[iFace] = aNbConn;
-#ifdef _EDF_NODE_IDS_
-                  if(anIsNodeNum)
-                    for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                      {
-                      aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
-                      iNode++;
-                      }
-                  else
-                    for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                      {
-                      aNodeIds[iNode++] = aConnSlice[iConn];
-                      }
-#else
-                  for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                    {
-                    aNodeIds[iNode++] = aConnSlice[iConn];
-                    }
 #endif          
+              if(!anElement){
+                aResult = DRS_WARN_SKIP_ELEM;
+              }else{
+                if(isRenum){
+                  anIsElemNum = eFAUX;
+                  takeNumbers = false;
+                  if (aResult < DRS_WARN_RENUMBER)
+                    aResult = DRS_WARN_RENUMBER;
                 }
-
-                bool isRenum = false;
-                SMDS_MeshElement* anElement = NULL;
-                TInt aFamNum = aPolyedreInfo->GetFamNum(iElem);
-                
-#ifndef _DEXCEPT_
-                try{
-#endif
-                  if(anIsElemNum){
-                    TInt anElemId = aPolyedreInfo->GetElemNum(iElem);
-                    anElement = myMesh->AddPolyhedralVolumeWithID(aNodeIds,aQuantities,anElemId);
-                  }
-                  if(!anElement){
-                    vector<const SMDS_MeshNode*> aNodes(aNbNodes);
-                    for(TInt iConn = 0; iConn < aNbNodes; iConn++)
-                      aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]);
-                    anElement = myMesh->AddPolyhedralVolume(aNodes,aQuantities);
-                    isRenum = anIsElemNum;
-                  }
-#ifndef _DEXCEPT_
-                }catch(const std::exception& exc){
-                  aResult = DRS_FAIL;
-                }catch(...){
-                  aResult = DRS_FAIL;
-                }
-#endif          
-                if(!anElement){
-                  aResult = DRS_WARN_SKIP_ELEM;
-                }else{
-                  if(isRenum){
-                    anIsElemNum = eFAUX;
-                    takeNumbers = false;
-                    if (aResult < DRS_WARN_RENUMBER)
-                      aResult = DRS_WARN_RENUMBER;
-                  }
-                  if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies )) {
-                    // Save reference to this element from its family
-                    aFamily->AddElement(anElement);
-                    aFamily->SetType(anElement->GetType());
-                  }
+                if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies )) {
+                  // Save reference to this element from its family
+                  aFamily->AddElement(anElement);
+                  aFamily->SetType(anElement->GetType());
                 }
               }
-              break;
             }
-            default: {
-              PCellInfo aCellInfo = aMed->GetPCellInfo(aMeshInfo,anEntity,aGeom);
-              EBooleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : eFAUX;
-              TInt aNbElems = aCellInfo->GetNbElem();
-              if(MYDEBUG) MESSAGE("Perform - anEntity = "<<anEntity<<"; anIsElemNum = "<<anIsElemNum);
-              if(MYDEBUG) MESSAGE("Perform - aGeom = "<<aGeom<<"; aNbElems = "<<aNbElems);
-
-              TInt aNbNodes = -1;
-              switch(aGeom){
-              case eSEG2:    aNbNodes = 2;  break;
-              case eSEG3:    aNbNodes = 3;  break;
-              case eTRIA3:   aNbNodes = 3;  break;
-              case eTRIA6:   aNbNodes = 6;  break;
-              case eTRIA7:   aNbNodes = 7;  break;
-              case eQUAD4:   aNbNodes = 4;  break;
-              case eQUAD8:   aNbNodes = 8;  break;
-              case eQUAD9:   aNbNodes = 9;  break;
-              case eTETRA4:  aNbNodes = 4;  break;
-              case eTETRA10: aNbNodes = 10; break;
-              case ePYRA5:   aNbNodes = 5;  break;
-              case ePYRA13:  aNbNodes = 13; break;
-              case ePENTA6:  aNbNodes = 6;  break;
-              case ePENTA15: aNbNodes = 15; break;
-              case eHEXA8:   aNbNodes = 8;  break;
-              case eHEXA20:  aNbNodes = 20; break;
-              case eHEXA27:  aNbNodes = 27; break;
-              case eOCTA12:  aNbNodes = 12; break;
-              case ePOINT1:  aNbNodes = 1;  break;
-              default:;
-              }
-              vector<TInt> aNodeIds(aNbNodes);
-              for(int iElem = 0; iElem < aNbElems; iElem++){
-                bool anIsValidConnect = false;
-                TCConnSlice aConnSlice = aCellInfo->GetConnSlice(iElem);
+            break;
+          }
+          default: {
+            PCellInfo aCellInfo = aMed->GetPCellInfo(aMeshInfo,anEntity,aGeom);
+            EBooleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : eFAUX;
+            TInt aNbElems = aCellInfo->GetNbElem();
+            if(MYDEBUG) MESSAGE("Perform - anEntity = "<<anEntity<<"; anIsElemNum = "<<anIsElemNum);
+            if(MYDEBUG) MESSAGE("Perform - aGeom = "<<aGeom<<"; aNbElems = "<<aNbElems);
+
+            TInt aNbNodes = -1;
+            switch(aGeom){
+            case eSEG2:    aNbNodes = 2;  break;
+            case eSEG3:    aNbNodes = 3;  break;
+            case eTRIA3:   aNbNodes = 3;  break;
+            case eTRIA6:   aNbNodes = 6;  break;
+            case eTRIA7:   aNbNodes = 7;  break;
+            case eQUAD4:   aNbNodes = 4;  break;
+            case eQUAD8:   aNbNodes = 8;  break;
+            case eQUAD9:   aNbNodes = 9;  break;
+            case eTETRA4:  aNbNodes = 4;  break;
+            case eTETRA10: aNbNodes = 10; break;
+            case ePYRA5:   aNbNodes = 5;  break;
+            case ePYRA13:  aNbNodes = 13; break;
+            case ePENTA6:  aNbNodes = 6;  break;
+            case ePENTA15: aNbNodes = 15; break;
+            case eHEXA8:   aNbNodes = 8;  break;
+            case eHEXA20:  aNbNodes = 20; break;
+            case eHEXA27:  aNbNodes = 27; break;
+            case eOCTA12:  aNbNodes = 12; break;
+            case ePOINT1:  aNbNodes = 1;  break;
+            default:;
+            }
+            vector<TInt> aNodeIds(aNbNodes);
+            for(int iElem = 0; iElem < aNbElems; iElem++){
+              bool anIsValidConnect = false;
+              TCConnSlice aConnSlice = aCellInfo->GetConnSlice(iElem);
 #ifndef _DEXCEPT_
-                try{
+              try{
 #endif
 #ifdef _EDF_NODE_IDS_
-                  if(anIsNodeNum)
-                    for(int iNode = 0; iNode < aNbNodes; iNode++)
-                      aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iNode] - 1);
-                  else
-                    for(int iNode = 0; iNode < aNbNodes; iNode++)
-                      aNodeIds[iNode] = aConnSlice[iNode];
-#else
+                if(anIsNodeNum)
+                  for(int iNode = 0; iNode < aNbNodes; iNode++)
+                    aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iNode] - 1);
+                else
                   for(int iNode = 0; iNode < aNbNodes; iNode++)
                     aNodeIds[iNode] = aConnSlice[iNode];
+#else
+                for(int iNode = 0; iNode < aNbNodes; iNode++)
+                  aNodeIds[iNode] = aConnSlice[iNode];
 #endif
-                  anIsValidConnect = true;
+                anIsValidConnect = true;
 #ifndef _DEXCEPT_
-                }catch(const std::exception& exc){
-                  INFOS("Following exception was caught:\n\t"<<exc.what());
-                  aResult = DRS_FAIL;
-                }catch(...){
-                  INFOS("Unknown exception was caught !!!");
-                  aResult = DRS_FAIL;
-                }
+              }catch(const std::exception& exc){
+                INFOS("Following exception was caught:\n\t"<<exc.what());
+                aResult = DRS_FAIL;
+              }catch(...){
+                INFOS("Unknown exception was caught !!!");
+                aResult = DRS_FAIL;
+              }
 #endif          
-                if(!anIsValidConnect)
-                  continue;
+              if(!anIsValidConnect)
+                continue;
 
-                bool isRenum = false;
-                const SMDS_MeshElement* anElement = NULL;
-                TInt aFamNum = aCellInfo->GetFamNum(iElem);
+              bool isRenum = false;
+              const SMDS_MeshElement* anElement = NULL;
+              TInt aFamNum = aCellInfo->GetFamNum(iElem);
 #ifndef _DEXCEPT_
-                try{
+              try{
 #endif
-                  //MESSAGE("Try to create element # " << iElem << " with id = "
-                  //        << aCellInfo->GetElemNum(iElem));
-                  switch(aGeom) {
-                  case ePOINT1:
-                    //anElement = FindNode(myMesh,aNodeIds[0]);
-                    if(anIsElemNum)
-                      anElement = myMesh->Add0DElementWithID
-                        (aNodeIds[0], aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->Add0DElement(FindNode(myMesh,aNodeIds[0]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eSEG2:
-                    if(anIsElemNum)
-                      anElement = myMesh->AddEdgeWithID(aNodeIds[0],
-                                                        aNodeIds[1],
+                //MESSAGE("Try to create element # " << iElem << " with id = "
+                //        << aCellInfo->GetElemNum(iElem));
+                switch(aGeom) {
+                case ePOINT1:
+                  //anElement = FindNode(myMesh,aNodeIds[0]);
+                  if(anIsElemNum)
+                    anElement = myMesh->Add0DElementWithID
+                      (aNodeIds[0], aCellInfo->GetElemNum(iElem));
+                  if (!anElement) {
+                    anElement = myMesh->Add0DElement(FindNode(myMesh,aNodeIds[0]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eSEG2:
+                  if(anIsElemNum)
+                    anElement = myMesh->AddEdgeWithID(aNodeIds[0],
+                                                      aNodeIds[1],
+                                                      aCellInfo->GetElemNum(iElem));
+                  if (!anElement) {
+                    anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
+                                                FindNode(myMesh,aNodeIds[1]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eSEG3:
+                  if(anIsElemNum)
+                    anElement = myMesh->AddEdgeWithID(aNodeIds[0],
+                                                      aNodeIds[1],
+                                                      aNodeIds[2],
+                                                      aCellInfo->GetElemNum(iElem));
+                  if (!anElement) {
+                    anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
+                                                FindNode(myMesh,aNodeIds[1]),
+                                                FindNode(myMesh,aNodeIds[2]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eTRIA3:
+                  aNbNodes = 3;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddFaceWithID(aNodeIds[0],
+                                                      aNodeIds[1],
+                                                      aNodeIds[2],
+                                                      aCellInfo->GetElemNum(iElem));
+                  if (!anElement) {
+                    anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                                                FindNode(myMesh,aNodeIds[1]),
+                                                FindNode(myMesh,aNodeIds[2]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eTRIA6:
+                  aNbNodes = 6;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                                                      aNodeIds[2], aNodeIds[3],
+                                                      aNodeIds[4], aNodeIds[5],
+                                                      aCellInfo->GetElemNum(iElem));
+                  if (!anElement) {
+                    anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                                                FindNode(myMesh,aNodeIds[1]),
+                                                FindNode(myMesh,aNodeIds[2]),
+                                                FindNode(myMesh,aNodeIds[3]),
+                                                FindNode(myMesh,aNodeIds[4]),
+                                                FindNode(myMesh,aNodeIds[5]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eTRIA7:
+                  aNbNodes = 7;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                                                      aNodeIds[2], aNodeIds[3],
+                                                      aNodeIds[4], aNodeIds[5], aNodeIds[6],
+                                                      aCellInfo->GetElemNum(iElem));
+                  if (!anElement) {
+                    anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                                                FindNode(myMesh,aNodeIds[1]),
+                                                FindNode(myMesh,aNodeIds[2]),
+                                                FindNode(myMesh,aNodeIds[3]),
+                                                FindNode(myMesh,aNodeIds[4]),
+                                                FindNode(myMesh,aNodeIds[5]),
+                                                FindNode(myMesh,aNodeIds[6]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eQUAD4:
+                  aNbNodes = 4;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                                                      aNodeIds[2], aNodeIds[3],
+                                                      aCellInfo->GetElemNum(iElem));
+                  if (!anElement) {
+                    anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                                                FindNode(myMesh,aNodeIds[1]),
+                                                FindNode(myMesh,aNodeIds[2]),
+                                                FindNode(myMesh,aNodeIds[3]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eQUAD8:
+                  aNbNodes = 8;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                                                      aNodeIds[2], aNodeIds[3],
+                                                      aNodeIds[4], aNodeIds[5],
+                                                      aNodeIds[6], aNodeIds[7],
+                                                      aCellInfo->GetElemNum(iElem));
+                  if (!anElement) {
+                    anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                                                FindNode(myMesh,aNodeIds[1]),
+                                                FindNode(myMesh,aNodeIds[2]),
+                                                FindNode(myMesh,aNodeIds[3]),
+                                                FindNode(myMesh,aNodeIds[4]),
+                                                FindNode(myMesh,aNodeIds[5]),
+                                                FindNode(myMesh,aNodeIds[6]),
+                                                FindNode(myMesh,aNodeIds[7]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eQUAD9:
+                  aNbNodes = 9;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                                                      aNodeIds[2], aNodeIds[3],
+                                                      aNodeIds[4], aNodeIds[5],
+                                                      aNodeIds[6], aNodeIds[7], aNodeIds[8],
+                                                      aCellInfo->GetElemNum(iElem));
+                  if (!anElement) {
+                    anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                                                FindNode(myMesh,aNodeIds[1]),
+                                                FindNode(myMesh,aNodeIds[2]),
+                                                FindNode(myMesh,aNodeIds[3]),
+                                                FindNode(myMesh,aNodeIds[4]),
+                                                FindNode(myMesh,aNodeIds[5]),
+                                                FindNode(myMesh,aNodeIds[6]),
+                                                FindNode(myMesh,aNodeIds[7]),
+                                                FindNode(myMesh,aNodeIds[8]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eTETRA4:
+                  aNbNodes = 4;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
+                                                        aNodeIds[2], aNodeIds[3],
                                                         aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
-                                                  FindNode(myMesh,aNodeIds[1]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eSEG3:
-                    if(anIsElemNum)
-                      anElement = myMesh->AddEdgeWithID(aNodeIds[0],
-                                                        aNodeIds[1],
-                                                        aNodeIds[2],
+                  if (!anElement) {
+                    anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
+                                                  FindNode(myMesh,aNodeIds[1]),
+                                                  FindNode(myMesh,aNodeIds[2]),
+                                                  FindNode(myMesh,aNodeIds[3]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eTETRA10:
+                  aNbNodes = 10;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
+                                                        aNodeIds[2], aNodeIds[3],
+                                                        aNodeIds[4], aNodeIds[5],
+                                                        aNodeIds[6], aNodeIds[7],
+                                                        aNodeIds[8], aNodeIds[9],
                                                         aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
+                  if (!anElement) {
+                    anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
                                                   FindNode(myMesh,aNodeIds[1]),
-                                                  FindNode(myMesh,aNodeIds[2]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eTRIA3:
-                    aNbNodes = 3;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddFaceWithID(aNodeIds[0],
-                                                        aNodeIds[1],
-                                                        aNodeIds[2],
+                                                  FindNode(myMesh,aNodeIds[2]),
+                                                  FindNode(myMesh,aNodeIds[3]),
+                                                  FindNode(myMesh,aNodeIds[4]),
+                                                  FindNode(myMesh,aNodeIds[5]),
+                                                  FindNode(myMesh,aNodeIds[6]),
+                                                  FindNode(myMesh,aNodeIds[7]),
+                                                  FindNode(myMesh,aNodeIds[8]),
+                                                  FindNode(myMesh,aNodeIds[9]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case ePYRA5:
+                  aNbNodes = 5;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
+                                                        aNodeIds[2], aNodeIds[3],
+                                                        aNodeIds[4],
                                                         aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                  if (!anElement) {
+                    anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
                                                   FindNode(myMesh,aNodeIds[1]),
-                                                  FindNode(myMesh,aNodeIds[2]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eTRIA6:
-                    aNbNodes = 6;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                                                  FindNode(myMesh,aNodeIds[2]),
+                                                  FindNode(myMesh,aNodeIds[3]),
+                                                  FindNode(myMesh,aNodeIds[4]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case ePYRA13:
+                  aNbNodes = 13;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
                                                         aNodeIds[2], aNodeIds[3],
                                                         aNodeIds[4], aNodeIds[5],
+                                                        aNodeIds[6], aNodeIds[7],
+                                                        aNodeIds[8], aNodeIds[9],
+                                                        aNodeIds[10], aNodeIds[11],
+                                                        aNodeIds[12],
+                                                        aCellInfo->GetElemNum(iElem));
+                  if (!anElement) {
+                    anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
+                                                  FindNode(myMesh,aNodeIds[1]),
+                                                  FindNode(myMesh,aNodeIds[2]),
+                                                  FindNode(myMesh,aNodeIds[3]),
+                                                  FindNode(myMesh,aNodeIds[4]),
+                                                  FindNode(myMesh,aNodeIds[5]),
+                                                  FindNode(myMesh,aNodeIds[6]),
+                                                  FindNode(myMesh,aNodeIds[7]),
+                                                  FindNode(myMesh,aNodeIds[8]),
+                                                  FindNode(myMesh,aNodeIds[9]),
+                                                  FindNode(myMesh,aNodeIds[10]),
+                                                  FindNode(myMesh,aNodeIds[11]),
+                                                  FindNode(myMesh,aNodeIds[12]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case ePENTA6:
+                  aNbNodes = 6;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddVolumeWithID(aNodeIds[0],
+                                                        aNodeIds[1],
+                                                        aNodeIds[2],
+                                                        aNodeIds[3],
+                                                        aNodeIds[4],
+                                                        aNodeIds[5],
                                                         aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                  if (!anElement) {
+                    anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
                                                   FindNode(myMesh,aNodeIds[1]),
                                                   FindNode(myMesh,aNodeIds[2]),
                                                   FindNode(myMesh,aNodeIds[3]),
                                                   FindNode(myMesh,aNodeIds[4]),
                                                   FindNode(myMesh,aNodeIds[5]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eTRIA7:
-                    aNbNodes = 7;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case ePENTA15:
+                  aNbNodes = 15;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
                                                         aNodeIds[2], aNodeIds[3],
-                                                        aNodeIds[4], aNodeIds[5], aNodeIds[6],
+                                                        aNodeIds[4], aNodeIds[5],
+                                                        aNodeIds[6], aNodeIds[7],
+                                                        aNodeIds[8], aNodeIds[9],
+                                                        aNodeIds[10], aNodeIds[11],
+                                                        aNodeIds[12], aNodeIds[13],
+                                                        aNodeIds[14],
                                                         aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                  if (!anElement) {
+                    anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
                                                   FindNode(myMesh,aNodeIds[1]),
                                                   FindNode(myMesh,aNodeIds[2]),
                                                   FindNode(myMesh,aNodeIds[3]),
                                                   FindNode(myMesh,aNodeIds[4]),
                                                   FindNode(myMesh,aNodeIds[5]),
-                                                  FindNode(myMesh,aNodeIds[6]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eQUAD4:
-                    aNbNodes = 4;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
-                                                        aNodeIds[2], aNodeIds[3],
+                                                  FindNode(myMesh,aNodeIds[6]),
+                                                  FindNode(myMesh,aNodeIds[7]),
+                                                  FindNode(myMesh,aNodeIds[8]),
+                                                  FindNode(myMesh,aNodeIds[9]),
+                                                  FindNode(myMesh,aNodeIds[10]),
+                                                  FindNode(myMesh,aNodeIds[11]),
+                                                  FindNode(myMesh,aNodeIds[12]),
+                                                  FindNode(myMesh,aNodeIds[13]),
+                                                  FindNode(myMesh,aNodeIds[14]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eHEXA8:
+                  aNbNodes = 8;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddVolumeWithID(aNodeIds[0],
+                                                        aNodeIds[1],
+                                                        aNodeIds[2],
+                                                        aNodeIds[3],
+                                                        aNodeIds[4],
+                                                        aNodeIds[5],
+                                                        aNodeIds[6],
+                                                        aNodeIds[7],
                                                         aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                  if (!anElement) {
+                    anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
                                                   FindNode(myMesh,aNodeIds[1]),
                                                   FindNode(myMesh,aNodeIds[2]),
-                                                  FindNode(myMesh,aNodeIds[3]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eQUAD8:
-                    aNbNodes = 8;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                                                  FindNode(myMesh,aNodeIds[3]),
+                                                  FindNode(myMesh,aNodeIds[4]),
+                                                  FindNode(myMesh,aNodeIds[5]),
+                                                  FindNode(myMesh,aNodeIds[6]),
+                                                  FindNode(myMesh,aNodeIds[7]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+
+                case eHEXA20:
+                  aNbNodes = 20;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
                                                         aNodeIds[2], aNodeIds[3],
                                                         aNodeIds[4], aNodeIds[5],
                                                         aNodeIds[6], aNodeIds[7],
+                                                        aNodeIds[8], aNodeIds[9],
+                                                        aNodeIds[10], aNodeIds[11],
+                                                        aNodeIds[12], aNodeIds[13],
+                                                        aNodeIds[14], aNodeIds[15],
+                                                        aNodeIds[16], aNodeIds[17],
+                                                        aNodeIds[18], aNodeIds[19],
                                                         aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                  if (!anElement) {
+                    anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
                                                   FindNode(myMesh,aNodeIds[1]),
                                                   FindNode(myMesh,aNodeIds[2]),
                                                   FindNode(myMesh,aNodeIds[3]),
                                                   FindNode(myMesh,aNodeIds[4]),
                                                   FindNode(myMesh,aNodeIds[5]),
                                                   FindNode(myMesh,aNodeIds[6]),
-                                                  FindNode(myMesh,aNodeIds[7]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eQUAD9:
-                    aNbNodes = 9;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                                                  FindNode(myMesh,aNodeIds[7]),
+                                                  FindNode(myMesh,aNodeIds[8]),
+                                                  FindNode(myMesh,aNodeIds[9]),
+                                                  FindNode(myMesh,aNodeIds[10]),
+                                                  FindNode(myMesh,aNodeIds[11]),
+                                                  FindNode(myMesh,aNodeIds[12]),
+                                                  FindNode(myMesh,aNodeIds[13]),
+                                                  FindNode(myMesh,aNodeIds[14]),
+                                                  FindNode(myMesh,aNodeIds[15]),
+                                                  FindNode(myMesh,aNodeIds[16]),
+                                                  FindNode(myMesh,aNodeIds[17]),
+                                                  FindNode(myMesh,aNodeIds[18]),
+                                                  FindNode(myMesh,aNodeIds[19]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+
+                case eHEXA27:
+                  aNbNodes = 27;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
                                                         aNodeIds[2], aNodeIds[3],
                                                         aNodeIds[4], aNodeIds[5],
-                                                        aNodeIds[6], aNodeIds[7], aNodeIds[8],
+                                                        aNodeIds[6], aNodeIds[7],
+                                                        aNodeIds[8], aNodeIds[9],
+                                                        aNodeIds[10], aNodeIds[11],
+                                                        aNodeIds[12], aNodeIds[13],
+                                                        aNodeIds[14], aNodeIds[15],
+                                                        aNodeIds[16], aNodeIds[17],
+                                                        aNodeIds[18], aNodeIds[19],
+                                                        aNodeIds[20], aNodeIds[21],
+                                                        aNodeIds[22], aNodeIds[23],
+                                                        aNodeIds[24], aNodeIds[25],
+                                                        aNodeIds[26],
                                                         aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                  if (!anElement) {
+                    anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
                                                   FindNode(myMesh,aNodeIds[1]),
                                                   FindNode(myMesh,aNodeIds[2]),
                                                   FindNode(myMesh,aNodeIds[3]),
@@ -642,322 +900,98 @@ DriverMED_R_SMESHDS_Mesh
                                                   FindNode(myMesh,aNodeIds[5]),
                                                   FindNode(myMesh,aNodeIds[6]),
                                                   FindNode(myMesh,aNodeIds[7]),
-                                                  FindNode(myMesh,aNodeIds[8]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eTETRA4:
-                    aNbNodes = 4;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
-                                                          aNodeIds[2], aNodeIds[3],
-                                                          aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
-                                                    FindNode(myMesh,aNodeIds[1]),
-                                                    FindNode(myMesh,aNodeIds[2]),
-                                                    FindNode(myMesh,aNodeIds[3]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eTETRA10:
-                    aNbNodes = 10;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
-                                                          aNodeIds[2], aNodeIds[3],
-                                                          aNodeIds[4], aNodeIds[5],
-                                                          aNodeIds[6], aNodeIds[7],
-                                                          aNodeIds[8], aNodeIds[9],
-                                                          aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
-                                                    FindNode(myMesh,aNodeIds[1]),
-                                                    FindNode(myMesh,aNodeIds[2]),
-                                                    FindNode(myMesh,aNodeIds[3]),
-                                                    FindNode(myMesh,aNodeIds[4]),
-                                                    FindNode(myMesh,aNodeIds[5]),
-                                                    FindNode(myMesh,aNodeIds[6]),
-                                                    FindNode(myMesh,aNodeIds[7]),
-                                                    FindNode(myMesh,aNodeIds[8]),
-                                                    FindNode(myMesh,aNodeIds[9]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case ePYRA5:
-                    aNbNodes = 5;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
-                                                          aNodeIds[2], aNodeIds[3],
-                                                          aNodeIds[4],
-                                                          aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
-                                                    FindNode(myMesh,aNodeIds[1]),
-                                                    FindNode(myMesh,aNodeIds[2]),
-                                                    FindNode(myMesh,aNodeIds[3]),
-                                                    FindNode(myMesh,aNodeIds[4]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case ePYRA13:
-                    aNbNodes = 13;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
-                                                          aNodeIds[2], aNodeIds[3],
-                                                          aNodeIds[4], aNodeIds[5],
-                                                          aNodeIds[6], aNodeIds[7],
-                                                          aNodeIds[8], aNodeIds[9],
-                                                          aNodeIds[10], aNodeIds[11],
-                                                          aNodeIds[12],
-                                                          aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
-                                                    FindNode(myMesh,aNodeIds[1]),
-                                                    FindNode(myMesh,aNodeIds[2]),
-                                                    FindNode(myMesh,aNodeIds[3]),
-                                                    FindNode(myMesh,aNodeIds[4]),
-                                                    FindNode(myMesh,aNodeIds[5]),
-                                                    FindNode(myMesh,aNodeIds[6]),
-                                                    FindNode(myMesh,aNodeIds[7]),
-                                                    FindNode(myMesh,aNodeIds[8]),
-                                                    FindNode(myMesh,aNodeIds[9]),
-                                                    FindNode(myMesh,aNodeIds[10]),
-                                                    FindNode(myMesh,aNodeIds[11]),
-                                                    FindNode(myMesh,aNodeIds[12]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case ePENTA6:
-                    aNbNodes = 6;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddVolumeWithID(aNodeIds[0],
-                                                          aNodeIds[1],
-                                                          aNodeIds[2],
-                                                          aNodeIds[3],
-                                                          aNodeIds[4],
-                                                          aNodeIds[5],
-                                                          aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
-                                                    FindNode(myMesh,aNodeIds[1]),
-                                                    FindNode(myMesh,aNodeIds[2]),
-                                                    FindNode(myMesh,aNodeIds[3]),
-                                                    FindNode(myMesh,aNodeIds[4]),
-                                                    FindNode(myMesh,aNodeIds[5]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case ePENTA15:
-                    aNbNodes = 15;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
-                                                          aNodeIds[2], aNodeIds[3],
-                                                          aNodeIds[4], aNodeIds[5],
-                                                          aNodeIds[6], aNodeIds[7],
-                                                          aNodeIds[8], aNodeIds[9],
-                                                          aNodeIds[10], aNodeIds[11],
-                                                          aNodeIds[12], aNodeIds[13],
-                                                          aNodeIds[14],
-                                                          aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
-                                                    FindNode(myMesh,aNodeIds[1]),
-                                                    FindNode(myMesh,aNodeIds[2]),
-                                                    FindNode(myMesh,aNodeIds[3]),
+                                                  FindNode(myMesh,aNodeIds[8]),
+                                                  FindNode(myMesh,aNodeIds[9]),
+                                                  FindNode(myMesh,aNodeIds[10]),
+                                                  FindNode(myMesh,aNodeIds[11]),
+                                                  FindNode(myMesh,aNodeIds[12]),
+                                                  FindNode(myMesh,aNodeIds[13]),
+                                                  FindNode(myMesh,aNodeIds[14]),
+                                                  FindNode(myMesh,aNodeIds[15]),
+                                                  FindNode(myMesh,aNodeIds[16]),
+                                                  FindNode(myMesh,aNodeIds[17]),
+                                                  FindNode(myMesh,aNodeIds[18]),
+                                                  FindNode(myMesh,aNodeIds[19]),
+                                                  FindNode(myMesh,aNodeIds[20]),
+                                                  FindNode(myMesh,aNodeIds[21]),
+                                                  FindNode(myMesh,aNodeIds[22]),
+                                                  FindNode(myMesh,aNodeIds[23]),
+                                                  FindNode(myMesh,aNodeIds[24]),
+                                                  FindNode(myMesh,aNodeIds[25]),
+                                                  FindNode(myMesh,aNodeIds[26]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+
+                case eOCTA12:
+                  aNbNodes = 12;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
+                                                        aNodeIds[2], aNodeIds[3],
+                                                        aNodeIds[4], aNodeIds[5],
+                                                        aNodeIds[6], aNodeIds[7],
+                                                        aNodeIds[8], aNodeIds[9],
+                                                        aNodeIds[10], aNodeIds[11],
+                                                        aCellInfo->GetElemNum(iElem));
+                  if (!anElement) {
+                    anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
+                                                  FindNode(myMesh,aNodeIds[1]),
+                                                  FindNode(myMesh,aNodeIds[2]),
+                                                  FindNode(myMesh,aNodeIds[3]),
                                                   FindNode(myMesh,aNodeIds[4]),
-                                                    FindNode(myMesh,aNodeIds[5]),
-                                                    FindNode(myMesh,aNodeIds[6]),
-                                                    FindNode(myMesh,aNodeIds[7]),
-                                                    FindNode(myMesh,aNodeIds[8]),
-                                                    FindNode(myMesh,aNodeIds[9]),
-                                                    FindNode(myMesh,aNodeIds[10]),
-                                                    FindNode(myMesh,aNodeIds[11]),
-                                                    FindNode(myMesh,aNodeIds[12]),
-                                                    FindNode(myMesh,aNodeIds[13]),
-                                                    FindNode(myMesh,aNodeIds[14]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eHEXA8:
-                    aNbNodes = 8;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddVolumeWithID(aNodeIds[0],
-                                                          aNodeIds[1],
-                                                          aNodeIds[2],
-                                                          aNodeIds[3],
-                                                          aNodeIds[4],
-                                                          aNodeIds[5],
-                                                          aNodeIds[6],
-                                                          aNodeIds[7],
-                                                          aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
-                                                    FindNode(myMesh,aNodeIds[1]),
-                                                    FindNode(myMesh,aNodeIds[2]),
-                                                    FindNode(myMesh,aNodeIds[3]),
-                                                    FindNode(myMesh,aNodeIds[4]),
-                                                    FindNode(myMesh,aNodeIds[5]),
-                                                    FindNode(myMesh,aNodeIds[6]),
-                                                    FindNode(myMesh,aNodeIds[7]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-
-                  case eHEXA20:
-                    aNbNodes = 20;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
-                                                          aNodeIds[2], aNodeIds[3],
-                                                          aNodeIds[4], aNodeIds[5],
-                                                          aNodeIds[6], aNodeIds[7],
-                                                          aNodeIds[8], aNodeIds[9],
-                                                          aNodeIds[10], aNodeIds[11],
-                                                          aNodeIds[12], aNodeIds[13],
-                                                          aNodeIds[14], aNodeIds[15],
-                                                          aNodeIds[16], aNodeIds[17],
-                                                          aNodeIds[18], aNodeIds[19],
-                                                          aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
-                                                    FindNode(myMesh,aNodeIds[1]),
-                                                    FindNode(myMesh,aNodeIds[2]),
-                                                    FindNode(myMesh,aNodeIds[3]),
-                                                    FindNode(myMesh,aNodeIds[4]),
-                                                    FindNode(myMesh,aNodeIds[5]),
-                                                    FindNode(myMesh,aNodeIds[6]),
-                                                    FindNode(myMesh,aNodeIds[7]),
-                                                    FindNode(myMesh,aNodeIds[8]),
-                                                    FindNode(myMesh,aNodeIds[9]),
-                                                    FindNode(myMesh,aNodeIds[10]),
-                                                    FindNode(myMesh,aNodeIds[11]),
-                                                    FindNode(myMesh,aNodeIds[12]),
-                                                    FindNode(myMesh,aNodeIds[13]),
-                                                    FindNode(myMesh,aNodeIds[14]),
-                                                    FindNode(myMesh,aNodeIds[15]),
-                                                    FindNode(myMesh,aNodeIds[16]),
-                                                    FindNode(myMesh,aNodeIds[17]),
-                                                    FindNode(myMesh,aNodeIds[18]),
-                                                    FindNode(myMesh,aNodeIds[19]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-
-                  case eHEXA27:
-                    aNbNodes = 27;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
-                                                          aNodeIds[2], aNodeIds[3],
-                                                          aNodeIds[4], aNodeIds[5],
-                                                          aNodeIds[6], aNodeIds[7],
-                                                          aNodeIds[8], aNodeIds[9],
-                                                          aNodeIds[10], aNodeIds[11],
-                                                          aNodeIds[12], aNodeIds[13],
-                                                          aNodeIds[14], aNodeIds[15],
-                                                          aNodeIds[16], aNodeIds[17],
-                                                          aNodeIds[18], aNodeIds[19],
-                                                          aNodeIds[20], aNodeIds[21],
-                                                          aNodeIds[22], aNodeIds[23],
-                                                          aNodeIds[24], aNodeIds[25],
-                                                          aNodeIds[26],
-                                                          aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
-                                                    FindNode(myMesh,aNodeIds[1]),
-                                                    FindNode(myMesh,aNodeIds[2]),
-                                                    FindNode(myMesh,aNodeIds[3]),
-                                                    FindNode(myMesh,aNodeIds[4]),
-                                                    FindNode(myMesh,aNodeIds[5]),
-                                                    FindNode(myMesh,aNodeIds[6]),
-                                                    FindNode(myMesh,aNodeIds[7]),
-                                                    FindNode(myMesh,aNodeIds[8]),
-                                                    FindNode(myMesh,aNodeIds[9]),
-                                                    FindNode(myMesh,aNodeIds[10]),
-                                                    FindNode(myMesh,aNodeIds[11]),
-                                                    FindNode(myMesh,aNodeIds[12]),
-                                                    FindNode(myMesh,aNodeIds[13]),
-                                                    FindNode(myMesh,aNodeIds[14]),
-                                                    FindNode(myMesh,aNodeIds[15]),
-                                                    FindNode(myMesh,aNodeIds[16]),
-                                                    FindNode(myMesh,aNodeIds[17]),
-                                                    FindNode(myMesh,aNodeIds[18]),
-                                                    FindNode(myMesh,aNodeIds[19]),
-                                                    FindNode(myMesh,aNodeIds[20]),
-                                                    FindNode(myMesh,aNodeIds[21]),
-                                                    FindNode(myMesh,aNodeIds[22]),
-                                                    FindNode(myMesh,aNodeIds[23]),
-                                                    FindNode(myMesh,aNodeIds[24]),
-                                                    FindNode(myMesh,aNodeIds[25]),
-                                                    FindNode(myMesh,aNodeIds[26]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-
-                  case eOCTA12:
-                    aNbNodes = 12;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
-                                                          aNodeIds[2], aNodeIds[3],
-                                                          aNodeIds[4], aNodeIds[5],
-                                                          aNodeIds[6], aNodeIds[7],
-                                                          aNodeIds[8], aNodeIds[9],
-                                                          aNodeIds[10], aNodeIds[11],
-                                                          aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
-                                                    FindNode(myMesh,aNodeIds[1]),
-                                                    FindNode(myMesh,aNodeIds[2]),
-                                                    FindNode(myMesh,aNodeIds[3]),
-                                                    FindNode(myMesh,aNodeIds[4]),
-                                                    FindNode(myMesh,aNodeIds[5]),
-                                                    FindNode(myMesh,aNodeIds[6]),
-                                                    FindNode(myMesh,aNodeIds[7]),
-                                                    FindNode(myMesh,aNodeIds[8]),
-                                                    FindNode(myMesh,aNodeIds[9]),
-                                                    FindNode(myMesh,aNodeIds[10]),
-                                                    FindNode(myMesh,aNodeIds[11]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-
-                  } // switch(aGeom)
+                                                  FindNode(myMesh,aNodeIds[5]),
+                                                  FindNode(myMesh,aNodeIds[6]),
+                                                  FindNode(myMesh,aNodeIds[7]),
+                                                  FindNode(myMesh,aNodeIds[8]),
+                                                  FindNode(myMesh,aNodeIds[9]),
+                                                  FindNode(myMesh,aNodeIds[10]),
+                                                  FindNode(myMesh,aNodeIds[11]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+
+                } // switch(aGeom)
 
 #ifndef _DEXCEPT_
-                }catch(const std::exception& exc){
-                  INFOS("The following exception was caught:\n\t"<<exc.what());
-                  aResult = DRS_FAIL;
-                }catch(...){
-                  INFOS("Unknown exception was caught !!!");
-                  aResult = DRS_FAIL;
-                }
+              }catch(const std::exception& exc){
+                INFOS("The following exception was caught:\n\t"<<exc.what());
+                aResult = DRS_FAIL;
+              }catch(...){
+                INFOS("Unknown exception was caught !!!");
+                aResult = DRS_FAIL;
+              }
 #endif          
-                if (!anElement) {
-                  aResult = DRS_WARN_SKIP_ELEM;
+              if (!anElement) {
+                aResult = DRS_WARN_SKIP_ELEM;
+              }
+              else {
+                if (isRenum) {
+                  anIsElemNum = eFAUX;
+                  takeNumbers = false;
+                  if (aResult < DRS_WARN_RENUMBER)
+                    aResult = DRS_WARN_RENUMBER;
                 }
-                else {
-                  if (isRenum) {
-                    anIsElemNum = eFAUX;
-                    takeNumbers = false;
-                    if (aResult < DRS_WARN_RENUMBER)
-                      aResult = DRS_WARN_RENUMBER;
-                  }
-                  if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies )) {
-                    // Save reference to this element from its family
-                    myFamilies[aFamNum]->AddElement(anElement);
-                    myFamilies[aFamNum]->SetType(anElement->GetType());
-                  }
+                if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies )) {
+                  // Save reference to this element from its family
+                  myFamilies[aFamNum]->AddElement(anElement);
+                  myFamilies[aFamNum]->SetType(anElement->GetType());
                 }
               }
-            }}
-          }
+            }
+          }}
         }
-        if (aDescendingEntitiesMap.Extent()) isDescConn = true; // Mantis issue 0020483
-      } // for(int iMesh = 0; iMesh < aNbMeshes; iMesh++)
-    } // if aNbMeshes
+      }
+      if (aDescendingEntitiesMap.Extent()) isDescConn = true; // Mantis issue 0020483
+    } // for(int iMesh = 0; iMesh < aNbMeshes; iMesh++)
 #ifndef _DEXCEPT_
-  }catch(const std::exception& exc){
+  }
+  catch(const std::exception& exc)
+  {
     INFOS("The following exception was caught:\n\t"<<exc.what());
     aResult = DRS_FAIL;
-  }catch(...){
+  }
+  catch(...)
+  {
     INFOS("Unknown exception was caught !!!");
     aResult = DRS_FAIL;
   }
index 86a41eb41adec9164b582bc37344f16e2aafb089..fa974f7bda27e8a61326b23f0b3d51b0ed5187e7 100644 (file)
@@ -605,12 +605,21 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
     if ( polyTypesSupported ) {
       aTElemTypeDatas.push_back( TElemTypeData(anEntity,
                                                ePOLYGONE,
-                                               nbElemInfo.NbPolygons(),
+                                               nbElemInfo.NbPolygons( ORDER_LINEAR ),
                                                SMDSAbs_Face));
       // we need one more loop on poly elements to count nb of their nodes
       aTElemTypeDatas.push_back( TElemTypeData(anEntity,
                                                ePOLYGONE,
-                                               nbElemInfo.NbPolygons(),
+                                               nbElemInfo.NbPolygons( ORDER_LINEAR ),
+                                               SMDSAbs_Face));
+      aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+                                               ePOLYGON2,
+                                               nbElemInfo.NbPolygons( ORDER_QUADRATIC ),
+                                               SMDSAbs_Face));
+      // we need one more loop on QUAD poly elements to count nb of their nodes
+      aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+                                               ePOLYGON2,
+                                               nbElemInfo.NbPolygons( ORDER_QUADRATIC ),
                                                SMDSAbs_Face));
     }
 #ifdef _ELEMENTS_BY_DIM_
@@ -706,9 +715,14 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
 
       // Treat POLYGONs
       // ---------------
-      if ( aElemTypeData->_geomType == ePOLYGONE )
+      if ( aElemTypeData->_geomType == ePOLYGONE ||
+           aElemTypeData->_geomType == ePOLYGON2 )
       {
-        elemIterator = myMesh->elementGeomIterator( SMDSGeom_POLYGON );
+        if ( aElemTypeData->_geomType == ePOLYGONE )
+          elemIterator = myMesh->elementEntityIterator( SMDSEntity_Polygon );
+        else
+          elemIterator = myMesh->elementEntityIterator( SMDSEntity_Quad_Polygon );
+
         if ( nbPolygonNodes == 0 ) {
           // Count nb of nodes
           while ( elemIterator->more() ) {
@@ -758,9 +772,10 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
               break;
           }
           myMed->SetPolygoneInfo(aPolygoneInfo);
-        }
 
-      } 
+          nbPolygonNodes = 0; // to treat next polygon type
+        }
+      }
 
       // Treat POLYEDREs
       // ----------------
index 2b393f44c84c10e8168b9348ac1fa4b80529a183..ff12d3821040724b39a49731e2ee292586cefc46 100644 (file)
@@ -71,7 +71,7 @@ namespace MED{
                 eQUAD4=204, eTRIA6=206, eTRIA7=207, eQUAD8=208, eQUAD9=209,eTETRA4=304,
                 ePYRA5=305, ePENTA6=306, eHEXA8=308, eOCTA12=312, eTETRA10=310, 
                 ePYRA13=313, ePENTA15=315, eHEXA20=320, eHEXA27=327,
-                ePOLYGONE=400, ePOLYEDRE=500, eNONE=0, 
+                ePOLYGONE=400, ePOLYGON2=420, ePOLYEDRE=500, eNONE=0, 
                 eBALL=1101 /*no such a type in med.h, it's just a trick*/,
                 eAllGeoType=-1 } EGeometrieElement;
 
index 1475ee8ab7d9d79cf68141f4616269cdfb1d8ec1..d04b0576241e1208954718f71dad4b8ea3a119c9 100644 (file)
@@ -79,6 +79,7 @@ bool InitEntity2GeomSet()
   aGeomFACESet.insert(eQUAD8);
   aGeomFACESet.insert(eQUAD9);
   aGeomFACESet.insert(ePOLYGONE);
+  aGeomFACESet.insert(ePOLYGON2);
 
   TGeomSet& aGeomMAILLESet = Entity2GeomSet[eMAILLE];
   aGeomMAILLESet.insert(ePOINT1);
index b12af78505f9ddac29a298e92982dbd30a058b24..549f1944aa5164e4474040d507b0466a7777222a 100644 (file)
@@ -960,22 +960,19 @@ namespace MED
 
       MED::TMeshInfo& aMeshInfo = *theInfo.myMeshInfo;
 
-      TValueHolder<TString, char> aMeshName(aMeshInfo.myName);
-      TValueHolder<TElemNum, med_int> anIndex(theInfo.myIndex);
-      TInt aNbElem = (TInt)theInfo.myElemNum->size();
-      TValueHolder<TElemNum, med_int> aConn(theInfo.myConn);
-      TValueHolder<EEntiteMaillage, med_entity_type> anEntity(theInfo.myEntity);
+      TValueHolder<TString, char                       > aMeshName(aMeshInfo.myName);
+      TValueHolder<TElemNum, med_int                   > anIndex  (theInfo.myIndex);
+      TValueHolder<TElemNum, med_int                   > aConn    (theInfo.myConn);
+      TValueHolder<EEntiteMaillage, med_entity_type    > anEntity (theInfo.myEntity);
+      TValueHolder<EGeometrieElement, med_geometry_type> aGeom    (theInfo.myGeom);
       TValueHolder<EConnectivite, med_connectivity_mode> aConnMode(theInfo.myConnMode);
+      TInt aNbElem = (TInt)theInfo.myElemNum->size();
 
       TErr aRet;
-      aRet = MEDmeshPolygonRd(myFile->Id(),
-                              &aMeshName,
-                              MED_NO_DT,
-                              MED_NO_IT,
-                              anEntity,
-                              aConnMode,
-                              &anIndex,
-                              &aConn);
+      aRet = MEDmeshPolygon2Rd(myFile->Id(), &aMeshName,
+                               MED_NO_DT, MED_NO_IT,
+                               anEntity, aGeom,
+                               aConnMode, &anIndex, &aConn);
 
       if(theErr) 
         *theErr = aRet;
@@ -983,18 +980,18 @@ namespace MED
         EXCEPTION(std::runtime_error,"GetPolygoneInfo - MEDmeshPolygonRd(...)");
 
       if(theInfo.myIsElemNames){
-        GetNames(theInfo,aNbElem,theInfo.myEntity,ePOLYGONE,&aRet);
+        GetNames(theInfo,aNbElem,theInfo.myEntity,theInfo.myGeom,&aRet);
         if(theErr) 
           *theErr = aRet;
       }
 
       if(theInfo.myIsElemNum){
-        GetNumeration(theInfo,aNbElem,theInfo.myEntity,ePOLYGONE,&aRet);
+        GetNumeration(theInfo,aNbElem,theInfo.myEntity,theInfo.myGeom,&aRet);
         if(theErr) 
           *theErr = aRet;
       }
 
-      GetFamilies(theInfo,aNbElem,theInfo.myEntity,ePOLYGONE,&aRet);
+      GetFamilies(theInfo,aNbElem,theInfo.myEntity,theInfo.myGeom,&aRet);
       if(theErr) 
         *theErr = aRet;
     }
@@ -1023,37 +1020,32 @@ namespace MED
       MED::TPolygoneInfo& anInfo = const_cast<MED::TPolygoneInfo&>(theInfo);
       MED::TMeshInfo& aMeshInfo = *anInfo.myMeshInfo;
 
-      TValueHolder<TString, char> aMeshName(aMeshInfo.myName);
-      TValueHolder<TElemNum, med_int> anIndex(anInfo.myIndex);
-      TValueHolder<TElemNum, med_int> aConn(anInfo.myConn);
-      TValueHolder<EEntiteMaillage, med_entity_type> anEntity(anInfo.myEntity);
+      TValueHolder<TString, char                       > aMeshName(aMeshInfo.myName);
+      TValueHolder<TElemNum, med_int                   > anIndex  (anInfo.myIndex);
+      TValueHolder<TElemNum, med_int                   > aConn    (anInfo.myConn);
+      TValueHolder<EEntiteMaillage, med_entity_type    > anEntity (anInfo.myEntity);
+      TValueHolder<EGeometrieElement, med_geometry_type> aGeom    (anInfo.myGeom);
       TValueHolder<EConnectivite, med_connectivity_mode> aConnMode(anInfo.myConnMode);
 
-      TErr aRet = MEDmeshPolygonWr(myFile->Id(),
-                                   &aMeshName,
-                                   MED_NO_DT,
-                                   MED_NO_IT,
-                                   MED_UNDEF_DT,
-                                   anEntity,
-                                   aConnMode,
-                                   anInfo.myNbElem + 1,
-                                   &anIndex,
-                                   &aConn);
-      
-      if(theErr) 
+      TErr aRet = MEDmeshPolygon2Wr(myFile->Id(), &aMeshName,
+                                    MED_NO_DT, MED_NO_IT, MED_UNDEF_DT,
+                                    anEntity, aGeom,
+                                    aConnMode, anInfo.myNbElem + 1,
+                                    &anIndex, &aConn);
+      if(theErr)
         *theErr = aRet;
       else if(aRet < 0)
         EXCEPTION(std::runtime_error,"SetPolygoneInfo - MEDmeshPolygonWr(...)");
       
-      SetNames(anInfo,theInfo.myEntity,ePOLYGONE,&aRet);
+      SetNames(anInfo,theInfo.myEntity,anInfo.myGeom,&aRet);
       if(theErr) 
         *theErr = aRet;
       
-      SetNumeration(anInfo,theInfo.myEntity,ePOLYGONE,&aRet);
+      SetNumeration(anInfo,theInfo.myEntity,anInfo.myGeom,&aRet);
       if(theErr) 
         *theErr = aRet;
       
-      SetFamilies(anInfo,theInfo.myEntity,ePOLYGONE,&aRet);
+      SetFamilies(anInfo,theInfo.myEntity,anInfo.myGeom,&aRet);
       if(theErr) 
         *theErr = aRet;
     }
@@ -1094,7 +1086,7 @@ namespace MED
                              MED_NO_DT,
                              MED_NO_IT,
                              med_entity_type(theEntity),
-                             MED_POLYGON,
+                             med_geometry_type(theGeom),
                              MED_CONNECTIVITY,
                              med_connectivity_mode(theConnMode),
                              &chgt,
@@ -1430,16 +1422,14 @@ namespace MED
       }
       return anInfo;
     }
-    
-    
+
+
     //-----------------------------------------------------------------
-    TInt
-    TVWrapper
-    ::GetNbCells(const MED::TMeshInfo& theMeshInfo, 
-                 EEntiteMaillage theEntity, 
-                 EGeometrieElement theGeom, 
-                 EConnectivite theConnMode,
-                 TErr* theErr)
+    TInt TVWrapper::GetNbCells(const MED::TMeshInfo& theMeshInfo,
+                               EEntiteMaillage theEntity,
+                               EGeometrieElement theGeom,
+                               EConnectivite theConnMode,
+                               TErr* theErr)
     {
       TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
 
@@ -1449,48 +1439,50 @@ namespace MED
       MED::TMeshInfo& aMeshInfo = const_cast<MED::TMeshInfo&>(theMeshInfo);
       TValueHolder<TString, char> aMeshName(aMeshInfo.myName);
       med_bool chgt,trsf;
-      if(theGeom!=MED::ePOLYGONE && theGeom!=MED::ePOLYEDRE && theGeom != MED::eBALL)
+      switch ( theGeom )
       {
-        return MEDmeshnEntity(myFile->Id(),
-                              &aMeshName,
-                              MED_NO_DT,
-                              MED_NO_IT,
-                              med_entity_type(theEntity),
-                              med_geometry_type(theGeom),
-                              MED_CONNECTIVITY,
-                              med_connectivity_mode(theConnMode),
-                              &chgt,
-                              &trsf);
-      }
-      else if(theGeom==MED::ePOLYGONE)
+      case MED::ePOLYGONE:
+      case MED::ePOLYGON2:
       {
-        return MEDmeshnEntity(myFile->Id(),&aMeshName,MED_NO_DT,MED_NO_IT,med_entity_type(theEntity),
-                              MED_POLYGON,MED_INDEX_NODE,med_connectivity_mode(theConnMode),&chgt,&trsf)-1;
+        return MEDmeshnEntity(myFile->Id(),&aMeshName,
+                              MED_NO_DT,MED_NO_IT,
+                              med_entity_type(theEntity),med_geometry_type(theGeom),
+                              MED_INDEX_NODE,med_connectivity_mode(theConnMode),
+                              &chgt,&trsf)-1;
       }
-      else if ( theGeom==MED::ePOLYEDRE )
+      case MED::ePOLYEDRE:
       {
-        return MEDmeshnEntity(myFile->Id(),&aMeshName,MED_NO_DT,MED_NO_IT,med_entity_type(theEntity),
-                              MED_POLYHEDRON,MED_INDEX_FACE,med_connectivity_mode(theConnMode),&chgt,&trsf)-1;
+        return MEDmeshnEntity(myFile->Id(),&aMeshName,
+                              MED_NO_DT,MED_NO_IT,
+                              med_entity_type(theEntity),MED_POLYHEDRON,
+                              MED_INDEX_FACE,med_connectivity_mode(theConnMode),
+                              &chgt,&trsf)-1;
       }
-      else if ( theGeom==MED::eBALL )
+      case MED::eBALL:
       {
         return GetNbBalls( theMeshInfo );
       }
+      default:
+      {
+        return MEDmeshnEntity(myFile->Id(),&aMeshName,
+                              MED_NO_DT,MED_NO_IT,
+                              med_entity_type(theEntity),med_geometry_type(theGeom),
+                              MED_CONNECTIVITY,med_connectivity_mode(theConnMode),
+                              &chgt,&trsf);
+      }
+      }
       return 0;
     }
 
 
     //----------------------------------------------------------------------------
-    void
-    TVWrapper
-    ::GetCellInfo(MED::TCellInfo& theInfo,
-                  TErr* theErr)
+    void TVWrapper::GetCellInfo(MED::TCellInfo& theInfo, TErr* theErr)
     {
       TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
 
       if(theErr && *theErr < 0)
         return;
-      
+
       MED::TMeshInfo& aMeshInfo = *theInfo.myMeshInfo;
 
       TValueHolder<TString, char>                        aMeshName    (aMeshInfo.myName);
index 65f9e87877ed7722a2c0f4cfd1579cb8f4d0134e..1c9af415d5b13b7b52435b590c1e1d92b1f71808 100644 (file)
@@ -222,10 +222,11 @@ SMESH_ActorDef::SMESH_ActorDef()
   aFilter = my2DActor->GetExtractUnstructuredGrid();
   aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
   aFilter->RegisterCellsWithType(VTK_TRIANGLE);
-  aFilter->RegisterCellsWithType(VTK_POLYGON);
   aFilter->RegisterCellsWithType(VTK_QUAD);
+  aFilter->RegisterCellsWithType(VTK_POLYGON);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON);
   aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
   aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE);
 
@@ -245,10 +246,11 @@ SMESH_ActorDef::SMESH_ActorDef()
   my2DExtActor->SetRepresentation(SMESH_DeviceActor::eInsideframe);
   aFilter = my2DExtActor->GetExtractUnstructuredGrid();
   aFilter->RegisterCellsWithType(VTK_TRIANGLE);
-  aFilter->RegisterCellsWithType(VTK_POLYGON);
   aFilter->RegisterCellsWithType(VTK_QUAD);
+  aFilter->RegisterCellsWithType(VTK_POLYGON);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON);
   aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
   aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE);
 
@@ -275,10 +277,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
   aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
-//#ifdef VTK_HAVE_POLYHEDRON
-  MESSAGE("RegisterCellsWithType(VTK_POLYHEDRON)");
   aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
-//#endif
 
   my3DExtProp = vtkProperty::New();
   my3DExtProp->DeepCopy(myNormalVProp);
@@ -1565,18 +1564,20 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode)
   if (myEntityMode & eFaces) {
     if (MYDEBUG) MESSAGE("FACES");
     aFilter->RegisterCellsWithType(VTK_TRIANGLE);
-    aFilter->RegisterCellsWithType(VTK_POLYGON);
     aFilter->RegisterCellsWithType(VTK_QUAD);
+    aFilter->RegisterCellsWithType(VTK_POLYGON);
     aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
     aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
+    aFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON);
     aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
     aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE);
 
     aHightFilter->RegisterCellsWithType(VTK_TRIANGLE);
-    aHightFilter->RegisterCellsWithType(VTK_POLYGON);
     aHightFilter->RegisterCellsWithType(VTK_QUAD);
+    aHightFilter->RegisterCellsWithType(VTK_POLYGON);
     aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
     aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
+    aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON);
     aHightFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
     aHightFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE);
   }
@@ -1595,9 +1596,7 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode)
     aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
     aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
     aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
-//#ifdef VTK_HAVE_POLYHEDRON
     aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
-//#endif
 
     aHightFilter->RegisterCellsWithType(VTK_TETRA);
     aHightFilter->RegisterCellsWithType(VTK_VOXEL);
@@ -1611,9 +1610,7 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode)
     aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
     aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
     aHightFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
-//#ifdef VTK_HAVE_POLYHEDRON
     aHightFilter->RegisterCellsWithType(VTK_POLYHEDRON);
-//#endif
   }
   aFilter->Update();
   if (MYDEBUG) MESSAGE(aFilter->GetOutput()->GetNumberOfCells());
index 3a9b380a3d117bae07491ded69269471ee17c6e5..b3ff7d74bd630b151851c9b49d1328db5e190d08 100644 (file)
@@ -55,35 +55,36 @@ SMESH_ExtractGeometry::SMESH_ExtractGeometry()
 {}
 
 
-SMESH_ExtractGeometry::~SMESH_ExtractGeometry(){}
-
+SMESH_ExtractGeometry::~SMESH_ExtractGeometry()
+{}
 
-vtkIdType SMESH_ExtractGeometry::GetElemObjId(int theVtkID){
+vtkIdType SMESH_ExtractGeometry::GetElemObjId(int theVtkID)
+{
   if( theVtkID < 0 || theVtkID >= myElemVTK2ObjIds.size()) return -1;
   return myElemVTK2ObjIds[theVtkID];
 }
 
 
-vtkIdType SMESH_ExtractGeometry::GetNodeObjId(int theVtkID){
+vtkIdType SMESH_ExtractGeometry::GetNodeObjId(int theVtkID)
+{
   if ( theVtkID < 0 || theVtkID >= myNodeVTK2ObjIds.size()) return -1;
   return myNodeVTK2ObjIds[theVtkID];
 }
 
 
-int SMESH_ExtractGeometry::RequestData(
-  vtkInformation *vtkNotUsed(request),
-  vtkInformationVector **inputVector,
-  vtkInformationVector *outputVector)
+int SMESH_ExtractGeometry::RequestData(vtkInformation *vtkNotUsed(request),
+                                       vtkInformationVector **inputVector,
+                                       vtkInformationVector *outputVector)
 {
   // get the info objects
   vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
   vtkInformation *outInfo = outputVector->GetInformationObject(0);
 
   // get the input and ouptut
-  vtkDataSet *input = vtkDataSet::SafeDownCast(
-    inInfo->Get(vtkDataObject::DATA_OBJECT()));
-  vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
-    outInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkDataSet *input =
+    vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkUnstructuredGrid *output =
+    vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
 
   vtkIdType ptId, numPts, numCells, i, cellId, newCellId, newId, *pointMap;
   vtkIdList *cellPts;
@@ -100,35 +101,35 @@ int SMESH_ExtractGeometry::RequestData(
   int npts;
   numCells = input->GetNumberOfCells();
   numPts = input->GetNumberOfPoints();
-  
+
   vtkDebugMacro(<< "Extracting geometry");
 
   if ( ! this->ImplicitFunction )
-    {
+  {
     vtkErrorMacro(<<"No implicit function specified");
     return 0;
-    }
+  }
 
   newCellPts = vtkIdList::New();
   newCellPts->Allocate(VTK_CELL_SIZE);
 
   if ( this->ExtractInside )
-    {
+  {
     multiplier = 1.0;
-    }
-  else 
-    {
+  }
+  else
+  {
     multiplier = -1.0;
-    }
+  }
 
   // Loop over all points determining whether they are inside the
   // implicit function. Copy the points and point data if they are.
   //
   pointMap = new vtkIdType[numPts]; // maps old point ids into new
   for (i=0; i < numPts; i++)
-    {
+  {
     pointMap[i] = -1;
-    }
+  }
 
   output->Allocate(numCells/4); //allocate storage for geometry/topology
   newPts = vtkPoints::New();
@@ -136,7 +137,7 @@ int SMESH_ExtractGeometry::RequestData(
   outputPD->CopyAllocate(pd);
   outputCD->CopyAllocate(cd);
   vtkFloatArray *newScalars = NULL;
-  
+
   if(myStoreMapping){
     myElemVTK2ObjIds.clear();
     myElemVTK2ObjIds.reserve(numCells);
@@ -145,110 +146,110 @@ int SMESH_ExtractGeometry::RequestData(
   }
 
   if ( ! this->ExtractBoundaryCells )
-    {
+  {
     for ( ptId=0; ptId < numPts; ptId++ )
-      {
+    {
       x = input->GetPoint(ptId);
       if ( (this->ImplicitFunction->FunctionValue(x)*multiplier) < 0.0 )
-        {
+      {
         newId = newPts->InsertNextPoint(x);
         pointMap[ptId] = newId;
         myNodeVTK2ObjIds.push_back(ptId);
         outputPD->CopyData(pd,ptId,newId);
-        }
       }
     }
+  }
   else
-    {
+  {
     // To extract boundary cells, we have to create supplemental information
     if ( this->ExtractBoundaryCells )
-      {
+    {
       double val;
       newScalars = vtkFloatArray::New();
       newScalars->SetNumberOfValues(numPts);
 
       for (ptId=0; ptId < numPts; ptId++ )
-        {
+      {
         x = input->GetPoint(ptId);
         val = this->ImplicitFunction->FunctionValue(x) * multiplier;
         newScalars->SetValue(ptId, val);
         if ( val < 0.0 )
-          {
+        {
           newId = newPts->InsertNextPoint(x);
           pointMap[ptId] = newId;
           myNodeVTK2ObjIds.push_back(ptId);
           outputPD->CopyData(pd,ptId,newId);
-          }
         }
       }
     }
+  }
 
   // Now loop over all cells to see whether they are inside implicit
   // function (or on boundary if ExtractBoundaryCells is on).
   //
   for (cellId=0; cellId < numCells; cellId++)
-    {
+  {
     cell = input->GetCell(cellId);
     cellPts = cell->GetPointIds();
     numCellPts = cell->GetNumberOfPoints();
 
     newCellPts->Reset();
     if ( ! this->ExtractBoundaryCells ) //requires less work
-      {
+    {
       for ( npts=0, i=0; i < numCellPts; i++, npts++)
-        {
+      {
         ptId = cellPts->GetId(i);
         if ( pointMap[ptId] < 0 )
-          {
+        {
           break; //this cell won't be inserted
-          }
+        }
         else
-          {
+        {
           newCellPts->InsertId(i,pointMap[ptId]);
-          }
         }
-      } //if don't want to extract boundary cells
-    
+      }
+    } //if don't want to extract boundary cells
+
     else //want boundary cells
-      {
+    {
       for ( npts=0, i=0; i < numCellPts; i++ )
-        {
+      {
         ptId = cellPts->GetId(i);
         if ( newScalars->GetValue(ptId) <= 0.0 )
-          {
+        {
           npts++;
-          }
         }
+      }
       if ( npts > 0 )
-        {
+      {
         for ( i=0; i < numCellPts; i++ )
-          {
+        {
           ptId = cellPts->GetId(i);
           if ( pointMap[ptId] < 0 )
-            {
+          {
             x = input->GetPoint(ptId);
             newId = newPts->InsertNextPoint(x);
             pointMap[ptId] = newId;
             myNodeVTK2ObjIds.push_back(ptId);
             outputPD->CopyData(pd,ptId,newId);
-            }
-          newCellPts->InsertId(i,pointMap[ptId]);
           }
-        }//a boundary or interior cell
-      }//if mapping boundary cells
-      
-    if ( npts >= numCellPts || (this->ExtractBoundaryCells && npts > 0) )
-      {
-        if(cell->GetCellType() == VTK_POLYHEDRON) {
-          newCellPts->Reset();
-          vtkUnstructuredGrid::SafeDownCast(input)->GetFaceStream( cellId ,newCellPts );        
-          vtkUnstructuredGrid::ConvertFaceStreamPointIds(newCellPts, pointMap);
+          newCellPts->InsertId(i,pointMap[ptId]);
         }
-          newCellId = output->InsertNextCell(cell->GetCellType(),newCellPts);
-          myElemVTK2ObjIds.push_back(cellId);
-          outputCD->CopyData(cd,cellId,newCellId);
+      }//a boundary or interior cell
+    }//if mapping boundary cells
+
+    if ( npts >= numCellPts || (this->ExtractBoundaryCells && npts > 0) )
+    {
+      if(cell->GetCellType() == VTK_POLYHEDRON) {
+        newCellPts->Reset();
+        vtkUnstructuredGrid::SafeDownCast(input)->GetFaceStream( cellId ,newCellPts );
+        vtkUnstructuredGrid::ConvertFaceStreamPointIds(newCellPts, pointMap);
       }
-    }//for all cells
+      newCellId = output->InsertNextCell(cell->GetCellType(),newCellPts);
+      myElemVTK2ObjIds.push_back(cellId);
+      outputCD->CopyData(cd,cellId,newCellId);
+    }
+  }//for all cells
 
   // Update ourselves and release memory
   //
@@ -256,11 +257,11 @@ int SMESH_ExtractGeometry::RequestData(
   newCellPts->Delete();
   output->SetPoints(newPts);
   newPts->Delete();
-  
+
   if ( this->ExtractBoundaryCells )
-    {
+  {
     newScalars->Delete();
-    }
+  }
 
   output->Squeeze();
   return 1;
index ec37985d4371aab42422491b331deb95b55fd288..bcb58993708aa9c89fc7ad7c18a2c68c6efd8be8 100644 (file)
 #include "SMESH_ObjectDef.h"
 #include "SMESH_ActorUtils.h"
 
+#include "SMDS_BallElement.hxx"
 #include "SMDS_Mesh.hxx"
+#include "SMDS_MeshCell.hxx"
 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
-#include "SMDS_BallElement.hxx"
 #include "SMESH_Actor.h"
 #include "SMESH_ControlsDef.hxx"
-#include "SalomeApp_Application.h"
-#include "VTKViewer_ExtractUnstructuredGrid.h"
-#include "VTKViewer_CellLocationsArray.h"
+
+#include <SalomeApp_Application.h>
+#include <VTKViewer_ExtractUnstructuredGrid.h>
+#include <VTKViewer_CellLocationsArray.h>
 
 #include CORBA_SERVER_HEADER(SMESH_Gen)
 #include CORBA_SERVER_HEADER(SALOME_Exception)
@@ -82,48 +84,48 @@ static int MYDEBUGWITHFILES = 0;
 // function : getCellType
 // purpose  : Get type of VTK cell
 //=================================================================================
-static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
-                                     const bool                thePoly,
-                                     const int                 theNbNodes )
-{
-  switch( theType )
-  {
-    case SMDSAbs_0DElement:         return VTK_VERTEX;
-
-    case SMDSAbs_Ball:              return VTK_POLY_VERTEX;
-
-    case SMDSAbs_Edge: 
-      if( theNbNodes == 2 )         return VTK_LINE;
-      else if ( theNbNodes == 3 )   return VTK_QUADRATIC_EDGE;
-      else return VTK_EMPTY_CELL;
-
-    case SMDSAbs_Face  :
-      if (thePoly && theNbNodes>2 ) return VTK_POLYGON;
-      else if ( theNbNodes == 3 )   return VTK_TRIANGLE;
-      else if ( theNbNodes == 4 )   return VTK_QUAD;
-      else if ( theNbNodes == 6 )   return VTK_QUADRATIC_TRIANGLE;
-      else if ( theNbNodes == 8 )   return VTK_QUADRATIC_QUAD;
-      else if ( theNbNodes == 9 )   return VTK_BIQUADRATIC_QUAD;
-      else if ( theNbNodes == 7 )   return VTK_BIQUADRATIC_TRIANGLE;
-      else return VTK_EMPTY_CELL;
+// static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
+//                                      const bool                thePoly,
+//                                      const int                 theNbNodes )
+// {
+//   switch( theType )
+//   {
+//     case SMDSAbs_0DElement:         return VTK_VERTEX;
+
+//     case SMDSAbs_Ball:              return VTK_POLY_VERTEX;
+
+//     case SMDSAbs_Edge: 
+//       if( theNbNodes == 2 )         return VTK_LINE;
+//       else if ( theNbNodes == 3 )   return VTK_QUADRATIC_EDGE;
+//       else return VTK_EMPTY_CELL;
+
+//     case SMDSAbs_Face  :
+//       if (thePoly && theNbNodes>2 ) return VTK_POLYGON;
+//       else if ( theNbNodes == 3 )   return VTK_TRIANGLE;
+//       else if ( theNbNodes == 4 )   return VTK_QUAD;
+//       else if ( theNbNodes == 6 )   return VTK_QUADRATIC_TRIANGLE;
+//       else if ( theNbNodes == 8 )   return VTK_QUADRATIC_QUAD;
+//       else if ( theNbNodes == 9 )   return VTK_BIQUADRATIC_QUAD;
+//       else if ( theNbNodes == 7 )   return VTK_BIQUADRATIC_TRIANGLE;
+//       else return VTK_EMPTY_CELL;
       
-    case SMDSAbs_Volume:
-      if (thePoly && theNbNodes>3 ) return VTK_POLYHEDRON; //VTK_CONVEX_POINT_SET;
-      else if ( theNbNodes == 4 )   return VTK_TETRA;
-      else if ( theNbNodes == 5 )   return VTK_PYRAMID;
-      else if ( theNbNodes == 6 )   return VTK_WEDGE;
-      else if ( theNbNodes == 8 )   return VTK_HEXAHEDRON;
-      else if ( theNbNodes == 12 )  return VTK_HEXAGONAL_PRISM;
-      else if ( theNbNodes == 10 )  return VTK_QUADRATIC_TETRA;
-      else if ( theNbNodes == 20 )  return VTK_QUADRATIC_HEXAHEDRON;
-      else if ( theNbNodes == 27 )  return VTK_TRIQUADRATIC_HEXAHEDRON;
-      else if ( theNbNodes == 15 )  return VTK_QUADRATIC_WEDGE;
-      else if ( theNbNodes == 13 )  return VTK_QUADRATIC_PYRAMID; //VTK_CONVEX_POINT_SET;
-      else return VTK_EMPTY_CELL;
-
-    default: return VTK_EMPTY_CELL;
-  }
-}
+//     case SMDSAbs_Volume:
+//       if (thePoly && theNbNodes>3 ) return VTK_POLYHEDRON; //VTK_CONVEX_POINT_SET;
+//       else if ( theNbNodes == 4 )   return VTK_TETRA;
+//       else if ( theNbNodes == 5 )   return VTK_PYRAMID;
+//       else if ( theNbNodes == 6 )   return VTK_WEDGE;
+//       else if ( theNbNodes == 8 )   return VTK_HEXAHEDRON;
+//       else if ( theNbNodes == 12 )  return VTK_HEXAGONAL_PRISM;
+//       else if ( theNbNodes == 10 )  return VTK_QUADRATIC_TETRA;
+//       else if ( theNbNodes == 20 )  return VTK_QUADRATIC_HEXAHEDRON;
+//       else if ( theNbNodes == 27 )  return VTK_TRIQUADRATIC_HEXAHEDRON;
+//       else if ( theNbNodes == 15 )  return VTK_QUADRATIC_WEDGE;
+//       else if ( theNbNodes == 13 )  return VTK_QUADRATIC_PYRAMID; //VTK_CONVEX_POINT_SET;
+//       else return VTK_EMPTY_CELL;
+
+//     default: return VTK_EMPTY_CELL;
+//   }
+// }
 
 //=================================================================================
 // functions : SMESH_VisualObjDef
@@ -438,23 +440,23 @@ void SMESH_VisualObjDef::buildElemPrs()
   for ( int i = 0; i < nbTypes; i++ ) // iterate through all types of elements
   {
     if ( nbEnts[ aTypes[ i ] ] > 0 ) {
-      
+
       const SMDSAbs_ElementType& aType = aTypes[ i ];
       const TEntityList& aList = anEnts[ aType ];
       TEntityList::const_iterator anIter;
       for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
       {
         const SMDS_MeshElement* anElem = *anIter;
-        
+
         vtkIdType aNbNodes = anElem->NbNodes();
         anIdList->SetNumberOfIds( aNbNodes );
-        const vtkIdType vtkElemType = getCellType( aType, anElem->IsPoly(), aNbNodes );
-        
+        const vtkIdType vtkElemType = SMDS_MeshCell::toVtkType( anElem->GetEntityType() );
+
         int anId = anElem->GetID();
-        
+
         mySMDS2VTKElems.insert( TMapOfIds::value_type( anId, iElem ) );
         myVTK2SMDSElems.insert( TMapOfIds::value_type( iElem, anId ) );
-        
+
         SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
         {
           // Convertions connectivities from SMDS to VTK
index 4503dd1c427faf93fb9a22e7a1503fe11d065cb0..78ec260d66517867302678585c98df832596c352 100644 (file)
@@ -123,7 +123,7 @@ SMESH_SVTKActor
   SVTK::CopyPoints( GetSource(), aSourceDataSet );
   SVTK::CopyPoints( myBallGrid, aSourceDataSet );
   SVTK::CopyPoints( my0DGrid,    aSourceDataSet );
-  
+
 
   int aNbOfParts = theMapIndex.Extent();
 
@@ -143,12 +143,14 @@ SMESH_SVTKActor
       {
         if(aCell->GetCellType() == VTK_VERTEX ) {
           my0DGrid->InsertNextCell(aCell->GetCellType(),aCell->GetPointIds());
-        } else if(aCell->GetCellType() == VTK_POLY_VERTEX ) {
+        }
+        else if(aCell->GetCellType() == VTK_POLY_VERTEX ) {
           vtkIdType newCellId = myBallGrid->InsertNextCell(aCell->GetCellType(),aCell->GetPointIds());
           if(myVisualObj) {
             outputCD->CopyData(cd, myVisualObj->GetElemVTKId(aPartId), newCellId);
           }
-        } else {
+        }
+        else {
           myUnstructuredGrid->InsertNextCell(aCell->GetCellType(),aCell->GetPointIds());
         }
       }
index 056509ffe419d7defdf50172e4a306f7a07c9a09..58641e56bc44f284cc5c37b5f90555bc61f9a7ab 100644 (file)
@@ -1339,8 +1339,6 @@ SMDS_Mesh::AddPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
   }
   else
   {
-    //#ifdef VTK_HAVE_POLYHEDRON
-    //MESSAGE("AddPolygonalFaceWithID vtk " << ID);
     myNodeIds.resize( nodes.size() );
     for ( size_t i = 0; i < nodes.size(); ++i )
       myNodeIds[i] = nodes[i]->getVtkId();
@@ -1354,25 +1352,12 @@ SMDS_Mesh::AddPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
       return 0;
     }
     face = facevtk;
-    //#else
-    //    MESSAGE("AddPolygonalFaceWithID smds " << ID);
-    //     for ( int i = 0; i < nodes.size(); ++i )
-    //      if ( !nodes[ i ] ) return 0;
-    //      face = new SMDS_PolygonalFaceOfNodes(nodes);
-    //#endif
+
     adjustmyCellsCapacity(ID);
     myCells[ID] = face;
     myInfo.myNbPolygons++;
   }
 
-  //#ifndef VTK_HAVE_POLYHEDRON
-  //  if (!registerElement(ID, face))
-  //    {
-  //      registerElement(myElementIDFactory->GetFreeID(), face);
-  //      //RemoveElement(face, false);
-  //      //face = NULL;
-  //    }
-  //#endif
   return face;
 }
 
@@ -1386,6 +1371,69 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const vector<const SMDS_MeshNode*> &
   return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Add a quadratic polygon defined by its nodes IDs
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector<int> & nodes_ids,
+                                                      const int           ID)
+{
+  vector<const SMDS_MeshNode*> nodes( nodes_ids.size() );
+  for ( size_t i = 0; i < nodes.size(); i++) {
+    nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
+    if (!nodes[i]) return NULL;
+  }
+  return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a quadratic polygon defined by its nodes
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace*
+SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
+                                       const int                            ID)
+{
+  SMDS_MeshFace * face;
+
+  if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if (hasConstructionEdges())
+  {
+    MESSAGE("Error : Not implemented");
+    return NULL;
+  }
+  else
+  {
+    myNodeIds.resize( nodes.size() );
+    for ( size_t i = 0; i < nodes.size(); ++i )
+      myNodeIds[i] = nodes[i]->getVtkId();
+
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->initQuadPoly(myNodeIds, this);
+    if (!this->registerElement(ID,facevtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+      myFacePool->destroy(facevtk);
+      return 0;
+    }
+    face = facevtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
+    myInfo.myNbQuadPolygons++;
+  }
+  return face;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a quadratic polygon defined by its nodes.
+/// An ID is automatically affected to the created face.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const vector<const SMDS_MeshNode*> & nodes)
+{
+  return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 /// Create a new polyhedral volume and add it to the mesh.
 /// @param ID The ID of the new volume
@@ -1779,8 +1827,8 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
 
 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
 {
-    MESSAGE("RemoveNode");
-        RemoveElement(node, true);
+  MESSAGE("RemoveNode");
+  RemoveElement(node, true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1789,7 +1837,7 @@ void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
 
 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
 {
-    MESSAGE("Remove0DElement");
+  MESSAGE("Remove0DElement");
   RemoveElement(elem0d,true);
 }
 
@@ -1799,8 +1847,8 @@ void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
 
 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
 {
-    MESSAGE("RemoveEdge");
-        RemoveElement(edge,true);
+  MESSAGE("RemoveEdge");
+  RemoveElement(edge,true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1809,8 +1857,8 @@ void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
 
 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
 {
-    MESSAGE("RemoveFace");
-        RemoveElement(face, true);
+  MESSAGE("RemoveFace");
+  RemoveElement(face, true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1819,8 +1867,8 @@ void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
 
 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
 {
-    MESSAGE("RemoveVolume");
-        RemoveElement(volume, true);
+  MESSAGE("RemoveVolume");
+  RemoveElement(volume, true);
 }
 
 //=======================================================================
@@ -1830,8 +1878,8 @@ void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
 
 bool SMDS_Mesh::RemoveFromParent()
 {
-        if (myParent==NULL) return false;
-        else return (myParent->RemoveSubMesh(this));
+  if (myParent==NULL) return false;
+  else return (myParent->RemoveSubMesh(this));
 }
 
 //=======================================================================
@@ -1841,20 +1889,20 @@ bool SMDS_Mesh::RemoveFromParent()
 
 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
 {
-        bool found = false;
+  bool found = false;
 
-        list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
-        for (; itmsh!=myChildren.end() && !found; itmsh++)
-        {
-                SMDS_Mesh * submesh = *itmsh;
-                if (submesh == aMesh)
-                {
-                        found = true;
-                        myChildren.erase(itmsh);
-                }
-        }
+  list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
+  for (; itmsh!=myChildren.end() && !found; itmsh++)
+  {
+    SMDS_Mesh * submesh = *itmsh;
+    if (submesh == aMesh)
+    {
+      found = true;
+      myChildren.erase(itmsh);
+    }
+  }
 
-        return found;
+  return found;
 }
 
 //=======================================================================
@@ -1874,10 +1922,10 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
   bool Ok = false;
   SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
   if (cell)
-    {
-      Ok = cell->vtkOrder(nodes, nbnodes);
-      Ok = cell->ChangeNodes(nodes, nbnodes);
-    }
+  {
+    Ok = cell->vtkOrder(nodes, nbnodes);
+    Ok = cell->ChangeNodes(nodes, nbnodes);
+  }
 
   if ( Ok ) { // update InverseElements
 
index de397bf109d5867088d75dbe2ea3b63cea2cf2f6..bc3c740126be2483e7172fa2c3ece994acf27cc8 100644 (file)
@@ -576,14 +576,22 @@ public:
 
   virtual SMDS_MeshFace* AddPolygonalFace (const std::vector<const SMDS_MeshNode*> & nodes);
 
+  virtual SMDS_MeshFace* AddQuadPolygonalFaceWithID(const std::vector<int> & nodes_ids,
+                                                    const int                ID);
+
+  virtual SMDS_MeshFace* AddQuadPolygonalFaceWithID(const std::vector<const SMDS_MeshNode*> & nodes,
+                                                    const int                                 ID);
+
+  virtual SMDS_MeshFace* AddQuadPolygonalFace(const std::vector<const SMDS_MeshNode*> & nodes);
+
   virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
-                           (const std::vector<int> & nodes_ids,
-                            const std::vector<int> & quantities,
-                            const int                ID);
+    (const std::vector<int> & nodes_ids,
+     const std::vector<int> & quantities,
+     const int                ID);
 
   virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
-                           (const std::vector<const SMDS_MeshNode*> & nodes,
-                            const std::vector<int>                  & quantities,
+    (const std::vector<const SMDS_MeshNode*> & nodes,
+     const std::vector<int>                  & quantities,
                             const int                                 ID);
 
   virtual SMDS_MeshVolume* AddPolyhedralVolume
index 2232f68295911ee66c8f79ac065b5744bd4fb483..e629a2f5b7a02a7e18fb5f5ba9c5889044ed34c0 100644 (file)
@@ -56,7 +56,7 @@ VTKCellType SMDS_MeshCell::toVtkType (SMDSAbs_EntityType smdsType)
     vtkTypes[ SMDSEntity_Quad_Quadrangle ]   = VTK_QUADRATIC_QUAD;
     vtkTypes[ SMDSEntity_BiQuad_Quadrangle ] = VTK_BIQUADRATIC_QUAD;
     vtkTypes[ SMDSEntity_Polygon ]           = VTK_POLYGON;
-    //vtkTypes[ SMDSEntity_Quad_Polygon ]      = ;
+    vtkTypes[ SMDSEntity_Quad_Polygon ]      = VTK_QUADRATIC_POLYGON;
     vtkTypes[ SMDSEntity_Tetra ]             = VTK_TETRA;
     vtkTypes[ SMDSEntity_Quad_Tetra ]        = VTK_QUADRATIC_TETRA;
     vtkTypes[ SMDSEntity_Pyramid ]           = VTK_PYRAMID;
@@ -166,12 +166,14 @@ const std::vector< int >& SMDS_MeshCell::toVtkOrder(SMDSAbs_EntityType smdsType)
 
 //================================================================================
 /*!
- * \brief Return indices to reverse an SMDS cell of given type
+ * \brief Return indices to reverse an SMDS cell of given type.
+ *        nbNodes is useful for polygons
  * Usage: reverseIDs[i] = forwardIDs[ indices[ i ]]
  */
 //================================================================================
 
-const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsType)
+const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsType,
+                                                        const size_t       nbNodes)
 {
   static std::vector< std::vector< int > > reverseInterlaces;
   if ( reverseInterlaces.empty() )
@@ -256,6 +258,31 @@ const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsT
       reverseInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
     }
   }
+
+  if ( smdsType == SMDSEntity_Polygon )
+  {
+    if ( reverseInterlaces[ smdsType ].size() != nbNodes )
+    {
+      reverseInterlaces[ smdsType ].resize( nbNodes );
+      for ( size_t i = 0; i < nbNodes; ++i )
+        reverseInterlaces[ smdsType ][i] = nbNodes - i - 1;
+    }
+  }
+  else if ( smdsType == SMDSEntity_Quad_Polygon )
+  {
+    if ( reverseInterlaces[ smdsType ].size() != nbNodes )
+    {
+      // e.g. for 8 nodes: [ 0, 3,2,1, 7,6,5,4 ]
+      reverseInterlaces[ smdsType ].resize( nbNodes );
+      size_t pos = 0;
+      reverseInterlaces[ smdsType ][pos++] = 0;
+      for ( int i = nbNodes / 2 - 1; i > 0 ; --i ) // 3,2,1
+        reverseInterlaces[ smdsType ][pos++] = i;
+      for ( int i = nbNodes - 1; i >= nbNodes / 2; --i ) // 7,6,5,4
+        reverseInterlaces[ smdsType ][pos++] = i;
+    }
+  }
+  
   return reverseInterlaces[smdsType];
 }
 
@@ -266,7 +293,8 @@ const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsT
  */
 //================================================================================
 
-const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType smdsType)
+const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType smdsType,
+                                                           const size_t       nbNodes)
 {
   static std::vector< std::vector< int > > interlace;
   if ( interlace.empty() )
@@ -278,15 +306,28 @@ const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType sm
     }
     {
       const int ids[] = {0,3,1,4,2,5,6};
-      interlace[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
+      interlace[SMDSEntity_Quad_Triangle  ].assign( &ids[0], &ids[0]+6 );
       interlace[SMDSEntity_BiQuad_Triangle].assign( &ids[0], &ids[0]+7 );
     }
     {
       const int ids[] = {0,4,1,5,2,6,3,7,8};
-      interlace[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
+      interlace[SMDSEntity_Quad_Quadrangle  ].assign( &ids[0], &ids[0]+8 );
       interlace[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
     }
   }
+
+  if ( smdsType == SMDSEntity_Quad_Polygon )
+  {
+    if ( interlace[smdsType].size() != nbNodes )
+    {
+      interlace[smdsType].resize( nbNodes );
+      for ( size_t i = 0; i < nbNodes / 2; ++i )
+      {
+        interlace[smdsType][i*2+0] = i;
+        interlace[smdsType][i*2+1] = i + nbNodes / 2;
+      }
+    }
+  }
   return interlace[smdsType];
 }
 
index 85cc7475e1b90f8191bfd6db02e3f97a6982df32..d56f7b5dea636bbb2a22330c23522f399f37d3c8 100644 (file)
@@ -45,10 +45,12 @@ public:
   static const std::vector<int>& fromVtkOrder(VTKCellType vtkType);
   static const std::vector<int>& fromVtkOrder(SMDSAbs_EntityType smdsType);
 
-  static const std::vector<int>& reverseSmdsOrder(SMDSAbs_EntityType smdsType);
-  static const std::vector<int>& interlacedSmdsOrder(SMDSAbs_EntityType smdsType);
+  static const std::vector<int>& reverseSmdsOrder(SMDSAbs_EntityType smdsType,
+                                                  const size_t       nbNodes=0);
+  static const std::vector<int>& interlacedSmdsOrder(SMDSAbs_EntityType smdsType,
+                                                     const size_t       nbNodes=0);
 
-  template< class VECT >
+  template< class VECT > // interlacedIDs[i] = smdsIDs[ indices[ i ]]
     static void applyInterlace( const std::vector<int>& interlace, VECT & data)
   {
     if ( interlace.empty() ) return;
@@ -57,6 +59,15 @@ public:
       tmpData[i] = data[ interlace[i] ];
     data.swap( tmpData );
   }
+  template< class VECT > // interlacedIDs[ indices[ i ]] = smdsIDs[i]
+    static void applyInterlaceRev( const std::vector<int>& interlace, VECT & data)
+  {
+    if ( interlace.empty() ) return;
+    VECT tmpData( data.size() );
+    for ( size_t i = 0; i < data.size(); ++i )
+      tmpData[ interlace[i] ] = data[i];
+    data.swap( tmpData );
+  }
 
   static int nbCells;
 
index fa49ecd24b00f9874de49edd8c70a32318282cfe..5c22d7f9b0e62016ae87f8cf77cadfa625a6ed83 100644 (file)
@@ -56,7 +56,7 @@ public:
   inline int NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) const;
   int NbBiQuadTriangles() const { return myNbBiQuadTriangles; }
   int NbBiQuadQuadrangles() const { return myNbBiQuadQuadrangles; }
-  int NbPolygons() const { return myNbPolygons; }
+  inline int NbPolygons(SMDSAbs_ElementOrder order = ORDER_ANY) const;
 
   inline int NbVolumes (SMDSAbs_ElementOrder order = ORDER_ANY) const;
   inline int NbTetras  (SMDSAbs_ElementOrder order = ORDER_ANY) const;
@@ -90,7 +90,7 @@ private:
   int myNbEdges      , myNbQuadEdges      ;
   int myNbTriangles  , myNbQuadTriangles,   myNbBiQuadTriangles  ;
   int myNbQuadrangles, myNbQuadQuadrangles, myNbBiQuadQuadrangles;
-  int myNbPolygons;
+  int myNbPolygons   , myNbQuadPolygons;
 
   int myNbTetras  , myNbQuadTetras  ;
   int myNbHexas   , myNbQuadHexas,    myNbTriQuadHexas;
@@ -110,7 +110,7 @@ inline SMDS_MeshInfo::SMDS_MeshInfo():
   myNbEdges      (0), myNbQuadEdges      (0),
   myNbTriangles  (0), myNbQuadTriangles  (0), myNbBiQuadTriangles(0),
   myNbQuadrangles(0), myNbQuadQuadrangles(0), myNbBiQuadQuadrangles(0),
-  myNbPolygons   (0),
+  myNbPolygons   (0), myNbQuadPolygons   (0),
   myNbTetras     (0), myNbQuadTetras  (0),
   myNbHexas      (0), myNbQuadHexas   (0), myNbTriQuadHexas(0),
   myNbPyramids   (0), myNbQuadPyramids(0),
@@ -193,15 +193,16 @@ inline SMDS_MeshInfo::SMDS_MeshInfo():
 inline SMDS_MeshInfo& // operator=
 SMDS_MeshInfo::operator=(const SMDS_MeshInfo& other)
 { for ( int i=0; i<myNb.size(); ++i ) if ( myNb[i] ) (*myNb[i])=(*other.myNb[i]);
-  myNbPolygons = other.myNbPolygons;
-  myNbPolyhedrons = other.myNbPolyhedrons;
+  myNbPolygons     = other.myNbPolygons;
+  myNbQuadPolygons = other.myNbQuadPolygons;
+  myNbPolyhedrons  = other.myNbPolyhedrons;
   return *this;
 }
 
 inline void // Clear
 SMDS_MeshInfo::Clear()
 { for ( int i=0; i<myNb.size(); ++i ) if ( myNb[i] ) (*myNb[i])=0;
-  myNbPolygons=myNbPolyhedrons=0;
+  myNbPolygons=myNbQuadPolygons=myNbPolyhedrons=0;
 }
 
 inline int // index
@@ -217,20 +218,26 @@ SMDS_MeshInfo::add(const SMDS_MeshElement* el)
 { ++(*myNb[ index(el->GetType(), el->NbNodes()) ]); }
 
 inline void // addWithPoly
-SMDS_MeshInfo::addWithPoly(const SMDS_MeshElement* el)
-{
-  if ( el->IsPoly() )
-    ++( el->GetType()==SMDSAbs_Face ? myNbPolygons : myNbPolyhedrons );
-  else
-    add(el);
+SMDS_MeshInfo::addWithPoly(const SMDS_MeshElement* el) {
+  switch ( el->GetEntityType() ) {
+  case SMDSEntity_Polygon:      ++myNbPolygons; break;
+  case SMDSEntity_Quad_Polygon: ++myNbQuadPolygons; break;
+  case SMDSEntity_Polyhedra:    ++myNbPolyhedrons; break;
+  default:                      add(el);
+  }
 }
 inline void // RemoveEdge
 SMDS_MeshInfo::RemoveEdge(const SMDS_MeshElement* el)
 { if ( el->IsQuadratic() ) --myNbQuadEdges; else --myNbEdges; }
 
 inline void // RemoveFace
-SMDS_MeshInfo::RemoveFace(const SMDS_MeshElement* el)
-{ if ( el->IsPoly() ) --myNbPolygons; else remove( el ); }
+SMDS_MeshInfo::RemoveFace(const SMDS_MeshElement* el) {
+  switch ( el->GetEntityType() ) {
+  case SMDSEntity_Polygon:      --myNbPolygons; break;
+  case SMDSEntity_Quad_Polygon: --myNbQuadPolygons; break;
+  default:                      remove(el);
+  }
+}
 
 inline void // RemoveVolume
 SMDS_MeshInfo::RemoveVolume(const SMDS_MeshElement* el)
@@ -242,7 +249,7 @@ SMDS_MeshInfo::NbEdges      (SMDSAbs_ElementOrder order) const
 
 inline int  // NbFaces
 SMDS_MeshInfo::NbFaces      (SMDSAbs_ElementOrder order) const
-{ return NbTriangles(order)+NbQuadrangles(order)+(order == ORDER_QUADRATIC ? 0 : myNbPolygons); }
+{ return NbTriangles(order)+NbQuadrangles(order)+(order == ORDER_ANY ? myNbPolygons+myNbQuadPolygons : order == ORDER_LINEAR ? myNbPolygons : myNbQuadPolygons ); }
 
 inline int  // NbTriangles
 SMDS_MeshInfo::NbTriangles  (SMDSAbs_ElementOrder order) const
@@ -252,6 +259,10 @@ 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  // NbPolygons
+SMDS_MeshInfo::NbPolygons(SMDSAbs_ElementOrder order) const
+{ return order == ORDER_ANY ? myNbPolygons+myNbQuadPolygons : order == ORDER_LINEAR ? myNbPolygons : myNbQuadPolygons; }
+
 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); }
@@ -283,7 +294,7 @@ SMDS_MeshInfo::NbElements(SMDSAbs_ElementType type) const
   switch (type) {
   case SMDSAbs_All:
     for ( int i=1+index( SMDSAbs_Node,1 ); i<myNb.size(); ++i ) if ( myNb[i] ) nb += *myNb[i];
-    nb += myNbPolygons + myNbPolyhedrons;
+    nb += myNbPolygons + myNbQuadPolygons + myNbPolyhedrons;
     break;
   case SMDSAbs_Volume:
     nb = ( myNbTetras+     myNbPyramids+     myNbPrisms+     myNbHexas+     myNbHexPrism+
@@ -293,7 +304,7 @@ SMDS_MeshInfo::NbElements(SMDSAbs_ElementType type) const
   case SMDSAbs_Face:
     nb = ( myNbTriangles+       myNbQuadrangles+
            myNbQuadTriangles+   myNbBiQuadTriangles+
-           myNbQuadQuadrangles+ myNbBiQuadQuadrangles+ myNbPolygons );
+           myNbQuadQuadrangles+ myNbBiQuadQuadrangles+ myNbPolygons+ myNbQuadPolygons );
     break;
   case SMDSAbs_Edge:
     nb = myNbEdges + myNbQuadEdges;
@@ -339,7 +350,7 @@ SMDS_MeshInfo::NbEntities(SMDSAbs_EntityType type) const
   case SMDSEntity_Polyhedra:        return myNbPolyhedrons;
   case SMDSEntity_0D:               return myNb0DElements;
   case SMDSEntity_Ball:             return myNbBalls;
-  case SMDSEntity_Quad_Polygon:
+  case SMDSEntity_Quad_Polygon:     return myNbQuadPolygons;
   case SMDSEntity_Quad_Polyhedra:
     break;
   }
@@ -362,7 +373,7 @@ SMDS_MeshInfo::NbElementsOfGeom(SMDSAbs_GeometryType geom) const
   case SMDSGeom_QUADRANGLE:      return (myNbQuadrangles +
                                          myNbQuadQuadrangles +
                                          myNbBiQuadQuadrangles );
-  case SMDSGeom_POLYGON:         return myNbPolygons;
+  case SMDSGeom_POLYGON:         return (myNbPolygons + myNbQuadPolygons );
     // 3D:
   case SMDSGeom_TETRA:           return (myNbTetras +
                                          myNbQuadTetras);
@@ -411,7 +422,7 @@ SMDS_MeshInfo::setNb(const SMDSAbs_EntityType geomType, const int nb)
   case SMDSEntity_Tetra:            myNbTetras            = nb; break;
   case SMDSEntity_TriQuad_Hexa:     myNbTriQuadHexas      = nb; break;
   case SMDSEntity_Triangle:         myNbTriangles         = nb; break;
-  case SMDSEntity_Quad_Polygon:
+  case SMDSEntity_Quad_Polygon:     myNbQuadPolygons      = nb; break;
   case SMDSEntity_Quad_Polyhedra:
     break;
   }
index 001387c5f4daa5b10efcb231c31277645c5cc80d..b86dc16c377a99bae4f78b2a322e75bc97aecd23 100644 (file)
@@ -43,6 +43,8 @@
 
 using namespace std;
 
+namespace
+{
 // ======================================================
 // Node indices in faces depending on volume orientation
 // making most faces normals external
@@ -349,8 +351,6 @@ static int TriQuadHexa_nbN [] = { 9, 9, 9, 9, 9, 9 };
 // ========================================================
 // to perform some calculations without linkage to CASCADE
 // ========================================================
-namespace
-{
 struct XYZ {
   double x;
   double y;
@@ -1498,6 +1498,7 @@ double SMDS_VolumeTool::MaxLinearSize2() const
 //================================================================================
 /*!
  * \brief fast check that only one volume is build on the face nodes
+ *        This check is valid for conformal meshes only
  */
 //================================================================================
 
@@ -1510,19 +1511,30 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherV
 
   const SMDS_MeshNode** nodes = GetFaceNodes( faceIndex );
 
-  const int di = myVolume->IsQuadratic() ? 2 : 1;
-  const SMDS_MeshNode* n1 = nodes[di*0];
-  const SMDS_MeshNode* n2 = nodes[di*1];
-  const SMDS_MeshNode* n3 = nodes[di*2];
+  const int  di = myVolume->IsQuadratic() ? 2 : 1;
+  const int nbN = ( myFaceNbNodes/di <= 4 && !IsPoly()) ? 3 : myFaceNbNodes/di; // nb nodes to check
 
-  SMDS_ElemIteratorPtr eIt = n1->GetInverseElementIterator( SMDSAbs_Volume );
-  SMDS_ElemIteratorPtr nIt;
-  while ( eIt->more() ) {
+  SMDS_ElemIteratorPtr eIt = nodes[0]->GetInverseElementIterator( SMDSAbs_Volume );
+  while ( eIt->more() )
+  {
     const SMDS_MeshElement* vol = eIt->next();
-    if ( vol != myVolume &&
-         vol->GetNodeIndex( n2 ) >= 0 &&
-         vol->GetNodeIndex( n3 ) >= 0 )
+    if ( vol == myVolume )
+      continue;
+    int iN;
+    for ( iN = 1; iN < nbN; ++iN )
+      if ( vol->GetNodeIndex( nodes[ iN*di ]) < 0 )
+        break;
+    if ( iN == nbN ) // nbN nodes are shared with vol
     {
+      // if ( vol->IsPoly() || vol->NbFaces() > 6 ) // vol is polyhed or hex prism 
+      // {
+      //   int nb = myFaceNbNodes;
+      //   if ( myVolume->GetEntityType() != vol->GetEntityType() )
+      //     nb -= ( GetCenterNodeIndex(0) > 0 );
+      //   set<const SMDS_MeshNode*> faceNodes( nodes, nodes + nb );
+      //   if ( SMDS_VolumeTool( vol ).GetFaceIndex( faceNodes ) < 0 )
+      //     continue;
+      // }
       if ( otherVol ) *otherVol = vol;
       return !isFree;
     }
index 987ca65bf4d5f2b21ac306e8665c334582747dd6..d050097fba3139295005ad6ba30851fcbf18b0da 100644 (file)
@@ -71,75 +71,73 @@ SMDS_VtkCellIteratorToUNV::SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCel
   vtkUnstructuredGrid* grid = _mesh->getGrid();
   grid->GetCellPoints((vtkIdType)_cellId, (vtkIdType&)_nbNodes, pts);
   _vtkIdList->SetNumberOfIds(_nbNodes);
-  int *ids = 0;
+  const int *ids = 0;
   switch (_type)
   {
-    case SMDSEntity_Quad_Edge:
-      {
-        static int id[] = { 0, 2, 1 };
-        ids = id;
-        break;
-      }
-    case SMDSEntity_Quad_Triangle:
-    case SMDSEntity_BiQuad_Triangle:
-      {
-        static int id[] = { 0, 3, 1, 4, 2, 5 };
-        ids = id;
-        _nbNodes = 6;
-        break;
-      }
-    case SMDSEntity_Quad_Quadrangle:
-    case SMDSEntity_BiQuad_Quadrangle:
-      {
-        static int id[] = { 0, 4, 1, 5, 2, 6, 3, 7 };
-        ids = id;
-        _nbNodes = 8;
-        break;
-      }
-    case SMDSEntity_Quad_Tetra:
-      {
-        static int id[] = { 0, 4, 1, 5, 2, 6, 7, 8, 9, 3 };
-        ids = id;
-        break;
-      }
-    case SMDSEntity_Quad_Pyramid:
-      {
-        static int id[] = { 0, 5, 1, 6, 2, 7, 3, 8, 9, 10, 11, 12, 4 };
-        ids = id;
-        break;
-      }
-    case SMDSEntity_Penta:
-      {
-        static int id[] = { 0, 2, 1, 3, 5, 4 };
-        ids = id;
-        break;
-      }
-    case SMDSEntity_Quad_Penta:
-      {
-        static int id[] = { 0, 8, 2, 7, 1, 6, 12, 14, 13, 3, 11, 5, 10, 4, 9 };
-        ids = id;
-        break;
-      }
-    case SMDSEntity_Quad_Hexa:
-    case SMDSEntity_TriQuad_Hexa:
-      {
-        static int id[] = { 0, 8, 1, 9, 2, 10, 3, 11, 16, 17, 18, 19, 4, 12, 5, 13, 6, 14, 7, 15 };
-        ids = id;
-        _nbNodes = 20;
-        break;
-      }
-    case SMDSEntity_Polygon:
-    case SMDSEntity_Quad_Polygon:
-    case SMDSEntity_Polyhedra:
-    case SMDSEntity_Quad_Polyhedra:
-    default:
-      {
-        // static int id[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
-        //                     25, 26, 27, 28, 29 };
-        // ids = id;
-        // break;
-      }
+  case SMDSEntity_Quad_Edge:
+  {
+    static int id[] = { 0, 2, 1 };
+    ids = id;
+    break;
+  }
+  case SMDSEntity_Quad_Triangle:
+  case SMDSEntity_BiQuad_Triangle:
+  {
+    static int id[] = { 0, 3, 1, 4, 2, 5 };
+    ids = id;
+    _nbNodes = 6;
+    break;
+  }
+  case SMDSEntity_Quad_Quadrangle:
+  case SMDSEntity_BiQuad_Quadrangle:
+  {
+    static int id[] = { 0, 4, 1, 5, 2, 6, 3, 7 };
+    ids = id;
+    _nbNodes = 8;
+    break;
   }
+  case SMDSEntity_Quad_Tetra:
+  {
+    static int id[] = { 0, 4, 1, 5, 2, 6, 7, 8, 9, 3 };
+    ids = id;
+    break;
+  }
+  case SMDSEntity_Quad_Pyramid:
+  {
+    static int id[] = { 0, 5, 1, 6, 2, 7, 3, 8, 9, 10, 11, 12, 4 };
+    ids = id;
+    break;
+  }
+  case SMDSEntity_Penta:
+  {
+    static int id[] = { 0, 2, 1, 3, 5, 4 };
+    ids = id;
+    break;
+  }
+  case SMDSEntity_Quad_Penta:
+  {
+    static int id[] = { 0, 8, 2, 7, 1, 6, 12, 14, 13, 3, 11, 5, 10, 4, 9 };
+    ids = id;
+    break;
+  }
+  case SMDSEntity_Quad_Hexa:
+  case SMDSEntity_TriQuad_Hexa:
+  {
+    static int id[] = { 0, 8, 1, 9, 2, 10, 3, 11, 16, 17, 18, 19, 4, 12, 5, 13, 6, 14, 7, 15 };
+    ids = id;
+    _nbNodes = 20;
+    break;
+  }
+  case SMDSEntity_Polygon:
+  case SMDSEntity_Quad_Polygon:
+  case SMDSEntity_Polyhedra:
+  case SMDSEntity_Quad_Polyhedra:
+  default:
+    const std::vector<int>& i = SMDS_MeshCell::interlacedSmdsOrder(aType, _nbNodes);
+    if ( !i.empty() )
+      ids = & i[0];
+  }
+
   if ( ids )
     for (int i = 0; i < _nbNodes; i++)
       _vtkIdList->SetId(i, pts[ids[i]]);
@@ -176,34 +174,34 @@ SMDS_VtkCellIteratorPolyH::SMDS_VtkCellIteratorPolyH(SMDS_Mesh* mesh, int vtkCel
   _nbNodes = _vtkIdList->GetNumberOfIds();
   switch (_type)
   {
-    case SMDSEntity_Polyhedra:
-      {
-        //MESSAGE("SMDS_VtkCellIterator Polyhedra");
-        vtkIdType nFaces = 0;
-        vtkIdType* ptIds = 0;
-        grid->GetFaceStream(_cellId, nFaces, ptIds);
-        int id = 0;
-        _nbNodesInFaces = 0;
-        for (int i = 0; i < nFaces; i++)
-          {
-            int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
-            _nbNodesInFaces += nodesInFace;
-            id += (nodesInFace + 1);
-          }
-        _vtkIdList->SetNumberOfIds(_nbNodesInFaces);
-        id = 0;
-        int n = 0;
-        for (int i = 0; i < nFaces; i++)
-          {
-            int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
-            for (int k = 1; k <= nodesInFace; k++)
-              _vtkIdList->SetId(n++, ptIds[id + k]);
-            id += (nodesInFace + 1);
-          }
-        break;
-      }
-    default:
-      assert(0);
+  case SMDSEntity_Polyhedra:
+  {
+    //MESSAGE("SMDS_VtkCellIterator Polyhedra");
+    vtkIdType nFaces = 0;
+    vtkIdType* ptIds = 0;
+    grid->GetFaceStream(_cellId, nFaces, ptIds);
+    int id = 0;
+    _nbNodesInFaces = 0;
+    for (int i = 0; i < nFaces; i++)
+    {
+      int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
+      _nbNodesInFaces += nodesInFace;
+      id += (nodesInFace + 1);
+    }
+    _vtkIdList->SetNumberOfIds(_nbNodesInFaces);
+    id = 0;
+    int n = 0;
+    for (int i = 0; i < nFaces; i++)
+    {
+      int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
+      for (int k = 1; k <= nodesInFace; k++)
+        _vtkIdList->SetId(n++, ptIds[id + k]);
+      id += (nodesInFace + 1);
+    }
+    break;
+  }
+  default:
+    assert(0);
   }
 }
 
index cd281e01a5dc56fbb0d04384e57beffe19285d01..0a772f53bc6be24307a17afbf475a3365fb03c1a 100644 (file)
@@ -85,6 +85,15 @@ void SMDS_VtkFace::initPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* me
   mesh->setMyModified();
 }
 
+void SMDS_VtkFace::initQuadPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
+{
+  SMDS_MeshFace::init();
+  vtkUnstructuredGrid* grid = mesh->getGrid();
+  myMeshId = mesh->getMeshId();
+  myVtkID = grid->InsertNextLinkedCell(VTK_QUADRATIC_POLYGON, nodeIds.size(), (vtkIdType*) &nodeIds[0]);
+  mesh->setMyModified();
+}
+
 bool SMDS_VtkFace::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
 {
   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
@@ -111,26 +120,28 @@ void SMDS_VtkFace::Print(std::ostream & OS) const
 
 int SMDS_VtkFace::NbEdges() const
 {
-  // TODO quadratic polygons ?
   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
   int nbEdges = 3;
   switch (aVtkType)
   {
-    case VTK_TRIANGLE:
-    case VTK_QUADRATIC_TRIANGLE:
-    case VTK_BIQUADRATIC_TRIANGLE:
-      nbEdges = 3;
-      break;
-    case VTK_QUAD:
-    case VTK_QUADRATIC_QUAD:
-    case VTK_BIQUADRATIC_QUAD:
-      nbEdges = 4;
-      break;
-    case VTK_POLYGON:
-    default:
-      nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints();
-      break;
+  case VTK_TRIANGLE:
+  case VTK_QUADRATIC_TRIANGLE:
+  case VTK_BIQUADRATIC_TRIANGLE:
+    nbEdges = 3;
+    break;
+  case VTK_QUAD:
+  case VTK_QUADRATIC_QUAD:
+  case VTK_BIQUADRATIC_QUAD:
+    nbEdges = 4;
+    break;
+  case VTK_QUADRATIC_POLYGON:
+    nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints() / 2;
+    break;
+  case VTK_POLYGON:
+  default:
+    nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints();
+    break;
   }
   return nbEdges;
 }
@@ -186,6 +197,7 @@ bool SMDS_VtkFace::IsQuadratic() const
   {
     case VTK_QUADRATIC_TRIANGLE:
     case VTK_QUADRATIC_QUAD:
+    case VTK_QUADRATIC_POLYGON:
     case VTK_BIQUADRATIC_QUAD:
     case VTK_BIQUADRATIC_TRIANGLE:
       return true;
@@ -199,7 +211,7 @@ bool SMDS_VtkFace::IsPoly() const
 {
   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
-  return (aVtkType == VTK_POLYGON);
+  return ( aVtkType == VTK_POLYGON || aVtkType == VTK_QUADRATIC_POLYGON );
 }
 
 bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const
@@ -209,33 +221,36 @@ bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const
   int rankFirstMedium = 0;
   switch (aVtkType)
   {
-    case VTK_QUADRATIC_TRIANGLE:
-    case VTK_BIQUADRATIC_TRIANGLE:
-      rankFirstMedium = 3; // medium nodes are of rank 3,4,5
-      break;
-    case VTK_QUADRATIC_QUAD:
-    case VTK_BIQUADRATIC_QUAD:
-      rankFirstMedium = 4; // medium nodes are of rank 4,5,6,7
-      break;
-    default:
-      //MESSAGE("wrong element type " << aVtkType);
-      return false;
+  case VTK_QUADRATIC_TRIANGLE:
+  case VTK_BIQUADRATIC_TRIANGLE:
+    rankFirstMedium = 3; // medium nodes are of rank 3,4,5
+    break;
+  case VTK_QUADRATIC_QUAD:
+  case VTK_BIQUADRATIC_QUAD:
+    rankFirstMedium = 4; // medium nodes are of rank 4,5,6,7
+    break;
+  case VTK_QUADRATIC_POLYGON:
+    rankFirstMedium = grid->GetCell(myVtkID)->GetNumberOfPoints() / 2;
+    break;
+  default:
+    //MESSAGE("wrong element type " << aVtkType);
+    return false;
   }
   vtkIdType npts = 0;
   vtkIdType* pts = 0;
   grid->GetCellPoints(myVtkID, npts, pts);
   vtkIdType nodeId = node->getVtkId();
   for (int rank = 0; rank < npts; rank++)
+  {
+    if (pts[rank] == nodeId)
     {
-      if (pts[rank] == nodeId)
-        {
-          //MESSAGE("rank " << rank << " is medium node " << (rank < rankFirstMedium));
-          if (rank < rankFirstMedium)
-            return false;
-          else
-            return true;
-        }
+      //MESSAGE("rank " << rank << " is medium node " << (rank < rankFirstMedium));
+      if (rank < rankFirstMedium)
+        return false;
+      else
+        return true;
     }
+  }
   //throw SALOME_Exception(LOCALIZED("node does not belong to this element"));
   MESSAGE("======================================================");
   MESSAGE("= IsMediumNode: node does not belong to this element =");
@@ -248,8 +263,17 @@ int SMDS_VtkFace::NbCornerNodes() const
   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
   int       nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
   vtkIdType aVtkType = grid->GetCellType(myVtkID);
-  if ( aVtkType != VTK_POLYGON )
-    return nbPoints <= 4 ? nbPoints : nbPoints / 2;
+  switch ( aVtkType )
+  {
+  case VTK_POLYGON:
+    break;
+  case VTK_QUADRATIC_POLYGON:
+    nbPoints /= 2;
+    break;
+  default:
+    if ( nbPoints > 4 )
+      nbPoints /= 2;
+  }
   return nbPoints;
 }
 
@@ -273,7 +297,8 @@ SMDSAbs_GeometryType SMDS_VtkFace::GetGeomType() const
   case VTK_QUADRATIC_QUAD:
   case VTK_BIQUADRATIC_QUAD: return SMDSGeom_QUADRANGLE;
 
-  case VTK_POLYGON: return SMDSGeom_POLYGON;
+  case VTK_POLYGON:
+  case VTK_QUADRATIC_POLYGON: return SMDSGeom_POLYGON;
   default:;
   }
   return SMDSGeom_NONE;
index 351c905f980d12130ce1cdb85ffb26e33f7c5249..235a9c2d8046535af8361fe1f80c35bd40fa3faa 100644 (file)
@@ -34,6 +34,7 @@ public:
   ~SMDS_VtkFace();
   void init(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
   void initPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
+  void initQuadPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
 
   bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes);
   void ChangeApex(SMDS_MeshNode* node); // to use only for tmp triangles
index 4b3444adf88aac5c6ce8302169e94421adc00d10..4ba42c977ddb40bc1b26aaa9f057e8d0b2b763b6 100644 (file)
@@ -1783,10 +1783,10 @@ int SMESH_Mesh::NbBiQuadQuadrangles() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbPolygons() const throw(SALOME_Exception)
+int SMESH_Mesh::NbPolygons(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbPolygons();
+  return _myMeshDS->GetMeshInfo().NbPolygons(order);
 }
 
 //================================================================================
index 4878dc4f96cd815f4d9c00bd403c8ef41a5f6529..5221ab7d2d1506486b714f020e07a7b49c986240 100644 (file)
@@ -283,7 +283,7 @@ class SMESH_EXPORT SMESH_Mesh
   int NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
   int NbBiQuadQuadrangles() const throw(SALOME_Exception);
   int NbBiQuadTriangles() const throw(SALOME_Exception);
-  int NbPolygons() const throw(SALOME_Exception);
+  int NbPolygons(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
   
   int NbVolumes(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
   int NbTetras(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
index b45e0117bb235707b4499f60e482f6619c487794..18666319fa8f48137eb04ab15b39536860f660ea 100644 (file)
@@ -137,6 +137,40 @@ void SMESH_MeshEditor::ClearLastCreated()
   myLastCreatedElems.Clear();
 }
 
+//================================================================================
+/*!
+ * \brief Initializes members by an existing element
+ *  \param [in] elem - the source element
+ *  \param [in] basicOnly - if true, does not set additional data of Ball and Polyhedron
+ */
+//================================================================================
+
+SMESH_MeshEditor::ElemFeatures&
+SMESH_MeshEditor::ElemFeatures::Init( const SMDS_MeshElement* elem, bool basicOnly )
+{
+  if ( elem )
+  {
+    myType = elem->GetType();
+    if ( myType == SMDSAbs_Face || myType == SMDSAbs_Volume )
+    {
+      myIsPoly = elem->IsPoly();
+      if ( myIsPoly )
+      {
+        myIsQuad = elem->IsQuadratic();
+        if ( myType == SMDSAbs_Volume && !basicOnly )
+        {
+          vector<int > quant = static_cast<const SMDS_VtkVolume* >( elem )->GetQuantities();
+          myPolyhedQuantities.swap( quant );
+        }
+      }
+    }
+    else if ( myType == SMDSAbs_Ball && !basicOnly )
+    {
+      myBallDiameter = static_cast<const SMDS_BallElement*>(elem)->GetDiameter();
+    }
+  }
+  return *this;
+}
 
 //=======================================================================
 /*!
@@ -146,18 +180,16 @@ void SMESH_MeshEditor::ClearLastCreated()
 
 SMDS_MeshElement*
 SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
-                             const SMDSAbs_ElementType            type,
-                             const bool                           isPoly,
-                             const int                            ID,
-                             const double                         ballDiameter)
+                             const ElemFeatures&                  features)
 {
-  //MESSAGE("AddElement " <<node.size() << " " << type << " " << isPoly << " " << ID);
   SMDS_MeshElement* e = 0;
   int nbnode = node.size();
   SMESHDS_Mesh* mesh = GetMeshDS();
-  switch ( type ) {
+  const int ID = features.myID;
+
+  switch ( features.myType ) {
   case SMDSAbs_Face:
-    if ( !isPoly ) {
+    if ( !features.myIsPoly ) {
       if      (nbnode == 3) {
         if ( ID >= 1 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], ID);
         else           e = mesh->AddFace      (node[0], node[1], node[2] );
@@ -190,14 +222,21 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
         else           e = mesh->AddFace      (node[0], node[1], node[2], node[3],
                                                node[4], node[5], node[6], node[7], node[8] );
       }
-    } else {
+    }
+    else if ( !features.myIsQuad )
+    {
       if ( ID >= 1 ) e = mesh->AddPolygonalFaceWithID(node, ID);
       else           e = mesh->AddPolygonalFace      (node    );
     }
+    else if ( nbnode % 2 == 0 ) // just a protection
+    {
+      if ( ID >= 1 ) e = mesh->AddQuadPolygonalFaceWithID(node, ID);
+      else           e = mesh->AddQuadPolygonalFace      (node    );
+    }
     break;
 
   case SMDSAbs_Volume:
-    if ( !isPoly ) {
+    if ( !features.myIsPoly ) {
       if      (nbnode == 4) {
         if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], ID);
         else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3] );
@@ -285,6 +324,16 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
                                                  node[24],node[25],node[26] );
       }
     }
+    else if ( !features.myIsQuad )
+    {
+      if ( ID >= 1 ) e = mesh->AddPolyhedralVolumeWithID(node, features.myPolyhedQuantities, ID);
+      else           e = mesh->AddPolyhedralVolume      (node, features.myPolyhedQuantities    );
+    }
+    else
+    {
+      // if ( ID >= 1 ) e = mesh->AddQuadPolyhedralVolumeWithID(node, features.myPolyhedQuantities,ID);
+      // else           e = mesh->AddQuadPolyhedralVolume      (node, features.myPolyhedQuantities   );
+    }
     break;
 
   case SMDSAbs_Edge:
@@ -307,12 +356,12 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
 
   case SMDSAbs_Node:
     if ( ID >= 1 ) e = mesh->AddNodeWithID(node[0]->X(), node[0]->Y(), node[0]->Z(), ID);
-    else           e = mesh->AddNode      (node[0]->X(), node[0]->Y(), node[0]->Z());
+    else           e = mesh->AddNode      (node[0]->X(), node[0]->Y(), node[0]->Z()    );
     break;
 
   case SMDSAbs_Ball:
-    if ( ID >= 1 ) e = mesh->AddBallWithID(node[0], ballDiameter, ID);
-    else           e = mesh->AddBall      (node[0], ballDiameter);
+    if ( ID >= 1 ) e = mesh->AddBallWithID(node[0], features.myBallDiameter, ID);
+    else           e = mesh->AddBall      (node[0], features.myBallDiameter    );
     break;
 
   default:;
@@ -327,10 +376,8 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
  */
 //=======================================================================
 
-SMDS_MeshElement* SMESH_MeshEditor::AddElement(const vector<int> &       nodeIDs,
-                                               const SMDSAbs_ElementType type,
-                                               const bool                isPoly,
-                                               const int                 ID)
+SMDS_MeshElement* SMESH_MeshEditor::AddElement(const vector<int> & nodeIDs,
+                                               const ElemFeatures& features)
 {
   vector<const SMDS_MeshNode*> nodes;
   nodes.reserve( nodeIDs.size() );
@@ -341,7 +388,7 @@ SMDS_MeshElement* SMESH_MeshEditor::AddElement(const vector<int> &       nodeIDs
     else
       return 0;
   }
-  return AddElement( nodes, type, isPoly, ID );
+  return AddElement( nodes, features );
 }
 
 //=======================================================================
@@ -1100,12 +1147,12 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
   else // other elements
   {
     vector<const SMDS_MeshNode*> nodes( theElem->begin_nodes(), theElem->end_nodes() );
-    const std::vector<int>& interlace = SMDS_MeshCell::reverseSmdsOrder( geomType );
+    const std::vector<int>& interlace = SMDS_MeshCell::reverseSmdsOrder( geomType, nodes.size() );
     if ( interlace.empty() )
     {
-      std::reverse( nodes.begin(), nodes.end() ); // polygon
+      std::reverse( nodes.begin(), nodes.end() ); // obsolete, just in case
     }
-    else if ( interlace.size() > 1 )
+    else
     {
       SMDS_MeshCell::applyInterlace( interlace, nodes );
     }
@@ -4326,7 +4373,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
     }
     else
     {
-      const vector<int>& ind = SMDS_MeshCell::reverseSmdsOrder( baseType );
+      const vector<int>& ind = SMDS_MeshCell::reverseSmdsOrder( baseType, nbNodes );
       SMDS_MeshCell::applyInterlace( ind, itNN );
       SMDS_MeshCell::applyInterlace( ind, prevNod );
       SMDS_MeshCell::applyInterlace( ind, nextNod );
@@ -4379,6 +4426,17 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
     iOpposSame   = ( iSameNode - 2 < 0  ? iSameNode + 2 : iSameNode - 2 );
   }
 
+  if ( baseType == SMDSEntity_Polygon )
+  {
+    if      ( nbNodes == 3 ) baseType = SMDSEntity_Triangle;
+    else if ( nbNodes == 4 ) baseType = SMDSEntity_Quadrangle;
+  }
+  else if ( baseType == SMDSEntity_Quad_Polygon )
+  {
+    if      ( nbNodes == 6 ) baseType = SMDSEntity_Quad_Triangle;
+    else if ( nbNodes == 8 ) baseType = SMDSEntity_Quad_Quadrangle;
+  }
+
   // make new elements
   for (int iStep = 0; iStep < nbSteps; iStep++ )
   {
@@ -4524,7 +4582,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
         break;
       }
       case SMDSEntity_Quad_Triangle:  // sweep (Bi)Quadratic TRIANGLE --->
-      case SMDSEntity_BiQuad_Triangle: /* ??? */ { 
+      case SMDSEntity_BiQuad_Triangle: /* ??? */ {
         if ( nbDouble+nbSame != 3 ) break;
         if(nbSame==0) {
           // --->  pentahedron with 15 nodes
@@ -4652,7 +4710,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
     {
       if ( baseType != SMDSEntity_Polygon )
       {
-        const std::vector<int>& ind = SMDS_MeshCell::interlacedSmdsOrder(baseType);
+        const std::vector<int>& ind = SMDS_MeshCell::interlacedSmdsOrder(baseType,nbNodes);
         SMDS_MeshCell::applyInterlace( ind, prevNod );
         SMDS_MeshCell::applyInterlace( ind, nextNod );
         SMDS_MeshCell::applyInterlace( ind, midlNod );
@@ -4677,21 +4735,30 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
       quantities.push_back( nbNodes );
 
       // side faces
-      for (int iface = 0; iface < nbNodes; iface++)
+      // 3--6--2
+      // |     |
+      // 7     5
+      // |     |
+      // 0--4--1
+      const int iQuad = elem->IsQuadratic();
+      for (int iface = 0; iface < nbNodes; iface += 1+iQuad )
       {
-        const int prevNbNodes = polyedre_nodes.size();
-        int inextface = (iface+1) % nbNodes;
-        polyedre_nodes.push_back( prevNod[inextface] );
-        polyedre_nodes.push_back( prevNod[iface] );
-        if ( prevNod[iface] != nextNod[iface] )
+        const int prevNbNodes = polyedre_nodes.size(); // to detect degenerated face
+        int inextface = (iface+1+iQuad) % nbNodes;
+        int imid      = (iface+1) % nbNodes;
+        polyedre_nodes.push_back( prevNod[inextface] );         // 0
+        if ( iQuad ) polyedre_nodes.push_back( prevNod[imid] ); // 4
+        polyedre_nodes.push_back( prevNod[iface] );             // 1
+        if ( prevNod[iface] != nextNod[iface] ) // 1 != 2
         {
-          if ( midlNod[ iface ]) polyedre_nodes.push_back( midlNod[ iface ]);
-          polyedre_nodes.push_back( nextNod[iface] );
+          if ( midlNod[ iface ]) polyedre_nodes.push_back( midlNod[ iface ]); // 5
+          polyedre_nodes.push_back( nextNod[iface] );                         // 2
         }
-        if ( prevNod[inextface] != nextNod[inextface] )
+        if ( iQuad ) polyedre_nodes.push_back( nextNod[imid] );               // 6
+        if ( prevNod[inextface] != nextNod[inextface] ) // 0 != 3
         {
-          polyedre_nodes.push_back( nextNod[inextface] );
-          if ( midlNod[ inextface ]) polyedre_nodes.push_back( midlNod[ inextface ]);
+          polyedre_nodes.push_back( nextNod[inextface] );                            // 3
+          if ( midlNod[ inextface ]) polyedre_nodes.push_back( midlNod[ inextface ]);// 7
         }
         const int nbFaceNodes = polyedre_nodes.size() - prevNbNodes;
         if ( nbFaceNodes > 2 )
@@ -4701,7 +4768,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
       }
       aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities);
 
-    } //  // try to create a polyherdal prism
+    } // try to create a polyherdal prism
 
     if ( aNewElem ) {
       newElems.push_back( aNewElem );
@@ -4752,13 +4819,14 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
     const SMDS_MeshElement* el = 0;
     SMDSAbs_ElementType highType = SMDSAbs_Edge; // count most complex elements only
     while ( eIt->more() && nbInitElems < 2 ) {
-      el = eIt->next();
-      SMDSAbs_ElementType type = el->GetType();
+      const SMDS_MeshElement* e = eIt->next();
+      SMDSAbs_ElementType type = e->GetType();
       if ( type == SMDSAbs_Volume || type < highType ) continue;
       if ( type > highType ) {
         nbInitElems = 0;
         highType = type;
       }
+      el = e;
       nbInitElems += elemSet.count(el);
     }
     if ( nbInitElems < 2 ) {
@@ -4774,6 +4842,8 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
   // Make a ceiling for each element ie an equal element of last new nodes.
   // Find free links of faces - make edges and sweep them into faces.
 
+  ElemFeatures polyFace( SMDSAbs_Face, /*isPoly=*/true ), anyFace;
+
   TTElemOfElemListMap::iterator  itElem      = newElemsMap.begin();
   TElemOfVecOfNnlmiMap::iterator itElemNodes = elemNewNodesMap.begin();
   for ( ; itElem != newElemsMap.end(); itElem++, itElemNodes++ )
@@ -4877,7 +4947,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
 
     // sweep free links into faces
 
-    if ( hasFreeLinks )  {
+    if ( hasFreeLinks ) {
       list<const SMDS_MeshElement*> & newVolumes = itElem->second;
       int iVol, volNb, nbVolumesByStep = newVolumes.size() / nbSteps;
 
@@ -4911,11 +4981,12 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
             freeInd.push_back( iF );
             // find source edge of a free face iF
             vector<const SMDS_MeshNode*> commonNodes; // shared by the initial and free faces
-            commonNodes.resize( initNodeSet.size(), NULL ); // avoid spoiling memory
-            std::set_intersection( faceNodeSet.begin(), faceNodeSet.end(),
-                                   initNodeSet.begin(), initNodeSet.end(),
-                                   commonNodes.begin());
-            if ( (*v)->IsQuadratic() )
+            vector<const SMDS_MeshNode*>::iterator lastCommom;
+            commonNodes.resize( nbNodes, 0 );
+            lastCommom = std::set_intersection( faceNodeSet.begin(), faceNodeSet.end(),
+                                                initNodeSet.begin(), initNodeSet.end(),
+                                                commonNodes.begin());
+            if ( std::distance( commonNodes.begin(), lastCommom ) == 3 )
               srcEdges.push_back(aMesh->FindEdge (commonNodes[0],commonNodes[1],commonNodes[2]));
             else
               srcEdges.push_back(aMesh->FindEdge (commonNodes[0],commonNodes[1]));
@@ -4931,10 +5002,11 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
         if ( freeInd.empty() )
           continue;
 
-        // create faces for all steps;
+        // create wall faces for all steps;
         // if such a face has been already created by sweep of edge,
         // assure that its orientation is OK
-        for ( int iStep = 0; iStep < nbSteps; iStep++ ) {
+        for ( int iStep = 0; iStep < nbSteps; iStep++ )
+        {
           vTool.Set( *v, /*ignoreCentralNodes=*/false );
           vTool.SetExternalNormal();
           const int nextShift = vTool.IsForward() ? +1 : -1;
@@ -5061,7 +5133,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
                 if ( f )
                   aMesh->ChangeElementNodes( f, &polygon_nodes[0], nbn );
                 else
-                  AddElement(polygon_nodes, SMDSAbs_Face, polygon_nodes.size()>4);
+                  AddElement( polygon_nodes, polyFace.SetQuad( (*v)->IsQuadratic() ));
               }
             }
 
@@ -5088,36 +5160,21 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
       aFaceLastNodes.erase( vecNewNodes.back()->second.back() );
       iF = lastVol.GetFaceIndex( aFaceLastNodes );
     }
-    if ( iF >= 0 ) {
+    if ( iF >= 0 )
+    {
       lastVol.SetExternalNormal();
       const SMDS_MeshNode** nodes = lastVol.GetFaceNodes( iF );
-      int nbn = lastVol.NbFaceNodes( iF );
-      // we do not use this->AddElement() because nodes are interlaced
+      const               int nbn = lastVol.NbFaceNodes( iF );
       vector<const SMDS_MeshNode*> nodeVec( nodes, nodes+nbn );
       if ( !hasFreeLinks ||
            !aMesh->FindElement( nodeVec, SMDSAbs_Face, /*noMedium=*/false) )
       {
-        if ( nbn == 3 )
-          myLastCreatedElems.Append(aMesh->AddFace( nodes[0], nodes[1], nodes[2] ));
-
-        else if ( nbn == 4 )
-          myLastCreatedElems.Append(aMesh->AddFace( nodes[0], nodes[1], nodes[2], nodes[3]));
-
-        else if ( nbn == 6 && isQuadratic )
-          myLastCreatedElems.Append(aMesh->AddFace( nodes[0], nodes[2], nodes[4],
-                                                    nodes[1], nodes[3], nodes[5]));
-        else if ( nbn == 7 && isQuadratic )
-          myLastCreatedElems.Append(aMesh->AddFace( nodes[0], nodes[2], nodes[4],
-                                                    nodes[1], nodes[3], nodes[5], nodes[6]));
-        else if ( nbn == 8 && isQuadratic )
-          myLastCreatedElems.Append(aMesh->AddFace( nodes[0], nodes[2], nodes[4], nodes[6],
-                                                    nodes[1], nodes[3], nodes[5], nodes[7]));
-        else if ( nbn == 9 && isQuadratic )
-          myLastCreatedElems.Append(aMesh->AddFace( nodes[0], nodes[2], nodes[4], nodes[6],
-                                                    nodes[1], nodes[3], nodes[5], nodes[7],
-                                                    nodes[8]));
-        else
-          myLastCreatedElems.Append(aMesh->AddPolygonalFace( nodeVec ));
+        const vector<int>& interlace =
+          SMDS_MeshCell::interlacedSmdsOrder( elem->GetEntityType(), nbn );
+        SMDS_MeshCell::applyInterlaceRev( interlace, nodeVec );
+
+        if ( const SMDS_MeshElement* face = AddElement( nodeVec, anyFace.Init( elem )))
+          myLastCreatedElems.Append( face );
 
         while ( srcElements.Length() < myLastCreatedElems.Length() )
           srcElements.Append( elem );
@@ -5181,7 +5238,6 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet   theElemSets[2],
       SMDS_ElemIteratorPtr itN = elem->nodesIterator();
       while ( itN->more() )
       {
-        // check if a node has been already sweeped
         const SMDS_MeshNode* node = cast2Node( itN->next() );
 
         gp_XYZ aXYZ( node->X(), node->Y(), node->Z() );
@@ -5189,6 +5245,7 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet   theElemSets[2],
         aXYZ.Coord( coord[0], coord[1], coord[2] );
         bool isOnAxis = ( aLine.SquareDistance( aXYZ ) <= aSqTol );
 
+        // check if a node has been already sweeped
         TNodeOfNodeListMapItr nIt =
           mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
         list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
@@ -6551,10 +6608,12 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
     groupPostfix = "transformed";
   }
 
-  SMESH_MeshEditor targetMeshEditor( theTargetMesh );
   SMESHDS_Mesh* aTgtMesh = theTargetMesh ? theTargetMesh->GetMeshDS() : 0;
   SMESHDS_Mesh* aMesh    = GetMeshDS();
 
+  SMESH_MeshEditor targetMeshEditor( theTargetMesh );
+  SMESH_MeshEditor* editor = theTargetMesh ? & targetMeshEditor : theCopy ? this : 0;
+  SMESH_MeshEditor::ElemFeatures elemType;
 
   // map old node to new one
   TNodeNodeMap nodeMap;
@@ -6586,70 +6645,68 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
 
   // loop on elements to transform nodes : first orphan nodes then elems
   TIDSortedElemSet::iterator itElem;
-  TIDSortedElemSet *elements[] = {&orphanNode, &theElems };
+  TIDSortedElemSet *elements[] = { &orphanNode, &theElems };
   for (int i=0; i<2; i++)
-  for ( itElem = elements[i]->begin(); itElem != elements[i]->end(); itElem++ ) {
-    const SMDS_MeshElement* elem = *itElem;
-    if ( !elem )
-      continue;
-
-    // loop on elem nodes
-    SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-    while ( itN->more() ) {
-
-      const SMDS_MeshNode* node = cast2Node( itN->next() );
-      // check if a node has been already transformed
-      pair<TNodeNodeMap::iterator,bool> n2n_isnew =
-        nodeMap.insert( make_pair ( node, node ));
-      if ( !n2n_isnew.second )
+    for ( itElem = elements[i]->begin(); itElem != elements[i]->end(); itElem++ )
+    {
+      const SMDS_MeshElement* elem = *itElem;
+      if ( !elem )
         continue;
 
+      // loop on elem nodes
       double coord[3];
-      coord[0] = node->X();
-      coord[1] = node->Y();
-      coord[2] = node->Z();
-      theTrsf.Transforms( coord[0], coord[1], coord[2] );
-      if ( theTargetMesh ) {
-        const SMDS_MeshNode * newNode = aTgtMesh->AddNode( coord[0], coord[1], coord[2] );
-        n2n_isnew.first->second = newNode;
-        myLastCreatedNodes.Append(newNode);
-        srcNodes.Append( node );
-      }
-      else if ( theCopy ) {
-        const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
-        n2n_isnew.first->second = newNode;
-        myLastCreatedNodes.Append(newNode);
-        srcNodes.Append( node );
-      }
-      else {
-        aMesh->MoveNode( node, coord[0], coord[1], coord[2] );
-        // node position on shape becomes invalid
-        const_cast< SMDS_MeshNode* > ( node )->SetPosition
-          ( SMDS_SpacePosition::originSpacePosition() );
-      }
+      SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+      while ( itN->more() )
+      {
+        const SMDS_MeshNode* node = cast2Node( itN->next() );
+        // check if a node has been already transformed
+        pair<TNodeNodeMap::iterator,bool> n2n_isnew =
+          nodeMap.insert( make_pair ( node, node ));
+        if ( !n2n_isnew.second )
+          continue;
 
-      // keep inverse elements
-      if ( !theCopy && !theTargetMesh && needReverse ) {
-        SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
-        while ( invElemIt->more() ) {
-          const SMDS_MeshElement* iel = invElemIt->next();
-          inverseElemSet.insert( iel );
+        node->GetXYZ( coord );
+        theTrsf.Transforms( coord[0], coord[1], coord[2] );
+        if ( theTargetMesh ) {
+          const SMDS_MeshNode * newNode = aTgtMesh->AddNode( coord[0], coord[1], coord[2] );
+          n2n_isnew.first->second = newNode;
+          myLastCreatedNodes.Append(newNode);
+          srcNodes.Append( node );
+        }
+        else if ( theCopy ) {
+          const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+          n2n_isnew.first->second = newNode;
+          myLastCreatedNodes.Append(newNode);
+          srcNodes.Append( node );
+        }
+        else {
+          aMesh->MoveNode( node, coord[0], coord[1], coord[2] );
+          // node position on shape becomes invalid
+          const_cast< SMDS_MeshNode* > ( node )->SetPosition
+            ( SMDS_SpacePosition::originSpacePosition() );
+        }
+
+        // keep inverse elements
+        if ( !theCopy && !theTargetMesh && needReverse ) {
+          SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
+          while ( invElemIt->more() ) {
+            const SMDS_MeshElement* iel = invElemIt->next();
+            inverseElemSet.insert( iel );
+          }
         }
       }
-    }
-  }
+    } // loop on elems in { &orphanNode, &theElems };
 
   // either create new elements or reverse mirrored ones
   if ( !theCopy && !needReverse && !theTargetMesh )
     return PGroupIDs();
 
-  TIDSortedElemSet::iterator invElemIt = inverseElemSet.begin();
-  for ( ; invElemIt != inverseElemSet.end(); invElemIt++ )
-    theElems.insert( *invElemIt );
+  theElems.insert( inverseElemSet.begin(),inverseElemSet.end() );
 
   // Replicate or reverse elements
 
   std::vector<int> iForw;
+  vector<const SMDS_MeshNode*> nodes;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
   {
     const SMDS_MeshElement* elem = *itElem;
@@ -6659,123 +6716,45 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
     int                  nbNodes  = elem->NbNodes();
     if ( geomType == SMDSGeom_NONE ) continue; // node
 
-    switch ( geomType ) {
+    nodes.resize( nbNodes );
 
-    case SMDSGeom_POLYGON:  // ---------------------- polygon
+    if ( geomType == SMDSGeom_POLYHEDRA )  // ------------------ polyhedral volume
+    {
+      const SMDS_VtkVolume* aPolyedre = dynamic_cast<const SMDS_VtkVolume*>( elem );
+      if (!aPolyedre)
+        continue;
+      nodes.clear();
+      bool allTransformed = true;
+      int nbFaces = aPolyedre->NbFaces();
+      for (int iface = 1; iface <= nbFaces && allTransformed; iface++)
       {
-        vector<const SMDS_MeshNode*> poly_nodes (nbNodes);
-        int iNode = 0;
-        SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-        while (itN->more()) {
-          const SMDS_MeshNode* node =
-            static_cast<const SMDS_MeshNode*>(itN->next());
+        int nbFaceNodes = aPolyedre->NbFaceNodes(iface);
+        for (int inode = 1; inode <= nbFaceNodes && allTransformed; inode++)
+        {
+          const SMDS_MeshNode* node = aPolyedre->GetFaceNode(iface, inode);
           TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node);
-          if (nodeMapIt == nodeMap.end())
-            break; // not all nodes transformed
-          if (needReverse) {
-            // reverse mirrored faces and volumes
-            poly_nodes[nbNodes - iNode - 1] = (*nodeMapIt).second;
-          } else {
-            poly_nodes[iNode] = (*nodeMapIt).second;
-          }
-          iNode++;
-        }
-        if ( iNode != nbNodes )
-          continue; // not all nodes transformed
-
-        if ( theTargetMesh ) {
-          myLastCreatedElems.Append(aTgtMesh->AddPolygonalFace(poly_nodes));
-          srcElems.Append( elem );
-        }
-        else if ( theCopy ) {
-          myLastCreatedElems.Append(aMesh->AddPolygonalFace(poly_nodes));
-          srcElems.Append( elem );
-        }
-        else {
-          aMesh->ChangePolygonNodes(elem, poly_nodes);
-        }
-      }
-      break;
-
-    case SMDSGeom_POLYHEDRA:  // ------------------ polyhedral volume
-      {
-        const SMDS_VtkVolume* aPolyedre =
-          dynamic_cast<const SMDS_VtkVolume*>( elem );
-        if (!aPolyedre) {
-          MESSAGE("Warning: bad volumic element");
-          continue;
-        }
-
-        vector<const SMDS_MeshNode*> poly_nodes; poly_nodes.reserve( nbNodes );
-        vector<int> quantities; quantities.reserve( nbNodes );
-
-        bool allTransformed = true;
-        int nbFaces = aPolyedre->NbFaces();
-        for (int iface = 1; iface <= nbFaces && allTransformed; iface++) {
-          int nbFaceNodes = aPolyedre->NbFaceNodes(iface);
-          for (int inode = 1; inode <= nbFaceNodes && allTransformed; inode++) {
-            const SMDS_MeshNode* node = aPolyedre->GetFaceNode(iface, inode);
-            TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node);
-            if (nodeMapIt == nodeMap.end()) {
-              allTransformed = false; // not all nodes transformed
-            } else {
-              poly_nodes.push_back((*nodeMapIt).second);
-            }
-            if ( needReverse && allTransformed )
-              std::reverse( poly_nodes.end() - nbFaceNodes, poly_nodes.end() );
-          }
-          quantities.push_back(nbFaceNodes);
-        }
-        if ( !allTransformed )
-          continue; // not all nodes transformed
-
-        if ( theTargetMesh ) {
-          myLastCreatedElems.Append(aTgtMesh->AddPolyhedralVolume(poly_nodes, quantities));
-          srcElems.Append( elem );
-        }
-        else if ( theCopy ) {
-          myLastCreatedElems.Append(aMesh->AddPolyhedralVolume(poly_nodes, quantities));
-          srcElems.Append( elem );
-        }
-        else {
-          aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
-        }
-      }
-      break;
-
-    case SMDSGeom_BALL: // -------------------- Ball
-      {
-        if ( !theCopy && !theTargetMesh ) continue;
-
-        TNodeNodeMap::iterator nodeMapIt = nodeMap.find( elem->GetNode(0) );
-        if (nodeMapIt == nodeMap.end())
-          continue; // not all nodes transformed
-
-        double diameter = static_cast<const SMDS_BallElement*>(elem)->GetDiameter();
-        if ( theTargetMesh ) {
-          myLastCreatedElems.Append(aTgtMesh->AddBall( nodeMapIt->second, diameter ));
-          srcElems.Append( elem );
-        }
-        else {
-          myLastCreatedElems.Append(aMesh->AddBall( nodeMapIt->second, diameter ));
-          srcElems.Append( elem );
+          if ( nodeMapIt == nodeMap.end() )
+            allTransformed = false; // not all nodes transformed
+          else
+            nodes.push_back((*nodeMapIt).second);
         }
+        if ( needReverse && allTransformed )
+          std::reverse( nodes.end() - nbFaceNodes, nodes.end() );
       }
-      break;
-
-    default: // ----------------------- Regular elements
-
+      if ( !allTransformed )
+        continue; // not all nodes transformed
+    }
+    else // ----------------------- the rest element types
+    {
       while ( iForw.size() < nbNodes ) iForw.push_back( iForw.size() );
-      const std::vector<int>& iRev = SMDS_MeshCell::reverseSmdsOrder( elem->GetEntityType() );
-      const std::vector<int>& i = needReverse ? iRev : iForw;
+      const vector<int>& iRev = SMDS_MeshCell::reverseSmdsOrder( elem->GetEntityType(), nbNodes );
+      const vector<int>&    i = needReverse ? iRev : iForw;
 
       // find transformed nodes
-      vector<const SMDS_MeshNode*> nodes(nbNodes);
       int iNode = 0;
       SMDS_ElemIteratorPtr itN = elem->nodesIterator();
       while ( itN->more() ) {
-        const SMDS_MeshNode* node =
-          static_cast<const SMDS_MeshNode*>( itN->next() );
+        const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( itN->next() );
         TNodeNodeMap::iterator nodeMapIt = nodeMap.find( node );
         if ( nodeMapIt == nodeMap.end() )
           break; // not all nodes transformed
@@ -6783,27 +6762,24 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
       }
       if ( iNode != nbNodes )
         continue; // not all nodes transformed
+    }
 
-      if ( theTargetMesh ) {
-        if ( SMDS_MeshElement* copy =
-             targetMeshEditor.AddElement( nodes, elem->GetType(), elem->IsPoly() )) {
-          myLastCreatedElems.Append( copy );
-          srcElems.Append( elem );
-        }
-      }
-      else if ( theCopy ) {
-        if ( AddElement( nodes, elem->GetType(), elem->IsPoly() ))
-          srcElems.Append( elem );
-      }
-      else {
-        // reverse element as it was reversed by transformation
-        if ( nbNodes > 2 )
-          aMesh->ChangeElementNodes( elem, &nodes[0], nbNodes );
-      }
-    } // switch ( geomType )
+    if ( editor ) {
+      // copy in this or a new mesh
+      if ( editor->AddElement( nodes, elemType.Init( elem, /*basicOnly=*/false )))
+        srcElems.Append( elem );
+    }
+    else {
+      // reverse element as it was reversed by transformation
+      if ( nbNodes > 2 )
+        aMesh->ChangeElementNodes( elem, &nodes[0], nbNodes );
+    }
 
   } // loop on elements
 
+  if ( editor && editor != this )
+    myLastCreatedElems = editor->myLastCreatedElems;
+
   PGroupIDs newGroupIDs;
 
   if ( ( theMakeGroups && theCopy ) ||
@@ -7032,7 +7008,7 @@ void SMESH_MeshEditor::FindCoincidentNodes (TIDSortedNodeSet &   theNodes,
 
 //=======================================================================
 //function : SimplifyFace
-//purpose  :
+//purpose  : split a chain of nodes into several closed chains
 //=======================================================================
 
 int SMESH_MeshEditor::SimplifyFace (const vector<const SMDS_MeshNode *>& faceNodes,
@@ -7164,29 +7140,34 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
   }
   // Change element nodes or remove an element
 
+  set<const SMDS_MeshNode*> nodeSet;
+  vector< const SMDS_MeshNode*> curNodes, uniqueNodes;
+  vector<int> iRepl;
+  ElemFeatures elemType;
+
   set<const SMDS_MeshElement*>::iterator eIt = elems.begin();
-  for ( ; eIt != elems.end(); eIt++ ) {
+  for ( ; eIt != elems.end(); eIt++ )
+  {
     const SMDS_MeshElement* elem = *eIt;
-    //MESSAGE(" ---- inverse elem on node to remove " << elem->GetID());
     int nbNodes = elem->NbNodes();
     int aShapeId = FindShape( elem );
 
-    set<const SMDS_MeshNode*> nodeSet;
-    vector< const SMDS_MeshNode*> curNodes( nbNodes ), uniqueNodes( nbNodes );
+    nodeSet.clear();
+    curNodes.resize( nbNodes );
+    uniqueNodes.resize( nbNodes );
+    iRepl.resize( nbNodes );
     int iUnique = 0, iCur = 0, nbRepl = 0;
-    vector<int> iRepl( nbNodes );
 
     // get new seq of nodes
     SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-    while ( itN->more() ) {
-      const SMDS_MeshNode* n =
-        static_cast<const SMDS_MeshNode*>( itN->next() );
+    while ( itN->more() )
+    {
+      const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( itN->next() );
 
       TNodeNodeMap::iterator nnIt = nodeNodeMap.find( n );
       if ( nnIt != nodeNodeMap.end() ) { // n sticks
         n = (*nnIt).second;
-        // BUG 0020185: begin
-        {
+        { ////////// BUG 0020185: begin
           bool stopRecur = false;
           set<const SMDS_MeshNode*> nodesRecur;
           nodesRecur.insert(n);
@@ -7202,8 +7183,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
             else
               stopRecur = true;
           }
-        }
-        // BUG 0020185: end
+        } ////////// BUG 0020185: end
       }
       curNodes[ iCur ] = n;
       bool isUnique = nodeSet.insert( n ).second;
@@ -7218,56 +7198,54 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
 
     bool isOk = true;
     int nbUniqueNodes = nodeSet.size();
-    //MESSAGE("nbNodes nbUniqueNodes " << nbNodes << " " << nbUniqueNodes);
-    if ( nbNodes != nbUniqueNodes ) { // some nodes stick
-      // Polygons and Polyhedral volumes
-      if (elem->IsPoly()) {
-
-        if (elem->GetType() == SMDSAbs_Face) {
-          // Polygon
-          vector<const SMDS_MeshNode *> face_nodes (nbNodes);
-          int inode = 0;
-          for (; inode < nbNodes; inode++) {
-            face_nodes[inode] = curNodes[inode];
-          }
+    if ( nbNodes != nbUniqueNodes ) // some nodes stick
+    {
+      if (elem->IsPoly()) // Polygons and Polyhedral volumes
+      {
+        if (elem->GetType() == SMDSAbs_Face) // Polygon
+        {
+          elemType.Init( elem );
+          const bool isQuad = elemType.myIsQuad;
+          if ( isQuad )
+            SMDS_MeshCell::applyInterlace // interlace medium and corner nodes
+              ( SMDS_MeshCell::interlacedSmdsOrder( SMDSEntity_Quad_Polygon, nbNodes ), curNodes );
 
+          // a polygon can divide into several elements
           vector<const SMDS_MeshNode *> polygons_nodes;
           vector<int> quantities;
-          int nbNew = SimplifyFace(face_nodes, polygons_nodes, quantities);
-          if (nbNew > 0) {
-            inode = 0;
-            for (int iface = 0; iface < nbNew; iface++) {
-              int nbNodes = quantities[iface];
-              vector<const SMDS_MeshNode *> poly_nodes (nbNodes);
-              for (int ii = 0; ii < nbNodes; ii++, inode++) {
-                poly_nodes[ii] = polygons_nodes[inode];
+          int nbNew = SimplifyFace( curNodes, polygons_nodes, quantities );
+          if (nbNew > 0)
+          {
+            vector<const SMDS_MeshNode *> face_nodes;
+            int inode = 0;
+            for (int iface = 0; iface < nbNew; iface++)
+            {
+              int nbNewNodes = quantities[iface];
+              face_nodes.assign( polygons_nodes.begin() + inode,
+                                 polygons_nodes.begin() + inode + nbNewNodes );
+              inode += nbNewNodes;
+              if ( isQuad ) // check if a result elem is a valid quadratic polygon
+              {
+                bool isValid = ( nbNewNodes % 2 == 0 );
+                for ( int i = 0; i < nbNewNodes && isValid; ++i )
+                  isValid = ( elem->IsMediumNode( face_nodes[i]) == bool( i % 2 ));
+                elemType.SetQuad( isValid );
+                if ( isValid ) // put medium nodes after corners
+                  SMDS_MeshCell::applyInterlaceRev
+                    ( SMDS_MeshCell::interlacedSmdsOrder( SMDSEntity_Quad_Polygon,
+                                                          nbNewNodes ), face_nodes );
               }
-              SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes);
-              myLastCreatedElems.Append(newElem);
-              if (aShapeId)
+              SMDS_MeshElement* newElem = AddElement( face_nodes, elemType );
+              if ( aShapeId )
                 aMesh->SetMeshElementOnShape(newElem, aShapeId);
             }
-
-            MESSAGE("ChangeElementNodes MergeNodes Polygon");
-            //aMesh->ChangeElementNodes(elem, &polygons_nodes[inode], quantities[nbNew - 1]);
-            vector<const SMDS_MeshNode *> polynodes(polygons_nodes.begin()+inode,polygons_nodes.end());
-            int quid =0;
-            if (nbNew > 0) quid = nbNew - 1;
-            vector<int> newquant(quantities.begin()+quid, quantities.end());
-            const SMDS_MeshElement* newElem = 0;
-            newElem = aMesh->AddPolyhedralVolume(polynodes, newquant);
-            myLastCreatedElems.Append(newElem);
-            if ( aShapeId && newElem )
-              aMesh->SetMeshElementOnShape( newElem, aShapeId );
-            rmElemIds.push_back(elem->GetID());
-          }
-          else {
-            rmElemIds.push_back(elem->GetID());
           }
+          rmElemIds.push_back(elem->GetID());
 
-        }
-        else if (elem->GetType() == SMDSAbs_Volume) {
-          // Polyhedral volume
+        } // Polygon
+
+        else if (elem->GetType() == SMDSAbs_Volume) // Polyhedral volume
+        {
           if (nbUniqueNodes < 4) {
             rmElemIds.push_back(elem->GetID());
           }
@@ -7302,16 +7280,15 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
               }
 
               if (quantities.size() > 3)
-                {
-                  MESSAGE("ChangeElementNodes MergeNodes Polyhedron");
-                  //aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
-                  const SMDS_MeshElement* newElem = 0;
-                  newElem = aMesh->AddPolyhedralVolume(poly_nodes, quantities);
-                  myLastCreatedElems.Append(newElem);
-                  if ( aShapeId && newElem )
-                    aMesh->SetMeshElementOnShape( newElem, aShapeId );
-                  rmElemIds.push_back(elem->GetID());
-                }
+              {
+                //aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
+                const SMDS_MeshElement* newElem =
+                  aMesh->AddPolyhedralVolume(poly_nodes, quantities);
+                myLastCreatedElems.Append(newElem);
+                if ( aShapeId && newElem )
+                  aMesh->SetMeshElementOnShape( newElem, aShapeId );
+                rmElemIds.push_back(elem->GetID());
+              }
             }
             else {
               rmElemIds.push_back(elem->GetID());
@@ -7710,51 +7687,19 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
 
     } // if ( nbNodes != nbUniqueNodes ) // some nodes stick
 
-    if ( isOk ) { // the elem remains valid after sticking nodes
-      if (elem->IsPoly() && elem->GetType() == SMDSAbs_Volume)
-      {
-        // Change nodes of polyedre
-        const SMDS_VtkVolume* aPolyedre =
-          dynamic_cast<const SMDS_VtkVolume*>( elem );
-        if (aPolyedre) {
-          int nbFaces = aPolyedre->NbFaces();
-
-          vector<const SMDS_MeshNode *> poly_nodes;
-          vector<int> quantities (nbFaces);
-
-          for (int iface = 1; iface <= nbFaces; iface++) {
-            int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface);
-            quantities[iface - 1] = nbFaceNodes;
-
-            for (inode = 1; inode <= nbFaceNodes; inode++) {
-              const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode);
-
-              TNodeNodeMap::iterator nnIt = nodeNodeMap.find( curNode );
-              if (nnIt != nodeNodeMap.end()) { // curNode sticks
-                curNode = (*nnIt).second;
-              }
-              poly_nodes.push_back(curNode);
-            }
-          }
-          aMesh->ChangePolyhedronNodes( elem, poly_nodes, quantities );
-        }
-      }
-      else // replace non-polyhedron elements
-      {
-        const SMDSAbs_ElementType etyp = elem->GetType();
-        const int elemId               = elem->GetID();
-        const bool isPoly              = (elem->GetEntityType() == SMDSEntity_Polygon);
-        uniqueNodes.resize(nbUniqueNodes);
+    if ( isOk ) // the non-poly elem remains valid after sticking nodes
+    {
+      elemType.Init( elem ).SetID( elem->GetID() );
 
-        SMESHDS_SubMesh * sm = aShapeId > 0 ? aMesh->MeshElements(aShapeId) : 0;
+      SMESHDS_SubMesh * sm = aShapeId > 0 ? aMesh->MeshElements(aShapeId) : 0;
+      aMesh->RemoveFreeElement(elem, sm, /*fromGroups=*/false);
 
-        aMesh->RemoveFreeElement(elem, sm, /*fromGroups=*/false);
-        SMDS_MeshElement* newElem = this->AddElement(uniqueNodes, etyp, isPoly, elemId);
-        if ( sm && newElem )
-          sm->AddElement( newElem );
-        if ( elem != newElem )
-          ReplaceElemInGroups( elem, newElem, aMesh );
-      }
+      uniqueNodes.resize(nbUniqueNodes);
+      SMDS_MeshElement* newElem = this->AddElement( uniqueNodes, elemType );
+      if ( sm && newElem )
+        sm->AddElement( newElem );
+      if ( elem != newElem )
+        ReplaceElemInGroups( elem, newElem, aMesh );
     }
     else {
       // Remove invalid regular element or invalid polygon
@@ -7768,6 +7713,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
   Remove( rmElemIds, false );
   Remove( rmNodeIds, true );
 
+  return;
 }
 
 
@@ -8996,7 +8942,7 @@ namespace
 
 //=======================================================================
 /*!
- * \brief Convert elements contained in a submesh to quadratic
+ * \brief Convert elements contained in a sub-mesh to quadratic
  * \return int - nb of checked elements
  */
 //=======================================================================
@@ -9519,6 +9465,8 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh *    theSm,
 {
   int nbElem = 0;
   SMESHDS_Mesh* meshDS = GetMeshDS();
+  ElemFeatures elemType;
+  vector<const SMDS_MeshNode *> nodes;
 
   while( theItr->more() )
   {
@@ -9526,11 +9474,11 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh *    theSm,
     nbElem++;
     if( elem && elem->IsQuadratic())
     {
-      int id                    = elem->GetID();
-      int nbCornerNodes         = elem->NbCornerNodes();
-      SMDSAbs_ElementType aType = elem->GetType();
+      // get elem data
+      int nbCornerNodes = elem->NbCornerNodes();
+      nodes.assign( elem->begin_nodes(), elem->end_nodes() );
 
-      vector<const SMDS_MeshNode *> nodes( elem->begin_nodes(), elem->end_nodes() );
+      elemType.Init( elem, /*basicOnly=*/false ).SetID( elem->GetID() ).SetQuad( false );
 
       //remove a quadratic element
       if ( !theSm || !theSm->Contains( elem ))
@@ -9538,13 +9486,13 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh *    theSm,
       meshDS->RemoveFreeElement( elem, theSm, /*fromGroups=*/false );
 
       // remove medium nodes
-      for ( unsigned i = nbCornerNodes; i < nodes.size(); ++i )
+      for ( size_t i = nbCornerNodes; i < nodes.size(); ++i )
         if ( nodes[i]->NbInverseElements() == 0 )
           meshDS->RemoveFreeNode( nodes[i], theSm );
 
       // add a linear element
       nodes.resize( nbCornerNodes );
-      SMDS_MeshElement * newElem = AddElement( nodes, aType, false, id );
+      SMDS_MeshElement * newElem = AddElement( nodes, elemType );
       ReplaceElemInGroups(elem, newElem, meshDS);
       if( theSm && newElem )
         theSm->AddElement( newElem );
@@ -10135,11 +10083,15 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
   if ( aResult != SEW_OK)
     return aResult;
 
-  list< int > nodeIDsToRemove/*, elemIDsToRemove*/;
+  list< int > nodeIDsToRemove;
+  vector< const SMDS_MeshNode*> nodes;
+  ElemFeatures elemType;
+
   // loop on nodes replacement map
   TNodeNodeMap::iterator nReplaceMapIt = nReplaceMap.begin(), nnIt;
   for ( ; nReplaceMapIt != nReplaceMap.end(); nReplaceMapIt++ )
-    if ( (*nReplaceMapIt).first != (*nReplaceMapIt).second ) {
+    if ( (*nReplaceMapIt).first != (*nReplaceMapIt).second )
+    {
       const SMDS_MeshNode* nToRemove = (*nReplaceMapIt).first;
       nodeIDsToRemove.push_back( nToRemove->GetID() );
       // loop on elements sharing nToRemove
@@ -10148,11 +10100,10 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
         const SMDS_MeshElement* e = invElemIt->next();
         // get a new suite of nodes: make replacement
         int nbReplaced = 0, i = 0, nbNodes = e->NbNodes();
-        vector< const SMDS_MeshNode*> nodes( nbNodes );
+        nodes.resize( nbNodes );
         SMDS_ElemIteratorPtr nIt = e->nodesIterator();
         while ( nIt->more() ) {
-          const SMDS_MeshNode* n =
-            static_cast<const SMDS_MeshNode*>( nIt->next() );
+          const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
           nnIt = nReplaceMap.find( n );
           if ( nnIt != nReplaceMap.end() ) {
             nbReplaced++;
@@ -10164,21 +10115,17 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
         //         elemIDsToRemove.push_back( e->GetID() );
         //       else
         if ( nbReplaced )
+        {
+          elemType.Init( e, /*basicOnly=*/false ).SetID( e->GetID() );
+          aMesh->RemoveElement( e );
+
+          if ( SMDS_MeshElement* newElem = this->AddElement( nodes, elemType ))
           {
-            SMDSAbs_ElementType etyp = e->GetType();
-            SMDS_MeshElement* newElem = this->AddElement(nodes, etyp, false);
-            if (newElem)
-              {
-                myLastCreatedElems.Append(newElem);
-                AddToSameGroups(newElem, e, aMesh);
-                int aShapeId = e->getshapeId();
-                if ( aShapeId )
-                  {
-                    aMesh->SetMeshElementOnShape( newElem, aShapeId );
-                  }
-              }
-            aMesh->RemoveElement(e);
+            AddToSameGroups( newElem, e, aMesh );
+            if ( int aShapeId = e->getshapeId() )
+              aMesh->SetMeshElementOnShape( newElem, aShapeId );
           }
+        }
       }
     }
 
@@ -10408,44 +10355,19 @@ void SMESH_MeshEditor::DoubleElements( const TIDSortedElemSet& theElements )
 
   // duplicate elements
 
-  if ( type == SMDSAbs_Ball )
-  {
-    SMDS_UnstructuredGrid* vtkGrid = mesh->getGrid();
-    while ( elemIt->more() )
-    {
-      const SMDS_MeshElement* elem = elemIt->next();
-      if ( elem->GetType() != SMDSAbs_Ball )
-        continue;
-      if (( elem = mesh->AddBall( elem->GetNode(0),
-                                  vtkGrid->GetBallDiameter( elem->getVtkId() ))))
-        myLastCreatedElems.Append( elem );
-    }
-  }
-  else
+  ElemFeatures elemType;
+
+  vector< const SMDS_MeshNode* > nodes;
+  while ( elemIt->more() )
   {
-    vector< const SMDS_MeshNode* > nodes;
-    while ( elemIt->more() )
-    {
-      const SMDS_MeshElement* elem = elemIt->next();
-      if ( elem->GetType() != type )
-        continue;
+    const SMDS_MeshElement* elem = elemIt->next();
+    if ( elem->GetType() != type )
+      continue;
 
-      nodes.assign( elem->begin_nodes(), elem->end_nodes() );
+    elemType.Init( elem, /*basicOnly=*/false );
+    nodes.assign( elem->begin_nodes(), elem->end_nodes() );
 
-      if ( type == SMDSAbs_Volume  && elem->GetVtkType() == VTK_POLYHEDRON )
-      {
-        std::vector<int> quantities =
-          static_cast< const SMDS_VtkVolume* >( elem )->GetQuantities();
-        elem = mesh->AddPolyhedralVolume( nodes, quantities );
-      }
-      else
-      {
-        AddElement( nodes, type, elem->IsPoly() );
-        elem = 0; // myLastCreatedElems is already filled
-      }
-      if ( elem )
-        myLastCreatedElems.Append( elem );
-    }
+    AddElement( nodes, elemType );
   }
 }
 
@@ -10476,7 +10398,7 @@ bool SMESH_MeshEditor::DoubleNodes( const TIDSortedElemSet& theElems,
     return false;
 
   bool res = false;
-  std::map< const SMDS_MeshNode*, const SMDS_MeshNode* > anOldNodeToNewNode;
+  TNodeNodeMap anOldNodeToNewNode;
   // duplicate elements and nodes
   res = doubleNodes( aMeshDS, theElems, theNodesNot, anOldNodeToNewNode, true );
   // replce nodes by duplications
@@ -10496,16 +10418,18 @@ bool SMESH_MeshEditor::DoubleNodes( const TIDSortedElemSet& theElems,
 */
 //================================================================================
 
-bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh*     theMeshDS,
-                                    const TIDSortedElemSet& theElems,
-                                    const TIDSortedElemSet& theNodesNot,
-                                    std::map< const SMDS_MeshNode*,
-                                    const SMDS_MeshNode* >& theNodeNodeMap,
-                                    const bool theIsDoubleElem )
+bool SMESH_MeshEditor::doubleNodes(SMESHDS_Mesh*           theMeshDS,
+                                   const TIDSortedElemSet& theElems,
+                                   const TIDSortedElemSet& theNodesNot,
+                                   TNodeNodeMap&           theNodeNodeMap,
+                                   const bool              theIsDoubleElem )
 {
   MESSAGE("doubleNodes");
-  // iterate on through element and duplicate them (by nodes duplication)
+  // iterate through element and duplicate them (by nodes duplication)
   bool res = false;
+  std::vector<const SMDS_MeshNode*> newNodes;
+  ElemFeatures elemType;
+
   TIDSortedElemSet::const_iterator elemItr = theElems.begin();
   for ( ;  elemItr != theElems.end(); ++elemItr )
   {
@@ -10513,19 +10437,21 @@ bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh*     theMeshDS,
     if (!anElem)
       continue;
 
-    bool isDuplicate = false;
     // duplicate nodes to duplicate element
-    std::vector<const SMDS_MeshNode*> newNodes( anElem->NbNodes() );
+    bool isDuplicate = false;
+    newNodes.resize( anElem->NbNodes() );
     SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
     int ind = 0;
     while ( anIter->more() )
     {
-
-      SMDS_MeshNode* aCurrNode = (SMDS_MeshNode*)anIter->next();
-      SMDS_MeshNode* aNewNode = aCurrNode;
-      if ( theNodeNodeMap.find( aCurrNode ) != theNodeNodeMap.end() )
-        aNewNode = (SMDS_MeshNode*)theNodeNodeMap[ aCurrNode ];
-      else if ( theIsDoubleElem && theNodesNot.find( aCurrNode ) == theNodesNot.end() )
+      const SMDS_MeshNode* aCurrNode = static_cast<const SMDS_MeshNode*>( anIter->next() );
+      const SMDS_MeshNode*  aNewNode = aCurrNode;
+      TNodeNodeMap::iterator     n2n = theNodeNodeMap.find( aCurrNode );
+      if ( n2n != theNodeNodeMap.end() )
+      {
+        aNewNode = n2n->second;
+      }
+      else if ( theIsDoubleElem && !theNodesNot.count( aCurrNode ))
       {
         // duplicate node
         aNewNode = theMeshDS->AddNode( aCurrNode->X(), aCurrNode->Y(), aCurrNode->Z() );
@@ -10540,9 +10466,9 @@ bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh*     theMeshDS,
       continue;
 
     if ( theIsDoubleElem )
-      AddElement(newNodes, anElem->GetType(), anElem->IsPoly());
+      AddElement( newNodes, elemType.Init( anElem, /*basicOnly=*/false ));
     else
-      theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], anElem->NbNodes() );
+      theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], newNodes.size() );
 
     res = true;
   }
@@ -12273,7 +12199,8 @@ bool SMESH_MeshEditor::Make2DMeshFrom3D()
   SMESHDS_Mesh* aMesh = GetMeshDS();
   if (!aMesh)
     return false;
-  //bool res = false;
+
+  ElemFeatures faceType( SMDSAbs_Face );
   int nbFree = 0, nbExisted = 0, nbCreated = 0;
   SMDS_VolumeIteratorPtr vIt = aMesh->volumesIterator();
   while(vIt->more())
@@ -12281,8 +12208,8 @@ bool SMESH_MeshEditor::Make2DMeshFrom3D()
     const SMDS_MeshVolume* volume = vIt->next();
     SMDS_VolumeTool vTool( volume, /*ignoreCentralNodes=*/false );
     vTool.SetExternalNormal();
-    //const bool isPoly = volume->IsPoly();
     const int iQuad = volume->IsQuadratic();
+    faceType.SetQuad( iQuad );
     for ( int iface = 0, n = vTool.NbFaces(); iface < n; iface++ )
     {
       if (!vTool.IsFreeFace(iface))
@@ -12294,22 +12221,27 @@ bool SMESH_MeshEditor::Make2DMeshFrom3D()
       int inode = 0;
       for ( ; inode < nbFaceNodes; inode += iQuad+1)
         nodes.push_back(faceNodes[inode]);
-      if (iQuad) { // add medium nodes
+
+      if (iQuad) // add medium nodes
+      {
         for ( inode = 1; inode < nbFaceNodes; inode += 2)
           nodes.push_back(faceNodes[inode]);
         if ( nbFaceNodes == 9 ) // bi-quadratic quad
           nodes.push_back(faceNodes[8]);
       }
       // add new face based on volume nodes
-      if (aMesh->FindElement( nodes, SMDSAbs_Face, /*noMedium=*/false) ) {
-        nbExisted++;
-        continue; // face already exsist
+      if (aMesh->FindElement( nodes, SMDSAbs_Face, /*noMedium=*/false) )
+      {
+        nbExisted++; // face already exsist
+      }
+      else
+      {
+        AddElement( nodes, faceType.SetPoly( nbFaceNodes/(iQuad+1) > 4 ));
+        nbCreated++;
       }
-      AddElement(nodes, SMDSAbs_Face, ( !iQuad && nbFaceNodes/(iQuad+1) > 4 ));
-      nbCreated++;
     }
   }
-  return ( nbFree==(nbExisted+nbCreated) );
+  return ( nbFree == ( nbExisted + nbCreated ));
 }
 
 namespace
@@ -12371,9 +12303,11 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
   SMDS_VolumeTool vTool;
   TIDSortedElemSet avoidSet;
   const TIDSortedElemSet emptySet, *elemSet = aroundElements ? &elements : &emptySet;
-  int inode;
+  size_t inode;
 
   typedef vector<const SMDS_MeshNode*> TConnectivity;
+  TConnectivity tgtNodes;
+  ElemFeatures elemKind( missType );
 
   SMDS_ElemIteratorPtr eIt;
   if (elements.empty()) eIt = aMesh->elementsIterator(elemType);
@@ -12383,6 +12317,7 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
   {
     const SMDS_MeshElement* elem = eIt->next();
     const int              iQuad = elem->IsQuadratic();
+    elemKind.SetQuad( iQuad );
 
     // ------------------------------------------------------------------------------------
     // 1. For an elem, get present bnd elements and connectivities of missing bnd elements
@@ -12400,7 +12335,7 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
              ( !aroundElements || elements.count( otherVol )))
           continue;
         const SMDS_MeshNode** nn = vTool.GetFaceNodes(iface);
-        const int    nbFaceNodes = vTool.NbFaceNodes (iface);
+        const size_t nbFaceNodes = vTool.NbFaceNodes (iface);
         if ( missType == SMDSAbs_Edge ) // boundary edges
         {
           nodes.resize( 2+iQuad );
@@ -12480,17 +12415,17 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
     if ( targetMesh != myMesh )
       // instead of making a map of nodes in this mesh and targetMesh,
       // we create nodes with same IDs.
-      for ( int i = 0; i < missingBndElems.size(); ++i )
+      for ( size_t i = 0; i < missingBndElems.size(); ++i )
       {
         TConnectivity& srcNodes = missingBndElems[i];
-        TConnectivity  nodes( srcNodes.size() );
-        for ( inode = 0; inode < nodes.size(); ++inode )
-          nodes[inode] = getNodeWithSameID( tgtMeshDS, srcNodes[inode] );
-        if ( aroundElements && tgtEditor.GetMeshDS()->FindElement( nodes,
+        tgtNodes.resize( srcNodes.size() );
+        for ( inode = 0; inode < srcNodes.size(); ++inode )
+          tgtNodes[inode] = getNodeWithSameID( tgtMeshDS, srcNodes[inode] );
+        if ( aroundElements && tgtEditor.GetMeshDS()->FindElement( tgtNodes,
                                                                    missType,
                                                                    /*noMedium=*/false))
           continue;
-        tgtEditor.AddElement(nodes, missType, !iQuad && nodes.size()/(iQuad+1)>4);
+        tgtEditor.AddElement( tgtNodes, elemKind.SetPoly( tgtNodes.size()/(iQuad+1) > 4 ));
         ++nbAddedBnd;
       }
     else
@@ -12501,16 +12436,16 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
                                                                    missType,
                                                                    /*noMedium=*/false))
           continue;
-        SMDS_MeshElement* elem =
-          tgtEditor.AddElement(nodes, missType, !iQuad && nodes.size()/(iQuad+1)>4);
-        ++nbAddedBnd;
+        SMDS_MeshElement* newElem = 
+          tgtEditor.AddElement( nodes, elemKind.SetPoly( nodes.size()/(iQuad+1) > 4 ));
+        nbAddedBnd += bool( newElem );
 
         // try to set a new element to a shape
         if ( myMesh->HasShapeToMesh() )
         {
           bool ok = true;
           set< pair<TopAbs_ShapeEnum, int > > mediumShapes;
-          const int nbN = nodes.size() / (iQuad+1 );
+          const size_t nbN = nodes.size() / (iQuad+1 );
           for ( inode = 0; inode < nbN && ok; ++inode )
           {
             pair<int, TopAbs_ShapeEnum> i_stype =
@@ -12530,7 +12465,7 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
             }
           }
           if ( ok && mediumShapes.begin()->first == missShapeType )
-            aMesh->SetMeshElementOnShape( elem, mediumShapes.begin()->second );
+            aMesh->SetMeshElementOnShape( newElem, mediumShapes.begin()->second );
         }
       }
 
@@ -12541,15 +12476,15 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
       for ( int i = 0 ; i < presentBndElems.size(); ++i )
       {
         const SMDS_MeshElement* e = presentBndElems[i];
-        TConnectivity nodes( e->NbNodes() );
+        tgtNodes.resize( e->NbNodes() );
         for ( inode = 0; inode < nodes.size(); ++inode )
-          nodes[inode] = getNodeWithSameID( tgtMeshDS, e->GetNode(inode) );
-        presentEditor->AddElement(nodes, e->GetType(), e->IsPoly());
+          tgtNodes[inode] = getNodeWithSameID( tgtMeshDS, e->GetNode(inode) );
+        presentEditor->AddElement( tgtNodes, elemKind.Init( e ));
       }
     else // store present elements to add them to a group
       for ( int i = 0 ; i < presentBndElems.size(); ++i )
       {
-        presentEditor->myLastCreatedElems.Append(presentBndElems[i]);
+        presentEditor->myLastCreatedElems.Append( presentBndElems[i] );
       }
 
   } // loop on given elements
@@ -12576,10 +12511,10 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
     while (eIt->more())
     {
       const SMDS_MeshElement* elem = eIt->next();
-      TConnectivity nodes( elem->NbNodes() );
-      for ( inode = 0; inode < nodes.size(); ++inode )
-        nodes[inode] = getNodeWithSameID( tgtMeshDS, elem->GetNode(inode) );
-      tgtEditor.AddElement(nodes, elemType, elem->IsPoly());
+      tgtNodes.resize( elem->NbNodes() );
+      for ( inode = 0; inode < tgtNodes.size(); ++inode )
+        tgtNodes[inode] = getNodeWithSameID( tgtMeshDS, elem->GetNode(inode) );
+      tgtEditor.AddElement( tgtNodes, elemKind.Init( elem ));
 
       tgtEditor.myLastCreatedElems.Clear();
     }
index 25c01f81d250281ac9b0d087ef8d777de801e1dc..cbe9466de8dc270d638effa1f9effb47cfc295da 100644 (file)
@@ -73,21 +73,49 @@ public:
   void                           ClearLastCreated();
   SMESH_ComputeErrorPtr &        GetError() { return myError; }
 
+  // --------------------------------------------------------------------------------
+  struct ElemFeatures //!< Features of element to create
+  {
+    SMDSAbs_ElementType myType;
+    bool                myIsPoly, myIsQuad;
+    int                 myID;
+    double              myBallDiameter;
+    std::vector<int>    myPolyhedQuantities;
+
+    ElemFeatures( SMDSAbs_ElementType type=SMDSAbs_All, bool isPoly=false, bool isQuad=false )
+      :myType( type ), myIsPoly(isPoly), myIsQuad(isQuad), myID(-1), myBallDiameter(0) {}
+
+    ElemFeatures& Init( SMDSAbs_ElementType type, bool isPoly=false, bool isQuad=false )
+    { myType = type; myIsPoly = isPoly; myIsQuad = isQuad; return *this; }
+
+    ElemFeatures& Init( const SMDS_MeshElement* elem, bool basicOnly=true );
+
+    ElemFeatures& Init( double diameter )
+    { myType = SMDSAbs_Ball; myBallDiameter = diameter; return *this; }
+
+    ElemFeatures& Init( vector<int>& quanities, bool isQuad=false )
+    { myType = SMDSAbs_Volume; myIsPoly = 1; myIsQuad = isQuad;
+      myPolyhedQuantities.swap( quanities ); return *this; }
+
+    ElemFeatures& Init( const vector<int>& quanities, bool isQuad=false )
+    { myType = SMDSAbs_Volume; myIsPoly = 1; myIsQuad = isQuad;
+      myPolyhedQuantities = quanities; return *this; }
+
+    ElemFeatures& SetPoly(bool isPoly) { myIsPoly = isPoly; return *this; }
+    ElemFeatures& SetQuad(bool isQuad) { myIsQuad = isQuad; return *this; }
+    ElemFeatures& SetID  (int ID)      { myID = ID; return *this; }
+  };
+
   /*!
    * \brief Add element
    */
   SMDS_MeshElement* AddElement(const std::vector<const SMDS_MeshNode*> & nodes,
-                               const SMDSAbs_ElementType                 type,
-                               const bool                                isPoly,
-                               const int                                 ID = -1,
-                               const double                              ballDiameter=0.);
+                               const ElemFeatures&                       features);
   /*!
    * \brief Add element
    */
-  SMDS_MeshElement* AddElement(const std::vector<int>  & nodeIDs,
-                               const SMDSAbs_ElementType type,
-                               const bool                isPoly,
-                               const int                 ID = -1);
+  SMDS_MeshElement* AddElement(const std::vector<int> & nodeIDs,
+                               const ElemFeatures&      features);
 
   int Remove (const std::list< int >& theElemIDs, const bool isNodes);
   // Remove a node or an element.
@@ -741,11 +769,11 @@ public:
   void LinearAngleVariation(const int     NbSteps,
                             list<double>& theAngles);
 
-  bool doubleNodes( SMESHDS_Mesh*                                           theMeshDS,
-                    const TIDSortedElemSet&                                 theElems,
-                    const TIDSortedElemSet&                                 theNodesNot,
-                    std::map< const SMDS_MeshNode*, const SMDS_MeshNode* >& theNodeNodeMap,
-                    const bool                                              theIsDoubleElem );
+  bool doubleNodes( SMESHDS_Mesh*           theMeshDS,
+                    const TIDSortedElemSet& theElems,
+                    const TIDSortedElemSet& theNodesNot,
+                    TNodeNodeMap&           theNodeNodeMap,
+                    const bool              theIsDoubleElem );
 
   void copyPosition( const SMDS_MeshNode* from,
                      const SMDS_MeshNode* to );
index 7537bf8a8b969383fa62b618213f10f8cb08d1bb..294882ac20b9ec4c60d71ad48463981345c74ea9 100644 (file)
@@ -1996,26 +1996,28 @@ SMDS_MeshFace* SMESH_MesherHelper::AddPolygonalFace (const vector<const SMDS_Mes
   SMESHDS_Mesh * meshDS = GetMeshDS();
   SMDS_MeshFace* elem = 0;
 
-  if(!myCreateQuadratic) {
+  if(!myCreateQuadratic)
+  {
     if(id)
       elem = meshDS->AddPolygonalFaceWithID(nodes, id);
     else
       elem = meshDS->AddPolygonalFace(nodes);
   }
-  else {
-    vector<const SMDS_MeshNode*> newNodes;
+  else
+  {
+    vector<const SMDS_MeshNode*> newNodes( nodes.size() * 2 );
+    newNodes = nodes;
     for ( int i = 0; i < nodes.size(); ++i )
     {
       const SMDS_MeshNode* n1 = nodes[i];
       const SMDS_MeshNode* n2 = nodes[(i+1)%nodes.size()];
       const SMDS_MeshNode* n12 = GetMediumNode( n1, n2, force3d, TopAbs_FACE );
-      newNodes.push_back( n1 );
       newNodes.push_back( n12 );
     }
     if(id)
-      elem = meshDS->AddPolygonalFaceWithID(newNodes, id);
+      elem = meshDS->AddQuadPolygonalFaceWithID(newNodes, id);
     else
-      elem = meshDS->AddPolygonalFace(newNodes);
+      elem = meshDS->AddQuadPolygonalFace(newNodes);
   }
   if ( mySetElemOnShape && myShapeID > 0 )
     meshDS->SetMeshElementOnShape( elem, myShapeID );
index 6787e0043de7e0cb9e867b3ca76503af81c1b1ec..f360512c63f1b2de891fb1f2fd785bd14b9247c5 100644 (file)
@@ -244,6 +244,33 @@ namespace
   }
 
 
+  //=======================================================================
+  //function : AddQaudPolygonsWithID
+  //=======================================================================
+  inline void AddQuadPolygonsWithID(SMDS_Mesh* theMesh,
+                                    SMESH::log_array_var& theSeq,
+                                    CORBA::Long theId)
+  {
+    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+    CORBA::Long anIndexId = 0, aNbElems = theSeq[theId].number;
+
+    for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++) {
+      int aFaceId = anIndexes[anIndexId++];
+
+      int aNbNodes = anIndexes[anIndexId++];
+      std::vector<int> nodes_ids (aNbNodes);
+      for (int i = 0; i < aNbNodes; i++) {
+        nodes_ids[i] = anIndexes[anIndexId++];
+      }
+
+      SMDS_MeshElement* anElem = theMesh->AddQuadPolygonalFaceWithID(nodes_ids, aFaceId);
+      if (!anElem)
+        EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddQaudPolygonalFaceWithID for ID = "
+                  << anElemId);
+    }
+  }
+
+
   //=======================================================================
   //function : AddTetrasWithID
   //=======================================================================
@@ -903,6 +930,7 @@ SMESH_Client::Update(bool theIsClear)
         case SMESH::ADD_QUADEDGE         : AddQuadEdgesWithID   ( mySMDSMesh, aSeq, anId ); break;
         case SMESH::ADD_QUADTRIANGLE     : AddQuadTriasWithID   ( mySMDSMesh, aSeq, anId ); break;
         case SMESH::ADD_QUADQUADRANGLE   : AddQuadQuadsWithID   ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_QUADPOLYGON      : AddQuadPolygonsWithID( mySMDSMesh, aSeq, anId ); break;
         case SMESH::ADD_QUADTETRAHEDRON  : AddQuadTetrasWithID  ( mySMDSMesh, aSeq, anId ); break;
         case SMESH::ADD_QUADPYRAMID      : AddQuadPiramidsWithID( mySMDSMesh, aSeq, anId ); break;
         case SMESH::ADD_QUADPENTAHEDRON  : AddQuadPentasWithID  ( mySMDSMesh, aSeq, anId ); break;
index 4fbd5464e1c6c22d86dadf521a10a9fb0ea78dae..b22079e6af166b84198e8a08d1352f743959a744 100644 (file)
@@ -295,6 +295,28 @@ void SMESHDS_Command::AddPolygonalFace (const int               ElementID,
   myNumber++;
 }
 
+//=======================================================================
+//function : AddQuadPolygonalFace
+//purpose  :
+//=======================================================================
+void SMESHDS_Command::AddQuadPolygonalFace (const int               ElementID,
+                                            const std::vector<int>& nodes_ids)
+{
+  if ( myType != SMESHDS_AddQuadPolygon) {
+    MESSAGE("SMESHDS_Command::AddQuadraticPolygonalFace : Bad Type");
+    return;
+  }
+  myIntegers.push_back(ElementID);
+
+  int i, nbNodes = nodes_ids.size();
+  myIntegers.push_back(nbNodes);
+  for (i = 0; i < nbNodes; i++) {
+    myIntegers.push_back(nodes_ids[i]);
+  }
+
+  myNumber++;
+}
+
 //=======================================================================
 //function : AddPolyhedralVolume
 //purpose  : 
index e52e4b7ac9ef6aefa58177aec0892c5075809dde..583cebe4a3a9e62b589c485257955862dd8afc56 100644 (file)
@@ -57,6 +57,8 @@ class SMESHDS_EXPORT SMESHDS_Command
                        int idnode9, int idnode10, int idnode11, int idnode12);
         void AddPolygonalFace (const int               ElementID,
                                const std::vector<int>& nodes_ids);
+        void AddQuadPolygonalFace (const int               ElementID,
+                                   const std::vector<int>& nodes_ids);
         void AddPolyhedralVolume (const int               ElementID,
                                   const std::vector<int>& nodes_ids,
                                   const std::vector<int>& quantities);
index a53532ddffb5182b01e8ae3c9bd912beb1b0bff2..c355386e54d9f508cbaaff717bde02ef51a026b7 100644 (file)
@@ -49,6 +49,7 @@ enum SMESHDS_CommandType {
   SMESHDS_AddQuadEdge,
   SMESHDS_AddQuadTriangle,
   SMESHDS_AddQuadQuadrangle,
+  SMESHDS_AddQuadPolygon,
   SMESHDS_AddQuadTetrahedron,
   SMESHDS_AddQuadPyramid,
   SMESHDS_AddQuadPentahedron,
index dc1e094b02c31ed4ee97b1e0e4d64d48e8ca8a16..d4a018b10c6ba96ae17965035cb2934e9158c76d 100644 (file)
@@ -213,7 +213,7 @@ void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z
 
 //=======================================================================
 //function : ChangeElementNodes
-//purpose  : 
+//purpose  : Changed nodes of an element provided that nb of nodes does not change
 //=======================================================================
 
 bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
@@ -708,9 +708,9 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector<int>& nod
   return anElem;
 }
 
-SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
-                             (const std::vector<const SMDS_MeshNode*>& nodes,
-                              const int                                ID)
+SMDS_MeshFace*
+SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*>& nodes,
+                                      const int                                ID)
 {
   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
   if (anElem) {
@@ -724,8 +724,8 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
   return anElem;
 }
 
-SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
-                             (const std::vector<const SMDS_MeshNode*>& nodes)
+SMDS_MeshFace*
+SMESHDS_Mesh::AddPolygonalFace (const std::vector<const SMDS_MeshNode*>& nodes)
 {
   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
   if (anElem) {
@@ -739,6 +739,53 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
   return anElem;
 }
 
+
+//=======================================================================
+//function : AddQuadPolygonalFace
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMESHDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<int>& nodes_ids,
+                                                         const int               ID)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes_ids, ID);
+  if (anElem) {
+    myScript->AddQuadPolygonalFace(ID, nodes_ids);
+  }
+  return anElem;
+}
+
+SMDS_MeshFace*
+SMESHDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*>& nodes,
+                                          const int                                ID)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID);
+  if (anElem) {
+    int i, len = nodes.size();
+    std::vector<int> nodes_ids (len);
+    for (i = 0; i < len; i++) {
+      nodes_ids[i] = nodes[i]->GetID();
+    }
+    myScript->AddQuadPolygonalFace(ID, nodes_ids);
+  }
+  return anElem;
+}
+
+SMDS_MeshFace*
+SMESHDS_Mesh::AddQuadPolygonalFace (const std::vector<const SMDS_MeshNode*>& nodes)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddQuadPolygonalFace(nodes);
+  if (anElem) {
+    int i, len = nodes.size();
+    std::vector<int> nodes_ids (len);
+    for (i = 0; i < len; i++) {
+      nodes_ids[i] = nodes[i]->GetID();
+    }
+    myScript->AddQuadPolygonalFace(anElem->GetID(), nodes_ids);
+  }
+  return anElem;
+}
+
+
 //=======================================================================
 //function : AddPolyhedralVolume
 //purpose  : 
index d7cf62597e9fa9ede07ecda7565ecb1839f9ab7d..6ec2d3d9cabf5c1438c63fbcf0cb005cbcb8a79c 100644 (file)
@@ -511,6 +511,14 @@ public:
 
   virtual SMDS_MeshFace* AddPolygonalFace (const std::vector<const SMDS_MeshNode*>& nodes);
 
+  virtual SMDS_MeshFace* AddQuadPolygonalFaceWithID(const std::vector<int> & nodes_ids,
+                                                    const int                ID);
+
+  virtual SMDS_MeshFace* AddQuadPolygonalFaceWithID(const std::vector<const SMDS_MeshNode*> & nodes,
+                                                    const int                                 ID);
+
+  virtual SMDS_MeshFace* AddQuadPolygonalFace(const std::vector<const SMDS_MeshNode*> & nodes);
+
   virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
                            (const std::vector<int>& nodes_ids,
                             const std::vector<int>& quantities,
index 5a5dac83bee45a40324ae79cea1872a6dc650131..e01109c3f254c9fc4909dc62614f43b74c32881e 100644 (file)
@@ -255,6 +255,19 @@ void SMESHDS_Script::AddPolygonalFace (int NewFaceID, const std::vector<int>& no
   getCommand(SMESHDS_AddPolygon)->AddPolygonalFace(NewFaceID, nodes_ids);
 }
 
+//=======================================================================
+//function : AddQuadPolygonalFace
+//purpose  : 
+//=======================================================================
+void SMESHDS_Script::AddQuadPolygonalFace(int NewFaceID, const std::vector<int>& nodes_ids)
+{
+  if(myIsEmbeddedMode){
+    myIsModified = true;
+    return;
+  }
+  getCommand(SMESHDS_AddQuadPolygon)->AddQuadPolygonalFace(NewFaceID, nodes_ids);
+}
+
 //=======================================================================
 //function : AddPolyhedralVolume
 //purpose  : 
index 72f7a44956249efb34a6caf3840bc9fb0b26cc99..3401ca6acd5cfc18d8bf07bc5693d77af02617cd 100644 (file)
@@ -64,6 +64,8 @@ class SMESHDS_EXPORT SMESHDS_Script
 
         void AddPolygonalFace (const int               NewFaceID,
                                const std::vector<int>& nodes_ids);
+        void AddQuadPolygonalFace (const int               NewFaceID,
+                                        const std::vector<int>& nodes_ids);
         void AddPolyhedralVolume (const int               NewVolID,
                                   const std::vector<int>& nodes_ids,
                                   const std::vector<int>& quantities);
index 5e507fc1387af53529d8020db0fe85d4235a7798..e434b8c4f70b731c6fe4fc215556325ab6f67f8f 100644 (file)
@@ -532,7 +532,6 @@ namespace
     {
       format = "CGNS";
       notSupportedElemTypes.push_back( SMESH::Entity_Ball );
-      notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Triangle );
     }
     else if ( isSAUV )
     {
@@ -543,6 +542,7 @@ namespace
       notSupportedElemTypes.push_back( SMESH::Entity_TriQuad_Hexa );
       notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
       notSupportedElemTypes.push_back( SMESH::Entity_Polygon );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon );
       notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
     }
     else if ( isGMF )
@@ -2079,7 +2079,7 @@ bool SMESHGUI::automaticUpdate( SMESH::SMESH_IDSource_ptr theMesh,
   long nbEdges   = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
   long nbFaces   = info[SMDSEntity_Triangle]   + info[SMDSEntity_Quad_Triangle]   + info[SMDSEntity_BiQuad_Triangle] + 
                    info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle] + 
-                   info[SMDSEntity_Polygon];
+                   info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon];
   long nbVolumes = info[SMDSEntity_Tetra]   + info[SMDSEntity_Quad_Tetra] + 
                    info[SMDSEntity_Hexa]    + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa] + 
                    info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid] + 
@@ -3274,6 +3274,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpBiQuadraticTriangle:
   case SMESHOp::OpQuadraticQuadrangle:
   case SMESHOp::OpBiQuadraticQuadrangle:
+  case SMESHOp::OpQuadraticPolygon:
   case SMESHOp::OpQuadraticTetrahedron:
   case SMESHOp::OpQuadraticPyramid:
   case SMESHOp::OpQuadraticPentahedron:
@@ -3286,15 +3287,16 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         SMDSAbs_EntityType type = SMDSEntity_Last;
 
         switch (theCommandID) {
-        case SMESHOp::OpQuadraticEdge: type = SMDSEntity_Quad_Edge; break;
-        case SMESHOp::OpQuadraticTriangle: type = SMDSEntity_Quad_Triangle; break;
-        case SMESHOp::OpBiQuadraticTriangle: type = SMDSEntity_BiQuad_Triangle; break;
-        case SMESHOp::OpQuadraticQuadrangle: type = SMDSEntity_Quad_Quadrangle; break;
-        case SMESHOp::OpBiQuadraticQuadrangle: type = SMDSEntity_BiQuad_Quadrangle; break;
-        case SMESHOp::OpQuadraticTetrahedron: type = SMDSEntity_Quad_Tetra; break;
-        case SMESHOp::OpQuadraticPyramid: type = SMDSEntity_Quad_Pyramid; break;
-        case SMESHOp::OpQuadraticPentahedron: type = SMDSEntity_Quad_Penta; break;
-        case SMESHOp::OpQuadraticHexahedron: type = SMDSEntity_Quad_Hexa; break;
+        case SMESHOp::OpQuadraticEdge:          type = SMDSEntity_Quad_Edge; break;
+        case SMESHOp::OpQuadraticTriangle:      type = SMDSEntity_Quad_Triangle; break;
+        case SMESHOp::OpBiQuadraticTriangle:    type = SMDSEntity_BiQuad_Triangle; break;
+        case SMESHOp::OpQuadraticQuadrangle:    type = SMDSEntity_Quad_Quadrangle; break;
+        case SMESHOp::OpBiQuadraticQuadrangle:  type = SMDSEntity_BiQuad_Quadrangle; break;
+        case SMESHOp::OpQuadraticPolygon:       type = SMDSEntity_Quad_Polygon; break;
+        case SMESHOp::OpQuadraticTetrahedron:   type = SMDSEntity_Quad_Tetra; break;
+        case SMESHOp::OpQuadraticPyramid:       type = SMDSEntity_Quad_Pyramid; break;
+        case SMESHOp::OpQuadraticPentahedron:   type = SMDSEntity_Quad_Penta; break;
+        case SMESHOp::OpQuadraticHexahedron:    type = SMDSEntity_Quad_Hexa; break;
         case SMESHOp::OpTriQuadraticHexahedron: type = SMDSEntity_TriQuad_Hexa; break;
         default: break;
         }
@@ -3909,6 +3911,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( SMESHOp::OpBiQuadraticTriangle,    "BIQUADRATIC_TRIANGLE",    "ICON_DLG_BIQUADRATIC_TRIANGLE" );
   createSMESHAction( SMESHOp::OpQuadraticQuadrangle,    "QUADRATIC_QUADRANGLE",    "ICON_DLG_QUADRATIC_QUADRANGLE" );
   createSMESHAction( SMESHOp::OpBiQuadraticQuadrangle,  "BIQUADRATIC_QUADRANGLE",  "ICON_DLG_BIQUADRATIC_QUADRANGLE" );
+  createSMESHAction( SMESHOp::OpQuadraticPolygon,       "QUADRATIC_POLYGON",       "ICON_DLG_QUADRATIC_POLYGON" );
   createSMESHAction( SMESHOp::OpQuadraticTetrahedron,   "QUADRATIC_TETRAHEDRON",   "ICON_DLG_QUADRATIC_TETRAHEDRON" );
   createSMESHAction( SMESHOp::OpQuadraticPyramid,       "QUADRATIC_PYRAMID",       "ICON_DLG_QUADRATIC_PYRAMID" );
   createSMESHAction( SMESHOp::OpQuadraticPentahedron,   "QUADRATIC_PENTAHEDRON",   "ICON_DLG_QUADRATIC_PENTAHEDRON" );
@@ -4139,6 +4142,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( SMESHOp::OpBiQuadraticTriangle ,   addId, -1 );
   createMenu( SMESHOp::OpQuadraticQuadrangle,    addId, -1 );
   createMenu( SMESHOp::OpBiQuadraticQuadrangle,  addId, -1 );
+  createMenu( SMESHOp::OpQuadraticPolygon,       addId, -1 );
   createMenu( SMESHOp::OpQuadraticTetrahedron,   addId, -1 );
   createMenu( SMESHOp::OpQuadraticPyramid,       addId, -1 );
   createMenu( SMESHOp::OpQuadraticPentahedron,   addId, -1 );
@@ -4276,6 +4280,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( SMESHOp::OpBiQuadraticTriangle,    addNonElemTb );
   createTool( SMESHOp::OpQuadraticQuadrangle,    addNonElemTb );
   createTool( SMESHOp::OpBiQuadraticQuadrangle,  addNonElemTb );
+  createTool( SMESHOp::OpQuadraticPolygon,       addNonElemTb );
   createTool( SMESHOp::OpQuadraticTetrahedron,   addNonElemTb );
   createTool( SMESHOp::OpQuadraticPyramid,       addNonElemTb );
   createTool( SMESHOp::OpQuadraticPentahedron,   addNonElemTb );
index 44cba417c84887f55bb10c98755ca80dc2c491db..a93494cc31eddf83720949befb879ed860283448 100644 (file)
@@ -214,12 +214,13 @@ namespace SMESH
       SetVisibility(true, theActor->GetFacesOriented(), false);
     }
 
-    void SetBallPosition(SMESH_Actor* theActor,TVTKIds& theIds, double theDiameter) {
+    void SetBallPosition(SMESH_Actor* theActor,TVTKIds& theIds, double theDiameter)
+    {
       vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid();
       myBallPolyData->Reset();
       myBallPolyData->DeleteCells();
       myBallPolyData->SetPoints(aGrid->GetPoints());
-      
+
       vtkDataArray* aScalars = vtkDataArray::CreateDataArray(VTK_DOUBLE);
       aScalars->SetNumberOfComponents(1);
       aScalars->SetNumberOfTuples(theIds.size());
@@ -235,7 +236,7 @@ namespace SMESH
         aScalars->SetTuple(anId,&d);
         anIds->Reset();
       }
-      
+
       anIds->Delete();
       myBallPolyData->Modified();
       SetVisibility (false, false, true);
@@ -582,6 +583,13 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
                                                tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
           if ( res == 1 ) return;
         }
+        SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( myGroups[idx-1] );
+        if ( !aFilterGroup->_is_nil() ) {
+          int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
+                                               tr( "MESH_FILTER_GRP_CHOSEN" ).arg( aGroupName ),
+                                               tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
+          if ( res == 1 ) return;
+        }
         aGroup = myGroups[idx-1];
       }
     }
@@ -590,16 +598,19 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
     SMESH::long_array_var anIdList = new SMESH::long_array;
     anIdList->length( 1 );
     anIdList[0] = -1;
-    const bool onlyNodesInMesh = ( myMesh->NbElements() == 0 );
+    //const bool onlyNodesInMesh = ( myMesh->NbElements() == 0 );
+    int nbElemsBefore = 0;
 
     switch (myElementType) {
     case SMDSAbs_0DElement:
+      nbElemsBefore = myMesh->Nb0DElements();
       anIdList->length( anArrayOfIndices->length() );
       for ( size_t i = 0; i < anArrayOfIndices->length(); ++i )
         anIdList[i] = aMeshEditor->Add0DElement(anArrayOfIndices[i]);
       break;
     case SMDSAbs_Ball:
       if ( myGeomType == SMDSEntity_Ball ) {
+        nbElemsBefore = myMesh->NbBalls();
         anIdList->length( anArrayOfIndices->length() );
         for ( size_t i = 0; i < anArrayOfIndices->length(); ++i )
           anIdList[i] = aMeshEditor->AddBall(anArrayOfIndices[i],
@@ -607,21 +618,24 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
       }
       break;
     case SMDSAbs_Edge:
+      nbElemsBefore = myMesh->NbEdges();
       anIdList[0] = aMeshEditor->AddEdge(anArrayOfIndices.inout()); break;
     case SMDSAbs_Face:
+      nbElemsBefore = myMesh->NbFaces();
       if ( myIsPoly )
         anIdList[0] = aMeshEditor->AddPolygonalFace(anArrayOfIndices.inout());
       else
         anIdList[0] = aMeshEditor->AddFace(anArrayOfIndices.inout());
       break;
     default:
+      nbElemsBefore = myMesh->NbVolumes();
       anIdList[0] = aMeshEditor->AddVolume(anArrayOfIndices.inout()); break;
     }
 
     if ( anIdList[0] > 0 && addToGroup && !aGroupName.isEmpty() ) {
       SMESH::SMESH_Group_var aGroupUsed;
       if ( aGroup->_is_nil() ) {
-        // create new group 
+        // create new group
         aGroupUsed = SMESH::AddGroup( myMesh, (SMESH::ElementType)myElementType, aGroupName );
         if ( !aGroupUsed->_is_nil() ) {
           myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed));
@@ -629,7 +643,8 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
         }
       }
       else {
-        SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
+        SMESH::SMESH_GroupOnGeom_var     aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
+        SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGroup );
         if ( !aGeomGroup->_is_nil() ) {
           aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
           if ( !aGroupUsed->_is_nil() && idx > 0 ) {
@@ -637,6 +652,13 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
             SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
           }
         }
+        else if ( !aFilterGroup->_is_nil() ) {
+          aGroupUsed = myMesh->ConvertToStandalone( aFilterGroup );
+          if ( !aGroupUsed->_is_nil() && idx > 0 ) {
+            myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
+            SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
+          }
+        }
         else
           aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
       }
@@ -650,8 +672,24 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
     mySelectionMgr->setSelectedObjects( aList, false );
 
     mySimulation->SetVisibility(false);
-    if ( onlyNodesInMesh )
-      myActor->SetRepresentation( SMESH_Actor::eEdge ); // wireframe
+    // if ( onlyNodesInMesh )
+    //   myActor->SetRepresentation( SMESH_Actor::eEdge ); // wireframe
+    if ( nbElemsBefore == 0  )
+    {
+      // 1st element of the type has been added, update actor to show this entity
+      unsigned int aMode = myActor->GetEntityMode();
+      switch ( myElementType ) {
+      case SMDSAbs_Edge:
+        myActor->SetRepresentation(SMESH_Actor::eEdge);
+        myActor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
+      case SMDSAbs_Face:
+        myActor->SetRepresentation(SMESH_Actor::eSurface);
+        myActor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
+      case SMDSAbs_Volume:
+        myActor->SetRepresentation(SMESH_Actor::eSurface);
+        myActor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
+      }
+    }
     SMESH::UpdateView();
 
     buttonOk->setEnabled(false);
index 10ada7bd0ea411ace73d0b83007d37c9a0a09549..5cfddb9ce8850d6010519951a9d9cb24e90ef2fb 100644 (file)
 
 namespace
 {
+
+  // Define the sequences of ids
+  static int FirstEdgeIds[] = {0};
+  static int LastEdgeIds[] =  {1};
+
+  static int FirstTriangleIds[] = {0,1,2};
+  static int LastTriangleIds[] =  {1,2,0};
+
+  static int FirstQuadrangleIds[] = {0,1,2,3};
+  static int LastQuadrangleIds[] =  {1,2,3,0};
+
+  static int FirstTetrahedronIds[] = {0,1,2,3,3,3};
+  static int LastTetrahedronIds[] =  {1,2,0,0,1,2};
+
+  static int FirstPyramidIds[] = {0,1,2,3,4,4,4,4};
+  static int LastPyramidIds[] =  {1,2,3,0,0,1,2,3};
+
+  static int FirstPentahedronIds[] = {0,1,2,3,4,5,0,1,2};
+  static int LastPentahedronIds[] =  {1,2,0,4,5,3,3,4,5};
+
+  static int FirstHexahedronIds[] = {0,1,2,3,4,5,6,7,0,1,2,3};
+  static int LastHexahedronIds[] =  {1,2,3,0,5,6,7,4,4,5,6,7};
+
+  static vector<int> FirstPolygonIds;
+  static vector<int> LastPolygonIds;
+
   void ReverseConnectivity( std::vector<vtkIdType> & ids, SMDSAbs_EntityType type,
                             bool toReverse, // inverse element
                             bool toVtkOrder ) // smds connectivity to vtk one
   {
     if ( toReverse ) // first reverse smds order
     {
-      const std::vector<int>& index = SMDS_MeshCell::reverseSmdsOrder(type);
+      const std::vector<int>& index = SMDS_MeshCell::reverseSmdsOrder(type, ids.size());
       SMDS_MeshCell::applyInterlace( index, ids );
     }
     if ( toVtkOrder ) // from smds to vtk connectivity
@@ -113,7 +139,8 @@ namespace
 }
 namespace SMESH
 {
-  class TElementSimulationQuad {
+  class TElementSimulationQuad
+  {
     SalomeApp_Application* myApplication;
     SUIT_ViewWindow* myViewWindow;
     SVTK_ViewWindow* myVTKViewWindow;
@@ -148,7 +175,7 @@ namespace SMESH
       myPreviewActor->PickableOff();
       myPreviewActor->VisibilityOff();
       myPreviewActor->SetMapper(myMapper);
-      
+
       QColor ffc, bfc;
       int delta;
       vtkProperty* myProp = vtkProperty::New();
@@ -249,35 +276,12 @@ namespace SMESH
 
       myGrid->Delete();
 
-//       myProp->Delete();
-//       myBackProp->Delete();
+      //       myProp->Delete();
+      //       myBackProp->Delete();
     }
   };
 }
 
-
-// Define the sequences of ids
-static int FirstEdgeIds[] = {0};
-static int LastEdgeIds[] =  {1};
-
-static int FirstTriangleIds[] = {0,1,2};
-static int LastTriangleIds[] =  {1,2,0};
-
-static int FirstQuadrangleIds[] = {0,1,2,3};
-static int LastQuadrangleIds[] =  {1,2,3,0};
-
-static int FirstTetrahedronIds[] = {0,1,2,3,3,3};
-static int LastTetrahedronIds[] =  {1,2,0,0,1,2};
-
-static int FirstPyramidIds[] = {0,1,2,3,4,4,4,4};
-static int LastPyramidIds[] =  {1,2,3,0,0,1,2,3};
-
-static int FirstPentahedronIds[] = {0,1,2,3,4,5,0,1,2};
-static int LastPentahedronIds[] =  {1,2,0,4,5,3,3,4,5};
-
-static int FirstHexahedronIds[] = {0,1,2,3,4,5,6,7,0,1,2,3};
-static int LastHexahedronIds[] =  {1,2,3,0,5,6,7,4,4,5,6,7};
-
 /*!
   \class BusyLocker
   \brief Simple 'busy state' flag locker.
@@ -335,7 +339,6 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM
     mySMESHGUI( theModule ),
     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
     myGeomType( theType ),
-    //myType( theType ),
     myBusy( false )
 {
   setModal( false );
@@ -359,6 +362,9 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM
   case SMDSEntity_Quad_Quadrangle:
     anElementName = QString("QUADRATIC_QUADRANGLE");
     break;
+  case SMDSEntity_Quad_Polygon:
+    anElementName = QString("QUADRATIC_POLYGON");
+    break;
   case SMDSEntity_BiQuad_Quadrangle:
     anElementName = QString("BIQUADRATIC_QUADRANGLE");
     break;
@@ -561,6 +567,11 @@ void SMESHGUI_AddQuadraticElementDlg::Init()
     myNbCenterNodes = 1;
     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles
     break;
+  case SMDSEntity_Quad_Polygon:
+    aNumRows = 5;
+    myNbCorners = 0; // no limit
+    myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_polygons
+    break;
   case SMDSEntity_Quad_Tetra:
     aNumRows = 6;
     myNbCorners = 4;
@@ -689,6 +700,7 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
     break;
   case SMDSEntity_Quad_Triangle:
   case SMDSEntity_Quad_Quadrangle:
+  case SMDSEntity_Quad_Polygon:
   case SMDSEntity_BiQuad_Triangle:
   case SMDSEntity_BiQuad_Quadrangle:
   case SMDSEntity_Quad_Tetra:
@@ -716,7 +728,7 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
   if ( myReverseCB->isChecked())
     ReverseConnectivity( anIds, myGeomType, /*toReverse=*/true, /*toVtkOrder=*/false );
 
-  int aNumberOfIds =  anIds.size();
+  int aNumberOfIds = anIds.size();
   SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
   anArrayOfIdeces->length( aNumberOfIds );
 
@@ -739,7 +751,14 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
       SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] );
       if ( !aGeomGroup->_is_nil() ) {
         int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
-                                             tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ),
+                                             tr( "MESH_GEOM_GRP_CHOSEN" ).arg( aGroupName ),
+                                             tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
+        if ( res == 1 ) return false;
+      }
+      SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( myGroups[idx-1] );
+      if ( !aFilterGroup->_is_nil() ) {
+        int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
+                                             tr( "MESH_FILTER_GRP_CHOSEN" ).arg( aGroupName ),
                                              tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
         if ( res == 1 ) return false;
       }
@@ -748,24 +767,31 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
   }
 
   SMESH::ElementType anElementType;
-  long anElemId = -1;
+  long anElemId = -1, nbElemsBefore = 0;
   SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
   switch (myGeomType) {
   case SMDSEntity_Quad_Edge:
     anElementType = SMESH::EDGE;
+    nbElemsBefore = myMesh->NbEdges();
     anElemId = aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
   case SMDSEntity_Quad_Triangle:
   case SMDSEntity_Quad_Quadrangle:
   case SMDSEntity_BiQuad_Triangle:
   case SMDSEntity_BiQuad_Quadrangle:
     anElementType = SMESH::FACE;
+    nbElemsBefore = myMesh->NbFaces();
     anElemId = aMeshEditor->AddFace(anArrayOfIdeces.inout()); break;
+  case SMDSEntity_Quad_Polygon:
+    anElementType = SMESH::FACE;
+    nbElemsBefore = myMesh->NbFaces();
+    anElemId = aMeshEditor->AddQuadPolygonalFace(anArrayOfIdeces.inout()); break;
   case SMDSEntity_Quad_Tetra:
   case SMDSEntity_Quad_Pyramid:
   case SMDSEntity_Quad_Penta:
   case SMDSEntity_Quad_Hexa:
   case SMDSEntity_TriQuad_Hexa:
     anElementType = SMESH::VOLUME;
+    nbElemsBefore = myMesh->NbVolumes();
     anElemId = aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
   default: break;
   }
@@ -781,7 +807,8 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
       }
     }
     else {
-      SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
+      SMESH::SMESH_GroupOnGeom_var     aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
+      SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGroup );
       if ( !aGeomGroup->_is_nil() ) {
         aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
         if ( !aGroupUsed->_is_nil() && idx > 0 ) {
@@ -789,6 +816,13 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
           SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
         }
       }
+      else if ( !aFilterGroup->_is_nil() ) {
+        aGroupUsed = myMesh->ConvertToStandalone( aFilterGroup );
+        if ( !aGroupUsed->_is_nil() && idx > 0 ) {
+          myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
+          SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
+        }
+      }
       else
         aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
     }
@@ -801,6 +835,23 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
     }
   }
 
+  if ( nbElemsBefore == 0  )
+  {
+    // 1st element of the type has been added, update actor to show this entity
+    unsigned int aMode = myActor->GetEntityMode();
+    switch ( anElementType ) {
+    case SMESH::EDGE:
+      myActor->SetRepresentation(SMESH_Actor::eEdge);
+      myActor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
+    case SMESH::FACE:
+      myActor->SetRepresentation(SMESH_Actor::eSurface);
+      myActor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
+    case SMESH::VOLUME:
+      myActor->SetRepresentation(SMESH_Actor::eSurface);
+      myActor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
+    }
+  }
+
   SALOME_ListIO aList; aList.Append( myActor->getIO() );
   mySelector->ClearIndex();
   mySelectionMgr->setSelectedObjects( aList, false );
@@ -1007,6 +1058,7 @@ void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
       anElementType = SMESH::EDGE; break;
     case SMDSEntity_Quad_Triangle:
     case SMDSEntity_Quad_Quadrangle:
+    case SMDSEntity_Quad_Polygon:
     case SMDSEntity_BiQuad_Triangle:
     case SMDSEntity_BiQuad_Quadrangle:
       anElementType = SMESH::FACE; break;
@@ -1269,6 +1321,44 @@ void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
 {
   QStringList aListCorners = myCornerNodes->text().split(" ", QString::SkipEmptyParts);
 
+  if ( myGeomType == SMDSEntity_Quad_Polygon )        // POLYGON
+  {
+    if ( aListCorners.count() < 3 )
+      theConersValidity = false;
+
+    if ( aListCorners.count() != myTable->rowCount() && theConersValidity )
+    {
+      // adjust nb of rows for the polygon
+      int oldNbRows = myTable->rowCount();
+      myTable->setRowCount( aListCorners.count() );
+      for ( int row = oldNbRows; row < myTable->rowCount(); row++ )
+      {
+        myTable->setItem( row, 0, new QTableWidgetItem( "" ) );
+        myTable->item( row, 0 )->setFlags(0);
+
+        IdEditItem* anEditItem = new IdEditItem( "" );
+        anEditItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
+        myTable->setItem(row, 1, anEditItem);
+
+        myTable->setItem( row, 2, new QTableWidgetItem( "" ) );
+        myTable->item( row, 2 )->setFlags(0);
+      }
+      myNbCorners = aListCorners.count();
+
+      // fill FirstPolygonIds and LastPolygonIds
+      FirstPolygonIds.resize( aListCorners.count() );
+      LastPolygonIds .resize( aListCorners.count() );
+      for ( int i = 0; i < aListCorners.count(); ++i )
+      {
+        FirstPolygonIds[i] = i;
+        LastPolygonIds [i] = i+1;
+      }
+      LastPolygonIds.back() = 0;
+
+      myNbCorners = aListCorners.count();
+    }
+  }
+
   if ( aListCorners.count() == myNbCorners && theConersValidity )
   {
     myTable->setEnabled( true );
@@ -1295,6 +1385,10 @@ void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
       aFirstColIds = FirstQuadrangleIds;
       aLastColIds  = LastQuadrangleIds;
       break;
+    case SMDSEntity_Quad_Polygon:
+      aFirstColIds = & FirstPolygonIds[0];
+      aLastColIds  = & LastPolygonIds[0];
+      break;
     case SMDSEntity_Quad_Tetra:
       aFirstColIds = FirstTetrahedronIds;
       aLastColIds  = LastTetrahedronIds;
index b042f8adde0774e5f85ad1b6abfa1f7a045fea3c..0f98bda2d4fe70dbd89d2c7f3debc1cd2401299a 100644 (file)
@@ -39,7 +39,7 @@ public:
 
 private:
   void InverseEntityMode( unsigned int& theOutputMode,
-                         unsigned int theMode );
+                          unsigned int theMode );
 
 private slots:
   void              onOk();
index e84876d44c3f15bd6042b930059bff3e390d552c..afbfd6861468424e494f144d0660aa9885ff8b88 100755 (executable)
@@ -1740,7 +1740,7 @@ static QList<int> entityTypes( const int theType )
     typeIds.append( SMDSEntity_Quad_Quadrangle );
     typeIds.append( SMDSEntity_BiQuad_Quadrangle );
     typeIds.append( SMDSEntity_Polygon );
-    //typeIds.append( SMDSEntity_Quad_Polygon );
+    typeIds.append( SMDSEntity_Quad_Polygon );
     break;
   case SMESH::VOLUME:
     typeIds.append( SMDSEntity_Tetra );
index 4d834c90560a47ab24b774dbf283c74aca3a4b01..f997d9a70cf4c018548878ec1701f3447516ca71 100644 (file)
@@ -306,11 +306,13 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
   QLabel*  a2DQuaBiQuad = createField();
   QLabel*  a2DPolLab    = new QLabel( tr( "POLYGONS_LAB" ), this );
   QLabel*  a2DPolTotal  = createField();
+  QLabel*  a2DPolLin    = createField();
+  QLabel*  a2DPolQuad   = createField();
   myWidgets[ index++ ] << a2DLine;
   myWidgets[ index++ ] << a2DLab    << a2DTotal    << a2DLin    << a2DQuad    << a2DBiQuad;
   myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad;
   myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad;
-  myWidgets[ index++ ] << a2DPolLab << a2DPolTotal;
+  myWidgets[ index++ ] << a2DPolLab << a2DPolTotal << a2DPolLin << a2DPolQuad;
 
   // ... 3D elements
   QWidget* a3DLine      = createLine();
@@ -414,6 +416,8 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
   l->addWidget( a2DQuaBiQuad, 17, 4 );
   l->addWidget( a2DPolLab,    18, 0 );
   l->addWidget( a2DPolTotal,  18, 1 );
+  l->addWidget( a2DPolLin,    18, 2 );
+  l->addWidget( a2DPolQuad,   18, 3 );
   l->addWidget( a3DLine,      19, 1, 1, 4 );
   l->addWidget( a3DLab,       20, 0 );
   l->addWidget( a3DTotal,     20, 1 );
@@ -503,8 +507,9 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
     myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ) );
     long nbTriangles     = info[SMDSEntity_Triangle]   + info[SMDSEntity_Quad_Triangle]   + info[SMDSEntity_BiQuad_Triangle];
     long nbQuadrangles   = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle];
+    long nb2DPolygons    = info[SMDSEntity_Polygon]    + info[SMDSEntity_Quad_Polygon];
     long nb2DLinear      = info[SMDSEntity_Triangle]        + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
-    long nb2DQuadratic   = info[SMDSEntity_Quad_Triangle]   + info[SMDSEntity_Quad_Quadrangle];
+    long nb2DQuadratic   = info[SMDSEntity_Quad_Triangle]   + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_Quad_Polygon];
     long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle];
     long nb2DTotal       = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic;
 
@@ -520,7 +525,9 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
     myWidgets[i2DQuadrangles][iLinear]      ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) );
     myWidgets[i2DQuadrangles][iQuadratic]   ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ) );
     myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] ) );
-    myWidgets[i2DPolygons][iTotal]          ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) );
+    myWidgets[i2DPolygons][iTotal]          ->setProperty( "text", QString::number( nb2DPolygons ));
+    myWidgets[i2DPolygons][iLinear]         ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) );
+    myWidgets[i2DPolygons][iQuadratic]      ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Polygon] ) );
     long nbTetrahedrons  = info[SMDSEntity_Tetra]   + info[SMDSEntity_Quad_Tetra];
     long nbHexahedrons   = info[SMDSEntity_Hexa]    + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
     long nbPyramids      = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
@@ -583,6 +590,8 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
           myWidgets[i2DQuadrangles][iLinear]      ->setProperty( "text", "?" );
           myWidgets[i2DQuadrangles][iQuadratic]   ->setProperty( "text", "?" );
           myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
+          myWidgets[i2DPolygons][iLinear]         ->setProperty( "text", "?" );
+          myWidgets[i2DPolygons][iQuadratic]      ->setProperty( "text", "?" );
           myWidgets[i2DPolygons][iTotal]          ->setProperty( "text", "?" );
           myWidgets[iNb][iTotal]                  ->setProperty( "text", "?" );
           myWidgets[iNb][iLinear]                 ->setProperty( "text", "?" );
@@ -712,6 +721,8 @@ void SMESHGUI_MeshInfo::clear()
   myWidgets[i2DQuadrangles][iLinear]      ->setProperty( "text", QString::number( 0 ) );
   myWidgets[i2DQuadrangles][iQuadratic]   ->setProperty( "text", QString::number( 0 ) );
   myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DPolygons][iLinear]         ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DPolygons][iQuadratic]      ->setProperty( "text", QString::number( 0 ) );
   myWidgets[i2DPolygons][iTotal]          ->setProperty( "text", QString::number( 0 ) );
   myWidgets[i3D][iTotal]                  ->setProperty( "text", QString::number( 0 ) );
   myWidgets[i3D][iLinear]                 ->setProperty( "text", QString::number( 0 ) );
@@ -836,6 +847,8 @@ void SMESHGUI_MeshInfo::saveInfo( QTextStream &out )
   out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
   out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" )     << "\n";
   out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" )        << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" ) ).toString() << "\n";
+  out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" )       << ": " << ( myWidgets[i2DPolygons][iLinear]->property( "text" ) ).toString() << "\n";
+  out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" )    << ": " << ( myWidgets[i2DPolygons][iQuadratic]->property( "text" ) ).toString() << "\n";
   out << QString( SPACING_INFO,   ' ' ) << tr( "3D_LAB" )           << "\n";
   out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" )        << ": " << ( myWidgets[i3D][iTotal]->property( "text" ) ).toString() << "\n";
   out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" )       << ": " << ( myWidgets[i3D][iLinear]->property( "text" ) ).toString() << "\n";
index c9b3a2f58e38a8800f8f91673f052579c477819b..cd28f8bd59eb7523791e628448ebefa34c2bd50d 100644 (file)
@@ -145,6 +145,7 @@ namespace SMESHOp {
     OpQuadraticPentahedron   = 4107,   // MENU MODIFICATION - ADD - QUADRATIC PENTAHEDRON
     OpQuadraticHexahedron    = 4108,   // MENU MODIFICATION - ADD - QUADRATIC HEXAHEDRON
     OpTriQuadraticHexahedron = 4109,   // MENU MODIFICATION - ADD - TRIQUADRATIC HEXAHEDRON
+    OpQuadraticPolygon       = 4110,   // MENU MODIFICATION - ADD - QUADRATIC POLYGON
     OpRemoveNodes            = 4200,   // MENU MODIFICATION - REMOVE - NODE
     OpRemoveElements         = 4201,   // MENU MODIFICATION - REMOVE - ELEMENTS
     OpRemoveOrphanNodes      = 4202,   // MENU MODIFICATION - REMOVE - ORPHAN NODES
index ead04a8829bdec481b0af84a52acb91ced8dcee8..c13a65eb6e824ff277208fd91402ac3943fec4a1 100644 (file)
             <source>ICON_DLG_BIQUADRATIC_QUADRANGLE</source>
             <translation>mesh_biquad_quadrangle.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_QUADRATIC_POLYGON</source>
+            <translation>mesh_quad_polygon.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_QUADRATIC_TETRAHEDRON</source>
             <translation>mesh_quad_tetrahedron.png</translation>
index 28302f1b426652f5676bdd01ce91270b82e22bd8..45b444feb2fc08149f4fe72cfa17ecdb1c1ef2c7 100644 (file)
         <source>MEN_POLYGON</source>
         <translation>Polygon</translation>
     </message>
+    <message>
+        <source>MEN_QUADRATIC_POLYGON</source>
+        <translation>Quadratic Polygon</translation>
+    </message>
     <message>
         <source>MEN_POLYHEDRON</source>
         <translation>Polyhedron</translation>
@@ -1127,8 +1131,13 @@ Please, select a mesh and try again</translation>
 Please enter a name of new group to be created or choose an existing one.</translation>
     </message>
     <message>
-        <source>MESH_STANDALONE_GRP_CHOSEN</source>
+        <source>MESH_GEOM_GRP_CHOSEN</source>
         <translation>Group on geometry is chosen: %1.
+Do you want to convert it to the standalone group?</translation>
+    </message>
+    <message>
+        <source>MESH_FILTER_GRP_CHOSEN</source>
+        <translation>Group on filter is chosen: %1.
 Do you want to convert it to the standalone group?</translation>
     </message>
     <message>
@@ -1225,6 +1234,14 @@ Please enter correct values and try again</translation>
         <source>SMESH_ADD_POLYGON_TITLE</source>
         <translation>Add Polygon</translation>
     </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_POLYGON</source>
+        <translation>Add Quadratic polygon</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_POLYGON_TITLE</source>
+        <translation>Add Quadratic Polygon</translation>
+    </message>
     <message>
         <source>SMESH_ADD_PENTA</source>
         <translation>Add pentahedron</translation>
@@ -3224,6 +3241,10 @@ Use Display Entity menu command to show them.
         <source>STB_POLYGON</source>
         <translation>Polygon</translation>
     </message>
+    <message>
+        <source>STB_QUADRATIC_POLYGON</source>
+        <translation>Quadratic Polygon</translation>
+    </message>
     <message>
         <source>STB_POLYHEDRON</source>
         <translation>Polyhedron</translation>
@@ -3880,6 +3901,10 @@ Use Display Entity menu command to show them.
         <source>TOP_POLYGON</source>
         <translation>Polygon</translation>
     </message>
+    <message>
+        <source>TOP_QUADRATIC_POLYGON</source>
+        <translation>Quadratic Polygon</translation>
+    </message>
     <message>
         <source>TOP_POLYHEDRON</source>
         <translation>Polyhedron</translation>
index dcde998818a64e9beca22921a4cfecd29c30bf23..b2c7a912ef1ed18096b41b95ec8f665110a3d851 100644 (file)
@@ -859,7 +859,7 @@ namespace
     }
 
     // associate branchIDs and the input branch vector (arg)
-    vector< const SMESH_MAT2d::Branch* > branchByID( branchEdges.size() );
+    vector< const SMESH_MAT2d::Branch* > branchByID( branchEdges.size(), 0 );
     int nbBranches = 0;
     for ( size_t i = 0; i < branchEdges.size(); ++i )
     {
@@ -912,28 +912,24 @@ namespace
         {
           edgeInd += dInd;
 
-          if ( edgeInd < 0 ||
-               edgeInd >= (int) branchEdges[ brID ].size() ||
-               branchEdges[ brID ][ edgeInd ] != bndSegs[ i ]._edge )
+          if (( edgeInd < 0 ||
+                edgeInd >= (int) branchEdges[ brID ].size() ) ||
+              ( branchEdges[ brID ][ edgeInd ]         != bndSegs[ i ]._edge &&
+                branchEdges[ brID ][ edgeInd ]->twin() != bndSegs[ i ]._edge ))
           {
-            if ( bndSegs[ i ]._branchID < 0 &&
-                 branchEdges[ brID ].back() == bndSegs[ i ]._edge )
+            if ( bndSegs[ i ]._branchID < 0 )
             {
-              edgeInd = branchEdges[ brID ].size() - 1;
               dInd = -1;
+              for ( edgeInd = branchEdges[ brID ].size() - 1; edgeInd > 0; --edgeInd )
+                if ( branchEdges[ brID ][ edgeInd ]->twin() == bndSegs[ i ]._edge )
+                  break;
             }
-            else if ( bndSegs[ i ]._branchID > 0 &&
-                      branchEdges[ brID ].front() == bndSegs[ i ]._edge )
+            else // bndSegs[ i ]._branchID > 0
             {
-              edgeInd = 0;
               dInd = +1;
-            }
-            else
-            {
               for ( edgeInd = 0; edgeInd < branchEdges[ brID ].size(); ++edgeInd )
                 if ( branchEdges[ brID ][ edgeInd ] == bndSegs[ i ]._edge )
                   break;
-              dInd = bndSegs[ i ]._branchID > 0 ? +1 : -1;
             }
           }
         }
@@ -942,7 +938,7 @@ namespace
           // no MA edge, bndSeg corresponds to an end point of a branch
           if ( bndPoints._maEdges.empty() )
           {
-            // should not get here according to algo design
+            // should not get here according to algo design???
             edgeInd = 0;
           }
           else
@@ -1037,7 +1033,7 @@ void SMESH_MAT2d::MedialAxis::getPoints( const Branch&         branch,
 //================================================================================
 /*!
  * \brief Returns a BranchPoint corresponding to a given point on a geom EDGE
- *  \param [in] iGeomEdge - index of geom EDGE within a vector passed at construction
+ *  \param [in] iGeomEdge - index of geom EDGE within a vector passed at MA construction
  *  \param [in] u - parameter of the point on EDGE curve
  *  \param [out] p - the found BranchPoint
  *  \return bool - is OK
@@ -1052,7 +1048,7 @@ bool SMESH_MAT2d::Boundary::getBranchPoint( const std::size_t iEdge,
     return false;
 
   const BndPoints& points = _pointsPerEdge[ iEdge ];
-  const bool edgeReverse = ( points._params[0] > points._params.back() );
+  const bool  edgeReverse = ( points._params[0] > points._params.back() );
 
   if ( u < ( edgeReverse ? points._params.back() : points._params[0] ))
     u = edgeReverse ? points._params.back() : points._params[0];
@@ -1071,13 +1067,29 @@ bool SMESH_MAT2d::Boundary::getBranchPoint( const std::size_t iEdge,
     while ( points._params[i  ] > u ) --i;
     while ( points._params[i+1] < u ) ++i;
   }
+
   double edgeParam = ( u - points._params[i] ) / ( points._params[i+1] - points._params[i] );
 
+  if ( !points._maEdges[ i ].second ) // no branch at the EDGE end
+  {
+    if ( i < points._maEdges.size() / 2 ) // near 1st point
+    {
+      while ( i < points._maEdges.size()-1 && !points._maEdges[ i ].second )
+        ++i;
+      edgeParam = edgeReverse;
+    }
+    else // near last point
+    {
+      while ( i > 0 && !points._maEdges[ i ].second )
+        --i;
+      edgeParam = !edgeReverse;
+    }
+  }
   const std::pair< const Branch*, int >& maE = points._maEdges[ i ];
   bool maReverse = ( maE.second < 0 );
 
   p._branch = maE.first;
-  p._iEdge  = maE.second - 1; // countered from 1 to store sign
+  p._iEdge  = ( maReverse ? -maE.second : maE.second ) - 1; // countered from 1 to store sign
   p._edgeParam = maReverse ? ( 1. - edgeParam ) : edgeParam;
 
   return true;
@@ -1244,6 +1256,8 @@ bool SMESH_MAT2d::Branch::getBoundaryPoints(std::size_t    iMAEdge,
 {
   if ( iMAEdge > _maEdges.size() )
     return false;
+  if ( iMAEdge == _maEdges.size() )
+    iMAEdge = _maEdges.size() - 1;
 
   size_t iGeom1 = getGeomEdge( _maEdges[ iMAEdge ] );
   size_t iGeom2 = getGeomEdge( _maEdges[ iMAEdge ]->twin() );
@@ -1277,6 +1291,8 @@ bool SMESH_MAT2d::Branch::getParameter(const BranchPoint & p, double & u ) const
 {
   if ( p._iEdge > _params.size()-1 )
     return false;
+  if ( p._iEdge == _params.size()-1 )
+    return u = 1.;
 
   u = ( _params[ p._iEdge   ] * ( 1 - p._edgeParam ) +
         _params[ p._iEdge+1 ] * p._edgeParam );
index 824655a8775c4ecb7d7f2d8052a879a2ed8cf4b0..81d0e15c1cb532051c33462127e18f8736546ec7 100644 (file)
@@ -2422,6 +2422,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
   ::SMESH_MeshEditor aNewEditor(&aLocMesh);
   SMESH::ListOfGroups_var aListOfGroups;
 
+  ::SMESH_MeshEditor::ElemFeatures  elemType;
   std::vector<const SMDS_MeshNode*> aNodesArray;
 
   // loop on sub-meshes
@@ -2476,31 +2477,12 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
       }
 
       // creates a corresponding element on existent nodes in new mesh
-      aNewElem = 0;
-      switch ( anElem->GetEntityType() )
-      {
-      case SMDSEntity_Polyhedra:
-        if ( const SMDS_VtkVolume* aVolume =
-             dynamic_cast<const SMDS_VtkVolume*> (anElem))
-        {
-          aNewElem = aNewMeshDS->AddPolyhedralVolume( aNodesArray,
-                                                      aVolume->GetQuantities() );
-        }
-        break;
-      case SMDSEntity_Ball:
-        if ( const SMDS_BallElement* aBall =
-             dynamic_cast<const SMDS_BallElement*> (anElem))
-        {
-          aNewElem = aNewEditor.AddElement( aNodesArray, SMDSAbs_Ball,
-                                            /*isPoly=*/false, /*id=*/0,
-                                            aBall->GetDiameter() );
-        }
-        break;
-      case SMDSEntity_Node:
-        break;
-      default:
-        aNewElem = aNewEditor.AddElement( aNodesArray, anElem->GetType(), anElem->IsPoly() );
-      }
+      if ( anElem->GetType() == SMDSAbs_Node )
+        aNewElem = 0;
+      else
+        aNewElem =
+          aNewEditor.AddElement( aNodesArray, elemType.Init( anElem, /*basicOnly=*/false ));
+
       if ( aNewElem )
         elemsMap.insert( make_pair( anElem, aNewElem ));
 
@@ -2737,6 +2719,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
   }
   SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS();
   ::SMESH_MeshEditor editor( &newMesh_i->GetImpl() );
+  ::SMESH_MeshEditor::ElemFeatures elemType;
 
   // 3. Get elements to copy
 
@@ -2808,30 +2791,12 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
     // add elements
     if ( elem->GetType() != SMDSAbs_Node )
     {
-      int ID = toKeepIDs ? elem->GetID() : 0;
-      const SMDS_MeshElement * newElem;
-      switch ( elem->GetEntityType() ) {
-      case SMDSEntity_Polyhedra:
-        if ( toKeepIDs )
-          newElem = editor.GetMeshDS()->
-            AddPolyhedralVolumeWithID( nodes,
-                                       static_cast<const SMDS_VtkVolume*>(elem)->GetQuantities(),
-                                       ID);
-        else
-          newElem = editor.GetMeshDS()->
-            AddPolyhedralVolume( nodes,
-                                 static_cast<const SMDS_VtkVolume*>(elem)->GetQuantities());
-        break;
-      case SMDSEntity_Ball:
-        newElem = editor.AddElement( nodes, SMDSAbs_Ball, false, ID,
-                                     static_cast<const SMDS_BallElement*>(elem)->GetDiameter());
-        break;
-      default:
-        newElem = editor.AddElement( nodes,elem->GetType(),elem->IsPoly(),ID);
+      elemType.Init( elem, /*basicOnly=*/false );
+      if ( toKeepIDs ) elemType.SetID( elem->GetID() );
 
+      const SMDS_MeshElement * newElem = editor.AddElement( nodes, elemType );
       if ( toCopyGroups && !toKeepIDs )
         e2eMapByType[ elem->GetType() ].insert( make_pair( elem, newElem ));
-      }
     }
   } // while ( srcElemIt->more() )
 
index e469b70393137718ceb3c7f453aa631e2ceb7b2b..06481f54b278b807778de755ae5375e543665231 100644 (file)
@@ -154,20 +154,11 @@ namespace MeshEditor_I {
       }
 
       // creates a corresponding element on copied nodes
-      SMDS_MeshElement* anElemCopy = 0;
-      if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
-      {
-        const SMDS_VtkVolume* ph =
-          dynamic_cast<const SMDS_VtkVolume*> (anElem);
-        if ( ph )
-          anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
-            (anElemNodesID, ph->GetQuantities(),anElem->GetID());
-      }
-      else {
-        anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
-                                                          anElem->GetType(),
-                                                          anElem->IsPoly() );
-      }
+      ::SMESH_MeshEditor::ElemFeatures elemType;
+      elemType.Init( anElem, /*basicOnly=*/false );
+      elemType.SetID( anElem->GetID() );
+      SMDS_MeshElement* anElemCopy =
+        ::SMESH_MeshEditor(this).AddElement( anElemNodesID, elemType );
       return anElemCopy;
     }
     //!< Copy a node
@@ -535,7 +526,7 @@ TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewEle
 
 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
   throw (SALOME::SALOME_Exception)
-{ 
+{
   SMESH_TRY;
   const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
 
@@ -557,7 +548,7 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
     myPreviewData = new SMESH::MeshPreviewStruct();
     myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
 
-    
+
     SMDSAbs_ElementType previewType = SMDSAbs_All;
     if ( !hasBadElems )
       if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
@@ -577,7 +568,10 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
 
     while ( itMeshElems->more() ) {
       const SMDS_MeshElement* aMeshElem = itMeshElems->next();
-      SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
+      SMDS_NodeIteratorPtr itElemNodes = 
+        (( aMeshElem->GetEntityType() == SMDSEntity_Quad_Polygon ) ?
+         aMeshElem->interlacedNodesIterator() :
+         aMeshElem->nodeIterator() );
       while ( itElemNodes->more() ) {
         const SMDS_MeshNode* aMeshNode = itElemNodes->next();
         int aNodeID = aMeshNode->GetID();
@@ -1059,6 +1053,7 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
  *  AddPolygonalFace
  */
 //=============================================================================
+
 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
   throw (SALOME::SALOME_Exception)
 {
@@ -1082,6 +1077,35 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsO
   return 0;
 }
 
+//=============================================================================
+/*!
+ *  AddQuadPolygonalFace
+ */
+//=============================================================================
+
+CORBA::Long SMESH_MeshEditor_i::AddQuadPolygonalFace (const SMESH::long_array & IDsOfNodes)
+  throw (SALOME::SALOME_Exception)
+{
+  SMESH_TRY;
+  initData();
+
+  int NbNodes = IDsOfNodes.length();
+  std::vector<const SMDS_MeshNode*> nodes (NbNodes);
+  for (int i = 0; i < NbNodes; i++)
+    nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
+
+  const SMDS_MeshElement* elem = getMeshDS()->AddQuadPolygonalFace(nodes);
+
+  // Update Python script
+  TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
+
+  declareMeshModified( /*isReComputeSafe=*/false );
+  return elem ? elem->GetID() : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
+
 //=============================================================================
 /*!
  * Create volume, either linear and quadratic (this is determed
index ec9ae9861f1a0766608eb4d3e9d18de23355b4f1..2cdf9fa6103440e705c7f7c497f39ecd5cb43a4a 100644 (file)
@@ -117,6 +117,8 @@ public:
     throw (SALOME::SALOME_Exception);
   CORBA::Long AddPolygonalFace(const SMESH::long_array & IDsOfNodes)
     throw (SALOME::SALOME_Exception);
+  CORBA::Long AddQuadPolygonalFace(const SMESH::long_array & IDsOfNodes)
+    throw (SALOME::SALOME_Exception);
   CORBA::Long AddVolume(const SMESH::long_array & IDsOfNodes)
     throw (SALOME::SALOME_Exception);
   CORBA::Long AddPolyhedralVolume(const SMESH::long_array & IDsOfNodes,
index 03420b0e4001a06ed711c1d0a41a34f7a25a9e6f..060329f4c9c80e2753980654bb25a11481970d43 100644 (file)
@@ -3765,13 +3765,13 @@ CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
   return _impl->NbBiQuadQuadrangles();
 }
 
-CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
+CORBA::Long SMESH_Mesh_i::NbPolygons(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
   if ( _preMeshInfo )
-    return _preMeshInfo->NbPolygons();
+    return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
 
-  return _impl->NbPolygons();
+  return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
 }
 
 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
@@ -4851,6 +4851,7 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int         theSubShapeID,
     THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
 
   SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
+  ::SMESH_MeshEditor::ElemFeatures elemType;
 
   // submesh by subshape id
   if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
@@ -4883,7 +4884,7 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int         theSubShapeID,
           if ( elem )
           {
             ::SMESH_MeshEditor editor( _impl );
-            elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
+            elem = editor.AddElement( nodes, elemType.Init( elem ));
           }
         }
         if ( elem )
index 45d01b10ed8a5e9a2ffc6af8e5af6b3575155219..24874a03a50b76ea55b2d2a54c5ce30d5a1afd12 100644 (file)
@@ -315,7 +315,7 @@ public:
   CORBA::Long NbBiQuadQuadrangles()
     throw (SALOME::SALOME_Exception);
 
-  CORBA::Long NbPolygons()
+  CORBA::Long NbPolygons(SMESH::ElementOrder order=SMESH::ORDER_ANY)
     throw (SALOME::SALOME_Exception);
 
   CORBA::Long NbVolumes()
index 07d46509b3362c896619414bcafe7749e41355a7..22e31b4ee57d079168ef08cb79136f6986d68cc0 100644 (file)
@@ -2242,11 +2242,11 @@ class Mesh:
     def NbBiQuadQuadrangles(self):
         return self.mesh.NbBiQuadQuadrangles()
 
-    ## Returns the number of polygons in the mesh
+    ## Returns the number of polygons of given order in the mesh
     #  @return an integer value
     #  @ingroup l1_meshinfo
-    def NbPolygons(self):
-        return self.mesh.NbPolygons()
+    def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
+        return self.mesh.NbPolygons(elementOrder)
 
     ## Returns the number of volumes in the mesh
     #  @return an integer value
@@ -2367,7 +2367,7 @@ class Mesh:
     ## Returns the type of mesh element
     #  @return the value from SMESH::ElementType enumeration
     #  @ingroup l1_meshinfo
-    def GetElementType(self, id, iselem):
+    def GetElementType(self, id, iselem=True):
         return self.mesh.GetElementType(id, iselem)
 
     ## Returns the geometric type of mesh element
@@ -2455,24 +2455,22 @@ class Mesh:
     def GetElementPosition(self,ElemID):
         return self.mesh.GetElementPosition(ElemID)
 
-    ## If the given element is a node, returns the ID of shape
-    #  \n If there is no node for the given ID - returns -1
-    #  @return an integer value
+    ## Returns the ID of the shape, on which the given node was generated.
+    #  @return an integer value > 0 or -1 if there is no node for the given
+    #          ID or the node is not assigned to any geometry
     #  @ingroup l1_meshinfo
     def GetShapeID(self, id):
         return self.mesh.GetShapeID(id)
 
-    ## Returns the ID of the result shape after
-    #  FindShape() from SMESH_MeshEditor for the given element
-    #  \n If there is no element for the given ID - returns -1
-    #  @return an integer value
+    ## Returns the ID of the shape, on which the given element was generated.
+    #  @return an integer value > 0 or -1 if there is no element for the given
+    #          ID or the element is not assigned to any geometry
     #  @ingroup l1_meshinfo
     def GetShapeIDForElem(self,id):
         return self.mesh.GetShapeIDForElem(id)
 
-    ## Returns the number of nodes for the given element
-    #  \n If there is no element for the given ID - returns -1
-    #  @return an integer value
+    ## Returns the number of nodes of the given element
+    #  @return an integer value > 0 or -1 if there is no element for the given ID
     #  @ingroup l1_meshinfo
     def GetElemNbNodes(self, id):
         return self.mesh.GetElemNbNodes(id)
@@ -2498,7 +2496,7 @@ class Mesh:
 
     ## Returns true if the given node is the medium node in one of quadratic elements
     #  @ingroup l1_meshinfo
-    def IsMediumNodeOfAnyElem(self, nodeID, elementType):
+    def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
         return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
 
     ## Returns the number of edges for the given element
@@ -2756,6 +2754,14 @@ class Mesh:
     def AddPolygonalFace(self, IdsOfNodes):
         return self.editor.AddPolygonalFace(IdsOfNodes)
 
+    ## Adds a quadratic polygonal face to the mesh by the list of node IDs
+    #  @param IdsOfNodes the list of node IDs for creation of the element;
+    #         corner nodes follow first.
+    #  @return the Id of the new face
+    #  @ingroup l2_modif_add
+    def AddQuadPolygonalFace(self, IdsOfNodes):
+        return self.editor.AddQuadPolygonalFace(IdsOfNodes)
+
     ## Creates both simple and quadratic volume (this is determined
     #  by the number of given nodes).
     #  @param IDsOfNodes the list of node IDs for creation of the element.
@@ -3990,8 +3996,8 @@ class Mesh:
     ## Creates a symmetrical copy of mesh elements
     #  @param IDsOfElements list of elements ids
     #  @param Mirror is AxisStruct or geom object(point, line, plane)
-    #  @param theMirrorType is  POINT, AXIS or PLANE
-    #  If the Mirror is a geom object this parameter is unnecessary
+    #  @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
+    #         If the Mirror is a geom object this parameter is unnecessary
     #  @param Copy allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
     #  @param MakeGroups forces the generation of new groups from existing ones (if Copy)
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
@@ -4012,8 +4018,8 @@ class Mesh:
     ## Creates a new mesh by a symmetrical copy of mesh elements
     #  @param IDsOfElements the list of elements ids
     #  @param Mirror is AxisStruct or geom object (point, line, plane)
-    #  @param theMirrorType is  POINT, AXIS or PLANE
-    #  If the Mirror is a geom object this parameter is unnecessary
+    #  @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
+    #         If the Mirror is a geom object this parameter is unnecessary
     #  @param MakeGroups to generate new groups from existing ones
     #  @param NewMeshName a name of the new mesh to create
     #  @return instance of Mesh class
@@ -4033,8 +4039,8 @@ class Mesh:
     ## Creates a symmetrical copy of the object
     #  @param theObject mesh, submesh or group
     #  @param Mirror AxisStruct or geom object (point, line, plane)
-    #  @param theMirrorType is  POINT, AXIS or PLANE
-    #  If the Mirror is a geom object this parameter is unnecessary
+    #  @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
+    #         If the Mirror is a geom object this parameter is unnecessary
     #  @param Copy allows copying the element (Copy is 1) or replacing it with its mirror (Copy is 0)
     #  @param MakeGroups forces the generation of new groups from existing ones (if Copy)
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
@@ -4055,8 +4061,8 @@ class Mesh:
     ## Creates a new mesh by a symmetrical copy of the object
     #  @param theObject mesh, submesh or group
     #  @param Mirror AxisStruct or geom object (point, line, plane)
-    #  @param theMirrorType POINT, AXIS or PLANE
-    #  If the Mirror is a geom object this parameter is unnecessary
+    #  @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
+    #         If the Mirror is a geom object this parameter is unnecessary
     #  @param MakeGroups forces the generation of new groups from existing ones
     #  @param NewMeshName the name of the new mesh to create
     #  @return instance of Mesh class
@@ -4420,8 +4426,9 @@ class Mesh:
     ## Creates Duplicates given elements, i.e. creates new elements based on the 
     #  same nodes as the given ones.
     #  @param theElements - container of elements to duplicate. It can be a Mesh,
-    #         sub-mesh, group, filter or a list of element IDs.
-    # @param theGroupName - a name of group to contain the generated elements.
+    #         sub-mesh, group, filter or a list of element IDs. If \a theElements is
+    #         a Mesh, elements of highest dimension are duplicated
+    #  @param theGroupName - a name of group to contain the generated elements.
     #                    If a group with such a name already exists, the new elements
     #                    are added to the existng group, else a new group is created.
     #                    If \a theGroupName is empty, new elements are not added 
index b5e9a567ae93de6857d234e8ee58104bcc9737b9..083f055f206ae815ae7e4390036d253865b929c6 100644 (file)
@@ -841,6 +841,7 @@ void StdMeshers_Import_1D::importMesh(const SMESH_Mesh*          srcMesh,
 
   // 1. Copy mesh
 
+  SMESH_MeshEditor::ElemFeatures elemType;
   vector<const SMDS_MeshNode*> newNodes;
   const SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
   SMDS_ElemIteratorPtr eIt = srcMeshDS->elementsIterator();
@@ -865,7 +866,7 @@ void StdMeshers_Import_1D::importMesh(const SMESH_Mesh*          srcMesh,
       tgtMeshDS->FindElement( newNodes, elem->GetType(), /*noMedium=*/false );
     if ( !newElem )
     {
-      newElem = additor.AddElement( newNodes, elem->GetType(), elem->IsPoly());
+      newElem = additor.AddElement( newNodes, elemType.Init( elem, /*basicOnly=*/false ));
       tgtSubMesh->AddElement( newElem );
     }
     if ( toCopyGroups )
index 196814b789a73d927d0a3d711c8ca531abd95af2..60b776254489ad854f7f7dd9452386aa3491ceb2 100644 (file)
@@ -454,7 +454,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
 
         if ( geomNorm * meshNorm < 0 )
           SMDS_MeshCell::applyInterlace
-            ( SMDS_MeshCell::reverseSmdsOrder( face->GetEntityType() ), newNodes );
+            ( SMDS_MeshCell::reverseSmdsOrder( face->GetEntityType(), newNodes.size() ), newNodes );
       }
 
       // make a new face
index a6d372d5fd34968508dad2e8d82d66fac143baee..4ac71c0b818a8b09e31b0d0d8d7a618978c24738 100644 (file)
@@ -29,6 +29,7 @@
 #include "SMESH_Gen.hxx"
 #include "SMESH_MAT2d.hxx"
 #include "SMESH_Mesh.hxx"
+#include "SMESH_MeshEditor.hxx"
 #include "SMESH_MesherHelper.hxx"
 #include "SMESH_ProxyMesh.hxx"
 #include "SMESH_subMesh.hxx"
@@ -124,6 +125,34 @@ bool StdMeshers_QuadFromMedialAxis_1D2D::CheckHypothesis(SMESH_Mesh&         aMe
 
 namespace
 {
+  typedef map< const SMDS_MeshNode*, list< const SMDS_MeshNode* > > TMergeMap;
+  
+  //================================================================================
+  /*!
+   * \brief Sinuous face
+   */
+  struct SinuousFace
+  {
+    FaceQuadStruct::Ptr   _quad;
+    vector< TopoDS_Edge > _edges;
+    vector< TopoDS_Edge > _sinuSide[2], _shortSide[2];
+    vector< TopoDS_Edge > _sinuEdges;
+    int                   _nbWires;
+    list< int >           _nbEdgesInWire;
+    TMergeMap             _nodesToMerge;
+
+    SinuousFace( const TopoDS_Face& f ): _quad( new FaceQuadStruct )
+    {
+      list< TopoDS_Edge > edges;
+      _nbWires = SMESH_Block::GetOrderedEdges (f, edges, _nbEdgesInWire);
+      _edges.assign( edges.begin(), edges.end() );
+
+      _quad->side.resize( 4 );
+      _quad->face = f;
+    }
+    const TopoDS_Face& Face() const { return _quad->face; }
+  };
+
   //================================================================================
   /*!
    * \brief Temporary mesh
@@ -136,6 +165,18 @@ namespace
     }
   };
 
+  //================================================================================
+  /*!
+   * \brief Return a member of a std::pair
+   */
+  //================================================================================
+
+  template< typename T >
+  T& get( std::pair< T, T >& thePair, bool is2nd )
+  {
+    return is2nd ? thePair.second : thePair.first;
+  }
+
   //================================================================================
   /*!
    * \brief Select two EDGEs from a map, either mapped to least values or to max values
@@ -331,36 +372,42 @@ namespace
   //================================================================================
   /*!
    * \brief Find EDGEs to discretize using projection from MA
-   *  \param [in] theFace - the FACE to be meshed
-   *  \param [in] theWire - ordered EDGEs of the FACE
-   *  \param [out] theSinuEdges - the EDGEs to discretize using projection from MA
-   *  \param [out] theShortEdges - other EDGEs
+   *  \param [in,out] theSinuFace - the FACE to be meshed
    *  \return bool - OK or not
    *
-   * Is separate all EDGEs into four sides of a quadrangle connected in the order:
+   * It separates all EDGEs into four sides of a quadrangle connected in the order:
    * theSinuEdges[0], theShortEdges[0], theSinuEdges[1], theShortEdges[1]
    */
   //================================================================================
 
   bool getSinuousEdges( SMESH_MesherHelper& theHelper,
-                        const TopoDS_Face&  theFace,
-                        list<TopoDS_Edge>&  theWire,
-                        vector<TopoDS_Edge> theSinuEdges[2],
-                        vector<TopoDS_Edge> theShortEdges[2])
+                        SinuousFace&        theSinuFace)
   {
+    vector<TopoDS_Edge> * theSinuEdges  = & theSinuFace._sinuSide [0];
+    vector<TopoDS_Edge> * theShortEdges = & theSinuFace._shortSide[0];
     theSinuEdges[0].clear();
     theSinuEdges[1].clear();
     theShortEdges[0].clear();
     theShortEdges[1].clear();
-
-    vector<TopoDS_Edge> allEdges( theWire.begin(), theWire.end() );
+   
+    vector<TopoDS_Edge> & allEdges = theSinuFace._edges;
     const size_t nbEdges = allEdges.size();
-    if ( nbEdges < 4 )
+    if ( nbEdges < 4 && theSinuFace._nbWires == 1 )
+      return false;
+
+    if ( theSinuFace._nbWires == 2 ) // ring
+    {
+      size_t nbOutEdges = theSinuFace._nbEdgesInWire.front();
+      theSinuEdges[0].assign ( allEdges.begin(), allEdges.begin() + nbOutEdges );
+      theSinuEdges[1].assign ( allEdges.begin() + nbOutEdges, allEdges.end() );
+      return true;
+    }
+    if ( theSinuFace._nbWires > 2 )
       return false;
 
     // create MedialAxis to find short edges by analyzing MA branches
     double minSegLen = getMinSegLen( theHelper, allEdges );
-    SMESH_MAT2d::MedialAxis ma( theFace, allEdges, minSegLen );
+    SMESH_MAT2d::MedialAxis ma( theSinuFace.Face(), allEdges, minSegLen * 3 );
 
     // in an initial request case, theFace represents a part of a river with almost parallel banks
     // so there should be two branch points
@@ -430,6 +477,10 @@ namespace
          !vCommon.IsSame( theHelper.IthVertex( 1, theSinuEdges[0].back() )))
       theShortEdges[0].swap( theShortEdges[1] );
 
+    theSinuFace._sinuEdges = theSinuEdges[0];
+    theSinuFace._sinuEdges.insert( theSinuFace._sinuEdges.end(),
+                                   theSinuEdges[1].begin(), theSinuEdges[1].end() );
+
     return ( theShortEdges[0].size() > 0 && theShortEdges[1].size() > 0 &&
              theSinuEdges [0].size() > 0 && theSinuEdges [1].size() > 0 );
 
@@ -437,17 +488,17 @@ namespace
     // therefor we use a complex criterion to find TWO short non-sinuous EDGEs
     // and the rest EDGEs will be treated as sinuous.
     // A short edge should have the following features:
-  // a) straight
-  // b) short
-  // c) with convex corners at ends
-  // d) far from the other short EDGE
+    // a) straight
+    // b) short
+    // c) with convex corners at ends
+    // d) far from the other short EDGE
 
-  // vector< double > isStraightEdge( nbEdges, 0 ); // criterion value
+    // vector< double > isStraightEdge( nbEdges, 0 ); // criterion value
 
-  // // a0) evaluate continuity
-  // const double contiWgt = 0.5; // weight of continuity in the criterion
-  // multimap< int, TopoDS_Edge > continuity;
-  // for ( size_t i = 0; i < nbEdges; ++I )
+    // // a0) evaluate continuity
+    // const double contiWgt = 0.5; // weight of continuity in the criterion
+    // multimap< int, TopoDS_Edge > continuity;
+    // for ( size_t i = 0; i < nbEdges; ++I )
     // {
     //   BRepAdaptor_Curve curve( allEdges[i] );
     //   GeomAbs_Shape C = GeomAbs_CN;
@@ -604,21 +655,21 @@ namespace
 
   bool divideMA( SMESH_MesherHelper&            theHelper,
                  const SMESH_MAT2d::MedialAxis& theMA,
-                 const vector<TopoDS_Edge>&     theSinuEdges,
-                 const size_t                   theSinuSide0Size,
+                 const SinuousFace&             theSinuFace,
                  SMESH_Algo*                    the1dAlgo,
                  vector<double>&                theMAParams )
   {
     // check if all EDGEs of one size are meshed, then MA discretization is not needed
     SMESH_Mesh* mesh = theHelper.GetMesh();
     size_t nbComputedEdges[2] = { 0, 0 };
-    for ( size_t i = 1; i < theSinuEdges.size(); ++i )
-    {
-      bool isComputed = ( ! mesh->GetSubMesh( theSinuEdges[i] )->IsEmpty() );
-      nbComputedEdges[ i < theSinuSide0Size ] += isComputed;
-    }
-    if ( nbComputedEdges[0] == theSinuSide0Size ||
-         nbComputedEdges[1] == theSinuEdges.size() - theSinuSide0Size )
+    for ( size_t iS = 0; iS < 2; ++iS )
+      for ( size_t i = 0; i < theSinuFace._sinuSide[iS].size(); ++i )
+      {
+        bool isComputed = ( ! mesh->GetSubMesh( theSinuFace._sinuSide[iS][i] )->IsEmpty() );
+        nbComputedEdges[ iS ] += isComputed;
+      }
+    if ( nbComputedEdges[0] == theSinuFace._sinuSide[0].size() ||
+         nbComputedEdges[1] == theSinuFace._sinuSide[1].size() )
       return true; // discretization is not needed
 
 
@@ -631,13 +682,13 @@ namespace
     // cout << "Write " << file << endl;
 
     // look for a most local hyps assigned to theSinuEdges
-    TopoDS_Edge edge = theSinuEdges[0];
+    TopoDS_Edge edge = theSinuFace._sinuEdges[0];
     int mostSimpleShape = (int) getHypShape( mesh, edge );
-    for ( size_t i = 1; i < theSinuEdges.size(); ++i )
+    for ( size_t i = 1; i < theSinuFace._sinuEdges.size(); ++i )
     {
-      int shapeType = (int) getHypShape( mesh, theSinuEdges[i] );
+      int shapeType = (int) getHypShape( mesh, theSinuFace._sinuEdges[i] );
       if ( shapeType > mostSimpleShape )
-        edge = theSinuEdges[i];
+        edge = theSinuFace._sinuEdges[i];
     }
 
     SMESH_Algo* algo = the1dAlgo;
@@ -664,14 +715,13 @@ namespace
 
   //================================================================================
   /*!
-   * \brief Modifies division parameters on MA to make them coincide with projections
-   *        of VERTEXes to MA for a given pair of opposite EDGEs
+   * \brief Select division parameters on MA and make them coincide at ends with
+   *        projections of VERTEXes to MA for a given pair of opposite EDGEs
    *  \param [in] theEdgePairInd - index of the EDGE pair
    *  \param [in] theDivPoints - the BranchPoint's dividing MA into parts each
    *         corresponding to a unique pair of opposite EDGEs
-   *  \param [in,out] theMAParams - the MA division parameters to modify
-   *  \param [in,out] theParBeg - index of the 1st division point for the given EDGE pair
-   *  \param [in,out] theParEnd - index of the last division point for the given EDGE pair
+   *  \param [in] theMAParams - the MA division parameters
+   *  \param [out] theSelectedMAParams - the selected MA parameters
    *  \return bool - is OK
    */
   //================================================================================
@@ -686,11 +736,49 @@ namespace
       theSelectedMAParams = theMAParams;
       return true;
     }
-    if ( theEdgePairInd > theDivPoints.size() )
+    if ( theEdgePairInd > theDivPoints.size() || theMAParams.empty() )
       return false;
 
-    // TODO
-    return false;
+    // find a range of params to copy
+
+    double par1 = 0;
+    size_t iPar1 = 0;
+    if ( theEdgePairInd > 0 )
+    {
+      const SMESH_MAT2d::BranchPoint& bp = theDivPoints[ theEdgePairInd-1 ];
+      bp._branch->getParameter( bp, par1 );
+      while ( theMAParams[ iPar1 ] < par1 ) ++iPar1;
+      if ( par1 - theMAParams[ iPar1-1 ] < theMAParams[ iPar1 ] - par1 )
+        --iPar1;
+    }
+
+    double par2 = 1;
+    size_t iPar2 = theMAParams.size() - 1;
+    if ( theEdgePairInd < theDivPoints.size() )
+    {
+      const SMESH_MAT2d::BranchPoint& bp = theDivPoints[ theEdgePairInd ];
+      bp._branch->getParameter( bp, par2 );
+      iPar2 = iPar1;
+      while ( theMAParams[ iPar2 ] < par2 ) ++iPar2;
+      if ( par2 - theMAParams[ iPar2-1 ] < theMAParams[ iPar2 ] - par2 )
+        --iPar2;
+    }
+
+    theSelectedMAParams.assign( theMAParams.begin() + iPar1,
+                                theMAParams.begin() + iPar2 + 1 );
+
+    // adjust theSelectedMAParams to fit between par1 and par2
+
+    double d = par1 - theSelectedMAParams[0];
+    double f = ( par2 - par1 ) / ( theSelectedMAParams.back() - theSelectedMAParams[0] );
+
+    for ( size_t i = 0; i < theSelectedMAParams.size(); ++i )
+    {
+      theSelectedMAParams[i] += d;
+      theSelectedMAParams[i] = par1 + ( theSelectedMAParams[i] - par1 ) * f;
+    }
+
+    return true;
   }
 
   //--------------------------------------------------------------------------------
@@ -701,9 +789,14 @@ namespace
     double               _u;
     int                  _edgeInd; // index in theSinuEdges vector
 
-    NodePoint(const SMDS_MeshNode* n=0 ): _node(n), _u(0), _edgeInd(-1) {}
+    NodePoint(): _node(0), _u(0), _edgeInd(-1) {}
+    NodePoint(const SMDS_MeshNode* n, double u, size_t iEdge ): _node(n), _u(u), _edgeInd(iEdge) {}
     NodePoint(double u, size_t iEdge) : _node(0), _u(u), _edgeInd(iEdge) {}
     NodePoint(const SMESH_MAT2d::BoundaryPoint& p) : _node(0), _u(p._param), _edgeInd(p._edgeIndex) {}
+    gp_Pnt Point(const vector< Handle(Geom_Curve) >& curves) const
+    {
+      return curves[ _edgeInd ]->Value( _u );
+    }
   };
 
   //================================================================================
@@ -726,11 +819,12 @@ namespace
 
     double f,l;
     BRep_Tool::Range( theSinuEdges[ theNodePnt._edgeInd ], f,l );
+    const double tol = 1e-3 * ( l - f );
 
     TopoDS_Vertex V;
-    if      ( Abs( f - theNodePnt._u ))
+    if      ( Abs( f - theNodePnt._u ) < tol )
       V = SMESH_MesherHelper::IthVertex( 0, theSinuEdges[ theNodePnt._edgeInd ], /*CumOri=*/false);
-    else if ( Abs( l - theNodePnt._u ))
+    else if ( Abs( l - theNodePnt._u ) < tol )
       V = SMESH_MesherHelper::IthVertex( 1, theSinuEdges[ theNodePnt._edgeInd ], /*CumOri=*/false);
 
     if ( !V.IsNull() )
@@ -752,21 +846,25 @@ namespace
    * \brief Add to the map of NodePoint's those on VERTEXes
    *  \param [in,out] theHelper - the helper
    *  \param [in] theMA - Medial Axis
+   *  \param [in] theMinSegLen - minimal segment length
    *  \param [in] theDivPoints - projections of VERTEXes to MA
    *  \param [in] theSinuEdges - the sinuous EDGEs
    *  \param [in] theSideEdgeIDs - indices of sinuous EDGEs per side
    *  \param [in] theIsEdgeComputed - is sinuous EGDE is meshed
    *  \param [in,out] thePointsOnE - the map to fill
+   *  \param [out] theNodes2Merge - the map of nodes to merge
    */
   //================================================================================
 
   bool projectVertices( SMESH_MesherHelper&                           theHelper,
+                        //const double                                  theMinSegLen,
                         const SMESH_MAT2d::MedialAxis&                theMA,
                         const vector< SMESH_MAT2d::BranchPoint >&     theDivPoints,
                         const vector<TopoDS_Edge>&                    theSinuEdges,
-                        //const vector< int >                           theSideEdgeIDs[2],
+                        const vector< Handle(Geom_Curve) >&           theCurves,
                         const vector< bool >&                         theIsEdgeComputed,
-                        map< double, pair< NodePoint, NodePoint > > & thePointsOnE)
+                        map< double, pair< NodePoint, NodePoint > > & thePointsOnE,
+                        TMergeMap&                                    theNodes2Merge)
   {
     if ( theDivPoints.empty() )
       return true;
@@ -784,29 +882,85 @@ namespace
       if ( !branch.getBoundaryPoints( theDivPoints[i], bp[0], bp[1] ))
         return false;
 
-      NodePoint np[2] = { NodePoint( bp[0] ),
-                          NodePoint( bp[1] ) };
+      NodePoint  np[2] = { NodePoint( bp[0] ),
+                           NodePoint( bp[1] )};
       bool isVertex[2] = { findVertex( np[0], theSinuEdges, meshDS ),
                            findVertex( np[1], theSinuEdges, meshDS )};
 
       map< double, pair< NodePoint, NodePoint > >::iterator u2NP =
         thePointsOnE.insert( make_pair( uMA, make_pair( np[0], np[1]))).first;
 
+      if ( !isVertex[0] && !isVertex[1] ) return false; // error
       if ( isVertex[0] && isVertex[1] )
         continue;
+      const size_t iVertex = isVertex[0] ? 0 : 1;
+      const size_t iNode   = 1 - iVertex;
 
-      bool isOppComputed = theIsEdgeComputed[ np[ isVertex[0] ]._edgeInd ];
-
+      bool isOppComputed = theIsEdgeComputed[ np[ iNode ]._edgeInd ];
       if ( !isOppComputed )
         continue;
 
       // a VERTEX is projected on a meshed EDGE; there are two options:
-      // - a projected point is joined with a closet node if a strip between this and neighbor
-      // projection is wide enough; joining is done by setting the same node to the BoundaryPoint
-      // - a neighbor projection is merged this this one if it too close; a node of deleted
+      // 1) a projected point is joined with a closet node if a strip between this and neighbor
+      // projection is WIDE enough; joining is done by creating a node coincident with the
+      //  existing node which will be merged together after all;
+      // 2) a neighbor projection is merged with this one if it is TOO CLOSE; a node of deleted
       // projection is set to the BoundaryPoint of this projection
 
+      // evaluate distance to neighbor projections
+      const double rShort = 0.2;
+      bool isShortPrev[2], isShortNext[2];
+      map< double, pair< NodePoint, NodePoint > >::iterator u2NPPrev = u2NP, u2NPNext = u2NP;
+      --u2NPPrev; ++u2NPNext;
+      for ( int iS = 0; iS < 2; ++iS ) // side with Vertex and side with Nodes
+      {
+        NodePoint np     = get( u2NP->second,     iS );
+        NodePoint npPrev = get( u2NPPrev->second, iS );
+        NodePoint npNext = get( u2NPNext->second, iS );
+        gp_Pnt     p     = np    .Point( theCurves );
+        gp_Pnt     pPrev = npPrev.Point( theCurves );
+        gp_Pnt     pNext = npNext.Point( theCurves );
+        double  distPrev = p.Distance( pPrev );
+        double  distNext = p.Distance( pNext );
+        double         r = distPrev / ( distPrev + distNext );
+        isShortPrev[iS] = ( r < rShort );
+        isShortNext[iS] = (( 1 - r ) > ( 1 - rShort ));
+      }
+
+      map< double, pair< NodePoint, NodePoint > >::iterator u2NPClose;
 
+      if (( isShortPrev[0] && isShortPrev[1] ) || // option 2) -> remove a too close projection
+          ( isShortNext[0] && isShortNext[1] ))
+      {
+        u2NPClose = isShortPrev[0] ? u2NPPrev : u2NPNext;
+        NodePoint& npProj  = get( u2NP->second, iNode );       // NP of VERTEX projection
+        NodePoint npCloseN = get( u2NPClose->second, iNode);   // NP close to npProj
+        NodePoint npCloseV = get( u2NPClose->second, iVertex); // NP close to VERTEX
+        if ( !npCloseV._node )
+        {
+          npProj = npCloseN;
+          thePointsOnE.erase( isShortPrev[0] ? u2NPPrev : u2NPNext );
+          continue;
+        }
+        else
+        {
+          // can't remove the neighbor projection as it is also from VERTEX, -> option 1)
+        }
+      }
+      // else option 1) - wide enough -> "duplicate" existing node
+      {
+        u2NPClose = isShortPrev[ iNode ] ? u2NPPrev : u2NPNext;
+        NodePoint& npProj   = get( u2NP->second, iNode );       // NP of VERTEX projection
+        NodePoint& npCloseN = get( u2NPClose->second, iNode );  // NP close to npProj
+        // npProj._edgeInd = npCloseN._edgeInd;
+        // npProj._u       = npCloseN._u + 1e-3 * Abs( get( u2NPPrev->second, iNode )._u -
+        //                                             get( u2NPNext->second, iNode )._u );
+        gp_Pnt        p = npProj.Point( theCurves );
+        npProj._node    = meshDS->AddNode( p.X(), p.Y(), p.Z() );
+        meshDS->SetNodeOnEdge( npProj._node, theSinuEdges[ npProj._edgeInd ], npProj._u  );
+
+        theNodes2Merge[ npCloseN._node ].push_back( npProj._node );
+      }
     }
     return true;
   }
@@ -816,6 +970,7 @@ namespace
    * \brief Divide the sinuous EDGEs by projecting the division point of Medial
    *        Axis to the EGDEs
    *  \param [in] theHelper - the helper
+   *  \param [in] theMinSegLen - minimal segment length
    *  \param [in] theMA - the Medial Axis
    *  \param [in] theMAParams - parameters of division points of \a theMA
    *  \param [in] theSinuEdges - the EDGEs to make nodes on
@@ -825,10 +980,10 @@ namespace
   //================================================================================
 
   bool computeSinuEdges( SMESH_MesherHelper&        theHelper,
+                         double                     /*theMinSegLen*/,
                          SMESH_MAT2d::MedialAxis&   theMA,
                          vector<double>&            theMAParams,
-                         const vector<TopoDS_Edge>& theSinuEdges,
-                         const size_t               theSinuSide0Size)
+                         SinuousFace&               theSinuFace)
   {
     if ( theMA.getBranches().size() != 1 )
       return false;
@@ -842,6 +997,7 @@ namespace
     SMESHDS_Mesh* meshDS = theHelper.GetMeshDS();
     double f,l;
 
+    const vector< TopoDS_Edge >& theSinuEdges = theSinuFace._sinuEdges;
     vector< Handle(Geom_Curve) > curves ( theSinuEdges.size() );
     vector< int >                edgeIDs( theSinuEdges.size() );
     vector< bool >            isComputed( theSinuEdges.size() );
@@ -854,8 +1010,23 @@ namespace
       SMESH_subMesh* sm = mesh->GetSubMesh( theSinuEdges[i] );
       edgeIDs   [i] = sm->GetId();
       isComputed[i] = ( !sm->IsEmpty() );
-      // if ( isComputed[i] )
-      //   hasComputed = true;
+      if ( isComputed[i] )
+      {
+        TopAbs_ShapeEnum shape = getHypShape( mesh, theSinuEdges[i] );
+        if ( shape == TopAbs_SHAPE || shape <= TopAbs_FACE )
+        {
+          // EDGE computed using global hypothesis -> clear it
+          bool hasComputedFace = false;
+          PShapeIteratorPtr faceIt = theHelper.GetAncestors( theSinuEdges[i], *mesh, TopAbs_FACE );
+          while ( const TopoDS_Shape* face = faceIt->next() )
+            if (( !face->IsSame( theSinuFace.Face())) &&
+                ( hasComputedFace = !mesh->GetSubMesh( *face )->IsEmpty() ))
+              break;
+          if ( !hasComputedFace )
+            sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
+          isComputed[i] = false;
+        }
+      }
     }
 
     const SMESH_MAT2d::Branch& branch = theMA.getBranches()[0];
@@ -907,7 +1078,7 @@ namespace
         branch.getParameter( brp, maParamLast );
 
         map< double, const SMDS_MeshNode* >::iterator u2n = nodeParams.begin(), u2nEnd = --nodeParams.end();
-        TMAPar2NPoints::iterator pos, end = pointsOnE.end();
+        TMAPar2NPoints::iterator end = pointsOnE.end(), pos = end;
         TMAPar2NPoints::iterator & hint = (maParamLast > maParam1st) ? end : pos;
         for ( ++u2n; u2n != u2nEnd; ++u2n )
         {
@@ -918,7 +1089,7 @@ namespace
           if ( !branch.getParameter( brp, maParam ))
             return false;
 
-          npN = NodePoint( u2n->second );
+          npN = NodePoint( u2n->second, u2n->first, iEdgeComputed );
           npB = NodePoint( bndPnt );
           pos = pointsOnE.insert( hint, make_pair( maParam, make_pair( np0, np1 )));
         }
@@ -950,7 +1121,8 @@ namespace
       ++iEdgePair;
     }
 
-    if ( !projectVertices( theHelper, theMA, divPoints, theSinuEdges, isComputed, pointsOnE ))
+    if ( !projectVertices( theHelper, theMA, divPoints, theSinuEdges, curves,
+                           isComputed, pointsOnE, theSinuFace._nodesToMerge ))
       return false;
 
     // create nodes
@@ -1115,6 +1287,29 @@ namespace
     return true;
   }
 
+  //================================================================================
+  /*!
+   * \brief Remove temporary node
+   */
+  //================================================================================
+
+  void mergeNodes( SMESH_MesherHelper& theHelper,
+                   SinuousFace&        theSinuFace )
+  {
+    SMESH_MeshEditor editor( theHelper.GetMesh() );
+    SMESH_MeshEditor::TListOfListOfNodes nodesGroups;
+
+    TMergeMap::iterator n2nn = theSinuFace._nodesToMerge.begin();
+    for ( ; n2nn != theSinuFace._nodesToMerge.end(); ++n2nn )
+    {
+      nodesGroups.push_back( list< const SMDS_MeshNode* >() );
+      list< const SMDS_MeshNode* > & group = nodesGroups.back();
+
+      group.push_back( n2nn->first );
+      group.splice( group.end(), n2nn->second );
+    }
+    editor.MergeNodes( nodesGroups );
+  }
 
 } // namespace
 
@@ -1181,7 +1376,7 @@ bool StdMeshers_QuadFromMedialAxis_1D2D::computeQuads( SMESH_MesherHelper&
 
   StdMeshers_Quadrangle_2D::myProxyMesh.reset();
   StdMeshers_Quadrangle_2D::myHelper = 0;
-  
+
   return ok;
 }
 
@@ -1200,37 +1395,49 @@ bool StdMeshers_QuadFromMedialAxis_1D2D::Compute(SMESH_Mesh&         theMesh,
   TopoDS_Face F = TopoDS::Face( theShape );
   if ( F.Orientation() >= TopAbs_INTERNAL ) F.Orientation( TopAbs_FORWARD );
 
-  list< TopoDS_Edge > edges;
-  list< int > nbEdgesInWire;
-  int nbWire = SMESH_Block::GetOrderedEdges (F, edges, nbEdgesInWire);
+  SinuousFace sinuFace( F );
+
+  _progress = 0.01;
 
-  vector< TopoDS_Edge > sinuSide[2], shortSide[2];
-  if ( nbWire == 1 && getSinuousEdges( helper, F, edges, sinuSide, shortSide ))
+  if ( getSinuousEdges( helper, sinuFace ))
   {
-    vector< TopoDS_Edge > sinuEdges  = sinuSide[0];
-    sinuEdges.insert( sinuEdges.end(), sinuSide[1].begin(), sinuSide[1].end() );
-    if ( sinuEdges.size() > 2 )
-      return error(COMPERR_BAD_SHAPE, "Not yet supported case" );
+    _progress = 0.2;
 
-    double minSegLen = getMinSegLen( helper, sinuEdges );
-    SMESH_MAT2d::MedialAxis ma( F, sinuEdges, minSegLen, /*ignoreCorners=*/true );
+    // if ( sinuFace._sinuEdges.size() > 2 )
+    //   return error(COMPERR_BAD_SHAPE, "Not yet supported case" );
+
+    double minSegLen = getMinSegLen( helper, sinuFace._sinuEdges );
+    SMESH_MAT2d::MedialAxis ma( F, sinuFace._sinuEdges, minSegLen, /*ignoreCorners=*/true );
 
     if ( !_regular1D )
       _regular1D = new Algo1D( _studyId, _gen );
     _regular1D->SetSegmentLength( minSegLen );
 
     vector<double> maParams;
-    if ( ! divideMA( helper, ma, sinuEdges, sinuSide[0].size(), _regular1D, maParams ))
+    if ( ! divideMA( helper, ma, sinuFace, _regular1D, maParams ))
       return error(COMPERR_BAD_SHAPE);
 
-    if ( !computeShortEdges( helper, shortSide[0], _regular1D ) ||
-         !computeShortEdges( helper, shortSide[1], _regular1D ))
+    _progress = 0.4;
+
+    if ( !computeShortEdges( helper, sinuFace._shortSide[0], _regular1D ) ||
+         !computeShortEdges( helper, sinuFace._shortSide[1], _regular1D ))
       return error("Failed to mesh short edges");
 
-    if ( !computeSinuEdges( helper, ma, maParams, sinuEdges, sinuSide[0].size() ))
+    _progress = 0.6;
+
+    if ( !computeSinuEdges( helper, minSegLen, ma, maParams, sinuFace ))
       return error("Failed to mesh sinuous edges");
 
-    return computeQuads( helper, F, sinuSide, shortSide );
+    _progress = 0.8;
+
+    bool ok = computeQuads( helper, F, sinuFace._sinuSide, sinuFace._shortSide );
+
+    if ( ok )
+      mergeNodes( helper, sinuFace );
+
+    _progress = 1.;
+
+    return ok;
   }
 
   return error(COMPERR_BAD_SHAPE, "Not implemented so far");
index 90005331aaa3d103a287dfc221d4bfe7b9e7a18e..0d567e4fb232d2e74af3458a136ca8d5cd6547f5 100644 (file)
@@ -106,7 +106,7 @@ StdMeshersGUI_DistrPreview::StdMeshersGUI_DistrPreview( QWidget* p, StdMeshers::
   myDistr->attach( this );
   QPen distrPen = QPen( Qt::blue, 1 );
   QwtSymbol* distrSymbol = new QwtSymbol( QwtSymbol::XCross, QBrush( Qt::blue ),
-                                                 QPen( Qt::blue ), QSize( 5, 5 ) );
+                                                  QPen( Qt::blue ), QSize( 5, 5 ) );
   myDistr->setPen( distrPen );
   myDistr->setSymbol( distrSymbol );
   if( Plot2d_QwtLegendLabel* anItem = getLegendLabel( myDistr ) ) {
index 63eb5de65f055e3a65d806d0bf367d6952fb65cd..03706a8fe392b5c65c59cc8d2a217d65a4d9131b 100644 (file)
@@ -57,7 +57,7 @@ public:
   StdMeshersGUI_ObjectReferenceParamWdg( SUIT_SelectionFilter* filter, 
                                          QWidget*              parent,
                                          bool                  multiSelection=false
-                                        /* ,bool                  stretch=true*/);
+                                         /* ,bool                  stretch=true*/);
   StdMeshersGUI_ObjectReferenceParamWdg( SMESH::MeshObjectType objType,
                                          QWidget*       parent,
                                          bool           multiSelection=false);