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