Salome HOME
Update copyright
[modules/smesh.git] / src / SMESH_I / SMESH_Group_i.cxx
1 // Copyright (C) 2007-2011  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
23 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
24 //  File   : SMESH_Group_i.cxx
25 //  Author : Sergey ANIKIN, OCC
26 //  Module : SMESH
27 //
28 #include "SMESH_Group_i.hxx"
29 #include "SMESH_Mesh_i.hxx"
30 #include "SMESH_Gen_i.hxx"
31 #include "SMESH_Group.hxx"
32 #include "SMESHDS_Group.hxx"
33 #include "SMESHDS_GroupOnGeom.hxx"
34 #include "SMDSAbs_ElementType.hxx"
35
36 #include "SMESH_Filter_i.hxx"
37 #include "SMESH_PythonDump.hxx"
38
39 #include CORBA_SERVER_HEADER(SMESH_Filter)
40
41 #include "utilities.h"
42
43 using namespace SMESH;
44
45 //=============================================================================
46 /*!
47  *  
48  */
49 //=============================================================================
50
51 SMESH_GroupBase_i::SMESH_GroupBase_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID )
52 : SALOME::GenericObj_i( thePOA ),
53   myMeshServant( theMeshServant ), 
54   myLocalID( theLocalID )
55 {
56   // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i,
57   // servant activation is performed by SMESH_Mesh_i::createGroup()
58   // thePOA->activate_object( this );
59 }
60
61 SMESH_Group_i::SMESH_Group_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID )
62      : SALOME::GenericObj_i( thePOA ),
63        SMESH_GroupBase_i( thePOA, theMeshServant, theLocalID )
64 {
65   //MESSAGE("SMESH_Group_i; this = "<<this );
66 }
67
68 SMESH_GroupOnGeom_i::SMESH_GroupOnGeom_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID )
69      : SALOME::GenericObj_i( thePOA ),
70        SMESH_GroupBase_i( thePOA, theMeshServant, theLocalID )
71 {
72   //MESSAGE("SMESH_GroupOnGeom_i; this = "<<this );
73 }
74
75 //=============================================================================
76 /*!
77  *  
78  */
79 //=============================================================================
80
81 SMESH_GroupBase_i::~SMESH_GroupBase_i()
82 {
83   MESSAGE("~SMESH_GroupBase_i; this = "<<this );
84   if ( myMeshServant )
85     myMeshServant->removeGroup(myLocalID);
86 }
87
88 //=======================================================================
89 //function : GetSmeshGroup
90 //purpose  : 
91 //=======================================================================
92
93 ::SMESH_Group* SMESH_GroupBase_i::GetSmeshGroup() const
94 {
95   if ( myMeshServant ) {
96     ::SMESH_Mesh& aMesh = myMeshServant->GetImpl();
97     return aMesh.GetGroup(myLocalID);
98   }
99   return 0;
100 }
101
102 //=======================================================================
103 //function : GetGroupDS
104 //purpose  : 
105 //=======================================================================
106
107 SMESHDS_GroupBase* SMESH_GroupBase_i::GetGroupDS() const
108 {
109   ::SMESH_Group* aGroup = GetSmeshGroup();
110   if ( aGroup )
111     return aGroup->GetGroupDS();
112   return 0;
113 }
114
115 //=============================================================================
116 /*!
117  *  
118  */
119 //=============================================================================
120
121 void SMESH_GroupBase_i::SetName( const char* theName )
122 {
123   // Perform renaming
124   ::SMESH_Group* aGroup = GetSmeshGroup();
125   if (!aGroup) {
126     MESSAGE("can't set name of a vague group");
127     return;
128   }
129
130   if ( aGroup->GetName() && !strcmp( aGroup->GetName(), theName ) )
131     return; // nothing to rename
132
133   aGroup->SetName(theName);
134
135   // Update group name in a study
136   SMESH_Gen_i* aGen = myMeshServant->GetGen();
137   aGen->SetName( aGen->ObjectToSObject( aGen->GetCurrentStudy(), _this() ), theName );
138   
139   // Update Python script
140   TPythonDump() <<  _this() << ".SetName( '" << theName << "' )";
141 }
142
143 //=============================================================================
144 /*!
145  *  
146  */
147 //=============================================================================
148
149 char* SMESH_GroupBase_i::GetName()
150 {
151   ::SMESH_Group* aGroup = GetSmeshGroup();
152   if (aGroup)
153     return CORBA::string_dup (aGroup->GetName());
154   MESSAGE("get name of a vague group");
155   return CORBA::string_dup( "NO_NAME" );
156 }
157
158 //=============================================================================
159 /*!
160  *  
161  */
162 //=============================================================================
163
164 SMESH::ElementType SMESH_GroupBase_i::GetType()
165 {
166   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
167   if (aGroupDS) {
168     SMDSAbs_ElementType aSMDSType = aGroupDS->GetType();
169     SMESH::ElementType aType;
170     switch (aSMDSType) {
171     case SMDSAbs_Node:      aType = SMESH::NODE;   break;
172     case SMDSAbs_Edge:      aType = SMESH::EDGE;   break;
173     case SMDSAbs_Face:      aType = SMESH::FACE;   break;
174     case SMDSAbs_Volume:    aType = SMESH::VOLUME; break;
175     case SMDSAbs_0DElement: aType = SMESH::ELEM0D; break;
176     default:                aType = SMESH::ALL;    break;
177     }
178     return aType;
179   }
180   MESSAGE("get type of a vague group");
181   return SMESH::ALL;
182 }
183
184
185 //=============================================================================
186 /*!
187  *  
188  */
189 //=============================================================================
190
191 CORBA::Long SMESH_GroupBase_i::Size()
192 {
193   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
194   if (aGroupDS)
195     return aGroupDS->Extent();
196   MESSAGE("get size of a vague group");
197   return 0;
198 }
199
200 //=============================================================================
201 /*!
202  *  
203  */
204 //=============================================================================
205
206 CORBA::Boolean SMESH_GroupBase_i::IsEmpty()
207 {
208   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
209   if (aGroupDS)
210     return aGroupDS->IsEmpty();
211   MESSAGE("checking IsEmpty of a vague group");
212   return true;
213 }
214
215 //=============================================================================
216 /*!
217  *  
218  */
219 //=============================================================================
220
221 void SMESH_Group_i::Clear()
222 {
223   // Update Python script
224   TPythonDump() << _this() << ".Clear()";
225
226   // Clear the group
227   SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
228   if (aGroupDS) {
229     aGroupDS->Clear();
230     return;
231   }
232   MESSAGE("attempt to clear a vague group");
233 }
234
235 //=============================================================================
236 /*!
237  *  
238  */
239 //=============================================================================
240
241 CORBA::Boolean SMESH_GroupBase_i::Contains( CORBA::Long theID )
242 {
243   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
244   if (aGroupDS)
245     return aGroupDS->Contains(theID);
246   MESSAGE("attempt to check contents of a vague group");
247   return false;
248 }
249
250 //=============================================================================
251 /*!
252  *  
253  */
254 //=============================================================================
255
256 CORBA::Long SMESH_Group_i::Add( const SMESH::long_array& theIDs )
257 {
258   // Update Python script
259   TPythonDump() << "nbAdd = " << _this() << ".Add( " << theIDs << " )";
260
261   // Add elements to the group
262   SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
263   if (aGroupDS) {
264     int nbAdd = 0;
265     for (int i = 0; i < theIDs.length(); i++) {
266       int anID = (int) theIDs[i];
267       if (aGroupDS->Add(anID))
268         nbAdd++;
269     }
270     return nbAdd;
271   }
272   MESSAGE("attempt to add elements to a vague group");
273   return 0;
274 }
275
276 //=============================================================================
277 /*!
278  *  
279  */
280 //=============================================================================
281
282 CORBA::Long SMESH_Group_i::Remove( const SMESH::long_array& theIDs )
283 {
284   // Update Python script
285   TPythonDump() << "nbDel = " << _this() << ".Remove( " << theIDs << " )";
286
287   // Remove elements from the group
288   SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
289   if (aGroupDS) {
290     int nbDel = 0;
291     for (int i = 0; i < theIDs.length(); i++) {
292       int anID = (int) theIDs[i];
293       if (aGroupDS->Remove(anID))
294         nbDel++;
295     }
296     return nbDel;
297   }
298   MESSAGE("attempt to remove elements from a vague group");
299   return 0;
300 }
301
302 //=============================================================================
303 /*!
304  *  
305  */
306 //=============================================================================
307
308 typedef bool (SMESHDS_Group::*TFunChangeGroup)(const int);
309
310 CORBA::Long 
311 ChangeByPredicate( SMESH::Predicate_i* thePredicate,
312                    SMESHDS_GroupBase* theGroupBase,
313                    TFunChangeGroup theFun)
314 {
315   CORBA::Long aNb = 0;
316   if(SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>(theGroupBase)){
317     SMESH::Controls::Filter::TIdSequence aSequence;
318     const SMDS_Mesh* aMesh = theGroupBase->GetMesh();
319     SMESH::Filter_i::GetElementsId(thePredicate,aMesh,aSequence);
320     
321     CORBA::Long i = 0, iEnd = aSequence.size();
322     for(; i < iEnd; i++)
323       if((aGroupDS->*theFun)(aSequence[i]))
324         aNb++;
325     return aNb;
326   }
327   return aNb;
328 }
329
330 CORBA::Long 
331 SMESH_Group_i::
332 AddByPredicate( SMESH::Predicate_ptr thePredicate )
333 {
334   if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){
335     TPythonDump()<<_this()<<".AddByPredicate("<<aPredicate<<")";
336     return ChangeByPredicate(aPredicate,GetGroupDS(),&SMESHDS_Group::Add);
337   }
338   return 0;
339 }
340
341 CORBA::Long 
342 SMESH_Group_i::
343 RemoveByPredicate( SMESH::Predicate_ptr thePredicate )
344 {
345   if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){
346     TPythonDump()<<_this()<<".RemoveByPredicate("<<aPredicate<<")";
347     return ChangeByPredicate(aPredicate,GetGroupDS(),&SMESHDS_Group::Remove);
348   }
349   return 0;
350 }
351
352 CORBA::Long SMESH_Group_i::AddFrom( SMESH::SMESH_IDSource_ptr theSource )
353 {
354   long nbAdd = 0;
355   SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
356   if (aGroupDS) {
357     SMESH::long_array_var anIds;
358     SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theSource);
359     SMESH::SMESH_Mesh_var mesh       = SMESH::SMESH_Mesh::_narrow(theSource);
360     SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow(theSource);
361     SMESH::Filter_var filter         = SMESH::Filter::_narrow(theSource);
362     if ( !group->_is_nil())
363       anIds = group->GetType()==GetType() ? theSource->GetIDs() :  new SMESH::long_array();
364     else if ( !mesh->_is_nil() )
365       anIds = mesh->GetElementsByType( GetType() );
366     else if ( !submesh->_is_nil())
367       anIds = submesh->GetElementsByType( GetType() );
368     else if ( !filter->_is_nil() )
369       anIds = filter->GetElementType()==GetType() ? theSource->GetIDs() : new SMESH::long_array();
370     else 
371       anIds = theSource->GetIDs();
372     for ( int i = 0, total = anIds->length(); i < total; i++ ) {
373       if ( aGroupDS->Add((int)anIds[i]) ) nbAdd++;
374     }
375   }
376
377   // Update Python script
378   TPythonDump() << "nbAdd = " << _this() << ".AddFrom( " << theSource << " )";
379
380   return nbAdd;
381 }
382
383 //=============================================================================
384 /*!
385  *  
386  */
387 //=============================================================================
388
389 CORBA::Long SMESH_GroupBase_i::GetID( CORBA::Long theIndex )
390 {
391   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
392   if (aGroupDS)
393     return aGroupDS->GetID(theIndex);
394   MESSAGE("attempt to iterate on a vague group");
395   return -1;
396 }
397
398 //=============================================================================
399 /*!
400  *  
401  */
402 //=============================================================================
403
404 SMESH::long_array* SMESH_GroupBase_i::GetListOfID()
405 {
406   SMESH::long_array_var aRes = new SMESH::long_array();
407   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
408   if (aGroupDS) {
409     int aSize = aGroupDS->Extent();
410     aRes->length(aSize);
411     for (int i = 0; i < aSize; i++)
412       aRes[i] = aGroupDS->GetID(i+1);
413     return aRes._retn();
414   }
415   MESSAGE("get list of IDs of a vague group");
416   return aRes._retn();
417 }
418
419 //=============================================================================
420 /*!
421  *  
422  */
423 //=============================================================================
424 SMESH::SMESH_Mesh_ptr SMESH_GroupBase_i::GetMesh()
425 {
426   SMESH::SMESH_Mesh_var aMesh;
427   if ( myMeshServant )
428     aMesh = SMESH::SMESH_Mesh::_narrow( myMeshServant->_this() );
429   return aMesh._retn();
430 }
431
432 //=======================================================================
433 //function : GetShape
434 //purpose  : 
435 //=======================================================================
436
437 GEOM::GEOM_Object_ptr SMESH_GroupOnGeom_i::GetShape()
438 {
439   GEOM::GEOM_Object_var aGeomObj;
440   SMESHDS_GroupOnGeom* aGroupDS = dynamic_cast<SMESHDS_GroupOnGeom*>( GetGroupDS() );
441   if ( aGroupDS ) {
442     SMESH_Gen_i* aGen = GetMeshServant()->GetGen();
443     aGeomObj = aGen->ShapeToGeomObject( aGroupDS->GetShape() );
444   }
445   return aGeomObj._retn();
446 }
447
448 //=============================================================================
449 /*!
450  *
451  */
452 //=============================================================================
453 SALOMEDS::Color SMESH_GroupBase_i::GetColor()
454 {
455   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
456   if (aGroupDS)
457   {
458     Quantity_Color aQColor = aGroupDS->GetColor();
459     SALOMEDS::Color aColor;
460     aColor.R = aQColor.Red();
461     aColor.G = aQColor.Green();
462     aColor.B = aQColor.Blue();
463
464     return aColor;
465   }
466   MESSAGE("get color of a group");
467   return SALOMEDS::Color();
468 }
469
470 //=============================================================================
471 /*!
472  *
473  */
474 //=============================================================================
475 void SMESH_GroupBase_i::SetColor(const SALOMEDS::Color& color)
476 {
477   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
478   if (aGroupDS)
479   {
480     Quantity_Color aQColor( color.R, color.G, color.B, Quantity_TOC_RGB );
481     aGroupDS->SetColor(aQColor);
482     TPythonDump()<<_this()<<".SetColor( SALOMEDS.Color( "<<color.R<<", "<<color.G<<", "<<color.B<<" ))";
483   }
484 }
485
486 //=============================================================================
487 /*!
488  *
489  */
490 //=============================================================================
491 CORBA::Long SMESH_GroupBase_i::GetColorNumber()
492 {
493   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
494   if (aGroupDS)
495     return aGroupDS->GetColorGroup();
496   MESSAGE("get color number of a group");
497   return 0;
498 }
499
500 //=============================================================================
501 /*!
502  *
503  */
504 //=============================================================================
505 void SMESH_GroupBase_i::SetColorNumber(CORBA::Long color)
506 {
507   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
508   if (aGroupDS)
509   {
510     aGroupDS->SetColorGroup(color);
511     TPythonDump()<<_this()<<".SetColorGroup( "<<color<<" )";
512   }
513   MESSAGE("set color number of a group");
514   return ;
515 }
516
517 //=============================================================================
518 /*!
519  * Returns statistic of mesh elements
520  * Result array of number enityties
521  * Inherited from SMESH_IDSource
522  */
523 //=============================================================================
524 SMESH::long_array* SMESH_GroupBase_i::GetMeshInfo()
525 {
526   SMESH::long_array_var aRes = new SMESH::long_array();
527   aRes->length(SMESH::Entity_Last);
528   for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
529     aRes[i] = 0;
530
531   SMESHDS_GroupBase* aGrpDS = GetGroupDS();
532   if ( !aGrpDS )
533     return aRes._retn();
534   if ( GetType() == NODE )
535     aRes[ SMESH::Entity_Node ] = aGrpDS->Extent();
536   else
537     SMESH_Mesh_i::CollectMeshInfo( aGrpDS->GetElements(), aRes);
538   return aRes._retn();
539 }
540
541 //=======================================================================
542 //function : GetIDs
543 //purpose  : Returns ids of members
544 //=======================================================================
545
546 SMESH::long_array* SMESH_GroupBase_i::GetIDs()
547 {
548   SMESH::long_array_var aResult = GetListOfID();
549   return aResult._retn();
550 }
551
552 //=======================================================================
553 //function : GetTypes
554 //purpose  : Returns types of elements it contains
555 //=======================================================================
556
557 SMESH::array_of_ElementType* SMESH_GroupBase_i::GetTypes()
558 {
559   SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
560   types->length( 1 );
561   types[0] = GetType();
562   return types._retn();
563 }
564