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