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