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