Salome HOME
Advanced feature for sewing - polygons creation instead of splitting.
[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  *  AddFace
128  */
129 //=============================================================================
130
131 CORBA::Boolean SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
132 {
133   int NbNodes = IDsOfNodes.length();
134   if (NbNodes < 3)
135   {
136     return false;
137   }
138
139   std::vector<const SMDS_MeshNode*> nodes (NbNodes);
140   //const SMDS_MeshNode* nodes [NbNodes];
141   for (int i = 0; i < NbNodes; i++)
142     nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
143
144   if (NbNodes == 3)
145   {
146     GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
147   }
148   else if (NbNodes == 4)
149   {
150     GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
151   }
152   else
153   {
154     GetMeshDS()->AddPolygonalFace(nodes);
155   }
156   return true;
157 };
158
159 //=============================================================================
160 /*!
161  *  
162  */
163 //=============================================================================
164
165 CORBA::Boolean SMESH_MeshEditor_i::AddVolume(const SMESH::
166         long_array & IDsOfNodes)
167 {
168         int NbNodes = IDsOfNodes.length();
169         const SMDS_MeshNode* n[8];
170         for(int i=0;i<NbNodes;i++) n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
171
172         switch(NbNodes)
173         {
174         case 4:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
175         case 5:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
176         case 6:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
177         case 8:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
178         }
179         return true;
180 };
181
182 //=============================================================================
183 /*!
184  *  AddPolyhedralVolume
185  */
186 //=============================================================================
187 CORBA::Boolean SMESH_MeshEditor_i::AddPolyhedralVolume
188                                    (const SMESH::long_array & IDsOfNodes,
189                                     const SMESH::long_array & Quantities)
190 {
191   int NbNodes = IDsOfNodes.length();
192   std::vector<const SMDS_MeshNode*> n (NbNodes);
193   //const SMDS_MeshNode* n [NbNodes];
194   for (int i = 0; i < NbNodes; i++)
195     n[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
196
197   int NbFaces = Quantities.length();
198   std::vector<int> q (NbFaces);
199   //int q [NbFaces];
200   for (int j = 0; j < NbFaces; j++)
201     q[j] = Quantities[j];
202
203   GetMeshDS()->AddPolyhedralVolume(n, q);
204   return true;
205 };
206
207 //=============================================================================
208 /*!
209  *  AddPolyhedralVolumeByFaces
210  */
211 //=============================================================================
212 CORBA::Boolean SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces
213                                    (const SMESH::long_array & IdsOfFaces)
214 {
215   int NbFaces = IdsOfFaces.length();
216   std::vector<const SMDS_MeshFace*> faces (NbFaces);
217   for (int i = 0; i < NbFaces; i++)
218     faces[i] = (SMDS_MeshFace *)GetMeshDS()->FindElement(IdsOfFaces[i]);
219
220   //GetMeshDS()->AddPolyhedralVolumeByFaces(faces);
221   //return true;
222   return false;
223 };
224
225 //=============================================================================
226 /*!
227  *  
228  */
229 //=============================================================================
230
231 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
232                                             CORBA::Double x,
233                                             CORBA::Double y,
234                                             CORBA::Double z)
235 {
236   const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
237   if ( !node )
238     return false;
239   
240   GetMeshDS()->MoveNode(node, x, y, z);
241
242   return true;
243 }
244
245 //=============================================================================
246 /*!
247  *  
248  */
249 //=============================================================================
250
251 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
252                                                CORBA::Long NodeID2)
253 {
254   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
255   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
256   if ( !n1 || !n2 )
257     return false;
258
259   ::SMESH_MeshEditor aMeshEditor( _myMesh );
260   return aMeshEditor.InverseDiag ( n1, n2 );
261 }
262
263 //=============================================================================
264 /*!
265  *  
266  */
267 //=============================================================================
268
269 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
270                                               CORBA::Long NodeID2)
271 {
272   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
273   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
274   if ( !n1 || !n2 )
275     return false;
276
277   ::SMESH_MeshEditor aMeshEditor( _myMesh );
278   return aMeshEditor.DeleteDiag ( n1, n2 );
279 }
280
281 //=============================================================================
282 /*!
283  *  
284  */
285 //=============================================================================
286
287 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
288 {
289   ::SMESH_MeshEditor anEditor( _myMesh );
290   for (int i = 0; i < IDsOfElements.length(); i++)
291   {
292     CORBA::Long index = IDsOfElements[i];
293     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
294     if ( elem )
295       anEditor.Reorient( elem );
296   }
297   return true;
298 }
299
300
301 //=============================================================================
302 /*!
303  *  
304  */
305 //=============================================================================
306
307 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
308 {
309   SMESH::long_array_var anElementsId = theObject->GetIDs();
310   return Reorient(anElementsId);
311 }
312
313 //=============================================================================
314 /*!
315  *  
316  */
317 //=============================================================================
318
319 CORBA::Boolean
320   SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfElements,
321                                  SMESH::NumericalFunctor_ptr Criterion,
322                                  CORBA::Double               MaxAngle)
323 {
324   set<const SMDS_MeshElement*> faces;
325   for (int i = 0; i < IDsOfElements.length(); i++)
326   {
327     CORBA::Long index = IDsOfElements[i];
328     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
329     if ( elem && elem->GetType() == SMDSAbs_Face)
330       faces.insert( elem );
331   }
332   SMESH::NumericalFunctor_i* aNumericalFunctor = 
333     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
334   SMESH::Controls::NumericalFunctorPtr aCrit;
335   if ( !aNumericalFunctor )
336     aCrit.reset( new SMESH::Controls::AspectRatio() );
337   else
338     aCrit = aNumericalFunctor->GetNumericalFunctor();
339
340   ::SMESH_MeshEditor anEditor( _myMesh );
341   return anEditor.TriToQuad( faces, aCrit, MaxAngle );
342 }
343
344 //=============================================================================
345 /*!
346  *  
347  */
348 //=============================================================================
349
350 CORBA::Boolean
351   SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr   theObject,
352                                        SMESH::NumericalFunctor_ptr Criterion,
353                                        CORBA::Double               MaxAngle)
354 {
355   SMESH::long_array_var anElementsId = theObject->GetIDs();
356   return TriToQuad(anElementsId, Criterion, MaxAngle);
357 }
358
359 //=============================================================================
360 /*!
361  *  
362  */
363 //=============================================================================
364
365 CORBA::Boolean
366   SMESH_MeshEditor_i::QuadToTri(const SMESH::long_array &   IDsOfElements,
367                                 SMESH::NumericalFunctor_ptr Criterion)
368 {
369   set<const SMDS_MeshElement*> faces;
370   for (int i = 0; i < IDsOfElements.length(); i++)
371   {
372     CORBA::Long index = IDsOfElements[i];
373     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
374     if ( elem && elem->GetType() == SMDSAbs_Face)
375       faces.insert( elem );
376   }
377   SMESH::NumericalFunctor_i* aNumericalFunctor = 
378     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
379   SMESH::Controls::NumericalFunctorPtr aCrit;
380   if ( !aNumericalFunctor )
381     aCrit.reset( new SMESH::Controls::AspectRatio() );
382   else
383     aCrit = aNumericalFunctor->GetNumericalFunctor();
384
385   ::SMESH_MeshEditor anEditor( _myMesh );
386   return anEditor.QuadToTri( faces, aCrit );
387 }
388
389 //=============================================================================
390 /*!
391  *  
392  */
393 //=============================================================================
394
395 CORBA::Boolean
396   SMESH_MeshEditor_i::SplitQuad(const SMESH::long_array & IDsOfElements,
397                                 CORBA::Boolean            Diag13)
398 {
399   set<const SMDS_MeshElement*> faces;
400   for (int i = 0; i < IDsOfElements.length(); i++)
401   {
402     CORBA::Long index = IDsOfElements[i];
403     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
404     if ( elem && elem->GetType() == SMDSAbs_Face)
405       faces.insert( elem );
406   }
407
408   ::SMESH_MeshEditor anEditor( _myMesh );
409   return anEditor.QuadToTri( faces, Diag13 );
410 }
411
412 //=============================================================================
413 /*!
414  *  
415  */
416 //=============================================================================
417
418 CORBA::Boolean
419   SMESH_MeshEditor_i::SplitQuadObject(SMESH::SMESH_IDSource_ptr theObject,
420                                       CORBA::Boolean            Diag13)
421 {
422   SMESH::long_array_var anElementsId = theObject->GetIDs();
423   return SplitQuad(anElementsId, Diag13);
424 }
425
426 //=============================================================================
427 /*!
428  *  
429  */
430 //=============================================================================
431
432 CORBA::Boolean
433   SMESH_MeshEditor_i::Smooth(const SMESH::long_array &              IDsOfElements,
434                              const SMESH::long_array &              IDsOfFixedNodes,
435                              CORBA::Long                            MaxNbOfIterations,
436                              CORBA::Double                          MaxAspectRatio,
437                              SMESH::SMESH_MeshEditor::Smooth_Method Method)
438 {
439   SMESHDS_Mesh* aMesh = GetMeshDS();
440
441   set<const SMDS_MeshElement*> elements;
442   for (int i = 0; i < IDsOfElements.length(); i++)
443   {
444     CORBA::Long index = IDsOfElements[i];
445     const SMDS_MeshElement * elem = aMesh->FindElement(index);
446     if ( elem && elem->GetType() == SMDSAbs_Face)
447       elements.insert( elem );
448   }
449
450   set<const SMDS_MeshNode*> fixedNodes;
451   for (int i = 0; i < IDsOfFixedNodes.length(); i++)
452   {
453     CORBA::Long index = IDsOfFixedNodes[i];
454     const SMDS_MeshNode * node = aMesh->FindNode(index);
455     if ( node )
456       fixedNodes.insert( node );
457   }
458   ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
459   if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
460      method = ::SMESH_MeshEditor::CENTROIDAL;
461
462   ::SMESH_MeshEditor anEditor( _myMesh );
463   anEditor.Smooth( elements, fixedNodes, method, MaxNbOfIterations, MaxAspectRatio );
464
465   return true;
466 }
467
468 //=============================================================================
469 /*!
470  *  
471  */
472 //=============================================================================
473
474 CORBA::Boolean
475   SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr              theObject,
476                                    const SMESH::long_array &              IDsOfFixedNodes,
477                                    CORBA::Long                            MaxNbOfIterations,
478                                    CORBA::Double                          MaxAspectRatio,
479                                    SMESH::SMESH_MeshEditor::Smooth_Method Method)
480 {
481   SMESH::long_array_var anElementsId = theObject->GetIDs();
482   return Smooth(anElementsId, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method);
483 }
484
485 //=============================================================================
486 /*!
487  *  
488  */
489 //=============================================================================
490
491 void SMESH_MeshEditor_i::RenumberNodes()
492 {
493   GetMeshDS()->Renumber( true );
494 }
495
496 //=============================================================================
497 /*!
498  *  
499  */
500 //=============================================================================
501
502 void SMESH_MeshEditor_i::RenumberElements()
503 {
504   GetMeshDS()->Renumber( false );
505 }
506
507 //=======================================================================
508 //function : RotationSweep
509 //purpose  : 
510 //=======================================================================
511
512 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
513                                        const SMESH::AxisStruct &  theAxis,
514                                        CORBA::Double             theAngleInRadians,
515                                        CORBA::Long               theNbOfSteps,
516                                        CORBA::Double             theTolerance)
517 {
518   SMESHDS_Mesh* aMesh = GetMeshDS();
519
520   set<const SMDS_MeshElement*> elements;
521   for (int i = 0; i < theIDsOfElements.length(); i++)
522   {
523     CORBA::Long index = theIDsOfElements[i];
524     const SMDS_MeshElement * elem = aMesh->FindElement(index);
525     if ( elem )
526       elements.insert( elem );
527   }
528   gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
529               gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
530
531   ::SMESH_MeshEditor anEditor( _myMesh );
532   anEditor.RotationSweep (elements, Ax1, theAngleInRadians,
533                           theNbOfSteps, theTolerance);
534 }
535
536 //=======================================================================
537 //function : RotationSweepObject
538 //purpose  : 
539 //=======================================================================
540
541 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
542                                              const SMESH::AxisStruct & theAxis,
543                                              CORBA::Double             theAngleInRadians,
544                                              CORBA::Long               theNbOfSteps,
545                                              CORBA::Double             theTolerance)
546 {
547   SMESH::long_array_var anElementsId = theObject->GetIDs();
548   RotationSweep(anElementsId, theAxis, theAngleInRadians, theNbOfSteps, theTolerance);
549 }
550
551 //=======================================================================
552 //function : ExtrusionSweep
553 //purpose  : 
554 //=======================================================================
555
556 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
557                                         const SMESH::DirStruct &   theStepVector,
558                                         CORBA::Long               theNbOfSteps)
559 {
560   SMESHDS_Mesh* aMesh = GetMeshDS();
561
562   set<const SMDS_MeshElement*> elements;
563   for (int i = 0; i < theIDsOfElements.length(); i++)
564   {
565     CORBA::Long index = theIDsOfElements[i];
566     const SMDS_MeshElement * elem = aMesh->FindElement(index);
567     if ( elem )
568       elements.insert( elem );
569   }
570   const SMESH::PointStruct * P = &theStepVector.PS;
571   gp_Vec stepVec( P->x, P->y, P->z );
572
573   ::SMESH_MeshEditor anEditor( _myMesh );
574   anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps);
575 }
576
577
578 //=======================================================================
579 //function : ExtrusionSweepObject
580 //purpose  : 
581 //=======================================================================
582
583 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
584                                               const SMESH::DirStruct &  theStepVector,
585                                               CORBA::Long               theNbOfSteps)
586 {
587   SMESH::long_array_var anElementsId = theObject->GetIDs();
588   ExtrusionSweep(anElementsId, theStepVector, theNbOfSteps);
589 }
590
591 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
592
593 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
594 {
595   switch ( e ) {
596   RETCASE( EXTR_OK );
597   RETCASE( EXTR_NO_ELEMENTS );
598   RETCASE( EXTR_PATH_NOT_EDGE );
599   RETCASE( EXTR_BAD_PATH_SHAPE );
600   RETCASE( EXTR_BAD_STARTING_NODE );
601   RETCASE( EXTR_BAD_ANGLES_NUMBER );
602   RETCASE( EXTR_CANT_GET_TANGENT );
603   }
604   return SMESH::SMESH_MeshEditor::EXTR_OK;
605 }
606
607 //=======================================================================
608 //function : ExtrusionAlongPath
609 //purpose  : 
610 //=======================================================================
611
612 SMESH::SMESH_MeshEditor::Extrusion_Error
613   SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
614                                          SMESH::SMESH_Mesh_ptr       thePathMesh,
615                                          GEOM::GEOM_Object_ptr       thePathShape,
616                                          CORBA::Long                 theNodeStart,
617                                          CORBA::Boolean              theHasAngles,
618                                          const SMESH::double_array & theAngles,
619                                          CORBA::Boolean              theHasRefPoint,
620                                          const SMESH::PointStruct &  theRefPoint)
621 {
622   SMESHDS_Mesh*  aMesh = GetMeshDS();
623
624   if ( thePathMesh->_is_nil() || thePathShape->_is_nil() )
625     return SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
626
627   SMESH_Mesh_i* aMeshImp = dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( thePathMesh ).in() );
628   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
629   SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
630
631   if ( !aSubMesh )
632     return SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
633
634   SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
635   if ( !nodeStart )
636     return SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
637
638   set<const SMDS_MeshElement*> elements;
639   for (int i = 0; i < theIDsOfElements.length(); i++)
640   {
641     CORBA::Long index = theIDsOfElements[i];
642     const SMDS_MeshElement * elem = aMesh->FindElement(index);
643     if ( elem )
644       elements.insert( elem );
645   }
646
647   list<double> angles;
648   for (int i = 0; i < theAngles.length(); i++)
649   {
650     angles.push_back( theAngles[i] );
651   }
652
653   gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
654
655   ::SMESH_MeshEditor anEditor( _myMesh );
656   return convExtrError( anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart, theHasAngles, angles, theHasRefPoint, refPnt ) );
657 }
658
659 //=======================================================================
660 //function : ExtrusionAlongPathObject
661 //purpose  : 
662 //=======================================================================
663
664 SMESH::SMESH_MeshEditor::Extrusion_Error
665   SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObject,
666                                                SMESH::SMESH_Mesh_ptr       thePathMesh,
667                                                GEOM::GEOM_Object_ptr       thePathShape,
668                                                CORBA::Long                 theNodeStart,
669                                                CORBA::Boolean              theHasAngles,
670                                                const SMESH::double_array & theAngles,
671                                                CORBA::Boolean              theHasRefPoint,
672                                                const SMESH::PointStruct &  theRefPoint)
673 {
674   SMESH::long_array_var anElementsId = theObject->GetIDs();
675   return ExtrusionAlongPath( anElementsId, thePathMesh, thePathShape, theNodeStart, theHasAngles, theAngles, theHasRefPoint, theRefPoint );
676 }
677
678 //=======================================================================
679 //function : Mirror
680 //purpose  : 
681 //=======================================================================
682
683 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElements,
684                                 const SMESH::AxisStruct &            theAxis,
685                                 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
686                                 CORBA::Boolean                      theCopy)
687 {
688   SMESHDS_Mesh* aMesh = GetMeshDS();
689
690   set<const SMDS_MeshElement*> elements;
691   for (int i = 0; i < theIDsOfElements.length(); i++)
692   {
693     CORBA::Long index = theIDsOfElements[i];
694     const SMDS_MeshElement * elem = aMesh->FindElement(index);
695     if ( elem )
696       elements.insert( elem );
697   }
698   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
699   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
700
701   gp_Trsf aTrsf;
702   switch ( theMirrorType ) {
703   case  SMESH::SMESH_MeshEditor::POINT:
704     aTrsf.SetMirror( P );
705     break;
706   case  SMESH::SMESH_MeshEditor::AXIS:
707     aTrsf.SetMirror( gp_Ax1( P, V ));
708     break;
709   default:
710     aTrsf.SetMirror( gp_Ax2( P, V ));
711   }
712
713   ::SMESH_MeshEditor anEditor( _myMesh );
714   anEditor.Transform (elements, aTrsf, theCopy);
715 }
716
717 //=======================================================================
718 //function : MirrorObject
719 //purpose  : 
720 //=======================================================================
721
722 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr           theObject,
723                                       const SMESH::AxisStruct &           theAxis,
724                                       SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
725                                       CORBA::Boolean                      theCopy)
726 {
727   SMESH::long_array_var anElementsId = theObject->GetIDs();
728   Mirror(anElementsId, theAxis, theMirrorType, theCopy);
729 }
730
731 //=======================================================================
732 //function : Translate
733 //purpose  : 
734 //=======================================================================
735
736 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
737                                    const SMESH::DirStruct &   theVector,
738                                    CORBA::Boolean            theCopy)
739 {
740   SMESHDS_Mesh* aMesh = GetMeshDS();
741
742   set<const SMDS_MeshElement*> elements;
743   for (int i = 0; i < theIDsOfElements.length(); i++)
744   {
745     CORBA::Long index = theIDsOfElements[i];
746     const SMDS_MeshElement * elem = aMesh->FindElement(index);
747     if ( elem )
748       elements.insert( elem );
749   }
750   gp_Trsf aTrsf;
751   const SMESH::PointStruct * P = &theVector.PS;
752   aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
753
754   ::SMESH_MeshEditor anEditor( _myMesh );
755   anEditor.Transform (elements, aTrsf, theCopy);
756 }
757
758 //=======================================================================
759 //function : TranslateObject
760 //purpose  : 
761 //=======================================================================
762
763 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
764                                          const SMESH::DirStruct &  theVector,
765                                          CORBA::Boolean            theCopy)
766 {
767   SMESH::long_array_var anElementsId = theObject->GetIDs();
768   Translate(anElementsId, theVector, theCopy);
769 }
770
771 //=======================================================================
772 //function : Rotate
773 //purpose  : 
774 //=======================================================================
775
776 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
777                                 const SMESH::AxisStruct &  theAxis,
778                                 CORBA::Double             theAngle,
779                                 CORBA::Boolean            theCopy)
780 {
781   SMESHDS_Mesh* aMesh = GetMeshDS();
782
783   set<const SMDS_MeshElement*> elements;
784   for (int i = 0; i < theIDsOfElements.length(); i++)
785   {
786     CORBA::Long index = theIDsOfElements[i];
787     const SMDS_MeshElement * elem = aMesh->FindElement(index);
788     if ( elem )
789       elements.insert( elem );
790   }
791   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
792   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
793
794   gp_Trsf aTrsf;
795   aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
796   
797
798   ::SMESH_MeshEditor anEditor( _myMesh );
799   anEditor.Transform (elements, aTrsf, theCopy);
800 }
801
802 //=======================================================================
803 //function : RotateObject
804 //purpose  : 
805 //=======================================================================
806
807 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
808                                       const SMESH::AxisStruct & theAxis,
809                                       CORBA::Double             theAngle,
810                                       CORBA::Boolean            theCopy)
811 {
812   SMESH::long_array_var anElementsId = theObject->GetIDs();
813   Rotate(anElementsId, theAxis, theAngle, theCopy);
814 }
815
816 //=======================================================================
817 //function : FindCoincidentNodes
818 //purpose  : 
819 //=======================================================================
820
821 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
822                                               SMESH::array_of_long_array_out GroupsOfNodes)
823 {
824   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
825   ::SMESH_MeshEditor anEditor( _myMesh );
826   set<const SMDS_MeshNode*> nodes; // no input nodes
827   anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
828
829   GroupsOfNodes = new SMESH::array_of_long_array;
830   GroupsOfNodes->length( aListOfListOfNodes.size() );
831   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
832   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
833   {
834     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
835     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
836     SMESH::long_array& aGroup = GroupsOfNodes[ i ];
837     aGroup.length( aListOfNodes.size() );
838     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
839       aGroup[ j ] = (*lIt)->GetID();
840   }
841 }
842
843 //=======================================================================
844 //function : MergeNodes
845 //purpose  : 
846 //=======================================================================
847
848 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
849 {
850   SMESHDS_Mesh* aMesh = GetMeshDS();
851
852   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
853   list<const SMDS_MeshElement*> elements;
854   for (int i = 0; i < GroupsOfNodes.length(); i++)
855   {
856     const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
857     aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
858     list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
859     for ( int j = 0; j < aNodeGroup.length(); j++ )
860     {
861       CORBA::Long index = aNodeGroup[ j ];
862       const SMDS_MeshNode * node = aMesh->FindNode(index);
863       if ( node )
864         aListOfNodes.push_back( node );
865     }
866     if ( aListOfNodes.size() < 2 )
867       aListOfListOfNodes.pop_back();
868   }
869   ::SMESH_MeshEditor anEditor( _myMesh );
870   anEditor.MergeNodes( aListOfListOfNodes );
871 }
872
873 //=======================================================================
874 //function : MergeEqualElements
875 //purpose  : 
876 //=======================================================================
877
878 void SMESH_MeshEditor_i::MergeEqualElements()
879 {
880   ::SMESH_MeshEditor anEditor( _myMesh );
881   anEditor.MergeEqualElements();
882 }
883
884 //=======================================================================
885 //function : operator
886 //purpose  : 
887 //=======================================================================
888
889 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
890
891 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
892 {
893   switch ( e ) {
894   RETCASE( SEW_OK );
895   RETCASE( SEW_BORDER1_NOT_FOUND );
896   RETCASE( SEW_BORDER2_NOT_FOUND );
897   RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
898   RETCASE( SEW_BAD_SIDE_NODES );
899   RETCASE( SEW_VOLUMES_TO_SPLIT );
900   RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
901   RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
902   RETCASE( SEW_BAD_SIDE1_NODES );
903   RETCASE( SEW_BAD_SIDE2_NODES );
904   }
905   return SMESH::SMESH_MeshEditor::SEW_OK;
906 }
907
908 //=======================================================================
909 //function : SewFreeBorders
910 //purpose  : 
911 //=======================================================================
912
913 SMESH::SMESH_MeshEditor::Sew_Error
914   SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
915                                      CORBA::Long SecondNodeID1,
916                                      CORBA::Long LastNodeID1,
917                                      CORBA::Long FirstNodeID2,
918                                      CORBA::Long SecondNodeID2,
919                                      CORBA::Long LastNodeID2,
920                                      CORBA::Boolean CreatePoly)
921 {
922   SMESHDS_Mesh* aMesh = GetMeshDS();
923
924   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
925   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
926   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
927   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
928   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
929   const SMDS_MeshNode* aSide2ThirdNode   = aMesh->FindNode( LastNodeID2   );
930
931   if (!aBorderFirstNode ||
932       !aBorderSecondNode||
933       !aBorderLastNode)
934     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
935   if (!aSide2FirstNode  ||
936       !aSide2SecondNode ||
937       !aSide2ThirdNode)
938     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
939
940   ::SMESH_MeshEditor anEditor( _myMesh );
941   return convError( anEditor.SewFreeBorder (aBorderFirstNode,
942                                             aBorderSecondNode,
943                                             aBorderLastNode,
944                                             aSide2FirstNode,
945                                             aSide2SecondNode,
946                                             aSide2ThirdNode,
947                                             true,
948                                             CreatePoly) );
949 }
950
951 //=======================================================================
952 //function : SewConformFreeBorders
953 //purpose  : 
954 //=======================================================================
955
956 SMESH::SMESH_MeshEditor::Sew_Error
957   SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
958                                             CORBA::Long SecondNodeID1,
959                                             CORBA::Long LastNodeID1,
960                                             CORBA::Long FirstNodeID2,
961                                             CORBA::Long SecondNodeID2)
962 {
963   SMESHDS_Mesh* aMesh = GetMeshDS();
964
965   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
966   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
967   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
968   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
969   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
970   const SMDS_MeshNode* aSide2ThirdNode   = 0;
971
972   if (!aBorderFirstNode ||
973       !aBorderSecondNode||
974       !aBorderLastNode )
975     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
976   if (!aSide2FirstNode  ||
977       !aSide2SecondNode)
978     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
979
980   ::SMESH_MeshEditor anEditor( _myMesh );
981   return convError( anEditor.SewFreeBorder (aBorderFirstNode,
982                                             aBorderSecondNode,
983                                             aBorderLastNode,
984                                             aSide2FirstNode,
985                                             aSide2SecondNode,
986                                             aSide2ThirdNode,
987                                             true,
988                                             false) );
989 }
990
991 //=======================================================================
992 //function : SewBorderToSide
993 //purpose  : 
994 //=======================================================================
995
996 SMESH::SMESH_MeshEditor::Sew_Error
997   SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
998                                       CORBA::Long SecondNodeIDOnFreeBorder,
999                                       CORBA::Long LastNodeIDOnFreeBorder,
1000                                       CORBA::Long FirstNodeIDOnSide,
1001                                       CORBA::Long LastNodeIDOnSide)
1002 {
1003   SMESHDS_Mesh* aMesh = GetMeshDS();
1004
1005   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeIDOnFreeBorder  );
1006   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
1007   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeIDOnFreeBorder   );
1008   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeIDOnSide  );
1009   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( LastNodeIDOnSide );
1010   const SMDS_MeshNode* aSide2ThirdNode   = 0;
1011
1012   if (!aBorderFirstNode ||
1013       !aBorderSecondNode||
1014       !aBorderLastNode  )
1015     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
1016   if (!aSide2FirstNode  ||
1017       !aSide2SecondNode)
1018     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
1019
1020   ::SMESH_MeshEditor anEditor( _myMesh );
1021   return convError( anEditor.SewFreeBorder (aBorderFirstNode,
1022                                             aBorderSecondNode,
1023                                             aBorderLastNode,
1024                                             aSide2FirstNode,
1025                                             aSide2SecondNode,
1026                                             aSide2ThirdNode,
1027                                             false,
1028                                             false) );
1029 }
1030
1031 //=======================================================================
1032 //function : SewSideElements
1033 //purpose  : 
1034 //=======================================================================
1035
1036 SMESH::SMESH_MeshEditor::Sew_Error
1037   SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
1038                                       const SMESH::long_array& IDsOfSide2Elements,
1039                                       CORBA::Long NodeID1OfSide1ToMerge,
1040                                       CORBA::Long NodeID1OfSide2ToMerge,
1041                                       CORBA::Long NodeID2OfSide1ToMerge,
1042                                       CORBA::Long NodeID2OfSide2ToMerge)
1043 {
1044   SMESHDS_Mesh* aMesh = GetMeshDS();
1045
1046   const SMDS_MeshNode* aFirstNode1ToMerge  = aMesh->FindNode( NodeID1OfSide1ToMerge );
1047   const SMDS_MeshNode* aFirstNode2ToMerge  = aMesh->FindNode( NodeID1OfSide2ToMerge );
1048   const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
1049   const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
1050
1051   if (!aFirstNode1ToMerge ||
1052       !aFirstNode2ToMerge )
1053     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
1054   if (!aSecondNode1ToMerge||
1055       !aSecondNode2ToMerge)
1056     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
1057
1058   set<const SMDS_MeshElement*> aSide1Elems, aSide2Elems;
1059   for (int i = 0; i < IDsOfSide1Elements.length(); i++)
1060   {
1061     CORBA::Long index = IDsOfSide1Elements[i];
1062     const SMDS_MeshElement * elem = aMesh->FindElement(index);
1063     if ( elem )
1064       aSide1Elems.insert( elem );
1065   }
1066   for (int i = 0; i < IDsOfSide2Elements.length(); i++)
1067   {
1068     CORBA::Long index = IDsOfSide2Elements[i];
1069     const SMDS_MeshElement * elem = aMesh->FindElement(index);
1070     if ( elem )
1071       aSide2Elems.insert( elem );
1072   }
1073   ::SMESH_MeshEditor anEditor( _myMesh );
1074   return convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
1075                                               aFirstNode1ToMerge,
1076                                               aFirstNode2ToMerge,
1077                                               aSecondNode1ToMerge,
1078                                               aSecondNode2ToMerge));
1079 }