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