Back to index

salome-smesh  6.5.0
SMESH_Group_i.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
00024 //  File   : SMESH_Group_i.cxx
00025 //  Author : Sergey ANIKIN, OCC
00026 //  Module : SMESH
00027 //
00028 #include "SMESH_Group_i.hxx"
00029 
00030 #include "SMDSAbs_ElementType.hxx"
00031 #include "SMESHDS_Group.hxx"
00032 #include "SMESHDS_GroupOnFilter.hxx"
00033 #include "SMESHDS_GroupOnGeom.hxx"
00034 #include "SMESH_Comment.hxx"
00035 #include "SMESH_Filter_i.hxx"
00036 #include "SMESH_Gen_i.hxx"
00037 #include "SMESH_Group.hxx"
00038 #include "SMESH_Mesh_i.hxx"
00039 #include "SMESH_PythonDump.hxx"
00040 #include "SMESH_PreMeshInfo.hxx"
00041 
00042 #include CORBA_SERVER_HEADER(SMESH_Filter)
00043 
00044 #include "utilities.h"
00045 
00046 using namespace SMESH;
00047 
00048 //=============================================================================
00052 //=============================================================================
00053 
00054 SMESH_GroupBase_i::SMESH_GroupBase_i( PortableServer::POA_ptr thePOA,
00055                                       SMESH_Mesh_i*           theMeshServant,
00056                                       const int               theLocalID )
00057 : SALOME::GenericObj_i( thePOA ),
00058   myMeshServant( theMeshServant ), 
00059   myLocalID( theLocalID ),
00060   myNbNodes(-1),
00061   myGroupDSTic(0),
00062   myPreMeshInfo(NULL)
00063 {
00064   // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i,
00065   // servant activation is performed by SMESH_Mesh_i::createGroup()
00066   // thePOA->activate_object( this );
00067 }
00068 
00069 SMESH_Group_i::SMESH_Group_i( PortableServer::POA_ptr thePOA,
00070                               SMESH_Mesh_i*           theMeshServant,
00071                               const int               theLocalID )
00072      : SALOME::GenericObj_i( thePOA ),
00073        SMESH_GroupBase_i( thePOA, theMeshServant, theLocalID )
00074 {
00075   //MESSAGE("SMESH_Group_i; this = "<<this );
00076 }
00077 
00078 SMESH_GroupOnGeom_i::SMESH_GroupOnGeom_i( PortableServer::POA_ptr thePOA,
00079                                           SMESH_Mesh_i*           theMeshServant,
00080                                           const int               theLocalID )
00081      : SALOME::GenericObj_i( thePOA ),
00082        SMESH_GroupBase_i( thePOA, theMeshServant, theLocalID )
00083 {
00084   //MESSAGE("SMESH_GroupOnGeom_i; this = "<<this );
00085 }
00086 
00087 SMESH_GroupOnFilter_i::SMESH_GroupOnFilter_i( PortableServer::POA_ptr thePOA,
00088                                               SMESH_Mesh_i*           theMeshServant,
00089                                               const int               theLocalID )
00090   : SALOME::GenericObj_i( thePOA ),
00091     SMESH_GroupBase_i( thePOA, theMeshServant, theLocalID )
00092 {
00093   //MESSAGE("SMESH_GroupOnGeom_i; this = "<<this );
00094 }
00095 
00096 //=============================================================================
00100 //=============================================================================
00101 
00102 SMESH_GroupBase_i::~SMESH_GroupBase_i()
00103 {
00104   MESSAGE("~SMESH_GroupBase_i; this = "<<this );
00105   if ( myMeshServant )
00106     myMeshServant->removeGroup(myLocalID);
00107 
00108   if ( myPreMeshInfo ) delete myPreMeshInfo; myPreMeshInfo = NULL;
00109 }
00110 
00111 //=======================================================================
00112 //function : GetSmeshGroup
00113 //purpose  : 
00114 //=======================================================================
00115 
00116 ::SMESH_Group* SMESH_GroupBase_i::GetSmeshGroup() const
00117 {
00118   if ( myMeshServant ) {
00119     ::SMESH_Mesh& aMesh = myMeshServant->GetImpl();
00120     return aMesh.GetGroup(myLocalID);
00121   }
00122   return 0;
00123 }
00124 
00125 //=======================================================================
00126 //function : GetGroupDS
00127 //purpose  : 
00128 //=======================================================================
00129 
00130 SMESHDS_GroupBase* SMESH_GroupBase_i::GetGroupDS() const
00131 {
00132   ::SMESH_Group* aGroup = GetSmeshGroup();
00133   if ( aGroup )
00134     return aGroup->GetGroupDS();
00135   return 0;
00136 }
00137 
00138 //=============================================================================
00142 //=============================================================================
00143 
00144 void SMESH_GroupBase_i::SetName( const char* theName )
00145 {
00146   // Perform renaming
00147   ::SMESH_Group* aGroup = GetSmeshGroup();
00148   if (!aGroup) {
00149     MESSAGE("can't set name of a vague group");
00150     return;
00151   }
00152 
00153   if ( aGroup->GetName() && !strcmp( aGroup->GetName(), theName ) )
00154     return; // nothing to rename
00155 
00156   aGroup->SetName(theName);
00157 
00158   // Update group name in a study
00159   SMESH_Gen_i* aGen = myMeshServant->GetGen();
00160   aGen->SetName( aGen->ObjectToSObject( aGen->GetCurrentStudy(), _this() ), theName );
00161   
00162   // Update Python script
00163   TPythonDump() <<  _this() << ".SetName( '" << theName << "' )";
00164 }
00165 
00166 //=============================================================================
00170 //=============================================================================
00171 
00172 char* SMESH_GroupBase_i::GetName()
00173 {
00174   ::SMESH_Group* aGroup = GetSmeshGroup();
00175   if (aGroup)
00176     return CORBA::string_dup (aGroup->GetName());
00177   MESSAGE("get name of a vague group");
00178   return CORBA::string_dup( "NO_NAME" );
00179 }
00180 
00181 //=============================================================================
00185 //=============================================================================
00186 
00187 SMESH::ElementType SMESH_GroupBase_i::GetType()
00188 {
00189   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
00190   if (aGroupDS) {
00191     SMDSAbs_ElementType aSMDSType = aGroupDS->GetType();
00192     SMESH::ElementType aType;
00193     switch (aSMDSType) {
00194     case SMDSAbs_Node:      aType = SMESH::NODE;   break;
00195     case SMDSAbs_Edge:      aType = SMESH::EDGE;   break;
00196     case SMDSAbs_Face:      aType = SMESH::FACE;   break;
00197     case SMDSAbs_Volume:    aType = SMESH::VOLUME; break;
00198     case SMDSAbs_0DElement: aType = SMESH::ELEM0D; break;
00199     default:                aType = SMESH::ALL;    break;
00200     }
00201     return aType;
00202   }
00203   MESSAGE("get type of a vague group");
00204   return SMESH::ALL;
00205 }
00206 
00207 
00208 //=============================================================================
00212 //=============================================================================
00213 
00214 CORBA::Long SMESH_GroupBase_i::Size()
00215 {
00216   if ( myPreMeshInfo )
00217     return GetType() == SMESH::NODE ? myPreMeshInfo->NbNodes() : myPreMeshInfo->NbElements();
00218 
00219   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
00220   if (aGroupDS)
00221     return aGroupDS->Extent();
00222   MESSAGE("get size of a vague group");
00223   return 0;
00224 }
00225 
00226 //=============================================================================
00230 //=============================================================================
00231 
00232 CORBA::Boolean SMESH_GroupBase_i::IsEmpty()
00233 {
00234   if ( myPreMeshInfo )
00235     return Size() == 0;
00236 
00237   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
00238   if (aGroupDS)
00239     return aGroupDS->IsEmpty();
00240   MESSAGE("checking IsEmpty of a vague group");
00241   return true;
00242 }
00243 
00244 //=============================================================================
00248 //=============================================================================
00249 
00250 void SMESH_Group_i::Clear()
00251 {
00252   if ( myPreMeshInfo )
00253     myPreMeshInfo->FullLoadFromFile();
00254 
00255   // Update Python script
00256   TPythonDump() << _this() << ".Clear()";
00257 
00258   // Clear the group
00259   SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
00260   if (aGroupDS) {
00261     aGroupDS->Clear();
00262     return;
00263   }
00264   MESSAGE("attempt to clear a vague group");
00265 }
00266 
00267 //=============================================================================
00271 //=============================================================================
00272 
00273 CORBA::Boolean SMESH_GroupBase_i::Contains( CORBA::Long theID )
00274 {
00275   if ( myPreMeshInfo )
00276     myPreMeshInfo->FullLoadFromFile();
00277 
00278   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
00279   if (aGroupDS)
00280     return aGroupDS->Contains(theID);
00281   MESSAGE("attempt to check contents of a vague group");
00282   return false;
00283 }
00284 
00285 //=============================================================================
00289 //=============================================================================
00290 
00291 CORBA::Long SMESH_Group_i::Add( const SMESH::long_array& theIDs )
00292 {
00293   if ( myPreMeshInfo )
00294     myPreMeshInfo->FullLoadFromFile();
00295 
00296   // Update Python script
00297   TPythonDump() << "nbAdd = " << _this() << ".Add( " << theIDs << " )";
00298 
00299   // Add elements to the group
00300   SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
00301   if (aGroupDS) {
00302     int nbAdd = 0;
00303     for (int i = 0; i < theIDs.length(); i++) {
00304       int anID = (int) theIDs[i];
00305       if (aGroupDS->Add(anID))
00306         nbAdd++;
00307     }
00308     return nbAdd;
00309   }
00310   MESSAGE("attempt to add elements to a vague group");
00311   return 0;
00312 }
00313 
00314 //=============================================================================
00318 //=============================================================================
00319 
00320 CORBA::Long SMESH_Group_i::Remove( const SMESH::long_array& theIDs )
00321 {
00322   if ( myPreMeshInfo )
00323     myPreMeshInfo->FullLoadFromFile();
00324 
00325   // Update Python script
00326   TPythonDump() << "nbDel = " << _this() << ".Remove( " << theIDs << " )";
00327 
00328   // Remove elements from the group
00329   SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
00330   if (aGroupDS) {
00331     int nbDel = 0;
00332     for (int i = 0; i < theIDs.length(); i++) {
00333       int anID = (int) theIDs[i];
00334       if (aGroupDS->Remove(anID))
00335         nbDel++;
00336     }
00337     return nbDel;
00338   }
00339   MESSAGE("attempt to remove elements from a vague group");
00340   return 0;
00341 }
00342 
00343 //=============================================================================
00347 //=============================================================================
00348 
00349 typedef bool (SMESHDS_Group::*TFunChangeGroup)(const int);
00350 
00351 CORBA::Long 
00352 ChangeByPredicate( SMESH::Predicate_i* thePredicate,
00353                    SMESHDS_GroupBase*  theGroupBase,
00354                    TFunChangeGroup     theFun)
00355 {
00356   CORBA::Long aNb = 0;
00357   if(SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>(theGroupBase)){
00358     SMESH::Controls::Filter::TIdSequence aSequence;
00359     const SMDS_Mesh* aMesh = theGroupBase->GetMesh();
00360     SMESH::Filter_i::GetElementsId(thePredicate,aMesh,aSequence);
00361     
00362     CORBA::Long i = 0, iEnd = aSequence.size();
00363     for(; i < iEnd; i++)
00364       if((aGroupDS->*theFun)(aSequence[i]))
00365         aNb++;
00366     return aNb;
00367   }
00368   return aNb;
00369 }
00370 
00371 CORBA::Long 
00372 SMESH_Group_i::
00373 AddByPredicate( SMESH::Predicate_ptr thePredicate )
00374 {
00375   if ( myPreMeshInfo )
00376     myPreMeshInfo->FullLoadFromFile();
00377 
00378   if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){
00379     TPythonDump()<<_this()<<".AddByPredicate("<<aPredicate<<")";
00380     return ChangeByPredicate(aPredicate,GetGroupDS(),&SMESHDS_Group::Add);
00381   }
00382   return 0;
00383 }
00384 
00385 CORBA::Long 
00386 SMESH_Group_i::
00387 RemoveByPredicate( SMESH::Predicate_ptr thePredicate )
00388 {
00389   if ( myPreMeshInfo )
00390     myPreMeshInfo->FullLoadFromFile();
00391 
00392   if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){
00393     TPythonDump()<<_this()<<".RemoveByPredicate("<<aPredicate<<")";
00394     return ChangeByPredicate(aPredicate,GetGroupDS(),&SMESHDS_Group::Remove);
00395   }
00396   return 0;
00397 }
00398 
00399 CORBA::Long SMESH_Group_i::AddFrom( SMESH::SMESH_IDSource_ptr theSource )
00400 {
00401   if ( myPreMeshInfo )
00402     myPreMeshInfo->FullLoadFromFile();
00403 
00404   TPythonDump pd;
00405   long nbAdd = 0;
00406   SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
00407   if (aGroupDS) {
00408     SMESH::long_array_var anIds;
00409     SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theSource);
00410     SMESH::SMESH_Mesh_var mesh       = SMESH::SMESH_Mesh::_narrow(theSource);
00411     SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow(theSource);
00412     SMESH::Filter_var filter         = SMESH::Filter::_narrow(theSource);
00413     if ( !group->_is_nil())
00414       anIds = group->GetType()==GetType() ? theSource->GetIDs() :  new SMESH::long_array();
00415     else if ( !mesh->_is_nil() )
00416       anIds = mesh->GetElementsByType( GetType() );
00417     else if ( !submesh->_is_nil())
00418       anIds = submesh->GetElementsByType( GetType() );
00419     else if ( !filter->_is_nil() ) {
00420       filter->SetMesh( GetMeshServant()->_this() );
00421       anIds = filter->GetElementType()==GetType() ? theSource->GetIDs() : new SMESH::long_array();
00422     }
00423     else 
00424       anIds = theSource->GetIDs();
00425     for ( int i = 0, total = anIds->length(); i < total; i++ ) {
00426       if ( aGroupDS->Add((int)anIds[i]) ) nbAdd++;
00427     }
00428   }
00429 
00430   // Update Python script
00431   pd << "nbAdd = " << _this() << ".AddFrom( " << theSource << " )";
00432 
00433   return nbAdd;
00434 }
00435 
00436 //=============================================================================
00440 //=============================================================================
00441 
00442 CORBA::Long SMESH_GroupBase_i::GetID( CORBA::Long theIndex )
00443 {
00444   if ( myPreMeshInfo )
00445     myPreMeshInfo->FullLoadFromFile();
00446 
00447   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
00448   if (aGroupDS)
00449     return aGroupDS->GetID(theIndex);
00450   MESSAGE("attempt to iterate on a vague group");
00451   return -1;
00452 }
00453 
00454 //=============================================================================
00458 //=============================================================================
00459 
00460 SMESH::long_array* SMESH_GroupBase_i::GetListOfID()
00461 {
00462   if ( myPreMeshInfo )
00463     myPreMeshInfo->FullLoadFromFile();
00464 
00465   SMESH::long_array_var aRes = new SMESH::long_array();
00466   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
00467   if (aGroupDS) {
00468     int aSize = aGroupDS->Extent();
00469     aRes->length(aSize);
00470     for (int i = 0; i < aSize; i++)
00471       aRes[i] = aGroupDS->GetID(i+1);
00472     return aRes._retn();
00473   }
00474   MESSAGE("get list of IDs of a vague group");
00475   return aRes._retn();
00476 }
00477 
00478 namespace
00479 {
00480   //================================================================================
00484   //================================================================================
00485 
00486   void getNodesOfElements(SMDS_ElemIteratorPtr        elemIt,
00487                           set<const SMDS_MeshNode* >& nodes)
00488   {
00489     while ( elemIt->more() )
00490     {
00491       const SMDS_MeshElement* e = elemIt->next();
00492       nodes.insert( e->begin_nodes(), e->end_nodes() );
00493     }
00494   }
00495 }
00496   
00497 //================================================================================
00501 //================================================================================
00502 
00503 CORBA::Long SMESH_GroupBase_i::GetNumberOfNodes()
00504 {
00505   if ( GetType() == SMESH::NODE )
00506     return Size();
00507 
00508   if ( myPreMeshInfo )
00509     myPreMeshInfo->FullLoadFromFile();
00510 
00511   if ( SMESHDS_GroupBase* g = GetGroupDS())
00512   {
00513     if ( myNbNodes < 0 || g->GetTic() != myGroupDSTic )
00514     {      
00515       set<const SMDS_MeshNode* > nodes;
00516       getNodesOfElements( g->GetElements(), nodes );
00517       myNbNodes = nodes.size();
00518       myGroupDSTic = g->GetTic();
00519     }
00520   }
00521   return myNbNodes;
00522 }
00523 
00524 //================================================================================
00528 //================================================================================
00529 
00530 CORBA::Boolean SMESH_GroupBase_i::IsNodeInfoAvailable()
00531 {
00532   if ( GetType() == SMESH::NODE/* || Size() < 100000 */)
00533     return true;
00534   if ( myPreMeshInfo )
00535     return false;
00536   if ( SMESHDS_GroupBase* g = GetGroupDS())
00537     return ( myNbNodes > -1 && g->GetTic() == myGroupDSTic);
00538   return false;
00539 }
00540 
00541 //================================================================================
00545 //================================================================================
00546 
00547 SMESH::long_array* SMESH_GroupBase_i::GetNodeIDs()
00548 {
00549   if ( GetType() == SMESH::NODE )
00550     return GetListOfID();
00551 
00552   if ( myPreMeshInfo )
00553     myPreMeshInfo->FullLoadFromFile();
00554 
00555   SMESH::long_array_var aRes = new SMESH::long_array();
00556   if ( SMESHDS_GroupBase* g = GetGroupDS())
00557   {
00558     set<const SMDS_MeshNode* > nodes;
00559     getNodesOfElements( g->GetElements(), nodes );
00560     aRes->length( nodes.size() );
00561     set<const SMDS_MeshNode*>::iterator nIt = nodes.begin(), nEnd = nodes.end();
00562     for ( int i = 0; nIt != nEnd; ++nIt, ++i )
00563       aRes[i] = (*nIt)->GetID();
00564   }
00565   return aRes._retn();
00566 }
00567 
00568 //=============================================================================
00572 //=============================================================================
00573 SMESH::SMESH_Mesh_ptr SMESH_GroupBase_i::GetMesh()
00574 {
00575   SMESH::SMESH_Mesh_var aMesh;
00576   if ( myMeshServant )
00577     aMesh = SMESH::SMESH_Mesh::_narrow( myMeshServant->_this() );
00578   return aMesh._retn();
00579 }
00580 
00581 //=======================================================================
00582 //function : GetShape
00583 //purpose  : 
00584 //=======================================================================
00585 
00586 GEOM::GEOM_Object_ptr SMESH_GroupOnGeom_i::GetShape()
00587 {
00588   GEOM::GEOM_Object_var aGeomObj;
00589   SMESHDS_GroupOnGeom* aGroupDS = dynamic_cast<SMESHDS_GroupOnGeom*>( GetGroupDS() );
00590   if ( aGroupDS ) {
00591     SMESH_Gen_i* aGen = GetMeshServant()->GetGen();
00592     aGeomObj = aGen->ShapeToGeomObject( aGroupDS->GetShape() );
00593   }
00594   return aGeomObj._retn();
00595 }
00596 
00597 //=============================================================================
00601 //=============================================================================
00602 SALOMEDS::Color SMESH_GroupBase_i::GetColor()
00603 {
00604   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
00605   if (aGroupDS)
00606   {
00607     Quantity_Color aQColor = aGroupDS->GetColor();
00608     SALOMEDS::Color aColor;
00609     aColor.R = aQColor.Red();
00610     aColor.G = aQColor.Green();
00611     aColor.B = aQColor.Blue();
00612 
00613     return aColor;
00614   }
00615   MESSAGE("get color of a group");
00616   return SALOMEDS::Color();
00617 }
00618 
00619 //=============================================================================
00623 //=============================================================================
00624 void SMESH_GroupBase_i::SetColor(const SALOMEDS::Color& color)
00625 {
00626   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
00627   if (aGroupDS)
00628   {
00629     Quantity_Color aQColor( color.R, color.G, color.B, Quantity_TOC_RGB );
00630     Quantity_Color oldColor = aGroupDS->GetColor();
00631     if ( oldColor != aQColor )
00632     {
00633       aGroupDS->SetColor(aQColor);
00634       TPythonDump()<<_this()<<".SetColor( SALOMEDS.Color( "<<color.R<<", "<<color.G<<", "<<color.B<<" ))";
00635     }
00636   }
00637 }
00638 
00639 //=============================================================================
00643 //=============================================================================
00644 CORBA::Long SMESH_GroupBase_i::GetColorNumber()
00645 {
00646   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
00647   if (aGroupDS)
00648     return aGroupDS->GetColorGroup();
00649   MESSAGE("get color number of a group");
00650   return 0;
00651 }
00652 
00653 //=============================================================================
00657 //=============================================================================
00658 void SMESH_GroupBase_i::SetColorNumber(CORBA::Long color)
00659 {
00660   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
00661   if (aGroupDS)
00662   {
00663     aGroupDS->SetColorGroup(color);
00664     TPythonDump()<<_this()<<".SetColorNumber( "<<color<<" )";
00665   }
00666   MESSAGE("set color number of a group");
00667   return ;
00668 }
00669 
00670 //=============================================================================
00676 //=============================================================================
00677 SMESH::long_array* SMESH_GroupBase_i::GetMeshInfo()
00678 {
00679   if ( myPreMeshInfo )
00680     return myPreMeshInfo->GetMeshInfo();
00681 
00682   SMESH::long_array_var aRes = new SMESH::long_array();
00683   aRes->length(SMESH::Entity_Last);
00684   for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
00685     aRes[i] = 0;
00686 
00687   if ( SMESHDS_GroupBase* g = GetGroupDS())
00688   {
00689     if ( g->GetType() == SMDSAbs_Node || ( myNbNodes > -1 && g->GetTic() == myGroupDSTic))
00690       aRes[ SMDSEntity_Node ] = GetNumberOfNodes();
00691 
00692     if ( g->GetType() != SMDSAbs_Node )
00693       SMESH_Mesh_i::CollectMeshInfo( g->GetElements(), aRes);
00694   }
00695 
00696   return aRes._retn();
00697 }
00698 
00699 //=======================================================================
00700 //function : GetIDs
00701 //purpose  : Returns ids of members
00702 //=======================================================================
00703 
00704 SMESH::long_array* SMESH_GroupBase_i::GetIDs()
00705 {
00706   return GetListOfID();
00707 }
00708 
00709 //=======================================================================
00710 //function : GetTypes
00711 //purpose  : Returns types of elements it contains
00712 //=======================================================================
00713 
00714 SMESH::array_of_ElementType* SMESH_GroupBase_i::GetTypes()
00715 {
00716   SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
00717   if ( !IsEmpty() )
00718   {
00719     types->length( 1 );
00720     types[0] = GetType();
00721   }
00722   return types._retn();
00723 }
00724 
00725 //=======================================================================
00726 //function : IsMeshInfoCorrect
00727 //purpose  : * Returns false if GetMeshInfo() returns incorrect information that may
00728 //           * happen if mesh data is not yet fully loaded from the file of study.
00729 //=======================================================================
00730 
00731 bool SMESH_GroupBase_i::IsMeshInfoCorrect()
00732 {
00733   return myPreMeshInfo ? myPreMeshInfo->IsMeshInfoCorrect() : true;
00734 }
00735 
00736 //================================================================================
00740 //================================================================================
00741 
00742 SMESH_PredicatePtr SMESH_GroupOnFilter_i::GetPredicate( SMESH::Filter_ptr filter )
00743 {
00744   SMESH_PredicatePtr predicate;
00745 
00746   if ( SMESH::Filter_i* filt_i = SMESH::DownCast< SMESH::Filter_i* >( filter ))
00747     if ( SMESH::Predicate_i* predic_i= filt_i->GetPredicate_i() )
00748       predicate = predic_i->GetPredicate();
00749 
00750   return predicate;
00751 }
00752 
00753 //================================================================================
00757 //================================================================================
00758 
00759 void SMESH_GroupOnFilter_i::SetFilter(SMESH::Filter_ptr theFilter)
00760 {
00761   if ( myPreMeshInfo )
00762     myPreMeshInfo->FullLoadFromFile();
00763 
00764   if ( ! myFilter->_is_nil() )
00765     myFilter->UnRegister();
00766 
00767   myFilter = SMESH::Filter::_duplicate( theFilter );
00768 
00769   if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() ))
00770     grDS->SetPredicate( GetPredicate( myFilter ));
00771 
00772   TPythonDump()<< _this() <<".SetFilter( "<<theFilter<<" )";
00773 
00774   if ( myFilter )
00775   {
00776     myFilter->Register();
00777     SMESH::DownCast< SMESH::Filter_i* >( myFilter )->AddWaiter( this );
00778   }
00779 }
00780 
00781 //================================================================================
00785 //================================================================================
00786 
00787 SMESH::Filter_ptr SMESH_GroupOnFilter_i::GetFilter()
00788 {
00789   SMESH::Filter_var f = myFilter;
00790   TPythonDump() << f << " = " << _this() << ".GetFilter()";
00791   return f._retn();
00792 }
00793 
00794 #define SEPAR '^'
00795 
00796 //================================================================================
00800 //================================================================================
00801 
00802 std::string SMESH_GroupOnFilter_i::FilterToString() const
00803 {
00804   SMESH_Comment result;
00805   SMESH::Filter::Criteria_var criteria;
00806   if ( !myFilter->_is_nil() && myFilter->GetCriteria( criteria.out() ))
00807   {
00808     result << criteria->length() << SEPAR;
00809     for ( unsigned i = 0; i < criteria->length(); ++i )
00810     {
00811       // write FunctorType as string but not as number to assure correct
00812       // persistence if enum FunctorType is modified by insertion in the middle
00813       SMESH::Filter::Criterion& crit = criteria[ i ];
00814       result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.Type ))    << SEPAR;
00815       result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.Compare )) << SEPAR;
00816       result << crit.Threshold                                                  << SEPAR;
00817       result << crit.ThresholdStr                                               << SEPAR;
00818       result << crit.ThresholdID                                                << SEPAR;
00819       result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.UnaryOp )) << SEPAR;
00820       result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.BinaryOp ))<< SEPAR;
00821       result << crit.Tolerance                                                  << SEPAR;
00822       result << crit.TypeOfElement                                              << SEPAR;
00823       result << crit.Precision                                                  << SEPAR;
00824     }
00825   }
00826   return result;
00827 }
00828 
00829 //================================================================================
00833 //================================================================================
00834 
00835 SMESH::Filter_ptr SMESH_GroupOnFilter_i::StringToFilter(const std::string& thePersistStr )
00836 {
00837   SMESH::Filter_var filter;
00838 
00839   // divide thePersistStr into sub-strings
00840   std::vector< std::string > strVec;
00841   std::string::size_type from = 0, to;
00842   while ( from < thePersistStr.size() )
00843   {
00844     to = thePersistStr.find( SEPAR, from );
00845     if ( to == std::string::npos )
00846       break;
00847     strVec.push_back( thePersistStr.substr( from, to-from ));
00848     from = to+1;
00849   }
00850   if ( strVec.empty() || strVec[0] == "0" )
00851     return filter._retn();
00852 #undef SEPAR
00853 
00854   // create Criteria
00855   int nbCrit = atoi( strVec[0].c_str() );
00856   SMESH::Filter::Criteria_var criteria = new SMESH::Filter::Criteria;
00857   criteria->length( nbCrit );
00858   int nbStrPerCrit = ( strVec.size() - 1 ) / nbCrit;
00859   for ( int i = 0; i < nbCrit; ++i )
00860   {
00861     SMESH::Filter::Criterion& crit = criteria[ i ];
00862     int iStr = 1 + i * nbStrPerCrit;
00863     crit.Type         = SMESH::StringToFunctorType( strVec[ iStr++ ].c_str() );
00864     crit.Compare      = SMESH::StringToFunctorType( strVec[ iStr++ ].c_str() );
00865     crit.Threshold    = atof(                       strVec[ iStr++ ].c_str() );
00866     crit.ThresholdStr =                             strVec[ iStr++ ].c_str();
00867     crit.ThresholdID  =                             strVec[ iStr++ ].c_str();
00868     crit.UnaryOp      = SMESH::StringToFunctorType( strVec[ iStr++ ].c_str() );
00869     crit.BinaryOp     = SMESH::StringToFunctorType( strVec[ iStr++ ].c_str() );
00870     crit.Tolerance    = atof(                       strVec[ iStr++ ].c_str() );
00871     crit.TypeOfElement= SMESH::ElementType( atoi(   strVec[ iStr++ ].c_str() ));
00872     crit.Precision    = atoi(                       strVec[ iStr++ ].c_str() );
00873   }
00874 
00875   // create a filter
00876   TPythonDump pd;
00877   SMESH::FilterManager_i* aFilterMgr = new SMESH::FilterManager_i();
00878   filter = aFilterMgr->CreateFilter();
00879   filter->SetCriteria( criteria.inout() );
00880   
00881   aFilterMgr->UnRegister();
00882 
00883   pd << ""; // to avoid optimizing pd out
00884 
00885   return filter._retn();
00886 }
00887 
00888 //================================================================================
00892 //================================================================================
00893 
00894 SMESH_GroupOnFilter_i::~SMESH_GroupOnFilter_i()
00895 {
00896   if ( ! myFilter->_is_nil() )
00897   {
00898     SMESH::DownCast< SMESH::Filter_i* >( myFilter )->RemoveWaiter( this );
00899     myFilter->UnRegister();
00900   }
00901 }
00902 
00903 //================================================================================
00907 //================================================================================
00908 
00909 void SMESH_GroupOnFilter_i::PredicateChanged()
00910 {
00911   if ( myPreMeshInfo )
00912     myPreMeshInfo->FullLoadFromFile();
00913 
00914   if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() ))
00915     grDS->SetPredicate( GetPredicate( myFilter ));
00916 }