Salome HOME
0020095: EDF 896 SMESH : Advanced Mesh info on a group
[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 =
921         (aType == SMDSAbs_Node ? aMesh->FindNode(ind)
922                               : aMesh->FindElement(ind));
923       if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
924         aMap.insert( elem );
925     }
926   }
927 }
928
929 //=============================================================================
930 /*!
931  *
932  */
933 //=============================================================================
934 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfElements,
935                                               SMESH::NumericalFunctor_ptr Criterion,
936                                               CORBA::Double               MaxAngle)
937 {
938   initData();
939
940   SMESHDS_Mesh* aMesh = GetMeshDS();
941   TIDSortedElemSet faces;
942   arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
943
944   SMESH::NumericalFunctor_i* aNumericalFunctor =
945     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
946   SMESH::Controls::NumericalFunctorPtr aCrit;
947   if ( !aNumericalFunctor )
948     aCrit.reset( new SMESH::Controls::AspectRatio() );
949   else
950     aCrit = aNumericalFunctor->GetNumericalFunctor();
951
952   // Update Python script
953   TPythonDump() << "isDone = " << this << ".TriToQuad( "
954                 << IDsOfElements << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
955 #ifdef _DEBUG_
956   TPythonDump() << "print 'TriToQuad: ', isDone";
957 #endif
958
959   ::SMESH_MeshEditor anEditor( myMesh );
960
961   bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
962
963   storeResult(anEditor);
964
965   return stat;
966 }
967
968
969 //=============================================================================
970 /*!
971  *
972  */
973 //=============================================================================
974 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr   theObject,
975                                                     SMESH::NumericalFunctor_ptr Criterion,
976                                                     CORBA::Double               MaxAngle)
977 {
978   initData();
979
980   SMESH::long_array_var anElementsId = theObject->GetIDs();
981   CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
982
983   // Clear python line(s), created by TriToQuad()
984   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
985   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
986 #ifdef _DEBUG_
987   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
988 #endif
989
990   SMESH::NumericalFunctor_i* aNumericalFunctor =
991     SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
992
993   // Update Python script
994   TPythonDump() << "isDone = " << this << ".TriToQuadObject("
995                 << theObject << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
996 #ifdef _DEBUG_
997   TPythonDump() << "print 'TriToQuadObject: ', isDone";
998 #endif
999
1000   return isDone;
1001 }
1002
1003
1004 //=============================================================================
1005 /*!
1006  *
1007  */
1008 //=============================================================================
1009 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array &   IDsOfElements,
1010                                               SMESH::NumericalFunctor_ptr Criterion)
1011 {
1012   initData();
1013
1014   SMESHDS_Mesh* aMesh = GetMeshDS();
1015   TIDSortedElemSet faces;
1016   arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1017
1018   SMESH::NumericalFunctor_i* aNumericalFunctor =
1019     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1020   SMESH::Controls::NumericalFunctorPtr aCrit;
1021   if ( !aNumericalFunctor )
1022     aCrit.reset( new SMESH::Controls::AspectRatio() );
1023   else
1024     aCrit = aNumericalFunctor->GetNumericalFunctor();
1025
1026
1027   // Update Python script
1028   TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1029 #ifdef _DEBUG_
1030   TPythonDump() << "print 'QuadToTri: ', isDone";
1031 #endif
1032
1033   ::SMESH_MeshEditor anEditor( myMesh );
1034   CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
1035
1036   storeResult(anEditor);
1037
1038   return stat;
1039 }
1040
1041
1042 //=============================================================================
1043 /*!
1044  *
1045  */
1046 //=============================================================================
1047 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr   theObject,
1048                                                     SMESH::NumericalFunctor_ptr Criterion)
1049 {
1050   initData();
1051
1052   SMESH::long_array_var anElementsId = theObject->GetIDs();
1053   CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1054
1055   // Clear python line(s), created by QuadToTri()
1056   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1057   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1058 #ifdef _DEBUG_
1059   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1060 #endif
1061
1062   SMESH::NumericalFunctor_i* aNumericalFunctor =
1063     SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1064
1065   // Update Python script
1066   TPythonDump() << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1067 #ifdef _DEBUG_
1068   TPythonDump() << "print 'QuadToTriObject: ', isDone";
1069 #endif
1070
1071   return isDone;
1072 }
1073
1074
1075 //=============================================================================
1076 /*!
1077  *
1078  */
1079 //=============================================================================
1080 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1081                                               CORBA::Boolean            Diag13)
1082 {
1083   initData();
1084
1085   SMESHDS_Mesh* aMesh = GetMeshDS();
1086   TIDSortedElemSet faces;
1087   arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1088
1089   // Update Python script
1090   TPythonDump() << "isDone = " << this << ".SplitQuad( "
1091                 << IDsOfElements << ", " << Diag13 << " )";
1092 #ifdef _DEBUG_
1093   TPythonDump() << "print 'SplitQuad: ', isDone";
1094 #endif
1095
1096   ::SMESH_MeshEditor anEditor( myMesh );
1097   CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
1098
1099   storeResult(anEditor);
1100
1101   return stat;
1102 }
1103
1104
1105 //=============================================================================
1106 /*!
1107  *
1108  */
1109 //=============================================================================
1110 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1111                                                     CORBA::Boolean            Diag13)
1112 {
1113   initData();
1114
1115   SMESH::long_array_var anElementsId = theObject->GetIDs();
1116   CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1117
1118   // Clear python line(s), created by SplitQuad()
1119   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1120   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1121 #ifdef _DEBUG_
1122   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1123 #endif
1124
1125   // Update Python script
1126   TPythonDump() << "isDone = " << this << ".SplitQuadObject( "
1127                 << theObject << ", " << Diag13 << " )";
1128 #ifdef _DEBUG_
1129   TPythonDump() << "print 'SplitQuadObject: ', isDone";
1130 #endif
1131
1132   return isDone;
1133 }
1134
1135
1136 //=============================================================================
1137 /*!
1138  *  BestSplit
1139  */
1140 //=============================================================================
1141 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long                 IDOfQuad,
1142                                            SMESH::NumericalFunctor_ptr Criterion)
1143 {
1144   const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
1145   if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1146   {
1147     SMESH::NumericalFunctor_i* aNumericalFunctor =
1148       dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1149     SMESH::Controls::NumericalFunctorPtr aCrit;
1150     if (aNumericalFunctor)
1151       aCrit = aNumericalFunctor->GetNumericalFunctor();
1152     else
1153       aCrit.reset(new SMESH::Controls::AspectRatio());
1154
1155     ::SMESH_MeshEditor anEditor (myMesh);
1156     return anEditor.BestSplit(quad, aCrit);
1157   }
1158   return -1;
1159 }
1160
1161
1162 //=======================================================================
1163 //function : Smooth
1164 //purpose  :
1165 //=======================================================================
1166
1167 CORBA::Boolean
1168   SMESH_MeshEditor_i::Smooth(const SMESH::long_array &              IDsOfElements,
1169                              const SMESH::long_array &              IDsOfFixedNodes,
1170                              CORBA::Long                            MaxNbOfIterations,
1171                              CORBA::Double                          MaxAspectRatio,
1172                              SMESH::SMESH_MeshEditor::Smooth_Method Method)
1173 {
1174   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1175                 MaxAspectRatio, Method, false );
1176 }
1177
1178
1179 //=======================================================================
1180 //function : SmoothParametric
1181 //purpose  :
1182 //=======================================================================
1183
1184 CORBA::Boolean
1185   SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array &              IDsOfElements,
1186                                        const SMESH::long_array &              IDsOfFixedNodes,
1187                                        CORBA::Long                            MaxNbOfIterations,
1188                                        CORBA::Double                          MaxAspectRatio,
1189                                        SMESH::SMESH_MeshEditor::Smooth_Method Method)
1190 {
1191   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1192                 MaxAspectRatio, Method, true );
1193 }
1194
1195
1196 //=======================================================================
1197 //function : SmoothObject
1198 //purpose  :
1199 //=======================================================================
1200
1201 CORBA::Boolean
1202   SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr              theObject,
1203                                    const SMESH::long_array &              IDsOfFixedNodes,
1204                                    CORBA::Long                            MaxNbOfIterations,
1205                                    CORBA::Double                          MaxAspectRatio,
1206                                    SMESH::SMESH_MeshEditor::Smooth_Method Method)
1207 {
1208   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1209                        MaxAspectRatio, Method, false);
1210 }
1211
1212
1213 //=======================================================================
1214 //function : SmoothParametricObject
1215 //purpose  :
1216 //=======================================================================
1217
1218 CORBA::Boolean
1219   SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr              theObject,
1220                                    const SMESH::long_array &              IDsOfFixedNodes,
1221                                    CORBA::Long                            MaxNbOfIterations,
1222                                    CORBA::Double                          MaxAspectRatio,
1223                                    SMESH::SMESH_MeshEditor::Smooth_Method Method)
1224 {
1225   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1226                        MaxAspectRatio, Method, true);
1227 }
1228
1229
1230 //=============================================================================
1231 /*!
1232  *
1233  */
1234 //=============================================================================
1235
1236 CORBA::Boolean
1237   SMESH_MeshEditor_i::smooth(const SMESH::long_array &              IDsOfElements,
1238                              const SMESH::long_array &              IDsOfFixedNodes,
1239                              CORBA::Long                            MaxNbOfIterations,
1240                              CORBA::Double                          MaxAspectRatio,
1241                              SMESH::SMESH_MeshEditor::Smooth_Method Method,
1242                              bool                                   IsParametric)
1243 {
1244   initData();
1245
1246   SMESHDS_Mesh* aMesh = GetMeshDS();
1247
1248   TIDSortedElemSet elements;
1249   arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1250
1251   set<const SMDS_MeshNode*> fixedNodes;
1252   for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1253     CORBA::Long index = IDsOfFixedNodes[i];
1254     const SMDS_MeshNode * node = aMesh->FindNode(index);
1255     if ( node )
1256       fixedNodes.insert( node );
1257   }
1258   ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1259   if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1260     method = ::SMESH_MeshEditor::CENTROIDAL;
1261
1262   ::SMESH_MeshEditor anEditor( myMesh );
1263   anEditor.Smooth(elements, fixedNodes, method,
1264                   MaxNbOfIterations, MaxAspectRatio, IsParametric );
1265
1266   storeResult(anEditor);
1267
1268   // Update Python script
1269   TPythonDump() << "isDone = " << this << "."
1270                 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1271                 << IDsOfElements << ", "     << IDsOfFixedNodes << ", "
1272                 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1273                 << "SMESH.SMESH_MeshEditor."
1274                 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1275                      "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1276 #ifdef _DEBUG_
1277   TPythonDump() << "print 'Smooth: ', isDone";
1278 #endif
1279
1280   return true;
1281 }
1282
1283
1284 //=============================================================================
1285 /*!
1286  *
1287  */
1288 //=============================================================================
1289
1290 CORBA::Boolean
1291 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr              theObject,
1292                                  const SMESH::long_array &              IDsOfFixedNodes,
1293                                  CORBA::Long                            MaxNbOfIterations,
1294                                  CORBA::Double                          MaxAspectRatio,
1295                                  SMESH::SMESH_MeshEditor::Smooth_Method Method,
1296                                  bool                                   IsParametric)
1297 {
1298   initData();
1299
1300   SMESH::long_array_var anElementsId = theObject->GetIDs();
1301   CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1302                                   MaxAspectRatio, Method, IsParametric);
1303
1304   // Clear python line(s), created by Smooth()
1305   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1306   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1307 #ifdef _DEBUG_
1308   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1309 #endif
1310
1311   // Update Python script
1312   TPythonDump() << "isDone = " << this << "."
1313                 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1314                 << theObject << ", " << IDsOfFixedNodes << ", "
1315                 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1316                 << "SMESH.SMESH_MeshEditor."
1317                 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1318                      "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1319 #ifdef _DEBUG_
1320   TPythonDump() << "print 'SmoothObject: ', isDone";
1321 #endif
1322
1323   return isDone;
1324 }
1325
1326
1327 //=============================================================================
1328 /*!
1329  *
1330  */
1331 //=============================================================================
1332
1333 void SMESH_MeshEditor_i::RenumberNodes()
1334 {
1335   // Update Python script
1336   TPythonDump() << this << ".RenumberNodes()";
1337
1338   GetMeshDS()->Renumber( true );
1339 }
1340
1341
1342 //=============================================================================
1343 /*!
1344  *
1345  */
1346 //=============================================================================
1347
1348 void SMESH_MeshEditor_i::RenumberElements()
1349 {
1350   // Update Python script
1351   TPythonDump() << this << ".RenumberElements()";
1352
1353   GetMeshDS()->Renumber( false );
1354 }
1355
1356 //=======================================================================
1357   /*!
1358    * \brief Return groups by their IDs
1359    */
1360 //=======================================================================
1361
1362 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
1363 {
1364   if ( !groupIDs )
1365     return 0;
1366   myMesh_i->CreateGroupServants();
1367   return myMesh_i->GetGroups( *groupIDs );
1368 }
1369
1370 //=======================================================================
1371 //function : rotationSweep
1372 //purpose  : 
1373 //=======================================================================
1374
1375 SMESH::ListOfGroups*
1376 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
1377                                   const SMESH::AxisStruct & theAxis,
1378                                   CORBA::Double             theAngleInRadians,
1379                                   CORBA::Long               theNbOfSteps,
1380                                   CORBA::Double             theTolerance,
1381                                   const bool                theMakeGroups,
1382                                   const SMDSAbs_ElementType theElementType)
1383 {
1384   initData();
1385
1386   TIDSortedElemSet inElements, copyElements;
1387   arrayToSet(theIDsOfElements, GetMeshDS(), inElements, theElementType);
1388
1389   TIDSortedElemSet* workElements = & inElements;
1390   TPreviewMesh      tmpMesh( SMDSAbs_Face );
1391   SMESH_Mesh*       mesh = 0;
1392   bool              makeWalls=true;
1393   if ( myPreviewMode )
1394   {
1395     SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1396     tmpMesh.Copy( inElements, copyElements, select, avoid );
1397     mesh = &tmpMesh;
1398     workElements = & copyElements;
1399     //makeWalls = false;
1400   }
1401   else
1402   {
1403     mesh = myMesh;
1404   }
1405
1406   gp_Ax1 Ax1 (gp_Pnt( theAxis.x,  theAxis.y,  theAxis.z ),
1407               gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
1408
1409   ::SMESH_MeshEditor anEditor( mesh );
1410   ::SMESH_MeshEditor::PGroupIDs groupIds =
1411     anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
1412                             theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
1413   storeResult(anEditor);
1414
1415   return theMakeGroups ? getGroups(groupIds.get()) : 0;
1416 }
1417
1418 //=======================================================================
1419 //function : RotationSweep
1420 //purpose  :
1421 //=======================================================================
1422
1423 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
1424                                        const SMESH::AxisStruct & theAxis,
1425                                        CORBA::Double             theAngleInRadians,
1426                                        CORBA::Long               theNbOfSteps,
1427                                        CORBA::Double             theTolerance)
1428 {
1429   if ( !myPreviewMode ) {
1430     TPythonDump() << this << ".RotationSweep( "
1431                   << theIDsOfElements << ", "
1432                   << theAxis << ", "
1433                   << theAngleInRadians << ", "
1434                   << theNbOfSteps << ", "
1435                   << theTolerance << " )";
1436   }
1437   rotationSweep(theIDsOfElements,
1438                 theAxis,
1439                 theAngleInRadians,
1440                 theNbOfSteps,
1441                 theTolerance,
1442                 false);
1443 }
1444
1445 //=======================================================================
1446 //function : RotationSweepMakeGroups
1447 //purpose  : 
1448 //=======================================================================
1449
1450 SMESH::ListOfGroups*
1451 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1452                                             const SMESH::AxisStruct& theAxis,
1453                                             CORBA::Double            theAngleInRadians,
1454                                             CORBA::Long              theNbOfSteps,
1455                                             CORBA::Double            theTolerance)
1456 {
1457   SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
1458                                                theAxis,
1459                                                theAngleInRadians,
1460                                                theNbOfSteps,
1461                                                theTolerance,
1462                                                true);
1463   if ( !myPreviewMode ) {
1464     TPythonDump aPythonDump;
1465     DumpGroupsList(aPythonDump,aGroups);
1466     aPythonDump<< this << ".RotationSweepMakeGroups( "
1467                << theIDsOfElements << ", "
1468                << theAxis << ", "
1469                << theAngleInRadians << ", "
1470                << theNbOfSteps << ", "
1471                << theTolerance << " )";
1472   }
1473   return aGroups;
1474 }
1475
1476 //=======================================================================
1477 //function : RotationSweepObject
1478 //purpose  :
1479 //=======================================================================
1480
1481 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1482                                              const SMESH::AxisStruct & theAxis,
1483                                              CORBA::Double             theAngleInRadians,
1484                                              CORBA::Long               theNbOfSteps,
1485                                              CORBA::Double             theTolerance)
1486 {
1487   if ( !myPreviewMode ) {
1488     TPythonDump() << this << ".RotationSweepObject( "
1489                   << theObject << ", "
1490                   << theAxis << ", "
1491                   << theAngleInRadians << ", "
1492                   << theNbOfSteps << ", "
1493                   << theTolerance << " )";
1494   }
1495   SMESH::long_array_var anElementsId = theObject->GetIDs();
1496   rotationSweep(anElementsId,
1497                 theAxis,
1498                 theAngleInRadians,
1499                 theNbOfSteps,
1500                 theTolerance,
1501                 false);
1502 }
1503
1504 //=======================================================================
1505 //function : RotationSweepObject1D
1506 //purpose  :
1507 //=======================================================================
1508
1509 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1510                                                const SMESH::AxisStruct & theAxis,
1511                                                CORBA::Double             theAngleInRadians,
1512                                                CORBA::Long               theNbOfSteps,
1513                                                CORBA::Double             theTolerance)
1514 {
1515   if ( !myPreviewMode ) {
1516     TPythonDump() << this << ".RotationSweepObject1D( "
1517                   << theObject << ", "
1518                   << theAxis << ", "
1519                   << theAngleInRadians << ", "
1520                   << theNbOfSteps << ", "
1521                   << theTolerance << " )";
1522   }
1523   SMESH::long_array_var anElementsId = theObject->GetIDs();
1524   rotationSweep(anElementsId,
1525                 theAxis,
1526                 theAngleInRadians,
1527                 theNbOfSteps,
1528                 theTolerance,
1529                 false,
1530                 SMDSAbs_Edge);
1531 }
1532
1533 //=======================================================================
1534 //function : RotationSweepObject2D
1535 //purpose  :
1536 //=======================================================================
1537
1538 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1539                                                const SMESH::AxisStruct & theAxis,
1540                                                CORBA::Double             theAngleInRadians,
1541                                                CORBA::Long               theNbOfSteps,
1542                                                CORBA::Double             theTolerance)
1543 {
1544   if ( !myPreviewMode ) {
1545     TPythonDump() << this << ".RotationSweepObject2D( "
1546                   << theObject << ", "
1547                   << theAxis << ", "
1548                   << theAngleInRadians << ", "
1549                   << theNbOfSteps << ", "
1550                   << theTolerance << " )";
1551   }
1552   SMESH::long_array_var anElementsId = theObject->GetIDs();
1553   rotationSweep(anElementsId,
1554                 theAxis,
1555                 theAngleInRadians,
1556                 theNbOfSteps,
1557                 theTolerance,
1558                 false,
1559                 SMDSAbs_Face);
1560 }
1561
1562 //=======================================================================
1563 //function : RotationSweepObjectMakeGroups
1564 //purpose  : 
1565 //=======================================================================
1566
1567 SMESH::ListOfGroups*
1568 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1569                                                   const SMESH::AxisStruct&  theAxis,
1570                                                   CORBA::Double             theAngleInRadians,
1571                                                   CORBA::Long               theNbOfSteps,
1572                                                   CORBA::Double             theTolerance)
1573 {
1574   SMESH::long_array_var anElementsId = theObject->GetIDs();
1575   SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1576                                                theAxis,
1577                                                theAngleInRadians,
1578                                                theNbOfSteps,
1579                                                theTolerance,
1580                                                true);
1581   if ( !myPreviewMode ) {
1582     TPythonDump aPythonDump;
1583     DumpGroupsList(aPythonDump,aGroups);
1584     aPythonDump<< this << ".RotationSweepObjectMakeGroups( "
1585                << theObject << ", "
1586                << theAxis << ", "
1587                << theAngleInRadians << ", "
1588                << theNbOfSteps << ", "
1589                << theTolerance << " )";
1590   }
1591   return aGroups;
1592 }
1593
1594 //=======================================================================
1595 //function : RotationSweepObject1DMakeGroups
1596 //purpose  : 
1597 //=======================================================================
1598
1599 SMESH::ListOfGroups*
1600 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1601                                                     const SMESH::AxisStruct&  theAxis,
1602                                                     CORBA::Double             theAngleInRadians,
1603                                                     CORBA::Long               theNbOfSteps,
1604                                                     CORBA::Double             theTolerance)
1605 {
1606   SMESH::long_array_var anElementsId = theObject->GetIDs();
1607   SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1608                                                theAxis,
1609                                                theAngleInRadians,
1610                                                theNbOfSteps,
1611                                                theTolerance,
1612                                                true,
1613                                                SMDSAbs_Edge);
1614   if ( !myPreviewMode ) {
1615     TPythonDump aPythonDump;
1616     DumpGroupsList(aPythonDump,aGroups);
1617     aPythonDump<< this << ".RotationSweepObject1DMakeGroups( "
1618                << theObject << ", "
1619                << theAxis << ", "
1620                << theAngleInRadians << ", "
1621                << theNbOfSteps << ", "
1622                << theTolerance << " )";
1623   }
1624   return aGroups;
1625 }
1626
1627 //=======================================================================
1628 //function : RotationSweepObject2DMakeGroups
1629 //purpose  : 
1630 //=======================================================================
1631
1632 SMESH::ListOfGroups*
1633 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1634                                                     const SMESH::AxisStruct&  theAxis,
1635                                                     CORBA::Double             theAngleInRadians,
1636                                                     CORBA::Long               theNbOfSteps,
1637                                                     CORBA::Double             theTolerance)
1638 {
1639   SMESH::long_array_var anElementsId = theObject->GetIDs();
1640   SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1641                                                theAxis,
1642                                                theAngleInRadians,
1643                                                theNbOfSteps,
1644                                                theTolerance,
1645                                                true,
1646                                                SMDSAbs_Face);
1647   if ( !myPreviewMode ) {
1648     TPythonDump aPythonDump;
1649     DumpGroupsList(aPythonDump,aGroups);
1650     aPythonDump<< this << ".RotationSweepObject2DMakeGroups( "
1651                << theObject << ", "
1652                << theAxis << ", "
1653                << theAngleInRadians << ", "
1654                << theNbOfSteps << ", "
1655                << theTolerance << " )";
1656   }
1657   return aGroups;
1658 }
1659
1660
1661 //=======================================================================
1662 //function : extrusionSweep
1663 //purpose  : 
1664 //=======================================================================
1665
1666 SMESH::ListOfGroups*
1667 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
1668                                    const SMESH::DirStruct &  theStepVector,
1669                                    CORBA::Long               theNbOfSteps,
1670                                    const bool                theMakeGroups,
1671                                    const SMDSAbs_ElementType theElementType)
1672 {
1673   initData();
1674
1675   try {   
1676 #ifdef NO_CAS_CATCH
1677     OCC_CATCH_SIGNALS;
1678 #endif
1679     TIDSortedElemSet elements;
1680     arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
1681
1682     const SMESH::PointStruct * P = &theStepVector.PS;
1683     gp_Vec stepVec( P->x, P->y, P->z );
1684
1685     TElemOfElemListMap aHystory;
1686     ::SMESH_MeshEditor anEditor( myMesh );
1687     ::SMESH_MeshEditor::PGroupIDs groupIds =
1688         anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
1689
1690     storeResult(anEditor);
1691
1692     return theMakeGroups ? getGroups(groupIds.get()) : 0;
1693
1694   } catch(Standard_Failure) {
1695     Handle(Standard_Failure) aFail = Standard_Failure::Caught();          
1696     INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
1697   }
1698   return 0;
1699 }
1700
1701 //=======================================================================
1702 //function : ExtrusionSweep
1703 //purpose  :
1704 //=======================================================================
1705
1706 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
1707                                         const SMESH::DirStruct &  theStepVector,
1708                                         CORBA::Long               theNbOfSteps)
1709 {
1710   extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
1711   if ( !myPreviewMode ) {
1712     TPythonDump() << this << ".ExtrusionSweep( "
1713                   << theIDsOfElements << ", " << theStepVector <<", " << theNbOfSteps << " )";
1714   }
1715 }
1716
1717
1718 //=======================================================================
1719 //function : ExtrusionSweepObject
1720 //purpose  :
1721 //=======================================================================
1722
1723 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1724                                               const SMESH::DirStruct &  theStepVector,
1725                                               CORBA::Long               theNbOfSteps)
1726 {
1727   SMESH::long_array_var anElementsId = theObject->GetIDs();
1728   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
1729   if ( !myPreviewMode ) {
1730     TPythonDump() << this << ".ExtrusionSweepObject( "
1731                   << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1732   }
1733 }
1734
1735 //=======================================================================
1736 //function : ExtrusionSweepObject1D
1737 //purpose  :
1738 //=======================================================================
1739
1740 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1741                                                 const SMESH::DirStruct &  theStepVector,
1742                                                 CORBA::Long               theNbOfSteps)
1743 {
1744   SMESH::long_array_var anElementsId = theObject->GetIDs();
1745   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
1746   if ( !myPreviewMode ) {
1747     TPythonDump() << this << ".ExtrusionSweepObject1D( "
1748                   << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1749   }
1750 }
1751
1752 //=======================================================================
1753 //function : ExtrusionSweepObject2D
1754 //purpose  :
1755 //=======================================================================
1756
1757 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1758                                                 const SMESH::DirStruct &  theStepVector,
1759                                                 CORBA::Long               theNbOfSteps)
1760 {
1761   SMESH::long_array_var anElementsId = theObject->GetIDs();
1762   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
1763   if ( !myPreviewMode ) {
1764     TPythonDump() << this << ".ExtrusionSweepObject2D( "
1765                   << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1766   }
1767 }
1768
1769 //=======================================================================
1770 //function : ExtrusionSweepMakeGroups
1771 //purpose  : 
1772 //=======================================================================
1773
1774 SMESH::ListOfGroups*
1775 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1776                                              const SMESH::DirStruct&  theStepVector,
1777                                              CORBA::Long              theNbOfSteps)
1778 {
1779   SMESH::ListOfGroups* aGroups = extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, true );
1780     
1781   if ( !myPreviewMode ) {
1782     TPythonDump aPythonDump;
1783     DumpGroupsList(aPythonDump,aGroups);
1784     aPythonDump  << this << ".ExtrusionSweepMakeGroups( "
1785                  << theIDsOfElements << ", " << theStepVector <<", " << theNbOfSteps << " )";
1786   }
1787   return aGroups;
1788 }
1789 //=======================================================================
1790 //function : ExtrusionSweepObjectMakeGroups
1791 //purpose  : 
1792 //=======================================================================
1793
1794 SMESH::ListOfGroups*
1795 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1796                                                    const SMESH::DirStruct&   theStepVector,
1797                                                    CORBA::Long               theNbOfSteps)
1798 {
1799   SMESH::long_array_var anElementsId = theObject->GetIDs();
1800   SMESH::ListOfGroups * aGroups = extrusionSweep (anElementsId, theStepVector, theNbOfSteps, true );
1801   
1802   if ( !myPreviewMode ) {
1803     TPythonDump aPythonDump;
1804     DumpGroupsList(aPythonDump,aGroups);
1805     aPythonDump<< this << ".ExtrusionSweepObjectMakeGroups( "
1806                << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1807   }
1808   return aGroups;
1809 }
1810
1811 //=======================================================================
1812 //function : ExtrusionSweepObject1DMakeGroups
1813 //purpose  : 
1814 //=======================================================================
1815
1816 SMESH::ListOfGroups*
1817 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1818                                                      const SMESH::DirStruct&   theStepVector,
1819                                                      CORBA::Long               theNbOfSteps)
1820 {
1821   SMESH::long_array_var anElementsId = theObject->GetIDs();
1822   SMESH::ListOfGroups * aGroups = extrusionSweep (anElementsId, theStepVector, theNbOfSteps, true, SMDSAbs_Edge );
1823   if ( !myPreviewMode ) {
1824     TPythonDump aPythonDump;
1825     DumpGroupsList(aPythonDump,aGroups);
1826     aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( "
1827                 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1828   }
1829   return aGroups;
1830 }
1831
1832 //=======================================================================
1833 //function : ExtrusionSweepObject2DMakeGroups
1834 //purpose  : 
1835 //=======================================================================
1836
1837 SMESH::ListOfGroups*
1838 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1839                                                      const SMESH::DirStruct&   theStepVector,
1840                                                      CORBA::Long               theNbOfSteps)
1841 {
1842   SMESH::long_array_var anElementsId = theObject->GetIDs();
1843   SMESH::ListOfGroups * aGroups = extrusionSweep (anElementsId, theStepVector, theNbOfSteps, true, SMDSAbs_Face );
1844   if ( !myPreviewMode ) {
1845     TPythonDump aPythonDump;
1846     DumpGroupsList(aPythonDump,aGroups);
1847     aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( "
1848                 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1849   }
1850   return aGroups;
1851 }
1852
1853
1854 //=======================================================================
1855 //function : advancedExtrusion
1856 //purpose  : 
1857 //=======================================================================
1858
1859 SMESH::ListOfGroups*
1860 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
1861                                       const SMESH::DirStruct &  theStepVector,
1862                                       CORBA::Long               theNbOfSteps,
1863                                       CORBA::Long               theExtrFlags,
1864                                       CORBA::Double             theSewTolerance,
1865                                       const bool                theMakeGroups)
1866 {
1867   initData();
1868
1869   TIDSortedElemSet elements;
1870   arrayToSet(theIDsOfElements, GetMeshDS(), elements);
1871
1872   const SMESH::PointStruct * P = &theStepVector.PS;
1873   gp_Vec stepVec( P->x, P->y, P->z );
1874
1875   ::SMESH_MeshEditor anEditor( myMesh );
1876   TElemOfElemListMap aHystory;
1877   ::SMESH_MeshEditor::PGroupIDs groupIds =
1878       anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
1879                                theMakeGroups, theExtrFlags, theSewTolerance);
1880   storeResult(anEditor);
1881
1882   return theMakeGroups ? getGroups(groupIds.get()) : 0;
1883 }
1884
1885 //=======================================================================
1886 //function : AdvancedExtrusion
1887 //purpose  :
1888 //=======================================================================
1889
1890 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
1891                                            const SMESH::DirStruct &  theStepVector,
1892                                            CORBA::Long               theNbOfSteps,
1893                                            CORBA::Long               theExtrFlags,
1894                                            CORBA::Double             theSewTolerance)
1895 {
1896   if ( !myPreviewMode ) {
1897     TPythonDump() << "stepVector = " << theStepVector;
1898     TPythonDump() << this << ".AdvancedExtrusion("
1899                   << theIDsOfElements
1900                   << ", stepVector, "
1901                   << theNbOfSteps << ","
1902                   << theExtrFlags << ", "
1903                   << theSewTolerance <<  " )";
1904   }
1905   advancedExtrusion( theIDsOfElements,
1906                      theStepVector,
1907                      theNbOfSteps,
1908                      theExtrFlags,
1909                      theSewTolerance,
1910                      false);
1911 }
1912
1913 //=======================================================================
1914 //function : AdvancedExtrusionMakeGroups
1915 //purpose  : 
1916 //=======================================================================
1917
1918 SMESH::ListOfGroups*
1919 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
1920                                                 const SMESH::DirStruct&  theStepVector,
1921                                                 CORBA::Long              theNbOfSteps,
1922                                                 CORBA::Long              theExtrFlags,
1923                                                 CORBA::Double            theSewTolerance)
1924 {
1925   SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
1926                                                     theStepVector,
1927                                                     theNbOfSteps,
1928                                                     theExtrFlags,
1929                                                     theSewTolerance,
1930                                                     true);
1931   
1932   if ( !myPreviewMode ) {
1933     TPythonDump() << "stepVector = " << theStepVector;
1934     TPythonDump aPythonDump;
1935     DumpGroupsList(aPythonDump,aGroups);
1936     aPythonDump << this << ".AdvancedExtrusionMakeGroups("
1937                 << theIDsOfElements
1938                 << ", stepVector, "
1939                 << theNbOfSteps << ","
1940                 << theExtrFlags << ", "
1941                 << theSewTolerance <<  " )";
1942   }
1943   return aGroups;
1944 }
1945
1946
1947 //================================================================================
1948 /*!
1949  * \brief Convert extrusion error to IDL enum
1950  */
1951 //================================================================================
1952
1953 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
1954
1955 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
1956 {
1957   switch ( e ) {
1958   RETCASE( EXTR_OK );
1959   RETCASE( EXTR_NO_ELEMENTS );
1960   RETCASE( EXTR_PATH_NOT_EDGE );
1961   RETCASE( EXTR_BAD_PATH_SHAPE );
1962   RETCASE( EXTR_BAD_STARTING_NODE );
1963   RETCASE( EXTR_BAD_ANGLES_NUMBER );
1964   RETCASE( EXTR_CANT_GET_TANGENT );
1965   }
1966   return SMESH::SMESH_MeshEditor::EXTR_OK;
1967 }
1968
1969
1970 //=======================================================================
1971 //function : extrusionAlongPath
1972 //purpose  : 
1973 //=======================================================================
1974
1975 SMESH::ListOfGroups*
1976 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
1977                                        SMESH::SMESH_Mesh_ptr       thePathMesh,
1978                                        GEOM::GEOM_Object_ptr       thePathShape,
1979                                        CORBA::Long                 theNodeStart,
1980                                        CORBA::Boolean              theHasAngles,
1981                                        const SMESH::double_array & theAngles,
1982                                        CORBA::Boolean              theHasRefPoint,
1983                                        const SMESH::PointStruct &  theRefPoint,
1984                                        const bool                  theMakeGroups,
1985                                        SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
1986                                        const SMDSAbs_ElementType   theElementType)
1987 {
1988   initData();
1989
1990   if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
1991     theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
1992     return 0;
1993   }
1994   SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
1995
1996   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
1997   SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
1998
1999   if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2000     theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2001     return 0;
2002   }
2003
2004   SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2005   if ( !nodeStart ) {
2006     theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2007     return 0;
2008   }
2009
2010   TIDSortedElemSet elements;
2011   arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
2012
2013   list<double> angles;
2014   for (int i = 0; i < theAngles.length(); i++) {
2015     angles.push_back( theAngles[i] );
2016   }
2017
2018   gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2019
2020   int nbOldGroups = myMesh->NbGroup();
2021
2022   ::SMESH_MeshEditor anEditor( myMesh );
2023   ::SMESH_MeshEditor::Extrusion_Error error =
2024       anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2025                                     theHasAngles, angles, false,
2026                                     theHasRefPoint, refPnt, theMakeGroups );
2027   storeResult(anEditor);
2028   theError = convExtrError( error );
2029
2030   if ( theMakeGroups ) {
2031     list<int> groupIDs = myMesh->GetGroupIds();
2032     list<int>::iterator newBegin = groupIDs.begin();
2033     std::advance( newBegin, nbOldGroups ); // skip old groups
2034     groupIDs.erase( groupIDs.begin(), newBegin );
2035     return getGroups( & groupIDs );
2036   }
2037   return 0;
2038 }
2039
2040
2041 //=======================================================================
2042 //function : extrusionAlongPathX
2043 //purpose  : 
2044 //=======================================================================
2045
2046 SMESH::ListOfGroups*
2047 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array &  IDsOfElements,
2048                                         SMESH::SMESH_IDSource_ptr  Path,
2049                                         CORBA::Long                NodeStart,
2050                                         CORBA::Boolean             HasAngles,
2051                                         const SMESH::double_array& Angles,
2052                                         CORBA::Boolean             LinearVariation,
2053                                         CORBA::Boolean             HasRefPoint,
2054                                         const SMESH::PointStruct&  RefPoint,
2055                                         const bool                 MakeGroups,
2056                                         const SMDSAbs_ElementType  ElementType,
2057                                         SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2058 {
2059   SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2060
2061   initData();
2062
2063   list<double> angles;
2064   for (int i = 0; i < Angles.length(); i++) {
2065     angles.push_back( Angles[i] );
2066   }
2067   gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2068   int nbOldGroups = myMesh->NbGroup();
2069
2070   if ( Path->_is_nil() ) {
2071     Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2072     return EmptyGr;
2073   }
2074
2075   TIDSortedElemSet elements;
2076   arrayToSet(IDsOfElements, GetMeshDS(), elements, ElementType);
2077
2078   ::SMESH_MeshEditor anEditor( myMesh );
2079   ::SMESH_MeshEditor::Extrusion_Error error;
2080
2081   SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path );
2082   if(aMeshImp) {
2083     // path as mesh
2084     SMDS_MeshNode* aNodeStart = 
2085       (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2086     if ( !aNodeStart ) {
2087       Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2088       return EmptyGr;
2089     }
2090     error = anEditor.ExtrusionAlongTrack( elements, &(aMeshImp->GetImpl()), aNodeStart,
2091                                           HasAngles, angles, LinearVariation,
2092                                           HasRefPoint, refPnt, MakeGroups );
2093   }
2094   else {
2095     SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path );
2096     if(aSubMeshImp) {
2097       // path as submesh
2098       SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2099       aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2100       SMDS_MeshNode* aNodeStart = 
2101         (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2102       if ( !aNodeStart ) {
2103         Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2104         return EmptyGr;
2105       }
2106       SMESH_subMesh* aSubMesh = 
2107         aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2108       error = anEditor.ExtrusionAlongTrack( elements, aSubMesh, aNodeStart,
2109                                             HasAngles, angles, LinearVariation,
2110                                             HasRefPoint, refPnt, MakeGroups );
2111     }
2112     else {
2113       SMESH_Group_i* aGroupImp = SMESH::DownCast<SMESH_Group_i*>( Path );
2114       if(aGroupImp) {
2115         // path as group of 1D elements
2116       }
2117       else {
2118         // invalid path
2119         Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2120         return EmptyGr;
2121       }
2122     }
2123   }
2124
2125   storeResult(anEditor);
2126   Error = convExtrError( error );
2127
2128   if ( MakeGroups ) {
2129     list<int> groupIDs = myMesh->GetGroupIds();
2130     list<int>::iterator newBegin = groupIDs.begin();
2131     std::advance( newBegin, nbOldGroups ); // skip old groups
2132     groupIDs.erase( groupIDs.begin(), newBegin );
2133     return getGroups( & groupIDs );
2134   }
2135   return EmptyGr;
2136 }
2137
2138
2139 //=======================================================================
2140 //function : ExtrusionAlongPath
2141 //purpose  :
2142 //=======================================================================
2143
2144 SMESH::SMESH_MeshEditor::Extrusion_Error
2145   SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
2146                                          SMESH::SMESH_Mesh_ptr       thePathMesh,
2147                                          GEOM::GEOM_Object_ptr       thePathShape,
2148                                          CORBA::Long                 theNodeStart,
2149                                          CORBA::Boolean              theHasAngles,
2150                                          const SMESH::double_array & theAngles,
2151                                          CORBA::Boolean              theHasRefPoint,
2152                                          const SMESH::PointStruct &  theRefPoint)
2153 {
2154   if ( !myPreviewMode ) {
2155     TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
2156                   << theIDsOfElements << ", "
2157                   << thePathMesh      << ", "
2158                   << thePathShape     << ", "
2159                   << theNodeStart     << ", "
2160                   << theHasAngles     << ", "
2161                   << theAngles        << ", "
2162                   << theHasRefPoint   << ", "
2163                   << "SMESH.PointStruct( "
2164                   << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2165                   << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2166                   << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2167   }
2168   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2169   extrusionAlongPath( theIDsOfElements,
2170                       thePathMesh,
2171                       thePathShape,
2172                       theNodeStart,
2173                       theHasAngles,
2174                       theAngles,
2175                       theHasRefPoint,
2176                       theRefPoint,
2177                       false,
2178                       anError);
2179   return anError;
2180 }
2181
2182 //=======================================================================
2183 //function : ExtrusionAlongPathObject
2184 //purpose  :
2185 //=======================================================================
2186
2187 SMESH::SMESH_MeshEditor::Extrusion_Error
2188 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObject,
2189                                              SMESH::SMESH_Mesh_ptr       thePathMesh,
2190                                              GEOM::GEOM_Object_ptr       thePathShape,
2191                                              CORBA::Long                 theNodeStart,
2192                                              CORBA::Boolean              theHasAngles,
2193                                              const SMESH::double_array & theAngles,
2194                                              CORBA::Boolean              theHasRefPoint,
2195                                              const SMESH::PointStruct &  theRefPoint)
2196 {
2197   if ( !myPreviewMode ) {
2198     TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
2199                   << theObject        << ", "
2200                   << thePathMesh      << ", "
2201                   << thePathShape     << ", "
2202                   << theNodeStart     << ", "
2203                   << theHasAngles     << ", "
2204                   << theAngles        << ", "
2205                   << theHasRefPoint   << ", "
2206                   << "SMESH.PointStruct( "
2207                   << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2208                   << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2209                   << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2210   }
2211   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2212   SMESH::long_array_var anElementsId = theObject->GetIDs();
2213   extrusionAlongPath( anElementsId,
2214                       thePathMesh,
2215                       thePathShape,
2216                       theNodeStart,
2217                       theHasAngles,
2218                       theAngles,
2219                       theHasRefPoint,
2220                       theRefPoint,
2221                       false,
2222                       anError);
2223   return anError;
2224 }
2225
2226 //=======================================================================
2227 //function : ExtrusionAlongPathObject1D
2228 //purpose  :
2229 //=======================================================================
2230
2231 SMESH::SMESH_MeshEditor::Extrusion_Error
2232 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr   theObject,
2233                                                SMESH::SMESH_Mesh_ptr       thePathMesh,
2234                                                GEOM::GEOM_Object_ptr       thePathShape,
2235                                                CORBA::Long                 theNodeStart,
2236                                                CORBA::Boolean              theHasAngles,
2237                                                const SMESH::double_array & theAngles,
2238                                                CORBA::Boolean              theHasRefPoint,
2239                                                const SMESH::PointStruct &  theRefPoint)
2240 {
2241   if ( !myPreviewMode ) {
2242     TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2243                   << theObject        << ", "
2244                   << thePathMesh      << ", "
2245                   << thePathShape     << ", "
2246                   << theNodeStart     << ", "
2247                   << theHasAngles     << ", "
2248                   << theAngles        << ", "
2249                   << theHasRefPoint   << ", "
2250                   << "SMESH.PointStruct( "
2251                   << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2252                   << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2253                   << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2254   }
2255   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2256   SMESH::long_array_var anElementsId = theObject->GetIDs();
2257   extrusionAlongPath( anElementsId,
2258                       thePathMesh,
2259                       thePathShape,
2260                       theNodeStart,
2261                       theHasAngles,
2262                       theAngles,
2263                       theHasRefPoint,
2264                       theRefPoint,
2265                       false,
2266                       anError,
2267                       SMDSAbs_Edge);
2268   return anError;
2269 }
2270
2271 //=======================================================================
2272 //function : ExtrusionAlongPathObject2D
2273 //purpose  :
2274 //=======================================================================
2275
2276 SMESH::SMESH_MeshEditor::Extrusion_Error
2277 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr   theObject,
2278                                                SMESH::SMESH_Mesh_ptr       thePathMesh,
2279                                                GEOM::GEOM_Object_ptr       thePathShape,
2280                                                CORBA::Long                 theNodeStart,
2281                                                CORBA::Boolean              theHasAngles,
2282                                                const SMESH::double_array & theAngles,
2283                                                CORBA::Boolean              theHasRefPoint,
2284                                                const SMESH::PointStruct &  theRefPoint)
2285 {
2286   if ( !myPreviewMode ) {
2287     TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
2288                   << theObject        << ", "
2289                   << thePathMesh      << ", "
2290                   << thePathShape     << ", "
2291                   << theNodeStart     << ", "
2292                   << theHasAngles     << ", "
2293                   << theAngles        << ", "
2294                   << theHasRefPoint   << ", "
2295                   << "SMESH.PointStruct( "
2296                   << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2297                   << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2298                   << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2299   }
2300   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2301   SMESH::long_array_var anElementsId = theObject->GetIDs();
2302   extrusionAlongPath( anElementsId,
2303                       thePathMesh,
2304                       thePathShape,
2305                       theNodeStart,
2306                       theHasAngles,
2307                       theAngles,
2308                       theHasRefPoint,
2309                       theRefPoint,
2310                       false,
2311                       anError,
2312                       SMDSAbs_Face);
2313   return anError;
2314 }
2315
2316
2317 //=======================================================================
2318 //function : ExtrusionAlongPathMakeGroups
2319 //purpose  : 
2320 //=======================================================================
2321
2322 SMESH::ListOfGroups*
2323 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array&   theIDsOfElements,
2324                                                  SMESH::SMESH_Mesh_ptr      thePathMesh,
2325                                                  GEOM::GEOM_Object_ptr      thePathShape,
2326                                                  CORBA::Long                theNodeStart,
2327                                                  CORBA::Boolean             theHasAngles,
2328                                                  const SMESH::double_array& theAngles,
2329                                                  CORBA::Boolean             theHasRefPoint,
2330                                                  const SMESH::PointStruct&  theRefPoint,
2331                                                  SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2332 {
2333     SMESH::ListOfGroups * aGroups =  extrusionAlongPath( theIDsOfElements,
2334                                                          thePathMesh,
2335                                                          thePathShape,
2336                                                          theNodeStart,
2337                                                          theHasAngles,
2338                                                          theAngles,
2339                                                          theHasRefPoint,
2340                                                          theRefPoint,
2341                                                          true,
2342                                                          Error);
2343   if ( !myPreviewMode ) {
2344     bool isDumpGroups = aGroups && aGroups->length() > 0;
2345     TPythonDump aPythonDump;
2346     if(isDumpGroups) {
2347       aPythonDump << "("<<aGroups;
2348     }
2349     if(isDumpGroups)
2350       aPythonDump << ", error)";
2351     else
2352       aPythonDump <<"error";
2353     
2354     aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
2355                << theIDsOfElements << ", "
2356                << thePathMesh      << ", "
2357                << thePathShape     << ", "
2358                << theNodeStart     << ", "
2359                << theHasAngles     << ", "
2360                << theAngles        << ", "
2361                << theHasRefPoint   << ", "
2362                << "SMESH.PointStruct( "
2363                << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2364                << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2365                << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2366   }
2367   return aGroups;
2368 }
2369
2370 //=======================================================================
2371 //function : ExtrusionAlongPathObjectMakeGroups
2372 //purpose  : 
2373 //=======================================================================
2374
2375 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2376 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
2377                                    SMESH::SMESH_Mesh_ptr      thePathMesh,
2378                                    GEOM::GEOM_Object_ptr      thePathShape,
2379                                    CORBA::Long                theNodeStart,
2380                                    CORBA::Boolean             theHasAngles,
2381                                    const SMESH::double_array& theAngles,
2382                                    CORBA::Boolean             theHasRefPoint,
2383                                    const SMESH::PointStruct&  theRefPoint,
2384                                    SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2385 {
2386   SMESH::long_array_var anElementsId = theObject->GetIDs();
2387   SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2388                                                       thePathMesh,
2389                                                       thePathShape,
2390                                                       theNodeStart,
2391                                                       theHasAngles,
2392                                                       theAngles,
2393                                                       theHasRefPoint,
2394                                                       theRefPoint,
2395                                                       true,
2396                                                       Error);
2397   
2398   if ( !myPreviewMode ) {
2399     bool isDumpGroups = aGroups && aGroups->length() > 0;
2400     TPythonDump aPythonDump;
2401     if(isDumpGroups) {
2402       aPythonDump << "("<<aGroups;
2403     }
2404     if(isDumpGroups)
2405       aPythonDump << ", error)";
2406     else
2407       aPythonDump <<"error";
2408
2409     aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
2410                 << theObject << ", "
2411                 << thePathMesh      << ", "
2412                 << thePathShape     << ", "
2413                 << theNodeStart     << ", "
2414                 << theHasAngles     << ", "
2415                 << theAngles        << ", "
2416                 << theHasRefPoint   << ", "
2417                 << "SMESH.PointStruct( "
2418                 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2419                 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2420                 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2421   }
2422   return aGroups;
2423 }
2424
2425 //=======================================================================
2426 //function : ExtrusionAlongPathObject1DMakeGroups
2427 //purpose  : 
2428 //=======================================================================
2429
2430 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2431 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
2432                                      SMESH::SMESH_Mesh_ptr      thePathMesh,
2433                                      GEOM::GEOM_Object_ptr      thePathShape,
2434                                      CORBA::Long                theNodeStart,
2435                                      CORBA::Boolean             theHasAngles,
2436                                      const SMESH::double_array& theAngles,
2437                                      CORBA::Boolean             theHasRefPoint,
2438                                      const SMESH::PointStruct&  theRefPoint,
2439                                      SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2440 {
2441   SMESH::long_array_var anElementsId = theObject->GetIDs();
2442   SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2443                                                       thePathMesh,
2444                                                       thePathShape,
2445                                                       theNodeStart,
2446                                                       theHasAngles,
2447                                                       theAngles,
2448                                                       theHasRefPoint,
2449                                                       theRefPoint,
2450                                                       true,
2451                                                       Error,
2452                                                       SMDSAbs_Edge);
2453   
2454   if ( !myPreviewMode ) {
2455     bool isDumpGroups = aGroups && aGroups->length() > 0;
2456     TPythonDump aPythonDump;
2457     if(isDumpGroups) {
2458       aPythonDump << "("<<aGroups;
2459     }
2460     if(isDumpGroups)
2461       aPythonDump << ", error)";
2462     else
2463       aPythonDump <<"error";
2464
2465     aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
2466                 << theObject << ", "
2467                 << thePathMesh      << ", "
2468                 << thePathShape     << ", "
2469                 << theNodeStart     << ", "
2470                 << theHasAngles     << ", "
2471                 << theAngles        << ", "
2472                 << theHasRefPoint   << ", "
2473                 << "SMESH.PointStruct( "
2474                 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2475                 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2476                 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2477   }
2478   return aGroups;
2479 }
2480
2481 //=======================================================================
2482 //function : ExtrusionAlongPathObject2DMakeGroups
2483 //purpose  : 
2484 //=======================================================================
2485
2486 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2487 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
2488                                      SMESH::SMESH_Mesh_ptr      thePathMesh,
2489                                      GEOM::GEOM_Object_ptr      thePathShape,
2490                                      CORBA::Long                theNodeStart,
2491                                      CORBA::Boolean             theHasAngles,
2492                                      const SMESH::double_array& theAngles,
2493                                      CORBA::Boolean             theHasRefPoint,
2494                                      const SMESH::PointStruct&  theRefPoint,
2495                                      SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2496 {
2497   SMESH::long_array_var anElementsId = theObject->GetIDs();
2498   SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2499                                                       thePathMesh,
2500                                                       thePathShape,
2501                                                       theNodeStart,
2502                                                       theHasAngles,
2503                                                       theAngles,
2504                                                       theHasRefPoint,
2505                                                       theRefPoint,
2506                                                       true,
2507                                                       Error,
2508                                                       SMDSAbs_Face);
2509   
2510   if ( !myPreviewMode ) {
2511     bool isDumpGroups = aGroups && aGroups->length() > 0;
2512     TPythonDump aPythonDump;
2513     if(isDumpGroups) {
2514       aPythonDump << "("<<aGroups;
2515     }
2516     if(isDumpGroups)
2517       aPythonDump << ", error)";
2518     else
2519       aPythonDump <<"error";
2520
2521     aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
2522                 << theObject << ", "
2523                 << thePathMesh      << ", "
2524                 << thePathShape     << ", "
2525                 << theNodeStart     << ", "
2526                 << theHasAngles     << ", "
2527                 << theAngles        << ", "
2528                 << theHasRefPoint   << ", "
2529                 << "SMESH.PointStruct( "
2530                 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2531                 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2532                 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2533   }
2534   return aGroups;
2535 }
2536
2537
2538 //=======================================================================
2539 //function : ExtrusionAlongPathObjX
2540 //purpose  : 
2541 //=======================================================================
2542 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2543 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr  Object,
2544                        SMESH::SMESH_IDSource_ptr  Path,
2545                        CORBA::Long                NodeStart,
2546                        CORBA::Boolean             HasAngles,
2547                        const SMESH::double_array& Angles,
2548                        CORBA::Boolean             LinearVariation,
2549                        CORBA::Boolean             HasRefPoint,
2550                        const SMESH::PointStruct&  RefPoint,
2551                        CORBA::Boolean             MakeGroups,
2552                        SMESH::ElementType         ElemType,
2553                        SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2554 {
2555   SMESH::long_array_var anElementsId = Object->GetIDs();
2556   SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
2557                                                       Path,
2558                                                       NodeStart,
2559                                                       HasAngles,
2560                                                       Angles,
2561                                                       LinearVariation,
2562                                                       HasRefPoint,
2563                                                       RefPoint,
2564                                                       MakeGroups,
2565                                                       (SMDSAbs_ElementType)ElemType,
2566                                                       Error);
2567   
2568   if ( !myPreviewMode ) {
2569     bool isDumpGroups = aGroups && aGroups->length() > 0;
2570     TPythonDump aPythonDump;
2571     if(isDumpGroups) {
2572       aPythonDump << "("<<aGroups;
2573     }
2574     if(isDumpGroups)
2575       aPythonDump << ", error)";
2576     else
2577       aPythonDump <<"error";
2578
2579     aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
2580                 << Object      << ", "
2581                 << Path        << ", "
2582                 << NodeStart   << ", "
2583                 << HasAngles   << ", "
2584                 << Angles      << ", "
2585                 << LinearVariation << ", "
2586                 << HasRefPoint << ", "
2587                 << "SMESH.PointStruct( "
2588                 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2589                 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2590                 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2591                 << ElemType << " )";
2592   }
2593   return aGroups;
2594 }
2595
2596
2597 //=======================================================================
2598 //function : ExtrusionAlongPathX
2599 //purpose  : 
2600 //=======================================================================
2601 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2602 ExtrusionAlongPathX(const SMESH::long_array&   IDsOfElements,
2603                     SMESH::SMESH_IDSource_ptr  Path,
2604                     CORBA::Long                NodeStart,
2605                     CORBA::Boolean             HasAngles,
2606                     const SMESH::double_array& Angles,
2607                     CORBA::Boolean             LinearVariation,
2608                     CORBA::Boolean             HasRefPoint,
2609                     const SMESH::PointStruct&  RefPoint,
2610                     CORBA::Boolean             MakeGroups,
2611                     SMESH::ElementType         ElemType,
2612                     SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2613 {
2614   SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
2615                                                       Path,
2616                                                       NodeStart,
2617                                                       HasAngles,
2618                                                       Angles,
2619                                                       LinearVariation,
2620                                                       HasRefPoint,
2621                                                       RefPoint,
2622                                                       MakeGroups,
2623                                                       (SMDSAbs_ElementType)ElemType,
2624                                                       Error);
2625   
2626   if ( !myPreviewMode ) {
2627     bool isDumpGroups = aGroups && aGroups->length() > 0;
2628     TPythonDump aPythonDump;
2629     if(isDumpGroups) {
2630       aPythonDump << "("<<aGroups;
2631     }
2632     if(isDumpGroups)
2633       aPythonDump << ", error)";
2634     else
2635       aPythonDump <<"error";
2636
2637     aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
2638                 << IDsOfElements << ", "
2639                 << Path        << ", "
2640                 << NodeStart   << ", "
2641                 << HasAngles   << ", "
2642                 << Angles      << ", "
2643                 << LinearVariation << ", "
2644                 << HasRefPoint << ", "
2645                 << "SMESH.PointStruct( "
2646                 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2647                 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2648                 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2649                 << ElemType << " )";
2650   }
2651   return aGroups;
2652 }
2653
2654
2655 //================================================================================
2656 /*!
2657  * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2658  * of given angles along path steps
2659   * \param PathMesh mesh containing a 1D sub-mesh on the edge, along 
2660   *                which proceeds the extrusion
2661   * \param PathShape is shape(edge); as the mesh can be complex, the edge 
2662   *                 is used to define the sub-mesh for the path
2663  */
2664 //================================================================================
2665
2666 SMESH::double_array*
2667 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr       thePathMesh,
2668                                           GEOM::GEOM_Object_ptr       thePathShape,
2669                                           const SMESH::double_array & theAngles)
2670 {
2671   SMESH::double_array_var aResult = new SMESH::double_array();
2672   int nbAngles = theAngles.length();
2673   if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
2674   {
2675     SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2676     TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2677     SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2678     if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
2679       return aResult._retn();
2680     int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
2681     if ( nbSteps == nbAngles )
2682     {
2683       aResult.inout() = theAngles;
2684     }
2685     else
2686     {
2687       aResult->length( nbSteps );
2688       double rAn2St = double( nbAngles ) / double( nbSteps );
2689       double angPrev = 0, angle;
2690       for ( int iSt = 0; iSt < nbSteps; ++iSt )
2691       {
2692         double angCur = rAn2St * ( iSt+1 );
2693         double angCurFloor  = floor( angCur );
2694         double angPrevFloor = floor( angPrev );
2695         if ( angPrevFloor == angCurFloor )
2696           angle = rAn2St * theAngles[ int( angCurFloor ) ];
2697         else
2698         {
2699           int iP = int( angPrevFloor );
2700           double angPrevCeil = ceil(angPrev);
2701           angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
2702           
2703           int iC = int( angCurFloor );
2704           if ( iC < nbAngles )
2705             angle += ( angCur - angCurFloor ) * theAngles[ iC ];
2706
2707           iP = int( angPrevCeil );
2708           while ( iC-- > iP )
2709             angle += theAngles[ iC ];
2710         }
2711         aResult[ iSt ] = angle;
2712         angPrev = angCur;
2713       }
2714     }
2715   }
2716   // Update Python script
2717   TPythonDump() << "rotAngles = " << theAngles;
2718   TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
2719                 << thePathMesh  << ", "
2720                 << thePathShape << ", "
2721                 << "rotAngles )";
2722
2723   return aResult._retn();
2724 }
2725
2726
2727 //=======================================================================
2728 //function : mirror
2729 //purpose  : 
2730 //=======================================================================
2731
2732 SMESH::ListOfGroups*
2733 SMESH_MeshEditor_i::mirror(const SMESH::long_array &           theIDsOfElements,
2734                            const SMESH::AxisStruct &           theAxis,
2735                            SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2736                            CORBA::Boolean                      theCopy,
2737                            const bool                          theMakeGroups,
2738                            ::SMESH_Mesh*                       theTargetMesh)
2739 {
2740   initData();
2741
2742   TIDSortedElemSet elements;
2743   arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2744
2745   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
2746   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
2747
2748   gp_Trsf aTrsf;
2749   switch ( theMirrorType ) {
2750   case  SMESH::SMESH_MeshEditor::POINT:
2751     aTrsf.SetMirror( P );
2752     break;
2753   case  SMESH::SMESH_MeshEditor::AXIS:
2754     aTrsf.SetMirror( gp_Ax1( P, V ));
2755     break;
2756   default:
2757     aTrsf.SetMirror( gp_Ax2( P, V ));
2758   }
2759
2760   ::SMESH_MeshEditor anEditor( myMesh );
2761   ::SMESH_MeshEditor::PGroupIDs groupIds =
2762       anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
2763
2764   if(theCopy) {
2765     storeResult(anEditor);
2766   }
2767   return theMakeGroups ? getGroups(groupIds.get()) : 0;
2768 }
2769
2770 //=======================================================================
2771 //function : Mirror
2772 //purpose  :
2773 //=======================================================================
2774
2775 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElements,
2776                                 const SMESH::AxisStruct &           theAxis,
2777                                 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2778                                 CORBA::Boolean                      theCopy)
2779 {
2780   if ( !myPreviewMode ) {
2781     TPythonDump() << this << ".Mirror( "
2782                   << theIDsOfElements << ", "
2783                   << theAxis          << ", "
2784                   << mirrorTypeName(theMirrorType) << ", "
2785                   << theCopy          << " )";
2786   }
2787   mirror(theIDsOfElements, theAxis, theMirrorType, theCopy, false);
2788 }
2789
2790
2791 //=======================================================================
2792 //function : MirrorObject
2793 //purpose  :
2794 //=======================================================================
2795
2796 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr           theObject,
2797                                       const SMESH::AxisStruct &           theAxis,
2798                                       SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2799                                       CORBA::Boolean                      theCopy)
2800 {
2801   if ( !myPreviewMode ) {
2802     TPythonDump() << this << ".MirrorObject( "
2803                   << theObject << ", "
2804                   << theAxis   << ", "
2805                   << mirrorTypeName(theMirrorType) << ", "
2806                   << theCopy   << " )";
2807   }
2808   SMESH::long_array_var anElementsId = theObject->GetIDs();
2809   mirror(anElementsId, theAxis, theMirrorType, theCopy, false);
2810 }
2811
2812 //=======================================================================
2813 //function : MirrorMakeGroups
2814 //purpose  : 
2815 //=======================================================================
2816
2817 SMESH::ListOfGroups*
2818 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array&            theIDsOfElements,
2819                                      const SMESH::AxisStruct&            theMirror,
2820                                      SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
2821 {
2822   SMESH::ListOfGroups * aGroups = mirror(theIDsOfElements, theMirror, theMirrorType, true, true);
2823   if ( !myPreviewMode ) {
2824     TPythonDump aPythonDump;
2825     DumpGroupsList(aPythonDump,aGroups);
2826     aPythonDump << this << ".MirrorMakeGroups( "
2827                 << theIDsOfElements << ", "
2828                 << theMirror << ", "
2829                 << mirrorTypeName(theMirrorType) << " )";
2830   }
2831   return aGroups;
2832 }
2833
2834 //=======================================================================
2835 //function : MirrorObjectMakeGroups
2836 //purpose  : 
2837 //=======================================================================
2838
2839 SMESH::ListOfGroups*
2840 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr           theObject,
2841                                            const SMESH::AxisStruct&            theMirror,
2842                                            SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
2843 {
2844   SMESH::long_array_var anElementsId = theObject->GetIDs();
2845   SMESH::ListOfGroups * aGroups = mirror(anElementsId, theMirror, theMirrorType, true, true);
2846   if ( !myPreviewMode ) {
2847     TPythonDump aPythonDump;
2848     DumpGroupsList(aPythonDump,aGroups);
2849     aPythonDump << this << ".MirrorObjectMakeGroups( "
2850                 << theObject << ", "
2851                 << theMirror << ", "
2852                 << mirrorTypeName(theMirrorType) << " )";
2853   }
2854   return aGroups;
2855 }
2856
2857 //=======================================================================
2858 //function : MirrorMakeMesh
2859 //purpose  : 
2860 //=======================================================================
2861
2862 SMESH::SMESH_Mesh_ptr
2863 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array&            theIDsOfElements,
2864                                    const SMESH::AxisStruct&            theMirror,
2865                                    SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2866                                    CORBA::Boolean                      theCopyGroups,
2867                                    const char*                         theMeshName)
2868 {
2869   SMESH_Mesh_i* mesh_i;
2870   SMESH::SMESH_Mesh_var mesh;
2871   { // open new scope to dump "MakeMesh" command
2872     // and then "GetGroups" using SMESH_Mesh::GetGroups()
2873     
2874     TPythonDump pydump; // to prevent dump at mesh creation
2875
2876     mesh = makeMesh( theMeshName );
2877     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
2878     if (mesh_i) {
2879       mirror(theIDsOfElements, theMirror, theMirrorType,
2880              false, theCopyGroups, & mesh_i->GetImpl());
2881       mesh_i->CreateGroupServants();
2882     }
2883     
2884     if ( !myPreviewMode ) {
2885       pydump << mesh << " = " << this << ".MirrorMakeMesh( "
2886              << theIDsOfElements << ", "
2887              << theMirror   << ", "
2888              << mirrorTypeName(theMirrorType) << ", "
2889              << theCopyGroups << ", '"
2890              << theMeshName << "' )";
2891     }
2892   }
2893
2894   //dump "GetGroups"
2895   if(!myPreviewMode && mesh_i)
2896     mesh_i->GetGroups();
2897   
2898   return mesh._retn();
2899 }
2900
2901 //=======================================================================
2902 //function : MirrorObjectMakeMesh
2903 //purpose  : 
2904 //=======================================================================
2905
2906 SMESH::SMESH_Mesh_ptr
2907 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr           theObject,
2908                                          const SMESH::AxisStruct&            theMirror,
2909                                          SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2910                                          CORBA::Boolean                      theCopyGroups,
2911                                          const char*                         theMeshName)
2912 {
2913   SMESH_Mesh_i* mesh_i;
2914   SMESH::SMESH_Mesh_var mesh;
2915   { // open new scope to dump "MakeMesh" command
2916     // and then "GetGroups" using SMESH_Mesh::GetGroups()
2917     
2918     TPythonDump pydump; // to prevent dump at mesh creation
2919
2920     mesh = makeMesh( theMeshName );
2921     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
2922     if ( mesh_i ) {
2923       SMESH::long_array_var anElementsId = theObject->GetIDs();
2924       mirror(anElementsId, theMirror, theMirrorType,
2925              false, theCopyGroups, & mesh_i->GetImpl());
2926       mesh_i->CreateGroupServants();
2927     }
2928
2929     if ( !myPreviewMode ) {
2930       pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
2931              << theObject << ", "
2932              << theMirror   << ", "
2933              << mirrorTypeName(theMirrorType) << ", "
2934              << theCopyGroups << ", '"
2935              << theMeshName << "' )";
2936     }
2937   } 
2938
2939   //dump "GetGroups"
2940   if(!myPreviewMode && mesh_i)
2941     mesh_i->GetGroups();
2942   
2943   return mesh._retn();
2944 }
2945
2946 //=======================================================================
2947 //function : translate
2948 //purpose  : 
2949 //=======================================================================
2950
2951 SMESH::ListOfGroups*
2952 SMESH_MeshEditor_i::translate(const SMESH::long_array & theIDsOfElements,
2953                               const SMESH::DirStruct &  theVector,
2954                               CORBA::Boolean            theCopy,
2955                               const bool                theMakeGroups,
2956                               ::SMESH_Mesh*             theTargetMesh)
2957 {
2958   initData();
2959
2960   TIDSortedElemSet elements;
2961   arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2962
2963   gp_Trsf aTrsf;
2964   const SMESH::PointStruct * P = &theVector.PS;
2965   aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
2966
2967   ::SMESH_MeshEditor anEditor( myMesh );
2968   ::SMESH_MeshEditor::PGroupIDs groupIds =
2969       anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
2970
2971   if(theCopy)
2972     storeResult(anEditor);
2973
2974   return theMakeGroups ? getGroups(groupIds.get()) : 0;
2975 }
2976
2977 //=======================================================================
2978 //function : Translate
2979 //purpose  :
2980 //=======================================================================
2981
2982 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
2983                                    const SMESH::DirStruct &  theVector,
2984                                    CORBA::Boolean            theCopy)
2985 {
2986   if ( !myPreviewMode ) {
2987     TPythonDump() << this << ".Translate( "
2988                   << theIDsOfElements << ", "
2989                   << theVector << ", "
2990                   << theCopy << " )";
2991   }
2992   translate(theIDsOfElements,
2993             theVector,
2994             theCopy,
2995             false);
2996 }
2997
2998 //=======================================================================
2999 //function : TranslateObject
3000 //purpose  :
3001 //=======================================================================
3002
3003 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3004                                          const SMESH::DirStruct &  theVector,
3005                                          CORBA::Boolean            theCopy)
3006 {
3007   if ( !myPreviewMode ) {
3008     TPythonDump() << this << ".TranslateObject( "
3009                   << theObject << ", "
3010                   << theVector << ", "
3011                   << theCopy << " )";
3012   }
3013   SMESH::long_array_var anElementsId = theObject->GetIDs();
3014   translate(anElementsId,
3015             theVector,
3016             theCopy,
3017             false);
3018 }
3019
3020 //=======================================================================
3021 //function : TranslateMakeGroups
3022 //purpose  : 
3023 //=======================================================================
3024
3025 SMESH::ListOfGroups*
3026 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3027                                         const SMESH::DirStruct&  theVector)
3028 {
3029   SMESH::ListOfGroups * aGroups = translate(theIDsOfElements,theVector,true,true);
3030   if ( !myPreviewMode ) {
3031     TPythonDump aPythonDump;
3032     DumpGroupsList(aPythonDump,aGroups);
3033     aPythonDump << this << ".TranslateMakeGroups( "
3034                 << theIDsOfElements << ", "
3035                 << theVector << " )";
3036   }
3037   return aGroups;
3038 }
3039
3040 //=======================================================================
3041 //function : TranslateObjectMakeGroups
3042 //purpose  : 
3043 //=======================================================================
3044
3045 SMESH::ListOfGroups*
3046 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3047                                               const SMESH::DirStruct&   theVector)
3048 {
3049   SMESH::long_array_var anElementsId = theObject->GetIDs();
3050   SMESH::ListOfGroups * aGroups = translate(anElementsId, theVector, true, true);
3051   
3052   if ( !myPreviewMode ) {
3053
3054     TPythonDump aPythonDump;
3055     DumpGroupsList(aPythonDump,aGroups);
3056     aPythonDump << this << ".TranslateObjectMakeGroups( "
3057                 << theObject << ", "
3058                 << theVector << " )";
3059   }
3060   return aGroups;
3061 }
3062
3063 //=======================================================================
3064 //function : TranslateMakeMesh
3065 //purpose  : 
3066 //=======================================================================
3067
3068 SMESH::SMESH_Mesh_ptr
3069 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3070                                       const SMESH::DirStruct&  theVector,
3071                                       CORBA::Boolean           theCopyGroups,
3072                                       const char*              theMeshName)
3073 {
3074   SMESH_Mesh_i* mesh_i;
3075   SMESH::SMESH_Mesh_var mesh;
3076   
3077   { // open new scope to dump "MakeMesh" command
3078     // and then "GetGroups" using SMESH_Mesh::GetGroups()
3079
3080     TPythonDump pydump; // to prevent dump at mesh creation
3081     
3082     mesh = makeMesh( theMeshName );
3083     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3084     
3085     if ( mesh_i ) {
3086       translate(theIDsOfElements, theVector,
3087                 false, theCopyGroups, & mesh_i->GetImpl());
3088       mesh_i->CreateGroupServants();
3089     }
3090     
3091     if ( !myPreviewMode ) {
3092       pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3093              << theIDsOfElements << ", "
3094              << theVector   << ", "
3095              << theCopyGroups << ", '"
3096              << theMeshName << "' )";
3097     }
3098   }
3099   
3100   //dump "GetGroups"
3101   if(!myPreviewMode && mesh_i)
3102     mesh_i->GetGroups();
3103   
3104   return mesh._retn();
3105 }
3106
3107 //=======================================================================
3108 //function : TranslateObjectMakeMesh
3109 //purpose  : 
3110 //=======================================================================
3111
3112 SMESH::SMESH_Mesh_ptr
3113 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3114                                             const SMESH::DirStruct&   theVector,
3115                                             CORBA::Boolean            theCopyGroups,
3116                                             const char*               theMeshName)
3117 {
3118   SMESH_Mesh_i* mesh_i;
3119   SMESH::SMESH_Mesh_var mesh;
3120   { // open new scope to dump "MakeMesh" command
3121     // and then "GetGroups" using SMESH_Mesh::GetGroups()
3122     
3123     TPythonDump pydump; // to prevent dump at mesh creation
3124     mesh = makeMesh( theMeshName );
3125     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3126     
3127     if ( mesh_i ) {
3128       SMESH::long_array_var anElementsId = theObject->GetIDs();
3129       translate(anElementsId, theVector,
3130                 false, theCopyGroups, & mesh_i->GetImpl());
3131       mesh_i->CreateGroupServants();
3132     }
3133     if ( !myPreviewMode ) {
3134       pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3135              << theObject << ", "
3136              << theVector   << ", "
3137              << theCopyGroups << ", '"
3138              << theMeshName << "' )";
3139     }
3140   }
3141   
3142   //dump "GetGroups"
3143   if(!myPreviewMode && mesh_i)
3144     mesh_i->GetGroups();
3145   
3146   return mesh._retn();
3147 }
3148
3149 //=======================================================================
3150 //function : rotate
3151 //purpose  : 
3152 //=======================================================================
3153
3154 SMESH::ListOfGroups*
3155 SMESH_MeshEditor_i::rotate(const SMESH::long_array & theIDsOfElements,
3156                            const SMESH::AxisStruct & theAxis,
3157                            CORBA::Double             theAngle,
3158                            CORBA::Boolean            theCopy,
3159                            const bool                theMakeGroups,
3160                            ::SMESH_Mesh*             theTargetMesh)
3161 {
3162   initData();
3163
3164   TIDSortedElemSet elements;
3165   arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3166
3167   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3168   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3169
3170   gp_Trsf aTrsf;
3171   aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3172
3173   ::SMESH_MeshEditor anEditor( myMesh );
3174   ::SMESH_MeshEditor::PGroupIDs groupIds =
3175       anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3176
3177   if(theCopy) {
3178     storeResult(anEditor);
3179   }
3180   return theMakeGroups ? getGroups(groupIds.get()) : 0;
3181 }
3182
3183 //=======================================================================
3184 //function : Rotate
3185 //purpose  :
3186 //=======================================================================
3187
3188 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3189                                 const SMESH::AxisStruct & theAxis,
3190                                 CORBA::Double             theAngle,
3191                                 CORBA::Boolean            theCopy)
3192 {
3193   if ( !myPreviewMode ) {
3194     TPythonDump() << this << ".Rotate( "
3195                   << theIDsOfElements << ", "
3196                   << theAxis << ", "
3197                   << theAngle << ", "
3198                   << theCopy << " )";
3199   }
3200   rotate(theIDsOfElements,
3201          theAxis,
3202          theAngle,
3203          theCopy,
3204          false);
3205 }
3206
3207 //=======================================================================
3208 //function : RotateObject
3209 //purpose  :
3210 //=======================================================================
3211
3212 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3213                                       const SMESH::AxisStruct & theAxis,
3214                                       CORBA::Double             theAngle,
3215                                       CORBA::Boolean            theCopy)
3216 {
3217   if ( !myPreviewMode ) {
3218     TPythonDump() << this << ".RotateObject( "
3219                   << theObject << ", "
3220                   << theAxis << ", "
3221                   << theAngle << ", "
3222                   << theCopy << " )";
3223   }
3224   SMESH::long_array_var anElementsId = theObject->GetIDs();
3225   rotate(anElementsId,
3226          theAxis,
3227          theAngle,
3228          theCopy,
3229          false);
3230 }
3231
3232 //=======================================================================
3233 //function : RotateMakeGroups
3234 //purpose  : 
3235 //=======================================================================
3236
3237 SMESH::ListOfGroups*
3238 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3239                                      const SMESH::AxisStruct& theAxis,
3240                                      CORBA::Double            theAngle)
3241 {
3242   SMESH::ListOfGroups * aGroups =  rotate(theIDsOfElements,theAxis,theAngle,true,true);
3243   if ( !myPreviewMode ) {
3244     TPythonDump aPythonDump;
3245     DumpGroupsList(aPythonDump,aGroups);
3246     aPythonDump << this << ".RotateMakeGroups( "
3247                 << theIDsOfElements << ", "
3248                 << theAxis << ", "
3249                 << theAngle << " )";
3250   }
3251   return aGroups;
3252 }
3253
3254 //=======================================================================
3255 //function : RotateObjectMakeGroups
3256 //purpose  : 
3257 //=======================================================================
3258
3259 SMESH::ListOfGroups*
3260 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3261                                            const SMESH::AxisStruct&  theAxis,
3262                                            CORBA::Double             theAngle)
3263 {
3264   SMESH::long_array_var anElementsId = theObject->GetIDs();
3265   SMESH::ListOfGroups * aGroups =  rotate(anElementsId,theAxis,theAngle,true,true);
3266  
3267   if ( !myPreviewMode ) {
3268     TPythonDump aPythonDump;
3269     DumpGroupsList(aPythonDump,aGroups);
3270     aPythonDump << this << ".RotateObjectMakeGroups( "
3271                 << theObject << ", "
3272                 << theAxis << ", "
3273                 << theAngle << " )";
3274   }
3275   return aGroups;
3276 }
3277
3278 //=======================================================================
3279 //function : RotateMakeMesh
3280 //purpose  : 
3281 //=======================================================================
3282
3283 SMESH::SMESH_Mesh_ptr 
3284 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
3285                                    const SMESH::AxisStruct& theAxis,
3286                                    CORBA::Double            theAngleInRadians,
3287                                    CORBA::Boolean           theCopyGroups,
3288                                    const char*              theMeshName)
3289 {
3290   SMESH::SMESH_Mesh_var mesh;
3291   SMESH_Mesh_i* mesh_i;
3292
3293   { // open new scope to dump "MakeMesh" command
3294     // and then "GetGroups" using SMESH_Mesh::GetGroups()
3295     
3296     TPythonDump pydump; // to prevent dump at mesh creation
3297
3298     mesh = makeMesh( theMeshName );
3299     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3300     
3301     if ( mesh_i ) {
3302       rotate(theIDsOfElements, theAxis, theAngleInRadians,
3303              false, theCopyGroups, & mesh_i->GetImpl());
3304       mesh_i->CreateGroupServants();
3305     }
3306     if ( !myPreviewMode ) {
3307       pydump << mesh << " = " << this << ".RotateMakeMesh( "
3308              << theIDsOfElements << ", "
3309              << theAxis << ", "
3310              << theAngleInRadians   << ", "
3311              << theCopyGroups << ", '"
3312              << theMeshName << "' )";
3313     }
3314   }
3315   
3316   //dump "GetGroups"
3317   if(!myPreviewMode && mesh_i)
3318     mesh_i->GetGroups();
3319   
3320   return mesh._retn();
3321 }
3322
3323 //=======================================================================
3324 //function : RotateObjectMakeMesh
3325 //purpose  : 
3326 //=======================================================================
3327
3328 SMESH::SMESH_Mesh_ptr 
3329 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3330                                          const SMESH::AxisStruct&  theAxis,
3331                                          CORBA::Double             theAngleInRadians,
3332                                          CORBA::Boolean            theCopyGroups,
3333                                          const char*               theMeshName)
3334 {
3335   SMESH::SMESH_Mesh_var mesh;
3336   SMESH_Mesh_i* mesh_i;
3337   
3338   {// open new scope to dump "MakeMesh" command
3339    // and then "GetGroups" using SMESH_Mesh::GetGroups()
3340     
3341     TPythonDump pydump; // to prevent dump at mesh creation
3342     mesh = makeMesh( theMeshName );
3343     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3344     
3345     if (mesh_i ) {
3346       SMESH::long_array_var anElementsId = theObject->GetIDs();
3347       rotate(anElementsId, theAxis, theAngleInRadians,
3348              false, theCopyGroups, & mesh_i->GetImpl());
3349       mesh_i->CreateGroupServants();
3350     }
3351     if ( !myPreviewMode ) {
3352       pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
3353              << theObject << ", "
3354              << theAxis << ", "
3355              << theAngleInRadians   << ", "
3356              << theCopyGroups << ", '"
3357              << theMeshName << "' )";
3358     }
3359   }
3360   
3361   //dump "GetGroups"
3362   if(!myPreviewMode && mesh_i)
3363     mesh_i->GetGroups();
3364   
3365   return mesh._retn();
3366 }
3367
3368 //=======================================================================
3369 //function : FindCoincidentNodes
3370 //purpose  :
3371 //=======================================================================
3372
3373 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
3374                                               SMESH::array_of_long_array_out GroupsOfNodes)
3375 {
3376   initData();
3377
3378   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3379   ::SMESH_MeshEditor anEditor( myMesh );
3380   set<const SMDS_MeshNode*> nodes; // no input nodes
3381   anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3382
3383   GroupsOfNodes = new SMESH::array_of_long_array;
3384   GroupsOfNodes->length( aListOfListOfNodes.size() );
3385   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3386   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
3387     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3388     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3389     SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3390     aGroup.length( aListOfNodes.size() );
3391     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3392       aGroup[ j ] = (*lIt)->GetID();
3393   }
3394   TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
3395                 << Tolerance << " )";
3396 }
3397
3398 //=======================================================================
3399 //function : FindCoincidentNodesOnPart
3400 //purpose  :
3401 //=======================================================================
3402 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr      theObject,
3403                                                    CORBA::Double                  Tolerance,
3404                                                    SMESH::array_of_long_array_out GroupsOfNodes)
3405 {
3406   initData();
3407   SMESH::long_array_var aElementsId = theObject->GetIDs();
3408
3409   SMESHDS_Mesh* aMesh = GetMeshDS();
3410   set<const SMDS_MeshNode*> nodes;
3411
3412   if ( !CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) &&
3413       SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) {
3414     for(int i = 0; i < aElementsId->length(); i++) {
3415       CORBA::Long ind = aElementsId[i];
3416       const SMDS_MeshNode * elem = aMesh->FindNode(ind);
3417       if(elem)
3418         nodes.insert(elem);
3419     }
3420   }
3421   else {
3422     for(int i = 0; i < aElementsId->length(); i++) {
3423       CORBA::Long ind = aElementsId[i];
3424       const SMDS_MeshElement * elem = aMesh->FindElement(ind);
3425       if(elem) {
3426         SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
3427         while ( nIt->more() )
3428           nodes.insert( nodes.end(),static_cast<const SMDS_MeshNode*>(nIt->next()));
3429       }
3430     }
3431   }
3432     
3433   
3434   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3435   ::SMESH_MeshEditor anEditor( myMesh );
3436   if(!nodes.empty())
3437     anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3438   
3439   GroupsOfNodes = new SMESH::array_of_long_array;
3440   GroupsOfNodes->length( aListOfListOfNodes.size() );
3441   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3442   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
3443     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3444     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3445     SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3446     aGroup.length( aListOfNodes.size() );
3447     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3448       aGroup[ j ] = (*lIt)->GetID();
3449   }
3450   TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
3451                 <<theObject<<", "
3452                 << Tolerance << " )";
3453 }
3454
3455 //=======================================================================
3456 //function : MergeNodes
3457 //purpose  :
3458 //=======================================================================
3459
3460 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
3461 {
3462   initData();
3463
3464   SMESHDS_Mesh* aMesh = GetMeshDS();
3465
3466   TPythonDump aTPythonDump;
3467   aTPythonDump << this << ".MergeNodes([";
3468   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3469   for (int i = 0; i < GroupsOfNodes.length(); i++)
3470   {
3471     const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
3472     aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
3473     list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
3474     for ( int j = 0; j < aNodeGroup.length(); j++ )
3475     {
3476       CORBA::Long index = aNodeGroup[ j ];
3477       const SMDS_MeshNode * node = aMesh->FindNode(index);
3478       if ( node )
3479         aListOfNodes.push_back( node );
3480     }
3481     if ( aListOfNodes.size() < 2 )
3482       aListOfListOfNodes.pop_back();
3483
3484     if ( i > 0 ) aTPythonDump << ", ";
3485     aTPythonDump << aNodeGroup;
3486   }
3487   ::SMESH_MeshEditor anEditor( myMesh );
3488   anEditor.MergeNodes( aListOfListOfNodes );
3489
3490   aTPythonDump <<  "])";
3491 }
3492
3493 //=======================================================================
3494 //function : FindEqualElements
3495 //purpose  :
3496 //=======================================================================
3497 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr      theObject,
3498                                            SMESH::array_of_long_array_out GroupsOfElementsID)
3499 {
3500   initData();
3501   if ( !(!CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) &&
3502          SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) ) {
3503     typedef list<int> TListOfIDs;
3504     set<const SMDS_MeshElement*> elems;
3505     SMESH::long_array_var aElementsId = theObject->GetIDs();
3506     SMESHDS_Mesh* aMesh = GetMeshDS();
3507
3508     for(int i = 0; i < aElementsId->length(); i++) {
3509       CORBA::Long anID = aElementsId[i];
3510       const SMDS_MeshElement * elem = aMesh->FindElement(anID);
3511       if (elem) {
3512         elems.insert(elem);
3513       }
3514     }
3515
3516     ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
3517     ::SMESH_MeshEditor anEditor( myMesh );
3518     anEditor.FindEqualElements( elems, aListOfListOfElementsID );
3519
3520     GroupsOfElementsID = new SMESH::array_of_long_array;
3521     GroupsOfElementsID->length( aListOfListOfElementsID.size() );
3522
3523     ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
3524     for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
3525       SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
3526       TListOfIDs& listOfIDs = *arraysIt;
3527       aGroup.length( listOfIDs.size() );
3528       TListOfIDs::iterator idIt = listOfIDs.begin();
3529       for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
3530         aGroup[ k ] = *idIt;
3531       }
3532     }
3533
3534   TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
3535                 <<theObject<<" )";
3536   }
3537 }
3538
3539 //=======================================================================
3540 //function : MergeElements
3541 //purpose  :
3542 //=======================================================================
3543
3544 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
3545 {
3546   initData();
3547
3548   TPythonDump aTPythonDump;
3549   aTPythonDump << this << ".MergeElements( [";
3550
3551   ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
3552
3553   for (int i = 0; i < GroupsOfElementsID.length(); i++) {
3554     const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
3555     aListOfListOfElementsID.push_back( list< int >() );
3556     list< int >& aListOfElemsID = aListOfListOfElementsID.back();
3557     for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
3558       CORBA::Long id = anElemsIDGroup[ j ];
3559       aListOfElemsID.push_back( id );
3560     }
3561     if ( aListOfElemsID.size() < 2 )
3562       aListOfListOfElementsID.pop_back();
3563     if ( i > 0 ) aTPythonDump << ", ";
3564     aTPythonDump << anElemsIDGroup;
3565   }
3566
3567   ::SMESH_MeshEditor anEditor( myMesh );
3568   anEditor.MergeElements(aListOfListOfElementsID);
3569
3570   aTPythonDump << "] )";
3571 }
3572
3573 //=======================================================================
3574 //function : MergeEqualElements
3575 //purpose  :
3576 //=======================================================================
3577
3578 void SMESH_MeshEditor_i::MergeEqualElements()
3579 {
3580   initData();
3581
3582   ::SMESH_MeshEditor anEditor( myMesh );
3583   anEditor.MergeEqualElements();
3584
3585   TPythonDump() << this << ".MergeEqualElements()";
3586 }
3587
3588 //================================================================================
3589 /*!
3590  * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
3591  * move the node closest to the point to point's location and return ID of the node
3592  */
3593 //================================================================================
3594
3595 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
3596                                                        CORBA::Double y,
3597                                                        CORBA::Double z,
3598                                                        CORBA::Long   theNodeID)
3599 {
3600   // We keep myNodeSearcher until any mesh modification:
3601   // 1) initData() deletes myNodeSearcher at any edition,
3602   // 2) TNodeSearcherDeleter - at any mesh compute event and mesh change
3603
3604   initData();
3605
3606   int nodeID = theNodeID;
3607   const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
3608   if ( !node )
3609   {
3610     static TNodeSearcherDeleter deleter;
3611     deleter.Set( myMesh );
3612     if ( !myNodeSearcher ) {
3613       ::SMESH_MeshEditor anEditor( myMesh );
3614       myNodeSearcher = anEditor.GetNodeSearcher();
3615     }
3616     gp_Pnt p( x,y,z );
3617     node = myNodeSearcher->FindClosestTo( p );
3618   }
3619   if ( node ) {
3620     nodeID = node->GetID();
3621     if ( myPreviewMode ) // make preview data
3622     {
3623       // in a preview mesh, make edges linked to a node
3624       TPreviewMesh tmpMesh;
3625       TIDSortedElemSet linkedNodes;
3626       ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
3627       TIDSortedElemSet::iterator nIt = linkedNodes.begin();
3628       for ( ; nIt != linkedNodes.end(); ++nIt )
3629       {
3630         SMDS_MeshEdge edge( node, cast2Node( *nIt ));
3631         tmpMesh.Copy( &edge );
3632       }
3633       // move copied node
3634       node = tmpMesh.GetMeshDS()->FindNode( nodeID );
3635       if ( node )
3636         tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
3637       // fill preview data
3638       ::SMESH_MeshEditor anEditor( & tmpMesh );
3639       storeResult( anEditor );
3640     }
3641     else
3642     {
3643       GetMeshDS()->MoveNode(node, x, y, z);
3644     }
3645   }
3646
3647   if ( !myPreviewMode ) {
3648     TPythonDump() << "nodeID = " << this
3649                   << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
3650                   << ", " << nodeID << " )";
3651   }
3652
3653   return nodeID;
3654 }
3655
3656 //=======================================================================
3657 //function : convError
3658 //purpose  :
3659 //=======================================================================
3660
3661 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
3662
3663 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
3664 {
3665   switch ( e ) {
3666   RETCASE( SEW_OK );
3667   RETCASE( SEW_BORDER1_NOT_FOUND );
3668   RETCASE( SEW_BORDER2_NOT_FOUND );
3669   RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
3670   RETCASE( SEW_BAD_SIDE_NODES );
3671   RETCASE( SEW_VOLUMES_TO_SPLIT );
3672   RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
3673   RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
3674   RETCASE( SEW_BAD_SIDE1_NODES );
3675   RETCASE( SEW_BAD_SIDE2_NODES );
3676   }
3677   return SMESH::SMESH_MeshEditor::SEW_OK;
3678 }
3679
3680 //=======================================================================
3681 //function : SewFreeBorders
3682 //purpose  :
3683 //=======================================================================
3684
3685 SMESH::SMESH_MeshEditor::Sew_Error
3686   SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
3687                                      CORBA::Long SecondNodeID1,
3688                                      CORBA::Long LastNodeID1,
3689                                      CORBA::Long FirstNodeID2,
3690                                      CORBA::Long SecondNodeID2,
3691                                      CORBA::Long LastNodeID2,
3692                                      CORBA::Boolean CreatePolygons,
3693                                      CORBA::Boolean CreatePolyedrs)
3694 {
3695   initData();
3696
3697   SMESHDS_Mesh* aMesh = GetMeshDS();
3698
3699   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
3700   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
3701   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
3702   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
3703   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
3704   const SMDS_MeshNode* aSide2ThirdNode   = aMesh->FindNode( LastNodeID2   );
3705
3706   if (!aBorderFirstNode ||
3707       !aBorderSecondNode||
3708       !aBorderLastNode)
3709     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
3710   if (!aSide2FirstNode  ||
3711       !aSide2SecondNode ||
3712       !aSide2ThirdNode)
3713     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
3714
3715   TPythonDump() << "error = " << this << ".SewFreeBorders( "
3716                 << FirstNodeID1  << ", "
3717                 << SecondNodeID1 << ", "
3718                 << LastNodeID1   << ", "
3719                 << FirstNodeID2  << ", "
3720                 << SecondNodeID2 << ", "
3721                 << LastNodeID2   << ", "
3722                 << CreatePolygons<< ", "
3723                 << CreatePolyedrs<< " )";
3724
3725   ::SMESH_MeshEditor anEditor( myMesh );
3726   SMESH::SMESH_MeshEditor::Sew_Error error =
3727     convError( anEditor.SewFreeBorder (aBorderFirstNode,
3728                                        aBorderSecondNode,
3729                                        aBorderLastNode,
3730                                        aSide2FirstNode,
3731                                        aSide2SecondNode,
3732                                        aSide2ThirdNode,
3733                                        true,
3734                                        CreatePolygons,
3735                                        CreatePolyedrs) );
3736
3737   storeResult(anEditor);
3738
3739   return error;
3740 }
3741
3742
3743 //=======================================================================
3744 //function : SewConformFreeBorders
3745 //purpose  :
3746 //=======================================================================
3747
3748 SMESH::SMESH_MeshEditor::Sew_Error
3749 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
3750                                           CORBA::Long SecondNodeID1,
3751                                           CORBA::Long LastNodeID1,
3752                                           CORBA::Long FirstNodeID2,
3753                                           CORBA::Long SecondNodeID2)
3754 {
3755   initData();
3756
3757   SMESHDS_Mesh* aMesh = GetMeshDS();
3758
3759   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
3760   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
3761   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
3762   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
3763   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
3764   const SMDS_MeshNode* aSide2ThirdNode   = 0;
3765
3766   if (!aBorderFirstNode ||
3767       !aBorderSecondNode||
3768       !aBorderLastNode )
3769     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
3770   if (!aSide2FirstNode  ||
3771       !aSide2SecondNode)
3772     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
3773
3774   TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
3775                 << FirstNodeID1  << ", "
3776                 << SecondNodeID1 << ", "
3777                 << LastNodeID1   << ", "
3778                 << FirstNodeID2  << ", "
3779                 << SecondNodeID2 << " )";
3780
3781   ::SMESH_MeshEditor anEditor( myMesh );
3782   SMESH::SMESH_MeshEditor::Sew_Error error =
3783     convError( anEditor.SewFreeBorder (aBorderFirstNode,
3784                                        aBorderSecondNode,
3785                                        aBorderLastNode,
3786                                        aSide2FirstNode,
3787                                        aSide2SecondNode,
3788                                        aSide2ThirdNode,
3789                                        true,
3790                                        false, false) );
3791
3792   storeResult(anEditor);
3793
3794   return error;
3795 }
3796
3797
3798 //=======================================================================
3799 //function : SewBorderToSide
3800 //purpose  :
3801 //=======================================================================
3802
3803 SMESH::SMESH_MeshEditor::Sew_Error
3804 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
3805                                     CORBA::Long SecondNodeIDOnFreeBorder,
3806                                     CORBA::Long LastNodeIDOnFreeBorder,
3807                                     CORBA::Long FirstNodeIDOnSide,
3808                                     CORBA::Long LastNodeIDOnSide,
3809                                     CORBA::Boolean CreatePolygons,
3810                                     CORBA::Boolean CreatePolyedrs)
3811 {
3812   initData();
3813
3814   SMESHDS_Mesh* aMesh = GetMeshDS();
3815
3816   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeIDOnFreeBorder  );
3817   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
3818   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeIDOnFreeBorder   );
3819   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeIDOnSide  );
3820   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( LastNodeIDOnSide );
3821   const SMDS_MeshNode* aSide2ThirdNode   = 0;
3822
3823   if (!aBorderFirstNode ||
3824       !aBorderSecondNode||
3825       !aBorderLastNode  )
3826     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
3827   if (!aSide2FirstNode  ||
3828       !aSide2SecondNode)
3829     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
3830
3831   TPythonDump() << "error = " << this << ".SewBorderToSide( "
3832                 << FirstNodeIDOnFreeBorder  << ", "
3833                 << SecondNodeIDOnFreeBorder << ", "
3834                 << LastNodeIDOnFreeBorder   << ", "
3835                 << FirstNodeIDOnSide        << ", "
3836                 << LastNodeIDOnSide         << ", "
3837                 << CreatePolygons           << ", "
3838                 << CreatePolyedrs           << ") ";
3839
3840   ::SMESH_MeshEditor anEditor( myMesh );
3841   SMESH::SMESH_MeshEditor::Sew_Error error =
3842     convError( anEditor.SewFreeBorder (aBorderFirstNode,
3843                                        aBorderSecondNode,
3844                                        aBorderLastNode,
3845                                        aSide2FirstNode,
3846                                        aSide2SecondNode,
3847                                        aSide2ThirdNode,
3848                                        false,
3849                                        CreatePolygons,
3850                                        CreatePolyedrs) );
3851
3852   storeResult(anEditor);
3853
3854   return error;
3855 }
3856
3857
3858 //=======================================================================
3859 //function : SewSideElements
3860 //purpose  :
3861 //=======================================================================
3862
3863 SMESH::SMESH_MeshEditor::Sew_Error
3864 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
3865                                     const SMESH::long_array& IDsOfSide2Elements,
3866                                     CORBA::Long NodeID1OfSide1ToMerge,
3867                                     CORBA::Long NodeID1OfSide2ToMerge,
3868                                     CORBA::Long NodeID2OfSide1ToMerge,
3869                                     CORBA::Long NodeID2OfSide2ToMerge)
3870 {
3871   initData();
3872
3873   SMESHDS_Mesh* aMesh = GetMeshDS();
3874
3875   const SMDS_MeshNode* aFirstNode1ToMerge  = aMesh->FindNode( NodeID1OfSide1ToMerge );
3876   const SMDS_MeshNode* aFirstNode2ToMerge  = aMesh->FindNode( NodeID1OfSide2ToMerge );
3877   const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
3878   const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
3879
3880   if (!aFirstNode1ToMerge ||
3881       !aFirstNode2ToMerge )
3882     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
3883   if (!aSecondNode1ToMerge||
3884       !aSecondNode2ToMerge)
3885     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
3886
3887   TIDSortedElemSet aSide1Elems, aSide2Elems;
3888   arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
3889   arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
3890
3891   TPythonDump() << "error = " << this << ".SewSideElements( "
3892                 << IDsOfSide1Elements << ", "
3893                 << IDsOfSide2Elements << ", "
3894                 << NodeID1OfSide1ToMerge << ", "
3895                 << NodeID1OfSide2ToMerge << ", "
3896                 << NodeID2OfSide1ToMerge << ", "
3897                 << NodeID2OfSide2ToMerge << ")";
3898
3899   ::SMESH_MeshEditor anEditor( myMesh );
3900   SMESH::SMESH_MeshEditor::Sew_Error error =
3901     convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
3902                                          aFirstNode1ToMerge,
3903                                          aFirstNode2ToMerge,
3904                                          aSecondNode1ToMerge,
3905                                          aSecondNode2ToMerge));
3906
3907   storeResult(anEditor);
3908
3909   return error;
3910 }
3911
3912 //================================================================================
3913 /*!
3914  * \brief Set new nodes for given element
3915   * \param ide - element id
3916   * \param newIDs - new node ids
3917   * \retval CORBA::Boolean - true if result is OK
3918  */
3919 //================================================================================
3920
3921 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
3922                                                    const SMESH::long_array& newIDs)
3923 {
3924   initData();
3925
3926   const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
3927   if(!elem) return false;
3928
3929   int nbn = newIDs.length();
3930   int i=0;
3931   vector<const SMDS_MeshNode*> aNodes(nbn);
3932   int nbn1=-1;
3933   for(; i<nbn; i++) {
3934     const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
3935     if(aNode) {
3936       nbn1++;
3937       aNodes[nbn1] = aNode;
3938     }
3939   }
3940   TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
3941                 << ide << ", " << newIDs << " )";
3942 #ifdef _DEBUG_
3943   TPythonDump() << "print 'ChangeElemNodes: ', isDone";
3944 #endif
3945
3946   return GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
3947 }
3948   
3949 //================================================================================
3950 /*!
3951  * \brief Update myLastCreated* or myPreviewData
3952   * \param anEditor - it contains last modification results
3953  */
3954 //================================================================================
3955
3956 void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& anEditor)
3957 {
3958   if ( myPreviewMode ) { // --- MeshPreviewStruct filling --- 
3959
3960     list<int> aNodesConnectivity;
3961     typedef map<int, int> TNodesMap;
3962     TNodesMap nodesMap;
3963
3964     TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
3965     SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
3966
3967     SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
3968     int nbEdges = aMeshDS->NbEdges();
3969     int nbFaces = aMeshDS->NbFaces();
3970     int nbVolum = aMeshDS->NbVolumes();
3971     switch ( previewType ) {
3972     case SMDSAbs_Edge  : nbFaces = nbVolum = 0; break;
3973     case SMDSAbs_Face  : nbEdges = nbVolum = 0; break;
3974     case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
3975     default:;
3976     }
3977     myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
3978     myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
3979     int i = 0, j = 0;
3980     SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
3981
3982     while ( itMeshElems->more() ) {
3983       const SMDS_MeshElement* aMeshElem = itMeshElems->next();
3984       if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
3985         continue;
3986
3987       SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
3988       while ( itElemNodes->more() ) {
3989         const SMDS_MeshNode* aMeshNode = 
3990           static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
3991         int aNodeID = aMeshNode->GetID();
3992         TNodesMap::iterator anIter = nodesMap.find(aNodeID);
3993         if ( anIter == nodesMap.end() ) {
3994           // filling the nodes coordinates
3995           myPreviewData->nodesXYZ[j].x = aMeshNode->X();
3996           myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
3997           myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
3998           anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
3999           j++;
4000         }
4001         aNodesConnectivity.push_back(anIter->second);
4002       }
4003
4004       // filling the elements types
4005       SMDSAbs_ElementType aType;
4006       bool isPoly;
4007       /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
4008         aType = SMDSAbs_Node;
4009         isPoly = false;
4010       }
4011       else*/ {
4012         aType = aMeshElem->GetType();
4013         isPoly = aMeshElem->IsPoly();
4014       }
4015
4016       myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
4017       myPreviewData->elementTypes[i].isPoly = isPoly;
4018       myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
4019       i++;
4020
4021     }
4022     myPreviewData->nodesXYZ.length( j );
4023
4024     // filling the elements connectivities
4025     list<int>::iterator aConnIter = aNodesConnectivity.begin();
4026     myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
4027     for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
4028       myPreviewData->elementConnectivities[i] = *aConnIter;
4029     
4030     return;
4031   }
4032
4033   {
4034     // add new nodes into myLastCreatedNodes
4035     const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
4036     myLastCreatedNodes->length(aSeq.Length());
4037     for(int i=0; i<aSeq.Length(); i++)
4038       myLastCreatedNodes[i] = aSeq.Value(i+1)->GetID();
4039   }
4040   {
4041     // add new elements into myLastCreatedElems
4042     const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
4043     myLastCreatedElems->length(aSeq.Length());
4044     for(int i=0; i<aSeq.Length(); i++)
4045       myLastCreatedElems[i] = aSeq.Value(i+1)->GetID();
4046   }
4047 }
4048
4049 //================================================================================
4050 /*!
4051  * Return data of mesh edition preview
4052  */
4053 //================================================================================
4054
4055 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
4056 {
4057   return myPreviewData._retn();
4058 }
4059
4060 //================================================================================
4061 /*!
4062  * \brief Returns list of it's IDs of created nodes
4063   * \retval SMESH::long_array* - list of node ID
4064  */
4065 //================================================================================
4066
4067 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
4068 {
4069   return myLastCreatedNodes._retn();
4070 }
4071
4072 //================================================================================
4073 /*!
4074  * \brief Returns list of it's IDs of created elements
4075   * \retval SMESH::long_array* - list of elements' ID
4076  */
4077 //================================================================================
4078
4079 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
4080 {
4081   return myLastCreatedElems._retn();
4082 }
4083
4084 //=======================================================================
4085 //function : ConvertToQuadratic
4086 //purpose  :
4087 //=======================================================================
4088
4089 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
4090 {
4091   ::SMESH_MeshEditor anEditor( myMesh );
4092   anEditor.ConvertToQuadratic(theForce3d);
4093   TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
4094 }
4095
4096 //=======================================================================
4097 //function : ConvertFromQuadratic
4098 //purpose  : 
4099 //=======================================================================
4100
4101 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
4102 {
4103   ::SMESH_MeshEditor anEditor( myMesh );
4104   CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
4105   TPythonDump() << this << ".ConvertFromQuadratic()";
4106   return isDone;
4107 }
4108
4109 //=======================================================================
4110 //function : makeMesh
4111 //purpose  : create a named imported mesh 
4112 //=======================================================================
4113
4114 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
4115 {
4116   SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
4117   SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
4118   SALOMEDS::Study_var study = gen->GetCurrentStudy();
4119   SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
4120   gen->SetName( meshSO, theMeshName, "Mesh" );
4121   gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
4122
4123   return mesh._retn();
4124 }
4125
4126 //=======================================================================
4127 //function : DumpGroupsList
4128 //purpose  :
4129 //=======================================================================
4130 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump &               theDumpPython, 
4131                                         const SMESH::ListOfGroups * theGroupList)
4132 {
4133   bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
4134   if(isDumpGroupList) {
4135     theDumpPython << theGroupList << " = ";
4136   }
4137 }
4138
4139 //================================================================================
4140 /*!
4141   \brief Creates a hole in a mesh by doubling the nodes of some particular elements
4142   \param theElems - the list of elements (edges or faces) to be replicated
4143         The nodes for duplication could be found from these elements
4144   \param theNodesNot - list of nodes to NOT replicate
4145   \param theAffectedElems - the list of elements (cells and edges) to which the 
4146         replicated nodes should be associated to.
4147   \return TRUE if operation has been completed successfully, FALSE otherwise
4148   \sa DoubleNodeGroup(), DoubleNodeGroups()
4149 */
4150 //================================================================================
4151
4152 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theElems, 
4153                                                 const SMESH::long_array& theNodesNot,
4154                                                 const SMESH::long_array& theAffectedElems )
4155  
4156 {
4157   initData();
4158
4159   ::SMESH_MeshEditor aMeshEditor( myMesh );
4160
4161   SMESHDS_Mesh* aMeshDS = GetMeshDS();
4162   TIDSortedElemSet anElems, aNodes, anAffected;
4163   arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
4164   arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
4165   arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
4166
4167   bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
4168
4169   storeResult( aMeshEditor) ;
4170
4171   return aResult;
4172 }
4173
4174 //================================================================================
4175 /*!
4176   \brief Creates a hole in a mesh by doubling the nodes of some particular elements
4177   \param theElems - the list of elements (edges or faces) to be replicated
4178         The nodes for duplication could be found from these elements
4179   \param theNodesNot - list of nodes to NOT replicate
4180   \param theShape - shape to detect affected elements (element which geometric center
4181          located on or inside shape).
4182          The replicated nodes should be associated to affected elements.
4183   \return TRUE if operation has been completed successfully, FALSE otherwise
4184   \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
4185 */
4186 //================================================================================
4187
4188 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesInRegion
4189   ( const SMESH::long_array& theElems, 
4190     const SMESH::long_array& theNodesNot,
4191     GEOM::GEOM_Object_ptr    theShape )
4192  
4193 {
4194   initData();
4195
4196   ::SMESH_MeshEditor aMeshEditor( myMesh );
4197
4198   SMESHDS_Mesh* aMeshDS = GetMeshDS();
4199   TIDSortedElemSet anElems, aNodes;
4200   arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
4201   arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
4202
4203   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
4204   bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
4205
4206   storeResult( aMeshEditor) ;
4207
4208   return aResult;
4209 }
4210
4211 //================================================================================
4212 /*!
4213   \brief Creates a hole in a mesh by doubling the nodes of some particular elements
4214   \param theElems - group of of elements (edges or faces) to be replicated
4215   \param theNodesNot - group of nodes not to replicated
4216   \param theAffectedElems - group of elements to which the replicated nodes
4217          should be associated to.
4218   \return TRUE if operation has been completed successfully, FALSE otherwise
4219   \sa DoubleNodes(), DoubleNodeGroups()
4220 */
4221 //================================================================================
4222
4223 static void groupToSet(SMESH::SMESH_GroupBase_ptr theGrp,
4224                        SMESHDS_Mesh*              theMeshDS,
4225                        TIDSortedElemSet&          theElemSet,
4226                        const SMDSAbs_ElementType  theType)
4227  
4228 {
4229   if ( CORBA::is_nil( theGrp ) )
4230     return;
4231   SMESH::long_array_var anIDs = theGrp->GetIDs();
4232   arrayToSet( anIDs, theMeshDS, theElemSet, theType);
4233 }
4234
4235 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup( 
4236   SMESH::SMESH_GroupBase_ptr theElems,
4237   SMESH::SMESH_GroupBase_ptr theNodesNot,
4238   SMESH::SMESH_GroupBase_ptr theAffectedElems )
4239
4240 {
4241   if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
4242     return false;
4243   
4244   initData();
4245
4246   ::SMESH_MeshEditor aMeshEditor( myMesh );
4247
4248   SMESHDS_Mesh* aMeshDS = GetMeshDS();
4249   TIDSortedElemSet anElems, aNodes, anAffected;
4250   groupToSet( theElems, aMeshDS, anElems, SMDSAbs_All ); 
4251   groupToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node ); 
4252   groupToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
4253
4254   bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
4255
4256   storeResult( aMeshEditor) ;
4257
4258   return aResult;
4259 }
4260
4261 //================================================================================
4262 /*!
4263   \brief Creates a hole in a mesh by doubling the nodes of some particular elements
4264   \param theElems - group of of elements (edges or faces) to be replicated
4265   \param theNodesNot - group of nodes not to replicated
4266   \param theShape - shape to detect affected elements (element which geometric center
4267          located on or inside shape).
4268          The replicated nodes should be associated to affected elements.
4269   \return TRUE if operation has been completed successfully, FALSE otherwise
4270   \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
4271 */
4272 //================================================================================
4273
4274 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroupInRegion( 
4275   SMESH::SMESH_GroupBase_ptr theElems,
4276   SMESH::SMESH_GroupBase_ptr theNodesNot,
4277   GEOM::GEOM_Object_ptr      theShape )
4278
4279 {
4280   if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
4281     return false;
4282   
4283   initData();
4284
4285   ::SMESH_MeshEditor aMeshEditor( myMesh );
4286
4287   SMESHDS_Mesh* aMeshDS = GetMeshDS();
4288   TIDSortedElemSet anElems, aNodes, anAffected;
4289   groupToSet( theElems, aMeshDS, anElems, SMDSAbs_All ); 
4290   groupToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node ); 
4291
4292   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
4293   bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
4294
4295   storeResult( aMeshEditor) ;
4296
4297   return aResult;
4298 }
4299
4300 //================================================================================
4301 /*!
4302   \brief Creates a hole in a mesh by doubling the nodes of some particular elements
4303   This method provided for convenience works as DoubleNodes() described above.
4304   \param theElems - list of groups of elements (edges or faces) to be replicated
4305   \param theNodesNot - list of groups of nodes not to replicated
4306   \param theAffectedElems - group of elements to which the replicated nodes
4307          should be associated to.
4308   \return TRUE if operation has been completed successfully, FALSE otherwise
4309   \sa DoubleNodeGroup(), DoubleNodes()
4310 */
4311 //================================================================================
4312
4313 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
4314                              SMESHDS_Mesh*              theMeshDS,
4315                              TIDSortedElemSet&          theElemSet,
4316                              const bool                 theIsNodeGrp)
4317 {
4318   for ( int i = 0, n = theGrpList.length(); i < n; i++ )
4319   {
4320     SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
4321     if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE 
4322                                                  : aGrp->GetType() != SMESH::NODE ) )
4323     {
4324       SMESH::long_array_var anIDs = aGrp->GetIDs();
4325       arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
4326     }
4327   }
4328 }
4329
4330 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups( 
4331   const SMESH::ListOfGroups& theElems,
4332   const SMESH::ListOfGroups& theNodesNot,
4333   const SMESH::ListOfGroups& theAffectedElems )
4334 {
4335   initData();
4336
4337   ::SMESH_MeshEditor aMeshEditor( myMesh );
4338
4339   SMESHDS_Mesh* aMeshDS = GetMeshDS();
4340   TIDSortedElemSet anElems, aNodes, anAffected;
4341   listOfGroupToSet(theElems, aMeshDS, anElems, false );
4342   listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
4343   listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
4344
4345   bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
4346
4347   storeResult( aMeshEditor) ;
4348
4349   return aResult;
4350 }
4351
4352 //================================================================================
4353 /*!
4354   \brief Creates a hole in a mesh by doubling the nodes of some particular elements
4355   This method provided for convenience works as DoubleNodes() described above.
4356   \param theElems - list of groups of elements (edges or faces) to be replicated
4357   \param theNodesNot - list of groups of nodes not to replicated
4358   \param theShape - shape to detect affected elements (element which geometric center
4359          located on or inside shape).
4360          The replicated nodes should be associated to affected elements.
4361   \return TRUE if operation has been completed successfully, FALSE otherwise
4362   \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
4363 */
4364 //================================================================================
4365
4366 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroupsInRegion( 
4367   const SMESH::ListOfGroups& theElems,
4368   const SMESH::ListOfGroups& theNodesNot,
4369   GEOM::GEOM_Object_ptr      theShape )
4370 {
4371   initData();
4372
4373   ::SMESH_MeshEditor aMeshEditor( myMesh );
4374
4375   SMESHDS_Mesh* aMeshDS = GetMeshDS();
4376   TIDSortedElemSet anElems, aNodes;
4377   listOfGroupToSet(theElems, aMeshDS, anElems,false );
4378   listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
4379
4380   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
4381   bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
4382
4383   storeResult( aMeshEditor) ;
4384
4385   return aResult;
4386 }