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