Salome HOME
1c7ff6a51fe8378e164da5362e3e60a33d841730
[modules/smesh.git] / src / SMESH_I / SMESH_Group_i.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
23 //  File   : SMESH_Group_i.cxx
24 //  Author : Sergey ANIKIN, OCC
25 //  Module : SMESH
26 //
27 #include "SMESH_Group_i.hxx"
28 #include "SMESH_Mesh_i.hxx"
29 #include "SMESH_Gen_i.hxx"
30 #include "SMESH_Group.hxx"
31 #include "SMESHDS_Group.hxx"
32 #include "SMESHDS_GroupOnGeom.hxx"
33 #include "SMDSAbs_ElementType.hxx"
34
35 #include "SMESH_Filter_i.hxx"
36 #include "SMESH_PythonDump.hxx"
37
38 #include "utilities.h"
39
40 using namespace SMESH;
41
42 //=============================================================================
43 /*!
44  *  
45  */
46 //=============================================================================
47
48 SMESH_GroupBase_i::SMESH_GroupBase_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID )
49 : SALOME::GenericObj_i( thePOA ),
50   myMeshServant( theMeshServant ), 
51   myLocalID( theLocalID )
52 {
53   // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i,
54   // servant activation is performed by SMESH_Mesh_i::createGroup()
55   // thePOA->activate_object( this );
56 }
57
58 SMESH_Group_i::SMESH_Group_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID )
59      : SALOME::GenericObj_i( thePOA ),
60        SMESH_GroupBase_i( thePOA, theMeshServant, theLocalID )
61 {
62   //MESSAGE("SMESH_Group_i; this = "<<this );
63 }
64
65 SMESH_GroupOnGeom_i::SMESH_GroupOnGeom_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID )
66      : SALOME::GenericObj_i( thePOA ),
67        SMESH_GroupBase_i( thePOA, theMeshServant, theLocalID )
68 {
69   //MESSAGE("SMESH_GroupOnGeom_i; this = "<<this );
70 }
71
72 //=============================================================================
73 /*!
74  *  
75  */
76 //=============================================================================
77
78 SMESH_GroupBase_i::~SMESH_GroupBase_i()
79 {
80   MESSAGE("~SMESH_GroupBase_i; this = "<<this );
81   if ( myMeshServant )
82     myMeshServant->removeGroup(myLocalID);
83 }
84
85 //=======================================================================
86 //function : GetSmeshGroup
87 //purpose  : 
88 //=======================================================================
89
90 ::SMESH_Group* SMESH_GroupBase_i::GetSmeshGroup() const
91 {
92   if ( myMeshServant ) {
93     ::SMESH_Mesh& aMesh = myMeshServant->GetImpl();
94     return aMesh.GetGroup(myLocalID);
95   }
96   return 0;
97 }
98
99 //=======================================================================
100 //function : GetGroupDS
101 //purpose  : 
102 //=======================================================================
103
104 SMESHDS_GroupBase* SMESH_GroupBase_i::GetGroupDS() const
105 {
106   ::SMESH_Group* aGroup = GetSmeshGroup();
107   if ( aGroup )
108     return aGroup->GetGroupDS();
109   return 0;
110 }
111
112 //=============================================================================
113 /*!
114  *  
115  */
116 //=============================================================================
117
118 void SMESH_GroupBase_i::SetName( const char* theName )
119 {
120   // Perform renaming
121   ::SMESH_Group* aGroup = GetSmeshGroup();
122   if (!aGroup) {
123     MESSAGE("can't set name of a vague group");
124     return;
125   }
126
127   if ( aGroup->GetName() && !strcmp( aGroup->GetName(), theName ) )
128     return; // nothing to rename
129
130   aGroup->SetName(theName);
131
132   // Update group name in a study
133   SMESH_Gen_i* aGen = myMeshServant->GetGen();
134   aGen->SetName( aGen->ObjectToSObject( aGen->GetCurrentStudy(), _this() ), theName );
135   
136   // Update Python script
137   TPythonDump() <<  _this() << ".SetName( '" << theName << "' )";
138 }
139
140 //=============================================================================
141 /*!
142  *  
143  */
144 //=============================================================================
145
146 char* SMESH_GroupBase_i::GetName()
147 {
148   ::SMESH_Group* aGroup = GetSmeshGroup();
149   if (aGroup)
150     return CORBA::string_dup (aGroup->GetName());
151   MESSAGE("get name of a vague group");
152   return CORBA::string_dup( "NO_NAME" );
153 }
154
155 //=============================================================================
156 /*!
157  *  
158  */
159 //=============================================================================
160
161 SMESH::ElementType SMESH_GroupBase_i::GetType()
162 {
163   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
164   if (aGroupDS) {
165     SMDSAbs_ElementType aSMDSType = aGroupDS->GetType();
166     SMESH::ElementType aType;
167     switch (aSMDSType) {
168     case SMDSAbs_Node:      aType = SMESH::NODE;   break;
169     case SMDSAbs_Edge:      aType = SMESH::EDGE;   break;
170     case SMDSAbs_Face:      aType = SMESH::FACE;   break;
171     case SMDSAbs_Volume:    aType = SMESH::VOLUME; break;
172     case SMDSAbs_0DElement: aType = SMESH::ELEM0D; break;
173     default:                aType = SMESH::ALL;    break;
174     }
175     return aType;
176   }
177   MESSAGE("get type of a vague group");
178   return SMESH::ALL;
179 }
180
181
182 //=============================================================================
183 /*!
184  *  
185  */
186 //=============================================================================
187
188 CORBA::Long SMESH_GroupBase_i::Size()
189 {
190   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
191   if (aGroupDS)
192     return aGroupDS->Extent();
193   MESSAGE("get size of a vague group");
194   return 0;
195 }
196
197 //=============================================================================
198 /*!
199  *  
200  */
201 //=============================================================================
202
203 CORBA::Boolean SMESH_GroupBase_i::IsEmpty()
204 {
205   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
206   if (aGroupDS)
207     return aGroupDS->IsEmpty();
208   MESSAGE("checking IsEmpty of a vague group");
209   return true;
210 }
211
212 //=============================================================================
213 /*!
214  *  
215  */
216 //=============================================================================
217
218 void SMESH_Group_i::Clear()
219 {
220   // Update Python script
221   TPythonDump() << _this() << ".Clear()";
222
223   // Clear the group
224   SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
225   if (aGroupDS) {
226     aGroupDS->Clear();
227     return;
228   }
229   MESSAGE("attempt to clear a vague group");
230 }
231
232 //=============================================================================
233 /*!
234  *  
235  */
236 //=============================================================================
237
238 CORBA::Boolean SMESH_GroupBase_i::Contains( CORBA::Long theID )
239 {
240   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
241   if (aGroupDS)
242     return aGroupDS->Contains(theID);
243   MESSAGE("attempt to check contents of a vague group");
244   return false;
245 }
246
247 //=============================================================================
248 /*!
249  *  
250  */
251 //=============================================================================
252
253 CORBA::Long SMESH_Group_i::Add( const SMESH::long_array& theIDs )
254 {
255   // Update Python script
256   TPythonDump() << "nbAdd = " << _this() << ".Add( " << theIDs << " )";
257
258   // Add elements to the group
259   SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
260   if (aGroupDS) {
261     int nbAdd = 0;
262     for (int i = 0; i < theIDs.length(); i++) {
263       int anID = (int) theIDs[i];
264       if (aGroupDS->Add(anID))
265         nbAdd++;
266     }
267     return nbAdd;
268   }
269   MESSAGE("attempt to add elements to a vague group");
270   return 0;
271 }
272
273 //=============================================================================
274 /*!
275  *  
276  */
277 //=============================================================================
278
279 CORBA::Long SMESH_Group_i::Remove( const SMESH::long_array& theIDs )
280 {
281   // Update Python script
282   TPythonDump() << "nbDel = " << _this() << ".Remove( " << theIDs << " )";
283
284   // Remove elements from the group
285   SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
286   if (aGroupDS) {
287     int nbDel = 0;
288     for (int i = 0; i < theIDs.length(); i++) {
289       int anID = (int) theIDs[i];
290       if (aGroupDS->Remove(anID))
291         nbDel++;
292     }
293     return nbDel;
294   }
295   MESSAGE("attempt to remove elements from a vague group");
296   return 0;
297 }
298
299 //=============================================================================
300 /*!
301  *  
302  */
303 //=============================================================================
304
305 typedef bool (SMESHDS_Group::*TFunChangeGroup)(const int);
306
307 CORBA::Long 
308 ChangeByPredicate( SMESH::Predicate_i* thePredicate,
309                    SMESHDS_GroupBase* theGroupBase,
310                    TFunChangeGroup theFun)
311 {
312   CORBA::Long aNb = 0;
313   if(SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>(theGroupBase)){
314     SMESH::Controls::Filter::TIdSequence aSequence;
315     const SMDS_Mesh* aMesh = theGroupBase->GetMesh();
316     SMESH::Filter_i::GetElementsId(thePredicate,aMesh,aSequence);
317     
318     CORBA::Long i = 0, iEnd = aSequence.size();
319     for(; i < iEnd; i++)
320       if((aGroupDS->*theFun)(aSequence[i]))
321         aNb++;
322     return aNb;
323   }
324   return aNb;
325 }
326
327 CORBA::Long 
328 SMESH_Group_i::
329 AddByPredicate( SMESH::Predicate_ptr thePredicate )
330 {
331   if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){
332     TPythonDump()<<_this()<<".AddByPredicate("<<aPredicate<<")";
333     return ChangeByPredicate(aPredicate,GetGroupDS(),&SMESHDS_Group::Add);
334   }
335   return 0;
336 }
337
338 CORBA::Long 
339 SMESH_Group_i::
340 RemoveByPredicate( SMESH::Predicate_ptr thePredicate )
341 {
342   if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){
343     TPythonDump()<<_this()<<".RemoveByPredicate("<<aPredicate<<")";
344     return ChangeByPredicate(aPredicate,GetGroupDS(),&SMESHDS_Group::Remove);
345   }
346   return 0;
347 }
348
349 //=============================================================================
350 /*!
351  *  
352  */
353 //=============================================================================
354
355 CORBA::Long SMESH_GroupBase_i::GetID( CORBA::Long theIndex )
356 {
357   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
358   if (aGroupDS)
359     return aGroupDS->GetID(theIndex);
360   MESSAGE("attempt to iterate on a vague group");
361   return -1;
362 }
363
364 //=============================================================================
365 /*!
366  *  
367  */
368 //=============================================================================
369
370 SMESH::long_array* SMESH_GroupBase_i::GetListOfID()
371 {
372   SMESH::long_array_var aRes = new SMESH::long_array();
373   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
374   if (aGroupDS) {
375     int aSize = aGroupDS->Extent();
376     aRes->length(aSize);
377     for (int i = 0; i < aSize; i++)
378       aRes[i] = aGroupDS->GetID(i+1);
379     return aRes._retn();
380   }
381   MESSAGE("get list of IDs of a vague group");
382   return aRes._retn();
383 }
384
385 //=============================================================================
386 /*!
387  *  
388  */
389 //=============================================================================
390 SMESH::SMESH_Mesh_ptr SMESH_GroupBase_i::GetMesh()
391 {
392   SMESH::SMESH_Mesh_var aMesh;
393   if ( myMeshServant )
394     aMesh = SMESH::SMESH_Mesh::_narrow( myMeshServant->_this() );
395   return aMesh._retn();
396 }
397
398 //=============================================================================
399 /*!
400  *  
401  */
402 //=============================================================================
403 SMESH::long_array* SMESH_GroupBase_i::GetIDs()
404 {
405   SMESH::long_array_var aResult = GetListOfID();
406   return aResult._retn();
407 }
408
409 //=======================================================================
410 //function : GetShape
411 //purpose  : 
412 //=======================================================================
413
414 GEOM::GEOM_Object_ptr SMESH_GroupOnGeom_i::GetShape()
415 {
416   GEOM::GEOM_Object_var aGeomObj;
417   SMESHDS_GroupOnGeom* aGroupDS = dynamic_cast<SMESHDS_GroupOnGeom*>( GetGroupDS() );
418   if ( aGroupDS ) {
419     SMESH_Gen_i* aGen = GetMeshServant()->GetGen();
420     aGeomObj = aGen->ShapeToGeomObject( aGroupDS->GetShape() );
421   }
422   return aGeomObj._retn();
423 }
424
425 //=============================================================================
426 /*!
427  *
428  */
429 //=============================================================================
430 SALOMEDS::Color SMESH_GroupBase_i::GetColor()
431 {
432   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
433   if (aGroupDS)
434   {
435     Quantity_Color aQColor = aGroupDS->GetColor();
436     SALOMEDS::Color aColor;
437     aColor.R = aQColor.Red();
438     aColor.G = aQColor.Green();
439     aColor.B = aQColor.Blue();
440
441     return aColor;
442   }
443   MESSAGE("get color of a group");
444   return SALOMEDS::Color();
445 }
446
447 //=============================================================================
448 /*!
449  *
450  */
451 //=============================================================================
452 void SMESH_GroupBase_i::SetColor(const SALOMEDS::Color& color)
453 {
454   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
455   if (aGroupDS)
456   {
457     Quantity_Color aQColor( color.R, color.G, color.B, Quantity_TOC_RGB );
458     return aGroupDS->SetColor(aQColor);
459   }
460   MESSAGE("set color of a group");
461   return ;
462 }
463
464 //=============================================================================
465 /*!
466  *
467  */
468 //=============================================================================
469 CORBA::Long SMESH_GroupBase_i::GetColorNumber()
470 {
471   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
472   if (aGroupDS)
473     return aGroupDS->GetColorGroup();
474   MESSAGE("get color number of a group");
475   return 0;
476 }
477
478 //=============================================================================
479 /*!
480  *
481  */
482 //=============================================================================
483 void SMESH_GroupBase_i::SetColorNumber(CORBA::Long color)
484 {
485   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
486   if (aGroupDS)
487     return aGroupDS->SetColorGroup(color);
488   MESSAGE("set color number of a group");
489   return ;
490 }
491
492 //=============================================================================
493 /*!
494  * Returns statistic of mesh elements
495  * Result array of number enityties
496  * Inherited from SMESH_IDSource
497  */
498 //=============================================================================
499 SMESH::long_array* SMESH_GroupBase_i::GetMeshInfo()
500 {
501   SMESH::long_array_var aRes = new SMESH::long_array();
502   aRes->length(SMESH::Entity_Last);
503   for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
504     aRes[i] = 0;
505
506   SMESHDS_GroupBase* aGrpDS = GetGroupDS();
507   if ( !aGrpDS )
508     return aRes._retn();
509   if ( GetType() == NODE )
510     aRes[ SMESH::Entity_Node ] = aGrpDS->Extent();
511   else
512     SMESH_Mesh_i::CollectMeshInfo( aGrpDS->GetElements(), aRes);
513   return aRes._retn();
514 }