Salome HOME
IMP19942 - Convert group on geometry into group of elements
[modules/smesh.git] / src / SMESH_I / SMESH_Mesh_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_Mesh_i.cxx
25 //  Author : Paul RASCLE, EDF
26 //  Module : SMESH
27 //  $Header$
28
29 #include "SMESH_Mesh_i.hxx"
30
31 #include "SMESH_Filter_i.hxx"
32 #include "SMESH_Gen_i.hxx"
33 #include "SMESH_Group_i.hxx"
34 #include "SMESH_MEDMesh_i.hxx"
35 #include "SMESH_MeshEditor_i.hxx"
36 #include "SMESH_PythonDump.hxx"
37 #include "SMESH_subMesh_i.hxx"
38
39 #include "DriverMED_R_SMESHDS_Mesh.h"
40 #include "DriverMED_W_SMESHDS_Mesh.h"
41 #include "SMDS_VolumeTool.hxx"
42 #include "SMESHDS_Command.hxx"
43 #include "SMESHDS_CommandType.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Group.hxx"
46 #include "SMESH_MeshEditor.hxx"
47 #include "SMESH_MesherHelper.hxx"
48 #include "SMDS_EdgePosition.hxx"
49 #include "SMDS_FacePosition.hxx"
50
51 #include "OpUtil.hxx"
52 #include "SALOME_NamingService.hxx"
53 #include "Utils_CorbaException.hxx"
54 #include "Utils_ExceptHandlers.hxx"
55 #include "Utils_SINGLETON.hxx"
56 #include "utilities.h"
57
58 // OCCT Includes
59 #include <BRep_Builder.hxx>
60 #include <OSD_Directory.hxx>
61 #include <OSD_File.hxx>
62 #include <OSD_Path.hxx>
63 #include <OSD_Protection.hxx>
64 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
65 #include <TColStd_MapOfInteger.hxx>
66 #include <TColStd_SequenceOfInteger.hxx>
67 #include <TCollection_AsciiString.hxx>
68 #include <TopExp_Explorer.hxx>
69 #include <TopoDS_Compound.hxx>
70
71 // STL Includes
72 #include <string>
73 #include <iostream>
74 #include <sstream>
75 #include <sys/stat.h>
76
77 #ifdef _DEBUG_
78 static int MYDEBUG = 0;
79 #else
80 static int MYDEBUG = 0;
81 #endif
82
83 using namespace std;
84 using SMESH::TPythonDump;
85
86 int SMESH_Mesh_i::myIdGenerator = 0;
87
88
89
90 //=============================================================================
91 /*!
92  *  Constructor
93  */
94 //=============================================================================
95
96 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
97                             SMESH_Gen_i*            gen_i,
98                             CORBA::Long studyId )
99 : SALOME::GenericObj_i( thePOA )
100 {
101   MESSAGE("SMESH_Mesh_i");
102   _impl = NULL;
103   _gen_i = gen_i;
104   _id = myIdGenerator++;
105   _studyId = studyId;
106 }
107
108 //=============================================================================
109 /*!
110  *  Destructor
111  */
112 //=============================================================================
113
114 SMESH_Mesh_i::~SMESH_Mesh_i()
115 {
116   INFOS("~SMESH_Mesh_i");
117   map<int, SMESH::SMESH_GroupBase_ptr>::iterator it;
118   for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) {
119     SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( it->second ).in() );
120     if ( aGroup ) {
121       // this method is colled from destructor of group (PAL6331)
122       //_impl->RemoveGroup( aGroup->GetLocalID() );
123       
124       aGroup->Destroy();
125     }
126   }
127   _mapGroups.clear();
128   delete _impl;
129 }
130
131 //=============================================================================
132 /*!
133  *  SetShape
134  *
135  *  Associates <this> mesh with <theShape> and puts a reference
136  *  to <theShape> into the current study;
137  *  the previous shape is substituted by the new one.
138  */
139 //=============================================================================
140
141 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
142     throw (SALOME::SALOME_Exception)
143 {
144   Unexpect aCatch(SALOME_SalomeException);
145   try {
146     _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
147   }
148   catch(SALOME_Exception & S_ex) {
149     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
150   }
151 }
152
153 //================================================================================
154 /*!
155  * \brief return true if mesh has a shape to build a shape on
156  */
157 //================================================================================
158
159 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
160   throw (SALOME::SALOME_Exception)
161 {
162   Unexpect aCatch(SALOME_SalomeException);
163   bool res = false;
164   try {
165     res = _impl->HasShapeToMesh();
166   }
167   catch(SALOME_Exception & S_ex) {
168     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
169   }
170   return res;
171 }
172
173 //=======================================================================
174 //function : GetShapeToMesh
175 //purpose  :
176 //=======================================================================
177
178 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
179   throw (SALOME::SALOME_Exception)
180 {
181   Unexpect aCatch(SALOME_SalomeException);
182   GEOM::GEOM_Object_var aShapeObj;
183   try {
184     TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
185     if ( !S.IsNull() )
186       aShapeObj = _gen_i->ShapeToGeomObject( S );
187   }
188   catch(SALOME_Exception & S_ex) {
189     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
190   }
191   return aShapeObj._retn();
192 }
193
194 //================================================================================
195 /*!
196  * \brief Remove all nodes and elements
197  */
198 //================================================================================
199
200 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
201 {
202   Unexpect aCatch(SALOME_SalomeException);
203   try {
204     _impl->Clear();
205   }
206   catch(SALOME_Exception & S_ex) {
207     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
208   }
209   TPythonDump() <<  _this() << ".Clear()";
210 }
211
212 //================================================================================
213 /*!
214  * \brief Remove all nodes and elements for indicated shape
215  */
216 //================================================================================
217
218 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
219   throw (SALOME::SALOME_Exception)
220 {
221   Unexpect aCatch(SALOME_SalomeException);
222   try {
223     _impl->ClearSubMesh( ShapeID );
224   }
225   catch(SALOME_Exception & S_ex) {
226     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
227   }
228 }
229
230 //=============================================================================
231 /*!
232  *
233  */
234 //=============================================================================
235
236 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
237 {
238   SMESH::DriverMED_ReadStatus res;
239   switch (theStatus)
240   {
241   case DriverMED_R_SMESHDS_Mesh::DRS_OK:
242     res = SMESH::DRS_OK; break;
243   case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
244     res = SMESH::DRS_EMPTY; break;
245   case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
246     res = SMESH::DRS_WARN_RENUMBER; break;
247   case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
248     res = SMESH::DRS_WARN_SKIP_ELEM; break;
249   case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
250   default:
251     res = SMESH::DRS_FAIL; break;
252   }
253   return res;
254 }
255
256 //=============================================================================
257 /*!
258  *  ImportMEDFile
259  *
260  *  Imports mesh data from MED file
261  */
262 //=============================================================================
263
264 SMESH::DriverMED_ReadStatus
265 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
266   throw ( SALOME::SALOME_Exception )
267 {
268   Unexpect aCatch(SALOME_SalomeException);
269   int status;
270   try {
271     status = _impl->MEDToMesh( theFileName, theMeshName );
272   }
273   catch( SALOME_Exception& S_ex ) {
274     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
275   }
276   catch ( ... ) {
277     THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
278   }
279
280   CreateGroupServants();
281
282   int major, minor, release;
283   if( !MED::getMEDVersion( theFileName, major, minor, release ) )
284     major = minor = release = -1;
285   myFileInfo           = new SALOME_MED::MedFileInfo();
286   myFileInfo->fileName = theFileName;
287   myFileInfo->fileSize = 0;
288 #ifdef WIN32
289   struct _stati64 d;
290   if ( ::_stati64( theFileName, &d ) != -1 )
291 #else
292   struct stat64 d;
293   if ( ::stat64( theFileName, &d ) != -1 )
294 #endif
295     myFileInfo->fileSize = d.st_size;
296   myFileInfo->major    = major;
297   myFileInfo->minor    = minor;
298   myFileInfo->release  = release;
299
300   return ConvertDriverMEDReadStatus(status);
301 }
302
303 //================================================================================
304 /*!
305  * \brief Return string representation of a MED file version comprising nbDigits
306  */
307 //================================================================================
308
309 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
310 {
311   std::string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
312                                                                nbDigits);
313   return CORBA::string_dup( ver.c_str() );
314 }
315
316 //=============================================================================
317 /*!
318  *  ImportUNVFile
319  *
320  *  Imports mesh data from MED file
321  */
322 //=============================================================================
323
324 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
325   throw ( SALOME::SALOME_Exception )
326 {
327   // Read mesh with name = <theMeshName> into SMESH_Mesh
328   _impl->UNVToMesh( theFileName );
329
330   CreateGroupServants();
331
332   return 1;
333 }
334
335 //=============================================================================
336 /*!
337  *  ImportSTLFile
338  *
339  *  Imports mesh data from STL file
340  */
341 //=============================================================================
342 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
343   throw ( SALOME::SALOME_Exception )
344 {
345   // Read mesh with name = <theMeshName> into SMESH_Mesh
346   _impl->STLToMesh( theFileName );
347
348   return 1;
349 }
350
351 //=============================================================================
352 /*!
353  *  importMEDFile
354  *
355  *  Imports mesh data from MED file
356  */
357 //=============================================================================
358
359 // int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
360 // {
361 //   // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
362 //   int status = _impl->MEDToMesh( theFileName, theMeshName );
363 //   CreateGroupServants();
364
365 //   return status;
366 // }
367
368 //=============================================================================
369 /*!
370  *
371  */
372 //=============================================================================
373
374 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
375
376 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
377                          (SMESH_Hypothesis::Hypothesis_Status theStatus)
378 {
379   switch (theStatus) {
380   RETURNCASE( HYP_OK            );
381   RETURNCASE( HYP_MISSING       );
382   RETURNCASE( HYP_CONCURENT     );
383   RETURNCASE( HYP_BAD_PARAMETER );
384   RETURNCASE( HYP_HIDDEN_ALGO   );
385   RETURNCASE( HYP_HIDING_ALGO   );
386   RETURNCASE( HYP_UNKNOWN_FATAL );
387   RETURNCASE( HYP_INCOMPATIBLE  );
388   RETURNCASE( HYP_NOTCONFORM    );
389   RETURNCASE( HYP_ALREADY_EXIST );
390   RETURNCASE( HYP_BAD_DIM       );
391   RETURNCASE( HYP_BAD_SUBSHAPE  );
392   RETURNCASE( HYP_BAD_GEOMETRY  );
393   RETURNCASE( HYP_NEED_SHAPE    );
394   default:;
395   }
396   return SMESH::HYP_UNKNOWN_FATAL;
397 }
398
399 //=============================================================================
400 /*!
401  *  AddHypothesis
402  *
403  *  calls internal addHypothesis() and then adds a reference to <anHyp> under
404  *  the SObject actually having a reference to <aSubShape>.
405  *  NB: For this method to work, it is necessary to add a reference to sub-shape first.
406  */
407 //=============================================================================
408
409 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
410                                                      SMESH::SMESH_Hypothesis_ptr anHyp)
411   throw(SALOME::SALOME_Exception)
412 {
413   Unexpect aCatch(SALOME_SalomeException);
414   SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
415
416   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
417     _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
418                                  aSubShapeObject, anHyp );
419
420   if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
421
422   // Update Python script
423   if(_impl->HasShapeToMesh()) {
424     TPythonDump() << "status = " << _this() << ".AddHypothesis( "
425                   << aSubShapeObject << ", " << anHyp << " )";
426   }
427   else {
428     TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
429   }
430   
431   return ConvertHypothesisStatus(status);
432 }
433
434 //=============================================================================
435 /*!
436  *
437  */
438 //=============================================================================
439
440 SMESH_Hypothesis::Hypothesis_Status
441   SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr       aSubShapeObject,
442                               SMESH::SMESH_Hypothesis_ptr anHyp)
443 {
444   if(MYDEBUG) MESSAGE("addHypothesis");
445
446   if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
447     THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
448                                  SALOME::BAD_PARAM);
449
450   SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
451   if (CORBA::is_nil(myHyp))
452     THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
453                                  SALOME::BAD_PARAM);
454
455   SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
456   try
457   {
458     TopoDS_Shape myLocSubShape;
459     //use PseudoShape in case if mesh has no shape
460     if(HasShapeToMesh())
461       myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
462     else              
463       myLocSubShape = _impl->GetShapeToMesh();
464     
465     int hypId = myHyp->GetId();
466     status = _impl->AddHypothesis(myLocSubShape, hypId);
467     if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
468       _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
469       // assure there is a corresponding submesh
470       if ( !_impl->IsMainShape( myLocSubShape )) {
471         int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
472         if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
473           createSubMesh( aSubShapeObject );
474       }
475     }
476   }
477   catch(SALOME_Exception & S_ex)
478   {
479     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
480   }
481   return status;
482 }
483
484 //=============================================================================
485 /*!
486  *
487  */
488 //=============================================================================
489
490 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
491                                                         SMESH::SMESH_Hypothesis_ptr anHyp)
492      throw(SALOME::SALOME_Exception)
493 {
494   Unexpect aCatch(SALOME_SalomeException);
495   SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
496
497   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
498     _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
499                                       aSubShapeObject, anHyp );
500
501   // Update Python script
502     // Update Python script
503   if(_impl->HasShapeToMesh()) {
504   TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
505                 << aSubShapeObject << ", " << anHyp << " )";
506   }
507   else {
508     TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
509                   << anHyp << " )";
510   }
511
512   return ConvertHypothesisStatus(status);
513 }
514
515 //=============================================================================
516 /*!
517  *
518  */
519 //=============================================================================
520
521 SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
522                                  SMESH::SMESH_Hypothesis_ptr anHyp)
523 {
524         if(MYDEBUG) MESSAGE("removeHypothesis()");
525         // **** proposer liste de subShape (selection multiple)
526
527         if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
528                 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
529                         SALOME::BAD_PARAM);
530
531         SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
532         if (CORBA::is_nil(myHyp))
533           THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
534                         SALOME::BAD_PARAM);
535
536         SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
537         try
538         {
539                 TopoDS_Shape myLocSubShape;
540                 //use PseudoShape in case if mesh has no shape
541                 if(HasShapeToMesh())
542                   myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
543                 else
544                   myLocSubShape = _impl->GetShapeToMesh();
545                 
546                 int hypId = myHyp->GetId();
547                 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
548                 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
549                   _mapHypo.erase( hypId );
550         }
551         catch(SALOME_Exception & S_ex)
552         {
553                 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
554         }
555         return status;
556 }
557
558 //=============================================================================
559 /*!
560  *
561  */
562 //=============================================================================
563
564 SMESH::ListOfHypothesis *
565         SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
566 throw(SALOME::SALOME_Exception)
567 {
568   Unexpect aCatch(SALOME_SalomeException);
569   if (MYDEBUG) MESSAGE("GetHypothesisList");
570   if (CORBA::is_nil(aSubShapeObject))
571     THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
572                                  SALOME::BAD_PARAM);
573
574   SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
575
576   try {
577     TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
578     const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
579     int i = 0, n = aLocalList.size();
580     aList->length( n );
581
582     for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
583       SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
584       if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
585         aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
586     }
587
588     aList->length( i );
589   }
590   catch(SALOME_Exception & S_ex) {
591     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
592   }
593
594   return aList._retn();
595 }
596
597 //=============================================================================
598 /*!
599  *
600  */
601 //=============================================================================
602 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
603                                                   const char*           theName )
604      throw(SALOME::SALOME_Exception)
605 {
606   Unexpect aCatch(SALOME_SalomeException);
607   MESSAGE("SMESH_Mesh_i::GetSubMesh");
608   if (CORBA::is_nil(aSubShapeObject))
609     THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
610                                  SALOME::BAD_PARAM);
611
612   SMESH::SMESH_subMesh_var subMesh;
613   SMESH::SMESH_Mesh_var    aMesh = SMESH::SMESH_Mesh::_narrow(_this());
614   try {
615     TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
616
617     //Get or Create the SMESH_subMesh object implementation
618
619     int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
620     subMesh = getSubMesh( subMeshId );
621
622     // create a new subMesh object servant if there is none for the shape
623     if ( subMesh->_is_nil() )
624       subMesh = createSubMesh( aSubShapeObject );
625
626     if ( _gen_i->CanPublishInStudy( subMesh )) {
627       SALOMEDS::SObject_var aSO =
628         _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
629                                subMesh, aSubShapeObject, theName );
630       if ( !aSO->_is_nil()) {
631         // Update Python script
632         TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
633                       << aSubShapeObject << ", '" << theName << "' )";
634       }
635     }
636   }
637   catch(SALOME_Exception & S_ex) {
638     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
639   }
640   return subMesh._retn();
641 }
642
643 //=============================================================================
644 /*!
645  *
646  */
647 //=============================================================================
648
649 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
650      throw (SALOME::SALOME_Exception)
651 {
652   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
653   if ( theSubMesh->_is_nil() )
654     return;
655
656   GEOM::GEOM_Object_var aSubShapeObject;
657   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
658   if ( !aStudy->_is_nil() )  {
659     // Remove submesh's SObject
660     SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
661     if ( !anSO->_is_nil() ) {
662       long aTag = SMESH_Gen_i::GetRefOnShapeTag();
663       SALOMEDS::SObject_var anObj, aRef;
664       if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
665         aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
666
667       aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
668
669       // Update Python script
670       TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
671     }
672   }
673
674   removeSubMesh( theSubMesh, aSubShapeObject.in() );
675 }
676
677 //=============================================================================
678 /*!
679  *  ElementTypeString
680  */
681 //=============================================================================
682 #define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
683 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
684 {
685   switch (theElemType) {
686     CASE2STRING( ALL );
687     CASE2STRING( NODE );
688     CASE2STRING( EDGE );
689     CASE2STRING( FACE );
690     CASE2STRING( VOLUME );
691   default:;
692   }
693   return "";
694 }
695
696 //=============================================================================
697 /*!
698  *
699  */
700 //=============================================================================
701
702 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
703                                                  const char*         theName )
704      throw(SALOME::SALOME_Exception)
705 {
706   Unexpect aCatch(SALOME_SalomeException);
707   SMESH::SMESH_Group_var aNewGroup =
708     SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
709
710   if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
711     SALOMEDS::SObject_var aSO =
712       _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
713                            aNewGroup, GEOM::GEOM_Object::_nil(), theName);
714     if ( !aSO->_is_nil()) {
715       // Update Python script
716       TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
717                     << ElementTypeString(theElemType) << ", '" << theName << "' )";
718     }
719   }
720   return aNewGroup._retn();
721 }
722
723
724 //=============================================================================
725 /*!
726  *
727  */
728 //=============================================================================
729 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType    theElemType,
730                                                                 const char*           theName,
731                                                                 GEOM::GEOM_Object_ptr theGeomObj)
732      throw(SALOME::SALOME_Exception)
733 {
734   Unexpect aCatch(SALOME_SalomeException);
735   SMESH::SMESH_GroupOnGeom_var aNewGroup;
736
737   TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
738   if ( !aShape.IsNull() ) {
739     aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
740       ( createGroup( theElemType, theName, aShape ));
741     if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
742       SALOMEDS::SObject_var aSO =
743         _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
744                              aNewGroup, theGeomObj, theName);
745       if ( !aSO->_is_nil()) {
746         // Update Python script
747         TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
748                       << ElementTypeString(theElemType) << ", '" << theName << "', "
749                       << theGeomObj << " )";
750       }
751     }
752   }
753
754   return aNewGroup._retn();
755 }
756
757 //=============================================================================
758 /*!
759  *
760  */
761 //=============================================================================
762
763 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
764      throw (SALOME::SALOME_Exception)
765 {
766   if ( theGroup->_is_nil() )
767     return;
768
769   SMESH_GroupBase_i* aGroup =
770     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
771   if ( !aGroup )
772     return;
773
774   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
775   if ( !aStudy->_is_nil() )  {
776     SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
777
778     if ( !aGroupSO->_is_nil() ) {
779       // Update Python script
780       TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
781
782       // Remove group's SObject
783       aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
784     }
785   }
786
787   // Remove the group from SMESH data structures
788   removeGroup( aGroup->GetLocalID() );
789 }
790
791 //=============================================================================
792 /*! RemoveGroupWithContents
793  *  Remove group with its contents
794  */
795 //=============================================================================
796 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
797   throw (SALOME::SALOME_Exception)
798 {
799   if ( theGroup->_is_nil() )
800     return;
801
802   SMESH_GroupBase_i* aGroup =
803     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
804   if ( !aGroup )
805     return;
806
807   SMESH::long_array_var anIds = aGroup->GetListOfID();
808   SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
809
810   // Update Python script
811   TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
812
813   // Remove contents
814   if ( aGroup->GetType() == SMESH::NODE )
815     aMeshEditor->RemoveNodes( anIds );
816   else
817     aMeshEditor->RemoveElements( anIds );
818
819   // Remove group
820   RemoveGroup( theGroup );
821
822   // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
823   _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
824   _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
825 }
826
827
828 //================================================================================
829 /*!
830  * \brief Get the list of groups existing in the mesh
831   * \retval SMESH::ListOfGroups * - list of groups
832  */
833 //================================================================================
834
835 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
836 {
837   Unexpect aCatch(SALOME_SalomeException);
838   if (MYDEBUG) MESSAGE("GetGroups");
839
840   SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
841
842   // Python Dump
843   TPythonDump aPythonDump;
844   if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
845     aPythonDump << "[ ";
846
847   try {
848     aList->length( _mapGroups.size() );
849     int i = 0;
850     map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
851     for ( ; it != _mapGroups.end(); it++ ) {
852       if ( CORBA::is_nil( it->second )) continue;
853       aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
854       // Python Dump
855       if (i > 1) aPythonDump << ", ";
856       aPythonDump << it->second;
857     }
858     aList->length( i );
859   }
860   catch(SALOME_Exception & S_ex) {
861     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
862   }
863
864   // Update Python script
865   if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
866     aPythonDump << " ] = " << _this() << ".GetGroups()";
867
868   return aList._retn();
869 }
870 //=============================================================================
871 /*!
872  *  Get number of groups existing in the mesh
873  */
874 //=============================================================================
875
876 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
877 {
878   Unexpect aCatch(SALOME_SalomeException);
879   return _mapGroups.size();
880 }
881
882 //=============================================================================
883 /*! UnionGroups
884  *  New group is created. All mesh elements that are
885  *  present in initial groups are added to the new one
886  */
887 //=============================================================================
888 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
889                                                   SMESH::SMESH_GroupBase_ptr theGroup2,
890                                                   const char* theName )
891   throw (SALOME::SALOME_Exception)
892 {
893   try
894   {
895     if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
896          theGroup1->GetType() != theGroup2->GetType() )
897       return SMESH::SMESH_Group::_nil();
898
899     // Create Union
900     SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
901     if ( aResGrp->_is_nil() )
902       return SMESH::SMESH_Group::_nil();
903
904     SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
905     SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
906
907     TColStd_MapOfInteger aResMap;
908
909     for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
910       aResMap.Add( anIds1[ i1 ] );
911
912     for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
913       aResMap.Add( anIds2[ i2 ] );
914
915     SMESH::long_array_var aResIds = new SMESH::long_array;
916     aResIds->length( aResMap.Extent() );
917
918     int resI = 0;
919     TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
920     for( ; anIter.More(); anIter.Next() )
921       aResIds[ resI++ ] = anIter.Key();
922
923     aResGrp->Add( aResIds );
924
925     // Clear python lines, created by CreateGroup() and Add()
926     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
927     _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
928     _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
929
930     // Update Python script
931     TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
932                   << theGroup1 << ", " << theGroup2 << ", '"
933                   << theName << "' )";
934
935     return aResGrp._retn();
936   }
937   catch( ... )
938   {
939     return SMESH::SMESH_Group::_nil();
940   }
941 }
942
943 //=============================================================================
944 /*!
945   \brief Union list of groups. New group is created. All mesh elements that are
946    present in initial groups are added to the new one.
947   \param theGroups list of groups
948   \param theName name of group to be created
949   \return pointer on the group
950 */
951 //=============================================================================
952 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups( 
953   const SMESH::ListOfGroups& theGroups, const char* theName )
954 throw (SALOME::SALOME_Exception)
955 {
956   if ( !theName )
957     return SMESH::SMESH_Group::_nil();
958
959   try
960   {
961     NCollection_Map< int > anIds;
962     SMESH::ElementType aType = SMESH::ALL;
963     for ( int g = 0, n = theGroups.length(); g < n; g++ )
964     {
965       SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
966       if ( CORBA::is_nil( aGrp ) )
967         continue;
968
969       // check type
970       SMESH::ElementType aCurrType = aGrp->GetType();
971       if ( aType == SMESH::ALL )
972         aType = aCurrType;
973       else 
974       {
975         if ( aType != aCurrType )
976           return SMESH::SMESH_Group::_nil();
977       }
978
979       // unite ids
980       SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
981       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
982       {
983         int aCurrId = aCurrIds[ i ];
984         anIds.Add( aCurrId );
985       }
986     }
987
988     // Create group
989     SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
990     if ( aResGrp->_is_nil() )
991       return SMESH::SMESH_Group::_nil();
992     
993     // Create array of identifiers
994     SMESH::long_array_var aResIds = new SMESH::long_array;
995     aResIds->length( anIds.Extent() );
996     
997     NCollection_Map< int >::Iterator anIter( anIds );
998     for ( int i = 0; anIter.More(); anIter.Next(), i++ )
999     {
1000       aResIds[ i ] = anIter.Value();
1001     }
1002     aResGrp->Add( aResIds );
1003
1004     // Clear python lines, created by CreateGroup() and Add()
1005     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1006     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1007     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1008
1009     // Update Python script
1010     
1011     TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1012                   << &theGroups << ", '" << theName << "' )";
1013
1014     return aResGrp._retn();
1015   }
1016   catch( ... )
1017   {
1018     return SMESH::SMESH_Group::_nil();
1019   }
1020 }
1021
1022 //=============================================================================
1023 /*! IntersectGroups
1024  *  New group is created. All mesh elements that are
1025  *  present in both initial groups are added to the new one.
1026  */
1027 //=============================================================================
1028 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1029                                                       SMESH::SMESH_GroupBase_ptr theGroup2,
1030                                                       const char* theName )
1031   throw (SALOME::SALOME_Exception)
1032 {
1033   if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1034        theGroup1->GetType() != theGroup2->GetType() )
1035     return SMESH::SMESH_Group::_nil();
1036
1037   // Create Intersection
1038   SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1039   if ( aResGrp->_is_nil() )
1040     return aResGrp;
1041
1042   SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1043   SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1044
1045   TColStd_MapOfInteger aMap1;
1046
1047   for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1048     aMap1.Add( anIds1[ i1 ] );
1049
1050   TColStd_SequenceOfInteger aSeq;
1051
1052   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1053     if ( aMap1.Contains( anIds2[ i2 ] ) )
1054       aSeq.Append( anIds2[ i2 ] );
1055
1056   SMESH::long_array_var aResIds = new SMESH::long_array;
1057   aResIds->length( aSeq.Length() );
1058
1059   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1060     aResIds[ resI ] = aSeq( resI + 1 );
1061
1062   aResGrp->Add( aResIds );
1063
1064   // Clear python lines, created by CreateGroup() and Add()
1065   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1066   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1067   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1068
1069   // Update Python script
1070   TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1071                 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1072
1073   return aResGrp._retn();
1074 }
1075
1076 //=============================================================================
1077 /*!
1078   \brief Intersect list of groups. New group is created. All mesh elements that 
1079   are present in all initial groups simultaneously are added to the new one.
1080   \param theGroups list of groups
1081   \param theName name of group to be created
1082   \return pointer on the group
1083 */
1084 //=============================================================================
1085 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups( 
1086   const SMESH::ListOfGroups& theGroups, const char* theName )
1087 throw (SALOME::SALOME_Exception)
1088 {
1089   if ( !theName )
1090     return SMESH::SMESH_Group::_nil();
1091
1092   try
1093   {
1094     NCollection_DataMap< int, int > anIdToCount;
1095     SMESH::ElementType aType = SMESH::ALL;
1096     for ( int g = 0, n = theGroups.length(); g < n; g++ )
1097     {
1098       SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1099       if ( CORBA::is_nil( aGrp ) )
1100         continue;
1101
1102       // check type
1103       SMESH::ElementType aCurrType = aGrp->GetType();
1104       if ( aType == SMESH::ALL )
1105         aType = aCurrType;
1106       else 
1107       {
1108         if ( aType != aCurrType )
1109           return SMESH::SMESH_Group::_nil();
1110       }
1111
1112       // calculates number of occurance ids in groups
1113       SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1114       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1115       {
1116         int aCurrId = aCurrIds[ i ];
1117         if ( !anIdToCount.IsBound( aCurrId ) )
1118           anIdToCount.Bind( aCurrId, 1 );
1119         else 
1120           anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1121       }
1122     }
1123     
1124     // create map of ids
1125     int nbGrp = theGroups.length();
1126     NCollection_Map< int > anIds;
1127     NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1128     for ( ; anIter.More(); anIter.Next() )
1129     {
1130       int aCurrId = anIter.Key();
1131       int aCurrNb = anIter.Value();
1132       if ( aCurrNb == nbGrp )
1133         anIds.Add( aCurrId );
1134     }
1135
1136     // Create group
1137     SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1138     if ( aResGrp->_is_nil() )
1139       return SMESH::SMESH_Group::_nil();
1140     
1141     // Create array of identifiers
1142     SMESH::long_array_var aResIds = new SMESH::long_array;
1143     aResIds->length( anIds.Extent() );
1144     
1145     NCollection_Map< int >::Iterator aListIter( anIds );
1146     for ( int i = 0; aListIter.More(); aListIter.Next(), i++ )
1147     {
1148       aResIds[ i ] = aListIter.Value();
1149     }
1150     aResGrp->Add( aResIds );
1151
1152     // Clear python lines, created by CreateGroup() and Add()
1153     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1154     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1155     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1156
1157     // Update Python script
1158     
1159     TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1160                   << &theGroups << ", '" << theName << "' )";
1161
1162     return aResGrp._retn();
1163   }
1164   catch( ... )
1165   {
1166     return SMESH::SMESH_Group::_nil();
1167   }
1168 }
1169
1170 //=============================================================================
1171 /*! CutGroups
1172  *  New group is created. All mesh elements that are present in
1173  *  main group but do not present in tool group are added to the new one
1174  */
1175 //=============================================================================
1176 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1177                                                 SMESH::SMESH_GroupBase_ptr theGroup2,
1178                                                 const char* theName )
1179   throw (SALOME::SALOME_Exception)
1180 {
1181   if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1182        theGroup1->GetType() != theGroup2->GetType() )
1183     return SMESH::SMESH_Group::_nil();
1184
1185   // Perform Cutting
1186   SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1187   if ( aResGrp->_is_nil() )
1188     return aResGrp;
1189
1190   SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1191   SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1192
1193   TColStd_MapOfInteger aMap2;
1194
1195   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1196     aMap2.Add( anIds2[ i2 ] );
1197
1198   TColStd_SequenceOfInteger aSeq;
1199   for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1200     if ( !aMap2.Contains( anIds1[ i1 ] ) )
1201       aSeq.Append( anIds1[ i1 ] );
1202
1203   SMESH::long_array_var aResIds = new SMESH::long_array;
1204   aResIds->length( aSeq.Length() );
1205
1206   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1207     aResIds[ resI ] = aSeq( resI + 1 );
1208
1209   aResGrp->Add( aResIds );
1210
1211   // Clear python lines, created by CreateGroup() and Add()
1212   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1213   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1214   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1215
1216   // Update Python script
1217   TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1218                 << theGroup1 << ", " << theGroup2 << ", '"
1219                 << theName << "' )";
1220
1221   return aResGrp._retn();
1222 }
1223
1224 //=============================================================================
1225 /*!
1226   \brief Cut lists of groups. New group is created. All mesh elements that are 
1227   present in main groups but do not present in tool groups are added to the new one
1228   \param theMainGroups list of main groups
1229   \param theToolGroups list of tool groups
1230   \param theName name of group to be created
1231   \return pointer on the group
1232 */
1233 //=============================================================================
1234 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( 
1235   const SMESH::ListOfGroups& theMainGroups, 
1236   const SMESH::ListOfGroups& theToolGroups, 
1237   const char* theName )
1238   throw (SALOME::SALOME_Exception)
1239 {
1240   if ( !theName )
1241     return SMESH::SMESH_Group::_nil();
1242
1243   try
1244   {
1245     NCollection_Map< int > aToolIds;
1246     SMESH::ElementType aType = SMESH::ALL;
1247     int g, n;
1248     // iterate through tool groups
1249     for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1250     {
1251       SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1252       if ( CORBA::is_nil( aGrp ) )
1253         continue;
1254
1255       // check type
1256       SMESH::ElementType aCurrType = aGrp->GetType();
1257       if ( aType == SMESH::ALL )
1258         aType = aCurrType;
1259       else 
1260       {
1261         if ( aType != aCurrType )
1262           return SMESH::SMESH_Group::_nil();
1263       }
1264
1265       // unite tool ids
1266       SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1267       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1268       {
1269         int aCurrId = aCurrIds[ i ];
1270         aToolIds.Add( aCurrId );
1271       }
1272     }
1273
1274     NCollection_Map< int > anIds; // result
1275
1276     // Iterate through main group 
1277     for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1278     {
1279       SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1280       if ( CORBA::is_nil( aGrp ) )
1281         continue;
1282
1283       // check type
1284       SMESH::ElementType aCurrType = aGrp->GetType();
1285       if ( aType == SMESH::ALL )
1286         aType = aCurrType;
1287       else 
1288       {
1289         if ( aType != aCurrType )
1290           return SMESH::SMESH_Group::_nil();
1291       }
1292
1293       // unite tool ids
1294       SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1295       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1296       {
1297         int aCurrId = aCurrIds[ i ];
1298         if ( !aToolIds.Contains( aCurrId ) )
1299           anIds.Add( aCurrId );
1300       }
1301     }
1302
1303     // Create group
1304     SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1305     if ( aResGrp->_is_nil() )
1306       return SMESH::SMESH_Group::_nil();
1307     
1308     // Create array of identifiers
1309     SMESH::long_array_var aResIds = new SMESH::long_array;
1310     aResIds->length( anIds.Extent() );
1311     
1312     NCollection_Map< int >::Iterator anIter( anIds );
1313     for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1314     {
1315       aResIds[ i ] = anIter.Value();
1316     }
1317     aResGrp->Add( aResIds );
1318
1319     // Clear python lines, created by CreateGroup() and Add()
1320     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1321     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1322     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1323
1324     // Update Python script
1325
1326     TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1327                   << &theMainGroups << ", " << &theToolGroups << ", '"
1328                   << theName << "' )";
1329     
1330     return aResGrp._retn();
1331   }
1332   catch( ... )
1333   {
1334     return SMESH::SMESH_Group::_nil();
1335   }
1336 }
1337
1338 //=============================================================================
1339 /*!
1340   \brief Create groups of entities from existing groups of superior dimensions 
1341   System 
1342   1) extract all nodes from each group,
1343   2) combine all elements of specified dimension laying on these nodes.
1344   \param theGroups list of source groups 
1345   \param theElemType dimension of elements 
1346   \param theName name of new group
1347   \return pointer on new group
1348 */
1349 //=============================================================================
1350 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( 
1351   const SMESH::ListOfGroups& theGroups, 
1352   SMESH::ElementType         theElemType, 
1353   const char*                theName )
1354   throw (SALOME::SALOME_Exception)
1355 {
1356   SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1357
1358   if ( !theName || !aMeshDS )
1359     return SMESH::SMESH_Group::_nil();
1360
1361   SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1362
1363   try
1364   {
1365     // Create map of nodes from all groups 
1366
1367     NCollection_Map< int > aNodeMap;
1368     
1369     for ( int g = 0, n = theGroups.length(); g < n; g++ )
1370     {
1371       SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1372       if ( CORBA::is_nil( aGrp ) )
1373         continue;
1374
1375       SMESH::ElementType aType = aGrp->GetType();
1376       if ( aType == SMESH::ALL )
1377         continue;
1378       else if ( aType == SMESH::NODE )
1379       {
1380         SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1381         for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1382         {
1383           int aCurrId = aCurrIds[ i ];
1384           const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1385           if ( aNode )
1386             aNodeMap.Add( aNode->GetID() );
1387         }
1388       }
1389       else 
1390       {
1391         SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1392         for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1393         {
1394           int aCurrId = aCurrIds[ i ];
1395           const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1396           if ( !anElem )
1397             continue;
1398           SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1399           while( aNodeIter->more() )
1400           {
1401             const SMDS_MeshNode* aNode = 
1402               dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1403             if ( aNode )
1404               aNodeMap.Add( aNode->GetID() );
1405           }
1406         }
1407       }
1408     }
1409
1410     // Get result identifiers 
1411
1412     NCollection_Map< int > aResultIds;
1413     if ( theElemType == SMESH::NODE )
1414     {
1415       NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1416       for ( ; aNodeIter.More(); aNodeIter.Next() )
1417         aResultIds.Add( aNodeIter.Value() );
1418     }
1419     else
1420     {
1421       // Create list of elements of given dimension constructed on the nodes
1422       NCollection_Map< int > anElemList;
1423       NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1424       for ( ; aNodeIter.More(); aNodeIter.Next() )
1425       {
1426         const SMDS_MeshElement* aNode = 
1427           dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( aNodeIter.Value() ) );
1428         if ( !aNode )
1429           continue;
1430
1431          SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1432         while( anElemIter->more() )
1433         {
1434           const SMDS_MeshElement* anElem = 
1435             dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1436           if ( anElem && anElem->GetType() == anElemType )
1437             anElemList.Add( anElem->GetID() );
1438         }
1439       }
1440
1441       // check whether all nodes of elements are present in nodes map
1442       NCollection_Map< int >::Iterator anIter( anElemList );
1443       for ( ; anIter.More(); anIter.Next() )
1444       {
1445         const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() );
1446         if ( !anElem )
1447           continue;
1448
1449         bool isOk = true;
1450         SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1451         while( aNodeIter->more() )
1452         {
1453           const SMDS_MeshNode* aNode = 
1454             dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1455           if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) )
1456           {
1457             isOk = false;
1458             break;
1459           }
1460         } 
1461         if ( isOk )
1462           aResultIds.Add( anElem->GetID() );
1463       }
1464     }
1465
1466     // Create group
1467
1468     SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1469     if ( aResGrp->_is_nil() )
1470       return SMESH::SMESH_Group::_nil();
1471     
1472     // Create array of identifiers
1473     SMESH::long_array_var aResIds = new SMESH::long_array;
1474     aResIds->length( aResultIds.Extent() );
1475     
1476     NCollection_Map< int >::Iterator aResIter( aResultIds );
1477     for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1478       aResIds[ i ] = aResIter.Value();
1479     aResGrp->Add( aResIds );
1480
1481     // Remove strings corresponding to group creation
1482     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1483     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1484     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1485
1486     // Update Python script
1487     
1488     TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1489                   << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1490
1491     return aResGrp._retn();
1492   }
1493   catch( ... )
1494   {
1495     return SMESH::SMESH_Group::_nil();
1496   }
1497 }
1498
1499 //================================================================================
1500 /*!
1501  * \brief Return group items of a group present in a study
1502  */
1503 //================================================================================
1504
1505 static GEOM::GEOM_Object_ptr getGroupItemsFromStudy(CORBA::Object_ptr    theMesh,
1506                                                     SMESH_Gen_i*         theGen,
1507                                                     list<TopoDS_Shape> & theItems)
1508 {
1509   GEOM::GEOM_Object_var groupObj;
1510   SALOMEDS::Study_var  study = theGen->GetCurrentStudy();
1511   GEOM::GEOM_Gen_var geomGen = theGen->GetGeomEngine();
1512   if ( study->_is_nil() || geomGen->_is_nil() )
1513     return groupObj._retn();
1514   
1515   GEOM::GEOM_IGroupOperations_var groupOp =
1516     geomGen->GetIGroupOperations( theGen->GetCurrentStudyID() );
1517   GEOM::GEOM_IShapesOperations_var shapeOp =
1518     geomGen->GetIShapesOperations( theGen->GetCurrentStudyID() );
1519
1520   SALOMEDS::SObject_var meshOS = theGen->ObjectToSObject(study, theMesh);
1521   if ( meshOS->_is_nil() || groupOp->_is_nil() || shapeOp->_is_nil() )
1522     return groupObj._retn();
1523   SALOMEDS::SObject_var fatherSO = meshOS->GetFather();
1524   if ( fatherSO->_is_nil() || fatherSO->Tag() != theGen->GetSubMeshOnCompoundTag() )
1525     return groupObj._retn(); // keep only submeshes on groups
1526
1527   SALOMEDS::ChildIterator_var anIter = study->NewChildIterator(meshOS);
1528   if ( anIter->_is_nil() ) return groupObj._retn();
1529   for ( ; anIter->More(); anIter->Next())
1530   {
1531     SALOMEDS::SObject_var aSObject = anIter->Value();
1532     SALOMEDS::SObject_var aRefSO;
1533     if ( !aSObject->_is_nil() && aSObject->ReferencedObject(aRefSO) )
1534     {
1535       groupObj = GEOM::GEOM_Object::_narrow(aRefSO->GetObject());
1536       if ( groupObj->_is_nil() ) break;
1537       GEOM::ListOfLong_var  ids = groupOp->GetObjects( groupObj );
1538       GEOM::GEOM_Object_var mainShape = groupObj->GetMainShape();
1539       for ( int i = 0; i < ids->length(); ++i ) {
1540         GEOM::GEOM_Object_var subShape = shapeOp->GetSubShape( mainShape, ids[i] );
1541         TopoDS_Shape S = theGen->GeomObjectToShape( subShape );
1542         if ( !S.IsNull() )
1543           theItems.push_back( S );
1544       }
1545       break;
1546     }
1547   }
1548   return groupObj._retn();
1549 }
1550
1551 //=============================================================================
1552 /*!
1553  * \brief Update hypotheses assigned to geom groups if the latter change
1554  * 
1555  * NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
1556  */
1557 //=============================================================================
1558
1559 void SMESH_Mesh_i::CheckGeomGroupModif()
1560 {
1561   if ( !_impl->HasShapeToMesh() ) return;
1562
1563   SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1564   if ( study->_is_nil() ) return;
1565
1566   // check if items of groups changed
1567   map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
1568   for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
1569   {
1570     const TopoDS_Shape & oldGroupShape = i_sm->second->GetSubShape();
1571     SMESHDS_SubMesh * oldDS = i_sm->second->GetSubMeshDS();
1572     if ( !oldDS /*|| !oldDS->IsComplexSubmesh()*/ )
1573       continue;
1574     int oldID = i_sm->first;
1575     map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldID );
1576     if ( i_smIor == _mapSubMeshIor.end() )
1577       continue;
1578     list< TopoDS_Shape> newItems;
1579     GEOM::GEOM_Object_var groupObj = getGroupItemsFromStudy ( i_smIor->second, _gen_i, newItems );
1580     if ( groupObj->_is_nil() )
1581       continue;
1582
1583     int nbOldItems = oldDS->IsComplexSubmesh() ? oldDS->NbSubMeshes() : 1;
1584     int nbNewItems = newItems.size();
1585     bool groupChanged = ( nbOldItems != nbNewItems);
1586     if ( !groupChanged ) {
1587       if ( !oldDS->IsComplexSubmesh() ) { // old group has one item
1588         groupChanged = ( oldGroupShape != newItems.front() );
1589       }
1590       else {
1591         list<TopoDS_Shape>::iterator item = newItems.begin();
1592         for ( ; item != newItems.end() && !groupChanged; ++item )
1593         {
1594           SMESHDS_SubMesh * itemDS = _impl->GetMeshDS()->MeshElements( *item );
1595           groupChanged = ( !itemDS || !oldDS->ContainsSubMesh( itemDS ));
1596         }
1597       }
1598     }
1599     // update hypotheses and submeshes if necessary
1600     if ( groupChanged )
1601     {
1602       // get a new group shape
1603       GEOM_Client* geomClient = _gen_i->GetShapeReader();
1604       if ( !geomClient ) continue;
1605       TCollection_AsciiString groupIOR = _gen_i->GetGeomEngine()->GetStringFromIOR( groupObj );
1606       geomClient->RemoveShapeFromBuffer( groupIOR );
1607       TopoDS_Shape newGroupShape = _gen_i->GeomObjectToShape( groupObj );
1608       // update hypotheses
1609       list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldGroupShape);
1610       list <const SMESHDS_Hypothesis * >::iterator hypIt;
1611       for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1612       {
1613         _impl->RemoveHypothesis( oldGroupShape, (*hypIt)->GetID());
1614         _impl->AddHypothesis   ( newGroupShape, (*hypIt)->GetID());
1615       }
1616       // care of submeshes
1617       SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newGroupShape );
1618       int newID = newSubmesh->GetId();
1619       if ( newID != oldID ) {
1620         _mapSubMesh   [ newID ] = newSubmesh;
1621         _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1622         _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1623         _mapSubMesh.erase   (oldID);
1624         _mapSubMesh_i.erase (oldID);
1625         _mapSubMeshIor.erase(oldID);
1626         _mapSubMesh_i [ newID ]->changeLocalId( newID );
1627       }
1628     }
1629   }
1630 }
1631
1632 //=============================================================================
1633 /*!
1634  * \brief Create standalone group instead if group on geometry
1635  * 
1636  */
1637 //=============================================================================
1638
1639 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
1640 {
1641   SMESH::SMESH_Group_var aGroup;
1642   if ( theGroup->_is_nil() )
1643     return aGroup._retn();
1644
1645   Unexpect aCatch(SALOME_SalomeException);
1646
1647   SMESH_GroupBase_i* aGroupToRem =
1648     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1649   if ( !aGroupToRem )
1650     return aGroup._retn();
1651
1652   int anId = aGroupToRem->GetLocalID();
1653   if ( !_impl->ConvertToStandalone( anId ) )
1654     return aGroup._retn();
1655
1656     SMESH_GroupBase_i* aGroupImpl;
1657       aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1658
1659
1660   // remove old instance of group from own map
1661   _mapGroups.erase( anId );
1662
1663   SALOMEDS::StudyBuilder_var builder;
1664   SALOMEDS::SObject_var aGroupSO;
1665   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1666   if ( !aStudy->_is_nil() )  {
1667     builder = aStudy->NewBuilder();
1668     aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1669     if ( !aGroupSO->_is_nil() ) {
1670
1671     // remove reference to geometry
1672     SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1673     for ( ; chItr->More(); chItr->Next() )
1674       // Remove group's child SObject
1675       builder->RemoveObject( chItr->Value() );
1676
1677       // Update Python script
1678       TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1679                     << aGroupSO << " )";
1680     }
1681   }
1682
1683   // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1684   SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1685   aGroupImpl->Register();
1686   // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1687
1688   // remember new group in own map
1689   aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1690   _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1691
1692   // register CORBA object for persistence
1693   //int nextId = _gen_i->RegisterObject( aGroup );
1694   //if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
1695   builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1696
1697   return aGroup._retn();
1698 }
1699
1700 //=============================================================================
1701 /*!
1702  *
1703  */
1704 //=============================================================================
1705
1706 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1707 {
1708   if(MYDEBUG) MESSAGE( "createSubMesh" );
1709   TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1710
1711   ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1712   int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1713   SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1714   SMESH::SMESH_subMesh_var subMesh
1715     = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1716
1717   _mapSubMesh[subMeshId] = mySubMesh;
1718   _mapSubMesh_i[subMeshId] = subMeshServant;
1719   _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1720
1721   // register CORBA object for persistence
1722   int nextId = _gen_i->RegisterObject( subMesh );
1723   if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1724
1725   return subMesh._retn();
1726 }
1727
1728 //=======================================================================
1729 //function : getSubMesh
1730 //purpose  :
1731 //=======================================================================
1732
1733 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
1734 {
1735   map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
1736   if ( it == _mapSubMeshIor.end() )
1737     return SMESH::SMESH_subMesh::_nil();
1738
1739   return SMESH::SMESH_subMesh::_duplicate( (*it).second );
1740 }
1741
1742
1743 //=============================================================================
1744 /*!
1745  *
1746  */
1747 //=============================================================================
1748
1749 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
1750                                   GEOM::GEOM_Object_ptr    theSubShapeObject )
1751 {
1752   MESSAGE("SMESH_Mesh_i::removeSubMesh()");
1753   if ( theSubMesh->_is_nil() || theSubShapeObject->_is_nil() )
1754     return;
1755
1756   try {
1757     SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
1758     for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
1759       removeHypothesis( theSubShapeObject, aHypList[i] );
1760     }
1761   }
1762   catch( const SALOME::SALOME_Exception& ) {
1763     INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
1764   }
1765
1766   int subMeshId = theSubMesh->GetId();
1767
1768   _mapSubMesh.erase(subMeshId);
1769   _mapSubMesh_i.erase(subMeshId);
1770   _mapSubMeshIor.erase(subMeshId);
1771   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
1772 }
1773
1774 //=============================================================================
1775 /*!
1776  *
1777  */
1778 //=============================================================================
1779
1780 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
1781                                                       const char*         theName,
1782                                                       const TopoDS_Shape& theShape )
1783 {
1784   int anId;
1785   SMESH::SMESH_GroupBase_var aGroup;
1786   if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
1787     SMESH_GroupBase_i* aGroupImpl;
1788     if ( !theShape.IsNull() )
1789       aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
1790     else
1791       aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1792
1793     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1794     SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1795     aGroupImpl->Register();
1796     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1797
1798     aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
1799     _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1800
1801     // register CORBA object for persistence
1802     int nextId = _gen_i->RegisterObject( aGroup );
1803     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
1804   }
1805   return aGroup._retn();
1806 }
1807
1808 //=============================================================================
1809 /*!
1810  * SMESH_Mesh_i::removeGroup
1811  *
1812  * Should be called by ~SMESH_Group_i()
1813  */
1814 //=============================================================================
1815
1816 void SMESH_Mesh_i::removeGroup( const int theId )
1817 {
1818   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
1819   if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
1820     _mapGroups.erase( theId );
1821     _impl->RemoveGroup( theId );
1822   }
1823 }
1824
1825
1826 //=============================================================================
1827 /*!
1828  *
1829  */
1830 //=============================================================================
1831
1832 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
1833 throw(SALOME::SALOME_Exception)
1834 {
1835   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
1836
1837   SMESH::log_array_var aLog;
1838   try{
1839     list < SMESHDS_Command * >logDS = _impl->GetLog();
1840     aLog = new SMESH::log_array;
1841     int indexLog = 0;
1842     int lg = logDS.size();
1843     SCRUTE(lg);
1844     aLog->length(lg);
1845     list < SMESHDS_Command * >::iterator its = logDS.begin();
1846     while(its != logDS.end()){
1847       SMESHDS_Command *com = *its;
1848       int comType = com->GetType();
1849       //SCRUTE(comType);
1850       int lgcom = com->GetNumber();
1851       //SCRUTE(lgcom);
1852       const list < int >&intList = com->GetIndexes();
1853       int inum = intList.size();
1854       //SCRUTE(inum);
1855       list < int >::const_iterator ii = intList.begin();
1856       const list < double >&coordList = com->GetCoords();
1857       int rnum = coordList.size();
1858       //SCRUTE(rnum);
1859       list < double >::const_iterator ir = coordList.begin();
1860       aLog[indexLog].commandType = comType;
1861       aLog[indexLog].number = lgcom;
1862       aLog[indexLog].coords.length(rnum);
1863       aLog[indexLog].indexes.length(inum);
1864       for(int i = 0; i < rnum; i++){
1865         aLog[indexLog].coords[i] = *ir;
1866         //MESSAGE(" "<<i<<" "<<ir.Value());
1867         ir++;
1868       }
1869       for(int i = 0; i < inum; i++){
1870         aLog[indexLog].indexes[i] = *ii;
1871         //MESSAGE(" "<<i<<" "<<ii.Value());
1872         ii++;
1873       }
1874       indexLog++;
1875       its++;
1876     }
1877     if(clearAfterGet)
1878       _impl->ClearLog();
1879   }
1880   catch(SALOME_Exception & S_ex){
1881     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1882   }
1883   return aLog._retn();
1884 }
1885
1886
1887 //=============================================================================
1888 /*!
1889  *
1890  */
1891 //=============================================================================
1892
1893 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
1894 {
1895   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
1896   // ****
1897 }
1898
1899 //=============================================================================
1900 /*!
1901  *
1902  */
1903 //=============================================================================
1904
1905 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
1906 {
1907   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
1908   return _id;
1909 }
1910
1911 //=============================================================================
1912 /*!
1913  *
1914  */
1915 //=============================================================================
1916
1917 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
1918 {
1919   return _studyId;
1920 }
1921
1922 //=============================================================================
1923 /*!
1924  *
1925  */
1926 //=============================================================================
1927
1928 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
1929 {
1930   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
1931   _impl = impl;
1932 }
1933
1934 //=============================================================================
1935 /*!
1936  *
1937  */
1938 //=============================================================================
1939
1940 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
1941 {
1942   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
1943   return *_impl;
1944 }
1945
1946 //=============================================================================
1947 /*!
1948  * Return mesh editor
1949  */
1950 //=============================================================================
1951
1952 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
1953 {
1954   // Create MeshEditor
1955   SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
1956   SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
1957
1958   // Update Python script
1959   TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
1960
1961   return aMesh._retn();
1962 }
1963
1964 //=============================================================================
1965 /*!
1966  * Return mesh edition previewer
1967  */
1968 //=============================================================================
1969
1970 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
1971 {
1972   SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
1973   SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
1974   return aMesh._retn();
1975 }
1976
1977 //=============================================================================
1978 /*!
1979  *
1980  */
1981 //=============================================================================
1982 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
1983 {
1984   Unexpect aCatch(SALOME_SalomeException);
1985   _impl->SetAutoColor(theAutoColor);
1986 }
1987
1988 //=============================================================================
1989 /*!
1990  *
1991  */
1992 //=============================================================================
1993 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
1994 {
1995   Unexpect aCatch(SALOME_SalomeException);
1996   return _impl->GetAutoColor();
1997 }
1998
1999
2000 //=============================================================================
2001 /*!
2002  *  Export in different formats
2003  */
2004 //=============================================================================
2005
2006 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2007 {
2008   return _impl->HasDuplicatedGroupNamesMED();
2009 }
2010
2011 void SMESH_Mesh_i::PrepareForWriting (const char* file)
2012 {
2013   TCollection_AsciiString aFullName ((char*)file);
2014   OSD_Path aPath (aFullName);
2015   OSD_File aFile (aPath);
2016   if (aFile.Exists()) {
2017     // existing filesystem node
2018     if (aFile.KindOfFile() == OSD_FILE) {
2019       if (aFile.IsWriteable()) {
2020         aFile.Reset();
2021         aFile.Remove();
2022         if (aFile.Failed()) {
2023           TCollection_AsciiString msg ("File ");
2024           msg += aFullName + " cannot be replaced.";
2025           THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2026         }
2027       } else {
2028         TCollection_AsciiString msg ("File ");
2029         msg += aFullName + " cannot be overwritten.";
2030         THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2031       }
2032     } else {
2033       TCollection_AsciiString msg ("Location ");
2034       msg += aFullName + " is not a file.";
2035       THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2036     }
2037   } else {
2038     // nonexisting file; check if it can be created
2039     aFile.Reset();
2040     aFile.Build(OSD_WriteOnly, OSD_Protection());
2041     if (aFile.Failed()) {
2042       TCollection_AsciiString msg ("You cannot create the file ");
2043       msg += aFullName + ". Check the directory existance and access rights.";
2044       THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2045     } else {
2046       aFile.Close();
2047       aFile.Remove();
2048     }
2049   }
2050 }
2051
2052 void SMESH_Mesh_i::ExportToMED (const char* file,
2053                                 CORBA::Boolean auto_groups,
2054                                 SMESH::MED_VERSION theVersion)
2055   throw(SALOME::SALOME_Exception)
2056 {
2057   Unexpect aCatch(SALOME_SalomeException);
2058
2059   // Perform Export
2060   PrepareForWriting(file);
2061   const char* aMeshName = "Mesh";
2062   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2063   if ( !aStudy->_is_nil() ) {
2064     SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2065     if ( !aMeshSO->_is_nil() ) {
2066       aMeshName = aMeshSO->GetName();
2067       // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2068       if ( !aStudy->GetProperties()->IsLocked() )
2069         {
2070         SALOMEDS::GenericAttribute_var anAttr;
2071         SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2072         SALOMEDS::AttributeExternalFileDef_var aFileName;
2073         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2074         aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2075         ASSERT(!aFileName->_is_nil());
2076         aFileName->SetValue(file);
2077         SALOMEDS::AttributeFileType_var aFileType;
2078         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2079         aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2080         ASSERT(!aFileType->_is_nil());
2081         aFileType->SetValue("FICHIERMED");
2082         }
2083     }
2084   }
2085   // Update Python script
2086   // set name of mesh before export
2087   TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2088   
2089   // check names of groups
2090   checkGroupNames();
2091
2092   TPythonDump() << _this() << ".ExportToMED( '"
2093                 << file << "', " << auto_groups << ", " << theVersion << " )";
2094
2095   _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2096 }
2097
2098 void SMESH_Mesh_i::ExportMED (const char* file,
2099                               CORBA::Boolean auto_groups)
2100   throw(SALOME::SALOME_Exception)
2101 {
2102   ExportToMED(file,auto_groups,SMESH::MED_V2_1);
2103 }
2104
2105 void SMESH_Mesh_i::ExportDAT (const char *file)
2106   throw(SALOME::SALOME_Exception)
2107 {
2108   Unexpect aCatch(SALOME_SalomeException);
2109
2110   // Update Python script
2111   // check names of groups
2112   checkGroupNames();
2113   TPythonDump() << _this() << ".ExportDAT( '" << file << "' )";
2114
2115   // Perform Export
2116   PrepareForWriting(file);
2117   _impl->ExportDAT(file);
2118 }
2119
2120 void SMESH_Mesh_i::ExportUNV (const char *file)
2121   throw(SALOME::SALOME_Exception)
2122 {
2123   Unexpect aCatch(SALOME_SalomeException);
2124
2125   // Update Python script
2126   // check names of groups
2127   checkGroupNames();
2128   TPythonDump() << _this() << ".ExportUNV( '" << file << "' )";
2129
2130   // Perform Export
2131   PrepareForWriting(file);
2132   _impl->ExportUNV(file);
2133 }
2134
2135 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2136   throw(SALOME::SALOME_Exception)
2137 {
2138   Unexpect aCatch(SALOME_SalomeException);
2139
2140   // Update Python script
2141   // check names of groups
2142   checkGroupNames();
2143   TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )";
2144
2145   // Perform Export
2146   PrepareForWriting(file);
2147   _impl->ExportSTL(file, isascii);
2148 }
2149
2150 //=============================================================================
2151 /*!
2152  *
2153  */
2154 //=============================================================================
2155
2156 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2157 {
2158   Unexpect aCatch(SALOME_SalomeException);
2159   SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2160   SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2161   return aMesh._retn();
2162 }
2163
2164 //=============================================================================
2165 /*!
2166  *
2167  */
2168 //=============================================================================
2169 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2170 {
2171   Unexpect aCatch(SALOME_SalomeException);
2172   return _impl->NbNodes();
2173 }
2174
2175 //=============================================================================
2176 /*!
2177  *
2178  */
2179 //=============================================================================
2180 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2181 {
2182   Unexpect aCatch(SALOME_SalomeException);
2183   return NbEdges() + NbFaces() + NbVolumes();
2184 }
2185
2186 //=============================================================================
2187 /*!
2188  *
2189  */
2190 //=============================================================================
2191 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2192 {
2193   Unexpect aCatch(SALOME_SalomeException);
2194   return _impl->NbEdges();
2195 }
2196
2197 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2198   throw(SALOME::SALOME_Exception)
2199 {
2200   Unexpect aCatch(SALOME_SalomeException);
2201   return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2202 }
2203
2204 //=============================================================================
2205 /*!
2206  *
2207  */
2208 //=============================================================================
2209 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2210 {
2211   Unexpect aCatch(SALOME_SalomeException);
2212   return _impl->NbFaces();
2213 }
2214
2215 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2216 {
2217   Unexpect aCatch(SALOME_SalomeException);
2218   return _impl->NbTriangles();
2219 }
2220
2221 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2222 {
2223   Unexpect aCatch(SALOME_SalomeException);
2224   return _impl->NbQuadrangles();
2225 }
2226
2227 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2228 {
2229   Unexpect aCatch(SALOME_SalomeException);
2230   return _impl->NbPolygons();
2231 }
2232
2233 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2234   throw(SALOME::SALOME_Exception)
2235 {
2236   Unexpect aCatch(SALOME_SalomeException);
2237   return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2238 }
2239
2240 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2241   throw(SALOME::SALOME_Exception)
2242 {
2243   Unexpect aCatch(SALOME_SalomeException);
2244   return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2245 }
2246
2247 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2248   throw(SALOME::SALOME_Exception)
2249 {
2250   Unexpect aCatch(SALOME_SalomeException);
2251   return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2252 }
2253
2254 //=============================================================================
2255 /*!
2256  *
2257  */
2258 //=============================================================================
2259 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2260 {
2261   Unexpect aCatch(SALOME_SalomeException);
2262   return _impl->NbVolumes();
2263 }
2264
2265 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2266 {
2267   Unexpect aCatch(SALOME_SalomeException);
2268   return _impl->NbTetras();
2269 }
2270
2271 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2272 {
2273   Unexpect aCatch(SALOME_SalomeException);
2274   return _impl->NbHexas();
2275 }
2276
2277 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2278 {
2279   Unexpect aCatch(SALOME_SalomeException);
2280   return _impl->NbPyramids();
2281 }
2282
2283 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2284 {
2285   Unexpect aCatch(SALOME_SalomeException);
2286   return _impl->NbPrisms();
2287 }
2288
2289 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2290 {
2291   Unexpect aCatch(SALOME_SalomeException);
2292   return _impl->NbPolyhedrons();
2293 }
2294
2295 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2296   throw(SALOME::SALOME_Exception)
2297 {
2298   Unexpect aCatch(SALOME_SalomeException);
2299   return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2300 }
2301
2302 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2303   throw(SALOME::SALOME_Exception)
2304 {
2305   Unexpect aCatch(SALOME_SalomeException);
2306   return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2307 }
2308
2309 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2310   throw(SALOME::SALOME_Exception)
2311 {
2312   Unexpect aCatch(SALOME_SalomeException);
2313   return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2314 }
2315
2316 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2317   throw(SALOME::SALOME_Exception)
2318 {
2319   Unexpect aCatch(SALOME_SalomeException);
2320   return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2321 }
2322
2323 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2324   throw(SALOME::SALOME_Exception)
2325 {
2326   Unexpect aCatch(SALOME_SalomeException);
2327   return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2328 }
2329
2330 //=============================================================================
2331 /*!
2332  *
2333  */
2334 //=============================================================================
2335 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2336 {
2337   Unexpect aCatch(SALOME_SalomeException);
2338   return _impl->NbSubMesh();
2339 }
2340
2341 //=============================================================================
2342 /*!
2343  *
2344  */
2345 //=============================================================================
2346 char* SMESH_Mesh_i::Dump()
2347 {
2348   std::ostringstream os;
2349   _impl->Dump( os );
2350   return CORBA::string_dup( os.str().c_str() );
2351 }
2352
2353 //=============================================================================
2354 /*!
2355  *
2356  */
2357 //=============================================================================
2358 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2359 {
2360 //   SMESH::long_array_var aResult = new SMESH::long_array();
2361 //   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2362 //   int aMinId = aSMESHDS_Mesh->MinElementID();
2363 //   int aMaxId =  aSMESHDS_Mesh->MaxElementID();
2364
2365 //   aResult->length(aMaxId - aMinId + 1);
2366
2367 //   for (int i = 0, id = aMinId; id <= aMaxId; id++  )
2368 //     aResult[i++] = id;
2369
2370 //   return aResult._retn();
2371   // PAL12398
2372   return GetElementsId();
2373 }
2374
2375 //=============================================================================
2376 /*!
2377  *
2378  */
2379 //=============================================================================
2380
2381 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2382      throw (SALOME::SALOME_Exception)
2383 {
2384   Unexpect aCatch(SALOME_SalomeException);
2385   MESSAGE("SMESH_Mesh_i::GetElementsId");
2386   SMESH::long_array_var aResult = new SMESH::long_array();
2387   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2388
2389   if ( aSMESHDS_Mesh == NULL )
2390     return aResult._retn();
2391
2392   long nbElements = NbElements();
2393   aResult->length( nbElements );
2394   SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2395   for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2396     aResult[i] = anIt->next()->GetID();
2397
2398   return aResult._retn();
2399 }
2400
2401
2402 //=============================================================================
2403 /*!
2404  *
2405  */
2406 //=============================================================================
2407
2408 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2409     throw (SALOME::SALOME_Exception)
2410 {
2411   Unexpect aCatch(SALOME_SalomeException);
2412   MESSAGE("SMESH_subMesh_i::GetElementsByType");
2413   SMESH::long_array_var aResult = new SMESH::long_array();
2414   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2415
2416   if ( aSMESHDS_Mesh == NULL )
2417     return aResult._retn();
2418
2419   long nbElements = NbElements();
2420
2421   // No sense in returning ids of elements along with ids of nodes:
2422   // when theElemType == SMESH::ALL, return node ids only if
2423   // there are no elements
2424   if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2425     return GetNodesId();
2426
2427   aResult->length( nbElements );
2428
2429   int i = 0;
2430
2431   SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2432   while ( i < nbElements && anIt->more() ) {
2433     const SMDS_MeshElement* anElem = anIt->next();
2434     if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2435       aResult[i++] = anElem->GetID();
2436   }
2437
2438   aResult->length( i );
2439
2440   return aResult._retn();
2441 }
2442
2443 //=============================================================================
2444 /*!
2445  *
2446  */
2447 //=============================================================================
2448
2449 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2450   throw (SALOME::SALOME_Exception)
2451 {
2452   Unexpect aCatch(SALOME_SalomeException);
2453   MESSAGE("SMESH_subMesh_i::GetNodesId");
2454   SMESH::long_array_var aResult = new SMESH::long_array();
2455   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2456
2457   if ( aSMESHDS_Mesh == NULL )
2458     return aResult._retn();
2459
2460   long nbNodes = NbNodes();
2461   aResult->length( nbNodes );
2462   SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
2463   for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2464     aResult[i] = anIt->next()->GetID();
2465
2466   return aResult._retn();
2467 }
2468
2469 //=============================================================================
2470 /*!
2471  *
2472  */
2473 //=============================================================================
2474
2475 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2476   throw (SALOME::SALOME_Exception)
2477 {
2478   return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2479 }
2480
2481
2482 //=============================================================================
2483 /*!
2484  * Returns ID of elements for given submesh
2485  */
2486 //=============================================================================
2487 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2488      throw (SALOME::SALOME_Exception)
2489 {
2490   SMESH::long_array_var aResult = new SMESH::long_array();
2491
2492   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2493   if(!SM) return aResult._retn();
2494
2495   SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2496   if(!SDSM) return aResult._retn();
2497
2498   aResult->length(SDSM->NbElements());
2499
2500   SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2501   int i = 0;
2502   while ( eIt->more() ) {
2503     aResult[i++] = eIt->next()->GetID();
2504   }
2505
2506   return aResult._retn();
2507 }
2508
2509
2510 //=============================================================================
2511 /*!
2512  * Returns ID of nodes for given submesh
2513  * If param all==true - returns all nodes, else -
2514  * returns only nodes on shapes.
2515  */
2516 //=============================================================================
2517 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2518      throw (SALOME::SALOME_Exception)
2519 {
2520   SMESH::long_array_var aResult = new SMESH::long_array();
2521
2522   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2523   if(!SM) return aResult._retn();
2524
2525   SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2526   if(!SDSM) return aResult._retn();
2527
2528   set<int> theElems;
2529   if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2530     SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2531     while ( nIt->more() ) {
2532       const SMDS_MeshNode* elem = nIt->next();
2533       theElems.insert( elem->GetID() );
2534     }
2535   }
2536   else { // all nodes of submesh elements
2537     SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2538     while ( eIt->more() ) {
2539       const SMDS_MeshElement* anElem = eIt->next();
2540       SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2541       while ( nIt->more() ) {
2542         const SMDS_MeshElement* elem = nIt->next();
2543         theElems.insert( elem->GetID() );
2544       }
2545     }
2546   }
2547
2548   aResult->length(theElems.size());
2549   set<int>::iterator itElem;
2550   int i = 0;
2551   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2552     aResult[i++] = *itElem;
2553
2554   return aResult._retn();
2555 }
2556   
2557
2558 //=============================================================================
2559 /*!
2560  * Returns type of elements for given submesh
2561  */
2562 //=============================================================================
2563 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2564      throw (SALOME::SALOME_Exception)
2565 {
2566   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2567   if(!SM) return SMESH::ALL;
2568
2569   SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2570   if(!SDSM) return SMESH::ALL;
2571
2572   if(SDSM->NbElements()==0)
2573     return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2574
2575   SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2576   const SMDS_MeshElement* anElem = eIt->next();
2577   return ( SMESH::ElementType ) anElem->GetType();
2578 }
2579   
2580
2581 //=============================================================================
2582 /*!
2583  *
2584  */
2585 //=============================================================================
2586
2587 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2588 {
2589   CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2590   if ( MYDEBUG )
2591     MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2592   return pointeur;
2593 }
2594
2595
2596 //=============================================================================
2597 /*!
2598  * Get XYZ coordinates of node as list of double
2599  * If there is not node for given ID - returns empty list
2600  */
2601 //=============================================================================
2602
2603 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2604 {
2605   SMESH::double_array_var aResult = new SMESH::double_array();
2606   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2607   if ( aSMESHDS_Mesh == NULL )
2608     return aResult._retn();
2609
2610   // find node
2611   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2612   if(!aNode)
2613     return aResult._retn();
2614
2615   // add coordinates
2616   aResult->length(3);
2617   aResult[0] = aNode->X();
2618   aResult[1] = aNode->Y();
2619   aResult[2] = aNode->Z();
2620   return aResult._retn();
2621 }
2622
2623
2624 //=============================================================================
2625 /*!
2626  * For given node returns list of IDs of inverse elements
2627  * If there is not node for given ID - returns empty list
2628  */
2629 //=============================================================================
2630
2631 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2632 {
2633   SMESH::long_array_var aResult = new SMESH::long_array();
2634   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2635   if ( aSMESHDS_Mesh == NULL )
2636     return aResult._retn();
2637
2638   // find node
2639   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2640   if(!aNode)
2641     return aResult._retn();
2642
2643   // find inverse elements
2644   SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
2645   TColStd_SequenceOfInteger IDs;
2646   while(eIt->more()) {
2647     const SMDS_MeshElement* elem = eIt->next();
2648     IDs.Append(elem->GetID());
2649   }
2650   if(IDs.Length()>0) {
2651     aResult->length(IDs.Length());
2652     int i = 1;
2653     for(; i<=IDs.Length(); i++) {
2654       aResult[i-1] = IDs.Value(i);
2655     }
2656   }
2657   return aResult._retn();
2658 }
2659
2660 //=============================================================================
2661 /*!
2662  * \brief Return position of a node on shape
2663  */
2664 //=============================================================================
2665
2666 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
2667 {
2668   SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
2669   aNodePosition->shapeID = 0;
2670   aNodePosition->shapeType = GEOM::SHAPE;
2671
2672   SMESHDS_Mesh* mesh = _impl->GetMeshDS();
2673   if ( !mesh ) return aNodePosition;
2674
2675   if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
2676   {
2677     if ( SMDS_PositionPtr pos = aNode->GetPosition() )
2678     {
2679       aNodePosition->shapeID = pos->GetShapeId();
2680       switch ( pos->GetTypeOfPosition() ) {
2681       case SMDS_TOP_EDGE:
2682         aNodePosition->shapeType = GEOM::EDGE;
2683         aNodePosition->params.length(1);
2684         aNodePosition->params[0] =
2685           static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
2686         break;
2687       case SMDS_TOP_FACE:
2688         aNodePosition->shapeType = GEOM::FACE;
2689         aNodePosition->params.length(2);
2690         aNodePosition->params[0] =
2691           static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
2692         aNodePosition->params[1] =
2693           static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
2694         break;
2695       case SMDS_TOP_VERTEX:
2696         aNodePosition->shapeType = GEOM::VERTEX;
2697         break;
2698       case SMDS_TOP_3DSPACE:
2699         if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
2700           aNodePosition->shapeType = GEOM::SOLID;
2701         else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
2702           aNodePosition->shapeType = GEOM::SHELL;
2703         break;
2704       default:;
2705       }
2706     }
2707   }
2708   return aNodePosition;
2709 }
2710
2711 //=============================================================================
2712 /*!
2713  * If given element is node returns IDs of shape from position
2714  * If there is not node for given ID - returns -1
2715  */
2716 //=============================================================================
2717
2718 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
2719 {
2720   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2721   if ( aSMESHDS_Mesh == NULL )
2722     return -1;
2723
2724   // try to find node
2725   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2726   if(aNode) {
2727     SMDS_PositionPtr pos = aNode->GetPosition();
2728     if(!pos)
2729       return -1;
2730     else
2731       return pos->GetShapeId();
2732   }
2733
2734   return -1;
2735 }
2736
2737
2738 //=============================================================================
2739 /*!
2740  * For given element returns ID of result shape after 
2741  * ::FindShape() from SMESH_MeshEditor
2742  * If there is not element for given ID - returns -1
2743  */
2744 //=============================================================================
2745
2746 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
2747 {
2748   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2749   if ( aSMESHDS_Mesh == NULL )
2750     return -1;
2751
2752   // try to find element
2753   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2754   if(!elem)
2755     return -1;
2756
2757   //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
2758   ::SMESH_MeshEditor aMeshEditor(_impl);
2759   int index = aMeshEditor.FindShape( elem );
2760   if(index>0)
2761     return index;
2762
2763   return -1;
2764 }
2765
2766
2767 //=============================================================================
2768 /*!
2769  * Returns number of nodes for given element
2770  * If there is not element for given ID - returns -1
2771  */
2772 //=============================================================================
2773
2774 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
2775 {
2776   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2777   if ( aSMESHDS_Mesh == NULL ) return -1;
2778   // try to find element
2779   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2780   if(!elem) return -1;
2781   return elem->NbNodes();
2782 }
2783
2784
2785 //=============================================================================
2786 /*!
2787  * Returns ID of node by given index for given element
2788  * If there is not element for given ID - returns -1
2789  * If there is not node for given index - returns -2
2790  */
2791 //=============================================================================
2792
2793 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
2794 {
2795   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2796   if ( aSMESHDS_Mesh == NULL ) return -1;
2797   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2798   if(!elem) return -1;
2799   if( index>=elem->NbNodes() || index<0 ) return -1;
2800   return elem->GetNode(index)->GetID();
2801 }
2802
2803 //=============================================================================
2804 /*!
2805  * Returns IDs of nodes of given element
2806  */
2807 //=============================================================================
2808
2809 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
2810 {
2811   SMESH::long_array_var aResult = new SMESH::long_array();
2812   if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
2813   {
2814     if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
2815     {
2816       aResult->length( elem->NbNodes() );
2817       for ( int i = 0; i < elem->NbNodes(); ++i )
2818         aResult[ i ] = elem->GetNode( i )->GetID();
2819     }
2820   }
2821   return aResult._retn();
2822 }
2823
2824 //=============================================================================
2825 /*!
2826  * Returns true if given node is medium node
2827  * in given quadratic element
2828  */
2829 //=============================================================================
2830
2831 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
2832 {
2833   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2834   if ( aSMESHDS_Mesh == NULL ) return false;
2835   // try to find node
2836   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
2837   if(!aNode) return false;
2838   // try to find element
2839   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
2840   if(!elem) return false;
2841
2842   return elem->IsMediumNode(aNode);
2843 }
2844
2845
2846 //=============================================================================
2847 /*!
2848  * Returns true if given node is medium node
2849  * in one of quadratic elements
2850  */
2851 //=============================================================================
2852
2853 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
2854                                                    SMESH::ElementType theElemType)
2855 {
2856   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2857   if ( aSMESHDS_Mesh == NULL ) return false;
2858
2859   // try to find node
2860   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
2861   if(!aNode) return false;
2862
2863   SMESH_MesherHelper aHelper( *(_impl) );
2864
2865   SMDSAbs_ElementType aType;
2866   if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
2867   else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
2868   else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
2869   else aType = SMDSAbs_All;
2870
2871   return aHelper.IsMedium(aNode,aType);
2872 }
2873
2874
2875 //=============================================================================
2876 /*!
2877  * Returns number of edges for given element
2878  */
2879 //=============================================================================
2880
2881 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
2882 {
2883   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2884   if ( aSMESHDS_Mesh == NULL ) return -1;
2885   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2886   if(!elem) return -1;
2887   return elem->NbEdges();
2888 }
2889
2890
2891 //=============================================================================
2892 /*!
2893  * Returns number of faces for given element
2894  */
2895 //=============================================================================
2896
2897 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
2898 {
2899   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2900   if ( aSMESHDS_Mesh == NULL ) return -1;
2901   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2902   if(!elem) return -1;
2903   return elem->NbFaces();
2904 }
2905
2906
2907 //=============================================================================
2908 /*!
2909  * Returns true if given element is polygon
2910  */
2911 //=============================================================================
2912
2913 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
2914 {
2915   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2916   if ( aSMESHDS_Mesh == NULL ) return false;
2917   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2918   if(!elem) return false;
2919   return elem->IsPoly();
2920 }
2921
2922
2923 //=============================================================================
2924 /*!
2925  * Returns true if given element is quadratic
2926  */
2927 //=============================================================================
2928
2929 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
2930 {
2931   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2932   if ( aSMESHDS_Mesh == NULL ) return false;
2933   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2934   if(!elem) return false;
2935   return elem->IsQuadratic();
2936 }
2937
2938
2939 //=============================================================================
2940 /*!
2941  * Returns bary center for given element
2942  */
2943 //=============================================================================
2944
2945 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
2946 {
2947   SMESH::double_array_var aResult = new SMESH::double_array();
2948   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2949   if ( aSMESHDS_Mesh == NULL )
2950     return aResult._retn();
2951
2952   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2953   if(!elem)
2954     return aResult._retn();
2955
2956   if(elem->GetType()==SMDSAbs_Volume) {
2957     SMDS_VolumeTool aTool;
2958     if(aTool.Set(elem)) {
2959       aResult->length(3);
2960       if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
2961         aResult->length(0);
2962     }
2963   }
2964   else {
2965     SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
2966     int nbn = 0;
2967     double x=0., y=0., z=0.;
2968     for(; anIt->more(); ) {
2969       nbn++;
2970       const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
2971       x += aNode->X();
2972       y += aNode->Y();
2973       z += aNode->Z();
2974     }
2975     if(nbn>0) {
2976       // add coordinates
2977       aResult->length(3);
2978       aResult[0] = x/nbn;
2979       aResult[1] = y/nbn;
2980       aResult[2] = z/nbn;
2981     }
2982   }
2983
2984   return aResult._retn();
2985 }
2986
2987
2988 //=============================================================================
2989 /*!
2990  * Create and publish group servants if any groups were imported or created anyhow
2991  */
2992 //=============================================================================
2993
2994 void SMESH_Mesh_i::CreateGroupServants() 
2995 {
2996   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2997
2998   ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
2999   while ( groupIt->more() )
3000   {
3001     ::SMESH_Group* group = groupIt->next();
3002     int            anId = group->GetGroupDS()->GetID();
3003
3004     map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3005     if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3006       continue;
3007
3008     SMESH_GroupBase_i* aGroupImpl;
3009     TopoDS_Shape       shape;
3010     if ( SMESHDS_GroupOnGeom* groupOnGeom =
3011          dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3012     {
3013       aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3014       shape      = groupOnGeom->GetShape();
3015     }
3016     else {
3017       aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3018     }
3019
3020     // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3021     SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3022     aGroupImpl->Register();
3023
3024     SMESH::SMESH_GroupBase_var groupVar =
3025       SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3026     _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3027
3028     // register CORBA object for persistence
3029     int nextId = _gen_i->RegisterObject( groupVar );
3030     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3031
3032     // publishing of the groups in the study
3033     if ( !aStudy->_is_nil() ) {
3034       GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3035       _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3036     }
3037   }
3038 }
3039
3040 //=============================================================================
3041 /*!
3042  * \brief Return groups cantained in _mapGroups by their IDs
3043  */
3044 //=============================================================================
3045
3046 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3047 {
3048   int nbGroups = groupIDs.size();
3049   SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3050   aList->length( nbGroups );
3051
3052   list<int>::const_iterator ids = groupIDs.begin();
3053   for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3054   {
3055     map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3056     if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3057       aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3058   }
3059   aList->length( nbGroups );
3060   return aList._retn();
3061 }
3062
3063 //=============================================================================
3064 /*!
3065  * \brief Return information about imported file
3066  */
3067 //=============================================================================
3068
3069 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3070 {
3071   SALOME_MED::MedFileInfo_var res( myFileInfo );
3072   if ( !res.operator->() ) {
3073     res = new SALOME_MED::MedFileInfo;
3074     res->fileName = "";
3075     res->fileSize = res->major = res->minor = res->release = -1;
3076   }
3077   return res._retn();
3078 }
3079
3080 //=============================================================================
3081 /*!
3082  * \brief Check and correct names of mesh groups
3083  */
3084 //=============================================================================
3085
3086 void SMESH_Mesh_i::checkGroupNames()
3087 {
3088   int nbGrp = NbGroups();
3089   if ( !nbGrp )
3090     return;
3091
3092   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3093   if ( aStudy->_is_nil() )
3094     return; // nothing to do
3095   
3096   SMESH::ListOfGroups* grpList = 0;
3097   // avoid dump of "GetGroups"
3098   {
3099     // store python dump into a local variable inside local scope
3100     SMESH::TPythonDump pDump; // do not delete this line of code
3101     grpList = GetGroups();
3102   }
3103
3104   for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3105     SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3106     if ( !aGrp )
3107       continue;
3108     SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3109     if ( aGrpSO->_is_nil() )
3110       continue;
3111     // correct name of the mesh group if necessary
3112     const char* guiName = aGrpSO->GetName();
3113     if ( strcmp(guiName, aGrp->GetName()) )
3114       aGrp->SetName( guiName );
3115   }
3116 }