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