Salome HOME
Integration of PAL/SALOME V2.1.0c from OCC
[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 using namespace std;
47
48 //=============================================================================
49 /*!
50  *  
51  */
52 //=============================================================================
53
54 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh* theMesh)
55 {
56         _myMesh = theMesh;
57 };
58
59 //=============================================================================
60 /*!
61  *  
62  */
63 //=============================================================================
64
65 CORBA::Boolean SMESH_MeshEditor_i::RemoveElements(const SMESH::
66         long_array & IDsOfElements)
67 {
68   ::SMESH_MeshEditor anEditor( _myMesh );
69   list< int > IdList;
70   for (int i = 0; i < IDsOfElements.length(); i++)
71     IdList.push_back( IDsOfElements[i] );
72
73   return anEditor.Remove( IdList, false );
74 };
75
76 //=============================================================================
77 /*!
78  *  
79  */
80 //=============================================================================
81
82 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::
83         long_array & IDsOfNodes)
84 {
85   ::SMESH_MeshEditor anEditor( _myMesh );
86   list< int > IdList;
87   for (int i = 0; i < IDsOfNodes.length(); i++)
88     IdList.push_back( IDsOfNodes[i] );
89
90   return anEditor.Remove( IdList, true );
91 };
92
93 //=============================================================================
94 /*!
95  *  
96  */
97 //=============================================================================
98
99 CORBA::Boolean SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
100 {
101         int NbNodes = IDsOfNodes.length();
102         if (NbNodes == 2)
103         {
104                 CORBA::Long index1 = IDsOfNodes[0];
105                 CORBA::Long index2 = IDsOfNodes[1];
106                 GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
107         }
108         return true;
109 }
110
111 //=============================================================================
112 /*!
113  *  
114  */
115 //=============================================================================
116
117 CORBA::Boolean SMESH_MeshEditor_i::AddNode(CORBA::Double x,
118         CORBA::Double y, CORBA::Double z)
119 {
120         MESSAGE(" AddNode " << x << " , " << y << " , " << z)
121                 int idNode = GetMeshDS()->AddNode(x, y, z)->GetID();
122         MESSAGE(" idNode " << idNode) return true;
123 }
124
125 //=============================================================================
126 /*!
127  *  
128  */
129 //=============================================================================
130
131 CORBA::Boolean SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
132 {
133         int NbNodes = IDsOfNodes.length();
134         const SMDS_MeshNode* nodes[4];
135         for(int i=0;i<NbNodes;i++) nodes[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
136         if (NbNodes == 3)
137         {
138                 GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
139         }
140         else if (NbNodes == 4)
141         {
142                 GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
143         }
144         return true;
145 };
146
147 //=============================================================================
148 /*!
149  *  
150  */
151 //=============================================================================
152
153 CORBA::Boolean SMESH_MeshEditor_i::AddVolume(const SMESH::
154         long_array & IDsOfNodes)
155 {
156         int NbNodes = IDsOfNodes.length();
157         const SMDS_MeshNode* n[8];
158         for(int i=0;i<NbNodes;i++) n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
159
160         switch(NbNodes)
161         {
162         case 4:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
163         case 5:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
164         case 6:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
165         case 8:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
166         }
167         return true;
168 };
169
170 //=============================================================================
171 /*!
172  *  
173  */
174 //=============================================================================
175
176 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
177                                             CORBA::Double x,
178                                             CORBA::Double y,
179                                             CORBA::Double z)
180 {
181   const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
182   if ( !node )
183     return false;
184   
185   GetMeshDS()->MoveNode(node, x, y, z);
186
187   return true;
188 }
189
190 //=============================================================================
191 /*!
192  *  
193  */
194 //=============================================================================
195
196 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
197                                                CORBA::Long NodeID2)
198 {
199   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
200   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
201   if ( !n1 || !n2 )
202     return false;
203
204   ::SMESH_MeshEditor aMeshEditor( _myMesh );
205   return aMeshEditor.InverseDiag ( n1, n2 );
206 }
207
208 //=============================================================================
209 /*!
210  *  
211  */
212 //=============================================================================
213
214 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
215                                               CORBA::Long NodeID2)
216 {
217   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
218   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
219   if ( !n1 || !n2 )
220     return false;
221
222   ::SMESH_MeshEditor aMeshEditor( _myMesh );
223   return aMeshEditor.DeleteDiag ( n1, n2 );
224 }
225
226 //=============================================================================
227 /*!
228  *  
229  */
230 //=============================================================================
231
232 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
233 {
234   ::SMESH_MeshEditor anEditor( _myMesh );
235   for (int i = 0; i < IDsOfElements.length(); i++)
236   {
237     CORBA::Long index = IDsOfElements[i];
238     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
239     if ( elem )
240       anEditor.Reorient( elem );
241   }
242   return true;
243 }
244
245 //=============================================================================
246 /*!
247  *  
248  */
249 //=============================================================================
250
251 CORBA::Boolean
252   SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfElements,
253                                  SMESH::NumericalFunctor_ptr Criterion,
254                                  CORBA::Double               MaxAngle)
255 {
256   set<const SMDS_MeshElement*> faces;
257   for (int i = 0; i < IDsOfElements.length(); i++)
258   {
259     CORBA::Long index = IDsOfElements[i];
260     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
261     if ( elem && elem->GetType() == SMDSAbs_Face)
262       faces.insert( elem );
263   }
264   SMESH::NumericalFunctor_i* aNumericalFunctor = 
265     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
266   SMESH::Controls::NumericalFunctorPtr aCrit;
267   if ( !aNumericalFunctor )
268     aCrit.reset( new SMESH::Controls::AspectRatio() );
269   else
270     aCrit = aNumericalFunctor->GetNumericalFunctor();
271
272   ::SMESH_MeshEditor anEditor( _myMesh );
273   return anEditor.TriToQuad( faces, aCrit, MaxAngle );
274 }
275
276 //=============================================================================
277 /*!
278  *  
279  */
280 //=============================================================================
281
282 CORBA::Boolean
283   SMESH_MeshEditor_i::QuadToTri(const SMESH::long_array &   IDsOfElements,
284                                 SMESH::NumericalFunctor_ptr Criterion)
285 {
286   set<const SMDS_MeshElement*> faces;
287   for (int i = 0; i < IDsOfElements.length(); i++)
288   {
289     CORBA::Long index = IDsOfElements[i];
290     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
291     if ( elem && elem->GetType() == SMDSAbs_Face)
292       faces.insert( elem );
293   }
294   SMESH::NumericalFunctor_i* aNumericalFunctor = 
295     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
296   SMESH::Controls::NumericalFunctorPtr aCrit;
297   if ( !aNumericalFunctor )
298     aCrit.reset( new SMESH::Controls::AspectRatio() );
299   else
300     aCrit = aNumericalFunctor->GetNumericalFunctor();
301
302   ::SMESH_MeshEditor anEditor( _myMesh );
303   return anEditor.QuadToTri( faces, aCrit );
304 }
305
306 //=============================================================================
307 /*!
308  *  
309  */
310 //=============================================================================
311
312 CORBA::Boolean
313   SMESH_MeshEditor_i::SplitQuad(const SMESH::long_array & IDsOfElements,
314                                 CORBA::Boolean            Diag13)
315 {
316   set<const SMDS_MeshElement*> faces;
317   for (int i = 0; i < IDsOfElements.length(); i++)
318   {
319     CORBA::Long index = IDsOfElements[i];
320     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
321     if ( elem && elem->GetType() == SMDSAbs_Face)
322       faces.insert( elem );
323   }
324
325   ::SMESH_MeshEditor anEditor( _myMesh );
326   return anEditor.QuadToTri( faces, Diag13 );
327 }
328
329 //=============================================================================
330 /*!
331  *  
332  */
333 //=============================================================================
334
335 CORBA::Boolean
336   SMESH_MeshEditor_i::Smooth(const SMESH::long_array &              IDsOfElements,
337                              const SMESH::long_array &              IDsOfFixedNodes,
338                              CORBA::Long                            MaxNbOfIterations,
339                              CORBA::Double                          MaxAspectRatio,
340                              SMESH::SMESH_MeshEditor::Smooth_Method Method)
341 {
342   SMESHDS_Mesh* aMesh = GetMeshDS();
343
344   set<const SMDS_MeshElement*> elements;
345   for (int i = 0; i < IDsOfElements.length(); i++)
346   {
347     CORBA::Long index = IDsOfElements[i];
348     const SMDS_MeshElement * elem = aMesh->FindElement(index);
349     if ( elem && elem->GetType() == SMDSAbs_Face)
350       elements.insert( elem );
351   }
352
353   set<const SMDS_MeshNode*> fixedNodes;
354   for (int i = 0; i < IDsOfFixedNodes.length(); i++)
355   {
356     CORBA::Long index = IDsOfFixedNodes[i];
357     const SMDS_MeshNode * node = aMesh->FindNode(index);
358     if ( node )
359       fixedNodes.insert( node );
360   }
361   ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
362   if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
363      method = ::SMESH_MeshEditor::CENTROIDAL;
364
365   ::SMESH_MeshEditor anEditor( _myMesh );
366   anEditor.Smooth( elements, fixedNodes, method, MaxNbOfIterations, MaxAspectRatio );
367
368   return true;
369 }
370
371 //=============================================================================
372 /*!
373  *  
374  */
375 //=============================================================================
376
377 void SMESH_MeshEditor_i::RenumberNodes()
378 {
379   GetMeshDS()->Renumber( true );
380 }
381
382 //=============================================================================
383 /*!
384  *  
385  */
386 //=============================================================================
387
388 void SMESH_MeshEditor_i::RenumberElements()
389 {
390   GetMeshDS()->Renumber( false );
391 }
392
393 //=======================================================================
394 //function : RotationSweep
395 //purpose  : 
396 //=======================================================================
397
398 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
399                                        const SMESH::AxisStruct &  theAxis,
400                                        CORBA::Double             theAngleInRadians,
401                                        CORBA::Long               theNbOfSteps,
402                                        CORBA::Double             theTolerance)
403 {
404   SMESHDS_Mesh* aMesh = GetMeshDS();
405
406   set<const SMDS_MeshElement*> elements;
407   for (int i = 0; i < theIDsOfElements.length(); i++)
408   {
409     CORBA::Long index = theIDsOfElements[i];
410     const SMDS_MeshElement * elem = aMesh->FindElement(index);
411     if ( elem )
412       elements.insert( elem );
413   }
414   gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
415               gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
416
417   ::SMESH_MeshEditor anEditor( _myMesh );
418   anEditor.RotationSweep (elements, Ax1, theAngleInRadians,
419                           theNbOfSteps, theTolerance);
420 }
421
422 //=======================================================================
423 //function : ExtrusionSweep
424 //purpose  : 
425 //=======================================================================
426
427 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
428                                         const SMESH::DirStruct &   theStepVector,
429                                         CORBA::Long               theNbOfSteps)
430 {
431   SMESHDS_Mesh* aMesh = GetMeshDS();
432
433   set<const SMDS_MeshElement*> elements;
434   for (int i = 0; i < theIDsOfElements.length(); i++)
435   {
436     CORBA::Long index = theIDsOfElements[i];
437     const SMDS_MeshElement * elem = aMesh->FindElement(index);
438     if ( elem )
439       elements.insert( elem );
440   }
441   const SMESH::PointStruct * P = &theStepVector.PS;
442   gp_Vec stepVec( P->x, P->y, P->z );
443
444   ::SMESH_MeshEditor anEditor( _myMesh );
445   anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps);
446 }
447
448 //=======================================================================
449 //function : Mirror
450 //purpose  : 
451 //=======================================================================
452
453 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElements,
454                                 const SMESH::AxisStruct &            theAxis,
455                                 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
456                                 CORBA::Boolean                      theCopy)
457 {
458   SMESHDS_Mesh* aMesh = GetMeshDS();
459
460   set<const SMDS_MeshElement*> elements;
461   for (int i = 0; i < theIDsOfElements.length(); i++)
462   {
463     CORBA::Long index = theIDsOfElements[i];
464     const SMDS_MeshElement * elem = aMesh->FindElement(index);
465     if ( elem )
466       elements.insert( elem );
467   }
468   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
469   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
470
471   gp_Trsf aTrsf;
472   switch ( theMirrorType ) {
473   case  SMESH::SMESH_MeshEditor::POINT:
474     aTrsf.SetMirror( P );
475     break;
476   case  SMESH::SMESH_MeshEditor::AXIS:
477     aTrsf.SetMirror( gp_Ax1( P, V ));
478     break;
479   default:
480     aTrsf.SetMirror( gp_Ax2( P, V ));
481   }
482
483   ::SMESH_MeshEditor anEditor( _myMesh );
484   anEditor.Transform (elements, aTrsf, theCopy);
485 }
486
487 //=======================================================================
488 //function : Translate
489 //purpose  : 
490 //=======================================================================
491
492 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
493                                    const SMESH::DirStruct &   theVector,
494                                    CORBA::Boolean            theCopy)
495 {
496   SMESHDS_Mesh* aMesh = GetMeshDS();
497
498   set<const SMDS_MeshElement*> elements;
499   for (int i = 0; i < theIDsOfElements.length(); i++)
500   {
501     CORBA::Long index = theIDsOfElements[i];
502     const SMDS_MeshElement * elem = aMesh->FindElement(index);
503     if ( elem )
504       elements.insert( elem );
505   }
506   gp_Trsf aTrsf;
507   const SMESH::PointStruct * P = &theVector.PS;
508   aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
509
510   ::SMESH_MeshEditor anEditor( _myMesh );
511   anEditor.Transform (elements, aTrsf, theCopy);
512 }
513
514 //=======================================================================
515 //function : Rotate
516 //purpose  : 
517 //=======================================================================
518
519 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
520                                 const SMESH::AxisStruct &  theAxis,
521                                 CORBA::Double             theAngle,
522                                 CORBA::Boolean            theCopy)
523 {
524   SMESHDS_Mesh* aMesh = GetMeshDS();
525
526   set<const SMDS_MeshElement*> elements;
527   for (int i = 0; i < theIDsOfElements.length(); i++)
528   {
529     CORBA::Long index = theIDsOfElements[i];
530     const SMDS_MeshElement * elem = aMesh->FindElement(index);
531     if ( elem )
532       elements.insert( elem );
533   }
534   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
535   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
536
537   gp_Trsf aTrsf;
538   aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
539   
540
541   ::SMESH_MeshEditor anEditor( _myMesh );
542   anEditor.Transform (elements, aTrsf, theCopy);
543 }
544
545 //=======================================================================
546 //function : FindCoincidentNodes
547 //purpose  : 
548 //=======================================================================
549
550 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
551                                               SMESH::array_of_long_array_out GroupsOfNodes)
552 {
553   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
554   ::SMESH_MeshEditor anEditor( _myMesh );
555   anEditor.FindCoincidentNodes( Tolerance, aListOfListOfNodes );
556
557   GroupsOfNodes = new SMESH::array_of_long_array;
558   GroupsOfNodes->length( aListOfListOfNodes.size() );
559   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
560   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
561   {
562     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
563     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
564     SMESH::long_array& aGroup = GroupsOfNodes[ i ];
565     aGroup.length( aListOfNodes.size() );
566     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
567       aGroup[ j ] = (*lIt)->GetID();
568   }
569 }
570
571 //=======================================================================
572 //function : MergeNodes
573 //purpose  : 
574 //=======================================================================
575
576 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
577 {
578   SMESHDS_Mesh* aMesh = GetMeshDS();
579
580   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
581   list<const SMDS_MeshElement*> elements;
582   for (int i = 0; i < GroupsOfNodes.length(); i++)
583   {
584     const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
585     aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
586     list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
587     for ( int j = 0; j < aNodeGroup.length(); j++ )
588     {
589       CORBA::Long index = aNodeGroup[ j ];
590       const SMDS_MeshNode * node = aMesh->FindNode(index);
591       if ( node )
592         aListOfNodes.push_back( node );
593     }
594     if ( aListOfNodes.size() < 2 )
595       aListOfListOfNodes.pop_back();
596   }
597   ::SMESH_MeshEditor anEditor( _myMesh );
598   anEditor.MergeNodes( aListOfListOfNodes );
599 }
600
601 //=======================================================================
602 //function : MergeEqualElements
603 //purpose  : 
604 //=======================================================================
605
606 void SMESH_MeshEditor_i::MergeEqualElements()
607 {
608   ::SMESH_MeshEditor anEditor( _myMesh );
609   anEditor.MergeEqualElements();
610 }
611
612 //=======================================================================
613 //function : SewFreeBorders
614 //purpose  : 
615 //=======================================================================
616
617 CORBA::Boolean SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
618                                                   CORBA::Long SecondNodeID1,
619                                                   CORBA::Long LastNodeID1,
620                                                   CORBA::Long FirstNodeID2,
621                                                   CORBA::Long SecondNodeID2,
622                                                   CORBA::Long LastNodeID2)
623 {
624   SMESHDS_Mesh* aMesh = GetMeshDS();
625
626   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
627   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
628   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
629   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
630   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
631   const SMDS_MeshNode* aSide2ThirdNode   = aMesh->FindNode( LastNodeID2   );
632
633   if (!aBorderFirstNode ||
634       !aBorderSecondNode||
635       !aBorderLastNode  ||
636       !aSide2FirstNode  ||
637       !aSide2SecondNode ||
638       !aSide2ThirdNode)
639     return false;
640
641   ::SMESH_MeshEditor anEditor( _myMesh );
642   return anEditor.SewFreeBorder (aBorderFirstNode,
643                                  aBorderSecondNode,
644                                  aBorderLastNode,
645                                  aSide2FirstNode,
646                                  aSide2SecondNode,
647                                  aSide2ThirdNode,
648                                  true);
649 }
650
651 //=======================================================================
652 //function : SewConformFreeBorders
653 //purpose  : 
654 //=======================================================================
655
656 CORBA::Boolean SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
657                                                          CORBA::Long SecondNodeID1,
658                                                          CORBA::Long LastNodeID1,
659                                                          CORBA::Long FirstNodeID2,
660                                                          CORBA::Long SecondNodeID2)
661 {
662   SMESHDS_Mesh* aMesh = GetMeshDS();
663
664   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
665   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
666   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
667   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
668   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
669   const SMDS_MeshNode* aSide2ThirdNode   = 0;
670
671   if (!aBorderFirstNode ||
672       !aBorderSecondNode||
673       !aBorderLastNode  ||
674       !aSide2FirstNode  ||
675       !aSide2SecondNode)
676     return false;
677
678   ::SMESH_MeshEditor anEditor( _myMesh );
679   return anEditor.SewFreeBorder (aBorderFirstNode,
680                                  aBorderSecondNode,
681                                  aBorderLastNode,
682                                  aSide2FirstNode,
683                                  aSide2SecondNode,
684                                  aSide2ThirdNode,
685                                  true);
686 }
687
688 //=======================================================================
689 //function : SewBorderToSide
690 //purpose  : 
691 //=======================================================================
692
693 CORBA::Boolean SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
694                                                    CORBA::Long SecondNodeIDOnFreeBorder,
695                                                    CORBA::Long LastNodeIDOnFreeBorder,
696                                                    CORBA::Long FirstNodeIDOnSide,
697                                                    CORBA::Long LastNodeIDOnSide)
698 {
699   SMESHDS_Mesh* aMesh = GetMeshDS();
700
701   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeIDOnFreeBorder  );
702   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
703   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeIDOnFreeBorder   );
704   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeIDOnSide  );
705   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( LastNodeIDOnSide );
706   const SMDS_MeshNode* aSide2ThirdNode   = 0;
707
708   if (!aBorderFirstNode ||
709       !aBorderSecondNode||
710       !aBorderLastNode  ||
711       !aSide2FirstNode  ||
712       !aSide2SecondNode)
713     return false;
714
715   ::SMESH_MeshEditor anEditor( _myMesh );
716   return anEditor.SewFreeBorder (aBorderFirstNode,
717                                  aBorderSecondNode,
718                                  aBorderLastNode,
719                                  aSide2FirstNode,
720                                  aSide2SecondNode,
721                                  aSide2ThirdNode,
722                                  false);
723 }
724
725 //=======================================================================
726 //function : SewSideElements
727 //purpose  : 
728 //=======================================================================
729
730 CORBA::Boolean SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
731                                                    const SMESH::long_array& IDsOfSide2Elements,
732                                                    CORBA::Long NodeID1OfSide1ToMerge,
733                                                    CORBA::Long NodeID1OfSide2ToMerge,
734                                                    CORBA::Long NodeID2OfSide1ToMerge,
735                                                    CORBA::Long NodeID2OfSide2ToMerge)
736 {
737   SMESHDS_Mesh* aMesh = GetMeshDS();
738
739   const SMDS_MeshNode* aFirstNode1ToMerge  = aMesh->FindNode( NodeID1OfSide1ToMerge );
740   const SMDS_MeshNode* aFirstNode2ToMerge  = aMesh->FindNode( NodeID1OfSide2ToMerge );
741   const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
742   const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
743
744   if (!aFirstNode1ToMerge ||
745       !aFirstNode2ToMerge ||
746       !aSecondNode1ToMerge||
747       !aSecondNode2ToMerge)
748     return false;
749
750   set<const SMDS_MeshElement*> aSide1Elems, aSide2Elems;
751   for (int i = 0; i < IDsOfSide1Elements.length(); i++)
752   {
753     CORBA::Long index = IDsOfSide1Elements[i];
754     const SMDS_MeshElement * elem = aMesh->FindElement(index);
755     if ( !elem )
756       return false;
757     aSide1Elems.insert( elem );
758   }
759   for (int i = 0; i < IDsOfSide2Elements.length(); i++)
760   {
761     CORBA::Long index = IDsOfSide2Elements[i];
762     const SMDS_MeshElement * elem = aMesh->FindElement(index);
763     if ( !elem )
764       return false;
765     aSide2Elems.insert( elem );
766   }
767   ::SMESH_MeshEditor anEditor( _myMesh );
768   return anEditor.SewSideElements (aSide1Elems, aSide2Elems,
769                                    aFirstNode1ToMerge,
770                                    aFirstNode2ToMerge,
771                                    aSecondNode1ToMerge,
772                                    aSecondNode2ToMerge);
773 }
774