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