]> SALOME platform Git repositories - modules/smesh.git/commitdiff
Salome HOME
Merge from OCC_Quadric_Mesh_2006
authoreap <eap@opencascade.com>
Mon, 6 Mar 2006 13:36:18 +0000 (13:36 +0000)
committereap <eap@opencascade.com>
Mon, 6 Mar 2006 13:36:18 +0000 (13:36 +0000)
87 files changed:
Makefile.in
idl/SMESH_BasicHypothesis.idl
idl/SMESH_Mesh.idl
resources/StdMeshers.xml
src/Controls/SMESH_Controls.cxx
src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx
src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx
src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx
src/DriverSTL/DriverSTL_W_SMDS_Mesh.cxx
src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx
src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx
src/DriverUNV/UNV2412_Structure.cxx
src/OBJECT/SMESH_Actor.cxx
src/OBJECT/SMESH_Object.cxx
src/SMDS/Makefile.in
src/SMDS/SMDS_ElemIterator.hxx
src/SMDS/SMDS_FaceOfEdges.cxx
src/SMDS/SMDS_FaceOfEdges.hxx
src/SMDS/SMDS_FaceOfNodes.cxx
src/SMDS/SMDS_FaceOfNodes.hxx
src/SMDS/SMDS_Mesh.cxx
src/SMDS/SMDS_Mesh.hxx
src/SMDS/SMDS_MeshEdge.cxx
src/SMDS/SMDS_MeshEdge.hxx
src/SMDS/SMDS_MeshElement.cxx
src/SMDS/SMDS_MeshElement.hxx
src/SMDS/SMDS_MeshNode.hxx
src/SMDS/SMDS_PolygonalFaceOfNodes.cxx
src/SMDS/SMDS_PolygonalFaceOfNodes.hxx
src/SMDS/SMDS_VolumeOfNodes.cxx
src/SMDS/SMDS_VolumeOfNodes.hxx
src/SMDS/SMDS_VolumeTool.cxx
src/SMDS/SMDS_VolumeTool.hxx
src/SMESH/Makefile.in
src/SMESH/SMESH_2D_Algo.cxx
src/SMESH/SMESH_2D_Algo.hxx
src/SMESH/SMESH_3D_Algo.cxx
src/SMESH/SMESH_3D_Algo.hxx
src/SMESH/SMESH_Algo.cxx
src/SMESH/SMESH_Algo.hxx
src/SMESH/SMESH_Gen.cxx
src/SMESH/SMESH_HypoFilter.cxx
src/SMESH/SMESH_HypoFilter.hxx
src/SMESH/SMESH_Hypothesis.cxx
src/SMESH/SMESH_Hypothesis.hxx
src/SMESH/SMESH_Mesh.cxx
src/SMESH/SMESH_Mesh.hxx
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_subMesh.cxx
src/SMESH/SMESH_subMesh.hxx
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/Makefile.in
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx
src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx
src/SMESHGUI/SMESH_icons.po
src/SMESHGUI/SMESH_images.po
src/SMESHGUI/SMESH_msg_en.po
src/SMESH_I/SMESH_2smeshpy.cxx
src/SMESH_I/SMESH_Hypothesis_i.cxx
src/SMESH_I/SMESH_MEDMesh_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.hxx
src/SMESH_SWIG/smesh.py
src/StdMeshers/Makefile.in
src/StdMeshers/StdMeshers_Hexa_3D.cxx
src/StdMeshers/StdMeshers_Hexa_3D.hxx
src/StdMeshers/StdMeshers_MEFISTO_2D.cxx
src/StdMeshers/StdMeshers_MEFISTO_2D.hxx
src/StdMeshers/StdMeshers_Penta_3D.cxx
src/StdMeshers/StdMeshers_Penta_3D.hxx
src/StdMeshers/StdMeshers_Propagation.cxx
src/StdMeshers/StdMeshers_Quadrangle_2D.cxx
src/StdMeshers/StdMeshers_Quadrangle_2D.hxx
src/StdMeshers/StdMeshers_QuadraticMesh.cxx
src/StdMeshers/StdMeshers_QuadraticMesh.hxx
src/StdMeshers/StdMeshers_Regular_1D.cxx
src/StdMeshers/StdMeshers_Regular_1D.hxx
src/StdMeshersGUI/StdMeshers_images.po
src/StdMeshers_I/Makefile.in
src/StdMeshers_I/StdMeshers_i.cxx

index f3a90dfb5a1b2f1b15f94676590ef6ca0a4db6f9..c01512951a21f331ed0e3c82298577004f8b7c26 100644 (file)
@@ -131,7 +131,14 @@ mesh_pattern.png \
 pattern_sample_2d.png \
 pattern_sample_3D.png \
 mesh_add.png \
-mesh_remove.png
+mesh_remove.png \
+mesh_quad_edge.png \
+mesh_quad_triangle.png \
+mesh_quad_quadrangle.png \
+mesh_quad_tetrahedron.png \
+mesh_quad_pyramid.png \
+mesh_quad_pentahedron.png \
+mesh_quad_hexahedron.png
 
 BIN_SCRIPT= \
 VERSION
index b6367b75ddec63826c7e21e57a168988ad956e69..7880020e72ee0ac27001647277fefdce42df8c2b 100644 (file)
@@ -286,6 +286,20 @@ module StdMeshers
   {
   };
 
+  /*!
+   * StdMeshers_QuadraticMesh: interface of "QuadraticMesh" hypothesis.
+   * This is an auxiliary 1D hypothesis whose presence forces construction 
+   * of quadratic edges.
+   * If the 2D mesher sees that all boundary edges are quadratic ones,
+   * it generates quadratic faces, else it generates linear faces using
+   * medium nodes as if they were vertex ones.
+   * The 3D mesher generates quadratic volumes only if all boundary faces
+   * are quadratic ones, else it fails.
+   */
+  interface StdMeshers_QuadraticMesh : SMESH::SMESH_Hypothesis
+  {
+  };
+
 
   /*!
    * StdMeshers_Regular_1D: interface of "Wire discretisation" algorithm
index 5a2915c8d4ef0d803eb024b6437bfcf289375f13..4b7b547071a67cef08821288b484f5fc4c877747 100644 (file)
@@ -69,7 +69,14 @@ module SMESH
       MOVE_NODE,
       CHANGE_ELEMENT_NODES,
       CHANGE_POLYHEDRON_NODES,
-      RENUMBER
+      RENUMBER,
+      ADD_QUADEDGE,
+      ADD_QUADTRIANGLE,
+      ADD_QUADQUADRANGLE,
+      ADD_QUADTETRAHEDRON,
+      ADD_QUADPYRAMID,
+      ADD_QUADPENTAHEDRON,
+      ADD_QUADHEXAHEDRON
     };
 
   struct log_block
@@ -526,6 +533,8 @@ module SMESH
 
     boolean AddFace(in long_array IDsOfNodes);
 
+    boolean AddPolygonalFace(in long_array IdsOfNodes);
+
     boolean AddVolume(in long_array IDsOfNodes);
 
     /*!
index 2c1cd12cccdea1748c34fda3467bb921d77a8acb..6daf06253c936a2ea5d1435d88479271cbca3c5d 100644 (file)
                 icon-id="mesh_algo_quad.png"
                 dim="2"/>
 
+    <hypothesis type="QuadraticMesh"
+                label-id="Quadratic Mesh"
+                icon-id="mesh_algo_quad.png"
+                dim="1"
+                auxiliary="true"/>                
+
     <hypothesis type="MaxElementArea"
                 label-id="Max. Element Area"
                 icon-id="mesh_hypo_area.png"
index 717f8e66ae41e82d0d06fdeef300d432aca0ff2d..008c83dfb61e6b7303d5a8c469cca3da01a25f49 100644 (file)
@@ -46,6 +46,8 @@
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_VolumeTool.hxx"
+#include "SMDS_QuadraticFaceOfNodes.hxx"
+#include "SMDS_QuadraticEdge.hxx"
 
 
 /*
@@ -87,32 +89,69 @@ namespace{
       return 0;
 
     const SMDS_MeshElement* anEdge = theMesh->FindElement( theId );
-    if ( anEdge == 0 || anEdge->GetType() != SMDSAbs_Edge || anEdge->NbNodes() != 2 )
+    if ( anEdge == 0 || anEdge->GetType() != SMDSAbs_Edge/* || anEdge->NbNodes() != 2 */)
       return 0;
 
-    TColStd_MapOfInteger aMap;
-
-    int aResult = 0;
-    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++;
-         }
-       }
+    // for each pair of nodes in anEdge (there are 2 pairs in a quadratic edge)
+    // count elements containing both nodes of the pair.
+    // Note that there may be such cases for a quadratic edge (a horizontal line):
+    //
+    //  Case 1          Case 2
+    //  |     |      |        |      |
+    //  |     |      |        |      |
+    //  +-----+------+  +-----+------+ 
+    //  |            |  |            |
+    //  |            |  |            |
+    // result sould be 2 in both cases
+    //
+    int aResult0 = 0, aResult1 = 0;
+     // last node, it is a medium one in a quadratic edge
+    const SMDS_MeshNode* aLastNode = anEdge->GetNode( anEdge->NbNodes() - 1 );
+    const SMDS_MeshNode* aNode0 = anEdge->GetNode( 0 );
+    const SMDS_MeshNode* aNode1 = anEdge->GetNode( 1 );
+    if ( aNode1 == aLastNode ) aNode1 = 0;
+
+    SMDS_ElemIteratorPtr anElemIter = aLastNode->GetInverseElementIterator();
+    while( anElemIter->more() ) {
+      const SMDS_MeshElement* anElem = anElemIter->next();
+      if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) {
+        SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
+        while ( anIter->more() ) {
+          if ( const SMDS_MeshElement* anElemNode = anIter->next() ) {
+            if ( anElemNode == aNode0 ) {
+              aResult0++;
+              if ( !aNode1 ) break; // not a quadratic edge
+            }
+            else if ( anElemNode == aNode1 )
+              aResult1++;
+          }
+        }
       }
     }
+    int aResult = 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;
   }
@@ -154,23 +193,41 @@ bool NumericalFunctor::GetPoints(const int theId,
 }
 
 bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem,
-                                 TSequenceOfXYZ& theRes )
+                                 TSequenceOfXYZ&         theRes )
 {
   theRes.clear();
 
   if ( anElem == 0)
     return false;
 
+  theRes.reserve( anElem->NbNodes() );
+
   // Get nodes of the element
-  SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
-  if ( anIter != 0 )
-  {
-    while( anIter->more() )
-    {
-      const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next();
-      if ( aNode != 0 ){
+  SMDS_ElemIteratorPtr anIter;
+
+  if ( anElem->IsQuadratic() ) {
+    switch ( anElem->GetType() ) {
+    case SMDSAbs_Edge:
+      anIter = static_cast<const SMDS_QuadraticEdge*>
+        (anElem)->interlacedNodesElemIterator();
+      break;
+    case SMDSAbs_Face:
+      anIter = static_cast<const SMDS_QuadraticFaceOfNodes*>
+        (anElem)->interlacedNodesElemIterator();
+      break;
+    default:
+      anIter = anElem->nodesIterator();
+      //return false;
+    }
+  }
+  else {
+    anIter = anElem->nodesIterator();
+  }
+
+  if ( anIter ) {
+    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() ) );
-      }
     }
   }
 
@@ -285,6 +342,7 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P )
   // According to "Mesh quality control" by Nadir Bouhamau referring to
   // Pascal Jean Frey and Paul-Louis George. Maillages, applications aux elements finis.
   // Hermes Science publications, Paris 1999 ISBN 2-7462-0024-4
+  // PAL10872
 
   int nbNodes = P.size();
 
@@ -840,22 +898,21 @@ SMDSAbs_ElementType Skew::GetType() const
 */
 double Area::GetValue( const TSequenceOfXYZ& P )
 {
-  double aArea = 0;
-  if ( P.size() == 3 )
-    return getArea( P( 1 ), P( 2 ), P( 3 ) );
-  else if (P.size() > 3)
-    aArea = getArea( P( 1 ), P( 2 ), P( 3 ) );
-  else
-    return 0;
-
-  for (int i=4; i<=P.size(); i++)
-    aArea += getArea(P(1),P(i-1),P(i));
-  return aArea;
+  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++) {
+    gp_Vec aVec1( P(i-1) - P(1) );
+    gp_Vec aVec2( P(i) - P(1) );
+    gp_Vec tmp = aVec1 ^ aVec2;
+    SumVec.Add(tmp);
+  }
+  return SumVec.Magnitude() * 0.5;
 }
 
 double Area::GetBadRate( double Value, int /*nbNodes*/ ) const
 {
-  // meaningless as it is not quality control functor
+  // meaningless as it is not quality control functor
   return Value;
 }
 
@@ -871,7 +928,11 @@ SMDSAbs_ElementType Area::GetType() const
 */
 double Length::GetValue( const TSequenceOfXYZ& P )
 {
-  return ( P.size() == 2 ? getDistance( P( 1 ), P( 2 ) ) : 0 );
+  switch ( P.size() ) {
+  case 2:  return getDistance( P( 1 ), P( 2 ) );
+  case 3:  return getDistance( P( 1 ), P( 2 ) ) + getDistance( P( 2 ), P( 3 ) );
+  default: return 0.;
+  }
 }
 
 double Length::GetBadRate( double Value, int /*nbNodes*/ ) const
@@ -894,7 +955,10 @@ 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 );
@@ -908,7 +972,11 @@ double Length2D::GetValue( long theElementId)
     case SMDSAbs_Edge:
       if (len == 2){
        aVal = getDistance( P( 1 ), P( 2 ) );
-       break;
+        break;
+      }
+      else if (len == 3){ // quadratic edge
+       aVal = getDistance(P( 1 ),P( 3 )) + getDistance(P( 3 ),P( 2 ));
+        break;
       }
     case SMDSAbs_Face:
       if (len == 3){ // triangles
@@ -926,6 +994,22 @@ double Length2D::GetValue( long theElementId)
        aVal = Max(Max(L1,L2),Max(L3,L4));
        break;
       }
+      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 = Max(L1,Max(L2,L3));
+        //cout<<"L1="<<L1<<" L2="<<L2<<"L3="<<L3<<" aVal="<<aVal<<endl;
+       break;
+      }
+      else 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 = Max(Max(L1,L2),Max(L3,L4));
+       break;
+      }
     case SMDSAbs_Volume:
       if (len == 4){ // tetraidrs
        double L1 = getDistance(P( 1 ),P( 2 ));
@@ -987,6 +1071,63 @@ double Length2D::GetValue( long theElementId)
 
       }
 
+      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 ));
+       double L3 = getDistance(P( 3 ),P( 7 )) + getDistance(P( 7 ),P( 1 ));
+       double L4 = getDistance(P( 1 ),P( 8 )) + getDistance(P( 8 ),P( 4 ));
+       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 = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+       break;
+      }
+      else 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( 1 ));
+       double L4 = getDistance(P( 4 ),P( 9 )) + getDistance(P( 9 ),P( 1 ));
+       double L5 = getDistance(P( 1 ),P( 10 )) + getDistance(P( 10 ),P( 5 ));
+       double L6 = getDistance(P( 2 ),P( 11 )) + getDistance(P( 11 ),P( 5 ));
+       double L7 = getDistance(P( 3 ),P( 12 )) + getDistance(P( 12 ),P( 5 ));
+       double L8 = getDistance(P( 4 ),P( 13 )) + getDistance(P( 13 ),P( 5 ));
+       aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+       aVal = Max(aVal,Max(L7,L8));
+       break;
+      }
+      else 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 ));
+       double L4 = getDistance(P( 4 ),P( 10 )) + getDistance(P( 10 ),P( 5 ));
+       double L5 = getDistance(P( 5 ),P( 11 )) + getDistance(P( 11 ),P( 6 ));
+       double L6 = getDistance(P( 6 ),P( 12 )) + getDistance(P( 12 ),P( 4 ));
+       double L7 = getDistance(P( 1 ),P( 13 )) + getDistance(P( 13 ),P( 4 ));
+       double L8 = getDistance(P( 2 ),P( 14 )) + getDistance(P( 14 ),P( 5 ));
+       double L9 = getDistance(P( 3 ),P( 15 )) + getDistance(P( 15 ),P( 6 ));
+       aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+       aVal = Max(aVal,Max(Max(L7,L8),L9));
+       break;
+      }
+      else 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 ));
+       double L4 = getDistance(P( 4 ),P( 12 )) + getDistance(P( 12 ),P( 1 ));
+       double L5 = getDistance(P( 5 ),P( 13 )) + getDistance(P( 13 ),P( 6 ));
+       double L6 = getDistance(P( 6 ),P( 14 )) + getDistance(P( 14 ),P( 7 ));
+       double L7 = getDistance(P( 7 ),P( 15 )) + getDistance(P( 15 ),P( 8 ));
+       double L8 = getDistance(P( 8 ),P( 16 )) + getDistance(P( 16 ),P( 5 ));
+       double L9 = getDistance(P( 1 ),P( 17 )) + getDistance(P( 17 ),P( 5 ));
+       double L10= getDistance(P( 2 ),P( 18 )) + getDistance(P( 18 ),P( 6 ));
+       double L11= getDistance(P( 3 ),P( 19 )) + getDistance(P( 19 ),P( 7 ));
+       double L12= getDistance(P( 4 ),P( 20 )) + getDistance(P( 20 ),P( 8 ));
+       aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+       aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10)));
+       aVal = Max(aVal,Max(L11,L12));
+       break;
+
+      }
+
     default: aVal=-1;
     }
 
@@ -1038,38 +1179,81 @@ void Length2D::GetValues(TValues& theValues){
   SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
   for(; anIter->more(); ){
     const SMDS_MeshFace* anElem = anIter->next();
-    SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
-    long aNodeId[2];
-    gp_Pnt P[3];
 
-    double aLength;
-    const SMDS_MeshElement* aNode;
-    if(aNodesIter->more()){
-      aNode = aNodesIter->next();
-      const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode;
-      P[0] = P[1] = gp_Pnt(aNodes->X(),aNodes->Y(),aNodes->Z());
-      aNodeId[0] = aNodeId[1] = aNode->GetID();
-      aLength = 0;
-    }
-    for(; aNodesIter->more(); ){
-      aNode = aNodesIter->next();
-      const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode;
-      long anId = aNode->GetID();
-
-      P[2] = gp_Pnt(aNodes->X(),aNodes->Y(),aNodes->Z());
+    if(anElem->IsQuadratic()) {
+      const SMDS_QuadraticFaceOfNodes* F =
+        static_cast<const SMDS_QuadraticFaceOfNodes*>(anElem);
+      // use special nodes iterator
+      SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+      long aNodeId[4];
+      gp_Pnt P[4];
+
+      double aLength;
+      const SMDS_MeshElement* aNode;
+      if(anIter->more()){
+        aNode = anIter->next();
+        const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode;
+        P[0] = P[1] = gp_Pnt(aNodes->X(),aNodes->Y(),aNodes->Z());
+        aNodeId[0] = aNodeId[1] = aNode->GetID();
+        aLength = 0;
+      }
+      for(; anIter->more(); ){
+        const SMDS_MeshNode* N1 = static_cast<const SMDS_MeshNode*> (anIter->next());
+        P[2] = gp_Pnt(N1->X(),N1->Y(),N1->Z());
+        aNodeId[2] = N1->GetID();
+        aLength = P[1].Distance(P[2]);
+        if(!anIter->more()) break;
+        const SMDS_MeshNode* N2 = static_cast<const SMDS_MeshNode*> (anIter->next());
+        P[3] = gp_Pnt(N2->X(),N2->Y(),N2->Z());
+        aNodeId[3] = N2->GetID();
+        aLength += P[2].Distance(P[3]);
+        Value aValue1(aLength,aNodeId[1],aNodeId[2]);
+        Value aValue2(aLength,aNodeId[2],aNodeId[3]);
+        P[1] = P[3];
+        aNodeId[1] = aNodeId[3];
+        theValues.insert(aValue1);
+        theValues.insert(aValue2);
+      }
+      aLength += P[2].Distance(P[0]);
+      Value aValue1(aLength,aNodeId[1],aNodeId[2]);
+      Value aValue2(aLength,aNodeId[2],aNodeId[0]);
+      theValues.insert(aValue1);
+      theValues.insert(aValue2);
+    }
+    else {
+      SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
+      long aNodeId[2];
+      gp_Pnt P[3];
+
+      double aLength;
+      const SMDS_MeshElement* aNode;
+      if(aNodesIter->more()){
+        aNode = aNodesIter->next();
+        const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode;
+        P[0] = P[1] = gp_Pnt(aNodes->X(),aNodes->Y(),aNodes->Z());
+        aNodeId[0] = aNodeId[1] = aNode->GetID();
+        aLength = 0;
+      }
+      for(; aNodesIter->more(); ){
+        aNode = aNodesIter->next();
+        const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode;
+        long anId = aNode->GetID();
+        
+        P[2] = gp_Pnt(aNodes->X(),aNodes->Y(),aNodes->Z());
+        
+        aLength = P[1].Distance(P[2]);
+        
+        Value aValue(aLength,aNodeId[1],anId);
+        aNodeId[1] = anId;
+        P[1] = P[2];
+        theValues.insert(aValue);
+      }
 
-      aLength = P[1].Distance(P[2]);
+      aLength = P[0].Distance(P[1]);
 
-      Value aValue(aLength,aNodeId[1],anId);
-      aNodeId[1] = anId;
-      P[1] = P[2];
+      Value aValue(aLength,aNodeId[0],aNodeId[1]);
       theValues.insert(aValue);
     }
-
-    aLength = P[0].Distance(P[1]);
-
-    Value aValue(aLength,aNodeId[0],aNodeId[1]);
-    theValues.insert(aValue);
   }
 }
 
@@ -1207,7 +1391,7 @@ void MultiConnection2D::GetValues(MValues& theValues){
       const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode1;
       aNodeId[0] = aNodeId[1] = aNodes->GetID();
     }
-    for(; aNodesIter->more(); ){
+    for(; aNodesIter->more(); ) {
       aNode2 = (SMDS_MeshNode*) aNodesIter->next();
       long anId = aNode2->GetID();
       aNodeId[2] = anId;
@@ -1217,7 +1401,8 @@ void MultiConnection2D::GetValues(MValues& theValues){
       if (aItr != theValues.end()){
        aItr->second += 1;
        //aNbConnects = nb;
-      } else {
+      }
+      else {
        theValues[aValue] = 1;
        //aNbConnects = 1;
       }
@@ -1227,10 +1412,11 @@ void MultiConnection2D::GetValues(MValues& theValues){
     }
     Value aValue(aNodeId[0],aNodeId[2]);
     MValues::iterator aItr = theValues.find(aValue);
-    if (aItr != theValues.end()){
+    if (aItr != theValues.end()) {
       aItr->second += 1;
       //aNbConnects = nb;
-    } else {
+    }
+    else {
       theValues[aValue] = 1;
       //aNbConnects = 1;
     }
@@ -1346,41 +1532,33 @@ bool FreeEdges::IsSatisfy( long theId )
   if ( aFace == 0 || aFace->GetType() != SMDSAbs_Face || aFace->NbNodes() < 3 )
     return false;
 
-  int nbNodes = aFace->NbNodes();
-  //const SMDS_MeshNode* aNodes[ nbNodes ];
-#ifndef WNT
-  const SMDS_MeshNode* aNodes [nbNodes];
-#else
-  const SMDS_MeshNode** aNodes = (const SMDS_MeshNode **)new SMDS_MeshNode*[nbNodes];
-#endif
-  int i = 0;
-  SMDS_ElemIteratorPtr anIter = aFace->nodesIterator();
+  SMDS_ElemIteratorPtr anIter;
+  if ( aFace->IsQuadratic() ) {
+    anIter = static_cast<const SMDS_QuadraticFaceOfNodes*>
+      (aFace)->interlacedNodesElemIterator();
+  }
+  else {
+    anIter = aFace->nodesIterator();
+  }
   if ( anIter != 0 )
+    return false;
+
+  int i = 0, nbNodes = aFace->NbNodes();
+  vector <const SMDS_MeshNode*> aNodes( nbNodes+1 );
+  while( anIter->more() )
   {
-    while( anIter->more() )
-    {
-      const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next();
-      if ( aNode == 0 )
-        return false;
-      aNodes[ i++ ] = aNode;
-    }
+    const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next();
+    if ( aNode == 0 )
+      return false;
+    aNodes[ i++ ] = aNode;
   }
+  aNodes[ nbNodes ] = aNodes[ 0 ];
 
-  for ( int i = 0; i < nbNodes - 1; i++ )
-         if ( IsFreeEdge( &aNodes[ i ], theId ) ) {
-#ifdef WNT
-               delete [] aNodes;
-#endif
+  for ( i = 0; i < nbNodes; i++ )
+    if ( IsFreeEdge( &aNodes[ i ], theId ) )
       return true;
-         }
 
-  aNodes[ 1 ] = aNodes[ nbNodes - 1 ];
-  const Standard_Boolean isFree = IsFreeEdge( &aNodes[ 0 ], theId );
-#ifdef WNT
-               delete [] aNodes;
-#endif
-//  return 
- return isFree;
+  return false;
 }
 
 SMDSAbs_ElementType FreeEdges::GetType() const
@@ -2088,8 +2266,7 @@ static gp_XYZ getNormale( const SMDS_MeshFace* theFace )
   TColgp_Array1OfXYZ anArrOfXYZ(1,4);
   SMDS_ElemIteratorPtr aNodeItr = theFace->nodesIterator();
   int i = 1;
-  for ( ; aNodeItr->more() && i <= 4; i++ )
-  {
+  for ( ; aNodeItr->more() && i <= 4; i++ ) {
     SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next();
     anArrOfXYZ.SetValue(i, gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) );
   }
@@ -2097,8 +2274,7 @@ static gp_XYZ getNormale( const SMDS_MeshFace* theFace )
   gp_XYZ q1 = anArrOfXYZ.Value(2) - anArrOfXYZ.Value(1);
   gp_XYZ q2 = anArrOfXYZ.Value(3) - anArrOfXYZ.Value(1);
   n  = q1 ^ q2;
-  if ( aNbNode > 3 )
-  {
+  if ( aNbNode > 3 ) {
     gp_XYZ q3 = anArrOfXYZ.Value(4) - anArrOfXYZ.Value(1);
     n += q2 ^ q3;
   }
index 1f8d5ab61bd45d0ff85d58b30097a54938f08881..a54156dc74314bc5cc1496fd9bf9f5e12a621fe1 100644 (file)
@@ -32,7 +32,7 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform()
   Status aResult = DRS_OK;
 
   int nbNodes, nbCells;
-  int i;
+  //int i;
   
   char *file2Read = (char *)myFile.c_str();
   FILE* aFileId = fopen(file2Read, "w+");
@@ -52,7 +52,7 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform()
   nbNodes = myMesh->NbNodes();
   
   /* Combien de mailles, faces ou aretes ? */
-  int nb_of_nodes, nb_of_edges, nb_of_faces, nb_of_volumes;
+  int /*nb_of_nodes,*/ nb_of_edges, nb_of_faces, nb_of_volumes;
   nb_of_edges = myMesh->NbEdges();
   nb_of_faces = myMesh->NbFaces();
   nb_of_volumes = myMesh->NbVolumes();
index 9a9a31c23b26df55f4d1fe947d6cf6b0c650bb04..49c645f47a23a09f89e2cce8f55c93330cc4f70b 100644 (file)
@@ -311,242 +311,385 @@ DriverMED_R_SMESHDS_Mesh
               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);
-             
-             for(int iElem = 0; iElem < aNbElems; iElem++){
-               TInt aNbNodes = -1;
-               switch(aGeom){
-               case eSEG2:
-               case eSEG3:
-                 aNbNodes = 2;
-                 break;
-               case eTRIA3:
-               case eTRIA6:
-                 aNbNodes = 3;
-                 break;
-                 break;
-               case eQUAD4:
-               case eQUAD8:
-                 aNbNodes = 4;
-                 break;
-               case eTETRA4:
-               case eTETRA10:
-                 aNbNodes = 4;
-                 break;
-               case ePYRA5:
-               case ePYRA13:
-                 aNbNodes = 5;
-                 break;
-               case ePENTA6:
-               case ePENTA15:
-                 aNbNodes = 6;
-                 break;
-               case eHEXA8:
-               case eHEXA20:
-                 aNbNodes = 8;
-                 break;
-               }
-               TNodeIds aNodeIds(aNbNodes);
-               bool anIsValidConnect = false;
-               TCConnSlice aConnSlice = aCellInfo->GetConnSlice(iElem);
+              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);
+
+              for(int iElem = 0; iElem < aNbElems; iElem++){
+                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 eQUAD4:   aNbNodes = 4;  break;
+                case eQUAD8:   aNbNodes = 8;  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;
+                default:;
+                }
+                vector<TInt> aNodeIds(aNbNodes);
+                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];
+                  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];
+                  for(int iNode = 0; iNode < aNbNodes; iNode++)
+                    aNodeIds[iNode] = aConnSlice[iNode];
 #endif
-                 anIsValidConnect = true;
+                  anIsValidConnect = true;
 #ifndef _DEXCEPT_
-               }catch(const std::exception& exc){
-                 //INFOS("Follow exception was cought:\n\t"<<exc.what());
-                 aResult = DRS_FAIL;
-               }catch(...){
-                 //INFOS("Unknown exception was cought !!!");
-                 aResult = DRS_FAIL;
-               }
-#endif         
-               if(!anIsValidConnect)
-                 continue;
-               
-               bool isRenum = false;
-               SMDS_MeshElement* anElement = NULL;
-               TInt aFamNum = aCellInfo->GetFamNum(iElem);
+                }catch(const std::exception& exc){
+                  //INFOS("Follow exception was cought:\n\t"<<exc.what());
+                  aResult = DRS_FAIL;
+                }catch(...){
+                  //INFOS("Unknown exception was cought !!!");
+                  aResult = DRS_FAIL;
+                }
+#endif          
+                if(!anIsValidConnect)
+                  continue;
+
+                bool isRenum = false;
+                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 eSEG2:
-                 case eSEG3:
-                   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 eTRIA3:
-                 case eTRIA6:
-                   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 eQUAD4:
-                 case eQUAD8:
-                   aNbNodes = 4;
-                   // There is some differnce between SMDS and MED
-                   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 eTETRA4:
-                 case eTETRA10:
-                   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 ePYRA5:
-                 case ePYRA13:
-                   aNbNodes = 5;
-                   // There is some differnce between SMDS and MED
-                   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 ePENTA6:
-                 case ePENTA15:
-                   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 eHEXA8:
-                 case eHEXA20:
-                   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;
-                 }
+                  //MESSAGE("Try to create element # " << iElem << " with id = "
+                  //        << aCellInfo->GetElemNum(iElem));
+                  switch(aGeom){
+                  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 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 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;
+                    // There is some differnce between SMDS and MED
+                    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;
+                    // There is some differnce between SMDS and MED
+                    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[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;
+                  }
 #ifndef _DEXCEPT_
-               }catch(const std::exception& exc){
-                 //INFOS("Follow exception was cought:\n\t"<<exc.what());
-                 aResult = DRS_FAIL;
-               }catch(...){
-                 //INFOS("Unknown exception was cought !!!");
-                 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 ( checkFamilyID ( aFamily, aFamNum )) {
-                   // Save reference to this element from its family
-                   myFamilies[aFamNum]->AddElement(anElement);
-                   myFamilies[aFamNum]->SetType(anElement->GetType());
-                 }
-               }
-             }
-           }}
-         }
-       }
+                }catch(const std::exception& exc){
+                  //INFOS("Follow exception was cought:\n\t"<<exc.what());
+                  aResult = DRS_FAIL;
+                }catch(...){
+                  //INFOS("Unknown exception was cought !!!");
+                  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 ( checkFamilyID ( aFamily, aFamNum )) {
+                    // Save reference to this element from its family
+                    myFamilies[aFamNum]->AddElement(anElement);
+                    myFamilies[aFamNum]->SetType(anElement->GetType());
+                  }
+                }
+              }
+            }}
+          }
+        }
       }
     }
 #ifndef _DEXCEPT_
index 22b33cf63a5c195834cfa3ef4167fede8c21300b..877c24a672f05e378dd0e86d5a7724c586babe08 100644 (file)
@@ -393,39 +393,90 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
 #ifdef _ELEMENTS_BY_DIM_
       SMDS_MED_ENTITY = eARETE;
 #endif
+      // count edges of diff types
+      int aNbSeg3 = 0, aNbSeg2 = 0;
       SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
-      TInt aNbConnectivity = MED::GetNbNodes(eSEG2);
-      MED::TIntVector anElemNums(aNbElems);
-      MED::TIntVector aFamilyNums(aNbElems);
-      MED::TIntVector aConnectivity(aNbElems*aNbConnectivity);
-
-      for(TInt iElem = 0, iConn = 0; anIter->more(); iElem++, iConn+=aNbConnectivity){
+      while ( anIter->more() )
+        if ( anIter->next()->NbNodes() == 3 )
+          ++aNbSeg3;
+      aNbSeg2 = aNbElems - aNbSeg3;
+
+      TInt aNbSeg2Conn = MED::GetNbNodes(eSEG2);
+      MED::TIntVector aSeg2ElemNums, aSeg2FamilyNums, aSeg2Conn;
+      aSeg2ElemNums  .reserve( aNbSeg2 );
+      aSeg2FamilyNums.reserve( aNbSeg2 );
+      aSeg2Conn      .reserve( aNbSeg2*aNbSeg2Conn );
+
+      TInt aNbSeg3Conn = MED::GetNbNodes(eSEG3);
+      MED::TIntVector aSeg3ElemNums, aSeg3FamilyNums, aSeg3Conn;
+      aSeg3ElemNums  .reserve( aNbSeg3 );
+      aSeg3FamilyNums.reserve( aNbSeg3 );
+      aSeg3Conn      .reserve( aNbSeg3*aNbSeg3Conn );
+
+      anIter = myMesh->edgesIterator();
+      while ( anIter->more() ) {
        const SMDS_MeshEdge* anElem = anIter->next();
-       SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
-       for(TInt iNode = 0; iNode < aNbConnectivity && aNodesIter->more(); iNode++){
-         const SMDS_MeshElement* aNode = aNodesIter->next();
+       TInt aNbNodes = anElem->NbNodes();
+
+       TInt aNbConnectivity;
+       MED::TIntVector* anElemNums;
+        MED::TIntVector* aFamilyNums;
+       MED::TIntVector* aConnectivity;
+        switch(aNbNodes){
+        case 2:
+          aNbConnectivity = aNbSeg2Conn;
+          anElemNums      = &aSeg2ElemNums;
+          aFamilyNums     = &aSeg2FamilyNums;
+          aConnectivity   = &aSeg2Conn;
+          break;
+        case 3:
+          aNbConnectivity = aNbSeg3Conn;
+          anElemNums      = &aSeg3ElemNums;
+          aFamilyNums     = &aSeg3FamilyNums;
+          aConnectivity   = &aSeg3Conn;
+          break;
+        default:
+          break;
+        }
+
+        for(TInt iNode = 0; iNode < aNbNodes; iNode++) {
+         const SMDS_MeshElement* aNode = anElem->GetNode( iNode );
 #ifdef _EDF_NODE_IDS_
-         aConnectivity[iConn+iNode] = aNodeIdMap[aNode->GetID()];
+         aConnectivity->push_back( aNodeIdMap[aNode->GetID()] );
 #else
-         aConnectivity[iConn+iNode] = aNode->GetID();
+         aConnectivity->push_back( aNode->GetID() );
 #endif
-       }
-       anElemNums[iElem] = anElem->GetID();
+        }
 
-        if (anElemFamMap.find(anElem) != anElemFamMap.end())
-          aFamilyNums[iElem] = anElemFamMap[anElem];
+       anElemNums->push_back(anElem->GetID());
+
+        map<const SMDS_MeshElement*,int>::iterator edge_fam = anElemFamMap.find( anElem );
+        if ( edge_fam != anElemFamMap.end() )
+          aFamilyNums->push_back( edge_fam->second );
         else
-          aFamilyNums[iElem] = myEdgesDefaultFamilyId;
+          aFamilyNums->push_back( myFacesDefaultFamilyId );
       }
       
-      PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
-                                             SMDS_MED_ENTITY,
-                                             eSEG2,
-                                             aConnectivity,
-                                             SMDS_MED_CONNECTIVITY,
-                                             aFamilyNums,
-                                             anElemNums);
-      myMed->SetCellInfo(aCellInfo);
+      if ( aNbSeg2 ) {
+        PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
+                                                SMDS_MED_ENTITY,
+                                                eSEG2,
+                                                aSeg2Conn,
+                                                SMDS_MED_CONNECTIVITY,
+                                                aSeg2FamilyNums,
+                                                aSeg2ElemNums);
+        myMed->SetCellInfo(aCellInfo);
+      }
+      if ( aNbSeg3 ) {
+        PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
+                                                SMDS_MED_ENTITY,
+                                                eSEG3,
+                                                aSeg3Conn,
+                                                SMDS_MED_CONNECTIVITY,
+                                                aSeg3FamilyNums,
+                                                aSeg3ElemNums);
+        myMed->SetCellInfo(aCellInfo);
+      }
     }
 
     // Storing SMDS Faces
@@ -442,6 +493,14 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
       MED::TIntVector aTriaConn;
       aTriaConn.reserve(aNbElems*aNbTriaConn);
 
+      TInt aNbTria6Conn = MED::GetNbNodes(eTRIA6);
+      MED::TIntVector anTria6ElemNums; 
+      anTria6ElemNums.reserve(aNbElems);
+      MED::TIntVector aTria6FamilyNums;
+      aTria6FamilyNums.reserve(aNbElems);
+      MED::TIntVector aTria6Conn;
+      aTria6Conn.reserve(aNbElems*aNbTria6Conn);
+
       TInt aNbQuadConn = MED::GetNbNodes(eQUAD4);
       MED::TIntVector aQuadElemNums;
       aQuadElemNums.reserve(aNbElems);
@@ -450,6 +509,14 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
       MED::TIntVector aQuadConn;
       aQuadConn.reserve(aNbElems*aNbQuadConn);
 
+      TInt aNbQuad8Conn = MED::GetNbNodes(eQUAD8);
+      MED::TIntVector aQuad8ElemNums;
+      aQuad8ElemNums.reserve(aNbElems);
+      MED::TIntVector aQuad8FamilyNums;
+      aQuad8FamilyNums.reserve(aNbElems);
+      MED::TIntVector aQuad8Conn;
+      aQuad8Conn.reserve(aNbElems*aNbQuad8Conn);
+
       MED::TIntVector aPolygoneElemNums;
       aPolygoneElemNums.reserve(aNbElems);
       MED::TIntVector aPolygoneInds;
@@ -473,7 +540,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
           anElemNums = &aPolygoneElemNums;
           aFamilyNums = &aPolygoneFamilyNums;
           aConnectivity = &aPolygoneConn;
-        } else {
+        }
+        else {
           switch(aNbNodes){
           case 3:
             aNbConnectivity = aNbTriaConn;
@@ -487,6 +555,18 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
             aFamilyNums = &aQuadFamilyNums;
             aConnectivity = &aQuadConn;
             break;
+          case 6:
+            aNbConnectivity = aNbTria6Conn;
+            anElemNums = &anTria6ElemNums;
+            aFamilyNums = &aTria6FamilyNums;
+            aConnectivity = &aTria6Conn;
+            break;
+          case 8:
+            aNbConnectivity = aNbQuad8Conn;
+            anElemNums = &aQuad8ElemNums;
+            aFamilyNums = &aQuad8FamilyNums;
+            aConnectivity = &aQuad8Conn;
+            break;
           default:
             break;
           }
@@ -550,6 +630,28 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
        MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eQUAD4<<"; aNbElems = "<<aNbElems);
        myMed->SetCellInfo(aCellInfo);
       }
+      if(TInt aNbElems = anTria6ElemNums.size()){
+       PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
+                                               SMDS_MED_ENTITY,
+                                               eTRIA6,
+                                               aTria6Conn,
+                                               SMDS_MED_CONNECTIVITY,
+                                               aTria6FamilyNums,
+                                               anTria6ElemNums);
+       MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eTRIA6<<"; aNbElems = "<<aNbElems);
+       myMed->SetCellInfo(aCellInfo);
+      }
+      if(TInt aNbElems = aQuad8ElemNums.size()){
+       PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
+                                               SMDS_MED_ENTITY,
+                                               eQUAD8,
+                                               aQuad8Conn,
+                                               SMDS_MED_CONNECTIVITY,
+                                               aQuad8FamilyNums,
+                                               aQuad8ElemNums);
+       MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eQUAD8<<"; aNbElems = "<<aNbElems);
+       myMed->SetCellInfo(aCellInfo);
+      }
       if(TInt aNbElems = aPolygoneElemNums.size()){
         // add one element in connectivities,
         // referenced by the last element in indices
@@ -606,6 +708,38 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
       MED::TIntVector aHexaConn;
       aHexaConn.reserve(aNbElems*aNbHexaConn);
 
+      TInt aNbTetra10Conn = MED::GetNbNodes(eTETRA10);
+      MED::TIntVector anTetra10ElemNums; 
+      anTetra10ElemNums.reserve(aNbElems);
+      MED::TIntVector aTetra10FamilyNums;
+      aTetra10FamilyNums.reserve(aNbElems);
+      MED::TIntVector aTetra10Conn;
+      aTetra10Conn.reserve(aNbElems*aNbTetra10Conn);
+
+      TInt aNbPyra13Conn = MED::GetNbNodes(ePYRA13);
+      MED::TIntVector anPyra13ElemNums; 
+      anPyra13ElemNums.reserve(aNbElems);
+      MED::TIntVector aPyra13FamilyNums;
+      aPyra13FamilyNums.reserve(aNbElems);
+      MED::TIntVector aPyra13Conn;
+      aPyra13Conn.reserve(aNbElems*aNbPyra13Conn);
+
+      TInt aNbPenta15Conn = MED::GetNbNodes(ePENTA15);
+      MED::TIntVector anPenta15ElemNums; 
+      anPenta15ElemNums.reserve(aNbElems);
+      MED::TIntVector aPenta15FamilyNums;
+      aPenta15FamilyNums.reserve(aNbElems);
+      MED::TIntVector aPenta15Conn;
+      aPenta15Conn.reserve(aNbElems*aNbPenta15Conn);
+
+      TInt aNbHexa20Conn = MED::GetNbNodes(eHEXA20);
+      MED::TIntVector aHexa20ElemNums;
+      aHexa20ElemNums.reserve(aNbElems);
+      MED::TIntVector aHexa20FamilyNums;
+      aHexa20FamilyNums.reserve(aNbElems);
+      MED::TIntVector aHexa20Conn;
+      aHexa20Conn.reserve(aNbElems*aNbHexa20Conn);
+
       MED::TIntVector aPolyedreElemNums;
       aPolyedreElemNums.reserve(aNbElems);
       MED::TIntVector aPolyedreInds;
@@ -653,7 +787,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
           TInt aPrevPos = aPolyedreInds.back();
           aPolyedreInds.push_back(aPrevPos + aNbFaces);
 
-        } else {
+        }
+        else {
           TInt aNbNodes = anElem->NbNodes();
           SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
           TInt aNbConnectivity;
@@ -682,6 +817,29 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
             anElemNums = &aHexaElemNums;
             aFamilyNums = &aHexaFamilyNums;
             aConnectivity = &aHexaConn;
+          case 10:
+            aNbConnectivity = aNbTetra10Conn;
+            anElemNums = &anTetra10ElemNums;
+            aFamilyNums = &aTetra10FamilyNums;
+            aConnectivity = &aTetra10Conn;
+            break;
+          case 13:
+            aNbConnectivity = aNbPyra13Conn;
+            anElemNums = &anPyra13ElemNums;
+            aFamilyNums = &aPyra13FamilyNums;
+            aConnectivity = &aPyra13Conn;
+            break;
+          case 15:
+            aNbConnectivity = aNbPenta15Conn;
+            anElemNums = &anPenta15ElemNums;
+            aFamilyNums = &aPenta15FamilyNums;
+            aConnectivity = &aPenta15Conn;
+            break;
+          case 20:
+            aNbConnectivity = aNbHexa20Conn;
+            anElemNums = &aHexa20ElemNums;
+            aFamilyNums = &aHexa20FamilyNums;
+            aConnectivity = &aHexa20Conn;
           }
 
           TInt aSize = aConnectivity->size();
@@ -762,6 +920,51 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
        MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eHEXA8<<"; aNbElems = "<<aNbElems);
        myMed->SetCellInfo(aCellInfo);
       }
+      if(TInt aNbElems = anTetra10ElemNums.size()){
+       PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
+                                               SMDS_MED_ENTITY,
+                                               eTETRA10,
+                                               aTetra10Conn,
+                                               SMDS_MED_CONNECTIVITY,
+                                               aTetra10FamilyNums,
+                                               anTetra10ElemNums);
+       MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eTETRA10<<"; aNbElems = "<<aNbElems);
+       myMed->SetCellInfo(aCellInfo);
+      }
+      if(TInt aNbElems = anPyra13ElemNums.size()){
+       PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
+                                               SMDS_MED_ENTITY,
+                                               ePYRA13,
+                                               aPyra13Conn,
+                                               SMDS_MED_CONNECTIVITY,
+                                               aPyra13FamilyNums,
+                                               anPyra13ElemNums);
+       MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePYRA13<<"; aNbElems = "<<aNbElems);
+       myMed->SetCellInfo(aCellInfo);
+      }
+      if(TInt aNbElems = anPenta15ElemNums.size()){
+       PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
+                                               SMDS_MED_ENTITY,
+                                               ePENTA15,
+                                               aPenta15Conn,
+                                               SMDS_MED_CONNECTIVITY,
+                                               aPenta15FamilyNums,
+                                               anPenta15ElemNums);
+       MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePENTA15<<"; aNbElems = "<<aNbElems);
+       myMed->SetCellInfo(aCellInfo);
+      }
+      if(TInt aNbElems = aHexa20ElemNums.size()){
+       PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
+                                               SMDS_MED_ENTITY,
+                                               eHEXA20,
+                                               aHexa20Conn,
+                                               SMDS_MED_CONNECTIVITY,
+                                               aHexa20FamilyNums,
+                                               aHexa20ElemNums);
+       MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eHEXA20<<"; aNbElems = "<<aNbElems);
+       myMed->SetCellInfo(aCellInfo);
+      }
+
       if(TInt aNbElems = aPolyedreElemNums.size()){
         // add one element in connectivities,
         // referenced by the last element in faces
@@ -780,9 +983,11 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
        myMed->SetPolyedreInfo(aCellInfo);
       }
     }
-  }catch(const std::exception& exc){
+  }
+  catch(const std::exception& exc) {
     INFOS("Follow exception was cought:\n\t"<<exc.what());
-  }catch(...){
+  }
+  catch(...) {
     INFOS("Unknown exception was cought !!!");
   }
 
index 04ce4058a724f18879cecfc256a2859fab3c57ec..ed7c48ebc4d4bdb191bf56151f243db8ff26bde5 100644 (file)
@@ -228,7 +228,7 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeBinary() const
   }
 
   // write number of triangles
-  unsigned int NBT = nbTri;
+  //unsigned int NBT = nbTri;
   aFile.Write((Standard_Address)sval,LABEL_SIZE);
   writeInteger(nbTri,aFile);  
 
index 12c091632e06d569d32d85bbf77864339de311d2..97ffd7d29c7d9c6404c436e6c6232d8c1e631aa3 100644 (file)
@@ -64,11 +64,22 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
        SMDS_MeshElement* anElement = NULL;
        const TElementLab& aLabel = anIter->first;
        const TRecord& aRec = anIter->second;
-       if(IsBeam(aRec.fe_descriptor_id)){
-         anElement = myMesh->AddEdgeWithID(aRec.node_labels[0],
-                                           aRec.node_labels[1],
-                                           aLabel);
-       }else if(IsFace(aRec.fe_descriptor_id)){
+       if(IsBeam(aRec.fe_descriptor_id)) {
+          if(aRec.fe_descriptor_id == 11) {
+            // edge with two nodes
+            anElement = myMesh->AddEdgeWithID(aRec.node_labels[0],
+                                              aRec.node_labels[1],
+                                              aLabel);
+          }
+          else {
+            // quadratic edge (with 3 nodes)
+            anElement = myMesh->AddEdgeWithID(aRec.node_labels[0],
+                                              aRec.node_labels[1],
+                                              aRec.node_labels[2],
+                                              aLabel);
+          }
+       }
+        else if(IsFace(aRec.fe_descriptor_id)) {
          switch(aRec.fe_descriptor_id){
          case 71: // TRI3
          case 72:
@@ -76,18 +87,31 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
            
          case 41: // Plane Stress Linear Triangle - TRI3
          case 91: // Thin Shell Linear Triangle - TRI3
+           anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
+                                             aRec.node_labels[1],
+                                             aRec.node_labels[2],
+                                             aLabel);
+           break;
            
          case 42: // Plane Stress Quadratic Triangle - TRI6
          case 92: // Thin Shell Quadratic Triangle - TRI6
-           
            anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
                                              aRec.node_labels[1],
                                              aRec.node_labels[2],
+                                             aRec.node_labels[3],
+                                             aRec.node_labels[4],
+                                             aRec.node_labels[5],
                                              aLabel);
            break;
            
          case 44: // Plane Stress Linear Quadrilateral - QUAD4
          case 94: // Thin Shell   Linear Quadrilateral -  QUAD4
+           anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
+                                             aRec.node_labels[1],
+                                             aRec.node_labels[2],
+                                             aRec.node_labels[3],
+                                             aLabel);
+           break;
            
          case 45: // Plane Stress Quadratic Quadrilateral - QUAD8
          case 95: // Thin Shell   Quadratic Quadrilateral - QUAD8
@@ -95,24 +119,40 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
                                              aRec.node_labels[1],
                                              aRec.node_labels[2],
                                              aRec.node_labels[3],
+                                             aRec.node_labels[4],
+                                             aRec.node_labels[5],
+                                             aRec.node_labels[6],
+                                             aRec.node_labels[7],
                                              aLabel);
            break;
          }
-       }else if(IsVolume(aRec.fe_descriptor_id)){
+       }
+        else if(IsVolume(aRec.fe_descriptor_id)){
          switch(aRec.fe_descriptor_id){
            
          case 111: // Solid Linear Tetrahedron - TET4
+           anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
+                                               aRec.node_labels[2],
+                                               aRec.node_labels[1],
+                                               aRec.node_labels[3],
+                                               aLabel);
+           break;
+
          case 118: // Solid Quadratic Tetrahedron - TET10
-           
            anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
                                                aRec.node_labels[2],
                                                aRec.node_labels[1],
                                                aRec.node_labels[3],
+                                               aRec.node_labels[6],
+                                               aRec.node_labels[5],
+                                               aRec.node_labels[4],
+                                               aRec.node_labels[7],
+                                               aRec.node_labels[9],
+                                               aRec.node_labels[8],
                                                aLabel);
            break;
            
          case 112: // Solid Linear Prism - PRISM6
-           
            anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
                                                aRec.node_labels[2],
                                                aRec.node_labels[1],
@@ -123,13 +163,21 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
            break;
            
          case 113: // Solid Quadratic Prism - PRISM15
-           
            anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
-                                               aRec.node_labels[4],
                                                aRec.node_labels[2],
+                                               aRec.node_labels[1],
+                                               aRec.node_labels[3],
+                                               aRec.node_labels[5],
+                                               aRec.node_labels[4],
+                                               aRec.node_labels[8],
+                                               aRec.node_labels[7],
+                                               aRec.node_labels[6],
+                                               aRec.node_labels[11],
+                                               aRec.node_labels[10],
                                                aRec.node_labels[9],
+                                               aRec.node_labels[12],
+                                               aRec.node_labels[14],
                                                aRec.node_labels[13],
-                                               aRec.node_labels[11],
                                                aLabel);
            break;
            
@@ -146,26 +194,57 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
            break;
 
          case 116: // Solid Quadratic Brick - HEX20
-           
            anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
-                                               aRec.node_labels[6],
-                                               aRec.node_labels[4],
+                                               aRec.node_labels[3],
                                                aRec.node_labels[2],
+                                               aRec.node_labels[1],
+                                               aRec.node_labels[4],
+                                               aRec.node_labels[7],
+                                               aRec.node_labels[6],
+                                               aRec.node_labels[5],
+                                               aRec.node_labels[11],
+                                               aRec.node_labels[10],
+                                               aRec.node_labels[9],
+                                               aRec.node_labels[8],
+                                               aRec.node_labels[15],
+                                               aRec.node_labels[14],
+                                               aRec.node_labels[13],
                                                aRec.node_labels[12],
-                                               aRec.node_labels[18],
                                                aRec.node_labels[16],
-                                               aRec.node_labels[14],
+                                               aRec.node_labels[19],
+                                               aRec.node_labels[18],
+                                               aRec.node_labels[17],
+                                               aLabel);
+           break;
+
+         case 114: // pyramid of 13 nodes (quadratic) - PIRA13
+           anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
+                                               aRec.node_labels[3],
+                                               aRec.node_labels[2],
+                                               aRec.node_labels[1],
+                                               aRec.node_labels[4],
+                                               aRec.node_labels[8],
+                                               aRec.node_labels[7],
+                                               aRec.node_labels[6],
+                                               aRec.node_labels[5],
+                                               aRec.node_labels[9],
+                                               aRec.node_labels[12],
+                                               aRec.node_labels[11],
+                                               aRec.node_labels[10],
                                                aLabel);
            break;
+
          }
        }
        if(!anElement)
          MESSAGE("DriverUNV_R_SMDS_Mesh::Perform - can not add element with ID = "<<aLabel<<" and type = "<<aRec.fe_descriptor_id);
       }
     }
-  }catch(const std::exception& exc){
+  }
+  catch(const std::exception& exc){
     INFOS("Follow exception was cought:\n\t"<<exc.what());
-  }catch(...){
+  }
+  catch(...){
     INFOS("Unknown exception was cought !!!");
   }
   return aResult;
index 3fe3b18ef78fb22e3bb88dbdd4a9048a3e8b9b9d..a716945d9ecfc0776ec1509226d277689519dc58 100644 (file)
@@ -91,7 +91,10 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
            const SMDS_MeshElement* aNode = aNodesIter->next();
            aRec.node_labels.push_back(aNode->GetID());
          }
-         aRec.fe_descriptor_id = 11;
+          if(aNbNodes==2)
+            aRec.fe_descriptor_id = 11;
+          else
+            aRec.fe_descriptor_id = 21;
          aDataSet2412.insert(TDataSet::value_type(aLabel,aRec));
        }
        MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
@@ -118,6 +121,12 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
          case 4:
            aRec.fe_descriptor_id = 44;
            break;
+         case 6:
+           aRec.fe_descriptor_id = 42;
+           break;
+         case 8:
+           aRec.fe_descriptor_id = 45;
+           break;
          default:
            continue;
          }
@@ -160,6 +169,30 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
            anId = 115;
            break;
          }
+         case 10: {
+           static int anIds[] = {0,2,1,3,6,5,4,7,9,8};
+           aConn = anIds;
+           anId = 118;
+           break;
+         }
+         case 13: {
+           static int anIds[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
+           aConn = anIds;
+           anId = 114;
+           break;
+         }
+         case 15: {
+           static int anIds[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13};
+           aConn = anIds;
+           anId = 113;
+           break;
+         }
+         case 20: {
+           static int anIds[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
+           aConn = anIds;
+           anId = 116;
+           break;
+         }
          default:
            continue;
          }
@@ -177,9 +210,11 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
       }
       UNV2412::Write(out_stream,aDataSet2412);
     }
-  }catch(const std::exception& exc){
+  }
+  catch(const std::exception& exc){
     INFOS("Follow exception was cought:\n\t"<<exc.what());
-  }catch(...){
+  }
+  catch(...){
     INFOS("Unknown exception was cought !!!");
   }
   return aResult;
index 0160d7b68ab3f112fc03d403f54a47a45915d112..2be3319f3e4e8013a4472204654f9b07a33fdf7c 100644 (file)
@@ -142,8 +142,8 @@ void UNV2412::Write(std::ofstream& out_stream, const TDataSet& theDataSet)
 
 bool UNV2412::IsBeam(int theFeDescriptorId){
   switch (theFeDescriptorId){
-  case 11:
-  case 21:
+  case 11: // edge with 2 nodes
+  case 21: // edge with 3 nodes (quadratic)
   case 22:
   case 24:
   case 25:
@@ -197,6 +197,8 @@ bool UNV2412::IsVolume(int theFeDescriptorId){
   case 116: // Solid Quadratic Brick - HEX20
 
   case 117: // Solid Cubic Brick
+
+  case 114: // pyramid of 13 nodes (quadratic)
     return true;
   }
   return false;
index a7250e80042b9edc530d1274a68c51a71036496c..7f2ee90d6cc6afe23ecb8bf4f6ce36f40c742d8a 100644 (file)
@@ -150,6 +150,8 @@ SMESH_ActorDef::SMESH_ActorDef()
   aFilter->RegisterCellsWithType(VTK_TRIANGLE);
   aFilter->RegisterCellsWithType(VTK_POLYGON);
   aFilter->RegisterCellsWithType(VTK_QUAD);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
 
   my3DActor = SMESH_DeviceActor::New();
   my3DActor->SetUserMatrix(aMatrix);
@@ -164,6 +166,8 @@ SMESH_ActorDef::SMESH_ActorDef()
   aFilter->RegisterCellsWithType(VTK_HEXAHEDRON);
   aFilter->RegisterCellsWithType(VTK_WEDGE);
   aFilter->RegisterCellsWithType(VTK_PYRAMID);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
   aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
 
   //Definition 1D divice of the actor
@@ -185,6 +189,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   aFilter = my1DActor->GetExtractUnstructuredGrid();
   aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
   aFilter->RegisterCellsWithType(VTK_LINE);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE);
 
   my1DProp = vtkProperty::New();
   my1DProp->DeepCopy(myEdgeProp);
@@ -210,6 +215,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   aFilter = my1DExtActor->GetExtractUnstructuredGrid();
   aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
   aFilter->RegisterCellsWithType(VTK_LINE);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE);
 
 
   //Definition 0D divice of the actor
@@ -1017,6 +1023,7 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode){
   if(myEntityMode & eEdges){
     if (MYDEBUG) MESSAGE("EDGES");
     aFilter->RegisterCellsWithType(VTK_LINE);
+    aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE);
   }
 
   if(myEntityMode & eFaces){
@@ -1024,6 +1031,8 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode){
     aFilter->RegisterCellsWithType(VTK_TRIANGLE);
     aFilter->RegisterCellsWithType(VTK_POLYGON);
     aFilter->RegisterCellsWithType(VTK_QUAD);
+    aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
+    aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
   }
 
   if(myEntityMode & eVolumes){
@@ -1033,6 +1042,8 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode){
     aFilter->RegisterCellsWithType(VTK_HEXAHEDRON);
     aFilter->RegisterCellsWithType(VTK_WEDGE);
     aFilter->RegisterCellsWithType(VTK_PYRAMID);
+    aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA);
+    aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
     aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
   }
   aFilter->Update();
index 4727832dd4346471178863825ee5bfeaeb9b9b79..7355e4b2bf106f8fd42633dbb0d3e6bdc33d8691 100644 (file)
@@ -90,12 +90,16 @@ static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
   switch( theType )
   {
     case SMDSAbs_Edge: 
-      return theNbNodes == 2 ? VTK_LINE : VTK_EMPTY_CELL;
+      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 return VTK_EMPTY_CELL;
       
     case SMDSAbs_Volume:
@@ -104,6 +108,15 @@ static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
       else if ( theNbNodes == 5 )   return VTK_PYRAMID;
       else if ( theNbNodes == 6 )   return VTK_WEDGE;
       else if ( theNbNodes == 8 )   return VTK_HEXAHEDRON;
+      else if ( theNbNodes == 10 )  {
+        return VTK_QUADRATIC_TETRA;
+      }
+      else if ( theNbNodes == 20 )  {
+        return VTK_QUADRATIC_HEXAHEDRON;
+      }
+      else if ( theNbNodes==13 || theNbNodes==15 )  {
+        return VTK_CONVEX_POINT_SET;
+      }
       else return VTK_EMPTY_CELL;
 
     default: return VTK_EMPTY_CELL;
@@ -391,11 +404,34 @@ void SMESH_VisualObjDef::buildElemPrs()
            static int anIds[] = {0,1,2,3,4,5};
            for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
 
-         } else if (aNbNodes == 8) {
+         }
+          else if (aNbNodes == 8) {
            static int anIds[] = {0,3,2,1,4,7,6,5};
            for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
 
-         } else {
+         }
+          else if (aNbNodes == 10) {
+           static int anIds[] = {0,2,1,3,6,5,4,7,9,8};
+           for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
+         }
+          else if (aNbNodes == 13) {
+           static int anIds[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
+           for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
+         }
+          else if (aNbNodes == 15) {
+           static int anIds[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13};
+           for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
+           //for (int k = 0; k < aNbNodes; k++) {
+            //  int nn = aConnectivities[k];
+            //  const SMDS_MeshNode* N = static_cast<const SMDS_MeshNode*> (aConnect[nn]);
+            //  cout<<"k="<<k<<"  N("<<N->X()<<","<<N->Y()<<","<<N->Z()<<")"<<endl;
+            //}
+         }
+          else if (aNbNodes == 20) {
+           static int anIds[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
+           for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
+         }
+          else {
           }
 
          if (aConnectivities.size() > 0) {
index e066e25e0bbb35d9cb600a6540e5f579f5f2d944..7ecaf313a8b0bc98241fb65fd2e34c340504c2f8 100644 (file)
@@ -59,21 +59,10 @@ LIB_SRC = \
        SMDS_FaceOfEdges.cxx \
        SMDS_FaceOfNodes.cxx \
        SMDS_PolygonalFaceOfNodes.cxx \
-       SMDS_VolumeTool.cxx
-#      SMDS_Tria3OfNodes.cxx \
-#      SMDS_HexahedronOfNodes.cxx
-
-#SMDSControl_BoundaryEdges.cxx \
-#SMDSControl_BoundaryFaces.cxx \
-#SMDSControl.cxx \
-#SMDSControl_MeshBoundary.cxx \
-#SMDSEdit_Transform.cxx \
-#SMDS_MeshNodeIDFactory.cxx \
-#SMDS_MeshPrism.cxx \
-#SMDS_MeshPyramid.cxx \
-#SMDS_MeshQuadrangle.cxx \
-#SMDS_MeshTetrahedron.cxx \
-#SMDS_MeshTriangle.cxx \
+       SMDS_VolumeTool.cxx \
+       SMDS_QuadraticEdge.cxx \
+       SMDS_QuadraticFaceOfNodes.cxx \
+       SMDS_QuadraticVolumeOfNodes.cxx
 
 
 LIB_CLIENT_IDL = 
@@ -113,21 +102,11 @@ EXPORT_HEADERS= \
        SMDS_FaceOfEdges.hxx \
        SMDS_FaceOfNodes.hxx \
        SMDS_PolygonalFaceOfNodes.hxx \
-       SMDS_VolumeTool.hxx
-#      SMDS_Tria3OfNodes.hxx \
-#      SMDS_HexahedronOfNodes.hxx
-
-#SMDSControl_BoundaryEdges.hxx \
-#SMDSControl_BoundaryFaces.hxx \
-#SMDSControl.hxx \
-#SMDSControl_MeshBoundary.hxx \
-#SMDSEdit_Transform.hxx \
-#SMDS_MeshPrism.hxx \
-#SMDS_MeshPyramid.hxx \
-#SMDS_MeshQuadrangle.hxx \
-#SMDS_MeshTetrahedron.hxx \
-#SMDS_MeshTriangle.hxx \
-#SMDS_MeshNodeIDFactory.hxx
+       SMDS_VolumeTool.hxx \
+       SMDS_QuadraticEdge.hxx \
+       SMDS_QuadraticFaceOfNodes.hxx \
+       SMDS_QuadraticVolumeOfNodes.hxx \
+       SMDS_SetIterator.hxx
 
 # additionnal information to compil and link file
 CPPFLAGS += -I${KERNEL_ROOT_DIR}/include/salome $(OCC_INCLUDES) $(BOOST_CPPFLAGS)
index c8432afddf0e0865c92f6132415fa577836628cb..6ff0986448f727bd97c074a496d0c3130af908bb 100755 (executable)
 #include <boost/shared_ptr.hpp>
 
 class SMDS_MeshElement;
+class SMDS_MeshNode;
+class SMDS_MeshEdge;
+class SMDS_MeshFace;
+class SMDS_MeshVolume;
 
 typedef SMDS_Iterator<const SMDS_MeshElement *> SMDS_ElemIterator;
 typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshElement *> > SMDS_ElemIteratorPtr;
 
+typedef SMDS_Iterator<const SMDS_MeshNode *> SMDS_NodeIterator;
+typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshNode *> > SMDS_NodeIteratorPtr;
+
+typedef SMDS_Iterator<const SMDS_MeshEdge *> SMDS_EdgeIterator;
+typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshEdge *> > SMDS_EdgeIteratorPtr;
+
+typedef SMDS_Iterator<const SMDS_MeshFace *> SMDS_FaceIterator;
+typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshFace *> > SMDS_FaceIteratorPtr;
+
+typedef SMDS_Iterator<const SMDS_MeshVolume *> SMDS_VolumeIterator;
+typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshVolume *> > SMDS_VolumeIteratorPtr;
+
 #endif
index 640c55d30194f44cd2835f4164abfaed5bc93a3b..7a014afb8bc6f10522930b8ee5696bdcccab1325 100644 (file)
@@ -155,3 +155,29 @@ SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
 
 }*/
 
+
+int SMDS_FaceOfEdges::NbNodes() const
+{
+  return myEdges[0]->NbNodes() + myEdges[1]->NbNodes() + myEdges[2]->NbNodes() +
+    ( myNbEdges == 4 ? myEdges[3]->NbNodes() : 0 ) - myNbEdges;
+}
+
+/*!
+ * \brief Return node by its index
+ * \param ind - node index
+ * \retval const SMDS_MeshNode* - the node
+ * 
+ * Index is wrapped if it is out of a valid range
+ */
+const SMDS_MeshNode* SMDS_FaceOfEdges::GetNode(const int ind) const
+{
+  int index = WrappedIndex( ind );
+  for ( int i = 0; i < myNbEdges; ++i ) {
+    if ( index >= myEdges[ i ]->NbNodes() )
+      index -= myEdges[ i ]->NbNodes();
+    else
+      return myEdges[ i ]->GetNode( index );
+  }
+  return 0;
+}
+
index cd8e5dd8f29ee2ca94343860f1ec1b3e86a9191a..54a9a688f95c919b7929064a7a58a74ba495e192 100644 (file)
@@ -42,10 +42,21 @@ class SMDS_FaceOfEdges:public SMDS_MeshFace
                          const SMDS_MeshEdge* edge4);
                
        SMDSAbs_ElementType GetType() const;
+       int NbNodes() const;
        int NbEdges() const;
        int NbFaces() const;
 //     friend bool operator<(const SMDS_FaceOfEdges& e1, const SMDS_FaceOfEdges& e2);
 
+
+  /*!
+   * \brief Return node by its index
+    * \param ind - node index
+    * \retval const SMDS_MeshNode* - the node
+   * 
+   * Index is wrapped if it is out of a valid range
+   */
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+
   protected:
        SMDS_ElemIteratorPtr
                elementsIterator(SMDSAbs_ElementType type) const;
index aa687082475c0633983a49b859093ecbd6b5bdca..018bd88a0d927efaef2a4d57ae01567d5cb133b6 100644 (file)
@@ -23,6 +23,7 @@
 #pragma warning(disable:4786)
 #endif
 
+#include "SMDS_SetIterator.hxx"
 #include "SMDS_FaceOfNodes.hxx"
 #include "SMDS_IteratorOfElements.hxx"
 #include "SMDS_MeshNode.hxx"
@@ -68,25 +69,11 @@ void SMDS_FaceOfNodes::Print(ostream & OS) const
 //purpose  : 
 //=======================================================================
 
-class SMDS_FaceOfNodes_MyIterator:public SMDS_ElemIterator
+class SMDS_FaceOfNodes_MyIterator:public SMDS_NodeArrayElemIterator
 {
-  const SMDS_MeshNode* const *mySet;
-  int myLength;
-  int index;
  public:
   SMDS_FaceOfNodes_MyIterator(const SMDS_MeshNode* const *s, int l):
-    mySet(s),myLength(l),index(0) {}
-
-  bool more()
-  {
-    return index<myLength;
-  }
-
-  const SMDS_MeshElement* next()
-  {
-    index++;
-    return mySet[index-1];
-  }
+    SMDS_NodeArrayElemIterator( s, & s[ l ] ) {}
 };
 
 SMDS_ElemIteratorPtr SMDS_FaceOfNodes::elementsIterator
@@ -147,6 +134,18 @@ bool SMDS_FaceOfNodes::ChangeNodes(const SMDS_MeshNode* nodes[],
   return true;
 }
 
+/*!
+ * \brief Return node by its index
+ * \param ind - node index
+ * \retval const SMDS_MeshNode* - the node
+ * 
+ * Index is wrapped if it is out of a valid range
+ */
+const SMDS_MeshNode* SMDS_FaceOfNodes::GetNode(const int ind) const
+{
+  return myNodes[ WrappedIndex( ind )];
+}
+
 /*bool operator<(const SMDS_FaceOfNodes& f1, const SMDS_FaceOfNodes& f2)
 {
        set<SMDS_MeshNode> set1,set2;
index 290195107d4844fbd2be02cfd5770209232a703c..8cbdf6f33ccdc95e64d69a3bf5d1ab73dcc0c735 100644 (file)
@@ -44,6 +44,16 @@ class SMDS_FaceOfNodes:public SMDS_MeshFace
        int NbEdges() const;
        int NbFaces() const;
        int NbNodes() const;
+
+  /*!
+   * \brief Return node by its index
+    * \param ind - node index
+    * \retval const SMDS_MeshNode* - the node
+   * 
+   * Index is wrapped if it is out of a valid range
+   */
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+
   protected:
        SMDS_ElemIteratorPtr
                elementsIterator(SMDSAbs_ElementType type) const;
index 58f3e52c2ba7e1b870fb02f31ca07b9e2716e6d4..5df2090e9abbf6bb74a520d9de7e39c21d042e58 100644 (file)
@@ -31,6 +31,9 @@
 #include "SMDS_FaceOfEdges.hxx"
 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
 #include "SMDS_PolygonalFaceOfNodes.hxx"
+#include "SMDS_QuadraticEdge.hxx"
+#include "SMDS_QuadraticFaceOfNodes.hxx"
+#include "SMDS_QuadraticVolumeOfNodes.hxx"
 
 #include <algorithm>
 #include <map>
@@ -1084,19 +1087,32 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
       if ( edge )
         Ok = const_cast<SMDS_MeshEdge*>( edge )->ChangeNodes( nodes[0], nodes[1] );
     }
+    else if ( nbnodes == 3 ) {
+      const SMDS_QuadraticEdge* edge = dynamic_cast<const SMDS_QuadraticEdge*>( elem );
+      if ( edge )
+        Ok = const_cast<SMDS_QuadraticEdge*>( edge )->ChangeNodes( nodes[0], nodes[1], nodes[2] );
+    }
     break;
   }
   case SMDSAbs_Face: {
     const SMDS_FaceOfNodes* face = dynamic_cast<const SMDS_FaceOfNodes*>( elem );
     if ( face ) {
       Ok = const_cast<SMDS_FaceOfNodes*>( face )->ChangeNodes( nodes, nbnodes );
-    } else {
-      /// ??? begin
-      const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
-      if (face) {
-        Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
+    }
+    else {
+      const SMDS_QuadraticFaceOfNodes* QF =
+        dynamic_cast<const SMDS_QuadraticFaceOfNodes*>( elem );
+      if ( QF ) {
+        Ok = const_cast<SMDS_QuadraticFaceOfNodes*>( QF )->ChangeNodes( nodes, nbnodes );
+      }
+      else {
+        /// ??? begin
+        const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
+        if (face) {
+          Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
+        }
+        /// ??? end
       }
-      /// ??? end
     }
     break;
   }
@@ -1109,8 +1125,15 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
   //}
   case SMDSAbs_Volume: {
     const SMDS_VolumeOfNodes* vol = dynamic_cast<const SMDS_VolumeOfNodes*>( elem );
-    if ( vol )
+    if ( vol ) {
       Ok = const_cast<SMDS_VolumeOfNodes*>( vol )->ChangeNodes( nodes, nbnodes );
+    }
+    else {
+      const SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<const SMDS_QuadraticVolumeOfNodes*>( elem );
+      if ( QV ) {
+        Ok = const_cast<SMDS_QuadraticVolumeOfNodes*>( QV )->ChangeNodes( nodes, nbnodes );
+      }
+    }
     break;
   }
   default:
@@ -1200,6 +1223,7 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
   return Ok;
 }
 
+
 //=======================================================================
 //function : FindEdge
 //purpose  :
@@ -1207,54 +1231,95 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
 
 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
 {
-       const SMDS_MeshNode * node1=FindNode(idnode1);
-       const SMDS_MeshNode * node2=FindNode(idnode2);
-       if((node1==NULL)||(node2==NULL)) return NULL;
-       return FindEdge(node1,node2);
+  const SMDS_MeshNode * node1=FindNode(idnode1);
+  const SMDS_MeshNode * node2=FindNode(idnode2);
+  if((node1==NULL)||(node2==NULL)) return NULL;
+  return FindEdge(node1,node2);
 }
 
 //#include "Profiler.h"
 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
                                          const SMDS_MeshNode * node2)
 {
-       const SMDS_MeshEdge * toReturn=NULL;
-       //PROFILER_Init();
-       //PROFILER_Set();
-       SMDS_ElemIteratorPtr it1=node1->edgesIterator();
-       //PROFILER_Get(0);
-       //PROFILER_Set();
-       while(it1->more())
-       {
-               const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *>
-                       (it1->next());
-               SMDS_ElemIteratorPtr it2=e->nodesIterator();
-               while(it2->more())
-               {
-                       if(it2->next()->GetID()==node2->GetID())
-                       {
-                               toReturn=e;
-                               break;
-                       }
-               }
-       }
-       //PROFILER_Get(1);
-       return toReturn;
+  const SMDS_MeshEdge * toReturn=NULL;
+  //PROFILER_Init();
+  //PROFILER_Set();
+  SMDS_ElemIteratorPtr it1=node1->edgesIterator();
+  //PROFILER_Get(0);
+  //PROFILER_Set();
+  while(it1->more()) {
+    const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *> (it1->next());
+    SMDS_ElemIteratorPtr it2=e->nodesIterator();
+    while(it2->more()) {
+      if(it2->next()->GetID()==node2->GetID()) {
+        toReturn = e;
+        break;
+      }
+    }
+  }
+  //PROFILER_Get(1);
+  return toReturn;
 }
 
 
+//=======================================================================
+//function : FindEdgeOrCreate
+//purpose  :
+//=======================================================================
+
 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
-       const SMDS_MeshNode * node2) 
+                                           const SMDS_MeshNode * node2) 
 {
-       SMDS_MeshEdge * toReturn=NULL;
-       toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
-       if(toReturn==NULL)      
-       {
-          toReturn=new SMDS_MeshEdge(node1,node2);
-          myEdges.Add(toReturn);
-       } 
-       return toReturn;
+  SMDS_MeshEdge * toReturn=NULL;
+  toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
+  if(toReturn==NULL) {
+    toReturn=new SMDS_MeshEdge(node1,node2);
+    myEdges.Add(toReturn);
+  } 
+  return toReturn;
 }
 
+
+//=======================================================================
+//function : FindEdge
+//purpose  :
+//=======================================================================
+
+const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
+                                         int idnode3) const
+{
+  const SMDS_MeshNode * node1=FindNode(idnode1);
+  const SMDS_MeshNode * node2=FindNode(idnode2);
+  const SMDS_MeshNode * node3=FindNode(idnode3);
+  if( (node1==NULL) || (node2==NULL)  || (node3==NULL) ) return NULL;
+  return FindEdge(node1,node2,node3);
+}
+
+const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
+                                         const SMDS_MeshNode * node2,
+                                         const SMDS_MeshNode * node3)
+{
+  const SMDS_MeshEdge * toReturn = NULL;
+  SMDS_ElemIteratorPtr it1 = node1->edgesIterator();
+  while(it1->more()) {
+    const SMDS_MeshEdge * e = static_cast<const SMDS_MeshEdge *> (it1->next());
+    SMDS_ElemIteratorPtr it2 = e->nodesIterator();
+    int tmp = 0;
+    while(it2->more()) {
+      int nID = it2->next()->GetID();
+      if( nID==node2->GetID() || nID==node3->GetID() ) {
+        tmp++;
+        if(tmp==2) {
+          toReturn = e;
+          break;
+        }
+      }
+    }
+  }
+  return toReturn;
+}
+
+
 //=======================================================================
 //function : FindFace
 //purpose  :
@@ -1263,118 +1328,219 @@ SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
        int idnode3) const
 {
-       const SMDS_MeshNode * node1=FindNode(idnode1);
-       const SMDS_MeshNode * node2=FindNode(idnode2);
-       const SMDS_MeshNode * node3=FindNode(idnode3);
-       if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
-       return FindFace(node1, node2, node3);
+  const SMDS_MeshNode * node1=FindNode(idnode1);
+  const SMDS_MeshNode * node2=FindNode(idnode2);
+  const SMDS_MeshNode * node3=FindNode(idnode3);
+  if( (node1==NULL) || (node2==NULL) || (node3==NULL) ) return NULL;
+  return FindFace(node1, node2, node3);
 }
 
-const SMDS_MeshFace* SMDS_Mesh::FindFace(
-               const SMDS_MeshNode *node1,
-               const SMDS_MeshNode *node2,
-               const SMDS_MeshNode *node3)
+const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
+                                         const SMDS_MeshNode *node2,
+                                         const SMDS_MeshNode *node3)
 {
-       const SMDS_MeshFace * face;
-       const SMDS_MeshElement * node;
-       bool node2found, node3found;
-
-       SMDS_ElemIteratorPtr it1=node1->facesIterator();
-       while(it1->more())
-       {
-               face=static_cast<const SMDS_MeshFace*>(it1->next());
-               if(face->NbNodes()!=3) continue;
-               SMDS_ElemIteratorPtr it2=face->nodesIterator();
-               node2found=false;
-               node3found=false;
-               while(it2->more())
-               {
-                       node=it2->next();
-                       if(node->GetID()==node2->GetID()) node2found=true;
-                       if(node->GetID()==node3->GetID()) node3found=true;
-               }
-               if(node2found&&node3found)
-                       return face;
-       }
-       return NULL;
+  const SMDS_MeshFace * face;
+  const SMDS_MeshElement * node;
+  bool node2found, node3found;
+
+  SMDS_ElemIteratorPtr it1 = node1->facesIterator();
+  while(it1->more()) {
+    face = static_cast<const SMDS_MeshFace*>(it1->next());
+    if(face->NbNodes()!=3) continue;
+    SMDS_ElemIteratorPtr it2 = face->nodesIterator();
+    node2found = false;
+    node3found = false;
+    while(it2->more()) {
+      node = it2->next();
+      if(node->GetID()==node2->GetID()) node2found = true;
+      if(node->GetID()==node3->GetID()) node3found = true;
+    }
+    if( node2found && node3found )
+      return face;
+  }
+  return NULL;
 }
 
-SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
-               const SMDS_MeshNode *node1,
-               const SMDS_MeshNode *node2,
-               const SMDS_MeshNode *node3)
+SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
+                                           const SMDS_MeshNode *node2,
+                                           const SMDS_MeshNode *node3)
 {
-       SMDS_MeshFace * toReturn=NULL;
-       toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
-       if(toReturn==NULL)
-       {
-         toReturn=createTriangle(node1,node2,node3);
-       }
-       return toReturn;
+  SMDS_MeshFace * toReturn=NULL;
+  toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
+  if(toReturn==NULL) {
+    toReturn = createTriangle(node1,node2,node3);
+  }
+  return toReturn;
 }
 
+
 //=======================================================================
 //function : FindFace
 //purpose  :
 //=======================================================================
 
-const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3,
-       int idnode4) const
+const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
+                                         int idnode3, int idnode4) const
 {
-       const SMDS_MeshNode * node1=FindNode(idnode1);
-       const SMDS_MeshNode * node2=FindNode(idnode2);
-       const SMDS_MeshNode * node3=FindNode(idnode3);
-       const SMDS_MeshNode * node4=FindNode(idnode4);
-       if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL;
-       return FindFace(node1, node2, node3, node4);
+  const SMDS_MeshNode * node1=FindNode(idnode1);
+  const SMDS_MeshNode * node2=FindNode(idnode2);
+  const SMDS_MeshNode * node3=FindNode(idnode3);
+  const SMDS_MeshNode * node4=FindNode(idnode4);
+  if( (node1==NULL) || (node2==NULL) || (node3==NULL) || (node4==NULL) )
+    return NULL;
+  return FindFace(node1, node2, node3, node4);
 }
 
-const SMDS_MeshFace* SMDS_Mesh::FindFace(
-               const SMDS_MeshNode *node1,
-               const SMDS_MeshNode *node2,
-               const SMDS_MeshNode *node3,
-               const SMDS_MeshNode *node4)
+const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
+                                         const SMDS_MeshNode *node2,
+                                         const SMDS_MeshNode *node3,
+                                         const SMDS_MeshNode *node4)
 {
-       const SMDS_MeshFace * face;
-       const SMDS_MeshElement * node;
-       bool node2found, node3found, node4found;
-       SMDS_ElemIteratorPtr it1=node1->facesIterator();
-       while(it1->more())
-       {
-               face=static_cast<const SMDS_MeshFace *>(it1->next());
-               if(face->NbNodes()!=4) continue;
-               SMDS_ElemIteratorPtr it2=face->nodesIterator();
-               node2found=false;
-               node3found=false;
-               node4found=false;
-               while(it2->more())
-               {
-                       node=it2->next();
-                       if(node->GetID()==node2->GetID()) node2found=true;
-                       if(node->GetID()==node3->GetID()) node3found=true;
-                       if(node->GetID()==node4->GetID()) node4found=true;
-               }
-               if(node2found&&node3found&&node4found)
-                       return face;
-       }
-       return NULL;
+  const SMDS_MeshFace * face;
+  const SMDS_MeshElement * node;
+  bool node2found, node3found, node4found;
+  SMDS_ElemIteratorPtr it1 = node1->facesIterator();
+  while(it1->more()) {
+    face = static_cast<const SMDS_MeshFace *>(it1->next());
+    if(face->NbNodes()!=4) continue;
+    SMDS_ElemIteratorPtr it2 = face->nodesIterator();
+    node2found = false;
+    node3found = false;
+    node4found = false;
+    while(it2->more()) {
+      node=it2->next();
+      if(node->GetID()==node2->GetID()) node2found = true;
+      if(node->GetID()==node3->GetID()) node3found = true;
+      if(node->GetID()==node4->GetID()) node4found = true;
+    }
+    if( node2found && node3found && node4found )
+      return face;
+  }
+  return NULL;
 }
 
-SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
-               const SMDS_MeshNode *node1,
-               const SMDS_MeshNode *node2,
-               const SMDS_MeshNode *node3,
-               const SMDS_MeshNode *node4)
+SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
+                                           const SMDS_MeshNode *node2,
+                                           const SMDS_MeshNode *node3,
+                                           const SMDS_MeshNode *node4)
 {
-       SMDS_MeshFace * toReturn=NULL;
-       toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
-       if(toReturn==NULL)
-       {
-         toReturn=createQuadrangle(node1,node2,node3,node4);
-       }
-       return toReturn;
+  SMDS_MeshFace * toReturn=NULL;
+  toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
+  if(toReturn==NULL) {
+    toReturn=createQuadrangle(node1,node2,node3,node4);
+  }
+  return toReturn;
+}
+
+
+//=======================================================================
+//function : FindFace
+//purpose  :quadratic triangle
+//=======================================================================
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
+                                         int idnode3, int idnode4,
+                                         int idnode5, int idnode6) const
+{
+  const SMDS_MeshNode * node1 = FindNode(idnode1);
+  const SMDS_MeshNode * node2 = FindNode(idnode2);
+  const SMDS_MeshNode * node3 = FindNode(idnode3);
+  const SMDS_MeshNode * node4 = FindNode(idnode4);
+  const SMDS_MeshNode * node5 = FindNode(idnode5);
+  const SMDS_MeshNode * node6 = FindNode(idnode6);
+  if( (node1==NULL) || (node2==NULL) || (node3==NULL) ||
+      (node4==NULL) || (node5==NULL) || (node6==NULL) ) return NULL;
+  return FindFace(node1, node2, node3, node4, node5, node6);
+}
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
+                                         const SMDS_MeshNode *node2,
+                                         const SMDS_MeshNode *node3,
+                                         const SMDS_MeshNode *node4,
+                                         const SMDS_MeshNode *node5,
+                                         const SMDS_MeshNode *node6)
+{
+  const SMDS_MeshFace * face;
+  const SMDS_MeshElement * node;
+  SMDS_ElemIteratorPtr it1 = node1->facesIterator();
+  while(it1->more()) {
+    face = static_cast<const SMDS_MeshFace*>(it1->next());
+    if(face->NbNodes()!=6) continue;
+    SMDS_ElemIteratorPtr it2 = face->nodesIterator();
+    int tmp = 0;
+    while(it2->more()) {
+      node = it2->next();
+      if(node->GetID()==node2->GetID()) tmp++;
+      if(node->GetID()==node3->GetID()) tmp++;
+      if(node->GetID()==node4->GetID()) tmp++;
+      if(node->GetID()==node5->GetID()) tmp++;
+      if(node->GetID()==node6->GetID()) tmp++;
+    }
+    if( tmp==5 )
+      return static_cast<const SMDS_MeshFace*>(face);
+  }
+  return NULL;
 }
 
+
+//=======================================================================
+//function : FindFace
+//purpose  : quadratic quadrangle
+//=======================================================================
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
+                                         int idnode3, int idnode4,
+                                         int idnode5, int idnode6,
+                                         int idnode7, int idnode8) const
+{
+  const SMDS_MeshNode * node1 = FindNode(idnode1);
+  const SMDS_MeshNode * node2 = FindNode(idnode2);
+  const SMDS_MeshNode * node3 = FindNode(idnode3);
+  const SMDS_MeshNode * node4 = FindNode(idnode4);
+  const SMDS_MeshNode * node5 = FindNode(idnode5);
+  const SMDS_MeshNode * node6 = FindNode(idnode6);
+  const SMDS_MeshNode * node7 = FindNode(idnode7);
+  const SMDS_MeshNode * node8 = FindNode(idnode8);
+  if( (node1==NULL) || (node2==NULL) || (node3==NULL) || (node4==NULL) ||
+      (node5==NULL) || (node6==NULL) || (node7==NULL) || (node8==NULL) )
+    return NULL;
+  return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
+}
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
+                                         const SMDS_MeshNode *node2,
+                                         const SMDS_MeshNode *node3,
+                                         const SMDS_MeshNode *node4,
+                                         const SMDS_MeshNode *node5,
+                                         const SMDS_MeshNode *node6,
+                                         const SMDS_MeshNode *node7,
+                                         const SMDS_MeshNode *node8)
+{
+  const SMDS_MeshFace * face;
+  const SMDS_MeshElement * node;
+  SMDS_ElemIteratorPtr it1 = node1->facesIterator();
+  while(it1->more()) {
+    face = static_cast<const SMDS_MeshFace *>(it1->next());
+    if(face->NbNodes()!=8) continue;
+    SMDS_ElemIteratorPtr it2 = face->nodesIterator();
+    int tmp = 0;
+    while(it2->more()) {
+      node = it2->next();
+      if(node->GetID()==node2->GetID()) tmp++;
+      if(node->GetID()==node3->GetID()) tmp++;
+      if(node->GetID()==node4->GetID()) tmp++;
+      if(node->GetID()==node5->GetID()) tmp++;
+      if(node->GetID()==node6->GetID()) tmp++;
+      if(node->GetID()==node7->GetID()) tmp++;
+      if(node->GetID()==node8->GetID()) tmp++;
+    }
+    if( tmp==7 )
+      return face;
+  }
+  return NULL;
+}
+
+
 //=======================================================================
 //function : FindElement
 //purpose  :
@@ -1382,7 +1548,7 @@ SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
 
 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
 {
-       return myElementIDFactory->MeshElement(IDelem);
+  return myElementIDFactory->MeshElement(IDelem);
 }
 
 //=======================================================================
@@ -2252,3 +2418,588 @@ SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem )
   else
     return elem->GetType();
 }
+
+
+
+//********************************************************************
+//********************************************************************
+//********                                                   *********
+//*****       Methods for addition of quadratic elements        ******
+//********                                                   *********
+//********************************************************************
+//********************************************************************
+
+//=======================================================================
+//function : AddEdgeWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) 
+{
+  SMDS_MeshNode* node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1);
+  SMDS_MeshNode* node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2);
+  SMDS_MeshNode* node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12);
+  if(!node1 || !node2 || !node12) return NULL;
+  return SMDS_Mesh::AddEdgeWithID(node1, node2, node12, ID);
+}
+
+//=======================================================================
+//function : AddEdge
+//purpose  : 
+//=======================================================================
+SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
+                                 const SMDS_MeshNode* n2,
+                                  const SMDS_MeshNode* n12)
+{
+  return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
+}
+
+//=======================================================================
+//function : AddEdgeWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
+                                       const SMDS_MeshNode * n2, 
+                                       const SMDS_MeshNode * n12, 
+                                       int ID)
+{
+  SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
+  if(myElementIDFactory->BindID(ID, edge)) {
+    SMDS_MeshNode *node1,*node2, *node12;
+    node1 = const_cast<SMDS_MeshNode*>(n1);
+    node2 = const_cast<SMDS_MeshNode*>(n2);
+    node12 = const_cast<SMDS_MeshNode*>(n12);
+    node1->AddInverseElement(edge);
+    node2->AddInverseElement(edge);
+    node12->AddInverseElement(edge);
+    myEdges.Add(edge);
+    return edge;
+  } 
+  else {
+    delete edge;
+    return NULL;
+  }
+}
+
+
+//=======================================================================
+//function : AddFace
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
+                                 const SMDS_MeshNode * n2,
+                                 const SMDS_MeshNode * n3,
+                                  const SMDS_MeshNode * n12,
+                                  const SMDS_MeshNode * n23,
+                                  const SMDS_MeshNode * n31)
+{
+  return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
+                                  myElementIDFactory->GetFreeID());
+}
+
+//=======================================================================
+//function : AddFaceWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
+                                        int n12,int n23,int n31, int ID)
+{
+  SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1);
+  SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2);
+  SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3);
+  SMDS_MeshNode * node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12);
+  SMDS_MeshNode * node23 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23);
+  SMDS_MeshNode * node31 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31);
+  if(!node1 || !node2 || !node3 || !node12 || !node23 || !node31) return NULL;
+  return SMDS_Mesh::AddFaceWithID(node1, node2, node3,
+                                  node12, node23, node31, ID);
+}
+
+//=======================================================================
+//function : AddFaceWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
+                                        const SMDS_MeshNode * n2,
+                                        const SMDS_MeshNode * n3,
+                                        const SMDS_MeshNode * n12,
+                                        const SMDS_MeshNode * n23,
+                                        const SMDS_MeshNode * n31, 
+                                        int ID)
+{
+  if(hasConstructionEdges()) {
+    // creation quadratic edges - not implemented
+  }
+  SMDS_QuadraticFaceOfNodes* face =
+    new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
+  myFaces.Add(face);
+
+  if (!registerElement(ID, face)) {
+    RemoveElement(face, false);
+    face = NULL;
+  }
+  return face;
+}
+
+
+//=======================================================================
+//function : AddFace
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
+                                 const SMDS_MeshNode * n2,
+                                 const SMDS_MeshNode * n3,
+                                 const SMDS_MeshNode * n4,
+                                  const SMDS_MeshNode * n12,
+                                  const SMDS_MeshNode * n23,
+                                  const SMDS_MeshNode * n34,
+                                  const SMDS_MeshNode * n41)
+{
+  return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
+                                  myElementIDFactory->GetFreeID());
+}
+
+//=======================================================================
+//function : AddFaceWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
+                                        int n12,int n23,int n34,int n41, int ID)
+{
+  SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1);
+  SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2);
+  SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3);
+  SMDS_MeshNode * node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4);
+  SMDS_MeshNode * node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12);
+  SMDS_MeshNode * node23 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23);
+  SMDS_MeshNode * node34 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34);
+  SMDS_MeshNode * node41 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41);
+  if(!node1 || !node2 || !node3 || !node4 ||
+     !node12 || !node23 || !node34 || !node41) return NULL;
+  return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4,
+                                  node12, node23, node34, node41, ID);
+}
+
+//=======================================================================
+//function : AddFaceWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
+                                        const SMDS_MeshNode * n2,
+                                        const SMDS_MeshNode * n3,
+                                        const SMDS_MeshNode * n4,
+                                        const SMDS_MeshNode * n12,
+                                        const SMDS_MeshNode * n23,
+                                        const SMDS_MeshNode * n34, 
+                                        const SMDS_MeshNode * n41, 
+                                        int ID)
+{
+  if(hasConstructionEdges()) {
+    // creation quadratic edges - not implemented
+  }
+  SMDS_QuadraticFaceOfNodes* face =
+    new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
+  myFaces.Add(face);
+
+  if (!registerElement(ID, face)) {
+    RemoveElement(face, false);
+    face = NULL;
+  }
+  return face;
+}
+
+
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                     const SMDS_MeshNode * n2, 
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4,
+                                      const SMDS_MeshNode * n12,
+                                      const SMDS_MeshNode * n23,
+                                      const SMDS_MeshNode * n31,
+                                      const SMDS_MeshNode * n14, 
+                                      const SMDS_MeshNode * n24,
+                                      const SMDS_MeshNode * n34)
+{
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
+                                                   n31, n14, n24, n34, ID);
+  if(v==NULL) myElementIDFactory->ReleaseID(ID);
+  return v;
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
+                                            int n12,int n23,int n31,
+                                            int n14,int n24,int n34, int ID)
+{
+  SMDS_MeshNode *node1, *node2, *node3, *node4, *node12, *node23;
+  SMDS_MeshNode *node31, *node14, *node24, *node34;
+  node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1);
+  node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2);
+  node3 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3);
+  node4 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4);
+  node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12);
+  node23 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23);
+  node31 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31);
+  node14 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14);
+  node24 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24);
+  node34 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34);
+  if( !node1 || !node2 || !node3 || !node4 || !node12 || !node23 ||
+     !node31 || !node14 || !node24 || !node34 ) return NULL;
+  return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node12, node23,
+                                    node31, node14, node24, node34, ID);
+}
+       
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 2d order tetrahedron of 10 nodes
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                            const SMDS_MeshNode * n2,
+                                            const SMDS_MeshNode * n3,
+                                            const SMDS_MeshNode * n4,
+                                            const SMDS_MeshNode * n12,
+                                            const SMDS_MeshNode * n23,
+                                            const SMDS_MeshNode * n31,
+                                            const SMDS_MeshNode * n14, 
+                                            const SMDS_MeshNode * n24,
+                                            const SMDS_MeshNode * n34,
+                                            int ID)
+{
+  if(hasConstructionFaces()) {
+    // creation quadratic faces - not implemented
+  }
+  SMDS_QuadraticVolumeOfNodes * volume =
+    new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
+  myVolumes.Add(volume);
+
+  if (!registerElement(ID, volume)) {
+    RemoveElement(volume, false);
+    volume = NULL;
+  }
+  return volume;
+}
+
+
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                     const SMDS_MeshNode * n2, 
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4,
+                                      const SMDS_MeshNode * n5, 
+                                      const SMDS_MeshNode * n12,
+                                      const SMDS_MeshNode * n23,
+                                      const SMDS_MeshNode * n34,
+                                      const SMDS_MeshNode * n41,
+                                      const SMDS_MeshNode * n15, 
+                                      const SMDS_MeshNode * n25,
+                                      const SMDS_MeshNode * n35,
+                                      const SMDS_MeshNode * n45)
+{
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshVolume * v =
+    SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
+                               n15, n25, n35, n45, ID);
+  if(v==NULL) myElementIDFactory->ReleaseID(ID);
+  return v;
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
+                                            int n12,int n23,int n34,int n41,
+                                            int n15,int n25,int n35,int n45, int ID)
+{
+  SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
+  SMDS_MeshNode *node12, *node23, *node34, *node41;
+  SMDS_MeshNode *node15, *node25, *node35, *node45;
+  node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1);
+  node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2);
+  node3 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3);
+  node4 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4);
+  node5 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5);
+  node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12);
+  node23 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23);
+  node34 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34);
+  node41 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41);
+  node15 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15);
+  node25 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25);
+  node35 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35);
+  node45 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45);
+  if( !node1 || !node2 || !node3 || !node4 || !node5 ||
+      !node12 || !node23 || !node34 || !node41 ||
+      !node15 || !node25 || !node35 || !node45 ) return NULL;
+  return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5,
+                                    node12, node23, node34, node41,
+                                    node15, node25, node35, node45, ID);
+}
+       
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 2d order pyramid of 13 nodes
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                            const SMDS_MeshNode * n2,
+                                            const SMDS_MeshNode * n3,
+                                            const SMDS_MeshNode * n4,
+                                            const SMDS_MeshNode * n5, 
+                                            const SMDS_MeshNode * n12,
+                                            const SMDS_MeshNode * n23,
+                                            const SMDS_MeshNode * n34,
+                                            const SMDS_MeshNode * n41,
+                                            const SMDS_MeshNode * n15, 
+                                            const SMDS_MeshNode * n25,
+                                            const SMDS_MeshNode * n35,
+                                            const SMDS_MeshNode * n45,
+                                            int ID)
+{
+  if(hasConstructionFaces()) {
+    // creation quadratic faces - not implemented
+  }
+  SMDS_QuadraticVolumeOfNodes * volume =
+    new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
+                                    n34,n41,n15,n25,n35,n45);
+  myVolumes.Add(volume);
+
+  if (!registerElement(ID, volume)) {
+    RemoveElement(volume, false);
+    volume = NULL;
+  }
+  return volume;
+}
+
+
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                     const SMDS_MeshNode * n2, 
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4,
+                                      const SMDS_MeshNode * n5, 
+                                      const SMDS_MeshNode * n6, 
+                                      const SMDS_MeshNode * n12,
+                                      const SMDS_MeshNode * n23,
+                                      const SMDS_MeshNode * n31, 
+                                      const SMDS_MeshNode * n45,
+                                      const SMDS_MeshNode * n56,
+                                      const SMDS_MeshNode * n64, 
+                                      const SMDS_MeshNode * n14,
+                                      const SMDS_MeshNode * n25,
+                                      const SMDS_MeshNode * n36)
+{
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshVolume * v =
+    SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
+                               n45, n56, n64, n14, n25, n36, ID);
+  if(v==NULL) myElementIDFactory->ReleaseID(ID);
+  return v;
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
+                                            int n4, int n5, int n6,
+                                            int n12,int n23,int n31,
+                                            int n45,int n56,int n64,
+                                            int n14,int n25,int n36, int ID)
+{
+  SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
+  SMDS_MeshNode *node12, *node23, *node31;
+  SMDS_MeshNode *node45, *node56, *node64;
+  SMDS_MeshNode *node14, *node25, *node36;
+  node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1);
+  node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2);
+  node3 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3);
+  node4 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4);
+  node5 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5);
+  node6 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6);
+  node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12);
+  node23 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23);
+  node31 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31);
+  node45 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45);
+  node56 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56);
+  node64 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64);
+  node14 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14);
+  node25 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25);
+  node36 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36);
+  if( !node1 || !node2 || !node3 || !node4 || !node5 || !node6 ||
+      !node12 || !node23 || !node31 || !node45 || !node56 ||
+      !node64 || !node14 || !node25 || !node36 ) return NULL;
+  return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
+                                    node12, node23, node31, node45, node56,
+                                    node64, node14, node25, node36, ID);
+}
+       
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 2d order Pentahedron with 15 nodes
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                            const SMDS_MeshNode * n2,
+                                            const SMDS_MeshNode * n3,
+                                            const SMDS_MeshNode * n4,
+                                            const SMDS_MeshNode * n5, 
+                                            const SMDS_MeshNode * n6, 
+                                            const SMDS_MeshNode * n12,
+                                            const SMDS_MeshNode * n23,
+                                            const SMDS_MeshNode * n31, 
+                                            const SMDS_MeshNode * n45,
+                                            const SMDS_MeshNode * n56,
+                                            const SMDS_MeshNode * n64, 
+                                            const SMDS_MeshNode * n14,
+                                            const SMDS_MeshNode * n25,
+                                            const SMDS_MeshNode * n36,
+                                            int ID)
+{
+  if(hasConstructionFaces()) {
+    // creation quadratic faces - not implemented
+  }
+  SMDS_QuadraticVolumeOfNodes * volume =
+    new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
+                                    n45,n56,n64,n14,n25,n36);
+  myVolumes.Add(volume);
+
+  if (!registerElement(ID, volume)) {
+    RemoveElement(volume, false);
+    volume = NULL;
+  }
+  return volume;
+}
+
+
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                     const SMDS_MeshNode * n2, 
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4,
+                                      const SMDS_MeshNode * n5, 
+                                      const SMDS_MeshNode * n6, 
+                                      const SMDS_MeshNode * n7,
+                                      const SMDS_MeshNode * n8, 
+                                      const SMDS_MeshNode * n12,
+                                      const SMDS_MeshNode * n23,
+                                      const SMDS_MeshNode * n34,
+                                      const SMDS_MeshNode * n41, 
+                                      const SMDS_MeshNode * n56,
+                                      const SMDS_MeshNode * n67,
+                                      const SMDS_MeshNode * n78,
+                                      const SMDS_MeshNode * n85, 
+                                      const SMDS_MeshNode * n15,
+                                      const SMDS_MeshNode * n26,
+                                      const SMDS_MeshNode * n37,
+                                      const SMDS_MeshNode * n48)
+{
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshVolume * v =
+    SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
+                               n56, n67, n78, n85, n15, n26, n37, n48, ID);
+  if(v==NULL) myElementIDFactory->ReleaseID(ID);
+  return v;
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
+                                            int n5, int n6, int n7, int n8,
+                                            int n12,int n23,int n34,int n41,
+                                            int n56,int n67,int n78,int n85,
+                                            int n15,int n26,int n37,int n48, int ID)
+{
+  SMDS_MeshNode *node1, *node2, *node3, *node4;
+  SMDS_MeshNode *node5, *node6, *node7, *node8;
+  SMDS_MeshNode *node12, *node23, *node34, *node41;
+  SMDS_MeshNode *node56, *node67, *node78, *node85;
+  SMDS_MeshNode *node15, *node26, *node37, *node48;
+  node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1);
+  node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2);
+  node3 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3);
+  node4 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4);
+  node5 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5);
+  node6 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6);
+  node7 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7);
+  node8 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8);
+  node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12);
+  node23 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23);
+  node34 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34);
+  node41 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41);
+  node56 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56);
+  node67 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67);
+  node78 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78);
+  node85 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85);
+  node15 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15);
+  node26 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26);
+  node37 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37);
+  node48 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48);
+  if( !node1 || !node2 || !node3 || !node4 ||
+      !node5 || !node6 || !node7 || !node8 ||
+      !node12 || !node23 || !node34 || !node41 ||
+      !node56 || !node67 || !node78 || !node85 ||
+      !node15 || !node26 || !node37 || !node48 ) return NULL;
+  return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4,
+                                    node5, node6, node7, node8,
+                                    node12, node23, node34, node41,
+                                    node56, node67, node78, node85,
+                                    node15, node26, node37, node48, ID);
+}
+       
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 2d order Hexahedrons with 20 nodes
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                            const SMDS_MeshNode * n2,
+                                            const SMDS_MeshNode * n3,
+                                            const SMDS_MeshNode * n4,
+                                            const SMDS_MeshNode * n5, 
+                                            const SMDS_MeshNode * n6, 
+                                            const SMDS_MeshNode * n7,
+                                            const SMDS_MeshNode * n8, 
+                                            const SMDS_MeshNode * n12,
+                                            const SMDS_MeshNode * n23,
+                                            const SMDS_MeshNode * n34,
+                                            const SMDS_MeshNode * n41, 
+                                            const SMDS_MeshNode * n56,
+                                            const SMDS_MeshNode * n67,
+                                            const SMDS_MeshNode * n78,
+                                            const SMDS_MeshNode * n85, 
+                                            const SMDS_MeshNode * n15,
+                                            const SMDS_MeshNode * n26,
+                                            const SMDS_MeshNode * n37,
+                                            const SMDS_MeshNode * n48,
+                                            int ID)
+{
+  if(hasConstructionFaces()) {
+    // creation quadratic faces - not implemented
+  }
+  SMDS_QuadraticVolumeOfNodes * volume =
+    new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
+                                    n56,n67,n78,n85,n15,n26,n37,n48);
+  myVolumes.Add(volume);
+
+  if (!registerElement(ID, volume)) {
+    RemoveElement(volume, false);
+    volume = NULL;
+  }
+  return volume;
+}
+
index 11f201cc892cebbdc09b5df3acce8c654901b0db..00db00fa1fceabb4cf3a9e5d2e703abb127c5575 100644 (file)
 #include <set>
 #include <list>
 
-typedef SMDS_Iterator<const SMDS_MeshNode *> SMDS_NodeIterator;
-typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshNode *> > SMDS_NodeIteratorPtr;
-typedef SMDS_Iterator<const SMDS_MeshEdge *> SMDS_EdgeIterator;
-typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshEdge *> > SMDS_EdgeIteratorPtr;
-typedef SMDS_Iterator<const SMDS_MeshFace *> SMDS_FaceIterator;
-typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshFace *> > SMDS_FaceIteratorPtr;
-typedef SMDS_Iterator<const SMDS_MeshVolume *> SMDS_VolumeIterator;
-typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshVolume *> > SMDS_VolumeIteratorPtr;
-
 class SMDS_WNT_EXPORT SMDS_Mesh:public SMDS_MeshObject{
 public:
   
@@ -84,6 +75,16 @@ public:
   virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1,
                                 const SMDS_MeshNode * n2);
   
+  // 2d order edge with 3 nodes: n12 - node between n1 and n2
+  virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int n12, int ID);
+  virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1,
+                                      const SMDS_MeshNode * n2, 
+                                      const SMDS_MeshNode * n12, 
+                                      int ID);
+  virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1,
+                                 const SMDS_MeshNode * n2,
+                                 const SMDS_MeshNode * n12);
+
   virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID);
   virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
                                       const SMDS_MeshNode * n2,
@@ -120,6 +121,44 @@ public:
                                  const SMDS_MeshEdge * e3,
                                  const SMDS_MeshEdge * e4);
 
+  // 2d order triangle of 6 nodes
+  virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3,
+                                       int n12,int n23,int n31, int ID);
+  virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3, 
+                                      const SMDS_MeshNode * n12,
+                                      const SMDS_MeshNode * n23,
+                                      const SMDS_MeshNode * n31, 
+                                      int ID);
+  virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1,
+                                const SMDS_MeshNode * n2,
+                                const SMDS_MeshNode * n3,
+                                 const SMDS_MeshNode * n12,
+                                const SMDS_MeshNode * n23,
+                                const SMDS_MeshNode * n31);
+
+  // 2d order quadrangle
+  virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4,
+                                       int n12,int n23,int n34,int n41, int ID);
+  virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3,
+                                      const SMDS_MeshNode * n4, 
+                                      const SMDS_MeshNode * n12,
+                                      const SMDS_MeshNode * n23,
+                                      const SMDS_MeshNode * n34,
+                                      const SMDS_MeshNode * n41, 
+                                      int ID);
+  virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1,
+                                const SMDS_MeshNode * n2,
+                                const SMDS_MeshNode * n3,
+                                const SMDS_MeshNode * n4,
+                                 const SMDS_MeshNode * n12,
+                                const SMDS_MeshNode * n23,
+                                const SMDS_MeshNode * n34,
+                                const SMDS_MeshNode * n41);
+
   virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int ID);
   virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
                                           const SMDS_MeshNode * n2,
@@ -214,6 +253,153 @@ public:
                                      const SMDS_MeshFace * f5,
                                      const SMDS_MeshFace * f6);
 
+  // 2d order tetrahedron of 10 nodes
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
+                                           int n12,int n23,int n31,
+                                           int n14,int n24,int n34, int ID);
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+                                          const SMDS_MeshNode * n2,
+                                          const SMDS_MeshNode * n3,
+                                          const SMDS_MeshNode * n4, 
+                                          const SMDS_MeshNode * n12,
+                                          const SMDS_MeshNode * n23,
+                                          const SMDS_MeshNode * n31,
+                                          const SMDS_MeshNode * n14, 
+                                          const SMDS_MeshNode * n24,
+                                          const SMDS_MeshNode * n34, 
+                                          int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+                                    const SMDS_MeshNode * n2,
+                                    const SMDS_MeshNode * n3,
+                                    const SMDS_MeshNode * n4,
+                                     const SMDS_MeshNode * n12,
+                                     const SMDS_MeshNode * n23,
+                                     const SMDS_MeshNode * n31,
+                                     const SMDS_MeshNode * n14, 
+                                     const SMDS_MeshNode * n24,
+                                     const SMDS_MeshNode * n34);
+
+  // 2d order pyramid of 13 nodes
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
+                                           int n12,int n23,int n34,int n41,
+                                           int n15,int n25,int n35,int n45,
+                                           int ID);
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+                                          const SMDS_MeshNode * n2,
+                                          const SMDS_MeshNode * n3,
+                                          const SMDS_MeshNode * n4,
+                                          const SMDS_MeshNode * n5, 
+                                          const SMDS_MeshNode * n12,
+                                          const SMDS_MeshNode * n23,
+                                          const SMDS_MeshNode * n34,
+                                          const SMDS_MeshNode * n41, 
+                                          const SMDS_MeshNode * n15,
+                                          const SMDS_MeshNode * n25,
+                                          const SMDS_MeshNode * n35,
+                                          const SMDS_MeshNode * n45, 
+                                          int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+                                    const SMDS_MeshNode * n2,
+                                    const SMDS_MeshNode * n3,
+                                    const SMDS_MeshNode * n4,
+                                    const SMDS_MeshNode * n5,
+                                     const SMDS_MeshNode * n12,
+                                     const SMDS_MeshNode * n23,
+                                     const SMDS_MeshNode * n34,
+                                     const SMDS_MeshNode * n41, 
+                                     const SMDS_MeshNode * n15,
+                                     const SMDS_MeshNode * n25,
+                                     const SMDS_MeshNode * n35,
+                                     const SMDS_MeshNode * n45);
+
+  // 2d order Pentahedron with 15 nodes
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3,
+                                           int n4, int n5, int n6,
+                                           int n12,int n23,int n31,
+                                           int n45,int n56,int n64,
+                                           int n14,int n25,int n36,
+                                           int ID);
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+                                          const SMDS_MeshNode * n2,
+                                          const SMDS_MeshNode * n3,
+                                          const SMDS_MeshNode * n4,
+                                          const SMDS_MeshNode * n5,
+                                          const SMDS_MeshNode * n6, 
+                                          const SMDS_MeshNode * n12,
+                                          const SMDS_MeshNode * n23,
+                                          const SMDS_MeshNode * n31, 
+                                          const SMDS_MeshNode * n45,
+                                          const SMDS_MeshNode * n56,
+                                          const SMDS_MeshNode * n64, 
+                                          const SMDS_MeshNode * n14,
+                                          const SMDS_MeshNode * n25,
+                                          const SMDS_MeshNode * n36, 
+                                          int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+                                    const SMDS_MeshNode * n2,
+                                    const SMDS_MeshNode * n3,
+                                    const SMDS_MeshNode * n4,
+                                    const SMDS_MeshNode * n5,
+                                    const SMDS_MeshNode * n6, 
+                                     const SMDS_MeshNode * n12,
+                                     const SMDS_MeshNode * n23,
+                                     const SMDS_MeshNode * n31, 
+                                     const SMDS_MeshNode * n45,
+                                     const SMDS_MeshNode * n56,
+                                     const SMDS_MeshNode * n64, 
+                                     const SMDS_MeshNode * n14,
+                                     const SMDS_MeshNode * n25,
+                                     const SMDS_MeshNode * n36);
+
+  // 2d oreder Hexahedrons with 20 nodes
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
+                                           int n5, int n6, int n7, int n8,
+                                           int n12,int n23,int n34,int n41,
+                                           int n56,int n67,int n78,int n85,
+                                           int n15,int n26,int n37,int n48,
+                                           int ID);
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+                                          const SMDS_MeshNode * n2,
+                                          const SMDS_MeshNode * n3,
+                                          const SMDS_MeshNode * n4,
+                                          const SMDS_MeshNode * n5,
+                                          const SMDS_MeshNode * n6,
+                                          const SMDS_MeshNode * n7,
+                                          const SMDS_MeshNode * n8, 
+                                          const SMDS_MeshNode * n12,
+                                          const SMDS_MeshNode * n23,
+                                          const SMDS_MeshNode * n34,
+                                          const SMDS_MeshNode * n41, 
+                                          const SMDS_MeshNode * n56,
+                                          const SMDS_MeshNode * n67,
+                                          const SMDS_MeshNode * n78,
+                                          const SMDS_MeshNode * n85, 
+                                          const SMDS_MeshNode * n15,
+                                          const SMDS_MeshNode * n26,
+                                          const SMDS_MeshNode * n37,
+                                          const SMDS_MeshNode * n48, 
+                                          int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+                                    const SMDS_MeshNode * n2,
+                                    const SMDS_MeshNode * n3,
+                                    const SMDS_MeshNode * n4,
+                                    const SMDS_MeshNode * n5,
+                                    const SMDS_MeshNode * n6,
+                                    const SMDS_MeshNode * n7,
+                                    const SMDS_MeshNode * n8, 
+                                     const SMDS_MeshNode * n12,
+                                     const SMDS_MeshNode * n23,
+                                     const SMDS_MeshNode * n34,
+                                     const SMDS_MeshNode * n41, 
+                                     const SMDS_MeshNode * n56,
+                                     const SMDS_MeshNode * n67,
+                                     const SMDS_MeshNode * n78,
+                                     const SMDS_MeshNode * n85, 
+                                     const SMDS_MeshNode * n15,
+                                     const SMDS_MeshNode * n26,
+                                     const SMDS_MeshNode * n37,
+                                     const SMDS_MeshNode * n48);
+
   virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector<int> nodes_ids,
                                                  const int        ID);
 
@@ -267,11 +453,19 @@ public:
 
   const SMDS_MeshNode *FindNode(int idnode) const;
   const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2) const;
+  const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2, int idnode3) const;
   const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3) const;
   const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4) const;
+  const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3,
+                                int idnode4, int idnode5, int idnode6) const;
+  const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4,
+                                int idnode5, int idnode6, int idnode7, int idnode8) const;
   const SMDS_MeshElement *FindElement(int IDelem) const;
   static const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1,
                                        const SMDS_MeshNode * n2);
+  static const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1,
+                                       const SMDS_MeshNode * n2,
+                                       const SMDS_MeshNode * n3);
   static const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1,
                                        const SMDS_MeshNode *n2,
                                        const SMDS_MeshNode *n3);
@@ -279,6 +473,20 @@ public:
                                        const SMDS_MeshNode *n2,
                                        const SMDS_MeshNode *n3,
                                        const SMDS_MeshNode *n4);
+  static const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1,
+                                       const SMDS_MeshNode *n2,
+                                       const SMDS_MeshNode *n3,
+                                       const SMDS_MeshNode *n4,
+                                       const SMDS_MeshNode *n5,
+                                       const SMDS_MeshNode *n6);
+  static const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1,
+                                       const SMDS_MeshNode *n2,
+                                       const SMDS_MeshNode *n3,
+                                       const SMDS_MeshNode *n4,
+                                       const SMDS_MeshNode *n5,
+                                       const SMDS_MeshNode *n6,
+                                       const SMDS_MeshNode *n7,
+                                       const SMDS_MeshNode *n8);
 
   const SMDS_MeshFace *FindFace(std::vector<int> nodes_ids) const;
   static const SMDS_MeshFace* FindFace(std::vector<const SMDS_MeshNode *> nodes);
index 66c8ae3d5cf36edf2e0ff37545f40a6e4d2e4b43..dc1dab968d5ec2f78b1440212e2af305f883a2a0 100644 (file)
@@ -135,6 +135,18 @@ bool operator<(const SMDS_MeshEdge & e1, const SMDS_MeshEdge & e2)
        else return false;
 }
 
+/*!
+ * \brief Return node by its index
+ * \param ind - node index
+ * \retval const SMDS_MeshNode* - the node
+ * 
+ * Index is wrapped if it is out of a valid range
+ */
+const SMDS_MeshNode* SMDS_MeshEdge::GetNode(const int ind) const
+{
+  return myNodes[ WrappedIndex( ind )];
+}
+
 //=======================================================================
 //function : ChangeNodes
 //purpose  : 
index 290210ca324b7265467d3186264a23cc29c37a5e..c99b08198c7cadbed6a246056b101192bf155186 100644 (file)
@@ -44,12 +44,22 @@ class SMDS_MeshEdge:public SMDS_MeshElement
        int NbNodes() const;
        int NbEdges() const;
        friend bool operator<(const SMDS_MeshEdge& e1, const SMDS_MeshEdge& e2);
+
+  /*!
+   * \brief Return node by its index
+    * \param ind - node index
+    * \retval const SMDS_MeshNode* - the node
+   * 
+   * Index is wrapped if it is out of a valid range
+   */
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+
   protected:
        SMDS_ElemIteratorPtr
                elementsIterator(SMDSAbs_ElementType type) const;
 
-  private:
-       const SMDS_MeshNode* myNodes[2];
+  protected:
+       const SMDS_MeshNode* myNodes[3];
 
 };
 #endif
index 8d4d9b75dc2e0bb913603c73ac5a5fefb72f9887..83f073fdbcc1c2c529c43fe5f0c469dc18ec722f 100644 (file)
@@ -192,3 +192,29 @@ bool operator<(const SMDS_MeshElement& e1, const SMDS_MeshElement& e2)
        }
         return false;
 }
+
+bool SMDS_MeshElement::IsValidIndex(const int ind) const
+{
+  return ( ind>-1 && ind<NbNodes() );
+}
+
+const SMDS_MeshNode* SMDS_MeshElement::GetNode(const int ind) const
+{
+  SMDS_ElemIteratorPtr it = nodesIterator();
+  int i = 0, index = WrappedIndex( ind );
+  while ( index != i++ )
+    it->next();
+  if ( it->more() )
+    return static_cast<const SMDS_MeshNode*> (it->next());
+  return 0;
+}
+
+bool SMDS_MeshElement::IsQuadratic() const
+{
+  return false;
+}
+
+bool SMDS_MeshElement::IsMediumNode(const SMDS_MeshNode* node) const
+{
+  return false;
+}
index 73870b707fbf37d96184688cd7ac4c763a98ca0a..67ac8f2473f36f7dd7fa00afcd795353a9102b4b 100644 (file)
@@ -56,32 +56,64 @@ class SMDS_MeshFace;
 ///////////////////////////////////////////////////////////////////////////////
 class SMDS_WNT_EXPORT SMDS_MeshElement:public SMDS_MeshObject
 {
+public:
 
-  public:
-       SMDS_ElemIteratorPtr nodesIterator() const;
-       SMDS_ElemIteratorPtr edgesIterator() const;
-       SMDS_ElemIteratorPtr facesIterator() const;
-       virtual SMDS_ElemIteratorPtr
-               elementsIterator(SMDSAbs_ElementType type) const;
+  SMDS_ElemIteratorPtr nodesIterator() const;
+  SMDS_ElemIteratorPtr edgesIterator() const;
+  SMDS_ElemIteratorPtr facesIterator() const;
+  virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
 
-       virtual int NbNodes() const;
-       virtual int NbEdges() const;
-       virtual int NbFaces() const;
-       int GetID() const;
+  virtual int NbNodes() const;
+  virtual int NbEdges() const;
+  virtual int NbFaces() const;
+  int GetID() const;
 
-       ///Return the type of the current element
-       virtual SMDSAbs_ElementType GetType() const = 0;
-       virtual bool IsPoly() const { return false; };
+  ///Return the type of the current element
+  virtual SMDSAbs_ElementType GetType() const = 0;
+  virtual bool IsPoly() const { return false; };
+  virtual bool IsQuadratic() const;
 
-       friend std::ostream & operator <<(std::ostream & OS, const SMDS_MeshElement *);
-       friend bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement*elem);
+  virtual bool IsMediumNode(const SMDS_MeshNode* node) const;
 
-  protected:
-       SMDS_MeshElement(int ID=-1);
-       virtual void Print(std::ostream & OS) const;
-       
-  private:
-       int myID;
+  friend std::ostream & operator <<(std::ostream & OS, const SMDS_MeshElement *);
+  friend bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement*elem);
+
+  // ===========================
+  //  Access to nodes by index
+  // ===========================
+  /*!
+   * \brief Return node by its index
+    * \param ind - node index
+    * \retval const SMDS_MeshNode* - the node
+   * 
+   * Index is wrapped if it is out of a valid range
+   */
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+
+  /*!
+   * \brief Return true if index of node is valid (0 <= ind < NbNodes())
+    * \param ind - node index
+    * \retval bool - index check result
+   */
+  virtual bool IsValidIndex(const int ind) const;
+
+  /*!
+   * \brief Return a valid node index, fixing the given one if necessary
+    * \param ind - node index
+    * \retval int - valid node index
+   */
+  int WrappedIndex(const int ind) const {
+    if ( ind < 0 ) return -( ind % NbNodes());
+    if ( ind >= NbNodes() ) return ind % NbNodes();
+    return ind;
+  }
+
+protected:
+  SMDS_MeshElement(int ID=-1);
+  virtual void Print(std::ostream & OS) const;
+
+private:
+  int myID;
 };
 
 #endif
index 042a1734af5bfdefef81be8e24fbb719339bfe8c..fad62253411a848c8b0675bef333b36332e43275 100644 (file)
@@ -64,6 +64,15 @@ class SMDS_WNT_EXPORT SMDS_MeshNode:public SMDS_MeshElement
        void setXYZ(double x, double y, double z);
        friend bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2);
 
+  /*!
+   * \brief Return node by its index
+    * \param ind - node index
+    * \retval const SMDS_MeshNode* - the node
+   * 
+   * Index is wrapped if it is out of a valid range
+   */
+  virtual const SMDS_MeshNode* GetNode(const int) const { return this; }
+
   protected:
        SMDS_ElemIteratorPtr
                elementsIterator(SMDSAbs_ElementType type) const;
index 38abf18c2f225e598249640cce2e308602e7f43a..568bd34d0095b128adce4c9d48c6166a518d425e 100644 (file)
@@ -26,7 +26,7 @@
 #include "SMDS_PolygonalFaceOfNodes.hxx"
 
 #include "SMDS_IteratorOfElements.hxx"
-//#include "SMDS_MeshNode.hxx"
+#include "SMDS_SetIterator.hxx"
 #include "utilities.h"
 
 using namespace std;
@@ -128,28 +128,11 @@ void SMDS_PolygonalFaceOfNodes::Print(ostream & OS) const
 //function : elementsIterator
 //purpose  : 
 //=======================================================================
-class SMDS_PolygonalFaceOfNodes_MyIterator:public SMDS_ElemIterator
+class SMDS_PolygonalFaceOfNodes_MyIterator:public SMDS_NodeVectorElemIterator
 {
-  //const SMDS_MeshNode* const *mySet;
-  const std::vector<const SMDS_MeshNode *> mySet;
-  //int myLength;
-  int index;
  public:
-  //SMDS_PolygonalFaceOfNodes_MyIterator(const SMDS_MeshNode* const *s, int l):
-  //  mySet(s),myLength(l),index(0) {}
-  SMDS_PolygonalFaceOfNodes_MyIterator(const std::vector<const SMDS_MeshNode *> s):
-    mySet(s),index(0) {}
-
-  bool more()
-  {
-    return index < mySet.size();
-  }
-
-  const SMDS_MeshElement* next()
-  {
-    index++;
-    return mySet[index-1];
-  }
+  SMDS_PolygonalFaceOfNodes_MyIterator(const vector<const SMDS_MeshNode *>& s):
+    SMDS_NodeVectorElemIterator( s.begin(), s.end() ) {}
 };
 
 SMDS_ElemIteratorPtr SMDS_PolygonalFaceOfNodes::elementsIterator
@@ -172,3 +155,16 @@ SMDS_ElemIteratorPtr SMDS_PolygonalFaceOfNodes::elementsIterator
   }
   return SMDS_ElemIteratorPtr();
 }
+
+/*!
+ * \brief Return node by its index
+ * \param ind - node index
+ * \retval const SMDS_MeshNode* - the node
+ * 
+ * Index is wrapped if it is out of a valid range
+ */
+const SMDS_MeshNode* SMDS_PolygonalFaceOfNodes::GetNode(const int ind) const
+{
+  return myNodes[ WrappedIndex( ind )];
+}
+
index 567746259105ba4b57fc28f184b7864aa15d2029..c8884b3197093327242060937c989ea973e7fea1 100644 (file)
@@ -50,6 +50,15 @@ class SMDS_PolygonalFaceOfNodes:public SMDS_MeshFace
 
   virtual void Print (std::ostream & OS) const;
 
+  /*!
+   * \brief Return node by its index
+    * \param ind - node index
+    * \retval const SMDS_MeshNode* - the node
+   * 
+   * Index is wrapped if it is out of a valid range
+   */
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+
  protected:
   virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const;
 
index cd893f484a87e45a70059e678810ce358bb25271..941f538c3e4a4eb30a712612c3e12f9fd04778e4 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "SMDS_VolumeOfNodes.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "SMDS_SetIterator.hxx"
 #include "utilities.h"
 
 using namespace std;
@@ -170,29 +171,14 @@ int SMDS_VolumeOfNodes::NbEdges() const
         return 0;
 }
 
-class SMDS_VolumeOfNodes_MyIterator:public SMDS_ElemIterator
+class SMDS_VolumeOfNodes_MyIterator:public SMDS_NodeArrayElemIterator
 {
-  const SMDS_MeshNode* const* mySet;
-  int myLength;
-  int index;
  public:
   SMDS_VolumeOfNodes_MyIterator(const SMDS_MeshNode* const* s, int l):
-    mySet(s),myLength(l),index(0) {}
-
-  bool more()
-  {
-    return index<myLength;
-  }
-
-  const SMDS_MeshElement* next()
-  {
-    index++;
-    return mySet[index-1];
-  }
+    SMDS_NodeArrayElemIterator( s, & s[ l ]) {}
 };
 
-SMDS_ElemIteratorPtr SMDS_VolumeOfNodes::
-       elementsIterator(SMDSAbs_ElementType type) const
+SMDS_ElemIteratorPtr SMDS_VolumeOfNodes::elementsIterator(SMDSAbs_ElementType type) const
 {
   switch(type)
   {
@@ -210,3 +196,15 @@ SMDSAbs_ElementType SMDS_VolumeOfNodes::GetType() const
 {
        return SMDSAbs_Volume;
 }
+
+/*!
+ * \brief Return node by its index
+ * \param ind - node index
+ * \retval const SMDS_MeshNode* - the node
+ * 
+ * Index is wrapped if it is out of a valid range
+ */
+const SMDS_MeshNode* SMDS_VolumeOfNodes::GetNode(const int ind) const
+{
+  return myNodes[ WrappedIndex( ind )];
+}
index bb553a03a003518bf96b42dd530591fc59f3ece9..7595174906a4879011ce5689762b4b939e9f4a0a 100644 (file)
@@ -70,6 +70,16 @@ class SMDS_VolumeOfNodes:public SMDS_MeshVolume
        int NbNodes() const;
        int NbEdges() const;
        SMDSAbs_ElementType GetType() const;    
+
+  /*!
+   * \brief Return node by its index
+    * \param ind - node index
+    * \retval const SMDS_MeshNode* - the node
+   * 
+   * Index is wrapped if it is out of a valid range
+   */
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+
   protected:
        SMDS_ElemIteratorPtr
                elementsIterator(SMDSAbs_ElementType type) const;
index 381b262ee334a19aef0bdaecace677be468baac4..9f35e015818776d4b5f64f2383a56492ebdd2086 100644 (file)
@@ -185,6 +185,184 @@ static int Hexa_RE [6][5] = { // REVERSED -> EXTERNAL
   { 1, 2, 6, 5, 1 }};
 static int Hexa_nbN [] = { 4, 4, 4, 4, 4, 4 };
 
+
+/*
+//           N3
+//           +
+//          /|\
+//        7/ | \8
+//        /  |4 \                    QUADRATIC
+//    N0 +---|---+ N1                TETRAHEDRON
+//       \   +9  /
+//        \  |  /
+//        6\ | /5
+//          \|/
+//           +
+//           N2
+*/
+static int QuadTetra_F [4][7] = { // FORWARD == EXTERNAL
+  { 0, 4, 1, 5, 2, 6, 0 },        // All faces have external normals
+  { 0, 7, 3, 8, 1, 4, 0 },
+  { 1, 8, 3, 9, 2, 5, 1 },
+  { 0, 6, 2, 9, 3, 7, 0 }}; 
+static int QuadTetra_R [4][7] = { // REVERSED
+  { 0, 4, 1, 5, 2, 6, 0 },        // All faces but a bottom have external normals
+  { 0, 4, 1, 8, 3, 7, 0 },
+  { 1, 5, 2, 9, 3, 8, 1 },
+  { 0, 7, 3, 9, 2, 6, 0 }};
+static int QuadTetra_RE [4][7] = { // REVERSED -> FORWARD (EXTERNAL)
+  { 0, 6, 2, 5, 1, 4, 0 },              // All faces have external normals
+  { 0, 4, 1, 8, 3, 7, 0 },
+  { 1, 5, 2, 9, 3, 8, 1 },
+  { 0, 7, 3, 9, 2, 6, 0 }};
+static int QuadTetra_nbN [] = { 6, 6, 6, 6 };
+
+//
+//     QUADRATIC
+//     PYRAMID
+//
+//            +4
+//
+//            
+//       10+-----+11
+//         |     |        9 - middle point for (0,4) etc.
+//         |     |
+//        9+-----+12
+//
+//            6
+//      1+----+----+2
+//       |         |
+//       |         |
+//      5+         +7
+//       |         |
+//       |         |
+//      0+----+----+3
+//            8
+static int QuadPyram_F [5][9] = {  // FORWARD == EXTERNAL
+  { 0, 5, 1, 6, 2, 7, 3, 8, 0 },   // All faces have external normals
+  { 0, 9, 4, 10,1, 5, 0, 4, 4 },
+  { 1, 10,4, 11,2, 6, 1, 4, 4 },
+  { 2, 11,4, 12,3, 7, 2, 4, 4 },
+  { 3, 12,4, 9, 0, 8, 3, 4, 4 }}; 
+static int QuadPyram_R [5][9] = {  // REVERSED
+  { 0, 5, 1, 6, 2, 7, 3, 8, 0 },   // All faces but a bottom have external normals
+  { 0, 5, 1, 10,4, 9, 0, 4, 4 },
+  { 1, 6, 2, 11,4, 10,1, 4, 4 },
+  { 2, 7, 3, 12,4, 11,2, 4, 4 },
+  { 3, 8, 0, 9, 4, 12,3, 4, 4 }}; 
+static int QuadPyram_RE [5][9] = { // REVERSED -> FORWARD (EXTERNAL)
+  { 0, 8, 3, 7, 2, 6, 1, 5, 0 },   // All faces but a bottom have external normals
+  { 0, 5, 1, 10,4, 9, 0, 4, 4 },
+  { 1, 6, 2, 11,4, 10,1, 4, 4 },
+  { 2, 7, 3, 12,4, 11,2, 4, 4 },
+  { 3, 8, 0, 9, 4, 12,3, 4, 4 }}; 
+static int QuadPyram_nbN [] = { 8, 6, 6, 6, 6 };
+
+/*   
+//            + N4
+//           /|\
+//         9/ | \10
+//         /  |  \
+//        /   |   \
+//    N3 +----+----+ N5
+//       |    |11  |
+//       |    |    |
+//       |    +13  |                QUADRATIC
+//       |    |    |                PENTAHEDRON
+//       |    |    |
+//       |    |    |
+//       |    |    |
+//     12+    |    +14
+//       |    |    |
+//       |    |    |
+//       |    + N1 |
+//       |   / \   |               
+//       | 6/   \7 |
+//       | /     \ |
+//       |/       \|
+//    N0 +---------+ N2
+//            8
+*/
+static int QuadPenta_F [5][9] = {  // FORWARD
+  { 0, 6, 1, 7, 2, 8, 0, 0, 0 },   // Top face has an internal normal, other - external
+  { 3, 9, 4, 10,5, 11,3, 3, 3 },   // 0 is bottom, 1 is top face
+  { 0, 8, 2, 14,5, 11,3, 12,0 },
+  { 1, 13,4, 10,5, 14,2, 7, 1 },
+  { 0, 12,3, 9, 4, 13,1, 6, 0 }}; 
+static int QuadPenta_R [5][9] = { // REVERSED
+  { 0, 6, 1, 7, 2, 8, 0, 0, 0 },  // Bottom face has an internal normal, other - external
+  { 3, 9, 4, 10,5, 11,3, 3, 3 },  // 0 is bottom, 1 is top face
+  { 0, 12,3, 11,5, 14,2, 8, 0 },
+  { 1, 7, 2, 14,5, 10,4, 13,1 },
+  { 0, 6, 1, 13,4, 9, 3, 12,0 }}; 
+static int QuadPenta_FE [5][9] = { // FORWARD -> EXTERNAL
+  { 0, 6, 1, 7, 2, 8, 0, 0, 0 },
+  { 3,11, 5, 10,4, 9, 3, 3, 3 },
+  { 0, 8, 2, 14,5, 11,3, 12,0 },
+  { 1, 13,4, 10,5, 14,2, 7, 1 },
+  { 0, 12,3, 9, 4, 13,1, 6, 0 }}; 
+static int QuadPenta_RE [5][9] = { // REVERSED -> EXTERNAL
+  { 0, 8, 2, 7, 1, 6, 0, 0, 0 },
+  { 3, 9, 4, 10,5, 11,3, 3, 3 },
+  { 0, 12,3, 11,5, 14,2, 8, 0 },
+  { 1, 7, 2, 14,5, 10,4, 13,1 },
+  { 0, 6, 1, 13,4, 9, 3, 12,0 }}; 
+static int QuadPenta_nbN [] = { 6, 6, 8, 8, 8 };
+
+/*
+//                 13
+//         N5+-----+-----+N6
+//          /|          /|
+//       12+ |       14+ |
+//        /  |        /  |
+//     N4+-----+-----+N7 |           QUADRATIC
+//       |   | 15    |   |           HEXAHEDRON
+//       |   |       |   |
+//       | 17+       |   +18
+//       |   |       |   |
+//       |   |       |   |
+//       |   |       |   |
+//     16+   |       +19 |
+//       |   |       |   |
+//       |   |     9 |   |
+//       | N1+-----+-|---+N2
+//       |  /        |  /
+//       | +8        | +10
+//       |/          |/
+//     N0+-----+-----+N3
+//             11
+*/
+static int QuadHexa_F [6][9] = {  // FORWARD
+  { 0, 8, 1, 9, 2, 10,3, 11,0 },  // opposite faces are neighbouring,
+  { 4, 12,5, 13,6, 14,7, 15,4 },  // odd face(1,3,5) normal is internal, even(0,2,4) - external
+  { 1, 8, 0, 16,4, 12,5, 17,1 },  // same index nodes of opposite faces are linked
+  { 2, 10,3, 19,7, 14,6, 18,2 }, 
+  { 0, 11,3, 19,7, 15,4, 16,0 }, 
+  { 1, 9, 2, 18,6, 13,5, 17,1 }};
+// static int Hexa_R [6][5] = { // REVERSED
+//   { 0, 3, 2, 1, 0 },         // opposite faces are neighbouring,
+//   { 4, 7, 6, 5, 4 },         // odd face(1,3,5) normal is external, even(0,2,4) - internal
+//   { 1, 5, 4, 0, 1 },         // same index nodes of opposite faces are linked
+//   { 2, 6, 7, 3, 2 }, 
+//   { 0, 4, 7, 3, 0 }, 
+//   { 1, 5, 6, 2, 1 }};
+static int QuadHexa_FE [6][9] = {  // FORWARD -> EXTERNAL
+  { 0, 8, 1, 9, 2, 10,3, 11,0 },   // opposite faces are neighbouring,
+  { 4, 15,7, 14,6, 13,5, 12,4 },   // all face normals are external,
+  { 0, 16,4, 12,5, 17,1, 8, 0 },   // links in opposite faces: 0-0, 1-3, 2-2, 3-1
+  { 3, 10,2, 18,6, 14,7, 19,3 }, 
+  { 0, 11,3, 19,7, 15,4, 16,0 },
+  { 1, 17,5, 13,6, 18,2, 9, 1 }};
+static int QuadHexa_RE [6][9] = {  // REVERSED -> EXTERNAL
+  { 0, 11,3, 10,2, 9, 1, 8, 0 },   // opposite faces are neighbouring,
+  { 4, 12,5, 13,6, 14,7, 15,4 },   // all face normals are external,
+  { 0, 8, 1, 17,5, 12,4, 16,0 },   // links in opposite faces: 0-0, 1-3, 2-2, 3-1
+  { 3, 19,7, 14,6, 18,2, 10,3 }, 
+  { 0, 16,4, 15,7, 19,3, 11,0 },
+  { 1, 9, 2, 18,6, 13,5, 17,1 }};
+static int QuadHexa_nbN [] = { 8, 8, 8, 8, 8, 8 };
+
+
 // ========================================================
 // to perform some calculations without linkage to CASCADE
 // ========================================================
@@ -323,12 +501,17 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume)
         MESSAGE("Warning: bad volumic element");
         return false;
       }
-    } else {
+    }
+    else {
       switch ( myVolumeNbNodes ) {
       case 4:
       case 5:
       case 6:
-      case 8: {
+      case 8:
+      case 10:
+      case 13:
+      case 15:
+      case 20: {
         // define volume orientation
         XYZ botNormal;
         GetFaceNormal( 0, botNormal.x, botNormal.y, botNormal.z );
@@ -387,6 +570,34 @@ void SMDS_VolumeTool::Inverse ()
     SWAP_NODES( myVolumeNodes, 1, 3 );
     SWAP_NODES( myVolumeNodes, 5, 7 );
     break;
+
+  case 10:
+    SWAP_NODES( myVolumeNodes, 1, 2 );
+    SWAP_NODES( myVolumeNodes, 4, 6 );
+    SWAP_NODES( myVolumeNodes, 8, 9 );
+    break;
+  case 13:
+    SWAP_NODES( myVolumeNodes, 1, 3 );
+    SWAP_NODES( myVolumeNodes, 5, 8 );
+    SWAP_NODES( myVolumeNodes, 6, 7 );
+    SWAP_NODES( myVolumeNodes, 10, 12 );
+    break;
+  case 15:
+    SWAP_NODES( myVolumeNodes, 1, 2 );
+    SWAP_NODES( myVolumeNodes, 4, 5 );
+    SWAP_NODES( myVolumeNodes, 6, 8 );
+    SWAP_NODES( myVolumeNodes, 9, 11 );
+    SWAP_NODES( myVolumeNodes, 13, 14 );
+    break;
+  case 20:
+    SWAP_NODES( myVolumeNodes, 1, 3 );
+    SWAP_NODES( myVolumeNodes, 5, 7 );
+    SWAP_NODES( myVolumeNodes, 8, 11 );
+    SWAP_NODES( myVolumeNodes, 9, 10 );
+    SWAP_NODES( myVolumeNodes, 12, 15 );
+    SWAP_NODES( myVolumeNodes, 13, 14 );
+    SWAP_NODES( myVolumeNodes, 17, 19 );
+    break;
   default:;
   }
 }
@@ -402,14 +613,25 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetVolumeType() const
     return POLYHEDA;
 
   if ( myVolume ) {
-    static const VolumeType types[] = {
-      TETRA,     // myVolumeNbNodes = 4
-      PYRAM,     // myVolumeNbNodes = 5
-      PENTA,     // myVolumeNbNodes = 6
-      UNKNOWN,   // myVolumeNbNodes = 7
-      HEXA       // myVolumeNbNodes = 8
-    };
-    return types[ myVolumeNbNodes - 4 ];
+//    static const VolumeType types[] = {
+//      TETRA,     // myVolumeNbNodes = 4
+//      PYRAM,     // myVolumeNbNodes = 5
+//      PENTA,     // myVolumeNbNodes = 6
+//      UNKNOWN,   // myVolumeNbNodes = 7
+//      HEXA       // myVolumeNbNodes = 8
+//    };
+//    return types[ myVolumeNbNodes - 4 ];
+    switch(myVolumeNbNodes) {
+    case 4: return TETRA; break;
+    case 5: return PYRAM; break;
+    case 6: return PENTA; break;
+    case 8: return HEXA; break;
+    case 10: return QUAD_TETRA; break;
+    case 13: return QUAD_PYRAM; break;
+    case 15: return QUAD_PENTA; break;
+    case 20: return QUAD_HEXA; break;
+    default: break;
+    }
   }
 
   return UNKNOWN;
@@ -491,7 +713,7 @@ double SMDS_VolumeTool::GetSize() const
   else 
   {
     const static int ind[] = {
-      0, 1, 3, 6, 11 };
+      0, 1, 3, 6, 11, 19, 32, 46, 66};
     const static int vtab[][4] = {
       // tetrahedron
       { 0, 1, 2, 3 },
@@ -507,15 +729,80 @@ double SMDS_VolumeTool::GetSize() const
       { 4, 1, 6, 5 },
       { 1, 3, 6, 2 },
       { 4, 6, 3, 7 },
-      { 1, 4, 6, 3 }
+      { 1, 4, 6, 3 },
+
+      // quadratic tetrahedron
+      { 0, 4, 6, 7 },
+      { 1, 5, 4, 8 },
+      { 2, 6, 5, 9 },
+      { 7, 8, 9, 3 },
+      { 4, 6, 7, 9 },
+      { 4, 5, 6, 9 },
+      { 4, 7, 8, 9 },
+      { 4, 5, 9, 8 },
+
+      // quadratic pyramid
+      { 0, 5, 8, 9 },
+      { 1, 5,10, 6 },
+      { 2, 6,11, 7 },
+      { 3, 7,12, 8 },
+      { 4, 9,11,10 },
+      { 4, 9,12,11 },
+      { 10, 5, 9, 8 },
+      { 10, 8, 9,12 },
+      { 10, 8,12, 7 },
+      { 10, 7,12,11 },
+      { 10, 7,11, 6 },
+      { 10, 5, 8, 6 },
+      { 10, 6, 8, 7 },
+
+      // quadratic pentahedron
+      { 12, 0, 8, 6 },
+      { 12, 8, 7, 6 },
+      { 12, 8, 2, 7 },
+      { 12, 6, 7, 1 },
+      { 12, 1, 7,13 },
+      { 12, 7, 2,13 },
+      { 12, 2,14,13 },
+
+      { 12, 3, 9,11 },
+      { 12,11, 9,10 },
+      { 12,11,10, 5 },
+      { 12, 9, 4,10 },
+      { 12,14, 5,10 },
+      { 12,14,10, 4 },
+      { 12,14, 4,13 },
+
+      // quadratic hexahedron
+      { 16, 0,11, 8 },
+      { 16,11, 9, 8 },
+      { 16, 8, 9, 1 },
+      { 16,11, 3,10 },
+      { 16,11,10, 9 },
+      { 16,10, 2, 9 },
+      { 16, 3,19, 2 },
+      { 16, 2,19,18 },
+      { 16, 2,18,17 },
+      { 16, 2,17, 1 },
+
+      { 16, 4,12,15 },
+      { 16,12, 5,13 },
+      { 16,12,13,15 },
+      { 16,13, 6,14 },
+      { 16,13,14,15 },
+      { 16,14, 7,15 },
+      { 16, 6, 5,17 },
+      { 16,18, 6,17 },
+      { 16,18, 7, 6 },
+      { 16,18,19, 7 },
+
     };
 
     int type = GetVolumeType();
     int n1 = ind[type];
     int n2 = ind[type+1];
 
-    for (int i = n1; i <  n2; i++)
-    {
+    for (int i = n1; i <  n2; i++) {
       V -= getTetraVolume( myVolumeNodes[ vtab[i][0] ],
                            myVolumeNodes[ vtab[i][1] ],
                            myVolumeNodes[ vtab[i][2] ],
@@ -647,12 +934,16 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex )
   switch ( myVolumeNbNodes ) {
   case 4:
   case 5:
+  case 10:
+  case 13:
     // only the bottom of a reversed tetrahedron can be internal
     return ( myVolForward || faceIndex != 0 );
   case 6:
+  case 15:
     // in a forward pentahedron, the top is internal, in a reversed one - bottom
     return ( myVolForward ? faceIndex != 1 : faceIndex != 0 );
-  case 8: {
+  case 8:
+  case 20: {
     // in a forward hexahedron, even face normal is external, odd - internal
     bool odd = faceIndex % 2;
     return ( myVolForward ? !odd : odd );
@@ -679,7 +970,8 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub
   XYZ aVec13( p3 - p1 );
   XYZ cross = aVec12.Crossed( aVec13 );
 
-  if ( myFaceNbNodes == 4 ) {
+  //if ( myFaceNbNodes == 4 ) {
+  if ( myFaceNbNodes >3 ) {
     XYZ p4 ( myFaceNodes[3] );
     XYZ aVec14( p4 - p1 );
     XYZ cross2 = aVec13.Crossed( aVec14 );
@@ -815,7 +1107,7 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1,
 bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
                                 const int theNode2Index) const
 {
-  if (myVolume->IsPoly()) {
+  if ( myVolume->IsPoly() ) {
     return IsLinked(myVolumeNodes[theNode1Index], myVolumeNodes[theNode2Index]);
   }
 
@@ -853,6 +1145,57 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
     default:;
     }
     break;
+  case 10:
+    {
+      switch ( minInd ) {
+      case 0: if( maxInd==4 ||  maxInd==6 ||  maxInd==7 ) return true;
+      case 1: if( maxInd==4 ||  maxInd==5 ||  maxInd==8 ) return true;
+      case 2: if( maxInd==5 ||  maxInd==6 ||  maxInd==9 ) return true;
+      case 3: if( maxInd==7 ||  maxInd==8 ||  maxInd==9 ) return true;
+      default:;
+      }
+      break;
+    }
+  case 13:
+    {
+      switch ( minInd ) {
+      case 0: if( maxInd==5 ||  maxInd==8 ||  maxInd==9 ) return true;
+      case 1: if( maxInd==5 ||  maxInd==6 ||  maxInd==10 ) return true;
+      case 2: if( maxInd==6 ||  maxInd==7 ||  maxInd==11 ) return true;
+      case 3: if( maxInd==7 ||  maxInd==8 ||  maxInd==12 ) return true;
+      case 4: if( maxInd==9 ||  maxInd==10 ||  maxInd==11 ||  maxInd==12 ) return true;
+      default:;
+      }
+      break;
+    }
+  case 15:
+    {
+      switch ( minInd ) {
+      case 0: if( maxInd==6 ||  maxInd==8 ||  maxInd==12 ) return true;
+      case 1: if( maxInd==6 ||  maxInd==7 ||  maxInd==13 ) return true;
+      case 2: if( maxInd==7 ||  maxInd==8 ||  maxInd==14 ) return true;
+      case 3: if( maxInd==9 ||  maxInd==11 ||  maxInd==12 ) return true;
+      case 4: if( maxInd==9 ||  maxInd==10 ||  maxInd==13 ) return true;
+      case 5: if( maxInd==10 ||  maxInd==11 ||  maxInd==14 ) return true;
+      default:;
+      }
+      break;
+    }
+  case 20:
+    {
+      switch ( minInd ) {
+      case 0: if( maxInd==8 ||  maxInd==11 ||  maxInd==16 ) return true;
+      case 1: if( maxInd==8 ||  maxInd==9 ||  maxInd==17 ) return true;
+      case 2: if( maxInd==9 ||  maxInd==10 ||  maxInd==18 ) return true;
+      case 3: if( maxInd==10 ||  maxInd==11 ||  maxInd==19 ) return true;
+      case 4: if( maxInd==12 ||  maxInd==15 ||  maxInd==16 ) return true;
+      case 5: if( maxInd==12 ||  maxInd==13 ||  maxInd==17 ) return true;
+      case 6: if( maxInd==13 ||  maxInd==14 ||  maxInd==18 ) return true;
+      case 7: if( maxInd==14 ||  maxInd==15 ||  maxInd==19 ) return true;
+      default:;
+      }
+      break;
+    }
   default:;
   }
   return false;
@@ -894,8 +1237,7 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex )
   typedef map< const SMDS_MeshElement*, int > TElemIntMap;
   TElemIntMap volNbShared;
   TElemIntMap::iterator vNbIt;
-  for ( int iNode = 0; iNode < nbFaceNodes; iNode++ )
-  {
+  for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) {
     const SMDS_MeshNode* n = nodes[ iNode ];
     SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator();
     while ( eIt->more() ) {
@@ -903,10 +1245,12 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex )
       if ( elem != myVolume && elem->GetType() == SMDSAbs_Volume ) {
         int nbShared = 1;
         vNbIt = volNbShared.find( elem );
-        if ( vNbIt == volNbShared.end() )
+        if ( vNbIt == volNbShared.end() ) {
           volNbShared.insert ( TElemIntMap::value_type( elem, nbShared ));
-        else
+        }
+        else {
           nbShared = ++(*vNbIt).second;
+        }
         if ( nbShared > maxNbShared )
           maxNbShared = nbShared;
       }
@@ -922,8 +1266,7 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex )
   if ( IsFaceExternal( faceIndex ))
     intNormal = XYZ( -intNormal.x, -intNormal.y, -intNormal.z );
   XYZ p0 ( nodes[0] ), baryCenter;
-  for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ )
-  {
+  for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) {
     int nbShared = (*vNbIt).second;
     if ( nbShared >= 3 ) {
       SMDS_VolumeTool volume( (*vNbIt).first );
@@ -935,20 +1278,20 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex )
     // remove a volume from volNbShared map
     volNbShared.erase( vNbIt );
   }
+
   // here volNbShared contains only volumes laying on the
   // opposite side of the face
-  if ( volNbShared.empty() )
+  if ( volNbShared.empty() ) {
     return free; // is free
+  }
 
   // check if the whole area of a face is shared
   bool isShared[] = { false, false, false, false }; // 4 triangle parts of a quadrangle
-  for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ )
-  {
+  for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) {
     SMDS_VolumeTool volume( (*vNbIt).first );
     bool prevLinkShared = false;
     int nbSharedLinks = 0;
-    for ( int iNode = 0; iNode < nbFaceNodes; iNode++ )
-    {
+    for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) {
       bool linkShared = volume.IsLinked( nodes[ iNode ], nodes[ iNode + 1] );
       if ( linkShared )
         nbSharedLinks++;
@@ -1059,7 +1402,8 @@ bool SMDS_VolumeTool::setFace( int faceIndex )
     }
     myFaceNodes[ myFaceNbNodes ] = myFaceNodes[ 0 ]; // last = first
 
-  } else {
+  }
+  else {
     // choose face node indices
     switch ( myVolumeNbNodes ) {
     case 4:
@@ -1090,6 +1434,34 @@ bool SMDS_VolumeTool::setFace( int faceIndex )
       else
         myFaceNodeIndices = Hexa_F[ faceIndex ];
       break;
+    case 10:
+      myFaceNbNodes = QuadTetra_nbN[ faceIndex ];
+      if ( myExternalFaces )
+        myFaceNodeIndices = myVolForward ? QuadTetra_F[ faceIndex ] : QuadTetra_RE[ faceIndex ];
+      else
+        myFaceNodeIndices = myVolForward ? QuadTetra_F[ faceIndex ] : QuadTetra_R[ faceIndex ];
+      break;
+    case 13:
+      myFaceNbNodes = QuadPyram_nbN[ faceIndex ];
+      if ( myExternalFaces )
+        myFaceNodeIndices = myVolForward ? QuadPyram_F[ faceIndex ] : QuadPyram_RE[ faceIndex ];
+      else
+        myFaceNodeIndices = myVolForward ? QuadPyram_F[ faceIndex ] : QuadPyram_R[ faceIndex ];
+      break;
+    case 15:
+      myFaceNbNodes = QuadPenta_nbN[ faceIndex ];
+      if ( myExternalFaces )
+        myFaceNodeIndices = myVolForward ? QuadPenta_FE[ faceIndex ] : QuadPenta_RE[ faceIndex ];
+      else
+        myFaceNodeIndices = myVolForward ? QuadPenta_F[ faceIndex ] : QuadPenta_R[ faceIndex ];
+      break;
+    case 20:
+      myFaceNbNodes = QuadHexa_nbN[ faceIndex ];
+      if ( myExternalFaces )
+        myFaceNodeIndices = myVolForward ? QuadHexa_FE[ faceIndex ] : QuadHexa_RE[ faceIndex ];
+      else
+        myFaceNodeIndices = QuadHexa_F[ faceIndex ];
+      break;
     default:
       return false;
     }
@@ -1118,6 +1490,10 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetType(int nbNodes)
   case 5: return PYRAM;
   case 6: return PENTA;
   case 8: return HEXA;
+  case 10: return QUAD_TETRA;
+  case 13: return QUAD_PYRAM;
+  case 15: return QUAD_PENTA;
+  case 20: return QUAD_HEXA;
   default:return UNKNOWN;
   }
 }
@@ -1130,10 +1506,14 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetType(int nbNodes)
 int SMDS_VolumeTool::NbFaces( VolumeType type )
 {
   switch ( type ) {
-  case TETRA: return 4;
-  case PYRAM: return 5;
-  case PENTA: return 5;
-  case HEXA : return 6;
+  case TETRA     :
+  case QUAD_TETRA: return 4;
+  case PYRAM     :
+  case QUAD_PYRAM: return 5;
+  case PENTA     :
+  case QUAD_PENTA: return 5;
+  case HEXA      :
+  case QUAD_HEXA : return 6;
   default:    return 0;
   }
 }
@@ -1155,6 +1535,10 @@ const int* SMDS_VolumeTool::GetFaceNodesIndices(VolumeType type,
   case PYRAM: return Pyramid_F[ faceIndex ];
   case PENTA: return external ? Penta_FE[ faceIndex ] : Penta_F[ faceIndex ];
   case HEXA:  return external ? Hexa_FE[ faceIndex ] : Hexa_F[ faceIndex ];
+  case QUAD_TETRA: return QuadTetra_F[ faceIndex ];
+  case QUAD_PYRAM: return QuadPyram_F[ faceIndex ];
+  case QUAD_PENTA: return external ? QuadPenta_FE[ faceIndex ] : QuadPenta_F[ faceIndex ];
+  case QUAD_HEXA:  return external ? QuadHexa_FE[ faceIndex ] : QuadHexa_F[ faceIndex ];
   default:;
   }
   return 0;
@@ -1173,6 +1557,10 @@ int SMDS_VolumeTool::NbFaceNodes(VolumeType type,
   case PYRAM: return Pyramid_nbN[ faceIndex ];
   case PENTA: return Penta_nbN[ faceIndex ];
   case HEXA:  return Hexa_nbN[ faceIndex ];
+  case QUAD_TETRA: return QuadTetra_nbN[ faceIndex ];
+  case QUAD_PYRAM: return QuadPyram_nbN[ faceIndex ];
+  case QUAD_PENTA: return QuadPenta_nbN[ faceIndex ];
+  case QUAD_HEXA:  return QuadHexa_nbN[ faceIndex ];
   default:;
   }
   return 0;
index beec061b700ec62c9c7ca0eb7e8ef48ab8871b12..b5528c10eae7ea082cbc59beb8b1e24578b983b3 100644 (file)
@@ -61,7 +61,8 @@ class SMDS_WNT_EXPORT SMDS_VolumeTool
 {
  public:
 
-  enum VolumeType { UNKNOWN = -1, TETRA = 0, PYRAM, PENTA, HEXA, POLYHEDA };
+  enum VolumeType { UNKNOWN = -1, TETRA = 0, PYRAM, PENTA, HEXA, QUAD_TETRA,
+                    QUAD_PYRAM, QUAD_PENTA, QUAD_HEXA, POLYHEDA };
 
   SMDS_VolumeTool ();
   ~SMDS_VolumeTool ();
index a311488eb6c7c7214d00d69767d63d1903584462..12c077a7dd797490dfdb996e2bd86edc5bccaa0e 100644 (file)
@@ -39,6 +39,7 @@ EXPORT_HEADERS= \
        SMESH_Mesh.hxx \
        SMESH_subMesh.hxx \
        SMESH_Hypothesis.hxx \
+       SMESH_HypoFilter.hxx \
        SMESH_Algo.hxx \
        SMESH_1D_Algo.hxx \
        SMESH_2D_Algo.hxx \
index d1084f7d4f75394c1c6327a1ad61a592a5af81fb..1c9af478a99a642caa94f60e5942c7fb36179f57 100644 (file)
@@ -29,7 +29,7 @@
 using namespace std;
 #include "SMESH_2D_Algo.hxx"
 #include "SMESH_Gen.hxx"
-#include "SMESH_subMesh.hxx"
+#include <TopExp.hxx>
 
 #include "utilities.h"
 
@@ -80,13 +80,14 @@ int SMESH_2D_Algo::NumberOfWires(const TopoDS_Shape& S)
 int SMESH_2D_Algo::NumberOfPoints(SMESH_Mesh& aMesh, const TopoDS_Wire& W)
 {
   int nbPoints = 0;
-  for (TopExp_Explorer exp(W,TopAbs_EDGE); exp.More(); exp.Next())
-    {
-      const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
-      int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
-      //SCRUTE(nb);
-      nbPoints += nb +1; // internal points plus 1 vertex of 2 (last point ?)
-    }
-  //SCRUTE(nbPoints);
+  for (TopExp_Explorer exp(W,TopAbs_EDGE); exp.More(); exp.Next()) {
+    const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
+    int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
+    if(_quadraticMesh)
+      nb = nb/2;
+    nbPoints += nb + 1; // internal points plus 1 vertex of 2 (last point ?)
+  }
   return nbPoints;
 }
+
+
index 5c904e22ef89ea1366a1c566a2f58c2ec647246e..259a51157f2dd7daa9f58ad8b509437c3a724fe7 100644 (file)
@@ -30,7 +30,8 @@
 #define _SMESH_2D_ALGO_HXX_
 
 #include "SMESH_Algo.hxx"
-#include <TopoDS_Wire.hxx>
+#include "SMESH_subMesh.hxx"
+#include "TopoDS_Wire.hxx"
 
 class SMESH_2D_Algo:
   public SMESH_Algo
@@ -41,6 +42,7 @@ public:
 
   int NumberOfWires(const TopoDS_Shape& S);
   int NumberOfPoints(SMESH_Mesh& aMesh,const TopoDS_Wire& W);
+
 };
 
 #endif
index d42680f62e998d457ebb7edff47d49c1b2ac19e0..6a05c16af75349e963213a1cf7d0410bf05f3929 100644 (file)
@@ -29,7 +29,6 @@
 using namespace std;
 #include "SMESH_3D_Algo.hxx"
 #include "SMESH_Gen.hxx"
-#include "SMESH_subMesh.hxx"
 
 #include "utilities.h"
 
@@ -56,3 +55,5 @@ SMESH_3D_Algo::SMESH_3D_Algo(int hypId, int studyId, SMESH_Gen* gen)
 SMESH_3D_Algo::~SMESH_3D_Algo()
 {
 }
+
+
index 62621ce3cf532645b7efa60e9a9279206790451a..21c53ca0f595ad788b87df66302b390d80820a1a 100644 (file)
@@ -37,6 +37,7 @@ class SMESH_3D_Algo:
 public:
   SMESH_3D_Algo(int hypId, int studyId, SMESH_Gen* gen);
   virtual ~SMESH_3D_Algo();
+
 };
 
 #endif
index 3cddc41e743edeaa9329d1ac4508f848e7fb218b..94803ac7c789a9bd2958307678eb571c90fa0f8b 100644 (file)
@@ -69,6 +69,7 @@ SMESH_Algo::SMESH_Algo(int hypId, int studyId,
        gen->_mapAlgo[hypId] = this;
 
         _onlyUnaryInput = _requireDescretBoundary = true;
+        _quadraticMesh = false;
 }
 
 //=============================================================================
@@ -102,18 +103,17 @@ const vector < string > &SMESH_Algo::GetCompatibleHypothesis()
  */
 //=============================================================================
 
-const list <const SMESHDS_Hypothesis *> & SMESH_Algo::GetUsedHypothesis(
-       SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
+const list <const SMESHDS_Hypothesis *> &
+SMESH_Algo::GetUsedHypothesis(SMESH_Mesh &         aMesh,
+                              const TopoDS_Shape & aShape,
+                              const bool           ignoreAuxiliary)
 {
   _usedHypList.clear();
-  if ( !_compatibleHypothesis.empty() )
+  SMESH_HypoFilter filter;
+  if ( InitCompatibleHypoFilter( filter, ignoreAuxiliary ))
   {
-    SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( _compatibleHypothesis[0] ));
-    for ( int i = 1; i < _compatibleHypothesis.size(); ++i )
-      filter.Or( filter.HasName( _compatibleHypothesis[ i ] ));
-
     aMesh.GetHypotheses( aShape, filter, _usedHypList, true );
-    if ( _usedHypList.size() > 1 )
+    if ( ignoreAuxiliary && _usedHypList.size() > 1 )
       _usedHypList.clear();    //only one compatible hypothesis allowed
   }
   return _usedHypList;
@@ -127,18 +127,16 @@ const list <const SMESHDS_Hypothesis *> & SMESH_Algo::GetUsedHypothesis(
  */
 //=============================================================================
 
-const list<const SMESHDS_Hypothesis *> & SMESH_Algo::GetAppliedHypothesis(
-       SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
+const list<const SMESHDS_Hypothesis *> &
+SMESH_Algo::GetAppliedHypothesis(SMESH_Mesh &         aMesh,
+                                 const TopoDS_Shape & aShape,
+                                 const bool           ignoreAuxiliary)
 {
   _appliedHypList.clear();
-  if ( !_compatibleHypothesis.empty() )
-  {
-    SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( _compatibleHypothesis[0] ));
-    for ( int i = 1; i < _compatibleHypothesis.size(); ++i )
-      filter.Or( filter.HasName( _compatibleHypothesis[ i ] ));
-    
+  SMESH_HypoFilter filter;
+  if ( InitCompatibleHypoFilter( filter, ignoreAuxiliary ))
     aMesh.GetHypotheses( aShape, filter, _appliedHypList, false );
-  }
+
   return _appliedHypList;
 }
 
@@ -344,3 +342,28 @@ bool SMESH_Algo::GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh,
 
   return theParams.size() > 1;
 }
+
+//================================================================================
+/*!
+ * \brief Make filter recognize only compatible hypotheses
+ * \param theFilter - the filter to initialize
+ * \param ignoreAuxiliary - make filter ignore compatible auxiliary hypotheses
+ */
+//================================================================================
+
+bool SMESH_Algo::InitCompatibleHypoFilter( SMESH_HypoFilter & theFilter,
+                                           const bool         ignoreAuxiliary) const
+{
+  if ( !_compatibleHypothesis.empty() )
+  {
+    theFilter.Init( theFilter.HasName( _compatibleHypothesis[0] ));
+    for ( int i = 1; i < _compatibleHypothesis.size(); ++i )
+      theFilter.Or( theFilter.HasName( _compatibleHypothesis[ i ] ));
+
+    if ( ignoreAuxiliary )
+      theFilter.AndNot( theFilter.IsAuxiliary() );
+
+    return true;
+  }
+  return false;
+}
index c92b5893fe83a7761436aff3e27df6e941da4715..57bc4245ae620d8f7babd98b4dbff371254e7614 100644 (file)
 
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Edge.hxx>
+#include <gp_XY.hxx>
 
 #include <string>
 #include <vector>
 #include <list>
+#include <map>
 
 class SMESH_Gen;
 class SMESH_Mesh;
+class SMESH_HypoFilter;
 class TopoDS_Face;
 class TopoDS_Shape;
 class SMESHDS_Mesh;
+class SMDS_MeshNode;
 
 class SMESH_Algo:public SMESH_Hypothesis
 {
@@ -58,13 +62,27 @@ class SMESH_Algo:public SMESH_Hypothesis
        virtual bool Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) = 0;
 
        virtual const std::list <const SMESHDS_Hypothesis *> &
-               GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
+               GetUsedHypothesis(SMESH_Mesh &         aMesh,
+                                  const TopoDS_Shape & aShape,
+                                  const bool           ignoreAuxiliary=true);
 
        const list <const SMESHDS_Hypothesis *> &
-               GetAppliedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
+               GetAppliedHypothesis(SMESH_Mesh &         aMesh,
+                                     const TopoDS_Shape & aShape,
+                                     const bool           ignoreAuxiliary=true);
 
        static double EdgeLength(const TopoDS_Edge & E);
 
+
+  /*!
+   * \brief Make filter recognize only compatible hypotheses
+    * \param theFilter - the filter to initialize
+    * \param ignoreAuxiliary - make filter ignore compatible auxiliary hypotheses
+    * \retval bool - true if the algo has compatible hypotheses
+   */
+  bool InitCompatibleHypoFilter( SMESH_HypoFilter & theFilter,
+                                 const bool         ignoreAuxiliary) const;
+
   /*!
    * \brief Fill vector of node parameters on geometrical edge, including vertex nodes
     * \param theMesh - The mesh containing nodes
@@ -121,6 +139,9 @@ class SMESH_Algo:public SMESH_Hypothesis
         std::vector<std::string> _compatibleHypothesis;
         std::list<const SMESHDS_Hypothesis *> _appliedHypList;
         std::list<const SMESHDS_Hypothesis *> _usedHypList;
+
+  // quadratic mesh creation required
+  bool _quadraticMesh;
 };
 
 #endif
index a93b1a4b41b60abe8e628323567f59a9b4a2676d..b615ad5662696d2b7afb1f4e4aace826609d5361 100644 (file)
@@ -633,13 +633,14 @@ SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
   if ( algoList.empty() )
     return NULL;
 
-  if (algoList.size() > 1 ) { // check if there is one algo several times
-    list <const SMESHDS_Hypothesis * >::iterator algo = algoList.begin();
-    for ( ; algo != algoList.end(); ++algo )
-      if ( (*algo) != algoList.front() &&
-           (*algo)->GetName() != algoList.front()->GetName() )
-        return NULL;
-  }
+  // Now it is checked in SMESH_Mesh::GetHypotheses()
+//   if (algoList.size() > 1 ) { // check if there is one algo several times
+//     list <const SMESHDS_Hypothesis * >::iterator algo = algoList.begin();
+//     for ( ; algo != algoList.end(); ++algo )
+//       if ( (*algo) != algoList.front() &&
+//            (*algo)->GetName() != algoList.front()->GetName() )
+//         return NULL;
+//   }
 
   return const_cast<SMESH_Algo*> ( static_cast<const SMESH_Algo* >( algoList.front() ));
 }
index ff14016d8dae8ae62af359d12b7862aaf5b3db77..3482b1d57c8e7de2df565d73a1c3987cbd04108f 100644 (file)
@@ -75,6 +75,17 @@ bool SMESH_HypoFilter::ApplicablePredicate::IsOk(const SMESH_Hypothesis* aHyp,
   return SMESH_subMesh::IsApplicableHypotesis( aHyp, (TopAbs_ShapeEnum)_shapeType );
 };
 
+//=======================================================================
+//function : IsAuxiliaryPredicate::IsOk
+//purpose  : 
+//=======================================================================
+
+bool SMESH_HypoFilter::IsAuxiliaryPredicate::IsOk(const SMESH_Hypothesis* aHyp,
+                                                  const TopoDS_Shape&     /*aShape*/) const
+{
+  return aHyp->IsAuxiliary();
+};
+
 //=======================================================================
 //function : ApplicablePredicate::ApplicablePredicate
 //purpose  : 
@@ -190,6 +201,17 @@ SMESH_HypoPredicate* SMESH_HypoFilter::IsAlgo()
   return new TypePredicate( MORE, SMESHDS_Hypothesis::PARAM_ALGO );
 }
 
+//=======================================================================
+//function : IsAuxiliary
+//purpose  : 
+//=======================================================================
+
+SMESH_HypoPredicate* SMESH_HypoFilter::IsAuxiliary()
+{
+  return new IsAuxiliaryPredicate();
+}
+
+
 //=======================================================================
 //function : IsGlobal
 //purpose  : 
index 6bc34bf5365f1fd994e93f7f389e9998f559e0a2..9638495d136fcb98a218f0067ec5b5cd7c284437 100644 (file)
@@ -67,6 +67,7 @@ class SMESH_HypoFilter: public SMESH_HypoPredicate
 
   // Create predicates
   static SMESH_HypoPredicate* IsAlgo();
+  static SMESH_HypoPredicate* IsAuxiliary();
   static SMESH_HypoPredicate* IsApplicableTo(const TopoDS_Shape& theShape);
   static SMESH_HypoPredicate* IsAssignedTo(const TopoDS_Shape& theShape);
   static SMESH_HypoPredicate* Is(const SMESH_Hypothesis* theHypo);
@@ -158,6 +159,11 @@ class SMESH_HypoFilter: public SMESH_HypoPredicate
               const TopoDS_Shape&     aShape) const;
   };
         
+  struct IsAuxiliaryPredicate : public SMESH_HypoPredicate {
+    bool IsOk(const SMESH_Hypothesis* aHyp,
+              const TopoDS_Shape&     aShape) const;
+  };
+        
 };
 
 
index 0107c3e36dccb22247f68b2cfb0f84ff5f13d238..268581791170f4134cbd12309f7dfe2118f5bb2d 100644 (file)
@@ -72,13 +72,14 @@ SMESH_Hypothesis::~SMESH_Hypothesis()
 
 int SMESH_Hypothesis::GetDim() const
 {
-  int dim = -1;
+  int dim = 0;
   switch (_type)
     {
     case ALGO_1D: dim = 1; break;
     case ALGO_2D: dim = 2; break;
     case ALGO_3D: dim = 3; break;
-    case PARAM_ALGO: dim = _param_algo_dim; break;
+    case PARAM_ALGO:
+      dim = ( _param_algo_dim < 0 ) ? -_param_algo_dim : _param_algo_dim; break;
     }
   return dim;
 }
@@ -124,14 +125,15 @@ void SMESH_Hypothesis::NotifySubMeshesHypothesisModification()
        itm++)
     {
       SMESH_Mesh* mesh = (*itm).second;
-      const list<SMESH_subMesh*>& subMeshes =
-        mesh->GetSubMeshUsingHypothesis(this);
+      mesh->NotifySubMeshesHypothesisModification( this );
+//       const list<SMESH_subMesh*>& subMeshes =
+//      mesh->GetSubMeshUsingHypothesis(this);
 
-      //for all subMeshes using hypothesis
+//       //for all subMeshes using hypothesis
        
-      list<SMESH_subMesh*>::const_iterator its;
-      for (its = subMeshes.begin(); its != subMeshes.end(); its++)
-       (*its)->ComputeStateEngine(SMESH_subMesh::MODIF_HYP);
+//       list<SMESH_subMesh*>::const_iterator its;
+//       for (its = subMeshes.begin(); its != subMeshes.end(); its++)
+//     (*its)->ComputeStateEngine(SMESH_subMesh::MODIF_HYP);
     }
 }
 
index 2ebd25a39163517ed0cdc55306973c8aede15acc..d7a12f9a0be025cdd1b12b350b3962c6ada14e9c 100644 (file)
@@ -57,11 +57,11 @@ public:
 
   SMESH_Hypothesis(int hypId, int studyId, SMESH_Gen* gen);
   virtual ~SMESH_Hypothesis();
-  int GetDim() const;
+  virtual int GetDim() const;
   int GetStudyId() const;
-  void NotifySubMeshesHypothesisModification();
-  int GetShapeType() const;
-  const char* GetLibName() const;
+  virtual void NotifySubMeshesHypothesisModification();
+  virtual int GetShapeType() const;
+  virtual const char* GetLibName() const;
   void  SetLibName(const char* theLibName);
 
   /*!
@@ -72,6 +72,17 @@ public:
    */
   virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape)=0;
 
+  /*!
+   * \brief Return true if me is an auxiliary hypothesis
+    * \retval bool - auxiliary or not
+   * 
+   * An auxiliary hypothesis is optional, i.e. an algorithm
+   * can work without it and another hypothesis of the same
+   * dimention can be assigned to the shape
+   */
+  virtual bool IsAuxiliary() const
+  { return GetType() == PARAM_ALGO && _param_algo_dim <= 0; }
+
 protected:
   SMESH_Gen* _gen;
   int _studyId;
index a8089b04ffa0629083a780a2cfe320ed864cfe4e..cd33d40a357f817cb1759c3550312855e0139f34 100644 (file)
@@ -526,45 +526,62 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape &    aSubS
 //purpose  : 
 //=======================================================================
 
-bool SMESH_Mesh::GetHypotheses(const TopoDS_Shape &                aSubShape,
-                               const SMESH_HypoFilter&             aFilter,
-                               list <const SMESHDS_Hypothesis * >& aHypList,
-                               const bool                          andAncestors) const
+//================================================================================
+/*!
+ * \brief Return hypothesis assigned to the shape
+  * \param aSubShape - the shape to check
+  * \param aFilter - the hypothesis filter
+  * \param aHypList - the list of the found hypotheses
+  * \param andAncestors - flag to check hypos assigned to ancestors of the shape
+  * \retval int - number of unique hypos in aHypList
+ */
+//================================================================================
+
+int SMESH_Mesh::GetHypotheses(const TopoDS_Shape &                aSubShape,
+                              const SMESH_HypoFilter&             aFilter,
+                              list <const SMESHDS_Hypothesis * >& aHypList,
+                              const bool                          andAncestors) const
 {
-  int nbHyp = 0;
+  set<string> hypTypes; // to exclude same type hypos from the result list
+  int nbHyps = 0;
+
+  // fill in hypTypes
+  list<const SMESHDS_Hypothesis*>::const_iterator hyp;
+  for ( hyp = aHypList.begin(); hyp != aHypList.end(); hyp++ )
+    if ( hypTypes.insert( (*hyp)->GetName() ).second )
+      nbHyps++;
+
+  // get hypos from aSubShape
   {
     const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
-    list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
-    for ( ; hyp != hypList.end(); hyp++ )
-      if ( aFilter.IsOk (static_cast<const SMESH_Hypothesis*>( *hyp ), aSubShape)) {
+    for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
+      if ( aFilter.IsOk (static_cast<const SMESH_Hypothesis*>( *hyp ), aSubShape) &&
+           hypTypes.insert( (*hyp)->GetName() ).second )
+      {
         aHypList.push_back( *hyp );
-        nbHyp++;
+        nbHyps++;
       }
   }
-  // get hypos from shape of one type only: if any hypo is found on edge, do
-  // not look up on faces
-  if ( !nbHyp && andAncestors )
+
+  // get hypos from ancestors of aSubShape
+  if ( andAncestors )
   {
     TopTools_MapOfShape map;
     TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape ));
-    int shapeType = it.More() ? it.Value().ShapeType() : TopAbs_SHAPE;
     for (; it.More(); it.Next() )
     {
-      if ( nbHyp && shapeType != it.Value().ShapeType() )
-        break;
-      shapeType = it.Value().ShapeType();
-      if ( !map.Add( it.Value() ))
+     if ( !map.Add( it.Value() ))
         continue;
       const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(it.Value());
-      list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
-      for ( ; hyp != hypList.end(); hyp++ )
-        if (aFilter.IsOk( static_cast<const SMESH_Hypothesis*>( *hyp ), it.Value() )) {
-        aHypList.push_back( *hyp );
-        nbHyp++;
-      }
+      for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
+        if (aFilter.IsOk( static_cast<const SMESH_Hypothesis*>( *hyp ), it.Value() ) &&
+            hypTypes.insert( (*hyp)->GetName() ).second ) {
+          aHypList.push_back( *hyp );
+          nbHyps++;
+        }
     }
   }
-  return nbHyp;
+  return !aHypList.empty();
 }
 
 //=============================================================================
@@ -696,15 +713,17 @@ throw(SALOME_Exception)
 //=======================================================================
 
 bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
-                                  const TopoDS_Shape & aSubShape)
+                                  const SMESH_subMesh* aSubMesh)
 {
   SMESH_Hypothesis* hyp = static_cast<SMESH_Hypothesis*>(anHyp);
-  // check if anHyp is applicable to aSubShape
-  SMESH_subMesh * subMesh = GetSubMeshContaining( aSubShape );
-  if ( !subMesh || !subMesh->IsApplicableHypotesis( hyp ))
+
+  // check if anHyp can be used to mesh aSubMesh
+  if ( !aSubMesh || !aSubMesh->IsApplicableHypotesis( hyp ))
     return false;
 
-  SMESH_Algo *algo = _gen->GetAlgo(*this, aSubShape);
+  const TopoDS_Shape & aSubShape = const_cast<SMESH_subMesh*>( aSubMesh )->GetSubShape();
+
+  SMESH_Algo *algo = _gen->GetAlgo(*this, aSubShape );
 
   // algorithm
   if (anHyp->GetType() > SMESHDS_Hypothesis::PARAM_ALGO)
@@ -714,17 +733,19 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
   if (algo)
   {
     // look trough hypotheses used by algo
-    const list <const SMESHDS_Hypothesis * >&usedHyps =
-      algo->GetUsedHypothesis(*this, aSubShape);
-    return ( find( usedHyps.begin(), usedHyps.end(), anHyp ) != usedHyps.end() );
+    SMESH_HypoFilter hypoKind;
+    if ( algo->InitCompatibleHypoFilter( hypoKind, !hyp->IsAuxiliary() )) {
+      list <const SMESHDS_Hypothesis * > usedHyps;
+      if ( GetHypotheses( aSubShape, hypoKind, usedHyps, true ))
+        return ( find( usedHyps.begin(), usedHyps.end(), anHyp ) != usedHyps.end() );
+    }
   }
 
   // look through all assigned hypotheses
-  SMESH_HypoFilter filter( SMESH_HypoFilter::Is( hyp ));
-  return GetHypothesis( aSubShape, filter, true );
+  //SMESH_HypoFilter filter( SMESH_HypoFilter::Is( hyp ));
+  return false; //GetHypothesis( aSubShape, filter, true );
 }
 
-
 //=============================================================================
 /*!
  *
@@ -732,20 +753,78 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
 //=============================================================================
 
 const list < SMESH_subMesh * >&
-       SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp)
-throw(SALOME_Exception)
+SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp)
+  throw(SALOME_Exception)
+{
+  Unexpect aCatch(SalomeException);
+  if(MYDEBUG) MESSAGE("SMESH_Mesh::GetSubMeshUsingHypothesis");
+  map < int, SMESH_subMesh * >::iterator itsm;
+  _subMeshesUsingHypothesisList.clear();
+  for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
+  {
+    SMESH_subMesh *aSubMesh = (*itsm).second;
+    if ( IsUsedHypothesis ( anHyp, aSubMesh ))
+      _subMeshesUsingHypothesisList.push_back(aSubMesh);
+  }
+  return _subMeshesUsingHypothesisList;
+}
+
+//=======================================================================
+//function : NotifySubMeshesHypothesisModification
+//purpose  : Say all submeshes using theChangedHyp that it has been modified
+//=======================================================================
+
+void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* theChangedHyp)
 {
   Unexpect aCatch(SalomeException);
-       if(MYDEBUG) MESSAGE("SMESH_Mesh::GetSubMeshUsingHypothesis");
-       map < int, SMESH_subMesh * >::iterator itsm;
-       _subMeshesUsingHypothesisList.clear();
-       for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
-       {
-               SMESH_subMesh *aSubMesh = (*itsm).second;
-               if ( IsUsedHypothesis ( anHyp, aSubMesh->GetSubShape() ))
-                       _subMeshesUsingHypothesisList.push_back(aSubMesh);
-       }
-       return _subMeshesUsingHypothesisList;
+
+  const SMESH_Hypothesis* hyp = static_cast<const SMESH_Hypothesis*>(theChangedHyp);
+
+  const SMESH_Algo *foundAlgo = 0;
+  SMESH_HypoFilter algoKind( SMESH_HypoFilter::IsAlgo() );
+  SMESH_HypoFilter compatibleHypoKind;
+  list <const SMESHDS_Hypothesis * > usedHyps;
+
+
+  map < int, SMESH_subMesh * >::iterator itsm;
+  for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
+  {
+    SMESH_subMesh *aSubMesh = (*itsm).second;
+    if ( aSubMesh->IsApplicableHypotesis( hyp ))
+    {
+      const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
+
+      if ( !foundAlgo ) // init filter for algo search
+        algoKind.And( algoKind.IsApplicableTo( aSubShape ));
+      
+      const SMESH_Algo *algo = static_cast<const SMESH_Algo*>
+        ( GetHypothesis( aSubShape, algoKind, true ));
+
+      if ( algo )
+      {
+        bool sameAlgo = ( algo == foundAlgo );
+        if ( !sameAlgo && foundAlgo )
+          sameAlgo = ( strcmp( algo->GetName(), foundAlgo->GetName() ) == 0);
+
+        if ( !sameAlgo ) { // init filter for used hypos search
+          if ( !algo->InitCompatibleHypoFilter( compatibleHypoKind, !hyp->IsAuxiliary() ))
+            continue; // algo does not use any hypothesis
+          foundAlgo = algo;
+        }
+
+        // check if hyp is used by algo
+        usedHyps.clear();
+        if ( GetHypotheses( aSubShape, compatibleHypoKind, usedHyps, true ) &&
+             find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() )
+        {
+          aSubMesh->ComputeStateEngine(SMESH_subMesh::MODIF_HYP);
+
+          if ( algo->GetDim() == 1 && IsPropagationHypothesis( aSubShape ))
+            CleanMeshOnPropagationChain( aSubShape );
+        }
+      }
+    }
+  }
 }
 
 //=============================================================================
@@ -895,7 +974,8 @@ int SMESH_Mesh::NbTriangles() throw(SALOME_Exception)
   const SMDS_MeshFace * curFace;
   while (itFaces->more()) {
     curFace = itFaces->next();
-    if (!curFace->IsPoly() && curFace->NbNodes() == 3) Nb++;
+    if ( !curFace->IsPoly() && 
+        ( curFace->NbNodes()==3 || curFace->NbNodes()==6 ) ) Nb++;
   }
   return Nb;
 }
@@ -913,7 +993,8 @@ int SMESH_Mesh::NbQuadrangles() throw(SALOME_Exception)
   const SMDS_MeshFace * curFace;
   while (itFaces->more()) {
     curFace = itFaces->next();
-    if (!curFace->IsPoly() && curFace->NbNodes() == 4) Nb++;
+    if ( !curFace->IsPoly() && 
+        ( curFace->NbNodes() == 4 || curFace->NbNodes()==8 ) ) Nb++;
   }
   return Nb;
 }
@@ -951,7 +1032,8 @@ int SMESH_Mesh::NbTetras() throw(SALOME_Exception)
   const SMDS_MeshVolume * curVolume;
   while (itVolumes->more()) {
     curVolume = itVolumes->next();
-    if (!curVolume->IsPoly() && curVolume->NbNodes() == 4) Nb++;
+    if ( !curVolume->IsPoly() && 
+        ( curVolume->NbNodes() == 4 || curVolume->NbNodes()==10 ) ) Nb++;
   }
   return Nb;
 }
@@ -965,7 +1047,8 @@ int SMESH_Mesh::NbHexas() throw(SALOME_Exception)
   const SMDS_MeshVolume * curVolume;
   while (itVolumes->more()) {
     curVolume = itVolumes->next();
-    if (!curVolume->IsPoly() && curVolume->NbNodes() == 8) Nb++;
+    if ( !curVolume->IsPoly() && 
+        ( curVolume->NbNodes() == 8 || curVolume->NbNodes()==20 ) ) Nb++;
   }
   return Nb;
 }
@@ -979,7 +1062,8 @@ int SMESH_Mesh::NbPyramids() throw(SALOME_Exception)
   const SMDS_MeshVolume * curVolume;
   while (itVolumes->more()) {
     curVolume = itVolumes->next();
-    if (!curVolume->IsPoly() && curVolume->NbNodes() == 5) Nb++;
+    if ( !curVolume->IsPoly() && 
+        ( curVolume->NbNodes() == 5 || curVolume->NbNodes()==13 ) ) Nb++;
   }
   return Nb;
 }
@@ -993,7 +1077,8 @@ int SMESH_Mesh::NbPrisms() throw(SALOME_Exception)
   const SMDS_MeshVolume * curVolume;
   while (itVolumes->more()) {
     curVolume = itVolumes->next();
-    if (!curVolume->IsPoly() && curVolume->NbNodes() == 6) Nb++;
+    if ( !curVolume->IsPoly() && 
+        ( curVolume->NbNodes() == 6 || curVolume->NbNodes()==15 ) ) Nb++;
   }
   return Nb;
 }
index 5d4e16bae60ff66796cadff98349ec60ddfbd7de..27d2a182b3898bd46f3f3a56707a6ab7cbc46b4b 100644 (file)
@@ -110,10 +110,10 @@ public:
                                          const SMESH_HypoFilter& aFilter,
                                          const bool              andAncestors) const;
   
-  bool GetHypotheses(const TopoDS_Shape &                aSubShape,
-                     const SMESH_HypoFilter&             aFilter,
-                     list <const SMESHDS_Hypothesis * >& aHypList,
-                     const bool                          andAncestors) const;
+  int GetHypotheses(const TopoDS_Shape &                aSubShape,
+                    const SMESH_HypoFilter&             aFilter,
+                    list <const SMESHDS_Hypothesis * >& aHypList,
+                    const bool                          andAncestors) const;
 
   const list<SMESHDS_Command*> & GetLog() throw(SALOME_Exception);
   
@@ -134,12 +134,15 @@ public:
   SMESH_subMesh *GetSubMeshContaining(const int aShapeID)
     throw(SALOME_Exception);
   
+  void NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* theChangedHyp);
+  // Say all submeshes that theChangedHyp has been modified
+
   const list < SMESH_subMesh * >&
   GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp)
     throw(SALOME_Exception);
   
-  bool IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
-                       const TopoDS_Shape & aSubShape);
+  bool IsUsedHypothesis(SMESHDS_Hypothesis *  anHyp,
+                       const SMESH_subMesh * aSubMesh);
   // Return True if anHyp is used to mesh aSubShape
   
   bool IsNotConformAllowed() const;
index d75adf3e730c4426cf38fd9617b9c7c2dc2cc0a3..ea1334bfb7c68831b43253e6f860e70a3db81623 100644 (file)
@@ -34,6 +34,7 @@
 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
 #include "SMDS_FacePosition.hxx"
 #include "SMDS_SpacePosition.hxx"
+#include "SMDS_QuadraticFaceOfNodes.hxx"
 
 #include "SMESHDS_Group.hxx"
 #include "SMESHDS_Mesh.hxx"
@@ -75,8 +76,12 @@ typedef map<const SMDS_MeshElement*, list<const SMDS_MeshNode*> >    TElemOfNode
 typedef map<const SMDS_MeshElement*, list<const SMDS_MeshElement*> > TElemOfElemListMap;
 typedef map<const SMDS_MeshNode*, list<const SMDS_MeshNode*> >       TNodeOfNodeListMap;
 typedef TNodeOfNodeListMap::iterator                                 TNodeOfNodeListMapItr;
+//typedef map<const SMDS_MeshNode*, vector<const SMDS_MeshNode*> >     TNodeOfNodeVecMap;
+//typedef TNodeOfNodeVecMap::iterator                                  TNodeOfNodeVecMapItr;
 typedef map<const SMDS_MeshElement*, vector<TNodeOfNodeListMapItr> > TElemOfVecOfNnlmiMap;
+//typedef map<const SMDS_MeshElement*, vector<TNodeOfNodeVecMapItr> >  TElemOfVecOfMapNodesMap;
 
+typedef pair<const SMDS_MeshNode*, const SMDS_MeshNode*> NLink;
 
 //=======================================================================
 //function : SMESH_MeshEditor
@@ -102,8 +107,7 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs,
   set< SMESH_subMesh *> smmap;
 
   list<int>::const_iterator it = theIDs.begin();
-  for ( ; it != theIDs.end(); it++ )
-  {
+  for ( ; it != theIDs.end(); it++ ) {
     const SMDS_MeshElement * elem;
     if ( isNodes )
       elem = aMesh->FindNode( *it );
@@ -114,8 +118,7 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs,
 
     // Find sub-meshes to notify about modification
     SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
-    while ( nodeIt->more() )
-    {
+    while ( nodeIt->more() ) {
       const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
       const SMDS_PositionPtr& aPosition = node->GetPosition();
       if ( aPosition.get() ) {
@@ -142,6 +145,7 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs,
     for ( smIt = smmap.begin(); smIt != smmap.end(); smIt++ )
       (*smIt)->ComputeStateEngine( SMESH_subMesh::MESH_ENTITY_REMOVED );
   }
+
   return true;
 }
 
@@ -157,8 +161,7 @@ int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem)
   if ( aMesh->ShapeToMesh().IsNull() )
     return 0;
 
-  if ( theElem->GetType() == SMDSAbs_Node )
-  {
+  if ( theElem->GetType() == SMDSAbs_Node ) {
     const SMDS_PositionPtr& aPosition =
       static_cast<const SMDS_MeshNode*>( theElem )->GetPosition();
     if ( aPosition.get() )
@@ -169,25 +172,22 @@ int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem)
 
   TopoDS_Shape aShape; // the shape a node is on
   SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator();
-  while ( nodeIt->more() )
-  {
+  while ( nodeIt->more() ) {
     const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
     const SMDS_PositionPtr& aPosition = node->GetPosition();
     if ( aPosition.get() ) {
-        int aShapeID = aPosition->GetShapeId();
-        SMESHDS_SubMesh * sm = aMesh->MeshElements( aShapeID );
-        if ( sm )
-        {
-          if ( sm->Contains( theElem ))
-            return aShapeID;
-          if ( aShape.IsNull() )
-            aShape = aMesh->IndexToShape( aShapeID );
-        }
-        else
-        {
-          //MESSAGE ( "::FindShape() No SubShape for aShapeID " << aShapeID );
-        }
+      int aShapeID = aPosition->GetShapeId();
+      SMESHDS_SubMesh * sm = aMesh->MeshElements( aShapeID );
+      if ( sm ) {
+        if ( sm->Contains( theElem ))
+          return aShapeID;
+        if ( aShape.IsNull() )
+          aShape = aMesh->IndexToShape( aShapeID );
+      }
+      else {
+        //MESSAGE ( "::FindShape() No SubShape for aShapeID " << aShapeID );
       }
+    }
   }
 
   // None of nodes is on a proper shape,
@@ -197,17 +197,89 @@ int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem)
     return 0;
   }
   TopTools_ListIteratorOfListOfShape ancIt( GetMesh()->GetAncestors( aShape ));
-  for ( ; ancIt.More(); ancIt.Next() )
-  {
-      SMESHDS_SubMesh * sm = aMesh->MeshElements( ancIt.Value() );
-      if ( sm && sm->Contains( theElem ))
-        return aMesh->ShapeToIndex( ancIt.Value() );
+  for ( ; ancIt.More(); ancIt.Next() ) {
+    SMESHDS_SubMesh * sm = aMesh->MeshElements( ancIt.Value() );
+    if ( sm && sm->Contains( theElem ))
+      return aMesh->ShapeToIndex( ancIt.Value() );
   }
 
   //MESSAGE ("::FindShape() - SHAPE NOT FOUND")
   return 0;
 }
 
+//=======================================================================
+//function : ShiftNodesQuadTria
+//purpose  : auxilary
+//           Shift nodes in the array corresponded to quadratic triangle
+//           example: (0,1,2,3,4,5) -> (1,2,0,4,5,3)
+//=======================================================================
+static void ShiftNodesQuadTria(const SMDS_MeshNode* aNodes[])
+{
+  const SMDS_MeshNode* nd1 = aNodes[0];
+  aNodes[0] = aNodes[1];
+  aNodes[1] = aNodes[2];
+  aNodes[2] = nd1;
+  const SMDS_MeshNode* nd2 = aNodes[3];
+  aNodes[3] = aNodes[4];
+  aNodes[4] = aNodes[5];
+  aNodes[5] = nd2;
+}
+
+//=======================================================================
+//function : GetNodesFromTwoTria
+//purpose  : auxilary
+//           Shift nodes in the array corresponded to quadratic triangle
+//           example: (0,1,2,3,4,5) -> (1,2,0,4,5,3)
+//=======================================================================
+static bool GetNodesFromTwoTria(const SMDS_MeshElement * theTria1,
+                                const SMDS_MeshElement * theTria2,
+                                const SMDS_MeshNode* N1[],
+                                const SMDS_MeshNode* N2[])
+{
+  SMDS_ElemIteratorPtr it = theTria1->nodesIterator();
+  int i=0;
+  while(i<6) {
+    N1[i] = static_cast<const SMDS_MeshNode*>( it->next() );
+    i++;
+  }
+  if(it->more()) return false;
+  it = theTria2->nodesIterator();
+  i=0;
+  while(i<6) {
+    N2[i] = static_cast<const SMDS_MeshNode*>( it->next() );
+    i++;
+  }
+  if(it->more()) return false;
+
+  int sames[3] = {-1,-1,-1};
+  int nbsames = 0;
+  int j;
+  for(i=0; i<3; i++) {
+    for(j=0; j<3; j++) {
+      if(N1[i]==N2[j]) {
+        sames[i] = j;
+        nbsames++;
+        break;
+      }
+    }
+  }
+  if(nbsames!=2) return false;
+  if(sames[0]>-1) {
+    ShiftNodesQuadTria(N1);
+    if(sames[1]>-1) {
+      ShiftNodesQuadTria(N1);
+    }
+  }
+  i = sames[0] + sames[1] + sames[2];
+  for(; i<2; i++) {
+    ShiftNodesQuadTria(N2);
+  }
+  // now we receive following N1 and N2 (using numeration as above image)
+  // tria1 : (1 2 4 5 9 7)  and  tria2 : (3 4 2 8 9 6) 
+  // i.e. first nodes from both arrays determ new diagonal
+  return true;
+}
+
 //=======================================================================
 //function : InverseDiag
 //purpose  : Replace two neighbour triangles with ones built on the same 4 nodes
@@ -220,71 +292,116 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1,
 {
   if (!theTria1 || !theTria2)
     return false;
+
   const SMDS_FaceOfNodes* F1 = dynamic_cast<const SMDS_FaceOfNodes*>( theTria1 );
-  if (!F1) return false;
   const SMDS_FaceOfNodes* F2 = dynamic_cast<const SMDS_FaceOfNodes*>( theTria2 );
-  if (!F2) return false;
+  if (F1 && F2) {
 
-  //  1 +--+ A  theTria1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A
-  //    | /|    theTria2: ( B A 2 ) B->1 ( 1 A 2 )   |\ |
-  //    |/ |                                         | \|
-  //  B +--+ 2                                     B +--+ 2
+    //  1 +--+ A  theTria1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A
+    //    | /|    theTria2: ( B A 2 ) B->1 ( 1 A 2 )   |\ |
+    //    |/ |                                         | \|
+    //  B +--+ 2                                     B +--+ 2
 
-  // put nodes in array and find out indices of the same ones
-  const SMDS_MeshNode* aNodes [6];
-  int sameInd [] = { 0, 0, 0, 0, 0, 0 };
-  int i = 0;
-  SMDS_ElemIteratorPtr it = theTria1->nodesIterator();
-  while ( it->more() )
-  {
-    aNodes[ i ] = static_cast<const SMDS_MeshNode*>( it->next() );
-
-    if ( i > 2 ) // theTria2
-      // find same node of theTria1
-      for ( int j = 0; j < 3; j++ )
-        if ( aNodes[ i ] == aNodes[ j ]) {
-          sameInd[ j ] = i;
-          sameInd[ i ] = j;
-          break;
-        }
-    // next
-    i++;
-    if ( i == 3 ) {
-      if ( it->more() )
-        return false; // theTria1 is not a triangle
-      it = theTria2->nodesIterator();
+    // put nodes in array and find out indices of the same ones
+    const SMDS_MeshNode* aNodes [6];
+    int sameInd [] = { 0, 0, 0, 0, 0, 0 };
+    int i = 0;
+    SMDS_ElemIteratorPtr it = theTria1->nodesIterator();
+    while ( it->more() ) {
+      aNodes[ i ] = static_cast<const SMDS_MeshNode*>( it->next() );
+      
+      if ( i > 2 ) // theTria2
+        // find same node of theTria1
+        for ( int j = 0; j < 3; j++ )
+          if ( aNodes[ i ] == aNodes[ j ]) {
+            sameInd[ j ] = i;
+            sameInd[ i ] = j;
+            break;
+          }
+      // next
+      i++;
+      if ( i == 3 ) {
+        if ( it->more() )
+          return false; // theTria1 is not a triangle
+        it = theTria2->nodesIterator();
+      }
+      if ( i == 6 && it->more() )
+        return false; // theTria2 is not a triangle
     }
-    if ( i == 6 && it->more() )
-      return false; // theTria2 is not a triangle
-  }
+    
+    // find indices of 1,2 and of A,B in theTria1
+    int iA = 0, iB = 0, i1 = 0, i2 = 0;
+    for ( i = 0; i < 6; i++ ) {
+      if ( sameInd [ i ] == 0 )
+        if ( i < 3 ) i1 = i;
+        else         i2 = i;
+      else if (i < 3)
+        if ( iA ) iB = i;
+        else      iA = i;
+    }
+    // nodes 1 and 2 should not be the same
+    if ( aNodes[ i1 ] == aNodes[ i2 ] )
+      return false;
+
+    // theTria1: A->2
+    aNodes[ iA ] = aNodes[ i2 ];
+    // theTria2: B->1
+    aNodes[ sameInd[ iB ]] = aNodes[ i1 ];
+
+    //MESSAGE( theTria1 << theTria2 );
+    
+    GetMeshDS()->ChangeElementNodes( theTria1, aNodes, 3 );
+    GetMeshDS()->ChangeElementNodes( theTria2, &aNodes[ 3 ], 3 );
+    
+    //MESSAGE( theTria1 << theTria2 );
 
-  // find indices of 1,2 and of A,B in theTria1
-  int iA = 0, iB = 0, i1 = 0, i2 = 0;
-  for ( i = 0; i < 6; i++ )
-  {
-    if ( sameInd [ i ] == 0 )
-      if ( i < 3 ) i1 = i;
-      else         i2 = i;
-    else if (i < 3)
-      if ( iA ) iB = i;
-      else      iA = i;
-  }
-  // nodes 1 and 2 should not be the same
-  if ( aNodes[ i1 ] == aNodes[ i2 ] )
+    return true;
+  
+  } // end if(F1 && F2)
+
+  // check case of quadratic faces
+  const SMDS_QuadraticFaceOfNodes* QF1 =
+    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (theTria1);
+  if(!QF1) return false;
+  const SMDS_QuadraticFaceOfNodes* QF2 =
+    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (theTria2);
+  if(!QF2) return false;
+
+  //       5
+  //  1 +--+--+ 2  theTria1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9)
+  //    |    /|    theTria2: (2 3 4 6 8 9) or (3 4 2 8 9 6) or (4 2 3 9 6 8)
+  //    |   / |  
+  //  7 +  +  + 6
+  //    | /9  |
+  //    |/    |
+  //  4 +--+--+ 3  
+  //       8
+  
+  const SMDS_MeshNode* N1 [6];
+  const SMDS_MeshNode* N2 [6];
+  if(!GetNodesFromTwoTria(theTria1,theTria2,N1,N2))
     return false;
-
-
-  // theTria1: A->2
-  aNodes[ iA ] = aNodes[ i2 ];
-  // theTria2: B->1
-  aNodes[ sameInd[ iB ]] = aNodes[ i1 ];
-
-  //MESSAGE( theTria1 << theTria2 );
-
-  GetMeshDS()->ChangeElementNodes( theTria1, aNodes, 3 );
-  GetMeshDS()->ChangeElementNodes( theTria2, &aNodes[ 3 ], 3 );
-
-  //MESSAGE( theTria1 << theTria2 );
+  // now we receive following N1 and N2 (using numeration as above image)
+  // tria1 : (1 2 4 5 9 7)  and  tria2 : (3 4 2 8 9 6) 
+  // i.e. first nodes from both arrays determ new diagonal
+
+  const SMDS_MeshNode* N1new [6];
+  const SMDS_MeshNode* N2new [6];
+  N1new[0] = N1[0];
+  N1new[1] = N2[0];
+  N1new[2] = N2[1];
+  N1new[3] = N1[4];
+  N1new[4] = N2[3];
+  N1new[5] = N1[5];
+  N2new[0] = N1[0];
+  N2new[1] = N1[1];
+  N2new[2] = N2[0];
+  N2new[3] = N1[3];
+  N2new[4] = N2[5];
+  N2new[5] = N1[4];
+  // replaces nodes in faces
+  GetMeshDS()->ChangeElementNodes( theTria1, N1new, 6 );
+  GetMeshDS()->ChangeElementNodes( theTria2, N2new, 6 );
 
   return true;
 }
@@ -318,7 +435,8 @@ static bool findTriangles(const SMDS_MeshNode *    theNode1,
       if ( theTria1 ) {
         theTria2 = elem;
         break;
-      } else {
+      }
+      else {
         theTria1 = elem;
       }
   }
@@ -342,55 +460,65 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1,
     return false;
 
   const SMDS_FaceOfNodes* F1 = dynamic_cast<const SMDS_FaceOfNodes*>( tr1 );
-  if (!F1) return false;
+  //if (!F1) return false;
   const SMDS_FaceOfNodes* F2 = dynamic_cast<const SMDS_FaceOfNodes*>( tr2 );
-  if (!F2) return false;
-
-  //  1 +--+ A  tr1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A
-  //    | /|    tr2: ( B A 2 ) B->1 ( 1 A 2 )   |\ |
-  //    |/ |                                    | \|
-  //  B +--+ 2                                B +--+ 2
-
-  // put nodes in array
-  // and find indices of 1,2 and of A in tr1 and of B in tr2
-  int i, iA1 = 0, i1 = 0;
-  const SMDS_MeshNode* aNodes1 [3];
-  SMDS_ElemIteratorPtr it;
-  for (i = 0, it = tr1->nodesIterator(); it->more(); i++ ) {
-    aNodes1[ i ] = static_cast<const SMDS_MeshNode*>( it->next() );
-    if ( aNodes1[ i ] == theNode1 )
-      iA1 = i; // node A in tr1
-    else if ( aNodes1[ i ] != theNode2 )
-      i1 = i;  // node 1
-  }
-  int iB2 = 0, i2 = 0;
-  const SMDS_MeshNode* aNodes2 [3];
-  for (i = 0, it = tr2->nodesIterator(); it->more(); i++ ) {
-    aNodes2[ i ] = static_cast<const SMDS_MeshNode*>( it->next() );
-    if ( aNodes2[ i ] == theNode2 )
-      iB2 = i; // node B in tr2
-    else if ( aNodes2[ i ] != theNode1 )
-      i2 = i;  // node 2
-  }
-
-  // nodes 1 and 2 should not be the same
-  if ( aNodes1[ i1 ] == aNodes2[ i2 ] )
-    return false;
-
-  // tr1: A->2
-  aNodes1[ iA1 ] = aNodes2[ i2 ];
-  // tr2: B->1
-  aNodes2[ iB2 ] = aNodes1[ i1 ];
+  //if (!F2) return false;
+  if (F1 && F2) {
+
+    //  1 +--+ A  tr1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A
+    //    | /|    tr2: ( B A 2 ) B->1 ( 1 A 2 )   |\ |
+    //    |/ |                                    | \|
+    //  B +--+ 2                                B +--+ 2
+
+    // put nodes in array
+    // and find indices of 1,2 and of A in tr1 and of B in tr2
+    int i, iA1 = 0, i1 = 0;
+    const SMDS_MeshNode* aNodes1 [3];
+    SMDS_ElemIteratorPtr it;
+    for (i = 0, it = tr1->nodesIterator(); it->more(); i++ ) {
+      aNodes1[ i ] = static_cast<const SMDS_MeshNode*>( it->next() );
+      if ( aNodes1[ i ] == theNode1 )
+        iA1 = i; // node A in tr1
+      else if ( aNodes1[ i ] != theNode2 )
+        i1 = i;  // node 1
+    }
+    int iB2 = 0, i2 = 0;
+    const SMDS_MeshNode* aNodes2 [3];
+    for (i = 0, it = tr2->nodesIterator(); it->more(); i++ ) {
+      aNodes2[ i ] = static_cast<const SMDS_MeshNode*>( it->next() );
+      if ( aNodes2[ i ] == theNode2 )
+        iB2 = i; // node B in tr2
+      else if ( aNodes2[ i ] != theNode1 )
+        i2 = i;  // node 2
+    }
+    
+    // nodes 1 and 2 should not be the same
+    if ( aNodes1[ i1 ] == aNodes2[ i2 ] )
+      return false;
 
-  //MESSAGE( tr1 << tr2 );
+    // tr1: A->2
+    aNodes1[ iA1 ] = aNodes2[ i2 ];
+    // tr2: B->1
+    aNodes2[ iB2 ] = aNodes1[ i1 ];
 
-  GetMeshDS()->ChangeElementNodes( tr1, aNodes1, 3 );
-  GetMeshDS()->ChangeElementNodes( tr2, aNodes2, 3 );
+    //MESSAGE( tr1 << tr2 );
 
-  //MESSAGE( tr1 << tr2 );
+    GetMeshDS()->ChangeElementNodes( tr1, aNodes1, 3 );
+    GetMeshDS()->ChangeElementNodes( tr2, aNodes2, 3 );
 
-  return true;
+    //MESSAGE( tr1 << tr2 );
+    
+    return true;
+  }
 
+  // check case of quadratic faces
+  const SMDS_QuadraticFaceOfNodes* QF1 =
+    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr1);
+  if(!QF1) return false;
+  const SMDS_QuadraticFaceOfNodes* QF2 =
+    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr2);
+  if(!QF2) return false;
+  return InverseDiag(tr1,tr2);
 }
 
 //=======================================================================
@@ -406,12 +534,16 @@ bool getQuadrangleNodes(const SMDS_MeshNode *    theQuadNodes [],
                         const SMDS_MeshElement * tr1,
                         const SMDS_MeshElement * tr2 )
 {
+  if( tr1->NbNodes() != tr2->NbNodes() )
+    return false;
   // find the 4-th node to insert into tr1
   const SMDS_MeshNode* n4 = 0;
   SMDS_ElemIteratorPtr it = tr2->nodesIterator();
-  while ( !n4 && it->more() )
-  {
+  int i=0;
+  //while ( !n4 && it->more() ) {
+  while ( !n4 && i<3 ) {
     const SMDS_MeshNode * n = static_cast<const SMDS_MeshNode*>( it->next() );
+    i++;
     bool isDiag = ( n == theNode1 || n == theNode2 );
     if ( !isDiag )
       n4 = n;
@@ -419,19 +551,19 @@ bool getQuadrangleNodes(const SMDS_MeshNode *    theQuadNodes [],
   // Make an array of nodes to be in a quadrangle
   int iNode = 0, iFirstDiag = -1;
   it = tr1->nodesIterator();
-  while ( it->more() )
-  {
+  i=0;
+  //while ( it->more() ) {
+  while ( i<3 ) {
     const SMDS_MeshNode * n = static_cast<const SMDS_MeshNode*>( it->next() );
+    i++;
     bool isDiag = ( n == theNode1 || n == theNode2 );
-    if ( isDiag )
-    {
+    if ( isDiag ) {
       if ( iFirstDiag < 0 )
         iFirstDiag = iNode;
       else if ( iNode - iFirstDiag == 1 )
         theQuadNodes[ iNode++ ] = n4; // insert the 4-th node between diagonal nodes
     }
-    else if ( n == n4 )
-    {
+    else if ( n == n4 ) {
       return false; // tr1 and tr2 should not have all the same nodes
     }
     theQuadNodes[ iNode++ ] = n;
@@ -459,20 +591,66 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1,
     return false;
 
   const SMDS_FaceOfNodes* F1 = dynamic_cast<const SMDS_FaceOfNodes*>( tr1 );
-  if (!F1) return false;
+  //if (!F1) return false;
   const SMDS_FaceOfNodes* F2 = dynamic_cast<const SMDS_FaceOfNodes*>( tr2 );
-  if (!F2) return false;
+  //if (!F2) return false;
+  if (F1 && F2) {
 
-  const SMDS_MeshNode* aNodes [ 4 ];
-  if ( ! getQuadrangleNodes( aNodes, theNode1, theNode2, tr1, tr2 ))
-    return false;
+    const SMDS_MeshNode* aNodes [ 4 ];
+    if ( ! getQuadrangleNodes( aNodes, theNode1, theNode2, tr1, tr2 ))
+      return false;
+
+    //MESSAGE( endl << tr1 << tr2 );
+
+    GetMeshDS()->ChangeElementNodes( tr1, aNodes, 4 );
+    GetMeshDS()->RemoveElement( tr2 );
 
-  //MESSAGE( endl << tr1 << tr2 );
+    //MESSAGE( endl << tr1 );
 
-  GetMeshDS()->ChangeElementNodes( tr1, aNodes, 4 );
+    return true;
+  }
+
+  // check case of quadratic faces
+  const SMDS_QuadraticFaceOfNodes* QF1 =
+    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr1);
+  if(!QF1) return false;
+  const SMDS_QuadraticFaceOfNodes* QF2 =
+    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr2);
+  if(!QF2) return false;
+
+  //       5
+  //  1 +--+--+ 2  tr1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9)
+  //    |    /|    tr2: (2 3 4 6 8 9) or (3 4 2 8 9 6) or (4 2 3 9 6 8)
+  //    |   / |  
+  //  7 +  +  + 6
+  //    | /9  |
+  //    |/    |
+  //  4 +--+--+ 3  
+  //       8
+  
+  const SMDS_MeshNode* N1 [6];
+  const SMDS_MeshNode* N2 [6];
+  if(!GetNodesFromTwoTria(tr1,tr2,N1,N2))
+    return false;
+  // now we receive following N1 and N2 (using numeration as above image)
+  // tria1 : (1 2 4 5 9 7)  and  tria2 : (3 4 2 8 9 6) 
+  // i.e. first nodes from both arrays determ new diagonal
+
+  const SMDS_MeshNode* aNodes[8];
+  aNodes[0] = N1[0];
+  aNodes[1] = N1[1];
+  aNodes[2] = N2[0];
+  aNodes[3] = N2[1];
+  aNodes[4] = N1[3];
+  aNodes[5] = N2[5];
+  aNodes[6] = N2[3];
+  aNodes[7] = N1[5];
+
+  GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
   GetMeshDS()->RemoveElement( tr2 );
 
-  //MESSAGE( endl << tr1 );
+  // remove middle node (9)
+  GetMeshDS()->RemoveNode( N1[4] );
 
   return true;
 }
@@ -493,16 +671,39 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
   switch ( theElem->GetType() ) {
 
   case SMDSAbs_Edge:
-  case SMDSAbs_Face:
-  {
-    int i = theElem->NbNodes();
-    vector<const SMDS_MeshNode*> aNodes( i );
-    while ( it->more() )
-      aNodes[ --i ]= static_cast<const SMDS_MeshNode*>( it->next() );
-    return GetMeshDS()->ChangeElementNodes( theElem, &aNodes[0], theElem->NbNodes() );
+  case SMDSAbs_Face: {
+    if(!theElem->IsQuadratic()) {
+      int i = theElem->NbNodes();
+      vector<const SMDS_MeshNode*> aNodes( i );
+      while ( it->more() )
+        aNodes[ --i ]= static_cast<const SMDS_MeshNode*>( it->next() );
+      return GetMeshDS()->ChangeElementNodes( theElem, &aNodes[0], theElem->NbNodes() );
+    }
+    else {
+      // quadratic elements
+      if(theElem->GetType()==SMDSAbs_Edge) {
+        vector<const SMDS_MeshNode*> aNodes(3);
+        aNodes[1]= static_cast<const SMDS_MeshNode*>( it->next() );
+        aNodes[0]= static_cast<const SMDS_MeshNode*>( it->next() );
+        aNodes[2]= static_cast<const SMDS_MeshNode*>( it->next() );
+        return GetMeshDS()->ChangeElementNodes( theElem, &aNodes[0], 3 );
+      }
+      else {
+        int nbn = theElem->NbNodes();
+        vector<const SMDS_MeshNode*> aNodes(nbn);
+        aNodes[0]= static_cast<const SMDS_MeshNode*>( it->next() );
+        int i=1;
+        for(; i<nbn/2; i++) {
+          aNodes[nbn/2-i]= static_cast<const SMDS_MeshNode*>( it->next() );
+        }
+        for(i=0; i<nbn/2; i++) {
+          aNodes[nbn-i-1]= static_cast<const SMDS_MeshNode*>( it->next() );
+        }
+        return GetMeshDS()->ChangeElementNodes( theElem, &aNodes[0], nbn );
+      }
+    }
   }
-  case SMDSAbs_Volume:
-  {
+  case SMDSAbs_Volume: {
     if (theElem->IsPoly()) {
       const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
         static_cast<const SMDS_PolyhedralVolumeOfNodes*>( theElem );
@@ -519,16 +720,17 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
       for (int iface = 1; iface <= nbFaces; iface++) {
         int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface);
         quantities[iface - 1] = nbFaceNodes;
-
+        
         for (inode = nbFaceNodes; inode >= 1; inode--) {
           const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode);
           poly_nodes.push_back(curNode);
         }
       }
-
+      
       return GetMeshDS()->ChangePolyhedronNodes( theElem, poly_nodes, quantities );
 
-    } else {
+    }
+    else {
       SMDS_VolumeTool vTool;
       if ( !vTool.Set( theElem ))
         return false;
@@ -574,54 +776,119 @@ bool SMESH_MeshEditor::QuadToTri (set<const SMDS_MeshElement*> &       theElems,
   SMESHDS_Mesh * aMesh = GetMeshDS();
 
   set< const SMDS_MeshElement * >::iterator itElem;
-  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
-  {
+  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
     const SMDS_MeshElement* elem = (*itElem);
-    if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() != 4 )
+    if ( !elem || elem->GetType() != SMDSAbs_Face )
       continue;
 
-    // retrieve element nodes
-    const SMDS_MeshNode* aNodes [4];
-    SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-    int i = 0;
-    while ( itN->more() )
-      aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
-
-    // compare two sets of possible triangles
-    double aBadRate1, aBadRate2; // to what extent a set is bad
-    SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] );
-    SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] );
-    aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit );
+    if(elem->NbNodes()==4) {
 
-    SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] );
-    SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] );
-    aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit );
+      // retrieve element nodes
+      const SMDS_MeshNode* aNodes [4];
+      SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+      int i = 0;
+      while ( itN->more() )
+        aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+
+      // compare two sets of possible triangles
+      double aBadRate1, aBadRate2; // to what extent a set is bad
+      SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] );
+      SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] );
+      aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit );
+      
+      SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] );
+      SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] );
+      aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit );
 
-    int aShapeId = FindShape( elem );
-    //MESSAGE( "aBadRate1 = " << aBadRate1 << "; aBadRate2 = " << aBadRate2
+      int aShapeId = FindShape( elem );
+      //MESSAGE( "aBadRate1 = " << aBadRate1 << "; aBadRate2 = " << aBadRate2
       //      << " ShapeID = " << aShapeId << endl << elem );
 
-    if ( aBadRate1 <= aBadRate2 ) {
-      // tr1 + tr2 is better
-      aMesh->ChangeElementNodes( elem, aNodes, 3 );
+      if ( aBadRate1 <= aBadRate2 ) {
+        // tr1 + tr2 is better
+        aMesh->ChangeElementNodes( elem, aNodes, 3 );
+        //MESSAGE( endl << elem );
+
+        elem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
+      }
+      else {
+        // tr3 + tr4 is better
+        aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
+        //MESSAGE( endl << elem );
+        
+        elem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+      }
       //MESSAGE( endl << elem );
 
-      elem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
+      // put a new triangle on the same shape
+      if ( aShapeId )
+        aMesh->SetMeshElementOnShape( elem, aShapeId );
     }
-    else {
-      // tr3 + tr4 is better
-      aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
-      //MESSAGE( endl << elem );
 
-      elem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+    if( elem->NbNodes()==8 && elem->IsQuadratic() ) {
+      const SMDS_MeshNode* aNodes [8];
+      SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+      int i = 0;
+      while ( itN->more() ) {
+        aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+      }
+
+      // compare two sets of possible triangles
+      // use for comparing simple triangles (not quadratic)
+      double aBadRate1, aBadRate2; // to what extent a set is bad
+      SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] );
+      SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] );
+      aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit );
+
+      SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] );
+      SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] );
+      aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit );
+
+      int aShapeId = FindShape( elem );
+      
+      // find middle point for (0,1,2,3)
+      // and create node in this point;
+      double x=0., y=0., z=0.;
+      for(i=0; i<4; i++) {
+        x += aNodes[i]->X();
+        y += aNodes[i]->Y();
+        z += aNodes[i]->Z();
+      }
+      const SMDS_MeshNode* newN = aMesh->AddNode(x/4, y/4, z/4);
+
+      if ( aBadRate1 <= aBadRate2 ) {
+        // tr1 + tr2 is better
+        const SMDS_MeshNode* N[6];
+        N[0] = aNodes[0];
+        N[1] = aNodes[1];
+        N[2] = aNodes[2];
+        N[3] = aNodes[4];
+        N[4] = aNodes[5];
+        N[5] = newN;
+        aMesh->ChangeElementNodes( elem, N, 6 );
+        elem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
+                              aNodes[6], aNodes[7], newN );
+      }
+      else {
+        // tr3 + tr4 is better
+        const SMDS_MeshNode* N[6];
+        N[0] = aNodes[1];
+        N[1] = aNodes[2];
+        N[2] = aNodes[3];
+        N[3] = aNodes[5];
+        N[4] = aNodes[6];
+        N[5] = newN;
+        aMesh->ChangeElementNodes( elem, N, 6 );
+        elem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
+                              aNodes[7], aNodes[4], newN );
+      }
+      // put a new triangle on the same shape
+      if ( aShapeId ) {
+        aMesh->SetMeshElementOnShape( elem, aShapeId );
+      }
     }
-    //MESSAGE( endl << elem );
 
-    // put a new triangle on the same shape
-    if ( aShapeId )
-      aMesh->SetMeshElementOnShape( elem, aShapeId );
   }
-
   return true;
 }
 
@@ -635,30 +902,36 @@ int SMESH_MeshEditor::BestSplit (const SMDS_MeshElement*              theQuad,
   if (!theCrit.get())
     return -1;
 
-  if (!theQuad || theQuad->GetType() != SMDSAbs_Face || theQuad->NbNodes() != 4)
+  if (!theQuad || theQuad->GetType() != SMDSAbs_Face )
     return -1;
 
-  // retrieve element nodes
-  const SMDS_MeshNode* aNodes [4];
-  SMDS_ElemIteratorPtr itN = theQuad->nodesIterator();
-  int i = 0;
-  while (itN->more())
-    aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+  if( theQuad->NbNodes()==4 ||
+      (theQuad->NbNodes()==8 && theQuad->IsQuadratic()) ) {
 
-  // compare two sets of possible triangles
-  double aBadRate1, aBadRate2; // to what extent a set is bad
-  SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] );
-  SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] );
-  aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit );
+    // retrieve element nodes
+    const SMDS_MeshNode* aNodes [4];
+    SMDS_ElemIteratorPtr itN = theQuad->nodesIterator();
+    int i = 0;
+    //while (itN->more())
+    while (i<4) {
+      aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+    }
+    // compare two sets of possible triangles
+    double aBadRate1, aBadRate2; // to what extent a set is bad
+    SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] );
+    SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] );
+    aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit );
 
-  SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] );
-  SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] );
-  aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit );
+    SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] );
+    SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] );
+    aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit );
 
-  if (aBadRate1 <= aBadRate2) // tr1 + tr2 is better
-    return 1; // diagonal 1-3
+    if (aBadRate1 <= aBadRate2) // tr1 + tr2 is better
+      return 1; // diagonal 1-3
 
-  return 2; // diagonal 2-4
+    return 2; // diagonal 2-4
+  }
+  return -1;
 }
 
 //=======================================================================
@@ -693,38 +966,86 @@ bool SMESH_MeshEditor::QuadToTri (std::set<const SMDS_MeshElement*> & theElems,
   SMESHDS_Mesh * aMesh = GetMeshDS();
 
   set< const SMDS_MeshElement * >::iterator itElem;
-  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
-  {
+  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
     const SMDS_MeshElement* elem = (*itElem);
-    if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() != 4 )
+    if ( !elem || elem->GetType() != SMDSAbs_Face )
       continue;
+    bool isquad = elem->NbNodes()==4 || elem->NbNodes()==8;
+    if(!isquad) continue;
 
-    // retrieve element nodes
-    const SMDS_MeshNode* aNodes [4];
-    SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-    int i = 0;
-    while ( itN->more() )
-      aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+    if(elem->NbNodes()==4) {
+      // retrieve element nodes
+      const SMDS_MeshNode* aNodes [4];
+      SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+      int i = 0;
+      while ( itN->more() )
+        aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
 
-    int aShapeId = FindShape( elem );
-    const SMDS_MeshElement* newElem = 0;
-    if ( the13Diag )
-    {
-      aMesh->ChangeElementNodes( elem, aNodes, 3 );
-      newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
-    }
-    else
-    {
-      aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
-      newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+      int aShapeId = FindShape( elem );
+      const SMDS_MeshElement* newElem = 0;
+      if ( the13Diag ) {
+        aMesh->ChangeElementNodes( elem, aNodes, 3 );
+        newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
+      }
+      else {
+        aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
+        newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+      }
+      // put a new triangle on the same shape and add to the same groups
+      if ( aShapeId )
+        aMesh->SetMeshElementOnShape( newElem, aShapeId );
+      AddToSameGroups( newElem, elem, aMesh );
     }
 
-    // put a new triangle on the same shape and add to the same groups
+    if( elem->NbNodes()==8 && elem->IsQuadratic() ) {
+      const SMDS_MeshNode* aNodes [8];
+      SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+      int i = 0;
+      while ( itN->more() ) {
+        aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+      }
 
-    if ( aShapeId )
-      aMesh->SetMeshElementOnShape( newElem, aShapeId );
+      // find middle point for (0,1,2,3)
+      // and create node in this point;
+      double x=0., y=0., z=0.;
+      for(i=0; i<4; i++) {
+        x += aNodes[i]->X();
+        y += aNodes[i]->Y();
+        z += aNodes[i]->Z();
+      }
+      const SMDS_MeshNode* newN = aMesh->AddNode(x/4, y/4, z/4);
 
-    AddToSameGroups( newElem, elem, aMesh );
+      int aShapeId = FindShape( elem );
+      const SMDS_MeshElement* newElem = 0;
+      if ( the13Diag ) {
+        const SMDS_MeshNode* N[6];
+        N[0] = aNodes[0];
+        N[1] = aNodes[1];
+        N[2] = aNodes[2];
+        N[3] = aNodes[4];
+        N[4] = aNodes[5];
+        N[5] = newN;
+        aMesh->ChangeElementNodes( elem, N, 6 );
+        elem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
+                              aNodes[6], aNodes[7], newN );
+      }
+      else {
+        const SMDS_MeshNode* N[6];
+        N[0] = aNodes[1];
+        N[1] = aNodes[2];
+        N[2] = aNodes[3];
+        N[3] = aNodes[5];
+        N[4] = aNodes[6];
+        N[5] = newN;
+        aMesh->ChangeElementNodes( elem, N, 6 );
+        elem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
+                              aNodes[7], aNodes[4], newN );
+      }
+      // put a new triangle on the same shape and add to the same groups
+      if ( aShapeId )
+        aMesh->SetMeshElementOnShape( newElem, aShapeId );
+      AddToSameGroups( newElem, elem, aMesh );
+    }
   }
 
   return true;
@@ -747,18 +1068,24 @@ double getAngle(const SMDS_MeshElement * tr1,
   if ( !SMESH::Controls::NumericalFunctor::GetPoints( tr1, P1 ) ||
        !SMESH::Controls::NumericalFunctor::GetPoints( tr2, P2 ))
     return angle;
-  gp_Vec N1 = gp_Vec( P1(2) - P1(1) ) ^ gp_Vec( P1(3) - P1(1) );
+  gp_Vec N1,N2;
+  if(!tr1->IsQuadratic())
+    N1 = gp_Vec( P1(2) - P1(1) ) ^ gp_Vec( P1(3) - P1(1) );
+  else
+    N1 = gp_Vec( P1(3) - P1(1) ) ^ gp_Vec( P1(5) - P1(1) );
   if ( N1.SquareMagnitude() <= gp::Resolution() )
     return angle;
-  gp_Vec N2 = gp_Vec( P2(2) - P2(1) ) ^ gp_Vec( P2(3) - P2(1) );
+  if(!tr2->IsQuadratic())
+    N2 = gp_Vec( P2(2) - P2(1) ) ^ gp_Vec( P2(3) - P2(1) );
+  else
+    N2 = gp_Vec( P2(3) - P2(1) ) ^ gp_Vec( P2(5) - P2(1) );
   if ( N2.SquareMagnitude() <= gp::Resolution() )
     return angle;
 
   // find the first diagonal node n1 in the triangles:
   // take in account a diagonal link orientation
   const SMDS_MeshElement *nFirst[2], *tr[] = { tr1, tr2 };
-  for ( int t = 0; t < 2; t++ )
-  {
+  for ( int t = 0; t < 2; t++ ) {
     SMDS_ElemIteratorPtr it = tr[ t ]->nodesIterator();
     int i = 0, iDiag = -1;
     while ( it->more()) {
@@ -788,7 +1115,6 @@ double getAngle(const SMDS_MeshElement * tr1,
 // class generating a unique ID for a pair of nodes
 // and able to return nodes by that ID
 // =================================================
-
 class LinkID_Gen {
  public:
 
@@ -819,6 +1145,7 @@ class LinkID_Gen {
   long                myMaxID;
 };
 
+
 //=======================================================================
 //function : TriToQuad
 //purpose  : Fuse neighbour triangles into quadrangles.
@@ -837,65 +1164,76 @@ bool SMESH_MeshEditor::TriToQuad (set<const SMDS_MeshElement*> &       theElems,
     return false;
 
   SMESHDS_Mesh * aMesh = GetMeshDS();
-  LinkID_Gen aLinkID_Gen( aMesh );
-
+  //LinkID_Gen aLinkID_Gen( aMesh );
 
   // Prepare data for algo: build
   // 1. map of elements with their linkIDs
   // 2. map of linkIDs with their elements
 
-  map< long, list< const SMDS_MeshElement* > > mapLi_listEl;
-  map< long, list< const SMDS_MeshElement* > >::iterator itLE;
-  map< const SMDS_MeshElement*, set< long > >  mapEl_setLi;
-  map< const SMDS_MeshElement*, set< long > >::iterator itEL;
+  //map< long, list< const SMDS_MeshElement* > > mapLi_listEl;
+  //map< long, list< const SMDS_MeshElement* > >::iterator itLE;
+  //map< const SMDS_MeshElement*, set< long > >  mapEl_setLi;
+  //map< const SMDS_MeshElement*, set< long > >::iterator itEL;
+
+  map< NLink, list< const SMDS_MeshElement* > > mapLi_listEl;
+  map< NLink, list< const SMDS_MeshElement* > >::iterator itLE;
+  map< const SMDS_MeshElement*, set< NLink > >  mapEl_setLi;
+  map< const SMDS_MeshElement*, set< NLink > >::iterator itEL;
 
   set<const SMDS_MeshElement*>::iterator itElem;
-  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
-  {
+  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
     const SMDS_MeshElement* elem = (*itElem);
-    if ( !elem || elem->NbNodes() != 3 )
-      continue;
+    //if ( !elem || elem->NbNodes() != 3 )
+    //  continue;
+    if(!elem || elem->GetType() != SMDSAbs_Face ) continue;
+    bool IsTria = elem->NbNodes()==3 || (elem->NbNodes()==6 && elem->IsQuadratic());
+    if(!IsTria) continue;
 
     // retrieve element nodes
     const SMDS_MeshNode* aNodes [4];
     SMDS_ElemIteratorPtr itN = elem->nodesIterator();
     int i = 0;
-    while ( itN->more() )
+    //while ( itN->more() )
+    while ( i<3 )
       aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
     ASSERT( i == 3 );
     aNodes[ 3 ] = aNodes[ 0 ];
 
     // fill maps
-    for ( i = 0; i < 3; i++ )
-    {
-      long linkID = aLinkID_Gen.GetLinkID( aNodes[ i ], aNodes[ i+1 ] );
+    for ( i = 0; i < 3; i++ ) {
+      //long linkID = aLinkID_Gen.GetLinkID( aNodes[ i ], aNodes[ i+1 ] );
+      NLink link(( aNodes[i] < aNodes[i+1] ? aNodes[i] : aNodes[i+1] ),
+                 ( aNodes[i] < aNodes[i+1] ? aNodes[i+1] : aNodes[i] ));
       // check if elements sharing a link can be fused
-      itLE = mapLi_listEl.find( linkID );
-      if ( itLE != mapLi_listEl.end() )
-      {
+      //itLE = mapLi_listEl.find( linkID );
+      itLE = mapLi_listEl.find( link );
+      if ( itLE != mapLi_listEl.end() ) {
         if ((*itLE).second.size() > 1 ) // consider only 2 elems adjacent by a link
           continue;
         const SMDS_MeshElement* elem2 = (*itLE).second.front();
-//         if ( FindShape( elem ) != FindShape( elem2 ))
-//           continue; // do not fuse triangles laying on different shapes
+        //if ( FindShape( elem ) != FindShape( elem2 ))
+        //  continue; // do not fuse triangles laying on different shapes
         if ( getAngle( elem, elem2, aNodes[i], aNodes[i+1] ) > theMaxAngle )
           continue; // avoid making badly shaped quads
         (*itLE).second.push_back( elem );
       }
-      else
-        mapLi_listEl[ linkID ].push_back( elem );
-      mapEl_setLi [ elem ].insert( linkID );
+      else {
+        //mapLi_listEl[ linkID ].push_back( elem );
+        mapLi_listEl[ link ].push_back( elem );
+      }
+      //mapEl_setLi [ elem ].insert( linkID );
+      mapEl_setLi [ elem ].insert( link );
     }
   }
   // Clean the maps from the links shared by a sole element, ie
   // links to which only one element is bound in mapLi_listEl
 
-  for ( itLE = mapLi_listEl.begin(); itLE != mapLi_listEl.end(); itLE++ )
-  {
+  for ( itLE = mapLi_listEl.begin(); itLE != mapLi_listEl.end(); itLE++ ) {
     int nbElems = (*itLE).second.size();
     if ( nbElems < 2  ) {
       const SMDS_MeshElement* elem = (*itLE).second.front();
-      long link = (*itLE).first;
+      //long link = (*itLE).first;
+      NLink link = (*itLE).first;
       mapEl_setLi[ elem ].erase( link );
       if ( mapEl_setLi[ elem ].empty() )
         mapEl_setLi.erase( elem );
@@ -904,18 +1242,15 @@ bool SMESH_MeshEditor::TriToQuad (set<const SMDS_MeshElement*> &       theElems,
 
   // Algo: fuse triangles into quadrangles
 
-  while ( ! mapEl_setLi.empty() )
-  {
+  while ( ! mapEl_setLi.empty() ) {
     // Look for the start element:
     // the element having the least nb of shared links
 
     const SMDS_MeshElement* startElem = 0;
     int minNbLinks = 4;
-    for ( itEL = mapEl_setLi.begin(); itEL != mapEl_setLi.end(); itEL++ )
-    {
+    for ( itEL = mapEl_setLi.begin(); itEL != mapEl_setLi.end(); itEL++ ) {
       int nbLinks = (*itEL).second.size();
-      if ( nbLinks < minNbLinks )
-      {
+      if ( nbLinks < minNbLinks ) {
         startElem = (*itEL).first;
         minNbLinks = nbLinks;
         if ( minNbLinks == 1 )
@@ -925,17 +1260,16 @@ bool SMESH_MeshEditor::TriToQuad (set<const SMDS_MeshElement*> &       theElems,
 
     // search elements to fuse starting from startElem or links of elements
     // fused earlyer - startLinks
-    list< long > startLinks;
-    while ( startElem || !startLinks.empty() )
-    {
-      while ( !startElem && !startLinks.empty() )
-      {
+    //list< long > startLinks;
+    list< NLink > startLinks;
+    while ( startElem || !startLinks.empty() ) {
+      while ( !startElem && !startLinks.empty() ) {
         // Get an element to start, by a link
-        long linkId = startLinks.front();
+        //long linkId = startLinks.front();
+        NLink linkId = startLinks.front();
         startLinks.pop_front();
         itLE = mapLi_listEl.find( linkId );
-        if ( itLE != mapLi_listEl.end() )
-        {
+        if ( itLE != mapLi_listEl.end() ) {
           list< const SMDS_MeshElement* > & listElem = (*itLE).second;
           list< const SMDS_MeshElement* >::iterator itE = listElem.begin();
           for ( ; itE != listElem.end() ; itE++ )
@@ -945,69 +1279,83 @@ bool SMESH_MeshEditor::TriToQuad (set<const SMDS_MeshElement*> &       theElems,
         }
       }
 
-      if ( startElem )
-      {
+      if ( startElem ) {
         // Get candidates to be fused
-
         const SMDS_MeshElement *tr1 = startElem, *tr2 = 0, *tr3 = 0;
-        long link12, link13;
+        //long link12, link13;
+        NLink link12, link13;
         startElem = 0;
         ASSERT( mapEl_setLi.find( tr1 ) != mapEl_setLi.end() );
-        set< long >& setLi = mapEl_setLi[ tr1 ];
+        //set< long >& setLi = mapEl_setLi[ tr1 ];
+        set< NLink >& setLi = mapEl_setLi[ tr1 ];
         ASSERT( !setLi.empty() );
-        set< long >::iterator itLi;
-        for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ )
-        {
-          long linkID = (*itLi);
+        //set< long >::iterator itLi;
+        set< NLink >::iterator itLi;
+        for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ ) {
+          //long linkID = (*itLi);
+          NLink linkID = (*itLi);
           itLE = mapLi_listEl.find( linkID );
           if ( itLE == mapLi_listEl.end() )
             continue;
+
           const SMDS_MeshElement* elem = (*itLE).second.front();
           if ( elem == tr1 )
             elem = (*itLE).second.back();
           mapLi_listEl.erase( itLE );
           if ( mapEl_setLi.find( elem ) == mapEl_setLi.end())
             continue;
-          if ( tr2 )
-          {
+          if ( tr2 ) {
             tr3 = elem;
             link13 = linkID;
           }
-          else
-          {
+          else {
             tr2 = elem;
             link12 = linkID;
           }
 
           // add other links of elem to list of links to re-start from
-          set< long >& links = mapEl_setLi[ elem ];
-          set< long >::iterator it;
-          for ( it = links.begin(); it != links.end(); it++ )
-          {
-            long linkID2 = (*it);
+          //set< long >& links = mapEl_setLi[ elem ];
+          //set< long >::iterator it;
+          set< NLink >& links = mapEl_setLi[ elem ];
+          set< NLink >::iterator it;
+          for ( it = links.begin(); it != links.end(); it++ ) {
+            //long linkID2 = (*it);
+            NLink linkID2 = (*it);
             if ( linkID2 != linkID )
               startLinks.push_back( linkID2 );
           }
         }
 
         // Get nodes of possible quadrangles
-
         const SMDS_MeshNode *n12 [4], *n13 [4];
         bool Ok12 = false, Ok13 = false;
+        //const SMDS_MeshNode *linkNode1, *linkNode2;
         const SMDS_MeshNode *linkNode1, *linkNode2;
-        if ( tr2 &&
-             aLinkID_Gen.GetNodes( link12, linkNode1, linkNode2 ) &&
-             getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 ))
-          Ok12 = true;
-        if ( tr3 &&
-             aLinkID_Gen.GetNodes( link13, linkNode1, linkNode2 ) &&
-             getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 ))
-          Ok13 = true;
+        if(tr2) {
+          //const SMDS_MeshNode *linkNode1 = link12.first;
+          //const SMDS_MeshNode *linkNode2 = link12.second;
+          linkNode1 = link12.first;
+          linkNode2 = link12.second;
+          //if ( tr2 &&
+          //     aLinkID_Gen.GetNodes( link12, linkNode1, linkNode2 ) &&
+          //     getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 ))
+          //  Ok12 = true;
+          if ( tr2 && getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 ))
+            Ok12 = true;
+        }
+        if(tr3) {
+          linkNode1 = link13.first;
+          linkNode2 = link13.second;
+          //if ( tr3 &&
+          //     aLinkID_Gen.GetNodes( link13, linkNode1, linkNode2 ) &&
+          //     getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 ))
+          //  Ok13 = true;
+          if ( tr3 && getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 ))
+            Ok13 = true;
+        }
 
         // Choose a pair to fuse
-
-        if ( Ok12 && Ok13 )
-        {
+        if ( Ok12 && Ok13 ) {
           SMDS_FaceOfNodes quad12 ( n12[ 0 ], n12[ 1 ], n12[ 2 ], n12[ 3 ] );
           SMDS_FaceOfNodes quad13 ( n13[ 0 ], n13[ 1 ], n13[ 2 ], n13[ 3 ] );
           double aBadRate12 = getBadRate( &quad12, theCrit );
@@ -1018,24 +1366,66 @@ bool SMESH_MeshEditor::TriToQuad (set<const SMDS_MeshElement*> &       theElems,
             Ok13 = false;
         }
 
-
         // Make quadrangles
         // and remove fused elems and removed links from the maps
-
         mapEl_setLi.erase( tr1 );
-        if ( Ok12 )
-        {
+        if ( Ok12 ) {
           mapEl_setLi.erase( tr2 );
           mapLi_listEl.erase( link12 );
-          aMesh->ChangeElementNodes( tr1, n12, 4 );
-          aMesh->RemoveElement( tr2 );
+          if(tr1->NbNodes()==3) {
+            aMesh->ChangeElementNodes( tr1, n12, 4 );
+            aMesh->RemoveElement( tr2 );
+          }
+          else {
+            const SMDS_MeshNode* N1 [6];
+            const SMDS_MeshNode* N2 [6];
+            GetNodesFromTwoTria(tr1,tr2,N1,N2);
+            // now we receive following N1 and N2 (using numeration as above image)
+            // tria1 : (1 2 4 5 9 7)  and  tria2 : (3 4 2 8 9 6) 
+            // i.e. first nodes from both arrays determ new diagonal
+            const SMDS_MeshNode* aNodes[8];
+            aNodes[0] = N1[0];
+            aNodes[1] = N1[1];
+            aNodes[2] = N2[0];
+            aNodes[3] = N2[1];
+            aNodes[4] = N1[3];
+            aNodes[5] = N2[5];
+            aNodes[6] = N2[3];
+            aNodes[7] = N1[5];
+            GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
+            GetMeshDS()->RemoveElement( tr2 );
+            // remove middle node (9)
+            GetMeshDS()->RemoveNode( N1[4] );
+          }
         }
-        else if ( Ok13 )
-        {
+        else if ( Ok13 ) {
           mapEl_setLi.erase( tr3 );
           mapLi_listEl.erase( link13 );
-          aMesh->ChangeElementNodes( tr1, n13, 4 );
-          aMesh->RemoveElement( tr3 );
+          if(tr1->NbNodes()==3) {
+            aMesh->ChangeElementNodes( tr1, n13, 4 );
+            aMesh->RemoveElement( tr3 );
+          }
+          else {
+            const SMDS_MeshNode* N1 [6];
+            const SMDS_MeshNode* N2 [6];
+            GetNodesFromTwoTria(tr1,tr3,N1,N2);
+            // now we receive following N1 and N2 (using numeration as above image)
+            // tria1 : (1 2 4 5 9 7)  and  tria2 : (3 4 2 8 9 6) 
+            // i.e. first nodes from both arrays determ new diagonal
+            const SMDS_MeshNode* aNodes[8];
+            aNodes[0] = N1[0];
+            aNodes[1] = N1[1];
+            aNodes[2] = N2[0];
+            aNodes[3] = N2[1];
+            aNodes[4] = N1[3];
+            aNodes[5] = N2[5];
+            aNodes[6] = N2[3];
+            aNodes[7] = N1[5];
+            GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
+            GetMeshDS()->RemoveElement( tr3 );
+            // remove middle node (9)
+            GetMeshDS()->RemoveNode( N1[4] );
+          }
         }
 
         // Next element to fuse: the rejected one
@@ -1352,13 +1742,25 @@ void laplacianSmooth(const SMDS_MeshNode*                 theNode,
     // put all nodes in array
     int nbNodes = 0, iNode = 0;
     vector< const SMDS_MeshNode*> aNodes( elem->NbNodes() );
-    SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-    while ( itN->more() )
-    {
-      aNodes[ nbNodes ] = static_cast<const SMDS_MeshNode*>( itN->next() );
-      if ( aNodes[ nbNodes ] == theNode )
-        iNode = nbNodes; // index of theNode within aNodes
-      nbNodes++;
+    if(!elem->IsQuadratic()) {
+      SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+      while ( itN->more() ) {
+        aNodes[ nbNodes ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+        if ( aNodes[ nbNodes ] == theNode )
+          iNode = nbNodes; // index of theNode within aNodes
+        nbNodes++;
+      }
+    }
+    else {
+      int nbn = elem->NbNodes()/2;
+      aNodes.resize(nbn);
+      SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+      while ( nbNodes<nbn ) {
+        aNodes[ nbNodes ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+        if ( aNodes[ nbNodes ] == theNode )
+          iNode = nbNodes; // index of theNode within aNodes
+        nbNodes++;
+      }
     }
     // add linked nodes
     int iAfter = ( iNode + 1 == nbNodes ) ? 0 : iNode + 1;
@@ -1435,9 +1837,13 @@ void centroidalSmooth(const SMDS_MeshNode*                 theNode,
     gp_XYZ elemCenter(0.,0.,0.);
     SMESH::Controls::TSequenceOfXYZ aNodePoints;
     SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-    while ( itN->more() )
-    {
+    int nn = elem->NbNodes();
+    if(elem->IsQuadratic()) nn = nn/2;
+    int i=0;
+    //while ( itN->more() ) {
+    while ( i<nn ) {
       const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>( itN->next() );
+      i++;
       gp_XYZ aP( aNode->X(), aNode->Y(), aNode->Z() );
       aNodePoints.push_back( aP );
       if ( !theSurface.IsNull() ) { // smooth in 2D
@@ -1509,6 +1915,8 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
   if ( theTgtAspectRatio < 1.0 )
     theTgtAspectRatio = 1.0;
 
+  double disttol = 1.e-16;
+
   SMESH::Controls::AspectRatio aQualityFunc;
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
@@ -1540,9 +1948,10 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
   // smooth elements on each TopoDS_Face separately
   // ===============================================
 
+  set<const SMDS_MeshElement*> QuadElems;
+
   set< int >::reverse_iterator fId = faceIdSet.rbegin(); // treate 0 fId at the end
-  for ( ; fId != faceIdSet.rend(); ++fId )
-  {
+  for ( ; fId != faceIdSet.rend(); ++fId ) {
     // get face surface and submesh
     Handle(Geom_Surface) surface;
     SMESHDS_SubMesh* faceSubMesh = 0;
@@ -1583,8 +1992,7 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
     int nbElemOnFace = 0;
     itElem = theElems.begin();
      // loop on not yet smoothed elements: look for elems on a face
-    while ( itElem != theElems.end() )
-    {
+    while ( itElem != theElems.end() ) {
       if ( faceSubMesh && nbElemOnFace == faceSubMesh->NbElements() )
         break; // all elements found
 
@@ -1595,6 +2003,9 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
         continue;
       }
       elemsOnFace.push_back( elem );
+      if(elem->IsQuadratic()) {
+        QuadElems.insert(elem);
+      }
       theElems.erase( itElem++ );
       nbElemOnFace++;
 
@@ -1602,7 +2013,13 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
       const SMDS_MeshNode* node;
       SMDS_TypeOfPosition posType;
       SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-      while ( itN->more() ) {
+      int nbn =  elem->NbNodes();
+      if(elem->IsQuadratic())
+        nbn = nbn/2;
+      int nn = 0;
+      //while ( itN->more() ) {
+      while ( nn<nbn ) {
+        nn++;
         node = static_cast<const SMDS_MeshNode*>( itN->next() );
         const SMDS_PositionPtr& pos = node->GetPosition();
         posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
@@ -1657,8 +2074,7 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
       }
       // check UV on face
       list< const SMDS_MeshNode* >::iterator n = uvCheckNodes.begin();
-      for ( ; n != uvCheckNodes.end(); ++n )
-      {
+      for ( ; n != uvCheckNodes.end(); ++n ) {
         node = *n;
         gp_XY uv( 0, 0 );
         const SMDS_PositionPtr& pos = node->GetPosition();
@@ -1725,21 +2141,31 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
 
     // fix nodes on mesh boundary
 
-    if ( checkBoundaryNodes )
-    {
+    if ( checkBoundaryNodes ) {
       typedef pair<const SMDS_MeshNode*, const SMDS_MeshNode*> TLink;
       map< TLink, int > linkNbMap; // how many times a link encounters in elemsOnFace
       map< TLink, int >::iterator link_nb;
       // put all elements links to linkNbMap
       list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
-      for ( ; elemIt != elemsOnFace.end(); ++elemIt )
-      {
+      for ( ; elemIt != elemsOnFace.end(); ++elemIt ) {
+        const SMDS_MeshElement* elem = (*elemIt);
         // put elem nodes in array
         vector< const SMDS_MeshNode* > nodes;
-        nodes.reserve( (*elemIt)->NbNodes() + 1 );
-        SMDS_ElemIteratorPtr itN = (*elemIt)->nodesIterator();
-        while ( itN->more() )
-          nodes.push_back( static_cast<const SMDS_MeshNode*>( itN->next() ));
+        if(!elem->IsQuadratic()) {
+          nodes.reserve( elem->NbNodes() + 1 );
+          SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+          while ( itN->more() )
+            nodes.push_back( static_cast<const SMDS_MeshNode*>( itN->next() ));
+        }
+        else {
+          nodes.reserve( elem->NbNodes()/2 + 1 );
+          SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+          int nbn = 0;
+          while ( nbn<elem->NbNodes()/2 ) {
+            nbn++;
+            nodes.push_back( static_cast<const SMDS_MeshNode*>( itN->next() ));
+          }
+        }
         nodes.push_back( nodes.front() );
         // loop on elem links: insert them in linkNbMap
         for ( int iN = 1; iN < nodes.size(); ++iN ) {
@@ -1771,11 +2197,9 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
     // -----------------------------------------------------
 
     set<const SMDS_MeshNode*> nodesNearSeam; // to smooth using uvMap2
-    if ( !surface.IsNull() )
-    {
+    if ( !surface.IsNull() ) {
       TopExp_Explorer eExp( face, TopAbs_EDGE );
-      for ( ; eExp.More(); eExp.Next() )
-      {
+      for ( ; eExp.More(); eExp.Next() ) {
         TopoDS_Edge edge = TopoDS::Edge( eExp.Current() );
         if ( !BRep_Tool::IsClosed( edge, face ))
           continue;
@@ -1812,8 +2236,7 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
         }
         // loop on nodes on seam
         list< const SMDS_MeshNode* >::iterator noSeIt = seamNodes.begin();
-        for ( ; noSeIt != seamNodes.end(); ++noSeIt )
-        {
+        for ( ; noSeIt != seamNodes.end(); ++noSeIt ) {
           const SMDS_MeshNode* nSeam = *noSeIt;
           map< const SMDS_MeshNode*, gp_XY* >::iterator n_uv = uvMap.find( nSeam );
           if ( n_uv == uvMap.end() )
@@ -1829,8 +2252,7 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
 
           // collect movable nodes linked to ones on seam in nodesNearSeam
           SMDS_ElemIteratorPtr eIt = nSeam->GetInverseElementIterator();
-          while ( eIt->more() )
-          {
+          while ( eIt->more() ) {
             const SMDS_MeshElement* e = eIt->next();
             if ( e->GetType() != SMDSAbs_Face )
               continue;
@@ -1858,8 +2280,7 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
             }
             // for centroidalSmooth all element nodes must
             // be on one side of a seam
-            if ( theSmoothMethod == CENTROIDAL && nbUseMap1 && nbUseMap2 )
-            {
+            if ( theSmoothMethod == CENTROIDAL && nbUseMap1 && nbUseMap2 ) {
               SMDS_ElemIteratorPtr nIt = e->nodesIterator();
               while ( nIt->more() ) {
                 const SMDS_MeshNode* n =
@@ -1884,12 +2305,10 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
     int it = -1;
     double maxRatio = -1., maxDisplacement = -1.;
     set<const SMDS_MeshNode*>::iterator nodeToMove;
-    for ( it = 0; it < theNbIterations; it++ )
-    {
+    for ( it = 0; it < theNbIterations; it++ ) {
       maxDisplacement = 0.;
       nodeToMove = setMovableNodes.begin();
-      for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ )
-      {
+      for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ ) {
         const SMDS_MeshNode* node = (*nodeToMove);
         gp_XYZ aPrevPos ( node->X(), node->Y(), node->Z() );
 
@@ -1907,7 +2326,8 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
           maxDisplacement = aDispl;
       }
       // no node movement => exit
-      if ( maxDisplacement < 1.e-16 ) {
+      //if ( maxDisplacement < 1.e-16 ) {
+      if ( maxDisplacement < disttol ) {
         MESSAGE("-- no node movement --");
         break;
       }
@@ -1915,8 +2335,7 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
       // check elements quality
       maxRatio  = 0;
       list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
-      for ( ; elemIt != elemsOnFace.end(); ++elemIt )
-      {
+      for ( ; elemIt != elemsOnFace.end(); ++elemIt ) {
         const SMDS_MeshElement* elem = (*elemIt);
         if ( !elem || elem->GetType() != SMDSAbs_Face )
           continue;
@@ -1945,10 +2364,8 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
     // new nodes positions are computed,
     // record movement in DS and set new UV
     // ---------------------------------------
-
     nodeToMove = setMovableNodes.begin();
-    for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ )
-    {
+    for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ ) {
       SMDS_MeshNode* node = const_cast< SMDS_MeshNode* > (*nodeToMove);
       aMesh->MoveNode( node, node->X(), node->Y(), node->Z() );
       map< const SMDS_MeshNode*, gp_XY* >::iterator node_uv = uvMap.find( node );
@@ -1960,6 +2377,38 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
     }
 
   } // loop on face ids
+
+  set< const SMDS_MeshElement* >::iterator itq;
+  for ( itq = QuadElems.begin(); itq != QuadElems.end(); itq++ ) {
+    const SMDS_QuadraticFaceOfNodes* QF =
+      dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (*itq);
+    if(QF) {
+      vector<const SMDS_MeshNode*> Ns(QF->NbNodes()+1);
+      SMDS_NodeIteratorPtr anIter = QF->interlacedNodesIterator();
+      int nn = 0;
+      while( anIter->more() ) {
+        Ns[nn++] = anIter->next();
+        //Ns.push_back(anIter->next());
+      }
+      Ns[nn] = Ns[0];
+      //Ns.push_back(Ns[0]);
+      int i=0;
+      for(; i<QF->NbNodes(); i=i+2) {
+        double x = (Ns[i]->X() + Ns[i+2]->X())/2;
+        double y = (Ns[i]->Y() + Ns[i+2]->Y())/2;
+        double z = (Ns[i]->Z() + Ns[i+2]->Z())/2;
+        if( fabs( Ns[i+1]->X() - x ) > disttol ||
+           fabs( Ns[i+1]->Y() - y ) > disttol ||
+           fabs( Ns[i+1]->Z() - z ) > disttol ) {
+          // we have to move i+1 node
+          const_cast<SMDS_MeshNode*>(Ns[i+1])->setXYZ(x,y,z);
+          aMesh->MoveNode( Ns[i+1], x, y, z );
+        }
+      }
+    }
+  }
+  QuadElems.clear();
+
 }
 
 //=======================================================================
@@ -2000,38 +2449,57 @@ static bool isReverse(const SMDS_MeshNode* prevNodes[],
 static void sweepElement(SMESHDS_Mesh*                         aMesh,
                          const SMDS_MeshElement*               elem,
                          const vector<TNodeOfNodeListMapItr> & newNodesItVec,
-                         list<const SMDS_MeshElement*>&        newElems)
+                         list<const SMDS_MeshElement*>&        newElems,
+                         const int nbSteps)
 {
   // Loop on elem nodes:
   // find new nodes and detect same nodes indices
   int nbNodes = elem->NbNodes();
   list<const SMDS_MeshNode*>::const_iterator itNN[ nbNodes ];
-  const SMDS_MeshNode* prevNod[ nbNodes ], *nextNod[ nbNodes ];
+  const SMDS_MeshNode* prevNod[ nbNodes ], *nextNod[ nbNodes ], *midlNod[ nbNodes ];
   int iNode, nbSame = 0, iNotSameNode = 0, iSameNode = 0;
+  vector<int> sames(nbNodes);
 
-  for ( iNode = 0; iNode < nbNodes; iNode++ )
-  {
+  bool issimple[nbNodes];
+
+  for ( iNode = 0; iNode < nbNodes; iNode++ ) {
     TNodeOfNodeListMapItr nnIt = newNodesItVec[ iNode ];
     const SMDS_MeshNode*                 node         = nnIt->first;
     const list< const SMDS_MeshNode* > & listNewNodes = nnIt->second;
     if ( listNewNodes.empty() )
       return;
 
+    if(listNewNodes.size()==nbSteps) {
+      issimple[iNode] = true;
+    }
+    else {
+      issimple[iNode] = false;
+    }
+
     itNN[ iNode ] = listNewNodes.begin();
     prevNod[ iNode ] = node;
     nextNod[ iNode ] = listNewNodes.front();
+//cout<<"iNode="<<iNode<<endl;
+//cout<<" prevNod[iNode]="<< prevNod[iNode]<<" nextNod[iNode]="<< nextNod[iNode]<<endl;
     if ( prevNod[ iNode ] != nextNod [ iNode ])
       iNotSameNode = iNode;
     else {
       iSameNode = iNode;
-      nbSame++;
+      //nbSame++;
+      sames[nbSame++] = iNode;
     }
   }
+//cout<<"1 nbSame="<<nbSame<<endl;
   if ( nbSame == nbNodes || nbSame > 2) {
     MESSAGE( " Too many same nodes of element " << elem->GetID() );
     return;
   }
 
+//  if( elem->IsQuadratic() && nbSame>0 ) {
+//    MESSAGE( "Can not rotate quadratic element " << elem->GetID() );
+//    return;
+//  }
+
   int iBeforeSame = 0, iAfterSame = 0, iOpposSame = 0;
   if ( nbSame > 0 ) {
     iBeforeSame = ( iSameNode == 0 ? nbNodes - 1 : iSameNode - 1 );
@@ -2039,6 +2507,12 @@ static void sweepElement(SMESHDS_Mesh*                         aMesh,
     iOpposSame  = ( iSameNode - 2 < 0  ? iSameNode + 2 : iSameNode - 2 );
   }
 
+//if(nbNodes==8)
+//cout<<" prevNod[0]="<< prevNod[0]<<" prevNod[1]="<< prevNod[1]
+//    <<" prevNod[2]="<< prevNod[2]<<" prevNod[3]="<< prevNod[4]
+//    <<" prevNod[4]="<< prevNod[4]<<" prevNod[5]="<< prevNod[5]
+//    <<" prevNod[6]="<< prevNod[6]<<" prevNod[7]="<< prevNod[7]<<endl;
+
   // check element orientation
   int i0 = 0, i2 = 2;
   if ( nbNodes > 2 && !isReverse( prevNod, nextNod, nbNodes, iNotSameNode )) {
@@ -2053,82 +2527,195 @@ static void sweepElement(SMESHDS_Mesh*                         aMesh,
   }
 
   // make new elements
-  int iStep, nbSteps = newNodesItVec[ 0 ]->second.size();
-  for (iStep = 0; iStep < nbSteps; iStep++ )
-  {
+  int iStep;//, nbSteps = newNodesItVec[ 0 ]->second.size();
+  for (iStep = 0; iStep < nbSteps; iStep++ ) {
     // get next nodes
     for ( iNode = 0; iNode < nbNodes; iNode++ ) {
-      nextNod[ iNode ] = *itNN[ iNode ];
-      itNN[ iNode ]++;
+      if(issimple[iNode]) {
+        nextNod[ iNode ] = *itNN[ iNode ];
+        itNN[ iNode ]++;
+      }
+      else {
+        if( elem->GetType()==SMDSAbs_Node ) {
+          // we have to use two nodes
+          midlNod[ iNode ] = *itNN[ iNode ];
+          itNN[ iNode ]++;
+          nextNod[ iNode ] = *itNN[ iNode ];
+          itNN[ iNode ]++;
+        }
+        else if(!elem->IsQuadratic() ||
+           elem->IsQuadratic() && elem->IsMediumNode(prevNod[iNode]) ) {
+          // we have to use each second node
+          itNN[ iNode ]++;
+          nextNod[ iNode ] = *itNN[ iNode ];
+          itNN[ iNode ]++;
+        }
+        else {
+          // we have to use two nodes
+          midlNod[ iNode ] = *itNN[ iNode ];
+          itNN[ iNode ]++;
+          nextNod[ iNode ] = *itNN[ iNode ];
+          itNN[ iNode ]++;
+        }
+      }
     }
     SMDS_MeshElement* aNewElem = 0;
-    switch ( nbNodes )
-    {
-    case 0:
-      return;
-    case 1: { // NODE
-      if ( nbSame == 0 )
-        aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ] );
-      break;
-    }
-    case 2: { // EDGE
-
-      if ( nbSame == 0 )
-        aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ],
-                                  nextNod[ 1 ], nextNod[ 0 ] );
-      else
-        aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ],
-                                  nextNod[ iNotSameNode ] );
-      break;
-    }
-    case 3: { // TRIANGLE
-
-      if ( nbSame == 0 )       // --- pentahedron
-        aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ],
-                                     nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ] );
+    if(!elem->IsPoly()) {
+      switch ( nbNodes ) {
+      case 0:
+        return;
+      case 1: { // NODE
+        if ( nbSame == 0 ) {
+          if(issimple[0])
+            aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ] );
+          else
+            aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ], midlNod[ 0 ] );
+        }
+        break;
+      }
+      case 2: { // EDGE
+        if ( nbSame == 0 )
+          aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ],
+                                    nextNod[ 1 ], nextNod[ 0 ] );
+        else
+          aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ],
+                                    nextNod[ iNotSameNode ] );
+        break;
+      }
 
-      else if ( nbSame == 1 )  // --- pyramid
-        aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ],  prevNod[ iAfterSame ],
-                                     nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
-                                     nextNod[ iSameNode ]);
+      case 3: { // TRIANGLE or quadratic edge
+        if(elem->GetType() == SMDSAbs_Face) { // TRIANGLE
 
-      else // 2 same nodes:      --- tetrahedron
-        aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ],
-                                     nextNod[ iNotSameNode ]);
-      break;
-    }
-    case 4: { // QUADRANGLE
+          if ( nbSame == 0 )       // --- pentahedron
+            aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ],
+                                         nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ] );
 
-      if ( nbSame == 0 )       // --- hexahedron
-        aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], prevNod[ 3 ],
-                                     nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ], nextNod[ 3 ]);
+          else if ( nbSame == 1 )  // --- pyramid
+            aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ],  prevNod[ iAfterSame ],
+                                         nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
+                                         nextNod[ iSameNode ]);
 
-      else if ( nbSame == 1 )  // --- pyramid + pentahedron
-      {
-        aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ],  prevNod[ iAfterSame ],
-                                     nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
-                                     nextNod[ iSameNode ]);
-        newElems.push_back( aNewElem );
-        aNewElem = aMesh->AddVolume (prevNod[ iAfterSame ], prevNod[ iOpposSame ],
-                                     prevNod[ iBeforeSame ],  nextNod[ iAfterSame ],
-                                     nextNod[ iOpposSame ],  nextNod[ iBeforeSame ] );
-      }
-      else if ( nbSame == 2 )  // pentahedron
-      {
-        if ( prevNod[ iBeforeSame ] == nextNod[ iBeforeSame ] )
-          // iBeforeSame is same too
-          aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iOpposSame ],
-                                       nextNod[ iOpposSame ], prevNod[ iSameNode ],
-                                       prevNod[ iAfterSame ],  nextNod[ iAfterSame ]);
-        else
-          // iAfterSame is same too
-          aNewElem = aMesh->AddVolume (prevNod[ iSameNode ], prevNod[ iBeforeSame ],
-                                       nextNod[ iBeforeSame ], prevNod[ iAfterSame ],
-                                       prevNod[ iOpposSame ],  nextNod[ iOpposSame ]);
+          else // 2 same nodes:      --- tetrahedron
+            aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ],
+                                         nextNod[ iNotSameNode ]);
+        }
+        else { // quadratic edge
+          if(nbSame==0) {     // quadratic quadrangle
+            aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], nextNod[1], prevNod[1],
+                                      midlNod[0], nextNod[2], midlNod[1], prevNod[2]);
+          }
+          else if(nbSame==1) { // quadratic triangle
+            if(sames[0]==2)
+              return; // medium node on axis
+            else if(sames[0]==0) {
+              aNewElem = aMesh->AddFace(prevNod[0], nextNod[1], prevNod[1],
+                                        nextNod[2], midlNod[1], prevNod[2]);
+            }
+            else { // sames[0]==1
+              aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], prevNod[1],
+                                        midlNod[0], nextNod[2], prevNod[2]);
+            }
+          }
+          else
+            return;
+        }
+        break;
+      }
+      case 4: { // QUADRANGLE
+
+        if ( nbSame == 0 )       // --- hexahedron
+          aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], prevNod[ 3 ],
+                                       nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ], nextNod[ 3 ]);
+        
+        else if ( nbSame == 1 ) { // --- pyramid + pentahedron
+          aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ],  prevNod[ iAfterSame ],
+                                       nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
+                                       nextNod[ iSameNode ]);
+          newElems.push_back( aNewElem );
+          aNewElem = aMesh->AddVolume (prevNod[ iAfterSame ], prevNod[ iOpposSame ],
+                                       prevNod[ iBeforeSame ],  nextNod[ iAfterSame ],
+                                       nextNod[ iOpposSame ],  nextNod[ iBeforeSame ] );
+        }
+        else if ( nbSame == 2 ) { // pentahedron
+          if ( prevNod[ iBeforeSame ] == nextNod[ iBeforeSame ] )
+            // iBeforeSame is same too
+            aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iOpposSame ],
+                                         nextNod[ iOpposSame ], prevNod[ iSameNode ],
+                                         prevNod[ iAfterSame ],  nextNod[ iAfterSame ]);
+          else
+            // iAfterSame is same too
+            aNewElem = aMesh->AddVolume (prevNod[ iSameNode ], prevNod[ iBeforeSame ],
+                                         nextNod[ iBeforeSame ], prevNod[ iAfterSame ],
+                                         prevNod[ iOpposSame ],  nextNod[ iOpposSame ]);
+        }
+        break;
+      }
+      case 6: { // quadratic triangle
+        // create pentahedron with 15 nodes
+        if(i0>0) { // reversed case
+          aNewElem = aMesh->AddVolume (prevNod[0], prevNod[2], prevNod[1],
+                                       nextNod[0], nextNod[2], nextNod[1],
+                                       prevNod[5], prevNod[4], prevNod[3],
+                                       nextNod[5], nextNod[4], nextNod[3],
+                                       midlNod[0], midlNod[2], midlNod[1]);
+        }
+        else { // not reversed case
+          aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2],
+                                       nextNod[0], nextNod[1], nextNod[2],
+                                       prevNod[3], prevNod[4], prevNod[5],
+                                       nextNod[3], nextNod[4], nextNod[5],
+                                       midlNod[0], midlNod[1], midlNod[2]);
+        }
+        break;
+      }
+      case 8: { // quadratic quadrangle
+        // create hexahedron with 20 nodes
+        if(i0>0) { // reversed case
+          aNewElem = aMesh->AddVolume (prevNod[0], prevNod[3], prevNod[2], prevNod[1],
+                                       nextNod[0], nextNod[3], nextNod[2], nextNod[1],
+                                       prevNod[7], prevNod[6], prevNod[5], prevNod[4],
+                                       nextNod[7], nextNod[6], nextNod[5], nextNod[4],
+                                       midlNod[0], midlNod[3], midlNod[2], midlNod[1]);
+        }
+        else { // not reversed case
+          aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], prevNod[3],
+                                       nextNod[0], nextNod[1], nextNod[2], nextNod[3],
+                                       prevNod[4], prevNod[5], prevNod[6], prevNod[7],
+                                       nextNod[4], nextNod[5], nextNod[6], nextNod[7],
+                                       midlNod[0], midlNod[1], midlNod[2], midlNod[3]);
+        }
+        break;
+      }
+      default: {
+        // realized for extrusion only
+        //vector<const SMDS_MeshNode*> polyedre_nodes (nbNodes*2 + 4*nbNodes);
+        //vector<int> quantities (nbNodes + 2);
+        
+        //quantities[0] = nbNodes; // bottom of prism
+        //for (int inode = 0; inode < nbNodes; inode++) {
+        //  polyedre_nodes[inode] = prevNod[inode];
+        //}
+
+        //quantities[1] = nbNodes; // top of prism
+        //for (int inode = 0; inode < nbNodes; inode++) {
+        //  polyedre_nodes[nbNodes + inode] = nextNod[inode];
+        //}
+        
+        //for (int iface = 0; iface < nbNodes; iface++) {
+        //  quantities[iface + 2] = 4;
+        //  int inextface = (iface == nbNodes - 1) ? 0 : iface + 1;
+        //  polyedre_nodes[2*nbNodes + 4*iface + 0] = prevNod[iface];
+        //  polyedre_nodes[2*nbNodes + 4*iface + 1] = prevNod[inextface];
+        //  polyedre_nodes[2*nbNodes + 4*iface + 2] = nextNod[inextface];
+        //  polyedre_nodes[2*nbNodes + 4*iface + 3] = nextNod[iface];
+        //}
+        //aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities);
+        break;
+      }
       }
-      break;
     }
-    default: {
+
+    if(!aNewElem) {
       // realized for extrusion only
       vector<const SMDS_MeshNode*> polyedre_nodes (nbNodes*2 + 4*nbNodes);
       vector<int> quantities (nbNodes + 2);
@@ -2153,9 +2740,10 @@ static void sweepElement(SMESHDS_Mesh*                         aMesh,
       }
       aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities);
     }
-    }
-    if ( aNewElem )
+
+    if ( aNewElem ) {
       newElems.push_back( aNewElem );
+    }
 
     // set new prev nodes
     for ( iNode = 0; iNode < nbNodes; iNode++ )
@@ -2173,26 +2761,33 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
                        TNodeOfNodeListMap &          mapNewNodes,
                        TElemOfElemListMap &          newElemsMap,
                        TElemOfVecOfNnlmiMap &        elemNewNodesMap,
-                       set<const SMDS_MeshElement*>& elemSet)
+                       set<const SMDS_MeshElement*>& elemSet,
+                       const int nbSteps)
 {
   ASSERT( newElemsMap.size() == elemNewNodesMap.size() );
 
   // Find nodes belonging to only one initial element - sweep them to get edges.
 
   TNodeOfNodeListMapItr nList = mapNewNodes.begin();
-  for ( ; nList != mapNewNodes.end(); nList++ )
-  {
+  for ( ; nList != mapNewNodes.end(); nList++ ) {
     const SMDS_MeshNode* node =
       static_cast<const SMDS_MeshNode*>( nList->first );
     SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator();
     int nbInitElems = 0;
-    while ( eIt->more() && nbInitElems < 2 )
-      if ( elemSet.find( eIt->next() ) != elemSet.end() )
+    const SMDS_MeshElement* el;
+    while ( eIt->more() && nbInitElems < 2 ) {
+      el = eIt->next();
+      //if ( elemSet.find( eIt->next() ) != elemSet.end() )
+      if ( elemSet.find(el) != elemSet.end() )
         nbInitElems++;
+    }
     if ( nbInitElems < 2 ) {
-      vector<TNodeOfNodeListMapItr> newNodesItVec( 1, nList );
-      list<const SMDS_MeshElement*> newEdges;
-      sweepElement( aMesh, node, newNodesItVec, newEdges );
+      bool NotCreateEdge = el->IsQuadratic() && el->IsMediumNode(node);
+      if(!NotCreateEdge) {
+        vector<TNodeOfNodeListMapItr> newNodesItVec( 1, nList );
+        list<const SMDS_MeshElement*> newEdges;
+        sweepElement( aMesh, node, newNodesItVec, newEdges, nbSteps );
+      }
     }
   }
 
@@ -2201,16 +2796,22 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
 
   TElemOfElemListMap::iterator   itElem      = newElemsMap.begin();
   TElemOfVecOfNnlmiMap::iterator itElemNodes = elemNewNodesMap.begin();
-  for ( ; itElem != newElemsMap.end(); itElem++, itElemNodes++ )
-  {
+  for ( ; itElem != newElemsMap.end(); itElem++, itElemNodes++ ) {
     const SMDS_MeshElement* elem = itElem->first;
     vector<TNodeOfNodeListMapItr>& vecNewNodes = itElemNodes->second;
 
-    if ( elem->GetType() == SMDSAbs_Edge )
-    {
-      // create a ceiling edge
-      aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
-                     vecNewNodes[ 1 ]->second.back() );
+    if ( elem->GetType() == SMDSAbs_Edge ) {
+      if(!elem->IsQuadratic()) {
+        // create a ceiling edge
+        aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
+                       vecNewNodes[ 1 ]->second.back() );
+      }
+      else {
+        // create a ceiling edge
+        aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
+                       vecNewNodes[ 1 ]->second.back(),
+                       vecNewNodes[ 2 ]->second.back());
+      }
     }
     if ( elem->GetType() != SMDSAbs_Face )
       continue;
@@ -2220,43 +2821,72 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
     set<const SMDS_MeshElement*> avoidSet;
     avoidSet.insert( elem );
 
-    // loop on a face nodes
     set<const SMDS_MeshNode*> aFaceLastNodes;
     int iNode, nbNodes = vecNewNodes.size();
-    for ( iNode = 0; iNode < nbNodes; iNode++ )
-    {
-      aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() );
-      // look for free links of a face
-      int iNext = ( iNode + 1 == nbNodes ) ? 0 : iNode + 1;
-      const SMDS_MeshNode* n1 = vecNewNodes[ iNode ]->first;
-      const SMDS_MeshNode* n2 = vecNewNodes[ iNext ]->first;
-      // check if a link is free
-      if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet ))
-      {
-        hasFreeLinks = true;
-        // make an edge and a ceiling for a new edge
-        if ( !aMesh->FindEdge( n1, n2 ))
-          aMesh->AddEdge( n1, n2 );
-        n1 = vecNewNodes[ iNode ]->second.back();
-        n2 = vecNewNodes[ iNext ]->second.back();
-        if ( !aMesh->FindEdge( n1, n2 ))
-          aMesh->AddEdge( n1, n2 );
+    if(!elem->IsQuadratic()) {
+      // loop on a face nodes
+      for ( iNode = 0; iNode < nbNodes; iNode++ ) {
+        aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() );
+        // look for free links of a face
+        int iNext = ( iNode + 1 == nbNodes ) ? 0 : iNode + 1;
+        const SMDS_MeshNode* n1 = vecNewNodes[ iNode ]->first;
+        const SMDS_MeshNode* n2 = vecNewNodes[ iNext ]->first;
+        // check if a link is free
+        if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet )) {
+          hasFreeLinks = true;
+          // make an edge and a ceiling for a new edge
+          if ( !aMesh->FindEdge( n1, n2 )) {
+            aMesh->AddEdge( n1, n2 );
+          }
+          n1 = vecNewNodes[ iNode ]->second.back();
+          n2 = vecNewNodes[ iNext ]->second.back();
+          if ( !aMesh->FindEdge( n1, n2 )) {
+            aMesh->AddEdge( n1, n2 );
+          }
+        }
+      }
+    }
+    else { // elem is quadratic face
+      int nbn = nbNodes/2;
+      for ( iNode = 0; iNode < nbn; iNode++ ) {
+        aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() );
+        int iNext = ( iNode + 1 == nbn ) ? 0 : iNode + 1;
+        const SMDS_MeshNode* n1 = vecNewNodes[ iNode ]->first;
+        const SMDS_MeshNode* n2 = vecNewNodes[ iNext ]->first;
+        // check if a link is free
+        if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet )) {
+          hasFreeLinks = true;
+          // make an edge and a ceiling for a new edge
+          // find medium node
+          const SMDS_MeshNode* n3 = vecNewNodes[ iNode+nbn ]->first;
+          if ( !aMesh->FindEdge( n1, n2, n3 )) {
+            aMesh->AddEdge( n1, n2, n3 );
+          }
+          n1 = vecNewNodes[ iNode ]->second.back();
+          n2 = vecNewNodes[ iNext ]->second.back();
+          n3 = vecNewNodes[ iNode+nbn ]->second.back();
+          if ( !aMesh->FindEdge( n1, n2, n3 )) {
+            aMesh->AddEdge( n1, n2, n3 );
+          }
+        }
+      }
+      for ( iNode = nbn; iNode < 2*nbn; iNode++ ) {
+        aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() );
       }
     }
+
     // sweep free links into faces
 
-    if ( hasFreeLinks )
-    {
+    if ( hasFreeLinks )  {
       list<const SMDS_MeshElement*> & newVolumes = itElem->second;
-      int iStep, nbSteps = vecNewNodes[0]->second.size();
+      int iStep; //, nbSteps = vecNewNodes[0]->second.size();
       int iVol, volNb, nbVolumesByStep = newVolumes.size() / nbSteps;
 
       set<const SMDS_MeshNode*> initNodeSet, faceNodeSet;
       for ( iNode = 0; iNode < nbNodes; iNode++ )
         initNodeSet.insert( vecNewNodes[ iNode ]->first );
 
-      for ( volNb = 0; volNb < nbVolumesByStep; volNb++ )
-      {
+      for ( volNb = 0; volNb < nbVolumesByStep; volNb++ ) {
         list<const SMDS_MeshElement*>::iterator v = newVolumes.begin();
         iVol = 0;
         while ( iVol++ < volNb ) v++;
@@ -2264,36 +2894,50 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
         list< int > fInd;
         SMDS_VolumeTool vTool( *v );
         int iF, nbF = vTool.NbFaces();
-        for ( iF = 0; iF < nbF; iF ++ )
+        for ( iF = 0; iF < nbF; iF ++ ) {
           if (vTool.IsFreeFace( iF ) &&
               vTool.GetFaceNodes( iF, faceNodeSet ) &&
               initNodeSet != faceNodeSet) // except an initial face
             fInd.push_back( iF );
+        }
         if ( fInd.empty() )
           continue;
 
         // create faces for all steps
-        for ( iStep = 0; iStep < nbSteps; iStep++ )
-        {
+        for ( iStep = 0; iStep < nbSteps; iStep++ )  {
           vTool.Set( *v );
           vTool.SetExternalNormal();
           list< int >::iterator ind = fInd.begin();
-          for ( ; ind != fInd.end(); ind++ )
-          {
+          for ( ; ind != fInd.end(); ind++ ) {
             const SMDS_MeshNode** nodes = vTool.GetFaceNodes( *ind );
-            switch ( vTool.NbFaceNodes( *ind ) ) {
+            int nbn = vTool.NbFaceNodes( *ind );
+            //switch ( vTool.NbFaceNodes( *ind ) ) {
+            switch ( nbn ) {
             case 3:
               aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ); break;
             case 4:
               aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ); break;
             default:
               {
-                int nbPolygonNodes = vTool.NbFaceNodes( *ind );
-                vector<const SMDS_MeshNode*> polygon_nodes (nbPolygonNodes);
-                for (int inode = 0; inode < nbPolygonNodes; inode++) {
-                  polygon_nodes[inode] = nodes[inode];
+                if( (*v)->IsQuadratic() ) {
+                  if(nbn==6) {
+                    aMesh->AddFace(nodes[0], nodes[2], nodes[4],
+                                   nodes[1], nodes[3], nodes[5]); break;
+                  }
+                  else {
+                      aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
+                                     nodes[1], nodes[3], nodes[5], nodes[7]);
+                      break;
+                  }
+                }
+                else {
+                  int nbPolygonNodes = vTool.NbFaceNodes( *ind );
+                  vector<const SMDS_MeshNode*> polygon_nodes (nbPolygonNodes);
+                  for (int inode = 0; inode < nbPolygonNodes; inode++) {
+                    polygon_nodes[inode] = nodes[inode];
+                  }
+                  aMesh->AddPolygonalFace(polygon_nodes);
                 }
-                aMesh->AddPolygonalFace(polygon_nodes);
                 break;
               }
             }
@@ -2308,12 +2952,13 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
     // make a ceiling face with a normal external to a volume
 
     SMDS_VolumeTool lastVol( itElem->second.back() );
+
     int iF = lastVol.GetFaceIndex( aFaceLastNodes );
-    if ( iF >= 0 )
-    {
+    if ( iF >= 0 ) {
       lastVol.SetExternalNormal();
       const SMDS_MeshNode** nodes = lastVol.GetFaceNodes( iF );
-      switch ( lastVol.NbFaceNodes( iF ) ) {
+      int nbn = lastVol.NbFaceNodes( iF );
+      switch ( nbn ) {
       case 3:
         if (!hasFreeLinks ||
             !aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ]))
@@ -2326,18 +2971,36 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
         break;
       default:
         {
-          int nbPolygonNodes = lastVol.NbFaceNodes( iF );
-          vector<const SMDS_MeshNode*> polygon_nodes (nbPolygonNodes);
-          for (int inode = 0; inode < nbPolygonNodes; inode++) {
-            polygon_nodes[inode] = nodes[inode];
+          if(itElem->second.back()->IsQuadratic()) {
+            if(nbn==6) {
+              if (!hasFreeLinks ||
+                  !aMesh->FindFace(nodes[0], nodes[2], nodes[4],
+                                   nodes[1], nodes[3], nodes[5]) ) {
+                aMesh->AddFace(nodes[0], nodes[2], nodes[4],
+                               nodes[1], nodes[3], nodes[5]); break;
+              }
+            }
+            else { // nbn==8
+              if (!hasFreeLinks ||
+                  !aMesh->FindFace(nodes[0], nodes[2], nodes[4], nodes[6],
+                                   nodes[1], nodes[3], nodes[5], nodes[7]) )
+                aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
+                               nodes[1], nodes[3], nodes[5], nodes[7]);
+            }
+          }
+          else {
+            int nbPolygonNodes = lastVol.NbFaceNodes( iF );
+            vector<const SMDS_MeshNode*> polygon_nodes (nbPolygonNodes);
+            for (int inode = 0; inode < nbPolygonNodes; inode++) {
+              polygon_nodes[inode] = nodes[inode];
+            }
+            if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes))
+              aMesh->AddPolygonalFace(polygon_nodes);
           }
-          if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes))
-            aMesh->AddPolygonalFace(polygon_nodes);
         }
         break;
       }
     }
-
   } // loop on swept elements
 }
 
@@ -2355,6 +3018,8 @@ void SMESH_MeshEditor::RotationSweep(set<const SMDS_MeshElement*> & theElems,
   MESSAGE( "RotationSweep()");
   gp_Trsf aTrsf;
   aTrsf.SetRotation( theAxis, theAngle );
+  gp_Trsf aTrsf2;
+  aTrsf2.SetRotation( theAxis, theAngle/2. );
 
   gp_Lin aLine( theAxis );
   double aSqTol = theTol * theTol;
@@ -2367,8 +3032,7 @@ void SMESH_MeshEditor::RotationSweep(set<const SMDS_MeshElement*> & theElems,
 
   // loop on theElems
   set< const SMDS_MeshElement* >::iterator itElem;
-  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
-  {
+  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
     const SMDS_MeshElement* elem = (*itElem);
     if ( !elem )
       continue;
@@ -2383,8 +3047,7 @@ void SMESH_MeshEditor::RotationSweep(set<const SMDS_MeshElement*> & theElems,
       const SMDS_MeshNode* node =
         static_cast<const SMDS_MeshNode*>( itN->next() );
       TNodeOfNodeListMapItr nIt = mapNewNodes.find( node );
-      if ( nIt == mapNewNodes.end() )
-      {
+      if ( nIt == mapNewNodes.end() ) {
         nIt = mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
         list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
 
@@ -2396,19 +3059,53 @@ void SMESH_MeshEditor::RotationSweep(set<const SMDS_MeshElement*> & theElems,
         const SMDS_MeshNode * newNode = node;
         for ( int i = 0; i < theNbSteps; i++ ) {
           if ( !isOnAxis ) {
-            aTrsf.Transforms( coord[0], coord[1], coord[2] );
+            if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
+              // create two nodes
+              aTrsf2.Transforms( coord[0], coord[1], coord[2] );
+              //aTrsf.Transforms( coord[0], coord[1], coord[2] );
+              newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+              listNewNodes.push_back( newNode );
+              aTrsf2.Transforms( coord[0], coord[1], coord[2] );
+              //aTrsf.Transforms( coord[0], coord[1], coord[2] );
+            }
+            else {
+              aTrsf.Transforms( coord[0], coord[1], coord[2] );
+            }
             newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
           }
-          listNewNodes.push_back( newNode );
+          listNewNodes.push_back( newNode );
+        }
+      }
+      else {
+        // if current elem is quadratic and current node is not medium
+        // we have to check - may be it is needed to insert additional nodes
+        if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
+          list< const SMDS_MeshNode* > & listNewNodes = nIt->second;
+          if(listNewNodes.size()==theNbSteps) {
+            listNewNodes.clear();
+            // make new nodes
+            gp_XYZ aXYZ( node->X(), node->Y(), node->Z() );
+            double coord[3];
+            aXYZ.Coord( coord[0], coord[1], coord[2] );
+            const SMDS_MeshNode * newNode = node;
+            for(int i = 0; i<theNbSteps; i++) {
+              aTrsf2.Transforms( coord[0], coord[1], coord[2] );
+              newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+              listNewNodes.push_back( newNode );
+              aTrsf2.Transforms( coord[0], coord[1], coord[2] );
+              newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+              listNewNodes.push_back( newNode );
+            }
+          }
         }
       }
       newNodesItVec.push_back( nIt );
     }
     // make new elements
-    sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem] );
+    sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], theNbSteps );
   }
 
-  makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems );
+  makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps );
 
 }
 
@@ -2493,19 +3190,23 @@ void SMESH_MeshEditor::ExtrusionSweep
 {
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
+  int nbsteps = theParams.mySteps->Length();
+
   TNodeOfNodeListMap mapNewNodes;
+  //TNodeOfNodeVecMap mapNewNodes;
   TElemOfVecOfNnlmiMap mapElemNewNodes;
+  //TElemOfVecOfMapNodesMap mapElemNewNodes;
 
   // loop on theElems
   set< const SMDS_MeshElement* >::iterator itElem;
-  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
-  {
+  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
     // check element type
     const SMDS_MeshElement* elem = (*itElem);
     if ( !elem )
       continue;
 
     vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
+    //vector<TNodeOfNodeVecMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
     newNodesItVec.reserve( elem->NbNodes() );
 
     // loop on elem nodes
@@ -2516,15 +3217,33 @@ void SMESH_MeshEditor::ExtrusionSweep
       const SMDS_MeshNode* node =
         static_cast<const SMDS_MeshNode*>( itN->next() );
       TNodeOfNodeListMap::iterator nIt = mapNewNodes.find( node );
-      if ( nIt == mapNewNodes.end() )
-      {
+      //TNodeOfNodeVecMap::iterator nIt = mapNewNodes.find( node );
+      if ( nIt == mapNewNodes.end() ) {
         nIt = mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
+        //nIt = mapNewNodes.insert( make_pair( node, vector<const SMDS_MeshNode*>() )).first;
         list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
+        //vector<const SMDS_MeshNode*>& vecNewNodes = nIt->second;
+        //vecNewNodes.reserve(nbsteps);
 
         // make new nodes
         double coord[] = { node->X(), node->Y(), node->Z() };
-        int nbsteps = theParams.mySteps->Length();
+        //int nbsteps = theParams.mySteps->Length();
         for ( int i = 0; i < nbsteps; i++ ) {
+          if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
+            // create additional node
+            double x = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1)/2.;
+            double y = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1)/2.;
+            double z = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1)/2.;
+            if( theFlags & EXTRUSION_FLAG_SEW ) {
+              const SMDS_MeshNode * newNode = CreateNode(x, y, z,
+                                                         theTolerance, theParams.myNodes);
+              listNewNodes.push_back( newNode );
+            }
+            else {
+              const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z);
+              listNewNodes.push_back( newNode );
+            }
+          }
           //aTrsf.Transforms( coord[0], coord[1], coord[2] );
           coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1);
           coord[1] = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1);
@@ -2533,20 +3252,59 @@ void SMESH_MeshEditor::ExtrusionSweep
             const SMDS_MeshNode * newNode = CreateNode(coord[0], coord[1], coord[2],
                                                        theTolerance, theParams.myNodes);
             listNewNodes.push_back( newNode );
+            //vecNewNodes[i]=newNode;
           }
           else {
             const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
             listNewNodes.push_back( newNode );
+            //vecNewNodes[i]=newNode;
+          }
+        }
+      }
+      else {
+        // if current elem is quadratic and current node is not medium
+        // we have to check - may be it is needed to insert additional nodes
+        if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
+          list< const SMDS_MeshNode* > & listNewNodes = nIt->second;
+          if(listNewNodes.size()==nbsteps) {
+            listNewNodes.clear();
+            double coord[] = { node->X(), node->Y(), node->Z() };
+            for ( int i = 0; i < nbsteps; i++ ) {
+              double x = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1);
+              double y = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1);
+              double z = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1);
+              if( theFlags & EXTRUSION_FLAG_SEW ) {
+                const SMDS_MeshNode * newNode = CreateNode(x, y, z,
+                                                           theTolerance, theParams.myNodes);
+                listNewNodes.push_back( newNode );
+              }
+              else {
+                const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z);
+                listNewNodes.push_back( newNode );
+              }
+              coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1);
+              coord[1] = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1);
+              coord[2] = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1);
+              if( theFlags & EXTRUSION_FLAG_SEW ) {
+                const SMDS_MeshNode * newNode = CreateNode(coord[0], coord[1], coord[2],
+                                                           theTolerance, theParams.myNodes);
+                listNewNodes.push_back( newNode );
+              }
+              else {
+                const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+                listNewNodes.push_back( newNode );
+              }
+            }
           }
         }
       }
       newNodesItVec.push_back( nIt );
     }
     // make new elements
-    sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem] );
+    sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], nbsteps );
   }
   if( theFlags & EXTRUSION_FLAG_BOUNDARY ) {
-    makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems );
+    makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps );
   }
 }
 
@@ -2855,6 +3613,14 @@ SMESH_MeshEditor::Extrusion_Error
          }
 
          // make new node
+          if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
+            // create additional node
+            double x = ( aPN1.X() + aPN0.X() )/2.;
+            double y = ( aPN1.Y() + aPN0.Y() )/2.;
+            double z = ( aPN1.Z() + aPN0.Z() )/2.;
+            const SMDS_MeshNode* newNode = aMesh->AddNode(x,y,z);
+            listNewNodes.push_back( newNode );
+          }
          aX = aPN1.X();
          aY = aPN1.Y();
          aZ = aPN1.Z();
@@ -2867,13 +3633,44 @@ SMESH_MeshEditor::Extrusion_Error
          aDT0x = aDT1x;
        }
       }
+
+      else {
+        // if current elem is quadratic and current node is not medium
+        // we have to check - may be it is needed to insert additional nodes
+        if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
+          list< const SMDS_MeshNode* > & listNewNodes = nIt->second;
+          if(listNewNodes.size()==aNbTP-1) {
+            vector<const SMDS_MeshNode*> aNodes(2*(aNbTP-1));
+            gp_XYZ P(node->X(), node->Y(), node->Z());
+            list< const SMDS_MeshNode* >::iterator it = listNewNodes.begin();
+            int i;
+            for(i=0; i<aNbTP-1; i++) {
+              const SMDS_MeshNode* N = *it;
+              double x = ( N->X() + P.X() )/2.;
+              double y = ( N->Y() + P.Y() )/2.;
+              double z = ( N->Z() + P.Z() )/2.;
+              const SMDS_MeshNode* newN = aMesh->AddNode(x,y,z);
+              aNodes[2*i] = newN;
+              aNodes[2*i+1] = N;
+              P = gp_XYZ(N->X(),N->Y(),N->Z());
+            }
+            listNewNodes.clear();
+            for(i=0; i<2*(aNbTP-1); i++) {
+              listNewNodes.push_back(aNodes[i]);
+            }
+          }
+        }
+      }
+
       newNodesItVec.push_back( nIt );
     }
     // make new elements
-    sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem] );
+    sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem],
+                  newNodesItVec[0]->second.size() );
   }
 
-  makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElements );
+  makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElements,
+            aNbTP-1 );
 
   return EXTR_OK;
 }
@@ -2908,8 +3705,7 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
 
   // loop on theElems
   set< const SMDS_MeshElement* >::iterator itElem;
-  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
-  {
+  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
     const SMDS_MeshElement* elem = (*itElem);
     if ( !elem )
       continue;
@@ -2979,8 +3775,7 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
     { 0, 1, 2, 3, 4, 5, 6, 7 }   // FORWARD
   };
 
-  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
-  {
+  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
     const SMDS_MeshElement* elem = (*itElem);
     if ( !elem || elem->GetType() == SMDSAbs_Node )
       continue;
@@ -3071,12 +3866,46 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
       else
         i = index[ nbNodes - 4 ];
 
+    if(elem->IsQuadratic()) {
+      static int anIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+      i = anIds;
+      if(needReverse) {
+        if(nbNodes==3) { // quadratic edge
+          static int anIds[] = {1,0,2};
+          i = anIds;
+        }
+        else if(nbNodes==6) { // quadratic triangle
+          static int anIds[] = {0,2,1,5,4,3};
+          i = anIds;
+        }
+        else if(nbNodes==8) { // quadratic quadrangle
+          static int anIds[] = {0,3,2,1,7,6,5,4};
+          i = anIds;
+        }
+        else if(nbNodes==10) { // quadratic tetrahedron of 10 nodes
+          static int anIds[] = {0,2,1,3,6,5,4,7,9,8};
+          i = anIds;
+        }
+        else if(nbNodes==13) { // quadratic pyramid of 13 nodes
+          static int anIds[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
+          i = anIds;
+        }
+        else if(nbNodes==15) { // quadratic pentahedron with 15 nodes
+          static int anIds[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13};
+          i = anIds;
+        }
+        else { // nbNodes==20 - quadratic hexahedron with 20 nodes
+          static int anIds[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
+          i = anIds;
+        }
+      }
+    }
+
     // find transformed nodes
     const SMDS_MeshNode* nodes[8];
     int iNode = 0;
     SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-    while ( itN->more() )
-    {
+    while ( itN->more() ) {
       const SMDS_MeshNode* node =
         static_cast<const SMDS_MeshNode*>( itN->next() );
       TNodeNodeMap::iterator nodeMapIt = nodeMap.find( node );
@@ -3087,18 +3916,26 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
     if ( iNode != nbNodes )
       continue; // not all nodes transformed
 
-    if ( theCopy )
-    {
+    if ( theCopy ) {
       // add a new element
       switch ( elemType ) {
       case SMDSAbs_Edge:
-        aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ] );
+        if ( nbNodes == 2 )
+          aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ] );
+        else
+          aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] );
         break;
       case SMDSAbs_Face:
         if ( nbNodes == 3 )
           aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] );
-        else
+        else if(nbNodes==4)
           aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ]);
+        else if(nbNodes==6)
+          aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
+                         nodes[4], nodes[5]);
+        else // nbNodes==8
+          aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
+                         nodes[4], nodes[5], nodes[6], nodes[7]);
         break;
       case SMDSAbs_Volume:
         if ( nbNodes == 4 )
@@ -3112,6 +3949,22 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
         else if ( nbNodes == 5 )
           aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
                             nodes[ 4 ]);
+        else if(nbNodes==10)
+          aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
+                           nodes[5], nodes[6], nodes[7], nodes[8], nodes[9]);
+        else if(nbNodes==13)
+          aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
+                           nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
+                           nodes[10], nodes[11], nodes[12]);
+        else if(nbNodes==15)
+          aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
+                           nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
+                           nodes[10], nodes[11], nodes[12], nodes[13], nodes[14]);
+        else // nbNodes==20
+          aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
+                           nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
+                           nodes[10], nodes[11], nodes[12], nodes[13], nodes[14],
+                           nodes[15], nodes[16], nodes[17], nodes[18], nodes[19]);
         break;
       default:;
       }
@@ -3275,13 +4128,11 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
   // Fill nodeNodeMap and elems
 
   TListOfListOfNodes::iterator grIt = theGroupsOfNodes.begin();
-  for ( ; grIt != theGroupsOfNodes.end(); grIt++ )
-  {
+  for ( ; grIt != theGroupsOfNodes.end(); grIt++ ) {
     list<const SMDS_MeshNode*>& nodes = *grIt;
     list<const SMDS_MeshNode*>::iterator nIt = nodes.begin();
     const SMDS_MeshNode* nToKeep = *nIt;
-    for ( ; nIt != nodes.end(); nIt++ )
-    {
+    for ( ; nIt != nodes.end(); nIt++ ) {
       const SMDS_MeshNode* nToRemove = *nIt;
       nodeNodeMap.insert( TNodeNodeMap::value_type( nToRemove, nToKeep ));
       if ( nToRemove != nToKeep ) {
@@ -3290,15 +4141,16 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
       }
 
       SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator();
-      while ( invElemIt->more() )
-        elems.insert( invElemIt->next() );
+      while ( invElemIt->more() ) {
+        const SMDS_MeshElement* elem = invElemIt->next();
+          elems.insert(elem);
+      }
     }
   }
   // Change element nodes or remove an element
 
   set<const SMDS_MeshElement*>::iterator eIt = elems.begin();
-  for ( ; eIt != elems.end(); eIt++ )
-  {
+  for ( ; eIt != elems.end(); eIt++ ) {
     const SMDS_MeshElement* elem = *eIt;
     int nbNodes = elem->NbNodes();
     int aShapeId = FindShape( elem );
@@ -3309,8 +4161,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
 
     // get new seq of nodes
     SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-    while ( itN->more() )
-    {
+    while ( itN->more() ) {
       const SMDS_MeshNode* n =
         static_cast<const SMDS_MeshNode*>( itN->next() );
 
@@ -3330,8 +4181,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
 
     bool isOk = true;
     int nbUniqueNodes = nodeSet.size();
-    if ( nbNodes != nbUniqueNodes ) // some nodes stick
-    {
+    if ( nbNodes != nbUniqueNodes ) { // some nodes stick
       // Polygons and Polyhedral volumes
       if (elem->IsPoly()) {
 
@@ -3360,15 +4210,18 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
                 aMesh->SetMeshElementOnShape(newElem, aShapeId);
             }
             aMesh->ChangeElementNodes(elem, &polygons_nodes[inode], quantities[nbNew - 1]);
-          } else {
+          }
+          else {
             rmElemIds.push_back(elem->GetID());
           }
 
-        } else if (elem->GetType() == SMDSAbs_Volume) {
+        }
+        else if (elem->GetType() == SMDSAbs_Volume) {
           // Polyhedral volume
           if (nbUniqueNodes < 4) {
             rmElemIds.push_back(elem->GetID());
-          } else {
+          }
+          else {
             // each face has to be analized in order to check volume validity
             const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
               static_cast<const SMDS_PolyhedralVolumeOfNodes*>( elem );
@@ -3403,11 +4256,13 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
               else
                 rmElemIds.push_back(elem->GetID());
 
-            } else {
+            }
+            else {
               rmElemIds.push_back(elem->GetID());
             }
           }
-        } else {
+        }
+        else {
         }
 
         continue;
@@ -3478,7 +4333,96 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
         else
           isOk = false;
         break;
-      case 8: { //////////////////////////////////// HEXAHEDRON
+      case 8: { 
+        if(elem->IsQuadratic()) { // Quadratic quadrangle
+          //   1    5    2
+          //    +---+---+
+          //    |       |
+          //    |       |
+          //   4+       +6
+          //    |       |
+          //    |       |
+          //    +---+---+
+          //   0    7    3
+          isOk = false;
+          if(nbRepl==3) {
+            nbUniqueNodes = 6;
+            if( iRepl[0]==0 && iRepl[1]==1 && iRepl[2]==4 ) {
+              uniqueNodes[0] = curNodes[0];
+              uniqueNodes[1] = curNodes[2];
+              uniqueNodes[2] = curNodes[3];
+              uniqueNodes[3] = curNodes[5];
+              uniqueNodes[4] = curNodes[6];
+              uniqueNodes[5] = curNodes[7];
+              isOk = true;
+            }
+            if( iRepl[0]==0 && iRepl[1]==3 && iRepl[2]==7 ) {
+              uniqueNodes[0] = curNodes[0];
+              uniqueNodes[1] = curNodes[1];
+              uniqueNodes[2] = curNodes[2];
+              uniqueNodes[3] = curNodes[4];
+              uniqueNodes[4] = curNodes[5];
+              uniqueNodes[5] = curNodes[6];
+              isOk = true;
+            }
+            if( iRepl[0]==0 && iRepl[1]==4 && iRepl[2]==7 ) {
+              uniqueNodes[0] = curNodes[1];
+              uniqueNodes[1] = curNodes[2];
+              uniqueNodes[2] = curNodes[3];
+              uniqueNodes[3] = curNodes[5];
+              uniqueNodes[4] = curNodes[6];
+              uniqueNodes[5] = curNodes[0];
+              isOk = true;
+            }
+            if( iRepl[0]==1 && iRepl[1]==2 && iRepl[2]==5 ) {
+              uniqueNodes[0] = curNodes[0];
+              uniqueNodes[1] = curNodes[1];
+              uniqueNodes[2] = curNodes[3];
+              uniqueNodes[3] = curNodes[4];
+              uniqueNodes[4] = curNodes[6];
+              uniqueNodes[5] = curNodes[7];
+              isOk = true;
+            }
+            if( iRepl[0]==1 && iRepl[1]==4 && iRepl[2]==5 ) {
+              uniqueNodes[0] = curNodes[0];
+              uniqueNodes[1] = curNodes[2];
+              uniqueNodes[2] = curNodes[3];
+              uniqueNodes[3] = curNodes[1];
+              uniqueNodes[4] = curNodes[6];
+              uniqueNodes[5] = curNodes[7];
+              isOk = true;
+            }
+            if( iRepl[0]==2 && iRepl[1]==3 && iRepl[2]==6 ) {
+              uniqueNodes[0] = curNodes[0];
+              uniqueNodes[1] = curNodes[1];
+              uniqueNodes[2] = curNodes[2];
+              uniqueNodes[3] = curNodes[4];
+              uniqueNodes[4] = curNodes[5];
+              uniqueNodes[5] = curNodes[7];
+              isOk = true;
+            }
+            if( iRepl[0]==2 && iRepl[1]==5 && iRepl[2]==6 ) {
+              uniqueNodes[0] = curNodes[0];
+              uniqueNodes[1] = curNodes[1];
+              uniqueNodes[2] = curNodes[3];
+              uniqueNodes[3] = curNodes[4];
+              uniqueNodes[4] = curNodes[2];
+              uniqueNodes[5] = curNodes[7];
+              isOk = true;
+            }
+            if( iRepl[0]==3 && iRepl[1]==6 && iRepl[2]==7 ) {
+              uniqueNodes[0] = curNodes[0];
+              uniqueNodes[1] = curNodes[1];
+              uniqueNodes[2] = curNodes[2];
+              uniqueNodes[3] = curNodes[4];
+              uniqueNodes[4] = curNodes[5];
+              uniqueNodes[5] = curNodes[3];
+              isOk = true;
+            }
+          }
+          break;
+        }
+        //////////////////////////////////// HEXAHEDRON
         isOk = false;
         SMDS_VolumeTool hexa (elem);
         hexa.SetExternalNormal();
@@ -3682,11 +4626,13 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
           }
           aMesh->ChangePolyhedronNodes( elem, poly_nodes, quantities );
         }
-      } else {
+      }
+      else {
         // Change regular element or polygon
         aMesh->ChangeElementNodes( elem, uniqueNodes, nbUniqueNodes );
       }
-    } else {
+    }
+    else {
       // Remove invalid regular element or invalid polygon
       rmElemIds.push_back( elem->GetID() );
     }
@@ -3779,14 +4725,52 @@ const SMDS_MeshElement*
         i1 = iNode - 1;
     }
     // find a n2 linked to n1
-    for ( iNode = 0; iNode < 2; iNode++ ) {
-      if ( iNode ) // node before n1
-        n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ];
-      else         // node after n1
-        n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ];
-      if ( n == n2 )
-        return elem;
+    if(!elem->IsQuadratic()) {
+      for ( iNode = 0; iNode < 2; iNode++ ) {
+        if ( iNode ) // node before n1
+          n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ];
+        else         // node after n1
+          n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ];
+        if ( n == n2 )
+          return elem;
+      }
     }
+    else { // analysis for quadratic elements
+      bool IsFind = false;
+      // check using only corner nodes
+      for ( iNode = 0; iNode < 2; iNode++ ) {
+        if ( iNode ) // node before n1
+          n = faceNodes[ i1 == 0 ? nbN/2 - 1 : i1 - 1 ];
+        else         // node after n1
+          n = faceNodes[ i1 + 1 == nbN/2 ? 0 : i1 + 1 ];
+        if ( n == n2 )
+          IsFind = true;
+      }
+      if(IsFind) {
+        return elem;
+      }
+      else {
+        // check using all nodes
+        const SMDS_QuadraticFaceOfNodes* F =
+          static_cast<const SMDS_QuadraticFaceOfNodes*>(elem);
+        // use special nodes iterator
+        SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+        while ( anIter->more() ) {
+          faceNodes[iNode] = static_cast<const SMDS_MeshNode*>(anIter->next());
+          if ( faceNodes[ iNode++ ] == n1 )
+            i1 = iNode - 1;
+        }
+        for ( iNode = 0; iNode < 2; iNode++ ) {
+          if ( iNode ) // node before n1
+            n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ];
+          else         // node after n1
+            n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ];
+          if ( n == n2 ) {
+            return elem;
+          }
+        }
+      }
+    } // end analysis for quadratic elements
   }
   return 0;
 }
@@ -3830,12 +4814,12 @@ static bool findFreeBorder (const SMDS_MeshNode*                theFirstNode,
   theNodes.push_back( theFirstNode );
   theNodes.push_back( theSecondNode );
 
-  const SMDS_MeshNode* nodes [5], *nIgnore = theFirstNode, * nStart = theSecondNode;
+  //vector<const SMDS_MeshNode*> nodes;
+  const SMDS_MeshNode *nIgnore = theFirstNode, *nStart = theSecondNode;
   set < const SMDS_MeshElement* > foundElems;
   bool needTheLast = ( theLastNode != 0 );
 
-  while ( nStart != theLastNode )
-  {
+  while ( nStart != theLastNode ) {
     if ( nStart == theFirstNode )
       return !needTheLast;
 
@@ -3846,13 +4830,24 @@ static bool findFreeBorder (const SMDS_MeshNode*                theFirstNode,
     SMDS_ElemIteratorPtr invElemIt = nStart->facesIterator();
     while ( invElemIt->more() ) {
       const SMDS_MeshElement* e = invElemIt->next();
-      if ( e == curElem || foundElems.insert( e ).second )
-      {
+      if ( e == curElem || foundElems.insert( e ).second ) {
         // get nodes
-        SMDS_ElemIteratorPtr nIt = e->nodesIterator();
         int iNode = 0, nbNodes = e->NbNodes();
-        while ( nIt->more() )
-          nodes[ iNode++ ] = static_cast<const SMDS_MeshNode*>( nIt->next() );
+        const SMDS_MeshNode* nodes[nbNodes+1];
+        if(e->IsQuadratic()) {
+          const SMDS_QuadraticFaceOfNodes* F =
+            static_cast<const SMDS_QuadraticFaceOfNodes*>(e);
+          // use special nodes iterator
+          SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+          while( anIter->more() ) {
+            nodes[ iNode++ ] = anIter->next();
+          }
+        }
+        else {
+          SMDS_ElemIteratorPtr nIt = e->nodesIterator();
+          while ( nIt->more() )
+            nodes[ iNode++ ] = static_cast<const SMDS_MeshNode*>( nIt->next() );
+        }
         nodes[ iNode ] = nodes[ 0 ];
         // check 2 links
         for ( iNode = 0; iNode < nbNodes; iNode++ )
@@ -3987,8 +4982,7 @@ SMESH_MeshEditor::Sew_Error
     MESSAGE(" Free Border 1 not found " );
     aResult = SEW_BORDER1_NOT_FOUND;
   }
-  if (theSideIsFreeBorder)
-  {
+  if (theSideIsFreeBorder) {
     // Free border 2
     // --------------
     if (!findFreeBorder(theSideFirstNode, theSideSecondNode, theSideThirdNode,
@@ -4000,8 +4994,7 @@ SMESH_MeshEditor::Sew_Error
   if ( aResult != SEW_OK )
     return aResult;
 
-  if (!theSideIsFreeBorder)
-  {
+  if (!theSideIsFreeBorder) {
     // Side 2
     // --------------
 
@@ -4027,8 +5020,7 @@ SMESH_MeshEditor::Sew_Error
     gp_XYZ Ps2( theSideSecondNode->X(), theSideSecondNode->Y(), theSideSecondNode->Z() );
     double tol2 = 1.e-8;
     gp_Vec Vbs1( Pb1 - Ps1 ),Vbs2( Pb2 - Ps2 );
-    if ( Vbs1.SquareMagnitude() > tol2 || Vbs2.SquareMagnitude() > tol2 )
-    {
+    if ( Vbs1.SquareMagnitude() > tol2 || Vbs2.SquareMagnitude() > tol2 ) {
       // Need node movement.
 
       // find X and Z axes to create trsf
@@ -4057,8 +5049,7 @@ SMESH_MeshEditor::Sew_Error
         nBordXYZ.insert( TNodeXYZMap::value_type( n, xyz ));
       }
     }
-    else
-    {
+    else {
       // just insert nodes XYZ in the nBordXYZ map
       for ( nBordIt = bordNodes.begin(); nBordIt != bordNodes.end(); nBordIt++ ) {
         const SMDS_MeshNode* n = *nBordIt;
@@ -4110,13 +5101,27 @@ SMESH_MeshEditor::Sew_Error
         const SMDS_MeshNode** nodes = isVolume ? volume.GetNodes() : faceNodes;
         if ( isVolume ) // --volume
           hasVolumes = true;
-        else if ( nbNodes > 2 ) { // --face
+        //else if ( nbNodes > 2 ) { // --face
+        else if ( elem->GetType()==SMDSAbs_Face ) { // --face
           // retrieve all face nodes and find iPrevNode - an index of the prevSideNode
-          SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
-          while ( nIt->more() ) {
-            nodes[ iNode ] = static_cast<const SMDS_MeshNode*>( nIt->next() );
-            if ( nodes[ iNode++ ] == prevSideNode )
-              iPrevNode = iNode - 1;
+          if(elem->IsQuadratic()) {
+            const SMDS_QuadraticFaceOfNodes* F =
+              static_cast<const SMDS_QuadraticFaceOfNodes*>(elem);
+            // use special nodes iterator
+            SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+            while( anIter->more() ) {
+              nodes[ iNode ] = anIter->next();
+              if ( nodes[ iNode++ ] == prevSideNode )
+                iPrevNode = iNode - 1;
+            }
+          }
+          else {
+            SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
+            while ( nIt->more() ) {
+              nodes[ iNode ] = static_cast<const SMDS_MeshNode*>( nIt->next() );
+              if ( nodes[ iNode++ ] == prevSideNode )
+                iPrevNode = iNode - 1;
+            }
           }
           // there are 2 links to check
           nbNodes = 2;
@@ -4129,7 +5134,8 @@ SMESH_MeshEditor::Sew_Error
           if ( isVolume ) {
             if ( !volume.IsLinked( n, prevSideNode ))
               continue;
-          } else {
+          }
+          else {
             if ( iNode ) // a node before prevSideNode
               n = nodes[ iPrevNode == 0 ? elem->NbNodes() - 1 : iPrevNode - 1 ];
             else         // a node after prevSideNode
@@ -4408,18 +5414,39 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
   int iNode = 0, il1, il2, i3, i4;
   il1 = il2 = i3 = i4 = -1;
   const SMDS_MeshNode* nodes[ theFace->NbNodes() ];
-  SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator();
-  while ( nodeIt->more() ) {
-    const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-    if ( n == theBetweenNode1 )
-      il1 = iNode;
-    else if ( n == theBetweenNode2 )
-      il2 = iNode;
-    else if ( i3 < 0 )
-      i3 = iNode;
-    else
-      i4 = iNode;
-    nodes[ iNode++ ] = n;
+
+  if(theFace->IsQuadratic()) {
+    const SMDS_QuadraticFaceOfNodes* F =
+      static_cast<const SMDS_QuadraticFaceOfNodes*>(theFace);
+    // use special nodes iterator
+    SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+    while( anIter->more() ) {
+      const SMDS_MeshNode* n = anIter->next();
+      if ( n == theBetweenNode1 )
+        il1 = iNode;
+      else if ( n == theBetweenNode2 )
+        il2 = iNode;
+      else if ( i3 < 0 )
+        i3 = iNode;
+      else
+        i4 = iNode;
+      nodes[ iNode++ ] = n;
+    }
+  }
+  else {
+    SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator();
+    while ( nodeIt->more() ) {
+      const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+      if ( n == theBetweenNode1 )
+        il1 = iNode;
+      else if ( n == theBetweenNode2 )
+        il2 = iNode;
+      else if ( i3 < 0 )
+        i3 = iNode;
+      else
+        i4 = iNode;
+      nodes[ iNode++ ] = n;
+    }
   }
   if ( il1 < 0 || il2 < 0 || i3 < 0 )
     return ;
@@ -4448,25 +5475,48 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
 
     // add nodes of face up to first node of link
     bool isFLN = false;
-    nodeIt = theFace->nodesIterator();
-    while ( nodeIt->more() && !isFLN ) {
-      const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-      poly_nodes[iNode++] = n;
-      if (n == nodes[il1]) {
-        isFLN = true;
-      }
-    }
 
-    // add nodes to insert
-    list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
-    for (; nIt != aNodesToInsert.end(); nIt++) {
-      poly_nodes[iNode++] = *nIt;
+    if(theFace->IsQuadratic()) {
+      const SMDS_QuadraticFaceOfNodes* F =
+        static_cast<const SMDS_QuadraticFaceOfNodes*>(theFace);
+      // use special nodes iterator
+      SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+      while( anIter->more()  && !isFLN ) {
+        const SMDS_MeshNode* n = anIter->next();
+        poly_nodes[iNode++] = n;
+        if (n == nodes[il1]) {
+          isFLN = true;
+        }
+      }
+      // add nodes to insert
+      list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
+      for (; nIt != aNodesToInsert.end(); nIt++) {
+        poly_nodes[iNode++] = *nIt;
+      }
+      // add nodes of face starting from last node of link
+      while ( anIter->more() ) {
+        poly_nodes[iNode++] = anIter->next();
+      }
     }
-
-    // add nodes of face starting from last node of link
-    while ( nodeIt->more() ) {
-      const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-      poly_nodes[iNode++] = n;
+    else {
+      SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator();
+      while ( nodeIt->more() && !isFLN ) {
+        const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+        poly_nodes[iNode++] = n;
+        if (n == nodes[il1]) {
+          isFLN = true;
+        }
+      }
+      // add nodes to insert
+      list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
+      for (; nIt != aNodesToInsert.end(); nIt++) {
+        poly_nodes[iNode++] = *nIt;
+      }
+      // add nodes of face starting from last node of link
+      while ( nodeIt->more() ) {
+        const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+        poly_nodes[iNode++] = n;
+      }
     }
 
     // edit or replace the face
@@ -4474,8 +5524,8 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
 
     if (theFace->IsPoly()) {
       aMesh->ChangePolygonNodes(theFace, poly_nodes);
-
-    else {
+    }
+    else {
       int aShapeId = FindShape( theFace );
 
       SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes);
@@ -4487,81 +5537,184 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     return;
   }
 
-  // put aNodesToInsert between theBetweenNode1 and theBetweenNode2
-  int nbLinkNodes = 2 + aNodesToInsert.size();
-  const SMDS_MeshNode* linkNodes[ nbLinkNodes ];
-  linkNodes[ 0 ] = nodes[ il1 ];
-  linkNodes[ nbLinkNodes - 1 ] = nodes[ il2 ];
-  list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
-  for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) {
-    linkNodes[ iNode++ ] = *nIt;
-  }
-  // decide how to split a quadrangle: compare possible variants
-  // and choose which of splits to be a quadrangle
-  int i1, i2, iSplit, nbSplits = nbLinkNodes - 1, iBestQuad;
-  if ( nbFaceNodes == 3 )
-  {
-    iBestQuad = nbSplits;
-    i4 = i3;
-  }
-  else if ( nbFaceNodes == 4 )
-  {
-    SMESH::Controls::NumericalFunctorPtr aCrit( new SMESH::Controls::AspectRatio);
-    double aBestRate = DBL_MAX;
-    for ( int iQuad = 0; iQuad < nbSplits; iQuad++ ) {
-      i1 = 0; i2 = 1;
-      double aBadRate = 0;
-      // evaluate elements quality
-      for ( iSplit = 0; iSplit < nbSplits; iSplit++ ) {
-        if ( iSplit == iQuad ) {
-          SMDS_FaceOfNodes quad (linkNodes[ i1++ ],
-                                 linkNodes[ i2++ ],
-                                 nodes[ i3 ],
-                                 nodes[ i4 ]);
-          aBadRate += getBadRate( &quad, aCrit );
+  if( !theFace->IsQuadratic() ) {
+
+    // put aNodesToInsert between theBetweenNode1 and theBetweenNode2
+    int nbLinkNodes = 2 + aNodesToInsert.size();
+    const SMDS_MeshNode* linkNodes[ nbLinkNodes ];
+    linkNodes[ 0 ] = nodes[ il1 ];
+    linkNodes[ nbLinkNodes - 1 ] = nodes[ il2 ];
+    list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
+    for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) {
+      linkNodes[ iNode++ ] = *nIt;
+    }
+    // decide how to split a quadrangle: compare possible variants
+    // and choose which of splits to be a quadrangle
+    int i1, i2, iSplit, nbSplits = nbLinkNodes - 1, iBestQuad;
+    if ( nbFaceNodes == 3 ) {
+      iBestQuad = nbSplits;
+      i4 = i3;
+    }
+    else if ( nbFaceNodes == 4 ) {
+      SMESH::Controls::NumericalFunctorPtr aCrit( new SMESH::Controls::AspectRatio);
+      double aBestRate = DBL_MAX;
+      for ( int iQuad = 0; iQuad < nbSplits; iQuad++ ) {
+        i1 = 0; i2 = 1;
+        double aBadRate = 0;
+        // evaluate elements quality
+        for ( iSplit = 0; iSplit < nbSplits; iSplit++ ) {
+          if ( iSplit == iQuad ) {
+            SMDS_FaceOfNodes quad (linkNodes[ i1++ ],
+                                   linkNodes[ i2++ ],
+                                   nodes[ i3 ],
+                                   nodes[ i4 ]);
+            aBadRate += getBadRate( &quad, aCrit );
+          }
+          else {
+            SMDS_FaceOfNodes tria (linkNodes[ i1++ ],
+                                   linkNodes[ i2++ ],
+                                   nodes[ iSplit < iQuad ? i4 : i3 ]);
+            aBadRate += getBadRate( &tria, aCrit );
+          }
         }
-        else {
-          SMDS_FaceOfNodes tria (linkNodes[ i1++ ],
-                                 linkNodes[ i2++ ],
-                                 nodes[ iSplit < iQuad ? i4 : i3 ]);
-          aBadRate += getBadRate( &tria, aCrit );
+        // choice
+        if ( aBadRate < aBestRate ) {
+          iBestQuad = iQuad;
+          aBestRate = aBadRate;
         }
       }
-      // choice
-      if ( aBadRate < aBestRate ) {
-        iBestQuad = iQuad;
-        aBestRate = aBadRate;
+    }
+    
+    // create new elements
+    SMESHDS_Mesh *aMesh = GetMeshDS();
+    int aShapeId = FindShape( theFace );
+    
+    i1 = 0; i2 = 1;
+    for ( iSplit = 0; iSplit < nbSplits - 1; iSplit++ ) {
+      SMDS_MeshElement* newElem = 0;
+      if ( iSplit == iBestQuad )
+        newElem = aMesh->AddFace (linkNodes[ i1++ ],
+                                  linkNodes[ i2++ ],
+                                  nodes[ i3 ],
+                                  nodes[ i4 ]);
+      else
+        newElem = aMesh->AddFace (linkNodes[ i1++ ],
+                                  linkNodes[ i2++ ],
+                                  nodes[ iSplit < iBestQuad ? i4 : i3 ]);
+      if ( aShapeId && newElem )
+        aMesh->SetMeshElementOnShape( newElem, aShapeId );
+    }
+    
+    // change nodes of theFace
+    const SMDS_MeshNode* newNodes[ 4 ];
+    newNodes[ 0 ] = linkNodes[ i1 ];
+    newNodes[ 1 ] = linkNodes[ i2 ];
+    newNodes[ 2 ] = nodes[ iSplit >= iBestQuad ? i3 : i4 ];
+    newNodes[ 3 ] = nodes[ i4 ];
+    aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 );
+  } // end if(!theFace->IsQuadratic())
+  else { // theFace is quadratic
+    // we have to split theFace on simple triangles and one simple quadrangle
+    int tmp = il1/2;
+    int nbshift = tmp*2;
+    // shift nodes in nodes[] by nbshift
+    int i,j;
+    for(i=0; i<nbshift; i++) {
+      const SMDS_MeshNode* n = nodes[0];
+      for(j=0; j<nbFaceNodes-1; j++) {
+        nodes[j] = nodes[j+1];
       }
+      nodes[nbFaceNodes-1] = n;
     }
-  }
+    il1 = il1 - nbshift;
+    // now have to insert nodes between n0 and n1 or n1 and n2 (see below)
+    //   n0      n1     n2    n0      n1     n2
+    //     +-----+-----+        +-----+-----+ 
+    //      \         /         |           |
+    //       \       /          |           |
+    //      n5+     +n3       n7+           +n3
+    //         \   /            |           |
+    //          \ /             |           |
+    //           +              +-----+-----+
+    //           n4           n6      n5     n4
+
+    // create new elements
+    SMESHDS_Mesh *aMesh = GetMeshDS();
+    int aShapeId = FindShape( theFace );
 
-  // create new elements
-  SMESHDS_Mesh *aMesh = GetMeshDS();
-  int aShapeId = FindShape( theFace );
-
-  i1 = 0; i2 = 1;
-  for ( iSplit = 0; iSplit < nbSplits - 1; iSplit++ ) {
-    SMDS_MeshElement* newElem = 0;
-    if ( iSplit == iBestQuad )
-      newElem = aMesh->AddFace (linkNodes[ i1++ ],
-                                linkNodes[ i2++ ],
-                                nodes[ i3 ],
-                                nodes[ i4 ]);
-    else
-      newElem = aMesh->AddFace (linkNodes[ i1++ ],
-                                linkNodes[ i2++ ],
-                                nodes[ iSplit < iBestQuad ? i4 : i3 ]);
-    if ( aShapeId && newElem )
-      aMesh->SetMeshElementOnShape( newElem, aShapeId );
+    int n1,n2,n3;
+    if(nbFaceNodes==6) { // quadratic triangle
+      SMDS_MeshElement* newElem =
+        aMesh->AddFace(nodes[3],nodes[4],nodes[5]);
+      if ( aShapeId && newElem )
+        aMesh->SetMeshElementOnShape( newElem, aShapeId );
+      if(theFace->IsMediumNode(nodes[il1])) {
+        // create quadrangle
+        newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[5]);
+        if ( aShapeId && newElem )
+          aMesh->SetMeshElementOnShape( newElem, aShapeId );
+        n1 = 1;
+        n2 = 2;
+        n3 = 3;
+      }
+      else {
+        // create quadrangle
+        newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[5]);
+        if ( aShapeId && newElem )
+          aMesh->SetMeshElementOnShape( newElem, aShapeId );
+        n1 = 0;
+        n2 = 1;
+        n3 = 5;
+      }
+    }
+    else { // nbFaceNodes==8 - quadratic quadrangle
+      SMDS_MeshElement* newElem =
+        aMesh->AddFace(nodes[3],nodes[4],nodes[5]);
+      if ( aShapeId && newElem )
+        aMesh->SetMeshElementOnShape( newElem, aShapeId );
+      newElem = aMesh->AddFace(nodes[5],nodes[6],nodes[7]);
+      if ( aShapeId && newElem )
+        aMesh->SetMeshElementOnShape( newElem, aShapeId );
+      newElem = aMesh->AddFace(nodes[5],nodes[7],nodes[3]);
+      if ( aShapeId && newElem )
+        aMesh->SetMeshElementOnShape( newElem, aShapeId );
+      if(theFace->IsMediumNode(nodes[il1])) {
+        // create quadrangle
+        newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[7]);
+        if ( aShapeId && newElem )
+          aMesh->SetMeshElementOnShape( newElem, aShapeId );
+        n1 = 1;
+        n2 = 2;
+        n3 = 3;
+      }
+      else {
+        // create quadrangle
+        newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[7]);
+        if ( aShapeId && newElem )
+          aMesh->SetMeshElementOnShape( newElem, aShapeId );
+        n1 = 0;
+        n2 = 1;
+        n3 = 7;
+      }
+    }
+    // create needed triangles using n1,n2,n3 and inserted nodes
+    int nbn = 2 + aNodesToInsert.size();
+    const SMDS_MeshNode* aNodes[nbn];
+    aNodes[0] = nodes[n1];
+    aNodes[nbn-1] = nodes[n2];
+    list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
+    for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) {
+      aNodes[iNode++] = *nIt;
+    }
+    for(i=1; i<nbn; i++) {
+      SMDS_MeshElement* newElem =
+        aMesh->AddFace(aNodes[i-1],aNodes[i],nodes[n3]);
+      if ( aShapeId && newElem )
+        aMesh->SetMeshElementOnShape( newElem, aShapeId );
+    }
+    // remove old quadratic face
+    aMesh->RemoveElement(theFace);
   }
-
-  // change nodes of theFace
-  const SMDS_MeshNode* newNodes[ 4 ];
-  newNodes[ 0 ] = linkNodes[ i1 ];
-  newNodes[ 1 ] = linkNodes[ i2 ];
-  newNodes[ 2 ] = nodes[ iSplit >= iBestQuad ? i3 : i4 ];
-  newNodes[ 3 ] = nodes[ i4 ];
-  aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 );
 }
 
 //=======================================================================
@@ -4607,7 +5760,8 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode*        theBetweenNode
                 poly_nodes.push_back(*nIt);
               }
             }
-          } else if (faceNodes[inode] == theBetweenNode2) {
+          }
+          else if (faceNodes[inode] == theBetweenNode2) {
             if (faceNodes[inode + 1] == theBetweenNode1) {
               nbInserted = theNodesToInsert.size();
 
@@ -4619,7 +5773,8 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode*        theBetweenNode
               }
               poly_nodes.push_back(*nIt);
             }
-          } else {
+          }
+          else {
           }
         }
       }
@@ -4632,7 +5787,8 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode*        theBetweenNode
     if (elem->IsPoly()) {
       aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
 
-    } else {
+    }
+    else {
       int aShapeId = FindShape( elem );
 
       SMDS_MeshElement* newElem =
@@ -4709,11 +5865,24 @@ SMESH_MeshEditor::Sew_Error
       if ( elem->GetType() == SMDSAbs_Face ) {
         faceSet->insert( elem );
         set <const SMDS_MeshNode*> faceNodeSet;
-        SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
-        while ( nodeIt->more() ) {
-          const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-          nodeSet->insert( n );
-          faceNodeSet.insert( n );
+        if(elem->IsQuadratic()) {
+          const SMDS_QuadraticFaceOfNodes* F =
+            static_cast<const SMDS_QuadraticFaceOfNodes*>(elem);
+          // use special nodes iterator
+          SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+          while( anIter->more() ) {
+            const SMDS_MeshNode* n = anIter->next();
+            nodeSet->insert( n );
+            faceNodeSet.insert( n );
+          }
+        }
+        else {
+          SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
+          while ( nodeIt->more() ) {
+            const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+            nodeSet->insert( n );
+            faceNodeSet.insert( n );
+          }
         }
         setOfFaceNodeSet.insert( faceNodeSet );
       }
@@ -4754,8 +5923,7 @@ SMESH_MeshEditor::Sew_Error
     //     face does not exist
     // -------------------------------------------------------------------------
 
-    if ( !volSet->empty() )
-    {
+    if ( !volSet->empty() ) {
       //int nodeSetSize = nodeSet->size();
 
       // loop on given volumes
@@ -4778,9 +5946,11 @@ SMESH_MeshEditor::Sew_Error
             // no such a face is given but it still can exist, check it
             if ( nbNodes == 3 ) {
               aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2] );
-            } else if ( nbNodes == 4 ) {
+            }
+            else if ( nbNodes == 4 ) {
               aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
-            } else {
+            }
+            else {
               vector<const SMDS_MeshNode *> poly_nodes (nbNodes);
               for (int inode = 0; inode < nbNodes; inode++) {
                 poly_nodes[inode] = fNodes[inode];
@@ -4792,9 +5962,11 @@ SMESH_MeshEditor::Sew_Error
             // create a temporary face
             if ( nbNodes == 3 ) {
               aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2] );
-            } else if ( nbNodes == 4 ) {
+            }
+            else if ( nbNodes == 4 ) {
               aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
-            } else {
+            }
+            else {
               vector<const SMDS_MeshNode *> poly_nodes (nbNodes);
               for (int inode = 0; inode < nbNodes; inode++) {
                 poly_nodes[inode] = fNodes[inode];
@@ -4946,8 +6118,7 @@ SMESH_MeshEditor::Sew_Error
   // loop on links in linkList; find faces by links and append links
   // of the found faces to linkList
   list< TPairOfNodes >::iterator linkIt[] = { linkList[0].begin(), linkList[1].begin() } ;
-  for ( ; linkIt[0] != linkList[0].end(); linkIt[0]++, linkIt[1]++ )
-  {
+  for ( ; linkIt[0] != linkList[0].end(); linkIt[0]++, linkIt[1]++ ) {
     TPairOfNodes link[] = { *linkIt[0], *linkIt[1] };
     long linkID = aLinkID_Gen.GetLinkID( link[0].first, link[0].second );
     if ( linkIdSet.find( linkID ) == linkIdSet.end() )
@@ -4959,8 +6130,12 @@ SMESH_MeshEditor::Sew_Error
     // ---------------------------------------------------------------
 
     const SMDS_MeshElement* face[] = { 0, 0 };
-    const SMDS_MeshNode* faceNodes[ 2 ][ 5 ];
-    const SMDS_MeshNode* notLinkNodes[ 2 ][ 2 ] = {{ 0, 0 },{ 0, 0 }} ;
+    //const SMDS_MeshNode* faceNodes[ 2 ][ 5 ];
+    vector<const SMDS_MeshNode*> fnodes1(9);
+    vector<const SMDS_MeshNode*> fnodes2(9);
+    //const SMDS_MeshNode* notLinkNodes[ 2 ][ 2 ] = {{ 0, 0 },{ 0, 0 }} ;
+    vector<const SMDS_MeshNode*> notLinkNodes1(6);
+    vector<const SMDS_MeshNode*> notLinkNodes2(6);
     int iLinkNode[2][2];
     for ( iSide = 0; iSide < 2; iSide++ ) { // loop on 2 sides
       const SMDS_MeshNode* n1 = link[iSide].first;
@@ -4984,40 +6159,109 @@ SMESH_MeshEditor::Sew_Error
             faceSet->erase( f );
             // get face nodes and find ones of a link
             iNode = 0;
-            SMDS_ElemIteratorPtr nIt = f->nodesIterator();
-            while ( nIt->more() ) {
-              const SMDS_MeshNode* n =
-                static_cast<const SMDS_MeshNode*>( nIt->next() );
-              if ( n == n1 )
-                iLinkNode[ iSide ][ 0 ] = iNode;
-              else if ( n == n2 )
-                iLinkNode[ iSide ][ 1 ] = iNode;
-              else if ( notLinkNodes[ iSide ][ 0 ] )
-                notLinkNodes[ iSide ][ 1 ] = n;
-              else
-                notLinkNodes[ iSide ][ 0 ] = n;
-              faceNodes[ iSide ][ iNode++ ] = n;
+            int nbl = -1;
+            if(f->IsPoly()) {
+              if(iSide==0) {
+                fnodes1.resize(f->NbNodes()+1);
+                notLinkNodes1.resize(f->NbNodes()-2);
+              }
+              else {
+                fnodes2.resize(f->NbNodes()+1);
+                notLinkNodes2.resize(f->NbNodes()-2);
+              }
+            }
+            if(!f->IsQuadratic()) {
+              SMDS_ElemIteratorPtr nIt = f->nodesIterator();
+              while ( nIt->more() ) {
+                const SMDS_MeshNode* n =
+                  static_cast<const SMDS_MeshNode*>( nIt->next() );
+                if ( n == n1 ) {
+                  iLinkNode[ iSide ][ 0 ] = iNode;
+                }
+                else if ( n == n2 ) {
+                  iLinkNode[ iSide ][ 1 ] = iNode;
+                }
+                //else if ( notLinkNodes[ iSide ][ 0 ] )
+                //  notLinkNodes[ iSide ][ 1 ] = n;
+                //else
+                //  notLinkNodes[ iSide ][ 0 ] = n;
+                else {
+                  nbl++;
+                  if(iSide==0)
+                    notLinkNodes1[nbl] = n;
+                    //notLinkNodes1.push_back(n);
+                  else
+                    notLinkNodes2[nbl] = n;
+                    //notLinkNodes2.push_back(n);
+                }
+                //faceNodes[ iSide ][ iNode++ ] = n;
+                if(iSide==0) {
+                  fnodes1[iNode++] = n;
+                }
+                else {
+                  fnodes2[iNode++] = n;
+                }
+              }
+            }
+            else { // f->IsQuadratic()
+              const SMDS_QuadraticFaceOfNodes* F =
+                static_cast<const SMDS_QuadraticFaceOfNodes*>(f);
+              // use special nodes iterator
+              SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+              while ( anIter->more() ) {
+                const SMDS_MeshNode* n =
+                  static_cast<const SMDS_MeshNode*>( anIter->next() );
+                if ( n == n1 ) {
+                  iLinkNode[ iSide ][ 0 ] = iNode;
+                }
+                else if ( n == n2 ) {
+                  iLinkNode[ iSide ][ 1 ] = iNode;
+                }
+                else {
+                  nbl++;
+                  if(iSide==0) {
+                    notLinkNodes1[nbl] = n;
+                  }
+                  else {
+                    notLinkNodes2[nbl] = n;
+                  }
+                }
+                if(iSide==0) {
+                  fnodes1[iNode++] = n;
+                }
+                else {
+                  fnodes2[iNode++] = n;
+                }
+              }
+            }
+            //faceNodes[ iSide ][ iNode ] = faceNodes[ iSide ][ 0 ];
+            if(iSide==0) {
+              fnodes1[iNode] = fnodes1[0];
+            }
+            else {
+              fnodes2[iNode] = fnodes1[0];
             }
-            faceNodes[ iSide ][ iNode ] = faceNodes[ iSide ][ 0 ];
           }
         }
       }
     }
+
     // check similarity of elements of the sides
     if (aResult == SEW_OK && ( face[0] && !face[1] ) || ( !face[0] && face[1] )) {
       MESSAGE("Correspondent face not found on side " << ( face[0] ? 1 : 0 ));
-      if ( nReplaceMap.size() == 2 ) // faces on input nodes not found
+      if ( nReplaceMap.size() == 2 ) // faces on input nodes not found
         aResult = ( face[0] ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES );
-      else
+      }
+      else {
         aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
+      }
       break; // do not return because it s necessary to remove tmp faces
     }
 
     // set nodes to merge
     // -------------------
 
-    if ( face[0] && face[1] )
-    {
+    if ( face[0] && face[1] )  {
       int nbNodes = face[0]->NbNodes();
       if ( nbNodes != face[1]->NbNodes() ) {
         MESSAGE("Diff nb of face nodes");
@@ -5025,9 +6269,12 @@ SMESH_MeshEditor::Sew_Error
         break; // do not return because it s necessary to remove tmp faces
       }
       bool reverse[] = { false, false }; // order of notLinkNodes of quadrangle
-      if ( nbNodes == 3 )
+      if ( nbNodes == 3 ) {
+        //nReplaceMap.insert( TNodeNodeMap::value_type
+        //                   ( notLinkNodes[0][0], notLinkNodes[1][0] ));
         nReplaceMap.insert( TNodeNodeMap::value_type
-                           ( notLinkNodes[0][0], notLinkNodes[1][0] ));
+                           ( notLinkNodes1[0], notLinkNodes2[0] ));
+      }
       else {
         for ( iSide = 0; iSide < 2; iSide++ ) { // loop on 2 sides
           // analyse link orientation in faces
@@ -5041,34 +6288,44 @@ SMESH_MeshEditor::Sew_Error
             reverse[ iSide ] = !reverse[ iSide ];
         }
         if ( reverse[0] == reverse[1] ) {
-          nReplaceMap.insert( TNodeNodeMap::value_type
-                             ( notLinkNodes[0][0], notLinkNodes[1][0] ));
-          nReplaceMap.insert( TNodeNodeMap::value_type
-                             ( notLinkNodes[0][1], notLinkNodes[1][1] ));
+          //nReplaceMap.insert( TNodeNodeMap::value_type
+          //                   ( notLinkNodes[0][0], notLinkNodes[1][0] ));
+          //nReplaceMap.insert( TNodeNodeMap::value_type
+          //                   ( notLinkNodes[0][1], notLinkNodes[1][1] ));
+          for(int nn=0; nn<nbNodes-2; nn++) {
+            nReplaceMap.insert( TNodeNodeMap::value_type
+                             ( notLinkNodes1[nn], notLinkNodes2[nn] ));
+          }
         }
         else {
-          nReplaceMap.insert( TNodeNodeMap::value_type
-                             ( notLinkNodes[0][0], notLinkNodes[1][1] ));
-          nReplaceMap.insert( TNodeNodeMap::value_type
-                             ( notLinkNodes[0][1], notLinkNodes[1][0] ));
+          //nReplaceMap.insert( TNodeNodeMap::value_type
+          //                   ( notLinkNodes[0][0], notLinkNodes[1][1] ));
+          //nReplaceMap.insert( TNodeNodeMap::value_type
+          //                   ( notLinkNodes[0][1], notLinkNodes[1][0] ));
+          for(int nn=0; nn<nbNodes-2; nn++) {
+            nReplaceMap.insert( TNodeNodeMap::value_type
+                             ( notLinkNodes1[nn], notLinkNodes2[nbNodes-3-nn] ));
+          }
         }
       }
 
       // add other links of the faces to linkList
       // -----------------------------------------
 
-      const SMDS_MeshNode** nodes = faceNodes[ 0 ];
-      for ( iNode = 0; iNode < nbNodes; iNode++ )
-      {
-        linkID = aLinkID_Gen.GetLinkID( nodes[iNode], nodes[iNode+1] );
+      //const SMDS_MeshNode** nodes = faceNodes[ 0 ];
+      for ( iNode = 0; iNode < nbNodes; iNode++ )  {
+        //linkID = aLinkID_Gen.GetLinkID( nodes[iNode], nodes[iNode+1] );
+        linkID = aLinkID_Gen.GetLinkID( fnodes1[iNode], fnodes1[iNode+1] );
         pair< set<long>::iterator, bool > iter_isnew = linkIdSet.insert( linkID );
         if ( !iter_isnew.second ) { // already in a set: no need to process
           linkIdSet.erase( iter_isnew.first );
         }
         else // new in set == encountered for the first time: add
         {
-          const SMDS_MeshNode* n1 = nodes[ iNode ];
-          const SMDS_MeshNode* n2 = nodes[ iNode + 1];
+          //const SMDS_MeshNode* n1 = nodes[ iNode ];
+          //const SMDS_MeshNode* n2 = nodes[ iNode + 1];
+          const SMDS_MeshNode* n1 = fnodes1[ iNode ];
+          const SMDS_MeshNode* n2 = fnodes1[ iNode + 1];
           linkList[0].push_back ( TPairOfNodes( n1, n2 ));
           linkList[1].push_back ( TPairOfNodes( nReplaceMap[n1], nReplaceMap[n2] ));
         }
@@ -5100,8 +6357,7 @@ SMESH_MeshEditor::Sew_Error
   // 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
@@ -5128,7 +6384,7 @@ SMESH_MeshEditor::Sew_Error
         if ( nbReplaced )
           aMesh->ChangeElementNodes( e, nodes, nbNodes );
       }
-  }
+    }
 
   Remove( nodeIDsToRemove, true );
 
index b3f104ae2c68e384e80b40602f5b368ae020da7f..a2c73ac6dbe793d38b1725d89d872fed4a9971e7 100644 (file)
@@ -433,7 +433,7 @@ void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape)
  */
 //=============================================================================
 
-const TopoDS_Shape & SMESH_subMesh::GetSubShape()
+const TopoDS_Shape & SMESH_subMesh::GetSubShape() const
 {
        //MESSAGE("SMESH_subMesh::GetSubShape");
        return _subShape;
@@ -540,7 +540,7 @@ SMESH_Hypothesis::Hypothesis_Status
     if ( ! CanAddHypothesis( anHyp ))
       return SMESH_Hypothesis::HYP_BAD_DIM;
 
-    if ( GetSimilarAttached( _subShape, anHyp ) )
+    if ( /*!anHyp->IsAuxiliary() &&*/ GetSimilarAttached( _subShape, anHyp ) )
       return SMESH_Hypothesis::HYP_ALREADY_EXIST;
 
     if ( !_meshDS->AddHypothesis(_subShape, anHyp))
@@ -549,9 +549,9 @@ SMESH_Hypothesis::Hypothesis_Status
     // Serve Propagation of 1D hypothesis
     if (event == ADD_HYP) {
       bool isPropagationOk = true;
-      string hypName = anHyp->GetName();
+      bool isPropagationHyp = ( strcmp( "Propagation", anHyp->GetName() ) == 0 );
 
-      if (hypName == "Propagation") {
+      if ( isPropagationHyp ) {
         TopExp_Explorer exp (_subShape, TopAbs_EDGE);
         TopTools_MapOfShape aMap;
         for (; exp.More(); exp.Next()) {
@@ -579,7 +579,11 @@ SMESH_Hypothesis::Hypothesis_Status
       } else {
       }
 
-      if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT) {
+      if ( isPropagationOk ) {
+        if ( isPropagationHyp )
+          return ret; // nothing more to do for "Propagation" hypothesis
+      }
+      else if ( ret < SMESH_Hypothesis::HYP_CONCURENT) {
         ret = SMESH_Hypothesis::HYP_CONCURENT;
       }
     } // Serve Propagation of 1D hypothesis
@@ -598,7 +602,9 @@ SMESH_Hypothesis::Hypothesis_Status
     {
       bool isPropagationOk = true;
       SMESH_HypoFilter propagFilter( SMESH_HypoFilter::HasName( "Propagation" ));
-      if ( propagFilter.IsOk( anHyp, _subShape ))
+      bool isPropagationHyp = propagFilter.IsOk( anHyp, _subShape );
+
+      if ( isPropagationHyp )
       {
         TopExp_Explorer exp (_subShape, TopAbs_EDGE);
         TopTools_MapOfShape aMap;
@@ -620,7 +626,11 @@ SMESH_Hypothesis::Hypothesis_Status
         isPropagationOk = _father->RebuildPropagationChains();
       }
 
-      if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT) {
+      if ( isPropagationOk ) {
+        if ( isPropagationHyp )
+          return ret; // nothing more to do for "Propagation" hypothesis
+      }
+      else if ( ret < SMESH_Hypothesis::HYP_CONCURENT) {
         ret = SMESH_Hypothesis::HYP_CONCURENT;
       }
     } // Serve Propagation of 1D hypothesis
@@ -698,7 +708,7 @@ SMESH_Hypothesis::Hypothesis_Status
         SetAlgoState(HYP_OK);
       if (SMESH_Hypothesis::IsStatusFatal( ret ))
         _meshDS->RemoveHypothesis(_subShape, anHyp);
-      else if (!_father->IsUsedHypothesis(  anHyp, _subShape ))
+      else if (!_father->IsUsedHypothesis( anHyp, this ))
       {
         _meshDS->RemoveHypothesis(_subShape, anHyp);
         ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
@@ -788,7 +798,7 @@ SMESH_Hypothesis::Hypothesis_Status
           // ret should be fatal: anHyp was not added
           ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
       }
-      else if (!_father->IsUsedHypothesis(  anHyp, _subShape ))
+      else if (!_father->IsUsedHypothesis(  anHyp, this ))
         ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
 
       if (SMESH_Hypothesis::IsStatusFatal( ret ))
@@ -852,7 +862,7 @@ SMESH_Hypothesis::Hypothesis_Status
       ASSERT(algo);
       if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
       {
-        if (_father->IsUsedHypothesis( anHyp, _subShape )) // new Hyp
+        if (_father->IsUsedHypothesis( anHyp, this )) // new Hyp
           modifiedHyp = true;
       }
       else
@@ -1607,8 +1617,9 @@ TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlg
   if ( mainShape.IsSame( _subShape ))
     return _subShape;
 
+  const bool ignoreAuxiliaryHyps = false;
   list<const SMESHDS_Hypothesis*> aUsedHyp =
-    theAlgo->GetUsedHypothesis( *_father, _subShape ); // copy
+    theAlgo->GetUsedHypothesis( *_father, _subShape, ignoreAuxiliaryHyps ); // copy
 
   // put in a compound all shapes with the same hypothesis assigned
   // and a good ComputState
@@ -1626,7 +1637,7 @@ TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlg
 
     if (subMesh->GetComputeState() == READY_TO_COMPUTE &&
         anAlgo == theAlgo &&
-        anAlgo->GetUsedHypothesis( *_father, S ) == aUsedHyp)
+        anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp)
     {
       aBuilder.Add( aCompound, S );
     }
@@ -1637,26 +1648,31 @@ TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlg
 
 //=======================================================================
 //function : GetSimilarAttached
-//purpose  : return nb of hypotheses attached to theShape.
+//purpose  : return a hypothesis attached to theShape.
 //           If theHyp is provided, similar but not same hypotheses
-//           are countered; else only applicable ones having theHypType
-//           are countered
+//           is returned; else only applicable ones having theHypType
+//           is returned
 //=======================================================================
 
 const SMESH_Hypothesis* SMESH_subMesh::GetSimilarAttached(const TopoDS_Shape&      theShape,
                                                           const SMESH_Hypothesis * theHyp,
                                                           const int                theHypType)
 {
-  SMESH_HypoFilter filter;
-  filter.Init( SMESH_HypoFilter::HasType( theHyp ? theHyp->GetType() : theHypType ));
+  SMESH_HypoFilter hypoKind;
+  hypoKind.Init( hypoKind.HasType( theHyp ? theHyp->GetType() : theHypType ));
   if ( theHyp ) {
-    filter.And( SMESH_HypoFilter::HasDim( theHyp->GetDim() ));
-    filter.AndNot( SMESH_HypoFilter::Is( theHyp ));
+    hypoKind.And   ( hypoKind.HasDim( theHyp->GetDim() ));
+    hypoKind.AndNot( hypoKind.Is( theHyp ));
+    if ( theHyp->IsAuxiliary() )
+      hypoKind.And( hypoKind.HasName( theHyp->GetName() ));
+    else
+      hypoKind.AndNot( hypoKind.IsAuxiliary());
+  }
+  else {
+    hypoKind.And( hypoKind.IsApplicableTo( theShape ));
   }
-  else
-    filter.And( SMESH_HypoFilter::IsApplicableTo( theShape ));
 
-  return _father->GetHypothesis( theShape, filter, false );
+  return _father->GetHypothesis( theShape, hypoKind, false );
 }
 
 //=======================================================================
index e2af61ac0e82054d7d1310a8264fe60ba7d560f3..5c5b92ec63985a915cde351908525031db532761 100644 (file)
@@ -70,7 +70,7 @@ class SMESH_subMesh
   const map < int, SMESH_subMesh * >&DependsOn();
   //const map < int, SMESH_subMesh * >&Dependants();
 
-  const TopoDS_Shape & GetSubShape();
+  const TopoDS_Shape & GetSubShape() const;
 
 //  bool _vertexSet;                   // only for vertex subMesh, set to false for dim > 0
 
@@ -103,17 +103,13 @@ class SMESH_subMesh
   SMESH_Hypothesis::Hypothesis_Status
     SubMeshesAlgoStateEngine(int event, SMESH_Hypothesis * anHyp);
 
-  int GetAlgoState() { return _algoState; }
+  int GetAlgoState() const { return _algoState; }
+  int GetComputeState() const { return _computeState; };
 
   void DumpAlgoState(bool isMain);
 
   bool ComputeStateEngine(int event);
 
-  int GetComputeState()
-  {
-    return _computeState;
-  };
-
   bool IsConform(const SMESH_Algo* theAlgo);
   // check if a conform mesh will be produced by the Algo
 
index d8b664e0e67480054d0b9f4e346ebac45b9a8287..7de0dc6378ac6f1525856be26b670e5c12f231e6 100644 (file)
@@ -416,3 +416,199 @@ const list < double >&SMESHDS_Command::GetCoords()
 {
        return myReals;
 }
+
+
+//********************************************************************
+//*****             Methods for quadratic elements              ******
+//********************************************************************
+
+//=======================================================================
+//function : AddEdge
+//purpose  : 
+//=======================================================================
+void SMESHDS_Command::AddEdge(int NewEdgeID, int n1, int n2, int n12)
+{
+  if (!myType == SMESHDS_AddQuadEdge) {
+    MESSAGE("SMESHDS_Command::AddEdge : Bad Type");
+    return;
+  }
+  myIntegers.push_back(NewEdgeID);
+  myIntegers.push_back(n1);
+  myIntegers.push_back(n2);
+  myIntegers.push_back(n12);
+  myNumber++;
+}
+
+//=======================================================================
+//function : AddFace
+//purpose  : 
+//=======================================================================
+void SMESHDS_Command::AddFace(int NewFaceID,
+                              int n1, int n2, int n3,
+                              int n12, int n23, int n31)
+{
+  if (!myType == SMESHDS_AddQuadTriangle) {
+    MESSAGE("SMESHDS_Command::AddFace : Bad Type");
+    return;
+  }
+  myIntegers.push_back(NewFaceID);
+  myIntegers.push_back(n1);
+  myIntegers.push_back(n2);
+  myIntegers.push_back(n3);
+  myIntegers.push_back(n12);
+  myIntegers.push_back(n23);
+  myIntegers.push_back(n31);
+  myNumber++;
+}
+
+//=======================================================================
+//function : AddFace
+//purpose  : 
+//=======================================================================
+void SMESHDS_Command::AddFace(int NewFaceID,
+                              int n1, int n2, int n3, int n4,
+                              int n12, int n23, int n34, int n41)
+{
+  if (!myType == SMESHDS_AddQuadQuadrangle) {
+    MESSAGE("SMESHDS_Command::AddFace : Bad Type");
+    return;
+  }
+  myIntegers.push_back(NewFaceID);
+  myIntegers.push_back(n1);
+  myIntegers.push_back(n2);
+  myIntegers.push_back(n3);
+  myIntegers.push_back(n4);
+  myIntegers.push_back(n12);
+  myIntegers.push_back(n23);
+  myIntegers.push_back(n34);
+  myIntegers.push_back(n41);
+  myNumber++;
+}
+
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
+                                int n12, int n23, int n31,
+                                int n14, int n24, int n34)
+{
+  if (!myType == SMESHDS_AddQuadTetrahedron) {
+    MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
+    return;
+  }
+  myIntegers.push_back(NewVolID);
+  myIntegers.push_back(n1);
+  myIntegers.push_back(n2);
+  myIntegers.push_back(n3);
+  myIntegers.push_back(n4);
+  myIntegers.push_back(n12);
+  myIntegers.push_back(n23);
+  myIntegers.push_back(n31);
+  myIntegers.push_back(n14);
+  myIntegers.push_back(n24);
+  myIntegers.push_back(n34);
+  myNumber++;
+}
+
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2,
+                                int n3, int n4, int n5,
+                                int n12, int n23, int n34, int n41,
+                                int n15, int n25, int n35, int n45)
+{
+  if (!myType == SMESHDS_AddQuadPyramid) {
+    MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
+    return;
+  }
+  myIntegers.push_back(NewVolID);
+  myIntegers.push_back(n1);
+  myIntegers.push_back(n2);
+  myIntegers.push_back(n3);
+  myIntegers.push_back(n4);
+  myIntegers.push_back(n5);
+  myIntegers.push_back(n12);
+  myIntegers.push_back(n23);
+  myIntegers.push_back(n34);
+  myIntegers.push_back(n41);
+  myIntegers.push_back(n15);
+  myIntegers.push_back(n25);
+  myIntegers.push_back(n35);
+  myIntegers.push_back(n45);
+  myNumber++;
+}
+
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2,
+                                int n3, int n4, int n5,int n6,
+                                int n12, int n23, int n31,
+                                int n45, int n56, int n64,
+                                int n14, int n25, int n36)
+{
+  if (!myType == SMESHDS_AddQuadPentahedron) {
+    MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
+    return;
+  }
+  myIntegers.push_back(NewVolID);
+  myIntegers.push_back(n1);
+  myIntegers.push_back(n2);
+  myIntegers.push_back(n3);
+  myIntegers.push_back(n4);
+  myIntegers.push_back(n5);
+  myIntegers.push_back(n6);
+  myIntegers.push_back(n12);
+  myIntegers.push_back(n23);
+  myIntegers.push_back(n31);
+  myIntegers.push_back(n45);
+  myIntegers.push_back(n56);
+  myIntegers.push_back(n64);
+  myIntegers.push_back(n14);
+  myIntegers.push_back(n25);
+  myIntegers.push_back(n36);
+  myNumber++;
+}
+
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, int n3,
+                                int n4, int n5, int n6, int n7, int n8,
+                                int n12, int n23, int n34, int n41,
+                                int n56, int n67, int n78, int n85,
+                                int n15, int n26, int n37, int n48)
+{
+  if (!myType == SMESHDS_AddQuadHexahedron) {
+    MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
+    return;
+  }
+  myIntegers.push_back(NewVolID);
+  myIntegers.push_back(n1);
+  myIntegers.push_back(n2);
+  myIntegers.push_back(n3);
+  myIntegers.push_back(n4);
+  myIntegers.push_back(n5);
+  myIntegers.push_back(n6);
+  myIntegers.push_back(n7);
+  myIntegers.push_back(n8);
+  myIntegers.push_back(n12);
+  myIntegers.push_back(n23);
+  myIntegers.push_back(n34);
+  myIntegers.push_back(n41);
+  myIntegers.push_back(n56);
+  myIntegers.push_back(n67);
+  myIntegers.push_back(n78);
+  myIntegers.push_back(n85);
+  myIntegers.push_back(n15);
+  myIntegers.push_back(n26);
+  myIntegers.push_back(n37);
+  myIntegers.push_back(n48);
+  myNumber++;
+}
+
index 3ecd762f30cbfd8e0d8c8155a249bdb671998c52..7f1e3dbd3e37a3e20780c52c24410d15def0395d 100644 (file)
@@ -54,6 +54,28 @@ class SMESHDS_Command
         void AddPolyhedralVolume (const int        ElementID,
                                   std::vector<int> nodes_ids,
                                   std::vector<int> quantities);
+        // special methods for quadratic elements
+       void AddEdge(int NewEdgeID, int n1, int n2, int n12);
+        void AddFace(int NewFaceID, int n1, int n2, int n3,
+                     int n12, int n23, int n31);
+        void AddFace(int NewFaceID, int n1, int n2, int n3, int n4,
+                     int n12, int n23, int n34, int n41);
+        void AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
+                       int n12, int n23, int n31, int n14, int n24, int n34);
+        void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n5,
+                       int n12, int n23, int n34, int n41,
+                       int n15, int n25, int n35, int n45);
+        void AddVolume(int NewVolID, int n1, int n2, int n3,
+                       int n4, int n5, int n6,
+                       int n12, int n23, int n31,
+                       int n45, int n56, int n64,
+                       int n14, int n25, int n36);
+        void AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
+                       int n5, int n6, int n7, int n8,
+                       int n12, int n23, int n34, int n41,
+                       int n56, int n67, int n78, int n85,
+                       int n15, int n26, int n37, int n48);
+        
        void MoveNode(int NewNodeID, double x, double y, double z);
        void RemoveNode(int NodeID);
        void RemoveElement(int ElementID);
index f2c505b1f66f12444696adc8681c39b3a76244d4..2f7455a5816fd73236bdced49c56dc69c063b579 100644 (file)
 //#include <Standard_PrimitiveTypes.hxx>
 
 enum SMESHDS_CommandType { 
- SMESHDS_AddNode,
- SMESHDS_AddEdge,
- SMESHDS_AddTriangle,
- SMESHDS_AddQuadrangle,
- SMESHDS_AddPolygon,
- SMESHDS_AddTetrahedron,
- SMESHDS_AddPyramid,
- SMESHDS_AddPrism,
- SMESHDS_AddHexahedron,
- SMESHDS_AddPolyhedron,
- SMESHDS_RemoveNode,
- SMESHDS_RemoveElement,
- SMESHDS_MoveNode,
- SMESHDS_ChangeElementNodes,
- SMESHDS_ChangePolyhedronNodes,
- SMESHDS_Renumber
+  SMESHDS_AddNode,
+  SMESHDS_AddEdge,
+  SMESHDS_AddTriangle,
+  SMESHDS_AddQuadrangle,
+  SMESHDS_AddPolygon,
+  SMESHDS_AddTetrahedron,
+  SMESHDS_AddPyramid,
+  SMESHDS_AddPrism,
+  SMESHDS_AddHexahedron,
+  SMESHDS_AddPolyhedron,
+  SMESHDS_RemoveNode,
+  SMESHDS_RemoveElement,
+  SMESHDS_MoveNode,
+  SMESHDS_ChangeElementNodes,
+  SMESHDS_ChangePolyhedronNodes,
+  SMESHDS_Renumber,
+  // special types for quadratic elements
+  SMESHDS_AddQuadEdge,
+  SMESHDS_AddQuadTriangle,
+  SMESHDS_AddQuadQuadrangle,
+  SMESHDS_AddQuadTetrahedron,
+  SMESHDS_AddQuadPyramid,
+  SMESHDS_AddQuadPentahedron,
+  SMESHDS_AddQuadHexahedron
 };
 
 
index d22746e325ff96be6664e8c5204ecc937086ad44..30fb84c6ca22683bed919c9fa8904fb2ffb6c997 100644 (file)
@@ -1184,3 +1184,460 @@ SMESHDS_Mesh::~SMESHDS_Mesh()
 {
   delete myScript;
 }
+
+
+
+//********************************************************************
+//********************************************************************
+//********                                                   *********
+//*****       Methods for addition of quadratic elements        ******
+//********                                                   *********
+//********************************************************************
+//********************************************************************
+
+//=======================================================================
+//function : AddEdgeWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) 
+{
+  SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID);
+  if(anElem) myScript->AddEdge(ID,n1,n2,n12);
+  return anElem;
+}
+
+//=======================================================================
+//function : AddEdge
+//purpose  : 
+//=======================================================================
+SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
+                                     const SMDS_MeshNode* n2,
+                                     const SMDS_MeshNode* n12)
+{
+  SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
+  if(anElem) myScript->AddEdge(anElem->GetID(), 
+                              n1->GetID(), 
+                              n2->GetID(),
+                               n12->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function : AddEdgeWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
+                                           const SMDS_MeshNode * n2, 
+                                           const SMDS_MeshNode * n12, 
+                                           int ID)
+{
+  return AddEdgeWithID(n1->GetID(),
+                      n2->GetID(),
+                       n12->GetID(),
+                      ID);
+}
+
+
+//=======================================================================
+//function : AddFace
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
+                                     const SMDS_MeshNode * n2,
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n12,
+                                     const SMDS_MeshNode * n23,
+                                     const SMDS_MeshNode * n31)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
+  if(anElem) myScript->AddFace(anElem->GetID(), 
+                              n1->GetID(), n2->GetID(), n3->GetID(),
+                               n12->GetID(), n23->GetID(), n31->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function : AddFaceWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
+                                           int n12,int n23,int n31, int ID)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID);
+  if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31);
+  return anElem;
+}
+
+//=======================================================================
+//function : AddFaceWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
+                                           const SMDS_MeshNode * n2,
+                                           const SMDS_MeshNode * n3,
+                                           const SMDS_MeshNode * n12,
+                                           const SMDS_MeshNode * n23,
+                                           const SMDS_MeshNode * n31, 
+                                           int ID)
+{
+  return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
+                       n12->GetID(), n23->GetID(), n31->GetID(),
+                      ID);
+}
+
+
+//=======================================================================
+//function : AddFace
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
+                                     const SMDS_MeshNode * n2,
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4,
+                                     const SMDS_MeshNode * n12,
+                                     const SMDS_MeshNode * n23,
+                                     const SMDS_MeshNode * n34,
+                                     const SMDS_MeshNode * n41)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
+  if(anElem) myScript->AddFace(anElem->GetID(), 
+                              n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
+                               n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function : AddFaceWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
+                                           int n12,int n23,int n34,int n41, int ID)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID);
+  if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41);
+  return anElem;
+}
+
+//=======================================================================
+//function : AddFaceWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
+                                           const SMDS_MeshNode * n2,
+                                           const SMDS_MeshNode * n3,
+                                           const SMDS_MeshNode * n4,
+                                           const SMDS_MeshNode * n12,
+                                           const SMDS_MeshNode * n23,
+                                           const SMDS_MeshNode * n34, 
+                                           const SMDS_MeshNode * n41, 
+                                           int ID)
+{
+  return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
+                       n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
+                      ID);
+}
+
+
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                         const SMDS_MeshNode * n2, 
+                                         const SMDS_MeshNode * n3,
+                                         const SMDS_MeshNode * n4,
+                                         const SMDS_MeshNode * n12,
+                                         const SMDS_MeshNode * n23,
+                                         const SMDS_MeshNode * n31,
+                                         const SMDS_MeshNode * n14, 
+                                         const SMDS_MeshNode * n24,
+                                         const SMDS_MeshNode * n34)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
+  if(anElem) myScript->AddVolume(anElem->GetID(), 
+                                n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
+                                n12->GetID(), n23->GetID(), n31->GetID(),
+                                 n14->GetID(), n24->GetID(), n34->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
+                                               int n12,int n23,int n31,
+                                               int n14,int n24,int n34, int ID)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23,
+                                                       n31,n14,n24,n34,ID);
+  if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
+  return anElem;
+}
+       
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 2d order tetrahedron of 10 nodes
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                               const SMDS_MeshNode * n2,
+                                               const SMDS_MeshNode * n3,
+                                               const SMDS_MeshNode * n4,
+                                               const SMDS_MeshNode * n12,
+                                               const SMDS_MeshNode * n23,
+                                               const SMDS_MeshNode * n31,
+                                               const SMDS_MeshNode * n14, 
+                                               const SMDS_MeshNode * n24,
+                                               const SMDS_MeshNode * n34,
+                                               int ID)
+{
+  return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
+                         n12->GetID(), n23->GetID(), n31->GetID(),
+                         n14->GetID(), n24->GetID(), n34->GetID(), ID);
+}
+
+
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                         const SMDS_MeshNode * n2, 
+                                         const SMDS_MeshNode * n3,
+                                         const SMDS_MeshNode * n4,
+                                         const SMDS_MeshNode * n5, 
+                                         const SMDS_MeshNode * n12,
+                                         const SMDS_MeshNode * n23,
+                                         const SMDS_MeshNode * n34,
+                                         const SMDS_MeshNode * n41,
+                                         const SMDS_MeshNode * n15, 
+                                         const SMDS_MeshNode * n25,
+                                         const SMDS_MeshNode * n35,
+                                         const SMDS_MeshNode * n45)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41,
+                                                 n15,n25,n35,n45);
+  if(anElem)
+    myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
+                        n3->GetID(), n4->GetID(), n5->GetID(),
+                        n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
+                        n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
+                                               int n12,int n23,int n34,int n41,
+                                               int n15,int n25,int n35,int n45, int ID)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,
+                                                       n12,n23,n34,n41,
+                                                       n15,n25,n35,n45,ID);
+  if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41,
+                                 n15,n25,n35,n45);
+  return anElem;
+}
+       
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 2d order pyramid of 13 nodes
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                               const SMDS_MeshNode * n2,
+                                               const SMDS_MeshNode * n3,
+                                               const SMDS_MeshNode * n4,
+                                               const SMDS_MeshNode * n5, 
+                                               const SMDS_MeshNode * n12,
+                                               const SMDS_MeshNode * n23,
+                                               const SMDS_MeshNode * n34,
+                                               const SMDS_MeshNode * n41,
+                                               const SMDS_MeshNode * n15, 
+                                               const SMDS_MeshNode * n25,
+                                               const SMDS_MeshNode * n35,
+                                               const SMDS_MeshNode * n45,
+                                               int ID)
+{
+  return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
+                         n4->GetID(), n5->GetID(),
+                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
+                         n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(),
+                         ID);
+}
+
+
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                         const SMDS_MeshNode * n2, 
+                                         const SMDS_MeshNode * n3,
+                                         const SMDS_MeshNode * n4,
+                                         const SMDS_MeshNode * n5, 
+                                         const SMDS_MeshNode * n6, 
+                                         const SMDS_MeshNode * n12,
+                                         const SMDS_MeshNode * n23,
+                                         const SMDS_MeshNode * n31, 
+                                         const SMDS_MeshNode * n45,
+                                         const SMDS_MeshNode * n56,
+                                         const SMDS_MeshNode * n64, 
+                                         const SMDS_MeshNode * n14,
+                                         const SMDS_MeshNode * n25,
+                                         const SMDS_MeshNode * n36)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
+                                                 n45,n56,n64,n14,n25,n36);
+  if(anElem)
+    myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
+                        n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
+                        n12->GetID(), n23->GetID(), n31->GetID(),
+                        n45->GetID(), n56->GetID(), n64->GetID(),
+                        n14->GetID(), n25->GetID(), n36->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
+                                               int n4, int n5, int n6,
+                                               int n12,int n23,int n31,
+                                               int n45,int n56,int n64,
+                                               int n14,int n25,int n36, int ID)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
+                                                       n12,n23,n31,
+                                                       n45,n56,n64,
+                                                       n14,n25,n36,ID);
+  if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
+                                 n45,n56,n64,n14,n25,n36);
+  return anElem;
+}
+       
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 2d order Pentahedron with 15 nodes
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                               const SMDS_MeshNode * n2,
+                                               const SMDS_MeshNode * n3,
+                                               const SMDS_MeshNode * n4,
+                                               const SMDS_MeshNode * n5, 
+                                               const SMDS_MeshNode * n6, 
+                                               const SMDS_MeshNode * n12,
+                                               const SMDS_MeshNode * n23,
+                                               const SMDS_MeshNode * n31, 
+                                               const SMDS_MeshNode * n45,
+                                               const SMDS_MeshNode * n56,
+                                               const SMDS_MeshNode * n64, 
+                                               const SMDS_MeshNode * n14,
+                                               const SMDS_MeshNode * n25,
+                                               const SMDS_MeshNode * n36,
+                                               int ID)
+{
+  return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
+                         n4->GetID(), n5->GetID(), n6->GetID(),
+                         n12->GetID(), n23->GetID(), n31->GetID(),
+                         n45->GetID(), n56->GetID(), n64->GetID(),
+                         n14->GetID(), n25->GetID(), n36->GetID(),
+                         ID);
+}
+
+
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                         const SMDS_MeshNode * n2, 
+                                         const SMDS_MeshNode * n3,
+                                         const SMDS_MeshNode * n4,
+                                         const SMDS_MeshNode * n5, 
+                                         const SMDS_MeshNode * n6, 
+                                         const SMDS_MeshNode * n7,
+                                         const SMDS_MeshNode * n8, 
+                                         const SMDS_MeshNode * n12,
+                                         const SMDS_MeshNode * n23,
+                                         const SMDS_MeshNode * n34,
+                                         const SMDS_MeshNode * n41, 
+                                         const SMDS_MeshNode * n56,
+                                         const SMDS_MeshNode * n67,
+                                         const SMDS_MeshNode * n78,
+                                         const SMDS_MeshNode * n85, 
+                                         const SMDS_MeshNode * n15,
+                                         const SMDS_MeshNode * n26,
+                                         const SMDS_MeshNode * n37,
+                                         const SMDS_MeshNode * n48)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
+                                                 n12,n23,n34,n41,
+                                                 n56,n67,n78,n85,
+                                                 n15,n26,n37,n48);
+  if(anElem)
+    myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
+                        n3->GetID(), n4->GetID(), n5->GetID(),
+                        n6->GetID(), n7->GetID(), n8->GetID(),
+                        n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
+                        n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
+                        n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
+                                               int n5, int n6, int n7, int n8,
+                                               int n12,int n23,int n34,int n41,
+                                               int n56,int n67,int n78,int n85,
+                                               int n15,int n26,int n37,int n48, int ID)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
+                                                       n12,n23,n34,n41,
+                                                       n56,n67,n78,n85,
+                                                       n15,n26,n37,n48,ID);
+  if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
+                                 n56,n67,n78,n85,n15,n26,n37,n48);
+  return anElem;
+}
+       
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 2d order Hexahedrons with 20 nodes
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                               const SMDS_MeshNode * n2,
+                                               const SMDS_MeshNode * n3,
+                                               const SMDS_MeshNode * n4,
+                                               const SMDS_MeshNode * n5, 
+                                               const SMDS_MeshNode * n6, 
+                                               const SMDS_MeshNode * n7,
+                                               const SMDS_MeshNode * n8, 
+                                               const SMDS_MeshNode * n12,
+                                               const SMDS_MeshNode * n23,
+                                               const SMDS_MeshNode * n34,
+                                               const SMDS_MeshNode * n41, 
+                                               const SMDS_MeshNode * n56,
+                                               const SMDS_MeshNode * n67,
+                                               const SMDS_MeshNode * n78,
+                                               const SMDS_MeshNode * n85, 
+                                               const SMDS_MeshNode * n15,
+                                               const SMDS_MeshNode * n26,
+                                               const SMDS_MeshNode * n37,
+                                               const SMDS_MeshNode * n48,
+                                               int ID)
+{
+  return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
+                         n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
+                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
+                         n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
+                         n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
+                         ID);
+}
+
+
index 88c531c9e5ae8071d889cb7206e609e2c0f3bab1..6a8f15e6d9038f00a5ad90d939891055fd372985 100644 (file)
@@ -93,6 +93,16 @@ public:
   virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1,
                                 const SMDS_MeshNode * n2);
   
+  // 2d order edge with 3 nodes: n12 - node between n1 and n2
+  virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int n12, int ID);
+  virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1,
+                                      const SMDS_MeshNode * n2, 
+                                      const SMDS_MeshNode * n12, 
+                                      int ID);
+  virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1,
+                                 const SMDS_MeshNode * n2,
+                                 const SMDS_MeshNode * n12);
+
   virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID);
   virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
                                       const SMDS_MeshNode * n2,
@@ -113,6 +123,44 @@ public:
                                 const SMDS_MeshNode * n3,
                                 const SMDS_MeshNode * n4);
 
+  // 2d order triangle of 6 nodes
+  virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3,
+                                       int n12,int n23,int n31, int ID);
+  virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3, 
+                                      const SMDS_MeshNode * n12,
+                                      const SMDS_MeshNode * n23,
+                                      const SMDS_MeshNode * n31, 
+                                      int ID);
+  virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1,
+                                const SMDS_MeshNode * n2,
+                                const SMDS_MeshNode * n3,
+                                 const SMDS_MeshNode * n12,
+                                const SMDS_MeshNode * n23,
+                                const SMDS_MeshNode * n31);
+
+  // 2d order quadrangle
+  virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4,
+                                       int n12,int n23,int n34,int n41, int ID);
+  virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3,
+                                      const SMDS_MeshNode * n4, 
+                                      const SMDS_MeshNode * n12,
+                                      const SMDS_MeshNode * n23,
+                                      const SMDS_MeshNode * n34,
+                                      const SMDS_MeshNode * n41, 
+                                      int ID);
+  virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1,
+                                const SMDS_MeshNode * n2,
+                                const SMDS_MeshNode * n3,
+                                const SMDS_MeshNode * n4,
+                                 const SMDS_MeshNode * n12,
+                                const SMDS_MeshNode * n23,
+                                const SMDS_MeshNode * n34,
+                                const SMDS_MeshNode * n41);
+
   virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int ID);
   virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
                                           const SMDS_MeshNode * n2,
@@ -171,6 +219,153 @@ public:
                                     const SMDS_MeshNode * n7,
                                     const SMDS_MeshNode * n8);
   
+  // 2d order tetrahedron of 10 nodes
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
+                                           int n12,int n23,int n31,
+                                           int n14,int n24,int n34, int ID);
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+                                          const SMDS_MeshNode * n2,
+                                          const SMDS_MeshNode * n3,
+                                          const SMDS_MeshNode * n4, 
+                                          const SMDS_MeshNode * n12,
+                                          const SMDS_MeshNode * n23,
+                                          const SMDS_MeshNode * n31,
+                                          const SMDS_MeshNode * n14, 
+                                          const SMDS_MeshNode * n24,
+                                          const SMDS_MeshNode * n34, 
+                                          int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+                                    const SMDS_MeshNode * n2,
+                                    const SMDS_MeshNode * n3,
+                                    const SMDS_MeshNode * n4,
+                                     const SMDS_MeshNode * n12,
+                                     const SMDS_MeshNode * n23,
+                                     const SMDS_MeshNode * n31,
+                                     const SMDS_MeshNode * n14, 
+                                     const SMDS_MeshNode * n24,
+                                     const SMDS_MeshNode * n34);
+
+  // 2d order pyramid of 13 nodes
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
+                                           int n12,int n23,int n34,int n41,
+                                           int n15,int n25,int n35,int n45,
+                                           int ID);
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+                                          const SMDS_MeshNode * n2,
+                                          const SMDS_MeshNode * n3,
+                                          const SMDS_MeshNode * n4,
+                                          const SMDS_MeshNode * n5, 
+                                          const SMDS_MeshNode * n12,
+                                          const SMDS_MeshNode * n23,
+                                          const SMDS_MeshNode * n34,
+                                          const SMDS_MeshNode * n41, 
+                                          const SMDS_MeshNode * n15,
+                                          const SMDS_MeshNode * n25,
+                                          const SMDS_MeshNode * n35,
+                                          const SMDS_MeshNode * n45, 
+                                          int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+                                    const SMDS_MeshNode * n2,
+                                    const SMDS_MeshNode * n3,
+                                    const SMDS_MeshNode * n4,
+                                    const SMDS_MeshNode * n5,
+                                     const SMDS_MeshNode * n12,
+                                     const SMDS_MeshNode * n23,
+                                     const SMDS_MeshNode * n34,
+                                     const SMDS_MeshNode * n41, 
+                                     const SMDS_MeshNode * n15,
+                                     const SMDS_MeshNode * n25,
+                                     const SMDS_MeshNode * n35,
+                                     const SMDS_MeshNode * n45);
+
+  // 2d order Pentahedron with 15 nodes
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3,
+                                           int n4, int n5, int n6,
+                                           int n12,int n23,int n31,
+                                           int n45,int n56,int n64,
+                                           int n14,int n25,int n36,
+                                           int ID);
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+                                          const SMDS_MeshNode * n2,
+                                          const SMDS_MeshNode * n3,
+                                          const SMDS_MeshNode * n4,
+                                          const SMDS_MeshNode * n5,
+                                          const SMDS_MeshNode * n6, 
+                                          const SMDS_MeshNode * n12,
+                                          const SMDS_MeshNode * n23,
+                                          const SMDS_MeshNode * n31, 
+                                          const SMDS_MeshNode * n45,
+                                          const SMDS_MeshNode * n56,
+                                          const SMDS_MeshNode * n64, 
+                                          const SMDS_MeshNode * n14,
+                                          const SMDS_MeshNode * n25,
+                                          const SMDS_MeshNode * n36, 
+                                          int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+                                    const SMDS_MeshNode * n2,
+                                    const SMDS_MeshNode * n3,
+                                    const SMDS_MeshNode * n4,
+                                    const SMDS_MeshNode * n5,
+                                    const SMDS_MeshNode * n6, 
+                                     const SMDS_MeshNode * n12,
+                                     const SMDS_MeshNode * n23,
+                                     const SMDS_MeshNode * n31, 
+                                     const SMDS_MeshNode * n45,
+                                     const SMDS_MeshNode * n56,
+                                     const SMDS_MeshNode * n64, 
+                                     const SMDS_MeshNode * n14,
+                                     const SMDS_MeshNode * n25,
+                                     const SMDS_MeshNode * n36);
+
+  // 2d order Hexahedrons with 20 nodes
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
+                                           int n5, int n6, int n7, int n8,
+                                           int n12,int n23,int n34,int n41,
+                                           int n56,int n67,int n78,int n85,
+                                           int n15,int n26,int n37,int n48,
+                                           int ID);
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+                                          const SMDS_MeshNode * n2,
+                                          const SMDS_MeshNode * n3,
+                                          const SMDS_MeshNode * n4,
+                                          const SMDS_MeshNode * n5,
+                                          const SMDS_MeshNode * n6,
+                                          const SMDS_MeshNode * n7,
+                                          const SMDS_MeshNode * n8, 
+                                          const SMDS_MeshNode * n12,
+                                          const SMDS_MeshNode * n23,
+                                          const SMDS_MeshNode * n34,
+                                          const SMDS_MeshNode * n41, 
+                                          const SMDS_MeshNode * n56,
+                                          const SMDS_MeshNode * n67,
+                                          const SMDS_MeshNode * n78,
+                                          const SMDS_MeshNode * n85, 
+                                          const SMDS_MeshNode * n15,
+                                          const SMDS_MeshNode * n26,
+                                          const SMDS_MeshNode * n37,
+                                          const SMDS_MeshNode * n48, 
+                                          int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+                                    const SMDS_MeshNode * n2,
+                                    const SMDS_MeshNode * n3,
+                                    const SMDS_MeshNode * n4,
+                                    const SMDS_MeshNode * n5,
+                                    const SMDS_MeshNode * n6,
+                                    const SMDS_MeshNode * n7,
+                                    const SMDS_MeshNode * n8, 
+                                     const SMDS_MeshNode * n12,
+                                     const SMDS_MeshNode * n23,
+                                     const SMDS_MeshNode * n34,
+                                     const SMDS_MeshNode * n41, 
+                                     const SMDS_MeshNode * n56,
+                                     const SMDS_MeshNode * n67,
+                                     const SMDS_MeshNode * n78,
+                                     const SMDS_MeshNode * n85, 
+                                     const SMDS_MeshNode * n15,
+                                     const SMDS_MeshNode * n26,
+                                     const SMDS_MeshNode * n37,
+                                     const SMDS_MeshNode * n48);
+
   virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector<int> nodes_ids,
                                                  const int        ID);
 
index 16c6069455f1caf82ec3bb8567f6a2c67f5a8d41..327a881619765ef036805936142207293ad86e69 100644 (file)
@@ -257,3 +257,98 @@ const list<SMESHDS_Command*>& SMESHDS_Script::GetCommands()
 {
   return myCommands;
 }
+
+
+//********************************************************************
+//*****             Methods for quadratic elements              ******
+//********************************************************************
+
+//=======================================================================
+//function : AddEdge
+//purpose  : 
+//=======================================================================
+void SMESHDS_Script::AddEdge(int NewEdgeID, int n1, int n2, int n12)
+{
+  getCommand(SMESHDS_AddQuadEdge)->AddEdge(NewEdgeID, n1, n2, n12);
+}
+
+//=======================================================================
+//function : AddFace
+//purpose  : 
+//=======================================================================
+void SMESHDS_Script::AddFace(int NewFaceID, int n1, int n2, int n3,
+                             int n12, int n23, int n31)
+{
+  getCommand(SMESHDS_AddQuadTriangle)->AddFace(NewFaceID, n1, n2, n3,
+                                               n12, n23, n31);
+}
+
+//=======================================================================
+//function : AddFace
+//purpose  : 
+//=======================================================================
+void SMESHDS_Script::AddFace(int NewFaceID, int n1, int n2, int n3, int n4,
+                             int n12, int n23, int n34, int n41)
+{
+  getCommand(SMESHDS_AddQuadQuadrangle)->AddFace(NewFaceID, n1, n2, n3, n4,
+                                                 n12, n23, n34, n41);
+}
+
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
+                               int n12, int n23, int n31,
+                               int n14, int n24, int n34)
+{
+  getCommand(SMESHDS_AddQuadTetrahedron)->AddVolume(NewVolID, n1, n2, n3, n4,
+                                                    n12, n23, n31,
+                                                    n14, n24, n34);
+}
+
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
+                               int n5, int n12, int n23, int n34, int n41,
+                               int n15, int n25, int n35, int n45)
+{
+  getCommand(SMESHDS_AddQuadPyramid)->AddVolume(NewVolID, n1, n2, n3, n4, n5,
+                                                n12, n23, n34, n41,
+                                                n15, n25, n35, n45);
+}
+
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
+                                int n5,int n6, int n12, int n23, int n31,
+                                int n45, int n56, int n64,
+                                int n14, int n25, int n36)
+{
+  getCommand(SMESHDS_AddQuadPentahedron)->AddVolume(NewVolID, n1,n2,n3,n4,n5,n6,
+                                                    n12, n23, n31,
+                                                    n45, n56, n64,
+                                                    n14, n25, n36);
+}
+
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3,
+                               int n4, int n5, int n6, int n7, int n8,
+                               int n12, int n23, int n34, int n41,
+                               int n56, int n67, int n78, int n85,
+                               int n15, int n26, int n37, int n48)
+{
+  getCommand(SMESHDS_AddQuadHexahedron)->AddVolume(NewVolID, n1, n2, n3, n4,
+                                                   n5, n6, n7, n8,
+                                                   n12, n23, n34, n41,
+                                                   n56, n67, n78, n85,
+                                                   n15, n26, n37, n48);
+}
+
index 366ac3bdcf481ce1b63310dcb63ffb63eeb91f60..95e5335ad97f9e0ad2670cdc1e19fbd8c5212e6a 100644 (file)
@@ -59,6 +59,27 @@ class SMESHDS_Script
                                   std::vector<int> nodes_ids,
                                   std::vector<int> quantities);
 
+        // special methods for quadratic elements
+       void AddEdge(int NewEdgeID, int n1, int n2, int n12);
+        void AddFace(int NewFaceID, int n1, int n2, int n3,
+                     int n12, int n23, int n31);
+        void AddFace(int NewFaceID, int n1, int n2, int n3, int n4,
+                     int n12, int n23, int n34, int n41);
+        void AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
+                       int n12, int n23, int n31, int n14, int n24, int n34);
+        void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n5,
+                       int n12, int n23, int n34, int n41,
+                       int n15, int n25, int n35, int n45);
+        void AddVolume(int NewVolID, int n1, int n2, int n3,
+                       int n4, int n5, int n6,
+                       int n12, int n23, int n31,
+                       int n45, int n56, int n64,
+                       int n14, int n25, int n36);
+        void AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
+                       int n5, int n6, int n7, int n8,
+                       int n12, int n23, int n34, int n41,
+                       int n56, int n67, int n78, int n85,
+                       int n15, int n26, int n37, int n48);
         void MoveNode(int NewNodeID, double x, double y, double z);
        void RemoveNode(int NodeID);
        void RemoveElement(int ElementID);
index 0dbb8e0a0b88fb7145972cab5638325ec1085d66..fe8f66ecf3c958047c3ea3f48d7889d86ce6c745 100644 (file)
@@ -109,7 +109,8 @@ LIB_SRC =   SMESHGUI.cxx \
                SMESHGUI_MeshOp.cxx \
                SMESHGUI_Displayer.cxx \
                SMESHGUI_Hypotheses.cxx \
-               SMESHGUI_ShapeByMeshDlg.cxx
+               SMESHGUI_ShapeByMeshDlg.cxx \
+               SMESHGUI_AddQuadraticElementDlg.cxx
 
 LIB_MOC = \
                SMESHGUI.h \
@@ -156,8 +157,8 @@ LIB_MOC = \
                SMESHGUI_Dialog.h \
                SMESHGUI_MeshDlg.h \
                SMESHGUI_MeshOp.h \
-               SMESHGUI_Hypotheses.h \
-               SMESHGUI_ShapeByMeshDlg.h
+               SMESHGUI_ShapeByMeshDlg.h \
+               SMESHGUI_AddQuadraticElementDlg.h
 
 
 LIB_CLIENT_IDL = SALOME_Exception.idl \
index 91b86ec1fb224906ab0cf618c1d8414e02984dca..f4df5d67dc08e6e1465e6b04c6cb0bb6f6eb8579 100644 (file)
@@ -40,6 +40,7 @@
 #include "SMESHGUI_Hypotheses.h"
 #include "SMESHGUI_MoveNodesDlg.h"
 #include "SMESHGUI_AddMeshElementDlg.h"
+#include "SMESHGUI_AddQuadraticElementDlg.h"
 #include "SMESHGUI_EditHypothesesDlg.h"
 #include "SMESHGUI_CreateHypothesesDlg.h"
 #include "SMESHGUI_FilterDlg.h"
@@ -1866,6 +1867,46 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       }
       break;
     }
+  case 4034:     // QUADRATIC EDGE
+  case 4035:     // QUADRATIC TRIANGLE
+  case 4036:     // QUADRATIC QUADRANGLE
+  case 4037:     // QUADRATIC TETRAHEDRON
+  case 4038:     // QUADRATIC PYRAMID
+  case 4039:     // QUADRATIC PENTAHEDRON
+  case 4040:     // QUADRATIC HEXAHEDRON
+    {
+      if(checkLock(aStudy)) break;
+      if ( vtkwnd ) {
+       EmitSignalDeactivateDialog();
+       int type;
+
+       switch (theCommandID) {
+       case 4034:                                      
+         type = QUAD_EDGE; break;
+       case 4035:                                      
+         type = QUAD_TRIANGLE; break;
+       case 4036:                                     
+         type = QUAD_QUADRANGLE; break;
+       case 4037:                                     
+         type = QUAD_TETRAHEDRON; break;
+       case 4038:                                     
+         type = QUAD_PYRAMID; break; 
+       case 4039:                                     
+         type = QUAD_PENTAHEDRON; break; 
+       case 4040:
+         type = QUAD_HEXAHEDRON;
+         break;
+       default:;
+       }
+        new SMESHGUI_AddQuadraticElementDlg( this, type );
+      }
+      else {
+       SUIT_MessageBox::warn1(SMESHGUI::desktop(),
+                              tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                              tr("SMESH_BUT_OK"));
+      }
+      break;
+    }
   case 4041:                                   // REMOVES NODES
     {
       if(checkLock(aStudy)) break;
@@ -2320,6 +2361,13 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( 301, "DISPLAY" );
   createSMESHAction( 302, "DISPLAY_ONLY" );
   createSMESHAction( 4033, "POLYHEDRON", "ICON_DLG_POLYHEDRON" );
+  createSMESHAction( 4034, "QUADRATIC_EDGE", "ICON_DLG_QUADRATIC_EDGE" );
+  createSMESHAction( 4035, "QUADRATIC_TRIANGLE", "ICON_DLG_QUADRATIC_TRIANGLE" );
+  createSMESHAction( 4036, "QUADRATIC_QUADRANGLE", "ICON_DLG_QUADRATIC_QUADRANGLE" );
+  createSMESHAction( 4037, "QUADRATIC_TETRAHEDRON", "ICON_DLG_QUADRATIC_TETRAHEDRON" );
+  createSMESHAction( 4038, "QUADRATIC_PYRAMID", "ICON_DLG_QUADRATIC_PYRAMID" );
+  createSMESHAction( 4039, "QUADRATIC_PENTAHEDRON", "ICON_DLG_QUADRATIC_PENTAHEDRON" );
+  createSMESHAction( 4040, "QUADRATIC_HEXAHEDRON", "ICON_DLG_QUADRATIC_HEXAHEDRON" );
 
   // ----- create menu --------------
   int fileId   = createMenu( tr( "MEN_FILE" ),   -1,  1 ),
@@ -2399,6 +2447,14 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 4031, addId, -1 );
   createMenu( 4032, addId, -1 );
   createMenu( 4033, addId, -1 );
+  createMenu( separator(), addId, -1 );
+  createMenu( 4034, addId, -1 );
+  createMenu( 4035, addId, -1 );
+  createMenu( 4036, addId, -1 );
+  createMenu( 4037, addId, -1 );
+  createMenu( 4038, addId, -1 );
+  createMenu( 4039, addId, -1 );
+  createMenu( 4040, addId, -1 );
 
   createMenu( 4041, removeId, -1 );
   createMenu( 4042, removeId, -1 );
@@ -2475,6 +2531,14 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( 4032, addRemTb );
   createTool( 4033, addRemTb );
   createTool( separator(), addRemTb );
+  createTool( 4034, addRemTb );
+  createTool( 4035, addRemTb );
+  createTool( 4036, addRemTb );
+  createTool( 4037, addRemTb );
+  createTool( 4038, addRemTb );
+  createTool( 4039, addRemTb );
+  createTool( 4040, addRemTb );
+  createTool( separator(), addRemTb );
   createTool( 4041, addRemTb );
   createTool( 4042, addRemTb );
   createTool( separator(), addRemTb );
index caf4ffc45017ad238cc090d3ff9e5d2ab6742851..06e6cf1b9f38526f80e81a5278a6fb366a19dc82 100644 (file)
@@ -37,6 +37,7 @@
 #include <vtkUnsignedCharArray.h>
 #include <vtkUnstructuredGrid.h>
 #include <vtkDataSetMapper.h>
+#include <vtkProperty.h>
 
 #include <vtkQuadraticEdge.h>
 #include <vtkQuadraticTriangle.h>
index 74ad155bd575c272e8dcc8dbaf788fbf5cbd4dd5..7d1cb98084c17b4c326f064c97c461177cbdf571 100755 (executable)
@@ -388,6 +388,35 @@ SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds()
       anActor = myActor;
     if (anActor != 0)
     {
+      // skl 07.02.2006
+      SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
+      if( myFilterType == SMESHGUI_TriaFilter || 
+         myFilterType == SMESHGUI_QuadFilter ||
+         myFilterType == SMESHGUI_FaceFilter ) {
+       SMDS_FaceIteratorPtr it = aMesh->facesIterator();
+       while(it->more()) {
+         const SMDS_MeshFace* f = it->next();
+         if(myFilterType == SMESHGUI_FaceFilter) {
+           myIds.Add(f->GetID());
+         }
+         else if( myFilterType==SMESHGUI_TriaFilter &&
+                  ( f->NbNodes()==3 || f->NbNodes()==6 ) ) {
+           myIds.Add(f->GetID());
+         }
+         else if( myFilterType==SMESHGUI_QuadFilter &&
+                  ( f->NbNodes()==4 || f->NbNodes()==8 ) ) {
+           myIds.Add(f->GetID());
+         }
+       }
+      }
+      else if(myFilterType == SMESHGUI_VolumeFilter) {
+       SMDS_VolumeIteratorPtr it = aMesh->volumesIterator();
+       while(it->more()) {
+         const SMDS_MeshVolume* f = it->next();
+         myIds.Add(f->GetID());
+       }
+      }
+      /* commented by skl 07.02.2006
       TVisualObjPtr aVisualObj = anActor->GetObject();
       vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid();
       if (aGrid != 0) {
@@ -411,6 +440,7 @@ SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds()
           }
         }
       }
+      */
     }
   }
 
index 60dff5a19bca3c6cbe91cf333066fe5018a4f701..463f6f37a1d49969f6fdd1802bed7859c6188c2e 100644 (file)
@@ -155,7 +155,33 @@ msgstr "mesh_tetra.png"
 msgid "ICON_DLG_HEXAS"
 msgstr "mesh_hexa.png"
 
+#Quadratic Edge
+msgid "ICON_DLG_QUADRATIC_EDGE"
+msgstr "mesh_quad_edge.png"
 
+#Quadratic Triangle
+msgid "ICON_DLG_QUADRATIC_TRIANGLE"
+msgstr "mesh_quad_triangle.png"
+
+#Quadratic Quadrangle
+msgid "ICON_DLG_QUADRATIC_QUADRANGLE"
+msgstr "mesh_quad_quadrangle.png"
+
+#Quadratic Tetrahedron
+msgid "ICON_DLG_QUADRATIC_TETRAHEDRON"
+msgstr "mesh_quad_tetrahedron.png"
+
+#Quadratic Pyramid
+msgid "ICON_DLG_QUADRATIC_PYRAMID"
+msgstr "mesh_quad_pyramid.png"
+
+#Quadratic Pentahedron
+msgid "ICON_DLG_QUADRATIC_PENTAHEDRON"
+msgstr "mesh_quad_pentahedron.png"
+
+#Quadratic Hexahedron
+msgid "ICON_DLG_QUADRATIC_HEXAHEDRON"
+msgstr "mesh_quad_hexahedron.png"
 #-----------------------------------------------------------
 # ObjectBrowser
 #-----------------------------------------------------------
index 2825f19a8adcc8ebb3758beee87fab8bd18d0cc6..16737d44aef883c63a59125d8ac6c27aff83d5e4 100644 (file)
@@ -170,6 +170,35 @@ msgstr "mesh_hexa.png"
 #Polyhedre
 msgid "ICON_DLG_POLYHEDRON"
 msgstr "mesh_polyhedron.png"
+
+#Quadratic Edge
+msgid "ICON_DLG_QUADRATIC_EDGE"
+msgstr "mesh_quad_edge.png"
+
+#Quadratic Triangle
+msgid "ICON_DLG_QUADRATIC_TRIANGLE"
+msgstr "mesh_quad_triangle.png"
+
+#Quadratic Quadrangle
+msgid "ICON_DLG_QUADRATIC_QUADRANGLE"
+msgstr "mesh_quad_quadrangle.png"
+
+#Quadratic Tetrahedron
+msgid "ICON_DLG_QUADRATIC_TETRAHEDRON"
+msgstr "mesh_quad_tetrahedron.png"
+
+#Quadratic Pyramid
+msgid "ICON_DLG_QUADRATIC_PYRAMID"
+msgstr "mesh_quad_pyramid.png"
+
+#Quadratic Pentahedron
+msgid "ICON_DLG_QUADRATIC_PENTAHEDRON"
+msgstr "mesh_quad_pentahedron.png"
+
+#Quadratic Hexahedron
+msgid "ICON_DLG_QUADRATIC_HEXAHEDRON"
+msgstr "mesh_quad_hexahedron.png"
+
 #-----------------------------------------------------------
 # ObjectBrowser
 #-----------------------------------------------------------
index 75439de3519066c29f03efbf22031fa75dab1112..c043fc30736b06798889c0a877e2718c5c9ee042 100644 (file)
@@ -1814,6 +1814,80 @@ msgstr "Polygon"
 msgid "SMESH_ADD_POLYGON"
 msgstr "Add polygon"
 
+msgid "SMESH_ADD_QUADRATIC_EDGE_TITLE"
+msgstr "Add Quadratic Edge"
+
+msgid "SMESH_ADD_QUADRATIC_TRIANGLE_TITLE"
+msgstr "Add Quadratic Triangle"
+
+msgid "SMESH_ADD_QUADRATIC_QUADRANGLE_TITLE"
+msgstr "Add Quadratic Quadrangle"
+
+msgid "SMESH_ADD_QUADRATIC_TETRAHEDRON_TITLE"
+msgstr "Add Quadratic Tetrahedron"
+
+msgid "SMESH_ADD_QUADRATIC_PYRAMID_TITLE"
+msgstr "Add Quadratic Pyramid"
+
+msgid "SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE"
+msgstr "Add Quadratic Pentahedron"
+
+msgid "SMESH_ADD_QUADRATIC_HEXAHEDRON_TITLE"
+msgstr "Add Quadratic Hexahedron"
+
+msgid "SMESH_QUADRATIC_EDGE"
+msgstr "Quadratic Edge"
+
+msgid "SMESH_QUADRATIC_TRIANGLE"
+msgstr "Quadratic Triangle"
+
+msgid "SMESH_QUADRATIC_QUADRANGLE"
+msgstr "Quadratic Quadrangle"
+
+msgid "SMESH_QUADRATIC_TETRAHEDRON"
+msgstr "Quadratic Tetrahedron"
+
+msgid "SMESH_QUADRATIC_PYRAMID"
+msgstr "Quadratic Pyramid"
+
+msgid "SMESH_QUADRATIC_PENTAHEDRON"
+msgstr "Quadratic Pentahedron"
+
+msgid "SMESH_QUADRATIC_HEXAHEDRON"
+msgstr "Quadratic Hexahedron"
+
+msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_CORNER_NODES"
+msgstr "Corner Nodes:"
+
+msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_EDGE"
+msgstr "Add Quadratic Edge"
+
+msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_TRIANGLE"
+msgstr "Add Quadratic Triangle"
+
+msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_QUADRANGLE"
+msgstr "Add Quadratic Quadrangle"
+
+msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_TETRAHEDRON"
+msgstr "Add Quadratic Tetrahedron"
+
+msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_PYRAMID"
+msgstr "Add Quadratic PYRAMID"
+
+msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_PENTAHEDRON"
+msgstr "Add Quadratic Pentahedron"
+
+msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_HEXAHEDRON"
+msgstr "Add Quadratic Hexahedron"
+
+msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_FIRST"
+msgstr "First"
+
+msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_MIDDLE"
+msgstr "Middle"
+
+msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_LAST"
+msgstr "Last"
 #----------------------------------------------------
 
 msgid "SMESHGUI_CreatePatternDlg::CAPTION"
@@ -2028,6 +2102,27 @@ msgstr "Polygon"
 msgid "MEN_POLYHEDRON"
 msgstr "Polyhedron"
 
+msgid "MEN_QUADRATIC_EDGE"
+msgstr "Quadratic Edge"
+
+msgid "MEN_QUADRATIC_TRIANGLE"
+msgstr "Quadratic Triangle"
+
+msgid "MEN_QUADRATIC_QUADRANGLE"
+msgstr "Quadratic Quadrangle"
+
+msgid "MEN_QUADRATIC_TETRAHEDRON"
+msgstr "Quadratic Tetrahedron"
+
+msgid "MEN_QUADRATIC_PYRAMID"
+msgstr "Quadratic Pyramid"
+
+msgid "MEN_QUADRATIC_PENTAHEDRON"
+msgstr "Quadratic Pentahedron"
+
+msgid "MEN_QUADRATIC_HEXAHEDRON"
+msgstr "Quadratic Hexahedron"
+
 msgid "MEN_NODES"
 msgstr "Nodes"
 
@@ -2357,6 +2452,27 @@ msgstr "Polygon"
 msgid "TOP_POLYHEDRON"
 msgstr "Polyhedron"
 
+msgid "TOP_QUADRATIC_EDGE"
+msgstr "Quadratic Edge"
+
+msgid "TOP_QUADRATIC_TRIANGLE"
+msgstr "Quadratic Triangle"
+
+msgid "TOP_QUADRATIC_QUADRANGLE"
+msgstr "Quadratic Quadrangle"
+
+msgid "TOP_QUADRATIC_TETRAHEDRON"
+msgstr "Quadratic Tetrahedron"
+
+msgid "TOP_QUADRATIC_PYRAMID"
+msgstr "Quadratic Pyramid"
+
+msgid "TOP_QUADRATIC_PENTAHEDRON"
+msgstr "Quadratic Pentahedron"
+
+msgid "TOP_QUADRATIC_HEXAHEDRON"
+msgstr "Quadratic Hexahedron"
+
 msgid "TOP_NODES"
 msgstr "Nodes"
 
@@ -2637,6 +2753,27 @@ msgstr "Polygon"
 msgid "STB_POLYHEDRON"
 msgstr "Polyhedron"
 
+msgid "STB_QUADRATIC_EDGE"
+msgstr "Quadratic Edge"
+
+msgid "STB_QUADRATIC_TRIANGLE"
+msgstr "Quadratic Triangle"
+
+msgid "STB_QUADRATIC_QUADRANGLE"
+msgstr "Quadratic Quadrangle"
+
+msgid "STB_QUADRATIC_TETRAHEDRON"
+msgstr "Quadratic Tetrahedron"
+
+msgid "STB_QUADRATIC_PYRAMID"
+msgstr "Quadratic Pyramid"
+
+msgid "STB_QUADRATIC_PENTAHEDRON"
+msgstr "Quadratic Pentahedron"
+
+msgid "STB_QUADRATIC_HEXAHEDRON"
+msgstr "Quadratic Hexahedron"
+
 msgid "STB_NODES"
 msgstr "Nodes"
 
index 6d8150db80a4ca98f62420780a0af5d6d1f45f1a..5adfa1c73a2a401369b904e621d327e73cc173b7 100644 (file)
@@ -1,3 +1,31 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESH_2D_Algo_i.hxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
 // File      : SMESH_2smeshpy.cxx
 // Created   : Fri Nov 18 13:20:10 2005
 // Author    : Edward AGAPOV (eap)
@@ -407,6 +435,13 @@ _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd): _pyObject(theCreation
  */
 //================================================================================
 
+//================================================================================
+/*!
+ * \brief Convert a IDL API command of SMESH::Mesh to a method call of python Mesh
+  * \param theCommand - Engine method called for this mesh
+ */
+//================================================================================
+
 void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
 {
   // smesh.py wraps the following methods:
@@ -663,6 +698,11 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th
     hyp->myCreationMethod = "Propagation";
     hyp->myType = "Regular_1D";
   }
+  else if ( hypType == "QuadraticMesh" ) {
+    hyp->myDim = 1;
+    hyp->myCreationMethod = "QuadraticMesh";
+    hyp->myType = "Regular_1D";
+  }
   else if ( hypType == "AutomaticLength" ) {
     hyp->myDim = 1;
     hyp->myCreationMethod = "AutomaticLength";
index d5cdce9fbc609496ddb130f93bfb02d8e1de9e51..768c37ad83db1395eafd5b52298d8c2fee86649f 100644 (file)
@@ -89,7 +89,7 @@ SMESH_Hypothesis_i::~SMESH_Hypothesis_i()
 
 char* SMESH_Hypothesis_i::GetName()
 {
-  MESSAGE( "SMESH_Hypothesis_i::GetName" );
+  //MESSAGE( "SMESH_Hypothesis_i::GetName" );
   return CORBA::string_dup( myBaseImpl->GetName() );
 };
 
index 3f1c017d444860ed4f43dd519368cb711a4fba28..bbf9590069631a612e308244c12bfd7fcd7b9668 100644 (file)
@@ -1121,7 +1121,7 @@ void SMESH_MEDMesh_i::createFamilies() throw(SALOME::SALOME_Exception)
        if (_creeFamily == false)
        {
                _creeFamily = true;
-               SMESH_subMesh_i *subMeshServant;
+               //SMESH_subMesh_i *subMeshServant;
 
                map < int, SMESH_subMesh_i * >::iterator it;
                for (it = _mesh_i->_mapSubMesh_i.begin();
index 9aa35ea1e2ce8320a14051225d9f6ed4260245a6..d852584403a3a2b87fca8881f2fa45d47a27c040 100644 (file)
@@ -128,6 +128,17 @@ CORBA::Boolean SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
     TPythonDump() << "isDone = " << this << ".AddEdge([ "
                   << index1 << ", " << index2 <<" ])";
   }
+  if (NbNodes == 3) {
+    CORBA::Long n1 = IDsOfNodes[0];
+    CORBA::Long n2 = IDsOfNodes[1];
+    CORBA::Long n12 = IDsOfNodes[2];
+    GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
+                         GetMeshDS()->FindNode(n2),
+                         GetMeshDS()->FindNode(n12));
+    // Update Python script
+    TPythonDump() << "isDone = " << this << ".AddEdge([ "
+                  <<n1<<", "<<n2<<", "<<n12<<" ])";
+  }
   return true;
 }
 
@@ -175,9 +186,15 @@ CORBA::Boolean SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
   {
     GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
   }
-  else
+  else if (NbNodes == 6)
   {
-    GetMeshDS()->AddPolygonalFace(nodes);
+    GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
+                         nodes[4], nodes[5]);
+  }
+  else if (NbNodes == 8)
+  {
+    GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
+                         nodes[4], nodes[5], nodes[6], nodes[7]);
   }
 
   // Update Python script
@@ -189,6 +206,30 @@ CORBA::Boolean SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
   return true;
 };
 
+//=============================================================================
+/*!
+ *  AddPolygonalFace
+ */
+//=============================================================================
+CORBA::Boolean SMESH_MeshEditor_i::AddPolygonalFace
+                                   (const SMESH::long_array & IDsOfNodes)
+{
+  int NbNodes = IDsOfNodes.length();
+  std::vector<const SMDS_MeshNode*> nodes (NbNodes);
+  for (int i = 0; i < NbNodes; i++)
+    nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
+
+  GetMeshDS()->AddPolygonalFace(nodes);
+  
+  // Update Python script
+  TPythonDump() <<"isDone = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
+#ifdef _DEBUG_
+  TPythonDump() << "print 'AddPolygonalFace: ', isDone";
+#endif
+
+  return true;
+};
+
 //=============================================================================
 /*!
  *
@@ -202,12 +243,26 @@ CORBA::Boolean SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNode
   for(int i=0;i<NbNodes;i++)
     n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
 
+  SMDS_MeshElement* elem = 0;
   switch(NbNodes)
   {
-  case 4:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
-  case 5:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
-  case 6:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
-  case 8:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
+  case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
+  case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
+  case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
+  case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
+  case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
+                                        n[6],n[7],n[8],n[9]);
+    break;
+  case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
+                                        n[7],n[8],n[9],n[10],n[11],n[12]);
+    break;
+  case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
+                                        n[9],n[10],n[11],n[12],n[13],n[14]);
+    break;
+  case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
+                                        n[8],n[9],n[10],n[11],n[12],n[13],n[14],
+                                        n[15],n[16],n[17],n[18],n[19]);
+    break;
   }
   // Update Python script
   TPythonDump() << "isDone = " << this << ".AddVolume( " << IDsOfNodes << " )";
@@ -215,7 +270,7 @@ CORBA::Boolean SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNode
   TPythonDump() << "print 'AddVolume: ', isDone";
 #endif
 
-  return true;
+  return elem;
 };
 
 //=============================================================================
index aa28198c1fb6bef8e5fc6d5833e33afb6543b30d..0632747a643098777209a1315fe0f22ddbe5aebe 100644 (file)
@@ -50,6 +50,7 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
   CORBA::Boolean AddNode(CORBA::Double x, CORBA::Double y, CORBA::Double z);
   CORBA::Boolean AddEdge(const SMESH::long_array & IDsOfNodes);
   CORBA::Boolean AddFace(const SMESH::long_array & IDsOfNodes);
+  CORBA::Boolean AddPolygonalFace(const SMESH::long_array & IDsOfNodes);
   CORBA::Boolean AddVolume(const SMESH::long_array & IDsOfNodes);
 
   CORBA::Boolean AddPolyhedralVolume(const SMESH::long_array & IDsOfNodes,
index 4242344af51be12ae23c454ea6e91914ed234afc..ec24cadfa1999533434d241ea8538fa1c6ee47bc 100644 (file)
@@ -250,6 +250,18 @@ class Mesh_Segment(Mesh_Algorithm):
         hyp.SetFineness( fineness )
         return hyp
 
+    def QuadraticMesh(self):
+        """
+         Define "QuadraticMesh" hypothesis, forcing construction of quadratic edges.
+         If the 2D mesher sees that all boundary edges are quadratic ones,
+         it generates quadratic faces, else it generates linear faces using
+         medium nodes as if they were vertex ones.
+         The 3D mesher generates quadratic volumes only if all boundary faces
+         are quadratic ones, else it fails.
+        """
+        hyp = self.Hypothesis("QuadraticMesh")
+        return hyp
+
 # Public class: Mesh_Segment_Python
 # ---------------------------------
 
index 592ff2b2b14620ec1ee2ce3755518ca7a51b201a..d210078161630cef6588ae51041270871f7b4667 100644 (file)
@@ -50,7 +50,9 @@ EXPORT_HEADERS = \
        StdMeshers_Hexa_3D.hxx \
        StdMeshers_AutomaticLength.hxx \
        StdMeshers_Distribution.hxx \
-       StdMeshers_QuadranglePreference.hxx
+       StdMeshers_QuadranglePreference.hxx \
+       StdMeshers_Helper.hxx \
+       StdMeshers_QuadraticMesh.hxx
 
 EXPORT_PYSCRIPTS =
 
@@ -76,7 +78,9 @@ LIB_SRC = \
        StdMeshers_Hexa_3D.cxx \
        StdMeshers_AutomaticLength.cxx \
        StdMeshers_Distribution.cxx \
-       StdMeshers_QuadranglePreference.cxx
+       StdMeshers_QuadranglePreference.cxx \
+       StdMeshers_Helper.cxx \
+       StdMeshers_QuadraticMesh.cxx
 
 LIB_SERVER_IDL = 
 
index a3ed4f11a7142cca9be57bc944b2e49de2af9d57..a5ed0982050e3df33487074e26b784be8db6a2fd 100644 (file)
@@ -45,6 +45,7 @@ using namespace std;
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TColStd_ListIteratorOfListOfInteger.hxx>
+#include <TColStd_MapOfInteger.hxx>
 
 #include <BRep_Tool.hxx>
 #include <Geom_Surface.hxx>
@@ -70,15 +71,14 @@ static bool ComputePentahedralMesh(SMESH_Mesh & aMesh,      const TopoDS_Shape & aSha
 //=============================================================================
 
 StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId,
-       SMESH_Gen * gen):SMESH_3D_Algo(hypId, studyId, gen)
+                                       SMESH_Gen * gen):SMESH_3D_Algo(hypId, studyId, gen)
 {
-       MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D");
-       _name = "Hexa_3D";
-//   _shapeType = TopAbs_SOLID;
-       _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit /shape type
-//   MESSAGE("_shapeType octal " << oct << _shapeType);
-       for (int i = 0; i < 6; i++)
-               _quads[i] = 0;
+  MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D");
+  _name = "Hexa_3D";
+  _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);      // 1 bit /shape type
+  for (int i = 0; i < 6; i++)
+    _quads[i] = 0;
+  myTool = 0;
 }
 
 //=============================================================================
@@ -89,11 +89,29 @@ StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId,
 
 StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D()
 {
-       MESSAGE("StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D");
-       for (int i = 0; i < 6; i++)
-               StdMeshers_Quadrangle_2D::QuadDelete(_quads[i]);
+  MESSAGE("StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D");
+  ClearAndReturn(true);
 }
 
+//================================================================================
+/*!
+ * \brief Clear fields and return the argument
+  * \param res - the value to return
+  * \retval bool - the argument value
+ */
+//================================================================================
+
+bool StdMeshers_Hexa_3D::ClearAndReturn(const bool res)
+{
+  for (int i = 0; i < 6; i++)
+    StdMeshers_Quadrangle_2D::QuadDelete(_quads[i]);
+  if ( myTool )
+    delete myTool;
+  myTool = 0;
+  return res;
+}
+
+
 //=============================================================================
 /*!
  *  
@@ -146,6 +164,7 @@ static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int&
   return true;
 }
 
+
 //=============================================================================
 /*!
  * Hexahedron mesh on hexaedron like form
@@ -163,534 +182,507 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
        const TopoDS_Shape & aShape)throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
-       MESSAGE("StdMeshers_Hexa_3D::Compute");
-       //bool isOk = false;
-       SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
-       //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
-       //const SMESHDS_SubMesh *& subMeshDS = theSubMesh->GetSubMeshDS();
-
-       // 0.  - shape and face mesh verification
-       // 0.1 - shape must be a solid (or a shell) with 6 faces
-       //MESSAGE("---");
-
-       vector < SMESH_subMesh * >meshFaces;
-       for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next())
-       {
-               SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
-               ASSERT(aSubMesh);
-               meshFaces.push_back(aSubMesh);
-       }
-       if (meshFaces.size() != 6)
-       {
-               SCRUTE(meshFaces.size());
-//             ASSERT(0);
-               return false;
-       }
-
-       // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges)
-       //MESSAGE("---");
-
-       for (int i = 0; i < 6; i++)
-       {
-         TopoDS_Shape aFace = meshFaces[i]->GetSubShape();
-         SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace);
-         string algoName = algo->GetName();
-          bool isAllQuad = false;
-         if (algoName == "Quadrangle_2D") {
-            SMESHDS_SubMesh * sm = meshDS->MeshElements( aFace );
-            if ( sm ) {
-              isAllQuad = true;
-              SMDS_ElemIteratorPtr eIt = sm->GetElements();
-              while ( isAllQuad && eIt->more() )
-                isAllQuad = ( eIt->next()->NbNodes() == 4 );
-            }
-          }
-          if ( ! isAllQuad ) {
-           //modified by NIZNHY-PKV Wed Nov 17 15:31:37 2004 f
-            bool bIsOk;
-            //
-            bIsOk=ComputePentahedralMesh(aMesh, aShape);
-            if (bIsOk) {
-              return true;
-            }
-           //modified by NIZNHY-PKV Wed Nov 17 15:31:42 2004 t
-           SCRUTE(algoName);
-           //                  ASSERT(0);
-           return false;
-         }
-         StdMeshers_Quadrangle_2D *quadAlgo =
-           dynamic_cast < StdMeshers_Quadrangle_2D * >(algo);
-         ASSERT(quadAlgo);
-         try
-           {
-             _quads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace);
-             // *** to delete after usage
-           }
-         catch(SALOME_Exception & S_ex)
-           {
-             // *** delete _quads
-             // *** throw exception
-             //                        ASSERT(0);
-             return false;
-           }
-
-         // 0.2.1 - number of points on the opposite edges must be the same
-         if (_quads[i]->nbPts[0] != _quads[i]->nbPts[2] ||
-             _quads[i]->nbPts[1] != _quads[i]->nbPts[3])
-           {
-             MESSAGE("different number of points on the opposite edges of face " << i);
-             //                  ASSERT(0);
-             return false;
-           }
-       }
-
-       // 1.  - identify faces and vertices of the "cube"
-       // 1.1 - ancestor maps vertex->edges in the cube
-       //MESSAGE("---");
-
-       TopTools_IndexedDataMapOfShapeListOfShape MS;
-       TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, MS);
-
-       // 1.2 - first face is choosen as face Y=0 of the unit cube
-       //MESSAGE("---");
-
-       const TopoDS_Shape & aFace = meshFaces[0]->GetSubShape();
-       const TopoDS_Face & F = TopoDS::Face(aFace);
-
-       // 1.3 - identify the 4 vertices of the face Y=0: V000, V100, V101, V001
-       //MESSAGE("---");
-
-       int i = 0;
-       TopoDS_Edge E = _quads[0]->edge[i];     //edge will be Y=0,Z=0 on unit cube
-       double f, l;
-       Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
-       TopoDS_Vertex VFirst, VLast;
-       TopExp::Vertices(E, VFirst, VLast);     // corresponds to f and l
-       bool isForward =
-               (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
-
-       if (isForward)
-       {
-               _cube.V000 = VFirst;    // will be (0,0,0) on the unit cube
-               _cube.V100 = VLast;             // will be (1,0,0) on the unit cube
-       }
-       else
-       {
-               _cube.V000 = VLast;
-               _cube.V100 = VFirst;
-       }
-
-       i = 1;
-       E = _quads[0]->edge[i];
-       C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
-       TopExp::Vertices(E, VFirst, VLast);
-       isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
-       if (isForward)
-               _cube.V101 = VLast;             // will be (1,0,1) on the unit cube
-       else
-               _cube.V101 = VFirst;
-
-       i = 2;
-       E = _quads[0]->edge[i];
-       C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
-       TopExp::Vertices(E, VFirst, VLast);
-       isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
-       if (isForward)
-               _cube.V001 = VLast;             // will be (0,0,1) on the unit cube
-       else
-               _cube.V001 = VFirst;
+  MESSAGE("StdMeshers_Hexa_3D::Compute");
+  SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+  
+  // 0.  - shape and face mesh verification
+  // 0.1 - shape must be a solid (or a shell) with 6 faces
+  //MESSAGE("---");
+
+  vector < SMESH_subMesh * >meshFaces;
+  for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
+    SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
+    ASSERT(aSubMesh);
+    meshFaces.push_back(aSubMesh);
+  }
+  if (meshFaces.size() != 6) {
+    SCRUTE(meshFaces.size());
+    return false;
+  }
 
-       // 1.4 - find edge X=0, Z=0 (ancestor of V000 not in face Y=0)
-       //     - find edge X=1, Z=0 (ancestor of V100 not in face Y=0)
-       //     - find edge X=1, Z=1 (ancestor of V101 not in face Y=0) 
-       //     - find edge X=0, Z=1 (ancestor of V001 not in face Y=0)
-       //MESSAGE("---");
+  // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges)
+  //MESSAGE("---");
+
+  myTool = new StdMeshers_Helper(aMesh);
+  _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
+
+  for (int i = 0; i < 6; i++) {
+    TopoDS_Shape aFace = meshFaces[i]->GetSubShape();
+    SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace);
+    string algoName = algo->GetName();
+    bool isAllQuad = false;
+    if (algoName == "Quadrangle_2D") {
+      SMESHDS_SubMesh * sm = meshDS->MeshElements( aFace );
+      if ( sm ) {
+        isAllQuad = true;
+        SMDS_ElemIteratorPtr eIt = sm->GetElements();
+        while ( isAllQuad && eIt->more() ) {
+          const SMDS_MeshElement* elem =  eIt->next();
+          isAllQuad = ( elem->NbNodes()==4 ||(_quadraticMesh && elem->NbNodes()==8) );
+        }
+      }
+    }
+    if ( ! isAllQuad ) {
+      //modified by NIZNHY-PKV Wed Nov 17 15:31:37 2004 f
+      bool bIsOk = ComputePentahedralMesh(aMesh, aShape);
+      return ClearAndReturn( bIsOk );
+    }
+    StdMeshers_Quadrangle_2D *quadAlgo =
+      dynamic_cast < StdMeshers_Quadrangle_2D * >(algo);
+    ASSERT(quadAlgo);
+    try {
+      _quads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace, _quadraticMesh);
+    }
+    catch(SALOME_Exception & S_ex) {
+      return ClearAndReturn( false );
+    }
 
-       TopoDS_Edge E_0Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V000, MS);
-       ASSERT(!E_0Y0.IsNull());
+    // 0.2.1 - number of points on the opposite edges must be the same
+    if (_quads[i]->nbPts[0] != _quads[i]->nbPts[2] ||
+        _quads[i]->nbPts[1] != _quads[i]->nbPts[3]) {
+      MESSAGE("different number of points on the opposite edges of face " << i);
+      //                  ASSERT(0);
+      return ClearAndReturn( false );
+    }
+  }
 
-       TopoDS_Edge E_1Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V100, MS);
-       ASSERT(!E_1Y0.IsNull());
+  // 1.  - identify faces and vertices of the "cube"
+  // 1.1 - ancestor maps vertex->edges in the cube
+  //MESSAGE("---");
 
-       TopoDS_Edge E_1Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V101, MS);
-       ASSERT(!E_1Y1.IsNull());
+  TopTools_IndexedDataMapOfShapeListOfShape MS;
+  TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, MS);
 
-       TopoDS_Edge E_0Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V001, MS);
-       ASSERT(!E_0Y1.IsNull());
+  // 1.2 - first face is choosen as face Y=0 of the unit cube
+  //MESSAGE("---");
 
-       // 1.5 - identify the 4 vertices in face Y=1: V010, V110, V111, V011
-       //MESSAGE("---");
+  const TopoDS_Shape & aFace = meshFaces[0]->GetSubShape();
+  const TopoDS_Face & F = TopoDS::Face(aFace);
 
-       TopExp::Vertices(E_0Y0, VFirst, VLast);
-       if (VFirst.IsSame(_cube.V000))
-               _cube.V010 = VLast;
-       else
-               _cube.V010 = VFirst;
+  // 1.3 - identify the 4 vertices of the face Y=0: V000, V100, V101, V001
+  //MESSAGE("---");
 
-       TopExp::Vertices(E_1Y0, VFirst, VLast);
-       if (VFirst.IsSame(_cube.V100))
-               _cube.V110 = VLast;
-       else
-               _cube.V110 = VFirst;
+  int i = 0;
+  TopoDS_Edge E = _quads[0]->edge[i];  //edge will be Y=0,Z=0 on unit cube
+  double f, l;
+  Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+  TopoDS_Vertex VFirst, VLast;
+  TopExp::Vertices(E, VFirst, VLast);  // corresponds to f and l
+  bool isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
 
-       TopExp::Vertices(E_1Y1, VFirst, VLast);
-       if (VFirst.IsSame(_cube.V101))
-               _cube.V111 = VLast;
-       else
-               _cube.V111 = VFirst;
+  if (isForward) {
+    _cube.V000 = VFirst;       // will be (0,0,0) on the unit cube
+    _cube.V100 = VLast;                // will be (1,0,0) on the unit cube
+  }
+  else {
+    _cube.V000 = VLast;
+    _cube.V100 = VFirst;
+  }
 
-       TopExp::Vertices(E_0Y1, VFirst, VLast);
-       if (VFirst.IsSame(_cube.V001))
-               _cube.V011 = VLast;
-       else
-               _cube.V011 = VFirst;
-
-       // 1.6 - find remaining faces given 4 vertices
-       //MESSAGE("---");
-
-       _indY0 = 0;
-       _cube.quad_Y0 = _quads[_indY0];
-
-       _indY1 = GetFaceIndex(aMesh, aShape, meshFaces,
-               _cube.V010, _cube.V011, _cube.V110, _cube.V111);
-       _cube.quad_Y1 = _quads[_indY1];
-
-       _indZ0 = GetFaceIndex(aMesh, aShape, meshFaces,
-               _cube.V000, _cube.V010, _cube.V100, _cube.V110);
-       _cube.quad_Z0 = _quads[_indZ0];
-
-       _indZ1 = GetFaceIndex(aMesh, aShape, meshFaces,
-               _cube.V001, _cube.V011, _cube.V101, _cube.V111);
-       _cube.quad_Z1 = _quads[_indZ1];
-
-       _indX0 = GetFaceIndex(aMesh, aShape, meshFaces,
-               _cube.V000, _cube.V001, _cube.V010, _cube.V011);
-       _cube.quad_X0 = _quads[_indX0];
-
-       _indX1 = GetFaceIndex(aMesh, aShape, meshFaces,
-               _cube.V100, _cube.V101, _cube.V110, _cube.V111);
-       _cube.quad_X1 = _quads[_indX1];
-
-       //MESSAGE("---");
-
-       // 1.7 - get convertion coefs from face 2D normalized to 3D normalized
-
-       Conv2DStruct cx0;                       // for face X=0
-       Conv2DStruct cx1;                       // for face X=1
-       Conv2DStruct cy0;
-       Conv2DStruct cy1;
-       Conv2DStruct cz0;
-       Conv2DStruct cz1;
-
-       GetConv2DCoefs(*_cube.quad_X0, meshFaces[_indX0]->GetSubShape(),
-               _cube.V000, _cube.V010, _cube.V011, _cube.V001, cx0);
-       GetConv2DCoefs(*_cube.quad_X1, meshFaces[_indX1]->GetSubShape(),
-               _cube.V100, _cube.V110, _cube.V111, _cube.V101, cx1);
-       GetConv2DCoefs(*_cube.quad_Y0, meshFaces[_indY0]->GetSubShape(),
-               _cube.V000, _cube.V100, _cube.V101, _cube.V001, cy0);
-       GetConv2DCoefs(*_cube.quad_Y1, meshFaces[_indY1]->GetSubShape(),
-               _cube.V010, _cube.V110, _cube.V111, _cube.V011, cy1);
-       GetConv2DCoefs(*_cube.quad_Z0, meshFaces[_indZ0]->GetSubShape(),
-               _cube.V000, _cube.V100, _cube.V110, _cube.V010, cz0);
-       GetConv2DCoefs(*_cube.quad_Z1, meshFaces[_indZ1]->GetSubShape(),
-               _cube.V001, _cube.V101, _cube.V111, _cube.V011, cz1);
-
-       // 1.8 - create a 3D structure for normalized values
-
-       //MESSAGE("---");
-        int nbx = _cube.quad_Z0->nbPts[0];
-        if (cz0.a1 == 0.) nbx = _cube.quad_Z0->nbPts[1];
+  i = 1;
+  E = _quads[0]->edge[i];
+  C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+  TopExp::Vertices(E, VFirst, VLast);
+  isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
+  if (isForward)
+    _cube.V101 = VLast;                // will be (1,0,1) on the unit cube
+  else
+    _cube.V101 = VFirst;
+
+  i = 2;
+  E = _quads[0]->edge[i];
+  C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+  TopExp::Vertices(E, VFirst, VLast);
+  isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
+  if (isForward)
+    _cube.V001 = VLast;                // will be (0,0,1) on the unit cube
+  else
+    _cube.V001 = VFirst;
+
+  // 1.4 - find edge X=0, Z=0 (ancestor of V000 not in face Y=0)
+  //     - find edge X=1, Z=0 (ancestor of V100 not in face Y=0)
+  //     - find edge X=1, Z=1 (ancestor of V101 not in face Y=0) 
+  //     - find edge X=0, Z=1 (ancestor of V001 not in face Y=0)
+  //MESSAGE("---");
+
+  TopoDS_Edge E_0Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V000, MS);
+  ASSERT(!E_0Y0.IsNull());
+
+  TopoDS_Edge E_1Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V100, MS);
+  ASSERT(!E_1Y0.IsNull());
+
+  TopoDS_Edge E_1Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V101, MS);
+  ASSERT(!E_1Y1.IsNull());
+
+  TopoDS_Edge E_0Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V001, MS);
+  ASSERT(!E_0Y1.IsNull());
+
+  // 1.5 - identify the 4 vertices in face Y=1: V010, V110, V111, V011
+  //MESSAGE("---");
+
+  TopExp::Vertices(E_0Y0, VFirst, VLast);
+  if (VFirst.IsSame(_cube.V000))
+    _cube.V010 = VLast;
+  else
+    _cube.V010 = VFirst;
+
+  TopExp::Vertices(E_1Y0, VFirst, VLast);
+  if (VFirst.IsSame(_cube.V100))
+    _cube.V110 = VLast;
+  else
+    _cube.V110 = VFirst;
+
+  TopExp::Vertices(E_1Y1, VFirst, VLast);
+  if (VFirst.IsSame(_cube.V101))
+    _cube.V111 = VLast;
+  else
+    _cube.V111 = VFirst;
+
+  TopExp::Vertices(E_0Y1, VFirst, VLast);
+  if (VFirst.IsSame(_cube.V001))
+    _cube.V011 = VLast;
+  else
+    _cube.V011 = VFirst;
+
+  // 1.6 - find remaining faces given 4 vertices
+  //MESSAGE("---");
+
+  _indY0 = 0;
+  _cube.quad_Y0 = _quads[_indY0];
+
+  _indY1 = GetFaceIndex(aMesh, aShape, meshFaces,
+                        _cube.V010, _cube.V011, _cube.V110, _cube.V111);
+  _cube.quad_Y1 = _quads[_indY1];
+
+  _indZ0 = GetFaceIndex(aMesh, aShape, meshFaces,
+                        _cube.V000, _cube.V010, _cube.V100, _cube.V110);
+  _cube.quad_Z0 = _quads[_indZ0];
+
+  _indZ1 = GetFaceIndex(aMesh, aShape, meshFaces,
+                        _cube.V001, _cube.V011, _cube.V101, _cube.V111);
+  _cube.quad_Z1 = _quads[_indZ1];
+
+  _indX0 = GetFaceIndex(aMesh, aShape, meshFaces,
+                        _cube.V000, _cube.V001, _cube.V010, _cube.V011);
+  _cube.quad_X0 = _quads[_indX0];
+
+  _indX1 = GetFaceIndex(aMesh, aShape, meshFaces,
+                        _cube.V100, _cube.V101, _cube.V110, _cube.V111);
+  _cube.quad_X1 = _quads[_indX1];
+
+  //MESSAGE("---");
+
+  // 1.7 - get convertion coefs from face 2D normalized to 3D normalized
+
+  Conv2DStruct cx0;                    // for face X=0
+  Conv2DStruct cx1;                    // for face X=1
+  Conv2DStruct cy0;
+  Conv2DStruct cy1;
+  Conv2DStruct cz0;
+  Conv2DStruct cz1;
+
+  GetConv2DCoefs(*_cube.quad_X0, meshFaces[_indX0]->GetSubShape(),
+                 _cube.V000, _cube.V010, _cube.V011, _cube.V001, cx0);
+  GetConv2DCoefs(*_cube.quad_X1, meshFaces[_indX1]->GetSubShape(),
+                 _cube.V100, _cube.V110, _cube.V111, _cube.V101, cx1);
+  GetConv2DCoefs(*_cube.quad_Y0, meshFaces[_indY0]->GetSubShape(),
+                 _cube.V000, _cube.V100, _cube.V101, _cube.V001, cy0);
+  GetConv2DCoefs(*_cube.quad_Y1, meshFaces[_indY1]->GetSubShape(),
+                 _cube.V010, _cube.V110, _cube.V111, _cube.V011, cy1);
+  GetConv2DCoefs(*_cube.quad_Z0, meshFaces[_indZ0]->GetSubShape(),
+                 _cube.V000, _cube.V100, _cube.V110, _cube.V010, cz0);
+  GetConv2DCoefs(*_cube.quad_Z1, meshFaces[_indZ1]->GetSubShape(),
+                 _cube.V001, _cube.V101, _cube.V111, _cube.V011, cz1);
+
+  // 1.8 - create a 3D structure for normalized values
+  
+  //MESSAGE("---");
+  int nbx = _cube.quad_Z0->nbPts[0];
+  if (cz0.a1 == 0.) nbx = _cube.quad_Z0->nbPts[1];
  
-        int nby = _cube.quad_X0->nbPts[0];
-        if (cx0.a1 == 0.) nby = _cube.quad_X0->nbPts[1];
+  int nby = _cube.quad_X0->nbPts[0];
+  if (cx0.a1 == 0.) nby = _cube.quad_X0->nbPts[1];
  
-        int nbz = _cube.quad_Y0->nbPts[0];
-        if (cy0.a1 != 0.) nbz = _cube.quad_Y0->nbPts[1];
+  int nbz = _cube.quad_Y0->nbPts[0];
+  if (cy0.a1 != 0.) nbz = _cube.quad_Y0->nbPts[1];
 
-       int i1, j1, nbxyz = nbx * nby * nbz;
-       Point3DStruct *np = new Point3DStruct[nbxyz];
+  int i1, j1, nbxyz = nbx * nby * nbz;
+  Point3DStruct *np = new Point3DStruct[nbxyz];
 
-       // 1.9 - store node indexes of faces
+  // 1.9 - store node indexes of faces
 
-       {
-               const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX0]->GetSubShape());
-
-               faceQuadStruct *quad = _cube.quad_X0;
-               int i = 0;                              // j = x/face , k = y/face
-               int nbdown = quad->nbPts[0];
-               int nbright = quad->nbPts[1];
+  {
+    const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX0]->GetSubShape());
 
+    faceQuadStruct *quad = _cube.quad_X0;
+    int i = 0;                         // j = x/face , k = y/face
+    int nbdown = quad->nbPts[0];
+    int nbright = quad->nbPts[1];
 
-               SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+    SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
                        
-               while(itf->more())
-               {
-                       const SMDS_MeshNode * node = itf->next();
-                        findIJ( node, quad, i1, j1 );
-                       int ij1 = j1 * nbdown + i1;
-                       quad->uv_grid[ij1].node = node;
-               }
-
-               for (int i1 = 0; i1 < nbdown; i1++)
-                       for (int j1 = 0; j1 < nbright; j1++)
-                       {
-                               int ij1 = j1 * nbdown + i1;
-                               int j = cx0.ia * i1 + cx0.ib * j1 + cx0.ic;     // j = x/face
-                               int k = cx0.ja * i1 + cx0.jb * j1 + cx0.jc;     // k = y/face
-                               int ijk = k * nbx * nby + j * nbx + i;
-                               //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
-                               np[ijk].node = quad->uv_grid[ij1].node;
-                               //SCRUTE(np[ijk].nodeId);
-                       }
-       }
+    while(itf->more()) {
+      const SMDS_MeshNode * node = itf->next();
+      if(myTool->IsMedium(node))
+        continue;
+      findIJ( node, quad, i1, j1 );
+      int ij1 = j1 * nbdown + i1;
+      quad->uv_grid[ij1].node = node;
+    }
 
-       {
-               const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX1]->GetSubShape());
+    for (int i1 = 0; i1 < nbdown; i1++)
+      for (int j1 = 0; j1 < nbright; j1++) {
+        int ij1 = j1 * nbdown + i1;
+        int j = cx0.ia * i1 + cx0.ib * j1 + cx0.ic;    // j = x/face
+        int k = cx0.ja * i1 + cx0.jb * j1 + cx0.jc;    // k = y/face
+        int ijk = k * nbx * nby + j * nbx + i;
+        //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+        np[ijk].node = quad->uv_grid[ij1].node;
+        //SCRUTE(np[ijk].nodeId);
+      }
+  }
 
-               SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+  {
+    const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX1]->GetSubShape());
 
-               faceQuadStruct *quad = _cube.quad_X1;
-               int i = nbx - 1;                // j = x/face , k = y/face
-               int nbdown = quad->nbPts[0];
-               int nbright = quad->nbPts[1];
+    SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
 
-               while(itf->more())
-               {
-                       const SMDS_MeshNode * node = itf->next();
-                        findIJ( node, quad, i1, j1 );
-                       int ij1 = j1 * nbdown + i1;
-                       quad->uv_grid[ij1].node = node;
-               }
+    faceQuadStruct *quad = _cube.quad_X1;
+    int i = nbx - 1;           // j = x/face , k = y/face
+    int nbdown = quad->nbPts[0];
+    int nbright = quad->nbPts[1];
 
-               for (int i1 = 0; i1 < nbdown; i1++)
-                       for (int j1 = 0; j1 < nbright; j1++)
-                       {
-                               int ij1 = j1 * nbdown + i1;
-                               int j = cx1.ia * i1 + cx1.ib * j1 + cx1.ic;     // j = x/face
-                               int k = cx1.ja * i1 + cx1.jb * j1 + cx1.jc;     // k = y/face
-                               int ijk = k * nbx * nby + j * nbx + i;
-                               //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
-                               np[ijk].node = quad->uv_grid[ij1].node;
-                               //SCRUTE(np[ijk].nodeId);
-                       }
-       }
+    while(itf->more()) {
+      const SMDS_MeshNode * node = itf->next();
+      if(myTool->IsMedium(node))
+        continue;
+      findIJ( node, quad, i1, j1 );
+      int ij1 = j1 * nbdown + i1;
+      quad->uv_grid[ij1].node = node;
+    }
 
-       {
-               const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY0]->GetSubShape());
+    for (int i1 = 0; i1 < nbdown; i1++)
+      for (int j1 = 0; j1 < nbright; j1++) {
+        int ij1 = j1 * nbdown + i1;
+        int j = cx1.ia * i1 + cx1.ib * j1 + cx1.ic;    // j = x/face
+        int k = cx1.ja * i1 + cx1.jb * j1 + cx1.jc;    // k = y/face
+        int ijk = k * nbx * nby + j * nbx + i;
+        //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+        np[ijk].node = quad->uv_grid[ij1].node;
+        //SCRUTE(np[ijk].nodeId);
+      }
+  }
 
-               SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+  {
+    const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY0]->GetSubShape());
 
-               faceQuadStruct *quad = _cube.quad_Y0;
-               int j = 0;                              // i = x/face , k = y/face
-               int nbdown = quad->nbPts[0];
-               int nbright = quad->nbPts[1];
+    SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
 
-               while(itf->more())
-               {
-                       const SMDS_MeshNode * node = itf->next();
-                        findIJ( node, quad, i1, j1 );
-                       int ij1 = j1 * nbdown + i1;
-                       quad->uv_grid[ij1].node = node;
-               }
+    faceQuadStruct *quad = _cube.quad_Y0;
+    int j = 0;                         // i = x/face , k = y/face
+    int nbdown = quad->nbPts[0];
+    int nbright = quad->nbPts[1];
 
-               for (int i1 = 0; i1 < nbdown; i1++)
-                       for (int j1 = 0; j1 < nbright; j1++)
-                       {
-                               int ij1 = j1 * nbdown + i1;
-                               int i = cy0.ia * i1 + cy0.ib * j1 + cy0.ic;     // i = x/face
-                               int k = cy0.ja * i1 + cy0.jb * j1 + cy0.jc;     // k = y/face
-                               int ijk = k * nbx * nby + j * nbx + i;
-                               //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
-                               np[ijk].node = quad->uv_grid[ij1].node;
-                               //SCRUTE(np[ijk].nodeId);
-                       }
-       }
+    while(itf->more()) {
+      const SMDS_MeshNode * node = itf->next();
+      if(myTool->IsMedium(node))
+        continue;
+      findIJ( node, quad, i1, j1 );
+      int ij1 = j1 * nbdown + i1;
+      quad->uv_grid[ij1].node = node;
+    }
 
-       {
-               const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY1]->GetSubShape());
+    for (int i1 = 0; i1 < nbdown; i1++)
+      for (int j1 = 0; j1 < nbright; j1++) {
+        int ij1 = j1 * nbdown + i1;
+        int i = cy0.ia * i1 + cy0.ib * j1 + cy0.ic;    // i = x/face
+        int k = cy0.ja * i1 + cy0.jb * j1 + cy0.jc;    // k = y/face
+        int ijk = k * nbx * nby + j * nbx + i;
+        //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+        np[ijk].node = quad->uv_grid[ij1].node;
+        //SCRUTE(np[ijk].nodeId);
+      }
+  }
 
-               SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+  {
+    const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY1]->GetSubShape());
 
-               faceQuadStruct *quad = _cube.quad_Y1;
-               int j = nby - 1;                // i = x/face , k = y/face
-               int nbdown = quad->nbPts[0];
-               int nbright = quad->nbPts[1];
+    SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
 
-               while(itf->more())
-               {
-                       const SMDS_MeshNode * node = itf->next();
-                        findIJ( node, quad, i1, j1 );
-                       int ij1 = j1 * nbdown + i1;
-                       quad->uv_grid[ij1].node = node;
-               }
+    faceQuadStruct *quad = _cube.quad_Y1;
+    int j = nby - 1;           // i = x/face , k = y/face
+    int nbdown = quad->nbPts[0];
+    int nbright = quad->nbPts[1];
 
-               for (int i1 = 0; i1 < nbdown; i1++)
-                       for (int j1 = 0; j1 < nbright; j1++)
-                       {
-                               int ij1 = j1 * nbdown + i1;
-                               int i = cy1.ia * i1 + cy1.ib * j1 + cy1.ic;     // i = x/face
-                               int k = cy1.ja * i1 + cy1.jb * j1 + cy1.jc;     // k = y/face
-                               int ijk = k * nbx * nby + j * nbx + i;
-                               //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
-                               np[ijk].node = quad->uv_grid[ij1].node;
-                               //SCRUTE(np[ijk].nodeId);
-                       }
-       }
+    while(itf->more()) {
+      const SMDS_MeshNode * node = itf->next();
+      if(myTool->IsMedium(node))
+        continue;
+      findIJ( node, quad, i1, j1 );
+      int ij1 = j1 * nbdown + i1;
+      quad->uv_grid[ij1].node = node;
+    }
 
-       {
-               const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ0]->GetSubShape());
+    for (int i1 = 0; i1 < nbdown; i1++)
+      for (int j1 = 0; j1 < nbright; j1++) {
+        int ij1 = j1 * nbdown + i1;
+        int i = cy1.ia * i1 + cy1.ib * j1 + cy1.ic;    // i = x/face
+        int k = cy1.ja * i1 + cy1.jb * j1 + cy1.jc;    // k = y/face
+        int ijk = k * nbx * nby + j * nbx + i;
+        //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+        np[ijk].node = quad->uv_grid[ij1].node;
+        //SCRUTE(np[ijk].nodeId);
+      }
+  }
 
-               SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+  {
+    const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ0]->GetSubShape());
 
-               faceQuadStruct *quad = _cube.quad_Z0;
-               int k = 0;                              // i = x/face , j = y/face
-               int nbdown = quad->nbPts[0];
-               int nbright = quad->nbPts[1];
+    SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
 
-               while(itf->more())
-               {
-                       const SMDS_MeshNode * node = itf->next();
-                        findIJ( node, quad, i1, j1 );
-                       int ij1 = j1 * nbdown + i1;
-                       quad->uv_grid[ij1].node = node;
-               }
+    faceQuadStruct *quad = _cube.quad_Z0;
+    int k = 0;                         // i = x/face , j = y/face
+    int nbdown = quad->nbPts[0];
+    int nbright = quad->nbPts[1];
 
-               for (int i1 = 0; i1 < nbdown; i1++)
-                       for (int j1 = 0; j1 < nbright; j1++)
-                       {
-                               int ij1 = j1 * nbdown + i1;
-                               int i = cz0.ia * i1 + cz0.ib * j1 + cz0.ic;     // i = x/face
-                               int j = cz0.ja * i1 + cz0.jb * j1 + cz0.jc;     // j = y/face
-                               int ijk = k * nbx * nby + j * nbx + i;
-                               //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
-                               np[ijk].node = quad->uv_grid[ij1].node;
-                               //SCRUTE(np[ijk].nodeId);
-                       }
-       }
-
-       {
-               const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ1]->GetSubShape());
-
-               SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+    while(itf->more()) {
+      const SMDS_MeshNode * node = itf->next();
+      if(myTool->IsMedium(node))
+        continue;
+      findIJ( node, quad, i1, j1 );
+      int ij1 = j1 * nbdown + i1;
+      quad->uv_grid[ij1].node = node;
+    }
 
-               faceQuadStruct *quad = _cube.quad_Z1;
-               int k = nbz - 1;                // i = x/face , j = y/face
-               int nbdown = quad->nbPts[0];
-               int nbright = quad->nbPts[1];
+    for (int i1 = 0; i1 < nbdown; i1++)
+      for (int j1 = 0; j1 < nbright; j1++) {
+        int ij1 = j1 * nbdown + i1;
+        int i = cz0.ia * i1 + cz0.ib * j1 + cz0.ic;    // i = x/face
+        int j = cz0.ja * i1 + cz0.jb * j1 + cz0.jc;    // j = y/face
+        int ijk = k * nbx * nby + j * nbx + i;
+        //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+        np[ijk].node = quad->uv_grid[ij1].node;
+        //SCRUTE(np[ijk].nodeId);
+      }
+  }
 
-               while(itf->more())
-               {
-                       const SMDS_MeshNode * node = itf->next();
-                        findIJ( node, quad, i1, j1 );
-                       int ij1 = j1 * nbdown + i1;
-                       quad->uv_grid[ij1].node = node;
-               }
+  {
+    const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ1]->GetSubShape());
+
+    SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+
+    faceQuadStruct *quad = _cube.quad_Z1;
+    int k = nbz - 1;           // i = x/face , j = y/face
+    int nbdown = quad->nbPts[0];
+    int nbright = quad->nbPts[1];
+    
+    while(itf->more()) {
+      const SMDS_MeshNode * node = itf->next();
+      if(myTool->IsMedium(node))
+        continue;
+      findIJ( node, quad, i1, j1 );
+      int ij1 = j1 * nbdown + i1;
+      quad->uv_grid[ij1].node = node;
+    }
 
-               for (int i1 = 0; i1 < nbdown; i1++)
-                       for (int j1 = 0; j1 < nbright; j1++)
-                       {
-                               int ij1 = j1 * nbdown + i1;
-                               int i = cz1.ia * i1 + cz1.ib * j1 + cz1.ic;     // i = x/face
-                               int j = cz1.ja * i1 + cz1.jb * j1 + cz1.jc;     // j = y/face
-                               int ijk = k * nbx * nby + j * nbx + i;
-                               //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
-                               np[ijk].node = quad->uv_grid[ij1].node;
-                               //SCRUTE(np[ijk].nodeId);
-                       }
-       }
+    for (int i1 = 0; i1 < nbdown; i1++)
+      for (int j1 = 0; j1 < nbright; j1++) {
+        int ij1 = j1 * nbdown + i1;
+        int i = cz1.ia * i1 + cz1.ib * j1 + cz1.ic;    // i = x/face
+        int j = cz1.ja * i1 + cz1.jb * j1 + cz1.jc;    // j = y/face
+        int ijk = k * nbx * nby + j * nbx + i;
+        //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+        np[ijk].node = quad->uv_grid[ij1].node;
+        //SCRUTE(np[ijk].nodeId);
+      }
+  }
 
-       // 2.0 - for each node of the cube:
-       //       - get the 8 points 3D = 8 vertices of the cube
-       //       - get the 12 points 3D on the 12 edges of the cube
-       //       - get the 6 points 3D on the 6 faces with their ID
-       //       - compute the point 3D
-       //       - store the point 3D in SMESHDS, store its ID in 3D structure
-
-        int shapeID = meshDS->ShapeToIndex( aShape );
-
-       Pt3 p000, p001, p010, p011, p100, p101, p110, p111;
-       Pt3 px00, px01, px10, px11;
-       Pt3 p0y0, p0y1, p1y0, p1y1;
-       Pt3 p00z, p01z, p10z, p11z;
-       Pt3 pxy0, pxy1, px0z, px1z, p0yz, p1yz;
-
-       GetPoint(p000, 0, 0, 0, nbx, nby, nbz, np, meshDS);
-       GetPoint(p001, 0, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
-       GetPoint(p010, 0, nby - 1, 0, nbx, nby, nbz, np, meshDS);
-       GetPoint(p011, 0, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
-       GetPoint(p100, nbx - 1, 0, 0, nbx, nby, nbz, np, meshDS);
-       GetPoint(p101, nbx - 1, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
-       GetPoint(p110, nbx - 1, nby - 1, 0, nbx, nby, nbz, np, meshDS);
-       GetPoint(p111, nbx - 1, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
-
-       for (int i = 1; i < nbx - 1; i++)
-       {
-               for (int j = 1; j < nby - 1; j++)
-               {
-                       for (int k = 1; k < nbz - 1; k++)
-                       {
-                               // *** seulement maillage regulier
-                               // 12 points on edges
-                               GetPoint(px00, i, 0, 0, nbx, nby, nbz, np, meshDS);
-                               GetPoint(px01, i, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
-                               GetPoint(px10, i, nby - 1, 0, nbx, nby, nbz, np, meshDS);
-                               GetPoint(px11, i, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
-
-                               GetPoint(p0y0, 0, j, 0, nbx, nby, nbz, np, meshDS);
-                               GetPoint(p0y1, 0, j, nbz - 1, nbx, nby, nbz, np, meshDS);
-                               GetPoint(p1y0, nbx - 1, j, 0, nbx, nby, nbz, np, meshDS);
-                               GetPoint(p1y1, nbx - 1, j, nbz - 1, nbx, nby, nbz, np, meshDS);
-
-                               GetPoint(p00z, 0, 0, k, nbx, nby, nbz, np, meshDS);
-                               GetPoint(p01z, 0, nby - 1, k, nbx, nby, nbz, np, meshDS);
-                               GetPoint(p10z, nbx - 1, 0, k, nbx, nby, nbz, np, meshDS);
-                               GetPoint(p11z, nbx - 1, nby - 1, k, nbx, nby, nbz, np, meshDS);
-
-                               // 12 points on faces
-                               GetPoint(pxy0, i, j, 0, nbx, nby, nbz, np, meshDS);
-                               GetPoint(pxy1, i, j, nbz - 1, nbx, nby, nbz, np, meshDS);
-                               GetPoint(px0z, i, 0, k, nbx, nby, nbz, np, meshDS);
-                               GetPoint(px1z, i, nby - 1, k, nbx, nby, nbz, np, meshDS);
-                               GetPoint(p0yz, 0, j, k, nbx, nby, nbz, np, meshDS);
-                               GetPoint(p1yz, nbx - 1, j, k, nbx, nby, nbz, np, meshDS);
-
-                               int ijk = k * nbx * nby + j * nbx + i;
-                               double x = double (i) / double (nbx - 1);       // *** seulement
-                               double y = double (j) / double (nby - 1);       // *** maillage
-                               double z = double (k) / double (nbz - 1);       // *** regulier
-
-                               Pt3 X;
-                               for (int i = 0; i < 3; i++)
-                               {
-                                       X[i] =
-                                               (1 - x) * p0yz[i] + x * p1yz[i]
-                                               + (1 - y) * px0z[i] + y * px1z[i]
-                                               + (1 - z) * pxy0[i] + z * pxy1[i]
-                                               - (1 - x) * ((1 - y) * p00z[i] + y * p01z[i])
-                                               - x * ((1 - y) * p10z[i] + y * p11z[i])
-                                               - (1 - y) * ((1 - z) * px00[i] + z * px01[i])
-                                               - y * ((1 - z) * px10[i] + z * px11[i])
-                                               - (1 - z) * ((1 - x) * p0y0[i] + x * p1y0[i])
-                                               - z * ((1 - x) * p0y1[i] + x * p1y1[i])
-                                               + (1 - x) * ((1 - y) * ((1 - z) * p000[i] + z * p001[i])
-                                               + y * ((1 - z) * p010[i] + z * p011[i]))
-                                               + x * ((1 - y) * ((1 - z) * p100[i] + z * p101[i])
-                                               + y * ((1 - z) * p110[i] + z * p111[i]));
-                               }
-
-                               SMDS_MeshNode * node = meshDS->AddNode(X[0], X[1], X[2]);
-                               np[ijk].node = node;
-                                meshDS->SetNodeInVolume(node, shapeID);
-                       }
-               }
-       }
+  // 2.0 - for each node of the cube:
+  //       - get the 8 points 3D = 8 vertices of the cube
+  //       - get the 12 points 3D on the 12 edges of the cube
+  //       - get the 6 points 3D on the 6 faces with their ID
+  //       - compute the point 3D
+  //       - store the point 3D in SMESHDS, store its ID in 3D structure
+
+  int shapeID = meshDS->ShapeToIndex( aShape );
+
+  Pt3 p000, p001, p010, p011, p100, p101, p110, p111;
+  Pt3 px00, px01, px10, px11;
+  Pt3 p0y0, p0y1, p1y0, p1y1;
+  Pt3 p00z, p01z, p10z, p11z;
+  Pt3 pxy0, pxy1, px0z, px1z, p0yz, p1yz;
+
+  GetPoint(p000, 0, 0, 0, nbx, nby, nbz, np, meshDS);
+  GetPoint(p001, 0, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
+  GetPoint(p010, 0, nby - 1, 0, nbx, nby, nbz, np, meshDS);
+  GetPoint(p011, 0, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
+  GetPoint(p100, nbx - 1, 0, 0, nbx, nby, nbz, np, meshDS);
+  GetPoint(p101, nbx - 1, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
+  GetPoint(p110, nbx - 1, nby - 1, 0, nbx, nby, nbz, np, meshDS);
+  GetPoint(p111, nbx - 1, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
+
+  for (int i = 1; i < nbx - 1; i++) {
+    for (int j = 1; j < nby - 1; j++) {
+      for (int k = 1; k < nbz - 1; k++) {
+        // *** seulement maillage regulier
+        // 12 points on edges
+        GetPoint(px00, i, 0, 0, nbx, nby, nbz, np, meshDS);
+        GetPoint(px01, i, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
+        GetPoint(px10, i, nby - 1, 0, nbx, nby, nbz, np, meshDS);
+        GetPoint(px11, i, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
+
+        GetPoint(p0y0, 0, j, 0, nbx, nby, nbz, np, meshDS);
+        GetPoint(p0y1, 0, j, nbz - 1, nbx, nby, nbz, np, meshDS);
+        GetPoint(p1y0, nbx - 1, j, 0, nbx, nby, nbz, np, meshDS);
+        GetPoint(p1y1, nbx - 1, j, nbz - 1, nbx, nby, nbz, np, meshDS);
+
+        GetPoint(p00z, 0, 0, k, nbx, nby, nbz, np, meshDS);
+        GetPoint(p01z, 0, nby - 1, k, nbx, nby, nbz, np, meshDS);
+        GetPoint(p10z, nbx - 1, 0, k, nbx, nby, nbz, np, meshDS);
+        GetPoint(p11z, nbx - 1, nby - 1, k, nbx, nby, nbz, np, meshDS);
+
+        // 12 points on faces
+        GetPoint(pxy0, i, j, 0, nbx, nby, nbz, np, meshDS);
+        GetPoint(pxy1, i, j, nbz - 1, nbx, nby, nbz, np, meshDS);
+        GetPoint(px0z, i, 0, k, nbx, nby, nbz, np, meshDS);
+        GetPoint(px1z, i, nby - 1, k, nbx, nby, nbz, np, meshDS);
+        GetPoint(p0yz, 0, j, k, nbx, nby, nbz, np, meshDS);
+        GetPoint(p1yz, nbx - 1, j, k, nbx, nby, nbz, np, meshDS);
+
+        int ijk = k * nbx * nby + j * nbx + i;
+        double x = double (i) / double (nbx - 1);      // *** seulement
+        double y = double (j) / double (nby - 1);      // *** maillage
+        double z = double (k) / double (nbz - 1);      // *** regulier
+
+        Pt3 X;
+        for (int i = 0; i < 3; i++) {
+          X[i] = (1 - x) * p0yz[i] + x * p1yz[i]
+                 + (1 - y) * px0z[i] + y * px1z[i]
+                 + (1 - z) * pxy0[i] + z * pxy1[i]
+                 - (1 - x) * ((1 - y) * p00z[i] + y * p01z[i])
+                 - x * ((1 - y) * p10z[i] + y * p11z[i])
+                 - (1 - y) * ((1 - z) * px00[i] + z * px01[i])
+                 - y * ((1 - z) * px10[i] + z * px11[i])
+                 - (1 - z) * ((1 - x) * p0y0[i] + x * p1y0[i])
+                 - z * ((1 - x) * p0y1[i] + x * p1y1[i])
+                 + (1 - x) * ((1 - y) * ((1 - z) * p000[i] + z * p001[i])
+                 + y * ((1 - z) * p010[i] + z * p011[i]))
+                 + x * ((1 - y) * ((1 - z) * p100[i] + z * p101[i])
+                 + y * ((1 - z) * p110[i] + z * p111[i]));
+        }
+
+        SMDS_MeshNode * node = meshDS->AddNode(X[0], X[1], X[2]);
+        np[ijk].node = node;
+        meshDS->SetNodeInVolume(node, shapeID);
+      }
+    }
+  }
 
   // find orientation of furute volumes according to MED convention
   vector< bool > forward( nbx * nby );
   SMDS_VolumeTool vTool;
-  for (int i = 0; i < nbx - 1; i++)
-    for (int j = 0; j < nby - 1; j++)
-    {
+  for (int i = 0; i < nbx - 1; i++) {
+    for (int j = 0; j < nby - 1; j++) {
       int n1 = j * nbx + i;
       int n2 = j * nbx + i + 1;
       int n3 = (j + 1) * nbx + i + 1;
@@ -705,51 +697,53 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
       vTool.Set( &tmpVol );
       forward[ n1 ] = vTool.IsForward();
     }
+  }
 
-       //2.1 - for each node of the cube (less 3 *1 Faces):
-       //      - store hexahedron in SMESHDS
-       MESSAGE("Storing hexahedron into the DS");
-       for (int i = 0; i < nbx - 1; i++)
-               for (int j = 0; j < nby - 1; j++)
-                {
-                        bool isForw = forward.at( j * nbx + i );
-                       for (int k = 0; k < nbz - 1; k++)
-                       {
-                               int n1 = k * nbx * nby + j * nbx + i;
-                               int n2 = k * nbx * nby + j * nbx + i + 1;
-                               int n3 = k * nbx * nby + (j + 1) * nbx + i + 1;
-                               int n4 = k * nbx * nby + (j + 1) * nbx + i;
-                               int n5 = (k + 1) * nbx * nby + j * nbx + i;
-                               int n6 = (k + 1) * nbx * nby + j * nbx + i + 1;
-                               int n7 = (k + 1) * nbx * nby + (j + 1) * nbx + i + 1;
-                               int n8 = (k + 1) * nbx * nby + (j + 1) * nbx + i;
-
-                               SMDS_MeshVolume * elt;
-                                if ( isForw )
-                                  elt = meshDS->AddVolume(np[n1].node,
-                                                          np[n2].node,
-                                                          np[n3].node,
-                                                          np[n4].node,
-                                                          np[n5].node,
-                                                          np[n6].node,
-                                                          np[n7].node,
-                                                          np[n8].node);
-                                else
-                                  elt = meshDS->AddVolume(np[n1].node,
-                                                          np[n4].node,
-                                                          np[n3].node,
-                                                          np[n2].node,
-                                                          np[n5].node,
-                                                          np[n8].node,
-                                                          np[n7].node,
-                                                          np[n6].node);
-
-                                meshDS->SetMeshElementOnShape(elt, shapeID);
-                              }
-                      }
+  //2.1 - for each node of the cube (less 3 *1 Faces):
+  //      - store hexahedron in SMESHDS
+  MESSAGE("Storing hexahedron into the DS");
+  for (int i = 0; i < nbx - 1; i++) {
+    for (int j = 0; j < nby - 1; j++) {
+      bool isForw = forward.at( j * nbx + i );
+      for (int k = 0; k < nbz - 1; k++) {
+        int n1 = k * nbx * nby + j * nbx + i;
+        int n2 = k * nbx * nby + j * nbx + i + 1;
+        int n3 = k * nbx * nby + (j + 1) * nbx + i + 1;
+        int n4 = k * nbx * nby + (j + 1) * nbx + i;
+        int n5 = (k + 1) * nbx * nby + j * nbx + i;
+        int n6 = (k + 1) * nbx * nby + j * nbx + i + 1;
+        int n7 = (k + 1) * nbx * nby + (j + 1) * nbx + i + 1;
+        int n8 = (k + 1) * nbx * nby + (j + 1) * nbx + i;
+
+        SMDS_MeshVolume * elt;
+        if ( isForw ) {
+          //elt = meshDS->AddVolume(np[n1].node, np[n2].node,
+          //                        np[n3].node, np[n4].node,
+          //                        np[n5].node, np[n6].node,
+          //                        np[n7].node, np[n8].node);
+          elt = myTool->AddVolume(np[n1].node, np[n2].node,
+                                  np[n3].node, np[n4].node,
+                                  np[n5].node, np[n6].node,
+                                  np[n7].node, np[n8].node);
+        }
+        else {
+          //elt = meshDS->AddVolume(np[n1].node, np[n4].node,
+          //                        np[n3].node, np[n2].node,
+          //                        np[n5].node, np[n8].node,
+          //                        np[n7].node, np[n6].node);
+          elt = myTool->AddVolume(np[n1].node, np[n4].node,
+                                  np[n3].node, np[n2].node,
+                                  np[n5].node, np[n8].node,
+                                  np[n7].node, np[n6].node);
+        }
+        
+        meshDS->SetMeshElementOnShape(elt, shapeID);
+      }
+    }
+  }
   if ( np ) delete [] np;
-       //MESSAGE("End of StdMeshers_Hexa_3D::Compute()");
-       return true;
+  //MESSAGE("End of StdMeshers_Hexa_3D::Compute()");
+  return ClearAndReturn( true );
 }
 
 //=============================================================================
@@ -1066,3 +1060,4 @@ bool ComputePentahedralMesh(SMESH_Mesh & aMesh,   const TopoDS_Shape & aShape)
   return bOK;
 }
 
+
index a9e20459c8ac94c51bea1ce88d10378acb8a1b63..273de63693dcce30b8003496ca1e031ebd7b02a4 100644 (file)
@@ -35,6 +35,8 @@
 #include "StdMeshers_Quadrangle_2D.hxx"
 #include "Utils_SALOME_Exception.hxx"
 
+#include "StdMeshers_Helper.hxx"
+
 typedef struct point3Dstruct
 {
        const SMDS_MeshNode * node;
@@ -127,6 +129,8 @@ protected:
                Point3DStruct *np,
                const SMESHDS_Mesh* meshDS);
 
+  bool ClearAndReturn(const bool res);
+
   CubeStruct _cube;
   FaceQuadStruct* _quads[6];
   int _indX0;
@@ -135,6 +139,9 @@ protected:
   int _indY1;
   int _indZ0;
   int _indZ1;
+
+  bool myCreateQuadratic;
+  StdMeshers_Helper* myTool; // toll for working with quadratic elements
 };
 
 #endif
index 4852ce4fe9c1d338db94bde8d09b3cf332dac151..8102e0a0335f3376f0a5f737d2db7a94f02741df 100644 (file)
@@ -62,9 +62,6 @@ using namespace std;
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
 
-#include <string>
-//#include <algorithm>
-
 //=============================================================================
 /*!
  *  
@@ -72,19 +69,19 @@ using namespace std;
 //=============================================================================
 
 StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId,
-       SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen)
+                                             SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen)
 {
-       MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D");
-       _name = "MEFISTO_2D";
-//   _shapeType = TopAbs_FACE;
-       _shapeType = (1 << TopAbs_FACE);
-       _compatibleHypothesis.push_back("MaxElementArea");
-       _compatibleHypothesis.push_back("LengthFromEdges");
-
-       _edgeLength = 0;
-       _maxElementArea = 0;
-       _hypMaxElementArea = NULL;
-       _hypLengthFromEdges = NULL;
+  MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D");
+  _name = "MEFISTO_2D";
+  _shapeType = (1 << TopAbs_FACE);
+  _compatibleHypothesis.push_back("MaxElementArea");
+  _compatibleHypothesis.push_back("LengthFromEdges");
+
+  _edgeLength = 0;
+  _maxElementArea = 0;
+  _hypMaxElementArea = NULL;
+  _hypLengthFromEdges = NULL;
+  myTool = 0;
 }
 
 //=============================================================================
@@ -95,7 +92,7 @@ StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId,
 
 StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D()
 {
-       MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D");
+  MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D");
 }
 
 //=============================================================================
@@ -184,112 +181,121 @@ bool StdMeshers_MEFISTO_2D::CheckHypothesis
 
 bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
 {
-       MESSAGE("StdMeshers_MEFISTO_2D::Compute");
+  MESSAGE("StdMeshers_MEFISTO_2D::Compute");
 
-       if (_hypLengthFromEdges)
-               _edgeLength = ComputeEdgeElementLength(aMesh, aShape);
+  if (_hypLengthFromEdges)
+    _edgeLength = ComputeEdgeElementLength(aMesh, aShape);
+  
+  bool isOk = false;
+  //const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+  //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
 
-       bool isOk = false;
-       //const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
-       //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
-
-       const TopoDS_Face & FF = TopoDS::Face(aShape);
-       bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
-       TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
-
-       Z nblf;                                         //nombre de lignes fermees (enveloppe en tete)
-       Z *nudslf = NULL;                       //numero du dernier sommet de chaque ligne fermee
-       R2 *uvslf = NULL;
-       Z nbpti = 0;                            //nombre points internes futurs sommets de la triangulation
-       R2 *uvpti = NULL;
-
-       Z nbst;
-       R2 *uvst = NULL;
-       Z nbt;
-       Z *nust = NULL;
-       Z ierr = 0;
-
-       Z nutysu = 1;                           // 1: il existe un fonction areteideale_()
-       // Z  nutysu=0;              // 0: on utilise aretmx
-       R aretmx = _edgeLength;         // longueur max aretes future triangulation
-
-       nblf = NumberOfWires(F);
-
-       nudslf = new Z[1 + nblf];
-       nudslf[0] = 0;
-       int iw = 1;
-       int nbpnt = 0;
-
-       myOuterWire = BRepTools::OuterWire(F);
-       nbpnt += NumberOfPoints(aMesh, myOuterWire);
-        if ( nbpnt < 3 ) // ex: a circle with 2 segments
-          return false;
-       nudslf[iw++] = nbpnt;
-
-       for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
-       {
-               const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
-               if (!myOuterWire.IsSame(W))
-               {
-                       nbpnt += NumberOfPoints(aMesh, W);
-                       nudslf[iw++] = nbpnt;
-               }
-       }
+  const TopoDS_Face & FF = TopoDS::Face(aShape);
+  bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
+  TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
+
+  Z nblf;                                              //nombre de lignes fermees (enveloppe en tete)
+  Z *nudslf = NULL;                    //numero du dernier sommet de chaque ligne fermee
+  R2 *uvslf = NULL;
+  Z nbpti = 0;                         //nombre points internes futurs sommets de la triangulation
+  R2 *uvpti = NULL;
+  
+  Z nbst;
+  R2 *uvst = NULL;
+  Z nbt;
+  Z *nust = NULL;
+  Z ierr = 0;
+
+  Z nutysu = 1;                                // 1: il existe un fonction areteideale_()
+  // Z  nutysu=0;              // 0: on utilise aretmx
+  R aretmx = _edgeLength;              // longueur max aretes future triangulation
+  
+  nblf = NumberOfWires(F);
+  
+  nudslf = new Z[1 + nblf];
+  nudslf[0] = 0;
+  int iw = 1;
+  int nbpnt = 0;
+
+  myTool = new StdMeshers_Helper(aMesh);
+  _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
+
+  myOuterWire = BRepTools::OuterWire(F);
+  nbpnt += NumberOfPoints(aMesh, myOuterWire);
+  if ( nbpnt < 3 ) { // ex: a circle with 2 segments
+    delete myTool; myTool = 0;
+    return false;
+  }
+  nudslf[iw++] = nbpnt;
 
-        // avoid passing same uv points for a vertex common to 2 wires
-        TopTools_IndexedDataMapOfShapeListOfShape VWMap;
-        if ( iw - 1 > 1 ) // nbofWires > 1
-          TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap );
+  for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) {
+    const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
+    if (!myOuterWire.IsSame(W)) {
+      nbpnt += NumberOfPoints(aMesh, W);
+      nudslf[iw++] = nbpnt;
+    }
+  }
 
-       uvslf = new R2[nudslf[nblf]];
-       int m = 0;
+  // avoid passing same uv points for a vertex common to 2 wires
+  TopTools_IndexedDataMapOfShapeListOfShape VWMap;
+  if ( iw - 1 > 1 ) // nbofWires > 1
+    TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap );
 
-        double scalex, scaley;
-        ComputeScaleOnFace(aMesh, F, scalex, scaley);
+  uvslf = new R2[nudslf[nblf]];
+  int m = 0;
 
-        map<int, const SMDS_MeshNode*> mefistoToDS;    // correspondence mefisto index--> points IDNodes
-       if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m,
-                         mefistoToDS, scalex, scaley, VWMap))
-          return false;
+  double scalex, scaley;
+  ComputeScaleOnFace(aMesh, F, scalex, scaley);
 
-       for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
-       {
-               const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
-               if (!myOuterWire.IsSame(W))
-               {
-                       if (! LoadPoints(aMesh, F, W, uvslf, m,
-                                         mefistoToDS, scalex, scaley, VWMap ))
-                          return false;
-               }
-       }
+  map<int, const SMDS_MeshNode*> mefistoToDS;  // correspondence mefisto index--> points IDNodes
+  if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m,
+                   mefistoToDS, scalex, scaley, VWMap) ) {
+    delete myTool; myTool = 0;
+    return false;
+  }
 
-       uvst = NULL;
-       nust = NULL;
-       aptrte(nutysu, aretmx,
-               nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
-
-       if (ierr == 0)
-         {
-           MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
-           MESSAGE("                                    Node Number " << nbst);
-           StoreResult(aMesh, nbst, uvst, nbt, nust, F,
-                       faceIsForward, mefistoToDS, scalex, scaley);
-           isOk = true;
-         }
-       else
-       {
-               MESSAGE("Error in Triangulation");
-               isOk = false;
-       }
-       if (nudslf != NULL)
-               delete[]nudslf;
-       if (uvslf != NULL)
-               delete[]uvslf;
-       if (uvst != NULL)
-               delete[]uvst;
-       if (nust != NULL)
-               delete[]nust;
-       return isOk;
+  for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
+  {
+    const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
+    if (!myOuterWire.IsSame(W))
+    {
+      if (! LoadPoints(aMesh, F, W, uvslf, m,
+                       mefistoToDS, scalex, scaley, VWMap )) {
+        delete myTool; myTool = 0;
+        return false;
+      }
+    }
+  }
+
+  uvst = NULL;
+  nust = NULL;
+  aptrte(nutysu, aretmx,
+         nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
+
+  if (ierr == 0)
+  {
+    MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
+    MESSAGE("                                    Node Number " << nbst);
+    StoreResult(aMesh, nbst, uvst, nbt, nust, F,
+                faceIsForward, mefistoToDS, scalex, scaley);
+    isOk = true;
+  }
+  else
+  {
+    MESSAGE("Error in Triangulation");
+    isOk = false;
+  }
+  if (nudslf != NULL)
+    delete[]nudslf;
+  if (uvslf != NULL)
+    delete[]uvslf;
+  if (uvst != NULL)
+    delete[]uvst;
+  if (nust != NULL)
+    delete[]nust;
+  delete myTool; myTool = 0;
+
+  return isOk;
 }
 
 //=======================================================================
@@ -354,7 +360,8 @@ static bool fixCommonVertexUV (gp_Pnt2d &           theUV,
                                const TopoDS_Wire&   theOW,
                                const TopoDS_Face&   theF,
                                const TopTools_IndexedDataMapOfShapeListOfShape & theVWMap,
-                               SMESH_Mesh &         theMesh)
+                               SMESH_Mesh &         theMesh,
+                               bool CreateQuadratic)
 {
   if( theW.IsSame( theOW ) ||
       !theVWMap.Contains( theV )) return false;
@@ -417,10 +424,12 @@ static bool fixCommonVertexUV (gp_Pnt2d &           theUV,
       umin = l;
       umax = f;
     }
-    else
-    {
+    else {
       while ( nIt->more() ) {
         const SMDS_MeshNode* node = nIt->next();
+        // check if node is medium
+        if ( CreateQuadratic && StdMeshers_Helper::IsMedium( node, SMDSAbs_Edge ))
+          continue;
         const SMDS_EdgePosition* epos =
           static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
         double u = epos->GetUParameter();
@@ -515,9 +524,13 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh &        aMesh,
     while ( nodeIt->more() )
     {
       node = nodeIt->next();
+      if ( _quadraticMesh && StdMeshers_Helper::IsMedium( node, SMDSAbs_Edge ))
+        continue;
       const SMDS_EdgePosition* epos =
         static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
-      params[ epos->GetUParameter() ] = node;
+      double param = epos->GetUParameter();
+      if ( !isForward ) param = -param;
+      params.insert( make_pair( param, node ));
     }
     int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
     if ( nbPoints != params.size())
@@ -535,7 +548,7 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh &        aMesh,
 
     // vertex node
     gp_Pnt2d p = C2d->Value( uFirst ).XY().Multiplied( scale );
-    if ( fixCommonVertexUV( p, V, W, myOuterWire, F, VWMap, aMesh ))
+    if ( fixCommonVertexUV( p, V, W, myOuterWire, F, VWMap, aMesh, _quadraticMesh ))
       myNodesOnCommonV.push_back( idFirst );
     mOnVertex.push_back( m );
     uvslf[m].x = p.X();
@@ -547,22 +560,13 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh &        aMesh,
 
     // internal nodes
     map<double, const SMDS_MeshNode*>::iterator u_n = params.begin();
-    map<double, const SMDS_MeshNode*>::reverse_iterator u_n_rev = params.rbegin();
-    for ( int i = 0; i < nbPoints; ++i )
+    for ( int i = 0; u_n != params.end(); ++u_n, ++i )
     {
-      if ( isForward ) {
-        u    = u_n->first;
-        node = u_n->second;
-        ++u_n;
-      } else {
-        u    = u_n_rev->first;
-        node = u_n_rev->second;
-        ++u_n_rev;
-      }
+      u = isForward ? u_n->first : - u_n->first;
       gp_Pnt2d p = C2d->Value( u ).XY().Multiplied( scale );
       uvslf[m].x = p.X();
       uvslf[m].y = p.Y();
-      mefistoToDS[m + 1] = node;
+      mefistoToDS[m + 1] = u_n->second;
       //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
       //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
       m++;
@@ -713,37 +717,31 @@ void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh,
   }
 
   m = 0;
-  //int mt = 0;
 
-  //SCRUTE(faceIsForward);
-  for (n = 1; n <= nbt; n++)
-  {
-    int inode1 = nust[m++];
-    int inode2 = nust[m++];
-    int inode3 = nust[m++];
+  // triangle points must be in trigonometric order if face is Forward
+  // else they must be put clockwise
 
-    const SMDS_MeshNode *n1, *n2, *n3;
-    n1 = mefistoToDS[inode1];
-    n2 = mefistoToDS[inode2];
-    n3 = mefistoToDS[inode3];
-    //MESSAGE("-- "<<inode1<<" "<<inode2<<" "<<inode3);
+  bool triangleIsWellOriented = faceIsForward;
 
-    // triangle points must be in trigonometric order if face is Forward
-    // else they must be put clockwise
-
-    bool triangleIsWellOriented = faceIsForward;
+  for (n = 1; n <= nbt; n++)
+  {
+    const SMDS_MeshNode * n1 = mefistoToDS[ nust[m++] ];
+    const SMDS_MeshNode * n2 = mefistoToDS[ nust[m++] ];
+    const SMDS_MeshNode * n3 = mefistoToDS[ nust[m++] ];
 
     SMDS_MeshElement * elt;
     if (triangleIsWellOriented)
-      elt = meshDS->AddFace(n1, n2, n3);
+      //elt = meshDS->AddFace(n1, n2, n3);
+      elt = myTool->AddFace(n1, n2, n3);
     else
-      elt = meshDS->AddFace(n1, n3, n2);
+      //elt = meshDS->AddFace(n1, n3, n2);
+      elt = myTool->AddFace(n1, n3, n2);
 
     meshDS->SetMeshElementOnShape(elt, faceID);
     m++;
   }
 
-  // remove bad elements build on vertices shared by wires
+  // remove bad elements built on vertices shared by wires
 
   list<const SMDS_MeshNode*>::iterator itN = myNodesOnCommonV.begin();
   for ( ; itN != myNodesOnCommonV.end(); itN++ )
@@ -779,17 +777,14 @@ double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh,
        //MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength");
        // **** a mettre dans SMESH_2D_Algo ?
 
-       const TopoDS_Face & FF = TopoDS::Face(aShape);
+       //const TopoDS_Face & FF = TopoDS::Face(aShape);
        //bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
-       TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
+       //TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
 
        double meanElementLength = 100;
        double wireLength = 0;
        int wireElementsNumber = 0;
-       for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
-       {
-               const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
-               for (TopExp_Explorer expe(W, TopAbs_EDGE); expe.More(); expe.Next())
+               for (TopExp_Explorer expe(aShape, TopAbs_EDGE); expe.More(); expe.Next())
                {
                        const TopoDS_Edge & E = TopoDS::Edge(expe.Current());
                        int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
@@ -797,7 +792,6 @@ double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh,
                        wireLength += length;
                        wireElementsNumber += nb;
                }
-       }
        if (wireElementsNumber)
                meanElementLength = wireLength / wireElementsNumber;
        //SCRUTE(meanElementLength);
index fac85f07d0a725d090b3f303291011d10e5a4529..180ceb7605e81a058977b234115f21e33d786655 100644 (file)
@@ -33,6 +33,8 @@
 #include "SMESH_2D_Algo.hxx"
 #include <TopoDS_Wire.hxx>
 
+#include "StdMeshers_Helper.hxx"
+
 class SMDS_MeshNode;
 class TopTools_IndexedDataMapOfShapeListOfShape;
 class TopoDS_Face;
@@ -95,6 +97,8 @@ protected:
 
   TopoDS_Wire myOuterWire;
   std::list<const SMDS_MeshNode*> myNodesOnCommonV;
+
+  StdMeshers_Helper* myTool; // toll for working with quadratic elements
 };
 
 #endif
index ad6ebc83198609b882539342061257d2b33e4f5d..efa96e08cfcb461bc2a1c8df4fb70c73516cde65 100644 (file)
@@ -51,6 +51,9 @@
 #include <TopoDS_Shell.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <gp_Pnt.hxx>
+#include <BRepTools.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <TopTools_MapOfShape.hxx>
 
 #include <stdio.h>
 #include <algorithm>
@@ -70,7 +73,20 @@ StdMeshers_Penta_3D::StdMeshers_Penta_3D()
   myTol3D=0.1;
   myWallNodesMaps.resize( SMESH_Block::NbFaces() );
   myShapeXYZ.resize( SMESH_Block::NbSubShapes() );
+  myTool = 0;
 }
+
+//=======================================================================
+//function : ~StdMeshers_Penta_3D
+//purpose  : 
+//=======================================================================
+
+StdMeshers_Penta_3D::~StdMeshers_Penta_3D()
+{
+  if ( myTool )
+    delete myTool;
+}
+
 //=======================================================================
 //function : Compute
 //purpose  : 
@@ -91,33 +107,43 @@ bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh,
   if (myErrorStatus){
     return bOK;
   }
+
+  myTool = new StdMeshers_Helper(aMesh);
+  myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape);
+
   //
   MakeBlock();
-    if (myErrorStatus){
+  if (myErrorStatus){
+    delete myTool; myTool = 0;
+    return bOK;
+  }
+  //
+  ClearMeshOnFxy1();
+  if (myErrorStatus) {
+    delete myTool; myTool = 0;
     return bOK;
   }
   //
   MakeNodes();
   if (myErrorStatus){
+    delete myTool; myTool = 0;
     return bOK;
   }
   //
   MakeConnectingMap();
   //
-  ClearMeshOnFxy1();
-  if (myErrorStatus) {
-    return bOK;
-  }
-  //
   MakeMeshOnFxy1();
   if (myErrorStatus) {
+    delete myTool; myTool = 0;
     return bOK;
   }
   //
   MakeVolumeMesh();
   //
+  delete myTool; myTool = 0;
   return !bOK;
 }
+
 //=======================================================================
 //function : MakeNodes
 //purpose  : 
@@ -144,12 +170,24 @@ void StdMeshers_Penta_3D::MakeNodes()
   // 1.1 Horizontal size
   myJSize=0;
   for (i=0; i<aNbSIDs; ++i) {
-    const TopoDS_Shape& aS=myBlock.Shape(aSIDs[i]);
+    const TopoDS_Shape& aS = myBlock.Shape(aSIDs[i]);
     SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aS);
     ASSERT(aSubMesh);
-    SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS();
-    iNbN=aSM->NbNodes();
-    myJSize+=iNbN;
+    SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS();
+    if(!myCreateQuadratic) {
+      iNbN = aSM->NbNodes();
+    }
+    else {
+      iNbN = 0;
+      SMDS_NodeIteratorPtr itn = aSM->GetNodes();
+      while(itn->more()) {
+        const SMDS_MeshNode* aNode = itn->next();
+        if(myTool->IsMedium(aNode))
+          continue;
+        iNbN++;
+      }
+    }
+    myJSize += iNbN;
   }
   //printf("***  Horizontal: number of nodes summary=%d\n", myJSize);
   //
@@ -159,9 +197,21 @@ void StdMeshers_Penta_3D::MakeNodes()
     const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_E00z);
     SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aS);
     ASSERT(aSubMesh);
-    SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS();
-    iNbN=aSM->NbNodes();
-    myISize+=iNbN;
+    SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS();
+    if(!myCreateQuadratic) {
+      iNbN = aSM->NbNodes();
+    }
+    else {
+      iNbN = 0;
+      SMDS_NodeIteratorPtr itn = aSM->GetNodes();
+      while(itn->more()) {
+        const SMDS_MeshNode* aNode = itn->next();
+        if(myTool->IsMedium(aNode))
+          continue;
+        iNbN++;
+      }
+    }
+    myISize += iNbN;
   }
   //printf("***  Vertical: number of nodes on edges and vertices=%d\n", myISize);
   //
@@ -177,18 +227,19 @@ void StdMeshers_Penta_3D::MakeNodes()
   // vertices
   for (k=0; k<aNbSIDs; ++k) {
     aSID=aSIDs[k];
-    const TopoDS_Shape& aS=myBlock.Shape(aSID);
-    SMDS_NodeIteratorPtr ite =pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes();
+    const TopoDS_Shape& aS = myBlock.Shape(aSID);
+    SMDS_NodeIteratorPtr ite = pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes();
     while(ite->more()) {
       const SMDS_MeshNode* aNode = ite->next();
+      if(myTool->IsMedium(aNode))
+        continue;
       aNodeID=aNode->GetID();
       //
       aTNode.SetNode(aNode);
       aTNode.SetShapeSupportID(aSID);
       aTNode.SetBaseNodeID(aNodeID);
       //
-      if ( SMESH_Block::IsEdgeID (aSID))
-      {
+      if ( SMESH_Block::IsEdgeID (aSID)) {
         const SMDS_EdgePosition* epos =
           static_cast<const SMDS_EdgePosition*>(aNode->GetPosition().get());
         myBlock.ComputeParameters( epos->GetUParameter(), aS, aCoords );
@@ -200,7 +251,7 @@ void StdMeshers_Penta_3D::MakeNodes()
         aP3D.SetCoord(aX, aY, aZ);
         myBlock.ComputeParameters(aP3D, aS, aCoords);
       }
-      iErr=myBlock.ErrorStatus();
+      iErr = myBlock.ErrorStatus();
       if (iErr) {
         MESSAGE("StdMeshers_Penta_3D::MakeNodes()," <<
                 "SMESHBlock: ComputeParameters operation failed");
@@ -325,8 +376,7 @@ void StdMeshers_Penta_3D::MakeNodes()
 
   // 3.3 set XYZ of vertices, and initialize of the rest
   SMESHDS_Mesh* aMesh = GetMesh()->GetMeshDS();
-  for ( int id = SMESH_Block::ID_V000; id < SMESH_Block::ID_Shell; ++id )
-  {
+  for ( int id = SMESH_Block::ID_V000; id < SMESH_Block::ID_Shell; ++id ) {
     if ( SMESH_Block::IsVertexID( id )) {
       TopoDS_Shape V = myBlock.Shape( id );
       SMESHDS_SubMesh* sm = aMesh->MeshElements( V );
@@ -344,23 +394,46 @@ void StdMeshers_Penta_3D::MakeNodes()
   SMESH_Block::TShapeID aSSID, aBNSSID;
   StdMeshers_TNode aTN;
   //
-  for (j=0; j<myJSize; ++j)
-  {
+
+  // create top face and find UV for it's corners
+  const TopoDS_Face& TopFace = TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy1));
+  SMESHDS_Mesh* meshDS = pMesh->GetMeshDS();
+  int topfaceID = meshDS->ShapeToIndex(TopFace);
+  const TopoDS_Vertex& v001 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V001));
+  SMDS_NodeIteratorPtr itn = pMesh->GetSubMeshContaining(v001)->GetSubMeshDS()->GetNodes();
+  const SMDS_MeshNode* N = itn->next();
+  gp_XY UV001 = myTool->GetNodeUV(TopFace,N);
+  const TopoDS_Vertex& v101 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V101));
+  itn = pMesh->GetSubMeshContaining(v101)->GetSubMeshDS()->GetNodes();
+  N = itn->next();
+  gp_XY UV101 = myTool->GetNodeUV(TopFace,N);
+  const TopoDS_Vertex& v011 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V011));
+  itn = pMesh->GetSubMeshContaining(v011)->GetSubMeshDS()->GetNodes();
+  N = itn->next();
+  gp_XY UV011 = myTool->GetNodeUV(TopFace,N);
+  const TopoDS_Vertex& v111 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V111));
+  itn = pMesh->GetSubMeshContaining(v111)->GetSubMeshDS()->GetNodes();
+  N = itn->next();
+  gp_XY UV111 = myTool->GetNodeUV(TopFace,N);
+
+  for (j=0; j<myJSize; ++j) {
     // base node info
-    const StdMeshers_TNode& aBN=myTNodes[j];
-    aBNSSID=(SMESH_Block::TShapeID)aBN.ShapeSupportID();
-    iBNID=aBN.BaseNodeID();
-    const gp_XYZ& aBNXYZ=aBN.NormCoord();
+    const StdMeshers_TNode& aBN = myTNodes[j];
+    aBNSSID = (SMESH_Block::TShapeID)aBN.ShapeSupportID();
+    iBNID = aBN.BaseNodeID();
+    const gp_XYZ& aBNXYZ = aBN.NormCoord();
     bool createNode = ( aBNSSID == SMESH_Block::ID_Fxy0 );
     //
     // set XYZ on horizontal edges and get node columns of faces:
     // 2 columns for each face, between which a base node is located
     vector<const SMDS_MeshNode*>* nColumns[8];
     double ratio[4]; // base node position between columns [0.-1.]
-    if ( createNode )
-      for ( k = 0; k < 4; ++k )
+    if ( createNode ) {
+      for ( k = 0; k < 4; ++k ) {
         ratio[ k ] = SetHorizEdgeXYZ (aBNXYZ, wallFaceID[ k ],
                                       nColumns[k*2], nColumns[k*2+1]);
+      }
+    }
     //
     // XYZ on the bottom and top faces
     const SMDS_MeshNode* n = aBN.Node();
@@ -368,8 +441,9 @@ void StdMeshers_Penta_3D::MakeNodes()
     myShapeXYZ[ SMESH_Block::ID_Fxy1 ].SetCoord( 0., 0., 0. );
     //
     // first create or find a top node, then the rest ones in a column
-    for (i=myISize-1; i>0; --i)
-    {
+    for (i=myISize-1; i>0; --i) {
+      bIsUpperLayer = (i==(myISize-1));
+      gp_XY UV_Ex01, UV_Ex11, UV_E0y1, UV_E1y1;
       if ( createNode ) {
         // set XYZ on vertical edges and faces
         for ( k = 0; k < 4; ++k ) {
@@ -377,11 +451,28 @@ void StdMeshers_Penta_3D::MakeNodes()
           myShapeXYZ[ verticEdgeID[ k ] ].SetCoord( n->X(), n->Y(), n->Z() );
           //
           n = (*nColumns[k*2]) [ i ];
+          gp_XY tmp1;
+          if( i==myISize-1 ) {
+            tmp1 = myTool->GetNodeUV(TopFace,n);
+            tmp1 = ( 1. - ratio[ k ]) * tmp1;
+          }
           gp_XYZ xyz( n->X(), n->Y(), n->Z() );
           myShapeXYZ[ wallFaceID[ k ]] = ( 1. - ratio[ k ]) * xyz;
           n = (*nColumns[k*2+1]) [ i ];
           xyz.SetCoord( n->X(), n->Y(), n->Z() );
           myShapeXYZ[ wallFaceID[ k ]] += ratio[ k ] * xyz;
+          if( i==myISize-1 ) {
+            gp_XY tmp2 = myTool->GetNodeUV(TopFace,n);
+            tmp1 +=  ratio[ k ] * tmp2;
+            if( k==0 )
+              UV_Ex01 = tmp1;
+            else if( k==1 )
+              UV_Ex11 = tmp1;
+            else if( k==2 )
+              UV_E0y1 = tmp1;
+            else
+              UV_E1y1 = tmp1;
+          }
         }
       }
       // fill current node info
@@ -395,7 +486,6 @@ void StdMeshers_Penta_3D::MakeNodes()
       aCoords.SetCoord(aX, aY, aZ);
       //
       //   suporting shape ID
-      bIsUpperLayer=(i==(myISize-1));
       ShapeSupportID(bIsUpperLayer, aBNSSID, aSSID);
       if (myErrorStatus) {
         MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
@@ -418,6 +508,30 @@ void StdMeshers_Penta_3D::MakeNodes()
         if ( bIsUpperLayer ) {
           const SMDS_MeshNode* n = aTN.Node();
           myShapeXYZ[ SMESH_Block::ID_Fxy1 ].SetCoord( n->X(), n->Y(), n->Z() );
+          // set node on top face:
+          // find UV parameter for this node
+          //              UV_Ex11
+          //   UV011+-----+----------+UV111
+          //        |                |
+          //        |                |
+          // UV_E0y1+     +node      +UV_E1y1
+          //        |                |
+          //        |                |
+          //        |                |
+          //   UV001+-----+----------+UV101
+          //              UV_Ex01
+          gp_Pnt2d aP;
+          double u = aCoords.X(), v = aCoords.Y();
+          double u1 = ( 1. - u ), v1 = ( 1. - v );
+          aP.ChangeCoord()  = UV_Ex01 * v1;
+          aP.ChangeCoord() += UV_Ex11 * v;
+          aP.ChangeCoord() += UV_E0y1 * u1;
+          aP.ChangeCoord() += UV_E1y1 * u;
+          aP.ChangeCoord() -= UV001 * u1 * v1;
+          aP.ChangeCoord() -= UV101 * u  * v1;
+          aP.ChangeCoord() -= UV011 * u1 * v;
+          aP.ChangeCoord() -= UV111 * u  * v;
+          meshDS->SetNodeOnFace((SMDS_MeshNode*)n, topfaceID, aP.X(), aP.Y());
         }
       }
       if (myErrorStatus) {
@@ -456,10 +570,13 @@ void StdMeshers_Penta_3D::MakeNodes()
   */
   //DEB t
 }
+
+
 //=======================================================================
 //function : FindNodeOnShape
 //purpose  : 
 //=======================================================================
+
 void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS,
                                          const gp_XYZ&       aParams,
                                           const int           z,
@@ -470,14 +587,13 @@ void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS,
   double aX, aY, aZ, aD, aTol2, minD;
   gp_Pnt aP1, aP2;
   //
-  SMESH_Mesh* pMesh=GetMesh();
-  aTol2=myTol3D*myTol3D;
+  SMESH_Mesh* pMesh = GetMesh();
+  aTol2 = myTol3D*myTol3D;
   minD = 1.e100;
-  SMDS_MeshNode* pNode=NULL;
+  SMDS_MeshNode* pNode = NULL;
   //
   if ( aS.ShapeType() == TopAbs_FACE ||
-       aS.ShapeType() == TopAbs_EDGE )
-  {
+       aS.ShapeType() == TopAbs_EDGE ) {
     // find a face ID to which aTN belongs to
     int faceID;
     if ( aS.ShapeType() == TopAbs_FACE )
@@ -492,13 +608,13 @@ void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS,
     }
     ASSERT( SMESH_Block::IsFaceID( faceID ));
     int fIndex = SMESH_Block::ShapeIndex( faceID );
-    StdMeshers_IJNodeMap & ijNodes= myWallNodesMaps[ fIndex ];
+    StdMeshers_IJNodeMap & ijNodes = myWallNodesMaps[ fIndex ];
     // look for a base node in ijNodes
     const SMDS_MeshNode* baseNode = pMesh->GetMeshDS()->FindNode( aTN.BaseNodeID() );
     StdMeshers_IJNodeMap::const_iterator par_nVec = ijNodes.begin();
     for ( ; par_nVec != ijNodes.end(); par_nVec++ )
       if ( par_nVec->second[ 0 ] == baseNode ) {
-        pNode=(SMDS_MeshNode*)par_nVec->second.at( z );
+        pNode = (SMDS_MeshNode*)par_nVec->second.at( z );
         aTN.SetNode(pNode);
         return;
       }
@@ -510,6 +626,8 @@ void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS,
     pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes();
   while(ite->more()) {
     const SMDS_MeshNode* aNode = ite->next();
+    if(myTool->IsMedium(aNode))
+      continue;
     aX=aNode->X();
     aY=aNode->Y();
     aZ=aNode->Z();
@@ -532,6 +650,7 @@ void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS,
   //myErrorStatus=11; // can not find the node;
 }
 
+
 //=======================================================================
 //function : SetHorizEdgeXYZ
 //purpose  : 
@@ -583,6 +702,7 @@ double StdMeshers_Penta_3D::SetHorizEdgeXYZ(const gp_XYZ&                  aBase
   return r;
 }
 
+
 //=======================================================================
 //function : MakeVolumeMesh
 //purpose  : 
@@ -593,20 +713,20 @@ void StdMeshers_Penta_3D::MakeVolumeMesh()
   //
   int i, j, ij, ik, i1, i2, aSSID; 
   //
-  SMESH_Mesh*   pMesh =GetMesh();
-  SMESHDS_Mesh* meshDS=pMesh->GetMeshDS();
+  SMESH_Mesh*   pMesh = GetMesh();
+  SMESHDS_Mesh* meshDS = pMesh->GetMeshDS();
   //
   int shapeID = meshDS->ShapeToIndex( myShape );
   //
   // 1. Set Node In Volume
-  ik=myISize-1;
+  ik = myISize-1;
   for (i=1; i<ik; ++i){
     for (j=0; j<myJSize; ++j){
       ij=i*myJSize+j;
-      const StdMeshers_TNode& aTN=myTNodes[ij];
+      const StdMeshers_TNode& aTN = myTNodes[ij];
       aSSID=aTN.ShapeSupportID();
       if (aSSID==SMESH_Block::ID_NONE) {
-       SMDS_MeshNode* aNode=(SMDS_MeshNode*)aTN.Node();
+       SMDS_MeshNode* aNode = (SMDS_MeshNode*)aTN.Node();
        meshDS->SetNodeInVolume(aNode, shapeID);
       }
     }
@@ -621,22 +741,28 @@ void StdMeshers_Penta_3D::MakeVolumeMesh()
   const TopoDS_Face& aFxy0=
     TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0));
   SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0);
-  SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS();
+  SMESHDS_SubMesh *aSM0 = aSubMesh0->GetSubMeshDS();
   //
-  itf=aSM0->GetElements();
+  itf = aSM0->GetElements();
   while(itf->more()) {
-    const SMDS_MeshElement* pE0=itf->next();
+    const SMDS_MeshElement* pE0 = itf->next();
     //
     int nbFaceNodes = pE0->NbNodes();
+    if(myCreateQuadratic)
+      nbFaceNodes = nbFaceNodes/2;
     if ( aN.size() < nbFaceNodes * 2 )
       aN.resize( nbFaceNodes * 2 );
     //
     k=0;
     aItNodes=pE0->nodesIterator();
     while (aItNodes->more()) {
-      const SMDS_MeshElement* pNode=aItNodes->next();
-      aID0=pNode->GetID();
-      aJ[k]=GetIndexOnLayer(aID0);
+      //const SMDS_MeshElement* pNode = aItNodes->next();
+      const SMDS_MeshNode* pNode =
+        static_cast<const SMDS_MeshNode*> (aItNodes->next());
+      if(myTool->IsMedium(pNode))
+        continue;
+      aID0 = pNode->GetID();
+      aJ[k] = GetIndexOnLayer(aID0);
       if (myErrorStatus) {
         MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh");
        return;
@@ -646,19 +772,19 @@ void StdMeshers_Penta_3D::MakeVolumeMesh()
     }
     //
     bool forward = true;
-    for (i=0; i<ik; ++i){
+    for (i=0; i<ik; ++i) {
       i1=i;
       i2=i+1;
       for(j=0; j<nbFaceNodes; ++j) {
-       ij=i1*myJSize+aJ[j];
-       const StdMeshers_TNode& aTN1=myTNodes[ij];
-       const SMDS_MeshNode* aN1=aTN1.Node();
+       ij = i1*myJSize+aJ[j];
+       const StdMeshers_TNode& aTN1 = myTNodes[ij];
+       const SMDS_MeshNode* aN1 = aTN1.Node();
        aN[j]=aN1;
        //
        ij=i2*myJSize+aJ[j];
-       const StdMeshers_TNode& aTN2=myTNodes[ij];
-       const SMDS_MeshNode* aN2=aTN2.Node();
-       aN[j+nbFaceNodes]=aN2;
+       const StdMeshers_TNode& aTN2 = myTNodes[ij];
+       const SMDS_MeshNode* aN2 = aTN2.Node();
+       aN[j+nbFaceNodes] = aN2;
       }
       // check if volume orientation will be ok
       if ( i == 0 ) {
@@ -685,20 +811,30 @@ void StdMeshers_Penta_3D::MakeVolumeMesh()
       SMDS_MeshVolume* aV = 0;
       switch ( nbFaceNodes ) {
       case 3:
-        if ( forward )
-          aV = meshDS->AddVolume(aN[0], aN[1], aN[2],
-                                 aN[3], aN[4], aN[5]);
-        else
-          aV = meshDS->AddVolume(aN[0], aN[2], aN[1],
-                                 aN[3], aN[5], aN[4]);
+        if ( forward ) {
+          //aV = meshDS->AddVolume(aN[0], aN[1], aN[2],
+          //                       aN[3], aN[4], aN[5]);
+          aV = myTool->AddVolume(aN[0], aN[1], aN[2], aN[3], aN[4], aN[5]);
+        }
+        else {
+          //aV = meshDS->AddVolume(aN[0], aN[2], aN[1],
+          //                       aN[3], aN[5], aN[4]);
+          aV = myTool->AddVolume(aN[0], aN[2], aN[1], aN[3], aN[5], aN[4]);
+        }
         break;
       case 4:
-        if ( forward )
-          aV = meshDS->AddVolume(aN[0], aN[1], aN[2], aN[3],
+        if ( forward ) {
+          //aV = meshDS->AddVolume(aN[0], aN[1], aN[2], aN[3],
+          //                       aN[4], aN[5], aN[6], aN[7]);
+          aV = myTool->AddVolume(aN[0], aN[1], aN[2], aN[3],
                                  aN[4], aN[5], aN[6], aN[7]);
-        else
-          aV = meshDS->AddVolume(aN[0], aN[3], aN[2], aN[1],
+        }
+        else {
+          //aV = meshDS->AddVolume(aN[0], aN[3], aN[2], aN[1],
+          //                       aN[4], aN[7], aN[6], aN[5]);
+          aV = myTool->AddVolume(aN[0], aN[3], aN[2], aN[1],
                                  aN[4], aN[7], aN[6], aN[5]);
+        }
         break;
       default:
         continue;
@@ -727,74 +863,68 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1()
   const TopoDS_Face& aFxy1=
     TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy1));
   //
-  SMESH_Mesh* pMesh=GetMesh();
+  SMESH_Mesh* pMesh = GetMesh();
   SMESHDS_Mesh * meshDS = pMesh->GetMeshDS();
   //
   SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0);
-  SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS();
+  SMESHDS_SubMesh *aSM0 = aSubMesh0->GetSubMeshDS();
   //
   // set nodes on aFxy1
-  aLevel=myISize-1;
-  itn=aSM0->GetNodes();
-  aNbNodes=aSM0->NbNodes();
+  aLevel = myISize-1;
+  itn = aSM0->GetNodes();
+  aNbNodes = aSM0->NbNodes();
   //printf("** aNbNodes=%d\n", aNbNodes);
-  while(itn->more()) {
-    const SMDS_MeshNode* aN0=itn->next();
-    aID0=aN0->GetID();
-    aJ=GetIndexOnLayer(aID0);
-    if (myErrorStatus) {
-      MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() ");
-      return;
-    }
-    //
-    ij=aLevel*myJSize+aJ;
-    const StdMeshers_TNode& aTN1=myTNodes[ij];
-    SMDS_MeshNode* aN1=(SMDS_MeshNode*)aTN1.Node();
-    //
-    meshDS->SetNodeOnFace(aN1, aFxy1);
-  }
+
   //
   // set elements on aFxy1
   vector<const SMDS_MeshNode*> aNodes1;
   //
-  itf=aSM0->GetElements();
+  itf = aSM0->GetElements();
   while(itf->more()) {
-    const SMDS_MeshElement * pE0=itf->next();
-    aElementType=pE0->GetType();
+    const SMDS_MeshElement* pE0 = itf->next();
+    aElementType = pE0->GetType();
     if (!aElementType==SMDSAbs_Face) {
       continue;
     }
-    aNbNodes=pE0->NbNodes();
+    aNbNodes = pE0->NbNodes();
+    if(myCreateQuadratic)
+      aNbNodes = aNbNodes/2;
 //     if (aNbNodes!=3) {
 //       continue;
 //     }
     if ( aNodes1.size() < aNbNodes )
       aNodes1.resize( aNbNodes );
     //
-    k=aNbNodes-1; // reverse a face
-    aItNodes=pE0->nodesIterator();
+    k = aNbNodes-1; // reverse a face
+    aItNodes = pE0->nodesIterator();
     while (aItNodes->more()) {
-      const SMDS_MeshElement* pNode=aItNodes->next();
-      aID0=pNode->GetID();
-      aJ=GetIndexOnLayer(aID0);
+      //const SMDS_MeshElement* pNode = aItNodes->next();
+      const SMDS_MeshNode* pNode =
+        static_cast<const SMDS_MeshNode*> (aItNodes->next());
+      if(myTool->IsMedium(pNode))
+        continue;
+      aID0 = pNode->GetID();
+      aJ = GetIndexOnLayer(aID0);
       if (myErrorStatus) {
         MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() ");
        return;
       }
       //
-      ij=aLevel*myJSize+aJ;
-      const StdMeshers_TNode& aTN1=myTNodes[ij];
-      const SMDS_MeshNode* aN1=aTN1.Node();
-      aNodes1[k]=aN1;
+      ij = aLevel*myJSize + aJ;
+      const StdMeshers_TNode& aTN1 = myTNodes[ij];
+      const SMDS_MeshNode* aN1 = aTN1.Node();
+      aNodes1[k] = aN1;
       --k;
     }
     SMDS_MeshFace * face = 0;
     switch ( aNbNodes ) {
     case 3:
-      face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]);
+      //face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]);
+      face = myTool->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]);
       break;
     case 4:
-      face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]);
+      //face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]);
+      face = myTool->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]);
       break;
     default:
       continue;
@@ -802,6 +932,7 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1()
     meshDS->SetMeshElementOnShape(face, aFxy1);
   }
 }
+
 //=======================================================================
 //function : ClearMeshOnFxy1
 //purpose  : 
@@ -838,6 +969,7 @@ int StdMeshers_Penta_3D::GetIndexOnLayer(const int aID)
   j=(*aMapIt).second;
   return j;
 }
+
 //=======================================================================
 //function : MakeConnectingMap
 //purpose  : 
@@ -852,6 +984,7 @@ void StdMeshers_Penta_3D::MakeConnectingMap()
     myConnectingMap[aBNID]=j;
   }
 }
+
 //=======================================================================
 //function : CreateNode
 //purpose  : 
@@ -879,8 +1012,7 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer,
 //     // point inside solid
 //     myBlock.Point(aParams, aP);
 //   }
-  if (bIsUpperLayer)
-  {
+  if (bIsUpperLayer) {
     double u = aParams.X(), v = aParams.Y();
     double u1 = ( 1. - u ), v1 = ( 1. - v );
     aP.ChangeCoord()  = myShapeXYZ[ SMESH_Block::ID_Ex01 ] * v1;
@@ -893,8 +1025,7 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer,
     aP.ChangeCoord() -= myShapeXYZ[ SMESH_Block::ID_V011 ] * u1 * v;
     aP.ChangeCoord() -= myShapeXYZ[ SMESH_Block::ID_V111 ] * u  * v;
   }
-  else
-  {
+  else {
     SMESH_Block::ShellPoint( aParams, myShapeXYZ, aP.ChangeCoord() );
   }
   //
@@ -906,12 +1037,14 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer,
   //
   aX=aP.X(); aY=aP.Y(); aZ=aP.Z(); 
   //
-  SMESH_Mesh* pMesh=GetMesh();
-  SMESHDS_Mesh* pMeshDS=pMesh->GetMeshDS();
+  SMESH_Mesh* pMesh = GetMesh();
+  SMESHDS_Mesh* pMeshDS = pMesh->GetMeshDS();
   //
   pNode = pMeshDS->AddNode(aX, aY, aZ);
+  
   aTN.SetNode(pNode);
 }
+
 //=======================================================================
 //function : ShapeSupportID
 //purpose  : 
@@ -980,21 +1113,21 @@ void StdMeshers_Penta_3D::MakeBlock()
   SMDSAbs_ElementType aElementType;
   SMESH_Mesh* pMesh=GetMesh();
   //
-  iCnt=0;
-  iNbF=aM.Extent();
+  iCnt = 0;
+  iNbF = aM.Extent();
   for (i=1; i<=iNbF; ++i) {
-    const TopoDS_Shape& aF=aM(i);
+    const TopoDS_Shape& aF = aM(i);
     SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aF);
     ASSERT(aSubMesh);
-    SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS();
-    SMDS_ElemIteratorPtr itf=aSM->GetElements();
+    SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS();
+    SMDS_ElemIteratorPtr itf = aSM->GetElements();
     while(itf->more()) {
-      const SMDS_MeshElement * pElement=itf->next();
-      aElementType=pElement->GetType();
+      const SMDS_MeshElement * pElement = itf->next();
+      aElementType = pElement->GetType();
       if (aElementType==SMDSAbs_Face) {
-       iNbNodes=pElement->NbNodes();
-       if (iNbNodes==3) {
-         aFTr=aF;
+       iNbNodes = pElement->NbNodes();
+       if ( iNbNodes==3 || (myCreateQuadratic && iNbNodes==6) ) {
+         aFTr = aF;
          ++iCnt;
          if (iCnt>1) {
             MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
@@ -1013,7 +1146,7 @@ void StdMeshers_Penta_3D::MakeBlock()
   TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMVES);
   //
   // 1.1 Base vertex V000
-  iNbE=aME.Extent();
+  iNbE = aME.Extent();
   if (iNbE!=4){
     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
     myErrorStatus=7; // too few edges are in base face aFTr 
@@ -1080,7 +1213,7 @@ void StdMeshers_Penta_3D::MakeBlock()
   // 2. Load Block
   const TopoDS_Shell& aShell=TopoDS::Shell(aME(1));
   myBlock.Load(aShell, aV000, aV001);
-  iErr=myBlock.ErrorStatus();
+  iErr = myBlock.ErrorStatus();
   if (iErr) {
     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
     myErrorStatus=100; // SMESHBlock: Load operation failed
@@ -1154,10 +1287,10 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
   bool rev1, CumOri = false;
   TopExp_Explorer exp( theFace, TopAbs_EDGE );
   int nbEdges = 0;
-  for ( ; exp.More(); exp.Next() )
-  {
-    if ( ++nbEdges > 4 )
+  for ( ; exp.More(); exp.Next() ) {
+    if ( ++nbEdges > 4 ) {
       return false; // more than 4 edges in theFace
+    }
     TopoDS_Edge e = TopoDS::Edge( exp.Current() );
     if ( theBaseEdge.IsSame( e ))
       continue;
@@ -1174,8 +1307,9 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
     else
       e2 = e;
   }
-  if ( nbEdges < 4 )
-    return false; // lass than 4 edges in theFace
+  if ( nbEdges < 4 ) {
+    return false; // less than 4 edges in theFace
+  }
 
   // submeshes corresponding to shapes
   SMESHDS_SubMesh* smFace = theMesh->MeshElements( theFace );
@@ -1200,13 +1334,32 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
     return false;
   }
   if ( sm1->NbNodes() * smb->NbNodes() != smFace->NbNodes() ) {
-    MESSAGE( "Wrong nb face nodes: " <<
-            sm1->NbNodes()<<" "<<smb->NbNodes()<<" "<<smFace->NbNodes());
-    return false;
+    // check quadratic case
+    if ( myCreateQuadratic ) {
+      int n1 = sm1->NbNodes()/2;
+      int n2 = smb->NbNodes()/2;
+      int n3 = sm1->NbNodes() - n1;
+      int n4 = smb->NbNodes() - n2;
+      int nf = sm1->NbNodes()*smb->NbNodes() - n3*n4;
+      if( nf != smFace->NbNodes() ) {
+        MESSAGE( "Wrong nb face nodes: " <<
+                sm1->NbNodes()<<" "<<smb->NbNodes()<<" "<<smFace->NbNodes());
+        return false;
+      }
+    }
+    else {
+      MESSAGE( "Wrong nb face nodes: " <<
+              sm1->NbNodes()<<" "<<smb->NbNodes()<<" "<<smFace->NbNodes());
+      return false;
+    }
   }
   // IJ size
   int vsize = sm1->NbNodes() + 2;
   int hsize = smb->NbNodes() + 2;
+  if(myCreateQuadratic) {
+    vsize = vsize - sm1->NbNodes()/2 -1;
+    hsize = hsize - smb->NbNodes()/2 -1;
+  }
 
   // load nodes from theBaseEdge
 
@@ -1226,12 +1379,15 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
   double range = l - f;
   SMDS_NodeIteratorPtr nIt = smb->GetNodes();
   const SMDS_MeshNode* node;
-  while ( nIt->more() )
-  {
+  while ( nIt->more() ) {
     node = nIt->next();
+    if(myTool->IsMedium(node))
+      continue;
     const SMDS_EdgePosition* pos =
       dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition().get() );
-    if ( !pos ) return false;
+    if ( !pos ) {
+      return false;
+    }
     double u = ( pos->GetUParameter() - f ) / range;
     vector<const SMDS_MeshNode*> & nVec = theIJNodes[ u ];
     nVec.resize( vsize, nullNode );
@@ -1246,19 +1402,21 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
 
   map< double, const SMDS_MeshNode*> sortedNodes; // sort by param on edge
   nIt = sm1->GetNodes();
-  while ( nIt->more() )
-  {
+  while ( nIt->more() ) {
     node = nIt->next();
+    if(myTool->IsMedium(node))
+      continue;
     const SMDS_EdgePosition* pos =
       dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition().get() );
-    if ( !pos ) return false;
+    if ( !pos ) {
+      return false;
+    }
     sortedNodes.insert( make_pair( pos->GetUParameter(), node ));
   }
   loadedNodes.insert( nVecf[ vsize - 1 ] = smVft->GetNodes()->next() );
   map< double, const SMDS_MeshNode*>::iterator u_n = sortedNodes.begin();
   int row = rev1 ? vsize - 1 : 0;
-  for ( ; u_n != sortedNodes.end(); u_n++ )
-  {
+  for ( ; u_n != sortedNodes.end(); u_n++ ) {
     if ( rev1 ) row--;
     else        row++;
     loadedNodes.insert( nVecf[ row ] = u_n->second );
@@ -1285,8 +1443,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
   StdMeshers_IJNodeMap::iterator par_nVec_2 = par_nVec_1;
   // loop on columns
   int col = 0;
-  for ( par_nVec_2++; par_nVec_2 != theIJNodes.end(); par_nVec_1++, par_nVec_2++ )
-  {
+  for ( par_nVec_2++; par_nVec_2 != theIJNodes.end(); par_nVec_1++, par_nVec_2++ ) {
     col++;
     row = 0;
     const SMDS_MeshNode* n1 = par_nVec_1->second[ row ];
@@ -1295,10 +1452,10 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
     do {
       // look for a face by 2 nodes
       face = SMESH_MeshEditor::FindFaceInSet( n1, n2, allFaces, foundFaces );
-      if ( face )
-      {
+      if ( face ) {
         int nbFaceNodes = face->NbNodes();
-        if ( nbFaceNodes > 4 ) {
+        if ( (!myCreateQuadratic && nbFaceNodes>4) ||
+             (myCreateQuadratic && nbFaceNodes>8) ) {
           MESSAGE(" Too many nodes in a face: " << nbFaceNodes );
           return false;
         }
@@ -1308,6 +1465,8 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
         eIt = face->nodesIterator() ;
         while ( !found && eIt->more() ) {
           node = static_cast<const SMDS_MeshNode*>( eIt->next() );
+          if(myTool->IsMedium(node))
+            continue;
           found = loadedNodes.insert( node ).second;
           if ( !found && node != n1 && node != n2 )
             n3 = node;
@@ -1320,18 +1479,21 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
           par_nVec_2->second[ row ] = node;
           foundFaces.insert( face );
           n2 = node;
-          if ( nbFaceNodes == 4 )
+          if ( nbFaceNodes==4 || (myCreateQuadratic && nbFaceNodes==8) ) {
             n1 = par_nVec_1->second[ row ];
+          }
         }
-        else if (nbFaceNodes == 3 &&
-                 n3 == par_nVec_1->second[ row ] )
+        else if ( (nbFaceNodes==3 || (myCreateQuadratic && nbFaceNodes==6) )  &&
+                 n3 == par_nVec_1->second[ row ] ) {
           n1 = n3;
+        }
         else {
           MESSAGE( "Not quad mesh, column "<< col );
           return false;
         }
       }
-    } while ( face && n1 && n2 );
+    }
+    while ( face && n1 && n2 );
 
     if ( row < vsize - 1 ) {
       MESSAGE( "Too few nodes in column "<< col <<": "<< row+1);
@@ -1390,17 +1552,18 @@ int StdMeshers_SMESHBlock::ErrorStatus() const
 {
   return myErrorStatus;
 }
+
 //=======================================================================
 //function : Load
 //purpose  : 
 //=======================================================================
 void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell)
 {
-  
   TopoDS_Vertex aV000, aV001;
   //
   Load(theShell, aV000, aV001);
 }
+
 //=======================================================================
 //function : Load
 //purpose  : 
@@ -1416,12 +1579,13 @@ void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell,
   bool bOk;
   //
   myShapeIDMap.Clear();  
-  bOk=myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap);
+  bOk = myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap);
   if (!bOk) {
     myErrorStatus=2;
     return;
   }
 }
+
 //=======================================================================
 //function : ComputeParameters
 //purpose  : 
@@ -1431,24 +1595,25 @@ void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt,
 {
   ComputeParameters(thePnt, myShell, theXYZ);
 }
+
 //=======================================================================
 //function : ComputeParameters
 //purpose  : 
 //=======================================================================
 void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt,
                                              const TopoDS_Shape& theShape,
-                                             gp_XYZ& theXYZ)
+                                              gp_XYZ& theXYZ)
 {
   myErrorStatus=0;
   //
   int aID;
   bool bOk;
   //
-  aID=ShapeID(theShape);
+  aID = ShapeID(theShape);
   if (myErrorStatus) {
     return;
   }
-  bOk=myTBlock.ComputeParameters(thePnt, theXYZ, aID);
+  bOk = myTBlock.ComputeParameters(thePnt, theXYZ, aID);
   if (!bOk) {
     myErrorStatus=4; // problems with computation Parameters 
     return;
@@ -1469,12 +1634,12 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU,
   int aID;
   bool bOk=false;
   //
-  aID=ShapeID(theShape);
+  aID = ShapeID(theShape);
   if (myErrorStatus) {
     return;
   }
   if ( SMESH_Block::IsEdgeID( aID ))
-      bOk=myTBlock.EdgeParameters( aID, theU, theXYZ );
+      bOk = myTBlock.EdgeParameters( aID, theU, theXYZ );
   if (!bOk) {
     myErrorStatus=4; // problems with computation Parameters 
     return;
@@ -1492,6 +1657,7 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU,
   //
   Point(theParams, aS, aP3D);
 }
+
 //=======================================================================
 //function : Point
 //purpose  : 
@@ -1500,15 +1666,15 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU,
                                   const TopoDS_Shape& theShape,
                                   gp_Pnt& aP3D)
 {
-  myErrorStatus=0;
+  myErrorStatus = 0;
   //
   int aID;
-  bool bOk=false;
+  bool bOk = false;
   gp_XYZ aXYZ(99.,99.,99.);
   aP3D.SetXYZ(aXYZ);
   //
   if (theShape.IsNull()) {
-    bOk=myTBlock.ShellPoint(theParams, aXYZ);
+    bOk = myTBlock.ShellPoint(theParams, aXYZ);
   }
   //
   else {
@@ -1518,14 +1684,14 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU,
     }
     //
     if (SMESH_Block::IsVertexID(aID)) {
-      bOk=myTBlock.VertexPoint(aID, aXYZ);
+      bOk = myTBlock.VertexPoint(aID, aXYZ);
     }
     else if (SMESH_Block::IsEdgeID(aID)) {
-      bOk=myTBlock.EdgePoint(aID, theParams, aXYZ);
+      bOk = myTBlock.EdgePoint(aID, theParams, aXYZ);
     }
     //
     else if (SMESH_Block::IsFaceID(aID)) {
-      bOk=myTBlock.FacePoint(aID, theParams, aXYZ);
+      bOk = myTBlock.FacePoint(aID, theParams, aXYZ);
     }
   }
   if (!bOk) {
@@ -1534,6 +1700,7 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU,
   }
   aP3D.SetXYZ(aXYZ);
 }
+
 //=======================================================================
 //function : ShapeID
 //purpose  : 
@@ -1561,6 +1728,7 @@ int StdMeshers_SMESHBlock::ShapeID(const TopoDS_Shape& theShape)
   myErrorStatus=2; // unknown shape;
   return aID;
 }
+
 //=======================================================================
 //function : Shape
 //purpose  : 
@@ -1580,3 +1748,5 @@ const TopoDS_Shape& StdMeshers_SMESHBlock::Shape(const int theID)
   const TopoDS_Shape& aS=myShapeIDMap.FindKey(theID);
   return aS;
 }
+
+
index dc8ba72cfe44ab531880ee08ea96c5a7a5d5441b..ae5b03c54c3a4b2d37d6ddb3b604720e381a48d7 100644 (file)
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS_Shell.hxx>
 #include <TopTools_IndexedMapOfOrientedShape.hxx>
+#include <TColStd_MapOfInteger.hxx>
 
 #include "SMESH_Block.hxx"
 
+#include "StdMeshers_Helper.hxx"
+
 typedef std::map< double, std::vector<const SMDS_MeshNode*> > StdMeshers_IJNodeMap;
 
 class StdMeshers_SMESHBlock {
@@ -165,7 +168,7 @@ class StdMeshers_Penta_3D {
   public: // methods
     StdMeshers_Penta_3D();
     
-    //~StdMeshers_Penta_3D();
+    ~StdMeshers_Penta_3D();
     
     bool Compute(SMESH_Mesh& , const TopoDS_Shape& );
     
@@ -181,10 +184,10 @@ class StdMeshers_Penta_3D {
       return myTol3D;
     }
 
-    static bool LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
-                            const TopoDS_Face&     theFace,
-                            const TopoDS_Edge&     theBaseEdge,
-                            SMESHDS_Mesh*          theMesh);
+    bool LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
+                     const TopoDS_Face&     theFace,
+                     const TopoDS_Edge&     theBaseEdge,
+                     SMESHDS_Mesh*          theMesh);
     // Load nodes bound to theFace into column (vectors) and rows
     // of theIJNodes.
     // The value of theIJNodes map is a vector of ordered nodes so
@@ -251,6 +254,9 @@ class StdMeshers_Penta_3D {
     //
     vector<StdMeshers_IJNodeMap> myWallNodesMaps; // nodes on a face
     vector<gp_XYZ>            myShapeXYZ; // point on each sub-shape
+
+    bool myCreateQuadratic;
+    StdMeshers_Helper* myTool; // toll for working with quadratic elements
 };
 
 #endif
index 6672e2565b6416d1bb3f04d0f71321c7ceefd812..f2d982bd1875b2a024a754dd073366b63e2341f5 100644 (file)
@@ -40,7 +40,7 @@ StdMeshers_Propagation::StdMeshers_Propagation (int hypId, int studyId,
      : SMESH_Hypothesis(hypId, studyId, gen)
 {
   _name = GetName();
-  _param_algo_dim = -2;
+  _param_algo_dim = -1; // 1D auxiliary
 }
 
 //=============================================================================
index 9ffa37d1f5ebf675ef727015f57a62f0550f4a3f..da30b67831fa28557255f9d0f62c2d222e04778a 100644 (file)
@@ -47,6 +47,7 @@ using namespace std;
 #include <Geom2d_Curve.hxx>
 #include <GeomAdaptor_Curve.hxx>
 #include <GCPnts_UniformAbscissa.hxx>
+#include <TopExp.hxx>
 
 #include <Precision.hxx>
 #include <gp_Pnt2d.hxx>
@@ -80,6 +81,7 @@ StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, SMES
   _name = "Quadrangle_2D";
   _shapeType = (1 << TopAbs_FACE);
   _compatibleHypothesis.push_back("QuadranglePreference");
+  myTool = 0;
 }
 
 //=============================================================================
@@ -91,6 +93,8 @@ StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, SMES
 StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D()
 {
   MESSAGE("StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D");
+  if ( myTool )
+    delete myTool;
 }
 
 //=============================================================================
@@ -128,11 +132,17 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
   SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
   aMesh.GetSubMesh(aShape);
 
+  if ( !myTool )
+    myTool = new StdMeshers_Helper(aMesh);
+  _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
+
   //FaceQuadStruct *quad = CheckAnd2Dcompute(aMesh, aShape);
   FaceQuadStruct* quad = CheckNbEdges(aMesh, aShape);
 
-  if (!quad)
+  if (!quad) {
+    delete myTool; myTool = 0;
     return false;
+  }
 
   if(myQuadranglePreference) {
     int n1 = quad->nbPts[0];
@@ -144,14 +154,18 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
     ntmp = ntmp*2;
     if( nfull==ntmp && ( (n1!=n3) || (n2!=n4) ) ) {
       // special path for using only quandrangle faces
-      return ComputeQuadPref(aMesh, aShape, quad);
+      bool ok = ComputeQuadPref(aMesh, aShape, quad);
+      delete myTool; myTool = 0;
+      return ok;
     }
   }
 
   // set normalized grid on unit square in parametric domain
   SetNormalizedGrid(aMesh, aShape, quad);
-  if (!quad)
+  if (!quad) {
+    delete myTool; myTool = 0;
     return false;
+  }
 
   // --- compute 3D values on points, store points & quadrangles
 
@@ -180,7 +194,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
       quad->uv_grid[ij].node = node;
     }
   }
-
+  
   // mesh faces
 
   //             [2]
@@ -194,16 +208,16 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
   //     0 > > > > > > > > nbhoriz
   //              i
   //             [0]
-
+  
   i = 0;
   int ilow = 0;
   int iup = nbhoriz - 1;
   if (quad->isEdgeOut[3]) { ilow++; } else { if (quad->isEdgeOut[1]) iup--; }
-
+  
   int jlow = 0;
   int jup = nbvertic - 1;
   if (quad->isEdgeOut[0]) { jlow++; } else { if (quad->isEdgeOut[2]) jup--; }
-
+  
   // regular quadrangles
   for (i = ilow; i < iup; i++) {
     for (j = jlow; j < jup; j++) {
@@ -212,11 +226,12 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
       b = quad->uv_grid[j * nbhoriz + i + 1].node;
       c = quad->uv_grid[(j + 1) * nbhoriz + i + 1].node;
       d = quad->uv_grid[(j + 1) * nbhoriz + i].node;
-      SMDS_MeshFace * face = meshDS->AddFace(a, b, c, d);
+      //SMDS_MeshFace * face = meshDS->AddFace(a, b, c, d);
+      SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
       meshDS->SetMeshElementOnShape(face, geomFaceID);
     }
   }
-
+  
   UVPtStruct *uv_e0 = quad->uv_edges[0];
   UVPtStruct *uv_e1 = quad->uv_edges[1];
   UVPtStruct *uv_e2 = quad->uv_edges[2];
@@ -225,7 +240,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
   double eps = Precision::Confusion();
 
   // Boundary quadrangles
-
+  
   if (quad->isEdgeOut[0]) {
     // Down edge is out
     // 
@@ -237,14 +252,14 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
     // .  .  .  .  .  .  .  .  . __ down edge nodes
     // 
     // >->->->->->->->->->->->-> -- direction of processing
-
+      
     int g = 0; // number of last processed node in the regular grid
-
+    
     // number of last node of the down edge to be processed
     int stop = nbdown - 1;
     // if right edge is out, we will stop at a node, previous to the last one
     if (quad->isEdgeOut[1]) stop--;
-
+    
     // for each node of the down edge find nearest node
     // in the first row of the regular grid and link them
     for (i = 0; i < stop; i++) {
@@ -252,18 +267,19 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
       a = uv_e0[i].node;
       b = uv_e0[i + 1].node;
       gp_Pnt pb (b->X(), b->Y(), b->Z());
-
+      
       // find node c in the regular grid, which will be linked with node b
       int near = g;
       if (i == stop - 1) {
         // right bound reached, link with the rightmost node
         near = iup;
         c = quad->uv_grid[nbhoriz + iup].node;
-      } else {
+      }
+      else {
         // find in the grid node c, nearest to the b
         double mind = RealLast();
         for (int k = g; k <= iup; k++) {
-
+          
           const SMDS_MeshNode *nk;
           if (k < ilow) // this can be, if left edge is out
             nk = uv_e3[1].node; // get node from the left edge
@@ -283,14 +299,17 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
       }
 
       if (near == g) { // make triangle
-        SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
+        //SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
+        SMDS_MeshFace* face = myTool->AddFace(a, b, c);
         meshDS->SetMeshElementOnShape(face, geomFaceID);
-      } else { // make quadrangle
+      }
+      else { // make quadrangle
         if (near - 1 < ilow)
           d = uv_e3[1].node;
         else
           d = quad->uv_grid[nbhoriz + near - 1].node;
-        SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
+        //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
+        SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
         meshDS->SetMeshElementOnShape(face, geomFaceID);
 
         // if node d is not at position g - make additional triangles
@@ -301,7 +320,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
               d = uv_e3[1].node;
             else
               d = quad->uv_grid[nbhoriz + k - 1].node;
-            SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
+            //SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
+            SMDS_MeshFace* face = myTool->AddFace(a, c, d);
             meshDS->SetMeshElementOnShape(face, geomFaceID);
           }
         }
@@ -363,14 +383,17 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
         }
 
         if (near == g) { // make triangle
-          SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
+          //SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
+          SMDS_MeshFace* face = myTool->AddFace(a, b, c);
           meshDS->SetMeshElementOnShape(face, geomFaceID);
-        } else { // make quadrangle
+        }
+        else { // make quadrangle
           if (near + 1 > iup)
             d = uv_e1[nbright - 2].node;
           else
             d = quad->uv_grid[nbhoriz*(nbvertic - 2) + near + 1].node;
-          SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
+          //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
+          SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
           meshDS->SetMeshElementOnShape(face, geomFaceID);
 
           if (near + 1 < g) { // if d not is at g - make additional triangles
@@ -380,7 +403,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
                 d = uv_e1[nbright - 2].node;
               else
                 d = quad->uv_grid[nbhoriz*(nbvertic - 2) + k + 1].node;
-              SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
+              //SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
+              SMDS_MeshFace* face = myTool->AddFace(a, c, d);
               meshDS->SetMeshElementOnShape(face, geomFaceID);
             }
           }
@@ -428,14 +452,17 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
       }
 
       if (near == g) { // make triangle
-        SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
+        //SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
+        SMDS_MeshFace* face = myTool->AddFace(a, b, c);
         meshDS->SetMeshElementOnShape(face, geomFaceID);
-      } else { // make quadrangle
+      }
+      else { // make quadrangle
         if (near - 1 < jlow)
           d = uv_e0[nbdown - 2].node;
         else
           d = quad->uv_grid[nbhoriz*near - 2].node;
-        SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
+        //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
+        SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
         meshDS->SetMeshElementOnShape(face, geomFaceID);
 
         if (near - 1 > g) { // if d not is at g - make additional triangles
@@ -445,7 +472,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
               d = uv_e0[nbdown - 2].node;
             else
               d = quad->uv_grid[nbhoriz*k - 2].node;
-            SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
+            //SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
+            SMDS_MeshFace* face = myTool->AddFace(a, c, d);
             meshDS->SetMeshElementOnShape(face, geomFaceID);
           }
         }
@@ -490,14 +518,17 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
         }
 
         if (near == g) { // make triangle
-          SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
+          //SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
+          SMDS_MeshFace* face = myTool->AddFace(a, b, c);
           meshDS->SetMeshElementOnShape(face, geomFaceID);
-        } else { // make quadrangle
+        }
+        else { // make quadrangle
           if (near + 1 > jup)
             d = uv_e2[1].node;
           else
             d = quad->uv_grid[nbhoriz*(near + 1) + 1].node;
-          SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
+          //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
+          SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
           meshDS->SetMeshElementOnShape(face, geomFaceID);
 
           if (near + 1 < g) { // if d not is at g - make additional triangles
@@ -507,7 +538,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
                 d = uv_e2[1].node;
               else
                 d = quad->uv_grid[nbhoriz*(k + 1) + 1].node;
-              SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
+              //SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
+              SMDS_MeshFace* face = myTool->AddFace(a, c, d);
               meshDS->SetMeshElementOnShape(face, geomFaceID);
             }
           }
@@ -518,6 +550,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
   }
 
   QuadDelete(quad);
+  delete myTool; myTool = 0;
+
   bool isOk = true;
   return isOk;
 }
@@ -557,7 +591,13 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMesh,
     int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
     if (nbEdges < 4) {
       quad->edge[nbEdges] = E;
-      quad->nbPts[nbEdges] = nb + 2; // internal points + 2 extrema
+      if(!_quadraticMesh) {
+        quad->nbPts[nbEdges] = nb + 2; // internal points + 2 extrema
+      }
+      else {
+        int tmp = nb/2;
+        quad->nbPts[nbEdges] = tmp + 2; // internal not medium points + 2 extrema
+      }
     }
     nbEdges++;
   }
@@ -571,18 +611,21 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMesh,
   return quad;
 }
 
-
 //=============================================================================
 /*!
- *  
+ *  CheckAnd2Dcompute
  */
 //=============================================================================
 
 FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute
-  (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) throw(SALOME_Exception)
+                           (SMESH_Mesh & aMesh,
+                            const TopoDS_Shape & aShape,
+                            const bool CreateQuadratic) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 
+  _quadraticMesh = CreateQuadratic;
+
   FaceQuadStruct *quad = CheckNbEdges(aMesh, aShape);
 
   if(!quad) return 0;
@@ -1185,13 +1228,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
       for(j=1; j<nl; j++) {
         if(WisF) {
           SMDS_MeshFace* F =
-            meshDS->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j),
+            myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j),
                             NodesL.Value(i+1,j+1), NodesL.Value(i,j+1));
           meshDS->SetMeshElementOnShape(F, geomFaceID);
         }
         else {
           SMDS_MeshFace* F =
-            meshDS->AddFace(NodesL.Value(i,j), NodesL.Value(i,j+1),
+            myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i,j+1),
                             NodesL.Value(i+1,j+1), NodesL.Value(i+1,j));
           meshDS->SetMeshElementOnShape(F, geomFaceID);
         }
@@ -1252,13 +1295,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
       for(j=1; j<nr; j++) {
         if(WisF) {
           SMDS_MeshFace* F =
-            meshDS->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j),
+            myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j),
                             NodesR.Value(i+1,j+1), NodesR.Value(i,j+1));
           meshDS->SetMeshElementOnShape(F, geomFaceID);
         }
         else {
           SMDS_MeshFace* F =
-            meshDS->AddFace(NodesR.Value(i,j), NodesR.Value(i,j+1),
+            myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i,j+1),
                             NodesR.Value(i+1,j+1), NodesR.Value(i+1,j));
           meshDS->SetMeshElementOnShape(F, geomFaceID);
         }
@@ -1335,13 +1378,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
     for(j=1; j<nbv; j++) {
       if(WisF) {
         SMDS_MeshFace* F =
-          meshDS->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
+          myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
                           NodesC.Value(i+1,j+1), NodesC.Value(i,j+1));
         meshDS->SetMeshElementOnShape(F, geomFaceID);
       }
       else {
         SMDS_MeshFace* F =
-          meshDS->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1),
+          myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1),
                           NodesC.Value(i+1,j+1), NodesC.Value(i+1,j));
         meshDS->SetMeshElementOnShape(F, geomFaceID);
       }
@@ -1389,16 +1432,47 @@ UVPtStruct* StdMeshers_Quadrangle_2D::LoadEdgePoints2 (SMESH_Mesh & aMesh,
 
   map<double, const SMDS_MeshNode *> params;
   SMDS_NodeIteratorPtr ite = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
+  int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
 
-  while(ite->more()) {
-    const SMDS_MeshNode* node = ite->next();
-    const SMDS_EdgePosition* epos =
-      static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
-    double param = epos->GetUParameter();
-    params[param] = node;
+  if(!_quadraticMesh) {
+    while(ite->more()) {
+      const SMDS_MeshNode* node = ite->next();
+      const SMDS_EdgePosition* epos =
+        static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+      double param = epos->GetUParameter();
+      params[param] = node;
+    }
+  }
+  else {
+    vector<const SMDS_MeshNode*> nodes(nbPoints+2);
+    nodes[0] = idFirst;
+    nodes[nbPoints+1] = idLast;
+    nbPoints = nbPoints/2;
+    int nn = 1;
+    while(ite->more()) {
+      const SMDS_MeshNode* node = ite->next();
+      nodes[nn++] = node;
+      // check if node is medium
+      bool IsMedium = false;
+      SMDS_ElemIteratorPtr itn = node->GetInverseElementIterator();
+      while (itn->more()) {
+        const SMDS_MeshElement* elem = itn->next();
+        if ( elem->GetType() != SMDSAbs_Edge )
+          continue;
+        if(elem->IsMediumNode(node)) {
+          IsMedium = true;
+          break;
+        }
+      }
+      if(IsMedium)
+        continue;
+      const SMDS_EdgePosition* epos =
+        static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+      double param = epos->GetUParameter();
+      params[param] = node;
+    }
   }
 
-  int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
   if (nbPoints != params.size()) {
     MESSAGE( "BAD NODE ON EDGE POSITIONS" );
     return 0;
@@ -1523,21 +1597,60 @@ UVPtStruct* StdMeshers_Quadrangle_2D::LoadEdgePoints (SMESH_Mesh & aMesh,
 
   // --- edge internal IDNodes (relies on good order storage, not checked)
 
+//  if(_quadraticMesh) {
+    // fill myNLinkNodeMap
+//    SMDS_ElemIteratorPtr iter = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetElements();
+//    while(iter->more()) {
+//      const SMDS_MeshElement* elem = iter->next();
+//      SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
+//      const SMDS_MeshNode* n1 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+//      const SMDS_MeshNode* n2 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+//      const SMDS_MeshNode* n3 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+//      NLink link(( n1 < n2 ? n1 : n2 ), ( n1 < n2 ? n2 : n1 ));
+//      myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n3));
+//      myNLinkNodeMap[link] = n3;
+//    }
+//  }
+
   map<double, const SMDS_MeshNode *> params;
   SMDS_NodeIteratorPtr ite = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
+  int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
 
-  while(ite->more())
-  {
-    const SMDS_MeshNode* node = ite->next();
-    const SMDS_EdgePosition* epos =
-      static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
-    double param = epos->GetUParameter();
-    params[param] = node;
+  if(!_quadraticMesh) {
+    while(ite->more()) {
+      const SMDS_MeshNode* node = ite->next();
+      const SMDS_EdgePosition* epos =
+        static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+      double param = epos->GetUParameter();
+      params[param] = node;
+    }
+  }
+  else {
+    nbPoints = nbPoints/2;
+    while(ite->more()) {
+      const SMDS_MeshNode* node = ite->next();
+      // check if node is medium
+      bool IsMedium = false;
+      SMDS_ElemIteratorPtr itn = node->GetInverseElementIterator();
+      while (itn->more()) {
+        const SMDS_MeshElement* elem = itn->next();
+        if ( elem->GetType() != SMDSAbs_Edge )
+          continue;
+        if(elem->IsMediumNode(node)) {
+          IsMedium = true;
+          break;
+        }
+      }
+      if(IsMedium)
+        continue;
+      const SMDS_EdgePosition* epos =
+        static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+      double param = epos->GetUParameter();
+      params[param] = node;
+    }
   }
 
-  int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
-  if (nbPoints != params.size())
-  {
+  if (nbPoints != params.size()) {
     MESSAGE( "BAD NODE ON EDGE POSITIONS" );
     return 0;
   }
index afb3498cbdba6a3923dd00229c21e61ff3aa4947..9abff008c1b806efc1dc4219ed49f5f63a7016c3 100644 (file)
 #include "SMESH_Mesh.hxx"
 #include "Utils_SALOME_Exception.hxx"
 
-class SMDS_MeshNode;
+#include "gp_XY.hxx"
+
+#include "StdMeshers_Helper.hxx"
+
+//class SMDS_MeshNode;
 
 typedef struct uvPtStruct
 {
@@ -75,11 +79,17 @@ public:
     throw (SALOME_Exception);
 
   FaceQuadStruct* CheckAnd2Dcompute(SMESH_Mesh& aMesh,
-                                   const TopoDS_Shape& aShape)
+                                   const TopoDS_Shape& aShape,
+                                    const bool CreateQuadratic)
     throw (SALOME_Exception);
 
   static void QuadDelete(FaceQuadStruct* quad);
 
+  /**
+   * Returns NLinkNodeMap from myTool
+   */
+  const NLinkNodeMap& GetNLinkNodeMap() { return myTool->GetNLinkNodeMap(); }
+
   ostream & SaveTo(ostream & save);
   istream & LoadFrom(istream & load);
   friend ostream & operator << (ostream & save, StdMeshers_Quadrangle_2D & hyp);
@@ -120,6 +130,8 @@ protected:
   // construction of quadrangles if the number of nodes on opposite edges
   // is not the same in the case where the global number of nodes on edges is even
   bool myQuadranglePreference;
+
+  StdMeshers_Helper* myTool; // toll for working with quadratic elements
 };
 
 #endif
index 013bde786dd2836abf72493a21462bd5fbebbc95..5ac5bd582f5eb6120f37b84362c1181b09af14f1 100644 (file)
@@ -98,3 +98,14 @@ istream & operator >>(istream & load, StdMeshers_QuadraticMesh & hyp)
 {
   return hyp.LoadFrom( load );
 }
+//================================================================================
+/*!
+ * \brief Initialize my parameter values by the mesh built on the geometry
+  * \retval bool - false as this hypothesis does not have parameters values
+ */
+//================================================================================
+
+bool StdMeshers_QuadraticMesh::SetParametersByMesh(const SMESH_Mesh*, const TopoDS_Shape&)
+{
+  return false;
+}
index 6f2cc7e8382d40000d4affd05ee3e3544e71ca94..8b88c93db6a1cd05b5b6d6d08b038beb4c212247 100644 (file)
@@ -49,6 +49,17 @@ class StdMeshers_QuadraticMesh:public SMESH_Hypothesis
   virtual std::istream & LoadFrom(std::istream & load);
   friend std::ostream & operator <<(std::ostream & save, StdMeshers_QuadraticMesh & hyp);
   friend std::istream & operator >>(std::istream & load, StdMeshers_QuadraticMesh & hyp);
+
+  /*!
+   * \brief Initialize my parameter values by the mesh built on the geometry
+    * \param theMesh - the built mesh
+    * \param theShape - the geometry of interest
+    * \retval bool - true if parameter values have been successfully defined
+    *
+    * Just return false as this hypothesis does not have parameters values
+   */
+  virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
+
 };
 
 #endif
index 0c6144988cca81e45a20bf2d3344afea9b00d6dc..dc1ec9bb42064f558075805889cb3727060f847c 100644 (file)
@@ -33,6 +33,8 @@ using namespace std;
 #include "StdMeshers_Distribution.hxx"
 #include "SMESH_Gen.hxx"
 #include "SMESH_Mesh.hxx"
+#include "SMESH_HypoFilter.hxx"
+#include "SMESH_subMesh.hxx"
 
 #include "StdMeshers_LocalLength.hxx"
 #include "StdMeshers_NumberOfSegments.hxx"
@@ -44,7 +46,6 @@ using namespace std;
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_EdgePosition.hxx"
-#include "SMESH_subMesh.hxx"
 
 #include "Utils_SALOME_Exception.hxx"
 #include "utilities.h"
@@ -90,6 +91,8 @@ StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId,
        _compatibleHypothesis.push_back("Deflection1D");
        _compatibleHypothesis.push_back("Arithmetic1D");
        _compatibleHypothesis.push_back("AutomaticLength");
+
+       _compatibleHypothesis.push_back("QuadraticMesh"); // auxiliary !!!
 }
 
 //=============================================================================
@@ -109,22 +112,37 @@ StdMeshers_Regular_1D::~StdMeshers_Regular_1D()
 //=============================================================================
 
 bool StdMeshers_Regular_1D::CheckHypothesis
-                         (SMESH_Mesh& aMesh,
-                          const TopoDS_Shape& aShape,
+                         (SMESH_Mesh&                          aMesh,
+                          const TopoDS_Shape&                  aShape,
                           SMESH_Hypothesis::Hypothesis_Status& aStatus)
 {
   _hypType = NONE;
+  _quadraticMesh = false;
+
+  const bool ignoreAuxiliaryHyps = false;
+  const list <const SMESHDS_Hypothesis * > & hyps =
+    GetUsedHypothesis(aMesh, aShape, ignoreAuxiliaryHyps);
+
+  // find non-auxiliary hypothesis
+  const SMESHDS_Hypothesis *theHyp = 0;
+  list <const SMESHDS_Hypothesis * >::const_iterator h = hyps.begin();
+  for ( ; h != hyps.end(); ++h ) {
+    if ( static_cast<const SMESH_Hypothesis*>(*h)->IsAuxiliary() ) {
+      if ( strcmp( "QuadraticMesh", (*h)->GetName() ) == 0 )
+        _quadraticMesh = true;
+    }
+    else {
+      if ( !theHyp )
+        theHyp = *h; // use only the first non-auxiliary hypothesis
+    }
+  }
 
-  const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
-  if (hyps.size() == 0)
+  if ( !theHyp )
   {
     aStatus = SMESH_Hypothesis::HYP_MISSING;
     return false;  // can't work without a hypothesis
   }
 
-  // use only the first hypothesis
-  const SMESHDS_Hypothesis *theHyp = hyps.front();
-
   string hypName = theHyp->GetName();
 
   if (hypName == "LocalLength")
@@ -538,15 +556,13 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
 
   ASSERT(!VLast.IsNull());
   lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
-  if (!lid->more())
-  {
+  if (!lid->more()) {
     MESSAGE (" NO NODE BUILT ON VERTEX ");
     return false;
   }
   const SMDS_MeshNode * idLast = lid->next();
 
-  if (!Curve.IsNull())
-  {
+  if (!Curve.IsNull()) {
     list< double > params;
     bool reversed = false;
     if ( !_mainEdge.IsNull() )
@@ -566,9 +582,14 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
     // only internal nodes receive an edge position with param on curve
 
     const SMDS_MeshNode * idPrev = idFirst;
+    double parPrev = f;
+    double parLast = l;
+//     if(reversed) {
+//       parPrev = l;
+//       parLast = f;
+//     }
     
-    for (list<double>::iterator itU = params.begin(); itU != params.end(); itU++)
-    {
+    for (list<double>::iterator itU = params.begin(); itU != params.end(); itU++) {
       double param = *itU;
       gp_Pnt P = Curve->Value(param);
 
@@ -576,17 +597,39 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
       SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
       meshDS->SetNodeOnEdge(node, shapeID, param);
 
-      SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node);
-      meshDS->SetMeshElementOnShape(edge, shapeID);
+      if(_quadraticMesh) {
+        // create medium node
+        double prm = ( parPrev + param )/2;
+        gp_Pnt PM = Curve->Value(prm);
+        SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z());
+        meshDS->SetNodeOnEdge(NM, shapeID, prm);
+        SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node, NM);
+        meshDS->SetMeshElementOnShape(edge, shapeID);
+      }
+      else {
+        SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node);
+        meshDS->SetMeshElementOnShape(edge, shapeID);
+      }
+
       idPrev = node;
+      parPrev = param;
+    }
+    if(_quadraticMesh) {
+      double prm = ( parPrev + parLast )/2;
+      gp_Pnt PM = Curve->Value(prm);
+      SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z());
+      meshDS->SetNodeOnEdge(NM, shapeID, prm);
+      SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast, NM);
+      meshDS->SetMeshElementOnShape(edge, shapeID);
+    }
+    else {
+      SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast);
+      meshDS->SetMeshElementOnShape(edge, shapeID);
     }
-    SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast);
-    meshDS->SetMeshElementOnShape(edge, shapeID);
   }
-  else
-  {
+  else {
     // Edge is a degenerated Edge : We put n = 5 points on the edge.
-    int NbPoints = 5;
+    const int NbPoints = 5;
     BRep_Tool::Range(E, f, l);
     double du = (l - f) / (NbPoints - 1);
     //MESSAGE("************* Degenerated edge! *****************");
@@ -596,18 +639,38 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
     gp_Pnt P = BRep_Tool::Pnt(V1);
 
     const SMDS_MeshNode * idPrev = idFirst;
-    for (int i = 2; i < NbPoints; i++)
-    {
+    for (int i = 2; i < NbPoints; i++) {
       double param = f + (i - 1) * du;
       SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
+      if(_quadraticMesh) {
+        // create medium node
+        double prm = param - du/2.;
+        gp_Pnt PM = Curve->Value(prm);
+        SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z());
+        meshDS->SetNodeOnEdge(NM, shapeID, prm);
+        SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node, NM);
+        meshDS->SetMeshElementOnShape(edge, shapeID);
+      }
+      else {
+        SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node);
+        meshDS->SetMeshElementOnShape(edge, shapeID);
+      }
       meshDS->SetNodeOnEdge(node, shapeID, param);
-
-      SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node);
-      meshDS->SetMeshElementOnShape(edge, shapeID);
       idPrev = node;
     }
-    SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast);
-    meshDS->SetMeshElementOnShape(edge, shapeID);
+    if(_quadraticMesh) {
+      // create medium node
+      double prm = l - du/2.;
+      gp_Pnt PM = Curve->Value(prm);
+      SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z());
+      meshDS->SetNodeOnEdge(NM, shapeID, prm);
+      SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast, NM);
+      meshDS->SetMeshElementOnShape(edge, shapeID);
+    }
+    else {
+      SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast);
+      meshDS->SetMeshElementOnShape(edge, shapeID);
+    }
   }
   return true;
 }
@@ -618,40 +681,47 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
  */
 //=============================================================================
 
-const list <const SMESHDS_Hypothesis *> & StdMeshers_Regular_1D::GetUsedHypothesis(
-       SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
+const list <const SMESHDS_Hypothesis *> &
+StdMeshers_Regular_1D::GetUsedHypothesis(SMESH_Mesh &         aMesh,
+                                         const TopoDS_Shape & aShape,
+                                         const bool           ignoreAuxiliary)
 {
   _usedHypList.clear();
-  _usedHypList = GetAppliedHypothesis(aMesh, aShape);  // copy
-  int nbHyp = _usedHypList.size();
   _mainEdge.Nullify();
+
+  SMESH_HypoFilter auxiliaryFilter, compatibleFilter;
+  auxiliaryFilter.Init( SMESH_HypoFilter::IsAuxiliary() );
+  const bool ignoreAux = true;
+  InitCompatibleHypoFilter( compatibleFilter, ignoreAux );
+
+  // get non-auxiliary assigned to aShape
+  int nbHyp = aMesh.GetHypotheses( aShape, compatibleFilter, _usedHypList, false );
+
   if (nbHyp == 0)
   {
     // Check, if propagated from some other edge
     if (aShape.ShapeType() == TopAbs_EDGE &&
         aMesh.IsPropagatedHypothesis(aShape, _mainEdge))
     {
-      // Propagation of 1D hypothesis from <aMainEdge> on this edge
-      //_usedHypList = GetAppliedHypothesis(aMesh, _mainEdge); // copy
-      // use a general method in order not to nullify _mainEdge
-      _usedHypList = SMESH_Algo::GetUsedHypothesis(aMesh, _mainEdge);  // copy
-      nbHyp = _usedHypList.size();
+      // Propagation of 1D hypothesis from <aMainEdge> on this edge;
+      // get non-auxiliary assigned to _mainEdge
+      nbHyp = aMesh.GetHypotheses( _mainEdge, compatibleFilter, _usedHypList, false );
     }
   }
-  if (nbHyp == 0)
+
+  if (nbHyp == 0) // nothing propagated nor assigned to aShape
   {
-    TopTools_ListIteratorOfListOfShape ancIt( aMesh.GetAncestors( aShape ));
-    for (; ancIt.More(); ancIt.Next())
-    {
-      const TopoDS_Shape& ancestor = ancIt.Value();
-      _usedHypList = GetAppliedHypothesis(aMesh, ancestor);    // copy
-      nbHyp = _usedHypList.size();
-      if (nbHyp == 1)
-        break;
-    }
+    SMESH_Algo::GetUsedHypothesis( aMesh, aShape, ignoreAuxiliary );
+    nbHyp = _usedHypList.size();
   }
-  if (nbHyp > 1)
-    _usedHypList.clear();      //only one compatible hypothesis allowed
+  else
+  {
+    // get auxiliary hyps from aShape
+    aMesh.GetHypotheses( aShape, auxiliaryFilter, _usedHypList, true );
+  }
+  if ( nbHyp > 1 && ignoreAuxiliary )
+    _usedHypList.clear(); //only one compatible non-auxiliary hypothesis allowed
+
   return _usedHypList;
 }
 
index 4ab58e9ce19ebc8f3ae64680c306b2a2d3ae7276..e2695901bd94c6b67916996a035ba50c37c849a6 100644 (file)
@@ -49,7 +49,7 @@ public:
                       const TopoDS_Shape& aShape);
 
   virtual const std::list <const SMESHDS_Hypothesis *> &
-    GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
+    GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, const bool=true);
 
   ostream & SaveTo(ostream & save);
   istream & LoadFrom(istream & load);
index c5978633b7c83adf77460ff2c2f825b720b72f92..64828da636f5904365dc2c9b3bf53581a1d8911a 100644 (file)
@@ -80,10 +80,14 @@ msgstr "mesh_tree_algo_quad.png"
 msgid "ICON_SMESH_TREE_HYPO_MaxElementArea"
 msgstr "mesh_tree_hypo_area.png"
 
-#mesh_tree_hypo_area
+#mesh_tree_hypo_quadranglepreference
 msgid "ICON_SMESH_TREE_HYPO_QuadranglePreference"
 msgstr "mesh_tree_algo_quad.png"
 
+#mesh_tree_hypo_quadraticmesh
+msgid "ICON_SMESH_TREE_HYPO_QuadraticMesh"
+msgstr "mesh_tree_hypo_length.png"
+
 #mesh_tree_hypo_length
 msgid "ICON_SMESH_TREE_HYPO_LocalLength"
 msgstr "mesh_tree_hypo_length.png"
index cb445cb85b7b9b3d61444c1e18157fe5163ace35..0f5cbcd180c883227661cc2c6202de26bccf5c26 100644 (file)
@@ -52,7 +52,8 @@ EXPORT_HEADERS = \
        StdMeshers_MEFISTO_2D_i.hxx \
        StdMeshers_Hexa_3D_i.hxx \
        StdMeshers_AutomaticLength_i.hxx \
-       StdMeshers_QuadranglePreference_i.hxx
+       StdMeshers_QuadranglePreference_i.hxx \
+       StdMeshers_QuadraticMesh_i.hxx
 
 # Libraries targets
 
@@ -75,7 +76,8 @@ LIB_SRC = \
         StdMeshers_MEFISTO_2D_i.cxx \
        StdMeshers_Hexa_3D_i.cxx \
        StdMeshers_AutomaticLength_i.cxx \
-       StdMeshers_QuadranglePreference_i.cxx
+       StdMeshers_QuadranglePreference_i.cxx \
+       StdMeshers_QuadraticMesh_i.cxx
 
 LIB_SERVER_IDL = SMESH_BasicHypothesis.idl
 
index 768d2c4fb0ed174bf6ec2b7496f9cbfb2357788d..a379e81ac2fa141000679e89bda00f0552757c03 100644 (file)
@@ -39,6 +39,7 @@ using namespace std;
 #include "StdMeshers_Propagation_i.hxx"
 #include "StdMeshers_LengthFromEdges_i.hxx"
 #include "StdMeshers_QuadranglePreference_i.hxx"
+#include "StdMeshers_QuadraticMesh_i.hxx"
 #include "StdMeshers_MaxElementArea_i.hxx"
 #include "StdMeshers_MaxElementVolume_i.hxx"
 #include "StdMeshers_NotConformAllowed_i.hxx"
@@ -87,6 +88,8 @@ extern "C"
       aCreator = new HypothesisCreator_i<StdMeshers_AutomaticLength_i>;
     else if (strcmp(aHypName, "QuadranglePreference") == 0)
       aCreator = new HypothesisCreator_i<StdMeshers_QuadranglePreference_i>;
+    else if (strcmp(aHypName, "QuadraticMesh") == 0)
+      aCreator = new HypothesisCreator_i<StdMeshers_QuadraticMesh_i>;
 
     // Algorithms
     else if (strcmp(aHypName, "Regular_1D") == 0)