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