Salome HOME
PAL16617 (Modification/Transformation operations with copy don't create a new mesh)
[modules/smesh.git] / src / SMESH_I / SMESH_MeshEditor_i.cxx
1 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
2 //
3 //  Copyright (C) 2003  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 //
23 //
24 //  File   : SMESH_MeshEditor_i.cxx
25 //  Author : Nicolas REJNERI
26 //  Module : SMESH
27 //  $Header$
28
29 #include "SMESH_MeshEditor_i.hxx"
30
31 #include "SMDS_MeshEdge.hxx"
32 #include "SMDS_MeshFace.hxx"
33 #include "SMDS_MeshVolume.hxx"
34 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
35 #include "SMESH_MeshEditor.hxx"
36 #include "SMESH_subMeshEventListener.hxx"
37 #include "SMESH_Gen_i.hxx"
38 #include "SMESH_Filter_i.hxx"
39 #include "SMESH_PythonDump.hxx"
40
41 #include "CASCatch.hxx"
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 #else
65 #include "CASCatch.hxx"
66 #endif
67
68 #include <sstream>
69
70 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
71
72 using namespace std;
73 using SMESH::TPythonDump;
74
75 namespace {
76
77   //=============================================================================
78   /*!
79    * \brief Mesh to apply modifications for preview purposes
80    */
81   //=============================================================================
82
83   struct TPreviewMesh: public SMESH_Mesh
84   {
85     SMDSAbs_ElementType myPreviewType; // type to show
86     //!< Constructor
87     TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
88       _isShapeToMesh = _id =_studyId =_idDoc = 0;
89       _myMeshDS  = new SMESHDS_Mesh( _id, true );
90       myPreviewType = previewElements;
91     }
92     //!< Destructor
93     virtual ~TPreviewMesh() { delete _myMeshDS; }
94     //!< Copy a set of elements
95     void Copy(const TIDSortedElemSet & theElements,
96               TIDSortedElemSet&        theCopyElements,
97               SMDSAbs_ElementType      theSelectType = SMDSAbs_All,
98               SMDSAbs_ElementType      theAvoidType = SMDSAbs_All)
99     {
100       // loop on theIDsOfElements
101       TIDSortedElemSet::const_iterator eIt = theElements.begin();
102       for ( ; eIt != theElements.end(); ++eIt )
103       {
104         const SMDS_MeshElement* anElem = *eIt;
105         if ( !anElem ) continue;
106         SMDSAbs_ElementType type = anElem->GetType();
107         if ( type == theAvoidType ||
108              ( theSelectType != SMDSAbs_All && type != theSelectType ))
109           continue;
110
111         if ( const SMDS_MeshElement* anElemCopy = Copy( anElem ))
112           theCopyElements.insert( theCopyElements.end(), anElemCopy );
113       }
114     }
115     //!< Copy an element
116     SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
117     {
118       // copy element nodes
119       int anElemNbNodes = anElem->NbNodes();
120       vector< int > anElemNodesID( anElemNbNodes ) ;
121       SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
122       for ( int i = 0; itElemNodes->more(); i++)
123       {
124         const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
125         Copy( anElemNode );
126         anElemNodesID[i] = anElemNode->GetID();
127       }
128
129       // creates a corresponding element on copied nodes
130       SMDS_MeshElement* anElemCopy = 0;
131       if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
132       {
133         const SMDS_PolyhedralVolumeOfNodes* ph =
134           dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem);
135         if ( ph )
136           anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
137             (anElemNodesID, ph->GetQuanities(),anElem->GetID());
138       }
139       else {
140         anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
141                                                           anElem->GetType(),
142                                                           anElem->IsPoly() );
143       }
144       return anElemCopy;
145     }
146     //!< Copy a node
147     SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
148     {
149       return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(), 
150                                       anElemNode->GetID());
151     }
152   };// struct TPreviewMesh
153
154   static SMESH_NodeSearcher * myNodeSearcher = 0;
155
156   //=============================================================================
157   /*!
158    * \brief Deleter of myNodeSearcher at any compute event occured
159    */
160   //=============================================================================
161
162   struct TNodeSearcherDeleter : public SMESH_subMeshEventListener
163   {
164     SMESH_Mesh* myMesh;
165     //!< Constructor
166     TNodeSearcherDeleter(): SMESH_subMeshEventListener( false ), // won't be deleted by submesh
167     myMesh(0) {}
168     //!< Delete myNodeSearcher
169     static void Delete()
170     {
171       if ( myNodeSearcher ) { delete myNodeSearcher; myNodeSearcher = 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 myNodeSearcher if other mesh is set
184     void Set(SMESH_Mesh* mesh)
185     {
186       if ( myMesh && myMesh != mesh ) {
187         Delete();
188         Unset( myMesh );
189       }
190       myMesh = mesh;
191       if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
192         const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
193         TDependsOnMap::const_iterator sm;
194         for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
195           sm->second->SetEventListener( this, 0, sm->second );
196       }
197     }
198     //!<  delete self from all submeshes
199     void Unset(SMESH_Mesh* mesh)
200     {
201       if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
202         const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
203         TDependsOnMap::const_iterator sm;
204         for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
205           sm->second->DeleteEventListener( this );
206       }
207     }
208   };
209
210   TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
211   {
212     TCollection_AsciiString typeStr;
213     switch ( theMirrorType ) {
214     case  SMESH::SMESH_MeshEditor::POINT:
215       typeStr = "SMESH.SMESH_MeshEditor.POINT";
216       break;
217     case  SMESH::SMESH_MeshEditor::AXIS:
218       typeStr = "SMESH.SMESH_MeshEditor.AXIS";
219       break;
220     default:
221       typeStr = "SMESH.SMESH_MeshEditor.PLANE";
222     }
223     return typeStr;
224   }
225 }
226
227 //=============================================================================
228 /*!
229  *
230  */
231 //=============================================================================
232
233 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview)
234 {
235   myMesh_i = theMesh;
236   myMesh = & theMesh->GetImpl();
237   myPreviewMode = isPreview;
238 }
239
240 //================================================================================
241 /*!
242  * \brief Destructor
243  */
244 //================================================================================
245
246 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
247 {
248 }
249
250 //================================================================================
251 /*!
252  * \brief Clear members
253  */
254 //================================================================================
255
256 void SMESH_MeshEditor_i::initData()
257 {
258   if ( myPreviewMode ) {
259     myPreviewData = new SMESH::MeshPreviewStruct();
260   }
261   else {
262     myLastCreatedElems = new SMESH::long_array();
263     myLastCreatedNodes = new SMESH::long_array();
264     TNodeSearcherDeleter::Delete();
265   }
266 }
267
268 //=============================================================================
269 /*!
270  *
271  */
272 //=============================================================================
273
274 CORBA::Boolean
275   SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
276 {
277   initData();
278
279   ::SMESH_MeshEditor anEditor( myMesh );
280   list< int > IdList;
281
282   for (int i = 0; i < IDsOfElements.length(); i++)
283     IdList.push_back( IDsOfElements[i] );
284
285   // Update Python script
286   TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
287 #ifdef _DEBUG_
288   TPythonDump() << "print 'RemoveElements: ', isDone";
289 #endif
290   // Remove Elements
291   return anEditor.Remove( IdList, false );
292 }
293
294 //=============================================================================
295 /*!
296  *
297  */
298 //=============================================================================
299
300 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
301 {
302   initData();
303
304   ::SMESH_MeshEditor anEditor( myMesh );
305   list< int > IdList;
306   for (int i = 0; i < IDsOfNodes.length(); i++)
307     IdList.push_back( IDsOfNodes[i] );
308
309   // Update Python script
310   TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
311 #ifdef _DEBUG_
312   TPythonDump() << "print 'RemoveNodes: ', isDone";
313 #endif
314
315   return anEditor.Remove( IdList, true );
316 }
317
318 //=============================================================================
319 /*!
320  *
321  */
322 //=============================================================================
323
324 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
325 {
326   initData();
327
328   int NbNodes = IDsOfNodes.length();
329   SMDS_MeshElement* elem = 0;
330   if (NbNodes == 2)
331   {
332     CORBA::Long index1 = IDsOfNodes[0];
333     CORBA::Long index2 = IDsOfNodes[1];
334     elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
335
336     // Update Python script
337     TPythonDump() << "edge = " << this << ".AddEdge([ "
338                   << index1 << ", " << index2 <<" ])";
339   }
340   if (NbNodes == 3) {
341     CORBA::Long n1 = IDsOfNodes[0];
342     CORBA::Long n2 = IDsOfNodes[1];
343     CORBA::Long n12 = IDsOfNodes[2];
344     elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
345                                 GetMeshDS()->FindNode(n2),
346                                 GetMeshDS()->FindNode(n12));
347     // Update Python script
348     TPythonDump() << "edgeID = " << this << ".AddEdge([ "
349                   <<n1<<", "<<n2<<", "<<n12<<" ])";
350   }
351
352   if(elem)
353     return elem->GetID();
354
355   return 0;
356 }
357
358 //=============================================================================
359 /*!
360  *
361  */
362 //=============================================================================
363
364 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
365                                         CORBA::Double y, CORBA::Double z)
366 {
367   initData();
368
369   const SMDS_MeshNode* N = GetMeshDS()->AddNode(x, y, z);
370
371   // Update Python script
372   TPythonDump() << "nodeID = " << this << ".AddNode( "
373                 << x << ", " << y << ", " << z << " )";
374
375   return N->GetID();
376 }
377
378 //=============================================================================
379 /*!
380  *  AddFace
381  */
382 //=============================================================================
383
384 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
385 {
386   initData();
387
388   int NbNodes = IDsOfNodes.length();
389   if (NbNodes < 3)
390   {
391     return false;
392   }
393
394   std::vector<const SMDS_MeshNode*> nodes (NbNodes);
395   for (int i = 0; i < NbNodes; i++)
396     nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
397
398   SMDS_MeshElement* elem = 0;
399   if (NbNodes == 3) {
400     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
401   }
402   else if (NbNodes == 4) {
403     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
404   }
405   else if (NbNodes == 6) {
406     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
407                                 nodes[4], nodes[5]);
408   }
409   else if (NbNodes == 8) {
410     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
411                                 nodes[4], nodes[5], nodes[6], nodes[7]);
412   }
413
414   // Update Python script
415   TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
416
417   if(elem)
418     return elem->GetID();
419
420   return 0;
421 }
422
423 //=============================================================================
424 /*!
425  *  AddPolygonalFace
426  */
427 //=============================================================================
428 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace
429                                    (const SMESH::long_array & IDsOfNodes)
430 {
431   initData();
432
433   int NbNodes = IDsOfNodes.length();
434   std::vector<const SMDS_MeshNode*> nodes (NbNodes);
435   for (int i = 0; i < NbNodes; i++)
436     nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
437
438   const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes);
439   
440   // Update Python script
441   TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
442 #ifdef _DEBUG_
443   TPythonDump() << "print 'AddPolygonalFace: ', faceID";
444 #endif
445
446   if(elem)
447     return elem->GetID();
448
449   return 0;
450 }
451
452 //=============================================================================
453 /*!
454  *
455  */
456 //=============================================================================
457
458 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
459 {
460   initData();
461
462   int NbNodes = IDsOfNodes.length();
463   vector< const SMDS_MeshNode*> n(NbNodes);
464   for(int i=0;i<NbNodes;i++)
465     n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
466
467   SMDS_MeshElement* elem = 0;
468   switch(NbNodes)
469   {
470   case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
471   case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
472   case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
473   case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
474   case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
475                                         n[6],n[7],n[8],n[9]);
476     break;
477   case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
478                                         n[7],n[8],n[9],n[10],n[11],n[12]);
479     break;
480   case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
481                                         n[9],n[10],n[11],n[12],n[13],n[14]);
482     break;
483   case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
484                                         n[8],n[9],n[10],n[11],n[12],n[13],n[14],
485                                         n[15],n[16],n[17],n[18],n[19]);
486     break;
487   }
488
489   // Update Python script
490   TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
491 #ifdef _DEBUG_
492   TPythonDump() << "print 'AddVolume: ', volID";
493 #endif
494
495   if(elem)
496     return elem->GetID();
497
498   return 0;
499 }
500
501 //=============================================================================
502 /*!
503  *  AddPolyhedralVolume
504  */
505 //=============================================================================
506 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume
507                                    (const SMESH::long_array & IDsOfNodes,
508                                     const SMESH::long_array & Quantities)
509 {
510   initData();
511
512   int NbNodes = IDsOfNodes.length();
513   std::vector<const SMDS_MeshNode*> n (NbNodes);
514   for (int i = 0; i < NbNodes; i++)
515     n[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
516
517   int NbFaces = Quantities.length();
518   std::vector<int> q (NbFaces);
519   for (int j = 0; j < NbFaces; j++)
520     q[j] = Quantities[j];
521
522   const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(n, q);
523
524   // Update Python script
525   TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
526                 << IDsOfNodes << ", " << Quantities << " )";
527 #ifdef _DEBUG_
528   TPythonDump() << "print 'AddPolyhedralVolume: ', volID";
529 #endif
530
531   if(elem)
532     return elem->GetID();
533
534   return 0;
535 }
536
537 //=============================================================================
538 /*!
539  *  AddPolyhedralVolumeByFaces
540  */
541 //=============================================================================
542 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces
543                                    (const SMESH::long_array & IdsOfFaces)
544 {
545   initData();
546
547   int NbFaces = IdsOfFaces.length();
548   std::vector<const SMDS_MeshNode*> poly_nodes;
549   std::vector<int> quantities (NbFaces);
550
551   for (int i = 0; i < NbFaces; i++) {
552     const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]);
553     quantities[i] = aFace->NbNodes();
554
555     SMDS_ElemIteratorPtr It = aFace->nodesIterator();
556     while (It->more()) {
557       poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
558     }
559   }
560
561   const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
562
563   // Update Python script
564   TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
565                 << IdsOfFaces << " )";
566 #ifdef _DEBUG_
567   TPythonDump() << "print 'AddPolyhedralVolume: ', volID";
568 #endif
569
570   if(elem)
571     return elem->GetID();
572
573   return 0;
574 }
575
576 //=============================================================================
577 /*!
578  * \brief Bind a node to a vertex
579  * \param NodeID - node ID
580  * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
581  * \retval boolean - false if NodeID or VertexID is invalid
582  */
583 //=============================================================================
584
585 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
586   throw (SALOME::SALOME_Exception)
587 {
588   Unexpect aCatch(SALOME_SalomeException);
589
590   SMESHDS_Mesh * mesh = GetMeshDS();
591   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
592   if ( !node )
593     THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
594
595   if ( mesh->MaxShapeIndex() < VertexID )
596     THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
597
598   TopoDS_Shape shape = mesh->IndexToShape( VertexID );
599   if ( shape.ShapeType() != TopAbs_VERTEX )
600     THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
601
602   mesh->SetNodeOnVertex( node, VertexID );
603 }
604
605 //=============================================================================
606 /*!
607  * \brief Store node position on an edge
608  * \param NodeID - node ID
609  * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
610  * \param paramOnEdge - parameter on edge where the node is located
611  * \retval boolean - false if any parameter is invalid
612  */
613 //=============================================================================
614
615 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
616                                        CORBA::Double paramOnEdge)
617   throw (SALOME::SALOME_Exception)
618 {
619   Unexpect aCatch(SALOME_SalomeException);
620
621   SMESHDS_Mesh * mesh = GetMeshDS();
622   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
623   if ( !node )
624     THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
625
626   if ( mesh->MaxShapeIndex() < EdgeID )
627     THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
628
629   TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
630   if ( shape.ShapeType() != TopAbs_EDGE )
631     THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
632
633   Standard_Real f,l;
634   BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
635   if ( paramOnEdge < f || paramOnEdge > l )
636     THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
637
638   mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
639 }
640
641 //=============================================================================
642 /*!
643  * \brief Store node position on a face
644  * \param NodeID - node ID
645  * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
646  * \param u - U parameter on face where the node is located
647  * \param v - V parameter on face where the node is located
648  * \retval boolean - false if any parameter is invalid
649  */
650 //=============================================================================
651
652 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
653                                        CORBA::Double u, CORBA::Double v)
654   throw (SALOME::SALOME_Exception)
655 {
656   Unexpect aCatch(SALOME_SalomeException);
657
658   SMESHDS_Mesh * mesh = GetMeshDS();
659   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
660   if ( !node )
661     THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
662
663   if ( mesh->MaxShapeIndex() < FaceID )
664     THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
665
666   TopoDS_Shape shape = mesh->IndexToShape( FaceID );
667   if ( shape.ShapeType() != TopAbs_FACE )
668     THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
669
670   BRepAdaptor_Surface surf( TopoDS::Face( shape ));
671   bool isOut = ( u < surf.FirstUParameter() ||
672                  u > surf.LastUParameter()  ||
673                  v < surf.FirstVParameter() ||
674                  v > surf.LastVParameter() );
675
676   if ( isOut ) {
677 #ifdef _DEBUG_
678     cout << "FACE " << FaceID << " (" << u << "," << v << ") out of "
679          << " u( " <<  surf.FirstUParameter() 
680          << "," <<  surf.LastUParameter()  
681          << ") v( " <<  surf.FirstVParameter() 
682          << "," <<  surf.LastVParameter()
683          << ")" << endl;
684 #endif    
685     THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
686   }
687
688   mesh->SetNodeOnFace( node, FaceID, u, v );
689 }
690
691 //=============================================================================
692 /*!
693  * \brief Bind a node to a solid
694  * \param NodeID - node ID
695  * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
696  * \retval boolean - false if NodeID or SolidID is invalid
697  */
698 //=============================================================================
699
700 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
701   throw (SALOME::SALOME_Exception)
702 {
703   Unexpect aCatch(SALOME_SalomeException);
704
705   SMESHDS_Mesh * mesh = GetMeshDS();
706   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
707   if ( !node )
708     THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
709
710   if ( mesh->MaxShapeIndex() < SolidID )
711     THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
712
713   TopoDS_Shape shape = mesh->IndexToShape( SolidID );
714   if ( shape.ShapeType() != TopAbs_SOLID &&
715        shape.ShapeType() != TopAbs_SHELL)
716     THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
717
718   mesh->SetNodeInVolume( node, SolidID );
719 }
720
721 //=============================================================================
722 /*!
723  * \brief Bind an element to a shape
724  * \param ElementID - element ID
725  * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
726  * \retval boolean - false if ElementID or ShapeID is invalid
727  */
728 //=============================================================================
729
730 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
731                                                CORBA::Long ShapeID)
732   throw (SALOME::SALOME_Exception)
733 {
734   Unexpect aCatch(SALOME_SalomeException);
735
736   SMESHDS_Mesh * mesh = GetMeshDS();
737   SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
738   if ( !elem )
739     THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
740
741   if ( mesh->MaxShapeIndex() < ShapeID )
742     THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
743
744   TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
745   if ( shape.ShapeType() != TopAbs_EDGE &&
746        shape.ShapeType() != TopAbs_FACE &&
747        shape.ShapeType() != TopAbs_SOLID &&
748        shape.ShapeType() != TopAbs_SHELL )
749     THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
750
751   mesh->SetMeshElementOnShape( elem, ShapeID );
752 }
753
754
755 //=============================================================================
756 /*!
757  *
758  */
759 //=============================================================================
760
761 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
762                                             CORBA::Double x,
763                                             CORBA::Double y,
764                                             CORBA::Double z)
765 {
766   initData();
767
768   const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
769   if ( !node )
770     return false;
771
772   GetMeshDS()->MoveNode(node, x, y, z);
773
774   // Update Python script
775   TPythonDump() << "isDone = " << this << ".MoveNode( "
776                 << NodeID << ", " << x << ", " << y << ", " << z << " )";
777
778   return true;
779 }
780
781 //=============================================================================
782 /*!
783  *
784  */
785 //=============================================================================
786
787 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
788                                                CORBA::Long NodeID2)
789 {
790   initData();
791
792   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
793   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
794   if ( !n1 || !n2 )
795     return false;
796
797   // Update Python script
798   TPythonDump() << "isDone = " << this << ".InverseDiag( "
799                 << NodeID1 << ", " << NodeID2 << " )";
800
801   ::SMESH_MeshEditor aMeshEditor( myMesh );
802   return aMeshEditor.InverseDiag ( n1, n2 );
803 }
804
805 //=============================================================================
806 /*!
807  *
808  */
809 //=============================================================================
810
811 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
812                                               CORBA::Long NodeID2)
813 {
814   initData();
815
816   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
817   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
818   if ( !n1 || !n2 )
819     return false;
820
821   // Update Python script
822   TPythonDump() << "isDone = " << this << ".DeleteDiag( "
823                 << NodeID1 << ", " << NodeID2 <<  " )";
824
825   ::SMESH_MeshEditor aMeshEditor( myMesh );
826
827   bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
828
829   storeResult(aMeshEditor);
830
831   return stat;
832 }
833
834 //=============================================================================
835 /*!
836  *
837  */
838 //=============================================================================
839
840 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
841 {
842   initData();
843
844   ::SMESH_MeshEditor anEditor( myMesh );
845   for (int i = 0; i < IDsOfElements.length(); i++)
846   {
847     CORBA::Long index = IDsOfElements[i];
848     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
849     if ( elem )
850       anEditor.Reorient( elem );
851   }
852   // Update Python script
853   TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
854
855   return true;
856 }
857
858
859 //=============================================================================
860 /*!
861  *
862  */
863 //=============================================================================
864
865 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
866 {
867   initData();
868
869   SMESH::long_array_var anElementsId = theObject->GetIDs();
870   CORBA::Boolean isDone = Reorient(anElementsId);
871
872   // Clear python line, created by Reorient()
873   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
874   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
875
876   // Update Python script
877   TPythonDump() << "isDone = " << this << ".ReorientObject( " << theObject << " )";
878
879   return isDone;
880 }
881
882 namespace
883 {
884   //================================================================================
885   /*!
886    * \brief function for conversion long_array to TIDSortedElemSet
887     * \param IDs - array of IDs
888     * \param aMesh - mesh
889     * \param aMap - collection to fill
890     * \param aType - element type
891    */
892   //================================================================================
893
894   void arrayToSet(const SMESH::long_array & IDs,
895                   const SMESHDS_Mesh*       aMesh,
896                   TIDSortedElemSet&         aMap,
897                   const SMDSAbs_ElementType aType = SMDSAbs_All )
898   { 
899     for (int i=0; i<IDs.length(); i++) {
900       CORBA::Long ind = IDs[i];
901       const SMDS_MeshElement * elem = aMesh->FindElement(ind);
902       if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
903         aMap.insert( elem );
904     }
905   }
906 }
907
908 //=============================================================================
909 /*!
910  *
911  */
912 //=============================================================================
913 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfElements,
914                                               SMESH::NumericalFunctor_ptr Criterion,
915                                               CORBA::Double               MaxAngle)
916 {
917   initData();
918
919   SMESHDS_Mesh* aMesh = GetMeshDS();
920   TIDSortedElemSet faces;
921   arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
922
923   SMESH::NumericalFunctor_i* aNumericalFunctor =
924     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
925   SMESH::Controls::NumericalFunctorPtr aCrit;
926   if ( !aNumericalFunctor )
927     aCrit.reset( new SMESH::Controls::AspectRatio() );
928   else
929     aCrit = aNumericalFunctor->GetNumericalFunctor();
930
931   // Update Python script
932   TPythonDump() << "isDone = " << this << ".TriToQuad( "
933                 << IDsOfElements << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
934 #ifdef _DEBUG_
935   TPythonDump() << "print 'TriToQuad: ', isDone";
936 #endif
937
938   ::SMESH_MeshEditor anEditor( myMesh );
939
940   bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
941
942   storeResult(anEditor);
943
944   return stat;
945 }
946
947
948 //=============================================================================
949 /*!
950  *
951  */
952 //=============================================================================
953 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr   theObject,
954                                                     SMESH::NumericalFunctor_ptr Criterion,
955                                                     CORBA::Double               MaxAngle)
956 {
957   initData();
958
959   SMESH::long_array_var anElementsId = theObject->GetIDs();
960   CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
961
962   // Clear python line(s), created by TriToQuad()
963   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
964   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
965 #ifdef _DEBUG_
966   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
967 #endif
968
969   SMESH::NumericalFunctor_i* aNumericalFunctor =
970     SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
971
972   // Update Python script
973   TPythonDump() << "isDone = " << this << ".TriToQuadObject("
974                 << theObject << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
975 #ifdef _DEBUG_
976   TPythonDump() << "print 'TriToQuadObject: ', isDone";
977 #endif
978
979   return isDone;
980 }
981
982
983 //=============================================================================
984 /*!
985  *
986  */
987 //=============================================================================
988 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array &   IDsOfElements,
989                                               SMESH::NumericalFunctor_ptr Criterion)
990 {
991   initData();
992
993   SMESHDS_Mesh* aMesh = GetMeshDS();
994   TIDSortedElemSet faces;
995   arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
996
997   SMESH::NumericalFunctor_i* aNumericalFunctor =
998     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
999   SMESH::Controls::NumericalFunctorPtr aCrit;
1000   if ( !aNumericalFunctor )
1001     aCrit.reset( new SMESH::Controls::AspectRatio() );
1002   else
1003     aCrit = aNumericalFunctor->GetNumericalFunctor();
1004
1005
1006   // Update Python script
1007   TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1008 #ifdef _DEBUG_
1009   TPythonDump() << "print 'QuadToTri: ', isDone";
1010 #endif
1011
1012   ::SMESH_MeshEditor anEditor( myMesh );
1013   CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
1014
1015   storeResult(anEditor);
1016
1017   return stat;
1018 }
1019
1020
1021 //=============================================================================
1022 /*!
1023  *
1024  */
1025 //=============================================================================
1026 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr   theObject,
1027                                                     SMESH::NumericalFunctor_ptr Criterion)
1028 {
1029   initData();
1030
1031   SMESH::long_array_var anElementsId = theObject->GetIDs();
1032   CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1033
1034   // Clear python line(s), created by QuadToTri()
1035   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1036   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1037 #ifdef _DEBUG_
1038   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1039 #endif
1040
1041   SMESH::NumericalFunctor_i* aNumericalFunctor =
1042     SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1043
1044   // Update Python script
1045   TPythonDump() << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1046 #ifdef _DEBUG_
1047   TPythonDump() << "print 'QuadToTriObject: ', isDone";
1048 #endif
1049
1050   return isDone;
1051 }
1052
1053
1054 //=============================================================================
1055 /*!
1056  *
1057  */
1058 //=============================================================================
1059 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1060                                               CORBA::Boolean            Diag13)
1061 {
1062   initData();
1063
1064   SMESHDS_Mesh* aMesh = GetMeshDS();
1065   TIDSortedElemSet faces;
1066   arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1067
1068   // Update Python script
1069   TPythonDump() << "isDone = " << this << ".SplitQuad( "
1070                 << IDsOfElements << ", " << Diag13 << " )";
1071 #ifdef _DEBUG_
1072   TPythonDump() << "print 'SplitQuad: ', isDone";
1073 #endif
1074
1075   ::SMESH_MeshEditor anEditor( myMesh );
1076   CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
1077
1078   storeResult(anEditor);
1079
1080   return stat;
1081 }
1082
1083
1084 //=============================================================================
1085 /*!
1086  *
1087  */
1088 //=============================================================================
1089 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1090                                                     CORBA::Boolean            Diag13)
1091 {
1092   initData();
1093
1094   SMESH::long_array_var anElementsId = theObject->GetIDs();
1095   CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1096
1097   // Clear python line(s), created by SplitQuad()
1098   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1099   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1100 #ifdef _DEBUG_
1101   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1102 #endif
1103
1104   // Update Python script
1105   TPythonDump() << "isDone = " << this << ".SplitQuadObject( "
1106                 << theObject << ", " << Diag13 << " )";
1107 #ifdef _DEBUG_
1108   TPythonDump() << "print 'SplitQuadObject: ', isDone";
1109 #endif
1110
1111   return isDone;
1112 }
1113
1114
1115 //=============================================================================
1116 /*!
1117  *  BestSplit
1118  */
1119 //=============================================================================
1120 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long                 IDOfQuad,
1121                                            SMESH::NumericalFunctor_ptr Criterion)
1122 {
1123   const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
1124   if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1125   {
1126     SMESH::NumericalFunctor_i* aNumericalFunctor =
1127       dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1128     SMESH::Controls::NumericalFunctorPtr aCrit;
1129     if (aNumericalFunctor)
1130       aCrit = aNumericalFunctor->GetNumericalFunctor();
1131     else
1132       aCrit.reset(new SMESH::Controls::AspectRatio());
1133
1134     ::SMESH_MeshEditor anEditor (myMesh);
1135     return anEditor.BestSplit(quad, aCrit);
1136   }
1137   return -1;
1138 }
1139
1140
1141 //=======================================================================
1142 //function : Smooth
1143 //purpose  :
1144 //=======================================================================
1145
1146 CORBA::Boolean
1147   SMESH_MeshEditor_i::Smooth(const SMESH::long_array &              IDsOfElements,
1148                              const SMESH::long_array &              IDsOfFixedNodes,
1149                              CORBA::Long                            MaxNbOfIterations,
1150                              CORBA::Double                          MaxAspectRatio,
1151                              SMESH::SMESH_MeshEditor::Smooth_Method Method)
1152 {
1153   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1154                 MaxAspectRatio, Method, false );
1155 }
1156
1157
1158 //=======================================================================
1159 //function : SmoothParametric
1160 //purpose  :
1161 //=======================================================================
1162
1163 CORBA::Boolean
1164   SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array &              IDsOfElements,
1165                                        const SMESH::long_array &              IDsOfFixedNodes,
1166                                        CORBA::Long                            MaxNbOfIterations,
1167                                        CORBA::Double                          MaxAspectRatio,
1168                                        SMESH::SMESH_MeshEditor::Smooth_Method Method)
1169 {
1170   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1171                 MaxAspectRatio, Method, true );
1172 }
1173
1174
1175 //=======================================================================
1176 //function : SmoothObject
1177 //purpose  :
1178 //=======================================================================
1179
1180 CORBA::Boolean
1181   SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr              theObject,
1182                                    const SMESH::long_array &              IDsOfFixedNodes,
1183                                    CORBA::Long                            MaxNbOfIterations,
1184                                    CORBA::Double                          MaxAspectRatio,
1185                                    SMESH::SMESH_MeshEditor::Smooth_Method Method)
1186 {
1187   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1188                        MaxAspectRatio, Method, false);
1189 }
1190
1191
1192 //=======================================================================
1193 //function : SmoothParametricObject
1194 //purpose  :
1195 //=======================================================================
1196
1197 CORBA::Boolean
1198   SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr              theObject,
1199                                    const SMESH::long_array &              IDsOfFixedNodes,
1200                                    CORBA::Long                            MaxNbOfIterations,
1201                                    CORBA::Double                          MaxAspectRatio,
1202                                    SMESH::SMESH_MeshEditor::Smooth_Method Method)
1203 {
1204   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1205                        MaxAspectRatio, Method, true);
1206 }
1207
1208
1209 //=============================================================================
1210 /*!
1211  *
1212  */
1213 //=============================================================================
1214
1215 CORBA::Boolean
1216   SMESH_MeshEditor_i::smooth(const SMESH::long_array &              IDsOfElements,
1217                              const SMESH::long_array &              IDsOfFixedNodes,
1218                              CORBA::Long                            MaxNbOfIterations,
1219                              CORBA::Double                          MaxAspectRatio,
1220                              SMESH::SMESH_MeshEditor::Smooth_Method Method,
1221                              bool                                   IsParametric)
1222 {
1223   initData();
1224
1225   SMESHDS_Mesh* aMesh = GetMeshDS();
1226
1227   TIDSortedElemSet elements;
1228   arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1229
1230   set<const SMDS_MeshNode*> fixedNodes;
1231   for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1232     CORBA::Long index = IDsOfFixedNodes[i];
1233     const SMDS_MeshNode * node = aMesh->FindNode(index);
1234     if ( node )
1235       fixedNodes.insert( node );
1236   }
1237   ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1238   if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1239     method = ::SMESH_MeshEditor::CENTROIDAL;
1240
1241   ::SMESH_MeshEditor anEditor( myMesh );
1242   anEditor.Smooth(elements, fixedNodes, method,
1243                   MaxNbOfIterations, MaxAspectRatio, IsParametric );
1244
1245   storeResult(anEditor);
1246
1247   // Update Python script
1248   TPythonDump() << "isDone = " << this << "."
1249                 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1250                 << IDsOfElements << ", "     << IDsOfFixedNodes << ", "
1251                 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1252                 << "SMESH.SMESH_MeshEditor."
1253                 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1254                      "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1255 #ifdef _DEBUG_
1256   TPythonDump() << "print 'Smooth: ', isDone";
1257 #endif
1258
1259   return true;
1260 }
1261
1262
1263 //=============================================================================
1264 /*!
1265  *
1266  */
1267 //=============================================================================
1268
1269 CORBA::Boolean
1270 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr              theObject,
1271                                  const SMESH::long_array &              IDsOfFixedNodes,
1272                                  CORBA::Long                            MaxNbOfIterations,
1273                                  CORBA::Double                          MaxAspectRatio,
1274                                  SMESH::SMESH_MeshEditor::Smooth_Method Method,
1275                                  bool                                   IsParametric)
1276 {
1277   initData();
1278
1279   SMESH::long_array_var anElementsId = theObject->GetIDs();
1280   CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1281                                   MaxAspectRatio, Method, IsParametric);
1282
1283   // Clear python line(s), created by Smooth()
1284   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1285   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1286 #ifdef _DEBUG_
1287   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1288 #endif
1289
1290   // Update Python script
1291   TPythonDump() << "isDone = " << this << "."
1292                 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1293                 << theObject << ", " << IDsOfFixedNodes << ", "
1294                 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1295                 << "SMESH.SMESH_MeshEditor."
1296                 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1297                      "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1298 #ifdef _DEBUG_
1299   TPythonDump() << "print 'SmoothObject: ', isDone";
1300 #endif
1301
1302   return isDone;
1303 }
1304
1305
1306 //=============================================================================
1307 /*!
1308  *
1309  */
1310 //=============================================================================
1311
1312 void SMESH_MeshEditor_i::RenumberNodes()
1313 {
1314   // Update Python script
1315   TPythonDump() << this << ".RenumberNodes()";
1316
1317   GetMeshDS()->Renumber( true );
1318 }
1319
1320
1321 //=============================================================================
1322 /*!
1323  *
1324  */
1325 //=============================================================================
1326
1327 void SMESH_MeshEditor_i::RenumberElements()
1328 {
1329   // Update Python script
1330   TPythonDump() << this << ".RenumberElements()";
1331
1332   GetMeshDS()->Renumber( false );
1333 }
1334
1335 //=======================================================================
1336   /*!
1337    * \brief Return groups by their IDs
1338    */
1339 //=======================================================================
1340
1341 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
1342 {
1343   if ( !groupIDs )
1344     return 0;
1345   myMesh_i->CreateGroupServants();
1346   return myMesh_i->GetGroups( *groupIDs );
1347 }
1348
1349 //=======================================================================
1350 //function : rotationSweep
1351 //purpose  : 
1352 //=======================================================================
1353
1354 SMESH::ListOfGroups*
1355 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
1356                                   const SMESH::AxisStruct & theAxis,
1357                                   CORBA::Double             theAngleInRadians,
1358                                   CORBA::Long               theNbOfSteps,
1359                                   CORBA::Double             theTolerance,
1360                                   const bool                theMakeGroups)
1361 {
1362   initData();
1363
1364   TIDSortedElemSet inElements, copyElements;
1365   arrayToSet(theIDsOfElements, GetMeshDS(), inElements);
1366
1367   TIDSortedElemSet* workElements = & inElements;
1368   TPreviewMesh      tmpMesh( SMDSAbs_Face );
1369   SMESH_Mesh*       mesh = 0;
1370   bool              makeWalls=true;
1371   if ( myPreviewMode )
1372   {
1373     SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1374     tmpMesh.Copy( inElements, copyElements, select, avoid );
1375     mesh = &tmpMesh;
1376     workElements = & copyElements;
1377     //makeWalls = false;
1378   }
1379   else
1380   {
1381     mesh = myMesh;
1382   }
1383
1384   gp_Ax1 Ax1 (gp_Pnt( theAxis.x,  theAxis.y,  theAxis.z ),
1385               gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
1386
1387   ::SMESH_MeshEditor anEditor( mesh );
1388   ::SMESH_MeshEditor::PGroupIDs groupIds =
1389     anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
1390                             theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
1391   storeResult(anEditor);
1392
1393   return theMakeGroups ? getGroups(groupIds.get()) : 0;
1394 }
1395
1396 //=======================================================================
1397 //function : RotationSweep
1398 //purpose  :
1399 //=======================================================================
1400
1401 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
1402                                        const SMESH::AxisStruct & theAxis,
1403                                        CORBA::Double             theAngleInRadians,
1404                                        CORBA::Long               theNbOfSteps,
1405                                        CORBA::Double             theTolerance)
1406 {
1407   if ( !myPreviewMode ) {
1408     TPythonDump() << "axis = " << theAxis;
1409     TPythonDump() << this << ".RotationSweep( "
1410                   << theIDsOfElements
1411                   << ", axis, "
1412                   << theAngleInRadians << ", "
1413                   << theNbOfSteps << ", "
1414                   << theTolerance << " )";
1415   }
1416   rotationSweep(theIDsOfElements,
1417                 theAxis,
1418                 theAngleInRadians,
1419                 theNbOfSteps,
1420                 theTolerance,
1421                 false);
1422 }
1423
1424 //=======================================================================
1425 //function : RotationSweepMakeGroups
1426 //purpose  : 
1427 //=======================================================================
1428
1429 SMESH::ListOfGroups*
1430 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1431                                             const SMESH::AxisStruct& theAxis,
1432                                             CORBA::Double            theAngleInRadians,
1433                                             CORBA::Long              theNbOfSteps,
1434                                             CORBA::Double            theTolerance)
1435 {
1436   if ( !myPreviewMode ) {
1437     TPythonDump() << "axis = " << theAxis;
1438     TPythonDump() << this << ".RotationSweepMakeGroups( "
1439                   << theIDsOfElements
1440                   << ", axis, "
1441                   << theAngleInRadians << ", "
1442                   << theNbOfSteps << ", "
1443                   << theTolerance << " )";
1444   }
1445   return rotationSweep(theIDsOfElements,
1446                        theAxis,
1447                        theAngleInRadians,
1448                        theNbOfSteps,
1449                        theTolerance,
1450                        true);
1451 }
1452
1453 //=======================================================================
1454 //function : RotationSweepObject
1455 //purpose  :
1456 //=======================================================================
1457
1458 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1459                                              const SMESH::AxisStruct & theAxis,
1460                                              CORBA::Double             theAngleInRadians,
1461                                              CORBA::Long               theNbOfSteps,
1462                                              CORBA::Double             theTolerance)
1463 {
1464   if ( !myPreviewMode ) {
1465     TPythonDump() << "axis = " << theAxis;
1466     TPythonDump() << this << ".RotationSweepObject( "
1467                   << theObject
1468                   << ", axis, "
1469                   << theAngleInRadians << ", "
1470                   << theNbOfSteps << ", "
1471                   << theTolerance << " )";
1472   }
1473   SMESH::long_array_var anElementsId = theObject->GetIDs();
1474   rotationSweep(anElementsId,
1475                 theAxis,
1476                 theAngleInRadians,
1477                 theNbOfSteps,
1478                 theTolerance,
1479                 false);
1480 }
1481
1482 //=======================================================================
1483 //function : RotationSweepObjectMakeGroups
1484 //purpose  : 
1485 //=======================================================================
1486
1487 SMESH::ListOfGroups*
1488 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1489                                                   const SMESH::AxisStruct&  theAxis,
1490                                                   CORBA::Double             theAngleInRadians,
1491                                                   CORBA::Long               theNbOfSteps,
1492                                                   CORBA::Double             theTolerance)
1493 {
1494   if ( !myPreviewMode ) {
1495     TPythonDump() << "axis = " << theAxis;
1496     TPythonDump() << this << ".RotationSweepObjectMakeGroups( "
1497                   << theObject
1498                   << ", axis, "
1499                   << theAngleInRadians << ", "
1500                   << theNbOfSteps << ", "
1501                   << theTolerance << " )";
1502   }
1503   SMESH::long_array_var anElementsId = theObject->GetIDs();
1504   return rotationSweep(anElementsId,
1505                        theAxis,
1506                        theAngleInRadians,
1507                        theNbOfSteps,
1508                        theTolerance,
1509                        true);
1510 }
1511
1512
1513 //=======================================================================
1514 //function : extrusionSweep
1515 //purpose  : 
1516 //=======================================================================
1517
1518 SMESH::ListOfGroups*
1519 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
1520                                    const SMESH::DirStruct &  theStepVector,
1521                                    CORBA::Long               theNbOfSteps,
1522                                    const bool                theMakeGroups,
1523                                    const SMDSAbs_ElementType theElementType)
1524 {
1525   initData();
1526
1527 #ifdef NO_CAS_CATCH
1528   try {   
1529     OCC_CATCH_SIGNALS;
1530 #else
1531   CASCatch_TRY {
1532 #endif
1533     TIDSortedElemSet elements;
1534     arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
1535
1536     const SMESH::PointStruct * P = &theStepVector.PS;
1537     gp_Vec stepVec( P->x, P->y, P->z );
1538
1539     TElemOfElemListMap aHystory;
1540     ::SMESH_MeshEditor anEditor( myMesh );
1541     ::SMESH_MeshEditor::PGroupIDs groupIds =
1542         anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
1543
1544     storeResult(anEditor);
1545
1546     return theMakeGroups ? getGroups(groupIds.get()) : 0;
1547
1548 #ifdef NO_CAS_CATCH
1549   } catch(Standard_Failure) {
1550 #else
1551   } CASCatch_CATCH(Standard_Failure) {
1552 #endif
1553     Handle(Standard_Failure) aFail = Standard_Failure::Caught();          
1554     INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
1555   }
1556   return 0;
1557 }
1558
1559 //=======================================================================
1560 //function : ExtrusionSweep
1561 //purpose  :
1562 //=======================================================================
1563
1564 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
1565                                         const SMESH::DirStruct &  theStepVector,
1566                                         CORBA::Long               theNbOfSteps)
1567 {
1568   extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
1569   if ( !myPreviewMode ) {
1570     TPythonDump() << "stepVector = " << theStepVector;
1571     TPythonDump() << this << ".ExtrusionSweep( "
1572                   << theIDsOfElements << ", stepVector, " << theNbOfSteps << " )";
1573   }
1574 }
1575
1576
1577 //=======================================================================
1578 //function : ExtrusionSweepObject
1579 //purpose  :
1580 //=======================================================================
1581
1582 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1583                                               const SMESH::DirStruct &  theStepVector,
1584                                               CORBA::Long               theNbOfSteps)
1585 {
1586   SMESH::long_array_var anElementsId = theObject->GetIDs();
1587   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
1588   if ( !myPreviewMode ) {
1589     TPythonDump() << "stepVector = " << theStepVector;
1590     TPythonDump() << this << ".ExtrusionSweepObject( "
1591                   << theObject << ", stepVector, " << theNbOfSteps << " )";
1592   }
1593 }
1594
1595 //=======================================================================
1596 //function : ExtrusionSweepObject1D
1597 //purpose  :
1598 //=======================================================================
1599
1600 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1601                                                 const SMESH::DirStruct &  theStepVector,
1602                                                 CORBA::Long               theNbOfSteps)
1603 {
1604   SMESH::long_array_var anElementsId = theObject->GetIDs();
1605   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
1606   if ( !myPreviewMode ) {
1607     TPythonDump() << "stepVector = " << theStepVector;
1608     TPythonDump() << this << ".ExtrusionSweepObject1D( "
1609                   << theObject << ", stepVector, " << theNbOfSteps << " )";
1610   }
1611 }
1612
1613 //=======================================================================
1614 //function : ExtrusionSweepObject2D
1615 //purpose  :
1616 //=======================================================================
1617
1618 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1619                                                 const SMESH::DirStruct &  theStepVector,
1620                                                 CORBA::Long               theNbOfSteps)
1621 {
1622   SMESH::long_array_var anElementsId = theObject->GetIDs();
1623   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
1624   if ( !myPreviewMode ) {
1625     TPythonDump() << "stepVector = " << theStepVector;
1626     TPythonDump() << this << ".ExtrusionSweepObject2D( "
1627                   << theObject << ", stepVector, " << theNbOfSteps << " )";
1628   }
1629 }
1630
1631 //=======================================================================
1632 //function : ExtrusionSweepMakeGroups
1633 //purpose  : 
1634 //=======================================================================
1635
1636 SMESH::ListOfGroups*
1637 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1638                                              const SMESH::DirStruct&  theStepVector,
1639                                              CORBA::Long              theNbOfSteps)
1640 {
1641   if ( !myPreviewMode ) {
1642     TPythonDump() << "stepVector = " << theStepVector;
1643     TPythonDump() << this << ".ExtrusionSweepMakeGroups( "
1644                   << theIDsOfElements << ", stepVector, " << theNbOfSteps << " )";
1645   }
1646   return extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, true );
1647 }
1648 //=======================================================================
1649 //function : ExtrusionSweepObjectMakeGroups
1650 //purpose  : 
1651 //=======================================================================
1652
1653 SMESH::ListOfGroups*
1654 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1655                                                    const SMESH::DirStruct&   theStepVector,
1656                                                    CORBA::Long               theNbOfSteps)
1657 {
1658   if ( !myPreviewMode ) {
1659     TPythonDump() << "stepVector = " << theStepVector;
1660     TPythonDump() << this << ".ExtrusionSweepObjectMakeGroups( "
1661                   << theObject << ", stepVector, " << theNbOfSteps << " )";
1662   }
1663   SMESH::long_array_var anElementsId = theObject->GetIDs();
1664   return extrusionSweep (anElementsId, theStepVector, theNbOfSteps, true );
1665 }
1666
1667 //=======================================================================
1668 //function : ExtrusionSweepObject1DMakeGroups
1669 //purpose  : 
1670 //=======================================================================
1671
1672 SMESH::ListOfGroups*
1673 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1674                                                      const SMESH::DirStruct&   theStepVector,
1675                                                      CORBA::Long               theNbOfSteps)
1676 {
1677   if ( !myPreviewMode ) {
1678     TPythonDump() << "stepVector = " << theStepVector;
1679     TPythonDump() << this << ".ExtrusionSweepObject1DMakeGroups( "
1680                   << theObject << ", stepVector, " << theNbOfSteps << " )";
1681   }
1682   SMESH::long_array_var anElementsId = theObject->GetIDs();
1683   return extrusionSweep (anElementsId, theStepVector, theNbOfSteps, true, SMDSAbs_Edge );
1684 }
1685
1686 //=======================================================================
1687 //function : ExtrusionSweepObject2DMakeGroups
1688 //purpose  : 
1689 //=======================================================================
1690
1691 SMESH::ListOfGroups*
1692 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1693                                                      const SMESH::DirStruct&   theStepVector,
1694                                                      CORBA::Long               theNbOfSteps)
1695 {
1696   if ( !myPreviewMode ) {
1697     TPythonDump() << "stepVector = " << theStepVector;
1698     TPythonDump() << this << ".ExtrusionSweepObject2DMakeGroups( "
1699                   << theObject << ", stepVector, " << theNbOfSteps << " )";
1700   }
1701   SMESH::long_array_var anElementsId = theObject->GetIDs();
1702   return extrusionSweep (anElementsId, theStepVector, theNbOfSteps, true, SMDSAbs_Face );
1703 }
1704
1705
1706 //=======================================================================
1707 //function : advancedExtrusion
1708 //purpose  : 
1709 //=======================================================================
1710
1711 SMESH::ListOfGroups*
1712 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
1713                                       const SMESH::DirStruct &  theStepVector,
1714                                       CORBA::Long               theNbOfSteps,
1715                                       CORBA::Long               theExtrFlags,
1716                                       CORBA::Double             theSewTolerance,
1717                                       const bool                theMakeGroups)
1718 {
1719   initData();
1720
1721   TIDSortedElemSet elements;
1722   arrayToSet(theIDsOfElements, GetMeshDS(), elements);
1723
1724   const SMESH::PointStruct * P = &theStepVector.PS;
1725   gp_Vec stepVec( P->x, P->y, P->z );
1726
1727   ::SMESH_MeshEditor anEditor( myMesh );
1728   TElemOfElemListMap aHystory;
1729   ::SMESH_MeshEditor::PGroupIDs groupIds =
1730       anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
1731                                theMakeGroups, theExtrFlags, theSewTolerance);
1732   storeResult(anEditor);
1733
1734   return theMakeGroups ? getGroups(groupIds.get()) : 0;
1735 }
1736
1737 //=======================================================================
1738 //function : AdvancedExtrusion
1739 //purpose  :
1740 //=======================================================================
1741
1742 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
1743                                            const SMESH::DirStruct &  theStepVector,
1744                                            CORBA::Long               theNbOfSteps,
1745                                            CORBA::Long               theExtrFlags,
1746                                            CORBA::Double             theSewTolerance)
1747 {
1748   if ( !myPreviewMode ) {
1749     TPythonDump() << "stepVector = " << theStepVector;
1750     TPythonDump() << this << ".AdvancedExtrusion("
1751                   << theIDsOfElements
1752                   << ", stepVector, "
1753                   << theNbOfSteps << ","
1754                   << theExtrFlags << ", "
1755                   << theSewTolerance <<  " )";
1756   }
1757   advancedExtrusion( theIDsOfElements,
1758                      theStepVector,
1759                      theNbOfSteps,
1760                      theExtrFlags,
1761                      theSewTolerance,
1762                      false);
1763 }
1764
1765 //=======================================================================
1766 //function : AdvancedExtrusionMakeGroups
1767 //purpose  : 
1768 //=======================================================================
1769
1770 SMESH::ListOfGroups*
1771 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
1772                                                 const SMESH::DirStruct&  theStepVector,
1773                                                 CORBA::Long              theNbOfSteps,
1774                                                 CORBA::Long              theExtrFlags,
1775                                                 CORBA::Double            theSewTolerance)
1776 {
1777   if ( !myPreviewMode ) {
1778     TPythonDump() << "stepVector = " << theStepVector;
1779     TPythonDump() << this << ".AdvancedExtrusionMakeGroups("
1780                   << theIDsOfElements
1781                   << ", stepVector, "
1782                   << theNbOfSteps << ","
1783                   << theExtrFlags << ", "
1784                   << theSewTolerance <<  " )";
1785   }
1786   return advancedExtrusion( theIDsOfElements,
1787                             theStepVector,
1788                             theNbOfSteps,
1789                             theExtrFlags,
1790                             theSewTolerance,
1791                             true);
1792 }
1793
1794
1795 //================================================================================
1796 /*!
1797  * \brief Convert extrusion error to IDL enum
1798  */
1799 //================================================================================
1800
1801 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
1802
1803 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
1804 {
1805   switch ( e ) {
1806   RETCASE( EXTR_OK );
1807   RETCASE( EXTR_NO_ELEMENTS );
1808   RETCASE( EXTR_PATH_NOT_EDGE );
1809   RETCASE( EXTR_BAD_PATH_SHAPE );
1810   RETCASE( EXTR_BAD_STARTING_NODE );
1811   RETCASE( EXTR_BAD_ANGLES_NUMBER );
1812   RETCASE( EXTR_CANT_GET_TANGENT );
1813   }
1814   return SMESH::SMESH_MeshEditor::EXTR_OK;
1815 }
1816
1817
1818 //=======================================================================
1819 //function : extrusionAlongPath
1820 //purpose  : 
1821 //=======================================================================
1822
1823 SMESH::ListOfGroups*
1824 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
1825                                        SMESH::SMESH_Mesh_ptr       thePathMesh,
1826                                        GEOM::GEOM_Object_ptr       thePathShape,
1827                                        CORBA::Long                 theNodeStart,
1828                                        CORBA::Boolean              theHasAngles,
1829                                        const SMESH::double_array & theAngles,
1830                                        CORBA::Boolean              theHasRefPoint,
1831                                        const SMESH::PointStruct &  theRefPoint,
1832                                        const bool                  theMakeGroups,
1833                                        SMESH::SMESH_MeshEditor::Extrusion_Error & theError)
1834 {
1835   initData();
1836
1837   if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
1838     theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
1839     return 0;
1840   }
1841   SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
1842
1843   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
1844   SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
1845
1846   if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
1847     theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
1848     return 0;
1849   }
1850
1851   SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
1852   if ( !nodeStart ) {
1853     theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
1854     return 0;
1855   }
1856
1857   TIDSortedElemSet elements;
1858   arrayToSet(theIDsOfElements, GetMeshDS(), elements);
1859
1860   list<double> angles;
1861   for (int i = 0; i < theAngles.length(); i++) {
1862     angles.push_back( theAngles[i] );
1863   }
1864
1865   gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
1866
1867   int nbOldGroups = myMesh->NbGroup();
1868
1869   ::SMESH_MeshEditor anEditor( myMesh );
1870   ::SMESH_MeshEditor::Extrusion_Error error =
1871       anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
1872                                     theHasAngles, angles,
1873                                     theHasRefPoint, refPnt, theMakeGroups );
1874   storeResult(anEditor);
1875   theError = convExtrError( error );
1876
1877   if ( theMakeGroups ) {
1878     list<int> groupIDs = myMesh->GetGroupIds();
1879     list<int>::iterator newBegin = groupIDs.begin();
1880     std::advance( newBegin, nbOldGroups ); // skip old groups
1881     groupIDs.erase( groupIDs.begin(), newBegin );
1882     return getGroups( & groupIDs );
1883   }
1884   return 0;
1885 }
1886
1887 //=======================================================================
1888 //function : ExtrusionAlongPath
1889 //purpose  :
1890 //=======================================================================
1891
1892 SMESH::SMESH_MeshEditor::Extrusion_Error
1893   SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
1894                                          SMESH::SMESH_Mesh_ptr       thePathMesh,
1895                                          GEOM::GEOM_Object_ptr       thePathShape,
1896                                          CORBA::Long                 theNodeStart,
1897                                          CORBA::Boolean              theHasAngles,
1898                                          const SMESH::double_array & theAngles,
1899                                          CORBA::Boolean              theHasRefPoint,
1900                                          const SMESH::PointStruct &  theRefPoint)
1901 {
1902   if ( !myPreviewMode ) {
1903     TPythonDump() << "rotAngles = " << theAngles;
1904
1905     if ( theHasRefPoint )
1906       TPythonDump() << "refPoint = SMESH.PointStruct( "
1907                     << theRefPoint.x << ", "
1908                     << theRefPoint.y << ", "
1909                     << theRefPoint.z << " )";
1910     else
1911       TPythonDump() << "refPoint = SMESH.PointStruct( 0,0,0 )";
1912
1913     TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
1914                   << theIDsOfElements << ", "
1915                   << thePathMesh      << ", "
1916                   << thePathShape     << ", "
1917                   << theNodeStart     << ", "
1918                   << theHasAngles     << ", "
1919                   << "rotAngles"      << ", "
1920                   << theHasRefPoint   << ", refPoint )";
1921   }
1922   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
1923   extrusionAlongPath( theIDsOfElements,
1924                       thePathMesh,
1925                       thePathShape,
1926                       theNodeStart,
1927                       theHasAngles,
1928                       theAngles,
1929                       theHasRefPoint,
1930                       theRefPoint,
1931                       false,
1932                       anError);
1933   return anError;
1934 }
1935
1936 //=======================================================================
1937 //function : ExtrusionAlongPathObject
1938 //purpose  :
1939 //=======================================================================
1940
1941 SMESH::SMESH_MeshEditor::Extrusion_Error
1942 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObject,
1943                                              SMESH::SMESH_Mesh_ptr       thePathMesh,
1944                                              GEOM::GEOM_Object_ptr       thePathShape,
1945                                              CORBA::Long                 theNodeStart,
1946                                              CORBA::Boolean              theHasAngles,
1947                                              const SMESH::double_array & theAngles,
1948                                              CORBA::Boolean              theHasRefPoint,
1949                                              const SMESH::PointStruct &  theRefPoint)
1950 {
1951   if ( !myPreviewMode ) {
1952     TPythonDump() << "rotAngles = " << theAngles;
1953
1954     if ( theHasRefPoint )
1955       TPythonDump() << "refPoint = SMESH.PointStruct( "
1956                     << theRefPoint.x << ", "
1957                     << theRefPoint.y << ", "
1958                     << theRefPoint.z << " )";
1959     else
1960       TPythonDump() << "refPoint = SMESH.PointStruct( 0,0,0 )";
1961
1962     TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
1963                   << theObject        << ", "
1964                   << thePathMesh      << ", "
1965                   << thePathShape     << ", "
1966                   << theNodeStart     << ", "
1967                   << theHasAngles     << ", "
1968                   << "rotAngles"      << ", "
1969                   << theHasRefPoint   << ", refPoint )";
1970   }
1971   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
1972   SMESH::long_array_var anElementsId = theObject->GetIDs();
1973   extrusionAlongPath( anElementsId,
1974                       thePathMesh,
1975                       thePathShape,
1976                       theNodeStart,
1977                       theHasAngles,
1978                       theAngles,
1979                       theHasRefPoint,
1980                       theRefPoint,
1981                       false,
1982                       anError);
1983   return anError;
1984 }
1985
1986
1987 //=======================================================================
1988 //function : ExtrusionAlongPathMakeGroups
1989 //purpose  : 
1990 //=======================================================================
1991
1992 SMESH::ListOfGroups*
1993 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array&   theIDsOfElements,
1994                                                  SMESH::SMESH_Mesh_ptr      thePathMesh,
1995                                                  GEOM::GEOM_Object_ptr      thePathShape,
1996                                                  CORBA::Long                theNodeStart,
1997                                                  CORBA::Boolean             theHasAngles,
1998                                                  const SMESH::double_array& theAngles,
1999                                                  CORBA::Boolean             theHasRefPoint,
2000                                                  const SMESH::PointStruct&  theRefPoint,
2001                                                  SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2002 {
2003   if ( !myPreviewMode ) {
2004     TPythonDump() << "rotAngles = " << theAngles;
2005
2006     if ( theHasRefPoint )
2007       TPythonDump() << "refPoint = SMESH.PointStruct( "
2008                     << theRefPoint.x << ", "
2009                     << theRefPoint.y << ", "
2010                     << theRefPoint.z << " )";
2011     else
2012       TPythonDump() << "refPoint = SMESH.PointStruct( 0,0,0 )";
2013
2014     TPythonDump() << "groups = " << this << ".ExtrusionAlongPathMakeGroups( "
2015                   << theIDsOfElements << ", "
2016                   << thePathMesh      << ", "
2017                   << thePathShape     << ", "
2018                   << theNodeStart     << ", "
2019                   << theHasAngles     << ", "
2020                   << "rotAngles"      << ", "
2021                   << theHasRefPoint   << ", refPoint )";
2022   }
2023   return extrusionAlongPath( theIDsOfElements,
2024                              thePathMesh,
2025                              thePathShape,
2026                              theNodeStart,
2027                              theHasAngles,
2028                              theAngles,
2029                              theHasRefPoint,
2030                              theRefPoint,
2031                              true,
2032                              Error);
2033 }
2034
2035 //=======================================================================
2036 //function : ExtrusionAlongPathObjectMakeGroups
2037 //purpose  : 
2038 //=======================================================================
2039
2040 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2041 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
2042                                    SMESH::SMESH_Mesh_ptr      thePathMesh,
2043                                    GEOM::GEOM_Object_ptr      thePathShape,
2044                                    CORBA::Long                theNodeStart,
2045                                    CORBA::Boolean             theHasAngles,
2046                                    const SMESH::double_array& theAngles,
2047                                    CORBA::Boolean             theHasRefPoint,
2048                                    const SMESH::PointStruct&  theRefPoint,
2049                                    SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2050 {
2051   if ( !myPreviewMode ) {
2052     TPythonDump() << "rotAngles = " << theAngles;
2053
2054     if ( theHasRefPoint )
2055       TPythonDump() << "refPoint = SMESH.PointStruct( "
2056                     << theRefPoint.x << ", "
2057                     << theRefPoint.y << ", "
2058                     << theRefPoint.z << " )";
2059     else
2060       TPythonDump() << "refPoint = SMESH.PointStruct( 0,0,0 )";
2061
2062     TPythonDump() << "groups = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
2063                   << theObject << ", "
2064                   << thePathMesh      << ", "
2065                   << thePathShape     << ", "
2066                   << theNodeStart     << ", "
2067                   << theHasAngles     << ", "
2068                   << "rotAngles"      << ", "
2069                   << theHasRefPoint   << ", refPoint )";
2070   }
2071   SMESH::long_array_var anElementsId = theObject->GetIDs();
2072   return extrusionAlongPath( anElementsId,
2073                              thePathMesh,
2074                              thePathShape,
2075                              theNodeStart,
2076                              theHasAngles,
2077                              theAngles,
2078                              theHasRefPoint,
2079                              theRefPoint,
2080                              true,
2081                              Error);
2082 }
2083
2084 //================================================================================
2085 /*!
2086  * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2087  * of given angles along path steps
2088   * \param PathMesh mesh containing a 1D sub-mesh on the edge, along 
2089   *                which proceeds the extrusion
2090   * \param PathShape is shape(edge); as the mesh can be complex, the edge 
2091   *                 is used to define the sub-mesh for the path
2092  */
2093 //================================================================================
2094
2095 SMESH::double_array*
2096 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr       thePathMesh,
2097                                           GEOM::GEOM_Object_ptr       thePathShape,
2098                                           const SMESH::double_array & theAngles)
2099 {
2100   SMESH::double_array_var aResult = new SMESH::double_array();
2101   return aResult._retn();
2102 }
2103
2104
2105 //=======================================================================
2106 //function : mirror
2107 //purpose  : 
2108 //=======================================================================
2109
2110 SMESH::ListOfGroups*
2111 SMESH_MeshEditor_i::mirror(const SMESH::long_array &           theIDsOfElements,
2112                            const SMESH::AxisStruct &           theAxis,
2113                            SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2114                            CORBA::Boolean                      theCopy,
2115                            const bool                          theMakeGroups,
2116                            ::SMESH_Mesh*                       theTargetMesh)
2117 {
2118   initData();
2119
2120   TIDSortedElemSet elements;
2121   arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2122
2123   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
2124   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
2125
2126   gp_Trsf aTrsf;
2127   switch ( theMirrorType ) {
2128   case  SMESH::SMESH_MeshEditor::POINT:
2129     aTrsf.SetMirror( P );
2130     break;
2131   case  SMESH::SMESH_MeshEditor::AXIS:
2132     aTrsf.SetMirror( gp_Ax1( P, V ));
2133     break;
2134   default:
2135     aTrsf.SetMirror( gp_Ax2( P, V ));
2136   }
2137
2138   ::SMESH_MeshEditor anEditor( myMesh );
2139   ::SMESH_MeshEditor::PGroupIDs groupIds =
2140       anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
2141
2142   if(theCopy) {
2143     storeResult(anEditor);
2144   }
2145   return theMakeGroups ? getGroups(groupIds.get()) : 0;
2146 }
2147
2148 //=======================================================================
2149 //function : Mirror
2150 //purpose  :
2151 //=======================================================================
2152
2153 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElements,
2154                                 const SMESH::AxisStruct &           theAxis,
2155                                 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2156                                 CORBA::Boolean                      theCopy)
2157 {
2158   if ( !myPreviewMode ) {
2159     TPythonDump() << this << ".Mirror( "
2160                   << theIDsOfElements << ", "
2161                   << theAxis          << ", "
2162                   << mirrorTypeName(theMirrorType) << ", "
2163                   << theCopy          << " )";
2164   }
2165   mirror(theIDsOfElements, theAxis, theMirrorType, theCopy, false);
2166 }
2167
2168
2169 //=======================================================================
2170 //function : MirrorObject
2171 //purpose  :
2172 //=======================================================================
2173
2174 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr           theObject,
2175                                       const SMESH::AxisStruct &           theAxis,
2176                                       SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2177                                       CORBA::Boolean                      theCopy)
2178 {
2179   if ( !myPreviewMode ) {
2180     TPythonDump() << this << ".MirrorObject( "
2181                   << theObject << ", "
2182                   << theAxis   << ", "
2183                   << mirrorTypeName(theMirrorType) << ", "
2184                   << theCopy   << " )";
2185   }
2186   SMESH::long_array_var anElementsId = theObject->GetIDs();
2187   mirror(anElementsId, theAxis, theMirrorType, theCopy, false);
2188 }
2189
2190 //=======================================================================
2191 //function : MirrorMakeGroups
2192 //purpose  : 
2193 //=======================================================================
2194
2195 SMESH::ListOfGroups*
2196 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array&            theIDsOfElements,
2197                                      const SMESH::AxisStruct&            theMirror,
2198                                      SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
2199 {
2200   if ( !myPreviewMode ) {
2201     TPythonDump() << this << ".MirrorMakeGroups( "
2202                   << theIDsOfElements << ", "
2203                   << theMirror          << ", "
2204                   << mirrorTypeName(theMirrorType) << " )";
2205   }
2206   return mirror(theIDsOfElements, theMirror, theMirrorType, true, true);
2207 }
2208
2209 //=======================================================================
2210 //function : MirrorObjectMakeGroups
2211 //purpose  : 
2212 //=======================================================================
2213
2214 SMESH::ListOfGroups*
2215 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr           theObject,
2216                                            const SMESH::AxisStruct&            theMirror,
2217                                            SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
2218 {
2219   if ( !myPreviewMode ) {
2220     TPythonDump() << this << ".MirrorObjectMakeGroups( "
2221                   << theObject << ", "
2222                   << theMirror   << ", "
2223                   << mirrorTypeName(theMirrorType) << " )";
2224   }
2225   SMESH::long_array_var anElementsId = theObject->GetIDs();
2226   return mirror(anElementsId, theMirror, theMirrorType, true, true);
2227 }
2228
2229 //=======================================================================
2230 //function : MirrorMakeMesh
2231 //purpose  : 
2232 //=======================================================================
2233
2234 SMESH::SMESH_Mesh_ptr
2235 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array&            theIDsOfElements,
2236                                    const SMESH::AxisStruct&            theMirror,
2237                                    SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2238                                    CORBA::Boolean                      theCopyGroups,
2239                                    const char*                         theMeshName)
2240 {
2241   TPythonDump pydump; // to prevent dump at mesh creation
2242
2243   SMESH::SMESH_Mesh_var mesh = makeMesh( theMeshName );
2244   if ( SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh ))
2245   {
2246     mirror(theIDsOfElements, theMirror, theMirrorType,
2247            false, theCopyGroups, & mesh_i->GetImpl());
2248     mesh_i->CreateGroupServants();
2249   }
2250
2251   if ( !myPreviewMode ) {
2252     pydump << mesh << " = " << this << ".MirrorMakeMesh( "
2253            << theIDsOfElements << ", "
2254            << theMirror   << ", "
2255            << mirrorTypeName(theMirrorType) << ", "
2256            << theCopyGroups << ", '"
2257            << theMeshName << "' )";
2258   }
2259   return mesh._retn();
2260 }
2261
2262 //=======================================================================
2263 //function : MirrorObjectMakeMesh
2264 //purpose  : 
2265 //=======================================================================
2266
2267 SMESH::SMESH_Mesh_ptr
2268 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr           theObject,
2269                                          const SMESH::AxisStruct&            theMirror,
2270                                          SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2271                                          CORBA::Boolean                      theCopyGroups,
2272                                          const char*                         theMeshName)
2273 {
2274   TPythonDump pydump; // to prevent dump at mesh creation
2275
2276   SMESH::SMESH_Mesh_var mesh = makeMesh( theMeshName );
2277   if ( SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh ))
2278   {
2279     SMESH::long_array_var anElementsId = theObject->GetIDs();
2280     mirror(anElementsId, theMirror, theMirrorType,
2281            false, theCopyGroups, & mesh_i->GetImpl());
2282     mesh_i->CreateGroupServants();
2283   }
2284   if ( !myPreviewMode ) {
2285     pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
2286            << theObject << ", "
2287            << theMirror   << ", "
2288            << mirrorTypeName(theMirrorType) << ", "
2289            << theCopyGroups << ", '"
2290            << theMeshName << "' )";
2291   }
2292   return mesh._retn();
2293 }
2294
2295 //=======================================================================
2296 //function : translate
2297 //purpose  : 
2298 //=======================================================================
2299
2300 SMESH::ListOfGroups*
2301 SMESH_MeshEditor_i::translate(const SMESH::long_array & theIDsOfElements,
2302                               const SMESH::DirStruct &  theVector,
2303                               CORBA::Boolean            theCopy,
2304                               const bool                theMakeGroups,
2305                               ::SMESH_Mesh*             theTargetMesh)
2306 {
2307   initData();
2308
2309   TIDSortedElemSet elements;
2310   arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2311
2312   gp_Trsf aTrsf;
2313   const SMESH::PointStruct * P = &theVector.PS;
2314   aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
2315
2316   ::SMESH_MeshEditor anEditor( myMesh );
2317   ::SMESH_MeshEditor::PGroupIDs groupIds =
2318       anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
2319
2320   if(theCopy)
2321     storeResult(anEditor);
2322
2323   return theMakeGroups ? getGroups(groupIds.get()) : 0;
2324 }
2325
2326 //=======================================================================
2327 //function : Translate
2328 //purpose  :
2329 //=======================================================================
2330
2331 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
2332                                    const SMESH::DirStruct &  theVector,
2333                                    CORBA::Boolean            theCopy)
2334 {
2335   if ( !myPreviewMode ) {
2336     TPythonDump() << "vector = " << theVector;
2337     TPythonDump() << this << ".Translate( "
2338                   << theIDsOfElements
2339                   << ", vector, "
2340                   << theCopy << " )";
2341   }
2342   translate(theIDsOfElements,
2343             theVector,
2344             theCopy,
2345             false);
2346 }
2347
2348 //=======================================================================
2349 //function : TranslateObject
2350 //purpose  :
2351 //=======================================================================
2352
2353 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
2354                                          const SMESH::DirStruct &  theVector,
2355                                          CORBA::Boolean            theCopy)
2356 {
2357   if ( !myPreviewMode ) {
2358     TPythonDump() << this << ".TranslateObject( "
2359                   << theObject
2360                   << ", vector, "
2361                   << theCopy << " )";
2362   }
2363   SMESH::long_array_var anElementsId = theObject->GetIDs();
2364   translate(anElementsId,
2365             theVector,
2366             theCopy,
2367             false);
2368 }
2369
2370 //=======================================================================
2371 //function : TranslateMakeGroups
2372 //purpose  : 
2373 //=======================================================================
2374
2375 SMESH::ListOfGroups*
2376 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
2377                                         const SMESH::DirStruct&  theVector)
2378 {
2379   if ( !myPreviewMode ) {
2380     TPythonDump() << "vector = " << theVector;
2381     TPythonDump() << this << ".TranslateMakeGroups( "
2382                   << theIDsOfElements
2383                   << ", vector )";
2384   }
2385   return translate(theIDsOfElements,theVector,true,true);
2386 }
2387
2388 //=======================================================================
2389 //function : TranslateObjectMakeGroups
2390 //purpose  : 
2391 //=======================================================================
2392
2393 SMESH::ListOfGroups*
2394 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2395                                               const SMESH::DirStruct&   theVector)
2396 {
2397   if ( !myPreviewMode ) {
2398     TPythonDump() << "vector = " << theVector;
2399     TPythonDump() << this << ".TranslateObjectMakeGroups( "
2400                   << theObject
2401                   << ", vector )";
2402   }
2403   SMESH::long_array_var anElementsId = theObject->GetIDs();
2404   return translate(anElementsId, theVector, true, true);
2405 }
2406
2407 //=======================================================================
2408 //function : TranslateMakeMesh
2409 //purpose  : 
2410 //=======================================================================
2411
2412 SMESH::SMESH_Mesh_ptr
2413 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
2414                                       const SMESH::DirStruct&  theVector,
2415                                       CORBA::Boolean           theCopyGroups,
2416                                       const char*              theMeshName)
2417 {
2418   TPythonDump pydump; // to prevent dump at mesh creation
2419   SMESH::SMESH_Mesh_var mesh = makeMesh( theMeshName );
2420
2421   if ( SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh )) {
2422     translate(theIDsOfElements, theVector,
2423               false, theCopyGroups, & mesh_i->GetImpl());
2424     mesh_i->CreateGroupServants();
2425   }
2426   if ( !myPreviewMode ) {
2427     pydump << mesh << " = " << this << ".TranslateMakeMesh( "
2428            << theIDsOfElements << ", "
2429            << theVector   << ", "
2430            << theCopyGroups << ", '"
2431            << theMeshName << "' )";
2432   }
2433   return mesh._retn();
2434 }
2435
2436 //=======================================================================
2437 //function : TranslateObjectMakeMesh
2438 //purpose  : 
2439 //=======================================================================
2440
2441 SMESH::SMESH_Mesh_ptr
2442 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
2443                                             const SMESH::DirStruct&   theVector,
2444                                             CORBA::Boolean            theCopyGroups,
2445                                             const char*               theMeshName)
2446 {
2447   TPythonDump pydump; // to prevent dump at mesh creation
2448   SMESH::SMESH_Mesh_var mesh = makeMesh( theMeshName );
2449
2450   if ( SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh )) {
2451     SMESH::long_array_var anElementsId = theObject->GetIDs();
2452     translate(anElementsId, theVector,
2453               false, theCopyGroups, & mesh_i->GetImpl());
2454     mesh_i->CreateGroupServants();
2455   }
2456   if ( !myPreviewMode ) {
2457     pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
2458            << theObject << ", "
2459            << theVector   << ", "
2460            << theCopyGroups << ", '"
2461            << theMeshName << "' )";
2462   }
2463   return mesh._retn();
2464 }
2465
2466 //=======================================================================
2467 //function : rotate
2468 //purpose  : 
2469 //=======================================================================
2470
2471 SMESH::ListOfGroups*
2472 SMESH_MeshEditor_i::rotate(const SMESH::long_array & theIDsOfElements,
2473                            const SMESH::AxisStruct & theAxis,
2474                            CORBA::Double             theAngle,
2475                            CORBA::Boolean            theCopy,
2476                            const bool                theMakeGroups,
2477                            ::SMESH_Mesh*             theTargetMesh)
2478 {
2479   initData();
2480
2481   TIDSortedElemSet elements;
2482   arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2483
2484   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
2485   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
2486
2487   gp_Trsf aTrsf;
2488   aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
2489
2490   ::SMESH_MeshEditor anEditor( myMesh );
2491   ::SMESH_MeshEditor::PGroupIDs groupIds =
2492       anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
2493
2494   if(theCopy) {
2495     storeResult(anEditor);
2496   }
2497   return theMakeGroups ? getGroups(groupIds.get()) : 0;
2498 }
2499
2500 //=======================================================================
2501 //function : Rotate
2502 //purpose  :
2503 //=======================================================================
2504
2505 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
2506                                 const SMESH::AxisStruct & theAxis,
2507                                 CORBA::Double             theAngle,
2508                                 CORBA::Boolean            theCopy)
2509 {
2510   if ( !myPreviewMode ) {
2511     TPythonDump() << "axis = " << theAxis;
2512     TPythonDump() << this << ".Rotate( "
2513                   << theIDsOfElements
2514                   << ", axis, "
2515                   << theAngle << ", "
2516                   << theCopy << " )";
2517   }
2518   rotate(theIDsOfElements,
2519          theAxis,
2520          theAngle,
2521          theCopy,
2522          false);
2523 }
2524
2525 //=======================================================================
2526 //function : RotateObject
2527 //purpose  :
2528 //=======================================================================
2529
2530 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
2531                                       const SMESH::AxisStruct & theAxis,
2532                                       CORBA::Double             theAngle,
2533                                       CORBA::Boolean            theCopy)
2534 {
2535   if ( !myPreviewMode ) {
2536     TPythonDump() << "axis = " << theAxis;
2537     TPythonDump() << this << ".RotateObject( "
2538                   << theObject
2539                   << ", axis, "
2540                   << theAngle << ", "
2541                   << theCopy << " )";
2542   }
2543   SMESH::long_array_var anElementsId = theObject->GetIDs();
2544   rotate(anElementsId,
2545          theAxis,
2546          theAngle,
2547          theCopy,
2548          false);
2549 }
2550
2551 //=======================================================================
2552 //function : RotateMakeGroups
2553 //purpose  : 
2554 //=======================================================================
2555
2556 SMESH::ListOfGroups*
2557 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
2558                                      const SMESH::AxisStruct& theAxis,
2559                                      CORBA::Double            theAngle)
2560 {
2561   if ( !myPreviewMode ) {
2562     TPythonDump() << "axis = " << theAxis;
2563     TPythonDump() << this << ".RotateMakeGroups( "
2564                   << theIDsOfElements
2565                   << ", axis, "
2566                   << theAngle << " )";
2567   }
2568   return rotate(theIDsOfElements,theAxis,theAngle,true,true);
2569 }
2570
2571 //=======================================================================
2572 //function : RotateObjectMakeGroups
2573 //purpose  : 
2574 //=======================================================================
2575
2576 SMESH::ListOfGroups*
2577 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2578                                            const SMESH::AxisStruct&  theAxis,
2579                                            CORBA::Double             theAngle)
2580 {
2581   if ( !myPreviewMode ) {
2582     TPythonDump() << "axis = " << theAxis;
2583     TPythonDump() << this << ".RotateObjectMakeGroups( "
2584                   << theObject
2585                   << ", axis, "
2586                   << theAngle << " )";
2587   }
2588   SMESH::long_array_var anElementsId = theObject->GetIDs();
2589   return rotate(anElementsId,theAxis,theAngle,true,true);
2590 }
2591
2592 //=======================================================================
2593 //function : RotateMakeMesh
2594 //purpose  : 
2595 //=======================================================================
2596
2597 SMESH::SMESH_Mesh_ptr 
2598 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
2599                                    const SMESH::AxisStruct& theAxis,
2600                                    CORBA::Double            theAngleInRadians,
2601                                    CORBA::Boolean           theCopyGroups,
2602                                    const char*              theMeshName)
2603 {
2604   TPythonDump pydump; // to prevent dump at mesh creation
2605   SMESH::SMESH_Mesh_var mesh = makeMesh( theMeshName );
2606
2607   if ( SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh )) {
2608     rotate(theIDsOfElements, theAxis, theAngleInRadians,
2609            false, theCopyGroups, & mesh_i->GetImpl());
2610     mesh_i->CreateGroupServants();
2611   }
2612   if ( !myPreviewMode ) {
2613     pydump << mesh << " = " << this << ".RotateMakeMesh( "
2614            << theIDsOfElements << ", "
2615            << theAxis << ", "
2616            << theAngleInRadians   << ", "
2617            << theCopyGroups << ", '"
2618            << theMeshName << "' )";
2619   }
2620   return mesh._retn();
2621 }
2622
2623 //=======================================================================
2624 //function : RotateObjectMakeMesh
2625 //purpose  : 
2626 //=======================================================================
2627
2628 SMESH::SMESH_Mesh_ptr 
2629 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
2630                                          const SMESH::AxisStruct&  theAxis,
2631                                          CORBA::Double             theAngleInRadians,
2632                                          CORBA::Boolean            theCopyGroups,
2633                                          const char*               theMeshName)
2634 {
2635   TPythonDump pydump; // to prevent dump at mesh creation
2636   SMESH::SMESH_Mesh_var mesh = makeMesh( theMeshName );
2637
2638   if ( SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh )) {
2639     SMESH::long_array_var anElementsId = theObject->GetIDs();
2640     rotate(anElementsId, theAxis, theAngleInRadians,
2641            false, theCopyGroups, & mesh_i->GetImpl());
2642     mesh_i->CreateGroupServants();
2643   }
2644   if ( !myPreviewMode ) {
2645     pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
2646            << theObject << ", "
2647            << theAxis << ", "
2648            << theAngleInRadians   << ", "
2649            << theCopyGroups << ", '"
2650            << theMeshName << "' )";
2651   }
2652   return mesh._retn();
2653 }
2654
2655 //=======================================================================
2656 //function : FindCoincidentNodes
2657 //purpose  :
2658 //=======================================================================
2659
2660 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
2661                                               SMESH::array_of_long_array_out GroupsOfNodes)
2662 {
2663   initData();
2664
2665   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
2666   ::SMESH_MeshEditor anEditor( myMesh );
2667   set<const SMDS_MeshNode*> nodes; // no input nodes
2668   anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
2669
2670   GroupsOfNodes = new SMESH::array_of_long_array;
2671   GroupsOfNodes->length( aListOfListOfNodes.size() );
2672   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
2673   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
2674     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
2675     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
2676     SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
2677     aGroup.length( aListOfNodes.size() );
2678     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
2679       aGroup[ j ] = (*lIt)->GetID();
2680   }
2681   TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
2682                 << Tolerance << " )";
2683 }
2684
2685 //=======================================================================
2686 //function : FindCoincidentNodesOnPart
2687 //purpose  :
2688 //=======================================================================
2689 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr      theObject,
2690                                                    CORBA::Double                  Tolerance,
2691                                                    SMESH::array_of_long_array_out GroupsOfNodes)
2692 {
2693   initData();
2694   SMESH::long_array_var aElementsId = theObject->GetIDs();
2695
2696   SMESHDS_Mesh* aMesh = GetMeshDS();
2697   set<const SMDS_MeshNode*> nodes;
2698
2699   if ( !CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) &&
2700       SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) {
2701     for(int i = 0; i < aElementsId->length(); i++) {
2702       CORBA::Long ind = aElementsId[i];
2703       const SMDS_MeshNode * elem = aMesh->FindNode(ind);
2704       if(elem)
2705         nodes.insert(elem);
2706     }
2707   }
2708   else {
2709     for(int i = 0; i < aElementsId->length(); i++) {
2710       CORBA::Long ind = aElementsId[i];
2711       const SMDS_MeshElement * elem = aMesh->FindElement(ind);
2712       if(elem) {
2713         SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
2714         while ( nIt->more() )
2715           nodes.insert( nodes.end(),static_cast<const SMDS_MeshNode*>(nIt->next()));
2716       }
2717     }
2718   }
2719     
2720   
2721   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
2722   ::SMESH_MeshEditor anEditor( myMesh );
2723   if(!nodes.empty())
2724     anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
2725   
2726   GroupsOfNodes = new SMESH::array_of_long_array;
2727   GroupsOfNodes->length( aListOfListOfNodes.size() );
2728   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
2729   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
2730     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
2731     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
2732     SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
2733     aGroup.length( aListOfNodes.size() );
2734     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
2735       aGroup[ j ] = (*lIt)->GetID();
2736   }
2737   TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
2738                 <<theObject<<", "
2739                 << Tolerance << " )";
2740 }
2741
2742 //=======================================================================
2743 //function : MergeNodes
2744 //purpose  :
2745 //=======================================================================
2746
2747 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
2748 {
2749   initData();
2750
2751   SMESHDS_Mesh* aMesh = GetMeshDS();
2752
2753   TPythonDump aTPythonDump;
2754   aTPythonDump << this << ".MergeNodes([";
2755   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
2756   for (int i = 0; i < GroupsOfNodes.length(); i++)
2757   {
2758     const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
2759     aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
2760     list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
2761     for ( int j = 0; j < aNodeGroup.length(); j++ )
2762     {
2763       CORBA::Long index = aNodeGroup[ j ];
2764       const SMDS_MeshNode * node = aMesh->FindNode(index);
2765       if ( node )
2766         aListOfNodes.push_back( node );
2767     }
2768     if ( aListOfNodes.size() < 2 )
2769       aListOfListOfNodes.pop_back();
2770
2771     if ( i > 0 ) aTPythonDump << ", ";
2772     aTPythonDump << aNodeGroup;
2773   }
2774   ::SMESH_MeshEditor anEditor( myMesh );
2775   anEditor.MergeNodes( aListOfListOfNodes );
2776
2777   aTPythonDump <<  "])";
2778 }
2779
2780 //=======================================================================
2781 //function : FindEqualElements
2782 //purpose  :
2783 //=======================================================================
2784 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr      theObject,
2785                                            SMESH::array_of_long_array_out GroupsOfElementsID)
2786 {
2787   initData();
2788   if ( !(!CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) &&
2789          SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) ) {
2790     typedef list<int> TListOfIDs;
2791     set<const SMDS_MeshElement*> elems;
2792     SMESH::long_array_var aElementsId = theObject->GetIDs();
2793     SMESHDS_Mesh* aMesh = GetMeshDS();
2794
2795     for(int i = 0; i < aElementsId->length(); i++) {
2796       CORBA::Long anID = aElementsId[i];
2797       const SMDS_MeshElement * elem = aMesh->FindElement(anID);
2798       if (elem) {
2799         elems.insert(elem);
2800       }
2801     }
2802
2803     ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
2804     ::SMESH_MeshEditor anEditor( myMesh );
2805     anEditor.FindEqualElements( elems, aListOfListOfElementsID );
2806
2807     GroupsOfElementsID = new SMESH::array_of_long_array;
2808     GroupsOfElementsID->length( aListOfListOfElementsID.size() );
2809
2810     ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
2811     for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
2812       SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
2813       TListOfIDs& listOfIDs = *arraysIt;
2814       aGroup.length( listOfIDs.size() );
2815       TListOfIDs::iterator idIt = listOfIDs.begin();
2816       for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
2817         aGroup[ k ] = *idIt;
2818       }
2819     }
2820
2821   TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
2822                 <<theObject<<" )";
2823   }
2824 }
2825
2826 //=======================================================================
2827 //function : MergeElements
2828 //purpose  :
2829 //=======================================================================
2830
2831 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
2832 {
2833   initData();
2834
2835   TPythonDump aTPythonDump;
2836   aTPythonDump << this << ".MergeElements( [";
2837
2838   ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
2839
2840   for (int i = 0; i < GroupsOfElementsID.length(); i++) {
2841     const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
2842     aListOfListOfElementsID.push_back( list< int >() );
2843     list< int >& aListOfElemsID = aListOfListOfElementsID.back();
2844     for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
2845       CORBA::Long id = anElemsIDGroup[ j ];
2846       aListOfElemsID.push_back( id );
2847     }
2848     if ( aListOfElemsID.size() < 2 )
2849       aListOfListOfElementsID.pop_back();
2850     if ( i > 0 ) aTPythonDump << ", ";
2851     aTPythonDump << anElemsIDGroup;
2852   }
2853
2854   ::SMESH_MeshEditor anEditor( myMesh );
2855   anEditor.MergeElements(aListOfListOfElementsID);
2856
2857   aTPythonDump << "] )";
2858 }
2859
2860 //=======================================================================
2861 //function : MergeEqualElements
2862 //purpose  :
2863 //=======================================================================
2864
2865 void SMESH_MeshEditor_i::MergeEqualElements()
2866 {
2867   initData();
2868
2869   ::SMESH_MeshEditor anEditor( myMesh );
2870   anEditor.MergeEqualElements();
2871
2872   TPythonDump() << this << ".MergeEqualElements()";
2873 }
2874
2875 //================================================================================
2876 /*!
2877  * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
2878  * move the node closest to the point to point's location and return ID of the node
2879  */
2880 //================================================================================
2881
2882 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
2883                                                        CORBA::Double y,
2884                                                        CORBA::Double z,
2885                                                        CORBA::Long   theNodeID)
2886 {
2887   // We keep myNodeSearcher until any mesh modification:
2888   // 1) initData() deletes myNodeSearcher at any edition,
2889   // 2) TNodeSearcherDeleter - at any mesh compute event and mesh change
2890
2891   initData();
2892
2893   int nodeID = theNodeID;
2894   const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
2895   if ( !node )
2896   {
2897     static TNodeSearcherDeleter deleter;
2898     deleter.Set( myMesh );
2899     if ( !myNodeSearcher ) {
2900       ::SMESH_MeshEditor anEditor( myMesh );
2901       myNodeSearcher = anEditor.GetNodeSearcher();
2902     }
2903     gp_Pnt p( x,y,z );
2904     node = myNodeSearcher->FindClosestTo( p );
2905   }
2906   if ( node ) {
2907     nodeID = node->GetID();
2908     if ( myPreviewMode ) // make preview data
2909     {
2910       // in a preview mesh, make edges linked to a node
2911       TPreviewMesh tmpMesh;
2912       TIDSortedElemSet linkedNodes;
2913       ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
2914       TIDSortedElemSet::iterator nIt = linkedNodes.begin();
2915       for ( ; nIt != linkedNodes.end(); ++nIt )
2916       {
2917         SMDS_MeshEdge edge( node, cast2Node( *nIt ));
2918         tmpMesh.Copy( &edge );
2919       }
2920       // move copied node
2921       node = tmpMesh.GetMeshDS()->FindNode( nodeID );
2922       if ( node )
2923         tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
2924       // fill preview data
2925       ::SMESH_MeshEditor anEditor( & tmpMesh );
2926       storeResult( anEditor );
2927     }
2928     else
2929     {
2930       GetMeshDS()->MoveNode(node, x, y, z);
2931     }
2932   }
2933
2934   if ( !myPreviewMode ) {
2935     TPythonDump() << "nodeID = " << this
2936                   << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z << " )";
2937   }
2938
2939   return nodeID;
2940 }
2941
2942 //=======================================================================
2943 //function : convError
2944 //purpose  :
2945 //=======================================================================
2946
2947 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2948
2949 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
2950 {
2951   switch ( e ) {
2952   RETCASE( SEW_OK );
2953   RETCASE( SEW_BORDER1_NOT_FOUND );
2954   RETCASE( SEW_BORDER2_NOT_FOUND );
2955   RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
2956   RETCASE( SEW_BAD_SIDE_NODES );
2957   RETCASE( SEW_VOLUMES_TO_SPLIT );
2958   RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
2959   RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
2960   RETCASE( SEW_BAD_SIDE1_NODES );
2961   RETCASE( SEW_BAD_SIDE2_NODES );
2962   }
2963   return SMESH::SMESH_MeshEditor::SEW_OK;
2964 }
2965
2966 //=======================================================================
2967 //function : SewFreeBorders
2968 //purpose  :
2969 //=======================================================================
2970
2971 SMESH::SMESH_MeshEditor::Sew_Error
2972   SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
2973                                      CORBA::Long SecondNodeID1,
2974                                      CORBA::Long LastNodeID1,
2975                                      CORBA::Long FirstNodeID2,
2976                                      CORBA::Long SecondNodeID2,
2977                                      CORBA::Long LastNodeID2,
2978                                      CORBA::Boolean CreatePolygons,
2979                                      CORBA::Boolean CreatePolyedrs)
2980 {
2981   initData();
2982
2983   SMESHDS_Mesh* aMesh = GetMeshDS();
2984
2985   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
2986   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
2987   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
2988   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
2989   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
2990   const SMDS_MeshNode* aSide2ThirdNode   = aMesh->FindNode( LastNodeID2   );
2991
2992   if (!aBorderFirstNode ||
2993       !aBorderSecondNode||
2994       !aBorderLastNode)
2995     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
2996   if (!aSide2FirstNode  ||
2997       !aSide2SecondNode ||
2998       !aSide2ThirdNode)
2999     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
3000
3001   TPythonDump() << "error = " << this << ".SewFreeBorders( "
3002                 << FirstNodeID1  << ", "
3003                 << SecondNodeID1 << ", "
3004                 << LastNodeID1   << ", "
3005                 << FirstNodeID2  << ", "
3006                 << SecondNodeID2 << ", "
3007                 << LastNodeID2   << ", "
3008                 << CreatePolygons<< ", "
3009                 << CreatePolyedrs<< " )";
3010
3011   ::SMESH_MeshEditor anEditor( myMesh );
3012   SMESH::SMESH_MeshEditor::Sew_Error error =
3013     convError( anEditor.SewFreeBorder (aBorderFirstNode,
3014                                        aBorderSecondNode,
3015                                        aBorderLastNode,
3016                                        aSide2FirstNode,
3017                                        aSide2SecondNode,
3018                                        aSide2ThirdNode,
3019                                        true,
3020                                        CreatePolygons,
3021                                        CreatePolyedrs) );
3022
3023   storeResult(anEditor);
3024
3025   return error;
3026 }
3027
3028
3029 //=======================================================================
3030 //function : SewConformFreeBorders
3031 //purpose  :
3032 //=======================================================================
3033
3034 SMESH::SMESH_MeshEditor::Sew_Error
3035 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
3036                                           CORBA::Long SecondNodeID1,
3037                                           CORBA::Long LastNodeID1,
3038                                           CORBA::Long FirstNodeID2,
3039                                           CORBA::Long SecondNodeID2)
3040 {
3041   initData();
3042
3043   SMESHDS_Mesh* aMesh = GetMeshDS();
3044
3045   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
3046   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
3047   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
3048   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
3049   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
3050   const SMDS_MeshNode* aSide2ThirdNode   = 0;
3051
3052   if (!aBorderFirstNode ||
3053       !aBorderSecondNode||
3054       !aBorderLastNode )
3055     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
3056   if (!aSide2FirstNode  ||
3057       !aSide2SecondNode)
3058     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
3059
3060   TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
3061                 << FirstNodeID1  << ", "
3062                 << SecondNodeID1 << ", "
3063                 << LastNodeID1   << ", "
3064                 << FirstNodeID2  << ", "
3065                 << SecondNodeID2 << " )";
3066
3067   ::SMESH_MeshEditor anEditor( myMesh );
3068   SMESH::SMESH_MeshEditor::Sew_Error error =
3069     convError( anEditor.SewFreeBorder (aBorderFirstNode,
3070                                        aBorderSecondNode,
3071                                        aBorderLastNode,
3072                                        aSide2FirstNode,
3073                                        aSide2SecondNode,
3074                                        aSide2ThirdNode,
3075                                        true,
3076                                        false, false) );
3077
3078   storeResult(anEditor);
3079
3080   return error;
3081 }
3082
3083
3084 //=======================================================================
3085 //function : SewBorderToSide
3086 //purpose  :
3087 //=======================================================================
3088
3089 SMESH::SMESH_MeshEditor::Sew_Error
3090 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
3091                                     CORBA::Long SecondNodeIDOnFreeBorder,
3092                                     CORBA::Long LastNodeIDOnFreeBorder,
3093                                     CORBA::Long FirstNodeIDOnSide,
3094                                     CORBA::Long LastNodeIDOnSide,
3095                                     CORBA::Boolean CreatePolygons,
3096                                     CORBA::Boolean CreatePolyedrs)
3097 {
3098   initData();
3099
3100   SMESHDS_Mesh* aMesh = GetMeshDS();
3101
3102   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeIDOnFreeBorder  );
3103   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
3104   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeIDOnFreeBorder   );
3105   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeIDOnSide  );
3106   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( LastNodeIDOnSide );
3107   const SMDS_MeshNode* aSide2ThirdNode   = 0;
3108
3109   if (!aBorderFirstNode ||
3110       !aBorderSecondNode||
3111       !aBorderLastNode  )
3112     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
3113   if (!aSide2FirstNode  ||
3114       !aSide2SecondNode)
3115     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
3116
3117   TPythonDump() << "error = " << this << ".SewBorderToSide( "
3118                 << FirstNodeIDOnFreeBorder  << ", "
3119                 << SecondNodeIDOnFreeBorder << ", "
3120                 << LastNodeIDOnFreeBorder   << ", "
3121                 << FirstNodeIDOnSide        << ", "
3122                 << LastNodeIDOnSide         << ", "
3123                 << CreatePolygons           << ", "
3124                 << CreatePolyedrs           << ") ";
3125
3126   ::SMESH_MeshEditor anEditor( myMesh );
3127   SMESH::SMESH_MeshEditor::Sew_Error error =
3128     convError( anEditor.SewFreeBorder (aBorderFirstNode,
3129                                        aBorderSecondNode,
3130                                        aBorderLastNode,
3131                                        aSide2FirstNode,
3132                                        aSide2SecondNode,
3133                                        aSide2ThirdNode,
3134                                        false,
3135                                        CreatePolygons,
3136                                        CreatePolyedrs) );
3137
3138   storeResult(anEditor);
3139
3140   return error;
3141 }
3142
3143
3144 //=======================================================================
3145 //function : SewSideElements
3146 //purpose  :
3147 //=======================================================================
3148
3149 SMESH::SMESH_MeshEditor::Sew_Error
3150 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
3151                                     const SMESH::long_array& IDsOfSide2Elements,
3152                                     CORBA::Long NodeID1OfSide1ToMerge,
3153                                     CORBA::Long NodeID1OfSide2ToMerge,
3154                                     CORBA::Long NodeID2OfSide1ToMerge,
3155                                     CORBA::Long NodeID2OfSide2ToMerge)
3156 {
3157   initData();
3158
3159   SMESHDS_Mesh* aMesh = GetMeshDS();
3160
3161   const SMDS_MeshNode* aFirstNode1ToMerge  = aMesh->FindNode( NodeID1OfSide1ToMerge );
3162   const SMDS_MeshNode* aFirstNode2ToMerge  = aMesh->FindNode( NodeID1OfSide2ToMerge );
3163   const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
3164   const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
3165
3166   if (!aFirstNode1ToMerge ||
3167       !aFirstNode2ToMerge )
3168     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
3169   if (!aSecondNode1ToMerge||
3170       !aSecondNode2ToMerge)
3171     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
3172
3173   TIDSortedElemSet aSide1Elems, aSide2Elems;
3174   arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
3175   arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
3176
3177   TPythonDump() << "error = " << this << ".SewSideElements( "
3178                 << IDsOfSide1Elements << ", "
3179                 << IDsOfSide2Elements << ", "
3180                 << NodeID1OfSide1ToMerge << ", "
3181                 << NodeID1OfSide2ToMerge << ", "
3182                 << NodeID2OfSide1ToMerge << ", "
3183                 << NodeID2OfSide2ToMerge << ")";
3184
3185   ::SMESH_MeshEditor anEditor( myMesh );
3186   SMESH::SMESH_MeshEditor::Sew_Error error =
3187     convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
3188                                          aFirstNode1ToMerge,
3189                                          aFirstNode2ToMerge,
3190                                          aSecondNode1ToMerge,
3191                                          aSecondNode2ToMerge));
3192
3193   storeResult(anEditor);
3194
3195   return error;
3196 }
3197
3198 //================================================================================
3199 /*!
3200  * \brief Set new nodes for given element
3201   * \param ide - element id
3202   * \param newIDs - new node ids
3203   * \retval CORBA::Boolean - true if result is OK
3204  */
3205 //================================================================================
3206
3207 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
3208                                                    const SMESH::long_array& newIDs)
3209 {
3210   initData();
3211
3212   const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
3213   if(!elem) return false;
3214
3215   int nbn = newIDs.length();
3216   int i=0;
3217   vector<const SMDS_MeshNode*> aNodes(nbn);
3218   int nbn1=-1;
3219   for(; i<nbn; i++) {
3220     const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
3221     if(aNode) {
3222       nbn1++;
3223       aNodes[nbn1] = aNode;
3224     }
3225   }
3226   TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
3227                 << ide << ", " << newIDs << " )";
3228 #ifdef _DEBUG_
3229   TPythonDump() << "print 'ChangeElemNodes: ', isDone";
3230 #endif
3231
3232   return GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
3233 }
3234   
3235 //================================================================================
3236 /*!
3237  * \brief Update myLastCreated* or myPreviewData
3238   * \param anEditor - it contains last modification results
3239  */
3240 //================================================================================
3241
3242 void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& anEditor)
3243 {
3244   if ( myPreviewMode ) { // --- MeshPreviewStruct filling --- 
3245
3246     list<int> aNodesConnectivity;
3247     typedef map<int, int> TNodesMap;
3248     TNodesMap nodesMap;
3249
3250     TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
3251     SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
3252
3253     SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
3254     int nbEdges = aMeshDS->NbEdges();
3255     int nbFaces = aMeshDS->NbFaces();
3256     int nbVolum = aMeshDS->NbVolumes();
3257     switch ( previewType ) {
3258     case SMDSAbs_Edge  : nbFaces = nbVolum = 0; break;
3259     case SMDSAbs_Face  : nbEdges = nbVolum = 0; break;
3260     case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
3261     default:;
3262     }
3263     myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
3264     myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
3265     int i = 0, j = 0;
3266     SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
3267
3268     while ( itMeshElems->more() ) {
3269       const SMDS_MeshElement* aMeshElem = itMeshElems->next();
3270       if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
3271         continue;
3272
3273       SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
3274       while ( itElemNodes->more() ) {
3275         const SMDS_MeshNode* aMeshNode = 
3276           static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
3277         int aNodeID = aMeshNode->GetID();
3278         TNodesMap::iterator anIter = nodesMap.find(aNodeID);
3279         if ( anIter == nodesMap.end() ) {
3280           // filling the nodes coordinates
3281           myPreviewData->nodesXYZ[j].x = aMeshNode->X();
3282           myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
3283           myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
3284           anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
3285           j++;
3286         }
3287         aNodesConnectivity.push_back(anIter->second);
3288       }
3289
3290       // filling the elements types
3291       SMDSAbs_ElementType aType;
3292       bool isPoly;
3293       /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
3294         aType = SMDSAbs_Node;
3295         isPoly = false;
3296       }
3297       else*/ {
3298         aType = aMeshElem->GetType();
3299         isPoly = aMeshElem->IsPoly();
3300       }
3301
3302       myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
3303       myPreviewData->elementTypes[i].isPoly = isPoly;
3304       myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
3305       i++;
3306
3307     }
3308     myPreviewData->nodesXYZ.length( j );
3309
3310     // filling the elements connectivities
3311     list<int>::iterator aConnIter = aNodesConnectivity.begin();
3312     myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
3313     for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
3314       myPreviewData->elementConnectivities[i] = *aConnIter;
3315     
3316     return;
3317   }
3318
3319   {
3320     // add new nodes into myLastCreatedNodes
3321     const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
3322     myLastCreatedNodes->length(aSeq.Length());
3323     for(int i=0; i<aSeq.Length(); i++)
3324       myLastCreatedNodes[i] = aSeq.Value(i+1)->GetID();
3325   }
3326   {
3327     // add new elements into myLastCreatedElems
3328     const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
3329     myLastCreatedElems->length(aSeq.Length());
3330     for(int i=0; i<aSeq.Length(); i++)
3331       myLastCreatedElems[i] = aSeq.Value(i+1)->GetID();
3332   }
3333 }
3334
3335 //================================================================================
3336 /*!
3337  * Return data of mesh edition preview
3338  */
3339 //================================================================================
3340
3341 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
3342 {
3343   return myPreviewData._retn();
3344 }
3345
3346 //================================================================================
3347 /*!
3348  * \brief Returns list of it's IDs of created nodes
3349   * \retval SMESH::long_array* - list of node ID
3350  */
3351 //================================================================================
3352
3353 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
3354 {
3355   return myLastCreatedNodes._retn();
3356 }
3357
3358 //================================================================================
3359 /*!
3360  * \brief Returns list of it's IDs of created elements
3361   * \retval SMESH::long_array* - list of elements' ID
3362  */
3363 //================================================================================
3364
3365 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
3366 {
3367   return myLastCreatedElems._retn();
3368 }
3369
3370 //=======================================================================
3371 //function : ConvertToQuadratic
3372 //purpose  :
3373 //=======================================================================
3374
3375 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
3376 {
3377   ::SMESH_MeshEditor anEditor( myMesh );
3378   anEditor.ConvertToQuadratic(theForce3d);
3379   TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
3380 }
3381
3382 //=======================================================================
3383 //function : ConvertFromQuadratic
3384 //purpose  : 
3385 //=======================================================================
3386
3387 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
3388 {
3389   ::SMESH_MeshEditor anEditor( myMesh );
3390   CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
3391   TPythonDump() << this << ".ConvertFromQuadratic()";
3392   return isDone;
3393 }
3394
3395 //=======================================================================
3396 //function : makeMesh
3397 //purpose  : create a named imported mesh 
3398 //=======================================================================
3399
3400 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
3401 {
3402   SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
3403   SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
3404   SALOMEDS::Study_var study = gen->GetCurrentStudy();
3405   SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
3406   gen->SetName( meshSO, theMeshName, "Mesh" );
3407
3408   SALOMEDS::StudyBuilder_var builder = study->NewBuilder();
3409   SALOMEDS::GenericAttribute_var anAttr
3410     = builder->FindOrCreateAttribute( meshSO, "AttributePixMap" );
3411   SALOMEDS::AttributePixMap::_narrow( anAttr )->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" );
3412
3413   return mesh._retn();
3414 }