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