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