1 // Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
24 // File : SMESH_Group_i.cxx
25 // Author : Sergey ANIKIN, OCC
28 #include "SMESH_Group_i.hxx"
30 #include "SMDSAbs_ElementType.hxx"
31 #include "SMESHDS_Group.hxx"
32 #include "SMESHDS_GroupOnFilter.hxx"
33 #include "SMESHDS_GroupOnGeom.hxx"
34 #include "SMESH_Comment.hxx"
35 #include "SMESH_Filter_i.hxx"
36 #include "SMESH_Gen_i.hxx"
37 #include "SMESH_Group.hxx"
38 #include "SMESH_Mesh_i.hxx"
39 #include "SMESH_PythonDump.hxx"
41 #include CORBA_SERVER_HEADER(SMESH_Filter)
43 #include "utilities.h"
45 using namespace SMESH;
47 //=============================================================================
51 //=============================================================================
53 SMESH_GroupBase_i::SMESH_GroupBase_i( PortableServer::POA_ptr thePOA,
54 SMESH_Mesh_i* theMeshServant,
55 const int theLocalID )
56 : SALOME::GenericObj_i( thePOA ),
57 myMeshServant( theMeshServant ),
58 myLocalID( theLocalID )
60 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i,
61 // servant activation is performed by SMESH_Mesh_i::createGroup()
62 // thePOA->activate_object( this );
65 SMESH_Group_i::SMESH_Group_i( PortableServer::POA_ptr thePOA,
66 SMESH_Mesh_i* theMeshServant,
67 const int theLocalID )
68 : SALOME::GenericObj_i( thePOA ),
69 SMESH_GroupBase_i( thePOA, theMeshServant, theLocalID )
71 //MESSAGE("SMESH_Group_i; this = "<<this );
74 SMESH_GroupOnGeom_i::SMESH_GroupOnGeom_i( PortableServer::POA_ptr thePOA,
75 SMESH_Mesh_i* theMeshServant,
76 const int theLocalID )
77 : SALOME::GenericObj_i( thePOA ),
78 SMESH_GroupBase_i( thePOA, theMeshServant, theLocalID )
80 //MESSAGE("SMESH_GroupOnGeom_i; this = "<<this );
83 SMESH_GroupOnFilter_i::SMESH_GroupOnFilter_i( PortableServer::POA_ptr thePOA,
84 SMESH_Mesh_i* theMeshServant,
85 const int theLocalID )
86 : SALOME::GenericObj_i( thePOA ),
87 SMESH_GroupBase_i( thePOA, theMeshServant, theLocalID )
89 //MESSAGE("SMESH_GroupOnGeom_i; this = "<<this );
92 //=============================================================================
96 //=============================================================================
98 SMESH_GroupBase_i::~SMESH_GroupBase_i()
100 MESSAGE("~SMESH_GroupBase_i; this = "<<this );
102 myMeshServant->removeGroup(myLocalID);
105 //=======================================================================
106 //function : GetSmeshGroup
108 //=======================================================================
110 ::SMESH_Group* SMESH_GroupBase_i::GetSmeshGroup() const
112 if ( myMeshServant ) {
113 ::SMESH_Mesh& aMesh = myMeshServant->GetImpl();
114 return aMesh.GetGroup(myLocalID);
119 //=======================================================================
120 //function : GetGroupDS
122 //=======================================================================
124 SMESHDS_GroupBase* SMESH_GroupBase_i::GetGroupDS() const
126 ::SMESH_Group* aGroup = GetSmeshGroup();
128 return aGroup->GetGroupDS();
132 //=============================================================================
136 //=============================================================================
138 void SMESH_GroupBase_i::SetName( const char* theName )
141 ::SMESH_Group* aGroup = GetSmeshGroup();
143 MESSAGE("can't set name of a vague group");
147 if ( aGroup->GetName() && !strcmp( aGroup->GetName(), theName ) )
148 return; // nothing to rename
150 aGroup->SetName(theName);
152 // Update group name in a study
153 SMESH_Gen_i* aGen = myMeshServant->GetGen();
154 aGen->SetName( aGen->ObjectToSObject( aGen->GetCurrentStudy(), _this() ), theName );
156 // Update Python script
157 TPythonDump() << _this() << ".SetName( '" << theName << "' )";
160 //=============================================================================
164 //=============================================================================
166 char* SMESH_GroupBase_i::GetName()
168 ::SMESH_Group* aGroup = GetSmeshGroup();
170 return CORBA::string_dup (aGroup->GetName());
171 MESSAGE("get name of a vague group");
172 return CORBA::string_dup( "NO_NAME" );
175 //=============================================================================
179 //=============================================================================
181 SMESH::ElementType SMESH_GroupBase_i::GetType()
183 SMESHDS_GroupBase* aGroupDS = GetGroupDS();
185 SMDSAbs_ElementType aSMDSType = aGroupDS->GetType();
186 SMESH::ElementType aType;
188 case SMDSAbs_Node: aType = SMESH::NODE; break;
189 case SMDSAbs_Edge: aType = SMESH::EDGE; break;
190 case SMDSAbs_Face: aType = SMESH::FACE; break;
191 case SMDSAbs_Volume: aType = SMESH::VOLUME; break;
192 case SMDSAbs_0DElement: aType = SMESH::ELEM0D; break;
193 default: aType = SMESH::ALL; break;
197 MESSAGE("get type of a vague group");
202 //=============================================================================
206 //=============================================================================
208 CORBA::Long SMESH_GroupBase_i::Size()
210 SMESHDS_GroupBase* aGroupDS = GetGroupDS();
212 return aGroupDS->Extent();
213 MESSAGE("get size of a vague group");
217 //=============================================================================
221 //=============================================================================
223 CORBA::Boolean SMESH_GroupBase_i::IsEmpty()
225 SMESHDS_GroupBase* aGroupDS = GetGroupDS();
227 return aGroupDS->IsEmpty();
228 MESSAGE("checking IsEmpty of a vague group");
232 //=============================================================================
236 //=============================================================================
238 void SMESH_Group_i::Clear()
240 // Update Python script
241 TPythonDump() << _this() << ".Clear()";
244 SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
249 MESSAGE("attempt to clear a vague group");
252 //=============================================================================
256 //=============================================================================
258 CORBA::Boolean SMESH_GroupBase_i::Contains( CORBA::Long theID )
260 SMESHDS_GroupBase* aGroupDS = GetGroupDS();
262 return aGroupDS->Contains(theID);
263 MESSAGE("attempt to check contents of a vague group");
267 //=============================================================================
271 //=============================================================================
273 CORBA::Long SMESH_Group_i::Add( const SMESH::long_array& theIDs )
275 // Update Python script
276 TPythonDump() << "nbAdd = " << _this() << ".Add( " << theIDs << " )";
278 // Add elements to the group
279 SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
282 for (int i = 0; i < theIDs.length(); i++) {
283 int anID = (int) theIDs[i];
284 if (aGroupDS->Add(anID))
289 MESSAGE("attempt to add elements to a vague group");
293 //=============================================================================
297 //=============================================================================
299 CORBA::Long SMESH_Group_i::Remove( const SMESH::long_array& theIDs )
301 // Update Python script
302 TPythonDump() << "nbDel = " << _this() << ".Remove( " << theIDs << " )";
304 // Remove elements from the group
305 SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
308 for (int i = 0; i < theIDs.length(); i++) {
309 int anID = (int) theIDs[i];
310 if (aGroupDS->Remove(anID))
315 MESSAGE("attempt to remove elements from a vague group");
319 //=============================================================================
323 //=============================================================================
325 typedef bool (SMESHDS_Group::*TFunChangeGroup)(const int);
328 ChangeByPredicate( SMESH::Predicate_i* thePredicate,
329 SMESHDS_GroupBase* theGroupBase,
330 TFunChangeGroup theFun)
333 if(SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>(theGroupBase)){
334 SMESH::Controls::Filter::TIdSequence aSequence;
335 const SMDS_Mesh* aMesh = theGroupBase->GetMesh();
336 SMESH::Filter_i::GetElementsId(thePredicate,aMesh,aSequence);
338 CORBA::Long i = 0, iEnd = aSequence.size();
340 if((aGroupDS->*theFun)(aSequence[i]))
349 AddByPredicate( SMESH::Predicate_ptr thePredicate )
351 if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){
352 TPythonDump()<<_this()<<".AddByPredicate("<<aPredicate<<")";
353 return ChangeByPredicate(aPredicate,GetGroupDS(),&SMESHDS_Group::Add);
360 RemoveByPredicate( SMESH::Predicate_ptr thePredicate )
362 if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){
363 TPythonDump()<<_this()<<".RemoveByPredicate("<<aPredicate<<")";
364 return ChangeByPredicate(aPredicate,GetGroupDS(),&SMESHDS_Group::Remove);
369 CORBA::Long SMESH_Group_i::AddFrom( SMESH::SMESH_IDSource_ptr theSource )
373 SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
375 SMESH::long_array_var anIds;
376 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theSource);
377 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow(theSource);
378 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow(theSource);
379 SMESH::Filter_var filter = SMESH::Filter::_narrow(theSource);
380 if ( !group->_is_nil())
381 anIds = group->GetType()==GetType() ? theSource->GetIDs() : new SMESH::long_array();
382 else if ( !mesh->_is_nil() )
383 anIds = mesh->GetElementsByType( GetType() );
384 else if ( !submesh->_is_nil())
385 anIds = submesh->GetElementsByType( GetType() );
386 else if ( !filter->_is_nil() ) {
387 filter->SetMesh( GetMeshServant()->_this() );
388 anIds = filter->GetElementType()==GetType() ? theSource->GetIDs() : new SMESH::long_array();
391 anIds = theSource->GetIDs();
392 for ( int i = 0, total = anIds->length(); i < total; i++ ) {
393 if ( aGroupDS->Add((int)anIds[i]) ) nbAdd++;
397 // Update Python script
398 pd << "nbAdd = " << _this() << ".AddFrom( " << theSource << " )";
403 //=============================================================================
407 //=============================================================================
409 CORBA::Long SMESH_GroupBase_i::GetID( CORBA::Long theIndex )
411 SMESHDS_GroupBase* aGroupDS = GetGroupDS();
413 return aGroupDS->GetID(theIndex);
414 MESSAGE("attempt to iterate on a vague group");
418 //=============================================================================
422 //=============================================================================
424 SMESH::long_array* SMESH_GroupBase_i::GetListOfID()
426 SMESH::long_array_var aRes = new SMESH::long_array();
427 SMESHDS_GroupBase* aGroupDS = GetGroupDS();
429 int aSize = aGroupDS->Extent();
431 for (int i = 0; i < aSize; i++)
432 aRes[i] = aGroupDS->GetID(i+1);
435 MESSAGE("get list of IDs of a vague group");
439 //=============================================================================
443 //=============================================================================
444 SMESH::SMESH_Mesh_ptr SMESH_GroupBase_i::GetMesh()
446 SMESH::SMESH_Mesh_var aMesh;
448 aMesh = SMESH::SMESH_Mesh::_narrow( myMeshServant->_this() );
449 return aMesh._retn();
452 //=======================================================================
453 //function : GetShape
455 //=======================================================================
457 GEOM::GEOM_Object_ptr SMESH_GroupOnGeom_i::GetShape()
459 GEOM::GEOM_Object_var aGeomObj;
460 SMESHDS_GroupOnGeom* aGroupDS = dynamic_cast<SMESHDS_GroupOnGeom*>( GetGroupDS() );
462 SMESH_Gen_i* aGen = GetMeshServant()->GetGen();
463 aGeomObj = aGen->ShapeToGeomObject( aGroupDS->GetShape() );
465 return aGeomObj._retn();
468 //=============================================================================
472 //=============================================================================
473 SALOMEDS::Color SMESH_GroupBase_i::GetColor()
475 SMESHDS_GroupBase* aGroupDS = GetGroupDS();
478 Quantity_Color aQColor = aGroupDS->GetColor();
479 SALOMEDS::Color aColor;
480 aColor.R = aQColor.Red();
481 aColor.G = aQColor.Green();
482 aColor.B = aQColor.Blue();
486 MESSAGE("get color of a group");
487 return SALOMEDS::Color();
490 //=============================================================================
494 //=============================================================================
495 void SMESH_GroupBase_i::SetColor(const SALOMEDS::Color& color)
497 SMESHDS_GroupBase* aGroupDS = GetGroupDS();
500 Quantity_Color aQColor( color.R, color.G, color.B, Quantity_TOC_RGB );
501 aGroupDS->SetColor(aQColor);
502 TPythonDump()<<_this()<<".SetColor( SALOMEDS.Color( "<<color.R<<", "<<color.G<<", "<<color.B<<" ))";
506 //=============================================================================
510 //=============================================================================
511 CORBA::Long SMESH_GroupBase_i::GetColorNumber()
513 SMESHDS_GroupBase* aGroupDS = GetGroupDS();
515 return aGroupDS->GetColorGroup();
516 MESSAGE("get color number of a group");
520 //=============================================================================
524 //=============================================================================
525 void SMESH_GroupBase_i::SetColorNumber(CORBA::Long color)
527 SMESHDS_GroupBase* aGroupDS = GetGroupDS();
530 aGroupDS->SetColorGroup(color);
531 TPythonDump()<<_this()<<".SetColorNumber( "<<color<<" )";
533 MESSAGE("set color number of a group");
537 //=============================================================================
539 * Returns statistic of mesh elements
540 * Result array of number enityties
541 * Inherited from SMESH_IDSource
543 //=============================================================================
544 SMESH::long_array* SMESH_GroupBase_i::GetMeshInfo()
546 SMESH::long_array_var aRes = new SMESH::long_array();
547 aRes->length(SMESH::Entity_Last);
548 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
551 SMESHDS_GroupBase* aGrpDS = GetGroupDS();
554 if ( GetType() == NODE )
555 aRes[ SMESH::Entity_Node ] = aGrpDS->Extent();
557 SMESH_Mesh_i::CollectMeshInfo( aGrpDS->GetElements(), aRes);
559 // SMDS_ElemIteratorPtr it = aGrpDS->GetElements();
562 // cout << "START" << endl;
563 // set< const SMDS_MeshElement* > nodes;
564 // const SMDS_MeshElement* e = it->next();
565 // for ( int i = 0; i < 1000000; ++i)
567 // SMDS_ElemIteratorPtr it = e->nodesIterator();
568 // nodes.insert( e + i );
570 // cout << "END "<< nodes.size() << endl;
576 //=======================================================================
578 //purpose : Returns ids of members
579 //=======================================================================
581 SMESH::long_array* SMESH_GroupBase_i::GetIDs()
583 SMESH::long_array_var aResult = GetListOfID();
584 return aResult._retn();
587 //=======================================================================
588 //function : GetTypes
589 //purpose : Returns types of elements it contains
590 //=======================================================================
592 SMESH::array_of_ElementType* SMESH_GroupBase_i::GetTypes()
594 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
595 if ( SMESHDS_GroupBase* ds = GetGroupDS() )
596 if ( !ds->IsEmpty() )
599 types[0] = GetType();
601 return types._retn();
604 //================================================================================
606 * \brief Retrieves the predicate from the filter
608 //================================================================================
610 SMESH_PredicatePtr SMESH_GroupOnFilter_i::GetPredicate( SMESH::Filter_ptr filter )
612 SMESH_PredicatePtr predicate;
614 if ( SMESH::Filter_i* filt_i = SMESH::DownCast< SMESH::Filter_i* >( filter ))
615 if ( SMESH::Predicate_i* predic_i= filt_i->GetPredicate_i() )
616 predicate = predic_i->GetPredicate();
621 //================================================================================
623 * \brief Sets the filter defining group contents
625 //================================================================================
627 void SMESH_GroupOnFilter_i::SetFilter(SMESH::Filter_ptr theFilter)
629 if ( ! myFilter->_is_nil() )
630 myFilter->UnRegister();
632 myFilter = SMESH::Filter::_duplicate( theFilter );
634 if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() ))
635 grDS->SetPredicate( GetPredicate( myFilter ));
637 TPythonDump()<< _this() <<".SetFilter( "<<theFilter<<" )";
641 myFilter->Register();
642 SMESH::DownCast< SMESH::Filter_i* >( myFilter )->AddWaiter( this );
646 //================================================================================
648 * \brief Returns the filter defining group contents
650 //================================================================================
652 SMESH::Filter_ptr SMESH_GroupOnFilter_i::GetFilter()
654 SMESH::Filter_var f = myFilter;
655 TPythonDump() << f << " = " << _this() << ".GetFilter()";
661 //================================================================================
663 * \brief Return a string to be used to store group definition in the study
665 //================================================================================
667 std::string SMESH_GroupOnFilter_i::FilterToString() const
669 SMESH_Comment result;
670 SMESH::Filter::Criteria_var criteria;
671 if ( !myFilter->_is_nil() && myFilter->GetCriteria( criteria.out() ))
673 result << criteria->length() << SEPAR;
674 for ( unsigned i = 0; i < criteria->length(); ++i )
676 // write FunctorType as string but not as number to assure correct
677 // persistence if enum FunctorType is modified by insertion in the middle
678 SMESH::Filter::Criterion& crit = criteria[ i ];
679 result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.Type )) << SEPAR;
680 result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.Compare )) << SEPAR;
681 result << crit.Threshold << SEPAR;
682 result << crit.ThresholdStr << SEPAR;
683 result << crit.ThresholdID << SEPAR;
684 result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.UnaryOp )) << SEPAR;
685 result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.BinaryOp ))<< SEPAR;
686 result << crit.Tolerance << SEPAR;
687 result << crit.TypeOfElement << SEPAR;
688 result << crit.Precision << SEPAR;
694 //================================================================================
696 * \brief Restore the filter by the persistent string
698 //================================================================================
700 SMESH::Filter_ptr SMESH_GroupOnFilter_i::StringToFilter(const std::string& thePersistStr )
702 SMESH::Filter_var filter;
704 // divide thePersistStr into sub-strings
705 std::vector< std::string > strVec;
706 std::string::size_type from = 0, to;
707 while ( from < thePersistStr.size() )
709 to = thePersistStr.find( SEPAR, from );
710 if ( to == std::string::npos )
712 strVec.push_back( thePersistStr.substr( from, to-from ));
715 if ( strVec.empty() || strVec[0] == "0" )
716 return filter._retn();
720 int nbCrit = atoi( strVec[0].c_str() );
721 SMESH::Filter::Criteria_var criteria = new SMESH::Filter::Criteria;
722 criteria->length( nbCrit );
723 int nbStrPerCrit = ( strVec.size() - 1 ) / nbCrit;
724 for ( int i = 0; i < nbCrit; ++i )
726 SMESH::Filter::Criterion& crit = criteria[ i ];
727 int iStr = 1 + i * nbStrPerCrit;
728 crit.Type = SMESH::StringToFunctorType( strVec[ iStr++ ].c_str() );
729 crit.Compare = SMESH::StringToFunctorType( strVec[ iStr++ ].c_str() );
730 crit.Threshold = atof( strVec[ iStr++ ].c_str() );
731 crit.ThresholdStr = strVec[ iStr++ ].c_str();
732 crit.ThresholdID = strVec[ iStr++ ].c_str();
733 crit.UnaryOp = SMESH::StringToFunctorType( strVec[ iStr++ ].c_str() );
734 crit.BinaryOp = SMESH::StringToFunctorType( strVec[ iStr++ ].c_str() );
735 crit.Tolerance = atof( strVec[ iStr++ ].c_str() );
736 crit.TypeOfElement= SMESH::ElementType( atoi( strVec[ iStr++ ].c_str() ));
737 crit.Precision = atoi( strVec[ iStr++ ].c_str() );
742 SMESH::FilterManager_i* aFilterMgr = new SMESH::FilterManager_i();
743 filter = aFilterMgr->CreateFilter();
744 filter->SetCriteria( criteria.inout() );
746 aFilterMgr->UnRegister();
748 pd << ""; // to avoid optimizing pd out
750 return filter._retn();
753 SMESH_GroupOnFilter_i::~SMESH_GroupOnFilter_i()
755 if ( ! myFilter->_is_nil() )
757 SMESH::DownCast< SMESH::Filter_i* >( myFilter )->RemoveWaiter( this );
758 myFilter->UnRegister();
762 void SMESH_GroupOnFilter_i::PredicateChanged()
764 if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() ))
765 grDS->SetPredicate( GetPredicate( myFilter ));