Salome HOME
PAL9997: Problem with ExportToMED if the file already exists
[modules/smesh.git] / src / SMESH_I / SMESH_Mesh_i.cxx
1 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SMESH_Mesh_i.cxx
25 //  Author : Paul RASCLE, EDF
26 //  Module : SMESH
27 //  $Header$
28
29 #include "SMESH_Mesh_i.hxx"
30 #include "SMESH_subMesh_i.hxx"
31 #include "SMESH_MEDMesh_i.hxx"
32 #include "SMESH_Group_i.hxx"
33 #include "SMESH_Filter_i.hxx"
34
35 #include "Utils_CorbaException.hxx"
36 #include "Utils_ExceptHandlers.hxx"
37 #include "utilities.h"
38
39 #include "SALOME_NamingService.hxx"
40 #include "Utils_SINGLETON.hxx"
41 #include "OpUtil.hxx"
42
43 #include "SMESHDS_Command.hxx"
44 #include "SMESHDS_CommandType.hxx"
45 #include "SMESH_MeshEditor_i.hxx"
46 #include "SMESH_Gen_i.hxx"
47 #include "DriverMED_R_SMESHDS_Mesh.h"
48
49 // OCCT Includes
50 #include <OSD_Path.hxx>
51 #include <OSD_File.hxx>
52 #include <OSD_Directory.hxx>
53 #include <OSD_Protection.hxx>
54 #include <TColStd_MapOfInteger.hxx>
55 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
56 #include <TColStd_SequenceOfInteger.hxx>
57 #include <TCollection_AsciiString.hxx>
58
59 // STL Includes
60 #include <string>
61 #include <iostream>
62 #include <sstream>
63
64 #ifdef _DEBUG_
65 static int MYDEBUG = 0;
66 #else
67 static int MYDEBUG = 0;
68 #endif
69
70 using namespace std;
71
72 int SMESH_Mesh_i::myIdGenerator = 0;
73
74 //=============================================================================
75 /*!
76  *  Constructor
77  */
78 //=============================================================================
79
80 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
81                             SMESH_Gen_i*            gen_i,
82                             CORBA::Long studyId )
83 : SALOME::GenericObj_i( thePOA )
84 {
85   INFOS("SMESH_Mesh_i; this = "<<this);
86   _impl = NULL;
87   _gen_i = gen_i;
88   _id = myIdGenerator++;
89   _studyId = studyId;
90   thePOA->activate_object( this );
91 }
92
93 //=============================================================================
94 /*!
95  *  Destructor
96  */
97 //=============================================================================
98
99 SMESH_Mesh_i::~SMESH_Mesh_i()
100 {
101   INFOS("~SMESH_Mesh_i; this = "<<this);
102   map<int, SMESH::SMESH_GroupBase_ptr>::iterator it;
103   for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) {
104     SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( it->second ).in() );
105     if ( aGroup ) {
106
107       // this method is colled from destructor of group (PAL6331)
108       //_impl->RemoveGroup( aGroup->GetLocalID() );
109       
110       aGroup->Destroy();
111     }
112   }
113   _mapGroups.clear();
114 }
115
116 //=============================================================================
117 /*!
118  *  SetShape
119  *
120  *  Associates <this> mesh with <theShape> and puts a reference  
121  *  to <theShape> into the current study; 
122  *  the previous shape is substituted by the new one.
123  */
124 //=============================================================================
125
126 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
127     throw (SALOME::SALOME_Exception)
128 {
129   Unexpect aCatch(SALOME_SalomeException);
130   try {
131     _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
132   }
133   catch(SALOME_Exception & S_ex) {
134     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
135   }
136 }
137
138 //=======================================================================
139 //function : GetShapeToMesh
140 //purpose  : 
141 //=======================================================================
142
143 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
144     throw (SALOME::SALOME_Exception)
145 {
146   Unexpect aCatch(SALOME_SalomeException);
147   GEOM::GEOM_Object_var aShapeObj;
148   try {
149     TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
150     if ( !S.IsNull() )
151       aShapeObj = _gen_i->ShapeToGeomObject( S );
152   }
153   catch(SALOME_Exception & S_ex) {
154     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
155   }
156   return aShapeObj._retn();
157 }
158
159 //=============================================================================
160 /*!
161  *  
162  */
163 //=============================================================================
164
165 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
166 {
167   SMESH::DriverMED_ReadStatus res;
168   switch (theStatus)
169   {
170   case DriverMED_R_SMESHDS_Mesh::DRS_OK:
171     res = SMESH::DRS_OK; break;
172   case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
173     res = SMESH::DRS_EMPTY; break;
174   case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
175     res = SMESH::DRS_WARN_RENUMBER; break;
176   case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
177     res = SMESH::DRS_WARN_SKIP_ELEM; break;
178   case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
179   default:
180     res = SMESH::DRS_FAIL; break;
181   }
182   return res;
183 }
184
185 //=============================================================================
186 /*!
187  *  ImportMEDFile
188  *
189  *  Imports mesh data from MED file
190  */
191 //=============================================================================
192
193 SMESH::DriverMED_ReadStatus
194 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
195   throw ( SALOME::SALOME_Exception )
196 {
197   Unexpect aCatch(SALOME_SalomeException);
198   int status;
199   try {
200     status = importMEDFile( theFileName, theMeshName );
201   }
202   catch( SALOME_Exception& S_ex ) {
203     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
204   }  
205   catch ( ... ) {
206     THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
207   }
208
209   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
210   if ( !aStudy->_is_nil() ) {
211     // publishing of the groups in the study (sub-meshes are out of scope of MED import)
212     map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
213     for (; it != _mapGroups.end(); it++ ) {
214       SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_duplicate( it->second );
215       _gen_i->PublishGroup( aStudy, _this(), aGroup,
216                            GEOM::GEOM_Object::_nil(), aGroup->GetName());
217     }
218   }
219   return ConvertDriverMEDReadStatus(status);
220 }
221
222 //=============================================================================
223 /*!
224  *  ImportUNVFile
225  *
226  *  Imports mesh data from MED file
227  */
228 //=============================================================================
229
230 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
231   throw ( SALOME::SALOME_Exception )
232 {
233   // Read mesh with name = <theMeshName> into SMESH_Mesh
234   _impl->UNVToMesh( theFileName );
235
236   return 1;
237 }
238
239 //=============================================================================
240 /*!
241  *  ImportSTLFile
242  *
243  *  Imports mesh data from STL file
244  */
245 //=============================================================================
246 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
247   throw ( SALOME::SALOME_Exception )
248 {
249   // Read mesh with name = <theMeshName> into SMESH_Mesh
250   _impl->STLToMesh( theFileName );
251
252   return 1;
253 }
254
255 //=============================================================================
256 /*!
257  *  importMEDFile
258  *
259  *  Imports mesh data from MED file
260  */
261 //=============================================================================
262
263 int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
264 {
265   // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
266   int status = _impl->MEDToMesh( theFileName, theMeshName );
267
268   // Create group servants, if any groups were imported
269   list<int> aGroupIds = _impl->GetGroupIds();
270   for ( list<int>::iterator it = aGroupIds.begin(); it != aGroupIds.end(); it++ ) {
271     SMESH_Group_i* aGroupImpl     = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, *it );
272
273     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
274     SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
275     aGroupImpl->Register();
276     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
277
278     SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
279     _mapGroups[*it]               = SMESH::SMESH_Group::_duplicate( aGroup );
280
281     // register CORBA object for persistence
282     int nextId = _gen_i->RegisterObject( aGroup );
283     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
284   }
285
286   return status;
287 }
288
289 //=============================================================================
290 /*!
291  *  
292  */
293 //=============================================================================
294
295 static SMESH::Hypothesis_Status ConvertHypothesisStatus
296                          (SMESH_Hypothesis::Hypothesis_Status theStatus)
297 {
298   SMESH::Hypothesis_Status res;
299   switch (theStatus)
300   {
301   case SMESH_Hypothesis::HYP_OK:
302     res = SMESH::HYP_OK; break;
303   case SMESH_Hypothesis::HYP_MISSING:
304     res = SMESH::HYP_MISSING; break;
305   case SMESH_Hypothesis::HYP_CONCURENT:
306     res = SMESH::HYP_CONCURENT; break;
307   case SMESH_Hypothesis::HYP_BAD_PARAMETER:
308     res = SMESH::HYP_BAD_PARAMETER; break;
309   case SMESH_Hypothesis::HYP_INCOMPATIBLE:
310     res = SMESH::HYP_INCOMPATIBLE; break;
311   case SMESH_Hypothesis::HYP_NOTCONFORM:
312     res = SMESH::HYP_NOTCONFORM; break;
313   case SMESH_Hypothesis::HYP_ALREADY_EXIST:
314     res = SMESH::HYP_ALREADY_EXIST; break;
315   case SMESH_Hypothesis::HYP_BAD_DIM:
316     res = SMESH::HYP_BAD_DIM; break;
317   default:
318     res = SMESH::HYP_UNKNOWN_FATAL;
319   }
320   return res;
321 }
322
323 //=============================================================================
324 /*!
325  *  AddHypothesis
326  *
327  *  calls internal addHypothesis() and then adds a reference to <anHyp> under 
328  *  the SObject actually having a reference to <aSubShape>.
329  *  NB: For this method to work, it is necessary to add a reference to sub-shape first.
330  */
331 //=============================================================================
332
333 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
334                                                      SMESH::SMESH_Hypothesis_ptr anHyp)
335   throw(SALOME::SALOME_Exception)
336 {
337   Unexpect aCatch(SALOME_SalomeException);
338   SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
339
340   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
341     _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
342                                  aSubShapeObject, anHyp );
343
344   if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
345
346   return ConvertHypothesisStatus(status);
347 }
348
349 //=============================================================================
350 /*!
351  *  
352  */
353 //=============================================================================
354
355 SMESH_Hypothesis::Hypothesis_Status
356   SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr       aSubShapeObject,
357                               SMESH::SMESH_Hypothesis_ptr anHyp)
358 {
359   if(MYDEBUG) MESSAGE("addHypothesis");
360
361   if (CORBA::is_nil(aSubShapeObject))
362     THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
363                                  SALOME::BAD_PARAM);
364
365   SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
366   if (CORBA::is_nil(myHyp))
367     THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
368                                  SALOME::BAD_PARAM);
369
370   SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
371   try
372   {
373     TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
374     int hypId = myHyp->GetId();
375     status = _impl->AddHypothesis(myLocSubShape, hypId);
376     if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
377       _mapHypo[hypId] = myHyp;
378       // assure there is a corresponding submesh
379       if ( !_impl->IsMainShape( myLocSubShape )) {
380         int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
381         if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
382           createSubMesh( aSubShapeObject );
383       }
384     }
385   }
386   catch(SALOME_Exception & S_ex)
387   {
388     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
389   }
390   return status;
391 }
392
393 //=============================================================================
394 /*!
395  *  
396  */
397 //=============================================================================
398
399 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
400                                                         SMESH::SMESH_Hypothesis_ptr anHyp)
401      throw(SALOME::SALOME_Exception)
402 {
403   Unexpect aCatch(SALOME_SalomeException);
404   SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
405
406   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
407     _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
408                                       aSubShapeObject, anHyp );
409
410   return ConvertHypothesisStatus(status);
411 }
412
413 //=============================================================================
414 /*!
415  *  
416  */
417 //=============================================================================
418
419 SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
420                                  SMESH::SMESH_Hypothesis_ptr anHyp)
421 {
422         if(MYDEBUG) MESSAGE("removeHypothesis()");
423         // **** proposer liste de subShape (selection multiple)
424
425         if (CORBA::is_nil(aSubShapeObject))
426                 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
427                         SALOME::BAD_PARAM);
428
429         SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
430         if (CORBA::is_nil(myHyp))
431           THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
432                         SALOME::BAD_PARAM);
433
434         SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
435         try
436         {
437                 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
438                 int hypId = myHyp->GetId();
439                 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
440                 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
441                   _mapHypo.erase( hypId );
442         }
443         catch(SALOME_Exception & S_ex)
444         {
445                 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
446         }
447         return status;
448 }
449
450 //=============================================================================
451 /*!
452  *  
453  */
454 //=============================================================================
455
456 SMESH::ListOfHypothesis *
457         SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
458 throw(SALOME::SALOME_Exception)
459 {
460   Unexpect aCatch(SALOME_SalomeException);
461   if (MYDEBUG) MESSAGE("GetHypothesisList");
462   if (CORBA::is_nil(aSubShapeObject))
463     THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
464                                  SALOME::BAD_PARAM);
465   
466   SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
467
468   try {
469     TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
470     const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
471     int i = 0, n = aLocalList.size();
472     aList->length( n );
473
474     for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
475       SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
476       if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
477         aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
478     }
479
480     aList->length( i );
481   }
482   catch(SALOME_Exception & S_ex) {
483     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
484   }
485   
486   return aList._retn();
487 }
488
489 //=============================================================================
490 /*!
491  *  
492  */
493 //=============================================================================
494 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
495                                                   const char*           theName ) 
496      throw(SALOME::SALOME_Exception)
497 {
498   Unexpect aCatch(SALOME_SalomeException);
499   MESSAGE("SMESH_Mesh_i::GetSubMesh");
500   if (CORBA::is_nil(aSubShapeObject))
501     THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
502                                  SALOME::BAD_PARAM);
503   
504   SMESH::SMESH_subMesh_var subMesh;
505   SMESH::SMESH_Mesh_var    aMesh = SMESH::SMESH_Mesh::_narrow(_this());
506   try {
507     TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
508     
509     //Get or Create the SMESH_subMesh object implementation
510     
511     int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
512     subMesh = getSubMesh( subMeshId );
513
514     // create a new subMesh object servant if there is none for the shape
515     if ( subMesh->_is_nil() )
516       subMesh = createSubMesh( aSubShapeObject );
517
518     if ( _gen_i->CanPublishInStudy( subMesh ))
519       _gen_i->PublishSubMesh (_gen_i->GetCurrentStudy(), aMesh,
520                               subMesh, aSubShapeObject, theName );
521   }
522   catch(SALOME_Exception & S_ex) {
523     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
524   }
525   return subMesh._retn();
526 }
527
528 //=============================================================================
529 /*!
530  *  
531  */
532 //=============================================================================
533
534 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
535      throw (SALOME::SALOME_Exception)
536 {
537   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
538   if ( theSubMesh->_is_nil() )
539     return;
540
541   GEOM::GEOM_Object_var aSubShapeObject;
542   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
543   if ( !aStudy->_is_nil() )  {
544     // Remove submesh's SObject
545     SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
546     if ( !anSO->_is_nil() ) {
547       long aTag = SMESH_Gen_i::GetRefOnShapeTag(); 
548       SALOMEDS::SObject_var anObj, aRef;
549       if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
550         aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
551
552       aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
553     }
554   }
555
556   removeSubMesh( theSubMesh, aSubShapeObject.in() );
557 }
558
559
560 //=============================================================================
561 /*!
562  *  
563  */
564 //=============================================================================
565
566 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
567                                                  const char*         theName )
568      throw(SALOME::SALOME_Exception)
569 {
570   Unexpect aCatch(SALOME_SalomeException);
571   SMESH::SMESH_Group_var aNewGroup =
572     SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
573
574   _gen_i->PublishGroup( _gen_i->GetCurrentStudy(), _this(),
575                        aNewGroup, GEOM::GEOM_Object::_nil(), theName);
576
577   return aNewGroup._retn();
578 }
579
580
581 //=============================================================================
582 /*!
583  *  
584  */
585 //=============================================================================
586 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM( SMESH::ElementType    theElemType,
587                                                                const char*           theName,
588                                                                GEOM::GEOM_Object_ptr theGeomObj)
589      throw(SALOME::SALOME_Exception)
590 {
591   Unexpect aCatch(SALOME_SalomeException);
592   SMESH::SMESH_GroupOnGeom_var aNewGroup;
593
594   TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
595   if ( !aShape.IsNull() ) {
596     aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
597       ( createGroup( theElemType, theName, aShape ));
598     if ( _gen_i->CanPublishInStudy( aNewGroup ) )
599       _gen_i->PublishGroup( _gen_i->GetCurrentStudy(), _this(), 
600                            aNewGroup, theGeomObj, theName );
601   }
602
603   return aNewGroup._retn();
604 }
605 //=============================================================================
606 /*!
607  *  
608  */
609 //=============================================================================
610
611 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
612      throw (SALOME::SALOME_Exception)
613 {
614   if ( theGroup->_is_nil() )
615     return;
616
617   SMESH_GroupBase_i* aGroup =
618     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
619   if ( !aGroup )
620     return;
621
622   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
623   if ( !aStudy->_is_nil() )  {
624     // Remove group's SObject
625     SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
626     if ( !aGroupSO->_is_nil() )
627       aStudy->NewBuilder()->RemoveObject( aGroupSO );
628   }
629
630   // Remove the group from SMESH data structures
631   removeGroup( aGroup->GetLocalID() );
632 }
633
634 //=============================================================================
635 /*! RemoveGroupWithContents
636  *  Remove group with its contents
637  */ 
638 //=============================================================================
639 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
640   throw (SALOME::SALOME_Exception)
641 {
642   if ( theGroup->_is_nil() )
643     return;
644
645   SMESH_GroupBase_i* aGroup =
646     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
647   if ( !aGroup )
648     return;
649   
650   SMESH::long_array_var anIds = aGroup->GetListOfID();
651   SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
652     
653   if ( aGroup->GetType() == SMESH::NODE )
654     aMeshEditor->RemoveNodes( anIds );
655   else
656     aMeshEditor->RemoveElements( anIds );
657   
658   RemoveGroup( theGroup );
659 }
660
661 //=============================================================================
662 /*! UnionGroups
663  *  New group is created. All mesh elements that are 
664  *  present in initial groups are added to the new one
665  */
666 //=============================================================================
667 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
668                                                   SMESH::SMESH_GroupBase_ptr theGroup2, 
669                                                   const char* theName )
670   throw (SALOME::SALOME_Exception)
671 {
672   try
673   {
674     SMESH::SMESH_Group_var aResGrp;
675
676     if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
677          theGroup1->GetType() != theGroup2->GetType() )
678       return SMESH::SMESH_Group::_nil();
679
680     aResGrp = CreateGroup( theGroup1->GetType(), theName );
681     if ( aResGrp->_is_nil() )
682       return SMESH::SMESH_Group::_nil();
683
684     SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
685     SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
686
687     TColStd_MapOfInteger aResMap;
688
689     for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
690       aResMap.Add( anIds1[ i1 ] );
691
692     for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
693       aResMap.Add( anIds2[ i2 ] );
694
695     SMESH::long_array_var aResIds = new SMESH::long_array;
696     aResIds->length( aResMap.Extent() );
697
698     int resI = 0;
699     TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
700     for( ; anIter.More(); anIter.Next() )
701       aResIds[ resI++ ] = anIter.Key();
702
703     aResGrp->Add( aResIds );
704
705     return aResGrp._retn();
706   }
707   catch( ... )
708   {
709     return SMESH::SMESH_Group::_nil();
710   }
711 }
712   
713 //=============================================================================
714 /*! IntersectGroups
715  *  New group is created. All mesh elements that are 
716  *  present in both initial groups are added to the new one.
717  */
718 //=============================================================================
719 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
720                                                       SMESH::SMESH_GroupBase_ptr theGroup2, 
721                                                       const char* theName )
722   throw (SALOME::SALOME_Exception)
723 {
724   SMESH::SMESH_Group_var aResGrp;
725   
726   if ( theGroup1->_is_nil() || theGroup2->_is_nil() || 
727        theGroup1->GetType() != theGroup2->GetType() )
728     return aResGrp;
729   
730   aResGrp = CreateGroup( theGroup1->GetType(), theName );
731   if ( aResGrp->_is_nil() )
732     return aResGrp;
733   
734   SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
735   SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
736   
737   TColStd_MapOfInteger aMap1;
738   
739   for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
740     aMap1.Add( anIds1[ i1 ] );
741
742   TColStd_SequenceOfInteger aSeq;
743
744   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
745     if ( aMap1.Contains( anIds2[ i2 ] ) )
746       aSeq.Append( anIds2[ i2 ] );
747   
748   SMESH::long_array_var aResIds = new SMESH::long_array;
749   aResIds->length( aSeq.Length() );
750   
751   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
752     aResIds[ resI ] = aSeq( resI + 1 );
753   
754   aResGrp->Add( aResIds );
755   
756   return aResGrp._retn();
757 }
758
759 //=============================================================================
760 /*! CutGroups
761  *  New group is created. All mesh elements that are present in 
762  *  main group but do not present in tool group are added to the new one 
763  */
764 //=============================================================================
765 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
766                                                 SMESH::SMESH_GroupBase_ptr theGroup2, 
767                                                 const char* theName )
768   throw (SALOME::SALOME_Exception)
769 {
770   SMESH::SMESH_Group_var aResGrp;
771   
772   if ( theGroup1->_is_nil() || theGroup2->_is_nil() || 
773        theGroup1->GetType() != theGroup2->GetType() )
774     return aResGrp;
775   
776   aResGrp = CreateGroup( theGroup1->GetType(), theName );
777   if ( aResGrp->_is_nil() )
778     return aResGrp;
779   
780   SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
781   SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
782   
783   TColStd_MapOfInteger aMap2;
784   
785   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
786     aMap2.Add( anIds2[ i2 ] );
787
788
789   TColStd_SequenceOfInteger aSeq;
790   for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
791     if ( !aMap2.Contains( anIds1[ i1 ] ) )
792       aSeq.Append( anIds1[ i1 ] );
793
794   SMESH::long_array_var aResIds = new SMESH::long_array;
795   aResIds->length( aSeq.Length() );
796
797   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
798     aResIds[ resI ] = aSeq( resI + 1 );  
799   
800   aResGrp->Add( aResIds );
801   
802   return aResGrp._retn();
803 }
804
805 //=============================================================================
806 /*!
807  *  
808  */
809 //=============================================================================
810
811 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
812 {
813   if(MYDEBUG) MESSAGE( "createSubMesh" );
814   TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
815
816   ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
817   int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
818   SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
819   SMESH::SMESH_subMesh_var subMesh
820     = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
821
822   _mapSubMesh[subMeshId] = mySubMesh;
823   _mapSubMesh_i[subMeshId] = subMeshServant;
824   _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
825
826   // register CORBA object for persistence
827   int nextId = _gen_i->RegisterObject( subMesh );
828   if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
829
830   return subMesh._retn(); 
831 }
832
833 //=======================================================================
834 //function : getSubMesh
835 //purpose  : 
836 //=======================================================================
837
838 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
839 {
840   map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
841   if ( it == _mapSubMeshIor.end() )
842     return SMESH::SMESH_subMesh::_nil();
843
844   return SMESH::SMESH_subMesh::_duplicate( (*it).second );
845 }
846
847
848 //=============================================================================
849 /*!
850  *  
851  */
852 //=============================================================================
853
854 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
855                                   GEOM::GEOM_Object_ptr    theSubShapeObject )
856 {
857   MESSAGE("SMESH_Mesh_i::removeSubMesh()");
858   if ( theSubMesh->_is_nil() || theSubShapeObject->_is_nil() )
859     return;
860
861   try {
862     SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
863     for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
864       removeHypothesis( theSubShapeObject, aHypList[i] );
865     }
866   }
867   catch( const SALOME::SALOME_Exception& ) {
868     INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
869   }
870
871   int subMeshId = theSubMesh->GetId();
872
873   _mapSubMesh.erase(subMeshId);
874   _mapSubMesh_i.erase(subMeshId);
875   _mapSubMeshIor.erase(subMeshId);
876   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
877 }
878
879 //=============================================================================
880 /*!
881  *  
882  */
883 //=============================================================================
884
885 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
886                                                       const char*         theName,
887                                                       const TopoDS_Shape& theShape )
888 {
889   int anId;
890   SMESH::SMESH_GroupBase_var aGroup;
891   if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
892     SMESH_GroupBase_i* aGroupImpl;
893     if ( !theShape.IsNull() )
894       aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
895     else
896       aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
897
898     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
899     SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
900     aGroupImpl->Register();
901     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
902
903     aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
904     _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
905
906     // register CORBA object for persistence
907     int nextId = _gen_i->RegisterObject( aGroup );
908     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
909   }
910   return aGroup._retn();
911 }
912
913 //=============================================================================
914 /*!
915  * SMESH_Mesh_i::removeGroup
916  *
917  * Should be called by ~SMESH_Group_i() 
918  */
919 //=============================================================================
920
921 void SMESH_Mesh_i::removeGroup( const int theId )
922 {
923   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );  
924   if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
925     _mapGroups.erase( theId );
926     _impl->RemoveGroup( theId );
927   }
928 }
929
930
931 //=============================================================================
932 /*!
933  *  
934  */
935 //=============================================================================
936
937 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
938 throw(SALOME::SALOME_Exception)
939 {
940   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
941   
942   SMESH::log_array_var aLog;
943   try{
944     list < SMESHDS_Command * >logDS = _impl->GetLog();
945     aLog = new SMESH::log_array;
946     int indexLog = 0;
947     int lg = logDS.size();
948     SCRUTE(lg);
949     aLog->length(lg);
950     list < SMESHDS_Command * >::iterator its = logDS.begin();
951     while(its != logDS.end()){
952       SMESHDS_Command *com = *its;
953       int comType = com->GetType();
954       //SCRUTE(comType);
955       int lgcom = com->GetNumber();
956       //SCRUTE(lgcom);
957       const list < int >&intList = com->GetIndexes();
958       int inum = intList.size();
959       //SCRUTE(inum);
960       list < int >::const_iterator ii = intList.begin();
961       const list < double >&coordList = com->GetCoords();
962       int rnum = coordList.size();
963       //SCRUTE(rnum);
964       list < double >::const_iterator ir = coordList.begin();
965       aLog[indexLog].commandType = comType;
966       aLog[indexLog].number = lgcom;
967       aLog[indexLog].coords.length(rnum);
968       aLog[indexLog].indexes.length(inum);
969       for(int i = 0; i < rnum; i++){
970         aLog[indexLog].coords[i] = *ir;
971         //MESSAGE(" "<<i<<" "<<ir.Value());
972         ir++;
973       }
974       for(int i = 0; i < inum; i++){
975         aLog[indexLog].indexes[i] = *ii;
976         //MESSAGE(" "<<i<<" "<<ii.Value());
977         ii++;
978       }
979       indexLog++;
980       its++;
981     }
982     if(clearAfterGet)
983       _impl->ClearLog();
984   }
985   catch(SALOME_Exception & S_ex){
986     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
987   }
988   return aLog._retn();
989 }
990
991
992 //=============================================================================
993 /*!
994  *  
995  */
996 //=============================================================================
997
998 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
999 {
1000   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
1001   // ****
1002 }
1003
1004 //=============================================================================
1005 /*!
1006  *  
1007  */
1008 //=============================================================================
1009
1010 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
1011 {
1012   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
1013   return _id;
1014 }
1015
1016 //=============================================================================
1017 /*!
1018  *  
1019  */
1020 //=============================================================================
1021
1022 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
1023 {
1024   return _studyId;
1025 }
1026
1027 //=============================================================================
1028 /*!
1029  *  
1030  */
1031 //=============================================================================
1032
1033 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
1034 {
1035   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
1036   _impl = impl;
1037 }
1038
1039 //=============================================================================
1040 /*!
1041  *  
1042  */
1043 //=============================================================================
1044
1045 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
1046 {
1047   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
1048   return *_impl;
1049 }
1050
1051
1052 //=============================================================================
1053 /*!
1054  *  
1055  */
1056 //=============================================================================
1057
1058 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
1059 {
1060         SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( _impl );
1061         SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
1062         return aMesh._retn();
1063 }
1064
1065 //=============================================================================
1066 /*!
1067  *  Export
1068  */
1069 //=============================================================================
1070
1071 static void PrepareForWriting (const char* file)
1072 {
1073   TCollection_AsciiString aFullName ((char*)file);
1074   OSD_Path aPath (aFullName);
1075   OSD_File aFile (aPath);
1076   if (aFile.Exists()) {
1077     // existing filesystem node
1078     if (aFile.KindOfFile() == OSD_FILE) {
1079       if (aFile.IsWriteable()) {
1080         aFile.Reset();
1081         aFile.Remove();
1082         if (aFile.Failed()) {
1083           TCollection_AsciiString msg ("File ");
1084           msg += aFullName + " cannot be replaced.";
1085           THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1086         }
1087       } else {
1088         TCollection_AsciiString msg ("File ");
1089         msg += aFullName + " cannot be overwritten.";
1090         THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1091       }
1092     } else {
1093       TCollection_AsciiString msg ("Location ");
1094       msg += aFullName + " is not a file.";
1095       THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1096     }
1097   } else {
1098     // nonexisting file
1099     TCollection_AsciiString aDirName = aPath.TrekValue(aPath.TrekLength());
1100     aPath.UpTrek();
1101     aPath.SetName(aDirName);
1102     aPath.SetExtension("");
1103     OSD_Directory aDir (aPath);
1104     TCollection_AsciiString aFullDirName;
1105     aPath.SystemName(aFullDirName);
1106     if (aDir.Exists()) {
1107       aFile.Reset();
1108       aFile.Build(OSD_WriteOnly, OSD_Protection());
1109       if (aFile.Failed()) {
1110         TCollection_AsciiString msg ("You cannot write to directory ");
1111         msg += aFullDirName + ".";
1112         THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1113       } else {
1114         aFile.Close();
1115         aFile.Remove();
1116       }
1117     } else {
1118       TCollection_AsciiString msg ("Directory ");
1119       msg += aFullDirName + " does not exist.";
1120       THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1121     }
1122   }
1123 }
1124
1125 void SMESH_Mesh_i::ExportToMED( const char* file, 
1126                                 CORBA::Boolean auto_groups, 
1127                                 SMESH::MED_VERSION theVersion )
1128   throw(SALOME::SALOME_Exception)
1129 {
1130   Unexpect aCatch(SALOME_SalomeException);
1131
1132   PrepareForWriting(file);
1133   char* aMeshName = "Mesh";
1134   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1135   if ( !aStudy->_is_nil() ) {
1136     SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
1137     if ( !aMeshSO->_is_nil() ) {
1138       aMeshName = aMeshSO->GetName();
1139       //SCRUTE(file);
1140       //SCRUTE(aMeshName);
1141       //SCRUTE(aMeshSO->GetID());
1142       
1143       // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes 
1144       if ( !aStudy->GetProperties()->IsLocked() ) 
1145         {
1146         SALOMEDS::GenericAttribute_var anAttr;
1147         SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
1148         SALOMEDS::AttributeExternalFileDef_var aFileName;
1149         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
1150         aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
1151         ASSERT(!aFileName->_is_nil());
1152         aFileName->SetValue(file);
1153         SALOMEDS::AttributeFileType_var aFileType;
1154         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
1155         aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
1156         ASSERT(!aFileType->_is_nil());
1157         aFileType->SetValue("FICHIERMED");
1158         }
1159     }
1160   }
1161   _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
1162 }
1163
1164 void SMESH_Mesh_i::ExportMED( const char* file, 
1165                               CORBA::Boolean auto_groups)
1166   throw(SALOME::SALOME_Exception)
1167 {
1168   ExportToMED(file,auto_groups,SMESH::MED_V2_1);
1169 }
1170
1171 void SMESH_Mesh_i::ExportDAT(const char *file) throw(SALOME::SALOME_Exception)
1172 {
1173   Unexpect aCatch(SALOME_SalomeException);
1174   PrepareForWriting(file);
1175   _impl->ExportDAT(file);
1176 }
1177 void SMESH_Mesh_i::ExportUNV(const char *file) throw(SALOME::SALOME_Exception)
1178 {
1179   Unexpect aCatch(SALOME_SalomeException);
1180   PrepareForWriting(file);
1181   _impl->ExportUNV(file);
1182 }
1183
1184 void SMESH_Mesh_i::ExportSTL(const char *file, const bool isascii) throw(SALOME::SALOME_Exception)
1185 {
1186   Unexpect aCatch(SALOME_SalomeException);
1187   PrepareForWriting(file);
1188   _impl->ExportSTL(file, isascii);
1189 }
1190
1191 //=============================================================================
1192 /*!
1193  *  
1194  */
1195 //=============================================================================
1196
1197 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
1198 {
1199   Unexpect aCatch(SALOME_SalomeException);
1200   SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
1201   SALOME_MED::MESH_var aMesh = aMedMesh->_this();
1202   return aMesh._retn();
1203 }
1204
1205 //=============================================================================
1206 /*!
1207  *  
1208  */
1209 //=============================================================================
1210 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
1211 {
1212   Unexpect aCatch(SALOME_SalomeException);
1213   return _impl->NbNodes();
1214 }
1215
1216 //=============================================================================
1217 /*!
1218  *  
1219  */
1220 //=============================================================================
1221 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
1222 {
1223   Unexpect aCatch(SALOME_SalomeException);
1224   return NbEdges() + NbFaces() + NbVolumes();
1225 }
1226   
1227 //=============================================================================
1228 /*!
1229  *  
1230  */
1231 //=============================================================================
1232 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
1233 {
1234   Unexpect aCatch(SALOME_SalomeException);
1235   return _impl->NbEdges();
1236 }
1237
1238 //=============================================================================
1239 /*!
1240  *  
1241  */
1242 //=============================================================================
1243 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
1244 {
1245   Unexpect aCatch(SALOME_SalomeException);
1246   return _impl->NbFaces();
1247 }
1248
1249 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
1250 {
1251   Unexpect aCatch(SALOME_SalomeException);
1252   return _impl->NbTriangles();
1253 }
1254
1255 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
1256 {
1257   Unexpect aCatch(SALOME_SalomeException);
1258   return _impl->NbQuadrangles();
1259 }
1260
1261 //=============================================================================
1262 /*!
1263  *  
1264  */
1265 //=============================================================================
1266 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
1267 {
1268   Unexpect aCatch(SALOME_SalomeException);
1269   return _impl->NbVolumes();
1270 }
1271
1272 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
1273 {
1274   Unexpect aCatch(SALOME_SalomeException);
1275   return _impl->NbTetras();
1276 }
1277
1278 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
1279 {
1280   Unexpect aCatch(SALOME_SalomeException);
1281   return _impl->NbHexas();
1282 }
1283
1284 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
1285 {
1286   Unexpect aCatch(SALOME_SalomeException);
1287   return _impl->NbPyramids();
1288 }
1289
1290 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
1291 {
1292   Unexpect aCatch(SALOME_SalomeException);
1293   return _impl->NbPrisms();
1294 }
1295
1296 //=============================================================================
1297 /*!
1298  *  
1299  */
1300 //=============================================================================
1301 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
1302 {
1303   Unexpect aCatch(SALOME_SalomeException);
1304   return _impl->NbSubMesh();
1305 }
1306
1307 //=============================================================================
1308 /*!
1309  *  
1310  */
1311 //=============================================================================
1312 char* SMESH_Mesh_i::Dump()
1313 {
1314   std::ostringstream os;
1315   _impl->Dump( os );
1316   return CORBA::string_dup( os.str().c_str() );
1317 }
1318
1319 //=============================================================================
1320 /*!
1321  *  
1322  */
1323 //=============================================================================
1324 SMESH::long_array* SMESH_Mesh_i::GetIDs()
1325 {
1326   SMESH::long_array_var aResult = new SMESH::long_array();
1327   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1328   int aMinId = aSMESHDS_Mesh->MinElementID();
1329   int aMaxId =  aSMESHDS_Mesh->MaxElementID();
1330
1331   aResult->length(aMaxId - aMinId + 1);
1332   
1333   for (int i = 0, id = aMinId; id <= aMaxId; id++  )
1334     aResult[i++] = id;
1335   
1336   return aResult._retn();
1337 }
1338
1339 //=============================================================================
1340 /*!
1341  *  
1342  */
1343 //=============================================================================
1344   
1345 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
1346      throw (SALOME::SALOME_Exception)
1347 {
1348   Unexpect aCatch(SALOME_SalomeException);
1349   MESSAGE("SMESH_Mesh_i::GetElementsId");
1350   SMESH::long_array_var aResult = new SMESH::long_array();
1351   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1352
1353   if ( aSMESHDS_Mesh == NULL )
1354     return aResult._retn();
1355
1356   long nbElements = NbElements();
1357   aResult->length( nbElements );
1358   SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
1359   for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
1360     aResult[i] = anIt->next()->GetID();
1361
1362   return aResult._retn();
1363 }
1364
1365
1366 //=============================================================================
1367 /*!
1368  *  
1369  */
1370 //=============================================================================
1371
1372 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
1373     throw (SALOME::SALOME_Exception)
1374 {
1375   Unexpect aCatch(SALOME_SalomeException);
1376   MESSAGE("SMESH_subMesh_i::GetElementsByType");
1377   SMESH::long_array_var aResult = new SMESH::long_array();
1378   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1379
1380   if ( aSMESHDS_Mesh == NULL )
1381     return aResult._retn();
1382
1383   long nbElements = NbElements();
1384
1385   // No sense in returning ids of elements along with ids of nodes:
1386   // when theElemType == SMESH::ALL, return node ids only if
1387   // there are no elements
1388   if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
1389     return GetNodesId();
1390
1391   aResult->length( nbElements );
1392
1393   int i = 0;
1394
1395   SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
1396   while ( i < nbElements && anIt->more() ) {
1397     const SMDS_MeshElement* anElem = anIt->next();
1398     if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
1399       aResult[i++] = anElem->GetID();
1400   }
1401
1402   aResult->length( i );
1403
1404   return aResult._retn();
1405 }
1406
1407 //=============================================================================
1408 /*!
1409  *  
1410  */
1411 //=============================================================================
1412   
1413 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
1414   throw (SALOME::SALOME_Exception)
1415 {
1416   Unexpect aCatch(SALOME_SalomeException);
1417   MESSAGE("SMESH_subMesh_i::GetNodesId");
1418   SMESH::long_array_var aResult = new SMESH::long_array();
1419   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1420
1421   if ( aSMESHDS_Mesh == NULL )
1422     return aResult._retn();
1423
1424   long nbNodes = NbNodes();
1425   aResult->length( nbNodes );
1426   SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
1427   for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
1428     aResult[i] = anIt->next()->GetID();
1429
1430   return aResult._retn();
1431 }
1432