Salome HOME
IPAL21120 SIGSEGV on Meshing attached Compound with Automatic Hexadralization
[modules/smesh.git] / src / SMESH_I / SMESH_Mesh_i.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  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 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
23 //  File   : SMESH_Mesh_i.cxx
24 //  Author : Paul RASCLE, EDF
25 //  Module : SMESH
26 //
27 #include "SMESH_Mesh_i.hxx"
28
29 #include "SMESH_Filter_i.hxx"
30 #include "SMESH_Gen_i.hxx"
31 #include "SMESH_Group_i.hxx"
32 #include "SMESH_MEDMesh_i.hxx"
33 #include "SMESH_MeshEditor_i.hxx"
34 #include "SMESH_PythonDump.hxx"
35 #include "SMESH_subMesh_i.hxx"
36
37 #include "DriverMED_R_SMESHDS_Mesh.h"
38 #include "DriverMED_W_SMESHDS_Mesh.h"
39 #include "SMDS_VolumeTool.hxx"
40 #include "SMESHDS_Command.hxx"
41 #include "SMESHDS_CommandType.hxx"
42 #include "SMESHDS_GroupOnGeom.hxx"
43 #include "SMESH_Group.hxx"
44 #include "SMESH_MeshEditor.hxx"
45 #include "SMESH_MesherHelper.hxx"
46 #include "SMDS_EdgePosition.hxx"
47 #include "SMDS_FacePosition.hxx"
48
49 #include "OpUtil.hxx"
50 #include "SALOME_NamingService.hxx"
51 #include "Utils_CorbaException.hxx"
52 #include "Utils_ExceptHandlers.hxx"
53 #include "Utils_SINGLETON.hxx"
54 #include "utilities.h"
55 #include "GEOMImpl_Types.hxx"
56
57 // OCCT Includes
58 #include <BRep_Builder.hxx>
59 #include <OSD_Directory.hxx>
60 #include <OSD_File.hxx>
61 #include <OSD_Path.hxx>
62 #include <OSD_Protection.hxx>
63 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
64 #include <TColStd_MapOfInteger.hxx>
65 #include <TColStd_SequenceOfInteger.hxx>
66 #include <TCollection_AsciiString.hxx>
67 #include <TopExp_Explorer.hxx>
68 #include <TopoDS_Compound.hxx>
69
70 // STL Includes
71 #include <string>
72 #include <iostream>
73 #include <sstream>
74 #include <sys/stat.h>
75
76 #ifdef _DEBUG_
77 static int MYDEBUG = 0;
78 #else
79 static int MYDEBUG = 0;
80 #endif
81
82 using namespace std;
83 using SMESH::TPythonDump;
84
85 int SMESH_Mesh_i::myIdGenerator = 0;
86
87
88
89 //=============================================================================
90 /*!
91  *  Constructor
92  */
93 //=============================================================================
94
95 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
96                             SMESH_Gen_i*            gen_i,
97                             CORBA::Long studyId )
98 : SALOME::GenericObj_i( thePOA )
99 {
100   MESSAGE("SMESH_Mesh_i");
101   _impl = NULL;
102   _gen_i = gen_i;
103   _id = myIdGenerator++;
104   _studyId = studyId;
105 }
106
107 //=============================================================================
108 /*!
109  *  Destructor
110  */
111 //=============================================================================
112
113 SMESH_Mesh_i::~SMESH_Mesh_i()
114 {
115   INFOS("~SMESH_Mesh_i");
116   map<int, SMESH::SMESH_GroupBase_ptr>::iterator it;
117   for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) {
118     SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( it->second ).in() );
119     if ( aGroup ) {
120       // this method is colled from destructor of group (PAL6331)
121       //_impl->RemoveGroup( aGroup->GetLocalID() );
122       
123       aGroup->Destroy();
124     }
125   }
126   _mapGroups.clear();
127 }
128
129 //=============================================================================
130 /*!
131  *  SetShape
132  *
133  *  Associates <this> mesh with <theShape> and puts a reference
134  *  to <theShape> into the current study;
135  *  the previous shape is substituted by the new one.
136  */
137 //=============================================================================
138
139 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
140     throw (SALOME::SALOME_Exception)
141 {
142   Unexpect aCatch(SALOME_SalomeException);
143   try {
144     _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
145   }
146   catch(SALOME_Exception & S_ex) {
147     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
148   }
149   // to track changes of GEOM groups
150   addGeomGroupData( theShapeObject, _this() );
151 }
152
153 //================================================================================
154 /*!
155  * \brief return true if mesh has a shape to build a shape on
156  */
157 //================================================================================
158
159 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
160   throw (SALOME::SALOME_Exception)
161 {
162   Unexpect aCatch(SALOME_SalomeException);
163   bool res = false;
164   try {
165     res = _impl->HasShapeToMesh();
166   }
167   catch(SALOME_Exception & S_ex) {
168     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
169   }
170   return res;
171 }
172
173 //=======================================================================
174 //function : GetShapeToMesh
175 //purpose  :
176 //=======================================================================
177
178 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
179   throw (SALOME::SALOME_Exception)
180 {
181   Unexpect aCatch(SALOME_SalomeException);
182   GEOM::GEOM_Object_var aShapeObj;
183   try {
184     TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
185     if ( !S.IsNull() )
186       aShapeObj = _gen_i->ShapeToGeomObject( S );
187   }
188   catch(SALOME_Exception & S_ex) {
189     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
190   }
191   return aShapeObj._retn();
192 }
193
194 //================================================================================
195 /*!
196  * \brief Remove all nodes and elements
197  */
198 //================================================================================
199
200 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
201 {
202   Unexpect aCatch(SALOME_SalomeException);
203   try {
204     _impl->Clear();
205   }
206   catch(SALOME_Exception & S_ex) {
207     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
208   }
209   TPythonDump() <<  _this() << ".Clear()";
210 }
211
212 //=============================================================================
213 /*!
214  *
215  */
216 //=============================================================================
217
218 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
219 {
220   SMESH::DriverMED_ReadStatus res;
221   switch (theStatus)
222   {
223   case DriverMED_R_SMESHDS_Mesh::DRS_OK:
224     res = SMESH::DRS_OK; break;
225   case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
226     res = SMESH::DRS_EMPTY; break;
227   case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
228     res = SMESH::DRS_WARN_RENUMBER; break;
229   case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
230     res = SMESH::DRS_WARN_SKIP_ELEM; break;
231   case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
232   default:
233     res = SMESH::DRS_FAIL; break;
234   }
235   return res;
236 }
237
238 //=============================================================================
239 /*!
240  *  ImportMEDFile
241  *
242  *  Imports mesh data from MED file
243  */
244 //=============================================================================
245
246 SMESH::DriverMED_ReadStatus
247 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
248   throw ( SALOME::SALOME_Exception )
249 {
250   Unexpect aCatch(SALOME_SalomeException);
251   int status;
252   try {
253     status = _impl->MEDToMesh( theFileName, theMeshName );
254   }
255   catch( SALOME_Exception& S_ex ) {
256     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
257   }
258   catch ( ... ) {
259     THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
260   }
261
262   CreateGroupServants();
263
264   int major, minor, release;
265   if( !MED::getMEDVersion( theFileName, major, minor, release ) )
266     major = minor = release = -1;
267   myFileInfo           = new SALOME_MED::MedFileInfo();
268   myFileInfo->fileName = theFileName;
269   myFileInfo->fileSize = 0;
270 #ifdef WIN32
271   struct _stati64 d;
272   if ( ::_stati64( theFileName, &d ) != -1 )
273 #else
274   struct stat64 d;
275   if ( ::stat64( theFileName, &d ) != -1 )
276 #endif
277     myFileInfo->fileSize = d.st_size;
278   myFileInfo->major    = major;
279   myFileInfo->minor    = minor;
280   myFileInfo->release  = release;
281
282   return ConvertDriverMEDReadStatus(status);
283 }
284
285 //================================================================================
286 /*!
287  * \brief Return string representation of a MED file version comprising nbDigits
288  */
289 //================================================================================
290
291 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
292 {
293   std::string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
294                                                                nbDigits);
295   return CORBA::string_dup( ver.c_str() );
296 }
297
298 //=============================================================================
299 /*!
300  *  ImportUNVFile
301  *
302  *  Imports mesh data from MED file
303  */
304 //=============================================================================
305
306 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
307   throw ( SALOME::SALOME_Exception )
308 {
309   // Read mesh with name = <theMeshName> into SMESH_Mesh
310   _impl->UNVToMesh( theFileName );
311
312   CreateGroupServants();
313
314   return 1;
315 }
316
317 //=============================================================================
318 /*!
319  *  ImportSTLFile
320  *
321  *  Imports mesh data from STL file
322  */
323 //=============================================================================
324 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
325   throw ( SALOME::SALOME_Exception )
326 {
327   // Read mesh with name = <theMeshName> into SMESH_Mesh
328   _impl->STLToMesh( theFileName );
329
330   return 1;
331 }
332
333 //=============================================================================
334 /*!
335  *  importMEDFile
336  *
337  *  Imports mesh data from MED file
338  */
339 //=============================================================================
340
341 // int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
342 // {
343 //   // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
344 //   int status = _impl->MEDToMesh( theFileName, theMeshName );
345 //   CreateGroupServants();
346
347 //   return status;
348 // }
349
350 //=============================================================================
351 /*!
352  *
353  */
354 //=============================================================================
355
356 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
357
358 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
359                          (SMESH_Hypothesis::Hypothesis_Status theStatus)
360 {
361   switch (theStatus) {
362   RETURNCASE( HYP_OK            );
363   RETURNCASE( HYP_MISSING       );
364   RETURNCASE( HYP_CONCURENT     );
365   RETURNCASE( HYP_BAD_PARAMETER );
366   RETURNCASE( HYP_HIDDEN_ALGO   );
367   RETURNCASE( HYP_HIDING_ALGO   );
368   RETURNCASE( HYP_UNKNOWN_FATAL );
369   RETURNCASE( HYP_INCOMPATIBLE  );
370   RETURNCASE( HYP_NOTCONFORM    );
371   RETURNCASE( HYP_ALREADY_EXIST );
372   RETURNCASE( HYP_BAD_DIM       );
373   RETURNCASE( HYP_BAD_SUBSHAPE  );
374   RETURNCASE( HYP_BAD_GEOMETRY  );
375   RETURNCASE( HYP_NEED_SHAPE    );
376   default:;
377   }
378   return SMESH::HYP_UNKNOWN_FATAL;
379 }
380
381 //=============================================================================
382 /*!
383  *  AddHypothesis
384  *
385  *  calls internal addHypothesis() and then adds a reference to <anHyp> under
386  *  the SObject actually having a reference to <aSubShape>.
387  *  NB: For this method to work, it is necessary to add a reference to sub-shape first.
388  */
389 //=============================================================================
390
391 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
392                                                      SMESH::SMESH_Hypothesis_ptr anHyp)
393   throw(SALOME::SALOME_Exception)
394 {
395   Unexpect aCatch(SALOME_SalomeException);
396   SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
397
398   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
399     _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
400                                  aSubShapeObject, anHyp );
401
402   if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
403
404   // Update Python script
405   if(_impl->HasShapeToMesh()) {
406     TPythonDump() << "status = " << _this() << ".AddHypothesis( "
407                   << aSubShapeObject << ", " << anHyp << " )";
408   }
409   else {
410     TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
411   }
412   
413   return ConvertHypothesisStatus(status);
414 }
415
416 //=============================================================================
417 /*!
418  *
419  */
420 //=============================================================================
421
422 SMESH_Hypothesis::Hypothesis_Status
423   SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr       aSubShapeObject,
424                               SMESH::SMESH_Hypothesis_ptr anHyp)
425 {
426   if(MYDEBUG) MESSAGE("addHypothesis");
427
428   if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
429     THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
430                                  SALOME::BAD_PARAM);
431
432   SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
433   if (CORBA::is_nil(myHyp))
434     THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
435                                  SALOME::BAD_PARAM);
436
437   SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
438   try
439   {
440     TopoDS_Shape myLocSubShape;
441     //use PseudoShape in case if mesh has no shape
442     if(HasShapeToMesh())
443       myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
444     else              
445       myLocSubShape = _impl->GetShapeToMesh();
446     
447     int hypId = myHyp->GetId();
448     status = _impl->AddHypothesis(myLocSubShape, hypId);
449     if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
450       _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
451       // assure there is a corresponding submesh
452       if ( !_impl->IsMainShape( myLocSubShape )) {
453         int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
454         if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
455           createSubMesh( aSubShapeObject );
456       }
457     }
458   }
459   catch(SALOME_Exception & S_ex)
460   {
461     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
462   }
463   return status;
464 }
465
466 //=============================================================================
467 /*!
468  *
469  */
470 //=============================================================================
471
472 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
473                                                         SMESH::SMESH_Hypothesis_ptr anHyp)
474      throw(SALOME::SALOME_Exception)
475 {
476   Unexpect aCatch(SALOME_SalomeException);
477   SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
478
479   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
480     _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
481                                       aSubShapeObject, anHyp );
482
483   // Update Python script
484     // Update Python script
485   if(_impl->HasShapeToMesh()) {
486   TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
487                 << aSubShapeObject << ", " << anHyp << " )";
488   }
489   else {
490     TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
491                   << anHyp << " )";
492   }
493
494   return ConvertHypothesisStatus(status);
495 }
496
497 //=============================================================================
498 /*!
499  *
500  */
501 //=============================================================================
502
503 SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
504                                  SMESH::SMESH_Hypothesis_ptr anHyp)
505 {
506         if(MYDEBUG) MESSAGE("removeHypothesis()");
507         // **** proposer liste de subShape (selection multiple)
508
509         if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
510                 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
511                         SALOME::BAD_PARAM);
512
513         SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
514         if (CORBA::is_nil(myHyp))
515           THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
516                         SALOME::BAD_PARAM);
517
518         SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
519         try
520         {
521                 TopoDS_Shape myLocSubShape;
522                 //use PseudoShape in case if mesh has no shape
523                 if(HasShapeToMesh())
524                   myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
525                 else
526                   myLocSubShape = _impl->GetShapeToMesh();
527                 
528                 int hypId = myHyp->GetId();
529                 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
530                 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
531                   _mapHypo.erase( hypId );
532         }
533         catch(SALOME_Exception & S_ex)
534         {
535                 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
536         }
537         return status;
538 }
539
540 //=============================================================================
541 /*!
542  *
543  */
544 //=============================================================================
545
546 SMESH::ListOfHypothesis *
547         SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
548 throw(SALOME::SALOME_Exception)
549 {
550   Unexpect aCatch(SALOME_SalomeException);
551   if (MYDEBUG) MESSAGE("GetHypothesisList");
552   if (CORBA::is_nil(aSubShapeObject))
553     THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
554                                  SALOME::BAD_PARAM);
555
556   SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
557
558   try {
559     TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
560     const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
561     int i = 0, n = aLocalList.size();
562     aList->length( n );
563
564     for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
565       SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
566       if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
567         aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
568     }
569
570     aList->length( i );
571   }
572   catch(SALOME_Exception & S_ex) {
573     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
574   }
575
576   return aList._retn();
577 }
578
579 //=============================================================================
580 /*!
581  *
582  */
583 //=============================================================================
584 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
585                                                   const char*           theName )
586      throw(SALOME::SALOME_Exception)
587 {
588   Unexpect aCatch(SALOME_SalomeException);
589   MESSAGE("SMESH_Mesh_i::GetSubMesh");
590   if (CORBA::is_nil(aSubShapeObject))
591     THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
592                                  SALOME::BAD_PARAM);
593
594   SMESH::SMESH_subMesh_var subMesh;
595   SMESH::SMESH_Mesh_var    aMesh = SMESH::SMESH_Mesh::_narrow(_this());
596   try {
597     TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
598
599     //Get or Create the SMESH_subMesh object implementation
600
601     int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
602     subMesh = getSubMesh( subMeshId );
603
604     // create a new subMesh object servant if there is none for the shape
605     if ( subMesh->_is_nil() )
606       subMesh = createSubMesh( aSubShapeObject );
607     if ( _gen_i->CanPublishInStudy( subMesh )) {
608       SALOMEDS::SObject_var aSO =
609         _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
610                                subMesh, aSubShapeObject, theName );
611       if ( !aSO->_is_nil()) {
612         // Update Python script
613         TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
614                       << aSubShapeObject << ", '" << theName << "' )";
615       }
616     }
617   }
618   catch(SALOME_Exception & S_ex) {
619     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
620   }
621   return subMesh._retn();
622 }
623
624 //=============================================================================
625 /*!
626  *
627  */
628 //=============================================================================
629
630 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
631      throw (SALOME::SALOME_Exception)
632 {
633   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
634   if ( theSubMesh->_is_nil() )
635     return;
636
637   GEOM::GEOM_Object_var aSubShapeObject;
638   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
639   if ( !aStudy->_is_nil() )  {
640     // Remove submesh's SObject
641     SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
642     if ( !anSO->_is_nil() ) {
643       long aTag = SMESH_Gen_i::GetRefOnShapeTag();
644       SALOMEDS::SObject_var anObj, aRef;
645       if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
646         aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
647
648       aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
649
650       // Update Python script
651       TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
652     }
653   }
654
655   removeSubMesh( theSubMesh, aSubShapeObject.in() );
656 }
657
658 //=============================================================================
659 /*!
660  *  ElementTypeString
661  */
662 //=============================================================================
663 #define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
664 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
665 {
666   switch (theElemType) {
667     CASE2STRING( ALL );
668     CASE2STRING( NODE );
669     CASE2STRING( EDGE );
670     CASE2STRING( FACE );
671     CASE2STRING( VOLUME );
672   default:;
673   }
674   return "";
675 }
676
677 //=============================================================================
678 /*!
679  *
680  */
681 //=============================================================================
682
683 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
684                                                  const char*         theName )
685      throw(SALOME::SALOME_Exception)
686 {
687   Unexpect aCatch(SALOME_SalomeException);
688   SMESH::SMESH_Group_var aNewGroup =
689     SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
690
691   if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
692     SALOMEDS::SObject_var aSO =
693       _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
694                            aNewGroup, GEOM::GEOM_Object::_nil(), theName);
695     if ( !aSO->_is_nil()) {
696       // Update Python script
697       TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
698                     << ElementTypeString(theElemType) << ", '" << theName << "' )";
699     }
700   }
701   return aNewGroup._retn();
702 }
703
704
705 //=============================================================================
706 /*!
707  *
708  */
709 //=============================================================================
710 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType    theElemType,
711                                                                 const char*           theName,
712                                                                 GEOM::GEOM_Object_ptr theGeomObj)
713      throw(SALOME::SALOME_Exception)
714 {
715   Unexpect aCatch(SALOME_SalomeException);
716   SMESH::SMESH_GroupOnGeom_var aNewGroup;
717
718   TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
719   if ( !aShape.IsNull() )
720   {
721     aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
722       ( createGroup( theElemType, theName, aShape ));
723
724     if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
725       SALOMEDS::SObject_var aSO =
726         _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
727                              aNewGroup, theGeomObj, theName);
728       if ( !aSO->_is_nil()) {
729         // Update Python script
730         TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
731                       << ElementTypeString(theElemType) << ", '" << theName << "', "
732                       << theGeomObj << " )";
733       }
734     }
735   }
736
737   return aNewGroup._retn();
738 }
739
740 //=============================================================================
741 /*!
742  *
743  */
744 //=============================================================================
745
746 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
747      throw (SALOME::SALOME_Exception)
748 {
749   if ( theGroup->_is_nil() )
750     return;
751
752   SMESH_GroupBase_i* aGroup =
753     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
754   if ( !aGroup )
755     return;
756
757   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
758   if ( !aStudy->_is_nil() )  {
759     SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
760
761     if ( !aGroupSO->_is_nil() ) {
762       // Update Python script
763       TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
764
765       // Remove group's SObject
766       aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
767     }
768   }
769
770   // Remove the group from SMESH data structures
771   removeGroup( aGroup->GetLocalID() );
772 }
773
774 //=============================================================================
775 /*! RemoveGroupWithContents
776  *  Remove group with its contents
777  */
778 //=============================================================================
779 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
780   throw (SALOME::SALOME_Exception)
781 {
782   if ( theGroup->_is_nil() )
783     return;
784
785   SMESH_GroupBase_i* aGroup =
786     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
787   if ( !aGroup )
788     return;
789
790   SMESH::long_array_var anIds = aGroup->GetListOfID();
791   SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
792
793   // Update Python script
794   TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
795
796   // Remove contents
797   if ( aGroup->GetType() == SMESH::NODE )
798     aMeshEditor->RemoveNodes( anIds );
799   else
800     aMeshEditor->RemoveElements( anIds );
801
802   // Remove group
803   RemoveGroup( theGroup );
804
805   // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
806   _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
807   _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
808 }
809
810
811 //================================================================================
812 /*!
813  * \brief Get the list of groups existing in the mesh
814   * \retval SMESH::ListOfGroups * - list of groups
815  */
816 //================================================================================
817
818 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
819 {
820   Unexpect aCatch(SALOME_SalomeException);
821   if (MYDEBUG) MESSAGE("GetGroups");
822
823   SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
824
825   // Python Dump
826   TPythonDump aPythonDump;
827   if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
828     aPythonDump << "[ ";
829
830   try {
831     aList->length( _mapGroups.size() );
832     int i = 0;
833     map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
834     for ( ; it != _mapGroups.end(); it++ ) {
835       if ( CORBA::is_nil( it->second )) continue;
836       aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
837       // Python Dump
838       if (i > 1) aPythonDump << ", ";
839       aPythonDump << it->second;
840     }
841     aList->length( i );
842   }
843   catch(SALOME_Exception & S_ex) {
844     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
845   }
846
847   // Update Python script
848   if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
849     aPythonDump << " ] = " << _this() << ".GetGroups()";
850
851   return aList._retn();
852 }
853 //=============================================================================
854 /*!
855  *  Get number of groups existing in the mesh
856  */
857 //=============================================================================
858
859 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
860 {
861   Unexpect aCatch(SALOME_SalomeException);
862   return _mapGroups.size();
863 }
864
865 //=============================================================================
866 /*! UnionGroups
867  *  New group is created. All mesh elements that are
868  *  present in initial groups are added to the new one
869  */
870 //=============================================================================
871 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
872                                                   SMESH::SMESH_GroupBase_ptr theGroup2,
873                                                   const char* theName )
874   throw (SALOME::SALOME_Exception)
875 {
876   try
877   {
878     if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
879          theGroup1->GetType() != theGroup2->GetType() )
880       return SMESH::SMESH_Group::_nil();
881
882     // Create Union
883     SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
884     if ( aResGrp->_is_nil() )
885       return SMESH::SMESH_Group::_nil();
886
887     SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
888     SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
889
890     TColStd_MapOfInteger aResMap;
891
892     for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
893       aResMap.Add( anIds1[ i1 ] );
894
895     for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
896       aResMap.Add( anIds2[ i2 ] );
897
898     SMESH::long_array_var aResIds = new SMESH::long_array;
899     aResIds->length( aResMap.Extent() );
900
901     int resI = 0;
902     TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
903     for( ; anIter.More(); anIter.Next() )
904       aResIds[ resI++ ] = anIter.Key();
905
906     aResGrp->Add( aResIds );
907
908     // Clear python lines, created by CreateGroup() and Add()
909     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
910     _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
911     _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
912
913     // Update Python script
914     TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
915                   << theGroup1 << ", " << theGroup2 << ", '"
916                   << theName << "' )";
917
918     return aResGrp._retn();
919   }
920   catch( ... )
921   {
922     return SMESH::SMESH_Group::_nil();
923   }
924 }
925
926 //=============================================================================
927 /*! IntersectGroups
928  *  New group is created. All mesh elements that are
929  *  present in both initial groups are added to the new one.
930  */
931 //=============================================================================
932 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
933                                                       SMESH::SMESH_GroupBase_ptr theGroup2,
934                                                       const char* theName )
935   throw (SALOME::SALOME_Exception)
936 {
937   if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
938        theGroup1->GetType() != theGroup2->GetType() )
939     return SMESH::SMESH_Group::_nil();
940
941   // Create Intersection
942   SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
943   if ( aResGrp->_is_nil() )
944     return aResGrp;
945
946   SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
947   SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
948
949   TColStd_MapOfInteger aMap1;
950
951   for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
952     aMap1.Add( anIds1[ i1 ] );
953
954   TColStd_SequenceOfInteger aSeq;
955
956   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
957     if ( aMap1.Contains( anIds2[ i2 ] ) )
958       aSeq.Append( anIds2[ i2 ] );
959
960   SMESH::long_array_var aResIds = new SMESH::long_array;
961   aResIds->length( aSeq.Length() );
962
963   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
964     aResIds[ resI ] = aSeq( resI + 1 );
965
966   aResGrp->Add( aResIds );
967
968   // Clear python lines, created by CreateGroup() and Add()
969   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
970   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
971   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
972
973   // Update Python script
974   TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
975                 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
976
977   return aResGrp._retn();
978 }
979
980 //=============================================================================
981 /*! CutGroups
982  *  New group is created. All mesh elements that are present in
983  *  main group but do not present in tool group are added to the new one
984  */
985 //=============================================================================
986 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
987                                                 SMESH::SMESH_GroupBase_ptr theGroup2,
988                                                 const char* theName )
989   throw (SALOME::SALOME_Exception)
990 {
991   if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
992        theGroup1->GetType() != theGroup2->GetType() )
993     return SMESH::SMESH_Group::_nil();
994
995   // Perform Cutting
996   SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
997   if ( aResGrp->_is_nil() )
998     return aResGrp;
999
1000   SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1001   SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1002
1003   TColStd_MapOfInteger aMap2;
1004
1005   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1006     aMap2.Add( anIds2[ i2 ] );
1007
1008   TColStd_SequenceOfInteger aSeq;
1009   for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1010     if ( !aMap2.Contains( anIds1[ i1 ] ) )
1011       aSeq.Append( anIds1[ i1 ] );
1012
1013   SMESH::long_array_var aResIds = new SMESH::long_array;
1014   aResIds->length( aSeq.Length() );
1015
1016   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1017     aResIds[ resI ] = aSeq( resI + 1 );
1018
1019   aResGrp->Add( aResIds );
1020
1021   // Clear python lines, created by CreateGroup() and Add()
1022   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1023   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1024   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1025
1026   // Update Python script
1027   TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1028                 << theGroup1 << ", " << theGroup2 << ", '"
1029                 << theName << "' )";
1030
1031   return aResGrp._retn();
1032 }
1033
1034 //================================================================================
1035 /*!
1036  * \brief Remember GEOM group data
1037  */
1038 //================================================================================
1039
1040 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1041                                     CORBA::Object_ptr     theSmeshObj)
1042 {
1043   if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1044     return;
1045   // group SO
1046   SALOMEDS::Study_var   study  = _gen_i->GetCurrentStudy();
1047   SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1048   if ( groupSO->_is_nil() )
1049     return;
1050   // group indices
1051   GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1052   GEOM::GEOM_IGroupOperations_var groupOp =
1053     geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1054   GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1055
1056   // store data
1057   _geomGroupData.push_back( TGeomGroupData() );
1058   TGeomGroupData & groupData = _geomGroupData.back();
1059   // entry
1060   CORBA::String_var entry = groupSO->GetID();
1061   groupData._groupEntry = entry.in();
1062   // indices
1063   for ( int i = 0; i < ids->length(); ++i )
1064     groupData._indices.insert( ids[i] );
1065   // SMESH object
1066   groupData._smeshObject = theSmeshObj;
1067 }
1068
1069 //================================================================================
1070 /*!
1071  * Remove GEOM group data relating to removed smesh object
1072  */
1073 //================================================================================
1074
1075 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1076 {
1077   list<TGeomGroupData>::iterator
1078     data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1079   for ( ; data != dataEnd; ++data ) {
1080     if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1081       _geomGroupData.erase( data );
1082       return;
1083     }
1084   }
1085 }
1086
1087 //================================================================================
1088 /*!
1089  * \brief Return new group contents if it has been changed and update group data
1090  */
1091 //================================================================================
1092
1093 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1094 {
1095   TopoDS_Shape newShape;
1096
1097   // get geom group
1098   SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1099   if ( study->_is_nil() ) return newShape; // means "not changed"
1100   SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1101   if ( !groupSO->_is_nil() )
1102   {
1103     CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1104     if ( CORBA::is_nil( groupObj )) return newShape;
1105     GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1106     
1107     // get indices of group items
1108     set<int> curIndices;
1109     GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1110     GEOM::GEOM_IGroupOperations_var groupOp =
1111       geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1112     GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1113     for ( int i = 0; i < ids->length(); ++i )
1114       curIndices.insert( ids[i] );
1115
1116     if ( groupData._indices == curIndices )
1117       return newShape; // group not changed
1118
1119     // update data
1120     groupData._indices = curIndices;
1121
1122     GEOM_Client* geomClient = _gen_i->GetShapeReader();
1123     if ( !geomClient ) return newShape;
1124     TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1125     geomClient->RemoveShapeFromBuffer( groupIOR );
1126     newShape = _gen_i->GeomObjectToShape( geomGroup );
1127   }    
1128
1129   if ( newShape.IsNull() ) {
1130     // geom group becomes empty - return empty compound
1131     TopoDS_Compound compound;
1132     BRep_Builder    builder;
1133     builder.MakeCompound(compound);
1134     newShape = compound;
1135   }
1136   return newShape;
1137 }
1138
1139 //=============================================================================
1140 /*!
1141  * \brief Update objects depending on changed geom groups
1142  * 
1143  * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1144  * issue 0020210: Update of a smesh group after modification of the associated geom group
1145  */
1146 //=============================================================================
1147
1148 void SMESH_Mesh_i::CheckGeomGroupModif()
1149 {
1150   if ( !_impl->HasShapeToMesh() ) return;
1151
1152   SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1153   if ( study->_is_nil() ) return;
1154
1155   CORBA::Long nbEntities = NbNodes() + NbElements();
1156
1157   // Check if group contents changed
1158
1159   typedef map< string, TopoDS_Shape > TEntry2Geom;
1160   TEntry2Geom newGroupContents;
1161
1162   list<TGeomGroupData>::iterator
1163     data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1164   for ( ; data != dataEnd; ++data )
1165   {
1166     pair< TEntry2Geom::iterator, bool > it_new =
1167       newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1168     bool processedGroup    = !it_new.second;
1169     TopoDS_Shape& newShape = it_new.first->second;
1170     if ( !processedGroup )
1171       newShape = newGroupShape( *data );
1172     if ( newShape.IsNull() )
1173       continue; // no changes
1174
1175     if ( processedGroup ) { // update group indices
1176       list<TGeomGroupData>::iterator data2 = data;
1177       for ( --data2; data2->_groupEntry != data->_groupEntry; --data2)
1178         data->_indices = data2->_indices;
1179     }
1180
1181     // Update SMESH objects according to new GEOM group contents
1182
1183     SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1184     if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1185     {
1186       // TODO
1187       continue;
1188     }
1189
1190     SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1191     if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1192     {
1193       int oldID = submesh->GetId();
1194       if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1195         continue;
1196       TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1197
1198       // update hypotheses
1199       list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1200       list <const SMESHDS_Hypothesis * >::iterator hypIt;
1201       for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1202       {
1203         _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1204         _impl->AddHypothesis   ( newShape, (*hypIt)->GetID());
1205       }
1206       // care of submeshes
1207       SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1208       int newID = newSubmesh->GetId();
1209       if ( newID != oldID ) {
1210         _mapSubMesh   [ newID ] = newSubmesh;
1211         _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1212         _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1213         _mapSubMesh.   erase(oldID);
1214         _mapSubMesh_i. erase(oldID);
1215         _mapSubMeshIor.erase(oldID);
1216         _mapSubMesh_i [ newID ]->changeLocalId( newID );
1217       }
1218       continue;
1219     }
1220
1221     SMESH::SMESH_GroupOnGeom_var smeshGroup =
1222       SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1223     if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1224     {
1225       SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1226       if ( group_i ) {
1227         ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1228         SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1229         ds->SetShape( newShape );
1230       }
1231       continue;
1232     }
1233   }
1234
1235   // Update icons
1236
1237   CORBA::Long newNbEntities = NbNodes() + NbElements();
1238   list< SALOMEDS::SObject_var > soToUpdateIcons;
1239   if ( newNbEntities != nbEntities )
1240   {
1241     // Add all SObjects with icons
1242     soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1243
1244     for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1245          i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1246       soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1247
1248     for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1249           i_gr != _mapGroups.end(); ++i_gr ) // groups
1250       soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1251   }
1252
1253   list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1254   for ( ; so != soToUpdateIcons.end(); ++so )
1255     _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1256 }
1257
1258 //=============================================================================
1259 /*!
1260  *
1261  */
1262 //=============================================================================
1263
1264 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1265 {
1266   if(MYDEBUG) MESSAGE( "createSubMesh" );
1267   TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1268
1269   ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1270   int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1271   SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1272   SMESH::SMESH_subMesh_var subMesh
1273     = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1274
1275   _mapSubMesh[subMeshId] = mySubMesh;
1276   _mapSubMesh_i[subMeshId] = subMeshServant;
1277   _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1278
1279   // register CORBA object for persistence
1280   int nextId = _gen_i->RegisterObject( subMesh );
1281   if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1282
1283   // to track changes of GEOM groups
1284   addGeomGroupData( theSubShapeObject, subMesh );
1285
1286   return subMesh._retn();
1287 }
1288
1289 //=======================================================================
1290 //function : getSubMesh
1291 //purpose  :
1292 //=======================================================================
1293
1294 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
1295 {
1296   map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
1297   if ( it == _mapSubMeshIor.end() )
1298     return SMESH::SMESH_subMesh::_nil();
1299
1300   return SMESH::SMESH_subMesh::_duplicate( (*it).second );
1301 }
1302
1303
1304 //=============================================================================
1305 /*!
1306  *
1307  */
1308 //=============================================================================
1309
1310 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
1311                                   GEOM::GEOM_Object_ptr    theSubShapeObject )
1312 {
1313   MESSAGE("SMESH_Mesh_i::removeSubMesh()");
1314   if ( theSubMesh->_is_nil() || theSubShapeObject->_is_nil() )
1315     return;
1316
1317   try {
1318     SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
1319     for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
1320       removeHypothesis( theSubShapeObject, aHypList[i] );
1321     }
1322   }
1323   catch( const SALOME::SALOME_Exception& ) {
1324     INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
1325   }
1326   removeGeomGroupData( theSubShapeObject );
1327
1328   int subMeshId = theSubMesh->GetId();
1329
1330   _mapSubMesh.erase(subMeshId);
1331   _mapSubMesh_i.erase(subMeshId);
1332   _mapSubMeshIor.erase(subMeshId);
1333   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
1334 }
1335
1336 //=============================================================================
1337 /*!
1338  *
1339  */
1340 //=============================================================================
1341
1342 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
1343                                                       const char*         theName,
1344                                                       const TopoDS_Shape& theShape )
1345 {
1346   int anId;
1347   SMESH::SMESH_GroupBase_var aGroup;
1348   if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
1349     SMESH_GroupBase_i* aGroupImpl;
1350     if ( !theShape.IsNull() )
1351       aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
1352     else
1353       aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1354
1355     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1356     SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1357     aGroupImpl->Register();
1358     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1359
1360     aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
1361     _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1362
1363     // register CORBA object for persistence
1364     int nextId = _gen_i->RegisterObject( aGroup );
1365     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
1366
1367     // to track changes of GEOM groups
1368     if ( !theShape.IsNull() ) {
1369       GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
1370       addGeomGroupData( geom, aGroup );
1371     }
1372   }
1373   return aGroup._retn();
1374 }
1375
1376 //=============================================================================
1377 /*!
1378  * SMESH_Mesh_i::removeGroup
1379  *
1380  * Should be called by ~SMESH_Group_i()
1381  */
1382 //=============================================================================
1383
1384 void SMESH_Mesh_i::removeGroup( const int theId )
1385 {
1386   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
1387   if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
1388     removeGeomGroupData( _mapGroups[theId] );
1389     _mapGroups.erase( theId );
1390     _impl->RemoveGroup( theId );
1391   }
1392 }
1393
1394
1395 //=============================================================================
1396 /*!
1397  *
1398  */
1399 //=============================================================================
1400
1401 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
1402 throw(SALOME::SALOME_Exception)
1403 {
1404   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
1405
1406   SMESH::log_array_var aLog;
1407   try{
1408     list < SMESHDS_Command * >logDS = _impl->GetLog();
1409     aLog = new SMESH::log_array;
1410     int indexLog = 0;
1411     int lg = logDS.size();
1412     SCRUTE(lg);
1413     aLog->length(lg);
1414     list < SMESHDS_Command * >::iterator its = logDS.begin();
1415     while(its != logDS.end()){
1416       SMESHDS_Command *com = *its;
1417       int comType = com->GetType();
1418       //SCRUTE(comType);
1419       int lgcom = com->GetNumber();
1420       //SCRUTE(lgcom);
1421       const list < int >&intList = com->GetIndexes();
1422       int inum = intList.size();
1423       //SCRUTE(inum);
1424       list < int >::const_iterator ii = intList.begin();
1425       const list < double >&coordList = com->GetCoords();
1426       int rnum = coordList.size();
1427       //SCRUTE(rnum);
1428       list < double >::const_iterator ir = coordList.begin();
1429       aLog[indexLog].commandType = comType;
1430       aLog[indexLog].number = lgcom;
1431       aLog[indexLog].coords.length(rnum);
1432       aLog[indexLog].indexes.length(inum);
1433       for(int i = 0; i < rnum; i++){
1434         aLog[indexLog].coords[i] = *ir;
1435         //MESSAGE(" "<<i<<" "<<ir.Value());
1436         ir++;
1437       }
1438       for(int i = 0; i < inum; i++){
1439         aLog[indexLog].indexes[i] = *ii;
1440         //MESSAGE(" "<<i<<" "<<ii.Value());
1441         ii++;
1442       }
1443       indexLog++;
1444       its++;
1445     }
1446     if(clearAfterGet)
1447       _impl->ClearLog();
1448   }
1449   catch(SALOME_Exception & S_ex){
1450     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1451   }
1452   return aLog._retn();
1453 }
1454
1455
1456 //=============================================================================
1457 /*!
1458  *
1459  */
1460 //=============================================================================
1461
1462 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
1463 {
1464   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
1465   // ****
1466 }
1467
1468 //=============================================================================
1469 /*!
1470  *
1471  */
1472 //=============================================================================
1473
1474 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
1475 {
1476   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
1477   return _id;
1478 }
1479
1480 //=============================================================================
1481 /*!
1482  *
1483  */
1484 //=============================================================================
1485
1486 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
1487 {
1488   return _studyId;
1489 }
1490
1491 //=============================================================================
1492 /*!
1493  *
1494  */
1495 //=============================================================================
1496
1497 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
1498 {
1499   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
1500   _impl = impl;
1501 }
1502
1503 //=============================================================================
1504 /*!
1505  *
1506  */
1507 //=============================================================================
1508
1509 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
1510 {
1511   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
1512   return *_impl;
1513 }
1514
1515 //=============================================================================
1516 /*!
1517  * Return mesh editor
1518  */
1519 //=============================================================================
1520
1521 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
1522 {
1523   // Create MeshEditor
1524   SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
1525   SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
1526
1527   // Update Python script
1528   TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
1529
1530   return aMesh._retn();
1531 }
1532
1533 //=============================================================================
1534 /*!
1535  * Return mesh edition previewer
1536  */
1537 //=============================================================================
1538
1539 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
1540 {
1541   SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
1542   SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
1543   return aMesh._retn();
1544 }
1545
1546 //=============================================================================
1547 /*!
1548  *
1549  */
1550 //=============================================================================
1551 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
1552 {
1553   Unexpect aCatch(SALOME_SalomeException);
1554   _impl->SetAutoColor(theAutoColor);
1555 }
1556
1557 //=============================================================================
1558 /*!
1559  *
1560  */
1561 //=============================================================================
1562 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
1563 {
1564   Unexpect aCatch(SALOME_SalomeException);
1565   return _impl->GetAutoColor();
1566 }
1567
1568
1569 //=============================================================================
1570 /*!
1571  *  Export in different formats
1572  */
1573 //=============================================================================
1574
1575 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
1576 {
1577   return _impl->HasDuplicatedGroupNamesMED();
1578 }
1579
1580 void SMESH_Mesh_i::PrepareForWriting (const char* file)
1581 {
1582   TCollection_AsciiString aFullName ((char*)file);
1583   OSD_Path aPath (aFullName);
1584   OSD_File aFile (aPath);
1585   if (aFile.Exists()) {
1586     // existing filesystem node
1587     if (aFile.KindOfFile() == OSD_FILE) {
1588       if (aFile.IsWriteable()) {
1589         aFile.Reset();
1590         aFile.Remove();
1591         if (aFile.Failed()) {
1592           TCollection_AsciiString msg ("File ");
1593           msg += aFullName + " cannot be replaced.";
1594           THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1595         }
1596       } else {
1597         TCollection_AsciiString msg ("File ");
1598         msg += aFullName + " cannot be overwritten.";
1599         THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1600       }
1601     } else {
1602       TCollection_AsciiString msg ("Location ");
1603       msg += aFullName + " is not a file.";
1604       THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1605     }
1606   } else {
1607     // nonexisting file; check if it can be created
1608     aFile.Reset();
1609     aFile.Build(OSD_WriteOnly, OSD_Protection());
1610     if (aFile.Failed()) {
1611       TCollection_AsciiString msg ("You cannot create the file ");
1612       msg += aFullName + ". Check the directory existance and access rights.";
1613       THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1614     } else {
1615       aFile.Close();
1616       aFile.Remove();
1617     }
1618   }
1619 }
1620
1621 void SMESH_Mesh_i::ExportToMED (const char* file,
1622                                 CORBA::Boolean auto_groups,
1623                                 SMESH::MED_VERSION theVersion)
1624   throw(SALOME::SALOME_Exception)
1625 {
1626   Unexpect aCatch(SALOME_SalomeException);
1627
1628   // Update Python script
1629   TPythonDump() << _this() << ".ExportToMED( '"
1630                 << file << "', " << auto_groups << ", " << theVersion << " )";
1631
1632   // Perform Export
1633   PrepareForWriting(file);
1634   char* aMeshName = "Mesh";
1635   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1636   if ( !aStudy->_is_nil() ) {
1637     SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
1638     if ( !aMeshSO->_is_nil() ) {
1639       aMeshName = aMeshSO->GetName();
1640       //SCRUTE(file);
1641       //SCRUTE(aMeshName);
1642       //SCRUTE(aMeshSO->GetID());
1643
1644       // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
1645       if ( !aStudy->GetProperties()->IsLocked() )
1646         {
1647         SALOMEDS::GenericAttribute_var anAttr;
1648         SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
1649         SALOMEDS::AttributeExternalFileDef_var aFileName;
1650         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
1651         aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
1652         ASSERT(!aFileName->_is_nil());
1653         aFileName->SetValue(file);
1654         SALOMEDS::AttributeFileType_var aFileType;
1655         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
1656         aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
1657         ASSERT(!aFileType->_is_nil());
1658         aFileType->SetValue("FICHIERMED");
1659         }
1660     }
1661   }
1662   _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
1663 }
1664
1665 void SMESH_Mesh_i::ExportMED (const char* file,
1666                               CORBA::Boolean auto_groups)
1667   throw(SALOME::SALOME_Exception)
1668 {
1669   ExportToMED(file,auto_groups,SMESH::MED_V2_1);
1670 }
1671
1672 void SMESH_Mesh_i::ExportDAT (const char *file)
1673   throw(SALOME::SALOME_Exception)
1674 {
1675   Unexpect aCatch(SALOME_SalomeException);
1676
1677   // Update Python script
1678   TPythonDump() << _this() << ".ExportDAT( '" << file << "' )";
1679
1680   // Perform Export
1681   PrepareForWriting(file);
1682   _impl->ExportDAT(file);
1683 }
1684
1685 void SMESH_Mesh_i::ExportUNV (const char *file)
1686   throw(SALOME::SALOME_Exception)
1687 {
1688   Unexpect aCatch(SALOME_SalomeException);
1689
1690   // Update Python script
1691   TPythonDump() << _this() << ".ExportUNV( '" << file << "' )";
1692
1693   // Perform Export
1694   PrepareForWriting(file);
1695   _impl->ExportUNV(file);
1696 }
1697
1698 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
1699   throw(SALOME::SALOME_Exception)
1700 {
1701   Unexpect aCatch(SALOME_SalomeException);
1702
1703   // Update Python script
1704   TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )";
1705
1706   // Perform Export
1707   PrepareForWriting(file);
1708   _impl->ExportSTL(file, isascii);
1709 }
1710
1711 //=============================================================================
1712 /*!
1713  *
1714  */
1715 //=============================================================================
1716
1717 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
1718 {
1719   Unexpect aCatch(SALOME_SalomeException);
1720   SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
1721   SALOME_MED::MESH_var aMesh = aMedMesh->_this();
1722   return aMesh._retn();
1723 }
1724
1725 //=============================================================================
1726 /*!
1727  *
1728  */
1729 //=============================================================================
1730 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
1731 {
1732   Unexpect aCatch(SALOME_SalomeException);
1733   return _impl->NbNodes();
1734 }
1735
1736 //=============================================================================
1737 /*!
1738  *
1739  */
1740 //=============================================================================
1741 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
1742 {
1743   Unexpect aCatch(SALOME_SalomeException);
1744   return NbEdges() + NbFaces() + NbVolumes();
1745 }
1746
1747 //=============================================================================
1748 /*!
1749  *
1750  */
1751 //=============================================================================
1752 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
1753 {
1754   Unexpect aCatch(SALOME_SalomeException);
1755   return _impl->NbEdges();
1756 }
1757
1758 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
1759   throw(SALOME::SALOME_Exception)
1760 {
1761   Unexpect aCatch(SALOME_SalomeException);
1762   return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
1763 }
1764
1765 //=============================================================================
1766 /*!
1767  *
1768  */
1769 //=============================================================================
1770 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
1771 {
1772   Unexpect aCatch(SALOME_SalomeException);
1773   return _impl->NbFaces();
1774 }
1775
1776 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
1777 {
1778   Unexpect aCatch(SALOME_SalomeException);
1779   return _impl->NbTriangles();
1780 }
1781
1782 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
1783 {
1784   Unexpect aCatch(SALOME_SalomeException);
1785   return _impl->NbQuadrangles();
1786 }
1787
1788 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
1789 {
1790   Unexpect aCatch(SALOME_SalomeException);
1791   return _impl->NbPolygons();
1792 }
1793
1794 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
1795   throw(SALOME::SALOME_Exception)
1796 {
1797   Unexpect aCatch(SALOME_SalomeException);
1798   return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
1799 }
1800
1801 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
1802   throw(SALOME::SALOME_Exception)
1803 {
1804   Unexpect aCatch(SALOME_SalomeException);
1805   return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
1806 }
1807
1808 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
1809   throw(SALOME::SALOME_Exception)
1810 {
1811   Unexpect aCatch(SALOME_SalomeException);
1812   return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
1813 }
1814
1815 //=============================================================================
1816 /*!
1817  *
1818  */
1819 //=============================================================================
1820 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
1821 {
1822   Unexpect aCatch(SALOME_SalomeException);
1823   return _impl->NbVolumes();
1824 }
1825
1826 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
1827 {
1828   Unexpect aCatch(SALOME_SalomeException);
1829   return _impl->NbTetras();
1830 }
1831
1832 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
1833 {
1834   Unexpect aCatch(SALOME_SalomeException);
1835   return _impl->NbHexas();
1836 }
1837
1838 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
1839 {
1840   Unexpect aCatch(SALOME_SalomeException);
1841   return _impl->NbPyramids();
1842 }
1843
1844 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
1845 {
1846   Unexpect aCatch(SALOME_SalomeException);
1847   return _impl->NbPrisms();
1848 }
1849
1850 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
1851 {
1852   Unexpect aCatch(SALOME_SalomeException);
1853   return _impl->NbPolyhedrons();
1854 }
1855
1856 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
1857   throw(SALOME::SALOME_Exception)
1858 {
1859   Unexpect aCatch(SALOME_SalomeException);
1860   return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
1861 }
1862
1863 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
1864   throw(SALOME::SALOME_Exception)
1865 {
1866   Unexpect aCatch(SALOME_SalomeException);
1867   return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
1868 }
1869
1870 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
1871   throw(SALOME::SALOME_Exception)
1872 {
1873   Unexpect aCatch(SALOME_SalomeException);
1874   return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
1875 }
1876
1877 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
1878   throw(SALOME::SALOME_Exception)
1879 {
1880   Unexpect aCatch(SALOME_SalomeException);
1881   return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
1882 }
1883
1884 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
1885   throw(SALOME::SALOME_Exception)
1886 {
1887   Unexpect aCatch(SALOME_SalomeException);
1888   return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
1889 }
1890
1891 //=============================================================================
1892 /*!
1893  *
1894  */
1895 //=============================================================================
1896 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
1897 {
1898   Unexpect aCatch(SALOME_SalomeException);
1899   return _mapSubMesh_i.size();
1900 }
1901
1902 //=============================================================================
1903 /*!
1904  *
1905  */
1906 //=============================================================================
1907 char* SMESH_Mesh_i::Dump()
1908 {
1909   std::ostringstream os;
1910   _impl->Dump( os );
1911   return CORBA::string_dup( os.str().c_str() );
1912 }
1913
1914 //=============================================================================
1915 /*!
1916  *
1917  */
1918 //=============================================================================
1919 SMESH::long_array* SMESH_Mesh_i::GetIDs()
1920 {
1921 //   SMESH::long_array_var aResult = new SMESH::long_array();
1922 //   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1923 //   int aMinId = aSMESHDS_Mesh->MinElementID();
1924 //   int aMaxId =  aSMESHDS_Mesh->MaxElementID();
1925
1926 //   aResult->length(aMaxId - aMinId + 1);
1927
1928 //   for (int i = 0, id = aMinId; id <= aMaxId; id++  )
1929 //     aResult[i++] = id;
1930
1931 //   return aResult._retn();
1932   // PAL12398
1933   return GetElementsId();
1934 }
1935
1936 //=============================================================================
1937 /*!
1938  *
1939  */
1940 //=============================================================================
1941
1942 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
1943      throw (SALOME::SALOME_Exception)
1944 {
1945   Unexpect aCatch(SALOME_SalomeException);
1946   MESSAGE("SMESH_Mesh_i::GetElementsId");
1947   SMESH::long_array_var aResult = new SMESH::long_array();
1948   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1949
1950   if ( aSMESHDS_Mesh == NULL )
1951     return aResult._retn();
1952
1953   long nbElements = NbElements();
1954   aResult->length( nbElements );
1955   SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
1956   for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
1957     aResult[i] = anIt->next()->GetID();
1958
1959   return aResult._retn();
1960 }
1961
1962
1963 //=============================================================================
1964 /*!
1965  *
1966  */
1967 //=============================================================================
1968
1969 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
1970     throw (SALOME::SALOME_Exception)
1971 {
1972   Unexpect aCatch(SALOME_SalomeException);
1973   MESSAGE("SMESH_subMesh_i::GetElementsByType");
1974   SMESH::long_array_var aResult = new SMESH::long_array();
1975   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1976
1977   if ( aSMESHDS_Mesh == NULL )
1978     return aResult._retn();
1979
1980   long nbElements = NbElements();
1981
1982   // No sense in returning ids of elements along with ids of nodes:
1983   // when theElemType == SMESH::ALL, return node ids only if
1984   // there are no elements
1985   if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
1986     return GetNodesId();
1987
1988   aResult->length( nbElements );
1989
1990   int i = 0;
1991
1992   SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
1993   while ( i < nbElements && anIt->more() ) {
1994     const SMDS_MeshElement* anElem = anIt->next();
1995     if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
1996       aResult[i++] = anElem->GetID();
1997   }
1998
1999   aResult->length( i );
2000
2001   return aResult._retn();
2002 }
2003
2004 //=============================================================================
2005 /*!
2006  *
2007  */
2008 //=============================================================================
2009
2010 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2011   throw (SALOME::SALOME_Exception)
2012 {
2013   Unexpect aCatch(SALOME_SalomeException);
2014   MESSAGE("SMESH_subMesh_i::GetNodesId");
2015   SMESH::long_array_var aResult = new SMESH::long_array();
2016   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2017
2018   if ( aSMESHDS_Mesh == NULL )
2019     return aResult._retn();
2020
2021   long nbNodes = NbNodes();
2022   aResult->length( nbNodes );
2023   SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
2024   for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2025     aResult[i] = anIt->next()->GetID();
2026
2027   return aResult._retn();
2028 }
2029
2030 //=============================================================================
2031 /*!
2032  *
2033  */
2034 //=============================================================================
2035
2036 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2037   throw (SALOME::SALOME_Exception)
2038 {
2039   return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2040 }
2041
2042
2043 //=============================================================================
2044 /*!
2045  * Returns ID of elements for given submesh
2046  */
2047 //=============================================================================
2048 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2049      throw (SALOME::SALOME_Exception)
2050 {
2051   SMESH::long_array_var aResult = new SMESH::long_array();
2052
2053   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2054   if(!SM) return aResult._retn();
2055
2056   SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2057   if(!SDSM) return aResult._retn();
2058
2059   aResult->length(SDSM->NbElements());
2060
2061   SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2062   int i = 0;
2063   while ( eIt->more() ) {
2064     aResult[i++] = eIt->next()->GetID();
2065   }
2066
2067   return aResult._retn();
2068 }
2069
2070
2071 //=============================================================================
2072 /*!
2073  * Returns ID of nodes for given submesh
2074  * If param all==true - returns all nodes, else -
2075  * returns only nodes on shapes.
2076  */
2077 //=============================================================================
2078 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2079      throw (SALOME::SALOME_Exception)
2080 {
2081   SMESH::long_array_var aResult = new SMESH::long_array();
2082
2083   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2084   if(!SM) return aResult._retn();
2085
2086   SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2087   if(!SDSM) return aResult._retn();
2088
2089   set<int> theElems;
2090   if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2091     SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2092     while ( nIt->more() ) {
2093       const SMDS_MeshNode* elem = nIt->next();
2094       theElems.insert( elem->GetID() );
2095     }
2096   }
2097   else { // all nodes of submesh elements
2098     SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2099     while ( eIt->more() ) {
2100       const SMDS_MeshElement* anElem = eIt->next();
2101       SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2102       while ( nIt->more() ) {
2103         const SMDS_MeshElement* elem = nIt->next();
2104         theElems.insert( elem->GetID() );
2105       }
2106     }
2107   }
2108
2109   aResult->length(theElems.size());
2110   set<int>::iterator itElem;
2111   int i = 0;
2112   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2113     aResult[i++] = *itElem;
2114
2115   return aResult._retn();
2116 }
2117   
2118
2119 //=============================================================================
2120 /*!
2121  * Returns type of elements for given submesh
2122  */
2123 //=============================================================================
2124 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2125      throw (SALOME::SALOME_Exception)
2126 {
2127   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2128   if(!SM) return SMESH::ALL;
2129
2130   SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2131   if(!SDSM) return SMESH::ALL;
2132
2133   if(SDSM->NbElements()==0)
2134     return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2135
2136   SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2137   const SMDS_MeshElement* anElem = eIt->next();
2138   return ( SMESH::ElementType ) anElem->GetType();
2139 }
2140   
2141
2142 //=============================================================================
2143 /*!
2144  *
2145  */
2146 //=============================================================================
2147
2148 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2149 {
2150   CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2151   if ( MYDEBUG )
2152     MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2153   return pointeur;
2154 }
2155
2156
2157 //=============================================================================
2158 /*!
2159  * Get XYZ coordinates of node as list of double
2160  * If there is not node for given ID - returns empty list
2161  */
2162 //=============================================================================
2163
2164 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2165 {
2166   SMESH::double_array_var aResult = new SMESH::double_array();
2167   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2168   if ( aSMESHDS_Mesh == NULL )
2169     return aResult._retn();
2170
2171   // find node
2172   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2173   if(!aNode)
2174     return aResult._retn();
2175
2176   // add coordinates
2177   aResult->length(3);
2178   aResult[0] = aNode->X();
2179   aResult[1] = aNode->Y();
2180   aResult[2] = aNode->Z();
2181   return aResult._retn();
2182 }
2183
2184
2185 //=============================================================================
2186 /*!
2187  * For given node returns list of IDs of inverse elements
2188  * If there is not node for given ID - returns empty list
2189  */
2190 //=============================================================================
2191
2192 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2193 {
2194   SMESH::long_array_var aResult = new SMESH::long_array();
2195   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2196   if ( aSMESHDS_Mesh == NULL )
2197     return aResult._retn();
2198
2199   // find node
2200   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2201   if(!aNode)
2202     return aResult._retn();
2203
2204   // find inverse elements
2205   SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
2206   TColStd_SequenceOfInteger IDs;
2207   while(eIt->more()) {
2208     const SMDS_MeshElement* elem = eIt->next();
2209     IDs.Append(elem->GetID());
2210   }
2211   if(IDs.Length()>0) {
2212     aResult->length(IDs.Length());
2213     int i = 1;
2214     for(; i<=IDs.Length(); i++) {
2215       aResult[i-1] = IDs.Value(i);
2216     }
2217   }
2218   return aResult._retn();
2219 }
2220
2221 //=============================================================================
2222 /*!
2223  * \brief Return position of a node on shape
2224  */
2225 //=============================================================================
2226
2227 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
2228 {
2229   SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
2230   aNodePosition->shapeID = 0;
2231   aNodePosition->shapeType = GEOM::SHAPE;
2232
2233   SMESHDS_Mesh* mesh = _impl->GetMeshDS();
2234   if ( !mesh ) return aNodePosition;
2235
2236   if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
2237   {
2238     if ( SMDS_PositionPtr pos = aNode->GetPosition() )
2239     {
2240       aNodePosition->shapeID = pos->GetShapeId();
2241       switch ( pos->GetTypeOfPosition() ) {
2242       case SMDS_TOP_EDGE:
2243         aNodePosition->shapeType = GEOM::EDGE;
2244         aNodePosition->params.length(1);
2245         aNodePosition->params[0] =
2246           static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
2247         break;
2248       case SMDS_TOP_FACE:
2249         aNodePosition->shapeType = GEOM::FACE;
2250         aNodePosition->params.length(2);
2251         aNodePosition->params[0] =
2252           static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
2253         aNodePosition->params[1] =
2254           static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
2255         break;
2256       case SMDS_TOP_VERTEX:
2257         aNodePosition->shapeType = GEOM::VERTEX;
2258         break;
2259       case SMDS_TOP_3DSPACE:
2260         if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
2261           aNodePosition->shapeType = GEOM::SOLID;
2262         else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
2263           aNodePosition->shapeType = GEOM::SHELL;
2264         break;
2265       default:;
2266       }
2267     }
2268   }
2269   return aNodePosition;
2270 }
2271
2272 //=============================================================================
2273 /*!
2274  * If given element is node returns IDs of shape from position
2275  * If there is not node for given ID - returns -1
2276  */
2277 //=============================================================================
2278
2279 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
2280 {
2281   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2282   if ( aSMESHDS_Mesh == NULL )
2283     return -1;
2284
2285   // try to find node
2286   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2287   if(aNode) {
2288     SMDS_PositionPtr pos = aNode->GetPosition();
2289     if(!pos)
2290       return -1;
2291     else
2292       return pos->GetShapeId();
2293   }
2294
2295   return -1;
2296 }
2297
2298
2299 //=============================================================================
2300 /*!
2301  * For given element returns ID of result shape after 
2302  * ::FindShape() from SMESH_MeshEditor
2303  * If there is not element for given ID - returns -1
2304  */
2305 //=============================================================================
2306
2307 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
2308 {
2309   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2310   if ( aSMESHDS_Mesh == NULL )
2311     return -1;
2312
2313   // try to find element
2314   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2315   if(!elem)
2316     return -1;
2317
2318   //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
2319   ::SMESH_MeshEditor aMeshEditor(_impl);
2320   int index = aMeshEditor.FindShape( elem );
2321   if(index>0)
2322     return index;
2323
2324   return -1;
2325 }
2326
2327
2328 //=============================================================================
2329 /*!
2330  * Returns number of nodes for given element
2331  * If there is not element for given ID - returns -1
2332  */
2333 //=============================================================================
2334
2335 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
2336 {
2337   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2338   if ( aSMESHDS_Mesh == NULL ) return -1;
2339   // try to find element
2340   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2341   if(!elem) return -1;
2342   return elem->NbNodes();
2343 }
2344
2345
2346 //=============================================================================
2347 /*!
2348  * Returns ID of node by given index for given element
2349  * If there is not element for given ID - returns -1
2350  * If there is not node for given index - returns -2
2351  */
2352 //=============================================================================
2353
2354 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
2355 {
2356   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2357   if ( aSMESHDS_Mesh == NULL ) return -1;
2358   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2359   if(!elem) return -1;
2360   if( index>=elem->NbNodes() || index<0 ) return -1;
2361   return elem->GetNode(index)->GetID();
2362 }
2363
2364 //=============================================================================
2365 /*!
2366  * Returns IDs of nodes of given element
2367  */
2368 //=============================================================================
2369
2370 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
2371 {
2372   SMESH::long_array_var aResult = new SMESH::long_array();
2373   if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
2374   {
2375     if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
2376     {
2377       aResult->length( elem->NbNodes() );
2378       for ( int i = 0; i < elem->NbNodes(); ++i )
2379         aResult[ i ] = elem->GetNode( i )->GetID();
2380     }
2381   }
2382   return aResult._retn();
2383 }
2384
2385 //=============================================================================
2386 /*!
2387  * Returns true if given node is medium node
2388  * in given quadratic element
2389  */
2390 //=============================================================================
2391
2392 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
2393 {
2394   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2395   if ( aSMESHDS_Mesh == NULL ) return false;
2396   // try to find node
2397   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
2398   if(!aNode) return false;
2399   // try to find element
2400   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
2401   if(!elem) return false;
2402
2403   return elem->IsMediumNode(aNode);
2404 }
2405
2406
2407 //=============================================================================
2408 /*!
2409  * Returns true if given node is medium node
2410  * in one of quadratic elements
2411  */
2412 //=============================================================================
2413
2414 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
2415                                                    SMESH::ElementType theElemType)
2416 {
2417   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2418   if ( aSMESHDS_Mesh == NULL ) return false;
2419
2420   // try to find node
2421   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
2422   if(!aNode) return false;
2423
2424   SMESH_MesherHelper aHelper( *(_impl) );
2425
2426   SMDSAbs_ElementType aType;
2427   if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
2428   else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
2429   else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
2430   else aType = SMDSAbs_All;
2431
2432   return aHelper.IsMedium(aNode,aType);
2433 }
2434
2435
2436 //=============================================================================
2437 /*!
2438  * Returns number of edges for given element
2439  */
2440 //=============================================================================
2441
2442 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
2443 {
2444   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2445   if ( aSMESHDS_Mesh == NULL ) return -1;
2446   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2447   if(!elem) return -1;
2448   return elem->NbEdges();
2449 }
2450
2451
2452 //=============================================================================
2453 /*!
2454  * Returns number of faces for given element
2455  */
2456 //=============================================================================
2457
2458 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
2459 {
2460   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2461   if ( aSMESHDS_Mesh == NULL ) return -1;
2462   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2463   if(!elem) return -1;
2464   return elem->NbFaces();
2465 }
2466
2467
2468 //=============================================================================
2469 /*!
2470  * Returns true if given element is polygon
2471  */
2472 //=============================================================================
2473
2474 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
2475 {
2476   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2477   if ( aSMESHDS_Mesh == NULL ) return false;
2478   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2479   if(!elem) return false;
2480   return elem->IsPoly();
2481 }
2482
2483
2484 //=============================================================================
2485 /*!
2486  * Returns true if given element is quadratic
2487  */
2488 //=============================================================================
2489
2490 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
2491 {
2492   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2493   if ( aSMESHDS_Mesh == NULL ) return false;
2494   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2495   if(!elem) return false;
2496   return elem->IsQuadratic();
2497 }
2498
2499
2500 //=============================================================================
2501 /*!
2502  * Returns bary center for given element
2503  */
2504 //=============================================================================
2505
2506 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
2507 {
2508   SMESH::double_array_var aResult = new SMESH::double_array();
2509   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2510   if ( aSMESHDS_Mesh == NULL )
2511     return aResult._retn();
2512
2513   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2514   if(!elem)
2515     return aResult._retn();
2516
2517   if(elem->GetType()==SMDSAbs_Volume) {
2518     SMDS_VolumeTool aTool;
2519     if(aTool.Set(elem)) {
2520       aResult->length(3);
2521       if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
2522         aResult->length(0);
2523     }
2524   }
2525   else {
2526     SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
2527     int nbn = 0;
2528     double x=0., y=0., z=0.;
2529     for(; anIt->more(); ) {
2530       nbn++;
2531       const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
2532       x += aNode->X();
2533       y += aNode->Y();
2534       z += aNode->Z();
2535     }
2536     if(nbn>0) {
2537       // add coordinates
2538       aResult->length(3);
2539       aResult[0] = x/nbn;
2540       aResult[1] = y/nbn;
2541       aResult[2] = z/nbn;
2542     }
2543   }
2544
2545   return aResult._retn();
2546 }
2547
2548
2549 //=============================================================================
2550 /*!
2551  * Create and publish group servants if any groups were imported or created anyhow
2552  */
2553 //=============================================================================
2554
2555 void SMESH_Mesh_i::CreateGroupServants() 
2556 {
2557   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2558
2559   ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
2560   while ( groupIt->more() )
2561   {
2562     ::SMESH_Group* group = groupIt->next();
2563     int            anId = group->GetGroupDS()->GetID();
2564
2565     map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
2566     if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
2567       continue;
2568
2569     SMESH_GroupBase_i* aGroupImpl;
2570     TopoDS_Shape       shape;
2571     if ( SMESHDS_GroupOnGeom* groupOnGeom =
2572          dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
2573     {
2574       aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2575       shape      = groupOnGeom->GetShape();
2576     }
2577     else {
2578       aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2579     }
2580
2581     // To ensure correct mapping of servant and correct reference counting in GenericObj_i
2582     SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2583     aGroupImpl->Register();
2584
2585     SMESH::SMESH_GroupBase_var groupVar =
2586       SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2587     _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
2588
2589     // register CORBA object for persistence
2590     int nextId = _gen_i->RegisterObject( groupVar );
2591     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2592
2593     // publishing of the groups in the study
2594     if ( !aStudy->_is_nil() ) {
2595       GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
2596       _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
2597     }
2598   }
2599 }
2600
2601 //=============================================================================
2602 /*!
2603  * \brief Return groups cantained in _mapGroups by their IDs
2604  */
2605 //=============================================================================
2606
2607 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
2608 {
2609   int nbGroups = groupIDs.size();
2610   SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
2611   aList->length( nbGroups );
2612
2613   list<int>::const_iterator ids = groupIDs.begin();
2614   for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
2615   {
2616     map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
2617     if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
2618       aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
2619   }
2620   aList->length( nbGroups );
2621   return aList._retn();
2622 }
2623
2624 //=============================================================================
2625 /*!
2626  * \brief Return information about imported file
2627  */
2628 //=============================================================================
2629
2630 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
2631 {
2632   SALOME_MED::MedFileInfo_var res( myFileInfo );
2633   if ( !res.operator->() ) {
2634     res = new SALOME_MED::MedFileInfo;
2635     res->fileName = "";
2636     res->fileSize = res->major = res->minor = res->release = -1;
2637   }
2638   return res._retn();
2639 }