]> SALOME platform Git repositories - modules/smesh.git/blobdiff - src/SMESH/SMESH_MeshEditor.cxx
Salome HOME
not initialized value
[modules/smesh.git] / src / SMESH / SMESH_MeshEditor.cxx
index a5740a0d27f92e971bef2f980e6e21a69e5b77e2..d6ad5acf2ded5e07c1e39c7f07ef97e08c908fa8 100644 (file)
@@ -132,99 +132,125 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
   int nbnode = node.size();
   SMESHDS_Mesh* mesh = GetMeshDS();
   switch ( type ) {
-  case SMDSAbs_0DElement:
-    if ( nbnode == 1 )
-      if ( ID >= 0 ) e = mesh->Add0DElementWithID(node[0], ID);
-      else      e = mesh->Add0DElement      (node[0] );
-    break;
-  case SMDSAbs_Edge:
-    if ( nbnode == 2 )
-      if ( ID >= 0 ) e = mesh->AddEdgeWithID(node[0], node[1], ID);
-      else      e = mesh->AddEdge      (node[0], node[1] );
-    else if ( nbnode == 3 )
-      if ( ID >= 0 ) e = mesh->AddEdgeWithID(node[0], node[1], node[2], ID);
-      else      e = mesh->AddEdge      (node[0], node[1], node[2] );
-    break;
   case SMDSAbs_Face:
     if ( !isPoly ) {
-      if      (nbnode == 3)
-        if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], ID);
-        else      e = mesh->AddFace      (node[0], node[1], node[2] );
-      else if (nbnode == 4) 
-        if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], ID);
-        else      e = mesh->AddFace      (node[0], node[1], node[2], node[3] );
-      else if (nbnode == 6)
-        if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
-                                          node[4], node[5], ID);
-        else      e = mesh->AddFace      (node[0], node[1], node[2], node[3],
-                                          node[4], node[5] );
-      else if (nbnode == 8)
-        if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
-                                          node[4], node[5], node[6], node[7], ID);
-        else      e = mesh->AddFace      (node[0], node[1], node[2], node[3],
-                                          node[4], node[5], node[6], node[7] );
+      if      (nbnode == 3) {
+        if ( ID >= 1 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], ID);
+        else           e = mesh->AddFace      (node[0], node[1], node[2] );
+      }
+      else if (nbnode == 4) {
+        if ( ID >= 1 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], ID);
+        else           e = mesh->AddFace      (node[0], node[1], node[2], node[3] );
+      }
+      else if (nbnode == 6) {
+        if ( ID >= 1 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
+                                               node[4], node[5], ID);
+        else           e = mesh->AddFace      (node[0], node[1], node[2], node[3],
+                                               node[4], node[5] );
+      }
+      else if (nbnode == 8) {
+        if ( ID >= 1 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
+                                               node[4], node[5], node[6], node[7], ID);
+        else           e = mesh->AddFace      (node[0], node[1], node[2], node[3],
+                                               node[4], node[5], node[6], node[7] );
+      }
     } else {
-      if ( ID >= 0 ) e = mesh->AddPolygonalFaceWithID(node, ID);
-      else      e = mesh->AddPolygonalFace      (node    );
+      if ( ID >= 1 ) e = mesh->AddPolygonalFaceWithID(node, ID);
+      else           e = mesh->AddPolygonalFace      (node    );
     }
     break;
