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