Salome HOME
f27cc396e78dff14f7ad4ce9ccab84e7950c2cd2
[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   return 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   return 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   return 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 : ExtrusionAlongPath
538 //purpose  : 
539 //=======================================================================
540
541 void SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
542                                             SMESH::SMESH_Mesh_ptr       thePathMesh,
543                                             GEOM::GEOM_Object_ptr       thePathShape,
544                                             CORBA::Long                 theNodeStart,
545                                             CORBA::Boolean              theHasAngles,
546                                             const SMESH::double_array & theAngles,
547                                             CORBA::Boolean              theHasRefPoint,
548                                             const SMESH::PointStruct &  theRefPoint)
549 {
550   SMESHDS_Mesh*  aMesh = GetMeshDS();
551
552   if ( thePathMesh->_is_nil() || thePathShape->_is_nil() )
553     return;
554
555   SMESH_Mesh_i* aMeshImp = dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( thePathMesh ).in() );
556   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
557   SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
558
559   if ( !aSubMesh )
560     return;
561
562   SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
563   if ( !nodeStart )
564     return;
565
566   set<const SMDS_MeshElement*> elements;
567   for (int i = 0; i < theIDsOfElements.length(); i++)
568   {
569     CORBA::Long index = theIDsOfElements[i];
570     const SMDS_MeshElement * elem = aMesh->FindElement(index);
571     if ( elem )
572       elements.insert( elem );
573   }
574
575   list<double> angles;
576   for (int i = 0; i < theAngles.length(); i++)
577   {
578     angles.push_back( theAngles[i] );
579   }
580
581   gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
582
583   ::SMESH_MeshEditor anEditor( _myMesh );
584   int res = anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart, theHasAngles, angles, theHasRefPoint, refPnt );
585 }
586
587 //=======================================================================
588 //function : ExtrusionAlongPathObject
589 //purpose  : 
590 //=======================================================================
591
592 void SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObject,
593                                                   SMESH::SMESH_Mesh_ptr       thePathMesh,
594                                                   GEOM::GEOM_Object_ptr       thePathShape,
595                                                   CORBA::Long                 theNodeStart,
596                                                   CORBA::Boolean              theHasAngles,
597                                                   const SMESH::double_array & theAngles,
598                                                   CORBA::Boolean              theHasRefPoint,
599                                                   const SMESH::PointStruct &  theRefPoint)
600 {
601   SMESH::long_array_var anElementsId = theObject->GetIDs();
602   ExtrusionAlongPath( anElementsId, thePathMesh, thePathShape, theNodeStart, theHasAngles, theAngles, theHasRefPoint, theRefPoint );
603 }
604
605 //=======================================================================
606 //function : Mirror
607 //purpose  : 
608 //=======================================================================
609
610 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElements,
611                                 const SMESH::AxisStruct &            theAxis,
612                                 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
613                                 CORBA::Boolean                      theCopy)
614 {
615   SMESHDS_Mesh* aMesh = GetMeshDS();
616
617   set<const SMDS_MeshElement*> elements;
618   for (int i = 0; i < theIDsOfElements.length(); i++)
619   {
620     CORBA::Long index = theIDsOfElements[i];
621     const SMDS_MeshElement * elem = aMesh->FindElement(index);
622     if ( elem )
623       elements.insert( elem );
624   }
625   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
626   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
627
628   gp_Trsf aTrsf;
629   switch ( theMirrorType ) {
630   case  SMESH::SMESH_MeshEditor::POINT:
631     aTrsf.SetMirror( P );
632     break;
633   case  SMESH::SMESH_MeshEditor::AXIS:
634     aTrsf.SetMirror( gp_Ax1( P, V ));
635     break;
636   default:
637     aTrsf.SetMirror( gp_Ax2( P, V ));
638   }
639
640   ::SMESH_MeshEditor anEditor( _myMesh );
641   anEditor.Transform (elements, aTrsf, theCopy);
642 }
643
644 //=======================================================================
645 //function : MirrorObject
646 //purpose  : 
647 //=======================================================================
648
649 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr           theObject,
650                                       const SMESH::AxisStruct &           theAxis,
651                                       SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
652                                       CORBA::Boolean                      theCopy)
653 {
654   SMESH::long_array_var anElementsId = theObject->GetIDs();
655   Mirror(anElementsId, theAxis, theMirrorType, theCopy);
656 }
657
658 //=======================================================================
659 //function : Translate
660 //purpose  : 
661 //=======================================================================
662
663 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
664                                    const SMESH::DirStruct &   theVector,
665                                    CORBA::Boolean            theCopy)
666 {
667   SMESHDS_Mesh* aMesh = GetMeshDS();
668
669   set<const SMDS_MeshElement*> elements;
670   for (int i = 0; i < theIDsOfElements.length(); i++)
671   {
672     CORBA::Long index = theIDsOfElements[i];
673     const SMDS_MeshElement * elem = aMesh->FindElement(index);
674     if ( elem )
675       elements.insert( elem );
676   }
677   gp_Trsf aTrsf;
678   const SMESH::PointStruct * P = &theVector.PS;
679   aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
680
681   ::SMESH_MeshEditor anEditor( _myMesh );
682   anEditor.Transform (elements, aTrsf, theCopy);
683 }
684
685 //=======================================================================
686 //function : TranslateObject
687 //purpose  : 
688 //=======================================================================
689
690 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
691                                          const SMESH::DirStruct &  theVector,
692                                          CORBA::Boolean            theCopy)
693 {
694   SMESH::long_array_var anElementsId = theObject->GetIDs();
695   Translate(anElementsId, theVector, theCopy);
696 }
697
698 //=======================================================================
699 //function : Rotate
700 //purpose  : 
701 //=======================================================================
702
703 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
704                                 const SMESH::AxisStruct &  theAxis,
705                                 CORBA::Double             theAngle,
706                                 CORBA::Boolean            theCopy)
707 {
708   SMESHDS_Mesh* aMesh = GetMeshDS();
709
710   set<const SMDS_MeshElement*> elements;
711   for (int i = 0; i < theIDsOfElements.length(); i++)
712   {
713     CORBA::Long index = theIDsOfElements[i];
714     const SMDS_MeshElement * elem = aMesh->FindElement(index);
715     if ( elem )
716       elements.insert( elem );
717   }
718   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
719   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
720
721   gp_Trsf aTrsf;
722   aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
723   
724
725   ::SMESH_MeshEditor anEditor( _myMesh );
726   anEditor.Transform (elements, aTrsf, theCopy);
727 }
728
729 //=======================================================================
730 //function : RotateObject
731 //purpose  : 
732 //=======================================================================
733
734 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
735                                       const SMESH::AxisStruct & theAxis,
736                                       CORBA::Double             theAngle,
737                                       CORBA::Boolean            theCopy)
738 {
739   SMESH::long_array_var anElementsId = theObject->GetIDs();
740   Rotate(anElementsId, theAxis, theAngle, theCopy);
741 }
742
743 //=======================================================================
744 //function : FindCoincidentNodes
745 //purpose  : 
746 //=======================================================================
747
748 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
749                                               SMESH::array_of_long_array_out GroupsOfNodes)
750 {
751   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
752   ::SMESH_MeshEditor anEditor( _myMesh );
753   set<const SMDS_MeshNode*> nodes; // no input nodes
754   anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
755
756   GroupsOfNodes = new SMESH::array_of_long_array;
757   GroupsOfNodes->length( aListOfListOfNodes.size() );
758   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
759   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
760   {
761     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
762     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
763     SMESH::long_array& aGroup = GroupsOfNodes[ i ];
764     aGroup.length( aListOfNodes.size() );
765     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
766       aGroup[ j ] = (*lIt)->GetID();
767   }
768 }
769
770 //=======================================================================
771 //function : MergeNodes
772 //purpose  : 
773 //=======================================================================
774
775 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
776 {
777   SMESHDS_Mesh* aMesh = GetMeshDS();
778
779   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
780   list<const SMDS_MeshElement*> elements;
781   for (int i = 0; i < GroupsOfNodes.length(); i++)
782   {
783     const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
784     aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
785     list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
786     for ( int j = 0; j < aNodeGroup.length(); j++ )
787     {
788       CORBA::Long index = aNodeGroup[ j ];
789       const SMDS_MeshNode * node = aMesh->FindNode(index);
790       if ( node )
791         aListOfNodes.push_back( node );
792     }
793     if ( aListOfNodes.size() < 2 )
794       aListOfListOfNodes.pop_back();
795   }
796   ::SMESH_MeshEditor anEditor( _myMesh );
797   anEditor.MergeNodes( aListOfListOfNodes );
798 }
799
800 //=======================================================================
801 //function : MergeEqualElements
802 //purpose  : 
803 //=======================================================================
804
805 void SMESH_MeshEditor_i::MergeEqualElements()
806 {
807   ::SMESH_MeshEditor anEditor( _myMesh );
808   anEditor.MergeEqualElements();
809 }
810
811 //=======================================================================
812 //function : operator
813 //purpose  : 
814 //=======================================================================
815
816 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
817
818 SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
819 {
820   switch ( e ) {
821   RETCASE( SEW_OK );
822   RETCASE( SEW_BORDER1_NOT_FOUND );
823   RETCASE( SEW_BORDER2_NOT_FOUND );
824   RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
825   RETCASE( SEW_BAD_SIDE_NODES );
826   RETCASE( SEW_VOLUMES_TO_SPLIT );
827   RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
828   RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
829   RETCASE( SEW_BAD_SIDE1_NODES );
830   RETCASE( SEW_BAD_SIDE2_NODES );
831   }
832   return SMESH::SMESH_MeshEditor::SEW_OK;
833 }
834
835 //=======================================================================
836 //function : SewFreeBorders
837 //purpose  : 
838 //=======================================================================
839
840 SMESH::SMESH_MeshEditor::Sew_Error
841   SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
842                                      CORBA::Long SecondNodeID1,
843                                      CORBA::Long LastNodeID1,
844                                      CORBA::Long FirstNodeID2,
845                                      CORBA::Long SecondNodeID2,
846                                      CORBA::Long LastNodeID2)
847 {
848   SMESHDS_Mesh* aMesh = GetMeshDS();
849
850   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
851   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
852   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
853   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
854   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
855   const SMDS_MeshNode* aSide2ThirdNode   = aMesh->FindNode( LastNodeID2   );
856
857   if (!aBorderFirstNode ||
858       !aBorderSecondNode||
859       !aBorderLastNode)
860     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
861   if (!aSide2FirstNode  ||
862       !aSide2SecondNode ||
863       !aSide2ThirdNode)
864     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
865
866   ::SMESH_MeshEditor anEditor( _myMesh );
867   return convError( anEditor.SewFreeBorder (aBorderFirstNode,
868                                             aBorderSecondNode,
869                                             aBorderLastNode,
870                                             aSide2FirstNode,
871                                             aSide2SecondNode,
872                                             aSide2ThirdNode,
873                                             true));
874 }
875
876 //=======================================================================
877 //function : SewConformFreeBorders
878 //purpose  : 
879 //=======================================================================
880
881 SMESH::SMESH_MeshEditor::Sew_Error
882   SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
883                                             CORBA::Long SecondNodeID1,
884                                             CORBA::Long LastNodeID1,
885                                             CORBA::Long FirstNodeID2,
886                                             CORBA::Long SecondNodeID2)
887 {
888   SMESHDS_Mesh* aMesh = GetMeshDS();
889
890   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
891   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
892   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
893   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
894   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
895   const SMDS_MeshNode* aSide2ThirdNode   = 0;
896
897   if (!aBorderFirstNode ||
898       !aBorderSecondNode||
899       !aBorderLastNode )
900     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
901   if (!aSide2FirstNode  ||
902       !aSide2SecondNode)
903     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
904
905   ::SMESH_MeshEditor anEditor( _myMesh );
906   return convError( anEditor.SewFreeBorder (aBorderFirstNode,
907                                             aBorderSecondNode,
908                                             aBorderLastNode,
909                                             aSide2FirstNode,
910                                             aSide2SecondNode,
911                                             aSide2ThirdNode,
912                                             true ));
913 }
914
915 //=======================================================================
916 //function : SewBorderToSide
917 //purpose  : 
918 //=======================================================================
919
920 SMESH::SMESH_MeshEditor::Sew_Error
921   SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
922                                       CORBA::Long SecondNodeIDOnFreeBorder,
923                                       CORBA::Long LastNodeIDOnFreeBorder,
924                                       CORBA::Long FirstNodeIDOnSide,
925                                       CORBA::Long LastNodeIDOnSide)
926 {
927   SMESHDS_Mesh* aMesh = GetMeshDS();
928
929   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeIDOnFreeBorder  );
930   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
931   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeIDOnFreeBorder   );
932   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeIDOnSide  );
933   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( LastNodeIDOnSide );
934   const SMDS_MeshNode* aSide2ThirdNode   = 0;
935
936   if (!aBorderFirstNode ||
937       !aBorderSecondNode||
938       !aBorderLastNode  )
939     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
940   if (!aSide2FirstNode  ||
941       !aSide2SecondNode)
942     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
943
944   ::SMESH_MeshEditor anEditor( _myMesh );
945   return convError( anEditor.SewFreeBorder (aBorderFirstNode,
946                                             aBorderSecondNode,
947                                             aBorderLastNode,
948                                             aSide2FirstNode,
949                                             aSide2SecondNode,
950                                             aSide2ThirdNode,
951                                             false));
952 }
953
954 //=======================================================================
955 //function : SewSideElements
956 //purpose  : 
957 //=======================================================================
958
959 SMESH::SMESH_MeshEditor::Sew_Error
960   SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
961                                       const SMESH::long_array& IDsOfSide2Elements,
962                                       CORBA::Long NodeID1OfSide1ToMerge,
963                                       CORBA::Long NodeID1OfSide2ToMerge,
964                                       CORBA::Long NodeID2OfSide1ToMerge,
965                                       CORBA::Long NodeID2OfSide2ToMerge)
966 {
967   SMESHDS_Mesh* aMesh = GetMeshDS();
968
969   const SMDS_MeshNode* aFirstNode1ToMerge  = aMesh->FindNode( NodeID1OfSide1ToMerge );
970   const SMDS_MeshNode* aFirstNode2ToMerge  = aMesh->FindNode( NodeID1OfSide2ToMerge );
971   const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
972   const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
973
974   if (!aFirstNode1ToMerge ||
975       !aFirstNode2ToMerge )
976     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
977   if (!aSecondNode1ToMerge||
978       !aSecondNode2ToMerge)
979     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
980
981   set<const SMDS_MeshElement*> aSide1Elems, aSide2Elems;
982   for (int i = 0; i < IDsOfSide1Elements.length(); i++)
983   {
984     CORBA::Long index = IDsOfSide1Elements[i];
985     const SMDS_MeshElement * elem = aMesh->FindElement(index);
986     if ( elem )
987       aSide1Elems.insert( elem );
988   }
989   for (int i = 0; i < IDsOfSide2Elements.length(); i++)
990   {
991     CORBA::Long index = IDsOfSide2Elements[i];
992     const SMDS_MeshElement * elem = aMesh->FindElement(index);
993     if ( elem )
994       aSide2Elems.insert( elem );
995   }
996   ::SMESH_MeshEditor anEditor( _myMesh );
997   return convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
998                                               aFirstNode1ToMerge,
999                                               aFirstNode2ToMerge,
1000                                               aSecondNode1ToMerge,
1001                                               aSecondNode2ToMerge));
1002 }