Salome HOME
Merge with version on tag OCC-V2_1_0d
[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
252 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
253 {
254   SMESH::long_array_var anElementsId = theObject->GetIDs();
255   Reorient(anElementsId);
256 }
257
258 //=============================================================================
259 /*!
260  *  
261  */
262 //=============================================================================
263
264 CORBA::Boolean
265   SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfElements,
266                                  SMESH::NumericalFunctor_ptr Criterion,
267                                  CORBA::Double               MaxAngle)
268 {
269   set<const SMDS_MeshElement*> faces;
270   for (int i = 0; i < IDsOfElements.length(); i++)
271   {
272     CORBA::Long index = IDsOfElements[i];
273     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
274     if ( elem && elem->GetType() == SMDSAbs_Face)
275       faces.insert( elem );
276   }
277   SMESH::NumericalFunctor_i* aNumericalFunctor = 
278     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
279   SMESH::Controls::NumericalFunctorPtr aCrit;
280   if ( !aNumericalFunctor )
281     aCrit.reset( new SMESH::Controls::AspectRatio() );
282   else
283     aCrit = aNumericalFunctor->GetNumericalFunctor();
284
285   ::SMESH_MeshEditor anEditor( _myMesh );
286   return anEditor.TriToQuad( faces, aCrit, MaxAngle );
287 }
288
289 //=============================================================================
290 /*!
291  *  
292  */
293 //=============================================================================
294
295 CORBA::Boolean
296   SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr   theObject,
297                                        SMESH::NumericalFunctor_ptr Criterion,
298                                        CORBA::Double               MaxAngle)
299 {
300   SMESH::long_array_var anElementsId = theObject->GetIDs();
301   TriToQuad(anElementsId, Criterion, MaxAngle);
302 }
303
304 //=============================================================================
305 /*!
306  *  
307  */
308 //=============================================================================
309
310 CORBA::Boolean
311   SMESH_MeshEditor_i::QuadToTri(const SMESH::long_array &   IDsOfElements,
312                                 SMESH::NumericalFunctor_ptr Criterion)
313 {
314   set<const SMDS_MeshElement*> faces;
315   for (int i = 0; i < IDsOfElements.length(); i++)
316   {
317     CORBA::Long index = IDsOfElements[i];
318     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
319     if ( elem && elem->GetType() == SMDSAbs_Face)
320       faces.insert( elem );
321   }
322   SMESH::NumericalFunctor_i* aNumericalFunctor = 
323     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
324   SMESH::Controls::NumericalFunctorPtr aCrit;
325   if ( !aNumericalFunctor )
326     aCrit.reset( new SMESH::Controls::AspectRatio() );
327   else
328     aCrit = aNumericalFunctor->GetNumericalFunctor();
329
330   ::SMESH_MeshEditor anEditor( _myMesh );
331   return anEditor.QuadToTri( faces, aCrit );
332 }
333
334 //=============================================================================
335 /*!
336  *  
337  */
338 //=============================================================================
339
340 CORBA::Boolean
341   SMESH_MeshEditor_i::SplitQuad(const SMESH::long_array & IDsOfElements,
342                                 CORBA::Boolean            Diag13)
343 {
344   set<const SMDS_MeshElement*> faces;
345   for (int i = 0; i < IDsOfElements.length(); i++)
346   {
347     CORBA::Long index = IDsOfElements[i];
348     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
349     if ( elem && elem->GetType() == SMDSAbs_Face)
350       faces.insert( elem );
351   }
352
353   ::SMESH_MeshEditor anEditor( _myMesh );
354   return anEditor.QuadToTri( faces, Diag13 );
355 }
356
357 //=============================================================================
358 /*!
359  *  
360  */
361 //=============================================================================
362
363 CORBA::Boolean
364   SMESH_MeshEditor_i::SplitQuadObject(SMESH::SMESH_IDSource_ptr theObject,
365                                       CORBA::Boolean            Diag13)
366 {
367   SMESH::long_array_var anElementsId = theObject->GetIDs();
368   SplitQuad(anElementsId, Diag13);
369 }
370
371 //=============================================================================
372 /*!
373  *  
374  */
375 //=============================================================================
376
377 CORBA::Boolean
378   SMESH_MeshEditor_i::Smooth(const SMESH::long_array &              IDsOfElements,
379                              const SMESH::long_array &              IDsOfFixedNodes,
380                              CORBA::Long                            MaxNbOfIterations,
381                              CORBA::Double                          MaxAspectRatio,
382                              SMESH::SMESH_MeshEditor::Smooth_Method Method)
383 {
384   SMESHDS_Mesh* aMesh = GetMeshDS();
385
386   set<const SMDS_MeshElement*> elements;
387   for (int i = 0; i < IDsOfElements.length(); i++)
388   {
389     CORBA::Long index = IDsOfElements[i];
390     const SMDS_MeshElement * elem = aMesh->FindElement(index);
391     if ( elem && elem->GetType() == SMDSAbs_Face)
392       elements.insert( elem );
393   }
394
395   set<const SMDS_MeshNode*> fixedNodes;
396   for (int i = 0; i < IDsOfFixedNodes.length(); i++)
397   {
398     CORBA::Long index = IDsOfFixedNodes[i];
399     const SMDS_MeshNode * node = aMesh->FindNode(index);
400     if ( node )
401       fixedNodes.insert( node );
402   }
403   ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
404   if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
405      method = ::SMESH_MeshEditor::CENTROIDAL;
406
407   ::SMESH_MeshEditor anEditor( _myMesh );
408   anEditor.Smooth( elements, fixedNodes, method, MaxNbOfIterations, MaxAspectRatio );
409
410   return true;
411 }
412
413 //=============================================================================
414 /*!
415  *  
416  */
417 //=============================================================================
418
419 CORBA::Boolean
420   SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr              theObject,
421                                    const SMESH::long_array &              IDsOfFixedNodes,
422                                    CORBA::Long                            MaxNbOfIterations,
423                                    CORBA::Double                          MaxAspectRatio,
424                                    SMESH::SMESH_MeshEditor::Smooth_Method Method)
425 {
426   SMESH::long_array_var anElementsId = theObject->GetIDs();
427   return Smooth(anElementsId, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method);
428 }
429
430 //=============================================================================
431 /*!
432  *  
433  */
434 //=============================================================================
435
436 void SMESH_MeshEditor_i::RenumberNodes()
437 {
438   GetMeshDS()->Renumber( true );
439 }
440
441 //=============================================================================
442 /*!
443  *  
444  */
445 //=============================================================================
446
447 void SMESH_MeshEditor_i::RenumberElements()
448 {
449   GetMeshDS()->Renumber( false );
450 }
451
452 //=======================================================================
453 //function : RotationSweep
454 //purpose  : 
455 //=======================================================================
456
457 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
458                                        const SMESH::AxisStruct &  theAxis,
459                                        CORBA::Double             theAngleInRadians,
460                                        CORBA::Long               theNbOfSteps,
461                                        CORBA::Double             theTolerance)
462 {
463   SMESHDS_Mesh* aMesh = GetMeshDS();
464
465   set<const SMDS_MeshElement*> elements;
466   for (int i = 0; i < theIDsOfElements.length(); i++)
467   {
468     CORBA::Long index = theIDsOfElements[i];
469     const SMDS_MeshElement * elem = aMesh->FindElement(index);
470     if ( elem )
471       elements.insert( elem );
472   }
473   gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
474               gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
475
476   ::SMESH_MeshEditor anEditor( _myMesh );
477   anEditor.RotationSweep (elements, Ax1, theAngleInRadians,
478                           theNbOfSteps, theTolerance);
479 }
480
481 //=======================================================================
482 //function : RotationSweepObject
483 //purpose  : 
484 //=======================================================================
485
486 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
487                                              const SMESH::AxisStruct & theAxis,
488                                              CORBA::Double             theAngleInRadians,
489                                              CORBA::Long               theNbOfSteps,
490                                              CORBA::Double             theTolerance)
491 {
492   SMESH::long_array_var anElementsId = theObject->GetIDs();
493   RotationSweep(anElementsId, theAxis, theAngleInRadians, theNbOfSteps, theTolerance);
494 }
495
496 //=======================================================================
497 //function : ExtrusionSweep
498 //purpose  : 
499 //=======================================================================
500
501 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
502                                         const SMESH::DirStruct &   theStepVector,
503                                         CORBA::Long               theNbOfSteps)
504 {
505   SMESHDS_Mesh* aMesh = GetMeshDS();
506
507   set<const SMDS_MeshElement*> elements;
508   for (int i = 0; i < theIDsOfElements.length(); i++)
509   {
510     CORBA::Long index = theIDsOfElements[i];
511     const SMDS_MeshElement * elem = aMesh->FindElement(index);
512     if ( elem )
513       elements.insert( elem );
514   }
515   const SMESH::PointStruct * P = &theStepVector.PS;
516   gp_Vec stepVec( P->x, P->y, P->z );
517
518   ::SMESH_MeshEditor anEditor( _myMesh );
519   anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps);
520 }
521
522
523 //=======================================================================
524 //function : ExtrusionSweepObject
525 //purpose  : 
526 //=======================================================================
527
528 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
529                                               const SMESH::DirStruct &  theStepVector,
530                                               CORBA::Long               theNbOfSteps)
531 {
532   SMESH::long_array_var anElementsId = theObject->GetIDs();
533   ExtrusionSweep(anElementsId, theStepVector, theNbOfSteps);
534 }
535
536 //=======================================================================
537 //function : Mirror
538 //purpose  : 
539 //=======================================================================
540
541 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElements,
542                                 const SMESH::AxisStruct &            theAxis,
543                                 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
544                                 CORBA::Boolean                      theCopy)
545 {
546   SMESHDS_Mesh* aMesh = GetMeshDS();
547
548   set<const SMDS_MeshElement*> elements;
549   for (int i = 0; i < theIDsOfElements.length(); i++)
550   {
551     CORBA::Long index = theIDsOfElements[i];
552     const SMDS_MeshElement * elem = aMesh->FindElement(index);
553     if ( elem )
554       elements.insert( elem );
555   }
556   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
557   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
558
559   gp_Trsf aTrsf;
560   switch ( theMirrorType ) {
561   case  SMESH::SMESH_MeshEditor::POINT:
562     aTrsf.SetMirror( P );
563     break;
564   case  SMESH::SMESH_MeshEditor::AXIS:
565     aTrsf.SetMirror( gp_Ax1( P, V ));
566     break;
567   default:
568     aTrsf.SetMirror( gp_Ax2( P, V ));
569   }
570
571   ::SMESH_MeshEditor anEditor( _myMesh );
572   anEditor.Transform (elements, aTrsf, theCopy);
573 }
574
575 //=======================================================================
576 //function : MirrorObject
577 //purpose  : 
578 //=======================================================================
579
580 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr           theObject,
581                                       const SMESH::AxisStruct &           theAxis,
582                                       SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
583                                       CORBA::Boolean                      theCopy)
584 {
585   SMESH::long_array_var anElementsId = theObject->GetIDs();
586   Mirror(anElementsId, theAxis, theMirrorType, theCopy);
587 }
588
589 //=======================================================================
590 //function : Translate
591 //purpose  : 
592 //=======================================================================
593
594 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
595                                    const SMESH::DirStruct &   theVector,
596                                    CORBA::Boolean            theCopy)
597 {
598   SMESHDS_Mesh* aMesh = GetMeshDS();
599
600   set<const SMDS_MeshElement*> elements;
601   for (int i = 0; i < theIDsOfElements.length(); i++)
602   {
603     CORBA::Long index = theIDsOfElements[i];
604     const SMDS_MeshElement * elem = aMesh->FindElement(index);
605     if ( elem )
606       elements.insert( elem );
607   }
608   gp_Trsf aTrsf;
609   const SMESH::PointStruct * P = &theVector.PS;
610   aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
611
612   ::SMESH_MeshEditor anEditor( _myMesh );
613   anEditor.Transform (elements, aTrsf, theCopy);
614 }
615
616 //=======================================================================
617 //function : TranslateObject
618 //purpose  : 
619 //=======================================================================
620
621 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
622                                          const SMESH::DirStruct &  theVector,
623                                          CORBA::Boolean            theCopy)
624 {
625   SMESH::long_array_var anElementsId = theObject->GetIDs();
626   Translate(anElementsId, theVector, theCopy);
627 }
628
629 //=======================================================================
630 //function : Rotate
631 //purpose  : 
632 //=======================================================================
633
634 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
635                                 const SMESH::AxisStruct &  theAxis,
636                                 CORBA::Double             theAngle,
637                                 CORBA::Boolean            theCopy)
638 {
639   SMESHDS_Mesh* aMesh = GetMeshDS();
640
641   set<const SMDS_MeshElement*> elements;
642   for (int i = 0; i < theIDsOfElements.length(); i++)
643   {
644     CORBA::Long index = theIDsOfElements[i];
645     const SMDS_MeshElement * elem = aMesh->FindElement(index);
646     if ( elem )
647       elements.insert( elem );
648   }
649   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
650   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
651
652   gp_Trsf aTrsf;
653   aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
654   
655
656   ::SMESH_MeshEditor anEditor( _myMesh );
657   anEditor.Transform (elements, aTrsf, theCopy);
658 }
659
660 //=======================================================================
661 //function : RotateObject
662 //purpose  : 
663 //=======================================================================
664
665 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
666                                       const SMESH::AxisStruct & theAxis,
667                                       CORBA::Double             theAngle,
668                                       CORBA::Boolean            theCopy)
669 {
670   SMESH::long_array_var anElementsId = theObject->GetIDs();
671   Rotate(anElementsId, theAxis, theAngle, theCopy);
672 }
673
674 //=======================================================================
675 //function : FindCoincidentNodes
676 //purpose  : 
677 //=======================================================================
678
679 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
680                                               SMESH::array_of_long_array_out GroupsOfNodes)
681 {
682   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
683   ::SMESH_MeshEditor anEditor( _myMesh );
684   anEditor.FindCoincidentNodes( Tolerance, aListOfListOfNodes );
685
686   GroupsOfNodes = new SMESH::array_of_long_array;
687   GroupsOfNodes->length( aListOfListOfNodes.size() );
688   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
689   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
690   {
691     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
692     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
693     SMESH::long_array& aGroup = GroupsOfNodes[ i ];
694     aGroup.length( aListOfNodes.size() );
695     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
696       aGroup[ j ] = (*lIt)->GetID();
697   }
698 }
699
700 //=======================================================================
701 //function : MergeNodes
702 //purpose  : 
703 //=======================================================================
704
705 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
706 {
707   SMESHDS_Mesh* aMesh = GetMeshDS();
708
709   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
710   list<const SMDS_MeshElement*> elements;
711   for (int i = 0; i < GroupsOfNodes.length(); i++)
712   {
713     const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
714     aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
715     list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
716     for ( int j = 0; j < aNodeGroup.length(); j++ )
717     {
718       CORBA::Long index = aNodeGroup[ j ];
719       const SMDS_MeshNode * node = aMesh->FindNode(index);
720       if ( node )
721         aListOfNodes.push_back( node );
722     }
723     if ( aListOfNodes.size() < 2 )
724       aListOfListOfNodes.pop_back();
725   }
726   ::SMESH_MeshEditor anEditor( _myMesh );
727   anEditor.MergeNodes( aListOfListOfNodes );
728 }
729
730 //=======================================================================
731 //function : MergeEqualElements
732 //purpose  : 
733 //=======================================================================
734
735 void SMESH_MeshEditor_i::MergeEqualElements()
736 {
737   ::SMESH_MeshEditor anEditor( _myMesh );
738   anEditor.MergeEqualElements();
739 }
740
741 //=======================================================================
742 //function : operator
743 //purpose  : 
744 //=======================================================================
745
746 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
747
748 SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
749 {
750   switch ( e ) {
751   RETCASE( SEW_OK );
752   RETCASE( SEW_BORDER1_NOT_FOUND );
753   RETCASE( SEW_BORDER2_NOT_FOUND );
754   RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
755   RETCASE( SEW_BAD_SIDE_NODES );
756   RETCASE( SEW_VOLUMES_TO_SPLIT );
757   RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
758   RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
759   RETCASE( SEW_BAD_SIDE1_NODES );
760   RETCASE( SEW_BAD_SIDE2_NODES );
761   }
762   return SMESH::SMESH_MeshEditor::SEW_OK;
763 }
764
765 //=======================================================================
766 //function : SewFreeBorders
767 //purpose  : 
768 //=======================================================================
769
770 SMESH::SMESH_MeshEditor::Sew_Error
771   SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
772                                      CORBA::Long SecondNodeID1,
773                                      CORBA::Long LastNodeID1,
774                                      CORBA::Long FirstNodeID2,
775                                      CORBA::Long SecondNodeID2,
776                                      CORBA::Long LastNodeID2)
777 {
778   SMESHDS_Mesh* aMesh = GetMeshDS();
779
780   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
781   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
782   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
783   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
784   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
785   const SMDS_MeshNode* aSide2ThirdNode   = aMesh->FindNode( LastNodeID2   );
786
787   if (!aBorderFirstNode ||
788       !aBorderSecondNode||
789       !aBorderLastNode)
790     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
791   if (!aSide2FirstNode  ||
792       !aSide2SecondNode ||
793       !aSide2ThirdNode)
794     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
795
796   ::SMESH_MeshEditor anEditor( _myMesh );
797   return convError( anEditor.SewFreeBorder (aBorderFirstNode,
798                                             aBorderSecondNode,
799                                             aBorderLastNode,
800                                             aSide2FirstNode,
801                                             aSide2SecondNode,
802                                             aSide2ThirdNode,
803                                             true));
804 }
805
806 //=======================================================================
807 //function : SewConformFreeBorders
808 //purpose  : 
809 //=======================================================================
810
811 SMESH::SMESH_MeshEditor::Sew_Error
812   SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
813                                             CORBA::Long SecondNodeID1,
814                                             CORBA::Long LastNodeID1,
815                                             CORBA::Long FirstNodeID2,
816                                             CORBA::Long SecondNodeID2)
817 {
818   SMESHDS_Mesh* aMesh = GetMeshDS();
819
820   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
821   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
822   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
823   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
824   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
825   const SMDS_MeshNode* aSide2ThirdNode   = 0;
826
827   if (!aBorderFirstNode ||
828       !aBorderSecondNode||
829       !aBorderLastNode )
830     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
831   if (!aSide2FirstNode  ||
832       !aSide2SecondNode)
833     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
834
835   ::SMESH_MeshEditor anEditor( _myMesh );
836   return convError( anEditor.SewFreeBorder (aBorderFirstNode,
837                                             aBorderSecondNode,
838                                             aBorderLastNode,
839                                             aSide2FirstNode,
840                                             aSide2SecondNode,
841                                             aSide2ThirdNode,
842                                             true ));
843 }
844
845 //=======================================================================
846 //function : SewBorderToSide
847 //purpose  : 
848 //=======================================================================
849
850 SMESH::SMESH_MeshEditor::Sew_Error
851   SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
852                                       CORBA::Long SecondNodeIDOnFreeBorder,
853                                       CORBA::Long LastNodeIDOnFreeBorder,
854                                       CORBA::Long FirstNodeIDOnSide,
855                                       CORBA::Long LastNodeIDOnSide)
856 {
857   SMESHDS_Mesh* aMesh = GetMeshDS();
858
859   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeIDOnFreeBorder  );
860   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
861   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeIDOnFreeBorder   );
862   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeIDOnSide  );
863   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( LastNodeIDOnSide );
864   const SMDS_MeshNode* aSide2ThirdNode   = 0;
865
866   if (!aBorderFirstNode ||
867       !aBorderSecondNode||
868       !aBorderLastNode  )
869     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
870   if (!aSide2FirstNode  ||
871       !aSide2SecondNode)
872     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
873
874   ::SMESH_MeshEditor anEditor( _myMesh );
875   return convError( anEditor.SewFreeBorder (aBorderFirstNode,
876                                             aBorderSecondNode,
877                                             aBorderLastNode,
878                                             aSide2FirstNode,
879                                             aSide2SecondNode,
880                                             aSide2ThirdNode,
881                                             false));
882 }
883
884 //=======================================================================
885 //function : SewSideElements
886 //purpose  : 
887 //=======================================================================
888
889 SMESH::SMESH_MeshEditor::Sew_Error
890   SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
891                                       const SMESH::long_array& IDsOfSide2Elements,
892                                       CORBA::Long NodeID1OfSide1ToMerge,
893                                       CORBA::Long NodeID1OfSide2ToMerge,
894                                       CORBA::Long NodeID2OfSide1ToMerge,
895                                       CORBA::Long NodeID2OfSide2ToMerge)
896 {
897   SMESHDS_Mesh* aMesh = GetMeshDS();
898
899   const SMDS_MeshNode* aFirstNode1ToMerge  = aMesh->FindNode( NodeID1OfSide1ToMerge );
900   const SMDS_MeshNode* aFirstNode2ToMerge  = aMesh->FindNode( NodeID1OfSide2ToMerge );
901   const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
902   const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
903
904   if (!aFirstNode1ToMerge ||
905       !aFirstNode2ToMerge )
906     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
907   if (!aSecondNode1ToMerge||
908       !aSecondNode2ToMerge)
909     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
910
911   set<const SMDS_MeshElement*> aSide1Elems, aSide2Elems;
912   for (int i = 0; i < IDsOfSide1Elements.length(); i++)
913   {
914     CORBA::Long index = IDsOfSide1Elements[i];
915     const SMDS_MeshElement * elem = aMesh->FindElement(index);
916     if ( elem )
917       aSide1Elems.insert( elem );
918   }
919   for (int i = 0; i < IDsOfSide2Elements.length(); i++)
920   {
921     CORBA::Long index = IDsOfSide2Elements[i];
922     const SMDS_MeshElement * elem = aMesh->FindElement(index);
923     if ( elem )
924       aSide2Elems.insert( elem );
925   }
926   ::SMESH_MeshEditor anEditor( _myMesh );
927   return convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
928                                               aFirstNode1ToMerge,
929                                               aFirstNode2ToMerge,
930                                               aSecondNode1ToMerge,
931                                               aSecondNode2ToMerge));
932 }