]> SALOME platform Git repositories - modules/smesh.git/blob - src/SMESH_I/SMESH_Mesh_i.cxx
Salome HOME
4ef420bda6e7d1008a66a92f151def1f3e5b5b03
[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 /*! UnionGroups
733  *  New group is created. All mesh elements that are
734  *  present in initial groups are added to the new one
735  */
736 //=============================================================================
737 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
738                                                   SMESH::SMESH_GroupBase_ptr theGroup2,
739                                                   const char* theName )
740   throw (SALOME::SALOME_Exception)
741 {
742   try
743   {
744     if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
745          theGroup1->GetType() != theGroup2->GetType() )
746       return SMESH::SMESH_Group::_nil();
747
748     // Create Union
749     SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
750     if ( aResGrp->_is_nil() )
751       return SMESH::SMESH_Group::_nil();
752
753     SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
754     SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
755
756     TColStd_MapOfInteger aResMap;
757
758     for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
759       aResMap.Add( anIds1[ i1 ] );
760
761     for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
762       aResMap.Add( anIds2[ i2 ] );
763
764     SMESH::long_array_var aResIds = new SMESH::long_array;
765     aResIds->length( aResMap.Extent() );
766
767     int resI = 0;
768     TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
769     for( ; anIter.More(); anIter.Next() )
770       aResIds[ resI++ ] = anIter.Key();
771
772     aResGrp->Add( aResIds );
773
774     // Clear python lines, created by CreateGroup() and Add()
775     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
776     _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
777     _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
778
779     // Update Python script
780     TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
781                   << theGroup1 << ", " << theGroup2 << ", '"
782                   << theName << "' )";
783
784     return aResGrp._retn();
785   }
786   catch( ... )
787   {
788     return SMESH::SMESH_Group::_nil();
789   }
790 }
791
792 //=============================================================================
793 /*! IntersectGroups
794  *  New group is created. All mesh elements that are
795  *  present in both initial groups are added to the new one.
796  */
797 //=============================================================================
798 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
799                                                       SMESH::SMESH_GroupBase_ptr theGroup2,
800                                                       const char* theName )
801   throw (SALOME::SALOME_Exception)
802 {
803   if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
804        theGroup1->GetType() != theGroup2->GetType() )
805     return SMESH::SMESH_Group::_nil();
806
807   // Create Intersection
808   SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
809   if ( aResGrp->_is_nil() )
810     return aResGrp;
811
812   SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
813   SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
814
815   TColStd_MapOfInteger aMap1;
816
817   for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
818     aMap1.Add( anIds1[ i1 ] );
819
820   TColStd_SequenceOfInteger aSeq;
821
822   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
823     if ( aMap1.Contains( anIds2[ i2 ] ) )
824       aSeq.Append( anIds2[ i2 ] );
825
826   SMESH::long_array_var aResIds = new SMESH::long_array;
827   aResIds->length( aSeq.Length() );
828
829   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
830     aResIds[ resI ] = aSeq( resI + 1 );
831
832   aResGrp->Add( aResIds );
833
834   // Clear python lines, created by CreateGroup() and Add()
835   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
836   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
837   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
838
839   // Update Python script
840   TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
841                 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
842
843   return aResGrp._retn();
844 }
845
846 //=============================================================================
847 /*! CutGroups
848  *  New group is created. All mesh elements that are present in
849  *  main group but do not present in tool group are added to the new one
850  */
851 //=============================================================================
852 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
853                                                 SMESH::SMESH_GroupBase_ptr theGroup2,
854                                                 const char* theName )
855   throw (SALOME::SALOME_Exception)
856 {
857   if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
858        theGroup1->GetType() != theGroup2->GetType() )
859     return SMESH::SMESH_Group::_nil();
860
861   // Perform Cutting
862   SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
863   if ( aResGrp->_is_nil() )
864     return aResGrp;
865
866   SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
867   SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
868
869   TColStd_MapOfInteger aMap2;
870
871   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
872     aMap2.Add( anIds2[ i2 ] );
873
874
875   TColStd_SequenceOfInteger aSeq;
876   for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
877     if ( !aMap2.Contains( anIds1[ i1 ] ) )
878       aSeq.Append( anIds1[ i1 ] );
879
880   SMESH::long_array_var aResIds = new SMESH::long_array;
881   aResIds->length( aSeq.Length() );
882
883   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
884     aResIds[ resI ] = aSeq( resI + 1 );
885
886   aResGrp->Add( aResIds );
887
888   // Clear python lines, created by CreateGroup() and Add()
889   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
890   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
891   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
892
893   // Update Python script
894   TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
895                 << theGroup1 << ", " << theGroup2 << ", '"
896                 << theName << "' )";
897
898   return aResGrp._retn();
899 }
900
901 //=============================================================================
902 /*!
903  *
904  */
905 //=============================================================================
906
907 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
908 {
909   if(MYDEBUG) MESSAGE( "createSubMesh" );
910   TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
911
912   ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
913   int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
914   SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
915   SMESH::SMESH_subMesh_var subMesh
916     = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
917
918   _mapSubMesh[subMeshId] = mySubMesh;
919   _mapSubMesh_i[subMeshId] = subMeshServant;
920   _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
921
922   // register CORBA object for persistence
923   int nextId = _gen_i->RegisterObject( subMesh );
924   if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
925
926   return subMesh._retn();
927 }
928
929 //=======================================================================
930 //function : getSubMesh
931 //purpose  :
932 //=======================================================================
933
934 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
935 {
936   map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
937   if ( it == _mapSubMeshIor.end() )
938     return SMESH::SMESH_subMesh::_nil();
939
940   return SMESH::SMESH_subMesh::_duplicate( (*it).second );
941 }
942
943
944 //=============================================================================
945 /*!
946  *
947  */
948 //=============================================================================
949
950 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
951                                   GEOM::GEOM_Object_ptr    theSubShapeObject )
952 {
953   MESSAGE("SMESH_Mesh_i::removeSubMesh()");
954   if ( theSubMesh->_is_nil() || theSubShapeObject->_is_nil() )
955     return;
956
957   try {
958     SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
959     for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
960       removeHypothesis( theSubShapeObject, aHypList[i] );
961     }
962   }
963   catch( const SALOME::SALOME_Exception& ) {
964     INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
965   }
966
967   int subMeshId = theSubMesh->GetId();
968
969   _mapSubMesh.erase(subMeshId);
970   _mapSubMesh_i.erase(subMeshId);
971   _mapSubMeshIor.erase(subMeshId);
972   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
973 }
974
975 //=============================================================================
976 /*!
977  *
978  */
979 //=============================================================================
980
981 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
982                                                       const char*         theName,
983                                                       const TopoDS_Shape& theShape )
984 {
985   int anId;
986   SMESH::SMESH_GroupBase_var aGroup;
987   if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
988     SMESH_GroupBase_i* aGroupImpl;
989     if ( !theShape.IsNull() )
990       aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
991     else
992       aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
993
994     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
995     SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
996     aGroupImpl->Register();
997     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
998
999     aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
1000     _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1001
1002     // register CORBA object for persistence
1003     int nextId = _gen_i->RegisterObject( aGroup );
1004     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
1005   }
1006   return aGroup._retn();
1007 }
1008
1009 //=============================================================================
1010 /*!
1011  * SMESH_Mesh_i::removeGroup
1012  *
1013  * Should be called by ~SMESH_Group_i()
1014  */
1015 //=============================================================================
1016
1017 void SMESH_Mesh_i::removeGroup( const int theId )
1018 {
1019   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
1020   if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
1021     _mapGroups.erase( theId );
1022     _impl->RemoveGroup( theId );
1023   }
1024 }
1025
1026
1027 //=============================================================================
1028 /*!
1029  *
1030  */
1031 //=============================================================================
1032
1033 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
1034 throw(SALOME::SALOME_Exception)
1035 {
1036   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
1037
1038   SMESH::log_array_var aLog;
1039   try{
1040     list < SMESHDS_Command * >logDS = _impl->GetLog();
1041     aLog = new SMESH::log_array;
1042     int indexLog = 0;
1043     int lg = logDS.size();
1044     SCRUTE(lg);
1045     aLog->length(lg);
1046     list < SMESHDS_Command * >::iterator its = logDS.begin();
1047     while(its != logDS.end()){
1048       SMESHDS_Command *com = *its;
1049       int comType = com->GetType();
1050       //SCRUTE(comType);
1051       int lgcom = com->GetNumber();
1052       //SCRUTE(lgcom);
1053       const list < int >&intList = com->GetIndexes();
1054       int inum = intList.size();
1055       //SCRUTE(inum);
1056       list < int >::const_iterator ii = intList.begin();
1057       const list < double >&coordList = com->GetCoords();
1058       int rnum = coordList.size();
1059       //SCRUTE(rnum);
1060       list < double >::const_iterator ir = coordList.begin();
1061       aLog[indexLog].commandType = comType;
1062       aLog[indexLog].number = lgcom;
1063       aLog[indexLog].coords.length(rnum);
1064       aLog[indexLog].indexes.length(inum);
1065       for(int i = 0; i < rnum; i++){
1066         aLog[indexLog].coords[i] = *ir;
1067         //MESSAGE(" "<<i<<" "<<ir.Value());
1068         ir++;
1069       }
1070       for(int i = 0; i < inum; i++){
1071         aLog[indexLog].indexes[i] = *ii;
1072         //MESSAGE(" "<<i<<" "<<ii.Value());
1073         ii++;
1074       }
1075       indexLog++;
1076       its++;
1077     }
1078     if(clearAfterGet)
1079       _impl->ClearLog();
1080   }
1081   catch(SALOME_Exception & S_ex){
1082     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1083   }
1084   return aLog._retn();
1085 }
1086
1087
1088 //=============================================================================
1089 /*!
1090  *
1091  */
1092 //=============================================================================
1093
1094 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
1095 {
1096   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
1097   // ****
1098 }
1099
1100 //=============================================================================
1101 /*!
1102  *
1103  */
1104 //=============================================================================
1105
1106 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
1107 {
1108   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
1109   return _id;
1110 }
1111
1112 //=============================================================================
1113 /*!
1114  *
1115  */
1116 //=============================================================================
1117
1118 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
1119 {
1120   return _studyId;
1121 }
1122
1123 //=============================================================================
1124 /*!
1125  *
1126  */
1127 //=============================================================================
1128
1129 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
1130 {
1131   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
1132   _impl = impl;
1133 }
1134
1135 //=============================================================================
1136 /*!
1137  *
1138  */
1139 //=============================================================================
1140
1141 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
1142 {
1143   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
1144   return *_impl;
1145 }
1146
1147
1148 //=============================================================================
1149 /*!
1150  *
1151  */
1152 //=============================================================================
1153
1154 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
1155 {
1156   // Create MeshEditor
1157   SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( _impl );
1158   SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
1159
1160   // Update Python script
1161   TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
1162
1163   return aMesh._retn();
1164 }
1165
1166 //=============================================================================
1167 /*!
1168  *  Export in different formats
1169  */
1170 //=============================================================================
1171
1172 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
1173 {
1174   return _impl->HasDuplicatedGroupNamesMED();
1175 }
1176
1177 static void PrepareForWriting (const char* file)
1178 {
1179   TCollection_AsciiString aFullName ((char*)file);
1180   OSD_Path aPath (aFullName);
1181   OSD_File aFile (aPath);
1182   if (aFile.Exists()) {
1183     // existing filesystem node
1184     if (aFile.KindOfFile() == OSD_FILE) {
1185       if (aFile.IsWriteable()) {
1186         aFile.Reset();
1187         aFile.Remove();
1188         if (aFile.Failed()) {
1189           TCollection_AsciiString msg ("File ");
1190           msg += aFullName + " cannot be replaced.";
1191           THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1192         }
1193       } else {
1194         TCollection_AsciiString msg ("File ");
1195         msg += aFullName + " cannot be overwritten.";
1196         THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1197       }
1198     } else {
1199       TCollection_AsciiString msg ("Location ");
1200       msg += aFullName + " is not a file.";
1201       THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1202     }
1203   } else {
1204     // nonexisting file; check if it can be created
1205     aFile.Reset();
1206     aFile.Build(OSD_WriteOnly, OSD_Protection());
1207     if (aFile.Failed()) {
1208       TCollection_AsciiString msg ("You cannot create the file ");
1209       msg += aFullName + ". Check the directory existance and access rights.";
1210       THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1211     } else {
1212       aFile.Close();
1213       aFile.Remove();
1214     }
1215   }
1216 }
1217
1218 void SMESH_Mesh_i::ExportToMED (const char* file,
1219                                 CORBA::Boolean auto_groups,
1220                                 SMESH::MED_VERSION theVersion)
1221   throw(SALOME::SALOME_Exception)
1222 {
1223   Unexpect aCatch(SALOME_SalomeException);
1224
1225   // Update Python script
1226   TPythonDump() << _this() << ".ExportToMED( '"
1227                 << file << "', " << auto_groups << ", " << theVersion << " )";
1228
1229   // Perform Export
1230   PrepareForWriting(file);
1231   char* aMeshName = "Mesh";
1232   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1233   if ( !aStudy->_is_nil() ) {
1234     SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
1235     if ( !aMeshSO->_is_nil() ) {
1236       aMeshName = aMeshSO->GetName();
1237       //SCRUTE(file);
1238       //SCRUTE(aMeshName);
1239       //SCRUTE(aMeshSO->GetID());
1240
1241       // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
1242       if ( !aStudy->GetProperties()->IsLocked() )
1243         {
1244         SALOMEDS::GenericAttribute_var anAttr;
1245         SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
1246         SALOMEDS::AttributeExternalFileDef_var aFileName;
1247         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
1248         aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
1249         ASSERT(!aFileName->_is_nil());
1250         aFileName->SetValue(file);
1251         SALOMEDS::AttributeFileType_var aFileType;
1252         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
1253         aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
1254         ASSERT(!aFileType->_is_nil());
1255         aFileType->SetValue("FICHIERMED");
1256         }
1257     }
1258   }
1259   _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
1260 }
1261
1262 void SMESH_Mesh_i::ExportMED (const char* file,
1263                               CORBA::Boolean auto_groups)
1264   throw(SALOME::SALOME_Exception)
1265 {
1266   ExportToMED(file,auto_groups,SMESH::MED_V2_1);
1267 }
1268
1269 void SMESH_Mesh_i::ExportDAT (const char *file)
1270   throw(SALOME::SALOME_Exception)
1271 {
1272   Unexpect aCatch(SALOME_SalomeException);
1273
1274   // Update Python script
1275   TPythonDump() << _this() << ".ExportDAT( '" << file << "' )";
1276
1277   // Perform Export
1278   PrepareForWriting(file);
1279   _impl->ExportDAT(file);
1280 }
1281
1282 void SMESH_Mesh_i::ExportUNV (const char *file)
1283   throw(SALOME::SALOME_Exception)
1284 {
1285   Unexpect aCatch(SALOME_SalomeException);
1286
1287   // Update Python script
1288   TPythonDump() << _this() << ".ExportUNV( '" << file << "' )";
1289
1290   // Perform Export
1291   PrepareForWriting(file);
1292   _impl->ExportUNV(file);
1293 }
1294
1295 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
1296   throw(SALOME::SALOME_Exception)
1297 {
1298   Unexpect aCatch(SALOME_SalomeException);
1299
1300   // Update Python script
1301   TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )";
1302
1303   // Perform Export
1304   PrepareForWriting(file);
1305   _impl->ExportSTL(file, isascii);
1306 }
1307
1308 //=============================================================================
1309 /*!
1310  *
1311  */
1312 //=============================================================================
1313
1314 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
1315 {
1316   Unexpect aCatch(SALOME_SalomeException);
1317   SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
1318   SALOME_MED::MESH_var aMesh = aMedMesh->_this();
1319   return aMesh._retn();
1320 }
1321
1322 //=============================================================================
1323 /*!
1324  *
1325  */
1326 //=============================================================================
1327 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
1328 {
1329   Unexpect aCatch(SALOME_SalomeException);
1330   return _impl->NbNodes();
1331 }
1332
1333 //=============================================================================
1334 /*!
1335  *
1336  */
1337 //=============================================================================
1338 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
1339 {
1340   Unexpect aCatch(SALOME_SalomeException);
1341   return NbEdges() + NbFaces() + NbVolumes();
1342 }
1343
1344 //=============================================================================
1345 /*!
1346  *
1347  */
1348 //=============================================================================
1349 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
1350 {
1351   Unexpect aCatch(SALOME_SalomeException);
1352   return _impl->NbEdges();
1353 }
1354
1355 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
1356   throw(SALOME::SALOME_Exception)
1357 {
1358   Unexpect aCatch(SALOME_SalomeException);
1359   return _impl->NbEdges( (::SMESH_Mesh::ElementOrder) order);
1360 }
1361
1362 //=============================================================================
1363 /*!
1364  *
1365  */
1366 //=============================================================================
1367 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
1368 {
1369   Unexpect aCatch(SALOME_SalomeException);
1370   return _impl->NbFaces();
1371 }
1372
1373 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
1374 {
1375   Unexpect aCatch(SALOME_SalomeException);
1376   return _impl->NbTriangles();
1377 }
1378
1379 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
1380 {
1381   Unexpect aCatch(SALOME_SalomeException);
1382   return _impl->NbQuadrangles();
1383 }
1384
1385 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
1386 {
1387   Unexpect aCatch(SALOME_SalomeException);
1388   return _impl->NbPolygons();
1389 }
1390
1391 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
1392   throw(SALOME::SALOME_Exception)
1393 {
1394   Unexpect aCatch(SALOME_SalomeException);
1395   return _impl->NbFaces( (::SMESH_Mesh::ElementOrder) order);
1396 }
1397
1398 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
1399   throw(SALOME::SALOME_Exception)
1400 {
1401   Unexpect aCatch(SALOME_SalomeException);
1402   return _impl->NbTriangles( (::SMESH_Mesh::ElementOrder) order);
1403 }
1404
1405 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
1406   throw(SALOME::SALOME_Exception)
1407 {
1408   Unexpect aCatch(SALOME_SalomeException);
1409   return _impl->NbQuadrangles( (::SMESH_Mesh::ElementOrder) order);
1410 }
1411
1412 //=============================================================================
1413 /*!
1414  *
1415  */
1416 //=============================================================================
1417 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
1418 {
1419   Unexpect aCatch(SALOME_SalomeException);
1420   return _impl->NbVolumes();
1421 }
1422
1423 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
1424 {
1425   Unexpect aCatch(SALOME_SalomeException);
1426   return _impl->NbTetras();
1427 }
1428
1429 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
1430 {
1431   Unexpect aCatch(SALOME_SalomeException);
1432   return _impl->NbHexas();
1433 }
1434
1435 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
1436 {
1437   Unexpect aCatch(SALOME_SalomeException);
1438   return _impl->NbPyramids();
1439 }
1440
1441 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
1442 {
1443   Unexpect aCatch(SALOME_SalomeException);
1444   return _impl->NbPrisms();
1445 }
1446
1447 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
1448 {
1449   Unexpect aCatch(SALOME_SalomeException);
1450   return _impl->NbPolyhedrons();
1451 }
1452
1453 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
1454   throw(SALOME::SALOME_Exception)
1455 {
1456   Unexpect aCatch(SALOME_SalomeException);
1457   return _impl->NbVolumes( (::SMESH_Mesh::ElementOrder) order);
1458 }
1459
1460 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
1461   throw(SALOME::SALOME_Exception)
1462 {
1463   Unexpect aCatch(SALOME_SalomeException);
1464   return _impl->NbTetras( (::SMESH_Mesh::ElementOrder) order);
1465 }
1466
1467 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
1468   throw(SALOME::SALOME_Exception)
1469 {
1470   Unexpect aCatch(SALOME_SalomeException);
1471   return _impl->NbHexas( (::SMESH_Mesh::ElementOrder) order);
1472 }
1473
1474 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
1475   throw(SALOME::SALOME_Exception)
1476 {
1477   Unexpect aCatch(SALOME_SalomeException);
1478   return _impl->NbPyramids( (::SMESH_Mesh::ElementOrder) order);
1479 }
1480
1481 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
1482   throw(SALOME::SALOME_Exception)
1483 {
1484   Unexpect aCatch(SALOME_SalomeException);
1485   return _impl->NbPrisms( (::SMESH_Mesh::ElementOrder) order);
1486 }
1487
1488 //=============================================================================
1489 /*!
1490  *
1491  */
1492 //=============================================================================
1493 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
1494 {
1495   Unexpect aCatch(SALOME_SalomeException);
1496   return _impl->NbSubMesh();
1497 }
1498
1499 //=============================================================================
1500 /*!
1501  *
1502  */
1503 //=============================================================================
1504 char* SMESH_Mesh_i::Dump()
1505 {
1506   std::ostringstream os;
1507   _impl->Dump( os );
1508   return CORBA::string_dup( os.str().c_str() );
1509 }
1510
1511 //=============================================================================
1512 /*!
1513  *
1514  */
1515 //=============================================================================
1516 SMESH::long_array* SMESH_Mesh_i::GetIDs()
1517 {
1518   SMESH::long_array_var aResult = new SMESH::long_array();
1519   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1520   int aMinId = aSMESHDS_Mesh->MinElementID();
1521   int aMaxId =  aSMESHDS_Mesh->MaxElementID();
1522
1523   aResult->length(aMaxId - aMinId + 1);
1524
1525   for (int i = 0, id = aMinId; id <= aMaxId; id++  )
1526     aResult[i++] = id;
1527
1528   return aResult._retn();
1529 }
1530
1531 //=============================================================================
1532 /*!
1533  *
1534  */
1535 //=============================================================================
1536
1537 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
1538      throw (SALOME::SALOME_Exception)
1539 {
1540   Unexpect aCatch(SALOME_SalomeException);
1541   MESSAGE("SMESH_Mesh_i::GetElementsId");
1542   SMESH::long_array_var aResult = new SMESH::long_array();
1543   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1544
1545   if ( aSMESHDS_Mesh == NULL )
1546     return aResult._retn();
1547
1548   long nbElements = NbElements();
1549   aResult->length( nbElements );
1550   SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
1551   for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
1552     aResult[i] = anIt->next()->GetID();
1553
1554   return aResult._retn();
1555 }
1556
1557
1558 //=============================================================================
1559 /*!
1560  *
1561  */
1562 //=============================================================================
1563
1564 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
1565     throw (SALOME::SALOME_Exception)
1566 {
1567   Unexpect aCatch(SALOME_SalomeException);
1568   MESSAGE("SMESH_subMesh_i::GetElementsByType");
1569   SMESH::long_array_var aResult = new SMESH::long_array();
1570   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1571
1572   if ( aSMESHDS_Mesh == NULL )
1573     return aResult._retn();
1574
1575   long nbElements = NbElements();
1576
1577   // No sense in returning ids of elements along with ids of nodes:
1578   // when theElemType == SMESH::ALL, return node ids only if
1579   // there are no elements
1580   if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
1581     return GetNodesId();
1582
1583   aResult->length( nbElements );
1584
1585   int i = 0;
1586
1587   SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
1588   while ( i < nbElements && anIt->more() ) {
1589     const SMDS_MeshElement* anElem = anIt->next();
1590     if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
1591       aResult[i++] = anElem->GetID();
1592   }
1593
1594   aResult->length( i );
1595
1596   return aResult._retn();
1597 }
1598
1599 //=============================================================================
1600 /*!
1601  *
1602  */
1603 //=============================================================================
1604
1605 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
1606   throw (SALOME::SALOME_Exception)
1607 {
1608   Unexpect aCatch(SALOME_SalomeException);
1609   MESSAGE("SMESH_subMesh_i::GetNodesId");
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 nbNodes = NbNodes();
1617   aResult->length( nbNodes );
1618   SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
1619   for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
1620     aResult[i] = anIt->next()->GetID();
1621
1622   return aResult._retn();
1623 }
1624
1625 //=============================================================================
1626 /*!
1627  *
1628  */
1629 //=============================================================================
1630
1631 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
1632   throw (SALOME::SALOME_Exception)
1633 {
1634   return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
1635 }
1636
1637
1638 //=============================================================================
1639 /*!
1640  * Returns ID of elements for given submesh
1641  */
1642 //=============================================================================
1643 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
1644      throw (SALOME::SALOME_Exception)
1645 {
1646   SMESH::long_array_var aResult = new SMESH::long_array();
1647
1648   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
1649   if(!SM) return aResult._retn();
1650
1651   SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
1652   if(!SDSM) return aResult._retn();
1653
1654   aResult->length(SDSM->NbElements());
1655
1656   SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
1657   int i = 0;
1658   while ( eIt->more() ) {
1659     aResult[i++] = eIt->next()->GetID();
1660   }
1661
1662   return aResult._retn();
1663 }
1664
1665
1666 //=============================================================================
1667 /*!
1668  * Returns ID of nodes for given submesh
1669  * If param all==true - returns all nodes, else -
1670  * returns only nodes on shapes.
1671  */
1672 //=============================================================================
1673 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
1674      throw (SALOME::SALOME_Exception)
1675 {
1676   SMESH::long_array_var aResult = new SMESH::long_array();
1677
1678   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
1679   if(!SM) return aResult._retn();
1680
1681   SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
1682   if(!SDSM) return aResult._retn();
1683
1684   map<int,const SMDS_MeshElement*> theElems;
1685   if( !all || (SDSM->NbElements()==0 && SDSM->NbNodes()==1) ) {
1686     SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
1687     while ( nIt->more() ) {
1688       const SMDS_MeshNode* elem = nIt->next();
1689       theElems.insert( make_pair(elem->GetID(),elem) );
1690     }
1691   }
1692   else { // all nodes of submesh elements
1693     SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
1694     while ( eIt->more() ) {
1695       const SMDS_MeshElement* anElem = eIt->next();
1696       SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
1697       while ( nIt->more() ) {
1698         const SMDS_MeshElement* elem = nIt->next();
1699         theElems.insert( make_pair(elem->GetID(),elem) );
1700       }
1701     }
1702   }
1703
1704   aResult->length(theElems.size());
1705   map<int, const SMDS_MeshElement * >::iterator itElem;
1706   int i = 0;
1707   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
1708     aResult[i++] = (*itElem).first;
1709
1710   return aResult._retn();
1711 }
1712   
1713
1714 //=============================================================================
1715 /*!
1716  * Returns type of elements for given submesh
1717  */
1718 //=============================================================================
1719 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
1720      throw (SALOME::SALOME_Exception)
1721 {
1722   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
1723   if(!SM) return SMESH::ALL;
1724
1725   SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
1726   if(!SDSM) return SMESH::ALL;
1727
1728   if(SDSM->NbElements()==0)
1729     return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
1730
1731   SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
1732   const SMDS_MeshElement* anElem = eIt->next();
1733   return ( SMESH::ElementType ) anElem->GetType();
1734 }
1735   
1736
1737 //=============================================================================
1738 /*!
1739  *
1740  */
1741 //=============================================================================
1742
1743 CORBA::Long SMESH_Mesh_i::GetMeshPtr()
1744 {
1745   return CORBA::Long(size_t(_impl));
1746 }
1747
1748
1749 //=============================================================================
1750 /*!
1751  * Get XYZ coordinates of node as list of double
1752  * If there is not node for given ID - returns empty list
1753  */
1754 //=============================================================================
1755
1756 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
1757 {
1758   SMESH::double_array_var aResult = new SMESH::double_array();
1759   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1760   if ( aSMESHDS_Mesh == NULL )
1761     return aResult._retn();
1762
1763   // find node
1764   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
1765   if(!aNode)
1766     return aResult._retn();
1767
1768   // add coordinates
1769   aResult->length(3);
1770   aResult[0] = aNode->X();
1771   aResult[1] = aNode->Y();
1772   aResult[2] = aNode->Z();
1773   return aResult._retn();
1774 }
1775
1776
1777 //=============================================================================
1778 /*!
1779  * For given node returns list of IDs of inverse elements
1780  * If there is not node for given ID - returns empty list
1781  */
1782 //=============================================================================
1783
1784 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
1785 {
1786   SMESH::long_array_var aResult = new SMESH::long_array();
1787   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1788   if ( aSMESHDS_Mesh == NULL )
1789     return aResult._retn();
1790
1791   // find node
1792   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
1793   if(!aNode)
1794     return aResult._retn();
1795
1796   // find inverse elements
1797   SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
1798   TColStd_SequenceOfInteger IDs;
1799   while(eIt->more()) {
1800     const SMDS_MeshElement* elem = eIt->next();
1801     IDs.Append(elem->GetID());
1802   }
1803   if(IDs.Length()>0) {
1804     aResult->length(IDs.Length());
1805     int i = 1;
1806     for(; i<=IDs.Length(); i++) {
1807       aResult[i-1] = IDs.Value(i);
1808     }
1809   }
1810   return aResult._retn();
1811 }
1812
1813
1814 //=============================================================================
1815 /*!
1816  * If given element is node returns IDs of shape from position
1817  * else - return ID of result shape after ::FindShape()
1818  * from SMESH_MeshEditor
1819  * If there is not element for given ID - returns -1
1820  */
1821 //=============================================================================
1822
1823 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
1824 {
1825   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1826   if ( aSMESHDS_Mesh == NULL )
1827     return -1;
1828
1829   // try to find node
1830   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
1831   if(aNode) {
1832     SMDS_PositionPtr pos = aNode->GetPosition();
1833     if(!pos)
1834       return -1;
1835     else
1836       return pos->GetShapeId();
1837   }
1838
1839   // try to find element
1840   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
1841   if(!elem)
1842     return -1;
1843
1844   // need implementation???????????????????????????????????????????????
1845   return -1;
1846 }
1847
1848
1849 //=============================================================================
1850 /*!
1851  * Returns number of nodes for given element
1852  * If there is not element for given ID - returns -1
1853  */
1854 //=============================================================================
1855
1856 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
1857 {
1858   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1859   if ( aSMESHDS_Mesh == NULL ) return -1;
1860   // try to find element
1861   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
1862   if(!elem) return -1;
1863   return elem->NbNodes();
1864 }
1865
1866
1867 //=============================================================================
1868 /*!
1869  * Returns ID of node by given index for given element
1870  * If there is not element for given ID - returns -1
1871  * If there is not node for given index - returns -2
1872  */
1873 //=============================================================================
1874
1875 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
1876 {
1877   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1878   if ( aSMESHDS_Mesh == NULL ) return -1;
1879   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
1880   if(!elem) return -1;
1881   if( index>=elem->NbNodes() || index<0 ) return -1;
1882   return elem->GetNode(index)->GetID();
1883 }
1884
1885
1886 //=============================================================================
1887 /*!
1888  * Returns true if given node is medium node
1889  * in given quadratic element
1890  */
1891 //=============================================================================
1892
1893 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
1894 {
1895   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1896   if ( aSMESHDS_Mesh == NULL ) return false;
1897   // try to find node
1898   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
1899   if(!aNode) return false;
1900   // try to find element
1901   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
1902   if(!elem) return false;
1903
1904   return elem->IsMediumNode(aNode);
1905 }
1906
1907
1908 //=============================================================================
1909 /*!
1910  * Returns true if given node is medium node
1911  * in one of quadratic elements
1912  */
1913 //=============================================================================
1914
1915 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
1916                                                    SMESH::ElementType theElemType)
1917 {
1918   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1919   if ( aSMESHDS_Mesh == NULL ) return false;
1920
1921   // try to find node
1922   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
1923   if(!aNode) return false;
1924
1925   SMESH_MesherHelper aHelper( *(_impl) );
1926
1927   SMDSAbs_ElementType aType;
1928   if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
1929   else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
1930   else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
1931   else aType = SMDSAbs_All;
1932
1933   return aHelper.IsMedium(aNode,aType);
1934 }
1935
1936
1937 //=============================================================================
1938 /*!
1939  * Returns number of edges for given element
1940  */
1941 //=============================================================================
1942
1943 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
1944 {
1945   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1946   if ( aSMESHDS_Mesh == NULL ) return -1;
1947   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
1948   if(!elem) return -1;
1949   return elem->NbEdges();
1950 }
1951
1952
1953 //=============================================================================
1954 /*!
1955  * Returns number of faces for given element
1956  */
1957 //=============================================================================
1958
1959 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
1960 {
1961   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1962   if ( aSMESHDS_Mesh == NULL ) return -1;
1963   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
1964   if(!elem) return -1;
1965   return elem->NbFaces();
1966 }
1967
1968
1969 //=============================================================================
1970 /*!
1971  * Returns true if given element is polygon
1972  */
1973 //=============================================================================
1974
1975 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
1976 {
1977   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1978   if ( aSMESHDS_Mesh == NULL ) return false;
1979   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
1980   if(!elem) return false;
1981   return elem->IsPoly();
1982 }
1983
1984
1985 //=============================================================================
1986 /*!
1987  * Returns true if given element is quadratic
1988  */
1989 //=============================================================================
1990
1991 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
1992 {
1993   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1994   if ( aSMESHDS_Mesh == NULL ) return false;
1995   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
1996   if(!elem) return false;
1997   return elem->IsQuadratic();
1998 }
1999
2000
2001 //=============================================================================
2002 /*!
2003  * Returns bary center for given element
2004  */
2005 //=============================================================================
2006
2007 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
2008 {
2009   SMESH::double_array_var aResult = new SMESH::double_array();
2010   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2011   if ( aSMESHDS_Mesh == NULL )
2012     return aResult._retn();
2013
2014   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2015   if(!elem)
2016     return aResult._retn();
2017
2018   if(elem->GetType()==SMDSAbs_Volume) {
2019     // use SMDS_VolumeTool
2020     SMDS_VolumeTool aTool;
2021     if(aTool.Set(elem)) {
2022       double x=0., y=0., z=0.;
2023       if(aTool.GetBaryCenter(x,y,z)) {
2024         // add coordinates
2025         aResult->length(3);
2026         aResult[0] = x;
2027         aResult[1] = y;
2028         aResult[2] = z;
2029       }
2030     }
2031   }
2032   else {
2033     SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
2034     int nbn = 0;
2035     double x=0., y=0., z=0.;
2036     for(; anIt->more(); ) {
2037       nbn++;
2038       const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
2039       x += aNode->X();
2040       y += aNode->Y();
2041       z += aNode->Z();
2042     }
2043     if(nbn>0) {
2044       // add coordinates
2045       aResult->length(3);
2046       aResult[0] = x/nbn;
2047       aResult[1] = y/nbn;
2048       aResult[2] = z/nbn;
2049     }
2050   }
2051
2052   return aResult._retn();
2053 }
2054
2055
2056 //=============================================================================
2057 /*!
2058  *
2059  */
2060 //=============================================================================
2061 void SMESH_Mesh_i::CreateGroupServants() 
2062 {
2063   // Create group servants, if any groups were imported
2064   list<int> aGroupIds = _impl->GetGroupIds();
2065   for ( list<int>::iterator it = aGroupIds.begin(); it != aGroupIds.end(); it++ ) {
2066     SMESH_Group_i* aGroupImpl     = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, *it );
2067
2068     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2069     SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2070     aGroupImpl->Register();
2071     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2072
2073     SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2074     _mapGroups[*it]               = SMESH::SMESH_Group::_duplicate( aGroup );
2075
2076     // register CORBA object for persistence
2077     int nextId = _gen_i->RegisterObject( aGroup );
2078     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2079   }
2080 }
2081