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