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