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