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