Salome HOME
IMP 0020089: Take into account 0D elements (MED_POINT1)
[modules/smesh.git] / src / SMESH_I / SMESH_MeshEditor_i.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
23 //  File   : SMESH_MeshEditor_i.cxx
24 //  Author : Nicolas REJNERI
25 //  Module : SMESH
26
27 #include "SMESH_MeshEditor_i.hxx"
28
29 #include "SMDS_Mesh0DElement.hxx"
30 #include "SMDS_MeshEdge.hxx"
31 #include "SMDS_MeshFace.hxx"
32 #include "SMDS_MeshVolume.hxx"
33 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
34 #include "SMESH_MeshEditor.hxx"
35 #include "SMESH_subMeshEventListener.hxx"
36 #include "SMESH_Gen_i.hxx"
37 #include "SMESH_Filter_i.hxx"
38 #include "SMESH_subMesh_i.hxx"
39 #include "SMESH_Group_i.hxx"
40 #include "SMESH_PythonDump.hxx"
41
42 #include "utilities.h"
43 #include "Utils_ExceptHandlers.hxx"
44 #include "Utils_CorbaException.hxx"
45
46 #include <BRepAdaptor_Surface.hxx>
47 #include <BRep_Tool.hxx>
48 #include <TopExp_Explorer.hxx>
49 #include <TopoDS.hxx>
50 #include <TopoDS_Edge.hxx>
51 #include <TopoDS_Face.hxx>
52 #include <gp_Ax1.hxx>
53 #include <gp_Ax2.hxx>
54 #include <gp_Vec.hxx>
55
56 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
57 #define NO_CAS_CATCH
58 #endif
59
60 #include <Standard_Failure.hxx>
61
62 #ifdef NO_CAS_CATCH
63 #include <Standard_ErrorHandler.hxx>
64 #endif
65
66 #include <sstream>
67
68 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
69
70 using namespace std;
71 using SMESH::TPythonDump;
72
73 namespace {
74
75   //=============================================================================
76   /*!
77    * \brief Mesh to apply modifications for preview purposes
78    */
79   //=============================================================================
80
81   struct TPreviewMesh: public SMESH_Mesh
82   {
83     SMDSAbs_ElementType myPreviewType; // type to show
84     //!< Constructor
85     TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
86       _isShapeToMesh = (_id =_studyId =_idDoc = 0);
87       _myMeshDS  = new SMESHDS_Mesh( _id, true );
88       myPreviewType = previewElements;
89     }
90     //!< Destructor
91     virtual ~TPreviewMesh() { delete _myMeshDS; }
92     //!< Copy a set of elements
93     void Copy(const TIDSortedElemSet & theElements,
94               TIDSortedElemSet&        theCopyElements,
95               SMDSAbs_ElementType      theSelectType = SMDSAbs_All,
96               SMDSAbs_ElementType      theAvoidType = SMDSAbs_All)
97     {
98       // loop on theIDsOfElements
99       TIDSortedElemSet::const_iterator eIt = theElements.begin();
100       for ( ; eIt != theElements.end(); ++eIt )
101       {
102         const SMDS_MeshElement* anElem = *eIt;
103         if ( !anElem ) continue;
104         SMDSAbs_ElementType type = anElem->GetType();
105         if ( type == theAvoidType ||
106              ( theSelectType != SMDSAbs_All && type != theSelectType ))
107           continue;
108
109         if ( const SMDS_MeshElement* anElemCopy = Copy( anElem ))
110           theCopyElements.insert( theCopyElements.end(), anElemCopy );
111       }
112     }
113     //!< Copy an element
114     SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
115     {
116       // copy element nodes
117       int anElemNbNodes = anElem->NbNodes();
118       vector< int > anElemNodesID( anElemNbNodes ) ;
119       SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
120       for ( int i = 0; itElemNodes->more(); i++)
121       {
122         const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
123         Copy( anElemNode );
124         anElemNodesID[i] = anElemNode->GetID();
125       }
126
127       // creates a corresponding element on copied nodes
128       SMDS_MeshElement* anElemCopy = 0;
129       if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
130       {
131         const SMDS_PolyhedralVolumeOfNodes* ph =
132           dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem);
133         if ( ph )
134           anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
135             (anElemNodesID, ph->GetQuanities(),anElem->GetID());
136       }
137       else {
138         anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
139                                                           anElem->GetType(),
140                                                           anElem->IsPoly() );
141       }
142       return anElemCopy;
143     }
144     //!< Copy a node
145     SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
146     {
147       return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(), 
148                                       anElemNode->GetID());
149     }
150   };// struct TPreviewMesh
151
152   static SMESH_NodeSearcher * myNodeSearcher = 0;
153
154   //=============================================================================
155   /*!
156    * \brief Deleter of myNodeSearcher at any compute event occured
157    */
158   //=============================================================================
159
160   struct TNodeSearcherDeleter : public SMESH_subMeshEventListener
161   {
162     SMESH_Mesh* myMesh;
163     //!< Constructor
164     TNodeSearcherDeleter(): SMESH_subMeshEventListener( false ), // won't be deleted by submesh
165     myMesh(0) {}
166     //!< Delete myNodeSearcher
167     static void Delete()
168     {
169       if ( myNodeSearcher ) { delete myNodeSearcher; myNodeSearcher = 0; }
170     }
171     typedef map < int, SMESH_subMesh * > TDependsOnMap;
172     //!< The meshod called by submesh: do my main job
173     void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
174                       SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
175     {
176       if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
177         Delete();
178         Unset( sm->GetFather() );
179       }
180     }
181     //!< set self on all submeshes and delete myNodeSearcher if other mesh is set
182     void Set(SMESH_Mesh* mesh)
183     {
184       if ( myMesh && myMesh != mesh ) {
185         Delete();
186         Unset( myMesh );
187       }
188       myMesh = mesh;
189       if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
190         const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
191         TDependsOnMap::const_iterator sm;
192         for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
193           sm->second->SetEventListener( this, 0, sm->second );
194       }
195     }
196     //!<  delete self from all submeshes
197     void Unset(SMESH_Mesh* mesh)
198     {
199       if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
200         const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
201         TDependsOnMap::const_iterator sm;
202         for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
203           sm->second->DeleteEventListener( this );
204       }
205       myMesh = 0;
206     }
207   };
208
209   TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
210   {
211     TCollection_AsciiString typeStr;
212     switch ( theMirrorType ) {
213     case  SMESH::SMESH_MeshEditor::POINT:
214       typeStr = "SMESH.SMESH_MeshEditor.POINT";
215       break;
216     case  SMESH::SMESH_MeshEditor::AXIS:
217       typeStr = "SMESH.SMESH_MeshEditor.AXIS";
218       break;
219     default:
220       typeStr = "SMESH.SMESH_MeshEditor.PLANE";
221     }
222     return typeStr;
223   }
224 }
225
226 //=============================================================================
227 /*!
228  *
229  */
230 //=============================================================================
231
232 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview)
233 {
234   myMesh_i = theMesh;
235   myMesh = & theMesh->GetImpl();
236   myPreviewMode = isPreview;
237 }
238
239 //================================================================================
240 /*!
241  * \brief Destructor
242  */
243 //================================================================================
244
245 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
246 {
247 }
248
249 //================================================================================
250 /*!
251  * \brief Clear members
252  */
253 //================================================================================
254
255 void SMESH_MeshEditor_i::initData()
256 {
257   if ( myPreviewMode ) {
258     myPreviewData = new SMESH::MeshPreviewStruct();
259   }
260   else {
261     myLastCreatedElems = new SMESH::long_array();
262     myLastCreatedNodes = new SMESH::long_array();
263     TNodeSearcherDeleter::Delete();
264   }
265 }
266
267 //=============================================================================
268 /*!
269  *
270  */
271 //=============================================================================
272
273 CORBA::Boolean
274   SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
275 {
276   initData();
277
278   ::SMESH_MeshEditor anEditor( myMesh );
279   list< int > IdList;
280
281   for (int i = 0; i < IDsOfElements.length(); i++)
282     IdList.push_back( IDsOfElements[i] );
283
284   // Update Python script
285   TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
286 #ifdef _DEBUG_
287   TPythonDump() << "print 'RemoveElements: ', isDone";
288 #endif
289   // Remove Elements
290   return anEditor.Remove( IdList, false );
291 }
292
293 //=============================================================================
294 /*!
295  *
296  */
297 //=============================================================================
298
299 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
300 {
301   initData();
302
303   ::SMESH_MeshEditor anEditor( myMesh );
304   list< int > IdList;
305   for (int i = 0; i < IDsOfNodes.length(); i++)
306     IdList.push_back( IDsOfNodes[i] );
307
308   // Update Python script
309   TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
310 #ifdef _DEBUG_
311   TPythonDump() << "print 'RemoveNodes: ', isDone";
312 #endif
313
314   return anEditor.Remove( IdList, true );
315 }
316
317 //=============================================================================
318 /*!
319  *
320  */
321 //=============================================================================
322
323 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
324                                         CORBA::Double y, CORBA::Double z)
325 {
326   initData();
327
328   const SMDS_MeshNode* N = GetMeshDS()->AddNode(x, y, z);
329
330   // Update Python script
331   TPythonDump() << "nodeID = " << this << ".AddNode( "
332                 << x << ", " << y << ", " << z << " )";
333
334   return N->GetID();
335 }
336
337 //=============================================================================
338 /*!
339  *
340  */
341 //=============================================================================
342 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
343 {
344   initData();
345
346   const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode);
347   SMDS_MeshElement* elem = GetMeshDS()->Add0DElement(aNode);
348
349   // Update Python script
350   TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
351
352   if (elem)
353     return elem->GetID();
354
355   return 0;
356 }
357
358 //=============================================================================
359 /*!
360  *
361  */
362 //=============================================================================
363
364 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
365 {
366   initData();
367
368   int NbNodes = IDsOfNodes.length();
369   SMDS_MeshElement* elem = 0;
370   if (NbNodes == 2)
371   {
372     CORBA::Long index1 = IDsOfNodes[0];
373     CORBA::Long index2 = IDsOfNodes[1];
374     elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
375
376     // Update Python script
377     TPythonDump() << "edge = " << this << ".AddEdge([ "
378                   << index1 << ", " << index2 <<" ])";
379   }
380   if (NbNodes == 3) {
381     CORBA::Long n1 = IDsOfNodes[0];
382     CORBA::Long n2 = IDsOfNodes[1];
383     CORBA::Long n12 = IDsOfNodes[2];
384     elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
385                                 GetMeshDS()->FindNode(n2),
386                                 GetMeshDS()->FindNode(n12));
387     // Update Python script
388     TPythonDump() << "edgeID = " << this << ".AddEdge([ "
389                   <<n1<<", "<<n2<<", "<<n12<<" ])";
390   }
391
392   if(elem)
393     return elem->GetID();
394
395   return 0;
396 }
397
398 //=============================================================================
399 /*!
400  *  AddFace
401  */
402 //=============================================================================
403
404 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
405 {
406   initData();
407
408   int NbNodes = IDsOfNodes.length();
409   if (NbNodes < 3)
410   {
411     return 0;
412   }
413
414   std::vector<const SMDS_MeshNode*> nodes (NbNodes);
415   for (int i = 0; i < NbNodes; i++)
416     nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
417
418   SMDS_MeshElement* elem = 0;
419   if (NbNodes == 3) {
420     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
421   }
422   else if (NbNodes == 4) {
423     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
424   }
425   else if (NbNodes == 6) {
426     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
427                                 nodes[4], nodes[5]);
428   }
429   else if (NbNodes == 8) {
430     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
431                                 nodes[4], nodes[5], nodes[6], nodes[7]);
432   }
433
434   // Update Python script
435   TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
436
437   if(elem)
438     return elem->GetID();
439
440   return 0;
441 }
442
443 //=============================================================================
444 /*!
445  *  AddPolygonalFace
446  */
447 //=============================================================================
448 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace
449                                    (const SMESH::long_array & IDsOfNodes)
450 {
451   initData();
452
453   int NbNodes = IDsOfNodes.length();
454   std::vector<const SMDS_MeshNode*> nodes (NbNodes);
455   for (int i = 0; i < NbNodes; i++)
456     nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
457
458   const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes);
459   
460   // Update Python script
461   TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
462 #ifdef _DEBUG_
463   TPythonDump() << "print 'AddPolygonalFace: ', faceID";
464 #endif
465
466   if(elem)
467     return elem->GetID();
468
469   return 0;
470 }
471
472 //=============================================================================
473 /*!
474  *
475  */
476 //=============================================================================
477
478 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
479 {
480   initData();
481
482   int NbNodes = IDsOfNodes.length();
483   vector< const SMDS_MeshNode*> n(NbNodes);
484   for(int i=0;i<NbNodes;i++)
485     n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
486
487   SMDS_MeshElement* elem = 0;
488   switch(NbNodes)
489   {
490   case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
491   case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
492   case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
493   case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
494   case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
495                                         n[6],n[7],n[8],n[9]);
496     break;
497   case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
498                                         n[7],n[8],n[9],n[10],n[11],n[12]);
499     break;
500   case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
501                                         n[9],n[10],n[11],n[12],n[13],n[14]);
502     break;
503   case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
504                                         n[8],n[9],n[10],n[11],n[12],n[13],n[14],
505                                         n[15],n[16],n[17],n[18],n[19]);
506     break;
507   }
508
509   // Update Python script
510   TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
511 #ifdef _DEBUG_
512   TPythonDump() << "print 'AddVolume: ', volID";
513 #endif
514
515   if(elem)
516     return elem->GetID();
517
518   return 0;
519 }
520
521 //=============================================================================
522 /*!
523  *  AddPolyhedralVolume
524  */
525 //=============================================================================
526 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume
527                                    (const SMESH::long_array & IDsOfNodes,
528                                     const SMESH::long_array & Quantities)
529 {
530   initData();
531
532   int NbNodes = IDsOfNodes.length();
533   std::vector<const SMDS_MeshNode*> n (NbNodes);
534   for (int i = 0; i < NbNodes; i++)
535     n[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
536
537   int NbFaces = Quantities.length();
538   std::vector<int> q (NbFaces);
539   for (int j = 0; j < NbFaces; j++)
540     q[j] = Quantities[j];
541
542   const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(n, q);
543
544   // Update Python script
545   TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
546                 << IDsOfNodes << ", " << Quantities << " )";
547 #ifdef _DEBUG_
548   TPythonDump() << "print 'AddPolyhedralVolume: ', volID";
549 #endif
550
551   if(elem)
552     return elem->GetID();
553
554   return 0;
555 }
556
557 //=============================================================================
558 /*!
559  *  AddPolyhedralVolumeByFaces
560  */
561 //=============================================================================
562 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces
563                                    (const SMESH::long_array & IdsOfFaces)
564 {
565   initData();
566
567   int NbFaces = IdsOfFaces.length();
568   std::vector<const SMDS_MeshNode*> poly_nodes;
569   std::vector<int> quantities (NbFaces);
570
571   for (int i = 0; i < NbFaces; i++) {
572     const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]);
573     quantities[i] = aFace->NbNodes();
574
575     SMDS_ElemIteratorPtr It = aFace->nodesIterator();
576     while (It->more()) {
577       poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
578     }
579   }
580
581   const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
582
583   // Update Python script
584   TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
585                 << IdsOfFaces << " )";
586 #ifdef _DEBUG_
587   TPythonDump() << "print 'AddPolyhedralVolume: ', volID";
588 #endif
589
590   if(elem)
591     return elem->GetID();
592
593   return 0;
594 }
595
596 //=============================================================================
597 /*!
598  * \brief Bind a node to a vertex
599  * \param NodeID - node ID
600  * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
601  * \retval boolean - false if NodeID or VertexID is invalid
602  */
603 //=============================================================================
604
605 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
606   throw (SALOME::SALOME_Exception)
607 {
608   Unexpect aCatch(SALOME_SalomeException);
609
610   SMESHDS_Mesh * mesh = GetMeshDS();
611   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
612   if ( !node )
613     THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
614
615   if ( mesh->MaxShapeIndex() < VertexID )
616     THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
617
618   TopoDS_Shape shape = mesh->IndexToShape( VertexID );
619   if ( shape.ShapeType() != TopAbs_VERTEX )
620     THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
621
622   mesh->SetNodeOnVertex( node, VertexID );
623 }
624
625 //=============================================================================
626 /*!
627  * \brief Store node position on an edge
628  * \param NodeID - node ID
629  * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
630  * \param paramOnEdge - parameter on edge where the node is located
631  * \retval boolean - false if any parameter is invalid
632  */
633 //=============================================================================
634
635 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
636                                        CORBA::Double paramOnEdge)
637   throw (SALOME::SALOME_Exception)
638 {
639   Unexpect aCatch(SALOME_SalomeException);
640
641   SMESHDS_Mesh * mesh = GetMeshDS();
642   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
643   if ( !node )
644     THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
645
646   if ( mesh->MaxShapeIndex() < EdgeID )
647     THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
648
649   TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
650   if ( shape.ShapeType() != TopAbs_EDGE )
651     THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
652
653   Standard_Real f,l;
654   BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
655   if ( paramOnEdge < f || paramOnEdge > l )
656     THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
657
658   mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
659 }
660
661 //=============================================================================
662 /*!
663  * \brief Store node position on a face
664  * \param NodeID - node ID
665  * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
666  * \param u - U parameter on face where the node is located
667  * \param v - V parameter on face where the node is located
668  * \retval boolean - false if any parameter is invalid
669  */
670 //=============================================================================
671
672 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
673                                        CORBA::Double u, CORBA::Double v)
674   throw (SALOME::SALOME_Exception)
675 {
676   Unexpect aCatch(SALOME_SalomeException);
677
678   SMESHDS_Mesh * mesh = GetMeshDS();
679   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
680   if ( !node )
681     THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
682
683   if ( mesh->MaxShapeIndex() < FaceID )
684     THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
685
686   TopoDS_Shape shape = mesh->IndexToShape( FaceID );
687   if ( shape.ShapeType() != TopAbs_FACE )
688     THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
689
690   BRepAdaptor_Surface surf( TopoDS::Face( shape ));
691   bool isOut = ( u < surf.FirstUParameter() ||
692                  u > surf.LastUParameter()  ||
693                  v < surf.FirstVParameter() ||
694                  v > surf.LastVParameter() );
695
696   if ( isOut ) {
697 #ifdef _DEBUG_
698     MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
699            << " u( " <<  surf.FirstUParameter() 
700            << "," <<  surf.LastUParameter()  
701            << ") v( " <<  surf.FirstVParameter() 
702            << "," <<  surf.LastVParameter() << ")" );
703 #endif    
704     THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
705   }
706
707   mesh->SetNodeOnFace( node, FaceID, u, v );
708 }
709
710 //=============================================================================
711 /*!
712  * \brief Bind a node to a solid
713  * \param NodeID - node ID
714  * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
715  * \retval boolean - false if NodeID or SolidID is invalid
716  */
717 //=============================================================================
718
719 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
720   throw (SALOME::SALOME_Exception)
721 {
722   Unexpect aCatch(SALOME_SalomeException);
723
724   SMESHDS_Mesh * mesh = GetMeshDS();
725   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
726   if ( !node )
727     THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
728
729   if ( mesh->MaxShapeIndex() < SolidID )
730     THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
731
732   TopoDS_Shape shape = mesh->IndexToShape( SolidID );
733   if ( shape.ShapeType() != TopAbs_SOLID &&
734        shape.ShapeType() != TopAbs_SHELL)
735     THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
736
737   mesh->SetNodeInVolume( node, SolidID );
738 }
739
740 //=============================================================================
741 /*!
742  * \brief Bind an element to a shape
743  * \param ElementID - element ID
744  * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
745  * \retval boolean - false if ElementID or ShapeID is invalid
746  */
747 //=============================================================================
748
749 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
750                                                CORBA::Long ShapeID)
751   throw (SALOME::SALOME_Exception)
752 {
753   Unexpect aCatch(SALOME_SalomeException);
754
755   SMESHDS_Mesh * mesh = GetMeshDS();
756   SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
757   if ( !elem )
758     THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
759
760   if ( mesh->MaxShapeIndex() < ShapeID )
761     THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
762
763   TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
764   if ( shape.ShapeType() != TopAbs_EDGE &&
765        shape.ShapeType() != TopAbs_FACE &&
766        shape.ShapeType() != TopAbs_SOLID &&
767        shape.ShapeType() != TopAbs_SHELL )
768     THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
769
770   mesh->SetMeshElementOnShape( elem, ShapeID );
771 }
772
773
774 //=============================================================================
775 /*!
776  *
777  */
778 //=============================================================================
779
780 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
781                                             CORBA::Double x,
782                                             CORBA::Double y,
783                                             CORBA::Double z)
784 {
785   initData();
786
787   const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
788   if ( !node )
789     return false;
790
791   GetMeshDS()->MoveNode(node, x, y, z);
792
793   // Update Python script
794   TPythonDump() << "isDone = " << this << ".MoveNode( "
795                 << NodeID << ", " << x << ", " << y << ", " << z << " )";
796
797   return true;
798 }
799
800 //=============================================================================
801 /*!
802  *
803  */
804 //=============================================================================
805
806 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
807                                                CORBA::Long NodeID2)
808 {
809   initData();
810
811   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
812   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
813   if ( !n1 || !n2 )
814     return false;
815
816   // Update Python script
817   TPythonDump() << "isDone = " << this << ".InverseDiag( "
818                 << NodeID1 << ", " << NodeID2 << " )";
819
820   ::SMESH_MeshEditor aMeshEditor( myMesh );
821   return aMeshEditor.InverseDiag ( n1, n2 );
822 }
823
824 //=============================================================================
825 /*!
826  *
827  */
828 //=============================================================================
829
830 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
831                                               CORBA::Long NodeID2)
832 {
833   initData();
834
835   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
836   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
837   if ( !n1 || !n2 )
838     return false;
839
840   // Update Python script
841   TPythonDump() << "isDone = " << this << ".DeleteDiag( "
842                 << NodeID1 << ", " << NodeID2 <<  " )";
843
844   ::SMESH_MeshEditor aMeshEditor( myMesh );
845
846   bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
847
848   storeResult(aMeshEditor);
849
850   return stat;
851 }
852
853 //=============================================================================
854 /*!
855  *
856  */
857 //=============================================================================
858
859 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
860 {
861   initData();
862
863   ::SMESH_MeshEditor anEditor( myMesh );
864   for (int i = 0; i < IDsOfElements.length(); i++)
865   {
866     CORBA::Long index = IDsOfElements[i];
867     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
868     if ( elem )
869       anEditor.Reorient( elem );
870   }
871   // Update Python script
872   TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
873
874   return true;
875 }
876
877
878 //=============================================================================
879 /*!
880  *
881  */
882 //=============================================================================
883
884 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
885 {
886   initData();
887
888   SMESH::long_array_var anElementsId = theObject->GetIDs();
889   CORBA::Boolean isDone = Reorient(anElementsId);
890
891   // Clear python line, created by Reorient()
892   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
893   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
894
895   // Update Python script
896   TPythonDump() << "isDone = " << this << ".ReorientObject( " << theObject << " )";
897
898   return isDone;
899 }
900
901 namespace
902 {
903   //================================================================================
904   /*!
905    * \brief function for conversion long_array to TIDSortedElemSet
906     * \param IDs - array of IDs
907     * \param aMesh - mesh
908     * \param aMap - collection to fill
909     * \param aType - element type
910    */
911   //================================================================================
912
913   void arrayToSet(const SMESH::long_array & IDs,
914                   const SMESHDS_Mesh*       aMesh,
915                   TIDSortedElemSet&         aMap,
916                   const SMDSAbs_ElementType aType = SMDSAbs_All )
917   { 
918     for (int i=0; i<IDs.length(); i++) {
919       CORBA::Long ind = IDs[i];
920       const SMDS_MeshElement * elem = aMesh->FindElement(ind);
921       if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
922         aMap.insert( elem );
923     }
924   }
925 }
926
927 //=============================================================================
928 /*!
929  *
930  */
931 //=============================================================================
932 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfElements,
933                                               SMESH::NumericalFunctor_ptr Criterion,
934                                               CORBA::Double               MaxAngle)
935 {
936   initData();
937
938   SMESHDS_Mesh* aMesh = GetMeshDS();
939   TIDSortedElemSet faces;
940   arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
941
942   SMESH::NumericalFunctor_i* aNumericalFunctor =
943     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
944   SMESH::Controls::NumericalFunctorPtr aCrit;
945   if ( !aNumericalFunctor )
946     aCrit.reset( new SMESH::Controls::AspectRatio() );
947   else
948     aCrit = aNumericalFunctor->GetNumericalFunctor();
949
950   // Update Python script
951   TPythonDump() << "isDone = " << this << ".TriToQuad( "
952                 << IDsOfElements << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
953 #ifdef _DEBUG_
954   TPythonDump() << "print 'TriToQuad: ', isDone";
955 #endif
956
957   ::SMESH_MeshEditor anEditor( myMesh );
958
959   bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
960
961   storeResult(anEditor);
962
963   return stat;
964 }
965
966
967 //=============================================================================
968 /*!
969  *
970  */
971 //=============================================================================
972 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr   theObject,
973                                                     SMESH::NumericalFunctor_ptr Criterion,
974                                                     CORBA::Double               MaxAngle)
975 {
976   initData();
977
978   SMESH::long_array_var anElementsId = theObject->GetIDs();
979   CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
980
981   // Clear python line(s), created by TriToQuad()
982   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
983   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
984 #ifdef _DEBUG_
985   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
986 #endif
987
988   SMESH::NumericalFunctor_i* aNumericalFunctor =
989     SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
990
991   // Update Python script
992   TPythonDump() << "isDone = " << this << ".TriToQuadObject("
993                 << theObject << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
994 #ifdef _DEBUG_
995   TPythonDump() << "print 'TriToQuadObject: ', isDone";
996 #endif
997
998   return isDone;
999 }
1000
1001
1002 //=============================================================================
1003 /*!
1004  *
1005  */
1006 //=============================================================================
1007 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array &   IDsOfElements,
1008                                               SMESH::NumericalFunctor_ptr Criterion)
1009 {
1010   initData();
1011
1012   SMESHDS_Mesh* aMesh = GetMeshDS();
1013   TIDSortedElemSet faces;
1014   arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1015
1016   SMESH::NumericalFunctor_i* aNumericalFunctor =
1017     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1018   SMESH::Controls::NumericalFunctorPtr aCrit;
1019   if ( !aNumericalFunctor )
1020     aCrit.reset( new SMESH::Controls::AspectRatio() );
1021   else
1022     aCrit = aNumericalFunctor->GetNumericalFunctor();
1023
1024
1025   // Update Python script
1026   TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1027 #ifdef _DEBUG_
1028   TPythonDump() << "print 'QuadToTri: ', isDone";
1029 #endif
1030
1031   ::SMESH_MeshEditor anEditor( myMesh );
1032   CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
1033
1034   storeResult(anEditor);
1035
1036   return stat;
1037 }
1038
1039
1040 //=============================================================================
1041 /*!
1042  *
1043  */
1044 //=============================================================================
1045 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr   theObject,
1046                                                     SMESH::NumericalFunctor_ptr Criterion)
1047 {
1048   initData();
1049
1050   SMESH::long_array_var anElementsId = theObject->GetIDs();
1051   CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1052
1053   // Clear python line(s), created by QuadToTri()
1054   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1055   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1056 #ifdef _DEBUG_
1057   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1058 #endif
1059
1060   SMESH::NumericalFunctor_i* aNumericalFunctor =
1061     SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1062
1063   // Update Python script
1064   TPythonDump() << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1065 #ifdef _DEBUG_
1066   TPythonDump() << "print 'QuadToTriObject: ', isDone";
1067 #endif
1068
1069   return isDone;
1070 }
1071
1072
1073 //=============================================================================
1074 /*!
1075  *
1076  */
1077 //=============================================================================
1078 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1079                                               CORBA::Boolean            Diag13)
1080 {
1081   initData();
1082
1083   SMESHDS_Mesh* aMesh = GetMeshDS();
1084   TIDSortedElemSet faces;
1085   arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1086
1087   // Update Python script
1088   TPythonDump() << "isDone = " << this << ".SplitQuad( "
1089                 << IDsOfElements << ", " << Diag13 << " )";
1090 #ifdef _DEBUG_
1091   TPythonDump() << "print 'SplitQuad: ', isDone";
1092 #endif
1093
1094   ::SMESH_MeshEditor anEditor( myMesh );
1095   CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
1096
1097   storeResult(anEditor);
1098
1099   return stat;
1100 }
1101
1102
1103 //=============================================================================
1104 /*!
1105  *
1106  */
1107 //=============================================================================
1108 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1109                                                     CORBA::Boolean            Diag13)
1110 {
1111   initData();
1112
1113   SMESH::long_array_var anElementsId = theObject->GetIDs();
1114   CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1115
1116   // Clear python line(s), created by SplitQuad()
1117   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1118   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1119 #ifdef _DEBUG_
1120   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1121 #endif
1122
1123   // Update Python script
1124   TPythonDump() << "isDone = " << this << ".SplitQuadObject( "
1125                 << theObject << ", " << Diag13 << " )";
1126 #ifdef _DEBUG_
1127   TPythonDump() << "print 'SplitQuadObject: ', isDone";
1128 #endif
1129
1130   return isDone;
1131 }
1132
1133
1134 //=============================================================================
1135 /*!
1136  *  BestSplit
1137  */
1138 //=============================================================================
1139 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long                 IDOfQuad,
1140                                            SMESH::NumericalFunctor_ptr Criterion)
1141 {
1142   const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
1143   if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1144   {
1145     SMESH::NumericalFunctor_i* aNumericalFunctor =
1146       dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1147     SMESH::Controls::NumericalFunctorPtr aCrit;
1148     if (aNumericalFunctor)
1149       aCrit = aNumericalFunctor->GetNumericalFunctor();
1150     else
1151       aCrit.reset(new SMESH::Controls::AspectRatio());
1152
1153     ::SMESH_MeshEditor anEditor (myMesh);
1154     return anEditor.BestSplit(quad, aCrit);
1155   }
1156   return -1;
1157 }
1158
1159
1160 //=======================================================================
1161 //function : Smooth
1162 //purpose  :
1163 //=======================================================================
1164
1165 CORBA::Boolean
1166   SMESH_MeshEditor_i::Smooth(const SMESH::long_array &              IDsOfElements,
1167                              const SMESH::long_array &              IDsOfFixedNodes,
1168                              CORBA::Long                            MaxNbOfIterations,
1169                              CORBA::Double                          MaxAspectRatio,
1170                              SMESH::SMESH_MeshEditor::Smooth_Method Method)
1171 {
1172   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1173                 MaxAspectRatio, Method, false );
1174 }
1175
1176
1177 //=======================================================================
1178 //function : SmoothParametric
1179 //purpose  :
1180 //=======================================================================
1181
1182 CORBA::Boolean
1183   SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array &              IDsOfElements,
1184                                        const SMESH::long_array &              IDsOfFixedNodes,
1185                                        CORBA::Long                            MaxNbOfIterations,
1186                                        CORBA::Double                          MaxAspectRatio,
1187                                        SMESH::SMESH_MeshEditor::Smooth_Method Method)
1188 {
1189   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1190                 MaxAspectRatio, Method, true );
1191 }
1192
1193
1194 //=======================================================================
1195 //function : SmoothObject
1196 //purpose  :
1197 //=======================================================================
1198
1199 CORBA::Boolean
1200   SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr              theObject,
1201                                    const SMESH::long_array &              IDsOfFixedNodes,
1202                                    CORBA::Long                            MaxNbOfIterations,
1203                                    CORBA::Double                          MaxAspectRatio,
1204                                    SMESH::SMESH_MeshEditor::Smooth_Method Method)
1205 {
1206   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1207                        MaxAspectRatio, Method, false);
1208 }
1209
1210
1211 //=======================================================================
1212 //function : SmoothParametricObject
1213 //purpose  :
1214 //=======================================================================
1215
1216 CORBA::Boolean
1217   SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr              theObject,
1218                                    const SMESH::long_array &              IDsOfFixedNodes,
1219                                    CORBA::Long                            MaxNbOfIterations,
1220                                    CORBA::Double                          MaxAspectRatio,
1221                                    SMESH::SMESH_MeshEditor::Smooth_Method Method)
1222 {
1223   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1224                        MaxAspectRatio, Method, true);
1225 }
1226
1227
1228 //=============================================================================
1229 /*!
1230  *
1231  */
1232 //=============================================================================
1233
1234 CORBA::Boolean
1235   SMESH_MeshEditor_i::smooth(const SMESH::long_array &              IDsOfElements,
1236                              const SMESH::long_array &              IDsOfFixedNodes,
1237                              CORBA::Long                            MaxNbOfIterations,
1238                              CORBA::Double                          MaxAspectRatio,
1239                              SMESH::SMESH_MeshEditor::Smooth_Method Method,
1240                              bool                                   IsParametric)
1241 {
1242   initData();
1243
1244   SMESHDS_Mesh* aMesh = GetMeshDS();
1245
1246   TIDSortedElemSet elements;
1247   arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1248
1249   set<const SMDS_MeshNode*> fixedNodes;
1250   for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1251     CORBA::Long index = IDsOfFixedNodes[i];
1252     const SMDS_MeshNode * node = aMesh->FindNode(index);
1253     if ( node )
1254       fixedNodes.insert( node );
1255   }
1256   ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1257   if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1258     method = ::SMESH_MeshEditor::CENTROIDAL;
1259
1260   ::SMESH_MeshEditor anEditor( myMesh );
1261   anEditor.Smooth(elements, fixedNodes, method,
1262                   MaxNbOfIterations, MaxAspectRatio, IsParametric );
1263
1264   storeResult(anEditor);
1265
1266   // Update Python script
1267   TPythonDump() << "isDone = " << this << "."
1268                 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1269                 << IDsOfElements << ", "     << IDsOfFixedNodes << ", "
1270                 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1271                 << "SMESH.SMESH_MeshEditor."
1272                 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1273                      "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1274 #ifdef _DEBUG_
1275   TPythonDump() << "print 'Smooth: ', isDone";
1276 #endif
1277
1278   return true;
1279 }
1280
1281
1282 //=============================================================================
1283 /*!
1284  *
1285  */
1286 //=============================================================================
1287
1288 CORBA::Boolean
1289 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr              theObject,
1290                                  const SMESH::long_array &              IDsOfFixedNodes,
1291                                  CORBA::Long                            MaxNbOfIterations,
1292                                  CORBA::Double                          MaxAspectRatio,
1293                                  SMESH::SMESH_MeshEditor::Smooth_Method Method,
1294                                  bool                                   IsParametric)
1295 {
1296   initData();
1297
1298   SMESH::long_array_var anElementsId = theObject->GetIDs();
1299   CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1300                                   MaxAspectRatio, Method, IsParametric);
1301
1302   // Clear python line(s), created by Smooth()
1303   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1304   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1305 #ifdef _DEBUG_
1306   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1307 #endif
1308
1309   // Update Python script
1310   TPythonDump() << "isDone = " << this << "."
1311                 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1312                 << theObject << ", " << IDsOfFixedNodes << ", "
1313                 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1314                 << "SMESH.SMESH_MeshEditor."
1315                 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1316                      "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1317 #ifdef _DEBUG_
1318   TPythonDump() << "print 'SmoothObject: ', isDone";
1319 #endif
1320
1321   return isDone;
1322 }
1323
1324
1325 //=============================================================================
1326 /*!
1327  *
1328  */
1329 //=============================================================================
1330
1331 void SMESH_MeshEditor_i::RenumberNodes()
1332 {
1333   // Update Python script
1334   TPythonDump() << this << ".RenumberNodes()";
1335
1336   GetMeshDS()->Renumber( true );
1337 }
1338
1339
1340 //=============================================================================
1341 /*!
1342  *
1343  */
1344 //=============================================================================
1345
1346 void SMESH_MeshEditor_i::RenumberElements()
1347 {
1348   // Update Python script
1349   TPythonDump() << this << ".RenumberElements()";
1350
1351   GetMeshDS()->Renumber( false );
1352 }
1353
1354 //=======================================================================
1355   /*!
1356    * \brief Return groups by their IDs
1357    */
1358 //=======================================================================
1359
1360 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
1361 {
1362   if ( !groupIDs )
1363     return 0;
1364   myMesh_i->CreateGroupServants();
1365   return myMesh_i->GetGroups( *groupIDs );
1366 }
1367
1368 //=======================================================================
1369 //function : rotationSweep
1370 //purpose  : 
1371 //=======================================================================
1372
1373 SMESH::ListOfGroups*
1374 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
1375                                   const SMESH::AxisStruct & theAxis,
1376                                   CORBA::Double             theAngleInRadians,
1377                                   CORBA::Long               theNbOfSteps,
1378                                   CORBA::Double             theTolerance,
1379                                   const bool                theMakeGroups,
1380                                   const SMDSAbs_ElementType theElementType)
1381 {
1382   initData();
1383
1384   TIDSortedElemSet inElements, copyElements;
1385   arrayToSet(theIDsOfElements, GetMeshDS(), inElements, theElementType);
1386
1387   TIDSortedElemSet* workElements = & inElements;
1388   TPreviewMesh      tmpMesh( SMDSAbs_Face );
1389   SMESH_Mesh*       mesh = 0;
1390   bool              makeWalls=true;
1391   if ( myPreviewMode )
1392   {
1393     SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1394     tmpMesh.Copy( inElements, copyElements, select, avoid );
1395     mesh = &tmpMesh;
1396     workElements = & copyElements;
1397     //makeWalls = false;
1398   }
1399   else
1400   {
1401     mesh = myMesh;
1402   }
1403
1404   gp_Ax1 Ax1 (gp_Pnt( theAxis.x,  theAxis.y,  theAxis.z ),
1405               gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
1406
1407   ::SMESH_MeshEditor anEditor( mesh );
1408   ::SMESH_MeshEditor::PGroupIDs groupIds =
1409     anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
1410                             theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
1411   storeResult(anEditor);
1412
1413   return theMakeGroups ? getGroups(groupIds.get()) : 0;
1414 }
1415
1416 //=======================================================================
1417 //function : RotationSweep
1418 //purpose  :
1419 //=======================================================================
1420
1421 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
1422                                        const SMESH::AxisStruct & theAxis,
1423                                        CORBA::Double             theAngleInRadians,
1424                                        CORBA::Long               theNbOfSteps,
1425                                        CORBA::Double             theTolerance)
1426 {
1427   if ( !myPreviewMode ) {
1428     TPythonDump() << this << ".RotationSweep( "
1429                   << theIDsOfElements << ", "
1430                   << theAxis << ", "
1431                   << theAngleInRadians << ", "
1432                   << theNbOfSteps << ", "
1433                   << theTolerance << " )";
1434   }
1435   rotationSweep(theIDsOfElements,
1436                 theAxis,
1437                 theAngleInRadians,
1438                 theNbOfSteps,
1439                 theTolerance,
1440                 false);
1441 }
1442
1443 //=======================================================================
1444 //function : RotationSweepMakeGroups
1445 //purpose  : 
1446 //=======================================================================
1447
1448 SMESH::ListOfGroups*
1449 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1450                                             const SMESH::AxisStruct& theAxis,
1451                                             CORBA::Double            theAngleInRadians,
1452                                             CORBA::Long              theNbOfSteps,
1453                                             CORBA::Double            theTolerance)
1454 {
1455   SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
1456                                                theAxis,
1457                                                theAngleInRadians,
1458                                                theNbOfSteps,
1459                                                theTolerance,
1460                                                true);
1461   if ( !myPreviewMode ) {
1462     TPythonDump aPythonDump;
1463     DumpGroupsList(aPythonDump,aGroups);
1464     aPythonDump<< this << ".RotationSweepMakeGroups( "
1465                << theIDsOfElements << ", "
1466                << theAxis << ", "
1467                << theAngleInRadians << ", "
1468                << theNbOfSteps << ", "
1469                << theTolerance << " )";
1470   }
1471   return aGroups;
1472 }
1473
1474 //=======================================================================
1475 //function : RotationSweepObject
1476 //purpose  :
1477 //=======================================================================
1478
1479 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1480                                              const SMESH::AxisStruct & theAxis,
1481                                              CORBA::Double             theAngleInRadians,
1482                                              CORBA::Long               theNbOfSteps,
1483                                              CORBA::Double             theTolerance)
1484 {
1485   if ( !myPreviewMode ) {
1486     TPythonDump() << this << ".RotationSweepObject( "
1487                   << theObject << ", "
1488                   << theAxis << ", "
1489                   << theAngleInRadians << ", "
1490                   << theNbOfSteps << ", "
1491                   << theTolerance << " )";
1492   }
1493   SMESH::long_array_var anElementsId = theObject->GetIDs();
1494   rotationSweep(anElementsId,
1495                 theAxis,
1496                 theAngleInRadians,
1497                 theNbOfSteps,
1498                 theTolerance,
1499                 false);
1500 }
1501
1502 //=======================================================================
1503 //function : RotationSweepObject1D
1504 //purpose  :
1505 //=======================================================================
1506
1507 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1508                                                const SMESH::AxisStruct & theAxis,
1509                                                CORBA::Double             theAngleInRadians,
1510                                                CORBA::Long               theNbOfSteps,
1511                                                CORBA::Double             theTolerance)
1512 {
1513   if ( !myPreviewMode ) {
1514     TPythonDump() << this << ".RotationSweepObject1D( "
1515                   << theObject << ", "
1516                   << theAxis << ", "
1517                   << theAngleInRadians << ", "
1518                   << theNbOfSteps << ", "
1519                   << theTolerance << " )";
1520   }
1521   SMESH::long_array_var anElementsId = theObject->GetIDs();
1522   rotationSweep(anElementsId,
1523                 theAxis,
1524                 theAngleInRadians,
1525                 theNbOfSteps,
1526                 theTolerance,
1527                 false,
1528                 SMDSAbs_Edge);
1529 }
1530
1531 //=======================================================================
1532 //function : RotationSweepObject2D
1533 //purpose  :
1534 //=======================================================================
1535
1536 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1537                                                const SMESH::AxisStruct & theAxis,
1538                                                CORBA::Double             theAngleInRadians,
1539                                                CORBA::Long               theNbOfSteps,
1540                                                CORBA::Double             theTolerance)
1541 {
1542   if ( !myPreviewMode ) {
1543     TPythonDump() << this << ".RotationSweepObject2D( "
1544                   << theObject << ", "
1545                   << theAxis << ", "
1546                   << theAngleInRadians << ", "
1547                   << theNbOfSteps << ", "
1548                   << theTolerance << " )";
1549   }
1550   SMESH::long_array_var anElementsId = theObject->GetIDs();
1551   rotationSweep(anElementsId,
1552                 theAxis,
1553                 theAngleInRadians,
1554                 theNbOfSteps,
1555                 theTolerance,
1556                 false,
1557                 SMDSAbs_Face);
1558 }
1559
1560 //=======================================================================
1561 //function : RotationSweepObjectMakeGroups
1562 //purpose  : 
1563 //=======================================================================
1564
1565 SMESH::ListOfGroups*
1566 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1567                                                   const SMESH::AxisStruct&  theAxis,
1568                                                   CORBA::Double             theAngleInRadians,
1569                                                   CORBA::Long               theNbOfSteps,
1570                                                   CORBA::Double             theTolerance)
1571 {
1572   SMESH::long_array_var anElementsId = theObject->GetIDs();
1573   SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1574                                                theAxis,
1575                                                theAngleInRadians,
1576                                                theNbOfSteps,
1577                                                theTolerance,
1578                                                true);
1579   if ( !myPreviewMode ) {
1580     TPythonDump aPythonDump;
1581     DumpGroupsList(aPythonDump,aGroups);
1582     aPythonDump<< this << ".RotationSweepObjectMakeGroups( "
1583                << theObject << ", "
1584                << theAxis << ", "
1585                << theAngleInRadians << ", "
1586                << theNbOfSteps << ", "
1587                << theTolerance << " )";
1588   }
1589   return aGroups;
1590 }
1591
1592 //=======================================================================
1593 //function : RotationSweepObject1DMakeGroups
1594 //purpose  : 
1595 //=======================================================================
1596
1597 SMESH::ListOfGroups*
1598 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1599                                                     const SMESH::AxisStruct&  theAxis,
1600                                                     CORBA::Double             theAngleInRadians,
1601                                                     CORBA::Long               theNbOfSteps,
1602                                                     CORBA::Double             theTolerance)
1603 {
1604   SMESH::long_array_var anElementsId = theObject->GetIDs();
1605   SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1606                                                theAxis,
1607                                                theAngleInRadians,
1608                                                theNbOfSteps,
1609                                                theTolerance,
1610                                                true,
1611                                                SMDSAbs_Edge);
1612   if ( !myPreviewMode ) {
1613     TPythonDump aPythonDump;
1614     DumpGroupsList(aPythonDump,aGroups);
1615     aPythonDump<< this << ".RotationSweepObject1DMakeGroups( "
1616                << theObject << ", "
1617                << theAxis << ", "
1618                << theAngleInRadians << ", "
1619                << theNbOfSteps << ", "
1620                << theTolerance << " )";
1621   }
1622   return aGroups;
1623 }
1624
1625 //=======================================================================
1626 //function : RotationSweepObject2DMakeGroups
1627 //purpose  : 
1628 //=======================================================================
1629
1630 SMESH::ListOfGroups*
1631 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1632                                                     const SMESH::AxisStruct&  theAxis,
1633                                                     CORBA::Double             theAngleInRadians,
1634                                                     CORBA::Long               theNbOfSteps,
1635                                                     CORBA::Double             theTolerance)
1636 {
1637   SMESH::long_array_var anElementsId = theObject->GetIDs();
1638   SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1639                                                theAxis,
1640                                                theAngleInRadians,
1641                                                theNbOfSteps,
1642                                                theTolerance,
1643                                                true,
1644                                                SMDSAbs_Face);
1645   if ( !myPreviewMode ) {
1646     TPythonDump aPythonDump;
1647     DumpGroupsList(aPythonDump,aGroups);
1648     aPythonDump<< this << ".RotationSweepObject2DMakeGroups( "
1649                << theObject << ", "
1650                << theAxis << ", "
1651                << theAngleInRadians << ", "
1652                << theNbOfSteps << ", "
1653                << theTolerance << " )";
1654   }
1655   return aGroups;
1656 }
1657
1658
1659 //=======================================================================
1660 //function : extrusionSweep
1661 //purpose  : 
1662 //=======================================================================
1663
1664 SMESH::ListOfGroups*
1665 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
1666                                    const SMESH::DirStruct &  theStepVector,
1667                                    CORBA::Long               theNbOfSteps,
1668                                    const bool                theMakeGroups,
1669                                    const SMDSAbs_ElementType theElementType)
1670 {
1671   initData();
1672
1673   try {   
1674 #ifdef NO_CAS_CATCH
1675     OCC_CATCH_SIGNALS;
1676 #endif
1677     TIDSortedElemSet elements;
1678     arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
1679
1680     const SMESH::PointStruct * P = &theStepVector.PS;
1681     gp_Vec stepVec( P->x, P->y, P->z );
1682
1683     TElemOfElemListMap aHystory;
1684     ::SMESH_MeshEditor anEditor( myMesh );
1685     ::SMESH_MeshEditor::PGroupIDs groupIds =
1686         anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
1687
1688     storeResult(anEditor);
1689
1690     return theMakeGroups ? getGroups(groupIds.get()) : 0;
1691
1692   } catch(Standard_Failure) {
1693     Handle(Standard_Failure) aFail = Standard_Failure::Caught();          
1694     INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
1695   }
1696   return 0;
1697 }
1698
1699 //=======================================================================
1700 //function : ExtrusionSweep
1701 //purpose  :
1702 //=======================================================================
1703
1704 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
1705                                         const SMESH::DirStruct &  theStepVector,
1706                                         CORBA::Long               theNbOfSteps)
1707 {
1708   extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
1709   if ( !myPreviewMode ) {
1710     TPythonDump() << this << ".ExtrusionSweep( "
1711                   << theIDsOfElements << ", " << theStepVector <<", " << theNbOfSteps << " )";
1712   }
1713 }
1714
1715
1716 //=======================================================================
1717 //function : ExtrusionSweepObject
1718 //purpose  :
1719 //=======================================================================
1720
1721 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1722                                               const SMESH::DirStruct &  theStepVector,
1723                                               CORBA::Long               theNbOfSteps)
1724 {
1725   SMESH::long_array_var anElementsId = theObject->GetIDs();
1726   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
1727   if ( !myPreviewMode ) {
1728     TPythonDump() << this << ".ExtrusionSweepObject( "
1729                   << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1730   }
1731 }
1732
1733 //=======================================================================
1734 //function : ExtrusionSweepObject1D
1735 //purpose  :
1736 //=======================================================================
1737
1738 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1739                                                 const SMESH::DirStruct &  theStepVector,
1740                                                 CORBA::Long               theNbOfSteps)
1741 {
1742   SMESH::long_array_var anElementsId = theObject->GetIDs();
1743   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
1744   if ( !myPreviewMode ) {
1745     TPythonDump() << this << ".ExtrusionSweepObject1D( "
1746                   << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1747   }
1748 }
1749
1750 //=======================================================================
1751 //function : ExtrusionSweepObject2D
1752 //purpose  :
1753 //=======================================================================
1754
1755 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1756                                                 const SMESH::DirStruct &  theStepVector,
1757                                                 CORBA::Long               theNbOfSteps)
1758 {
1759   SMESH::long_array_var anElementsId = theObject->GetIDs();
1760   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
1761   if ( !myPreviewMode ) {
1762     TPythonDump() << this << ".ExtrusionSweepObject2D( "
1763                   << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1764   }
1765 }
1766
1767 //=======================================================================
1768 //function : ExtrusionSweepMakeGroups
1769 //purpose  : 
1770 //=======================================================================
1771
1772 SMESH::ListOfGroups*
1773 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1774                                              const SMESH::DirStruct&  theStepVector,
1775                                              CORBA::Long              theNbOfSteps)
1776 {
1777   SMESH::ListOfGroups* aGroups = extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, true );
1778     
1779   if ( !myPreviewMode ) {
1780     TPythonDump aPythonDump;
1781     DumpGroupsList(aPythonDump,aGroups);
1782     aPythonDump  << this << ".ExtrusionSweepMakeGroups( "
1783                  << theIDsOfElements << ", " << theStepVector <<", " << theNbOfSteps << " )";
1784   }
1785   return aGroups;
1786 }
1787 //=======================================================================
1788 //function : ExtrusionSweepObjectMakeGroups
1789 //purpose  : 
1790 //=======================================================================
1791
1792 SMESH::ListOfGroups*
1793 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1794                                                    const SMESH::DirStruct&   theStepVector,
1795                                                    CORBA::Long               theNbOfSteps)
1796 {
1797   SMESH::long_array_var anElementsId = theObject->GetIDs();
1798   SMESH::ListOfGroups * aGroups = extrusionSweep (anElementsId, theStepVector, theNbOfSteps, true );
1799   
1800   if ( !myPreviewMode ) {
1801     TPythonDump aPythonDump;
1802     DumpGroupsList(aPythonDump,aGroups);
1803     aPythonDump<< this << ".ExtrusionSweepObjectMakeGroups( "
1804                << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1805   }
1806   return aGroups;
1807 }
1808
1809 //=======================================================================
1810 //function : ExtrusionSweepObject1DMakeGroups
1811 //purpose  : 
1812 //=======================================================================
1813
1814 SMESH::ListOfGroups*
1815 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1816                                                      const SMESH::DirStruct&   theStepVector,
1817                                                      CORBA::Long               theNbOfSteps)
1818 {
1819   SMESH::long_array_var anElementsId = theObject->GetIDs();
1820   SMESH::ListOfGroups * aGroups = extrusionSweep (anElementsId, theStepVector, theNbOfSteps, true, SMDSAbs_Edge );
1821   if ( !myPreviewMode ) {
1822     TPythonDump aPythonDump;
1823     DumpGroupsList(aPythonDump,aGroups);
1824     aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( "
1825                 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1826   }
1827   return aGroups;
1828 }
1829
1830 //=======================================================================
1831 //function : ExtrusionSweepObject2DMakeGroups
1832 //purpose  : 
1833 //=======================================================================
1834
1835 SMESH::ListOfGroups*
1836 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1837                                                      const SMESH::DirStruct&   theStepVector,
1838                                                      CORBA::Long               theNbOfSteps)
1839 {
1840   SMESH::long_array_var anElementsId = theObject->GetIDs();
1841   SMESH::ListOfGroups * aGroups = extrusionSweep (anElementsId, theStepVector, theNbOfSteps, true, SMDSAbs_Face );
1842   if ( !myPreviewMode ) {
1843     TPythonDump aPythonDump;
1844     DumpGroupsList(aPythonDump,aGroups);
1845     aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( "
1846                 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1847   }
1848   return aGroups;
1849 }
1850
1851
1852 //=======================================================================
1853 //function : advancedExtrusion
1854 //purpose  : 
1855 //=======================================================================
1856
1857 SMESH::ListOfGroups*
1858 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
1859                                       const SMESH::DirStruct &  theStepVector,
1860                                       CORBA::Long               theNbOfSteps,
1861                                       CORBA::Long               theExtrFlags,
1862                                       CORBA::Double             theSewTolerance,
1863                                       const bool                theMakeGroups)
1864 {
1865   initData();
1866
1867   TIDSortedElemSet elements;
1868   arrayToSet(theIDsOfElements, GetMeshDS(), elements);
1869
1870   const SMESH::PointStruct * P = &theStepVector.PS;
1871   gp_Vec stepVec( P->x, P->y, P->z );
1872
1873   ::SMESH_MeshEditor anEditor( myMesh );
1874   TElemOfElemListMap aHystory;
1875   ::SMESH_MeshEditor::PGroupIDs groupIds =
1876       anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
1877                                theMakeGroups, theExtrFlags, theSewTolerance);
1878   storeResult(anEditor);
1879
1880   return theMakeGroups ? getGroups(groupIds.get()) : 0;
1881 }
1882
1883 //=======================================================================
1884 //function : AdvancedExtrusion
1885 //purpose  :
1886 //=======================================================================
1887
1888 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
1889                                            const SMESH::DirStruct &  theStepVector,
1890                                            CORBA::Long               theNbOfSteps,
1891                                            CORBA::Long               theExtrFlags,
1892                                            CORBA::Double             theSewTolerance)
1893 {
1894   if ( !myPreviewMode ) {
1895     TPythonDump() << "stepVector = " << theStepVector;
1896     TPythonDump() << this << ".AdvancedExtrusion("
1897                   << theIDsOfElements
1898                   << ", stepVector, "
1899                   << theNbOfSteps << ","
1900                   << theExtrFlags << ", "
1901                   << theSewTolerance <<  " )";
1902   }
1903   advancedExtrusion( theIDsOfElements,
1904                      theStepVector,
1905                      theNbOfSteps,
1906                      theExtrFlags,
1907                      theSewTolerance,
1908                      false);
1909 }
1910
1911 //=======================================================================
1912 //function : AdvancedExtrusionMakeGroups
1913 //purpose  : 
1914 //=======================================================================
1915
1916 SMESH::ListOfGroups*
1917 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
1918                                                 const SMESH::DirStruct&  theStepVector,
1919                                                 CORBA::Long              theNbOfSteps,
1920                                                 CORBA::Long              theExtrFlags,
1921                                                 CORBA::Double            theSewTolerance)
1922 {
1923   SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
1924                                                     theStepVector,
1925                                                     theNbOfSteps,
1926                                                     theExtrFlags,
1927                                                     theSewTolerance,
1928                                                     true);
1929   
1930   if ( !myPreviewMode ) {
1931     TPythonDump() << "stepVector = " << theStepVector;
1932     TPythonDump aPythonDump;
1933     DumpGroupsList(aPythonDump,aGroups);
1934     aPythonDump << this << ".AdvancedExtrusionMakeGroups("
1935                 << theIDsOfElements
1936                 << ", stepVector, "
1937                 << theNbOfSteps << ","
1938                 << theExtrFlags << ", "
1939                 << theSewTolerance <<  " )";
1940   }
1941   return aGroups;
1942 }
1943
1944
1945 //================================================================================
1946 /*!
1947  * \brief Convert extrusion error to IDL enum
1948  */
1949 //================================================================================
1950
1951 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
1952
1953 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
1954 {
1955   switch ( e ) {
1956   RETCASE( EXTR_OK );
1957   RETCASE( EXTR_NO_ELEMENTS );
1958   RETCASE( EXTR_PATH_NOT_EDGE );
1959   RETCASE( EXTR_BAD_PATH_SHAPE );
1960   RETCASE( EXTR_BAD_STARTING_NODE );
1961   RETCASE( EXTR_BAD_ANGLES_NUMBER );
1962   RETCASE( EXTR_CANT_GET_TANGENT );
1963   }
1964   return SMESH::SMESH_MeshEditor::EXTR_OK;
1965 }
1966
1967
1968 //=======================================================================
1969 //function : extrusionAlongPath
1970 //purpose  : 
1971 //=======================================================================
1972
1973 SMESH::ListOfGroups*
1974 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
1975                                        SMESH::SMESH_Mesh_ptr       thePathMesh,
1976                                        GEOM::GEOM_Object_ptr       thePathShape,
1977                                        CORBA::Long                 theNodeStart,
1978                                        CORBA::Boolean              theHasAngles,
1979                                        const SMESH::double_array & theAngles,
1980                                        CORBA::Boolean              theHasRefPoint,
1981                                        const SMESH::PointStruct &  theRefPoint,
1982                                        const bool                  theMakeGroups,
1983                                        SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
1984                                        const SMDSAbs_ElementType   theElementType)
1985 {
1986   initData();
1987
1988   if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
1989     theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
1990     return 0;
1991   }
1992   SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
1993
1994   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
1995   SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
1996
1997   if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
1998     theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
1999     return 0;
2000   }
2001
2002   SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2003   if ( !nodeStart ) {
2004     theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2005     return 0;
2006   }
2007
2008   TIDSortedElemSet elements;
2009   arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
2010
2011   list<double> angles;
2012   for (int i = 0; i < theAngles.length(); i++) {
2013     angles.push_back( theAngles[i] );
2014   }
2015
2016   gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2017
2018   int nbOldGroups = myMesh->NbGroup();
2019
2020   ::SMESH_MeshEditor anEditor( myMesh );
2021   ::SMESH_MeshEditor::Extrusion_Error error =
2022       anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2023                                     theHasAngles, angles, false,
2024                                     theHasRefPoint, refPnt, theMakeGroups );
2025   storeResult(anEditor);
2026   theError = convExtrError( error );
2027
2028   if ( theMakeGroups ) {
2029     list<int> groupIDs = myMesh->GetGroupIds();
2030     list<int>::iterator newBegin = groupIDs.begin();
2031     std::advance( newBegin, nbOldGroups ); // skip old groups
2032     groupIDs.erase( groupIDs.begin(), newBegin );
2033     return getGroups( & groupIDs );
2034   }
2035   return 0;
2036 }
2037
2038
2039 //=======================================================================
2040 //function : extrusionAlongPathX
2041 //purpose  : 
2042 //=======================================================================
2043
2044 SMESH::ListOfGroups*
2045 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array &  IDsOfElements,
2046                                         SMESH::SMESH_IDSource_ptr  Path,
2047                                         CORBA::Long                NodeStart,
2048                                         CORBA::Boolean             HasAngles,
2049                                         const SMESH::double_array& Angles,
2050                                         CORBA::Boolean             LinearVariation,
2051                                         CORBA::Boolean             HasRefPoint,
2052                                         const SMESH::PointStruct&  RefPoint,
2053                                         const bool                 MakeGroups,
2054                                         const SMDSAbs_ElementType  ElementType,
2055                                         SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2056 {
2057   SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2058
2059   initData();
2060
2061   list<double> angles;
2062   for (int i = 0; i < Angles.length(); i++) {
2063     angles.push_back( Angles[i] );
2064   }
2065   gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2066   int nbOldGroups = myMesh->NbGroup();
2067
2068   if ( Path->_is_nil() ) {
2069     Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2070     return EmptyGr;
2071   }
2072
2073   TIDSortedElemSet elements;
2074   arrayToSet(IDsOfElements, GetMeshDS(), elements, ElementType);
2075
2076   ::SMESH_MeshEditor anEditor( myMesh );
2077   ::SMESH_MeshEditor::Extrusion_Error error;
2078
2079   SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path );
2080   if(aMeshImp) {
2081     // path as mesh
2082     SMDS_MeshNode* aNodeStart = 
2083       (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2084     if ( !aNodeStart ) {
2085       Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2086       return EmptyGr;
2087     }
2088     error = anEditor.ExtrusionAlongTrack( elements, &(aMeshImp->GetImpl()), aNodeStart,
2089                                           HasAngles, angles, LinearVariation,
2090                                           HasRefPoint, refPnt, MakeGroups );
2091   }
2092   else {
2093     SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path );
2094     if(aSubMeshImp) {
2095       // path as submesh
2096       SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2097       aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2098       SMDS_MeshNode* aNodeStart = 
2099         (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2100       if ( !aNodeStart ) {
2101         Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2102         return EmptyGr;
2103       }
2104       SMESH_subMesh* aSubMesh = 
2105         aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2106       error = anEditor.ExtrusionAlongTrack( elements, aSubMesh, aNodeStart,
2107                                             HasAngles, angles, LinearVariation,
2108                                             HasRefPoint, refPnt, MakeGroups );
2109     }
2110     else {
2111       SMESH_Group_i* aGroupImp = SMESH::DownCast<SMESH_Group_i*>( Path );
2112       if(aGroupImp) {
2113         // path as group of 1D elements
2114       }
2115       else {
2116         // invalid path
2117         Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2118         return EmptyGr;
2119       }
2120     }
2121   }
2122
2123   storeResult(anEditor);
2124   Error = convExtrError( error );
2125
2126   if ( MakeGroups ) {
2127     list<int> groupIDs = myMesh->GetGroupIds();
2128     list<int>::iterator newBegin = groupIDs.begin();
2129     std::advance( newBegin, nbOldGroups ); // skip old groups
2130     groupIDs.erase( groupIDs.begin(), newBegin );
2131     return getGroups( & groupIDs );
2132   }
2133   return EmptyGr;
2134 }
2135
2136
2137 //=======================================================================
2138 //function : ExtrusionAlongPath
2139 //purpose  :
2140 //=======================================================================
2141
2142 SMESH::SMESH_MeshEditor::Extrusion_Error
2143   SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
2144                                          SMESH::SMESH_Mesh_ptr       thePathMesh,
2145                                          GEOM::GEOM_Object_ptr       thePathShape,
2146                                          CORBA::Long                 theNodeStart,
2147                                          CORBA::Boolean              theHasAngles,
2148                                          const SMESH::double_array & theAngles,
2149                                          CORBA::Boolean              theHasRefPoint,
2150                                          const SMESH::PointStruct &  theRefPoint)
2151 {
2152   if ( !myPreviewMode ) {
2153     TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
2154                   << theIDsOfElements << ", "
2155                   << thePathMesh      << ", "
2156                   << thePathShape     << ", "
2157                   << theNodeStart     << ", "
2158                   << theHasAngles     << ", "
2159                   << theAngles        << ", "
2160                   << theHasRefPoint   << ", "
2161                   << "SMESH.PointStruct( "
2162                   << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2163                   << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2164                   << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2165   }
2166   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2167   extrusionAlongPath( theIDsOfElements,
2168                       thePathMesh,
2169                       thePathShape,
2170                       theNodeStart,
2171                       theHasAngles,
2172                       theAngles,
2173                       theHasRefPoint,
2174                       theRefPoint,
2175                       false,
2176                       anError);
2177   return anError;
2178 }
2179
2180 //=======================================================================
2181 //function : ExtrusionAlongPathObject
2182 //purpose  :
2183 //=======================================================================
2184
2185 SMESH::SMESH_MeshEditor::Extrusion_Error
2186 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObject,
2187                                              SMESH::SMESH_Mesh_ptr       thePathMesh,
2188                                              GEOM::GEOM_Object_ptr       thePathShape,
2189                                              CORBA::Long                 theNodeStart,
2190                                              CORBA::Boolean              theHasAngles,
2191                                              const SMESH::double_array & theAngles,
2192                                              CORBA::Boolean              theHasRefPoint,
2193                                              const SMESH::PointStruct &  theRefPoint)
2194 {
2195   if ( !myPreviewMode ) {
2196     TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
2197                   << theObject        << ", "
2198                   << thePathMesh      << ", "
2199                   << thePathShape     << ", "
2200                   << theNodeStart     << ", "
2201                   << theHasAngles     << ", "
2202                   << theAngles        << ", "
2203                   << theHasRefPoint   << ", "
2204                   << "SMESH.PointStruct( "
2205                   << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2206                   << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2207                   << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2208   }
2209   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2210   SMESH::long_array_var anElementsId = theObject->GetIDs();
2211   extrusionAlongPath( anElementsId,
2212                       thePathMesh,
2213                       thePathShape,
2214                       theNodeStart,
2215                       theHasAngles,
2216                       theAngles,
2217                       theHasRefPoint,
2218                       theRefPoint,
2219                       false,
2220                       anError);
2221   return anError;
2222 }
2223
2224 //=======================================================================
2225 //function : ExtrusionAlongPathObject1D
2226 //purpose  :
2227 //=======================================================================
2228
2229 SMESH::SMESH_MeshEditor::Extrusion_Error
2230 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr   theObject,
2231                                                SMESH::SMESH_Mesh_ptr       thePathMesh,
2232                                                GEOM::GEOM_Object_ptr       thePathShape,
2233                                                CORBA::Long                 theNodeStart,
2234                                                CORBA::Boolean              theHasAngles,
2235                                                const SMESH::double_array & theAngles,
2236                                                CORBA::Boolean              theHasRefPoint,
2237                                                const SMESH::PointStruct &  theRefPoint)
2238 {
2239   if ( !myPreviewMode ) {
2240     TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2241                   << theObject        << ", "
2242                   << thePathMesh      << ", "
2243                   << thePathShape     << ", "
2244                   << theNodeStart     << ", "
2245                   << theHasAngles     << ", "
2246                   << theAngles        << ", "
2247                   << theHasRefPoint   << ", "
2248                   << "SMESH.PointStruct( "
2249                   << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2250                   << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2251                   << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2252   }
2253   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2254   SMESH::long_array_var anElementsId = theObject->GetIDs();
2255   extrusionAlongPath( anElementsId,
2256                       thePathMesh,
2257                       thePathShape,
2258                       theNodeStart,
2259                       theHasAngles,
2260                       theAngles,
2261                       theHasRefPoint,
2262                       theRefPoint,
2263                       false,
2264                       anError,
2265                       SMDSAbs_Edge);
2266   return anError;
2267 }
2268
2269 //=======================================================================
2270 //function : ExtrusionAlongPathObject2D
2271 //purpose  :
2272 //=======================================================================
2273
2274 SMESH::SMESH_MeshEditor::Extrusion_Error
2275 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr   theObject,
2276                                                SMESH::SMESH_Mesh_ptr       thePathMesh,
2277                                                GEOM::GEOM_Object_ptr       thePathShape,
2278                                                CORBA::Long                 theNodeStart,
2279                                                CORBA::Boolean              theHasAngles,
2280                                                const SMESH::double_array & theAngles,
2281                                                CORBA::Boolean              theHasRefPoint,
2282                                                const SMESH::PointStruct &  theRefPoint)
2283 {
2284   if ( !myPreviewMode ) {
2285     TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
2286                   << theObject        << ", "
2287                   << thePathMesh      << ", "
2288                   << thePathShape     << ", "
2289                   << theNodeStart     << ", "
2290                   << theHasAngles     << ", "
2291                   << theAngles        << ", "
2292                   << theHasRefPoint   << ", "
2293                   << "SMESH.PointStruct( "
2294                   << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2295                   << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2296                   << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2297   }
2298   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2299   SMESH::long_array_var anElementsId = theObject->GetIDs();
2300   extrusionAlongPath( anElementsId,
2301                       thePathMesh,
2302                       thePathShape,
2303                       theNodeStart,
2304                       theHasAngles,
2305                       theAngles,
2306                       theHasRefPoint,
2307                       theRefPoint,
2308                       false,
2309                       anError,
2310                       SMDSAbs_Face);
2311   return anError;
2312 }
2313
2314
2315 //=======================================================================
2316 //function : ExtrusionAlongPathMakeGroups
2317 //purpose  : 
2318 //=======================================================================
2319
2320 SMESH::ListOfGroups*
2321 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array&   theIDsOfElements,
2322                                                  SMESH::SMESH_Mesh_ptr      thePathMesh,
2323                                                  GEOM::GEOM_Object_ptr      thePathShape,
2324                                                  CORBA::Long                theNodeStart,
2325                                                  CORBA::Boolean             theHasAngles,
2326                                                  const SMESH::double_array& theAngles,
2327                                                  CORBA::Boolean             theHasRefPoint,
2328                                                  const SMESH::PointStruct&  theRefPoint,
2329                                                  SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2330 {
2331     SMESH::ListOfGroups * aGroups =  extrusionAlongPath( theIDsOfElements,
2332                                                          thePathMesh,
2333                                                          thePathShape,
2334                                                          theNodeStart,
2335                                                          theHasAngles,
2336                                                          theAngles,
2337                                                          theHasRefPoint,
2338                                                          theRefPoint,
2339                                                          true,
2340                                                          Error);
2341   if ( !myPreviewMode ) {
2342     bool isDumpGroups = aGroups && aGroups->length() > 0;
2343     TPythonDump aPythonDump;
2344     if(isDumpGroups) {
2345       aPythonDump << "("<<aGroups;
2346     }
2347     if(isDumpGroups)
2348       aPythonDump << ", error)";
2349     else
2350       aPythonDump <<"error";
2351     
2352     aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
2353                << theIDsOfElements << ", "
2354                << thePathMesh      << ", "
2355                << thePathShape     << ", "
2356                << theNodeStart     << ", "
2357                << theHasAngles     << ", "
2358                << theAngles        << ", "
2359                << theHasRefPoint   << ", "
2360                << "SMESH.PointStruct( "
2361                << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2362                << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2363                << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2364   }
2365   return aGroups;
2366 }
2367
2368 //=======================================================================
2369 //function : ExtrusionAlongPathObjectMakeGroups
2370 //purpose  : 
2371 //=======================================================================
2372
2373 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2374 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
2375                                    SMESH::SMESH_Mesh_ptr      thePathMesh,
2376                                    GEOM::GEOM_Object_ptr      thePathShape,
2377                                    CORBA::Long                theNodeStart,
2378                                    CORBA::Boolean             theHasAngles,
2379                                    const SMESH::double_array& theAngles,
2380                                    CORBA::Boolean             theHasRefPoint,
2381                                    const SMESH::PointStruct&  theRefPoint,
2382                                    SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2383 {
2384   SMESH::long_array_var anElementsId = theObject->GetIDs();
2385   SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2386                                                       thePathMesh,
2387                                                       thePathShape,
2388                                                       theNodeStart,
2389                                                       theHasAngles,
2390                                                       theAngles,
2391                                                       theHasRefPoint,
2392                                                       theRefPoint,
2393                                                       true,
2394                                                       Error);
2395   
2396   if ( !myPreviewMode ) {
2397     bool isDumpGroups = aGroups && aGroups->length() > 0;
2398     TPythonDump aPythonDump;
2399     if(isDumpGroups) {
2400       aPythonDump << "("<<aGroups;
2401     }
2402     if(isDumpGroups)
2403       aPythonDump << ", error)";
2404     else
2405       aPythonDump <<"error";
2406
2407     aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
2408                 << theObject << ", "
2409                 << thePathMesh      << ", "
2410                 << thePathShape     << ", "
2411                 << theNodeStart     << ", "
2412                 << theHasAngles     << ", "
2413                 << theAngles        << ", "
2414                 << theHasRefPoint   << ", "
2415                 << "SMESH.PointStruct( "
2416                 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2417                 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2418                 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2419   }
2420   return aGroups;
2421 }
2422
2423 //=======================================================================
2424 //function : ExtrusionAlongPathObject1DMakeGroups
2425 //purpose  : 
2426 //=======================================================================
2427
2428 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2429 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
2430                                      SMESH::SMESH_Mesh_ptr      thePathMesh,
2431                                      GEOM::GEOM_Object_ptr      thePathShape,
2432                                      CORBA::Long                theNodeStart,
2433                                      CORBA::Boolean             theHasAngles,
2434                                      const SMESH::double_array& theAngles,
2435                                      CORBA::Boolean             theHasRefPoint,
2436                                      const SMESH::PointStruct&  theRefPoint,
2437                                      SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2438 {
2439   SMESH::long_array_var anElementsId = theObject->GetIDs();
2440   SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2441                                                       thePathMesh,
2442                                                       thePathShape,
2443                                                       theNodeStart,
2444                                                       theHasAngles,
2445                                                       theAngles,
2446                                                       theHasRefPoint,
2447                                                       theRefPoint,
2448                                                       true,
2449                                                       Error,
2450                                                       SMDSAbs_Edge);
2451   
2452   if ( !myPreviewMode ) {
2453     bool isDumpGroups = aGroups && aGroups->length() > 0;
2454     TPythonDump aPythonDump;
2455     if(isDumpGroups) {
2456       aPythonDump << "("<<aGroups;
2457     }
2458     if(isDumpGroups)
2459       aPythonDump << ", error)";
2460     else
2461       aPythonDump <<"error";
2462
2463     aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
2464                 << theObject << ", "
2465                 << thePathMesh      << ", "
2466                 << thePathShape     << ", "
2467                 << theNodeStart     << ", "
2468                 << theHasAngles     << ", "
2469                 << theAngles        << ", "
2470                 << theHasRefPoint   << ", "
2471                 << "SMESH.PointStruct( "
2472                 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2473                 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2474                 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2475   }
2476   return aGroups;
2477 }
2478
2479 //=======================================================================
2480 //function : ExtrusionAlongPathObject2DMakeGroups
2481 //purpose  : 
2482 //=======================================================================
2483
2484 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2485 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
2486                                      SMESH::SMESH_Mesh_ptr      thePathMesh,
2487                                      GEOM::GEOM_Object_ptr      thePathShape,
2488                                      CORBA::Long                theNodeStart,
2489                                      CORBA::Boolean             theHasAngles,
2490                                      const SMESH::double_array& theAngles,
2491                                      CORBA::Boolean             theHasRefPoint,
2492                                      const SMESH::PointStruct&  theRefPoint,
2493                                      SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2494 {
2495   SMESH::long_array_var anElementsId = theObject->GetIDs();
2496   SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2497                                                       thePathMesh,
2498                                                       thePathShape,
2499                                                       theNodeStart,
2500                                                       theHasAngles,
2501                                                       theAngles,
2502                                                       theHasRefPoint,
2503                                                       theRefPoint,
2504                                                       true,
2505                                                       Error,
2506                                                       SMDSAbs_Face);
2507   
2508   if ( !myPreviewMode ) {
2509     bool isDumpGroups = aGroups && aGroups->length() > 0;
2510     TPythonDump aPythonDump;
2511     if(isDumpGroups) {
2512       aPythonDump << "("<<aGroups;
2513     }
2514     if(isDumpGroups)
2515       aPythonDump << ", error)";
2516     else
2517       aPythonDump <<"error";
2518
2519     aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
2520                 << theObject << ", "
2521                 << thePathMesh      << ", "
2522                 << thePathShape     << ", "
2523                 << theNodeStart     << ", "
2524                 << theHasAngles     << ", "
2525                 << theAngles        << ", "
2526                 << theHasRefPoint   << ", "
2527                 << "SMESH.PointStruct( "
2528                 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2529                 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2530                 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2531   }
2532   return aGroups;
2533 }
2534
2535
2536 //=======================================================================
2537 //function : ExtrusionAlongPathObjX
2538 //purpose  : 
2539 //=======================================================================
2540 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2541 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr  Object,
2542                        SMESH::SMESH_IDSource_ptr  Path,
2543                        CORBA::Long                NodeStart,
2544                        CORBA::Boolean             HasAngles,
2545                        const SMESH::double_array& Angles,
2546                        CORBA::Boolean             LinearVariation,
2547                        CORBA::Boolean             HasRefPoint,
2548                        const SMESH::PointStruct&  RefPoint,
2549                        CORBA::Boolean             MakeGroups,
2550                        SMESH::ElementType         ElemType,
2551                        SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2552 {
2553   SMESH::long_array_var anElementsId = Object->GetIDs();
2554   SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
2555                                                       Path,
2556                                                       NodeStart,
2557                                                       HasAngles,
2558                                                       Angles,
2559                                                       LinearVariation,
2560                                                       HasRefPoint,
2561                                                       RefPoint,
2562                                                       MakeGroups,
2563                                                       (SMDSAbs_ElementType)ElemType,
2564                                                       Error);
2565   
2566   if ( !myPreviewMode ) {
2567     bool isDumpGroups = aGroups && aGroups->length() > 0;
2568     TPythonDump aPythonDump;
2569     if(isDumpGroups) {
2570       aPythonDump << "("<<aGroups;
2571     }
2572     if(isDumpGroups)
2573       aPythonDump << ", error)";
2574     else
2575       aPythonDump <<"error";
2576
2577     aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
2578                 << Object      << ", "
2579                 << Path        << ", "
2580                 << NodeStart   << ", "
2581                 << HasAngles   << ", "
2582                 << Angles      << ", "
2583                 << LinearVariation << ", "
2584                 << HasRefPoint << ", "
2585                 << "SMESH.PointStruct( "
2586                 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2587                 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2588                 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2589                 << ElemType << " )";
2590   }
2591   return aGroups;
2592 }
2593
2594
2595 //=======================================================================
2596 //function : ExtrusionAlongPathX
2597 //purpose  : 
2598 //=======================================================================
2599 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2600 ExtrusionAlongPathX(const SMESH::long_array&   IDsOfElements,
2601                     SMESH::SMESH_IDSource_ptr  Path,
2602                     CORBA::Long                NodeStart,
2603                     CORBA::Boolean             HasAngles,
2604                     const SMESH::double_array& Angles,
2605                     CORBA::Boolean             LinearVariation,
2606                     CORBA::Boolean             HasRefPoint,
2607                     const SMESH::PointStruct&  RefPoint,
2608                     CORBA::Boolean             MakeGroups,
2609                     SMESH::ElementType         ElemType,
2610                     SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2611 {
2612   SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
2613                                                       Path,
2614                                                       NodeStart,
2615                                                       HasAngles,
2616                                                       Angles,
2617                                                       LinearVariation,
2618                                                       HasRefPoint,
2619                                                       RefPoint,
2620                                                       MakeGroups,
2621                                                       (SMDSAbs_ElementType)ElemType,
2622                                                       Error);
2623   
2624   if ( !myPreviewMode ) {
2625     bool isDumpGroups = aGroups && aGroups->length() > 0;
2626     TPythonDump aPythonDump;
2627     if(isDumpGroups) {
2628       aPythonDump << "("<<aGroups;
2629     }
2630     if(isDumpGroups)
2631       aPythonDump << ", error)";
2632     else
2633       aPythonDump <<"error";
2634
2635     aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
2636                 << IDsOfElements << ", "
2637                 << Path        << ", "
2638                 << NodeStart   << ", "
2639                 << HasAngles   << ", "
2640                 << Angles      << ", "
2641                 << LinearVariation << ", "
2642                 << HasRefPoint << ", "
2643                 << "SMESH.PointStruct( "
2644                 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2645                 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2646                 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2647                 << ElemType << " )";
2648   }
2649   return aGroups;
2650 }
2651
2652
2653 //================================================================================
2654 /*!
2655  * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2656  * of given angles along path steps
2657   * \param PathMesh mesh containing a 1D sub-mesh on the edge, along 
2658   *                which proceeds the extrusion
2659   * \param PathShape is shape(edge); as the mesh can be complex, the edge 
2660   *                 is used to define the sub-mesh for the path
2661  */
2662 //================================================================================
2663
2664 SMESH::double_array*
2665 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr       thePathMesh,
2666                                           GEOM::GEOM_Object_ptr       thePathShape,
2667                                           const SMESH::double_array & theAngles)
2668 {
2669   SMESH::double_array_var aResult = new SMESH::double_array();
2670   int nbAngles = theAngles.length();
2671   if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
2672   {
2673     SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2674     TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2675     SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2676     if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
2677       return aResult._retn();
2678     int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
2679     if ( nbSteps == nbAngles )
2680     {
2681       aResult.inout() = theAngles;
2682     }
2683     else
2684     {
2685       aResult->length( nbSteps );
2686       double rAn2St = double( nbAngles ) / double( nbSteps );
2687       double angPrev = 0, angle;
2688       for ( int iSt = 0; iSt < nbSteps; ++iSt )
2689       {
2690         double angCur = rAn2St * ( iSt+1 );
2691         double angCurFloor  = floor( angCur );
2692         double angPrevFloor = floor( angPrev );
2693         if ( angPrevFloor == angCurFloor )
2694           angle = rAn2St * theAngles[ int( angCurFloor ) ];
2695         else
2696         {
2697           int iP = int( angPrevFloor );
2698           double angPrevCeil = ceil(angPrev);
2699           angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
2700           
2701           int iC = int( angCurFloor );
2702           if ( iC < nbAngles )
2703             angle += ( angCur - angCurFloor ) * theAngles[ iC ];
2704
2705           iP = int( angPrevCeil );
2706           while ( iC-- > iP )
2707             angle += theAngles[ iC ];
2708         }
2709         aResult[ iSt ] = angle;
2710         angPrev = angCur;
2711       }
2712     }
2713   }
2714   // Update Python script
2715   TPythonDump() << "rotAngles = " << theAngles;
2716   TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
2717                 << thePathMesh  << ", "
2718                 << thePathShape << ", "
2719                 << "rotAngles )";
2720
2721   return aResult._retn();
2722 }
2723
2724
2725 //=======================================================================
2726 //function : mirror
2727 //purpose  : 
2728 //=======================================================================
2729
2730 SMESH::ListOfGroups*
2731 SMESH_MeshEditor_i::mirror(const SMESH::long_array &           theIDsOfElements,
2732                            const SMESH::AxisStruct &           theAxis,
2733                            SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2734                            CORBA::Boolean                      theCopy,
2735                            const bool                          theMakeGroups,
2736                            ::SMESH_Mesh*                       theTargetMesh)
2737 {
2738   initData();
2739
2740   TIDSortedElemSet elements;
2741   arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2742
2743   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
2744   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
2745
2746   gp_Trsf aTrsf;
2747   switch ( theMirrorType ) {
2748   case  SMESH::SMESH_MeshEditor::POINT:
2749     aTrsf.SetMirror( P );
2750     break;
2751   case  SMESH::SMESH_MeshEditor::AXIS:
2752     aTrsf.SetMirror( gp_Ax1( P, V ));
2753     break;
2754   default:
2755     aTrsf.SetMirror( gp_Ax2( P, V ));
2756   }
2757
2758   ::SMESH_MeshEditor anEditor( myMesh );
2759   ::SMESH_MeshEditor::PGroupIDs groupIds =
2760       anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
2761
2762   if(theCopy) {
2763     storeResult(anEditor);
2764   }
2765   return theMakeGroups ? getGroups(groupIds.get()) : 0;
2766 }
2767
2768 //=======================================================================
2769 //function : Mirror
2770 //purpose  :
2771 //=======================================================================
2772
2773 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElements,
2774                                 const SMESH::AxisStruct &           theAxis,
2775                                 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2776                                 CORBA::Boolean                      theCopy)
2777 {
2778   if ( !myPreviewMode ) {
2779     TPythonDump() << this << ".Mirror( "
2780                   << theIDsOfElements << ", "
2781                   << theAxis          << ", "
2782                   << mirrorTypeName(theMirrorType) << ", "
2783                   << theCopy          << " )";
2784   }
2785   mirror(theIDsOfElements, theAxis, theMirrorType, theCopy, false);
2786 }
2787
2788
2789 //=======================================================================
2790 //function : MirrorObject
2791 //purpose  :
2792 //=======================================================================
2793
2794 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr           theObject,
2795                                       const SMESH::AxisStruct &           theAxis,
2796                                       SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2797                                       CORBA::Boolean                      theCopy)
2798 {
2799   if ( !myPreviewMode ) {
2800     TPythonDump() << this << ".MirrorObject( "
2801                   << theObject << ", "
2802                   << theAxis   << ", "
2803                   << mirrorTypeName(theMirrorType) << ", "
2804                   << theCopy   << " )";
2805   }
2806   SMESH::long_array_var anElementsId = theObject->GetIDs();
2807   mirror(anElementsId, theAxis, theMirrorType, theCopy, false);
2808 }
2809
2810 //=======================================================================
2811 //function : MirrorMakeGroups
2812 //purpose  : 
2813 //=======================================================================
2814
2815 SMESH::ListOfGroups*
2816 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array&            theIDsOfElements,
2817                                      const SMESH::AxisStruct&            theMirror,
2818                                      SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
2819 {
2820   SMESH::ListOfGroups * aGroups = mirror(theIDsOfElements, theMirror, theMirrorType, true, true);
2821   if ( !myPreviewMode ) {
2822     TPythonDump aPythonDump;
2823     DumpGroupsList(aPythonDump,aGroups);
2824     aPythonDump << this << ".MirrorMakeGroups( "
2825                 << theIDsOfElements << ", "
2826                 << theMirror << ", "
2827                 << mirrorTypeName(theMirrorType) << " )";
2828   }
2829   return aGroups;
2830 }
2831
2832 //=======================================================================
2833 //function : MirrorObjectMakeGroups
2834 //purpose  : 
2835 //=======================================================================
2836
2837 SMESH::ListOfGroups*
2838 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr           theObject,
2839                                            const SMESH::AxisStruct&            theMirror,
2840                                            SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
2841 {
2842   SMESH::long_array_var anElementsId = theObject->GetIDs();
2843   SMESH::ListOfGroups * aGroups = mirror(anElementsId, theMirror, theMirrorType, true, true);
2844   if ( !myPreviewMode ) {
2845     TPythonDump aPythonDump;
2846     DumpGroupsList(aPythonDump,aGroups);
2847     aPythonDump << this << ".MirrorObjectMakeGroups( "
2848                 << theObject << ", "
2849                 << theMirror << ", "
2850                 << mirrorTypeName(theMirrorType) << " )";
2851   }
2852   return aGroups;
2853 }
2854
2855 //=======================================================================
2856 //function : MirrorMakeMesh
2857 //purpose  : 
2858 //=======================================================================
2859
2860 SMESH::SMESH_Mesh_ptr
2861 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array&            theIDsOfElements,
2862                                    const SMESH::AxisStruct&            theMirror,
2863                                    SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2864                                    CORBA::Boolean                      theCopyGroups,
2865                                    const char*                         theMeshName)
2866 {
2867   SMESH_Mesh_i* mesh_i;
2868   SMESH::SMESH_Mesh_var mesh;
2869   { // open new scope to dump "MakeMesh" command
2870     // and then "GetGroups" using SMESH_Mesh::GetGroups()
2871     
2872     TPythonDump pydump; // to prevent dump at mesh creation
2873
2874     mesh = makeMesh( theMeshName );
2875     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
2876     if (mesh_i) {
2877       mirror(theIDsOfElements, theMirror, theMirrorType,
2878              false, theCopyGroups, & mesh_i->GetImpl());
2879       mesh_i->CreateGroupServants();
2880     }
2881     
2882     if ( !myPreviewMode ) {
2883       pydump << mesh << " = " << this << ".MirrorMakeMesh( "
2884              << theIDsOfElements << ", "
2885              << theMirror   << ", "
2886              << mirrorTypeName(theMirrorType) << ", "
2887              << theCopyGroups << ", '"
2888              << theMeshName << "' )";
2889     }
2890   }
2891
2892   //dump "GetGroups"
2893   if(!myPreviewMode && mesh_i)
2894     mesh_i->GetGroups();
2895   
2896   return mesh._retn();
2897 }
2898
2899 //=======================================================================
2900 //function : MirrorObjectMakeMesh
2901 //purpose  : 
2902 //=======================================================================
2903
2904 SMESH::SMESH_Mesh_ptr
2905 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr           theObject,
2906                                          const SMESH::AxisStruct&            theMirror,
2907                                          SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2908                                          CORBA::Boolean                      theCopyGroups,
2909                                          const char*                         theMeshName)
2910 {
2911   SMESH_Mesh_i* mesh_i;
2912   SMESH::SMESH_Mesh_var mesh;
2913   { // open new scope to dump "MakeMesh" command
2914     // and then "GetGroups" using SMESH_Mesh::GetGroups()
2915     
2916     TPythonDump pydump; // to prevent dump at mesh creation
2917
2918     mesh = makeMesh( theMeshName );
2919     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
2920     if ( mesh_i ) {
2921       SMESH::long_array_var anElementsId = theObject->GetIDs();
2922       mirror(anElementsId, theMirror, theMirrorType,
2923              false, theCopyGroups, & mesh_i->GetImpl());
2924       mesh_i->CreateGroupServants();
2925     }
2926
2927     if ( !myPreviewMode ) {
2928       pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
2929              << theObject << ", "
2930              << theMirror   << ", "
2931              << mirrorTypeName(theMirrorType) << ", "
2932              << theCopyGroups << ", '"
2933              << theMeshName << "' )";
2934     }
2935   } 
2936
2937   //dump "GetGroups"
2938   if(!myPreviewMode && mesh_i)
2939     mesh_i->GetGroups();
2940   
2941   return mesh._retn();
2942 }
2943
2944 //=======================================================================
2945 //function : translate
2946 //purpose  : 
2947 //=======================================================================
2948
2949 SMESH::ListOfGroups*
2950 SMESH_MeshEditor_i::translate(const SMESH::long_array & theIDsOfElements,
2951                               const SMESH::DirStruct &  theVector,
2952                               CORBA::Boolean            theCopy,
2953                               const bool                theMakeGroups,
2954                               ::SMESH_Mesh*             theTargetMesh)
2955 {
2956   initData();
2957
2958   TIDSortedElemSet elements;
2959   arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2960
2961   gp_Trsf aTrsf;
2962   const SMESH::PointStruct * P = &theVector.PS;
2963   aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
2964
2965   ::SMESH_MeshEditor anEditor( myMesh );
2966   ::SMESH_MeshEditor::PGroupIDs groupIds =
2967       anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
2968
2969   if(theCopy)
2970     storeResult(anEditor);
2971
2972   return theMakeGroups ? getGroups(groupIds.get()) : 0;
2973 }
2974
2975 //=======================================================================
2976 //function : Translate
2977 //purpose  :
2978 //=======================================================================
2979
2980 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
2981                                    const SMESH::DirStruct &  theVector,
2982                                    CORBA::Boolean            theCopy)
2983 {
2984   if ( !myPreviewMode ) {
2985     TPythonDump() << this << ".Translate( "
2986                   << theIDsOfElements << ", "
2987                   << theVector << ", "
2988                   << theCopy << " )";
2989   }
2990   translate(theIDsOfElements,
2991             theVector,
2992             theCopy,
2993             false);
2994 }
2995
2996 //=======================================================================
2997 //function : TranslateObject
2998 //purpose  :
2999 //=======================================================================
3000
3001 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3002                                          const SMESH::DirStruct &  theVector,
3003                                          CORBA::Boolean            theCopy)
3004 {
3005   if ( !myPreviewMode ) {
3006     TPythonDump() << this << ".TranslateObject( "
3007                   << theObject << ", "
3008                   << theVector << ", "
3009                   << theCopy << " )";
3010   }
3011   SMESH::long_array_var anElementsId = theObject->GetIDs();
3012   translate(anElementsId,
3013             theVector,
3014             theCopy,
3015             false);
3016 }
3017
3018 //=======================================================================
3019 //function : TranslateMakeGroups
3020 //purpose  : 
3021 //=======================================================================
3022
3023 SMESH::ListOfGroups*
3024 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3025                                         const SMESH::DirStruct&  theVector)
3026 {
3027   SMESH::ListOfGroups * aGroups = translate(theIDsOfElements,theVector,true,true);
3028   if ( !myPreviewMode ) {
3029     TPythonDump aPythonDump;
3030     DumpGroupsList(aPythonDump,aGroups);
3031     aPythonDump << this << ".TranslateMakeGroups( "
3032                 << theIDsOfElements << ", "
3033                 << theVector << " )";
3034   }
3035   return aGroups;
3036 }
3037
3038 //=======================================================================
3039 //function : TranslateObjectMakeGroups
3040 //purpose  : 
3041 //=======================================================================
3042
3043 SMESH::ListOfGroups*
3044 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3045                                               const SMESH::DirStruct&   theVector)
3046 {
3047   SMESH::long_array_var anElementsId = theObject->GetIDs();
3048   SMESH::ListOfGroups * aGroups = translate(anElementsId, theVector, true, true);
3049   
3050   if ( !myPreviewMode ) {
3051
3052     TPythonDump aPythonDump;
3053     DumpGroupsList(aPythonDump,aGroups);
3054     aPythonDump << this << ".TranslateObjectMakeGroups( "
3055                 << theObject << ", "
3056                 << theVector << " )";
3057   }
3058   return aGroups;
3059 }
3060
3061 //=======================================================================
3062 //function : TranslateMakeMesh
3063 //purpose  : 
3064 //=======================================================================
3065
3066 SMESH::SMESH_Mesh_ptr
3067 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3068                                       const SMESH::DirStruct&  theVector,
3069                                       CORBA::Boolean           theCopyGroups,
3070                                       const char*              theMeshName)
3071 {
3072   SMESH_Mesh_i* mesh_i;
3073   SMESH::SMESH_Mesh_var mesh;
3074   
3075   { // open new scope to dump "MakeMesh" command
3076     // and then "GetGroups" using SMESH_Mesh::GetGroups()
3077
3078     TPythonDump pydump; // to prevent dump at mesh creation
3079     
3080     mesh = makeMesh( theMeshName );
3081     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3082     
3083     if ( mesh_i ) {
3084       translate(theIDsOfElements, theVector,
3085                 false, theCopyGroups, & mesh_i->GetImpl());
3086       mesh_i->CreateGroupServants();
3087     }
3088     
3089     if ( !myPreviewMode ) {
3090       pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3091              << theIDsOfElements << ", "
3092              << theVector   << ", "
3093              << theCopyGroups << ", '"
3094              << theMeshName << "' )";
3095     }
3096   }
3097   
3098   //dump "GetGroups"
3099   if(!myPreviewMode && mesh_i)
3100     mesh_i->GetGroups();
3101   
3102   return mesh._retn();
3103 }
3104
3105 //=======================================================================
3106 //function : TranslateObjectMakeMesh
3107 //purpose  : 
3108 //=======================================================================
3109
3110 SMESH::SMESH_Mesh_ptr
3111 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3112                                             const SMESH::DirStruct&   theVector,
3113                                             CORBA::Boolean            theCopyGroups,
3114                                             const char*               theMeshName)
3115 {
3116   SMESH_Mesh_i* mesh_i;
3117   SMESH::SMESH_Mesh_var mesh;
3118   { // open new scope to dump "MakeMesh" command
3119     // and then "GetGroups" using SMESH_Mesh::GetGroups()
3120     
3121     TPythonDump pydump; // to prevent dump at mesh creation
3122     mesh = makeMesh( theMeshName );
3123     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3124     
3125     if ( mesh_i ) {
3126       SMESH::long_array_var anElementsId = theObject->GetIDs();
3127       translate(anElementsId, theVector,
3128                 false, theCopyGroups, & mesh_i->GetImpl());
3129       mesh_i->CreateGroupServants();
3130     }
3131     if ( !myPreviewMode ) {
3132       pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3133              << theObject << ", "
3134              << theVector   << ", "
3135              << theCopyGroups << ", '"
3136              << theMeshName << "' )";
3137     }
3138   }
3139   
3140   //dump "GetGroups"
3141   if(!myPreviewMode && mesh_i)
3142     mesh_i->GetGroups();
3143   
3144   return mesh._retn();
3145 }
3146
3147 //=======================================================================
3148 //function : rotate
3149 //purpose  : 
3150 //=======================================================================
3151
3152 SMESH::ListOfGroups*
3153 SMESH_MeshEditor_i::rotate(const SMESH::long_array & theIDsOfElements,
3154                            const SMESH::AxisStruct & theAxis,
3155                            CORBA::Double             theAngle,
3156                            CORBA::Boolean            theCopy,
3157                            const bool                theMakeGroups,
3158                            ::SMESH_Mesh*             theTargetMesh)
3159 {
3160   initData();
3161
3162   TIDSortedElemSet elements;
3163   arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3164
3165   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3166   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3167
3168   gp_Trsf aTrsf;
3169   aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3170
3171   ::SMESH_MeshEditor anEditor( myMesh );
3172   ::SMESH_MeshEditor::PGroupIDs groupIds =
3173       anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3174
3175   if(theCopy) {
3176     storeResult(anEditor);
3177   }
3178   return theMakeGroups ? getGroups(groupIds.get()) : 0;
3179 }
3180
3181 //=======================================================================
3182 //function : Rotate
3183 //purpose  :
3184 //=======================================================================
3185
3186 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3187                                 const SMESH::AxisStruct & theAxis,
3188                                 CORBA::Double             theAngle,
3189                                 CORBA::Boolean            theCopy)
3190 {
3191   if ( !myPreviewMode ) {
3192     TPythonDump() << this << ".Rotate( "
3193                   << theIDsOfElements << ", "
3194                   << theAxis << ", "
3195                   << theAngle << ", "
3196                   << theCopy << " )";
3197   }
3198   rotate(theIDsOfElements,
3199          theAxis,
3200          theAngle,
3201          theCopy,
3202          false);
3203 }
3204
3205 //=======================================================================
3206 //function : RotateObject
3207 //purpose  :
3208 //=======================================================================
3209
3210 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3211                                       const SMESH::AxisStruct & theAxis,
3212                                       CORBA::Double             theAngle,
3213                                       CORBA::Boolean            theCopy)
3214 {
3215   if ( !myPreviewMode ) {
3216     TPythonDump() << this << ".RotateObject( "
3217                   << theObject << ", "
3218                   << theAxis << ", "
3219                   << theAngle << ", "
3220                   << theCopy << " )";
3221   }
3222   SMESH::long_array_var anElementsId = theObject->GetIDs();
3223   rotate(anElementsId,
3224          theAxis,
3225          theAngle,
3226          theCopy,
3227          false);
3228 }
3229
3230 //=======================================================================
3231 //function : RotateMakeGroups
3232 //purpose  : 
3233 //=======================================================================
3234
3235 SMESH::ListOfGroups*
3236 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3237                                      const SMESH::AxisStruct& theAxis,
3238                                      CORBA::Double            theAngle)
3239 {
3240   SMESH::ListOfGroups * aGroups =  rotate(theIDsOfElements,theAxis,theAngle,true,true);
3241   if ( !myPreviewMode ) {
3242     TPythonDump aPythonDump;
3243     DumpGroupsList(aPythonDump,aGroups);
3244     aPythonDump << this << ".RotateMakeGroups( "
3245                 << theIDsOfElements << ", "
3246                 << theAxis << ", "
3247                 << theAngle << " )";
3248   }
3249   return aGroups;
3250 }
3251
3252 //=======================================================================
3253 //function : RotateObjectMakeGroups
3254 //purpose  : 
3255 //=======================================================================
3256
3257 SMESH::ListOfGroups*
3258 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3259                                            const SMESH::AxisStruct&  theAxis,
3260                                            CORBA::Double             theAngle)
3261 {
3262   SMESH::long_array_var anElementsId = theObject->GetIDs();
3263   SMESH::ListOfGroups * aGroups =  rotate(anElementsId,theAxis,theAngle,true,true);
3264  
3265   if ( !myPreviewMode ) {
3266     TPythonDump aPythonDump;
3267     DumpGroupsList(aPythonDump,aGroups);
3268     aPythonDump << this << ".RotateObjectMakeGroups( "
3269                 << theObject << ", "
3270                 << theAxis << ", "
3271                 << theAngle << " )";
3272   }
3273   return aGroups;
3274 }
3275
3276 //=======================================================================
3277 //function : RotateMakeMesh
3278 //purpose  : 
3279 //=======================================================================
3280
3281 SMESH::SMESH_Mesh_ptr 
3282 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
3283                                    const SMESH::AxisStruct& theAxis,
3284                                    CORBA::Double            theAngleInRadians,
3285                                    CORBA::Boolean           theCopyGroups,
3286                                    const char*              theMeshName)
3287 {
3288   SMESH::SMESH_Mesh_var mesh;
3289   SMESH_Mesh_i* mesh_i;
3290
3291   { // open new scope to dump "MakeMesh" command
3292     // and then "GetGroups" using SMESH_Mesh::GetGroups()
3293     
3294     TPythonDump pydump; // to prevent dump at mesh creation
3295
3296     mesh = makeMesh( theMeshName );
3297     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3298     
3299     if ( mesh_i ) {
3300       rotate(theIDsOfElements, theAxis, theAngleInRadians,
3301              false, theCopyGroups, & mesh_i->GetImpl());
3302       mesh_i->CreateGroupServants();
3303     }
3304     if ( !myPreviewMode ) {
3305       pydump << mesh << " = " << this << ".RotateMakeMesh( "
3306              << theIDsOfElements << ", "
3307              << theAxis << ", "
3308              << theAngleInRadians   << ", "
3309              << theCopyGroups << ", '"
3310              << theMeshName << "' )";
3311     }
3312   }
3313   
3314   //dump "GetGroups"
3315   if(!myPreviewMode && mesh_i)
3316     mesh_i->GetGroups();
3317   
3318   return mesh._retn();
3319 }
3320
3321 //=======================================================================
3322 //function : RotateObjectMakeMesh
3323 //purpose  : 
3324 //=======================================================================
3325
3326 SMESH::SMESH_Mesh_ptr 
3327 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3328                                          const SMESH::AxisStruct&  theAxis,
3329                                          CORBA::Double             theAngleInRadians,
3330                                          CORBA::Boolean            theCopyGroups,
3331                                          const char*               theMeshName)
3332 {
3333   SMESH::SMESH_Mesh_var mesh;
3334   SMESH_Mesh_i* mesh_i;
3335   
3336   {// open new scope to dump "MakeMesh" command
3337    // and then "GetGroups" using SMESH_Mesh::GetGroups()
3338     
3339     TPythonDump pydump; // to prevent dump at mesh creation
3340     mesh = makeMesh( theMeshName );
3341     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3342     
3343     if (mesh_i ) {
3344       SMESH::long_array_var anElementsId = theObject->GetIDs();
3345       rotate(anElementsId, theAxis, theAngleInRadians,
3346              false, theCopyGroups, & mesh_i->GetImpl());
3347       mesh_i->CreateGroupServants();
3348     }
3349     if ( !myPreviewMode ) {
3350       pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
3351              << theObject << ", "
3352              << theAxis << ", "
3353              << theAngleInRadians   << ", "
3354              << theCopyGroups << ", '"
3355              << theMeshName << "' )";
3356     }
3357   }
3358   
3359   //dump "GetGroups"
3360   if(!myPreviewMode && mesh_i)
3361     mesh_i->GetGroups();
3362   
3363   return mesh._retn();
3364 }
3365
3366 //=======================================================================
3367 //function : FindCoincidentNodes
3368 //purpose  :
3369 //=======================================================================
3370
3371 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
3372                                               SMESH::array_of_long_array_out GroupsOfNodes)
3373 {
3374   initData();
3375
3376   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3377   ::SMESH_MeshEditor anEditor( myMesh );
3378   set<const SMDS_MeshNode*> nodes; // no input nodes
3379   anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3380
3381   GroupsOfNodes = new SMESH::array_of_long_array;
3382   GroupsOfNodes->length( aListOfListOfNodes.size() );
3383   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3384   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
3385     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3386     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3387     SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3388     aGroup.length( aListOfNodes.size() );
3389     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3390       aGroup[ j ] = (*lIt)->GetID();
3391   }
3392   TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
3393                 << Tolerance << " )";
3394 }
3395
3396 //=======================================================================
3397 //function : FindCoincidentNodesOnPart
3398 //purpose  :
3399 //=======================================================================
3400 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr      theObject,
3401                                                    CORBA::Double                  Tolerance,
3402                                                    SMESH::array_of_long_array_out GroupsOfNodes)
3403 {
3404   initData();
3405   SMESH::long_array_var aElementsId = theObject->GetIDs();
3406
3407   SMESHDS_Mesh* aMesh = GetMeshDS();
3408   set<const SMDS_MeshNode*> nodes;
3409
3410   if ( !CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) &&
3411       SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) {
3412     for(int i = 0; i < aElementsId->length(); i++) {
3413       CORBA::Long ind = aElementsId[i];
3414       const SMDS_MeshNode * elem = aMesh->FindNode(ind);
3415       if(elem)
3416         nodes.insert(elem);
3417     }
3418   }
3419   else {
3420     for(int i = 0; i < aElementsId->length(); i++) {
3421       CORBA::Long ind = aElementsId[i];
3422       const SMDS_MeshElement * elem = aMesh->FindElement(ind);
3423       if(elem) {
3424         SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
3425         while ( nIt->more() )
3426           nodes.insert( nodes.end(),static_cast<const SMDS_MeshNode*>(nIt->next()));
3427       }
3428     }
3429   }
3430     
3431   
3432   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3433   ::SMESH_MeshEditor anEditor( myMesh );
3434   if(!nodes.empty())
3435     anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3436   
3437   GroupsOfNodes = new SMESH::array_of_long_array;
3438   GroupsOfNodes->length( aListOfListOfNodes.size() );
3439   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3440   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
3441     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3442     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3443     SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3444     aGroup.length( aListOfNodes.size() );
3445     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3446       aGroup[ j ] = (*lIt)->GetID();
3447   }
3448   TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
3449                 <<theObject<<", "
3450                 << Tolerance << " )";
3451 }
3452
3453 //=======================================================================
3454 //function : MergeNodes
3455 //purpose  :
3456 //=======================================================================
3457
3458 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
3459 {
3460   initData();
3461
3462   SMESHDS_Mesh* aMesh = GetMeshDS();
3463
3464   TPythonDump aTPythonDump;
3465   aTPythonDump << this << ".MergeNodes([";
3466   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3467   for (int i = 0; i < GroupsOfNodes.length(); i++)
3468   {
3469     const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
3470     aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
3471     list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
3472     for ( int j = 0; j < aNodeGroup.length(); j++ )
3473     {
3474       CORBA::Long index = aNodeGroup[ j ];
3475       const SMDS_MeshNode * node = aMesh->FindNode(index);
3476       if ( node )
3477         aListOfNodes.push_back( node );
3478     }
3479     if ( aListOfNodes.size() < 2 )
3480       aListOfListOfNodes.pop_back();
3481
3482     if ( i > 0 ) aTPythonDump << ", ";
3483     aTPythonDump << aNodeGroup;
3484   }
3485   ::SMESH_MeshEditor anEditor( myMesh );
3486   anEditor.MergeNodes( aListOfListOfNodes );
3487
3488   aTPythonDump <<  "])";
3489 }
3490
3491 //=======================================================================
3492 //function : FindEqualElements
3493 //purpose  :
3494 //=======================================================================
3495 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr      theObject,
3496                                            SMESH::array_of_long_array_out GroupsOfElementsID)
3497 {
3498   initData();
3499   if ( !(!CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) &&
3500          SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) ) {
3501     typedef list<int> TListOfIDs;
3502     set<const SMDS_MeshElement*> elems;
3503     SMESH::long_array_var aElementsId = theObject->GetIDs();
3504     SMESHDS_Mesh* aMesh = GetMeshDS();
3505
3506     for(int i = 0; i < aElementsId->length(); i++) {
3507       CORBA::Long anID = aElementsId[i];
3508       const SMDS_MeshElement * elem = aMesh->FindElement(anID);
3509       if (elem) {
3510         elems.insert(elem);
3511       }
3512     }
3513
3514     ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
3515     ::SMESH_MeshEditor anEditor( myMesh );
3516     anEditor.FindEqualElements( elems, aListOfListOfElementsID );
3517
3518     GroupsOfElementsID = new SMESH::array_of_long_array;
3519     GroupsOfElementsID->length( aListOfListOfElementsID.size() );
3520
3521     ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
3522     for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
3523       SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
3524       TListOfIDs& listOfIDs = *arraysIt;
3525       aGroup.length( listOfIDs.size() );
3526       TListOfIDs::iterator idIt = listOfIDs.begin();
3527       for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
3528         aGroup[ k ] = *idIt;
3529       }
3530     }
3531
3532   TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
3533                 <<theObject<<" )";
3534   }
3535 }
3536
3537 //=======================================================================
3538 //function : MergeElements
3539 //purpose  :
3540 //=======================================================================
3541
3542 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
3543 {
3544   initData();
3545
3546   TPythonDump aTPythonDump;
3547   aTPythonDump << this << ".MergeElements( [";
3548
3549   ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
3550
3551   for (int i = 0; i < GroupsOfElementsID.length(); i++) {
3552     const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
3553     aListOfListOfElementsID.push_back( list< int >() );
3554     list< int >& aListOfElemsID = aListOfListOfElementsID.back();
3555     for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
3556       CORBA::Long id = anElemsIDGroup[ j ];
3557       aListOfElemsID.push_back( id );
3558     }
3559     if ( aListOfElemsID.size() < 2 )
3560       aListOfListOfElementsID.pop_back();
3561     if ( i > 0 ) aTPythonDump << ", ";
3562     aTPythonDump << anElemsIDGroup;
3563   }
3564
3565   ::SMESH_MeshEditor anEditor( myMesh );
3566   anEditor.MergeElements(aListOfListOfElementsID);
3567
3568   aTPythonDump << "] )";
3569 }
3570
3571 //=======================================================================
3572 //function : MergeEqualElements
3573 //purpose  :
3574 //=======================================================================
3575
3576 void SMESH_MeshEditor_i::MergeEqualElements()
3577 {
3578   initData();
3579
3580   ::SMESH_MeshEditor anEditor( myMesh );
3581   anEditor.MergeEqualElements();
3582
3583   TPythonDump() << this << ".MergeEqualElements()";
3584 }
3585
3586 //================================================================================
3587 /*!
3588  * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
3589  * move the node closest to the point to point's location and return ID of the node
3590  */
3591 //================================================================================
3592
3593 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
3594                                                        CORBA::Double y,
3595                                                        CORBA::Double z,
3596                                                        CORBA::Long   theNodeID)
3597 {
3598   // We keep myNodeSearcher until any mesh modification:
3599   // 1) initData() deletes myNodeSearcher at any edition,
3600   // 2) TNodeSearcherDeleter - at any mesh compute event and mesh change
3601
3602   initData();
3603
3604   int nodeID = theNodeID;
3605   const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
3606   if ( !node )
3607   {
3608     static TNodeSearcherDeleter deleter;
3609     deleter.Set( myMesh );
3610     if ( !myNodeSearcher ) {
3611       ::SMESH_MeshEditor anEditor( myMesh );
3612       myNodeSearcher = anEditor.GetNodeSearcher();
3613     }
3614     gp_Pnt p( x,y,z );
3615     node = myNodeSearcher->FindClosestTo( p );
3616   }
3617   if ( node ) {
3618     nodeID = node->GetID();
3619     if ( myPreviewMode ) // make preview data
3620     {
3621       // in a preview mesh, make edges linked to a node
3622       TPreviewMesh tmpMesh;
3623       TIDSortedElemSet linkedNodes;
3624       ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
3625       TIDSortedElemSet::iterator nIt = linkedNodes.begin();
3626       for ( ; nIt != linkedNodes.end(); ++nIt )
3627       {
3628         SMDS_MeshEdge edge( node, cast2Node( *nIt ));
3629         tmpMesh.Copy( &edge );
3630       }
3631       // move copied node
3632       node = tmpMesh.GetMeshDS()->FindNode( nodeID );
3633       if ( node )
3634         tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
3635       // fill preview data
3636       ::SMESH_MeshEditor anEditor( & tmpMesh );
3637       storeResult( anEditor );
3638     }
3639     else
3640     {
3641       GetMeshDS()->MoveNode(node, x, y, z);
3642     }
3643   }
3644
3645   if ( !myPreviewMode ) {
3646     TPythonDump() << "nodeID = " << this
3647                   << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
3648                   << ", " << nodeID << " )";
3649   }
3650
3651   return nodeID;
3652 }
3653
3654 //=======================================================================
3655 //function : convError
3656 //purpose  :
3657 //=======================================================================
3658
3659 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
3660
3661 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
3662 {
3663   switch ( e ) {
3664   RETCASE( SEW_OK );
3665   RETCASE( SEW_BORDER1_NOT_FOUND );
3666   RETCASE( SEW_BORDER2_NOT_FOUND );
3667   RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
3668   RETCASE( SEW_BAD_SIDE_NODES );
3669   RETCASE( SEW_VOLUMES_TO_SPLIT );
3670   RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
3671   RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
3672   RETCASE( SEW_BAD_SIDE1_NODES );
3673   RETCASE( SEW_BAD_SIDE2_NODES );
3674   }
3675   return SMESH::SMESH_MeshEditor::SEW_OK;
3676 }
3677
3678 //=======================================================================
3679 //function : SewFreeBorders
3680 //purpose  :
3681 //=======================================================================
3682
3683 SMESH::SMESH_MeshEditor::Sew_Error
3684   SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
3685                                      CORBA::Long SecondNodeID1,
3686                                      CORBA::Long LastNodeID1,
3687                                      CORBA::Long FirstNodeID2,
3688                                      CORBA::Long SecondNodeID2,
3689                                      CORBA::Long LastNodeID2,
3690                                      CORBA::Boolean CreatePolygons,
3691                                      CORBA::Boolean CreatePolyedrs)
3692 {
3693   initData();
3694
3695   SMESHDS_Mesh* aMesh = GetMeshDS();
3696
3697   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
3698   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
3699   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
3700   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
3701   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
3702   const SMDS_MeshNode* aSide2ThirdNode   = aMesh->FindNode( LastNodeID2   );
3703
3704   if (!aBorderFirstNode ||
3705       !aBorderSecondNode||
3706       !aBorderLastNode)
3707     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
3708   if (!aSide2FirstNode  ||
3709       !aSide2SecondNode ||
3710       !aSide2ThirdNode)
3711     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
3712
3713   TPythonDump() << "error = " << this << ".SewFreeBorders( "
3714                 << FirstNodeID1  << ", "
3715                 << SecondNodeID1 << ", "
3716                 << LastNodeID1   << ", "
3717                 << FirstNodeID2  << ", "
3718                 << SecondNodeID2 << ", "
3719                 << LastNodeID2   << ", "
3720                 << CreatePolygons<< ", "
3721                 << CreatePolyedrs<< " )";
3722
3723   ::SMESH_MeshEditor anEditor( myMesh );
3724   SMESH::SMESH_MeshEditor::Sew_Error error =
3725     convError( anEditor.SewFreeBorder (aBorderFirstNode,
3726                                        aBorderSecondNode,
3727                                        aBorderLastNode,
3728                                        aSide2FirstNode,
3729                                        aSide2SecondNode,
3730                                        aSide2ThirdNode,
3731                                        true,
3732                                        CreatePolygons,
3733                                        CreatePolyedrs) );
3734
3735   storeResult(anEditor);
3736
3737   return error;
3738 }
3739
3740
3741 //=======================================================================
3742 //function : SewConformFreeBorders
3743 //purpose  :
3744 //=======================================================================
3745
3746 SMESH::SMESH_MeshEditor::Sew_Error
3747 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
3748                                           CORBA::Long SecondNodeID1,
3749                                           CORBA::Long LastNodeID1,
3750                                           CORBA::Long FirstNodeID2,
3751                                           CORBA::Long SecondNodeID2)
3752 {
3753   initData();
3754
3755   SMESHDS_Mesh* aMesh = GetMeshDS();
3756
3757   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
3758   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
3759   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
3760   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
3761   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
3762   const SMDS_MeshNode* aSide2ThirdNode   = 0;
3763
3764   if (!aBorderFirstNode ||
3765       !aBorderSecondNode||
3766       !aBorderLastNode )
3767     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
3768   if (!aSide2FirstNode  ||
3769       !aSide2SecondNode)
3770     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
3771
3772   TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
3773                 << FirstNodeID1  << ", "
3774                 << SecondNodeID1 << ", "
3775                 << LastNodeID1   << ", "
3776                 << FirstNodeID2  << ", "
3777                 << SecondNodeID2 << " )";
3778
3779   ::SMESH_MeshEditor anEditor( myMesh );
3780   SMESH::SMESH_MeshEditor::Sew_Error error =
3781     convError( anEditor.SewFreeBorder (aBorderFirstNode,
3782                                        aBorderSecondNode,
3783                                        aBorderLastNode,
3784                                        aSide2FirstNode,
3785                                        aSide2SecondNode,
3786                                        aSide2ThirdNode,
3787                                        true,
3788                                        false, false) );
3789
3790   storeResult(anEditor);
3791
3792   return error;
3793 }
3794
3795
3796 //=======================================================================
3797 //function : SewBorderToSide
3798 //purpose  :
3799 //=======================================================================
3800
3801 SMESH::SMESH_MeshEditor::Sew_Error
3802 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
3803                                     CORBA::Long SecondNodeIDOnFreeBorder,
3804                                     CORBA::Long LastNodeIDOnFreeBorder,
3805                                     CORBA::Long FirstNodeIDOnSide,
3806                                     CORBA::Long LastNodeIDOnSide,
3807                                     CORBA::Boolean CreatePolygons,
3808                                     CORBA::Boolean CreatePolyedrs)
3809 {
3810   initData();
3811
3812   SMESHDS_Mesh* aMesh = GetMeshDS();
3813
3814   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeIDOnFreeBorder  );
3815   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
3816   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeIDOnFreeBorder   );
3817   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeIDOnSide  );
3818   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( LastNodeIDOnSide );
3819   const SMDS_MeshNode* aSide2ThirdNode   = 0;
3820
3821   if (!aBorderFirstNode ||
3822       !aBorderSecondNode||
3823       !aBorderLastNode  )
3824     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
3825   if (!aSide2FirstNode  ||
3826       !aSide2SecondNode)
3827     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
3828
3829   TPythonDump() << "error = " << this << ".SewBorderToSide( "
3830                 << FirstNodeIDOnFreeBorder  << ", "
3831                 << SecondNodeIDOnFreeBorder << ", "
3832                 << LastNodeIDOnFreeBorder   << ", "
3833                 << FirstNodeIDOnSide        << ", "
3834                 << LastNodeIDOnSide         << ", "
3835                 << CreatePolygons           << ", "
3836                 << CreatePolyedrs           << ") ";
3837
3838   ::SMESH_MeshEditor anEditor( myMesh );
3839   SMESH::SMESH_MeshEditor::Sew_Error error =
3840     convError( anEditor.SewFreeBorder (aBorderFirstNode,
3841                                        aBorderSecondNode,
3842                                        aBorderLastNode,
3843                                        aSide2FirstNode,
3844                                        aSide2SecondNode,
3845                                        aSide2ThirdNode,
3846                                        false,
3847                                        CreatePolygons,
3848                                        CreatePolyedrs) );
3849
3850   storeResult(anEditor);
3851
3852   return error;
3853 }
3854
3855
3856 //=======================================================================
3857 //function : SewSideElements
3858 //purpose  :
3859 //=======================================================================
3860
3861 SMESH::SMESH_MeshEditor::Sew_Error
3862 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
3863                                     const SMESH::long_array& IDsOfSide2Elements,
3864                                     CORBA::Long NodeID1OfSide1ToMerge,
3865                                     CORBA::Long NodeID1OfSide2ToMerge,
3866                                     CORBA::Long NodeID2OfSide1ToMerge,
3867                                     CORBA::Long NodeID2OfSide2ToMerge)
3868 {
3869   initData();
3870
3871   SMESHDS_Mesh* aMesh = GetMeshDS();
3872
3873   const SMDS_MeshNode* aFirstNode1ToMerge  = aMesh->FindNode( NodeID1OfSide1ToMerge );
3874   const SMDS_MeshNode* aFirstNode2ToMerge  = aMesh->FindNode( NodeID1OfSide2ToMerge );
3875   const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
3876   const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
3877
3878   if (!aFirstNode1ToMerge ||
3879       !aFirstNode2ToMerge )
3880     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
3881   if (!aSecondNode1ToMerge||
3882       !aSecondNode2ToMerge)
3883     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
3884
3885   TIDSortedElemSet aSide1Elems, aSide2Elems;
3886   arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
3887   arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
3888
3889   TPythonDump() << "error = " << this << ".SewSideElements( "
3890                 << IDsOfSide1Elements << ", "
3891                 << IDsOfSide2Elements << ", "
3892                 << NodeID1OfSide1ToMerge << ", "
3893                 << NodeID1OfSide2ToMerge << ", "
3894                 << NodeID2OfSide1ToMerge << ", "
3895                 << NodeID2OfSide2ToMerge << ")";
3896
3897   ::SMESH_MeshEditor anEditor( myMesh );
3898   SMESH::SMESH_MeshEditor::Sew_Error error =
3899     convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
3900                                          aFirstNode1ToMerge,
3901                                          aFirstNode2ToMerge,
3902                                          aSecondNode1ToMerge,
3903                                          aSecondNode2ToMerge));
3904
3905   storeResult(anEditor);
3906
3907   return error;
3908 }
3909
3910 //================================================================================
3911 /*!
3912  * \brief Set new nodes for given element
3913   * \param ide - element id
3914   * \param newIDs - new node ids
3915   * \retval CORBA::Boolean - true if result is OK
3916  */
3917 //================================================================================
3918
3919 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
3920                                                    const SMESH::long_array& newIDs)
3921 {
3922   initData();
3923
3924   const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
3925   if(!elem) return false;
3926
3927   int nbn = newIDs.length();
3928   int i=0;
3929   vector<const SMDS_MeshNode*> aNodes(nbn);
3930   int nbn1=-1;
3931   for(; i<nbn; i++) {
3932     const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
3933     if(aNode) {
3934       nbn1++;
3935       aNodes[nbn1] = aNode;
3936     }
3937   }
3938   TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
3939                 << ide << ", " << newIDs << " )";
3940 #ifdef _DEBUG_
3941   TPythonDump() << "print 'ChangeElemNodes: ', isDone";
3942 #endif
3943
3944   return GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
3945 }
3946   
3947 //================================================================================
3948 /*!
3949  * \brief Update myLastCreated* or myPreviewData
3950   * \param anEditor - it contains last modification results
3951  */
3952 //================================================================================
3953
3954 void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& anEditor)
3955 {
3956   if ( myPreviewMode ) { // --- MeshPreviewStruct filling --- 
3957
3958     list<int> aNodesConnectivity;
3959     typedef map<int, int> TNodesMap;
3960     TNodesMap nodesMap;
3961
3962     TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
3963     SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
3964
3965     SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
3966     int nbEdges = aMeshDS->NbEdges();
3967     int nbFaces = aMeshDS->NbFaces();
3968     int nbVolum = aMeshDS->NbVolumes();
3969     switch ( previewType ) {
3970     case SMDSAbs_Edge  : nbFaces = nbVolum = 0; break;
3971     case SMDSAbs_Face  : nbEdges = nbVolum = 0; break;
3972     case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
3973     default:;
3974     }
3975     myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
3976     myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
3977     int i = 0, j = 0;
3978     SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
3979
3980     while ( itMeshElems->more() ) {
3981       const SMDS_MeshElement* aMeshElem = itMeshElems->next();
3982       if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
3983         continue;
3984
3985       SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
3986       while ( itElemNodes->more() ) {
3987         const SMDS_MeshNode* aMeshNode = 
3988           static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
3989         int aNodeID = aMeshNode->GetID();
3990         TNodesMap::iterator anIter = nodesMap.find(aNodeID);
3991         if ( anIter == nodesMap.end() ) {
3992           // filling the nodes coordinates
3993           myPreviewData->nodesXYZ[j].x = aMeshNode->X();
3994           myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
3995           myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
3996           anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
3997           j++;
3998         }
3999         aNodesConnectivity.push_back(anIter->second);
4000       }
4001
4002       // filling the elements types
4003       SMDSAbs_ElementType aType;
4004       bool isPoly;
4005       /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
4006         aType = SMDSAbs_Node;
4007         isPoly = false;
4008       }
4009       else*/ {
4010         aType = aMeshElem->GetType();
4011         isPoly = aMeshElem->IsPoly();
4012       }
4013
4014       myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
4015       myPreviewData->elementTypes[i].isPoly = isPoly;
4016       myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
4017       i++;
4018
4019     }
4020     myPreviewData->nodesXYZ.length( j );
4021
4022     // filling the elements connectivities
4023     list<int>::iterator aConnIter = aNodesConnectivity.begin();
4024     myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
4025     for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
4026       myPreviewData->elementConnectivities[i] = *aConnIter;
4027     
4028     return;
4029   }
4030
4031   {
4032     // add new nodes into myLastCreatedNodes
4033     const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
4034     myLastCreatedNodes->length(aSeq.Length());
4035     for(int i=0; i<aSeq.Length(); i++)
4036       myLastCreatedNodes[i] = aSeq.Value(i+1)->GetID();
4037   }
4038   {
4039     // add new elements into myLastCreatedElems
4040     const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
4041     myLastCreatedElems->length(aSeq.Length());
4042     for(int i=0; i<aSeq.Length(); i++)
4043       myLastCreatedElems[i] = aSeq.Value(i+1)->GetID();
4044   }
4045 }
4046
4047 //================================================================================
4048 /*!
4049  * Return data of mesh edition preview
4050  */
4051 //================================================================================
4052
4053 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
4054 {
4055   return myPreviewData._retn();
4056 }
4057
4058 //================================================================================
4059 /*!
4060  * \brief Returns list of it's IDs of created nodes
4061   * \retval SMESH::long_array* - list of node ID
4062  */
4063 //================================================================================
4064
4065 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
4066 {
4067   return myLastCreatedNodes._retn();
4068 }
4069
4070 //================================================================================
4071 /*!
4072  * \brief Returns list of it's IDs of created elements
4073   * \retval SMESH::long_array* - list of elements' ID
4074  */
4075 //================================================================================
4076
4077 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
4078 {
4079   return myLastCreatedElems._retn();
4080 }
4081
4082 //=======================================================================
4083 //function : ConvertToQuadratic
4084 //purpose  :
4085 //=======================================================================
4086
4087 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
4088 {
4089   ::SMESH_MeshEditor anEditor( myMesh );
4090   anEditor.ConvertToQuadratic(theForce3d);
4091   TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
4092 }
4093
4094 //=======================================================================
4095 //function : ConvertFromQuadratic
4096 //purpose  : 
4097 //=======================================================================
4098
4099 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
4100 {
4101   ::SMESH_MeshEditor anEditor( myMesh );
4102   CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
4103   TPythonDump() << this << ".ConvertFromQuadratic()";
4104   return isDone;
4105 }
4106
4107 //=======================================================================
4108 //function : makeMesh
4109 //purpose  : create a named imported mesh 
4110 //=======================================================================
4111
4112 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
4113 {
4114   SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
4115   SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
4116   SALOMEDS::Study_var study = gen->GetCurrentStudy();
4117   SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
4118   gen->SetName( meshSO, theMeshName, "Mesh" );
4119   gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
4120
4121   return mesh._retn();
4122 }
4123
4124 //=======================================================================
4125 //function : DumpGroupsList
4126 //purpose  :
4127 //=======================================================================
4128 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump &               theDumpPython, 
4129                                         const SMESH::ListOfGroups * theGroupList)
4130 {
4131   bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
4132   if(isDumpGroupList) {
4133     theDumpPython << theGroupList << " = ";
4134   }
4135 }
4136
4137 //================================================================================
4138 /*!
4139   \brief Creates a hole in a mesh by doubling the nodes of some particular elements
4140   \param theNodes - identifiers of nodes to be doubled
4141   \param theModifiedElems - identifiers of elements to be updated by the new (doubled) 
4142          nodes. If list of element identifiers is empty then nodes are doubled but 
4143          they not assigned to elements
4144   \return TRUE if operation has been completed successfully, FALSE otherwise
4145   \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
4146 */
4147 //================================================================================
4148
4149 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes, 
4150                                                 const SMESH::long_array& theModifiedElems )
4151 {
4152   initData();
4153
4154   ::SMESH_MeshEditor aMeshEditor( myMesh );
4155   list< int > aListOfNodes;
4156   int i, n;
4157   for ( i = 0, n = theNodes.length(); i < n; i++ )
4158     aListOfNodes.push_back( theNodes[ i ] );
4159
4160   list< int > aListOfElems;
4161   for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
4162     aListOfElems.push_back( theModifiedElems[ i ] );
4163
4164   bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems );
4165
4166   storeResult( aMeshEditor) ;
4167
4168   return aResult;
4169 }
4170
4171 //================================================================================
4172 /*!
4173   \brief Creates a hole in a mesh by doubling the nodes of some particular elements
4174   This method provided for convenience works as DoubleNodes() described above.
4175   \param theNodeId - identifier of node to be doubled.
4176   \param theModifiedElems - identifiers of elements to be updated.
4177   \return TRUE if operation has been completed successfully, FALSE otherwise
4178   \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
4179 */
4180 //================================================================================
4181
4182 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long              theNodeId, 
4183                                                const SMESH::long_array& theModifiedElems )
4184 {
4185   SMESH::long_array_var aNodes = new SMESH::long_array;
4186   aNodes->length( 1 );
4187   aNodes[ 0 ] = theNodeId;
4188   return DoubleNodes( aNodes, theModifiedElems );
4189 }
4190
4191 //================================================================================
4192 /*!
4193   \brief Creates a hole in a mesh by doubling the nodes of some particular elements
4194   This method provided for convenience works as DoubleNodes() described above.
4195   \param theNodes - group of nodes to be doubled.
4196   \param theModifiedElems - group of elements to be updated.
4197   \return TRUE if operation has been completed successfully, FALSE otherwise
4198   \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
4199 */
4200 //================================================================================
4201
4202 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup( 
4203   SMESH::SMESH_GroupBase_ptr theNodes,
4204   SMESH::SMESH_GroupBase_ptr theModifiedElems )
4205 {
4206   if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
4207     return false;
4208
4209   SMESH::long_array_var aNodes = theNodes->GetListOfID();
4210   SMESH::long_array_var aModifiedElems;
4211   if ( !CORBA::is_nil( theModifiedElems ) )
4212     aModifiedElems = theModifiedElems->GetListOfID();
4213   else 
4214   {
4215     aModifiedElems = new SMESH::long_array;
4216     aModifiedElems->length( 0 );
4217   }
4218
4219   return DoubleNodes( aNodes, aModifiedElems );
4220 }
4221
4222 //================================================================================
4223 /*!
4224   \brief Creates a hole in a mesh by doubling the nodes of some particular elements
4225   This method provided for convenience works as DoubleNodes() described above.
4226   \param theNodes - list of groups of nodes to be doubled
4227   \param theModifiedElems - list of groups of elements to be updated.
4228   \return TRUE if operation has been completed successfully, FALSE otherwise
4229   \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
4230 */
4231 //================================================================================
4232
4233 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups( 
4234   const SMESH::ListOfGroups& theNodes,
4235   const SMESH::ListOfGroups& theModifiedElems )
4236 {
4237   initData();
4238
4239   ::SMESH_MeshEditor aMeshEditor( myMesh );
4240
4241   std::list< int > aNodes;
4242   int i, n, j, m;
4243   for ( i = 0, n = theNodes.length(); i < n; i++ )
4244   {
4245     SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
4246     if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
4247     {
4248       SMESH::long_array_var aCurr = aGrp->GetListOfID();
4249       for ( j = 0, m = aCurr->length(); j < m; j++ )
4250         aNodes.push_back( aCurr[ j ] );
4251     }
4252   }
4253
4254   std::list< int > anElems;
4255   for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
4256   {
4257     SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
4258     if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
4259     {
4260       SMESH::long_array_var aCurr = aGrp->GetListOfID();
4261       for ( j = 0, m = aCurr->length(); j < m; j++ )
4262         anElems.push_back( aCurr[ j ] );
4263     }
4264   }
4265
4266   bool aResult = aMeshEditor.DoubleNodes( aNodes, anElems );
4267
4268   storeResult( aMeshEditor) ;
4269
4270   return aResult;
4271 }