Salome HOME
PAL11238: Crash in ExportMED.
[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; check if it can be created
1099     aFile.Reset();
1100     aFile.Build(OSD_WriteOnly, OSD_Protection());
1101     if (aFile.Failed()) {
1102       TCollection_AsciiString msg ("You cannot create the file ");
1103       msg += aFullName + ". Check the directory existance and access rights.";
1104       THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1105     } else {
1106       aFile.Close();
1107       aFile.Remove();
1108     }
1109   }
1110 }
1111
1112 void SMESH_Mesh_i::ExportToMED( const char* file, 
1113                                 CORBA::Boolean auto_groups, 
1114                                 SMESH::MED_VERSION theVersion )
1115   throw(SALOME::SALOME_Exception)
1116 {
1117   Unexpect aCatch(SALOME_SalomeException);
1118
1119   PrepareForWriting(file);
1120   char* aMeshName = "Mesh";
1121   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1122   if ( !aStudy->_is_nil() ) {
1123     SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
1124     if ( !aMeshSO->_is_nil() ) {
1125       aMeshName = aMeshSO->GetName();
1126       //SCRUTE(file);
1127       //SCRUTE(aMeshName);
1128       //SCRUTE(aMeshSO->GetID());
1129       
1130       // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes 
1131       if ( !aStudy->GetProperties()->IsLocked() ) 
1132         {
1133         SALOMEDS::GenericAttribute_var anAttr;
1134         SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
1135         SALOMEDS::AttributeExternalFileDef_var aFileName;
1136         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
1137         aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
1138         ASSERT(!aFileName->_is_nil());
1139         aFileName->SetValue(file);
1140         SALOMEDS::AttributeFileType_var aFileType;
1141         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
1142         aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
1143         ASSERT(!aFileType->_is_nil());
1144         aFileType->SetValue("FICHIERMED");
1145         }
1146     }
1147   }
1148   _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
1149 }
1150
1151 void SMESH_Mesh_i::ExportMED( const char* file, 
1152                               CORBA::Boolean auto_groups)
1153   throw(SALOME::SALOME_Exception)
1154 {
1155   ExportToMED(file,auto_groups,SMESH::MED_V2_1);
1156 }
1157
1158 void SMESH_Mesh_i::ExportDAT(const char *file) throw(SALOME::SALOME_Exception)
1159 {
1160   Unexpect aCatch(SALOME_SalomeException);
1161   PrepareForWriting(file);
1162   _impl->ExportDAT(file);
1163 }
1164 void SMESH_Mesh_i::ExportUNV(const char *file) throw(SALOME::SALOME_Exception)
1165 {
1166   Unexpect aCatch(SALOME_SalomeException);
1167   PrepareForWriting(file);
1168   _impl->ExportUNV(file);
1169 }
1170
1171 void SMESH_Mesh_i::ExportSTL(const char *file, const bool isascii) throw(SALOME::SALOME_Exception)
1172 {
1173   Unexpect aCatch(SALOME_SalomeException);
1174   PrepareForWriting(file);
1175   _impl->ExportSTL(file, isascii);
1176 }
1177
1178 //=============================================================================
1179 /*!
1180  *  
1181  */
1182 //=============================================================================
1183
1184 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
1185 {
1186   Unexpect aCatch(SALOME_SalomeException);
1187   SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
1188   SALOME_MED::MESH_var aMesh = aMedMesh->_this();
1189   return aMesh._retn();
1190 }
1191
1192 //=============================================================================
1193 /*!
1194  *  
1195  */
1196 //=============================================================================
1197 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
1198 {
1199   Unexpect aCatch(SALOME_SalomeException);
1200   return _impl->NbNodes();
1201 }
1202
1203 //=============================================================================
1204 /*!
1205  *  
1206  */
1207 //=============================================================================
1208 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
1209 {
1210   Unexpect aCatch(SALOME_SalomeException);
1211   return NbEdges() + NbFaces() + NbVolumes();
1212 }
1213   
1214 //=============================================================================
1215 /*!
1216  *  
1217  */
1218 //=============================================================================
1219 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
1220 {
1221   Unexpect aCatch(SALOME_SalomeException);
1222   return _impl->NbEdges();
1223 }
1224
1225 //=============================================================================
1226 /*!
1227  *  
1228  */
1229 //=============================================================================
1230 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
1231 {
1232   Unexpect aCatch(SALOME_SalomeException);
1233   return _impl->NbFaces();
1234 }
1235
1236 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
1237 {
1238   Unexpect aCatch(SALOME_SalomeException);
1239   return _impl->NbTriangles();
1240 }
1241
1242 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
1243 {
1244   Unexpect aCatch(SALOME_SalomeException);
1245   return _impl->NbQuadrangles();
1246 }
1247
1248 //=============================================================================
1249 /*!
1250  *  
1251  */
1252 //=============================================================================
1253 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
1254 {
1255   Unexpect aCatch(SALOME_SalomeException);
1256   return _impl->NbVolumes();
1257 }
1258
1259 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
1260 {
1261   Unexpect aCatch(SALOME_SalomeException);
1262   return _impl->NbTetras();
1263 }
1264
1265 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
1266 {
1267   Unexpect aCatch(SALOME_SalomeException);
1268   return _impl->NbHexas();
1269 }
1270
1271 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
1272 {
1273   Unexpect aCatch(SALOME_SalomeException);
1274   return _impl->NbPyramids();
1275 }
1276
1277 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
1278 {
1279   Unexpect aCatch(SALOME_SalomeException);
1280   return _impl->NbPrisms();
1281 }
1282
1283 //=============================================================================
1284 /*!
1285  *  
1286  */
1287 //=============================================================================
1288 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
1289 {
1290   Unexpect aCatch(SALOME_SalomeException);
1291   return _impl->NbSubMesh();
1292 }
1293
1294 //=============================================================================
1295 /*!
1296  *  
1297  */
1298 //=============================================================================
1299 char* SMESH_Mesh_i::Dump()
1300 {
1301   std::ostringstream os;
1302   _impl->Dump( os );
1303   return CORBA::string_dup( os.str().c_str() );
1304 }
1305
1306 //=============================================================================
1307 /*!
1308  *  
1309  */
1310 //=============================================================================
1311 SMESH::long_array* SMESH_Mesh_i::GetIDs()
1312 {
1313   SMESH::long_array_var aResult = new SMESH::long_array();
1314   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1315   int aMinId = aSMESHDS_Mesh->MinElementID();
1316   int aMaxId =  aSMESHDS_Mesh->MaxElementID();
1317
1318   aResult->length(aMaxId - aMinId + 1);
1319   
1320   for (int i = 0, id = aMinId; id <= aMaxId; id++  )
1321     aResult[i++] = id;
1322   
1323   return aResult._retn();
1324 }
1325
1326 //=============================================================================
1327 /*!
1328  *  
1329  */
1330 //=============================================================================
1331   
1332 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
1333      throw (SALOME::SALOME_Exception)
1334 {
1335   Unexpect aCatch(SALOME_SalomeException);
1336   MESSAGE("SMESH_Mesh_i::GetElementsId");
1337   SMESH::long_array_var aResult = new SMESH::long_array();
1338   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1339
1340   if ( aSMESHDS_Mesh == NULL )
1341     return aResult._retn();
1342
1343   long nbElements = NbElements();
1344   aResult->length( nbElements );
1345   SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
1346   for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
1347     aResult[i] = anIt->next()->GetID();
1348
1349   return aResult._retn();
1350 }
1351
1352
1353 //=============================================================================
1354 /*!
1355  *  
1356  */
1357 //=============================================================================
1358
1359 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
1360     throw (SALOME::SALOME_Exception)
1361 {
1362   Unexpect aCatch(SALOME_SalomeException);
1363   MESSAGE("SMESH_subMesh_i::GetElementsByType");
1364   SMESH::long_array_var aResult = new SMESH::long_array();
1365   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1366
1367   if ( aSMESHDS_Mesh == NULL )
1368     return aResult._retn();
1369
1370   long nbElements = NbElements();
1371
1372   // No sense in returning ids of elements along with ids of nodes:
1373   // when theElemType == SMESH::ALL, return node ids only if
1374   // there are no elements
1375   if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
1376     return GetNodesId();
1377
1378   aResult->length( nbElements );
1379
1380   int i = 0;
1381
1382   SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
1383   while ( i < nbElements && anIt->more() ) {
1384     const SMDS_MeshElement* anElem = anIt->next();
1385     if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
1386       aResult[i++] = anElem->GetID();
1387   }
1388
1389   aResult->length( i );
1390
1391   return aResult._retn();
1392 }
1393
1394 //=============================================================================
1395 /*!
1396  *  
1397  */
1398 //=============================================================================
1399   
1400 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
1401   throw (SALOME::SALOME_Exception)
1402 {
1403   Unexpect aCatch(SALOME_SalomeException);
1404   MESSAGE("SMESH_subMesh_i::GetNodesId");
1405   SMESH::long_array_var aResult = new SMESH::long_array();
1406   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1407
1408   if ( aSMESHDS_Mesh == NULL )
1409     return aResult._retn();
1410
1411   long nbNodes = NbNodes();
1412   aResult->length( nbNodes );
1413   SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
1414   for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
1415     aResult[i] = anIt->next()->GetID();
1416
1417   return aResult._retn();
1418 }
1419