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