Salome HOME
PAL8581. Really check smoothing
[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 #include <sstream>
47
48 using namespace std;
49
50 //=======================================================================
51 //function : addAxis
52 //purpose  : 
53 //=======================================================================
54
55 static TCollection_AsciiString& addAxis(TCollection_AsciiString&  theStr,
56                                         const SMESH::AxisStruct & theAxis)
57 {
58   theStr += "SMESH.AxisStruct( ";
59   theStr += TCollection_AsciiString( theAxis.x  ) + ", ";
60   theStr += TCollection_AsciiString( theAxis.y  ) + ", ";
61   theStr += TCollection_AsciiString( theAxis.z  ) + ", ";
62   theStr += TCollection_AsciiString( theAxis.vx ) + ", ";
63   theStr += TCollection_AsciiString( theAxis.vy ) + ", ";
64   theStr += TCollection_AsciiString( theAxis.vz ) + " )";
65   return theStr;
66 }
67
68 //=============================================================================
69 /*!
70  *  
71  */
72 //=============================================================================
73
74 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh* theMesh)
75 {
76         _myMesh = theMesh;
77 };
78
79 //=============================================================================
80 /*!
81  *  
82  */
83 //=============================================================================
84
85 CORBA::Boolean
86   SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
87 {
88   ::SMESH_MeshEditor anEditor( _myMesh );
89   list< int > IdList;
90
91   for (int i = 0; i < IDsOfElements.length(); i++)
92     IdList.push_back( IDsOfElements[i] );
93
94   // Update Python script
95   TCollection_AsciiString str ("isDone = mesh_editor.RemoveElements(");
96   SMESH_Gen_i::AddArray( str, IDsOfElements ) += ")";
97   SMESH_Gen_i::AddToCurrentPyScript( str );
98 #ifdef _DEBUG_
99   SMESH_Gen_i::AddToCurrentPyScript( "print \"RemoveElements: \", isDone" );
100 #endif
101   // Remove Elements
102   return anEditor.Remove( IdList, false );
103 };
104
105 //=============================================================================
106 /*!
107  *  
108  */
109 //=============================================================================
110
111 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::
112         long_array & IDsOfNodes)
113 {
114   ::SMESH_MeshEditor anEditor( _myMesh );
115   list< int > IdList;
116   for (int i = 0; i < IDsOfNodes.length(); i++)
117     IdList.push_back( IDsOfNodes[i] );
118
119   // Update Python script
120   TCollection_AsciiString str ("isDone = mesh_editor.RemoveNodes(");
121   SMESH_Gen_i::AddArray( str, IDsOfNodes ) += ")";
122   SMESH_Gen_i::AddToCurrentPyScript( str );
123 #ifdef _DEBUG_
124   SMESH_Gen_i::AddToCurrentPyScript( "print \"RemoveNodes: \", isDone" );
125 #endif
126
127   return anEditor.Remove( IdList, true );
128 };
129
130 //=============================================================================
131 /*!
132  *  
133  */
134 //=============================================================================
135
136 CORBA::Boolean SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
137 {
138   int NbNodes = IDsOfNodes.length();
139   if (NbNodes == 2)
140   {
141     CORBA::Long index1 = IDsOfNodes[0];
142     CORBA::Long index2 = IDsOfNodes[1];
143     GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
144
145     // Update Python script
146     TCollection_AsciiString str ("isDone = mesh_editor.AddEdge([");
147     str += TCollection_AsciiString((int) index1) + ", ";
148     str += TCollection_AsciiString((int) index2) + " ])";
149     SMESH_Gen_i::AddToCurrentPyScript( str );
150   }
151   return true;
152 }
153
154 //=============================================================================
155 /*!
156  *  
157  */
158 //=============================================================================
159
160 CORBA::Boolean SMESH_MeshEditor_i::AddNode(CORBA::Double x,
161                                            CORBA::Double y, CORBA::Double z)
162 {
163   GetMeshDS()->AddNode(x, y, z);
164
165   // Update Python script
166   TCollection_AsciiString str ("isDone = mesh_editor.AddNode(");
167   str += TCollection_AsciiString( x ) + ", ";
168   str += TCollection_AsciiString( y ) + ", ";
169   str += TCollection_AsciiString( z ) + " )";
170   SMESH_Gen_i::AddToCurrentPyScript( str );
171
172   return true;
173 }
174
175 //=============================================================================
176 /*!
177  *  AddFace
178  */
179 //=============================================================================
180
181 CORBA::Boolean SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
182 {
183   int NbNodes = IDsOfNodes.length();
184   if (NbNodes < 3)
185   {
186     return false;
187   }
188
189   std::vector<const SMDS_MeshNode*> nodes (NbNodes);
190   for (int i = 0; i < NbNodes; i++)
191     nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
192
193   if (NbNodes == 3)
194   {
195     GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
196   }
197   else if (NbNodes == 4)
198   {
199     GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
200   }
201   else
202   {
203     GetMeshDS()->AddPolygonalFace(nodes);
204   }
205
206   // Update Python script
207   TCollection_AsciiString str ("isDone = mesh_editor.AddFace(");
208   SMESH_Gen_i::AddArray( str, IDsOfNodes ) += ")";
209   SMESH_Gen_i::AddToCurrentPyScript( str );
210 #ifdef _DEBUG_
211   SMESH_Gen_i::AddToCurrentPyScript( "print \"AddFace: \", isDone" );
212 #endif
213
214   return true;
215 };
216
217 //=============================================================================
218 /*!
219  *  
220  */
221 //=============================================================================
222
223 CORBA::Boolean SMESH_MeshEditor_i::AddVolume(const SMESH::
224                                              long_array & IDsOfNodes)
225 {
226   int NbNodes = IDsOfNodes.length();
227   vector< const SMDS_MeshNode*> n(NbNodes);
228   for(int i=0;i<NbNodes;i++)
229     n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
230
231   switch(NbNodes)
232   {
233   case 4:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
234   case 5:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
235   case 6:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
236   case 8:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
237   }
238   // Update Python script
239   TCollection_AsciiString str ("isDone = mesh_editor.AddVolume(");
240   SMESH_Gen_i::AddArray( str, IDsOfNodes ) += ")";
241   SMESH_Gen_i::AddToCurrentPyScript( str );
242 #ifdef _DEBUG_
243   SMESH_Gen_i::AddToCurrentPyScript( "print \"AddVolume: \", isDone" );
244 #endif
245   
246   return true;
247 };
248
249 //=============================================================================
250 /*!
251  *  AddPolyhedralVolume
252  */
253 //=============================================================================
254 CORBA::Boolean SMESH_MeshEditor_i::AddPolyhedralVolume
255                                    (const SMESH::long_array & IDsOfNodes,
256                                     const SMESH::long_array & Quantities)
257 {
258   int NbNodes = IDsOfNodes.length();
259   std::vector<const SMDS_MeshNode*> n (NbNodes);
260   for (int i = 0; i < NbNodes; i++)
261     n[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
262
263   int NbFaces = Quantities.length();
264   std::vector<int> q (NbFaces);
265   for (int j = 0; j < NbFaces; j++)
266     q[j] = Quantities[j];
267
268   GetMeshDS()->AddPolyhedralVolume(n, q);
269
270   // Update Python script
271   TCollection_AsciiString str ("isDone = mesh_editor.AddPolyhedralVolume(");
272   SMESH_Gen_i::AddArray( str, IDsOfNodes ) += ", ";
273   SMESH_Gen_i::AddArray( str, Quantities ) += ")";
274   SMESH_Gen_i::AddToCurrentPyScript( str );
275 #ifdef _DEBUG_
276   SMESH_Gen_i::AddToCurrentPyScript( "print \"AddPolyhedralVolume: \", isDone" );
277 #endif
278
279   return true;
280 };
281
282 //=============================================================================
283 /*!
284  *  AddPolyhedralVolumeByFaces
285  */
286 //=============================================================================
287 CORBA::Boolean SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces
288                                    (const SMESH::long_array & IdsOfFaces)
289 {
290   int NbFaces = IdsOfFaces.length();
291   std::vector<const SMDS_MeshNode*> poly_nodes;
292   std::vector<int> quantities (NbFaces);
293
294   for (int i = 0; i < NbFaces; i++) {
295     const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]);
296     quantities[i] = aFace->NbNodes();
297
298     SMDS_ElemIteratorPtr It = aFace->nodesIterator();
299     while (It->more()) {
300       poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
301     }
302   }
303
304   GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
305
306   // Update Python script
307   TCollection_AsciiString str ("isDone = mesh_editor.AddPolyhedralVolumeByFaces(");
308   SMESH_Gen_i::AddArray( str, IdsOfFaces ) += ")";
309   SMESH_Gen_i::AddToCurrentPyScript( str );
310 #ifdef _DEBUG_
311   SMESH_Gen_i::AddToCurrentPyScript( "print \"AddPolyhedralVolume: \", isDone" );
312 #endif
313
314   return true;
315 };
316
317 //=============================================================================
318 /*!
319  *  
320  */
321 //=============================================================================
322
323 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
324                                             CORBA::Double x,
325                                             CORBA::Double y,
326                                             CORBA::Double z)
327 {
328   const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
329   if ( !node )
330     return false;
331   
332   GetMeshDS()->MoveNode(node, x, y, z);
333
334   // Update Python script
335   TCollection_AsciiString str ("isDone = mesh_editor.MoveNode(");
336   str += TCollection_AsciiString((Standard_Integer) NodeID) + ", ";
337   str += TCollection_AsciiString((Standard_Real) x) + ", ";
338   str += TCollection_AsciiString((Standard_Real) y) + ", ";
339   str += TCollection_AsciiString((Standard_Real) z) + " )";
340   SMESH_Gen_i::AddToCurrentPyScript( str );
341
342   return true;
343 }
344
345 //=============================================================================
346 /*!
347  *  
348  */
349 //=============================================================================
350
351 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
352                                                CORBA::Long NodeID2)
353 {
354   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
355   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
356   if ( !n1 || !n2 )
357     return false;
358
359   // Update Python script
360   TCollection_AsciiString str ("isDone = mesh_editor.InverseDiag(");
361   str += TCollection_AsciiString((Standard_Integer) NodeID1) + ", ";
362   str += TCollection_AsciiString((Standard_Integer) NodeID2) + " )";
363   SMESH_Gen_i::AddToCurrentPyScript( str );
364
365   ::SMESH_MeshEditor aMeshEditor( _myMesh );
366   return aMeshEditor.InverseDiag ( n1, n2 );
367 }
368
369 //=============================================================================
370 /*!
371  *  
372  */
373 //=============================================================================
374
375 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
376                                               CORBA::Long NodeID2)
377 {
378   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
379   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
380   if ( !n1 || !n2 )
381     return false;
382
383   // Update Python script
384   TCollection_AsciiString str ("isDone = mesh_editor.DeleteDiag(");
385   str += TCollection_AsciiString((Standard_Integer) NodeID1) + ", ";
386   str += TCollection_AsciiString((Standard_Integer) NodeID2) + " )";
387   SMESH_Gen_i::AddToCurrentPyScript( str );
388
389   ::SMESH_MeshEditor aMeshEditor( _myMesh );
390   return aMeshEditor.DeleteDiag ( n1, n2 );
391 }
392
393 //=============================================================================
394 /*!
395  *  
396  */
397 //=============================================================================
398
399 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
400 {
401   ::SMESH_MeshEditor anEditor( _myMesh );
402   for (int i = 0; i < IDsOfElements.length(); i++)
403   {
404     CORBA::Long index = IDsOfElements[i];
405     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
406     if ( elem )
407       anEditor.Reorient( elem );
408   }
409   // Update Python script
410   TCollection_AsciiString str ("isDone = mesh_editor.Reorient(");
411   SMESH_Gen_i::AddArray( str, IDsOfElements ) += ")";
412   SMESH_Gen_i::AddToCurrentPyScript( str );
413
414   return true;
415 }
416
417
418 //=============================================================================
419 /*!
420  *  
421  */
422 //=============================================================================
423
424 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
425 {
426   SMESH::long_array_var anElementsId = theObject->GetIDs();
427   CORBA::Boolean isDone = Reorient(anElementsId);
428
429   // Clear python line, created by Reorient()
430   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
431   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
432
433   // Update Python script
434   TCollection_AsciiString str ("isDone = mesh_editor.ReorientObject(");
435   SMESH_Gen_i::AddObject( str, theObject ) += ")";
436   SMESH_Gen_i::AddToCurrentPyScript( str );
437
438   return isDone;
439 }
440
441 //=============================================================================
442 /*!
443  *  
444  */
445 //=============================================================================
446
447 CORBA::Boolean
448   SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfElements,
449                                  SMESH::NumericalFunctor_ptr Criterion,
450                                  CORBA::Double               MaxAngle)
451 {
452   set<const SMDS_MeshElement*> faces;
453   for (int i = 0; i < IDsOfElements.length(); i++)
454   {
455     CORBA::Long index = IDsOfElements[i];
456     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
457     if ( elem && elem->GetType() == SMDSAbs_Face)
458       faces.insert( elem );
459   }
460   SMESH::NumericalFunctor_i* aNumericalFunctor = 
461     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
462   SMESH::Controls::NumericalFunctorPtr aCrit;
463   if ( !aNumericalFunctor )
464     aCrit.reset( new SMESH::Controls::AspectRatio() );
465   else
466     aCrit = aNumericalFunctor->GetNumericalFunctor();
467
468   // Update Python script
469   TCollection_AsciiString str ("isDone = mesh_editor.TriToQuad(");
470   SMESH_Gen_i::AddArray( str, IDsOfElements ) += ", None, ";
471   str += (Standard_Real) MaxAngle;
472   SMESH_Gen_i::AddToCurrentPyScript( str + ")" );
473 #ifdef _DEBUG_
474   SMESH_Gen_i::AddToCurrentPyScript( "print \"TriToQuad: \", isDone" );
475 #endif
476
477   ::SMESH_MeshEditor anEditor( _myMesh );
478   return anEditor.TriToQuad( faces, aCrit, MaxAngle );
479 }
480
481 //=============================================================================
482 /*!
483  *  
484  */
485 //=============================================================================
486
487 CORBA::Boolean
488   SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr   theObject,
489                                        SMESH::NumericalFunctor_ptr Criterion,
490                                        CORBA::Double               MaxAngle)
491 {
492   SMESH::long_array_var anElementsId = theObject->GetIDs();
493   CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
494
495   // Clear python line(s), created by TriToQuad()
496   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
497   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
498 #ifdef _DEBUG_
499   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
500 #endif
501
502   // Update Python script
503   TCollection_AsciiString str ("isDone = mesh_editor.TriToQuadObject(");
504   SMESH_Gen_i::AddObject( str, theObject ) += ", None, ";
505   str += (Standard_Real) MaxAngle;
506   SMESH_Gen_i::AddToCurrentPyScript( str + ")" );
507 #ifdef _DEBUG_
508   SMESH_Gen_i::AddToCurrentPyScript( "print \"TriToQuadObject: \", isDone" );
509 #endif
510
511   return isDone;
512 }
513
514 //=============================================================================
515 /*!
516  *  
517  */
518 //=============================================================================
519
520 CORBA::Boolean
521   SMESH_MeshEditor_i::QuadToTri(const SMESH::long_array &   IDsOfElements,
522                                 SMESH::NumericalFunctor_ptr Criterion)
523 {
524   set<const SMDS_MeshElement*> faces;
525   for (int i = 0; i < IDsOfElements.length(); i++)
526   {
527     CORBA::Long index = IDsOfElements[i];
528     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
529     if ( elem && elem->GetType() == SMDSAbs_Face)
530       faces.insert( elem );
531   }
532   SMESH::NumericalFunctor_i* aNumericalFunctor = 
533     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
534   SMESH::Controls::NumericalFunctorPtr aCrit;
535   if ( !aNumericalFunctor )
536     aCrit.reset( new SMESH::Controls::AspectRatio() );
537   else
538     aCrit = aNumericalFunctor->GetNumericalFunctor();
539
540
541   // Update Python script
542   TCollection_AsciiString str ("isDone = mesh_editor.QuadToTri(");
543   SMESH_Gen_i::AddArray( str, IDsOfElements ) += ", None ), ";
544   SMESH_Gen_i::AddToCurrentPyScript( str );
545 #ifdef _DEBUG_
546   SMESH_Gen_i::AddToCurrentPyScript( "print \"QuadToTri: \", isDone" );
547 #endif
548
549   ::SMESH_MeshEditor anEditor( _myMesh );
550   return anEditor.QuadToTri( faces, aCrit );
551 }
552
553 //=============================================================================
554 /*!
555  *  
556  */
557 //=============================================================================
558
559 CORBA::Boolean
560   SMESH_MeshEditor_i::SplitQuad(const SMESH::long_array & IDsOfElements,
561                                 CORBA::Boolean            Diag13)
562 {
563   set<const SMDS_MeshElement*> faces;
564   for (int i = 0; i < IDsOfElements.length(); i++)
565   {
566     CORBA::Long index = IDsOfElements[i];
567     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
568     if ( elem && elem->GetType() == SMDSAbs_Face)
569       faces.insert( elem );
570   }
571
572   // Update Python script
573   TCollection_AsciiString str ("isDone = mesh_editor.SplitQuad(");
574   SMESH_Gen_i::AddArray( str, IDsOfElements ) += ", ";
575   str += TCollection_AsciiString( Diag13 );
576   SMESH_Gen_i::AddToCurrentPyScript( str + ")" );
577 #ifdef _DEBUG_
578   SMESH_Gen_i::AddToCurrentPyScript( "print \"SplitQuad: \", isDone" );
579 #endif
580
581   ::SMESH_MeshEditor anEditor( _myMesh );
582   return anEditor.QuadToTri( faces, Diag13 );
583 }
584
585 //=============================================================================
586 /*!
587  *  
588  */
589 //=============================================================================
590
591 CORBA::Boolean
592   SMESH_MeshEditor_i::SplitQuadObject(SMESH::SMESH_IDSource_ptr theObject,
593                                       CORBA::Boolean            Diag13)
594 {
595   SMESH::long_array_var anElementsId = theObject->GetIDs();
596   CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
597
598   // Clear python line(s), created by SplitQuad()
599   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
600   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
601 #ifdef _DEBUG_
602   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
603 #endif
604
605   // Update Python script
606   TCollection_AsciiString str ("isDone = mesh_editor.SplitQuadObject(");
607   SMESH_Gen_i::AddObject( str, theObject ) += ", ";
608   str += TCollection_AsciiString( Diag13 ) + ")";
609   SMESH_Gen_i::AddToCurrentPyScript( str );
610 #ifdef _DEBUG_
611   SMESH_Gen_i::AddToCurrentPyScript( "print \"SplitQuadObject: \", isDone" );
612 #endif
613
614   return isDone;
615 }
616
617 //=============================================================================
618 /*!
619  *  
620  */
621 //=============================================================================
622
623 CORBA::Boolean
624   SMESH_MeshEditor_i::Smooth(const SMESH::long_array &              IDsOfElements,
625                              const SMESH::long_array &              IDsOfFixedNodes,
626                              CORBA::Long                            MaxNbOfIterations,
627                              CORBA::Double                          MaxAspectRatio,
628                              SMESH::SMESH_MeshEditor::Smooth_Method Method)
629 {
630   SMESHDS_Mesh* aMesh = GetMeshDS();
631
632   set<const SMDS_MeshElement*> elements;
633   for (int i = 0; i < IDsOfElements.length(); i++)
634   {
635     CORBA::Long index = IDsOfElements[i];
636     const SMDS_MeshElement * elem = aMesh->FindElement(index);
637     if ( elem && elem->GetType() == SMDSAbs_Face)
638       elements.insert( elem );
639   }
640
641   set<const SMDS_MeshNode*> fixedNodes;
642   for (int i = 0; i < IDsOfFixedNodes.length(); i++)
643   {
644     CORBA::Long index = IDsOfFixedNodes[i];
645     const SMDS_MeshNode * node = aMesh->FindNode(index);
646     if ( node )
647       fixedNodes.insert( node );
648   }
649   ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
650   if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
651     method = ::SMESH_MeshEditor::CENTROIDAL;
652
653   ::SMESH_MeshEditor anEditor( _myMesh );
654   anEditor.Smooth( elements, fixedNodes, method, MaxNbOfIterations, MaxAspectRatio );
655
656   // Update Python script
657   TCollection_AsciiString str ("isDone = mesh_editor.Smooth(");
658   SMESH_Gen_i::AddArray( str, IDsOfElements ) += ", ";
659   SMESH_Gen_i::AddArray( str, IDsOfFixedNodes ) += ", ";
660   str += (Standard_Integer) MaxNbOfIterations;
661   str += ", ";
662   str += (Standard_Real) MaxAspectRatio;
663   if ( method == ::SMESH_MeshEditor::CENTROIDAL )
664     str += ", SMESH.SMESH_MeshEditor.CENTROIDAL_SMOOTH )";
665   else
666     str += ", SMESH.SMESH_MeshEditor.LAPLACIAN_SMOOTH )";
667   SMESH_Gen_i::AddToCurrentPyScript( str );
668 #ifdef _DEBUG_
669   SMESH_Gen_i::AddToCurrentPyScript( "print \"Smooth: \", isDone" );
670 #endif
671
672   return true;
673 }
674
675 //=============================================================================
676 /*!
677  *  
678  */
679 //=============================================================================
680
681 CORBA::Boolean
682   SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr              theObject,
683                                    const SMESH::long_array &              IDsOfFixedNodes,
684                                    CORBA::Long                            MaxNbOfIterations,
685                                    CORBA::Double                          MaxAspectRatio,
686                                    SMESH::SMESH_MeshEditor::Smooth_Method Method)
687 {
688   SMESH::long_array_var anElementsId = theObject->GetIDs();
689   CORBA::Boolean isDone = Smooth
690     (anElementsId, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method);
691
692   // Clear python line(s), created by Smooth()
693   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
694   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
695 #ifdef _DEBUG_
696   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
697 #endif
698
699   // Update Python script
700   TCollection_AsciiString str ("isDone = mesh_editor.SmoothObject(");
701   SMESH_Gen_i::AddObject( str, theObject ) += ", ";
702   SMESH_Gen_i::AddArray( str, IDsOfFixedNodes ) += ", ";
703   str += (Standard_Integer) MaxNbOfIterations;
704   str += ", ";
705   str += (Standard_Real) MaxAspectRatio;
706   if ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH )
707     str += ", SMESH.SMESH_MeshEditor.CENTROIDAL_SMOOTH )";
708   else
709     str += ", SMESH.SMESH_MeshEditor.LAPLACIAN_SMOOTH )";
710   SMESH_Gen_i::AddToCurrentPyScript( str );
711 #ifdef _DEBUG_
712   SMESH_Gen_i::AddToCurrentPyScript( "print \"SmoothObject: \", isDone" );
713 #endif
714
715   return isDone;
716 }
717
718 //=============================================================================
719 /*!
720  *  
721  */
722 //=============================================================================
723
724 void SMESH_MeshEditor_i::RenumberNodes()
725 {
726   // Update Python script
727   SMESH_Gen_i::AddToCurrentPyScript( "mesh_editor.RenumberNodes()" );
728
729   GetMeshDS()->Renumber( true );
730 }
731
732 //=============================================================================
733 /*!
734  *  
735  */
736 //=============================================================================
737
738 void SMESH_MeshEditor_i::RenumberElements()
739 {
740   // Update Python script
741   SMESH_Gen_i::AddToCurrentPyScript( "mesh_editor.RenumberElements()" );
742
743   GetMeshDS()->Renumber( false );
744 }
745
746 //=======================================================================
747 //function : RotationSweep
748 //purpose  : 
749 //=======================================================================
750
751 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
752                                        const SMESH::AxisStruct & theAxis,
753                                        CORBA::Double             theAngleInRadians,
754                                        CORBA::Long               theNbOfSteps,
755                                        CORBA::Double             theTolerance)
756 {
757   SMESHDS_Mesh* aMesh = GetMeshDS();
758
759   set<const SMDS_MeshElement*> elements;
760   for (int i = 0; i < theIDsOfElements.length(); i++)
761   {
762     CORBA::Long index = theIDsOfElements[i];
763     const SMDS_MeshElement * elem = aMesh->FindElement(index);
764     if ( elem )
765       elements.insert( elem );
766   }
767   gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
768               gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
769
770   ::SMESH_MeshEditor anEditor( _myMesh );
771   anEditor.RotationSweep (elements, Ax1, theAngleInRadians,
772                           theNbOfSteps, theTolerance);
773
774   // Update Python script
775   TCollection_AsciiString str = "axis = ";
776   addAxis( str, theAxis );
777   SMESH_Gen_i::AddToCurrentPyScript( str );
778   str = "mesh_editor.RotationSweep(";
779   SMESH_Gen_i::AddArray( str, theIDsOfElements ) += ", axis, ";
780   str += TCollection_AsciiString( theAngleInRadians ) + ", ";
781   str += TCollection_AsciiString( (int)theNbOfSteps ) + ", ";
782   str += TCollection_AsciiString( theTolerance      ) + " )";
783   SMESH_Gen_i::AddToCurrentPyScript( str );
784 }
785
786 //=======================================================================
787 //function : RotationSweepObject
788 //purpose  : 
789 //=======================================================================
790
791 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
792                                              const SMESH::AxisStruct & theAxis,
793                                              CORBA::Double             theAngleInRadians,
794                                              CORBA::Long               theNbOfSteps,
795                                              CORBA::Double             theTolerance)
796 {
797   SMESH::long_array_var anElementsId = theObject->GetIDs();
798   RotationSweep(anElementsId, theAxis, theAngleInRadians, theNbOfSteps, theTolerance);
799
800   // Clear python line, created by RotationSweep()
801   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
802   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
803
804   // Update Python script
805   TCollection_AsciiString str ("mesh_editor.RotationSweepObject(");
806   SMESH_Gen_i::AddObject( str, theObject ) += ", axis, ";
807   str += TCollection_AsciiString( theAngleInRadians ) + ", ";
808   str += TCollection_AsciiString( (int)theNbOfSteps ) + ", ";
809   str += TCollection_AsciiString( theTolerance      ) + " )";
810   SMESH_Gen_i::AddToCurrentPyScript( str );
811 }
812
813 //=======================================================================
814 //function : ExtrusionSweep
815 //purpose  : 
816 //=======================================================================
817
818 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
819                                         const SMESH::DirStruct &  theStepVector,
820                                         CORBA::Long               theNbOfSteps)
821 {
822   SMESHDS_Mesh* aMesh = GetMeshDS();
823
824   set<const SMDS_MeshElement*> elements;
825   for (int i = 0; i < theIDsOfElements.length(); i++)
826   {
827     CORBA::Long index = theIDsOfElements[i];
828     const SMDS_MeshElement * elem = aMesh->FindElement(index);
829     if ( elem )
830       elements.insert( elem );
831   }
832   const SMESH::PointStruct * P = &theStepVector.PS;
833   gp_Vec stepVec( P->x, P->y, P->z );
834
835   ::SMESH_MeshEditor anEditor( _myMesh );
836   anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps);
837
838   // Update Python script
839   TCollection_AsciiString str = "stepVector = SMESH.DirStruct( SMESH.PointStruct ( ";
840   str += (TCollection_AsciiString) stepVec.X() + ", ";
841   str += (TCollection_AsciiString) stepVec.Y() + ", ";
842   str += (TCollection_AsciiString) stepVec.Z() + " ))";
843   SMESH_Gen_i::AddToCurrentPyScript( str );
844   str = ("mesh_editor.ExtrusionSweep(");
845   SMESH_Gen_i::AddArray( str, theIDsOfElements ) += ", stepVector, ";
846   str += TCollection_AsciiString((int)theNbOfSteps) + " )";
847   SMESH_Gen_i::AddToCurrentPyScript( str );
848 }
849
850
851 //=======================================================================
852 //function : ExtrusionSweepObject
853 //purpose  : 
854 //=======================================================================
855
856 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
857                                               const SMESH::DirStruct &  theStepVector,
858                                               CORBA::Long               theNbOfSteps)
859 {
860   SMESH::long_array_var anElementsId = theObject->GetIDs();
861   ExtrusionSweep(anElementsId, theStepVector, theNbOfSteps);
862
863   // Clear python line, created by ExtrusionSweep()
864   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
865   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
866
867   // Update Python script
868   TCollection_AsciiString str ("mesh_editor.ExtrusionSweepObject(");
869   SMESH_Gen_i::AddObject( str, theObject ) += ", stepVector, ";
870   str += TCollection_AsciiString((int)theNbOfSteps) + " )";
871   SMESH_Gen_i::AddToCurrentPyScript( str );
872 }
873
874 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
875
876 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
877 {
878   switch ( e ) {
879   RETCASE( EXTR_OK );
880   RETCASE( EXTR_NO_ELEMENTS );
881   RETCASE( EXTR_PATH_NOT_EDGE );
882   RETCASE( EXTR_BAD_PATH_SHAPE );
883   RETCASE( EXTR_BAD_STARTING_NODE );
884   RETCASE( EXTR_BAD_ANGLES_NUMBER );
885   RETCASE( EXTR_CANT_GET_TANGENT );
886   }
887   return SMESH::SMESH_MeshEditor::EXTR_OK;
888 }
889
890 //=======================================================================
891 //function : ExtrusionAlongPath
892 //purpose  : 
893 //=======================================================================
894
895 SMESH::SMESH_MeshEditor::Extrusion_Error
896   SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
897                                          SMESH::SMESH_Mesh_ptr       thePathMesh,
898                                          GEOM::GEOM_Object_ptr       thePathShape,
899                                          CORBA::Long                 theNodeStart,
900                                          CORBA::Boolean              theHasAngles,
901                                          const SMESH::double_array & theAngles,
902                                          CORBA::Boolean              theHasRefPoint,
903                                          const SMESH::PointStruct &  theRefPoint)
904 {
905   SMESHDS_Mesh*  aMesh = GetMeshDS();
906
907   if ( thePathMesh->_is_nil() || thePathShape->_is_nil() )
908     return SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
909
910   SMESH_Mesh_i* aMeshImp = dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( thePathMesh ).in() );
911   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
912   SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
913
914   if ( !aSubMesh )
915     return SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
916
917   SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
918   if ( !nodeStart )
919     return SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
920
921   set<const SMDS_MeshElement*> elements;
922   for (int i = 0; i < theIDsOfElements.length(); i++)
923   {
924     CORBA::Long index = theIDsOfElements[i];
925     const SMDS_MeshElement * elem = aMesh->FindElement(index);
926     if ( elem )
927       elements.insert( elem );
928   }
929
930   list<double> angles;
931   for (int i = 0; i < theAngles.length(); i++)
932   {
933     angles.push_back( theAngles[i] );
934   }
935
936   gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
937
938   // Update Python script
939   TCollection_AsciiString str = "refPoint = SMESH.PointStruct( ";
940   str += (TCollection_AsciiString) refPnt.X() + ", ";
941   str += (TCollection_AsciiString) refPnt.Y() + ", ";
942   str += (TCollection_AsciiString) refPnt.Z() + " )";
943   SMESH_Gen_i::AddToCurrentPyScript( str );
944   str = ("error = mesh_editor.ExtrusionAlongPath(");
945   SMESH_Gen_i::AddArray ( str, theIDsOfElements ) += ", ";
946   SMESH_Gen_i::AddObject( str, thePathMesh ) += ", ";
947   SMESH_Gen_i::AddObject( str, thePathShape ) += ", ";
948   str += TCollection_AsciiString( (int)theNodeStart ) + ", ";
949   str += TCollection_AsciiString( (int)theHasAngles ) + ", ";
950   SMESH_Gen_i::AddArray ( str, theAngles ) += ", ";
951   str += (TCollection_AsciiString) theHasRefPoint + ", refPoint )";
952   SMESH_Gen_i::AddToCurrentPyScript( str );
953
954   ::SMESH_MeshEditor anEditor( _myMesh );
955   return convExtrError( anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart, theHasAngles, angles, theHasRefPoint, refPnt ) );
956 }
957
958 //=======================================================================
959 //function : ExtrusionAlongPathObject
960 //purpose  : 
961 //=======================================================================
962
963 SMESH::SMESH_MeshEditor::Extrusion_Error
964   SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObject,
965                                                SMESH::SMESH_Mesh_ptr       thePathMesh,
966                                                GEOM::GEOM_Object_ptr       thePathShape,
967                                                CORBA::Long                 theNodeStart,
968                                                CORBA::Boolean              theHasAngles,
969                                                const SMESH::double_array & theAngles,
970                                                CORBA::Boolean              theHasRefPoint,
971                                                const SMESH::PointStruct &  theRefPoint)
972 {
973   SMESH::long_array_var anElementsId = theObject->GetIDs();
974   SMESH::SMESH_MeshEditor::Extrusion_Error error = ExtrusionAlongPath
975     (anElementsId, thePathMesh, thePathShape, theNodeStart,
976      theHasAngles, theAngles, theHasRefPoint, theRefPoint);
977
978   // Clear python line, created by ExtrusionAlongPath()
979   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
980   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
981
982   // Update Python script
983   TCollection_AsciiString str ("error = mesh_editor.ExtrusionAlongPathObject(");
984   SMESH_Gen_i::AddObject( str, theObject ) += ", ";
985   SMESH_Gen_i::AddObject( str, thePathMesh ) += ", ";
986   SMESH_Gen_i::AddObject( str, thePathShape ) += ", ";
987   str += TCollection_AsciiString( (int)theNodeStart ) + ", ";
988   str += TCollection_AsciiString( theHasAngles ) + ", ";
989   SMESH_Gen_i::AddArray ( str, theAngles ) += ", ";
990   str += TCollection_AsciiString( theHasRefPoint ) + ", refPoint )";
991   SMESH_Gen_i::AddToCurrentPyScript( str );
992
993   return error;
994 }
995
996 //=======================================================================
997 //function : Mirror
998 //purpose  : 
999 //=======================================================================
1000
1001 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElements,
1002                                 const SMESH::AxisStruct &           theAxis,
1003                                 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
1004                                 CORBA::Boolean                      theCopy)
1005 {
1006   SMESHDS_Mesh* aMesh = GetMeshDS();
1007
1008   set<const SMDS_MeshElement*> elements;
1009   for (int i = 0; i < theIDsOfElements.length(); i++)
1010   {
1011     CORBA::Long index = theIDsOfElements[i];
1012     const SMDS_MeshElement * elem = aMesh->FindElement(index);
1013     if ( elem )
1014       elements.insert( elem );
1015   }
1016   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
1017   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
1018
1019   gp_Trsf aTrsf;
1020   TCollection_AsciiString typeStr, copyStr( theCopy );
1021   switch ( theMirrorType ) {
1022   case  SMESH::SMESH_MeshEditor::POINT:
1023     aTrsf.SetMirror( P );
1024     typeStr = "SMESH.SMESH_MeshEditor.POINT";
1025     break;
1026   case  SMESH::SMESH_MeshEditor::AXIS:
1027     aTrsf.SetMirror( gp_Ax1( P, V ));
1028     typeStr = "SMESH.SMESH_MeshEditor.AXIS";
1029     break;
1030   default:
1031     aTrsf.SetMirror( gp_Ax2( P, V ));
1032     typeStr = "SMESH.SMESH_MeshEditor.PLANE";
1033   }
1034
1035   // Update Python script
1036   TCollection_AsciiString str ("mesh_editor.Mirror(");
1037   SMESH_Gen_i::AddArray( str, theIDsOfElements ) += ", ";
1038   addAxis( str, theAxis )           += ", ";
1039   str += typeStr                     + ", ";
1040   str += copyStr                     + " )";
1041   SMESH_Gen_i::AddToCurrentPyScript( str );
1042
1043   ::SMESH_MeshEditor anEditor( _myMesh );
1044   anEditor.Transform (elements, aTrsf, theCopy);
1045 }
1046
1047 //=======================================================================
1048 //function : MirrorObject
1049 //purpose  : 
1050 //=======================================================================
1051
1052 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr           theObject,
1053                                       const SMESH::AxisStruct &           theAxis,
1054                                       SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
1055                                       CORBA::Boolean                      theCopy)
1056 {
1057   SMESH::long_array_var anElementsId = theObject->GetIDs();
1058   Mirror(anElementsId, theAxis, theMirrorType, theCopy);
1059
1060   // Clear python line, created by Mirror()
1061   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1062   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1063
1064   // Update Python script
1065   TCollection_AsciiString typeStr, copyStr( theCopy );
1066   switch ( theMirrorType ) {
1067   case  SMESH::SMESH_MeshEditor::POINT:
1068     typeStr = "SMESH.SMESH_MeshEditor.POINT";
1069     break;
1070   case  SMESH::SMESH_MeshEditor::AXIS:
1071     typeStr = "SMESH.SMESH_MeshEditor.AXIS";
1072     break;
1073   default:
1074     typeStr = "SMESH.SMESH_MeshEditor.PLANE";
1075   }
1076
1077   TCollection_AsciiString str ("mesh_editor.MirrorObject(");
1078   SMESH_Gen_i::AddObject( str, theObject ) += ", ";
1079   addAxis( str, theAxis ) += ", ";
1080   str += typeStr + ", " + copyStr + " )";
1081   SMESH_Gen_i::AddToCurrentPyScript( str );
1082 }
1083
1084 //=======================================================================
1085 //function : Translate
1086 //purpose  : 
1087 //=======================================================================
1088
1089 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
1090                                    const SMESH::DirStruct &  theVector,
1091                                    CORBA::Boolean            theCopy)
1092 {
1093   SMESHDS_Mesh* aMesh = GetMeshDS();
1094
1095   set<const SMDS_MeshElement*> elements;
1096   for (int i = 0; i < theIDsOfElements.length(); i++)
1097   {
1098     CORBA::Long index = theIDsOfElements[i];
1099     const SMDS_MeshElement * elem = aMesh->FindElement(index);
1100     if ( elem )
1101       elements.insert( elem );
1102   }
1103   gp_Trsf aTrsf;
1104   const SMESH::PointStruct * P = &theVector.PS;
1105   aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
1106
1107   ::SMESH_MeshEditor anEditor( _myMesh );
1108   anEditor.Transform (elements, aTrsf, theCopy);
1109
1110   // Update Python script
1111   TCollection_AsciiString str = "vector = SMESH.DirStruct( SMESH.PointStruct ( ";
1112   str += (TCollection_AsciiString) P->x + ", ";
1113   str += (TCollection_AsciiString) P->y + ", ";
1114   str += (TCollection_AsciiString) P->z + " ))";
1115   SMESH_Gen_i::AddToCurrentPyScript( str );
1116   str = ("mesh_editor.Translate(");
1117   SMESH_Gen_i::AddArray( str, theIDsOfElements ) += ", vector, ";
1118   str += (TCollection_AsciiString) theCopy + " )";
1119   SMESH_Gen_i::AddToCurrentPyScript( str );
1120 }
1121
1122 //=======================================================================
1123 //function : TranslateObject
1124 //purpose  : 
1125 //=======================================================================
1126
1127 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
1128                                          const SMESH::DirStruct &  theVector,
1129                                          CORBA::Boolean            theCopy)
1130 {
1131   SMESH::long_array_var anElementsId = theObject->GetIDs();
1132   Translate(anElementsId, theVector, theCopy);
1133
1134   // Clear python line, created by Translate()
1135   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1136   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1137
1138   // Update Python script
1139   TCollection_AsciiString str ("mesh_editor.TranslateObject(");
1140   SMESH_Gen_i::AddObject( str, theObject ) += ", vector, ";
1141   str += TCollection_AsciiString( theCopy ) + " )";
1142   SMESH_Gen_i::AddToCurrentPyScript( str );
1143 }
1144
1145 //=======================================================================
1146 //function : Rotate
1147 //purpose  : 
1148 //=======================================================================
1149
1150 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
1151                                 const SMESH::AxisStruct & theAxis,
1152                                 CORBA::Double             theAngle,
1153                                 CORBA::Boolean            theCopy)
1154 {
1155   SMESHDS_Mesh* aMesh = GetMeshDS();
1156
1157   set<const SMDS_MeshElement*> elements;
1158   for (int i = 0; i < theIDsOfElements.length(); i++)
1159   {
1160     CORBA::Long index = theIDsOfElements[i];
1161     const SMDS_MeshElement * elem = aMesh->FindElement(index);
1162     if ( elem )
1163       elements.insert( elem );
1164   }
1165   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
1166   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
1167
1168   gp_Trsf aTrsf;
1169   aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
1170   
1171   ::SMESH_MeshEditor anEditor( _myMesh );
1172   anEditor.Transform (elements, aTrsf, theCopy);
1173
1174   // Update Python script
1175   TCollection_AsciiString str ("axis = ");
1176   addAxis( str, theAxis );
1177   SMESH_Gen_i::AddToCurrentPyScript( str );
1178   str = ("mesh_editor.Rotate(");
1179   SMESH_Gen_i::AddArray( str, theIDsOfElements ) += ", axis, ";
1180   str += (TCollection_AsciiString) theAngle + ", ";
1181   str += (TCollection_AsciiString) theCopy + " )";
1182   SMESH_Gen_i::AddToCurrentPyScript( str );
1183 }
1184
1185 //=======================================================================
1186 //function : RotateObject
1187 //purpose  : 
1188 //=======================================================================
1189
1190 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
1191                                       const SMESH::AxisStruct & theAxis,
1192                                       CORBA::Double             theAngle,
1193                                       CORBA::Boolean            theCopy)
1194 {
1195   SMESH::long_array_var anElementsId = theObject->GetIDs();
1196   Rotate(anElementsId, theAxis, theAngle, theCopy);
1197
1198   // Clear python line, created by Rotate()
1199   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1200   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1201
1202   // Update Python script
1203   TCollection_AsciiString str ("mesh_editor.RotateObject(");
1204   SMESH_Gen_i::AddObject( str, theObject ) += ", axis, ";
1205   str += TCollection_AsciiString( theAngle ) + ", ";
1206   str += TCollection_AsciiString( theCopy ) + " )";
1207   SMESH_Gen_i::AddToCurrentPyScript( str );
1208 }
1209
1210 //=======================================================================
1211 //function : FindCoincidentNodes
1212 //purpose  : 
1213 //=======================================================================
1214
1215 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
1216                                               SMESH::array_of_long_array_out GroupsOfNodes)
1217 {
1218   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
1219   ::SMESH_MeshEditor anEditor( _myMesh );
1220   set<const SMDS_MeshNode*> nodes; // no input nodes
1221   anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
1222
1223   GroupsOfNodes = new SMESH::array_of_long_array;
1224   GroupsOfNodes->length( aListOfListOfNodes.size() );
1225   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
1226   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
1227   {
1228     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
1229     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
1230     SMESH::long_array& aGroup = GroupsOfNodes[ i ];
1231     aGroup.length( aListOfNodes.size() );
1232     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
1233       aGroup[ j ] = (*lIt)->GetID();
1234   }
1235 }
1236
1237 //=======================================================================
1238 //function : MergeNodes
1239 //purpose  : 
1240 //=======================================================================
1241
1242 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
1243 {
1244   SMESHDS_Mesh* aMesh = GetMeshDS();
1245
1246   TCollection_AsciiString str( "mesh_editor.MergeNodes([" );
1247   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
1248   for (int i = 0; i < GroupsOfNodes.length(); i++)
1249   {
1250     const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
1251     aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
1252     list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
1253     for ( int j = 0; j < aNodeGroup.length(); j++ )
1254     {
1255       CORBA::Long index = aNodeGroup[ j ];
1256       const SMDS_MeshNode * node = aMesh->FindNode(index);
1257       if ( node )
1258         aListOfNodes.push_back( node );
1259     }
1260     if ( aListOfNodes.size() < 2 )
1261       aListOfListOfNodes.pop_back();
1262
1263     if ( i > 0 )
1264       str += ",";
1265     SMESH_Gen_i::AddArray( str, aNodeGroup );
1266   }
1267   ::SMESH_MeshEditor anEditor( _myMesh );
1268   anEditor.MergeNodes( aListOfListOfNodes );
1269
1270   // Update Python script
1271   SMESH_Gen_i::AddToCurrentPyScript( str + "])" );
1272 }
1273
1274 //=======================================================================
1275 //function : MergeEqualElements
1276 //purpose  : 
1277 //=======================================================================
1278
1279 void SMESH_MeshEditor_i::MergeEqualElements()
1280 {
1281   ::SMESH_MeshEditor anEditor( _myMesh );
1282   anEditor.MergeEqualElements();
1283
1284   // Update Python script
1285   SMESH_Gen_i::AddToCurrentPyScript( "mesh_editor.MergeEqualElements()" );
1286 }
1287
1288 //=======================================================================
1289 //function : operator
1290 //purpose  : 
1291 //=======================================================================
1292
1293 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
1294
1295 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
1296 {
1297   switch ( e ) {
1298   RETCASE( SEW_OK );
1299   RETCASE( SEW_BORDER1_NOT_FOUND );
1300   RETCASE( SEW_BORDER2_NOT_FOUND );
1301   RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
1302   RETCASE( SEW_BAD_SIDE_NODES );
1303   RETCASE( SEW_VOLUMES_TO_SPLIT );
1304   RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
1305   RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
1306   RETCASE( SEW_BAD_SIDE1_NODES );
1307   RETCASE( SEW_BAD_SIDE2_NODES );
1308   }
1309   return SMESH::SMESH_MeshEditor::SEW_OK;
1310 }
1311
1312 //=======================================================================
1313 //function : SewFreeBorders
1314 //purpose  : 
1315 //=======================================================================
1316
1317 SMESH::SMESH_MeshEditor::Sew_Error
1318   SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
1319                                      CORBA::Long SecondNodeID1,
1320                                      CORBA::Long LastNodeID1,
1321                                      CORBA::Long FirstNodeID2,
1322                                      CORBA::Long SecondNodeID2,
1323                                      CORBA::Long LastNodeID2,
1324                                      CORBA::Boolean CreatePolygons,
1325                                      CORBA::Boolean CreatePolyedrs)
1326 {
1327   SMESHDS_Mesh* aMesh = GetMeshDS();
1328
1329   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
1330   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
1331   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
1332   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
1333   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
1334   const SMDS_MeshNode* aSide2ThirdNode   = aMesh->FindNode( LastNodeID2   );
1335
1336   if (!aBorderFirstNode ||
1337       !aBorderSecondNode||
1338       !aBorderLastNode)
1339     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
1340   if (!aSide2FirstNode  ||
1341       !aSide2SecondNode ||
1342       !aSide2ThirdNode)
1343     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
1344
1345   // Update Python script
1346   TCollection_AsciiString str ("error = mesh_editor.SewFreeBorders( ");
1347   str += TCollection_AsciiString( (int) FirstNodeID1  )  + ", ";
1348   str += TCollection_AsciiString( (int) SecondNodeID1 )  + ", ";
1349   str += TCollection_AsciiString( (int) LastNodeID1   )  + ", ";
1350   str += TCollection_AsciiString( (int) FirstNodeID2  )  + ", ";
1351   str += TCollection_AsciiString( (int) SecondNodeID2 )  + ", ";
1352   str += TCollection_AsciiString( (int) LastNodeID2   )  + ", ";
1353   str += TCollection_AsciiString( CreatePolygons      )  + ", ";
1354   str += TCollection_AsciiString( CreatePolyedrs      )  + ") ";
1355   SMESH_Gen_i::AddToCurrentPyScript( str );
1356
1357   ::SMESH_MeshEditor anEditor( _myMesh );
1358   return convError( anEditor.SewFreeBorder (aBorderFirstNode,
1359                                             aBorderSecondNode,
1360                                             aBorderLastNode,
1361                                             aSide2FirstNode,
1362                                             aSide2SecondNode,
1363                                             aSide2ThirdNode,
1364                                             true,
1365                                             CreatePolygons,
1366                                             CreatePolyedrs) );
1367 }
1368
1369 //=======================================================================
1370 //function : SewConformFreeBorders
1371 //purpose  : 
1372 //=======================================================================
1373
1374 SMESH::SMESH_MeshEditor::Sew_Error
1375   SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
1376                                             CORBA::Long SecondNodeID1,
1377                                             CORBA::Long LastNodeID1,
1378                                             CORBA::Long FirstNodeID2,
1379                                             CORBA::Long SecondNodeID2)
1380 {
1381   SMESHDS_Mesh* aMesh = GetMeshDS();
1382
1383   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
1384   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
1385   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
1386   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
1387   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
1388   const SMDS_MeshNode* aSide2ThirdNode   = 0;
1389
1390   if (!aBorderFirstNode ||
1391       !aBorderSecondNode||
1392       !aBorderLastNode )
1393     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
1394   if (!aSide2FirstNode  ||
1395       !aSide2SecondNode)
1396     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
1397
1398   // Update Python script
1399   TCollection_AsciiString str ("error = mesh_editor.SewConformFreeBorders( ");
1400   str += TCollection_AsciiString( (int) FirstNodeID1  )  + ", ";
1401   str += TCollection_AsciiString( (int) SecondNodeID1 )  + ", ";
1402   str += TCollection_AsciiString( (int) LastNodeID1   )  + ", ";
1403   str += TCollection_AsciiString( (int) FirstNodeID2  )  + ", ";
1404   str += TCollection_AsciiString( (int) SecondNodeID2 )  + ")";
1405   SMESH_Gen_i::AddToCurrentPyScript( str );
1406
1407   ::SMESH_MeshEditor anEditor( _myMesh );
1408   return convError( anEditor.SewFreeBorder (aBorderFirstNode,
1409                                             aBorderSecondNode,
1410                                             aBorderLastNode,
1411                                             aSide2FirstNode,
1412                                             aSide2SecondNode,
1413                                             aSide2ThirdNode,
1414                                             true,
1415                                             false, false) );
1416 }
1417
1418 //=======================================================================
1419 //function : SewBorderToSide
1420 //purpose  : 
1421 //=======================================================================
1422
1423 SMESH::SMESH_MeshEditor::Sew_Error
1424   SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
1425                                       CORBA::Long SecondNodeIDOnFreeBorder,
1426                                       CORBA::Long LastNodeIDOnFreeBorder,
1427                                       CORBA::Long FirstNodeIDOnSide,
1428                                       CORBA::Long LastNodeIDOnSide,
1429                                       CORBA::Boolean CreatePolygons,
1430                                       CORBA::Boolean CreatePolyedrs)
1431 {
1432   SMESHDS_Mesh* aMesh = GetMeshDS();
1433
1434   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeIDOnFreeBorder  );
1435   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
1436   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeIDOnFreeBorder   );
1437   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeIDOnSide  );
1438   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( LastNodeIDOnSide );
1439   const SMDS_MeshNode* aSide2ThirdNode   = 0;
1440
1441   if (!aBorderFirstNode ||
1442       !aBorderSecondNode||
1443       !aBorderLastNode  )
1444     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
1445   if (!aSide2FirstNode  ||
1446       !aSide2SecondNode)
1447     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
1448
1449   // Update Python script
1450   TCollection_AsciiString str ("error = mesh_editor.SewBorderToSide( ");
1451   str += TCollection_AsciiString( (int) FirstNodeIDOnFreeBorder  ) + ", ";
1452   str += TCollection_AsciiString( (int) SecondNodeIDOnFreeBorder ) + ", ";
1453   str += TCollection_AsciiString( (int) LastNodeIDOnFreeBorder   ) + ", ";
1454   str += TCollection_AsciiString( (int) FirstNodeIDOnSide        ) + ", ";
1455   str += TCollection_AsciiString( (int) LastNodeIDOnSide         ) + ", ";
1456   str += TCollection_AsciiString( CreatePolygons                 ) + ", ";
1457   str += TCollection_AsciiString( CreatePolyedrs                 ) + ") ";
1458   SMESH_Gen_i::AddToCurrentPyScript( str );
1459
1460   ::SMESH_MeshEditor anEditor( _myMesh );
1461   return convError( anEditor.SewFreeBorder (aBorderFirstNode,
1462                                             aBorderSecondNode,
1463                                             aBorderLastNode,
1464                                             aSide2FirstNode,
1465                                             aSide2SecondNode,
1466                                             aSide2ThirdNode,
1467                                             false,
1468                                             CreatePolygons,
1469                                             CreatePolyedrs) );
1470 }
1471
1472 //=======================================================================
1473 //function : SewSideElements
1474 //purpose  : 
1475 //=======================================================================
1476
1477 SMESH::SMESH_MeshEditor::Sew_Error
1478   SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
1479                                       const SMESH::long_array& IDsOfSide2Elements,
1480                                       CORBA::Long NodeID1OfSide1ToMerge,
1481                                       CORBA::Long NodeID1OfSide2ToMerge,
1482                                       CORBA::Long NodeID2OfSide1ToMerge,
1483                                       CORBA::Long NodeID2OfSide2ToMerge)
1484 {
1485   SMESHDS_Mesh* aMesh = GetMeshDS();
1486
1487   const SMDS_MeshNode* aFirstNode1ToMerge  = aMesh->FindNode( NodeID1OfSide1ToMerge );
1488   const SMDS_MeshNode* aFirstNode2ToMerge  = aMesh->FindNode( NodeID1OfSide2ToMerge );
1489   const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
1490   const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
1491
1492   if (!aFirstNode1ToMerge ||
1493       !aFirstNode2ToMerge )
1494     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
1495   if (!aSecondNode1ToMerge||
1496       !aSecondNode2ToMerge)
1497     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
1498
1499   set<const SMDS_MeshElement*> aSide1Elems, aSide2Elems;
1500   for (int i = 0; i < IDsOfSide1Elements.length(); i++)
1501   {
1502     CORBA::Long index = IDsOfSide1Elements[i];
1503     const SMDS_MeshElement * elem = aMesh->FindElement(index);
1504     if ( elem )
1505       aSide1Elems.insert( elem );
1506   }
1507   for (int i = 0; i < IDsOfSide2Elements.length(); i++)
1508   {
1509     CORBA::Long index = IDsOfSide2Elements[i];
1510     const SMDS_MeshElement * elem = aMesh->FindElement(index);
1511     if ( elem )
1512       aSide2Elems.insert( elem );
1513   }
1514   // Update Python script
1515   TCollection_AsciiString str ("error = mesh_editor.SewSideElements( ");
1516   SMESH_Gen_i::AddArray( str, IDsOfSide1Elements ) += ", ";
1517   SMESH_Gen_i::AddArray( str, IDsOfSide2Elements ) += ", ";
1518   str += TCollection_AsciiString( (int) NodeID1OfSide1ToMerge ) + ", ";
1519   str += TCollection_AsciiString( (int) NodeID1OfSide2ToMerge ) + ", ";
1520   str += TCollection_AsciiString( (int) NodeID2OfSide1ToMerge ) + ", ";
1521   str += TCollection_AsciiString( (int) NodeID2OfSide2ToMerge ) + ")";
1522   SMESH_Gen_i::AddToCurrentPyScript( str );
1523
1524   ::SMESH_MeshEditor anEditor( _myMesh );
1525   return convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
1526                                               aFirstNode1ToMerge,
1527                                               aFirstNode2ToMerge,
1528                                               aSecondNode1ToMerge,
1529                                               aSecondNode2ToMerge));
1530 }