Salome HOME
PAL13460 (PAL EDF 301 force the mesh to go through a point)
[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
36 #include "SMESH_MeshEditor.hxx"
37
38 #include "SMESH_Gen_i.hxx"
39 #include "SMESH_Filter_i.hxx"
40 #include "SMESH_PythonDump.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 using namespace std;
63 using SMESH::TPythonDump;
64
65 //=============================================================================
66 /*!
67  * \brief Mesh to apply modifications for preview purposes
68  */
69 //=============================================================================
70
71 struct TPreviewMesh: public SMESH_Mesh
72 {
73   SMDSAbs_ElementType myPreviewType; // type to show
74
75   TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
76     _isShapeToMesh = _id =_studyId =_idDoc = 0;
77     _myMeshDS  = new SMESHDS_Mesh( _id, true );
78     myPreviewType = previewElements;
79   }
80   virtual ~TPreviewMesh() { delete _myMeshDS; }
81   //
82   void Copy( const SMESH::long_array & theIDsOfElements,
83              SMESH_Mesh&               theMesh,
84              TIDSortedElemSet&         theElements,
85              SMDSAbs_ElementType       theSelectType = SMDSAbs_All,
86              SMDSAbs_ElementType       theAvoidType = SMDSAbs_All)
87   {
88     SMESHDS_Mesh* aMeshDS = _myMeshDS;
89
90     // loop on theIDsOfElements
91     for ( int i=0; i<theIDsOfElements.length(); ++i )
92     {
93       const SMDS_MeshElement* anElem =
94         theMesh.GetMeshDS()->FindElement(theIDsOfElements[i]);
95       if ( !anElem ) continue;
96       SMDSAbs_ElementType type = anElem->GetType();
97       if ( type == theAvoidType ||
98            ( theSelectType != SMDSAbs_All && type != theSelectType ))
99         continue;
100
101       // copy element nodes
102       int anElemNbNodes = anElem->NbNodes();
103       vector< int > anElemNodesID( anElemNbNodes ) ;
104       SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
105       for ( int i = 0; itElemNodes->more(); i++)
106       {
107         const SMDS_MeshNode* anElemNode = 
108           static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
109         _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(), 
110                                  anElemNode->GetID());
111         anElemNodesID[i] = anElemNode->GetID();
112       }
113
114       // creates a corresponding element on copied nodes
115       const SMDS_MeshElement* anElemCopy = 0;
116       if ( anElem->IsPoly() && type == SMDSAbs_Volume )
117       {
118         const SMDS_PolyhedralVolumeOfNodes* ph =
119           dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem);
120         if ( ph )
121           anElemCopy = aMeshDS->AddPolyhedralVolumeWithID
122             (anElemNodesID, ph->GetQuanities(),anElem->GetID());
123       }
124       else {
125         anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
126                                                           type,
127                                                           anElem->IsPoly() );
128       }
129       if ( anElemCopy )
130         theElements.insert( anElemCopy );
131     }// loop on theElems
132   }
133
134 };// struct TPreviewMesh
135
136 //=============================================================================
137 /*!
138  *
139  */
140 //=============================================================================
141
142 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh* theMesh, bool isPreview)
143 {
144   _myMesh = theMesh;
145   myPreviewMode = isPreview;
146 }
147
148 //================================================================================
149 /*!
150  * \brief Destructor
151  */
152 //================================================================================
153
154 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
155 {
156 }
157
158 //================================================================================
159 /*!
160  * \brief Clear members
161  */
162 //================================================================================
163
164 void SMESH_MeshEditor_i::initData()
165 {
166   if ( myPreviewMode ) {
167     myPreviewData = new SMESH::MeshPreviewStruct();
168   }
169   else {
170     myLastCreatedElems = new SMESH::long_array();
171     myLastCreatedNodes = new SMESH::long_array();
172   }
173 }
174
175 //=============================================================================
176 /*!
177  *
178  */
179 //=============================================================================
180
181 CORBA::Boolean
182   SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
183 {
184   initData();
185
186   ::SMESH_MeshEditor anEditor( _myMesh );
187   list< int > IdList;
188
189   for (int i = 0; i < IDsOfElements.length(); i++)
190     IdList.push_back( IDsOfElements[i] );
191
192   // Update Python script
193   TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
194 #ifdef _DEBUG_
195   TPythonDump() << "print 'RemoveElements: ', isDone";
196 #endif
197   // Remove Elements
198   return anEditor.Remove( IdList, false );
199 }
200
201 //=============================================================================
202 /*!
203  *
204  */
205 //=============================================================================
206
207 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
208 {
209   initData();
210
211   ::SMESH_MeshEditor anEditor( _myMesh );
212   list< int > IdList;
213   for (int i = 0; i < IDsOfNodes.length(); i++)
214     IdList.push_back( IDsOfNodes[i] );
215
216   // Update Python script
217   TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
218 #ifdef _DEBUG_
219   TPythonDump() << "print 'RemoveNodes: ', isDone";
220 #endif
221
222   return anEditor.Remove( IdList, true );
223 }
224
225 //=============================================================================
226 /*!
227  *
228  */
229 //=============================================================================
230
231 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
232 {
233   initData();
234
235   int NbNodes = IDsOfNodes.length();
236   SMDS_MeshElement* elem = 0;
237   if (NbNodes == 2)
238   {
239     CORBA::Long index1 = IDsOfNodes[0];
240     CORBA::Long index2 = IDsOfNodes[1];
241     elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
242
243     // Update Python script
244     TPythonDump() << "edge = " << this << ".AddEdge([ "
245                   << index1 << ", " << index2 <<" ])";
246   }
247   if (NbNodes == 3) {
248     CORBA::Long n1 = IDsOfNodes[0];
249     CORBA::Long n2 = IDsOfNodes[1];
250     CORBA::Long n12 = IDsOfNodes[2];
251     elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
252                                 GetMeshDS()->FindNode(n2),
253                                 GetMeshDS()->FindNode(n12));
254     // Update Python script
255     TPythonDump() << "edgeID = " << this << ".AddEdge([ "
256                   <<n1<<", "<<n2<<", "<<n12<<" ])";
257   }
258
259   if(elem)
260     return elem->GetID();
261
262   return 0;
263 }
264
265 //=============================================================================
266 /*!
267  *
268  */
269 //=============================================================================
270
271 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
272                                         CORBA::Double y, CORBA::Double z)
273 {
274   initData();
275
276   const SMDS_MeshNode* N = GetMeshDS()->AddNode(x, y, z);
277
278   // Update Python script
279   TPythonDump() << "nodeID = " << this << ".AddNode( "
280                 << x << ", " << y << ", " << z << " )";
281
282   return N->GetID();
283 }
284
285 //=============================================================================
286 /*!
287  *  AddFace
288  */
289 //=============================================================================
290
291 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
292 {
293   initData();
294
295   int NbNodes = IDsOfNodes.length();
296   if (NbNodes < 3)
297   {
298     return false;
299   }
300
301   std::vector<const SMDS_MeshNode*> nodes (NbNodes);
302   for (int i = 0; i < NbNodes; i++)
303     nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
304
305   SMDS_MeshElement* elem = 0;
306   if (NbNodes == 3) {
307     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
308   }
309   else if (NbNodes == 4) {
310     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
311   }
312   else if (NbNodes == 6) {
313     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
314                                 nodes[4], nodes[5]);
315   }
316   else if (NbNodes == 8) {
317     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
318                                 nodes[4], nodes[5], nodes[6], nodes[7]);
319   }
320
321   // Update Python script
322   TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
323
324   if(elem)
325     return elem->GetID();
326
327   return 0;
328 }
329
330 //=============================================================================
331 /*!
332  *  AddPolygonalFace
333  */
334 //=============================================================================
335 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace
336                                    (const SMESH::long_array & IDsOfNodes)
337 {
338   initData();
339
340   int NbNodes = IDsOfNodes.length();
341   std::vector<const SMDS_MeshNode*> nodes (NbNodes);
342   for (int i = 0; i < NbNodes; i++)
343     nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
344
345   const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes);
346   
347   // Update Python script
348   TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
349 #ifdef _DEBUG_
350   TPythonDump() << "print 'AddPolygonalFace: ', faceID";
351 #endif
352
353   if(elem)
354     return elem->GetID();
355
356   return 0;
357 }
358
359 //=============================================================================
360 /*!
361  *
362  */
363 //=============================================================================
364
365 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
366 {
367   initData();
368
369   int NbNodes = IDsOfNodes.length();
370   vector< const SMDS_MeshNode*> n(NbNodes);
371   for(int i=0;i<NbNodes;i++)
372     n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
373
374   SMDS_MeshElement* elem = 0;
375   switch(NbNodes)
376   {
377   case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
378   case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
379   case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
380   case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
381   case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
382                                         n[6],n[7],n[8],n[9]);
383     break;
384   case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
385                                         n[7],n[8],n[9],n[10],n[11],n[12]);
386     break;
387   case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
388                                         n[9],n[10],n[11],n[12],n[13],n[14]);
389     break;
390   case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
391                                         n[8],n[9],n[10],n[11],n[12],n[13],n[14],
392                                         n[15],n[16],n[17],n[18],n[19]);
393     break;
394   }
395
396   // Update Python script
397   TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
398 #ifdef _DEBUG_
399   TPythonDump() << "print 'AddVolume: ', volID";
400 #endif
401
402   if(elem)
403     return elem->GetID();
404
405   return 0;
406 }
407
408 //=============================================================================
409 /*!
410  *  AddPolyhedralVolume
411  */
412 //=============================================================================
413 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume
414                                    (const SMESH::long_array & IDsOfNodes,
415                                     const SMESH::long_array & Quantities)
416 {
417   initData();
418
419   int NbNodes = IDsOfNodes.length();
420   std::vector<const SMDS_MeshNode*> n (NbNodes);
421   for (int i = 0; i < NbNodes; i++)
422     n[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
423
424   int NbFaces = Quantities.length();
425   std::vector<int> q (NbFaces);
426   for (int j = 0; j < NbFaces; j++)
427     q[j] = Quantities[j];
428
429   const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(n, q);
430
431   // Update Python script
432   TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
433                 << IDsOfNodes << ", " << Quantities << " )";
434 #ifdef _DEBUG_
435   TPythonDump() << "print 'AddPolyhedralVolume: ', volID";
436 #endif
437
438   if(elem)
439     return elem->GetID();
440
441   return 0;
442 }
443
444 //=============================================================================
445 /*!
446  *  AddPolyhedralVolumeByFaces
447  */
448 //=============================================================================
449 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces
450                                    (const SMESH::long_array & IdsOfFaces)
451 {
452   initData();
453
454   int NbFaces = IdsOfFaces.length();
455   std::vector<const SMDS_MeshNode*> poly_nodes;
456   std::vector<int> quantities (NbFaces);
457
458   for (int i = 0; i < NbFaces; i++) {
459     const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]);
460     quantities[i] = aFace->NbNodes();
461
462     SMDS_ElemIteratorPtr It = aFace->nodesIterator();
463     while (It->more()) {
464       poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
465     }
466   }
467
468   const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
469
470   // Update Python script
471   TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
472                 << IdsOfFaces << " )";
473 #ifdef _DEBUG_
474   TPythonDump() << "print 'AddPolyhedralVolume: ', volID";
475 #endif
476
477   if(elem)
478     return elem->GetID();
479
480   return 0;
481 }
482
483 //=============================================================================
484 /*!
485  *
486  */
487 //=============================================================================
488
489 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
490                                             CORBA::Double x,
491                                             CORBA::Double y,
492                                             CORBA::Double z)
493 {
494   initData();
495
496   const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
497   if ( !node )
498     return false;
499
500   GetMeshDS()->MoveNode(node, x, y, z);
501
502   // Update Python script
503   TPythonDump() << "isDone = " << this << ".MoveNode( "
504                 << NodeID << ", " << x << ", " << y << ", " << z << " )";
505
506   return true;
507 }
508
509 //=============================================================================
510 /*!
511  *
512  */
513 //=============================================================================
514
515 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
516                                                CORBA::Long NodeID2)
517 {
518   initData();
519
520   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
521   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
522   if ( !n1 || !n2 )
523     return false;
524
525   // Update Python script
526   TPythonDump() << "isDone = " << this << ".InverseDiag( "
527                 << NodeID1 << ", " << NodeID2 << " )";
528
529   ::SMESH_MeshEditor aMeshEditor( _myMesh );
530   return aMeshEditor.InverseDiag ( n1, n2 );
531 }
532
533 //=============================================================================
534 /*!
535  *
536  */
537 //=============================================================================
538
539 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
540                                               CORBA::Long NodeID2)
541 {
542   initData();
543
544   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
545   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
546   if ( !n1 || !n2 )
547     return false;
548
549   // Update Python script
550   TPythonDump() << "isDone = " << this << ".DeleteDiag( "
551                 << NodeID1 << ", " << NodeID2 <<  " )";
552
553   ::SMESH_MeshEditor aMeshEditor( _myMesh );
554
555   bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
556
557   StoreResult(aMeshEditor);
558
559   return stat;
560 }
561
562 //=============================================================================
563 /*!
564  *
565  */
566 //=============================================================================
567
568 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
569 {
570   initData();
571
572   ::SMESH_MeshEditor anEditor( _myMesh );
573   for (int i = 0; i < IDsOfElements.length(); i++)
574   {
575     CORBA::Long index = IDsOfElements[i];
576     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
577     if ( elem )
578       anEditor.Reorient( elem );
579   }
580   // Update Python script
581   TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
582
583   return true;
584 }
585
586
587 //=============================================================================
588 /*!
589  *
590  */
591 //=============================================================================
592
593 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
594 {
595   initData();
596
597   SMESH::long_array_var anElementsId = theObject->GetIDs();
598   CORBA::Boolean isDone = Reorient(anElementsId);
599
600   // Clear python line, created by Reorient()
601   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
602   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
603
604   // Update Python script
605   TPythonDump() << "isDone = " << this << ".ReorientObject( " << theObject << " )";
606
607   return isDone;
608 }
609
610 namespace
611 {
612   //================================================================================
613   /*!
614    * \brief function for conversion long_array to TIDSortedElemSet
615     * \param IDs - array of IDs
616     * \param aMesh - mesh
617     * \param aMap - collection to fill
618     * \param aType - element type
619    */
620   //================================================================================
621
622   void ToMap(const SMESH::long_array & IDs,
623              const SMESHDS_Mesh*       aMesh,
624              TIDSortedElemSet&         aMap,
625              const SMDSAbs_ElementType aType = SMDSAbs_All )
626   { 
627     for (int i=0; i<IDs.length(); i++) {
628       CORBA::Long ind = IDs[i];
629       const SMDS_MeshElement * elem = aMesh->FindElement(ind);
630       if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
631         aMap.insert( elem );
632     }
633   }
634 }
635
636 //=============================================================================
637 /*!
638  *
639  */
640 //=============================================================================
641 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfElements,
642                                               SMESH::NumericalFunctor_ptr Criterion,
643                                               CORBA::Double               MaxAngle)
644 {
645   initData();
646
647   SMESHDS_Mesh* aMesh = GetMeshDS();
648   TIDSortedElemSet faces;
649   ToMap(IDsOfElements, aMesh, faces, SMDSAbs_Face);
650
651   SMESH::NumericalFunctor_i* aNumericalFunctor =
652     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
653   SMESH::Controls::NumericalFunctorPtr aCrit;
654   if ( !aNumericalFunctor )
655     aCrit.reset( new SMESH::Controls::AspectRatio() );
656   else
657     aCrit = aNumericalFunctor->GetNumericalFunctor();
658
659   // Update Python script
660   TPythonDump() << "isDone = " << this << ".TriToQuad( "
661                 << IDsOfElements << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
662 #ifdef _DEBUG_
663   TPythonDump() << "print 'TriToQuad: ', isDone";
664 #endif
665
666   ::SMESH_MeshEditor anEditor( _myMesh );
667
668   bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
669
670   StoreResult(anEditor);
671
672   return stat;
673 }
674
675
676 //=============================================================================
677 /*!
678  *
679  */
680 //=============================================================================
681 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr   theObject,
682                                                     SMESH::NumericalFunctor_ptr Criterion,
683                                                     CORBA::Double               MaxAngle)
684 {
685   initData();
686
687   SMESH::long_array_var anElementsId = theObject->GetIDs();
688   CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
689
690   // Clear python line(s), created by TriToQuad()
691   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
692   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
693 #ifdef _DEBUG_
694   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
695 #endif
696
697   SMESH::NumericalFunctor_i* aNumericalFunctor =
698     SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
699
700   // Update Python script
701   TPythonDump() << "isDone = " << this << ".TriToQuadObject("
702                 << theObject << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
703 #ifdef _DEBUG_
704   TPythonDump() << "print 'TriToQuadObject: ', isDone";
705 #endif
706
707   return isDone;
708 }
709
710
711 //=============================================================================
712 /*!
713  *
714  */
715 //=============================================================================
716 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array &   IDsOfElements,
717                                               SMESH::NumericalFunctor_ptr Criterion)
718 {
719   initData();
720
721   SMESHDS_Mesh* aMesh = GetMeshDS();
722   TIDSortedElemSet faces;
723   ToMap(IDsOfElements, aMesh, faces, SMDSAbs_Face);
724
725   SMESH::NumericalFunctor_i* aNumericalFunctor =
726     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
727   SMESH::Controls::NumericalFunctorPtr aCrit;
728   if ( !aNumericalFunctor )
729     aCrit.reset( new SMESH::Controls::AspectRatio() );
730   else
731     aCrit = aNumericalFunctor->GetNumericalFunctor();
732
733
734   // Update Python script
735   TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
736 #ifdef _DEBUG_
737   TPythonDump() << "print 'QuadToTri: ', isDone";
738 #endif
739
740   ::SMESH_MeshEditor anEditor( _myMesh );
741   CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
742
743   StoreResult(anEditor);
744
745   return stat;
746 }
747
748
749 //=============================================================================
750 /*!
751  *
752  */
753 //=============================================================================
754 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr   theObject,
755                                                     SMESH::NumericalFunctor_ptr Criterion)
756 {
757   initData();
758
759   SMESH::long_array_var anElementsId = theObject->GetIDs();
760   CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
761
762   // Clear python line(s), created by QuadToTri()
763   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
764   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
765 #ifdef _DEBUG_
766   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
767 #endif
768
769   SMESH::NumericalFunctor_i* aNumericalFunctor =
770     SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
771
772   // Update Python script
773   TPythonDump() << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
774 #ifdef _DEBUG_
775   TPythonDump() << "print 'QuadToTriObject: ', isDone";
776 #endif
777
778   return isDone;
779 }
780
781
782 //=============================================================================
783 /*!
784  *
785  */
786 //=============================================================================
787 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
788                                               CORBA::Boolean            Diag13)
789 {
790   initData();
791
792   SMESHDS_Mesh* aMesh = GetMeshDS();
793   TIDSortedElemSet faces;
794   ToMap(IDsOfElements, aMesh, faces, SMDSAbs_Face);
795
796   // Update Python script
797   TPythonDump() << "isDone = " << this << ".SplitQuad( "
798                 << IDsOfElements << ", " << Diag13 << " )";
799 #ifdef _DEBUG_
800   TPythonDump() << "print 'SplitQuad: ', isDone";
801 #endif
802
803   ::SMESH_MeshEditor anEditor( _myMesh );
804   CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
805
806   StoreResult(anEditor);
807
808   return stat;
809 }
810
811
812 //=============================================================================
813 /*!
814  *
815  */
816 //=============================================================================
817 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
818                                                     CORBA::Boolean            Diag13)
819 {
820   initData();
821
822   SMESH::long_array_var anElementsId = theObject->GetIDs();
823   CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
824
825   // Clear python line(s), created by SplitQuad()
826   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
827   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
828 #ifdef _DEBUG_
829   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
830 #endif
831
832   // Update Python script
833   TPythonDump() << "isDone = " << this << ".SplitQuadObject( "
834                 << theObject << ", " << Diag13 << " )";
835 #ifdef _DEBUG_
836   TPythonDump() << "print 'SplitQuadObject: ', isDone";
837 #endif
838
839   return isDone;
840 }
841
842
843 //=============================================================================
844 /*!
845  *  BestSplit
846  */
847 //=============================================================================
848 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long                 IDOfQuad,
849                                            SMESH::NumericalFunctor_ptr Criterion)
850 {
851   const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
852   if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
853   {
854     SMESH::NumericalFunctor_i* aNumericalFunctor =
855       dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
856     SMESH::Controls::NumericalFunctorPtr aCrit;
857     if (aNumericalFunctor)
858       aCrit = aNumericalFunctor->GetNumericalFunctor();
859     else
860       aCrit.reset(new SMESH::Controls::AspectRatio());
861
862     ::SMESH_MeshEditor anEditor (_myMesh);
863     return anEditor.BestSplit(quad, aCrit);
864   }
865   return -1;
866 }
867
868
869 //=======================================================================
870 //function : Smooth
871 //purpose  :
872 //=======================================================================
873
874 CORBA::Boolean
875   SMESH_MeshEditor_i::Smooth(const SMESH::long_array &              IDsOfElements,
876                              const SMESH::long_array &              IDsOfFixedNodes,
877                              CORBA::Long                            MaxNbOfIterations,
878                              CORBA::Double                          MaxAspectRatio,
879                              SMESH::SMESH_MeshEditor::Smooth_Method Method)
880 {
881   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
882                 MaxAspectRatio, Method, false );
883 }
884
885
886 //=======================================================================
887 //function : SmoothParametric
888 //purpose  :
889 //=======================================================================
890
891 CORBA::Boolean
892   SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array &              IDsOfElements,
893                                        const SMESH::long_array &              IDsOfFixedNodes,
894                                        CORBA::Long                            MaxNbOfIterations,
895                                        CORBA::Double                          MaxAspectRatio,
896                                        SMESH::SMESH_MeshEditor::Smooth_Method Method)
897 {
898   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
899                 MaxAspectRatio, Method, true );
900 }
901
902
903 //=======================================================================
904 //function : SmoothObject
905 //purpose  :
906 //=======================================================================
907
908 CORBA::Boolean
909   SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr              theObject,
910                                    const SMESH::long_array &              IDsOfFixedNodes,
911                                    CORBA::Long                            MaxNbOfIterations,
912                                    CORBA::Double                          MaxAspectRatio,
913                                    SMESH::SMESH_MeshEditor::Smooth_Method Method)
914 {
915   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
916                        MaxAspectRatio, Method, false);
917 }
918
919
920 //=======================================================================
921 //function : SmoothParametricObject
922 //purpose  :
923 //=======================================================================
924
925 CORBA::Boolean
926   SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr              theObject,
927                                    const SMESH::long_array &              IDsOfFixedNodes,
928                                    CORBA::Long                            MaxNbOfIterations,
929                                    CORBA::Double                          MaxAspectRatio,
930                                    SMESH::SMESH_MeshEditor::Smooth_Method Method)
931 {
932   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
933                        MaxAspectRatio, Method, true);
934 }
935
936
937 //=============================================================================
938 /*!
939  *
940  */
941 //=============================================================================
942
943 CORBA::Boolean
944   SMESH_MeshEditor_i::smooth(const SMESH::long_array &              IDsOfElements,
945                              const SMESH::long_array &              IDsOfFixedNodes,
946                              CORBA::Long                            MaxNbOfIterations,
947                              CORBA::Double                          MaxAspectRatio,
948                              SMESH::SMESH_MeshEditor::Smooth_Method Method,
949                              bool                                   IsParametric)
950 {
951   initData();
952
953   SMESHDS_Mesh* aMesh = GetMeshDS();
954
955   TIDSortedElemSet elements;
956   ToMap(IDsOfElements, aMesh, elements, SMDSAbs_Face);
957
958   set<const SMDS_MeshNode*> fixedNodes;
959   for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
960     CORBA::Long index = IDsOfFixedNodes[i];
961     const SMDS_MeshNode * node = aMesh->FindNode(index);
962     if ( node )
963       fixedNodes.insert( node );
964   }
965   ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
966   if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
967     method = ::SMESH_MeshEditor::CENTROIDAL;
968
969   ::SMESH_MeshEditor anEditor( _myMesh );
970   anEditor.Smooth(elements, fixedNodes, method,
971                   MaxNbOfIterations, MaxAspectRatio, IsParametric );
972
973   StoreResult(anEditor);
974
975   // Update Python script
976   TPythonDump() << "isDone = " << this << "."
977                 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
978                 << IDsOfElements << ", "     << IDsOfFixedNodes << ", "
979                 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
980                 << "SMESH.SMESH_MeshEditor."
981                 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
982                      "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
983 #ifdef _DEBUG_
984   TPythonDump() << "print 'Smooth: ', isDone";
985 #endif
986
987   return true;
988 }
989
990
991 //=============================================================================
992 /*!
993  *
994  */
995 //=============================================================================
996
997 CORBA::Boolean
998 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr              theObject,
999                                  const SMESH::long_array &              IDsOfFixedNodes,
1000                                  CORBA::Long                            MaxNbOfIterations,
1001                                  CORBA::Double                          MaxAspectRatio,
1002                                  SMESH::SMESH_MeshEditor::Smooth_Method Method,
1003                                  bool                                   IsParametric)
1004 {
1005   initData();
1006
1007   SMESH::long_array_var anElementsId = theObject->GetIDs();
1008   CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1009                                   MaxAspectRatio, Method, IsParametric);
1010
1011   // Clear python line(s), created by Smooth()
1012   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1013   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1014 #ifdef _DEBUG_
1015   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1016 #endif
1017
1018   // Update Python script
1019   TPythonDump() << "isDone = " << this << "."
1020                 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1021                 << theObject << ", " << IDsOfFixedNodes << ", "
1022                 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1023                 << "SMESH.SMESH_MeshEditor."
1024                 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1025                      "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1026 #ifdef _DEBUG_
1027   TPythonDump() << "print 'SmoothObject: ', isDone";
1028 #endif
1029
1030   return isDone;
1031 }
1032
1033
1034 //=============================================================================
1035 /*!
1036  *
1037  */
1038 //=============================================================================
1039
1040 void SMESH_MeshEditor_i::RenumberNodes()
1041 {
1042   // Update Python script
1043   TPythonDump() << this << ".RenumberNodes()";
1044
1045   GetMeshDS()->Renumber( true );
1046 }
1047
1048
1049 //=============================================================================
1050 /*!
1051  *
1052  */
1053 //=============================================================================
1054
1055 void SMESH_MeshEditor_i::RenumberElements()
1056 {
1057   // Update Python script
1058   TPythonDump() << this << ".RenumberElements()";
1059
1060   GetMeshDS()->Renumber( false );
1061 }
1062
1063
1064 //=======================================================================
1065 //function : RotationSweep
1066 //purpose  :
1067 //=======================================================================
1068
1069 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
1070                                        const SMESH::AxisStruct & theAxis,
1071                                        CORBA::Double             theAngleInRadians,
1072                                        CORBA::Long               theNbOfSteps,
1073                                        CORBA::Double             theTolerance)
1074 {
1075   initData();
1076
1077   TIDSortedElemSet elements;
1078   TPreviewMesh     tmpMesh( SMDSAbs_Face );
1079   SMESH_Mesh*      mesh = 0;
1080   bool             makeWalls=true;
1081   if ( myPreviewMode )
1082   {
1083     SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1084     tmpMesh.Copy( theIDsOfElements, *_myMesh, elements, select, avoid );
1085     mesh = &tmpMesh;
1086     //makeWalls = false;
1087   }
1088   else
1089   {
1090     ToMap(theIDsOfElements, GetMeshDS(), elements);
1091     mesh = _myMesh;
1092   }
1093
1094   gp_Ax1 Ax1 (gp_Pnt( theAxis.x,  theAxis.y,  theAxis.z ),
1095               gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
1096
1097   ::SMESH_MeshEditor anEditor( mesh );
1098   anEditor.RotationSweep (elements, Ax1, theAngleInRadians,
1099                           theNbOfSteps, theTolerance, makeWalls);
1100
1101   StoreResult(anEditor);
1102
1103   if ( !myPreviewMode ) {
1104     // Update Python script
1105     TPythonDump() << "axis = " << theAxis;
1106     TPythonDump() << this << ".RotationSweep( "
1107                   << theIDsOfElements
1108                   << ", axis, "
1109                   << theAngleInRadians << ", "
1110                   << theNbOfSteps << ", "
1111                   << theTolerance << " )";
1112   }
1113 }
1114
1115 //=======================================================================
1116 //function : RotationSweepObject
1117 //purpose  :
1118 //=======================================================================
1119
1120 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1121                                              const SMESH::AxisStruct & theAxis,
1122                                              CORBA::Double             theAngleInRadians,
1123                                              CORBA::Long               theNbOfSteps,
1124                                              CORBA::Double             theTolerance)
1125 {
1126   initData();
1127
1128   SMESH::long_array_var anElementsId = theObject->GetIDs();
1129   RotationSweep(anElementsId, theAxis, theAngleInRadians, theNbOfSteps, theTolerance);
1130
1131   // Clear python line, created by RotationSweep()
1132   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1133   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1134
1135   // Update Python script
1136   TPythonDump() << this << ".RotationSweepObject( "
1137                 << theObject
1138                 << ", axis, "
1139                 << theAngleInRadians << ", "
1140                 << theNbOfSteps << ", "
1141                 << theTolerance << " )";
1142 }
1143
1144 //=======================================================================
1145 //function : ExtrusionSweep
1146 //purpose  :
1147 //=======================================================================
1148
1149 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
1150                                         const SMESH::DirStruct &  theStepVector,
1151                                         CORBA::Long               theNbOfSteps)
1152 {
1153   initData();
1154
1155 #ifdef NO_CAS_CATCH
1156   try {   
1157     OCC_CATCH_SIGNALS;
1158 #else
1159   CASCatch_TRY {
1160 #endif
1161     SMESHDS_Mesh* aMesh = GetMeshDS();
1162
1163     TIDSortedElemSet elements;
1164     ToMap(theIDsOfElements, aMesh, elements);
1165
1166     const SMESH::PointStruct * P = &theStepVector.PS;
1167     gp_Vec stepVec( P->x, P->y, P->z );
1168
1169     TElemOfElemListMap aHystory;
1170     ::SMESH_MeshEditor anEditor( _myMesh );
1171     anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory);
1172
1173     StoreResult(anEditor);
1174
1175     // Update Python script
1176     TPythonDump() << "stepVector = " << theStepVector;
1177     TPythonDump() << this << ".ExtrusionSweep( "
1178                   << theIDsOfElements << ", stepVector, " << theNbOfSteps << " )";
1179
1180 #ifdef NO_CAS_CATCH
1181   } catch(Standard_Failure) {
1182 #else
1183   } CASCatch_CATCH(Standard_Failure) {
1184 #endif
1185     Handle(Standard_Failure) aFail = Standard_Failure::Caught();          
1186     INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
1187   }
1188 }
1189
1190
1191 //=======================================================================
1192 //function : ExtrusionSweepObject
1193 //purpose  :
1194 //=======================================================================
1195
1196 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1197                                               const SMESH::DirStruct &  theStepVector,
1198                                               CORBA::Long               theNbOfSteps)
1199 {
1200   initData();
1201
1202   SMESH::long_array_var anElementsId = theObject->GetIDs();
1203   ExtrusionSweep(anElementsId, theStepVector, theNbOfSteps);
1204
1205   // Clear python line, created by ExtrusionSweep()
1206   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1207   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1208
1209   // Update Python script
1210   TPythonDump() << this << ".ExtrusionSweepObject( "
1211                 << theObject << ", stepVector, " << theNbOfSteps << " )";
1212 }
1213
1214 //=======================================================================
1215 //function : ExtrusionSweepObject1D
1216 //purpose  :
1217 //=======================================================================
1218
1219 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1220                                                 const SMESH::DirStruct &  theStepVector,
1221                                                 CORBA::Long               theNbOfSteps)
1222 {
1223   initData();
1224
1225   SMESHDS_Mesh* aMesh = GetMeshDS();
1226
1227   SMESH::long_array_var allElementsId = theObject->GetIDs();
1228
1229   TIDSortedElemSet elements;
1230   ToMap(allElementsId, aMesh, elements);
1231
1232   const SMESH::PointStruct * P = &theStepVector.PS;
1233   gp_Vec stepVec( P->x, P->y, P->z );
1234
1235   ::SMESH_MeshEditor anEditor( _myMesh );
1236   //anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps);
1237   TElemOfElemListMap aHystory;
1238   anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory);
1239
1240   StoreResult(anEditor);
1241
1242   // Update Python script
1243   TPythonDump() << "stepVector = " << theStepVector;
1244   TPythonDump() << this << ".ExtrusionSweepObject1D( "
1245                 << theObject << ", stepVector, " << theNbOfSteps << " )";
1246 }
1247
1248 //=======================================================================
1249 //function : ExtrusionSweepObject2D
1250 //purpose  :
1251 //=======================================================================
1252
1253 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1254                                                 const SMESH::DirStruct &  theStepVector,
1255                                                 CORBA::Long               theNbOfSteps)
1256 {
1257   initData();
1258
1259   SMESHDS_Mesh* aMesh = GetMeshDS();
1260
1261   SMESH::long_array_var allElementsId = theObject->GetIDs();
1262
1263   TIDSortedElemSet elements;
1264   ToMap(allElementsId, aMesh, elements);
1265
1266   const SMESH::PointStruct * P = &theStepVector.PS;
1267   gp_Vec stepVec( P->x, P->y, P->z );
1268
1269   ::SMESH_MeshEditor anEditor( _myMesh );
1270   //anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps);
1271   TElemOfElemListMap aHystory;
1272   anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory);
1273
1274   StoreResult(anEditor);
1275
1276   // Update Python script
1277   TPythonDump() << "stepVector = " << theStepVector;
1278   TPythonDump() << this << ".ExtrusionSweepObject2D( "
1279                 << theObject << ", stepVector, " << theNbOfSteps << " )";
1280 }
1281
1282
1283 //=======================================================================
1284 //function : AdvancedExtrusion
1285 //purpose  :
1286 //=======================================================================
1287
1288 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
1289                                            const SMESH::DirStruct &  theStepVector,
1290                                            CORBA::Long               theNbOfSteps,
1291                                            CORBA::Long               theExtrFlags,
1292                                            CORBA::Double             theSewTolerance)
1293 {
1294   initData();
1295
1296   SMESHDS_Mesh* aMesh = GetMeshDS();
1297
1298   TIDSortedElemSet elements;
1299   ToMap(theIDsOfElements, aMesh, elements);
1300
1301   const SMESH::PointStruct * P = &theStepVector.PS;
1302   gp_Vec stepVec( P->x, P->y, P->z );
1303
1304   ::SMESH_MeshEditor anEditor( _myMesh );
1305   TElemOfElemListMap aHystory;
1306   anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
1307                            theExtrFlags, theSewTolerance);
1308
1309   StoreResult(anEditor);
1310
1311   // Update Python script
1312   TPythonDump() << "stepVector = " << theStepVector;
1313   TPythonDump() << this << ".AdvancedExtrusion("
1314                 << theIDsOfElements
1315                 << ", stepVector, "
1316                 << theNbOfSteps << ","
1317                 << theExtrFlags << ", "
1318                 << theSewTolerance <<  " )";
1319 }
1320
1321
1322 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
1323
1324 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
1325 {
1326   switch ( e ) {
1327   RETCASE( EXTR_OK );
1328   RETCASE( EXTR_NO_ELEMENTS );
1329   RETCASE( EXTR_PATH_NOT_EDGE );
1330   RETCASE( EXTR_BAD_PATH_SHAPE );
1331   RETCASE( EXTR_BAD_STARTING_NODE );
1332   RETCASE( EXTR_BAD_ANGLES_NUMBER );
1333   RETCASE( EXTR_CANT_GET_TANGENT );
1334   }
1335   return SMESH::SMESH_MeshEditor::EXTR_OK;
1336 }
1337
1338 //=======================================================================
1339 //function : ExtrusionAlongPath
1340 //purpose  :
1341 //=======================================================================
1342
1343 SMESH::SMESH_MeshEditor::Extrusion_Error
1344   SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
1345                                          SMESH::SMESH_Mesh_ptr       thePathMesh,
1346                                          GEOM::GEOM_Object_ptr       thePathShape,
1347                                          CORBA::Long                 theNodeStart,
1348                                          CORBA::Boolean              theHasAngles,
1349                                          const SMESH::double_array & theAngles,
1350                                          CORBA::Boolean              theHasRefPoint,
1351                                          const SMESH::PointStruct &  theRefPoint)
1352 {
1353   initData();
1354
1355   SMESHDS_Mesh*  aMesh = GetMeshDS();
1356
1357   if ( thePathMesh->_is_nil() || thePathShape->_is_nil() )
1358     return SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
1359
1360   SMESH_Mesh_i* aMeshImp = dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( thePathMesh ).in() );
1361   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
1362   SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
1363
1364   if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
1365     return SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
1366
1367   SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
1368   if ( !nodeStart )
1369     return SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
1370
1371   TIDSortedElemSet elements;
1372   ToMap(theIDsOfElements, aMesh, elements);
1373
1374   list<double> angles;
1375   for (int i = 0; i < theAngles.length(); i++) {
1376     angles.push_back( theAngles[i] );
1377   }
1378
1379   gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
1380
1381   // Update Python script
1382   TPythonDump() << "rotAngles = " << theAngles;
1383
1384   if ( theHasRefPoint )
1385     TPythonDump() << "refPoint = SMESH.PointStruct( "
1386                   << refPnt.X() << ", "
1387                   << refPnt.Y() << ", "
1388                   << refPnt.Z() << " )";
1389   else
1390     TPythonDump() << "refPoint = SMESH.PointStruct( 0,0,0 )";
1391
1392   TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
1393                 << theIDsOfElements << ", "
1394                 << thePathMesh      << ", "
1395                 << thePathShape     << ", "
1396                 << theNodeStart     << ", "
1397                 << theHasAngles     << ", "
1398                 << "rotAngles"      << ", "
1399                 << theHasRefPoint   << ", refPoint )";
1400
1401   ::SMESH_MeshEditor anEditor( _myMesh );
1402   SMESH::SMESH_MeshEditor::Extrusion_Error error = 
1403     convExtrError( anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
1404                                                 theHasAngles, angles,
1405                                                 theHasRefPoint, refPnt ) );
1406
1407   StoreResult(anEditor);
1408
1409   return error;
1410 }
1411
1412 //=======================================================================
1413 //function : ExtrusionAlongPathObject
1414 //purpose  :
1415 //=======================================================================
1416
1417 SMESH::SMESH_MeshEditor::Extrusion_Error
1418 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObject,
1419                                              SMESH::SMESH_Mesh_ptr       thePathMesh,
1420                                              GEOM::GEOM_Object_ptr       thePathShape,
1421                                              CORBA::Long                 theNodeStart,
1422                                              CORBA::Boolean              theHasAngles,
1423                                              const SMESH::double_array & theAngles,
1424                                              CORBA::Boolean              theHasRefPoint,
1425                                              const SMESH::PointStruct &  theRefPoint)
1426 {
1427   initData();
1428
1429   SMESH::long_array_var anElementsId = theObject->GetIDs();
1430   SMESH::SMESH_MeshEditor::Extrusion_Error error = ExtrusionAlongPath
1431     (anElementsId, thePathMesh, thePathShape, theNodeStart,
1432      theHasAngles, theAngles, theHasRefPoint, theRefPoint);
1433
1434   // Clear python line, created by ExtrusionAlongPath()
1435   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1436   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1437
1438   // Update Python script
1439   TPythonDump() << "rotAngles = " << theAngles;
1440   TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
1441                 << theObject    << ", "
1442                 << thePathMesh  << ", "
1443                 << thePathShape << ", "
1444                 << theNodeStart << ", "
1445                 << theHasAngles << ", "
1446                 << "rotAngles"     << ", "
1447                 << theHasRefPoint<<", refPoint )";
1448
1449   return error;
1450 }
1451
1452 //================================================================================
1453 /*!
1454  * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
1455  * of given angles along path steps
1456   * \param PathMesh mesh containing a 1D sub-mesh on the edge, along 
1457   *                which proceeds the extrusion
1458   * \param PathShape is shape(edge); as the mesh can be complex, the edge 
1459   *                 is used to define the sub-mesh for the path
1460  */
1461 //================================================================================
1462
1463 SMESH::double_array*
1464 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr       thePathMesh,
1465                                           GEOM::GEOM_Object_ptr       thePathShape,
1466                                           const SMESH::double_array & theAngles)
1467 {
1468   SMESH::double_array_var aResult = new SMESH::double_array();
1469   return aResult._retn();
1470 }
1471
1472 //=======================================================================
1473 //function : Mirror
1474 //purpose  :
1475 //=======================================================================
1476
1477 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElements,
1478                                 const SMESH::AxisStruct &           theAxis,
1479                                 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
1480                                 CORBA::Boolean                      theCopy)
1481 {
1482   initData();
1483
1484   SMESHDS_Mesh* aMesh = GetMeshDS();
1485
1486   TIDSortedElemSet elements;
1487   ToMap(theIDsOfElements, aMesh, elements);
1488
1489   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
1490   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
1491
1492   gp_Trsf aTrsf;
1493   TCollection_AsciiString typeStr;
1494   switch ( theMirrorType ) {
1495   case  SMESH::SMESH_MeshEditor::POINT:
1496     aTrsf.SetMirror( P );
1497     typeStr = "SMESH.SMESH_MeshEditor.POINT";
1498     break;
1499   case  SMESH::SMESH_MeshEditor::AXIS:
1500     aTrsf.SetMirror( gp_Ax1( P, V ));
1501     typeStr = "SMESH.SMESH_MeshEditor.AXIS";
1502     break;
1503   default:
1504     aTrsf.SetMirror( gp_Ax2( P, V ));
1505     typeStr = "SMESH.SMESH_MeshEditor.PLANE";
1506   }
1507
1508   // Update Python script
1509   TPythonDump() << this << ".Mirror( "
1510                 << theIDsOfElements << ", "
1511                 << theAxis           << ", "
1512                 << typeStr           << ", "
1513                 << theCopy           << " )";
1514
1515   ::SMESH_MeshEditor anEditor( _myMesh );
1516   anEditor.Transform (elements, aTrsf, theCopy);
1517
1518   if(theCopy) {
1519     StoreResult(anEditor);
1520   }
1521 }
1522
1523
1524 //=======================================================================
1525 //function : MirrorObject
1526 //purpose  :
1527 //=======================================================================
1528
1529 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr           theObject,
1530                                       const SMESH::AxisStruct &           theAxis,
1531                                       SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
1532                                       CORBA::Boolean                      theCopy)
1533 {
1534   initData();
1535
1536   SMESH::long_array_var anElementsId = theObject->GetIDs();
1537   Mirror(anElementsId, theAxis, theMirrorType, theCopy);
1538
1539   // Clear python line, created by Mirror()
1540   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1541   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1542
1543   // Update Python script
1544   TCollection_AsciiString typeStr;
1545   switch ( theMirrorType ) {
1546   case  SMESH::SMESH_MeshEditor::POINT:
1547     typeStr = "SMESH.SMESH_MeshEditor.POINT";
1548     break;
1549   case  SMESH::SMESH_MeshEditor::AXIS:
1550     typeStr = "SMESH.SMESH_MeshEditor.AXIS";
1551     break;
1552   default:
1553     typeStr = "SMESH.SMESH_MeshEditor.PLANE";
1554   }
1555   TPythonDump() << "axis = " << theAxis;
1556   TPythonDump() << this << ".MirrorObject( "
1557                 << theObject << ", "
1558                 << "axis, "
1559                 << typeStr << ", "
1560                 << theCopy << " )";
1561 }
1562
1563 //=======================================================================
1564 //function : Translate
1565 //purpose  :
1566 //=======================================================================
1567
1568 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
1569                                    const SMESH::DirStruct &  theVector,
1570                                    CORBA::Boolean            theCopy)
1571 {
1572   initData();
1573
1574   SMESHDS_Mesh* aMesh = GetMeshDS();
1575
1576   TIDSortedElemSet elements;
1577   ToMap(theIDsOfElements, aMesh, elements);
1578
1579   gp_Trsf aTrsf;
1580   const SMESH::PointStruct * P = &theVector.PS;
1581   aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
1582
1583   ::SMESH_MeshEditor anEditor( _myMesh );
1584   anEditor.Transform (elements, aTrsf, theCopy);
1585
1586   if(theCopy) {
1587     StoreResult(anEditor);
1588   }
1589
1590   // Update Python script
1591   TPythonDump() << "vector = " << theVector;
1592   TPythonDump() << this << ".Translate( "
1593                 << theIDsOfElements
1594                 << ", vector, "
1595                 << theCopy << " )";
1596 }
1597
1598 //=======================================================================
1599 //function : TranslateObject
1600 //purpose  :
1601 //=======================================================================
1602
1603 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
1604                                          const SMESH::DirStruct &  theVector,
1605                                          CORBA::Boolean            theCopy)
1606 {
1607   initData();
1608
1609   SMESH::long_array_var anElementsId = theObject->GetIDs();
1610   Translate(anElementsId, theVector, theCopy);
1611
1612   // Clear python line, created by Translate()
1613   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1614   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1615
1616   // Update Python script
1617   TPythonDump() << this << ".TranslateObject( "
1618                 << theObject
1619                 << ", vector, "
1620                 << theCopy << " )";
1621 }
1622
1623 //=======================================================================
1624 //function : Rotate
1625 //purpose  :
1626 //=======================================================================
1627
1628 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
1629                                 const SMESH::AxisStruct & theAxis,
1630                                 CORBA::Double             theAngle,
1631                                 CORBA::Boolean            theCopy)
1632 {
1633   initData();
1634
1635   SMESHDS_Mesh* aMesh = GetMeshDS();
1636
1637   TIDSortedElemSet elements;
1638   ToMap(theIDsOfElements, aMesh, elements);
1639
1640   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
1641   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
1642
1643   gp_Trsf aTrsf;
1644   aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
1645
1646   ::SMESH_MeshEditor anEditor( _myMesh );
1647   anEditor.Transform (elements, aTrsf, theCopy);
1648
1649   if(theCopy) {
1650     StoreResult(anEditor);
1651   }
1652
1653   // Update Python script
1654   TPythonDump() << "axis = " << theAxis;
1655   TPythonDump() << this << ".Rotate( "
1656                 << theIDsOfElements
1657                 << ", axis, "
1658                 << theAngle << ", "
1659                 << theCopy << " )";
1660 }
1661
1662 //=======================================================================
1663 //function : RotateObject
1664 //purpose  :
1665 //=======================================================================
1666
1667 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
1668                                       const SMESH::AxisStruct & theAxis,
1669                                       CORBA::Double             theAngle,
1670                                       CORBA::Boolean            theCopy)
1671 {
1672   initData();
1673
1674   SMESH::long_array_var anElementsId = theObject->GetIDs();
1675   Rotate(anElementsId, theAxis, theAngle, theCopy);
1676
1677   // Clear python line, created by Rotate()
1678   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1679   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1680
1681   // Update Python script
1682   TPythonDump() << this << ".RotateObject( "
1683                 << theObject
1684                 << ", axis, "
1685                 << theAngle << ", "
1686                 << theCopy << " )";
1687 }
1688
1689 //=======================================================================
1690 //function : FindCoincidentNodes
1691 //purpose  :
1692 //=======================================================================
1693
1694 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
1695                                               SMESH::array_of_long_array_out GroupsOfNodes)
1696 {
1697   initData();
1698
1699   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
1700   ::SMESH_MeshEditor anEditor( _myMesh );
1701   set<const SMDS_MeshNode*> nodes; // no input nodes
1702   anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
1703
1704   GroupsOfNodes = new SMESH::array_of_long_array;
1705   GroupsOfNodes->length( aListOfListOfNodes.size() );
1706   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
1707   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
1708     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
1709     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
1710     SMESH::long_array& aGroup = GroupsOfNodes[ i ];
1711     aGroup.length( aListOfNodes.size() );
1712     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
1713       aGroup[ j ] = (*lIt)->GetID();
1714   }
1715   // Update Python script
1716   TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
1717                 << Tolerance << " )";
1718 }
1719
1720 //=======================================================================
1721 //function : MergeNodes
1722 //purpose  :
1723 //=======================================================================
1724
1725 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
1726 {
1727   initData();
1728
1729   SMESHDS_Mesh* aMesh = GetMeshDS();
1730
1731   TPythonDump aTPythonDump;
1732   aTPythonDump << this << ".MergeNodes([";
1733   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
1734   for (int i = 0; i < GroupsOfNodes.length(); i++)
1735   {
1736     const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
1737     aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
1738     list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
1739     for ( int j = 0; j < aNodeGroup.length(); j++ )
1740     {
1741       CORBA::Long index = aNodeGroup[ j ];
1742       const SMDS_MeshNode * node = aMesh->FindNode(index);
1743       if ( node )
1744         aListOfNodes.push_back( node );
1745     }
1746     if ( aListOfNodes.size() < 2 )
1747       aListOfListOfNodes.pop_back();
1748
1749     if ( i > 0 ) aTPythonDump << ", ";
1750     aTPythonDump << aNodeGroup;
1751   }
1752   ::SMESH_MeshEditor anEditor( _myMesh );
1753   anEditor.MergeNodes( aListOfListOfNodes );
1754
1755   // Update Python script
1756   aTPythonDump <<  "])";
1757 }
1758
1759 //=======================================================================
1760 //function : MergeEqualElements
1761 //purpose  :
1762 //=======================================================================
1763
1764 void SMESH_MeshEditor_i::MergeEqualElements()
1765 {
1766   initData();
1767
1768   ::SMESH_MeshEditor anEditor( _myMesh );
1769   anEditor.MergeEqualElements();
1770
1771   // Update Python script
1772   TPythonDump() << this << ".MergeEqualElements()";
1773 }
1774
1775 //=======================================================================
1776 //function : operator
1777 //purpose  :
1778 //=======================================================================
1779
1780 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
1781
1782 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
1783 {
1784   switch ( e ) {
1785   RETCASE( SEW_OK );
1786   RETCASE( SEW_BORDER1_NOT_FOUND );
1787   RETCASE( SEW_BORDER2_NOT_FOUND );
1788   RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
1789   RETCASE( SEW_BAD_SIDE_NODES );
1790   RETCASE( SEW_VOLUMES_TO_SPLIT );
1791   RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
1792   RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
1793   RETCASE( SEW_BAD_SIDE1_NODES );
1794   RETCASE( SEW_BAD_SIDE2_NODES );
1795   }
1796   return SMESH::SMESH_MeshEditor::SEW_OK;
1797 }
1798
1799 //=======================================================================
1800 //function : SewFreeBorders
1801 //purpose  :
1802 //=======================================================================
1803
1804 SMESH::SMESH_MeshEditor::Sew_Error
1805   SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
1806                                      CORBA::Long SecondNodeID1,
1807                                      CORBA::Long LastNodeID1,
1808                                      CORBA::Long FirstNodeID2,
1809                                      CORBA::Long SecondNodeID2,
1810                                      CORBA::Long LastNodeID2,
1811                                      CORBA::Boolean CreatePolygons,
1812                                      CORBA::Boolean CreatePolyedrs)
1813 {
1814   initData();
1815
1816   SMESHDS_Mesh* aMesh = GetMeshDS();
1817
1818   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
1819   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
1820   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
1821   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
1822   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
1823   const SMDS_MeshNode* aSide2ThirdNode   = aMesh->FindNode( LastNodeID2   );
1824
1825   if (!aBorderFirstNode ||
1826       !aBorderSecondNode||
1827       !aBorderLastNode)
1828     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
1829   if (!aSide2FirstNode  ||
1830       !aSide2SecondNode ||
1831       !aSide2ThirdNode)
1832     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
1833
1834   // Update Python script
1835   TPythonDump() << "error = " << this << ".SewFreeBorders( "
1836                 << FirstNodeID1  << ", "
1837                 << SecondNodeID1 << ", "
1838                 << LastNodeID1   << ", "
1839                 << FirstNodeID2  << ", "
1840                 << SecondNodeID2 << ", "
1841                 << LastNodeID2   << ", "
1842                 << CreatePolygons<< ", "
1843                 << CreatePolyedrs<< " )";
1844
1845   ::SMESH_MeshEditor anEditor( _myMesh );
1846   SMESH::SMESH_MeshEditor::Sew_Error error =
1847     convError( anEditor.SewFreeBorder (aBorderFirstNode,
1848                                        aBorderSecondNode,
1849                                        aBorderLastNode,
1850                                        aSide2FirstNode,
1851                                        aSide2SecondNode,
1852                                        aSide2ThirdNode,
1853                                        true,
1854                                        CreatePolygons,
1855                                        CreatePolyedrs) );
1856
1857   StoreResult(anEditor);
1858
1859   return error;
1860 }
1861
1862
1863 //=======================================================================
1864 //function : SewConformFreeBorders
1865 //purpose  :
1866 //=======================================================================
1867
1868 SMESH::SMESH_MeshEditor::Sew_Error
1869 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
1870                                           CORBA::Long SecondNodeID1,
1871                                           CORBA::Long LastNodeID1,
1872                                           CORBA::Long FirstNodeID2,
1873                                           CORBA::Long SecondNodeID2)
1874 {
1875   initData();
1876
1877   SMESHDS_Mesh* aMesh = GetMeshDS();
1878
1879   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
1880   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
1881   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
1882   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
1883   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
1884   const SMDS_MeshNode* aSide2ThirdNode   = 0;
1885
1886   if (!aBorderFirstNode ||
1887       !aBorderSecondNode||
1888       !aBorderLastNode )
1889     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
1890   if (!aSide2FirstNode  ||
1891       !aSide2SecondNode)
1892     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
1893
1894   // Update Python script
1895   TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
1896                 << FirstNodeID1  << ", "
1897                 << SecondNodeID1 << ", "
1898                 << LastNodeID1   << ", "
1899                 << FirstNodeID2  << ", "
1900                 << SecondNodeID2 << " )";
1901
1902   ::SMESH_MeshEditor anEditor( _myMesh );
1903   SMESH::SMESH_MeshEditor::Sew_Error error =
1904     convError( anEditor.SewFreeBorder (aBorderFirstNode,
1905                                        aBorderSecondNode,
1906                                        aBorderLastNode,
1907                                        aSide2FirstNode,
1908                                        aSide2SecondNode,
1909                                        aSide2ThirdNode,
1910                                        true,
1911                                        false, false) );
1912
1913   StoreResult(anEditor);
1914
1915   return error;
1916 }
1917
1918
1919 //=======================================================================
1920 //function : SewBorderToSide
1921 //purpose  :
1922 //=======================================================================
1923
1924 SMESH::SMESH_MeshEditor::Sew_Error
1925 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
1926                                     CORBA::Long SecondNodeIDOnFreeBorder,
1927                                     CORBA::Long LastNodeIDOnFreeBorder,
1928                                     CORBA::Long FirstNodeIDOnSide,
1929                                     CORBA::Long LastNodeIDOnSide,
1930                                     CORBA::Boolean CreatePolygons,
1931                                     CORBA::Boolean CreatePolyedrs)
1932 {
1933   initData();
1934
1935   SMESHDS_Mesh* aMesh = GetMeshDS();
1936
1937   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeIDOnFreeBorder  );
1938   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
1939   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeIDOnFreeBorder   );
1940   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeIDOnSide  );
1941   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( LastNodeIDOnSide );
1942   const SMDS_MeshNode* aSide2ThirdNode   = 0;
1943
1944   if (!aBorderFirstNode ||
1945       !aBorderSecondNode||
1946       !aBorderLastNode  )
1947     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
1948   if (!aSide2FirstNode  ||
1949       !aSide2SecondNode)
1950     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
1951
1952   // Update Python script
1953   TPythonDump() << "error = " << this << ".SewBorderToSide( "
1954                 << FirstNodeIDOnFreeBorder  << ", "
1955                 << SecondNodeIDOnFreeBorder << ", "
1956                 << LastNodeIDOnFreeBorder   << ", "
1957                 << FirstNodeIDOnSide        << ", "
1958                 << LastNodeIDOnSide         << ", "
1959                 << CreatePolygons           << ", "
1960                 << CreatePolyedrs           << ") ";
1961
1962   ::SMESH_MeshEditor anEditor( _myMesh );
1963   SMESH::SMESH_MeshEditor::Sew_Error error =
1964     convError( anEditor.SewFreeBorder (aBorderFirstNode,
1965                                        aBorderSecondNode,
1966                                        aBorderLastNode,
1967                                        aSide2FirstNode,
1968                                        aSide2SecondNode,
1969                                        aSide2ThirdNode,
1970                                        false,
1971                                        CreatePolygons,
1972                                        CreatePolyedrs) );
1973
1974   StoreResult(anEditor);
1975
1976   return error;
1977 }
1978
1979
1980 //=======================================================================
1981 //function : SewSideElements
1982 //purpose  :
1983 //=======================================================================
1984
1985 SMESH::SMESH_MeshEditor::Sew_Error
1986 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
1987                                     const SMESH::long_array& IDsOfSide2Elements,
1988                                     CORBA::Long NodeID1OfSide1ToMerge,
1989                                     CORBA::Long NodeID1OfSide2ToMerge,
1990                                     CORBA::Long NodeID2OfSide1ToMerge,
1991                                     CORBA::Long NodeID2OfSide2ToMerge)
1992 {
1993   initData();
1994
1995   SMESHDS_Mesh* aMesh = GetMeshDS();
1996
1997   const SMDS_MeshNode* aFirstNode1ToMerge  = aMesh->FindNode( NodeID1OfSide1ToMerge );
1998   const SMDS_MeshNode* aFirstNode2ToMerge  = aMesh->FindNode( NodeID1OfSide2ToMerge );
1999   const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
2000   const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
2001
2002   if (!aFirstNode1ToMerge ||
2003       !aFirstNode2ToMerge )
2004     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
2005   if (!aSecondNode1ToMerge||
2006       !aSecondNode2ToMerge)
2007     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
2008
2009   TIDSortedElemSet aSide1Elems, aSide2Elems;
2010   ToMap(IDsOfSide1Elements, aMesh, aSide1Elems);
2011   ToMap(IDsOfSide2Elements, aMesh, aSide2Elems);
2012
2013   // Update Python script
2014   TPythonDump() << "error = " << this << ".SewSideElements( "
2015                 << IDsOfSide1Elements << ", "
2016                 << IDsOfSide2Elements << ", "
2017                 << NodeID1OfSide1ToMerge << ", "
2018                 << NodeID1OfSide2ToMerge << ", "
2019                 << NodeID2OfSide1ToMerge << ", "
2020                 << NodeID2OfSide2ToMerge << ")";
2021
2022   ::SMESH_MeshEditor anEditor( _myMesh );
2023   SMESH::SMESH_MeshEditor::Sew_Error error =
2024     convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
2025                                          aFirstNode1ToMerge,
2026                                          aFirstNode2ToMerge,
2027                                          aSecondNode1ToMerge,
2028                                          aSecondNode2ToMerge));
2029
2030   StoreResult(anEditor);
2031
2032   return error;
2033 }
2034
2035 //================================================================================
2036 /*!
2037  * \brief Set new nodes for given element
2038   * \param ide - element id
2039   * \param newIDs - new node ids
2040   * \retval CORBA::Boolean - true if result is OK
2041  */
2042 //================================================================================
2043
2044 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
2045                                                    const SMESH::long_array& newIDs)
2046 {
2047   initData();
2048
2049   const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
2050   if(!elem) return false;
2051
2052   int nbn = newIDs.length();
2053   int i=0;
2054   const SMDS_MeshNode* aNodes [nbn];
2055   int nbn1=-1;
2056   for(; i<nbn; i++) {
2057     const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
2058     if(aNode) {
2059       nbn1++;
2060       aNodes[nbn1] = aNode;
2061     }
2062   }
2063   // Update Python script
2064   TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
2065                 << ide << ", " << newIDs << " )";
2066 #ifdef _DEBUG_
2067   TPythonDump() << "print 'ChangeElemNodes: ', isDone";
2068 #endif
2069
2070   return GetMeshDS()->ChangeElementNodes( elem, aNodes, nbn1+1 );
2071 }
2072   
2073 //================================================================================
2074 /*!
2075  * \brief Update myLastCreated* or myPreviewData
2076   * \param anEditor - it contains last modification results
2077  */
2078 //================================================================================
2079
2080 void SMESH_MeshEditor_i::StoreResult(::SMESH_MeshEditor& anEditor)
2081 {
2082   if ( myPreviewMode ) { // --- MeshPreviewStruct filling --- 
2083
2084     list<int> aNodesConnectivity;
2085     typedef map<int, int> TNodesMap;
2086     TNodesMap nodesMap;
2087
2088     TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
2089     SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
2090
2091     SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
2092     int nbEdges = aMeshDS->NbEdges();
2093     int nbFaces = aMeshDS->NbFaces();
2094     int nbVolum = aMeshDS->NbVolumes();
2095     switch ( previewType ) {
2096     case SMDSAbs_Edge  : nbFaces = nbVolum = 0; break;
2097     case SMDSAbs_Face  : nbEdges = nbVolum = 0; break;
2098     case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
2099     default:;
2100     }
2101     myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
2102     myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
2103     int i = 0, j = 0;
2104     SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
2105
2106     while ( itMeshElems->more() ) {
2107       const SMDS_MeshElement* aMeshElem = itMeshElems->next();
2108       if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
2109         continue;
2110
2111       SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
2112       while ( itElemNodes->more() ) {
2113         const SMDS_MeshNode* aMeshNode = 
2114           static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
2115         int aNodeID = aMeshNode->GetID();
2116         TNodesMap::iterator anIter = nodesMap.find(aNodeID);
2117         if ( anIter == nodesMap.end() ) {
2118           // filling the nodes coordinates
2119           myPreviewData->nodesXYZ[j].x = aMeshNode->X();
2120           myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
2121           myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
2122           anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
2123           j++;
2124         }
2125         aNodesConnectivity.push_back(anIter->second);
2126       }
2127
2128       // filling the elements types
2129       SMDSAbs_ElementType aType;
2130       bool isPoly;
2131       /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
2132         aType = SMDSAbs_Node;
2133         isPoly = false;
2134       }
2135       else*/ {
2136         aType = aMeshElem->GetType();
2137         isPoly = aMeshElem->IsPoly();
2138       }
2139
2140       myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
2141       myPreviewData->elementTypes[i].isPoly = isPoly;
2142       myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
2143       i++;
2144
2145     }
2146     myPreviewData->nodesXYZ.length( j );
2147
2148     // filling the elements connectivities
2149     list<int>::iterator aConnIter = aNodesConnectivity.begin();
2150     myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
2151     for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
2152       myPreviewData->elementConnectivities[i] = *aConnIter;
2153     
2154     return;
2155   }
2156
2157   {
2158     // add new nodes into myLastCreatedNodes
2159     const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
2160     myLastCreatedNodes->length(aSeq.Length());
2161     for(int i=0; i<aSeq.Length(); i++)
2162       myLastCreatedNodes[i] = aSeq.Value(i+1)->GetID();
2163   }
2164   {
2165     // add new elements into myLastCreatedElems
2166     const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
2167     myLastCreatedElems->length(aSeq.Length());
2168     for(int i=0; i<aSeq.Length(); i++)
2169       myLastCreatedElems[i] = aSeq.Value(i+1)->GetID();
2170   }
2171 }
2172
2173 //================================================================================
2174 /*!
2175  * Return data of mesh edition preview
2176  */
2177 //================================================================================
2178
2179 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
2180 {
2181   return myPreviewData._retn();
2182 }
2183
2184 //================================================================================
2185 /*!
2186  * \brief Returns list of it's IDs of created nodes
2187   * \retval SMESH::long_array* - list of node ID
2188  */
2189 //================================================================================
2190
2191 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
2192 {
2193   return myLastCreatedNodes._retn();
2194 }
2195
2196 //================================================================================
2197 /*!
2198  * \brief Returns list of it's IDs of created elements
2199   * \retval SMESH::long_array* - list of elements' ID
2200  */
2201 //================================================================================
2202
2203 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
2204 {
2205   return myLastCreatedElems._retn();
2206 }
2207
2208 //=======================================================================
2209 //function : ConvertToQuadratic
2210 //purpose  :
2211 //=======================================================================
2212
2213 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
2214 {
2215   ::SMESH_MeshEditor anEditor( _myMesh );
2216   anEditor.ConvertToQuadratic(theForce3d);
2217  // Update Python script
2218   TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
2219 }
2220
2221 //=======================================================================
2222 //function : ConvertFromQuadratic
2223 //purpose  :
2224 //=======================================================================
2225
2226 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
2227 {
2228   ::SMESH_MeshEditor anEditor( _myMesh );
2229   CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
2230   // Update Python script
2231   TPythonDump() << this << ".ConvertFromQuadratic()";
2232   return isDone;
2233 }