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