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