]> SALOME platform Git repositories - modules/smesh.git/blob - src/SMESH_I/SMESH_Mesh_i.cxx
Salome HOME
0019939: EDF 762 SMESH : Definition of groups from other existing groups
[modules/smesh.git] / src / SMESH_I / SMESH_Mesh_i.cxx
1 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //
23 //
24 //  File   : SMESH_Mesh_i.cxx
25 //  Author : Paul RASCLE, EDF
26 //  Module : SMESH
27 //  $Header$
28
29 #include "SMESH_Mesh_i.hxx"
30
31 #include "SMESH_Filter_i.hxx"
32 #include "SMESH_Gen_i.hxx"
33 #include "SMESH_Group_i.hxx"
34 #include "SMESH_MEDMesh_i.hxx"
35 #include "SMESH_MeshEditor_i.hxx"
36 #include "SMESH_PythonDump.hxx"
37 #include "SMESH_subMesh_i.hxx"
38
39 #include "DriverMED_R_SMESHDS_Mesh.h"
40 #include "DriverMED_W_SMESHDS_Mesh.h"
41 #include "SMDS_VolumeTool.hxx"
42 #include "SMESHDS_Command.hxx"
43 #include "SMESHDS_CommandType.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Group.hxx"
46 #include "SMESH_MeshEditor.hxx"
47 #include "SMESH_MesherHelper.hxx"
48 #include "SMDS_EdgePosition.hxx"
49 #include "SMDS_FacePosition.hxx"
50
51 #include "OpUtil.hxx"
52 #include "SALOME_NamingService.hxx"
53 #include "Utils_CorbaException.hxx"
54 #include "Utils_ExceptHandlers.hxx"
55 #include "Utils_SINGLETON.hxx"
56 #include "utilities.h"
57
58 // OCCT Includes
59 #include <BRep_Builder.hxx>
60 #include <OSD_Directory.hxx>
61 #include <OSD_File.hxx>
62 #include <OSD_Path.hxx>
63 #include <OSD_Protection.hxx>
64 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
65 #include <TColStd_MapOfInteger.hxx>
66 #include <TColStd_SequenceOfInteger.hxx>
67 #include <TCollection_AsciiString.hxx>
68 #include <TopExp_Explorer.hxx>
69 #include <TopoDS_Compound.hxx>
70
71 // STL Includes
72 #include <string>
73 #include <iostream>
74 #include <sstream>
75 #include <sys/stat.h>
76
77 #ifdef _DEBUG_
78 static int MYDEBUG = 0;
79 #else
80 static int MYDEBUG = 0;
81 #endif
82
83 using namespace std;
84 using SMESH::TPythonDump;
85
86 int SMESH_Mesh_i::myIdGenerator = 0;
87
88
89
90 //=============================================================================
91 /*!
92  *  Constructor
93  */
94 //=============================================================================
95
96 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
97                             SMESH_Gen_i*            gen_i,
98                             CORBA::Long studyId )
99 : SALOME::GenericObj_i( thePOA )
100 {
101   MESSAGE("SMESH_Mesh_i");
102   _impl = NULL;
103   _gen_i = gen_i;
104   _id = myIdGenerator++;
105   _studyId = studyId;
106 }
107
108 //=============================================================================
109 /*!
110  *  Destructor
111  */
112 //=============================================================================
113
114 SMESH_Mesh_i::~SMESH_Mesh_i()
115 {
116   INFOS("~SMESH_Mesh_i");
117   map<int, SMESH::SMESH_GroupBase_ptr>::iterator it;
118   for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) {
119     SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( it->second ).in() );
120     if ( aGroup ) {
121       // this method is colled from destructor of group (PAL6331)
122       //_impl->RemoveGroup( aGroup->GetLocalID() );
123       
124       aGroup->Destroy();
125     }
126   }
127   _mapGroups.clear();
128   delete _impl;
129 }
130
131 //=============================================================================
132 /*!
133  *  SetShape
134  *
135  *  Associates <this> mesh with <theShape> and puts a reference
136  *  to <theShape> into the current study;
137  *  the previous shape is substituted by the new one.
138  */
139 //=============================================================================
140
141 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
142     throw (SALOME::SALOME_Exception)
143 {
144   Unexpect aCatch(SALOME_SalomeException);
145   try {
146     _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
147   }
148   catch(SALOME_Exception & S_ex) {
149     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
150   }
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
608     if ( _gen_i->CanPublishInStudy( subMesh )) {
609       SALOMEDS::SObject_var aSO =
610         _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
611                                subMesh, aSubShapeObject, theName );
612       if ( !aSO->_is_nil()) {
613         // Update Python script
614         TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
615                       << aSubShapeObject << ", '" << theName << "' )";
616       }
617     }
618   }
619   catch(SALOME_Exception & S_ex) {
620     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
621   }
622   return subMesh._retn();
623 }
624
625 //=============================================================================
626 /*!
627  *
628  */
629 //=============================================================================
630
631 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
632      throw (SALOME::SALOME_Exception)
633 {
634   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
635   if ( theSubMesh->_is_nil() )
636     return;
637
638   GEOM::GEOM_Object_var aSubShapeObject;
639   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
640   if ( !aStudy->_is_nil() )  {
641     // Remove submesh's SObject
642     SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
643     if ( !anSO->_is_nil() ) {
644       long aTag = SMESH_Gen_i::GetRefOnShapeTag();
645       SALOMEDS::SObject_var anObj, aRef;
646       if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
647         aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
648
649       aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
650
651       // Update Python script
652       TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
653     }
654   }
655
656   removeSubMesh( theSubMesh, aSubShapeObject.in() );
657 }
658
659 //=============================================================================
660 /*!
661  *  ElementTypeString
662  */
663 //=============================================================================
664 #define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
665 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
666 {
667   switch (theElemType) {
668     CASE2STRING( ALL );
669     CASE2STRING( NODE );
670     CASE2STRING( EDGE );
671     CASE2STRING( FACE );
672     CASE2STRING( VOLUME );
673   default:;
674   }
675   return "";
676 }
677
678 //=============================================================================
679 /*!
680  *
681  */
682 //=============================================================================
683
684 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
685                                                  const char*         theName )
686      throw(SALOME::SALOME_Exception)
687 {
688   Unexpect aCatch(SALOME_SalomeException);
689   SMESH::SMESH_Group_var aNewGroup =
690     SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
691
692   if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
693     SALOMEDS::SObject_var aSO =
694       _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
695                            aNewGroup, GEOM::GEOM_Object::_nil(), theName);
696     if ( !aSO->_is_nil()) {
697       // Update Python script
698       TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
699                     << ElementTypeString(theElemType) << ", '" << theName << "' )";
700     }
701   }
702   return aNewGroup._retn();
703 }
704
705
706 //=============================================================================
707 /*!
708  *
709  */
710 //=============================================================================
711 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType    theElemType,
712                                                                 const char*           theName,
713                                                                 GEOM::GEOM_Object_ptr theGeomObj)
714      throw(SALOME::SALOME_Exception)
715 {
716   Unexpect aCatch(SALOME_SalomeException);
717   SMESH::SMESH_GroupOnGeom_var aNewGroup;
718
719   TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
720   if ( !aShape.IsNull() ) {
721     aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
722       ( createGroup( theElemType, theName, aShape ));
723     if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
724       SALOMEDS::SObject_var aSO =
725         _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
726                              aNewGroup, theGeomObj, theName);
727       if ( !aSO->_is_nil()) {
728         // Update Python script
729         TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
730                       << ElementTypeString(theElemType) << ", '" << theName << "', "
731                       << theGeomObj << " )";
732       }
733     }
734   }
735
736   return aNewGroup._retn();
737 }
738
739 //=============================================================================
740 /*!
741  *
742  */
743 //=============================================================================
744
745 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
746      throw (SALOME::SALOME_Exception)
747 {
748   if ( theGroup->_is_nil() )
749     return;
750
751   SMESH_GroupBase_i* aGroup =
752     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
753   if ( !aGroup )
754     return;
755
756   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
757   if ( !aStudy->_is_nil() )  {
758     SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
759
760     if ( !aGroupSO->_is_nil() ) {
761       // Update Python script
762       TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
763
764       // Remove group's SObject
765       aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
766     }
767   }
768
769   // Remove the group from SMESH data structures
770   removeGroup( aGroup->GetLocalID() );
771 }
772
773 //=============================================================================
774 /*! RemoveGroupWithContents
775  *  Remove group with its contents
776  */
777 //=============================================================================
778 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
779   throw (SALOME::SALOME_Exception)
780 {
781   if ( theGroup->_is_nil() )
782     return;
783
784   SMESH_GroupBase_i* aGroup =
785     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
786   if ( !aGroup )
787     return;
788
789   SMESH::long_array_var anIds = aGroup->GetListOfID();
790   SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
791
792   // Update Python script
793   TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
794
795   // Remove contents
796   if ( aGroup->GetType() == SMESH::NODE )
797     aMeshEditor->RemoveNodes( anIds );
798   else
799     aMeshEditor->RemoveElements( anIds );
800
801   // Remove group
802   RemoveGroup( theGroup );
803
804   // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
805   _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
806   _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
807 }
808
809
810 //================================================================================
811 /*!
812  * \brief Get the list of groups existing in the mesh
813   * \retval SMESH::ListOfGroups * - list of groups
814  */
815 //================================================================================
816
817 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
818 {
819   Unexpect aCatch(SALOME_SalomeException);
820   if (MYDEBUG) MESSAGE("GetGroups");
821
822   SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
823
824   // Python Dump
825   TPythonDump aPythonDump;
826   if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
827     aPythonDump << "[ ";
828
829   try {
830     aList->length( _mapGroups.size() );
831     int i = 0;
832     map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
833     for ( ; it != _mapGroups.end(); it++ ) {
834       if ( CORBA::is_nil( it->second )) continue;
835       aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
836       // Python Dump
837       if (i > 1) aPythonDump << ", ";
838       aPythonDump << it->second;
839     }
840     aList->length( i );
841   }
842   catch(SALOME_Exception & S_ex) {
843     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
844   }
845
846   // Update Python script
847   if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
848     aPythonDump << " ] = " << _this() << ".GetGroups()";
849
850   return aList._retn();
851 }
852 //=============================================================================
853 /*!
854  *  Get number of groups existing in the mesh
855  */
856 //=============================================================================
857
858 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
859 {
860   Unexpect aCatch(SALOME_SalomeException);
861   return _mapGroups.size();
862 }
863
864 //=============================================================================
865 /*! UnionGroups
866  *  New group is created. All mesh elements that are
867  *  present in initial groups are added to the new one
868  */
869 //=============================================================================
870 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
871                                                   SMESH::SMESH_GroupBase_ptr theGroup2,
872                                                   const char* theName )
873   throw (SALOME::SALOME_Exception)
874 {
875   try
876   {
877     if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
878          theGroup1->GetType() != theGroup2->GetType() )
879       return SMESH::SMESH_Group::_nil();
880
881     // Create Union
882     SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
883     if ( aResGrp->_is_nil() )
884       return SMESH::SMESH_Group::_nil();
885
886     SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
887     SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
888
889     TColStd_MapOfInteger aResMap;
890
891     for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
892       aResMap.Add( anIds1[ i1 ] );
893
894     for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
895       aResMap.Add( anIds2[ i2 ] );
896
897     SMESH::long_array_var aResIds = new SMESH::long_array;
898     aResIds->length( aResMap.Extent() );
899
900     int resI = 0;
901     TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
902     for( ; anIter.More(); anIter.Next() )
903       aResIds[ resI++ ] = anIter.Key();
904
905     aResGrp->Add( aResIds );
906
907     // Clear python lines, created by CreateGroup() and Add()
908     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
909     _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
910     _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
911
912     // Update Python script
913     TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
914                   << theGroup1 << ", " << theGroup2 << ", '"
915                   << theName << "' )";
916
917     return aResGrp._retn();
918   }
919   catch( ... )
920   {
921     return SMESH::SMESH_Group::_nil();
922   }
923 }
924
925 //=============================================================================
926 /*!
927   \brief Union list of groups. New group is created. All mesh elements that are
928    present in initial groups are added to the new one.
929   \param theGroups list of groups
930   \param theName name of group to be created
931   \return pointer on the group
932 */
933 //=============================================================================
934 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups( 
935   const SMESH::ListOfGroups& theGroups, const char* theName )
936 throw (SALOME::SALOME_Exception)
937 {
938   if ( !theName )
939     return SMESH::SMESH_Group::_nil();
940
941   try
942   {
943     NCollection_Map< int > anIds;
944     SMESH::ElementType aType = SMESH::ALL;
945     for ( int g = 0, n = theGroups.length(); g < n; g++ )
946     {
947       SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
948       if ( CORBA::is_nil( aGrp ) )
949         continue;
950
951       // check type
952       SMESH::ElementType aCurrType = aGrp->GetType();
953       if ( aType == SMESH::ALL )
954         aType = aCurrType;
955       else 
956       {
957         if ( aType != aCurrType )
958           return SMESH::SMESH_Group::_nil();
959       }
960
961       // unite ids
962       SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
963       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
964       {
965         int aCurrId = aCurrIds[ i ];
966         anIds.Add( aCurrId );
967       }
968     }
969
970     // Create group
971     SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
972     if ( aResGrp->_is_nil() )
973       return SMESH::SMESH_Group::_nil();
974     
975     // Create array of identifiers
976     SMESH::long_array_var aResIds = new SMESH::long_array;
977     aResIds->length( anIds.Extent() );
978     
979     NCollection_Map< int >::Iterator anIter( anIds );
980     for ( int i = 0; anIter.More(); anIter.Next(), i++ )
981     {
982       aResIds[ i ] = anIter.Value();
983     }
984     aResGrp->Add( aResIds );
985
986     // Clear python lines, created by CreateGroup() and Add()
987     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
988     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
989     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
990
991     // Update Python script
992     
993     TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
994                   << &theGroups << ", '" << theName << "' )";
995
996     return aResGrp._retn();
997   }
998   catch( ... )
999   {
1000     return SMESH::SMESH_Group::_nil();
1001   }
1002 }
1003
1004 //=============================================================================
1005 /*! IntersectGroups
1006  *  New group is created. All mesh elements that are
1007  *  present in both initial groups are added to the new one.
1008  */
1009 //=============================================================================
1010 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1011                                                       SMESH::SMESH_GroupBase_ptr theGroup2,
1012                                                       const char* theName )
1013   throw (SALOME::SALOME_Exception)
1014 {
1015   if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1016        theGroup1->GetType() != theGroup2->GetType() )
1017     return SMESH::SMESH_Group::_nil();
1018
1019   // Create Intersection
1020   SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1021   if ( aResGrp->_is_nil() )
1022     return aResGrp;
1023
1024   SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1025   SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1026
1027   TColStd_MapOfInteger aMap1;
1028
1029   for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1030     aMap1.Add( anIds1[ i1 ] );
1031
1032   TColStd_SequenceOfInteger aSeq;
1033
1034   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1035     if ( aMap1.Contains( anIds2[ i2 ] ) )
1036       aSeq.Append( anIds2[ i2 ] );
1037
1038   SMESH::long_array_var aResIds = new SMESH::long_array;
1039   aResIds->length( aSeq.Length() );
1040
1041   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1042     aResIds[ resI ] = aSeq( resI + 1 );
1043
1044   aResGrp->Add( aResIds );
1045
1046   // Clear python lines, created by CreateGroup() and Add()
1047   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1048   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1049   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1050
1051   // Update Python script
1052   TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1053                 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1054
1055   return aResGrp._retn();
1056 }
1057
1058 //=============================================================================
1059 /*!
1060   \brief Intersect list of groups. New group is created. All mesh elements that 
1061   are present in all initial groups simultaneously are added to the new one.
1062   \param theGroups list of groups
1063   \param theName name of group to be created
1064   \return pointer on the group
1065 */
1066 //=============================================================================
1067 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups( 
1068   const SMESH::ListOfGroups& theGroups, const char* theName )
1069 throw (SALOME::SALOME_Exception)
1070 {
1071   if ( !theName )
1072     return SMESH::SMESH_Group::_nil();
1073
1074   try
1075   {
1076     NCollection_DataMap< int, int > anIdToCount;
1077     SMESH::ElementType aType = SMESH::ALL;
1078     for ( int g = 0, n = theGroups.length(); g < n; g++ )
1079     {
1080       SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1081       if ( CORBA::is_nil( aGrp ) )
1082         continue;
1083
1084       // check type
1085       SMESH::ElementType aCurrType = aGrp->GetType();
1086       if ( aType == SMESH::ALL )
1087         aType = aCurrType;
1088       else 
1089       {
1090         if ( aType != aCurrType )
1091           return SMESH::SMESH_Group::_nil();
1092       }
1093
1094       // calculates number of occurance ids in groups
1095       SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1096       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1097       {
1098         int aCurrId = aCurrIds[ i ];
1099         if ( !anIdToCount.IsBound( aCurrId ) )
1100           anIdToCount.Bind( aCurrId, 1 );
1101         else 
1102           anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1103       }
1104     }
1105     
1106     // create map of ids
1107     int nbGrp = theGroups.length();
1108     NCollection_Map< int > anIds;
1109     NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1110     for ( ; anIter.More(); anIter.Next() )
1111     {
1112       int aCurrId = anIter.Key();
1113       int aCurrNb = anIter.Value();
1114       if ( aCurrNb == nbGrp )
1115         anIds.Add( aCurrId );
1116     }
1117
1118     // Create group
1119     SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1120     if ( aResGrp->_is_nil() )
1121       return SMESH::SMESH_Group::_nil();
1122     
1123     // Create array of identifiers
1124     SMESH::long_array_var aResIds = new SMESH::long_array;
1125     aResIds->length( anIds.Extent() );
1126     
1127     NCollection_Map< int >::Iterator aListIter( anIds );
1128     for ( int i = 0; aListIter.More(); aListIter.Next(), i++ )
1129     {
1130       aResIds[ i ] = aListIter.Value();
1131     }
1132     aResGrp->Add( aResIds );
1133
1134     // Clear python lines, created by CreateGroup() and Add()
1135     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1136     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1137     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1138
1139     // Update Python script
1140     
1141     TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1142                   << &theGroups << ", '" << theName << "' )";
1143
1144     return aResGrp._retn();
1145   }
1146   catch( ... )
1147   {
1148     return SMESH::SMESH_Group::_nil();
1149   }
1150 }
1151
1152 //=============================================================================
1153 /*! CutGroups
1154  *  New group is created. All mesh elements that are present in
1155  *  main group but do not present in tool group are added to the new one
1156  */
1157 //=============================================================================
1158 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1159                                                 SMESH::SMESH_GroupBase_ptr theGroup2,
1160                                                 const char* theName )
1161   throw (SALOME::SALOME_Exception)
1162 {
1163   if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1164        theGroup1->GetType() != theGroup2->GetType() )
1165     return SMESH::SMESH_Group::_nil();
1166
1167   // Perform Cutting
1168   SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1169   if ( aResGrp->_is_nil() )
1170     return aResGrp;
1171
1172   SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1173   SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1174
1175   TColStd_MapOfInteger aMap2;
1176
1177   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1178     aMap2.Add( anIds2[ i2 ] );
1179
1180   TColStd_SequenceOfInteger aSeq;
1181   for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1182     if ( !aMap2.Contains( anIds1[ i1 ] ) )
1183       aSeq.Append( anIds1[ i1 ] );
1184
1185   SMESH::long_array_var aResIds = new SMESH::long_array;
1186   aResIds->length( aSeq.Length() );
1187
1188   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1189     aResIds[ resI ] = aSeq( resI + 1 );
1190
1191   aResGrp->Add( aResIds );
1192
1193   // Clear python lines, created by CreateGroup() and Add()
1194   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1195   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1196   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1197
1198   // Update Python script
1199   TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1200                 << theGroup1 << ", " << theGroup2 << ", '"
1201                 << theName << "' )";
1202
1203   return aResGrp._retn();
1204 }
1205
1206 //=============================================================================
1207 /*!
1208   \brief Cut lists of groups. New group is created. All mesh elements that are 
1209   present in main groups but do not present in tool groups are added to the new one
1210   \param theMainGroups list of main groups
1211   \param theToolGroups list of tool groups
1212   \param theName name of group to be created
1213   \return pointer on the group
1214 */
1215 //=============================================================================
1216 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( 
1217   const SMESH::ListOfGroups& theMainGroups, 
1218   const SMESH::ListOfGroups& theToolGroups, 
1219   const char* theName )
1220   throw (SALOME::SALOME_Exception)
1221 {
1222   if ( !theName )
1223     return SMESH::SMESH_Group::_nil();
1224
1225   try
1226   {
1227     NCollection_Map< int > aToolIds;
1228     SMESH::ElementType aType = SMESH::ALL;
1229     int g, n;
1230     // iterate through tool groups
1231     for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1232     {
1233       SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1234       if ( CORBA::is_nil( aGrp ) )
1235         continue;
1236
1237       // check type
1238       SMESH::ElementType aCurrType = aGrp->GetType();
1239       if ( aType == SMESH::ALL )
1240         aType = aCurrType;
1241       else 
1242       {
1243         if ( aType != aCurrType )
1244           return SMESH::SMESH_Group::_nil();
1245       }
1246
1247       // unite tool ids
1248       SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1249       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1250       {
1251         int aCurrId = aCurrIds[ i ];
1252         aToolIds.Add( aCurrId );
1253       }
1254     }
1255
1256     NCollection_Map< int > anIds; // result
1257
1258     // Iterate through main group 
1259     for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1260     {
1261       SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1262       if ( CORBA::is_nil( aGrp ) )
1263         continue;
1264
1265       // check type
1266       SMESH::ElementType aCurrType = aGrp->GetType();
1267       if ( aType == SMESH::ALL )
1268         aType = aCurrType;
1269       else 
1270       {
1271         if ( aType != aCurrType )
1272           return SMESH::SMESH_Group::_nil();
1273       }
1274
1275       // unite tool ids
1276       SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1277       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1278       {
1279         int aCurrId = aCurrIds[ i ];
1280         if ( !aToolIds.Contains( aCurrId ) )
1281           anIds.Add( aCurrId );
1282       }
1283     }
1284
1285     // Create group
1286     SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1287     if ( aResGrp->_is_nil() )
1288       return SMESH::SMESH_Group::_nil();
1289     
1290     // Create array of identifiers
1291     SMESH::long_array_var aResIds = new SMESH::long_array;
1292     aResIds->length( anIds.Extent() );
1293     
1294     NCollection_Map< int >::Iterator anIter( anIds );
1295     for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1296     {
1297       aResIds[ i ] = anIter.Value();
1298     }
1299     aResGrp->Add( aResIds );
1300
1301     // Clear python lines, created by CreateGroup() and Add()
1302     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1303     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1304     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1305
1306     // Update Python script
1307
1308     TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1309                   << &theMainGroups << ", " << &theToolGroups << ", '"
1310                   << theName << "' )";
1311     
1312     return aResGrp._retn();
1313   }
1314   catch( ... )
1315   {
1316     return SMESH::SMESH_Group::_nil();
1317   }
1318 }
1319
1320 //=============================================================================
1321 /*!
1322   \brief Create groups of entities from existing groups of superior dimensions 
1323   System 
1324   1) extract all nodes from each group,
1325   2) combine all elements of specified dimension laying on these nodes.
1326   \param theGroups list of source groups 
1327   \param theElemType dimension of elements 
1328   \param theName name of new group
1329   \return pointer on new group
1330 */
1331 //=============================================================================
1332 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( 
1333   const SMESH::ListOfGroups& theGroups, 
1334   SMESH::ElementType         theElemType, 
1335   const char*                theName )
1336   throw (SALOME::SALOME_Exception)
1337 {
1338   SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1339
1340   if ( !theName || !aMeshDS )
1341     return SMESH::SMESH_Group::_nil();
1342
1343   SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1344
1345   try
1346   {
1347     // Create map of nodes from all groups 
1348
1349     NCollection_Map< int > aNodeMap;
1350     
1351     for ( int g = 0, n = theGroups.length(); g < n; g++ )
1352     {
1353       SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1354       if ( CORBA::is_nil( aGrp ) )
1355         continue;
1356
1357       SMESH::ElementType aType = aGrp->GetType();
1358       if ( aType == SMESH::ALL )
1359         continue;
1360       else if ( aType == SMESH::NODE )
1361       {
1362         SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1363         for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1364         {
1365           int aCurrId = aCurrIds[ i ];
1366           const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1367           if ( aNode )
1368             aNodeMap.Add( aNode->GetID() );
1369         }
1370       }
1371       else 
1372       {
1373         SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1374         for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1375         {
1376           int aCurrId = aCurrIds[ i ];
1377           const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1378           if ( !anElem )
1379             continue;
1380           SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1381           while( aNodeIter->more() )
1382           {
1383             const SMDS_MeshNode* aNode = 
1384               dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1385             if ( aNode )
1386               aNodeMap.Add( aNode->GetID() );
1387           }
1388         }
1389       }
1390     }
1391
1392     // Get result identifiers 
1393
1394     NCollection_Map< int > aResultIds;
1395     if ( theElemType == SMESH::NODE )
1396     {
1397       NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1398       for ( ; aNodeIter.More(); aNodeIter.Next() )
1399         aResultIds.Add( aNodeIter.Value() );
1400     }
1401     else
1402     {
1403       // Create list of elements of given dimension constructed on the nodes
1404       NCollection_Map< int > anElemList;
1405       NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1406       for ( ; aNodeIter.More(); aNodeIter.Next() )
1407       {
1408         const SMDS_MeshElement* aNode = 
1409           dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( aNodeIter.Value() ) );
1410         if ( !aNode )
1411           continue;
1412
1413          SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1414         while( anElemIter->more() )
1415         {
1416           const SMDS_MeshElement* anElem = 
1417             dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1418           if ( anElem && anElem->GetType() == anElemType )
1419             anElemList.Add( anElem->GetID() );
1420         }
1421       }
1422
1423       // check whether all nodes of elements are present in nodes map
1424       NCollection_Map< int >::Iterator anIter( anElemList );
1425       for ( ; anIter.More(); anIter.Next() )
1426       {
1427         const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() );
1428         if ( !anElem )
1429           continue;
1430
1431         bool isOk = true;
1432         SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1433         while( aNodeIter->more() )
1434         {
1435           const SMDS_MeshNode* aNode = 
1436             dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1437           if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) )
1438           {
1439             isOk = false;
1440             break;
1441           }
1442         } 
1443         if ( isOk )
1444           aResultIds.Add( anElem->GetID() );
1445       }
1446     }
1447
1448     // Create group
1449
1450     SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1451     if ( aResGrp->_is_nil() )
1452       return SMESH::SMESH_Group::_nil();
1453     
1454     // Create array of identifiers
1455     SMESH::long_array_var aResIds = new SMESH::long_array;
1456     aResIds->length( aResultIds.Extent() );
1457     
1458     NCollection_Map< int >::Iterator aResIter( aResultIds );
1459     for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1460       aResIds[ i ] = aResIter.Value();
1461     aResGrp->Add( aResIds );
1462
1463     // Remove strings corresponding to group creation
1464     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1465     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1466     _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1467
1468     // Update Python script
1469     
1470     TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1471                   << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1472
1473     return aResGrp._retn();
1474   }
1475   catch( ... )
1476   {
1477     return SMESH::SMESH_Group::_nil();
1478   }
1479 }
1480
1481 //================================================================================
1482 /*!
1483  * \brief Return group items of a group present in a study
1484  */
1485 //================================================================================
1486
1487 static GEOM::GEOM_Object_ptr getGroupItemsFromStudy(CORBA::Object_ptr    theMesh,
1488                                                     SMESH_Gen_i*         theGen,
1489                                                     list<TopoDS_Shape> & theItems)
1490 {
1491   GEOM::GEOM_Object_var groupObj;
1492   SALOMEDS::Study_var  study = theGen->GetCurrentStudy();
1493   GEOM::GEOM_Gen_var geomGen = theGen->GetGeomEngine();
1494   if ( study->_is_nil() || geomGen->_is_nil() )
1495     return groupObj._retn();
1496   
1497   GEOM::GEOM_IGroupOperations_var groupOp =
1498     geomGen->GetIGroupOperations( theGen->GetCurrentStudyID() );
1499   GEOM::GEOM_IShapesOperations_var shapeOp =
1500     geomGen->GetIShapesOperations( theGen->GetCurrentStudyID() );
1501
1502   SALOMEDS::SObject_var meshOS = theGen->ObjectToSObject(study, theMesh);
1503   if ( meshOS->_is_nil() || groupOp->_is_nil() || shapeOp->_is_nil() )
1504     return groupObj._retn();
1505   SALOMEDS::SObject_var fatherSO = meshOS->GetFather();
1506   if ( fatherSO->_is_nil() || fatherSO->Tag() != theGen->GetSubMeshOnCompoundTag() )
1507     return groupObj._retn(); // keep only submeshes on groups
1508
1509   SALOMEDS::ChildIterator_var anIter = study->NewChildIterator(meshOS);
1510   if ( anIter->_is_nil() ) return groupObj._retn();
1511   for ( ; anIter->More(); anIter->Next())
1512   {
1513     SALOMEDS::SObject_var aSObject = anIter->Value();
1514     SALOMEDS::SObject_var aRefSO;
1515     if ( !aSObject->_is_nil() && aSObject->ReferencedObject(aRefSO) )
1516     {
1517       groupObj = GEOM::GEOM_Object::_narrow(aRefSO->GetObject());
1518       if ( groupObj->_is_nil() ) break;
1519       GEOM::ListOfLong_var  ids = groupOp->GetObjects( groupObj );
1520       GEOM::GEOM_Object_var mainShape = groupObj->GetMainShape();
1521       for ( int i = 0; i < ids->length(); ++i ) {
1522         GEOM::GEOM_Object_var subShape = shapeOp->GetSubShape( mainShape, ids[i] );
1523         TopoDS_Shape S = theGen->GeomObjectToShape( subShape );
1524         if ( !S.IsNull() )
1525           theItems.push_back( S );
1526       }
1527       break;
1528     }
1529   }
1530   return groupObj._retn();
1531 }
1532
1533 //=============================================================================
1534 /*!
1535  * \brief Update hypotheses assigned to geom groups if the latter change
1536  * 
1537  * NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
1538  */
1539 //=============================================================================
1540
1541 void SMESH_Mesh_i::CheckGeomGroupModif()
1542 {
1543   if ( !_impl->HasShapeToMesh() ) return;
1544
1545   SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1546   if ( study->_is_nil() ) return;
1547
1548   // check if items of groups changed
1549   map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
1550   for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
1551   {
1552     const TopoDS_Shape & oldGroupShape = i_sm->second->GetSubShape();
1553     SMESHDS_SubMesh * oldDS = i_sm->second->GetSubMeshDS();
1554     if ( !oldDS /*|| !oldDS->IsComplexSubmesh()*/ )
1555       continue;
1556     int oldID = i_sm->first;
1557     map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldID );
1558     if ( i_smIor == _mapSubMeshIor.end() )
1559       continue;
1560     list< TopoDS_Shape> newItems;
1561     GEOM::GEOM_Object_var groupObj = getGroupItemsFromStudy ( i_smIor->second, _gen_i, newItems );
1562     if ( groupObj->_is_nil() )
1563       continue;
1564
1565     int nbOldItems = oldDS->IsComplexSubmesh() ? oldDS->NbSubMeshes() : 1;
1566     int nbNewItems = newItems.size();
1567     bool groupChanged = ( nbOldItems != nbNewItems);
1568     if ( !groupChanged ) {
1569       if ( !oldDS->IsComplexSubmesh() ) { // old group has one item
1570         groupChanged = ( oldGroupShape != newItems.front() );
1571       }
1572       else {
1573         list<TopoDS_Shape>::iterator item = newItems.begin();
1574         for ( ; item != newItems.end() && !groupChanged; ++item )
1575         {
1576           SMESHDS_SubMesh * itemDS = _impl->GetMeshDS()->MeshElements( *item );
1577           groupChanged = ( !itemDS || !oldDS->ContainsSubMesh( itemDS ));
1578         }
1579       }
1580     }
1581     // update hypotheses and submeshes if necessary
1582     if ( groupChanged )
1583     {
1584       // get a new group shape
1585       GEOM_Client* geomClient = _gen_i->GetShapeReader();
1586       if ( !geomClient ) continue;
1587       TCollection_AsciiString groupIOR = _gen_i->GetGeomEngine()->GetStringFromIOR( groupObj );
1588       geomClient->RemoveShapeFromBuffer( groupIOR );
1589       TopoDS_Shape newGroupShape = _gen_i->GeomObjectToShape( groupObj );
1590       // update hypotheses
1591       list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldGroupShape);
1592       list <const SMESHDS_Hypothesis * >::iterator hypIt;
1593       for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1594       {
1595         _impl->RemoveHypothesis( oldGroupShape, (*hypIt)->GetID());
1596         _impl->AddHypothesis   ( newGroupShape, (*hypIt)->GetID());
1597       }
1598       // care of submeshes
1599       SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newGroupShape );
1600       int newID = newSubmesh->GetId();
1601       if ( newID != oldID ) {
1602         _mapSubMesh   [ newID ] = newSubmesh;
1603         _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1604         _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1605         _mapSubMesh.erase   (oldID);
1606         _mapSubMesh_i.erase (oldID);
1607         _mapSubMeshIor.erase(oldID);
1608         _mapSubMesh_i [ newID ]->changeLocalId( newID );
1609       }
1610     }
1611   }
1612 }
1613
1614 //=============================================================================
1615 /*!
1616  *
1617  */
1618 //=============================================================================
1619
1620 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1621 {
1622   if(MYDEBUG) MESSAGE( "createSubMesh" );
1623   TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1624
1625   ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1626   int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1627   SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1628   SMESH::SMESH_subMesh_var subMesh
1629     = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1630
1631   _mapSubMesh[subMeshId] = mySubMesh;
1632   _mapSubMesh_i[subMeshId] = subMeshServant;
1633   _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1634
1635   // register CORBA object for persistence
1636   int nextId = _gen_i->RegisterObject( subMesh );
1637   if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1638
1639   return subMesh._retn();
1640 }
1641
1642 //=======================================================================
1643 //function : getSubMesh
1644 //purpose  :
1645 //=======================================================================
1646
1647 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
1648 {
1649   map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
1650   if ( it == _mapSubMeshIor.end() )
1651     return SMESH::SMESH_subMesh::_nil();
1652
1653   return SMESH::SMESH_subMesh::_duplicate( (*it).second );
1654 }
1655
1656
1657 //=============================================================================
1658 /*!
1659  *
1660  */
1661 //=============================================================================
1662
1663 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
1664                                   GEOM::GEOM_Object_ptr    theSubShapeObject )
1665 {
1666   MESSAGE("SMESH_Mesh_i::removeSubMesh()");
1667   if ( theSubMesh->_is_nil() || theSubShapeObject->_is_nil() )
1668     return;
1669
1670   try {
1671     SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
1672     for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
1673       removeHypothesis( theSubShapeObject, aHypList[i] );
1674     }
1675   }
1676   catch( const SALOME::SALOME_Exception& ) {
1677     INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
1678   }
1679
1680   int subMeshId = theSubMesh->GetId();
1681
1682   _mapSubMesh.erase(subMeshId);
1683   _mapSubMesh_i.erase(subMeshId);
1684   _mapSubMeshIor.erase(subMeshId);
1685   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
1686 }
1687
1688 //=============================================================================
1689 /*!
1690  *
1691  */
1692 //=============================================================================
1693
1694 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
1695                                                       const char*         theName,
1696                                                       const TopoDS_Shape& theShape )
1697 {
1698   int anId;
1699   SMESH::SMESH_GroupBase_var aGroup;
1700   if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
1701     SMESH_GroupBase_i* aGroupImpl;
1702     if ( !theShape.IsNull() )
1703       aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
1704     else
1705       aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1706
1707     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1708     SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1709     aGroupImpl->Register();
1710     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1711
1712     aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
1713     _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1714
1715     // register CORBA object for persistence
1716     int nextId = _gen_i->RegisterObject( aGroup );
1717     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
1718   }
1719   return aGroup._retn();
1720 }
1721
1722 //=============================================================================
1723 /*!
1724  * SMESH_Mesh_i::removeGroup
1725  *
1726  * Should be called by ~SMESH_Group_i()
1727  */
1728 //=============================================================================
1729
1730 void SMESH_Mesh_i::removeGroup( const int theId )
1731 {
1732   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
1733   if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
1734     _mapGroups.erase( theId );
1735     _impl->RemoveGroup( theId );
1736   }
1737 }
1738
1739
1740 //=============================================================================
1741 /*!
1742  *
1743  */
1744 //=============================================================================
1745
1746 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
1747 throw(SALOME::SALOME_Exception)
1748 {
1749   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
1750
1751   SMESH::log_array_var aLog;
1752   try{
1753     list < SMESHDS_Command * >logDS = _impl->GetLog();
1754     aLog = new SMESH::log_array;
1755     int indexLog = 0;
1756     int lg = logDS.size();
1757     SCRUTE(lg);
1758     aLog->length(lg);
1759     list < SMESHDS_Command * >::iterator its = logDS.begin();
1760     while(its != logDS.end()){
1761       SMESHDS_Command *com = *its;
1762       int comType = com->GetType();
1763       //SCRUTE(comType);
1764       int lgcom = com->GetNumber();
1765       //SCRUTE(lgcom);
1766       const list < int >&intList = com->GetIndexes();
1767       int inum = intList.size();
1768       //SCRUTE(inum);
1769       list < int >::const_iterator ii = intList.begin();
1770       const list < double >&coordList = com->GetCoords();
1771       int rnum = coordList.size();
1772       //SCRUTE(rnum);
1773       list < double >::const_iterator ir = coordList.begin();
1774       aLog[indexLog].commandType = comType;
1775       aLog[indexLog].number = lgcom;
1776       aLog[indexLog].coords.length(rnum);
1777       aLog[indexLog].indexes.length(inum);
1778       for(int i = 0; i < rnum; i++){
1779         aLog[indexLog].coords[i] = *ir;
1780         //MESSAGE(" "<<i<<" "<<ir.Value());
1781         ir++;
1782       }
1783       for(int i = 0; i < inum; i++){
1784         aLog[indexLog].indexes[i] = *ii;
1785         //MESSAGE(" "<<i<<" "<<ii.Value());
1786         ii++;
1787       }
1788       indexLog++;
1789       its++;
1790     }
1791     if(clearAfterGet)
1792       _impl->ClearLog();
1793   }
1794   catch(SALOME_Exception & S_ex){
1795     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1796   }
1797   return aLog._retn();
1798 }
1799
1800
1801 //=============================================================================
1802 /*!
1803  *
1804  */
1805 //=============================================================================
1806
1807 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
1808 {
1809   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
1810   // ****
1811 }
1812
1813 //=============================================================================
1814 /*!
1815  *
1816  */
1817 //=============================================================================
1818
1819 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
1820 {
1821   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
1822   return _id;
1823 }
1824
1825 //=============================================================================
1826 /*!
1827  *
1828  */
1829 //=============================================================================
1830
1831 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
1832 {
1833   return _studyId;
1834 }
1835
1836 //=============================================================================
1837 /*!
1838  *
1839  */
1840 //=============================================================================
1841
1842 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
1843 {
1844   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
1845   _impl = impl;
1846 }
1847
1848 //=============================================================================
1849 /*!
1850  *
1851  */
1852 //=============================================================================
1853
1854 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
1855 {
1856   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
1857   return *_impl;
1858 }
1859
1860 //=============================================================================
1861 /*!
1862  * Return mesh editor
1863  */
1864 //=============================================================================
1865
1866 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
1867 {
1868   // Create MeshEditor
1869   SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
1870   SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
1871
1872   // Update Python script
1873   TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
1874
1875   return aMesh._retn();
1876 }
1877
1878 //=============================================================================
1879 /*!
1880  * Return mesh edition previewer
1881  */
1882 //=============================================================================
1883
1884 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
1885 {
1886   SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
1887   SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
1888   return aMesh._retn();
1889 }
1890
1891 //=============================================================================
1892 /*!
1893  *
1894  */
1895 //=============================================================================
1896 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
1897 {
1898   Unexpect aCatch(SALOME_SalomeException);
1899   _impl->SetAutoColor(theAutoColor);
1900 }
1901
1902 //=============================================================================
1903 /*!
1904  *
1905  */
1906 //=============================================================================
1907 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
1908 {
1909   Unexpect aCatch(SALOME_SalomeException);
1910   return _impl->GetAutoColor();
1911 }
1912
1913
1914 //=============================================================================
1915 /*!
1916  *  Export in different formats
1917  */
1918 //=============================================================================
1919
1920 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
1921 {
1922   return _impl->HasDuplicatedGroupNamesMED();
1923 }
1924
1925 void SMESH_Mesh_i::PrepareForWriting (const char* file)
1926 {
1927   TCollection_AsciiString aFullName ((char*)file);
1928   OSD_Path aPath (aFullName);
1929   OSD_File aFile (aPath);
1930   if (aFile.Exists()) {
1931     // existing filesystem node
1932     if (aFile.KindOfFile() == OSD_FILE) {
1933       if (aFile.IsWriteable()) {
1934         aFile.Reset();
1935         aFile.Remove();
1936         if (aFile.Failed()) {
1937           TCollection_AsciiString msg ("File ");
1938           msg += aFullName + " cannot be replaced.";
1939           THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1940         }
1941       } else {
1942         TCollection_AsciiString msg ("File ");
1943         msg += aFullName + " cannot be overwritten.";
1944         THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1945       }
1946     } else {
1947       TCollection_AsciiString msg ("Location ");
1948       msg += aFullName + " is not a file.";
1949       THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1950     }
1951   } else {
1952     // nonexisting file; check if it can be created
1953     aFile.Reset();
1954     aFile.Build(OSD_WriteOnly, OSD_Protection());
1955     if (aFile.Failed()) {
1956       TCollection_AsciiString msg ("You cannot create the file ");
1957       msg += aFullName + ". Check the directory existance and access rights.";
1958       THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
1959     } else {
1960       aFile.Close();
1961       aFile.Remove();
1962     }
1963   }
1964 }
1965
1966 void SMESH_Mesh_i::ExportToMED (const char* file,
1967                                 CORBA::Boolean auto_groups,
1968                                 SMESH::MED_VERSION theVersion)
1969   throw(SALOME::SALOME_Exception)
1970 {
1971   Unexpect aCatch(SALOME_SalomeException);
1972
1973   // Update Python script
1974   TPythonDump() << _this() << ".ExportToMED( '"
1975                 << file << "', " << auto_groups << ", " << theVersion << " )";
1976
1977   // Perform Export
1978   PrepareForWriting(file);
1979   char* aMeshName = "Mesh";
1980   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1981   if ( !aStudy->_is_nil() ) {
1982     SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
1983     if ( !aMeshSO->_is_nil() ) {
1984       aMeshName = aMeshSO->GetName();
1985       //SCRUTE(file);
1986       //SCRUTE(aMeshName);
1987       //SCRUTE(aMeshSO->GetID());
1988
1989       // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
1990       if ( !aStudy->GetProperties()->IsLocked() )
1991         {
1992         SALOMEDS::GenericAttribute_var anAttr;
1993         SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
1994         SALOMEDS::AttributeExternalFileDef_var aFileName;
1995         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
1996         aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
1997         ASSERT(!aFileName->_is_nil());
1998         aFileName->SetValue(file);
1999         SALOMEDS::AttributeFileType_var aFileType;
2000         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2001         aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2002         ASSERT(!aFileType->_is_nil());
2003         aFileType->SetValue("FICHIERMED");
2004         }
2005     }
2006   }
2007   _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2008 }
2009
2010 void SMESH_Mesh_i::ExportMED (const char* file,
2011                               CORBA::Boolean auto_groups)
2012   throw(SALOME::SALOME_Exception)
2013 {
2014   ExportToMED(file,auto_groups,SMESH::MED_V2_1);
2015 }
2016
2017 void SMESH_Mesh_i::ExportDAT (const char *file)
2018   throw(SALOME::SALOME_Exception)
2019 {
2020   Unexpect aCatch(SALOME_SalomeException);
2021
2022   // Update Python script
2023   TPythonDump() << _this() << ".ExportDAT( '" << file << "' )";
2024
2025   // Perform Export
2026   PrepareForWriting(file);
2027   _impl->ExportDAT(file);
2028 }
2029
2030 void SMESH_Mesh_i::ExportUNV (const char *file)
2031   throw(SALOME::SALOME_Exception)
2032 {
2033   Unexpect aCatch(SALOME_SalomeException);
2034
2035   // Update Python script
2036   TPythonDump() << _this() << ".ExportUNV( '" << file << "' )";
2037
2038   // Perform Export
2039   PrepareForWriting(file);
2040   _impl->ExportUNV(file);
2041 }
2042
2043 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2044   throw(SALOME::SALOME_Exception)
2045 {
2046   Unexpect aCatch(SALOME_SalomeException);
2047
2048   // Update Python script
2049   TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )";
2050
2051   // Perform Export
2052   PrepareForWriting(file);
2053   _impl->ExportSTL(file, isascii);
2054 }
2055
2056 //=============================================================================
2057 /*!
2058  *
2059  */
2060 //=============================================================================
2061
2062 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2063 {
2064   Unexpect aCatch(SALOME_SalomeException);
2065   SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2066   SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2067   return aMesh._retn();
2068 }
2069
2070 //=============================================================================
2071 /*!
2072  *
2073  */
2074 //=============================================================================
2075 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2076 {
2077   Unexpect aCatch(SALOME_SalomeException);
2078   return _impl->NbNodes();
2079 }
2080
2081 //=============================================================================
2082 /*!
2083  *
2084  */
2085 //=============================================================================
2086 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2087 {
2088   Unexpect aCatch(SALOME_SalomeException);
2089   return NbEdges() + NbFaces() + NbVolumes();
2090 }
2091
2092 //=============================================================================
2093 /*!
2094  *
2095  */
2096 //=============================================================================
2097 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2098 {
2099   Unexpect aCatch(SALOME_SalomeException);
2100   return _impl->NbEdges();
2101 }
2102
2103 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2104   throw(SALOME::SALOME_Exception)
2105 {
2106   Unexpect aCatch(SALOME_SalomeException);
2107   return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2108 }
2109
2110 //=============================================================================
2111 /*!
2112  *
2113  */
2114 //=============================================================================
2115 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2116 {
2117   Unexpect aCatch(SALOME_SalomeException);
2118   return _impl->NbFaces();
2119 }
2120
2121 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2122 {
2123   Unexpect aCatch(SALOME_SalomeException);
2124   return _impl->NbTriangles();
2125 }
2126
2127 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2128 {
2129   Unexpect aCatch(SALOME_SalomeException);
2130   return _impl->NbQuadrangles();
2131 }
2132
2133 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2134 {
2135   Unexpect aCatch(SALOME_SalomeException);
2136   return _impl->NbPolygons();
2137 }
2138
2139 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2140   throw(SALOME::SALOME_Exception)
2141 {
2142   Unexpect aCatch(SALOME_SalomeException);
2143   return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2144 }
2145
2146 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2147   throw(SALOME::SALOME_Exception)
2148 {
2149   Unexpect aCatch(SALOME_SalomeException);
2150   return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2151 }
2152
2153 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2154   throw(SALOME::SALOME_Exception)
2155 {
2156   Unexpect aCatch(SALOME_SalomeException);
2157   return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2158 }
2159
2160 //=============================================================================
2161 /*!
2162  *
2163  */
2164 //=============================================================================
2165 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2166 {
2167   Unexpect aCatch(SALOME_SalomeException);
2168   return _impl->NbVolumes();
2169 }
2170
2171 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2172 {
2173   Unexpect aCatch(SALOME_SalomeException);
2174   return _impl->NbTetras();
2175 }
2176
2177 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2178 {
2179   Unexpect aCatch(SALOME_SalomeException);
2180   return _impl->NbHexas();
2181 }
2182
2183 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2184 {
2185   Unexpect aCatch(SALOME_SalomeException);
2186   return _impl->NbPyramids();
2187 }
2188
2189 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2190 {
2191   Unexpect aCatch(SALOME_SalomeException);
2192   return _impl->NbPrisms();
2193 }
2194
2195 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2196 {
2197   Unexpect aCatch(SALOME_SalomeException);
2198   return _impl->NbPolyhedrons();
2199 }
2200
2201 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2202   throw(SALOME::SALOME_Exception)
2203 {
2204   Unexpect aCatch(SALOME_SalomeException);
2205   return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2206 }
2207
2208 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2209   throw(SALOME::SALOME_Exception)
2210 {
2211   Unexpect aCatch(SALOME_SalomeException);
2212   return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2213 }
2214
2215 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2216   throw(SALOME::SALOME_Exception)
2217 {
2218   Unexpect aCatch(SALOME_SalomeException);
2219   return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2220 }
2221
2222 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2223   throw(SALOME::SALOME_Exception)
2224 {
2225   Unexpect aCatch(SALOME_SalomeException);
2226   return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2227 }
2228
2229 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2230   throw(SALOME::SALOME_Exception)
2231 {
2232   Unexpect aCatch(SALOME_SalomeException);
2233   return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2234 }
2235
2236 //=============================================================================
2237 /*!
2238  *
2239  */
2240 //=============================================================================
2241 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2242 {
2243   Unexpect aCatch(SALOME_SalomeException);
2244   return _impl->NbSubMesh();
2245 }
2246
2247 //=============================================================================
2248 /*!
2249  *
2250  */
2251 //=============================================================================
2252 char* SMESH_Mesh_i::Dump()
2253 {
2254   std::ostringstream os;
2255   _impl->Dump( os );
2256   return CORBA::string_dup( os.str().c_str() );
2257 }
2258
2259 //=============================================================================
2260 /*!
2261  *
2262  */
2263 //=============================================================================
2264 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2265 {
2266 //   SMESH::long_array_var aResult = new SMESH::long_array();
2267 //   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2268 //   int aMinId = aSMESHDS_Mesh->MinElementID();
2269 //   int aMaxId =  aSMESHDS_Mesh->MaxElementID();
2270
2271 //   aResult->length(aMaxId - aMinId + 1);
2272
2273 //   for (int i = 0, id = aMinId; id <= aMaxId; id++  )
2274 //     aResult[i++] = id;
2275
2276 //   return aResult._retn();
2277   // PAL12398
2278   return GetElementsId();
2279 }
2280
2281 //=============================================================================
2282 /*!
2283  *
2284  */
2285 //=============================================================================
2286
2287 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2288      throw (SALOME::SALOME_Exception)
2289 {
2290   Unexpect aCatch(SALOME_SalomeException);
2291   MESSAGE("SMESH_Mesh_i::GetElementsId");
2292   SMESH::long_array_var aResult = new SMESH::long_array();
2293   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2294
2295   if ( aSMESHDS_Mesh == NULL )
2296     return aResult._retn();
2297
2298   long nbElements = NbElements();
2299   aResult->length( nbElements );
2300   SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2301   for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2302     aResult[i] = anIt->next()->GetID();
2303
2304   return aResult._retn();
2305 }
2306
2307
2308 //=============================================================================
2309 /*!
2310  *
2311  */
2312 //=============================================================================
2313
2314 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2315     throw (SALOME::SALOME_Exception)
2316 {
2317   Unexpect aCatch(SALOME_SalomeException);
2318   MESSAGE("SMESH_subMesh_i::GetElementsByType");
2319   SMESH::long_array_var aResult = new SMESH::long_array();
2320   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2321
2322   if ( aSMESHDS_Mesh == NULL )
2323     return aResult._retn();
2324
2325   long nbElements = NbElements();
2326
2327   // No sense in returning ids of elements along with ids of nodes:
2328   // when theElemType == SMESH::ALL, return node ids only if
2329   // there are no elements
2330   if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2331     return GetNodesId();
2332
2333   aResult->length( nbElements );
2334
2335   int i = 0;
2336
2337   SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2338   while ( i < nbElements && anIt->more() ) {
2339     const SMDS_MeshElement* anElem = anIt->next();
2340     if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2341       aResult[i++] = anElem->GetID();
2342   }
2343
2344   aResult->length( i );
2345
2346   return aResult._retn();
2347 }
2348
2349 //=============================================================================
2350 /*!
2351  *
2352  */
2353 //=============================================================================
2354
2355 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2356   throw (SALOME::SALOME_Exception)
2357 {
2358   Unexpect aCatch(SALOME_SalomeException);
2359   MESSAGE("SMESH_subMesh_i::GetNodesId");
2360   SMESH::long_array_var aResult = new SMESH::long_array();
2361   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2362
2363   if ( aSMESHDS_Mesh == NULL )
2364     return aResult._retn();
2365
2366   long nbNodes = NbNodes();
2367   aResult->length( nbNodes );
2368   SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
2369   for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2370     aResult[i] = anIt->next()->GetID();
2371
2372   return aResult._retn();
2373 }
2374
2375 //=============================================================================
2376 /*!
2377  *
2378  */
2379 //=============================================================================
2380
2381 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2382   throw (SALOME::SALOME_Exception)
2383 {
2384   return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2385 }
2386
2387
2388 //=============================================================================
2389 /*!
2390  * Returns ID of elements for given submesh
2391  */
2392 //=============================================================================
2393 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2394      throw (SALOME::SALOME_Exception)
2395 {
2396   SMESH::long_array_var aResult = new SMESH::long_array();
2397
2398   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2399   if(!SM) return aResult._retn();
2400
2401   SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2402   if(!SDSM) return aResult._retn();
2403
2404   aResult->length(SDSM->NbElements());
2405
2406   SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2407   int i = 0;
2408   while ( eIt->more() ) {
2409     aResult[i++] = eIt->next()->GetID();
2410   }
2411
2412   return aResult._retn();
2413 }
2414
2415
2416 //=============================================================================
2417 /*!
2418  * Returns ID of nodes for given submesh
2419  * If param all==true - returns all nodes, else -
2420  * returns only nodes on shapes.
2421  */
2422 //=============================================================================
2423 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2424      throw (SALOME::SALOME_Exception)
2425 {
2426   SMESH::long_array_var aResult = new SMESH::long_array();
2427
2428   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2429   if(!SM) return aResult._retn();
2430
2431   SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2432   if(!SDSM) return aResult._retn();
2433
2434   set<int> theElems;
2435   if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2436     SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2437     while ( nIt->more() ) {
2438       const SMDS_MeshNode* elem = nIt->next();
2439       theElems.insert( elem->GetID() );
2440     }
2441   }
2442   else { // all nodes of submesh elements
2443     SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2444     while ( eIt->more() ) {
2445       const SMDS_MeshElement* anElem = eIt->next();
2446       SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2447       while ( nIt->more() ) {
2448         const SMDS_MeshElement* elem = nIt->next();
2449         theElems.insert( elem->GetID() );
2450       }
2451     }
2452   }
2453
2454   aResult->length(theElems.size());
2455   set<int>::iterator itElem;
2456   int i = 0;
2457   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2458     aResult[i++] = *itElem;
2459
2460   return aResult._retn();
2461 }
2462   
2463
2464 //=============================================================================
2465 /*!
2466  * Returns type of elements for given submesh
2467  */
2468 //=============================================================================
2469 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2470      throw (SALOME::SALOME_Exception)
2471 {
2472   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2473   if(!SM) return SMESH::ALL;
2474
2475   SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2476   if(!SDSM) return SMESH::ALL;
2477
2478   if(SDSM->NbElements()==0)
2479     return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2480
2481   SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2482   const SMDS_MeshElement* anElem = eIt->next();
2483   return ( SMESH::ElementType ) anElem->GetType();
2484 }
2485   
2486
2487 //=============================================================================
2488 /*!
2489  *
2490  */
2491 //=============================================================================
2492
2493 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2494 {
2495   CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2496   if ( MYDEBUG )
2497     MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2498   return pointeur;
2499 }
2500
2501
2502 //=============================================================================
2503 /*!
2504  * Get XYZ coordinates of node as list of double
2505  * If there is not node for given ID - returns empty list
2506  */
2507 //=============================================================================
2508
2509 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2510 {
2511   SMESH::double_array_var aResult = new SMESH::double_array();
2512   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2513   if ( aSMESHDS_Mesh == NULL )
2514     return aResult._retn();
2515
2516   // find node
2517   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2518   if(!aNode)
2519     return aResult._retn();
2520
2521   // add coordinates
2522   aResult->length(3);
2523   aResult[0] = aNode->X();
2524   aResult[1] = aNode->Y();
2525   aResult[2] = aNode->Z();
2526   return aResult._retn();
2527 }
2528
2529
2530 //=============================================================================
2531 /*!
2532  * For given node returns list of IDs of inverse elements
2533  * If there is not node for given ID - returns empty list
2534  */
2535 //=============================================================================
2536
2537 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2538 {
2539   SMESH::long_array_var aResult = new SMESH::long_array();
2540   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2541   if ( aSMESHDS_Mesh == NULL )
2542     return aResult._retn();
2543
2544   // find node
2545   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2546   if(!aNode)
2547     return aResult._retn();
2548
2549   // find inverse elements
2550   SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
2551   TColStd_SequenceOfInteger IDs;
2552   while(eIt->more()) {
2553     const SMDS_MeshElement* elem = eIt->next();
2554     IDs.Append(elem->GetID());
2555   }
2556   if(IDs.Length()>0) {
2557     aResult->length(IDs.Length());
2558     int i = 1;
2559     for(; i<=IDs.Length(); i++) {
2560       aResult[i-1] = IDs.Value(i);
2561     }
2562   }
2563   return aResult._retn();
2564 }
2565
2566 //=============================================================================
2567 /*!
2568  * \brief Return position of a node on shape
2569  */
2570 //=============================================================================
2571
2572 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
2573 {
2574   SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
2575   aNodePosition->shapeID = 0;
2576   aNodePosition->shapeType = GEOM::SHAPE;
2577
2578   SMESHDS_Mesh* mesh = _impl->GetMeshDS();
2579   if ( !mesh ) return aNodePosition;
2580
2581   if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
2582   {
2583     if ( SMDS_PositionPtr pos = aNode->GetPosition() )
2584     {
2585       aNodePosition->shapeID = pos->GetShapeId();
2586       switch ( pos->GetTypeOfPosition() ) {
2587       case SMDS_TOP_EDGE:
2588         aNodePosition->shapeType = GEOM::EDGE;
2589         aNodePosition->params.length(1);
2590         aNodePosition->params[0] =
2591           static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
2592         break;
2593       case SMDS_TOP_FACE:
2594         aNodePosition->shapeType = GEOM::FACE;
2595         aNodePosition->params.length(2);
2596         aNodePosition->params[0] =
2597           static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
2598         aNodePosition->params[1] =
2599           static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
2600         break;
2601       case SMDS_TOP_VERTEX:
2602         aNodePosition->shapeType = GEOM::VERTEX;
2603         break;
2604       case SMDS_TOP_3DSPACE:
2605         if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
2606           aNodePosition->shapeType = GEOM::SOLID;
2607         else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
2608           aNodePosition->shapeType = GEOM::SHELL;
2609         break;
2610       default:;
2611       }
2612     }
2613   }
2614   return aNodePosition;
2615 }
2616
2617 //=============================================================================
2618 /*!
2619  * If given element is node returns IDs of shape from position
2620  * If there is not node for given ID - returns -1
2621  */
2622 //=============================================================================
2623
2624 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
2625 {
2626   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2627   if ( aSMESHDS_Mesh == NULL )
2628     return -1;
2629
2630   // try to find node
2631   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2632   if(aNode) {
2633     SMDS_PositionPtr pos = aNode->GetPosition();
2634     if(!pos)
2635       return -1;
2636     else
2637       return pos->GetShapeId();
2638   }
2639
2640   return -1;
2641 }
2642
2643
2644 //=============================================================================
2645 /*!
2646  * For given element returns ID of result shape after 
2647  * ::FindShape() from SMESH_MeshEditor
2648  * If there is not element for given ID - returns -1
2649  */
2650 //=============================================================================
2651
2652 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
2653 {
2654   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2655   if ( aSMESHDS_Mesh == NULL )
2656     return -1;
2657
2658   // try to find element
2659   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2660   if(!elem)
2661     return -1;
2662
2663   //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
2664   ::SMESH_MeshEditor aMeshEditor(_impl);
2665   int index = aMeshEditor.FindShape( elem );
2666   if(index>0)
2667     return index;
2668
2669   return -1;
2670 }
2671
2672
2673 //=============================================================================
2674 /*!
2675  * Returns number of nodes for given element
2676  * If there is not element for given ID - returns -1
2677  */
2678 //=============================================================================
2679
2680 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
2681 {
2682   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2683   if ( aSMESHDS_Mesh == NULL ) return -1;
2684   // try to find element
2685   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2686   if(!elem) return -1;
2687   return elem->NbNodes();
2688 }
2689
2690
2691 //=============================================================================
2692 /*!
2693  * Returns ID of node by given index for given element
2694  * If there is not element for given ID - returns -1
2695  * If there is not node for given index - returns -2
2696  */
2697 //=============================================================================
2698
2699 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
2700 {
2701   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2702   if ( aSMESHDS_Mesh == NULL ) return -1;
2703   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2704   if(!elem) return -1;
2705   if( index>=elem->NbNodes() || index<0 ) return -1;
2706   return elem->GetNode(index)->GetID();
2707 }
2708
2709 //=============================================================================
2710 /*!
2711  * Returns IDs of nodes of given element
2712  */
2713 //=============================================================================
2714
2715 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
2716 {
2717   SMESH::long_array_var aResult = new SMESH::long_array();
2718   if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
2719   {
2720     if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
2721     {
2722       aResult->length( elem->NbNodes() );
2723       for ( int i = 0; i < elem->NbNodes(); ++i )
2724         aResult[ i ] = elem->GetNode( i )->GetID();
2725     }
2726   }
2727   return aResult._retn();
2728 }
2729
2730 //=============================================================================
2731 /*!
2732  * Returns true if given node is medium node
2733  * in given quadratic element
2734  */
2735 //=============================================================================
2736
2737 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
2738 {
2739   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2740   if ( aSMESHDS_Mesh == NULL ) return false;
2741   // try to find node
2742   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
2743   if(!aNode) return false;
2744   // try to find element
2745   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
2746   if(!elem) return false;
2747
2748   return elem->IsMediumNode(aNode);
2749 }
2750
2751
2752 //=============================================================================
2753 /*!
2754  * Returns true if given node is medium node
2755  * in one of quadratic elements
2756  */
2757 //=============================================================================
2758
2759 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
2760                                                    SMESH::ElementType theElemType)
2761 {
2762   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2763   if ( aSMESHDS_Mesh == NULL ) return false;
2764
2765   // try to find node
2766   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
2767   if(!aNode) return false;
2768
2769   SMESH_MesherHelper aHelper( *(_impl) );
2770
2771   SMDSAbs_ElementType aType;
2772   if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
2773   else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
2774   else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
2775   else aType = SMDSAbs_All;
2776
2777   return aHelper.IsMedium(aNode,aType);
2778 }
2779
2780
2781 //=============================================================================
2782 /*!
2783  * Returns number of edges for given element
2784  */
2785 //=============================================================================
2786
2787 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
2788 {
2789   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2790   if ( aSMESHDS_Mesh == NULL ) return -1;
2791   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2792   if(!elem) return -1;
2793   return elem->NbEdges();
2794 }
2795
2796
2797 //=============================================================================
2798 /*!
2799  * Returns number of faces for given element
2800  */
2801 //=============================================================================
2802
2803 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
2804 {
2805   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2806   if ( aSMESHDS_Mesh == NULL ) return -1;
2807   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2808   if(!elem) return -1;
2809   return elem->NbFaces();
2810 }
2811
2812
2813 //=============================================================================
2814 /*!
2815  * Returns true if given element is polygon
2816  */
2817 //=============================================================================
2818
2819 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
2820 {
2821   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2822   if ( aSMESHDS_Mesh == NULL ) return false;
2823   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2824   if(!elem) return false;
2825   return elem->IsPoly();
2826 }
2827
2828
2829 //=============================================================================
2830 /*!
2831  * Returns true if given element is quadratic
2832  */
2833 //=============================================================================
2834
2835 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
2836 {
2837   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2838   if ( aSMESHDS_Mesh == NULL ) return false;
2839   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2840   if(!elem) return false;
2841   return elem->IsQuadratic();
2842 }
2843
2844
2845 //=============================================================================
2846 /*!
2847  * Returns bary center for given element
2848  */
2849 //=============================================================================
2850
2851 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
2852 {
2853   SMESH::double_array_var aResult = new SMESH::double_array();
2854   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2855   if ( aSMESHDS_Mesh == NULL )
2856     return aResult._retn();
2857
2858   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
2859   if(!elem)
2860     return aResult._retn();
2861
2862   if(elem->GetType()==SMDSAbs_Volume) {
2863     SMDS_VolumeTool aTool;
2864     if(aTool.Set(elem)) {
2865       aResult->length(3);
2866       if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
2867         aResult->length(0);
2868     }
2869   }
2870   else {
2871     SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
2872     int nbn = 0;
2873     double x=0., y=0., z=0.;
2874     for(; anIt->more(); ) {
2875       nbn++;
2876       const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
2877       x += aNode->X();
2878       y += aNode->Y();
2879       z += aNode->Z();
2880     }
2881     if(nbn>0) {
2882       // add coordinates
2883       aResult->length(3);
2884       aResult[0] = x/nbn;
2885       aResult[1] = y/nbn;
2886       aResult[2] = z/nbn;
2887     }
2888   }
2889
2890   return aResult._retn();
2891 }
2892
2893
2894 //=============================================================================
2895 /*!
2896  * Create and publish group servants if any groups were imported or created anyhow
2897  */
2898 //=============================================================================
2899
2900 void SMESH_Mesh_i::CreateGroupServants() 
2901 {
2902   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2903
2904   ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
2905   while ( groupIt->more() )
2906   {
2907     ::SMESH_Group* group = groupIt->next();
2908     int            anId = group->GetGroupDS()->GetID();
2909
2910     map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
2911     if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
2912       continue;
2913
2914     SMESH_GroupBase_i* aGroupImpl;
2915     TopoDS_Shape       shape;
2916     if ( SMESHDS_GroupOnGeom* groupOnGeom =
2917          dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
2918     {
2919       aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2920       shape      = groupOnGeom->GetShape();
2921     }
2922     else {
2923       aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2924     }
2925
2926     // To ensure correct mapping of servant and correct reference counting in GenericObj_i
2927     SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2928     aGroupImpl->Register();
2929
2930     SMESH::SMESH_GroupBase_var groupVar =
2931       SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2932     _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
2933
2934     // register CORBA object for persistence
2935     int nextId = _gen_i->RegisterObject( groupVar );
2936     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2937
2938     // publishing of the groups in the study
2939     if ( !aStudy->_is_nil() ) {
2940       GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
2941       _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
2942     }
2943   }
2944 }
2945
2946 //=============================================================================
2947 /*!
2948  * \brief Return groups cantained in _mapGroups by their IDs
2949  */
2950 //=============================================================================
2951
2952 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
2953 {
2954   int nbGroups = groupIDs.size();
2955   SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
2956   aList->length( nbGroups );
2957
2958   list<int>::const_iterator ids = groupIDs.begin();
2959   for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
2960   {
2961     map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
2962     if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
2963       aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
2964   }
2965   aList->length( nbGroups );
2966   return aList._retn();
2967 }
2968
2969 //=============================================================================
2970 /*!
2971  * \brief Return information about imported file
2972  */
2973 //=============================================================================
2974
2975 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
2976 {
2977   SALOME_MED::MedFileInfo_var res( myFileInfo );
2978   if ( !res.operator->() ) {
2979     res = new SALOME_MED::MedFileInfo;
2980     res->fileName = "";
2981     res->fileSize = res->major = res->minor = res->release = -1;
2982   }
2983   return res._retn();
2984 }