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 14b7a54..a67f47d 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 e46385b..1aa0661 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 6a9527b..2fd906b 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 976783d..80c3f59 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 bb193bc..0805ce2 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 cc6dc08..3cdbea8 100644 (file)
@@ -144,6 +144,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).
      *  \param IdsOfNodes List of node IDs for creation of element.
index 24a83d0..c50ed7e 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 0b53dd2..c70528f 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 41448b1..8a2ff7e 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 a083475..f83fe91 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 61b6fec..ba85161 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 86a41eb..fa974f7 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 2b393f4..ff12d38 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 1475ee8..d04b057 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 b12af78..549f194 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 65f9e87..1c9af41 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 3a9b380..b3ff7d7 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 ec37985..bcb5899 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 4503dd1..78ec260 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 056509f..58641e5 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;
 }
 
@@ -1387,6 +1372,69 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const vector<const SMDS_MeshNode*> &
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+/// 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
 /// @return The created volume or NULL if an element with this ID already exists
@@ -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 de397bf..bc3c740 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 2232f68..e629a2f 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 85cc747..d56f7b5 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 fa49ecd..5c22d7f 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 001387c..b86dc16 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 987ca65..d050097 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 cd281e0..0a772f5 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 351c905..235a9c2 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 4b3444a..4ba42c9 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 4878dc4..5221ab7 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 b45e011..1866631 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 25c01f8..cbe9466 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 7537bf8..294882a 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 6787e00..f360512 100644 (file)
@@ -245,6 +245,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
   //=======================================================================
   inline void AddTetrasWithID(SMDS_Mesh* theMesh,
@@ -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 4fbd546..b22079e 100644 (file)
@@ -296,6 +296,28 @@ void SMESHDS_Command::AddPolygonalFace (const int               ElementID,
 }
 
 //=======================================================================
+//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  : 
 //=======================================================================