+template<class TElement, class TIterator, class TPredicate>
+static void collectMeshInfo(const TIterator& theItr,
+ TPredicate& thePred,
+ SMESH::long_array& theRes)
+{
+ if (!theItr)
+ return;
+ while (theItr->more()) {
+ const SMDS_MeshElement* anElem = theItr->next();
+ if ( thePred->IsSatisfy( anElem->GetID() ) )
+ theRes[ anElem->GetEntityType() ]++;
+ }
+}
+
+//=============================================================================
+/*!
+ * \brief Returns statistic of mesh elements
+ */
+//=============================================================================
+SMESH::long_array* ::Filter_i::GetMeshInfo()
+{
+ SMESH::long_array_var aRes = new SMESH::long_array();
+ aRes->length(SMESH::Entity_Last);
+ for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
+ aRes[i] = 0;
+
+ if(!CORBA::is_nil(myMesh) && myPredicate) {
+ const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh);
+ SMDS_ElemIteratorPtr it;
+ switch( GetElementType() )
+ {
+ case SMDSAbs_Node:
+ collectMeshInfo<const SMDS_MeshNode*>(aMesh->nodesIterator(),myPredicate,aRes);
+ break;
+ case SMDSAbs_Edge:
+ collectMeshInfo<const SMDS_MeshElement*>(aMesh->edgesIterator(),myPredicate,aRes);
+ break;
+ case SMDSAbs_Face:
+ collectMeshInfo<const SMDS_MeshElement*>(aMesh->facesIterator(),myPredicate,aRes);
+ break;
+ case SMDSAbs_Volume:
+ collectMeshInfo<const SMDS_MeshElement*>(aMesh->volumesIterator(),myPredicate,aRes);
+ break;
+ case SMDSAbs_All:
+ default:
+ collectMeshInfo<const SMDS_MeshElement*>(aMesh->elementsIterator(),myPredicate,aRes);
+ break;
+ }
+ }
+
+ return aRes._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Return GetElementType() within an array
+ * Implement SMESH_IDSource interface
+ */
+//================================================================================
+
+SMESH::array_of_ElementType* Filter_i::GetTypes()
+{
+ SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
+
+ // check if any element passes through the filter
+ if ( !CORBA::is_nil(myMesh) && myPredicate )
+ {
+ const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh);
+ SMDS_ElemIteratorPtr it = aMesh->elementsIterator( SMDSAbs_ElementType( GetElementType() ));
+ bool satisfies = false;
+ while ( !satisfies && it->more() )
+ satisfies = myPredicate->IsSatisfy( it->next()->GetID() );
+ if ( satisfies ) {
+ types->length( 1 );
+ types[0] = GetElementType();
+ }
+ }
+ return types._retn();
+}
+
+//=======================================================================
+//function : GetMesh
+//purpose : Returns mesh
+//=======================================================================
+
+SMESH::SMESH_Mesh_ptr Filter_i::GetMesh()
+{
+ return SMESH_Mesh::_duplicate( myMesh );
+}
+
+//================================================================================
+/*!
+ * \brief Stores an object to be notified on change of predicate
+ */
+//================================================================================
+
+void Filter_i::AddWaiter( TPredicateChangeWaiter* waiter )
+{
+ if ( waiter )
+ myWaiters.push_back( waiter );
+}
+
+//================================================================================
+/*!
+ * \brief Removes an object to be notified on change of predicate
+ */
+//================================================================================
+
+void Filter_i::RemoveWaiter( TPredicateChangeWaiter* waiter )
+{
+ myWaiters.remove( waiter );
+}
+