Salome HOME
Fix PAL8562: rpath (rpath-link) option needs parameter - directory to search shared...
[modules/smesh.git] / src / SMESH_I / SMESH_MeshEditor_i.cxx
1 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SMESH_MeshEditor_i.cxx
25 //  Author : Nicolas REJNERI
26 //  Module : SMESH
27 //  $Header$
28
29 #include "SMESH_MeshEditor_i.hxx"
30
31 #include "SMDS_MeshEdge.hxx"
32 #include "SMDS_MeshFace.hxx"
33 #include "SMDS_MeshVolume.hxx"
34
35 #include "SMESH_MeshEditor.hxx"
36
37 #include "SMESH_Gen_i.hxx"
38 #include "SMESH_Filter_i.hxx"
39
40 #include "utilities.h"
41
42 #include <gp_Ax1.hxx>
43 #include <gp_Ax2.hxx>
44 #include <gp_Vec.hxx>
45
46 using namespace std;
47
48 //=============================================================================
49 /*!
50  *  
51  */
52 //=============================================================================
53
54 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh* theMesh)
55 {
56         _myMesh = theMesh;
57 };
58
59 //=============================================================================
60 /*!
61  *  
62  */
63 //=============================================================================
64
65 CORBA::Boolean SMESH_MeshEditor_i::RemoveElements(const SMESH::
66         long_array & IDsOfElements)
67 {
68   ::SMESH_MeshEditor anEditor( _myMesh );
69   list< int > IdList;
70   for (int i = 0; i < IDsOfElements.length(); i++)
71     IdList.push_back( IDsOfElements[i] );
72
73   return anEditor.Remove( IdList, false );
74 };
75
76 //=============================================================================
77 /*!
78  *  
79  */
80 //=============================================================================
81
82 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::
83         long_array & IDsOfNodes)
84 {
85   ::SMESH_MeshEditor anEditor( _myMesh );
86   list< int > IdList;
87   for (int i = 0; i < IDsOfNodes.length(); i++)
88     IdList.push_back( IDsOfNodes[i] );
89
90   return anEditor.Remove( IdList, true );
91 };
92
93 //=============================================================================
94 /*!
95  *  
96  */
97 //=============================================================================
98
99 CORBA::Boolean SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
100 {
101         int NbNodes = IDsOfNodes.length();
102         if (NbNodes == 2)
103         {
104                 CORBA::Long index1 = IDsOfNodes[0];
105                 CORBA::Long index2 = IDsOfNodes[1];
106                 GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
107         }
108         return true;
109 }
110
111 //=============================================================================
112 /*!
113  *  
114  */
115 //=============================================================================
116
117 CORBA::Boolean SMESH_MeshEditor_i::AddNode(CORBA::Double x,
118         CORBA::Double y, CORBA::Double z)
119 {
120         MESSAGE(" AddNode " << x << " , " << y << " , " << z)
121                 int idNode = GetMeshDS()->AddNode(x, y, z)->GetID();
122         MESSAGE(" idNode " << idNode) return true;
123 }
124
125 //=============================================================================
126 /*!
127  *  
128  */
129 //=============================================================================
130
131 CORBA::Boolean SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
132 {
133         int NbNodes = IDsOfNodes.length();
134         const SMDS_MeshNode* nodes[4];
135         for(int i=0;i<NbNodes;i++) nodes[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
136         if (NbNodes == 3)
137         {
138                 GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
139         }
140         else if (NbNodes == 4)
141         {
142                 GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
143         }
144         return true;
145 };
146
147 //=============================================================================
148 /*!
149  *  
150  */
151 //=============================================================================
152
153 CORBA::Boolean SMESH_MeshEditor_i::AddVolume(const SMESH::
154         long_array & IDsOfNodes)
155 {
156         int NbNodes = IDsOfNodes.length();
157         const SMDS_MeshNode* n[8];
158         for(int i=0;i<NbNodes;i++) n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
159
160         switch(NbNodes)
161         {
162         case 4:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
163         case 5:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
164         case 6:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
165         case 8:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
166         }
167         return true;
168 };
169
170 //=============================================================================
171 /*!
172  *  
173  */
174 //=============================================================================
175
176 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
177                                             CORBA::Double x,
178                                             CORBA::Double y,
179                                             CORBA::Double z)
180 {
181   const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
182   if ( !node )
183     return false;
184   
185   GetMeshDS()->MoveNode(node, x, y, z);
186
187   return true;
188 }
189
190 //=============================================================================
191 /*!
192  *  
193  */
194 //=============================================================================
195
196 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
197                                                CORBA::Long NodeID2)
198 {
199   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
200   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
201   if ( !n1 || !n2 )
202     return false;
203
204   ::SMESH_MeshEditor aMeshEditor( _myMesh );
205   return aMeshEditor.InverseDiag ( n1, n2 );
206 }
207
208 //=============================================================================
209 /*!
210  *  
211  */
212 //=============================================================================
213
214 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
215                                               CORBA::Long NodeID2)
216 {
217   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
218   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
219   if ( !n1 || !n2 )
220     return false;
221
222   ::SMESH_MeshEditor aMeshEditor( _myMesh );
223   return aMeshEditor.DeleteDiag ( n1, n2 );
224 }
225
226 //=============================================================================
227 /*!
228  *  
229  */
230 //=============================================================================
231
232 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
233 {
234   ::SMESH_MeshEditor anEditor( _myMesh );
235   for (int i = 0; i < IDsOfElements.length(); i++)
236   {
237     CORBA::Long index = IDsOfElements[i];
238     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
239     if ( elem )
240       anEditor.Reorient( elem );
241   }
242   return true;
243 }
244
245
246 //=============================================================================
247 /*!
248  *  
249  */
250 //=============================================================================
251
252 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
253 {
254   SMESH::long_array_var anElementsId = theObject->GetIDs();
255   return Reorient(anElementsId);
256 }
257
258 //=============================================================================
259 /*!
260  *  
261  */
262 //=============================================================================
263
264 CORBA::Boolean
265   SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfElements,
266                                  SMESH::NumericalFunctor_ptr Criterion,
267                                  CORBA::Double               MaxAngle)
268 {
269   set<const SMDS_MeshElement*> faces;
270   for (int i = 0; i < IDsOfElements.length(); i++)
271   {
272     CORBA::Long index = IDsOfElements[i];
273     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
274     if ( elem && elem->GetType() == SMDSAbs_Face)
275       faces.insert( elem );
276   }
277   SMESH::NumericalFunctor_i* aNumericalFunctor = 
278     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
279   SMESH::Controls::NumericalFunctorPtr aCrit;
280   if ( !aNumericalFunctor )
281     aCrit.reset( new SMESH::Controls::AspectRatio() );
282   else
283     aCrit = aNumericalFunctor->GetNumericalFunctor();
284
285   ::SMESH_MeshEditor anEditor( _myMesh );
286   return anEditor.TriToQuad( faces, aCrit, MaxAngle );
287 }
288
289 //=============================================================================
290 /*!
291  *  
292  */
293 //=============================================================================
294
295 CORBA::Boolean
296   SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr   theObject,
297                                        SMESH::NumericalFunctor_ptr Criterion,
298                                        CORBA::Double               MaxAngle)
299 {
300   SMESH::long_array_var anElementsId = theObject->GetIDs();
301   return TriToQuad(anElementsId, Criterion, MaxAngle);
302 }
303
304 //=============================================================================
305 /*!
306  *  
307  */
308 //=============================================================================
309
310 CORBA::Boolean
311   SMESH_MeshEditor_i::QuadToTri(const SMESH::long_array &   IDsOfElements,
312                                 SMESH::NumericalFunctor_ptr Criterion)
313 {
314   set<const SMDS_MeshElement*> faces;
315   for (int i = 0; i < IDsOfElements.length(); i++)
316   {
317     CORBA::Long index = IDsOfElements[i];
318     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
319     if ( elem && elem->GetType() == SMDSAbs_Face)
320       faces.insert( elem );
321   }
322   SMESH::NumericalFunctor_i* aNumericalFunctor = 
323     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
324   SMESH::Controls::NumericalFunctorPtr aCrit;
325   if ( !aNumericalFunctor )
326     aCrit.reset( new SMESH::Controls::AspectRatio() );
327   else
328     aCrit = aNumericalFunctor->GetNumericalFunctor();
329
330   ::SMESH_MeshEditor anEditor( _myMesh );
331   return anEditor.QuadToTri( faces, aCrit );
332 }
333
334 //=============================================================================
335 /*!
336  *  
337  */
338 //=============================================================================
339
340 CORBA::Boolean
341   SMESH_MeshEditor_i::SplitQuad(const SMESH::long_array & IDsOfElements,
342                                 CORBA::Boolean            Diag13)
343 {
344   set<const SMDS_MeshElement*> faces;
345   for (int i = 0; i < IDsOfElements.length(); i++)
346   {
347     CORBA::Long index = IDsOfElements[i];
348     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
349     if ( elem && elem->GetType() == SMDSAbs_Face)
350       faces.insert( elem );
351   }
352
353   ::SMESH_MeshEditor anEditor( _myMesh );
354   return anEditor.QuadToTri( faces, Diag13 );
355 }
356
357 //=============================================================================
358 /*!
359  *  
360  */
361 //=============================================================================
362
363 CORBA::Boolean
364   SMESH_MeshEditor_i::SplitQuadObject(SMESH::SMESH_IDSource_ptr theObject,
365                                       CORBA::Boolean            Diag13)
366 {
367   SMESH::long_array_var anElementsId = theObject->GetIDs();
368   return SplitQuad(anElementsId, Diag13);
369 }
370
371 //=============================================================================
372 /*!
373  *  
374  */
375 //=============================================================================
376
377 CORBA::Boolean
378   SMESH_MeshEditor_i::Smooth(const SMESH::long_array &              IDsOfElements,
379                              const SMESH::long_array &              IDsOfFixedNodes,
380                              CORBA::Long                            MaxNbOfIterations,
381                              CORBA::Double                          MaxAspectRatio,
382                              SMESH::SMESH_MeshEditor::Smooth_Method Method)
383 {
384   SMESHDS_Mesh* aMesh = GetMeshDS();
385
386   set<const SMDS_MeshElement*> elements;
387   for (int i = 0; i < IDsOfElements.length(); i++)
388   {
389     CORBA::Long index = IDsOfElements[i];
390     const SMDS_MeshElement * elem = aMesh->FindElement(index);
391     if ( elem && elem->GetType() == SMDSAbs_Face)
392       elements.insert( elem );
393   }
394
395   set<const SMDS_MeshNode*> fixedNodes;
396   for (int i = 0; i < IDsOfFixedNodes.length(); i++)
397   {
398     CORBA::Long index = IDsOfFixedNodes[i];
399     const SMDS_MeshNode * node = aMesh->FindNode(index);
400     if ( node )
401       fixedNodes.insert( node );
402   }
403   ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
404   if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
405      method = ::SMESH_MeshEditor::CENTROIDAL;
406
407   ::SMESH_MeshEditor anEditor( _myMesh );
408   anEditor.Smooth( elements, fixedNodes, method, MaxNbOfIterations, MaxAspectRatio );
409
410   return true;
411 }
412
413 //=============================================================================
414 /*!
415  *  
416  */
417 //=============================================================================
418
419 CORBA::Boolean
420   SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr              theObject,
421                                    const SMESH::long_array &              IDsOfFixedNodes,
422                                    CORBA::Long                            MaxNbOfIterations,
423                                    CORBA::Double                          MaxAspectRatio,
424                                    SMESH::SMESH_MeshEditor::Smooth_Method Method)
425 {
426   SMESH::long_array_var anElementsId = theObject->GetIDs();
427   return Smooth(anElementsId, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method);
428 }
429
430 //=============================================================================
431 /*!
432  *  
433  */
434 //=============================================================================
435
436 void SMESH_MeshEditor_i::RenumberNodes()
437 {
438   GetMeshDS()->Renumber( true );
439 }
440
441 //=============================================================================
442 /*!
443  *  
444  */
445 //=============================================================================
446
447 void SMESH_MeshEditor_i::RenumberElements()
448 {
449   GetMeshDS()->Renumber( false );
450 }
451
452 //=======================================================================
453 //function : RotationSweep
454 //purpose  : 
455 //=======================================================================
456
457 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
458                                        const SMESH::AxisStruct &  theAxis,
459                                        CORBA::Double             theAngleInRadians,
460                                        CORBA::Long               theNbOfSteps,
461                                        CORBA::Double             theTolerance)
462 {
463   SMESHDS_Mesh* aMesh = GetMeshDS();
464
465   set<const SMDS_MeshElement*> elements;
466   for (int i = 0; i < theIDsOfElements.length(); i++)
467   {
468     CORBA::Long index = theIDsOfElements[i];
469     const SMDS_MeshElement * elem = aMesh->FindElement(index);
470     if ( elem )
471       elements.insert( elem );
472   }
473   gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
474               gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
475
476   ::SMESH_MeshEditor anEditor( _myMesh );
477   anEditor.RotationSweep (elements, Ax1, theAngleInRadians,
478                           theNbOfSteps, theTolerance);
479 }
480
481 //=======================================================================
482 //function : RotationSweepObject
483 //purpose  : 
484 //=======================================================================
485
486 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
487                                              const SMESH::AxisStruct & theAxis,
488                                              CORBA::Double             theAngleInRadians,
489                                              CORBA::Long               theNbOfSteps,
490                                              CORBA::Double             theTolerance)
491 {
492   SMESH::long_array_var anElementsId = theObject->GetIDs();
493   RotationSweep(anElementsId, theAxis, theAngleInRadians, theNbOfSteps, theTolerance);
494 }
495
496 //=======================================================================
497 //function : ExtrusionSweep
498 //purpose  : 
499 //=======================================================================
500
501 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
502                                         const SMESH::DirStruct &   theStepVector,
503                                         CORBA::Long               theNbOfSteps)
504 {
505   SMESHDS_Mesh* aMesh = GetMeshDS();
506
507   set<const SMDS_MeshElement*> elements;
508   for (int i = 0; i < theIDsOfElements.length(); i++)
509   {
510     CORBA::Long index = theIDsOfElements[i];
511     const SMDS_MeshElement * elem = aMesh->FindElement(index);
512     if ( elem )
513       elements.insert( elem );
514   }
515   const SMESH::PointStruct * P = &theStepVector.PS;
516   gp_Vec stepVec( P->x, P->y, P->z );
517
518   ::SMESH_MeshEditor anEditor( _myMesh );
519   anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps);
520 }
521
522
523 //=======================================================================
524 //function : ExtrusionSweepObject
525 //purpose  : 
526 //=======================================================================
527
528 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
529                                               const SMESH::DirStruct &  theStepVector,
530                                               CORBA::Long               theNbOfSteps)
531 {
532   SMESH::long_array_var anElementsId = theObject->GetIDs();
533   ExtrusionSweep(anElementsId, theStepVector, theNbOfSteps);
534 }
535
536 //=======================================================================
537 //function : ExtrusionSweepObject1D
538 //purpose  : 
539 //=======================================================================
540
541 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
542                                                 const SMESH::DirStruct &  theStepVector,
543                                                 CORBA::Long               theNbOfSteps)
544 {
545   SMESHDS_Mesh* aMesh = GetMeshDS();
546
547   SMESH::long_array_var allElementsId = theObject->GetIDs();
548
549   set<const SMDS_MeshElement*> elements;
550   for (int i = 0; i < allElementsId->length(); i++)
551   {
552     CORBA::Long index = allElementsId[i];
553     const SMDS_MeshElement * elem = aMesh->FindElement(index);
554     if ( elem && elem->GetType() == SMDSAbs_Edge )
555       elements.insert( elem );
556   }
557   const SMESH::PointStruct * P = &theStepVector.PS;
558   gp_Vec stepVec( P->x, P->y, P->z );
559
560   ::SMESH_MeshEditor anEditor( _myMesh );
561   anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps);
562 }
563
564 //=======================================================================
565 //function : ExtrusionSweepObject2D
566 //purpose  : 
567 //=======================================================================
568
569 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
570                                                 const SMESH::DirStruct &  theStepVector,
571                                                 CORBA::Long               theNbOfSteps)
572 {
573   SMESHDS_Mesh* aMesh = GetMeshDS();
574
575   SMESH::long_array_var allElementsId = theObject->GetIDs();
576
577   set<const SMDS_MeshElement*> elements;
578   for (int i = 0; i < allElementsId->length(); i++)
579   {
580     CORBA::Long index = allElementsId[i];
581     const SMDS_MeshElement * elem = aMesh->FindElement(index);
582     if ( elem && elem->GetType() == SMDSAbs_Face )
583       elements.insert( elem );
584   }
585   const SMESH::PointStruct * P = &theStepVector.PS;
586   gp_Vec stepVec( P->x, P->y, P->z );
587
588   ::SMESH_MeshEditor anEditor( _myMesh );
589   anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps);
590 }
591
592 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
593
594 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
595 {
596   switch ( e ) {
597   RETCASE( EXTR_OK );
598   RETCASE( EXTR_NO_ELEMENTS );
599   RETCASE( EXTR_PATH_NOT_EDGE );
600   RETCASE( EXTR_BAD_PATH_SHAPE );
601   RETCASE( EXTR_BAD_STARTING_NODE );
602   RETCASE( EXTR_BAD_ANGLES_NUMBER );
603   RETCASE( EXTR_CANT_GET_TANGENT );
604   }
605   return SMESH::SMESH_MeshEditor::EXTR_OK;
606 }
607
608 //=======================================================================
609 //function : ExtrusionAlongPath
610 //purpose  : 
611 //=======================================================================
612
613 SMESH::SMESH_MeshEditor::Extrusion_Error
614   SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
615                                          SMESH::SMESH_Mesh_ptr       thePathMesh,
616                                          GEOM::GEOM_Object_ptr       thePathShape,
617                                          CORBA::Long                 theNodeStart,
618                                          CORBA::Boolean              theHasAngles,
619                                          const SMESH::double_array & theAngles,
620                                          CORBA::Boolean              theHasRefPoint,
621                                          const SMESH::PointStruct &  theRefPoint)
622 {
623   SMESHDS_Mesh*  aMesh = GetMeshDS();
624
625   if ( thePathMesh->_is_nil() || thePathShape->_is_nil() )
626     return SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
627
628   SMESH_Mesh_i* aMeshImp = dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( thePathMesh ).in() );
629   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
630   SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
631
632   if ( !aSubMesh )
633     return SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
634
635   SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
636   if ( !nodeStart )
637     return SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
638
639   set<const SMDS_MeshElement*> elements;
640   for (int i = 0; i < theIDsOfElements.length(); i++)
641   {
642     CORBA::Long index = theIDsOfElements[i];
643     const SMDS_MeshElement * elem = aMesh->FindElement(index);
644     if ( elem )
645       elements.insert( elem );
646   }
647
648   list<double> angles;
649   for (int i = 0; i < theAngles.length(); i++)
650   {
651     angles.push_back( theAngles[i] );
652   }
653
654   gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
655
656   ::SMESH_MeshEditor anEditor( _myMesh );
657   return convExtrError( anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart, theHasAngles, angles, theHasRefPoint, refPnt ) );
658 }
659
660 //=======================================================================
661 //function : ExtrusionAlongPathObject
662 //purpose  : 
663 //=======================================================================
664
665 SMESH::SMESH_MeshEditor::Extrusion_Error
666   SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObject,
667                                                SMESH::SMESH_Mesh_ptr       thePathMesh,
668                                                GEOM::GEOM_Object_ptr       thePathShape,
669                                                CORBA::Long                 theNodeStart,
670                                                CORBA::Boolean              theHasAngles,
671                                                const SMESH::double_array & theAngles,
672                                                CORBA::Boolean              theHasRefPoint,
673                                                const SMESH::PointStruct &  theRefPoint)
674 {
675   SMESH::long_array_var anElementsId = theObject->GetIDs();
676   return ExtrusionAlongPath( anElementsId, thePathMesh, thePathShape, theNodeStart, theHasAngles, theAngles, theHasRefPoint, theRefPoint );
677 }
678
679 //=======================================================================
680 //function : Mirror
681 //purpose  : 
682 //=======================================================================
683
684 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElements,
685                                 const SMESH::AxisStruct &            theAxis,
686                                 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
687                                 CORBA::Boolean                      theCopy)
688 {
689   SMESHDS_Mesh* aMesh = GetMeshDS();
690
691   set<const SMDS_MeshElement*> elements;
692   for (int i = 0; i < theIDsOfElements.length(); i++)
693   {
694     CORBA::Long index = theIDsOfElements[i];
695     const SMDS_MeshElement * elem = aMesh->FindElement(index);
696     if ( elem )
697       elements.insert( elem );
698   }
699   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
700   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
701
702   gp_Trsf aTrsf;
703   switch ( theMirrorType ) {
704   case  SMESH::SMESH_MeshEditor::POINT:
705     aTrsf.SetMirror( P );
706     break;
707   case  SMESH::SMESH_MeshEditor::AXIS:
708     aTrsf.SetMirror( gp_Ax1( P, V ));
709     break;
710   default:
711     aTrsf.SetMirror( gp_Ax2( P, V ));
712   }
713
714   ::SMESH_MeshEditor anEditor( _myMesh );
715   anEditor.Transform (elements, aTrsf, theCopy);
716 }
717
718 //=======================================================================
719 //function : MirrorObject
720 //purpose  : 
721 //=======================================================================
722
723 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr           theObject,
724                                       const SMESH::AxisStruct &           theAxis,
725                                       SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
726                                       CORBA::Boolean                      theCopy)
727 {
728   SMESH::long_array_var anElementsId = theObject->GetIDs();
729   Mirror(anElementsId, theAxis, theMirrorType, theCopy);
730 }
731
732 //=======================================================================
733 //function : Translate
734 //purpose  : 
735 //=======================================================================
736
737 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
738                                    const SMESH::DirStruct &   theVector,
739                                    CORBA::Boolean            theCopy)
740 {
741   SMESHDS_Mesh* aMesh = GetMeshDS();
742
743   set<const SMDS_MeshElement*> elements;
744   for (int i = 0; i < theIDsOfElements.length(); i++)
745   {
746     CORBA::Long index = theIDsOfElements[i];
747     const SMDS_MeshElement * elem = aMesh->FindElement(index);
748     if ( elem )
749       elements.insert( elem );
750   }
751   gp_Trsf aTrsf;
752   const SMESH::PointStruct * P = &theVector.PS;
753   aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
754
755   ::SMESH_MeshEditor anEditor( _myMesh );
756   anEditor.Transform (elements, aTrsf, theCopy);
757 }
758
759 //=======================================================================
760 //function : TranslateObject
761 //purpose  : 
762 //=======================================================================
763
764 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
765                                          const SMESH::DirStruct &  theVector,
766                                          CORBA::Boolean            theCopy)
767 {
768   SMESH::long_array_var anElementsId = theObject->GetIDs();
769   Translate(anElementsId, theVector, theCopy);
770 }
771
772 //=======================================================================
773 //function : Rotate
774 //purpose  : 
775 //=======================================================================
776
777 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
778                                 const SMESH::AxisStruct &  theAxis,
779                                 CORBA::Double             theAngle,
780                                 CORBA::Boolean            theCopy)
781 {
782   SMESHDS_Mesh* aMesh = GetMeshDS();
783
784   set<const SMDS_MeshElement*> elements;
785   for (int i = 0; i < theIDsOfElements.length(); i++)
786   {
787     CORBA::Long index = theIDsOfElements[i];
788     const SMDS_MeshElement * elem = aMesh->FindElement(index);
789     if ( elem )
790       elements.insert( elem );
791   }
792   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
793   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
794
795   gp_Trsf aTrsf;
796   aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
797   
798
799   ::SMESH_MeshEditor anEditor( _myMesh );
800   anEditor.Transform (elements, aTrsf, theCopy);
801 }
802
803 //=======================================================================
804 //function : RotateObject
805 //purpose  : 
806 //=======================================================================
807
808 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
809                                       const SMESH::AxisStruct & theAxis,
810                                       CORBA::Double             theAngle,
811                                       CORBA::Boolean            theCopy)
812 {
813   SMESH::long_array_var anElementsId = theObject->GetIDs();
814   Rotate(anElementsId, theAxis, theAngle, theCopy);
815 }
816
817 //=======================================================================
818 //function : FindCoincidentNodes
819 //purpose  : 
820 //=======================================================================
821
822 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
823                                               SMESH::array_of_long_array_out GroupsOfNodes)
824 {
825   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
826   ::SMESH_MeshEditor anEditor( _myMesh );
827   set<const SMDS_MeshNode*> nodes; // no input nodes
828   anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
829
830   GroupsOfNodes = new SMESH::array_of_long_array;
831   GroupsOfNodes->length( aListOfListOfNodes.size() );
832   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
833   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
834   {
835     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
836     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
837     SMESH::long_array& aGroup = GroupsOfNodes[ i ];
838     aGroup.length( aListOfNodes.size() );
839     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
840       aGroup[ j ] = (*lIt)->GetID();
841   }
842 }
843
844 //=======================================================================
845 //function : MergeNodes
846 //purpose  : 
847 //=======================================================================
848
849 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
850 {
851   SMESHDS_Mesh* aMesh = GetMeshDS();
852
853   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
854   list<const SMDS_MeshElement*> elements;
855   for (int i = 0; i < GroupsOfNodes.length(); i++)
856   {
857     const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
858     aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
859     list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
860     for ( int j = 0; j < aNodeGroup.length(); j++ )
861     {
862       CORBA::Long index = aNodeGroup[ j ];
863       const SMDS_MeshNode * node = aMesh->FindNode(index);
864       if ( node )
865         aListOfNodes.push_back( node );
866     }
867     if ( aListOfNodes.size() < 2 )
868       aListOfListOfNodes.pop_back();
869   }
870   ::SMESH_MeshEditor anEditor( _myMesh );
871   anEditor.MergeNodes( aListOfListOfNodes );
872 }
873
874 //=======================================================================
875 //function : MergeEqualElements
876 //purpose  : 
877 //=======================================================================
878
879 void SMESH_MeshEditor_i::MergeEqualElements()
880 {
881   ::SMESH_MeshEditor anEditor( _myMesh );
882   anEditor.MergeEqualElements();
883 }
884
885 //=======================================================================
886 //function : operator
887 //purpose  : 
888 //=======================================================================
889
890 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
891
892 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
893 {
894   switch ( e ) {
895   RETCASE( SEW_OK );
896   RETCASE( SEW_BORDER1_NOT_FOUND );
897   RETCASE( SEW_BORDER2_NOT_FOUND );
898   RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
899   RETCASE( SEW_BAD_SIDE_NODES );
900   RETCASE( SEW_VOLUMES_TO_SPLIT );
901   RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
902   RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
903   RETCASE( SEW_BAD_SIDE1_NODES );
904   RETCASE( SEW_BAD_SIDE2_NODES );
905   }
906   return SMESH::SMESH_MeshEditor::SEW_OK;
907 }
908
909 //=======================================================================
910 //function : SewFreeBorders
911 //purpose  : 
912 //=======================================================================
913
914 SMESH::SMESH_MeshEditor::Sew_Error
915   SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
916                                      CORBA::Long SecondNodeID1,
917                                      CORBA::Long LastNodeID1,
918                                      CORBA::Long FirstNodeID2,
919                                      CORBA::Long SecondNodeID2,
920                                      CORBA::Long LastNodeID2)
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 }
949
950 //=======================================================================
951 //function : SewConformFreeBorders
952 //purpose  : 
953 //=======================================================================
954
955 SMESH::SMESH_MeshEditor::Sew_Error
956   SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
957                                             CORBA::Long SecondNodeID1,
958                                             CORBA::Long LastNodeID1,
959                                             CORBA::Long FirstNodeID2,
960                                             CORBA::Long SecondNodeID2)
961 {
962   SMESHDS_Mesh* aMesh = GetMeshDS();
963
964   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
965   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
966   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
967   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
968   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
969   const SMDS_MeshNode* aSide2ThirdNode   = 0;
970
971   if (!aBorderFirstNode ||
972       !aBorderSecondNode||
973       !aBorderLastNode )
974     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
975   if (!aSide2FirstNode  ||
976       !aSide2SecondNode)
977     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
978
979   ::SMESH_MeshEditor anEditor( _myMesh );
980   return convError( anEditor.SewFreeBorder (aBorderFirstNode,
981                                             aBorderSecondNode,
982                                             aBorderLastNode,
983                                             aSide2FirstNode,
984                                             aSide2SecondNode,
985                                             aSide2ThirdNode,
986                                             true ));
987 }
988
989 //=======================================================================
990 //function : SewBorderToSide
991 //purpose  : 
992 //=======================================================================
993
994 SMESH::SMESH_MeshEditor::Sew_Error
995   SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
996                                       CORBA::Long SecondNodeIDOnFreeBorder,
997                                       CORBA::Long LastNodeIDOnFreeBorder,
998                                       CORBA::Long FirstNodeIDOnSide,
999                                       CORBA::Long LastNodeIDOnSide)
1000 {
1001   SMESHDS_Mesh* aMesh = GetMeshDS();
1002
1003   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeIDOnFreeBorder  );
1004   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
1005   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeIDOnFreeBorder   );
1006   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeIDOnSide  );
1007   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( LastNodeIDOnSide );
1008   const SMDS_MeshNode* aSide2ThirdNode   = 0;
1009
1010   if (!aBorderFirstNode ||
1011       !aBorderSecondNode||
1012       !aBorderLastNode  )
1013     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
1014   if (!aSide2FirstNode  ||
1015       !aSide2SecondNode)
1016     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
1017
1018   ::SMESH_MeshEditor anEditor( _myMesh );
1019   return convError( anEditor.SewFreeBorder (aBorderFirstNode,
1020                                             aBorderSecondNode,
1021                                             aBorderLastNode,
1022                                             aSide2FirstNode,
1023                                             aSide2SecondNode,
1024                                             aSide2ThirdNode,
1025                                             false));
1026 }
1027
1028 //=======================================================================
1029 //function : SewSideElements
1030 //purpose  : 
1031 //=======================================================================
1032
1033 SMESH::SMESH_MeshEditor::Sew_Error
1034   SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
1035                                       const SMESH::long_array& IDsOfSide2Elements,
1036                                       CORBA::Long NodeID1OfSide1ToMerge,
1037                                       CORBA::Long NodeID1OfSide2ToMerge,
1038                                       CORBA::Long NodeID2OfSide1ToMerge,
1039                                       CORBA::Long NodeID2OfSide2ToMerge)
1040 {
1041   SMESHDS_Mesh* aMesh = GetMeshDS();
1042
1043   const SMDS_MeshNode* aFirstNode1ToMerge  = aMesh->FindNode( NodeID1OfSide1ToMerge );
1044   const SMDS_MeshNode* aFirstNode2ToMerge  = aMesh->FindNode( NodeID1OfSide2ToMerge );
1045   const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
1046   const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
1047
1048   if (!aFirstNode1ToMerge ||
1049       !aFirstNode2ToMerge )
1050     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
1051   if (!aSecondNode1ToMerge||
1052       !aSecondNode2ToMerge)
1053     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
1054
1055   set<const SMDS_MeshElement*> aSide1Elems, aSide2Elems;
1056   for (int i = 0; i < IDsOfSide1Elements.length(); i++)
1057   {
1058     CORBA::Long index = IDsOfSide1Elements[i];
1059     const SMDS_MeshElement * elem = aMesh->FindElement(index);
1060     if ( elem )
1061       aSide1Elems.insert( elem );
1062   }
1063   for (int i = 0; i < IDsOfSide2Elements.length(); i++)
1064   {
1065     CORBA::Long index = IDsOfSide2Elements[i];
1066     const SMDS_MeshElement * elem = aMesh->FindElement(index);
1067     if ( elem )
1068       aSide2Elems.insert( elem );
1069   }
1070   ::SMESH_MeshEditor anEditor( _myMesh );
1071   return convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
1072                                               aFirstNode1ToMerge,
1073                                               aFirstNode2ToMerge,
1074                                               aSecondNode1ToMerge,
1075                                               aSecondNode2ToMerge));
1076 }