Salome HOME
Merge with version on tag OCC-V2_1_0d
[modules/smesh.git] / src / SMESH_I / SMESH_Mesh_i.cxx
1 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SMESH_Mesh_i.cxx
25 //  Author : Paul RASCLE, EDF
26 //  Module : SMESH
27 //  $Header$
28
29 #include "SMESH_Mesh_i.hxx"
30 #include "SMESH_subMesh_i.hxx"
31 #include "SMESH_MEDMesh_i.hxx"
32 #include "SMESH_Group_i.hxx"
33 #include "SMESH_Filter_i.hxx"
34
35 #include "Utils_CorbaException.hxx"
36 #include "Utils_ExceptHandlers.hxx"
37 #include "utilities.h"
38
39 #include "SALOME_NamingService.hxx"
40 #include "Utils_SINGLETON.hxx"
41 #include "OpUtil.hxx"
42
43 #include "TCollection_AsciiString.hxx"
44 #include <TColStd_MapOfInteger.hxx>
45 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
46 #include <TColStd_SequenceOfInteger.hxx>
47 #include "SMESHDS_Command.hxx"
48 #include "SMESHDS_CommandType.hxx"
49 #include "SMESH_MeshEditor_i.hxx"
50 #include "SMESH_Gen_i.hxx"
51 #include "DriverMED_R_SMESHDS_Mesh.h"
52
53 #include <string>
54 #include <iostream>
55 // _CS_gbo_050504 Ajout explicite du sstream pour ostringstream 
56 #include <sstream>
57
58 #ifdef _DEBUG_
59 static int MYDEBUG = 0;
60 #else
61 static int MYDEBUG = 0;
62 #endif
63
64 using namespace std;
65
66 int SMESH_Mesh_i::myIdGenerator = 0;
67
68 //=============================================================================
69 /*!
70  *  Constructor
71  */
72 //=============================================================================
73
74 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
75                             SMESH_Gen_i*            gen_i,
76                             CORBA::Long studyId )
77 : SALOME::GenericObj_i( thePOA )
78 {
79   INFOS("SMESH_Mesh_i");
80   _gen_i = gen_i;
81   _id = myIdGenerator++;
82   _studyId = studyId;
83   thePOA->activate_object( this );
84 }
85
86 //=============================================================================
87 /*!
88  *  Destructor
89  */
90 //=============================================================================
91
92 SMESH_Mesh_i::~SMESH_Mesh_i()
93 {
94   INFOS("~SMESH_Mesh_i");
95   map<int, SMESH::SMESH_GroupBase_ptr>::iterator it;
96   for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) {
97     SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( it->second ).in() );
98     if ( aGroup ) {
99
100       // this method is colled from destructor of group (PAL6331)
101       //_impl->RemoveGroup( aGroup->GetLocalID() );
102       
103       aGroup->Destroy();
104     }
105   }
106   _mapGroups.clear();
107 }
108
109 //=============================================================================
110 /*!
111  *  SetShape
112  *
113  *  Associates <this> mesh with <theShape> and puts a reference  
114  *  to <theShape> into the current study; 
115  *  the previous shape is substituted by the new one.
116  */
117 //=============================================================================
118
119 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
120     throw (SALOME::SALOME_Exception)
121 {
122   Unexpect aCatch(SALOME_SalomeException);
123   try {
124     _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
125   }
126   catch(SALOME_Exception & S_ex) {
127     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
128   }
129 }
130
131 //=======================================================================
132 //function : GetShapeToMesh
133 //purpose  : 
134 //=======================================================================
135
136 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
137     throw (SALOME::SALOME_Exception)
138 {
139   Unexpect aCatch(SALOME_SalomeException);
140   GEOM::GEOM_Object_var aShapeObj;
141   try {
142     TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
143     if ( !S.IsNull() )
144       aShapeObj = _gen_i->ShapeToGeomObject( S );
145   }
146   catch(SALOME_Exception & S_ex) {
147     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
148   }
149   return aShapeObj._retn();
150 }
151
152 //=============================================================================
153 /*!
154  *  
155  */
156 //=============================================================================
157
158 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
159 {
160   SMESH::DriverMED_ReadStatus res;
161   switch (theStatus)
162   {
163   case DriverMED_R_SMESHDS_Mesh::DRS_OK:
164     res = SMESH::DRS_OK; break;
165   case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
166     res = SMESH::DRS_EMPTY; break;
167   case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
168     res = SMESH::DRS_WARN_RENUMBER; break;
169   case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
170     res = SMESH::DRS_WARN_SKIP_ELEM; break;
171   case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
172   default:
173     res = SMESH::DRS_FAIL; break;
174   }
175   return res;
176 }
177
178 //=============================================================================
179 /*!
180  *  ImportMEDFile
181  *
182  *  Imports mesh data from MED file
183  */
184 //=============================================================================
185
186 SMESH::DriverMED_ReadStatus
187 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
188   throw ( SALOME::SALOME_Exception )
189 {
190   Unexpect aCatch(SALOME_SalomeException);
191   int status;
192   try {
193     status = importMEDFile( theFileName, theMeshName );
194   }
195   catch( SALOME_Exception& S_ex ) {
196     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
197   }  
198   catch ( ... ) {
199     THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
200   }
201
202   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
203   if ( !aStudy->_is_nil() ) {
204     // publishing of the groups in the study (sub-meshes are out of scope of MED import)
205     map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
206     for (; it != _mapGroups.end(); it++ ) {
207       SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_duplicate( it->second );
208       _gen_i->PublishGroup( aStudy, _this(), aGroup,
209                            GEOM::GEOM_Object::_nil(), aGroup->GetName());
210     }
211   }
212   return ConvertDriverMEDReadStatus(status);
213 }
214
215 //=============================================================================
216 /*!
217  *  ImportUNVFile
218  *
219  *  Imports mesh data from MED file
220  */
221 //=============================================================================
222
223 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
224   throw ( SALOME::SALOME_Exception )
225 {
226   // Read mesh with name = <theMeshName> into SMESH_Mesh
227   _impl->UNVToMesh( theFileName );
228
229   return 1;
230 }
231
232 //=============================================================================
233 /*!
234  *  ImportSTLFile
235  *
236  *  Imports mesh data from STL file
237  */
238 //=============================================================================
239 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
240   throw ( SALOME::SALOME_Exception )
241 {
242   // Read mesh with name = <theMeshName> into SMESH_Mesh
243   _impl->STLToMesh( theFileName );
244
245   return 1;
246 }
247
248 //=============================================================================
249 /*!
250  *  importMEDFile
251  *
252  *  Imports mesh data from MED file
253  */
254 //=============================================================================
255
256 int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
257 {
258   // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
259   int status = _impl->MEDToMesh( theFileName, theMeshName );
260
261   // Create group servants, if any groups were imported
262   list<int> aGroupIds = _impl->GetGroupIds();
263   for ( list<int>::iterator it = aGroupIds.begin(); it != aGroupIds.end(); it++ ) {
264     SMESH_Group_i* aGroupImpl     = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, *it );
265     SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
266     _mapGroups[*it]               = SMESH::SMESH_Group::_duplicate( aGroup );
267
268     // register CORBA object for persistence
269     int nextId = _gen_i->RegisterObject( aGroup );
270     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
271   }
272
273   return status;
274 }
275
276 //=============================================================================
277 /*!
278  *  
279  */
280 //=============================================================================
281
282 static SMESH::Hypothesis_Status ConvertHypothesisStatus
283                          (SMESH_Hypothesis::Hypothesis_Status theStatus)
284 {
285   SMESH::Hypothesis_Status res;
286   switch (theStatus)
287   {
288   case SMESH_Hypothesis::HYP_OK:
289     res = SMESH::HYP_OK; break;
290   case SMESH_Hypothesis::HYP_MISSING:
291     res = SMESH::HYP_MISSING; break;
292   case SMESH_Hypothesis::HYP_CONCURENT:
293     res = SMESH::HYP_CONCURENT; break;
294   case SMESH_Hypothesis::HYP_BAD_PARAMETER:
295     res = SMESH::HYP_BAD_PARAMETER; break;
296   case SMESH_Hypothesis::HYP_INCOMPATIBLE:
297     res = SMESH::HYP_INCOMPATIBLE; break;
298   case SMESH_Hypothesis::HYP_NOTCONFORM:
299     res = SMESH::HYP_NOTCONFORM; break;
300   case SMESH_Hypothesis::HYP_ALREADY_EXIST:
301     res = SMESH::HYP_ALREADY_EXIST; break;
302   case SMESH_Hypothesis::HYP_BAD_DIM:
303     res = SMESH::HYP_BAD_DIM; break;
304   default:
305     res = SMESH::HYP_UNKNOWN_FATAL;
306   }
307   return res;
308 }
309
310 //=============================================================================
311 /*!
312  *  AddHypothesis
313  *
314  *  calls internal addHypothesis() and then adds a reference to <anHyp> under 
315  *  the SObject actually having a reference to <aSubShape>.
316  *  NB: For this method to work, it is necessary to add a reference to sub-shape first.
317  */
318 //=============================================================================
319
320 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
321                                                      SMESH::SMESH_Hypothesis_ptr anHyp)
322   throw(SALOME::SALOME_Exception)
323 {
324   Unexpect aCatch(SALOME_SalomeException);
325   SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
326
327   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
328     _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
329                                  aSubShapeObject, anHyp );
330
331   if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
332
333   return ConvertHypothesisStatus(status);
334 }
335
336 //=============================================================================
337 /*!
338  *  
339  */
340 //=============================================================================
341
342 SMESH_Hypothesis::Hypothesis_Status
343   SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr       aSubShapeObject,
344                               SMESH::SMESH_Hypothesis_ptr anHyp)
345 {
346   if(MYDEBUG) MESSAGE("addHypothesis");
347
348   if (CORBA::is_nil(aSubShapeObject))
349     THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
350                                  SALOME::BAD_PARAM);
351
352   SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
353   if (CORBA::is_nil(myHyp))
354     THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
355                                  SALOME::BAD_PARAM);
356
357   SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
358   try
359   {
360     TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
361     int hypId = myHyp->GetId();
362     status = _impl->AddHypothesis(myLocSubShape, hypId);
363     if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
364       _mapHypo[hypId] = myHyp;
365       // assure there is a corresponding submesh
366       if ( !_impl->IsMainShape( myLocSubShape )) {
367         int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
368         if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
369           createSubMesh( aSubShapeObject );
370       }
371     }
372   }
373   catch(SALOME_Exception & S_ex)
374   {
375     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
376   }
377   return status;
378 }
379
380 //=============================================================================
381 /*!
382  *  
383  */
384 //=============================================================================
385
386 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
387                                                         SMESH::SMESH_Hypothesis_ptr anHyp)
388      throw(SALOME::SALOME_Exception)
389 {
390   Unexpect aCatch(SALOME_SalomeException);
391   SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
392
393   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
394     _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
395                                       aSubShapeObject, anHyp );
396
397   return ConvertHypothesisStatus(status);
398 }
399
400 //=============================================================================
401 /*!
402  *  
403  */
404 //=============================================================================
405
406 SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
407                                  SMESH::SMESH_Hypothesis_ptr anHyp)
408 {
409         if(MYDEBUG) MESSAGE("removeHypothesis()");
410         // **** proposer liste de subShape (selection multiple)
411
412         if (CORBA::is_nil(aSubShapeObject))
413                 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
414                         SALOME::BAD_PARAM);
415
416         SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
417         if (CORBA::is_nil(myHyp))
418           THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
419                         SALOME::BAD_PARAM);
420
421         SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
422         try
423         {
424                 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
425                 int hypId = myHyp->GetId();
426                 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
427                 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
428                   _mapHypo.erase( hypId );
429         }
430         catch(SALOME_Exception & S_ex)
431         {
432                 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
433         }
434         return status;
435 }
436
437 //=============================================================================
438 /*!
439  *  
440  */
441 //=============================================================================
442
443 SMESH::ListOfHypothesis *
444         SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
445 throw(SALOME::SALOME_Exception)
446 {
447   Unexpect aCatch(SALOME_SalomeException);
448   if (MYDEBUG) MESSAGE("GetHypothesisList");
449   if (CORBA::is_nil(aSubShapeObject))
450     THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
451                                  SALOME::BAD_PARAM);
452   
453   SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
454
455   try {
456     TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
457     const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
458     int i = 0, n = aLocalList.size();
459     aList->length( n );
460
461     for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
462       SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
463       if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
464         aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
465     }
466
467     aList->length( i );
468   }
469   catch(SALOME_Exception & S_ex) {
470     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
471   }
472   
473   return aList._retn();
474 }
475
476 //=============================================================================
477 /*!
478  *  
479  */
480 //=============================================================================
481 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
482                                                   const char*           theName ) 
483      throw(SALOME::SALOME_Exception)
484 {
485   Unexpect aCatch(SALOME_SalomeException);
486   MESSAGE("SMESH_Mesh_i::GetSubMesh");
487   if (CORBA::is_nil(aSubShapeObject))
488     THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
489                                  SALOME::BAD_PARAM);
490   
491   SMESH::SMESH_subMesh_var subMesh;
492   SMESH::SMESH_Mesh_var    aMesh = SMESH::SMESH_Mesh::_narrow(_this());
493   try {
494     TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
495     
496     //Get or Create the SMESH_subMesh object implementation
497     
498     int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
499     subMesh = getSubMesh( subMeshId );
500
501     // create a new subMesh object servant if there is none for the shape
502     if ( subMesh->_is_nil() )
503       subMesh = createSubMesh( aSubShapeObject );
504
505     if ( _gen_i->CanPublishInStudy( subMesh ))
506       _gen_i->PublishSubMesh (_gen_i->GetCurrentStudy(), aMesh,
507                               subMesh, aSubShapeObject, theName );
508   }
509   catch(SALOME_Exception & S_ex) {
510     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
511   }
512   return subMesh;
513 }
514
515 //=============================================================================
516 /*!
517  *  
518  */
519 //=============================================================================
520
521 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
522      throw (SALOME::SALOME_Exception)
523 {
524   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
525   if ( theSubMesh->_is_nil() )
526     return;
527
528   GEOM::GEOM_Object_var aSubShapeObject;
529   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
530   if ( !aStudy->_is_nil() )  {
531     // Remove submesh's SObject
532     SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
533     if ( !anSO->_is_nil() ) {
534       long aTag = SMESH_Gen_i::GetRefOnShapeTag(); 
535       SALOMEDS::SObject_var anObj, aRef;
536       if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
537         aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
538
539       aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
540     }
541   }
542
543   removeSubMesh( theSubMesh, aSubShapeObject.in() );
544 }
545
546
547 //=============================================================================
548 /*!
549  *  
550  */
551 //=============================================================================
552
553 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
554                                                  const char*         theName )
555      throw(SALOME::SALOME_Exception)
556 {
557   Unexpect aCatch(SALOME_SalomeException);
558   SMESH::SMESH_Group_var aNewGroup =
559     SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
560
561   _gen_i->PublishGroup( _gen_i->GetCurrentStudy(), _this(),
562                        aNewGroup, GEOM::GEOM_Object::_nil(), theName);
563
564   return aNewGroup._retn();
565 }
566
567
568 //=============================================================================
569 /*!
570  *  
571  */
572 //=============================================================================
573 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM( SMESH::ElementType    theElemType,
574                                                                const char*           theName,
575                                                                GEOM::GEOM_Object_ptr theGeomObj)
576      throw(SALOME::SALOME_Exception)
577 {
578   Unexpect aCatch(SALOME_SalomeException);
579   SMESH::SMESH_GroupOnGeom_var aNewGroup;
580
581   TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
582   if ( !aShape.IsNull() ) {
583     aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
584       ( createGroup( theElemType, theName, aShape ));
585     if ( _gen_i->CanPublishInStudy( aNewGroup ) )
586       _gen_i->PublishGroup( _gen_i->GetCurrentStudy(), _this(), 
587                            aNewGroup, theGeomObj, theName );
588   }
589
590   return aNewGroup._retn();
591 }
592 //=============================================================================
593 /*!
594  *  
595  */
596 //=============================================================================
597
598 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
599      throw (SALOME::SALOME_Exception)
600 {
601   if ( theGroup->_is_nil() )
602     return;
603
604   SMESH_GroupBase_i* aGroup =
605     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
606   if ( !aGroup )
607     return;
608
609   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
610   if ( !aStudy->_is_nil() )  {
611     // Remove group's SObject
612     SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
613     if ( !aGroupSO->_is_nil() )
614       aStudy->NewBuilder()->RemoveObject( aGroupSO );
615   }
616
617   // Remove the group from SMESH data structures
618   removeGroup( aGroup->GetLocalID() );
619 }
620
621 //=============================================================================
622 /*! RemoveGroupWithContents
623  *  Remove group with its contents
624  */ 
625 //=============================================================================
626 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
627   throw (SALOME::SALOME_Exception)
628 {
629   if ( theGroup->_is_nil() )
630     return;
631
632   SMESH_GroupBase_i* aGroup =
633     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
634   if ( !aGroup )
635     return;
636   
637   SMESH::long_array_var anIds = aGroup->GetListOfID();
638   SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
639     
640   if ( aGroup->GetType() == SMESH::NODE )
641     aMeshEditor->RemoveNodes( anIds );
642   else
643     aMeshEditor->RemoveElements( anIds );
644   
645   RemoveGroup( theGroup );
646 }
647
648 //=============================================================================
649 /*! UnionGroups
650  *  New group is created. All mesh elements that are 
651  *  present in initial groups are added to the new one
652  */
653 //=============================================================================
654 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
655                                                   SMESH::SMESH_GroupBase_ptr theGroup2, 
656                                                   const char* theName )
657   throw (SALOME::SALOME_Exception)
658 {
659   try
660   {
661     SMESH::SMESH_Group_var aResGrp;
662
663     if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
664          theGroup1->GetType() != theGroup2->GetType() )
665       return SMESH::SMESH_Group::_nil();
666
667     aResGrp = CreateGroup( theGroup1->GetType(), theName );
668     if ( aResGrp->_is_nil() )
669       return SMESH::SMESH_Group::_nil();
670
671     SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
672     SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
673
674     TColStd_MapOfInteger aResMap;
675
676     for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
677       aResMap.Add( anIds1[ i1 ] );
678
679     for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
680       aResMap.Add( anIds2[ i2 ] );
681
682     SMESH::long_array_var aResIds = new SMESH::long_array;
683     aResIds->length( aResMap.Extent() );
684
685     int resI = 0;
686     TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
687     for( ; anIter.More(); anIter.Next() )
688       aResIds[ resI++ ] = anIter.Key();
689
690     aResGrp->Add( aResIds );
691
692     return aResGrp._retn();
693   }
694   catch( ... )
695   {
696     return SMESH::SMESH_Group::_nil();
697   }
698 }
699   
700 //=============================================================================
701 /*! IntersectGroups
702  *  New group is created. All mesh elements that are 
703  *  present in both initial groups are added to the new one.
704  */
705 //=============================================================================
706 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
707                                                       SMESH::SMESH_GroupBase_ptr theGroup2, 
708                                                       const char* theName )
709   throw (SALOME::SALOME_Exception)
710 {
711   SMESH::SMESH_Group_var aResGrp;
712   
713   if ( theGroup1->_is_nil() || theGroup2->_is_nil() || 
714        theGroup1->GetType() != theGroup2->GetType() )
715     return aResGrp;
716   
717   aResGrp = CreateGroup( theGroup1->GetType(), theName );
718   if ( aResGrp->_is_nil() )
719     return aResGrp;
720   
721   SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
722   SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
723   
724   TColStd_MapOfInteger aMap1;
725   
726   for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
727     aMap1.Add( anIds1[ i1 ] );
728
729   TColStd_SequenceOfInteger aSeq;
730
731   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
732     if ( aMap1.Contains( anIds2[ i2 ] ) )
733       aSeq.Append( anIds2[ i2 ] );
734   
735   SMESH::long_array_var aResIds = new SMESH::long_array;
736   aResIds->length( aSeq.Length() );
737   
738   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
739     aResIds[ resI ] = aSeq( resI + 1 );
740   
741   aResGrp->Add( aResIds );
742   
743   return aResGrp._retn();
744 }
745
746 //=============================================================================
747 /*! CutGroups
748  *  New group is created. All mesh elements that are present in 
749  *  main group but do not present in tool group are added to the new one 
750  */
751 //=============================================================================
752 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
753                                                 SMESH::SMESH_GroupBase_ptr theGroup2, 
754                                                 const char* theName )
755   throw (SALOME::SALOME_Exception)
756 {
757   SMESH::SMESH_Group_var aResGrp;
758   
759   if ( theGroup1->_is_nil() || theGroup2->_is_nil() || 
760        theGroup1->GetType() != theGroup2->GetType() )
761     return aResGrp;
762   
763   aResGrp = CreateGroup( theGroup1->GetType(), theName );
764   if ( aResGrp->_is_nil() )
765     return aResGrp;
766   
767   SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
768   SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
769   
770   TColStd_MapOfInteger aMap2;
771   
772   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
773     aMap2.Add( anIds2[ i2 ] );
774
775
776   TColStd_SequenceOfInteger aSeq;
777   for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
778     if ( !aMap2.Contains( anIds1[ i1 ] ) )
779       aSeq.Append( anIds1[ i1 ] );
780
781   SMESH::long_array_var aResIds = new SMESH::long_array;
782   aResIds->length( aSeq.Length() );
783
784   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
785     aResIds[ resI ] = aSeq( resI + 1 );  
786   
787   aResGrp->Add( aResIds );
788   
789   return aResGrp._retn();
790 }
791
792 //=============================================================================
793 /*!
794  *  
795  */
796 //=============================================================================
797
798 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
799 {
800   if(MYDEBUG) MESSAGE( "createSubMesh" );
801   TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
802
803   ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
804   int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
805   SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
806   SMESH::SMESH_subMesh_var subMesh
807     = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
808
809   _mapSubMesh[subMeshId] = mySubMesh;
810   _mapSubMesh_i[subMeshId] = subMeshServant;
811   _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
812
813   // register CORBA object for persistence
814   int nextId = _gen_i->RegisterObject( subMesh );
815   if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
816
817   return subMesh._retn(); 
818 }
819
820 //=======================================================================
821 //function : getSubMesh
822 //purpose  : 
823 //=======================================================================
824
825 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
826 {
827   map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
828   if ( it == _mapSubMeshIor.end() )
829     return SMESH::SMESH_subMesh::_nil();
830
831   return SMESH::SMESH_subMesh::_duplicate( (*it).second );
832 }
833
834
835 //=============================================================================
836 /*!
837  *  
838  */
839 //=============================================================================
840
841 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
842                                   GEOM::GEOM_Object_ptr    theSubShapeObject )
843 {
844   MESSAGE("SMESH_Mesh_i::removeSubMesh()");
845   if ( theSubMesh->_is_nil() || theSubShapeObject->_is_nil() )
846     return;
847
848   try {
849     SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
850     for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
851       removeHypothesis( theSubShapeObject, aHypList[i] );
852     }
853   }
854   catch( const SALOME::SALOME_Exception& ) {
855     INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
856   }
857
858   int subMeshId = theSubMesh->GetId();
859
860   _mapSubMesh.erase(subMeshId);
861   _mapSubMesh_i.erase(subMeshId);
862   _mapSubMeshIor.erase(subMeshId);
863   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
864 }
865
866 //=============================================================================
867 /*!
868  *  
869  */
870 //=============================================================================
871
872 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
873                                                       const char*         theName,
874                                                       const TopoDS_Shape& theShape )
875 {
876   int anId;
877   SMESH::SMESH_GroupBase_var aGroup;
878   if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
879     SMESH_GroupBase_i* aGroupImpl;
880     if ( !theShape.IsNull() )
881       aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
882     else
883       aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
884     aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
885     _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
886
887     // register CORBA object for persistence
888     int nextId = _gen_i->RegisterObject( aGroup );
889     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
890   }
891   return aGroup._retn();
892 }
893
894 //=============================================================================
895 /*!
896  * SMESH_Mesh_i::removeGroup
897  *
898  * Should be called by ~SMESH_Group_i() 
899  */
900 //=============================================================================
901
902 void SMESH_Mesh_i::removeGroup( const int theId )
903 {
904   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );  
905   if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
906     _mapGroups.erase( theId );
907     _impl->RemoveGroup( theId );
908   }
909 }
910
911
912 //=============================================================================
913 /*!
914  *  
915  */
916 //=============================================================================
917
918 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
919 throw(SALOME::SALOME_Exception)
920 {
921   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
922   
923   SMESH::log_array_var aLog;
924   try{
925     list < SMESHDS_Command * >logDS = _impl->GetLog();
926     aLog = new SMESH::log_array;
927     int indexLog = 0;
928     int lg = logDS.size();
929     SCRUTE(lg);
930     aLog->length(lg);
931     list < SMESHDS_Command * >::iterator its = logDS.begin();
932     while(its != logDS.end()){
933       SMESHDS_Command *com = *its;
934       int comType = com->GetType();
935       //SCRUTE(comType);
936       int lgcom = com->GetNumber();
937       //SCRUTE(lgcom);
938       const list < int >&intList = com->GetIndexes();
939       int inum = intList.size();
940       //SCRUTE(inum);
941       list < int >::const_iterator ii = intList.begin();
942       const list < double >&coordList = com->GetCoords();
943       int rnum = coordList.size();
944       //SCRUTE(rnum);
945       list < double >::const_iterator ir = coordList.begin();
946       aLog[indexLog].commandType = comType;
947       aLog[indexLog].number = lgcom;
948       aLog[indexLog].coords.length(rnum);
949       aLog[indexLog].indexes.length(inum);
950       for(int i = 0; i < rnum; i++){
951         aLog[indexLog].coords[i] = *ir;
952         //MESSAGE(" "<<i<<" "<<ir.Value());
953         ir++;
954       }
955       for(int i = 0; i < inum; i++){
956         aLog[indexLog].indexes[i] = *ii;
957         //MESSAGE(" "<<i<<" "<<ii.Value());
958         ii++;
959       }
960       indexLog++;
961       its++;
962     }
963     if(clearAfterGet)
964       _impl->ClearLog();
965   }
966   catch(SALOME_Exception & S_ex){
967     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
968   }
969   return aLog._retn();
970 }
971
972
973 //=============================================================================
974 /*!
975  *  
976  */
977 //=============================================================================
978
979 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
980 {
981   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
982   // ****
983 }
984
985 //=============================================================================
986 /*!
987  *  
988  */
989 //=============================================================================
990
991 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
992 {
993   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
994   return _id;
995 }
996
997 //=============================================================================
998 /*!
999  *  
1000  */
1001 //=============================================================================
1002
1003 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
1004 {
1005   return _studyId;
1006 }
1007
1008 //=============================================================================
1009 /*!
1010  *  
1011  */
1012 //=============================================================================
1013
1014 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
1015 {
1016   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
1017   _impl = impl;
1018 }
1019
1020 //=============================================================================
1021 /*!
1022  *  
1023  */
1024 //=============================================================================
1025
1026 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
1027 {
1028   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
1029   return *_impl;
1030 }
1031
1032
1033 //=============================================================================
1034 /*!
1035  *  
1036  */
1037 //=============================================================================
1038
1039 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
1040 {
1041         SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( _impl );
1042         SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
1043         return aMesh._retn();
1044 }
1045
1046 //=============================================================================
1047 /*!
1048  *  
1049  */
1050 //=============================================================================
1051
1052 void SMESH_Mesh_i::ExportMED(const char *file, CORBA::Boolean auto_groups) throw(SALOME::SALOME_Exception)
1053 {
1054   Unexpect aCatch(SALOME_SalomeException);
1055
1056   char* aMeshName = "Mesh";
1057   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1058   if ( !aStudy->_is_nil() ) {
1059     SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
1060     if ( !aMeshSO->_is_nil() ) {
1061       aMeshName = aMeshSO->GetName();
1062       //SCRUTE(file);
1063       //SCRUTE(aMeshName);
1064       //SCRUTE(aMeshSO->GetID());
1065
1066       // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes 
1067       if ( !aStudy->GetProperties()->IsLocked() ) 
1068       {
1069         SALOMEDS::GenericAttribute_var anAttr;
1070         SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
1071         SALOMEDS::AttributeExternalFileDef_var aFileName;
1072         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
1073         aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
1074         ASSERT(!aFileName->_is_nil());
1075         aFileName->SetValue(file);
1076         SALOMEDS::AttributeFileType_var aFileType;
1077         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
1078         aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
1079         ASSERT(!aFileType->_is_nil());
1080         aFileType->SetValue("FICHIERMED");
1081       }
1082     }
1083   }
1084   _impl->ExportMED( file, aMeshName, auto_groups );
1085 }
1086
1087 void SMESH_Mesh_i::ExportDAT(const char *file) throw(SALOME::SALOME_Exception)
1088 {
1089   Unexpect aCatch(SALOME_SalomeException);
1090   _impl->ExportDAT(file);
1091 }
1092 void SMESH_Mesh_i::ExportUNV(const char *file) throw(SALOME::SALOME_Exception)
1093 {
1094   Unexpect aCatch(SALOME_SalomeException);
1095   _impl->ExportUNV(file);
1096 }
1097
1098 void SMESH_Mesh_i::ExportSTL(const char *file, const bool isascii) throw(SALOME::SALOME_Exception)
1099 {
1100   Unexpect aCatch(SALOME_SalomeException);
1101   _impl->ExportSTL(file, isascii);
1102 }
1103
1104 //=============================================================================
1105 /*!
1106  *  
1107  */
1108 //=============================================================================
1109
1110 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
1111 {
1112   Unexpect aCatch(SALOME_SalomeException);
1113   SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
1114   SALOME_MED::MESH_var aMesh = aMedMesh->_this();
1115   return aMesh._retn();
1116 }
1117
1118 //=============================================================================
1119 /*!
1120  *  
1121  */
1122 //=============================================================================
1123 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
1124 {
1125   Unexpect aCatch(SALOME_SalomeException);
1126   return _impl->NbNodes();
1127 }
1128
1129 //=============================================================================
1130 /*!
1131  *  
1132  */
1133 //=============================================================================
1134 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
1135 {
1136   Unexpect aCatch(SALOME_SalomeException);
1137   return _impl->NbEdges();
1138 }
1139
1140 //=============================================================================
1141 /*!
1142  *  
1143  */
1144 //=============================================================================
1145 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
1146 {
1147   Unexpect aCatch(SALOME_SalomeException);
1148   return _impl->NbFaces();
1149 }
1150
1151 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
1152 {
1153   Unexpect aCatch(SALOME_SalomeException);
1154   return _impl->NbTriangles();
1155 }
1156
1157 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
1158 {
1159   Unexpect aCatch(SALOME_SalomeException);
1160   return _impl->NbQuadrangles();
1161 }
1162
1163 //=============================================================================
1164 /*!
1165  *  
1166  */
1167 //=============================================================================
1168 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
1169 {
1170   Unexpect aCatch(SALOME_SalomeException);
1171   return _impl->NbVolumes();
1172 }
1173
1174 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
1175 {
1176   Unexpect aCatch(SALOME_SalomeException);
1177   return _impl->NbTetras();
1178 }
1179
1180 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
1181 {
1182   Unexpect aCatch(SALOME_SalomeException);
1183   return _impl->NbHexas();
1184 }
1185
1186 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
1187 {
1188   Unexpect aCatch(SALOME_SalomeException);
1189   return _impl->NbPyramids();
1190 }
1191
1192 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
1193 {
1194   Unexpect aCatch(SALOME_SalomeException);
1195   return _impl->NbPrisms();
1196 }
1197
1198 //=============================================================================
1199 /*!
1200  *  
1201  */
1202 //=============================================================================
1203 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
1204 {
1205   Unexpect aCatch(SALOME_SalomeException);
1206   return _impl->NbSubMesh();
1207 }
1208
1209 //=============================================================================
1210 /*!
1211  *  
1212  */
1213 //=============================================================================
1214 char* SMESH_Mesh_i::Dump()
1215 {
1216   std::ostringstream os;
1217   _impl->Dump( os );
1218   return CORBA::string_dup( os.str().c_str() );
1219 }
1220
1221 //=============================================================================
1222 /*!
1223  *  
1224  */
1225 //=============================================================================
1226 SMESH::long_array* SMESH_Mesh_i::GetIDs()
1227 {
1228   SMESH::long_array_var aResult = new SMESH::long_array();
1229   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1230   int aMinId = aSMESHDS_Mesh->MinElementID();
1231   int aMaxId =  aSMESHDS_Mesh->MaxElementID();
1232
1233   aResult->length(aMaxId - aMinId + 1);
1234   
1235   for (int i = 0, id = aMinId; id <= aMaxId; id++  )
1236     aResult[i++] = id;
1237   
1238   return aResult._retn();
1239 }