+
   case SMDSAbs_Volume:
     if ( !isPoly ) {
-      if      (nbnode == 4)
-        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3] );
-      else if (nbnode == 5)
-        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4] );
-      else if (nbnode == 6)
-        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4], node[5] );
-      else if (nbnode == 8)
-        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7], ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7] );
-      else if (nbnode == 10)
-        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9] );
-      else if (nbnode == 13)
-        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], node[10],node[11],
-                                            node[12],ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], node[10],node[11],
-                                            node[12] );
-      else if (nbnode == 15)
-        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], node[10],node[11],
-                                            node[12],node[13],node[14],ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], node[10],node[11],
-                                            node[12],node[13],node[14] );
-      else if (nbnode == 20)
-        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], node[10],node[11],
-                                            node[12],node[13],node[14],node[15],
-                                            node[16],node[17],node[18],node[19],ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], node[10],node[11],
-                                            node[12],node[13],node[14],node[15],
-                                            node[16],node[17],node[18],node[19] );
+      if      (nbnode == 4) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3] );
+      }
+      else if (nbnode == 5) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4] );
+      }
+      else if (nbnode == 6) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4], node[5] );
+      }
+      else if (nbnode == 8) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7], ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7] );
+      }
+      else if (nbnode == 10) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9] );
+      }
+      else if (nbnode == 13) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12] );
+      }
+      else if (nbnode == 15) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],node[13],node[14],ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],node[13],node[14] );
+      }
+      else if (nbnode == 20) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],node[13],node[14],node[15],
+                                                 node[16],node[17],node[18],node[19],ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],node[13],node[14],node[15],
+                                                 node[16],node[17],node[18],node[19] );
+      }
+    }
+    break;
+
+  case SMDSAbs_Edge:
+    if ( nbnode == 2 ) {
+      if ( ID >= 1 ) e = mesh->AddEdgeWithID(node[0], node[1], ID);
+      else           e = mesh->AddEdge      (node[0], node[1] );
+    }
+    else if ( nbnode == 3 ) {
+      if ( ID >= 1 ) e = mesh->AddEdgeWithID(node[0], node[1], node[2], ID);
+      else           e = mesh->AddEdge      (node[0], node[1], node[2] );
+    }
+    break;
+
+  case SMDSAbs_0DElement:
+    if ( nbnode == 1 ) {
+      if ( ID >= 1 ) e = mesh->Add0DElementWithID(node[0], ID);
+      else           e = mesh->Add0DElement      (node[0] );
     }
+    break;
+
+  case SMDSAbs_Node:
+    if ( ID >= 1 ) e = mesh->AddNodeWithID(node[0]->X(), node[0]->Y(), node[0]->Z(), ID);
+    else           e = mesh->AddNode      (node[0]->X(), node[0]->Y(), node[0]->Z());
+    break;
+
+  default:;
   }
   if ( e ) myLastCreatedElems.Append( e );
   return e;
@@ -531,12 +557,14 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1,
     // 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 ( sameInd [ i ] == 0 ) {
         if ( i < 3 ) i1 = i;
         else         i2 = i;
