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