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