-      else if (i < 3)
+      }
+      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 ] )
@@ -623,7 +651,7 @@ static bool findTriangles(const SMDS_MeshNode *    theNode1,
   it = theNode2->GetInverseElementIterator(SMDSAbs_Face);
   while (it->more()) {
     const SMDS_MeshElement* elem = it->next();
-    if ( emap.find( elem ) != emap.end() )
+    if ( emap.find( elem ) != emap.end() ) {
       if ( theTria1 ) {
         // theTria1 must be element with minimum ID
         if( theTria1->GetID() < elem->GetID() ) {
@@ -638,6 +666,7 @@ static bool findTriangles(const SMDS_MeshNode *    theNode1,
       else {
         theTria1 = elem;
       }
+    }
   }
   return ( theTria1 && theTria2 );
 }
@@ -1540,8 +1569,8 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems,
   SMDS_VolumeTool    volTool;
   SMESH_MesherHelper helper( *GetMesh());
 
-  SMESHDS_SubMesh* subMesh = GetMeshDS()->MeshElements(1);
-  SMESHDS_SubMesh* fSubMesh = subMesh;
+  SMESHDS_SubMesh* subMesh = 0;//GetMeshDS()->MeshElements(1);
+  SMESHDS_SubMesh* fSubMesh = 0;//subMesh;
   
   SMESH_SequenceOfElemPtr newNodes, newElems;
 
@@ -1699,10 +1728,10 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems,
         }
         for ( int i = 0; i < triangles.size(); ++i )
         {
-          if ( !triangles.back() ) continue;
+          if ( !triangles[i] ) continue;
           if ( fSubMesh )
-            fSubMesh->AddElement( triangles.back());
-          newElems.Append( triangles.back() );
+            fSubMesh->AddElement( triangles[i]);
+          newElems.Append( triangles[i] );
         }
         ReplaceElemInGroups( face, triangles, GetMeshDS() );
         GetMeshDS()->RemoveFreeElement( face, fSubMesh, /*fromGroups=*/false );
@@ -1998,7 +2027,7 @@ double getAngle(const SMDS_MeshElement * tr1,
     int i = 0, iDiag = -1;
     while ( it->more()) {
       const SMDS_MeshElement *n = it->next();
-      if ( n == n1 || n == n2 )
+      if ( n == n1 || n == n2 ) {
         if ( iDiag < 0)
           iDiag = i;
         else {
@@ -2008,6 +2037,7 @@ double getAngle(const SMDS_MeshElement * tr1,
             nFirst[ t ] = n;
           break;
         }
+      }
       i++;
     }
   }
@@ -3855,6 +3885,8 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
     const SMDS_MeshElement* elem = itElem->first;
     vector<TNodeOfNodeListMapItr>& vecNewNodes = itElemNodes->second;
 
+    if(itElem->second.size()==0) continue;
+
     if ( elem->GetType() == SMDSAbs_Edge ) {
       // create a ceiling edge
       if (!elem->IsQuadratic()) {
@@ -3879,8 +3911,6 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
     if ( elem->GetType() != SMDSAbs_Face )
       continue;
 
-    if(itElem->second.size()==0) continue;
-
     bool hasFreeLinks = false;
 
     TIDSortedElemSet avoidSet;
@@ -5291,22 +5321,37 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
   string groupPostfix;
   switch ( theTrsf.Form() ) {
   case gp_PntMirror:
+    MESSAGE("gp_PntMirror");
+    needReverse = true;
+    groupPostfix = "mirrored";
+    break;
   case gp_Ax1Mirror:
+    MESSAGE("gp_Ax1Mirror");
+    groupPostfix = "mirrored";
+    break;
   case gp_Ax2Mirror:
+    MESSAGE("gp_Ax2Mirror");
     needReverse = true;
     groupPostfix = "mirrored";
     break;
   case gp_Rotation:
+    MESSAGE("gp_Rotation");
     groupPostfix = "rotated";
     break;
   case gp_Translation:
+    MESSAGE("gp_Translation");
     groupPostfix = "translated";
     break;
   case gp_Scale:
+    MESSAGE("gp_Scale");
+    groupPostfix = "scaled";
+    break;
   case gp_CompoundTrsf: // different scale by axis
+    MESSAGE("gp_CompoundTrsf");
     groupPostfix = "scaled";
     break;
   default:
+    MESSAGE("default");
     needReverse = false;
     groupPostfix = "transformed";
   }
@@ -5326,38 +5371,29 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
   // source elements for each generated one
   SMESH_SequenceOfElemPtr srcElems, srcNodes;
 
-//  // issue 021015: EDF 1578 SMESH: Free nodes are removed when translating a mesh
-//  list<SMDS_MeshNode>          orphanCopy; // copies of orphan nodes
-//  vector<const SMDS_MeshNode*> orphanNode; // original orphan nodes
-//
-//  if ( theElems.empty() ) // transform the whole mesh
-//  {
-//    // add all elements
-//    SMDS_ElemIteratorPtr eIt = aMesh->elementsIterator();
-//    while ( eIt->more() ) theElems.insert( eIt->next() );
-//    // add orphan nodes
-//    SMDS_MeshElementIDFactory idFactory;
-//    SMDS_NodeIteratorPtr nIt = aMesh->nodesIterator();
-//    while ( nIt->more() )
-//    {
-//      const SMDS_MeshNode* node = nIt->next();
-//      if ( node->NbInverseElements() == 0 && !theElems.insert( node ).second )
-//      {
-//        // node was not inserted into theElems because an element with the same ID
-//        // is already there. As a work around we insert a copy of node with
-//        // an ID = -<index in orphanNode>
-//        orphanCopy.push_back( *node ); // copy node
-//        SMDS_MeshNode* nodeCopy = &orphanCopy.back();
-//        int uniqueID = -orphanNode.size();
-//        orphanNode.push_back( node );
-//        idFactory.BindID( uniqueID, nodeCopy );
-//        theElems.insert( nodeCopy );
-//      }
-//    }
-//  }
-  // loop on theElems to transorm nodes
+  // issue 021015: EDF 1578 SMESH: Free nodes are removed when translating a mesh
+  TIDSortedElemSet orphanNode;
+
+  if ( theElems.empty() ) // transform the whole mesh
+  {
+    // add all elements
+    SMDS_ElemIteratorPtr eIt = aMesh->elementsIterator();
+    while ( eIt->more() ) theElems.insert( eIt->next() );
+    // add orphan nodes
+    SMDS_NodeIteratorPtr nIt = aMesh->nodesIterator();
+    while ( nIt->more() )
+    {
+      const SMDS_MeshNode* node = nIt->next();
+      if ( node->NbInverseElements() == 0)
+        orphanNode.insert( node );
+    }
+  }
+
+  // loop on elements to transform nodes : first orphan nodes then elems
   TIDSortedElemSet::iterator itElem;
-  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
+  TIDSortedElemSet *elements[] = {&orphanNode, &theElems };
+  for (int i=0; i<2; i++)
+  for ( itElem = elements[i]->begin(); itElem != elements[i]->end(); itElem++ ) {
     const SMDS_MeshElement* elem = *itElem;
     if ( !elem )
       continue;
@@ -5367,8 +5403,6 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
     while ( itN->more() ) {
 
       const SMDS_MeshNode* node = cast2Node( itN->next() );
-//      if ( node->GetID() < 0 )
-//        node = orphanNode[ -node->GetID() ];
       // check if a node has been already transformed
       pair<TNodeNodeMap::iterator,bool> n2n_isnew =
         nodeMap.insert( make_pair ( node, node ));
@@ -5535,12 +5569,12 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
 
     // Regular elements
     int* i = index[ FORWARD ];
-    if ( needReverse && nbNodes > 2) // reverse mirrored faces and volumes
+    if ( needReverse && nbNodes > 2) {// reverse mirrored faces and volumes
       if ( elemType == SMDSAbs_Face )
         i = index[ REV_FACE ];
       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;
@@ -6262,7 +6296,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
   {
   public:
 
-    ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, double tolerance = NodeRadius );
+    ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, SMDS_ElemIteratorPtr theElemIt = SMDS_ElemIteratorPtr(), double tolerance = NodeRadius );
     void getElementsNearPoint( const gp_Pnt& point, TIDSortedElemSet& foundElems);
     void getElementsNearLine ( const gp_Ax1& line, TIDSortedElemSet& foundElems);
     ~ElementBndBoxTree();
@@ -6289,13 +6323,13 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
    */
   //================================================================================
 
-  ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, double tolerance)
+  ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, SMDS_ElemIteratorPtr theElemIt, double tolerance)
     :SMESH_Octree( new SMESH_Octree::Limit( MaxLevel, /*minSize=*/0. ))
   {
     int nbElems = mesh.GetMeshInfo().NbElements( elemType );
     _elements.reserve( nbElems );
 
-    SMDS_ElemIteratorPtr elemIt = mesh.elementsIterator( elemType );
+    SMDS_ElemIteratorPtr elemIt = theElemIt ? theElemIt : mesh.elementsIterator( elemType );
     while ( elemIt->more() )
       _elements.push_back( new ElementBox( elemIt->next(),tolerance  ));
 
@@ -6443,6 +6477,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
 struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
 {
   SMESHDS_Mesh*                _mesh;
+  SMDS_ElemIteratorPtr         _meshPartIt;
   ElementBndBoxTree*           _ebbTree;
   SMESH_NodeSearcherImpl*      _nodeSearcher;
   SMDSAbs_ElementType          _elementType;
@@ -6450,8 +6485,8 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
   bool                         _outerFacesFound;
   set<const SMDS_MeshElement*> _outerFaces; // empty means "no internal faces at all"
 
-  SMESH_ElementSearcherImpl( SMESHDS_Mesh& mesh )
-    : _mesh(&mesh),_ebbTree(0),_nodeSearcher(0), _tolerance(-1), _outerFacesFound(false) {}
+  SMESH_ElementSearcherImpl( SMESHDS_Mesh& mesh, SMDS_ElemIteratorPtr elemIt=SMDS_ElemIteratorPtr())
+    : _mesh(&mesh),_meshPartIt(elemIt),_ebbTree(0),_nodeSearcher(0),_tolerance(-1),_outerFacesFound(false) {}
   ~SMESH_ElementSearcherImpl()
   {
     if ( _ebbTree )      delete _ebbTree;      _ebbTree      = 0;
@@ -6542,6 +6577,7 @@ double SMESH_ElementSearcherImpl::getTolerance()
         const SMDS_MeshElement* elem = elemIt->next();
         SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
         SMESH_MeshEditor::TNodeXYZ n1( cast2Node( nodeIt->next() ));
+        elemSize = 0;
         while ( nodeIt->more() )
         {
           double dist = n1.Distance( cast2Node( nodeIt->next() ));
@@ -6739,7 +6775,7 @@ FindElementsByPoint(const gp_Pnt&                      point,
     if ( !_ebbTree || _elementType != type )
     {
       if ( _ebbTree ) delete _ebbTree;
-      _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, tolerance );
+      _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt, tolerance );
     }
     TIDSortedElemSet suspectElems;
     _ebbTree->getElementsNearPoint( point, suspectElems );
@@ -6763,7 +6799,7 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
   if ( !_ebbTree || _elementType != SMDSAbs_Face )
   {
     if ( _ebbTree ) delete _ebbTree;
-    _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = SMDSAbs_Face );
+    _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = SMDSAbs_Face, _meshPartIt );
   }
   // Algo: analyse transition of a line starting at the point through mesh boundary;
   // try three lines parallel to axis of the coordinate system and perform rough
@@ -6987,7 +7023,7 @@ void SMESH_ElementSearcherImpl::GetElementsNearLine( const gp_Ax1&
   if ( !_ebbTree || _elementType != type )
   {
     if ( _ebbTree ) delete _ebbTree;
-    _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type );
+    _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt );
   }
   TIDSortedElemSet suspectFaces; // elements possibly intersecting the line
   _ebbTree->getElementsNearLine( line, suspectFaces );
@@ -7005,6 +7041,17 @@ SMESH_ElementSearcher* SMESH_MeshEditor::GetElementSearcher()
   return new SMESH_ElementSearcherImpl( *GetMeshDS() );
 }
 
+//=======================================================================
+/*!
+ * \brief Return SMESH_ElementSearcher
+ */
+//=======================================================================
+
+SMESH_ElementSearcher* SMESH_MeshEditor::GetElementSearcher(SMDS_ElemIteratorPtr elemIt)
+{
+  return new SMESH_ElementSearcherImpl( *GetMeshDS(), elemIt );
+}
+
 //=======================================================================
 /*!
  * \brief Return true if the point is IN or ON of the element
@@ -7024,12 +7071,12 @@ bool SMESH_MeshEditor::isOut( const SMDS_MeshElement* element, const gp_Pnt& poi
   vector<const SMDS_MeshNode*> nodeList;
 
   SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
-  if ( element->IsQuadratic() )
+  if ( element->IsQuadratic() ) {
     if (const SMDS_VtkFace* f=dynamic_cast<const SMDS_VtkFace*>(element))
       nodeIt = f->interlacedNodesElemIterator();
     else if (const SMDS_VtkEdge*  e =dynamic_cast<const SMDS_VtkEdge*>(element))
       nodeIt = e->interlacedNodesElemIterator();
-
+  }
   while ( nodeIt->more() )
     {
       const SMDS_MeshNode* node = cast2Node( nodeIt->next() );
@@ -7360,10 +7407,9 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
           vector<const SMDS_MeshNode *> polygons_nodes;
           vector<int> quantities;
           int nbNew = SimplifyFace(face_nodes, polygons_nodes, quantities);
-
           if (nbNew > 0) {
             inode = 0;
-            for (int iface = 0; iface < nbNew - 1; iface++) {
+            for (int iface = 0; iface < nbNew; iface++) {
               int nbNodes = quantities[iface];
               vector<const SMDS_MeshNode *> poly_nodes (nbNodes);
               for (int ii = 0; ii < nbNodes; ii++, inode++) {
@@ -7826,11 +7872,15 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
         }
       }
       else {
-        int elemId = elem->GetID();
+        //int elemId = elem->GetID();
         //MESSAGE("Change regular element or polygon " << elemId);
         SMDSAbs_ElementType etyp = elem->GetType();
         uniqueNodes.resize(nbUniqueNodes);
-        SMDS_MeshElement* newElem = this->AddElement(uniqueNodes, etyp, false);
+        SMDS_MeshElement* newElem = 0;
+        if (elem->GetEntityType() == SMDSEntity_Polygon)
+          newElem = this->AddElement(uniqueNodes, etyp, true);
+        else
+          newElem = this->AddElement(uniqueNodes, etyp, false);
         if (newElem)
           {
             myLastCreatedElems.Append(newElem);