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