Salome HOME
22bde5e382bbfc837bd79dfa91f64ad505f019cf
[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 "SMESHDS_Command.hxx"
45 #include "SMESHDS_CommandType.hxx"
46 #include "SMESH_MeshEditor_i.hxx"
47 #include "SMESH_Gen_i.hxx"
48 #include "DriverMED_R_SMESHDS_Mesh.h"
49
50 #include <TColStd_MapOfInteger.hxx>
51 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
52 #include <TColStd_SequenceOfInteger.hxx>
53
54 #include <string>
55 #include <iostream>
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   _impl = NULL;
81   _gen_i = gen_i;
82   _id = myIdGenerator++;
83   _studyId = studyId;
84   thePOA->activate_object( this );
85 }
86
87 //=============================================================================
88 /*!
89  *  Destructor
90  */
91 //=============================================================================
92
93 SMESH_Mesh_i::~SMESH_Mesh_i()
94 {
95   INFOS("~SMESH_Mesh_i");
96   map<int, SMESH::SMESH_GroupBase_ptr>::iterator it;
97   for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) {
98     SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( it->second ).in() );
99     if ( aGroup ) {
100
101       // this method is colled from destructor of group (PAL6331)
102       //_impl->RemoveGroup( aGroup->GetLocalID() );
103       
104       aGroup->Destroy();
105     }
106   }
107   _mapGroups.clear();
108 }
109
110 //=============================================================================
111 /*!
112  *  SetShape
113  *
114  *  Associates <this> mesh with <theShape> and puts a reference  
115  *  to <theShape> into the current study; 
116  *  the previous shape is substituted by the new one.
117  */
118 //=============================================================================
119
120 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
121     throw (SALOME::SALOME_Exception)
122 {
123   Unexpect aCatch(SALOME_SalomeException);
124   try {
125     _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
126   }
127   catch(SALOME_Exception & S_ex) {
128     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
129   }
130 }
131
132 //=======================================================================
133 //function : GetShapeToMesh
134 //purpose  : 
135 //=======================================================================
136
137 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
138     throw (SALOME::SALOME_Exception)
139 {
140   Unexpect aCatch(SALOME_SalomeException);
141   GEOM::GEOM_Object_var aShapeObj;
142   try {
143     TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
144     if ( !S.IsNull() )
145       aShapeObj = _gen_i->ShapeToGeomObject( S );
146   }
147   catch(SALOME_Exception & S_ex) {
148     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
149   }
150   return aShapeObj._retn();
151 }
152
153 //=============================================================================
154 /*!
155  *  
156  */
157 //=============================================================================
158
159 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
160 {
161   SMESH::DriverMED_ReadStatus res;
162   switch (theStatus)
163   {
164   case DriverMED_R_SMESHDS_Mesh::DRS_OK:
165     res = SMESH::DRS_OK; break;
166   case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
167     res = SMESH::DRS_EMPTY; break;
168   case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
169     res = SMESH::DRS_WARN_RENUMBER; break;
170   case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
171     res = SMESH::DRS_WARN_SKIP_ELEM; break;
172   case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
173   default:
174     res = SMESH::DRS_FAIL; break;
175   }
176   return res;
177 }
178
179 //=============================================================================
180 /*!
181  *  ImportMEDFile
182  *
183  *  Imports mesh data from MED file
184  */
185 //=============================================================================
186
187 SMESH::DriverMED_ReadStatus
188 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
189   throw ( SALOME::SALOME_Exception )
190 {
191   Unexpect aCatch(SALOME_SalomeException);
192   int status;
193   try {
194     status = importMEDFile( theFileName, theMeshName );
195   }
196   catch( SALOME_Exception& S_ex ) {
197     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
198   }  
199   catch ( ... ) {
200     THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
201   }
202
203   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
204   if ( !aStudy->_is_nil() ) {
205     // publishing of the groups in the study (sub-meshes are out of scope of MED import)
206     map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
207     for (; it != _mapGroups.end(); it++ ) {
208       SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_duplicate( it->second );
209       _gen_i->PublishGroup( aStudy, _this(), aGroup,
210                            GEOM::GEOM_Object::_nil(), aGroup->GetName());
211     }
212   }
213   return ConvertDriverMEDReadStatus(status);
214 }
215
216 //=============================================================================
217 /*!
218  *  ImportUNVFile
219  *
220  *  Imports mesh data from MED file
221  */
222 //=============================================================================
223
224 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
225   throw ( SALOME::SALOME_Exception )
226 {
227   // Read mesh with name = <theMeshName> into SMESH_Mesh
228   _impl->UNVToMesh( theFileName );
229
230   return 1;
231 }
232
233 //=============================================================================
234 /*!
235  *  ImportSTLFile
236  *
237  *  Imports mesh data from STL file
238  */
239 //=============================================================================
240 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
241   throw ( SALOME::SALOME_Exception )
242 {
243   // Read mesh with name = <theMeshName> into SMESH_Mesh
244   _impl->STLToMesh( theFileName );
245
246   return 1;
247 }
248
249 //=============================================================================
250 /*!
251  *  importMEDFile
252  *
253  *  Imports mesh data from MED file
254  */
255 //=============================================================================
256
257 int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
258 {
259   // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
260   int status = _impl->MEDToMesh( theFileName, theMeshName );
261
262   // Create group servants, if any groups were imported
263   list<int> aGroupIds = _impl->GetGroupIds();
264   for ( list<int>::iterator it = aGroupIds.begin(); it != aGroupIds.end(); it++ ) {
265     SMESH_Group_i* aGroupImpl     = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, *it );
266
267     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
268     SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
269     aGroupImpl->Register();
270     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
271
272     SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
273     _mapGroups[*it]               = SMESH::SMESH_Group::_duplicate( aGroup );
274
275     // register CORBA object for persistence
276     int nextId = _gen_i->RegisterObject( aGroup );
277     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
278   }
279
280   return status;
281 }
282
283 //=============================================================================
284 /*!
285  *  
286  */
287 //=============================================================================
288
289 static SMESH::Hypothesis_Status ConvertHypothesisStatus
290                          (SMESH_Hypothesis::Hypothesis_Status theStatus)
291 {
292   SMESH::Hypothesis_Status res;
293   switch (theStatus)
294   {
295   case SMESH_Hypothesis::HYP_OK:
296     res = SMESH::HYP_OK; break;
297   case SMESH_Hypothesis::HYP_MISSING:
298     res = SMESH::HYP_MISSING; break;
299   case SMESH_Hypothesis::HYP_CONCURENT:
300     res = SMESH::HYP_CONCURENT; break;
301   case SMESH_Hypothesis::HYP_BAD_PARAMETER:
302     res = SMESH::HYP_BAD_PARAMETER; break;
303   case SMESH_Hypothesis::HYP_INCOMPATIBLE:
304     res = SMESH::HYP_INCOMPATIBLE; break;
305   case SMESH_Hypothesis::HYP_NOTCONFORM:
306     res = SMESH::HYP_NOTCONFORM; break;
307   case SMESH_Hypothesis::HYP_ALREADY_EXIST:
308     res = SMESH::HYP_ALREADY_EXIST; break;
309   case SMESH_Hypothesis::HYP_BAD_DIM:
310     res = SMESH::HYP_BAD_DIM; break;
311   default:
312     res = SMESH::HYP_UNKNOWN_FATAL;
313   }
314   return res;
315 }
316
317 //=============================================================================
318 /*!
319  *  AddHypothesis
320  *
321  *  calls internal addHypothesis() and then adds a reference to <anHyp> under 
322  *  the SObject actually having a reference to <aSubShape>.
323  *  NB: For this method to work, it is necessary to add a reference to sub-shape first.
324  */
325 //=============================================================================
326
327 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
328                                                      SMESH::SMESH_Hypothesis_ptr anHyp)
329   throw(SALOME::SALOME_Exception)
330 {
331   Unexpect aCatch(SALOME_SalomeException);
332   SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
333
334   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
335     _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
336                                  aSubShapeObject, anHyp );
337
338   if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
339
340   // Update Python script
341   TCollection_AsciiString aStr ("status = ");
342   SMESH_Gen_i::AddObject(aStr, _this()) += ".AddHypothesis(";
343   SMESH_Gen_i::AddObject(aStr, aSubShapeObject) += ", ";
344   SMESH_Gen_i::AddObject(aStr, anHyp) += ")";
345
346   SMESH_Gen_i::AddToCurrentPyScript(aStr);
347
348   return ConvertHypothesisStatus(status);
349 }
350
351 //=============================================================================
352 /*!
353  *  
354  */
355 //=============================================================================
356
357 SMESH_Hypothesis::Hypothesis_Status
358   SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr       aSubShapeObject,
359                               SMESH::SMESH_Hypothesis_ptr anHyp)
360 {
361   if(MYDEBUG) MESSAGE("addHypothesis");
362
363   if (CORBA::is_nil(aSubShapeObject))
364     THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
365                                  SALOME::BAD_PARAM);
366
367   SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
368   if (CORBA::is_nil(myHyp))
369     THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
370                                  SALOME::BAD_PARAM);
371
372   SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
373   try
374   {
375     TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
376     int hypId = myHyp->GetId();
377     status = _impl->AddHypothesis(myLocSubShape, hypId);
378     if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
379       _mapHypo[hypId] = myHyp;
380       // assure there is a corresponding submesh
381       if ( !_impl->IsMainShape( myLocSubShape )) {
382         int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
383         if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
384           createSubMesh( aSubShapeObject );
385       }
386     }
387   }
388   catch(SALOME_Exception & S_ex)
389   {
390     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
391   }
392   return status;
393 }
394
395 //=============================================================================
396 /*!
397  *  
398  */
399 //=============================================================================
400
401 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
402                                                         SMESH::SMESH_Hypothesis_ptr anHyp)
403      throw(SALOME::SALOME_Exception)
404 {
405   Unexpect aCatch(SALOME_SalomeException);
406   SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
407
408   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
409     _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
410                                       aSubShapeObject, anHyp );
411
412   // Update Python script
413   TCollection_AsciiString aStr ("status = ");
414   SMESH_Gen_i::AddObject(aStr, _this()) += ".RemoveHypothesis(";
415   SMESH_Gen_i::AddObject(aStr, aSubShapeObject) += ", ";
416   SMESH_Gen_i::AddObject(aStr, anHyp) += ")";
417
418   SMESH_Gen_i::AddToCurrentPyScript(aStr);
419
420   return ConvertHypothesisStatus(status);
421 }
422
423 //=============================================================================
424 /*!
425  *  
426  */
427 //=============================================================================
428
429 SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
430                                  SMESH::SMESH_Hypothesis_ptr anHyp)
431 {
432         if(MYDEBUG) MESSAGE("removeHypothesis()");
433         // **** proposer liste de subShape (selection multiple)
434
435         if (CORBA::is_nil(aSubShapeObject))
436                 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
437                         SALOME::BAD_PARAM);
438
439         SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
440         if (CORBA::is_nil(myHyp))
441           THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
442                         SALOME::BAD_PARAM);
443
444         SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
445         try
446         {
447                 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
448                 int hypId = myHyp->GetId();
449                 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
450                 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
451                   _mapHypo.erase( hypId );
452         }
453         catch(SALOME_Exception & S_ex)
454         {
455                 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
456         }
457         return status;
458 }
459
460 //=============================================================================
461 /*!
462  *  
463  */
464 //=============================================================================
465
466 SMESH::ListOfHypothesis *
467         SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
468 throw(SALOME::SALOME_Exception)
469 {
470   Unexpect aCatch(SALOME_SalomeException);
471   if (MYDEBUG) MESSAGE("GetHypothesisList");
472   if (CORBA::is_nil(aSubShapeObject))
473     THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
474                                  SALOME::BAD_PARAM);
475   
476   SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
477
478   try {
479     TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
480     const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
481     int i = 0, n = aLocalList.size();
482     aList->length( n );
483
484     for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
485       SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
486       if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
487         aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
488     }
489
490     aList->length( i );
491   }
492   catch(SALOME_Exception & S_ex) {
493     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
494   }
495   
496   return aList._retn();
497 }
498
499 //=============================================================================
500 /*!
501  *  
502  */
503 //=============================================================================
504 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
505                                                   const char*           theName ) 
506      throw(SALOME::SALOME_Exception)
507 {
508   Unexpect aCatch(SALOME_SalomeException);
509   MESSAGE("SMESH_Mesh_i::GetSubMesh");
510   if (CORBA::is_nil(aSubShapeObject))
511     THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
512                                  SALOME::BAD_PARAM);
513   
514   SMESH::SMESH_subMesh_var subMesh;
515   SMESH::SMESH_Mesh_var    aMesh = SMESH::SMESH_Mesh::_narrow(_this());
516   try {
517     TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
518     
519     //Get or Create the SMESH_subMesh object implementation
520     
521     int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
522     subMesh = getSubMesh( subMeshId );
523
524     // create a new subMesh object servant if there is none for the shape
525     if ( subMesh->_is_nil() )
526       subMesh = createSubMesh( aSubShapeObject );
527
528     if ( _gen_i->CanPublishInStudy( subMesh )) {
529       SALOMEDS::SObject_var aSO =
530         _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
531                                subMesh, aSubShapeObject, theName );
532       if ( !aSO->_is_nil()) {
533         // Update Python script
534         TCollection_AsciiString aStr (aSO->GetID());
535         aStr += " = ";
536         SMESH_Gen_i::AddObject(aStr, _this()) += ".GetSubMesh(";
537         SMESH_Gen_i::AddObject(aStr, aSubShapeObject) += ", \"";
538         aStr += (char*)theName;
539         aStr += "\")";
540
541         SMESH_Gen_i::AddToCurrentPyScript(aStr);
542       }
543     }
544   }
545   catch(SALOME_Exception & S_ex) {
546     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
547   }
548   return subMesh._retn();
549 }
550
551 //=============================================================================
552 /*!
553  *  
554  */
555 //=============================================================================
556
557 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
558      throw (SALOME::SALOME_Exception)
559 {
560   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
561   if ( theSubMesh->_is_nil() )
562     return;
563
564   GEOM::GEOM_Object_var aSubShapeObject;
565   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
566   if ( !aStudy->_is_nil() )  {
567     // Remove submesh's SObject
568     SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
569     if ( !anSO->_is_nil() ) {
570       long aTag = SMESH_Gen_i::GetRefOnShapeTag(); 
571       SALOMEDS::SObject_var anObj, aRef;
572       if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
573         aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
574
575       aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
576
577       // Update Python script
578       TCollection_AsciiString aStr;
579       SMESH_Gen_i::AddObject(aStr, _this()) += ".RemoveSubMesh(";
580       aStr += anSO->GetID();
581       aStr += ")";
582
583       SMESH_Gen_i::AddToCurrentPyScript(aStr);
584     }
585   }
586
587   removeSubMesh( theSubMesh, aSubShapeObject.in() );
588 }
589
590 //=============================================================================
591 /*!
592  *  ElementTypeString
593  */
594 //=============================================================================
595 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
596 {
597   TCollection_AsciiString aStr;
598   switch (theElemType) {
599   case SMESH::ALL:
600     aStr = "SMESH.ALL";
601     break;
602   case SMESH::NODE:
603     aStr = "SMESH.NODE";
604     break;
605   case SMESH::EDGE:
606     aStr = "SMESH.EDGE";
607     break;
608   case SMESH::FACE:
609     aStr = "SMESH.FACE";
610     break;
611   case SMESH::VOLUME:
612     aStr = "SMESH.VOLUME";
613     break;
614   default:
615     break;
616   }
617   return aStr;
618 }
619
620 //=============================================================================
621 /*!
622  *  
623  */
624 //=============================================================================
625
626 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
627                                                  const char*         theName )
628      throw(SALOME::SALOME_Exception)
629 {
630   Unexpect aCatch(SALOME_SalomeException);
631   SMESH::SMESH_Group_var aNewGroup =
632     SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
633
634   if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
635     SALOMEDS::SObject_var aSO =
636       _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
637                            aNewGroup, GEOM::GEOM_Object::_nil(), theName);
638     if ( !aSO->_is_nil()) {
639       // Update Python script
640       TCollection_AsciiString aStr (aSO->GetID());
641       aStr += " = ";
642       SMESH_Gen_i::AddObject(aStr, _this()) += ".CreateGroup(";
643       aStr += ElementTypeString(theElemType) + ", \"" + (char*)theName + "\")";
644
645       SMESH_Gen_i::AddToCurrentPyScript(aStr);
646     }
647   }
648
649   return aNewGroup._retn();
650 }
651
652
653 //=============================================================================
654 /*!
655  *  
656  */
657 //=============================================================================
658 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType    theElemType,
659                                                                 const char*           theName,
660                                                                 GEOM::GEOM_Object_ptr theGeomObj)
661      throw(SALOME::SALOME_Exception)
662 {
663   Unexpect aCatch(SALOME_SalomeException);
664   SMESH::SMESH_GroupOnGeom_var aNewGroup;
665
666   TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
667   if ( !aShape.IsNull() ) {
668     aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
669       ( createGroup( theElemType, theName, aShape ));
670     if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
671       SALOMEDS::SObject_var aSO =
672         _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), 
673                              aNewGroup, theGeomObj, theName);
674       if ( !aSO->_is_nil()) {
675         // Update Python script
676         TCollection_AsciiString aStr (aSO->GetID());
677         aStr += " = ";
678         SMESH_Gen_i::AddObject(aStr, _this()) += ".CreateGroupFromGEOM(";
679         aStr += ElementTypeString(theElemType) + ", \"" + (char*)theName + "\", ";
680         SMESH_Gen_i::AddObject(aStr, theGeomObj) += ")";
681
682         SMESH_Gen_i::AddToCurrentPyScript(aStr);
683       }
684     }
685   }
686
687   return aNewGroup._retn();
688 }
689
690 //=============================================================================
691 /*!
692  *  
693  */
694 //=============================================================================
695
696 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
697      throw (SALOME::SALOME_Exception)
698 {
699   if ( theGroup->_is_nil() )
700     return;
701
702   SMESH_GroupBase_i* aGroup =
703     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
704   if ( !aGroup )
705     return;
706
707   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
708   if ( !aStudy->_is_nil() )  {
709     SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
710
711     if ( !aGroupSO->_is_nil() ) {
712       // Update Python script
713       TCollection_AsciiString aStr;
714       SMESH_Gen_i::AddObject(aStr, _this()) += ".RemoveGroup(";
715       aStr += aGroupSO->GetID();
716       aStr += ")";
717
718       SMESH_Gen_i::AddToCurrentPyScript(aStr);
719
720       // Remove group's SObject
721       aStudy->NewBuilder()->RemoveObject( aGroupSO );
722     }
723   }
724
725   // Remove the group from SMESH data structures
726   removeGroup( aGroup->GetLocalID() );
727 }
728
729 //=============================================================================
730 /*! RemoveGroupWithContents
731  *  Remove group with its contents
732  */ 
733 //=============================================================================
734 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
735   throw (SALOME::SALOME_Exception)
736 {
737   if ( theGroup->_is_nil() )
738     return;
739
740   SMESH_GroupBase_i* aGroup =
741     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
742   if ( !aGroup )
743     return;
744   
745   SMESH::long_array_var anIds = aGroup->GetListOfID();
746   SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
747
748   // Update Python script
749   TCollection_AsciiString aStr;
750   SMESH_Gen_i::AddObject(aStr, _this()) += ".RemoveGroupWithContents(";
751   SMESH_Gen_i::AddObject(aStr, theGroup) += ")";
752
753   SMESH_Gen_i::AddToCurrentPyScript(aStr);
754
755   // Remove contents
756   if ( aGroup->GetType() == SMESH::NODE )
757     aMeshEditor->RemoveNodes( anIds );
758   else
759     aMeshEditor->RemoveElements( anIds );
760
761   // Remove group
762   RemoveGroup( theGroup );
763
764   // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
765   _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
766   _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
767 }
768
769 //=============================================================================
770 /*! UnionGroups
771  *  New group is created. All mesh elements that are 
772  *  present in initial groups are added to the new one
773  */
774 //=============================================================================
775 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
776                                                   SMESH::SMESH_GroupBase_ptr theGroup2, 
777                                                   const char* theName )
778   throw (SALOME::SALOME_Exception)
779 {
780   try
781   {
782     if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
783          theGroup1->GetType() != theGroup2->GetType() )
784       return SMESH::SMESH_Group::_nil();
785
786     // Create Union
787     SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
788     if ( aResGrp->_is_nil() )
789       return SMESH::SMESH_Group::_nil();
790
791     SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
792     SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
793
794     TColStd_MapOfInteger aResMap;
795
796     for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
797       aResMap.Add( anIds1[ i1 ] );
798
799     for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
800       aResMap.Add( anIds2[ i2 ] );
801
802     SMESH::long_array_var aResIds = new SMESH::long_array;
803     aResIds->length( aResMap.Extent() );
804
805     int resI = 0;
806     TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
807     for( ; anIter.More(); anIter.Next() )
808       aResIds[ resI++ ] = anIter.Key();
809
810     aResGrp->Add( aResIds );
811
812     // Clear python lines, created by CreateGroup() and Add()
813     SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
814     _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
815     _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
816
817     // Update Python script
818     TCollection_AsciiString aStr;
819     SMESH_Gen_i::AddObject(aStr, aResGrp) += " = ";
820     SMESH_Gen_i::AddObject(aStr, _this()) += ".UnionGroups(";
821     SMESH_Gen_i::AddObject(aStr, theGroup1) += ", ";
822     SMESH_Gen_i::AddObject(aStr, theGroup2) += ", \"";
823     aStr += TCollection_AsciiString((char*)theName) + "\")";
824
825     SMESH_Gen_i::AddToCurrentPyScript(aStr);
826
827     return aResGrp._retn();
828   }
829   catch( ... )
830   {
831     return SMESH::SMESH_Group::_nil();
832   }
833 }
834   
835 //=============================================================================
836 /*! IntersectGroups
837  *  New group is created. All mesh elements that are 
838  *  present in both initial groups are added to the new one.
839  */
840 //=============================================================================
841 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
842                                                       SMESH::SMESH_GroupBase_ptr theGroup2, 
843                                                       const char* theName )
844   throw (SALOME::SALOME_Exception)
845 {
846   if ( theGroup1->_is_nil() || theGroup2->_is_nil() || 
847        theGroup1->GetType() != theGroup2->GetType() )
848     return SMESH::SMESH_Group::_nil();
849
850   // Create Intersection
851   SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
852   if ( aResGrp->_is_nil() )
853     return aResGrp;
854
855   SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
856   SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
857
858   TColStd_MapOfInteger aMap1;
859
860   for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
861     aMap1.Add( anIds1[ i1 ] );
862
863   TColStd_SequenceOfInteger aSeq;
864
865   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
866     if ( aMap1.Contains( anIds2[ i2 ] ) )
867       aSeq.Append( anIds2[ i2 ] );
868
869   SMESH::long_array_var aResIds = new SMESH::long_array;
870   aResIds->length( aSeq.Length() );
871
872   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
873     aResIds[ resI ] = aSeq( resI + 1 );
874
875   aResGrp->Add( aResIds );
876
877   // Clear python lines, created by CreateGroup() and Add()
878   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
879   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
880   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
881
882   // Update Python script
883   TCollection_AsciiString aStr;
884   SMESH_Gen_i::AddObject(aStr, aResGrp) += " = ";
885   SMESH_Gen_i::AddObject(aStr, _this()) += ".IntersectGroups(";
886   SMESH_Gen_i::AddObject(aStr, theGroup1) += ", ";
887   SMESH_Gen_i::AddObject(aStr, theGroup2) += ", \"";
888   aStr += TCollection_AsciiString((char*)theName) + "\")";
889
890   SMESH_Gen_i::AddToCurrentPyScript(aStr);
891
892   return aResGrp._retn();
893 }
894
895 //=============================================================================
896 /*! CutGroups
897  *  New group is created. All mesh elements that are present in 
898  *  main group but do not present in tool group are added to the new one 
899  */
900 //=============================================================================
901 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
902                                                 SMESH::SMESH_GroupBase_ptr theGroup2, 
903                                                 const char* theName )
904   throw (SALOME::SALOME_Exception)
905 {
906   if ( theGroup1->_is_nil() || theGroup2->_is_nil() || 
907        theGroup1->GetType() != theGroup2->GetType() )
908     return SMESH::SMESH_Group::_nil();
909
910   // Perform Cutting
911   SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
912   if ( aResGrp->_is_nil() )
913     return aResGrp;
914
915   SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
916   SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
917
918   TColStd_MapOfInteger aMap2;
919
920   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
921     aMap2.Add( anIds2[ i2 ] );
922
923
924   TColStd_SequenceOfInteger aSeq;
925   for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
926     if ( !aMap2.Contains( anIds1[ i1 ] ) )
927       aSeq.Append( anIds1[ i1 ] );
928
929   SMESH::long_array_var aResIds = new SMESH::long_array;
930   aResIds->length( aSeq.Length() );
931
932   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
933     aResIds[ resI ] = aSeq( resI + 1 );  
934
935   aResGrp->Add( aResIds );
936
937   // Clear python lines, created by CreateGroup() and Add()
938   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
939   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
940   _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
941
942   // Update Python script
943   TCollection_AsciiString aStr;
944   SMESH_Gen_i::AddObject(aStr, aResGrp) += " = ";
945   SMESH_Gen_i::AddObject(aStr, _this()) += ".CutGroups(";
946   SMESH_Gen_i::AddObject(aStr, theGroup1) += ", ";
947   SMESH_Gen_i::AddObject(aStr, theGroup2) += ", \"";
948   aStr += TCollection_AsciiString((char*)theName) + "\")";
949
950   SMESH_Gen_i::AddToCurrentPyScript(aStr);
951
952   return aResGrp._retn();
953 }
954
955 //=============================================================================
956 /*!
957  *  
958  */
959 //=============================================================================
960
961 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
962 {
963   if(MYDEBUG) MESSAGE( "createSubMesh" );
964   TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
965
966   ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
967   int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
968   SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
969   SMESH::SMESH_subMesh_var subMesh
970     = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
971
972   _mapSubMesh[subMeshId] = mySubMesh;
973   _mapSubMesh_i[subMeshId] = subMeshServant;
974   _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
975
976   // register CORBA object for persistence
977   int nextId = _gen_i->RegisterObject( subMesh );
978   if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
979
980   return subMesh._retn(); 
981 }
982
983 //=======================================================================
984 //function : getSubMesh
985 //purpose  : 
986 //=======================================================================
987
988 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
989 {
990   map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
991   if ( it == _mapSubMeshIor.end() )
992     return SMESH::SMESH_subMesh::_nil();
993
994   return SMESH::SMESH_subMesh::_duplicate( (*it).second );
995 }
996
997
998 //=============================================================================
999 /*!
1000  *  
1001  */
1002 //=============================================================================
1003
1004 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
1005                                   GEOM::GEOM_Object_ptr    theSubShapeObject )
1006 {
1007   MESSAGE("SMESH_Mesh_i::removeSubMesh()");
1008   if ( theSubMesh->_is_nil() || theSubShapeObject->_is_nil() )
1009     return;
1010
1011   try {
1012     SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
1013     for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
1014       removeHypothesis( theSubShapeObject, aHypList[i] );
1015     }
1016   }
1017   catch( const SALOME::SALOME_Exception& ) {
1018     INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
1019   }
1020
1021   int subMeshId = theSubMesh->GetId();
1022
1023   _mapSubMesh.erase(subMeshId);
1024   _mapSubMesh_i.erase(subMeshId);
1025   _mapSubMeshIor.erase(subMeshId);
1026   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
1027 }
1028
1029 //=============================================================================
1030 /*!
1031  *  
1032  */
1033 //=============================================================================
1034
1035 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
1036                                                       const char*         theName,
1037                                                       const TopoDS_Shape& theShape )
1038 {
1039   int anId;
1040   SMESH::SMESH_GroupBase_var aGroup;
1041   if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
1042     SMESH_GroupBase_i* aGroupImpl;
1043     if ( !theShape.IsNull() )
1044       aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
1045     else
1046       aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1047
1048     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1049     SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1050     aGroupImpl->Register();
1051     // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1052
1053     aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
1054     _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1055
1056     // register CORBA object for persistence
1057     int nextId = _gen_i->RegisterObject( aGroup );
1058     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
1059   }
1060   return aGroup._retn();
1061 }
1062
1063 //=============================================================================
1064 /*!
1065  * SMESH_Mesh_i::removeGroup
1066  *
1067  * Should be called by ~SMESH_Group_i() 
1068  */
1069 //=============================================================================
1070
1071 void SMESH_Mesh_i::removeGroup( const int theId )
1072 {
1073   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );  
1074   if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
1075     _mapGroups.erase( theId );
1076     _impl->RemoveGroup( theId );
1077   }
1078 }
1079
1080
1081 //=============================================================================
1082 /*!
1083  *  
1084  */
1085 //=============================================================================
1086
1087 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
1088 throw(SALOME::SALOME_Exception)
1089 {
1090   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
1091   
1092   SMESH::log_array_var aLog;
1093   try{
1094     list < SMESHDS_Command * >logDS = _impl->GetLog();
1095     aLog = new SMESH::log_array;
1096     int indexLog = 0;
1097     int lg = logDS.size();
1098     SCRUTE(lg);
1099     aLog->length(lg);
1100     list < SMESHDS_Command * >::iterator its = logDS.begin();
1101     while(its != logDS.end()){
1102       SMESHDS_Command *com = *its;
1103       int comType = com->GetType();
1104       //SCRUTE(comType);
1105       int lgcom = com->GetNumber();
1106       //SCRUTE(lgcom);
1107       const list < int >&intList = com->GetIndexes();
1108       int inum = intList.size();
1109       //SCRUTE(inum);
1110       list < int >::const_iterator ii = intList.begin();
1111       const list < double >&coordList = com->GetCoords();
1112       int rnum = coordList.size();
1113       //SCRUTE(rnum);
1114       list < double >::const_iterator ir = coordList.begin();
1115       aLog[indexLog].commandType = comType;
1116       aLog[indexLog].number = lgcom;
1117       aLog[indexLog].coords.length(rnum);
1118       aLog[indexLog].indexes.length(inum);
1119       for(int i = 0; i < rnum; i++){
1120         aLog[indexLog].coords[i] = *ir;
1121         //MESSAGE(" "<<i<<" "<<ir.Value());
1122         ir++;
1123       }
1124       for(int i = 0; i < inum; i++){
1125         aLog[indexLog].indexes[i] = *ii;
1126         //MESSAGE(" "<<i<<" "<<ii.Value());
1127         ii++;
1128       }
1129       indexLog++;
1130       its++;
1131     }
1132     if(clearAfterGet)
1133       _impl->ClearLog();
1134   }
1135   catch(SALOME_Exception & S_ex){
1136     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1137   }
1138   return aLog._retn();
1139 }
1140
1141
1142 //=============================================================================
1143 /*!
1144  *  
1145  */
1146 //=============================================================================
1147
1148 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
1149 {
1150   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
1151   // ****
1152 }
1153
1154 //=============================================================================
1155 /*!
1156  *  
1157  */
1158 //=============================================================================
1159
1160 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
1161 {
1162   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
1163   return _id;
1164 }
1165
1166 //=============================================================================
1167 /*!
1168  *  
1169  */
1170 //=============================================================================
1171
1172 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
1173 {
1174   return _studyId;
1175 }
1176
1177 //=============================================================================
1178 /*!
1179  *  
1180  */
1181 //=============================================================================
1182
1183 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
1184 {
1185   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
1186   _impl = impl;
1187 }
1188
1189 //=============================================================================
1190 /*!
1191  *  
1192  */
1193 //=============================================================================
1194
1195 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
1196 {
1197   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
1198   return *_impl;
1199 }
1200
1201
1202 //=============================================================================
1203 /*!
1204  *  
1205  */
1206 //=============================================================================
1207
1208 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
1209 {
1210   // Update Python script
1211   TCollection_AsciiString aStr ("mesh_editor = ");
1212   SMESH_Gen_i::AddObject(aStr, _this()) += ".GetMeshEditor()";
1213
1214   SMESH_Gen_i::AddToCurrentPyScript(aStr);
1215
1216   // Create MeshEditor
1217   SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( _impl );
1218   SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
1219   return aMesh._retn();
1220 }
1221
1222 //=============================================================================
1223 /*!
1224  *  Export in different formats
1225  */
1226 //=============================================================================
1227
1228 void SMESH_Mesh_i::ExportToMED (const char* file, 
1229                                 CORBA::Boolean auto_groups, 
1230                                 SMESH::MED_VERSION theVersion)
1231   throw(SALOME::SALOME_Exception)
1232 {
1233   Unexpect aCatch(SALOME_SalomeException);
1234
1235   // Update Python script
1236   TCollection_AsciiString aStr;
1237   SMESH_Gen_i::AddObject(aStr, _this()) += ".ExportToMED(\"";
1238   aStr += TCollection_AsciiString((char*)file) + "\", ";
1239   aStr += TCollection_AsciiString((int)auto_groups) + ", ";
1240   switch (theVersion) {
1241   case SMESH::MED_V2_1:
1242     aStr += "SMESH.MED_V2_1)";
1243     break;
1244   case SMESH::MED_V2_2:
1245     aStr += "SMESH.MED_V2_2)";
1246     break;
1247   default:
1248     aStr += TCollection_AsciiString(theVersion) + ")";
1249     break;
1250   }
1251
1252   SMESH_Gen_i::AddToCurrentPyScript(aStr);
1253
1254   // Perform Export
1255   char* aMeshName = "Mesh";
1256   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1257   if ( !aStudy->_is_nil() ) {
1258     SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
1259     if ( !aMeshSO->_is_nil() ) {
1260       aMeshName = aMeshSO->GetName();
1261       //SCRUTE(file);
1262       //SCRUTE(aMeshName);
1263       //SCRUTE(aMeshSO->GetID());
1264       
1265       // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes 
1266       if ( !aStudy->GetProperties()->IsLocked() ) 
1267         {
1268         SALOMEDS::GenericAttribute_var anAttr;
1269         SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
1270         SALOMEDS::AttributeExternalFileDef_var aFileName;
1271         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
1272         aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
1273         ASSERT(!aFileName->_is_nil());
1274         aFileName->SetValue(file);
1275         SALOMEDS::AttributeFileType_var aFileType;
1276         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
1277         aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
1278         ASSERT(!aFileType->_is_nil());
1279         aFileType->SetValue("FICHIERMED");
1280         }
1281     }
1282   }
1283   _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
1284 }
1285
1286 void SMESH_Mesh_i::ExportMED (const char* file, 
1287                               CORBA::Boolean auto_groups)
1288   throw(SALOME::SALOME_Exception)
1289 {
1290   ExportToMED(file,auto_groups,SMESH::MED_V2_1);
1291 }
1292
1293 void SMESH_Mesh_i::ExportDAT (const char *file)
1294   throw(SALOME::SALOME_Exception)
1295 {
1296   Unexpect aCatch(SALOME_SalomeException);
1297
1298   // Update Python script
1299   TCollection_AsciiString aStr;
1300   SMESH_Gen_i::AddObject(aStr, _this()) += ".ExportDAT(\"";
1301   aStr += TCollection_AsciiString((char*)file) + "\")";
1302
1303   SMESH_Gen_i::AddToCurrentPyScript(aStr);
1304
1305   // Perform Export
1306   _impl->ExportDAT(file);
1307 }
1308
1309 void SMESH_Mesh_i::ExportUNV (const char *file)
1310   throw(SALOME::SALOME_Exception)
1311 {
1312   Unexpect aCatch(SALOME_SalomeException);
1313
1314   // Update Python script
1315   TCollection_AsciiString aStr;
1316   SMESH_Gen_i::AddObject(aStr, _this()) += ".ExportUNV(\"";
1317   aStr += TCollection_AsciiString((char*)file) + "\")";
1318
1319   SMESH_Gen_i::AddToCurrentPyScript(aStr);
1320
1321   // Perform Export
1322   _impl->ExportUNV(file);
1323 }
1324
1325 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
1326   throw(SALOME::SALOME_Exception)
1327 {
1328   Unexpect aCatch(SALOME_SalomeException);
1329
1330   // Update Python script
1331   TCollection_AsciiString aStr;
1332   SMESH_Gen_i::AddObject(aStr, _this()) += ".ExportToMED(\"";
1333   aStr += TCollection_AsciiString((char*)file) + "\", ";
1334   aStr += TCollection_AsciiString((int)isascii) + ")";
1335
1336   SMESH_Gen_i::AddToCurrentPyScript(aStr);
1337
1338   // Perform Export
1339   _impl->ExportSTL(file, isascii);
1340 }
1341
1342 //=============================================================================
1343 /*!
1344  *  
1345  */
1346 //=============================================================================
1347
1348 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
1349 {
1350   Unexpect aCatch(SALOME_SalomeException);
1351   SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
1352   SALOME_MED::MESH_var aMesh = aMedMesh->_this();
1353   return aMesh._retn();
1354 }
1355
1356 //=============================================================================
1357 /*!
1358  *  
1359  */
1360 //=============================================================================
1361 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
1362 {
1363   Unexpect aCatch(SALOME_SalomeException);
1364   return _impl->NbNodes();
1365 }
1366
1367 //=============================================================================
1368 /*!
1369  *  
1370  */
1371 //=============================================================================
1372 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
1373 {
1374   Unexpect aCatch(SALOME_SalomeException);
1375   return NbEdges() + NbFaces() + NbVolumes();
1376 }
1377   
1378 //=============================================================================
1379 /*!
1380  *  
1381  */
1382 //=============================================================================
1383 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
1384 {
1385   Unexpect aCatch(SALOME_SalomeException);
1386   return _impl->NbEdges();
1387 }
1388
1389 //=============================================================================
1390 /*!
1391  *  
1392  */
1393 //=============================================================================
1394 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
1395 {
1396   Unexpect aCatch(SALOME_SalomeException);
1397   return _impl->NbFaces();
1398 }
1399
1400 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
1401 {
1402   Unexpect aCatch(SALOME_SalomeException);
1403   return _impl->NbTriangles();
1404 }
1405
1406 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
1407 {
1408   Unexpect aCatch(SALOME_SalomeException);
1409   return _impl->NbQuadrangles();
1410 }
1411
1412 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
1413 {
1414   Unexpect aCatch(SALOME_SalomeException);
1415   return _impl->NbPolygons();
1416 }
1417
1418 //=============================================================================
1419 /*!
1420  *  
1421  */
1422 //=============================================================================
1423 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
1424 {
1425   Unexpect aCatch(SALOME_SalomeException);
1426   return _impl->NbVolumes();
1427 }
1428
1429 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
1430 {
1431   Unexpect aCatch(SALOME_SalomeException);
1432   return _impl->NbTetras();
1433 }
1434
1435 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
1436 {
1437   Unexpect aCatch(SALOME_SalomeException);
1438   return _impl->NbHexas();
1439 }
1440
1441 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
1442 {
1443   Unexpect aCatch(SALOME_SalomeException);
1444   return _impl->NbPyramids();
1445 }
1446
1447 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
1448 {
1449   Unexpect aCatch(SALOME_SalomeException);
1450   return _impl->NbPrisms();
1451 }
1452
1453 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
1454 {
1455   Unexpect aCatch(SALOME_SalomeException);
1456   return _impl->NbPolyhedrons();
1457 }
1458
1459 //=============================================================================
1460 /*!
1461  *  
1462  */
1463 //=============================================================================
1464 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
1465 {
1466   Unexpect aCatch(SALOME_SalomeException);
1467   return _impl->NbSubMesh();
1468 }
1469
1470 //=============================================================================
1471 /*!
1472  *  
1473  */
1474 //=============================================================================
1475 char* SMESH_Mesh_i::Dump()
1476 {
1477   std::ostringstream os;
1478   _impl->Dump( os );
1479   return CORBA::string_dup( os.str().c_str() );
1480 }
1481
1482 //=============================================================================
1483 /*!
1484  *  
1485  */
1486 //=============================================================================
1487 SMESH::long_array* SMESH_Mesh_i::GetIDs()
1488 {
1489   SMESH::long_array_var aResult = new SMESH::long_array();
1490   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1491   int aMinId = aSMESHDS_Mesh->MinElementID();
1492   int aMaxId =  aSMESHDS_Mesh->MaxElementID();
1493
1494   aResult->length(aMaxId - aMinId + 1);
1495   
1496   for (int i = 0, id = aMinId; id <= aMaxId; id++  )
1497     aResult[i++] = id;
1498   
1499   return aResult._retn();
1500 }
1501
1502 //=============================================================================
1503 /*!
1504  *  
1505  */
1506 //=============================================================================
1507   
1508 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
1509      throw (SALOME::SALOME_Exception)
1510 {
1511   Unexpect aCatch(SALOME_SalomeException);
1512   MESSAGE("SMESH_Mesh_i::GetElementsId");
1513   SMESH::long_array_var aResult = new SMESH::long_array();
1514   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1515
1516   if ( aSMESHDS_Mesh == NULL )
1517     return aResult._retn();
1518
1519   long nbElements = NbElements();
1520   aResult->length( nbElements );
1521   SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
1522   for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
1523     aResult[i] = anIt->next()->GetID();
1524
1525   return aResult._retn();
1526 }
1527
1528
1529 //=============================================================================
1530 /*!
1531  *  
1532  */
1533 //=============================================================================
1534
1535 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
1536     throw (SALOME::SALOME_Exception)
1537 {
1538   Unexpect aCatch(SALOME_SalomeException);
1539   MESSAGE("SMESH_subMesh_i::GetElementsByType");
1540   SMESH::long_array_var aResult = new SMESH::long_array();
1541   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1542
1543   if ( aSMESHDS_Mesh == NULL )
1544     return aResult._retn();
1545
1546   long nbElements = NbElements();
1547
1548   // No sense in returning ids of elements along with ids of nodes:
1549   // when theElemType == SMESH::ALL, return node ids only if
1550   // there are no elements
1551   if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
1552     return GetNodesId();
1553
1554   aResult->length( nbElements );
1555
1556   int i = 0;
1557
1558   SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
1559   while ( i < nbElements && anIt->more() ) {
1560     const SMDS_MeshElement* anElem = anIt->next();
1561     if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
1562       aResult[i++] = anElem->GetID();
1563   }
1564
1565   aResult->length( i );
1566
1567   return aResult._retn();
1568 }
1569
1570 //=============================================================================
1571 /*!
1572  *  
1573  */
1574 //=============================================================================
1575   
1576 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
1577   throw (SALOME::SALOME_Exception)
1578 {
1579   Unexpect aCatch(SALOME_SalomeException);
1580   MESSAGE("SMESH_subMesh_i::GetNodesId");
1581   SMESH::long_array_var aResult = new SMESH::long_array();
1582   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
1583
1584   if ( aSMESHDS_Mesh == NULL )
1585     return aResult._retn();
1586
1587   long nbNodes = NbNodes();
1588   aResult->length( nbNodes );
1589   SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
1590   for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
1591     aResult[i] = anIt->next()->GetID();
1592
1593   return aResult._retn();
1594 }
1595
1596 //=============================================================================
1597 /*!
1598  *
1599  */
1600 //=============================================================================
1601
1602 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
1603   throw (SALOME::SALOME_Exception)
1604 {
1605   return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
1606 }