Salome HOME
PAL16774 (Crash after display of many groups)
[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 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
35 #include "SMESH_MeshEditor.hxx"
36 #include "SMESH_subMeshEventListener.hxx"
37 #include "SMESH_Gen_i.hxx"
38 #include "SMESH_Filter_i.hxx"
39 #include "SMESH_PythonDump.hxx"
40 #include "CASCatch.hxx"
41
42 #include "utilities.h"
43
44 #include <gp_Ax1.hxx>
45 #include <gp_Ax2.hxx>
46 #include <gp_Vec.hxx>
47
48 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
49 #define NO_CAS_CATCH
50 #endif
51
52 #include <Standard_Failure.hxx>
53
54 #ifdef NO_CAS_CATCH
55 #include <Standard_ErrorHandler.hxx>
56 #else
57 #include "CASCatch.hxx"
58 #endif
59
60 #include <sstream>
61
62 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
63
64 using namespace std;
65 using SMESH::TPythonDump;
66
67 namespace {
68
69   //=============================================================================
70   /*!
71    * \brief Mesh to apply modifications for preview purposes
72    */
73   //=============================================================================
74
75   struct TPreviewMesh: public SMESH_Mesh
76   {
77     SMDSAbs_ElementType myPreviewType; // type to show
78     //!< Constructor
79     TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
80       _isShapeToMesh = _id =_studyId =_idDoc = 0;
81       _myMeshDS  = new SMESHDS_Mesh( _id, true );
82       myPreviewType = previewElements;
83     }
84     //!< Destructor
85     virtual ~TPreviewMesh() { delete _myMeshDS; }
86     //!< Copy a set of elements
87     void Copy(const TIDSortedElemSet & theElements,
88               TIDSortedElemSet&        theCopyElements,
89               SMDSAbs_ElementType      theSelectType = SMDSAbs_All,
90               SMDSAbs_ElementType      theAvoidType = SMDSAbs_All)
91     {
92       // loop on theIDsOfElements
93       TIDSortedElemSet::const_iterator eIt = theElements.begin();
94       for ( ; eIt != theElements.end(); ++eIt )
95       {
96         const SMDS_MeshElement* anElem = *eIt;
97         if ( !anElem ) continue;
98         SMDSAbs_ElementType type = anElem->GetType();
99         if ( type == theAvoidType ||
100              ( theSelectType != SMDSAbs_All && type != theSelectType ))
101           continue;
102
103         if ( const SMDS_MeshElement* anElemCopy = Copy( anElem ))
104           theCopyElements.insert( theCopyElements.end(), anElemCopy );
105       }
106     }
107     //!< Copy an element
108     SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
109     {
110       // copy element nodes
111       int anElemNbNodes = anElem->NbNodes();
112       vector< int > anElemNodesID( anElemNbNodes ) ;
113       SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
114       for ( int i = 0; itElemNodes->more(); i++)
115       {
116         const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
117         Copy( anElemNode );
118         anElemNodesID[i] = anElemNode->GetID();
119       }
120
121       // creates a corresponding element on copied nodes
122       SMDS_MeshElement* anElemCopy = 0;
123       if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
124       {
125         const SMDS_PolyhedralVolumeOfNodes* ph =
126           dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem);
127         if ( ph )
128           anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
129             (anElemNodesID, ph->GetQuanities(),anElem->GetID());
130       }
131       else {
132         anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
133                                                           anElem->GetType(),
134                                                           anElem->IsPoly() );
135       }
136       return anElemCopy;
137     }
138     //!< Copy a node
139     SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
140     {
141       return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(), 
142                                       anElemNode->GetID());
143     }
144   };// struct TPreviewMesh
145
146   static SMESH_NodeSearcher * myNodeSearcher = 0;
147
148   //=============================================================================
149   /*!
150    * \brief Deleter of myNodeSearcher at any compute event occured
151    */
152   //=============================================================================
153
154   struct TNodeSearcherDeleter : public SMESH_subMeshEventListener
155   {
156     SMESH_Mesh* myMesh;
157     //!< Constructor
158     TNodeSearcherDeleter(): SMESH_subMeshEventListener( false ), // won't be deleted by submesh
159     myMesh(0) {}
160     //!< Delete myNodeSearcher
161     static void Delete()
162     {
163       if ( myNodeSearcher ) { delete myNodeSearcher; myNodeSearcher = 0; }
164     }
165     typedef map < int, SMESH_subMesh * > TDependsOnMap;
166     //!< The meshod called by submesh: do my main job
167     void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
168                       SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
169     {
170       if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
171         Delete();
172         Unset( sm->GetFather() );
173       }
174     }
175     //!< set self on all submeshes and delete myNodeSearcher if other mesh is set
176     void Set(SMESH_Mesh* mesh)
177     {
178       if ( myMesh && myMesh != mesh ) {
179         Delete();
180         Unset( myMesh );
181       }
182       myMesh = mesh;
183       if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
184         const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
185         TDependsOnMap::const_iterator sm;
186         for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
187           sm->second->SetEventListener( this, 0, sm->second );
188       }
189     }
190     //!<  delete self from all submeshes
191     void Unset(SMESH_Mesh* mesh)
192     {
193       if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
194         const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
195         TDependsOnMap::const_iterator sm;
196         for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
197           sm->second->DeleteEventListener( this );
198       }
199     }
200   };
201 }
202
203 //=============================================================================
204 /*!
205  *
206  */
207 //=============================================================================
208
209 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh* theMesh, bool isPreview)
210 {
211   myMesh = theMesh;
212   myPreviewMode = isPreview;
213 }
214
215 //================================================================================
216 /*!
217  * \brief Destructor
218  */
219 //================================================================================
220
221 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
222 {
223 }
224
225 //================================================================================
226 /*!
227  * \brief Clear members
228  */
229 //================================================================================
230
231 void SMESH_MeshEditor_i::initData()
232 {
233   if ( myPreviewMode ) {
234     myPreviewData = new SMESH::MeshPreviewStruct();
235   }
236   else {
237     myLastCreatedElems = new SMESH::long_array();
238     myLastCreatedNodes = new SMESH::long_array();
239     TNodeSearcherDeleter::Delete();
240   }
241 }
242
243 //=============================================================================
244 /*!
245  *
246  */
247 //=============================================================================
248
249 CORBA::Boolean
250   SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
251 {
252   initData();
253
254   ::SMESH_MeshEditor anEditor( myMesh );
255   list< int > IdList;
256
257   for (int i = 0; i < IDsOfElements.length(); i++)
258     IdList.push_back( IDsOfElements[i] );
259
260   // Update Python script
261   TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
262 #ifdef _DEBUG_
263   TPythonDump() << "print 'RemoveElements: ', isDone";
264 #endif
265   // Remove Elements
266   return anEditor.Remove( IdList, false );
267 }
268
269 //=============================================================================
270 /*!
271  *
272  */
273 //=============================================================================
274
275 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
276 {
277   initData();
278
279   ::SMESH_MeshEditor anEditor( myMesh );
280   list< int > IdList;
281   for (int i = 0; i < IDsOfNodes.length(); i++)
282     IdList.push_back( IDsOfNodes[i] );
283
284   // Update Python script
285   TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
286 #ifdef _DEBUG_
287   TPythonDump() << "print 'RemoveNodes: ', isDone";
288 #endif
289
290   return anEditor.Remove( IdList, true );
291 }
292
293 //=============================================================================
294 /*!
295  *
296  */
297 //=============================================================================
298
299 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
300 {
301   initData();
302
303   int NbNodes = IDsOfNodes.length();
304   SMDS_MeshElement* elem = 0;
305   if (NbNodes == 2)
306   {
307     CORBA::Long index1 = IDsOfNodes[0];
308     CORBA::Long index2 = IDsOfNodes[1];
309     elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
310
311     // Update Python script
312     TPythonDump() << "edge = " << this << ".AddEdge([ "
313                   << index1 << ", " << index2 <<" ])";
314   }
315   if (NbNodes == 3) {
316     CORBA::Long n1 = IDsOfNodes[0];
317     CORBA::Long n2 = IDsOfNodes[1];
318     CORBA::Long n12 = IDsOfNodes[2];
319     elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
320                                 GetMeshDS()->FindNode(n2),
321                                 GetMeshDS()->FindNode(n12));
322     // Update Python script
323     TPythonDump() << "edgeID = " << this << ".AddEdge([ "
324                   <<n1<<", "<<n2<<", "<<n12<<" ])";
325   }
326
327   if(elem)
328     return elem->GetID();
329
330   return 0;
331 }
332
333 //=============================================================================
334 /*!
335  *
336  */
337 //=============================================================================
338
339 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
340                                         CORBA::Double y, CORBA::Double z)
341 {
342   initData();
343
344   const SMDS_MeshNode* N = GetMeshDS()->AddNode(x, y, z);
345
346   // Update Python script
347   TPythonDump() << "nodeID = " << this << ".AddNode( "
348                 << x << ", " << y << ", " << z << " )";
349
350   return N->GetID();
351 }
352
353 //=============================================================================
354 /*!
355  *  AddFace
356  */
357 //=============================================================================
358
359 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
360 {
361   initData();
362
363   int NbNodes = IDsOfNodes.length();
364   if (NbNodes < 3)
365   {
366     return false;
367   }
368
369   std::vector<const SMDS_MeshNode*> nodes (NbNodes);
370   for (int i = 0; i < NbNodes; i++)
371     nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
372
373   SMDS_MeshElement* elem = 0;
374   if (NbNodes == 3) {
375     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
376   }
377   else if (NbNodes == 4) {
378     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
379   }
380   else if (NbNodes == 6) {
381     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
382                                 nodes[4], nodes[5]);
383   }
384   else if (NbNodes == 8) {
385     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
386                                 nodes[4], nodes[5], nodes[6], nodes[7]);
387   }
388
389   // Update Python script
390   TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
391
392   if(elem)
393     return elem->GetID();
394
395   return 0;
396 }
397
398 //=============================================================================
399 /*!
400  *  AddPolygonalFace
401  */
402 //=============================================================================
403 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace
404                                    (const SMESH::long_array & IDsOfNodes)
405 {
406   initData();
407
408   int NbNodes = IDsOfNodes.length();
409   std::vector<const SMDS_MeshNode*> nodes (NbNodes);
410   for (int i = 0; i < NbNodes; i++)
411     nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
412
413   const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes);
414   
415   // Update Python script
416   TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
417 #ifdef _DEBUG_
418   TPythonDump() << "print 'AddPolygonalFace: ', faceID";
419 #endif
420
421   if(elem)
422     return elem->GetID();
423
424   return 0;
425 }
426
427 //=============================================================================
428 /*!
429  *
430  */
431 //=============================================================================
432
433 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
434 {
435   initData();
436
437   int NbNodes = IDsOfNodes.length();
438   vector< const SMDS_MeshNode*> n(NbNodes);
439   for(int i=0;i<NbNodes;i++)
440     n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
441
442   SMDS_MeshElement* elem = 0;
443   switch(NbNodes)
444   {
445   case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
446   case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
447   case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
448   case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
449   case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
450                                         n[6],n[7],n[8],n[9]);
451     break;
452   case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
453                                         n[7],n[8],n[9],n[10],n[11],n[12]);
454     break;
455   case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
456                                         n[9],n[10],n[11],n[12],n[13],n[14]);
457     break;
458   case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
459                                         n[8],n[9],n[10],n[11],n[12],n[13],n[14],
460                                         n[15],n[16],n[17],n[18],n[19]);
461     break;
462   }
463
464   // Update Python script
465   TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
466 #ifdef _DEBUG_
467   TPythonDump() << "print 'AddVolume: ', volID";
468 #endif
469
470   if(elem)
471     return elem->GetID();
472
473   return 0;
474 }
475
476 //=============================================================================
477 /*!
478  *  AddPolyhedralVolume
479  */
480 //=============================================================================
481 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume
482                                    (const SMESH::long_array & IDsOfNodes,
483                                     const SMESH::long_array & Quantities)
484 {
485   initData();
486
487   int NbNodes = IDsOfNodes.length();
488   std::vector<const SMDS_MeshNode*> n (NbNodes);
489   for (int i = 0; i < NbNodes; i++)
490     n[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
491
492   int NbFaces = Quantities.length();
493   std::vector<int> q (NbFaces);
494   for (int j = 0; j < NbFaces; j++)
495     q[j] = Quantities[j];
496
497   const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(n, q);
498
499   // Update Python script
500   TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
501                 << IDsOfNodes << ", " << Quantities << " )";
502 #ifdef _DEBUG_
503   TPythonDump() << "print 'AddPolyhedralVolume: ', volID";
504 #endif
505
506   if(elem)
507     return elem->GetID();
508
509   return 0;
510 }
511
512 //=============================================================================
513 /*!
514  *  AddPolyhedralVolumeByFaces
515  */
516 //=============================================================================
517 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces
518                                    (const SMESH::long_array & IdsOfFaces)
519 {
520   initData();
521
522   int NbFaces = IdsOfFaces.length();
523   std::vector<const SMDS_MeshNode*> poly_nodes;
524   std::vector<int> quantities (NbFaces);
525
526   for (int i = 0; i < NbFaces; i++) {
527     const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]);
528     quantities[i] = aFace->NbNodes();
529
530     SMDS_ElemIteratorPtr It = aFace->nodesIterator();
531     while (It->more()) {
532       poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
533     }
534   }
535
536   const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
537
538   // Update Python script
539   TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
540                 << IdsOfFaces << " )";
541 #ifdef _DEBUG_
542   TPythonDump() << "print 'AddPolyhedralVolume: ', volID";
543 #endif
544
545   if(elem)
546     return elem->GetID();
547
548   return 0;
549 }
550
551 //=============================================================================
552 /*!
553  *
554  */
555 //=============================================================================
556
557 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
558                                             CORBA::Double x,
559                                             CORBA::Double y,
560                                             CORBA::Double z)
561 {
562   initData();
563
564   const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
565   if ( !node )
566     return false;
567
568   GetMeshDS()->MoveNode(node, x, y, z);
569
570   // Update Python script
571   TPythonDump() << "isDone = " << this << ".MoveNode( "
572                 << NodeID << ", " << x << ", " << y << ", " << z << " )";
573
574   return true;
575 }
576
577 //=============================================================================
578 /*!
579  *
580  */
581 //=============================================================================
582
583 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
584                                                CORBA::Long NodeID2)
585 {
586   initData();
587
588   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
589   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
590   if ( !n1 || !n2 )
591     return false;
592
593   // Update Python script
594   TPythonDump() << "isDone = " << this << ".InverseDiag( "
595                 << NodeID1 << ", " << NodeID2 << " )";
596
597   ::SMESH_MeshEditor aMeshEditor( myMesh );
598   return aMeshEditor.InverseDiag ( n1, n2 );
599 }
600
601 //=============================================================================
602 /*!
603  *
604  */
605 //=============================================================================
606
607 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
608                                               CORBA::Long NodeID2)
609 {
610   initData();
611
612   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
613   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
614   if ( !n1 || !n2 )
615     return false;
616
617   // Update Python script
618   TPythonDump() << "isDone = " << this << ".DeleteDiag( "
619                 << NodeID1 << ", " << NodeID2 <<  " )";
620
621   ::SMESH_MeshEditor aMeshEditor( myMesh );
622
623   bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
624
625   StoreResult(aMeshEditor);
626
627   return stat;
628 }
629
630 //=============================================================================
631 /*!
632  *
633  */
634 //=============================================================================
635
636 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
637 {
638   initData();
639
640   ::SMESH_MeshEditor anEditor( myMesh );
641   for (int i = 0; i < IDsOfElements.length(); i++)
642   {
643     CORBA::Long index = IDsOfElements[i];
644     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
645     if ( elem )
646       anEditor.Reorient( elem );
647   }
648   // Update Python script
649   TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
650
651   return true;
652 }
653
654
655 //=============================================================================
656 /*!
657  *
658  */
659 //=============================================================================
660
661 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
662 {
663   initData();
664
665   SMESH::long_array_var anElementsId = theObject->GetIDs();
666   CORBA::Boolean isDone = Reorient(anElementsId);
667
668   // Clear python line, created by Reorient()
669   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
670   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
671
672   // Update Python script
673   TPythonDump() << "isDone = " << this << ".ReorientObject( " << theObject << " )";
674
675   return isDone;
676 }
677
678 namespace
679 {
680   //================================================================================
681   /*!
682    * \brief function for conversion long_array to TIDSortedElemSet
683     * \param IDs - array of IDs
684     * \param aMesh - mesh
685     * \param aMap - collection to fill
686     * \param aType - element type
687    */
688   //================================================================================
689
690   void ToMap(const SMESH::long_array & IDs,
691              const SMESHDS_Mesh*       aMesh,
692              TIDSortedElemSet&         aMap,
693              const SMDSAbs_ElementType aType = SMDSAbs_All )
694   { 
695     for (int i=0; i<IDs.length(); i++) {
696       CORBA::Long ind = IDs[i];
697       const SMDS_MeshElement * elem = aMesh->FindElement(ind);
698       if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
699         aMap.insert( elem );
700     }
701   }
702 }
703
704 //=============================================================================
705 /*!
706  *
707  */
708 //=============================================================================
709 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfElements,
710                                               SMESH::NumericalFunctor_ptr Criterion,
711                                               CORBA::Double               MaxAngle)
712 {
713   initData();
714
715   SMESHDS_Mesh* aMesh = GetMeshDS();
716   TIDSortedElemSet faces;
717   ToMap(IDsOfElements, aMesh, faces, SMDSAbs_Face);
718
719   SMESH::NumericalFunctor_i* aNumericalFunctor =
720     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
721   SMESH::Controls::NumericalFunctorPtr aCrit;
722   if ( !aNumericalFunctor )
723     aCrit.reset( new SMESH::Controls::AspectRatio() );
724   else
725     aCrit = aNumericalFunctor->GetNumericalFunctor();
726
727   // Update Python script
728   TPythonDump() << "isDone = " << this << ".TriToQuad( "
729                 << IDsOfElements << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
730 #ifdef _DEBUG_
731   TPythonDump() << "print 'TriToQuad: ', isDone";
732 #endif
733
734   ::SMESH_MeshEditor anEditor( myMesh );
735
736   bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
737
738   StoreResult(anEditor);
739
740   return stat;
741 }
742
743
744 //=============================================================================
745 /*!
746  *
747  */
748 //=============================================================================
749 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr   theObject,
750                                                     SMESH::NumericalFunctor_ptr Criterion,
751                                                     CORBA::Double               MaxAngle)
752 {
753   initData();
754
755   SMESH::long_array_var anElementsId = theObject->GetIDs();
756   CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
757
758   // Clear python line(s), created by TriToQuad()
759   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
760   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
761 #ifdef _DEBUG_
762   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
763 #endif
764
765   SMESH::NumericalFunctor_i* aNumericalFunctor =
766     SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
767
768   // Update Python script
769   TPythonDump() << "isDone = " << this << ".TriToQuadObject("
770                 << theObject << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
771 #ifdef _DEBUG_
772   TPythonDump() << "print 'TriToQuadObject: ', isDone";
773 #endif
774
775   return isDone;
776 }
777
778
779 //=============================================================================
780 /*!
781  *
782  */
783 //=============================================================================
784 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array &   IDsOfElements,
785                                               SMESH::NumericalFunctor_ptr Criterion)
786 {
787   initData();
788
789   SMESHDS_Mesh* aMesh = GetMeshDS();
790   TIDSortedElemSet faces;
791   ToMap(IDsOfElements, aMesh, faces, SMDSAbs_Face);
792
793   SMESH::NumericalFunctor_i* aNumericalFunctor =
794     dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
795   SMESH::Controls::NumericalFunctorPtr aCrit;
796   if ( !aNumericalFunctor )
797     aCrit.reset( new SMESH::Controls::AspectRatio() );
798   else
799     aCrit = aNumericalFunctor->GetNumericalFunctor();
800
801
802   // Update Python script
803   TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
804 #ifdef _DEBUG_
805   TPythonDump() << "print 'QuadToTri: ', isDone";
806 #endif
807
808   ::SMESH_MeshEditor anEditor( myMesh );
809   CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
810
811   StoreResult(anEditor);
812
813   return stat;
814 }
815
816
817 //=============================================================================
818 /*!
819  *
820  */
821 //=============================================================================
822 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr   theObject,
823                                                     SMESH::NumericalFunctor_ptr Criterion)
824 {
825   initData();
826
827   SMESH::long_array_var anElementsId = theObject->GetIDs();
828   CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
829
830   // Clear python line(s), created by QuadToTri()
831   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
832   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
833 #ifdef _DEBUG_
834   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
835 #endif
836
837   SMESH::NumericalFunctor_i* aNumericalFunctor =
838     SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
839
840   // Update Python script
841   TPythonDump() << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
842 #ifdef _DEBUG_
843   TPythonDump() << "print 'QuadToTriObject: ', isDone";
844 #endif
845
846   return isDone;
847 }
848
849
850 //=============================================================================
851 /*!
852  *
853  */
854 //=============================================================================
855 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
856                                               CORBA::Boolean            Diag13)
857 {
858   initData();
859
860   SMESHDS_Mesh* aMesh = GetMeshDS();
861   TIDSortedElemSet faces;
862   ToMap(IDsOfElements, aMesh, faces, SMDSAbs_Face);
863
864   // Update Python script
865   TPythonDump() << "isDone = " << this << ".SplitQuad( "
866                 << IDsOfElements << ", " << Diag13 << " )";
867 #ifdef _DEBUG_
868   TPythonDump() << "print 'SplitQuad: ', isDone";
869 #endif
870
871   ::SMESH_MeshEditor anEditor( myMesh );
872   CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
873
874   StoreResult(anEditor);
875
876   return stat;
877 }
878
879
880 //=============================================================================
881 /*!
882  *
883  */
884 //=============================================================================
885 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
886                                                     CORBA::Boolean            Diag13)
887 {
888   initData();
889
890   SMESH::long_array_var anElementsId = theObject->GetIDs();
891   CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
892
893   // Clear python line(s), created by SplitQuad()
894   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
895   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
896 #ifdef _DEBUG_
897   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
898 #endif
899
900   // Update Python script
901   TPythonDump() << "isDone = " << this << ".SplitQuadObject( "
902                 << theObject << ", " << Diag13 << " )";
903 #ifdef _DEBUG_
904   TPythonDump() << "print 'SplitQuadObject: ', isDone";
905 #endif
906
907   return isDone;
908 }
909
910
911 //=============================================================================
912 /*!
913  *  BestSplit
914  */
915 //=============================================================================
916 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long                 IDOfQuad,
917                                            SMESH::NumericalFunctor_ptr Criterion)
918 {
919   const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
920   if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
921   {
922     SMESH::NumericalFunctor_i* aNumericalFunctor =
923       dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
924     SMESH::Controls::NumericalFunctorPtr aCrit;
925     if (aNumericalFunctor)
926       aCrit = aNumericalFunctor->GetNumericalFunctor();
927     else
928       aCrit.reset(new SMESH::Controls::AspectRatio());
929
930     ::SMESH_MeshEditor anEditor (myMesh);
931     return anEditor.BestSplit(quad, aCrit);
932   }
933   return -1;
934 }
935
936
937 //=======================================================================
938 //function : Smooth
939 //purpose  :
940 //=======================================================================
941
942 CORBA::Boolean
943   SMESH_MeshEditor_i::Smooth(const SMESH::long_array &              IDsOfElements,
944                              const SMESH::long_array &              IDsOfFixedNodes,
945                              CORBA::Long                            MaxNbOfIterations,
946                              CORBA::Double                          MaxAspectRatio,
947                              SMESH::SMESH_MeshEditor::Smooth_Method Method)
948 {
949   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
950                 MaxAspectRatio, Method, false );
951 }
952
953
954 //=======================================================================
955 //function : SmoothParametric
956 //purpose  :
957 //=======================================================================
958
959 CORBA::Boolean
960   SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array &              IDsOfElements,
961                                        const SMESH::long_array &              IDsOfFixedNodes,
962                                        CORBA::Long                            MaxNbOfIterations,
963                                        CORBA::Double                          MaxAspectRatio,
964                                        SMESH::SMESH_MeshEditor::Smooth_Method Method)
965 {
966   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
967                 MaxAspectRatio, Method, true );
968 }
969
970
971 //=======================================================================
972 //function : SmoothObject
973 //purpose  :
974 //=======================================================================
975
976 CORBA::Boolean
977   SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr              theObject,
978                                    const SMESH::long_array &              IDsOfFixedNodes,
979                                    CORBA::Long                            MaxNbOfIterations,
980                                    CORBA::Double                          MaxAspectRatio,
981                                    SMESH::SMESH_MeshEditor::Smooth_Method Method)
982 {
983   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
984                        MaxAspectRatio, Method, false);
985 }
986
987
988 //=======================================================================
989 //function : SmoothParametricObject
990 //purpose  :
991 //=======================================================================
992
993 CORBA::Boolean
994   SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr              theObject,
995                                    const SMESH::long_array &              IDsOfFixedNodes,
996                                    CORBA::Long                            MaxNbOfIterations,
997                                    CORBA::Double                          MaxAspectRatio,
998                                    SMESH::SMESH_MeshEditor::Smooth_Method Method)
999 {
1000   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1001                        MaxAspectRatio, Method, true);
1002 }
1003
1004
1005 //=============================================================================
1006 /*!
1007  *
1008  */
1009 //=============================================================================
1010
1011 CORBA::Boolean
1012   SMESH_MeshEditor_i::smooth(const SMESH::long_array &              IDsOfElements,
1013                              const SMESH::long_array &              IDsOfFixedNodes,
1014                              CORBA::Long                            MaxNbOfIterations,
1015                              CORBA::Double                          MaxAspectRatio,
1016                              SMESH::SMESH_MeshEditor::Smooth_Method Method,
1017                              bool                                   IsParametric)
1018 {
1019   initData();
1020
1021   SMESHDS_Mesh* aMesh = GetMeshDS();
1022
1023   TIDSortedElemSet elements;
1024   ToMap(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1025
1026   set<const SMDS_MeshNode*> fixedNodes;
1027   for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1028     CORBA::Long index = IDsOfFixedNodes[i];
1029     const SMDS_MeshNode * node = aMesh->FindNode(index);
1030     if ( node )
1031       fixedNodes.insert( node );
1032   }
1033   ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1034   if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1035     method = ::SMESH_MeshEditor::CENTROIDAL;
1036
1037   ::SMESH_MeshEditor anEditor( myMesh );
1038   anEditor.Smooth(elements, fixedNodes, method,
1039                   MaxNbOfIterations, MaxAspectRatio, IsParametric );
1040
1041   StoreResult(anEditor);
1042
1043   // Update Python script
1044   TPythonDump() << "isDone = " << this << "."
1045                 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1046                 << IDsOfElements << ", "     << IDsOfFixedNodes << ", "
1047                 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1048                 << "SMESH.SMESH_MeshEditor."
1049                 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1050                      "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1051 #ifdef _DEBUG_
1052   TPythonDump() << "print 'Smooth: ', isDone";
1053 #endif
1054
1055   return true;
1056 }
1057
1058
1059 //=============================================================================
1060 /*!
1061  *
1062  */
1063 //=============================================================================
1064
1065 CORBA::Boolean
1066 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr              theObject,
1067                                  const SMESH::long_array &              IDsOfFixedNodes,
1068                                  CORBA::Long                            MaxNbOfIterations,
1069                                  CORBA::Double                          MaxAspectRatio,
1070                                  SMESH::SMESH_MeshEditor::Smooth_Method Method,
1071                                  bool                                   IsParametric)
1072 {
1073   initData();
1074
1075   SMESH::long_array_var anElementsId = theObject->GetIDs();
1076   CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1077                                   MaxAspectRatio, Method, IsParametric);
1078
1079   // Clear python line(s), created by Smooth()
1080   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1081   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1082 #ifdef _DEBUG_
1083   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1084 #endif
1085
1086   // Update Python script
1087   TPythonDump() << "isDone = " << this << "."
1088                 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1089                 << theObject << ", " << IDsOfFixedNodes << ", "
1090                 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1091                 << "SMESH.SMESH_MeshEditor."
1092                 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1093                      "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1094 #ifdef _DEBUG_
1095   TPythonDump() << "print 'SmoothObject: ', isDone";
1096 #endif
1097
1098   return isDone;
1099 }
1100
1101
1102 //=============================================================================
1103 /*!
1104  *
1105  */
1106 //=============================================================================
1107
1108 void SMESH_MeshEditor_i::RenumberNodes()
1109 {
1110   // Update Python script
1111   TPythonDump() << this << ".RenumberNodes()";
1112
1113   GetMeshDS()->Renumber( true );
1114 }
1115
1116
1117 //=============================================================================
1118 /*!
1119  *
1120  */
1121 //=============================================================================
1122
1123 void SMESH_MeshEditor_i::RenumberElements()
1124 {
1125   // Update Python script
1126   TPythonDump() << this << ".RenumberElements()";
1127
1128   GetMeshDS()->Renumber( false );
1129 }
1130
1131
1132 //=======================================================================
1133 //function : RotationSweep
1134 //purpose  :
1135 //=======================================================================
1136
1137 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
1138                                        const SMESH::AxisStruct & theAxis,
1139                                        CORBA::Double             theAngleInRadians,
1140                                        CORBA::Long               theNbOfSteps,
1141                                        CORBA::Double             theTolerance)
1142 {
1143   initData();
1144
1145   TIDSortedElemSet inElements, copyElements;
1146   ToMap(theIDsOfElements, GetMeshDS(), inElements);
1147
1148   TIDSortedElemSet* workElements = & inElements;
1149   TPreviewMesh      tmpMesh( SMDSAbs_Face );
1150   SMESH_Mesh*       mesh = 0;
1151   bool              makeWalls=true;
1152   if ( myPreviewMode )
1153   {
1154     SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1155     tmpMesh.Copy( inElements, copyElements, select, avoid );
1156     mesh = &tmpMesh;
1157     workElements = & copyElements;
1158     //makeWalls = false;
1159   }
1160   else
1161   {
1162     mesh = myMesh;
1163   }
1164
1165   gp_Ax1 Ax1 (gp_Pnt( theAxis.x,  theAxis.y,  theAxis.z ),
1166               gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
1167
1168   ::SMESH_MeshEditor anEditor( mesh );
1169   anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
1170                           theNbOfSteps, theTolerance, makeWalls);
1171
1172   StoreResult(anEditor);
1173
1174   if ( !myPreviewMode ) {
1175     // Update Python script
1176     TPythonDump() << "axis = " << theAxis;
1177     TPythonDump() << this << ".RotationSweep( "
1178                   << theIDsOfElements
1179                   << ", axis, "
1180                   << theAngleInRadians << ", "
1181                   << theNbOfSteps << ", "
1182                   << theTolerance << " )";
1183   }
1184 }
1185
1186 //=======================================================================
1187 //function : RotationSweepObject
1188 //purpose  :
1189 //=======================================================================
1190
1191 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1192                                              const SMESH::AxisStruct & theAxis,
1193                                              CORBA::Double             theAngleInRadians,
1194                                              CORBA::Long               theNbOfSteps,
1195                                              CORBA::Double             theTolerance)
1196 {
1197   initData();
1198
1199   SMESH::long_array_var anElementsId = theObject->GetIDs();
1200   RotationSweep(anElementsId, theAxis, theAngleInRadians, theNbOfSteps, theTolerance);
1201
1202   // Clear python line, created by RotationSweep()
1203   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1204   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1205
1206   // Update Python script
1207   TPythonDump() << this << ".RotationSweepObject( "
1208                 << theObject
1209                 << ", axis, "
1210                 << theAngleInRadians << ", "
1211                 << theNbOfSteps << ", "
1212                 << theTolerance << " )";
1213 }
1214
1215 //=======================================================================
1216 //function : ExtrusionSweep
1217 //purpose  :
1218 //=======================================================================
1219
1220 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
1221                                         const SMESH::DirStruct &  theStepVector,
1222                                         CORBA::Long               theNbOfSteps)
1223 {
1224   initData();
1225
1226 #ifdef NO_CAS_CATCH
1227   try {   
1228     OCC_CATCH_SIGNALS;
1229 #else
1230   CASCatch_TRY {
1231 #endif
1232     SMESHDS_Mesh* aMesh = GetMeshDS();
1233
1234     TIDSortedElemSet elements;
1235     ToMap(theIDsOfElements, aMesh, elements);
1236
1237     const SMESH::PointStruct * P = &theStepVector.PS;
1238     gp_Vec stepVec( P->x, P->y, P->z );
1239
1240     TElemOfElemListMap aHystory;
1241     ::SMESH_MeshEditor anEditor( myMesh );
1242     anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory);
1243
1244     StoreResult(anEditor);
1245
1246     // Update Python script
1247     TPythonDump() << "stepVector = " << theStepVector;
1248     TPythonDump() << this << ".ExtrusionSweep( "
1249                   << theIDsOfElements << ", stepVector, " << theNbOfSteps << " )";
1250
1251 #ifdef NO_CAS_CATCH
1252   } catch(Standard_Failure) {
1253 #else
1254   } CASCatch_CATCH(Standard_Failure) {
1255 #endif
1256     Handle(Standard_Failure) aFail = Standard_Failure::Caught();          
1257     INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
1258   }
1259 }
1260
1261
1262 //=======================================================================
1263 //function : ExtrusionSweepObject
1264 //purpose  :
1265 //=======================================================================
1266
1267 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1268                                               const SMESH::DirStruct &  theStepVector,
1269                                               CORBA::Long               theNbOfSteps)
1270 {
1271   initData();
1272
1273   SMESH::long_array_var anElementsId = theObject->GetIDs();
1274   ExtrusionSweep(anElementsId, theStepVector, theNbOfSteps);
1275
1276   // Clear python line, created by ExtrusionSweep()
1277   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1278   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1279
1280   // Update Python script
1281   TPythonDump() << this << ".ExtrusionSweepObject( "
1282                 << theObject << ", stepVector, " << theNbOfSteps << " )";
1283 }
1284
1285 //=======================================================================
1286 //function : ExtrusionSweepObject1D
1287 //purpose  :
1288 //=======================================================================
1289
1290 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1291                                                 const SMESH::DirStruct &  theStepVector,
1292                                                 CORBA::Long               theNbOfSteps)
1293 {
1294   initData();
1295
1296   SMESHDS_Mesh* aMesh = GetMeshDS();
1297
1298   SMESH::long_array_var allElementsId = theObject->GetIDs();
1299
1300   TIDSortedElemSet elements;
1301   ToMap(allElementsId, aMesh, elements);
1302
1303   const SMESH::PointStruct * P = &theStepVector.PS;
1304   gp_Vec stepVec( P->x, P->y, P->z );
1305
1306   ::SMESH_MeshEditor anEditor( myMesh );
1307   //anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps);
1308   TElemOfElemListMap aHystory;
1309   anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory);
1310
1311   StoreResult(anEditor);
1312
1313   // Update Python script
1314   TPythonDump() << "stepVector = " << theStepVector;
1315   TPythonDump() << this << ".ExtrusionSweepObject1D( "
1316                 << theObject << ", stepVector, " << theNbOfSteps << " )";
1317 }
1318
1319 //=======================================================================
1320 //function : ExtrusionSweepObject2D
1321 //purpose  :
1322 //=======================================================================
1323
1324 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1325                                                 const SMESH::DirStruct &  theStepVector,
1326                                                 CORBA::Long               theNbOfSteps)
1327 {
1328   initData();
1329
1330   SMESHDS_Mesh* aMesh = GetMeshDS();
1331
1332   SMESH::long_array_var allElementsId = theObject->GetIDs();
1333
1334   TIDSortedElemSet elements;
1335   ToMap(allElementsId, aMesh, elements);
1336
1337   const SMESH::PointStruct * P = &theStepVector.PS;
1338   gp_Vec stepVec( P->x, P->y, P->z );
1339
1340   ::SMESH_MeshEditor anEditor( myMesh );
1341   //anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps);
1342   TElemOfElemListMap aHystory;
1343   anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory);
1344
1345   StoreResult(anEditor);
1346
1347   // Update Python script
1348   TPythonDump() << "stepVector = " << theStepVector;
1349   TPythonDump() << this << ".ExtrusionSweepObject2D( "
1350                 << theObject << ", stepVector, " << theNbOfSteps << " )";
1351 }
1352
1353
1354 //=======================================================================
1355 //function : AdvancedExtrusion
1356 //purpose  :
1357 //=======================================================================
1358
1359 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
1360                                            const SMESH::DirStruct &  theStepVector,
1361                                            CORBA::Long               theNbOfSteps,
1362                                            CORBA::Long               theExtrFlags,
1363                                            CORBA::Double             theSewTolerance)
1364 {
1365   initData();
1366
1367   SMESHDS_Mesh* aMesh = GetMeshDS();
1368
1369   TIDSortedElemSet elements;
1370   ToMap(theIDsOfElements, aMesh, elements);
1371
1372   const SMESH::PointStruct * P = &theStepVector.PS;
1373   gp_Vec stepVec( P->x, P->y, P->z );
1374
1375   ::SMESH_MeshEditor anEditor( myMesh );
1376   TElemOfElemListMap aHystory;
1377   anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
1378                            theExtrFlags, theSewTolerance);
1379
1380   StoreResult(anEditor);
1381
1382   // Update Python script
1383   TPythonDump() << "stepVector = " << theStepVector;
1384   TPythonDump() << this << ".AdvancedExtrusion("
1385                 << theIDsOfElements
1386                 << ", stepVector, "
1387                 << theNbOfSteps << ","
1388                 << theExtrFlags << ", "
1389                 << theSewTolerance <<  " )";
1390 }
1391
1392
1393 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
1394
1395 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
1396 {
1397   switch ( e ) {
1398   RETCASE( EXTR_OK );
1399   RETCASE( EXTR_NO_ELEMENTS );
1400   RETCASE( EXTR_PATH_NOT_EDGE );
1401   RETCASE( EXTR_BAD_PATH_SHAPE );
1402   RETCASE( EXTR_BAD_STARTING_NODE );
1403   RETCASE( EXTR_BAD_ANGLES_NUMBER );
1404   RETCASE( EXTR_CANT_GET_TANGENT );
1405   }
1406   return SMESH::SMESH_MeshEditor::EXTR_OK;
1407 }
1408
1409 //=======================================================================
1410 //function : ExtrusionAlongPath
1411 //purpose  :
1412 //=======================================================================
1413
1414 SMESH::SMESH_MeshEditor::Extrusion_Error
1415   SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
1416                                          SMESH::SMESH_Mesh_ptr       thePathMesh,
1417                                          GEOM::GEOM_Object_ptr       thePathShape,
1418                                          CORBA::Long                 theNodeStart,
1419                                          CORBA::Boolean              theHasAngles,
1420                                          const SMESH::double_array & theAngles,
1421                                          CORBA::Boolean              theHasRefPoint,
1422                                          const SMESH::PointStruct &  theRefPoint)
1423 {
1424   initData();
1425
1426   SMESHDS_Mesh*  aMesh = GetMeshDS();
1427
1428   if ( thePathMesh->_is_nil() || thePathShape->_is_nil() )
1429     return SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
1430
1431   SMESH_Mesh_i* aMeshImp = dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( thePathMesh ).in() );
1432   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
1433   SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
1434
1435   if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
1436     return SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
1437
1438   SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
1439   if ( !nodeStart )
1440     return SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
1441
1442   TIDSortedElemSet elements;
1443   ToMap(theIDsOfElements, aMesh, elements);
1444
1445   list<double> angles;
1446   for (int i = 0; i < theAngles.length(); i++) {
1447     angles.push_back( theAngles[i] );
1448   }
1449
1450   gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
1451
1452   // Update Python script
1453   TPythonDump() << "rotAngles = " << theAngles;
1454
1455   if ( theHasRefPoint )
1456     TPythonDump() << "refPoint = SMESH.PointStruct( "
1457                   << refPnt.X() << ", "
1458                   << refPnt.Y() << ", "
1459                   << refPnt.Z() << " )";
1460   else
1461     TPythonDump() << "refPoint = SMESH.PointStruct( 0,0,0 )";
1462
1463   TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
1464                 << theIDsOfElements << ", "
1465                 << thePathMesh      << ", "
1466                 << thePathShape     << ", "
1467                 << theNodeStart     << ", "
1468                 << theHasAngles     << ", "
1469                 << "rotAngles"      << ", "
1470                 << theHasRefPoint   << ", refPoint )";
1471
1472   ::SMESH_MeshEditor anEditor( myMesh );
1473   SMESH::SMESH_MeshEditor::Extrusion_Error error = 
1474     convExtrError( anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
1475                                                 theHasAngles, angles,
1476                                                 theHasRefPoint, refPnt ) );
1477
1478   StoreResult(anEditor);
1479
1480   return error;
1481 }
1482
1483 //=======================================================================
1484 //function : ExtrusionAlongPathObject
1485 //purpose  :
1486 //=======================================================================
1487
1488 SMESH::SMESH_MeshEditor::Extrusion_Error
1489 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObject,
1490                                              SMESH::SMESH_Mesh_ptr       thePathMesh,
1491                                              GEOM::GEOM_Object_ptr       thePathShape,
1492                                              CORBA::Long                 theNodeStart,
1493                                              CORBA::Boolean              theHasAngles,
1494                                              const SMESH::double_array & theAngles,
1495                                              CORBA::Boolean              theHasRefPoint,
1496                                              const SMESH::PointStruct &  theRefPoint)
1497 {
1498   initData();
1499
1500   SMESH::long_array_var anElementsId = theObject->GetIDs();
1501   SMESH::SMESH_MeshEditor::Extrusion_Error error = ExtrusionAlongPath
1502     (anElementsId, thePathMesh, thePathShape, theNodeStart,
1503      theHasAngles, theAngles, theHasRefPoint, theRefPoint);
1504
1505   // Clear python line, created by ExtrusionAlongPath()
1506   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1507   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1508
1509   // Update Python script
1510   TPythonDump() << "rotAngles = " << theAngles;
1511   TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
1512                 << theObject    << ", "
1513                 << thePathMesh  << ", "
1514                 << thePathShape << ", "
1515                 << theNodeStart << ", "
1516                 << theHasAngles << ", "
1517                 << "rotAngles"     << ", "
1518                 << theHasRefPoint<<", refPoint )";
1519
1520   return error;
1521 }
1522
1523 //================================================================================
1524 /*!
1525  * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
1526  * of given angles along path steps
1527   * \param PathMesh mesh containing a 1D sub-mesh on the edge, along 
1528   *                which proceeds the extrusion
1529   * \param PathShape is shape(edge); as the mesh can be complex, the edge 
1530   *                 is used to define the sub-mesh for the path
1531  */
1532 //================================================================================
1533
1534 SMESH::double_array*
1535 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr       thePathMesh,
1536                                           GEOM::GEOM_Object_ptr       thePathShape,
1537                                           const SMESH::double_array & theAngles)
1538 {
1539   SMESH::double_array_var aResult = new SMESH::double_array();
1540   return aResult._retn();
1541 }
1542
1543 //=======================================================================
1544 //function : Mirror
1545 //purpose  :
1546 //=======================================================================
1547
1548 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElements,
1549                                 const SMESH::AxisStruct &           theAxis,
1550                                 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
1551                                 CORBA::Boolean                      theCopy)
1552 {
1553   initData();
1554
1555   SMESHDS_Mesh* aMesh = GetMeshDS();
1556
1557   TIDSortedElemSet elements;
1558   ToMap(theIDsOfElements, aMesh, elements);
1559
1560   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
1561   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
1562
1563   gp_Trsf aTrsf;
1564   TCollection_AsciiString typeStr;
1565   switch ( theMirrorType ) {
1566   case  SMESH::SMESH_MeshEditor::POINT:
1567     aTrsf.SetMirror( P );
1568     typeStr = "SMESH.SMESH_MeshEditor.POINT";
1569     break;
1570   case  SMESH::SMESH_MeshEditor::AXIS:
1571     aTrsf.SetMirror( gp_Ax1( P, V ));
1572     typeStr = "SMESH.SMESH_MeshEditor.AXIS";
1573     break;
1574   default:
1575     aTrsf.SetMirror( gp_Ax2( P, V ));
1576     typeStr = "SMESH.SMESH_MeshEditor.PLANE";
1577   }
1578
1579   // Update Python script
1580   TPythonDump() << this << ".Mirror( "
1581                 << theIDsOfElements << ", "
1582                 << theAxis           << ", "
1583                 << typeStr           << ", "
1584                 << theCopy           << " )";
1585
1586   ::SMESH_MeshEditor anEditor( myMesh );
1587   anEditor.Transform (elements, aTrsf, theCopy);
1588
1589   if(theCopy) {
1590     StoreResult(anEditor);
1591   }
1592 }
1593
1594
1595 //=======================================================================
1596 //function : MirrorObject
1597 //purpose  :
1598 //=======================================================================
1599
1600 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr           theObject,
1601                                       const SMESH::AxisStruct &           theAxis,
1602                                       SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
1603                                       CORBA::Boolean                      theCopy)
1604 {
1605   initData();
1606
1607   SMESH::long_array_var anElementsId = theObject->GetIDs();
1608   Mirror(anElementsId, theAxis, theMirrorType, theCopy);
1609
1610   // Clear python line, created by Mirror()
1611   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1612   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1613
1614   // Update Python script
1615   TCollection_AsciiString typeStr;
1616   switch ( theMirrorType ) {
1617   case  SMESH::SMESH_MeshEditor::POINT:
1618     typeStr = "SMESH.SMESH_MeshEditor.POINT";
1619     break;
1620   case  SMESH::SMESH_MeshEditor::AXIS:
1621     typeStr = "SMESH.SMESH_MeshEditor.AXIS";
1622     break;
1623   default:
1624     typeStr = "SMESH.SMESH_MeshEditor.PLANE";
1625   }
1626   TPythonDump() << "axis = " << theAxis;
1627   TPythonDump() << this << ".MirrorObject( "
1628                 << theObject << ", "
1629                 << "axis, "
1630                 << typeStr << ", "
1631                 << theCopy << " )";
1632 }
1633
1634 //=======================================================================
1635 //function : Translate
1636 //purpose  :
1637 //=======================================================================
1638
1639 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
1640                                    const SMESH::DirStruct &  theVector,
1641                                    CORBA::Boolean            theCopy)
1642 {
1643   initData();
1644
1645   SMESHDS_Mesh* aMesh = GetMeshDS();
1646
1647   TIDSortedElemSet elements;
1648   ToMap(theIDsOfElements, aMesh, elements);
1649
1650   gp_Trsf aTrsf;
1651   const SMESH::PointStruct * P = &theVector.PS;
1652   aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
1653
1654   ::SMESH_MeshEditor anEditor( myMesh );
1655   anEditor.Transform (elements, aTrsf, theCopy);
1656
1657   if(theCopy) {
1658     StoreResult(anEditor);
1659   }
1660
1661   // Update Python script
1662   TPythonDump() << "vector = " << theVector;
1663   TPythonDump() << this << ".Translate( "
1664                 << theIDsOfElements
1665                 << ", vector, "
1666                 << theCopy << " )";
1667 }
1668
1669 //=======================================================================
1670 //function : TranslateObject
1671 //purpose  :
1672 //=======================================================================
1673
1674 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
1675                                          const SMESH::DirStruct &  theVector,
1676                                          CORBA::Boolean            theCopy)
1677 {
1678   initData();
1679
1680   SMESH::long_array_var anElementsId = theObject->GetIDs();
1681   Translate(anElementsId, theVector, theCopy);
1682
1683   // Clear python line, created by Translate()
1684   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1685   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1686
1687   // Update Python script
1688   TPythonDump() << this << ".TranslateObject( "
1689                 << theObject
1690                 << ", vector, "
1691                 << theCopy << " )";
1692 }
1693
1694 //=======================================================================
1695 //function : Rotate
1696 //purpose  :
1697 //=======================================================================
1698
1699 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
1700                                 const SMESH::AxisStruct & theAxis,
1701                                 CORBA::Double             theAngle,
1702                                 CORBA::Boolean            theCopy)
1703 {
1704   initData();
1705
1706   SMESHDS_Mesh* aMesh = GetMeshDS();
1707
1708   TIDSortedElemSet elements;
1709   ToMap(theIDsOfElements, aMesh, elements);
1710
1711   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
1712   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
1713
1714   gp_Trsf aTrsf;
1715   aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
1716
1717   ::SMESH_MeshEditor anEditor( myMesh );
1718   anEditor.Transform (elements, aTrsf, theCopy);
1719
1720   if(theCopy) {
1721     StoreResult(anEditor);
1722   }
1723
1724   // Update Python script
1725   TPythonDump() << "axis = " << theAxis;
1726   TPythonDump() << this << ".Rotate( "
1727                 << theIDsOfElements
1728                 << ", axis, "
1729                 << theAngle << ", "
1730                 << theCopy << " )";
1731 }
1732
1733 //=======================================================================
1734 //function : RotateObject
1735 //purpose  :
1736 //=======================================================================
1737
1738 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
1739                                       const SMESH::AxisStruct & theAxis,
1740                                       CORBA::Double             theAngle,
1741                                       CORBA::Boolean            theCopy)
1742 {
1743   initData();
1744
1745   SMESH::long_array_var anElementsId = theObject->GetIDs();
1746   Rotate(anElementsId, theAxis, theAngle, theCopy);
1747
1748   // Clear python line, created by Rotate()
1749   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1750   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
1751
1752   // Update Python script
1753   TPythonDump() << this << ".RotateObject( "
1754                 << theObject
1755                 << ", axis, "
1756                 << theAngle << ", "
1757                 << theCopy << " )";
1758 }
1759
1760 //=======================================================================
1761 //function : FindCoincidentNodes
1762 //purpose  :
1763 //=======================================================================
1764
1765 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
1766                                               SMESH::array_of_long_array_out GroupsOfNodes)
1767 {
1768   initData();
1769
1770   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
1771   ::SMESH_MeshEditor anEditor( myMesh );
1772   set<const SMDS_MeshNode*> nodes; // no input nodes
1773   anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
1774
1775   GroupsOfNodes = new SMESH::array_of_long_array;
1776   GroupsOfNodes->length( aListOfListOfNodes.size() );
1777   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
1778   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
1779     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
1780     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
1781     SMESH::long_array& aGroup = (*GroupsOfNodes)[i];
1782     aGroup.length( aListOfNodes.size() );
1783     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
1784       aGroup[ j ] = (*lIt)->GetID();
1785   }
1786   // Update Python script
1787   TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
1788                 << Tolerance << " )";
1789 }
1790
1791 //=======================================================================
1792 //function : FindCoincidentNodesOnPart
1793 //purpose  :
1794 //=======================================================================
1795 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr      theObject,
1796                                                    CORBA::Double                  Tolerance,
1797                                                    SMESH::array_of_long_array_out GroupsOfNodes)
1798 {
1799   initData();
1800   SMESH::long_array_var aElementsId = theObject->GetIDs();
1801
1802   SMESHDS_Mesh* aMesh = GetMeshDS();
1803   set<const SMDS_MeshNode*> nodes;
1804
1805   if ( !CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) &&
1806       SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) {
1807     for(int i = 0; i < aElementsId->length(); i++) {
1808       CORBA::Long ind = aElementsId[i];
1809       const SMDS_MeshNode * elem = aMesh->FindNode(ind);
1810       if(elem)
1811         nodes.insert(elem);
1812     }
1813   }
1814   else {
1815     for(int i = 0; i < aElementsId->length(); i++) {
1816       CORBA::Long ind = aElementsId[i];
1817       const SMDS_MeshElement * elem = aMesh->FindElement(ind);
1818       if(elem) {
1819         SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
1820         while ( nIt->more() )
1821           nodes.insert( nodes.end(),static_cast<const SMDS_MeshNode*>(nIt->next()));
1822       }
1823     }
1824   }
1825     
1826   
1827   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
1828   ::SMESH_MeshEditor anEditor( myMesh );
1829   if(!nodes.empty())
1830     anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
1831   
1832   GroupsOfNodes = new SMESH::array_of_long_array;
1833   GroupsOfNodes->length( aListOfListOfNodes.size() );
1834   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
1835   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
1836     list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
1837     list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
1838     SMESH::long_array& aGroup = (*GroupsOfNodes)[i];
1839     aGroup.length( aListOfNodes.size() );
1840     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
1841       aGroup[ j ] = (*lIt)->GetID();
1842   }
1843   // Update Python script
1844   TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
1845                 <<theObject<<", "
1846                 << Tolerance << " )";
1847 }
1848
1849 //=======================================================================
1850 //function : MergeNodes
1851 //purpose  :
1852 //=======================================================================
1853
1854 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
1855 {
1856   initData();
1857
1858   SMESHDS_Mesh* aMesh = GetMeshDS();
1859
1860   TPythonDump aTPythonDump;
1861   aTPythonDump << this << ".MergeNodes([";
1862   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
1863   for (int i = 0; i < GroupsOfNodes.length(); i++)
1864   {
1865     const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
1866     aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
1867     list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
1868     for ( int j = 0; j < aNodeGroup.length(); j++ )
1869     {
1870       CORBA::Long index = aNodeGroup[ j ];
1871       const SMDS_MeshNode * node = aMesh->FindNode(index);
1872       if ( node )
1873         aListOfNodes.push_back( node );
1874     }
1875     if ( aListOfNodes.size() < 2 )
1876       aListOfListOfNodes.pop_back();
1877
1878     if ( i > 0 ) aTPythonDump << ", ";
1879     aTPythonDump << aNodeGroup;
1880   }
1881   ::SMESH_MeshEditor anEditor( myMesh );
1882   anEditor.MergeNodes( aListOfListOfNodes );
1883
1884   // Update Python script
1885   aTPythonDump <<  "])";
1886 }
1887
1888 //=======================================================================
1889 //function : FindEqualElements
1890 //purpose  :
1891 //=======================================================================
1892 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr      theObject,
1893                                            SMESH::array_of_long_array_out GroupsOfElementsID)
1894 {
1895   initData();
1896   if ( !(!CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) &&
1897          SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) ) {
1898     typedef list<int> TListOfIDs;
1899     set<const SMDS_MeshElement*> elems;
1900     SMESH::long_array_var aElementsId = theObject->GetIDs();
1901     SMESHDS_Mesh* aMesh = GetMeshDS();
1902
1903     for(int i = 0; i < aElementsId->length(); i++) {
1904       CORBA::Long anID = aElementsId[i];
1905       const SMDS_MeshElement * elem = aMesh->FindElement(anID);
1906       if (elem) {
1907         elems.insert(elem);
1908       }
1909     }
1910
1911     ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
1912     ::SMESH_MeshEditor anEditor( myMesh );
1913     anEditor.FindEqualElements( elems, aListOfListOfElementsID );
1914
1915     GroupsOfElementsID = new SMESH::array_of_long_array;
1916     GroupsOfElementsID->length( aListOfListOfElementsID.size() );
1917
1918     ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
1919     for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
1920       SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
1921       TListOfIDs& listOfIDs = *arraysIt;
1922       aGroup.length( listOfIDs.size() );
1923       TListOfIDs::iterator idIt = listOfIDs.begin();
1924       for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
1925         aGroup[ k ] = *idIt;
1926       }
1927     }
1928
1929   // Update Python script
1930   TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
1931                 <<theObject<<" )";
1932   }
1933 }
1934
1935 //=======================================================================
1936 //function : MergeElements
1937 //purpose  :
1938 //=======================================================================
1939
1940 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
1941 {
1942   initData();
1943
1944   TPythonDump aTPythonDump;
1945   aTPythonDump << this << ".MergeElements( [";
1946
1947   ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
1948
1949   for (int i = 0; i < GroupsOfElementsID.length(); i++) {
1950     const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
1951     aListOfListOfElementsID.push_back( list< int >() );
1952     list< int >& aListOfElemsID = aListOfListOfElementsID.back();
1953     for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
1954       CORBA::Long id = anElemsIDGroup[ j ];
1955       aListOfElemsID.push_back( id );
1956     }
1957     if ( aListOfElemsID.size() < 2 )
1958       aListOfListOfElementsID.pop_back();
1959     if ( i > 0 ) aTPythonDump << ", ";
1960     aTPythonDump << anElemsIDGroup;
1961   }
1962
1963   ::SMESH_MeshEditor anEditor( myMesh );
1964   anEditor.MergeElements(aListOfListOfElementsID);
1965
1966   // Update Python script
1967   aTPythonDump << "] )";
1968 }
1969
1970 //=======================================================================
1971 //function : MergeEqualElements
1972 //purpose  :
1973 //=======================================================================
1974
1975 void SMESH_MeshEditor_i::MergeEqualElements()
1976 {
1977   initData();
1978
1979   ::SMESH_MeshEditor anEditor( myMesh );
1980   anEditor.MergeEqualElements();
1981
1982   // Update Python script
1983   TPythonDump() << this << ".MergeEqualElements()";
1984 }
1985
1986 //================================================================================
1987 /*!
1988  * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
1989  * move the node closest to the point to point's location and return ID of the node
1990  */
1991 //================================================================================
1992
1993 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
1994                                                        CORBA::Double y,
1995                                                        CORBA::Double z,
1996                                                        CORBA::Long   theNodeID)
1997 {
1998   // We keep myNodeSearcher until any mesh modification:
1999   // 1) initData() deletes myNodeSearcher at any edition,
2000   // 2) TNodeSearcherDeleter - at any mesh compute event and mesh change
2001
2002   initData();
2003
2004   int nodeID = theNodeID;
2005   const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
2006   if ( !node )
2007   {
2008     static TNodeSearcherDeleter deleter;
2009     deleter.Set( myMesh );
2010     if ( !myNodeSearcher ) {
2011       ::SMESH_MeshEditor anEditor( myMesh );
2012       myNodeSearcher = anEditor.GetNodeSearcher();
2013     }
2014     gp_Pnt p( x,y,z );
2015     node = myNodeSearcher->FindClosestTo( p );
2016   }
2017   if ( node ) {
2018     nodeID = node->GetID();
2019     if ( myPreviewMode ) // make preview data
2020     {
2021       // in a preview mesh, make edges linked to a node
2022       TPreviewMesh tmpMesh;
2023       TIDSortedElemSet linkedNodes;
2024       ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
2025       TIDSortedElemSet::iterator nIt = linkedNodes.begin();
2026       for ( ; nIt != linkedNodes.end(); ++nIt )
2027       {
2028         SMDS_MeshEdge edge( node, cast2Node( *nIt ));
2029         tmpMesh.Copy( &edge );
2030       }
2031       // move copied node
2032       node = tmpMesh.GetMeshDS()->FindNode( nodeID );
2033       if ( node )
2034         tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
2035       // fill preview data
2036       ::SMESH_MeshEditor anEditor( & tmpMesh );
2037       StoreResult( anEditor );
2038     }
2039     else
2040     {
2041       GetMeshDS()->MoveNode(node, x, y, z);
2042     }
2043   }
2044
2045   if ( !myPreviewMode ) {
2046     // Update Python script
2047     TPythonDump() << "nodeID = " << this
2048                   << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z << " )";
2049   }
2050
2051   return nodeID;
2052 }
2053
2054 //=======================================================================
2055 //function : convError
2056 //purpose  :
2057 //=======================================================================
2058
2059 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2060
2061 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
2062 {
2063   switch ( e ) {
2064   RETCASE( SEW_OK );
2065   RETCASE( SEW_BORDER1_NOT_FOUND );
2066   RETCASE( SEW_BORDER2_NOT_FOUND );
2067   RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
2068   RETCASE( SEW_BAD_SIDE_NODES );
2069   RETCASE( SEW_VOLUMES_TO_SPLIT );
2070   RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
2071   RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
2072   RETCASE( SEW_BAD_SIDE1_NODES );
2073   RETCASE( SEW_BAD_SIDE2_NODES );
2074   }
2075   return SMESH::SMESH_MeshEditor::SEW_OK;
2076 }
2077
2078 //=======================================================================
2079 //function : SewFreeBorders
2080 //purpose  :
2081 //=======================================================================
2082
2083 SMESH::SMESH_MeshEditor::Sew_Error
2084   SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
2085                                      CORBA::Long SecondNodeID1,
2086                                      CORBA::Long LastNodeID1,
2087                                      CORBA::Long FirstNodeID2,
2088                                      CORBA::Long SecondNodeID2,
2089                                      CORBA::Long LastNodeID2,
2090                                      CORBA::Boolean CreatePolygons,
2091                                      CORBA::Boolean CreatePolyedrs)
2092 {
2093   initData();
2094
2095   SMESHDS_Mesh* aMesh = GetMeshDS();
2096
2097   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
2098   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
2099   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
2100   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
2101   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
2102   const SMDS_MeshNode* aSide2ThirdNode   = aMesh->FindNode( LastNodeID2   );
2103
2104   if (!aBorderFirstNode ||
2105       !aBorderSecondNode||
2106       !aBorderLastNode)
2107     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
2108   if (!aSide2FirstNode  ||
2109       !aSide2SecondNode ||
2110       !aSide2ThirdNode)
2111     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
2112
2113   // Update Python script
2114   TPythonDump() << "error = " << this << ".SewFreeBorders( "
2115                 << FirstNodeID1  << ", "
2116                 << SecondNodeID1 << ", "
2117                 << LastNodeID1   << ", "
2118                 << FirstNodeID2  << ", "
2119                 << SecondNodeID2 << ", "
2120                 << LastNodeID2   << ", "
2121                 << CreatePolygons<< ", "
2122                 << CreatePolyedrs<< " )";
2123
2124   ::SMESH_MeshEditor anEditor( myMesh );
2125   SMESH::SMESH_MeshEditor::Sew_Error error =
2126     convError( anEditor.SewFreeBorder (aBorderFirstNode,
2127                                        aBorderSecondNode,
2128                                        aBorderLastNode,
2129                                        aSide2FirstNode,
2130                                        aSide2SecondNode,
2131                                        aSide2ThirdNode,
2132                                        true,
2133                                        CreatePolygons,
2134                                        CreatePolyedrs) );
2135
2136   StoreResult(anEditor);
2137
2138   return error;
2139 }
2140
2141
2142 //=======================================================================
2143 //function : SewConformFreeBorders
2144 //purpose  :
2145 //=======================================================================
2146
2147 SMESH::SMESH_MeshEditor::Sew_Error
2148 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
2149                                           CORBA::Long SecondNodeID1,
2150                                           CORBA::Long LastNodeID1,
2151                                           CORBA::Long FirstNodeID2,
2152                                           CORBA::Long SecondNodeID2)
2153 {
2154   initData();
2155
2156   SMESHDS_Mesh* aMesh = GetMeshDS();
2157
2158   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeID1  );
2159   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
2160   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeID1   );
2161   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeID2  );
2162   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( SecondNodeID2 );
2163   const SMDS_MeshNode* aSide2ThirdNode   = 0;
2164
2165   if (!aBorderFirstNode ||
2166       !aBorderSecondNode||
2167       !aBorderLastNode )
2168     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
2169   if (!aSide2FirstNode  ||
2170       !aSide2SecondNode)
2171     return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
2172
2173   // Update Python script
2174   TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
2175                 << FirstNodeID1  << ", "
2176                 << SecondNodeID1 << ", "
2177                 << LastNodeID1   << ", "
2178                 << FirstNodeID2  << ", "
2179                 << SecondNodeID2 << " )";
2180
2181   ::SMESH_MeshEditor anEditor( myMesh );
2182   SMESH::SMESH_MeshEditor::Sew_Error error =
2183     convError( anEditor.SewFreeBorder (aBorderFirstNode,
2184                                        aBorderSecondNode,
2185                                        aBorderLastNode,
2186                                        aSide2FirstNode,
2187                                        aSide2SecondNode,
2188                                        aSide2ThirdNode,
2189                                        true,
2190                                        false, false) );
2191
2192   StoreResult(anEditor);
2193
2194   return error;
2195 }
2196
2197
2198 //=======================================================================
2199 //function : SewBorderToSide
2200 //purpose  :
2201 //=======================================================================
2202
2203 SMESH::SMESH_MeshEditor::Sew_Error
2204 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
2205                                     CORBA::Long SecondNodeIDOnFreeBorder,
2206                                     CORBA::Long LastNodeIDOnFreeBorder,
2207                                     CORBA::Long FirstNodeIDOnSide,
2208                                     CORBA::Long LastNodeIDOnSide,
2209                                     CORBA::Boolean CreatePolygons,
2210                                     CORBA::Boolean CreatePolyedrs)
2211 {
2212   initData();
2213
2214   SMESHDS_Mesh* aMesh = GetMeshDS();
2215
2216   const SMDS_MeshNode* aBorderFirstNode  = aMesh->FindNode( FirstNodeIDOnFreeBorder  );
2217   const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
2218   const SMDS_MeshNode* aBorderLastNode   = aMesh->FindNode( LastNodeIDOnFreeBorder   );
2219   const SMDS_MeshNode* aSide2FirstNode   = aMesh->FindNode( FirstNodeIDOnSide  );
2220   const SMDS_MeshNode* aSide2SecondNode  = aMesh->FindNode( LastNodeIDOnSide );
2221   const SMDS_MeshNode* aSide2ThirdNode   = 0;
2222
2223   if (!aBorderFirstNode ||
2224       !aBorderSecondNode||
2225       !aBorderLastNode  )
2226     return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
2227   if (!aSide2FirstNode  ||
2228       !aSide2SecondNode)
2229     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
2230
2231   // Update Python script
2232   TPythonDump() << "error = " << this << ".SewBorderToSide( "
2233                 << FirstNodeIDOnFreeBorder  << ", "
2234                 << SecondNodeIDOnFreeBorder << ", "
2235                 << LastNodeIDOnFreeBorder   << ", "
2236                 << FirstNodeIDOnSide        << ", "
2237                 << LastNodeIDOnSide         << ", "
2238                 << CreatePolygons           << ", "
2239                 << CreatePolyedrs           << ") ";
2240
2241   ::SMESH_MeshEditor anEditor( myMesh );
2242   SMESH::SMESH_MeshEditor::Sew_Error error =
2243     convError( anEditor.SewFreeBorder (aBorderFirstNode,
2244                                        aBorderSecondNode,
2245                                        aBorderLastNode,
2246                                        aSide2FirstNode,
2247                                        aSide2SecondNode,
2248                                        aSide2ThirdNode,
2249                                        false,
2250                                        CreatePolygons,
2251                                        CreatePolyedrs) );
2252
2253   StoreResult(anEditor);
2254
2255   return error;
2256 }
2257
2258
2259 //=======================================================================
2260 //function : SewSideElements
2261 //purpose  :
2262 //=======================================================================
2263
2264 SMESH::SMESH_MeshEditor::Sew_Error
2265 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
2266                                     const SMESH::long_array& IDsOfSide2Elements,
2267                                     CORBA::Long NodeID1OfSide1ToMerge,
2268                                     CORBA::Long NodeID1OfSide2ToMerge,
2269                                     CORBA::Long NodeID2OfSide1ToMerge,
2270                                     CORBA::Long NodeID2OfSide2ToMerge)
2271 {
2272   initData();
2273
2274   SMESHDS_Mesh* aMesh = GetMeshDS();
2275
2276   const SMDS_MeshNode* aFirstNode1ToMerge  = aMesh->FindNode( NodeID1OfSide1ToMerge );
2277   const SMDS_MeshNode* aFirstNode2ToMerge  = aMesh->FindNode( NodeID1OfSide2ToMerge );
2278   const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
2279   const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
2280
2281   if (!aFirstNode1ToMerge ||
2282       !aFirstNode2ToMerge )
2283     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
2284   if (!aSecondNode1ToMerge||
2285       !aSecondNode2ToMerge)
2286     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
2287
2288   TIDSortedElemSet aSide1Elems, aSide2Elems;
2289   ToMap(IDsOfSide1Elements, aMesh, aSide1Elems);
2290   ToMap(IDsOfSide2Elements, aMesh, aSide2Elems);
2291
2292   // Update Python script
2293   TPythonDump() << "error = " << this << ".SewSideElements( "
2294                 << IDsOfSide1Elements << ", "
2295                 << IDsOfSide2Elements << ", "
2296                 << NodeID1OfSide1ToMerge << ", "
2297                 << NodeID1OfSide2ToMerge << ", "
2298                 << NodeID2OfSide1ToMerge << ", "
2299                 << NodeID2OfSide2ToMerge << ")";
2300
2301   ::SMESH_MeshEditor anEditor( myMesh );
2302   SMESH::SMESH_MeshEditor::Sew_Error error =
2303     convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
2304                                          aFirstNode1ToMerge,
2305                                          aFirstNode2ToMerge,
2306                                          aSecondNode1ToMerge,
2307                                          aSecondNode2ToMerge));
2308
2309   StoreResult(anEditor);
2310
2311   return error;
2312 }
2313
2314 //================================================================================
2315 /*!
2316  * \brief Set new nodes for given element
2317   * \param ide - element id
2318   * \param newIDs - new node ids
2319   * \retval CORBA::Boolean - true if result is OK
2320  */
2321 //================================================================================
2322
2323 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
2324                                                    const SMESH::long_array& newIDs)
2325 {
2326   initData();
2327
2328   const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
2329   if(!elem) return false;
2330
2331   int nbn = newIDs.length();
2332   int i=0;
2333   vector<const SMDS_MeshNode*> aNodes (nbn);
2334   int nbn1=-1;
2335   for(; i<nbn; i++) {
2336     const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
2337     if(aNode) {
2338       nbn1++;
2339       aNodes[nbn1] = aNode;
2340     }
2341   }
2342   // Update Python script
2343   TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
2344                 << ide << ", " << newIDs << " )";
2345 #ifdef _DEBUG_
2346   TPythonDump() << "print 'ChangeElemNodes: ', isDone";
2347 #endif
2348
2349   return GetMeshDS()->ChangeElementNodes( elem, &aNodes[0], nbn1+1 );
2350 }
2351   
2352 //================================================================================
2353 /*!
2354  * \brief Update myLastCreated* or myPreviewData
2355   * \param anEditor - it contains last modification results
2356  */
2357 //================================================================================
2358
2359 void SMESH_MeshEditor_i::StoreResult(::SMESH_MeshEditor& anEditor)
2360 {
2361   if ( myPreviewMode ) { // --- MeshPreviewStruct filling --- 
2362
2363     list<int> aNodesConnectivity;
2364     typedef map<int, int> TNodesMap;
2365     TNodesMap nodesMap;
2366
2367     TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
2368     SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
2369
2370     SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
2371     int nbEdges = aMeshDS->NbEdges();
2372     int nbFaces = aMeshDS->NbFaces();
2373     int nbVolum = aMeshDS->NbVolumes();
2374     switch ( previewType ) {
2375     case SMDSAbs_Edge  : nbFaces = nbVolum = 0; break;
2376     case SMDSAbs_Face  : nbEdges = nbVolum = 0; break;
2377     case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
2378     default:;
2379     }
2380     myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
2381     myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
2382     int i = 0, j = 0;
2383     SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
2384
2385     while ( itMeshElems->more() ) {
2386       const SMDS_MeshElement* aMeshElem = itMeshElems->next();
2387       if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
2388         continue;
2389
2390       SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
2391       while ( itElemNodes->more() ) {
2392         const SMDS_MeshNode* aMeshNode = 
2393           static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
2394         int aNodeID = aMeshNode->GetID();
2395         TNodesMap::iterator anIter = nodesMap.find(aNodeID);
2396         if ( anIter == nodesMap.end() ) {
2397           // filling the nodes coordinates
2398           myPreviewData->nodesXYZ[j].x = aMeshNode->X();
2399           myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
2400           myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
2401           anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
2402           j++;
2403         }
2404         aNodesConnectivity.push_back(anIter->second);
2405       }
2406
2407       // filling the elements types
2408       SMDSAbs_ElementType aType;
2409       bool isPoly;
2410       /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
2411         aType = SMDSAbs_Node;
2412         isPoly = false;
2413       }
2414       else*/ {
2415         aType = aMeshElem->GetType();
2416         isPoly = aMeshElem->IsPoly();
2417       }
2418
2419       myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
2420       myPreviewData->elementTypes[i].isPoly = isPoly;
2421       myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
2422       i++;
2423
2424     }
2425     myPreviewData->nodesXYZ.length( j );
2426
2427     // filling the elements connectivities
2428     list<int>::iterator aConnIter = aNodesConnectivity.begin();
2429     myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
2430     for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
2431       myPreviewData->elementConnectivities[i] = *aConnIter;
2432     
2433     return;
2434   }
2435
2436   {
2437     // add new nodes into myLastCreatedNodes
2438     const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
2439     myLastCreatedNodes->length(aSeq.Length());
2440     for(int i=0; i<aSeq.Length(); i++)
2441       myLastCreatedNodes[i] = aSeq.Value(i+1)->GetID();
2442   }
2443   {
2444     // add new elements into myLastCreatedElems
2445     const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
2446     myLastCreatedElems->length(aSeq.Length());
2447     for(int i=0; i<aSeq.Length(); i++)
2448       myLastCreatedElems[i] = aSeq.Value(i+1)->GetID();
2449   }
2450 }
2451
2452 //================================================================================
2453 /*!
2454  * Return data of mesh edition preview
2455  */
2456 //================================================================================
2457
2458 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
2459 {
2460   return myPreviewData._retn();
2461 }
2462
2463 //================================================================================
2464 /*!
2465  * \brief Returns list of it's IDs of created nodes
2466   * \retval SMESH::long_array* - list of node ID
2467  */
2468 //================================================================================
2469
2470 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
2471 {
2472   return myLastCreatedNodes._retn();
2473 }
2474
2475 //================================================================================
2476 /*!
2477  * \brief Returns list of it's IDs of created elements
2478   * \retval SMESH::long_array* - list of elements' ID
2479  */
2480 //================================================================================
2481
2482 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
2483 {
2484   return myLastCreatedElems._retn();
2485 }
2486
2487 //=======================================================================
2488 //function : ConvertToQuadratic
2489 //purpose  :
2490 //=======================================================================
2491
2492 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
2493 {
2494   ::SMESH_MeshEditor anEditor( myMesh );
2495   anEditor.ConvertToQuadratic(theForce3d);
2496  // Update Python script
2497   TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
2498 }
2499
2500 //=======================================================================
2501 //function : ConvertFromQuadratic
2502 //purpose  :
2503 //=======================================================================
2504
2505 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
2506 {
2507   ::SMESH_MeshEditor anEditor( myMesh );
2508   CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
2509   // Update Python script
2510   TPythonDump() << this << ".ConvertFromQuadratic()";
2511   return isDone;
2512 }