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