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