Salome HOME
PAL0023627: [IMACS] ASERIS: project point to the mesh
[modules/smesh.git] / src / SMESH_I / SMESH_MeshEditor_i.cxx
index 55b451188d212e0b8f6b141a308a4f2dfd52891b..9ca11239b8daa1167a563fd2ee3cc978b1cb3136 100644 (file)
@@ -42,7 +42,6 @@
 #include "SMDS_Mesh0DElement.hxx"
 #include "SMDS_MeshFace.hxx"
 #include "SMDS_MeshVolume.hxx"
-#include "SMDS_PolyhedralVolumeOfNodes.hxx"
 #include "SMDS_SetIterator.hxx"
 #include "SMDS_VolumeTool.hxx"
 #include "SMESHDS_Group.hxx"
@@ -102,7 +101,7 @@ namespace MeshEditor_I {
     SMDSAbs_ElementType myPreviewType; // type to show
     //!< Constructor
     TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
-      _isShapeToMesh = (_id =_studyId = 0);
+      _isShapeToMesh = (_id = 0);
       _myMeshDS  = new SMESHDS_Mesh( _id, true );
       myPreviewType = previewElements;
     }
@@ -165,7 +164,10 @@ namespace MeshEditor_I {
     }
     void Remove( SMDSAbs_ElementType type )
     {
-      SMDS_ElemIteratorPtr eIt = GetMeshDS()->elementsIterator( type );
+      Remove( GetMeshDS()->elementsIterator( type ));
+    }
+    void Remove( SMDS_ElemIteratorPtr eIt )
+    {
       while ( eIt->more() )
         GetMeshDS()->RemoveFreeElement( eIt->next(), /*sm=*/0, /*fromGroups=*/false );
     }
