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