@@ -176,7 +178,7 @@ namespace MeshEditor_I {
 
   //=============================================================================
   /*!
-   * \brief Deleter of theNodeSearcher at any compute event occurred
+   * \brief Deleter of theNodeSearcher and theElementSearcher at any compute event occurred
    */
   //=============================================================================
 
@@ -379,7 +381,7 @@ namespace MeshEditor_I {
    */
   //================================================================================
 
-  string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
+  string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type = SMESH::ALL )
   {
     string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
     if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
@@ -522,16 +524,18 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
   SMESH_TRY;
   const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
 
-  if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
-
+  if ( myIsPreviewMode || hasBadElems )
+  {
     list<int> aNodesConnectivity;
     typedef map<int, int> TNodesMap;
     TNodesMap nodesMap;
 
     SMESHDS_Mesh* aMeshDS;
-    std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
+    std::unique_ptr< SMESH_MeshPartDS > aMeshPartDS;
     if ( hasBadElems ) {
-      aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
+      const list<const SMDS_MeshElement*>& badElems =
+        static_cast<SMESH_BadInputElements*>( getEditor().GetError().get() )->myBadElements;
+      aMeshPartDS.reset( new SMESH_MeshPartDS( badElems ));
       aMeshDS = aMeshPartDS.get();
     }
     else {
@@ -615,9 +619,9 @@ SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
   SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
 
   const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
-  myLastCreatedNodes->length( aSeq.Length() );
-  for (int i = 1; i <= aSeq.Length(); i++)
-    myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
+  myLastCreatedNodes->length( aSeq.size() );
+  for ( size_t i = 0; i < aSeq.size(); i++)
+    myLastCreatedNodes[i] = aSeq[i]->GetID();
 
   return myLastCreatedNodes._retn();
   SMESH_CATCH( SMESH::throwCorbaException );
@@ -638,9 +642,9 @@ SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
   SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
 
   const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
-  myLastCreatedElems->length( aSeq.Length() );
-  for ( int i = 1; i <= aSeq.Length(); i++ )
-    myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
+  myLastCreatedElems->length( aSeq.size() );
+  for ( size_t i = 0; i < aSeq.size(); i++ )
+    myLastCreatedElems[i] = aSeq[i]->GetID();
 
   return myLastCreatedElems._retn();
   SMESH_CATCH( SMESH::throwCorbaException );
@@ -677,7 +681,7 @@ SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
     errOut->code       = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
     errOut->comment    = errIn->myComment.c_str();
     errOut->subShapeID = -1;
-    errOut->hasBadMesh = !errIn->myBadElements.empty();
+    errOut->hasBadMesh = errIn->HasBadElems();
   }
   else
   {
@@ -2593,7 +2597,7 @@ namespace MeshEditor_I
  *  \param [in] nbOfSteps - number of elements to generate from one element
  *  \param [in] toMakeGroups - if true, new elements will be included into new groups
  *              corresponding to groups the input elements included in.
- *  \return ListOfGroups - new groups craeted if \a toMakeGroups is true
+ *  \return ListOfGroups - new groups created if \a toMakeGroups is true
  */
 //=======================================================================
 
@@ -4014,6 +4018,99 @@ SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr  theObject,
   return mesh._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Make an offset mesh from a source 2D mesh
+ *  \param [inout] theObject - source mesh. New elements are added to this mesh
+ *         if \a theMeshName is empty.
+ *  \param [in] theValue - offset value
+ *  \param [in] theCopyGroups - to generate groups
+ *  \param [in] theMeshName - optional name of a new mesh
+ *  \param [out] theGroups - new groups
+ *  \return SMESH::SMESH_Mesh_ptr - the modified mesh
+ */
+//================================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::Offset( SMESH::SMESH_IDSource_ptr theObject,
+                                                  CORBA::Double             theValue,
+                                                  CORBA::Boolean            theCopyGroups,
+                                                  CORBA::Boolean            theCopyElements,
+                                                  const char*               theMeshName,
+                                                  SMESH::ListOfGroups_out   theGroups)
+  throw (SALOME::SALOME_Exception)
+{
+  SMESH_TRY;
+  initData();
+
+  SMESHDS_Mesh* aMeshDS = getMeshDS();
+
+  SMESH::SMESH_Mesh_var         mesh_var;
+  ::SMESH_MeshEditor::PGroupIDs groupIds;
+
+  TPythonDump pyDump;
+
+  TIDSortedElemSet elements, copyElements;
+  if ( idSourceToSet( theObject, aMeshDS, elements, SMDSAbs_Face,
+                      /*emptyIfIsMesh=*/ !myIsPreviewMode ))
+  {
+    // mesh to modify
+    SMESH_Mesh* tgtMesh = 0;
+    if ( myIsPreviewMode )
+    {
+      TPreviewMesh * tmpMesh = getPreviewMesh();
+      tgtMesh = tmpMesh;
+      tmpMesh->Copy( elements, copyElements );
+      elements.swap( copyElements );
+      theCopyGroups = false;
+      theCopyElements = false;
+    }
+    else
+    {
+      mesh_var =
+        *theMeshName ? makeMesh( theMeshName ) : SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
+      SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
+      tgtMesh = & mesh_i->GetImpl();
+    }
+    groupIds = getEditor().Offset( elements, theValue, tgtMesh,
+                                   theCopyGroups, theCopyElements, !myIsPreviewMode );
+
+    tgtMesh->GetMeshDS()->Modified();
+  }
+
+  if ( myIsPreviewMode )
+  {
+    //getPreviewMesh()->Remove( SMESHUtils::elemSetIterator( copyElements ));
+  }
+  else
+  {
+    theGroups = theCopyGroups ? getGroups( groupIds.get() ) : new SMESH::ListOfGroups;
+
+    if ( *theMeshName && mesh_var->NbFaces() == 0 )
+    {
+      // new mesh empty, remove it
+      SALOMEDS::Study_var          study = SMESH_Gen_i::getStudyServant();
+      SALOMEDS::StudyBuilder_var builder = study->NewBuilder();
+      SALOMEDS::SObject_wrap      meshSO = SMESH_Gen_i::ObjectToSObject( mesh_var );
+      builder->RemoveObjectWithChildren( meshSO );
+      THROW_SALOME_CORBA_EXCEPTION("Offset failed", SALOME::INTERNAL_ERROR);
+    }
+
+    // result of Offset() is a tuple (mesh, groups)
+    if ( mesh_var->_is_nil() ) pyDump << myMesh_i->_this() << ", ";
+    else                       pyDump << mesh_var          << ", ";
+    pyDump << theGroups << " = " << this << ".Offset( "
+           << theObject << ", "
+           << theValue << ", "
+           << theCopyGroups << ", "
+           << theCopyElements << ", "
+           << "'" << theMeshName<< "')";
+  }
+
+  return mesh_var._retn();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return SMESH::SMESH_Mesh::_nil();
+}
 
 //=======================================================================
 //function : findCoincidentNodes
@@ -4097,7 +4194,7 @@ FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr      theObject,
 
 //================================================================================
 /*!
- * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
+ * \brief Finds nodes coincident with Tolerance within Object excluding nodes within
  *        ExceptSubMeshOrGroups
  */
 //================================================================================
@@ -4555,6 +4652,68 @@ SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementID
   return 0;
 }
 
+//=======================================================================
+//function : ProjectPoint
+//purpose  : Project a point to a mesh object.
+//           Return ID of an element of given type where the given point is projected
+//           and coordinates of the projection point.
+//           In the case if nothing found, return -1 and []
+//=======================================================================
+
+CORBA::Long SMESH_MeshEditor_i::ProjectPoint(CORBA::Double             x,
+                                             CORBA::Double             y,
+                                             CORBA::Double             z,
+                                             SMESH::SMESH_IDSource_ptr meshObject,
+                                             SMESH::ElementType        type,
+                                             SMESH::double_array_out   projecton)
+  throw (SALOME::SALOME_Exception)
+{
+  if ( CORBA::is_nil( meshObject ))
+    THROW_SALOME_CORBA_EXCEPTION("NULL meshObject", SALOME::BAD_PARAM);
+
+  SMESH_TRY;
+
+  SMESH::SMESH_Mesh_var mesh = meshObject->GetMesh();
+  SMESH_Mesh_i*       mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
+  if ( mesh_i != myMesh_i )
+  {
+    SMESH::SMESH_MeshEditor_var editor=
+      myIsPreviewMode ? mesh_i->GetMeshEditPreviewer() : mesh_i->GetMeshEditor();
+    return editor->ProjectPoint( x,y,z, meshObject, type, projecton );
+  }
+
+
+  theSearchersDeleter.Set( myMesh, getPartIOR( meshObject ));
+  if ( !theElementSearcher )
+  {
+    // create a searcher from meshObject
+
+    SMDS_ElemIteratorPtr elemIt;
+    if ( ! SMESH::DownCast<SMESH_Mesh_i*>( meshObject ))
+      elemIt = myMesh_i->GetElements( meshObject, type );
+
+    theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemIt );
+  }
+
+  const SMDS_MeshElement* elem = 0;
+  gp_XYZ pProj = theElementSearcher->Project( gp_Pnt( x,y,z ),
+                                              SMDSAbs_ElementType( type ),
+                                              &elem );
+
+  projecton = new SMESH::double_array();
+  if ( elem && !elem->IsNull() )
+  {
+    projecton->length( 3 );
+    projecton[0] = pProj.X();
+    projecton[1] = pProj.Y();
+    projecton[2] = pProj.Z();
+    return elem->GetID();
+  }
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return -1;
+}
+
 //=======================================================================
 //function : GetPointState
 //purpose  : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
@@ -4654,7 +4813,9 @@ SMESH::ListOfFreeBorders* SMESH_MeshEditor_i::FindFreeBorders(CORBA::Boolean clo
 //purpose  : Fill with 2D elements a hole defined by a FreeBorder.
 //=======================================================================
 
-void SMESH_MeshEditor_i::FillHole(const SMESH::FreeBorder& theHole)
+SMESH::SMESH_Group_ptr 
+SMESH_MeshEditor_i::FillHole(const SMESH::FreeBorder& theHole,
+                             const char*              theGroupName)
   throw (SALOME::SALOME_Exception)
 {
   initData();
@@ -4677,6 +4838,7 @@ void SMESH_MeshEditor_i::FillHole(const SMESH::FreeBorder& theHole)
 
   SMESH_TRY;
 
+  // prepare a preview mesh
   MeshEditor_I::TPreviewMesh* previewMesh = 0;
   SMDS_Mesh* meshDS = getMeshDS();
   if ( myIsPreviewMode )
@@ -4699,27 +4861,66 @@ void SMESH_MeshEditor_i::FillHole(const SMESH::FreeBorder& theHole)
     meshDS = previewMesh->GetMeshDS();
   }
 
+  // fill the hole
   std::vector<const SMDS_MeshElement*> newFaces;
   SMESH_MeshAlgos::FillHole( bordNodes, *meshDS, newFaces );
 
   if ( myIsPreviewMode )
   {
+    // show new faces
     previewMesh->Clear();
     for ( size_t i = 0; i < newFaces.size(); ++i )
       previewMesh->Copy( newFaces[i] );
   }
   else
   {
+    // return new faces via a group
+    SMESH::SMESH_Group_var group;
+    if ( theGroupName && theGroupName[0] && !newFaces.empty() )
+    {
+      SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
+      for ( CORBA::ULong i = 0; i < groups->length(); ++i )
+      {
+        SMESH::SMESH_GroupBase_var g = groups[ i ];
+        if ( g->GetType() != SMESH::FACE ) continue;
+        SMESH::SMESH_Group_var standalone = SMESH::SMESH_Group::_narrow( g );
+        if ( standalone->_is_nil() ) continue;
+        CORBA::String_var name = g->GetName();
+        if ( strcmp( theGroupName, name.in() ) == 0 )
+        {
+          group = standalone;
+          break;
+        }
+      }
+      if ( group->_is_nil() )
+        group = myMesh_i->CreateGroup( SMESH::FACE, theGroupName );
+
+      if ( !group->_is_nil() )
+      {
+        SMESH_GroupBase_i * grpI = SMESH::DownCast< SMESH_GroupBase_i* >( group );
+        SMESHDS_Group*     grpDS = static_cast< SMESHDS_Group* >( grpI->GetGroupDS() );
+        for ( size_t i = 0; i < newFaces.size(); ++i )
+          grpDS->Add( newFaces[ i ]);
+      }
+    }
+
+    // fill LastCreated
     getEditor().ClearLastCreated();
     SMESH_SequenceOfElemPtr& aSeq =
       const_cast<SMESH_SequenceOfElemPtr&>( getEditor().GetLastCreatedElems() );
-    for ( size_t i = 0; i < newFaces.size(); ++i )
-      aSeq.Append( newFaces[i] );
+    aSeq.swap( newFaces );
+
+    TPythonDump pyDump;
+    if ( group->_is_nil() ) pyDump << "_group = ";
+    else                    pyDump << group << " = ";
+    pyDump << this << ".FillHole( SMESH.FreeBorder(" << theHole.nodeIDs << " ))";
 
-    TPythonDump() << this << ".FillHole( SMESH.FreeBorder(" << theHole.nodeIDs << " ))";
+    return group._retn();
   }
 
   SMESH_CATCH( SMESH::throwCorbaException );
+
+  return SMESH::SMESH_Group::_nil();
 }
 
 //=======================================================================
@@ -5395,8 +5596,7 @@ SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
 {
   SMESH_Gen_i*              gen = SMESH_Gen_i::GetSMESHGen();
   SMESH::SMESH_Mesh_var    mesh = gen->CreateEmptyMesh();
-  SALOMEDS::Study_var     study = gen->GetCurrentStudy();
-  SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
+  SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( mesh );
   gen->SetName( meshSO, theMeshName, "Mesh" );
   gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
 
@@ -5529,7 +5729,7 @@ bool SMESH_MeshEditor_i::idSourceToSet(SMESH::SMESH_IDSource_ptr  theIDSource,
  * \param theElements - container of elements to duplicate.
  * \param theGroupName - a name of group to contain the generated elements.
  *                    If a group with such a name already exists, the new elements
- *                    are added to the existng group, else a new group is created.
+ *                    are added to the existing group, else a new group is created.
  *                    If \a theGroupName is empty, new elements are not added 
  *                    in any group.
  * \return a group where the new elements are added. NULL if theGroupName == "".
@@ -5554,11 +5754,11 @@ SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
   {
     getEditor().DoubleElements( elems );
 
-    if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
+    if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().empty() )
     {
       // group type
       SMESH::ElementType type =
-        SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
+        SMESH::ElementType( getEditor().GetLastCreatedElems()[0]->GetType() );
       // find existing group
       SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
       for ( size_t i = 0; i < groups->length(); ++i )
@@ -5578,8 +5778,8 @@ SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
       {
         SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
         const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
-        for ( int i = 1; i <= aSeq.Length(); i++ )
-          groupDS->SMDSGroup().Add( aSeq(i) );
+        for ( size_t i = 0; i < aSeq.size(); i++ )
+          groupDS->SMDSGroup().Add( aSeq[i] );
       }
     }
   }
@@ -5691,10 +5891,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr th
   if ( !CORBA::is_nil( theModifiedElems ) )
     aModifiedElems = theModifiedElems->GetListOfID();
   else
-  {
     aModifiedElems = new SMESH::long_array;
-    aModifiedElems->length( 0 );
-  }
 
   TPythonDump pyDump; // suppress dump by the next line
 
@@ -6073,14 +6270,14 @@ SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
     // Create group with newly created elements
     CORBA::String_var elemGroupName = theElems->GetName();
     std::string aNewName = generateGroupName( std::string(elemGroupName.in()) + "_double");
-    if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
+    if ( !getEditor().GetLastCreatedElems().empty() && theElemGroupNeeded )
     {
       SMESH::long_array_var anIds = GetLastCreatedElems();
       SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
       aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
       aNewElemGroup->Add(anIds);
     }
-    if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
+    if ( !getEditor().GetLastCreatedNodes().empty() && theNodeGroupNeeded )
     {
       SMESH::long_array_var anIds = GetLastCreatedNodes();
       aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
@@ -6305,14 +6502,14 @@ SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems
     // Create group with newly created elements
     CORBA::String_var elemGroupName = theElems[0]->GetName();
     std::string aNewName = generateGroupName( std::string(elemGroupName.in()) + "_double");
-    if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
+    if ( !getEditor().GetLastCreatedElems().empty() && theElemGroupNeeded )
     {
       SMESH::long_array_var anIds = GetLastCreatedElems();
       SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
       aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
       aNewElemGroup->Add(anIds);
     }
-    if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
+    if ( !getEditor().GetLastCreatedNodes().empty() && theNodeGroupNeeded )
     {
       SMESH::long_array_var anIds = GetLastCreatedNodes();
       aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
@@ -6407,12 +6604,9 @@ SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theEl
 {
   SMESH_TRY;
   SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
-  bool isEdgeGroup = false;
-  bool isFaceGroup = false;
-  bool isVolumeGroup = false;
-  SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
-  SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
-  SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
+  SMESH::SMESH_Group_var aNewEdgeGroup   = SMESH::SMESH_Group::_nil();
+  SMESH::SMESH_Group_var aNewFaceGroup   = SMESH::SMESH_Group::_nil();
+  SMESH::SMESH_Group_var aNewVolumeGroup = SMESH::SMESH_Group::_nil();
 
   initData();
 
@@ -6420,75 +6614,75 @@ SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theEl
 
   SMESHDS_Mesh* aMeshDS = getMeshDS();
   TIDSortedElemSet anElems, aNodes;
-  listOfGroupToSet(theElems, aMeshDS, anElems, false);
+  bool isNodeGrp = theElems.length() ? theElems[0]->GetType() == SMESH::NODE : false;
+  listOfGroupToSet(theElems, aMeshDS, anElems, isNodeGrp);
   listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
 
   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
   TIDSortedElemSet anAffected;
   bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
 
-
   declareMeshModified( /*isReComputeSafe=*/ !aResult );
 
   TPythonDump pyDump;
-  if (aResult)
+  if ( aResult && anAffected.size() > 0 )
   {
-    int lg = anAffected.size();
     SMESH::long_array_var volumeIds = new SMESH::long_array;
-    volumeIds->length(lg);
-    SMESH::long_array_var faceIds = new SMESH::long_array;
-    faceIds->length(lg);
-    SMESH::long_array_var edgeIds = new SMESH::long_array;
-    edgeIds->length(lg);
+    SMESH::long_array_var   faceIds = new SMESH::long_array;
+    SMESH::long_array_var   edgeIds = new SMESH::long_array;
+    volumeIds->length( anAffected.size() );
+    faceIds  ->length( anAffected.size() );
+    edgeIds  ->length( anAffected.size() );
+
     int ivol = 0;
     int iface = 0;
     int iedge = 0;
-
     TIDSortedElemSet::const_iterator eIt = anAffected.begin();
     for (; eIt != anAffected.end(); ++eIt)
     {
       const SMDS_MeshElement* anElem = *eIt;
-      if (!anElem)
-        continue;
       int elemId = anElem->GetID();
-      if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
-        volumeIds[ivol++] = elemId;
-      else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
-        faceIds[iface++] = elemId;
-      else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
-        edgeIds[iedge++] = elemId;
+      switch ( anElem->GetType() ) {
+      case SMDSAbs_Volume: volumeIds[ivol++] = elemId; break;
+      case SMDSAbs_Face:    faceIds[iface++] = elemId; break;
+      case SMDSAbs_Edge:    edgeIds[iedge++] = elemId; break;
+      default:;
+      }
     }
     volumeIds->length(ivol);
     faceIds->length(iface);
     edgeIds->length(iedge);
 
-    aNewVolumeGroup->Add(volumeIds);
-    aNewFaceGroup->Add(faceIds);
-    aNewEdgeGroup->Add(edgeIds);
-    isVolumeGroup = (aNewVolumeGroup->Size() > 0);
-    isFaceGroup = (aNewFaceGroup->Size() > 0);
-    isEdgeGroup = (aNewEdgeGroup->Size() > 0);
+    int nbGroups = 0;
+    if ( ivol > 0 )
+    {
+      aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME,
+                                              generateGroupName("affectedVolumes").c_str());
+      aNewVolumeGroup->Add(volumeIds);
+      aListOfGroups->length( nbGroups+1 );
+      aListOfGroups[ nbGroups++ ] = aNewVolumeGroup._retn();
+    }
+    if ( iface > 0 )
+    {
+      aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE,
+                                            generateGroupName("affectedFaces").c_str());
+      aNewFaceGroup->Add(faceIds);
+      aListOfGroups->length( nbGroups+1 );
+      aListOfGroups[ nbGroups++ ] = aNewFaceGroup._retn();
+    }
+    if ( iedge > 0 )
+    {
+      aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE,
+                                            generateGroupName("affectedEdges").c_str());
+      aNewEdgeGroup->Add(edgeIds);
+      aListOfGroups->length( nbGroups+1 );
+      aListOfGroups[ nbGroups++ ] = aNewEdgeGroup._retn();
+    }
   }
 
-  int nbGroups = 0;
-  if (isEdgeGroup)   nbGroups++;
-  if (isFaceGroup)   nbGroups++;
-  if (isVolumeGroup) nbGroups++;
-  aListOfGroups->length(nbGroups);
-
-  int i = 0;
-  if (isEdgeGroup)   aListOfGroups[i++] = aNewEdgeGroup._retn();
-  if (isFaceGroup)   aListOfGroups[i++] = aNewFaceGroup._retn();
-  if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
-
   // Update Python script
 
-  pyDump << "[ ";
-  if (isEdgeGroup)   pyDump << aNewEdgeGroup << ", ";
-  if (isFaceGroup)   pyDump << aNewFaceGroup << ", ";
-  if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
-  pyDump << "] = ";
-  pyDump << this << ".AffectedElemGroupsInRegion( "
+  pyDump << aListOfGroups << " = " << this << ".AffectedElemGroupsInRegion( "
          << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
 
   return aListOfGroups._retn();
@@ -6500,7 +6694,7 @@ SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theEl
 //================================================================================
 /*!
   \brief Generated skin mesh (containing 2D cells) from 3D mesh
-   The created 2D mesh elements based on nodes of free faces of boundary volumes
+  The created 2D mesh elements based on nodes of free faces of boundary volumes
   \return TRUE if operation has been completed successfully, FALSE otherwise
 */
 //================================================================================
@@ -6889,7 +7083,7 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
   // group of boundary elements
   SMESH_Group* smesh_group = 0;
   SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
-  if ( strlen(groupName) )
+  if ( strlen( groupName ))
   {
     SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
     group_var = mesh_i->CreateGroup( groupType, groupName );
@@ -7030,15 +7224,15 @@ void SMESH_MeshEditor_i::MakePolyLine(SMESH::ListOfPolySegments& theSegments,
     segOut.myNode2[0] = meshDS->FindNode( segIn.node1ID2 );
     segOut.myNode1[1] = meshDS->FindNode( segIn.node2ID1 );
     segOut.myNode2[1] = meshDS->FindNode( segIn.node2ID2 );
+    segOut.myXYZ[0].SetCoord( segIn.xyz1.x,
+                              segIn.xyz1.y,
+                              segIn.xyz1.z);
+    segOut.myXYZ[1].SetCoord( segIn.xyz2.x,
+                              segIn.xyz2.y,
+                              segIn.xyz2.z);
     segOut.myVector.SetCoord( segIn.vector.PS.x,
                               segIn.vector.PS.y,
                               segIn.vector.PS.z );
-    if ( !segOut.myNode1[0] )
-      THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID: ") << segIn.node1ID1,
-                                    SALOME::BAD_PARAM );
-    if ( !segOut.myNode1[1] )
-      THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID: ") << segIn.node2ID1,
-                                    SALOME::BAD_PARAM );
   }
 
   // get a static ElementSearcher