Salome HOME
Update of CheckDone
[modules/smesh.git] / src / SMESH_I / SMESH_Filter_i.cxx
1 // Copyright (C) 2007-2024  CEA, EDF, 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, or (at your option) any later version.
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_Filter_i.cxx
25 //  Author : Alexey Petrov, OCC
26 //  Module : SMESH
27
28 #include "SMESH_Filter_i.hxx"
29
30 #include "SMDS_ElemIterator.hxx"
31 #include "SMDS_Mesh.hxx"
32 #include "SMDS_MeshElement.hxx"
33 #include "SMDS_MeshNode.hxx"
34 #include "SMESHDS_GroupBase.hxx"
35 #include "SMESHDS_Mesh.hxx"
36 #include "SMESH_Gen_i.hxx"
37 #include "SMESH_Group_i.hxx"
38 #include "SMESH_PythonDump.hxx"
39
40 #include <SALOMEDS_wrap.hxx>
41 #include <GEOM_wrap.hxx>
42
43 #include <BRep_Tool.hxx>
44 #include <Geom_CylindricalSurface.hxx>
45 #include <Geom_Plane.hxx>
46 #include <LDOMParser.hxx>
47 #include <LDOMString.hxx>
48 #include <LDOM_Document.hxx>
49 #include <LDOM_Element.hxx>
50 #include <LDOM_Node.hxx>
51 #include <LDOM_XmlWriter.hxx>
52 #include <Precision.hxx>
53 #include <TColStd_ListIteratorOfListOfInteger.hxx>
54 #include <TColStd_ListIteratorOfListOfReal.hxx>
55 #include <TColStd_ListOfInteger.hxx>
56 #include <TColStd_ListOfReal.hxx>
57 #include <TColStd_SequenceOfHAsciiString.hxx>
58 #include <TCollection_HAsciiString.hxx>
59 #include <TopExp_Explorer.hxx>
60 #include <TopoDS.hxx>
61 #include <TopoDS_Shape.hxx>
62
63 //using namespace SMESH;
64 //using namespace SMESH::Controls;
65
66
67 namespace SMESH
68 {
69   Predicate_i*
70   GetPredicate( Predicate_ptr thePredicate )
71   {
72     return DownCast<Predicate_i*>(thePredicate);
73   }
74 }
75
76 /*
77                             AUXILIARY METHODS
78 */
79
80 inline
81 const SMDS_Mesh*
82 MeshPtr2SMDSMesh( SMESH::SMESH_Mesh_ptr theMesh )
83 {
84   SMESH_Mesh_i* anImplPtr = SMESH::DownCast<SMESH_Mesh_i*>(theMesh);
85   return anImplPtr ? anImplPtr->GetImpl().GetMeshDS() : 0;
86 }
87
88 inline
89 SMESH::long_array*
90 toArray( const TColStd_ListOfInteger& aList )
91 {
92   SMESH::long_array_var anArray = new SMESH::long_array;
93   anArray->length( aList.Extent() );
94   TColStd_ListIteratorOfListOfInteger anIter( aList );
95   int i = 0;
96   for( ; anIter.More(); anIter.Next() )
97     anArray[ i++ ] = anIter.Value();
98
99   return anArray._retn();
100 }
101
102 inline
103 SMESH::double_array*
104 toArray( const TColStd_ListOfReal& aList )
105 {
106   SMESH::double_array_var anArray = new SMESH::double_array;
107   anArray->length( aList.Extent() );
108   TColStd_ListIteratorOfListOfReal anIter( aList );
109   int i = 0;
110   for( ; anIter.More(); anIter.Next() )
111     anArray[ i++ ] = anIter.Value();
112
113   return anArray._retn();
114 }
115
116 static SMESH::Filter::Criterion createCriterion()
117 {
118   SMESH::Filter::Criterion aCriterion;
119
120   aCriterion.Type          = SMESH::FT_Undefined;
121   aCriterion.Compare       = SMESH::FT_Undefined;
122   aCriterion.Threshold     = 0;
123   aCriterion.UnaryOp       = SMESH::FT_Undefined;
124   aCriterion.BinaryOp      = SMESH::FT_Undefined;
125   aCriterion.ThresholdStr  = "";
126   aCriterion.ThresholdID   = "";
127   aCriterion.Tolerance     = Precision::Confusion();
128   aCriterion.TypeOfElement = SMESH::ALL;
129   aCriterion.Precision     = -1;
130
131   return aCriterion;
132 }
133
134 static TopoDS_Shape getShapeByName( const char* theName )
135 {
136   if ( theName != 0 )
137   {
138     SMESH_Gen_i* aSMESHGen     = SMESH_Gen_i::GetSMESHGen();
139     SALOMEDS::Study::ListOfSObject_var aList = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectByName( theName, "GEOM" );
140     if ( aList->length() == 0 )
141       aList = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectByName( theName, "SHAPERSTUDY" );
142     if ( aList->length() > 0 )
143     {
144       CORBA::Object_var        anObj = aList[ 0 ]->GetObject();
145       GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( anObj );
146       TopoDS_Shape             shape = aSMESHGen->GeomObjectToShape( aGeomObj );
147       SALOME::UnRegister( aList ); // UnRegister() objects in aList
148       return shape;
149     }
150   }
151   return TopoDS_Shape();
152 }
153
154 static TopoDS_Shape getShapeByID (const char* theID)
155 {
156   if ( theID && strlen( theID ) > 0 ) {
157     SMESH_Gen_i*     aSMESHGen = SMESH_Gen_i::GetSMESHGen();
158     SALOMEDS::SObject_wrap aSObj = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectID(theID);
159     if ( !aSObj->_is_nil() ) {
160       CORBA::Object_var          obj = aSObj->GetObject();
161       GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(obj);
162       return aSMESHGen->GeomObjectToShape( aGeomObj );
163     }
164   }
165   return TopoDS_Shape();
166 }
167
168 // static std::string getShapeNameByID (const char* theID)
169 // {
170 //   if ( theID && strlen( theID ) > 0 ) {
171 //     SALOMEDS::SObject_wrap aSObj = SMESH_Gen_i::getStudyServant()->FindObjectID(theID);
172 //     if ( !aSObj->_is_nil() ) {
173 //       CORBA::String_var name = aSObj->GetName();
174 //       return name.in();
175 //     }
176 //   }
177 //   return "";
178 // }
179
180 /*
181                                 FUNCTORS
182 */
183
184 //=============================================================================
185 /*!
186  *  SMESH_Gen_i::CreateFilterManager
187  *
188  *  Create filter manager
189  */
190  //=============================================================================
191
192 SMESH::FilterManager_ptr SMESH_Gen_i::CreateFilterManager()
193 {
194   SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i();
195   SMESH::FilterManager_var anObj = aFilter->_this();
196   return anObj._retn();
197 }
198
199 namespace SMESH {
200   /*
201     Class       : Functor_i
202     Description : An abstract class for all functors
203   */
204   Functor_i::Functor_i():
205     SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
206   {
207     //Base class Salome_GenericObject do it inmplicitly by overriding PortableServer::POA_ptr _default_POA() method  
208     //PortableServer::ObjectId_var anObjectId =
209     //  SMESH_Gen_i::GetPOA()->activate_object( this );
210   }
211
212   Functor_i::~Functor_i()
213   {
214     //TPythonDump()<<this<<".UnRegister()";
215   }
216
217   void Functor_i::SetMesh( SMESH_Mesh_ptr theMesh )
218   {
219     myFunctorPtr->SetMesh( MeshPtr2SMDSMesh( theMesh ) );
220     TPythonDump()<<this<<".SetMesh("<<theMesh<<")";
221   }
222
223   ElementType Functor_i::GetElementType()
224   {
225     return ( ElementType )myFunctorPtr->GetType();
226   }
227
228
229   /*
230     Class       : NumericalFunctor_i
231     Description : Base class for numerical functors
232   */
233   CORBA::Double NumericalFunctor_i::GetValue( SMESH::smIdType theId )
234   {
235     return myNumericalFunctorPtr->GetValue( theId );
236   }
237
238   CORBA::Boolean NumericalFunctor_i::IsApplicable( SMESH::smIdType theElementId )
239   {
240     return myNumericalFunctorPtr->IsApplicable( theElementId );
241   }
242
243   SMESH::Histogram* NumericalFunctor_i::GetHistogram(CORBA::Short nbIntervals, CORBA::Boolean isLogarithmic)
244   {
245     std::vector<int> nbEvents;
246     std::vector<double> funValues;
247     std::vector<::smIdType> elements;
248     myNumericalFunctorPtr->GetHistogram(nbIntervals, nbEvents, funValues ,elements, 0, isLogarithmic);
249
250     SMESH::Histogram_var histogram = new SMESH::Histogram;
251
252     nbIntervals = CORBA::Short( Min( int( nbEvents.size()),
253                                      int( funValues.size() - 1 )));
254     if ( nbIntervals > 0 )
255     {
256       histogram->length( nbIntervals );
257       for ( int i = 0; i < nbIntervals; ++i )
258       {
259         HistogramRectangle& rect = histogram[i];
260         rect.nbEvents = nbEvents[i];
261         rect.min = funValues[i];
262         rect.max = funValues[i+1];
263       }
264     }
265     return histogram._retn();
266   }
267
268   SMESH::Histogram* NumericalFunctor_i::GetLocalHistogram(CORBA::Short              nbIntervals,
269                                                           CORBA::Boolean            isLogarithmic,
270                                                           SMESH::SMESH_IDSource_ptr object)
271   {
272     SMESH::Histogram_var histogram = new SMESH::Histogram;
273
274     std::vector<int>             nbEvents;
275     std::vector<double>          funValues;
276     std::vector<::smIdType> elements;
277
278     SMDS_ElemIteratorPtr elemIt;
279     if ( SMESH::DownCast< SMESH_GroupOnFilter_i* >( object ) ||
280          SMESH::DownCast< SMESH::Filter_i* >( object ))
281     {
282       elemIt = SMESH_Mesh_i::GetElements( object, GetElementType() );
283       if ( !elemIt ) return histogram._retn();
284     }
285     else
286     {
287       SMESH::SMESH_Mesh_var            mesh = object->GetMesh();
288       SMESH::smIdType_array_var  objNbElems = object->GetNbElementsByType();
289       SMESH::smIdType_array_var meshNbElems = mesh->  GetNbElementsByType();
290       if ( meshNbElems[ GetElementType() ] !=
291            objNbElems [ GetElementType() ] )
292       {
293         elements.reserve( objNbElems[ GetElementType() ]);
294         elemIt = SMESH_Mesh_i::GetElements( object, GetElementType() );
295       }
296     }
297     if ( elemIt )
298     {
299       while ( elemIt->more() )
300         elements.push_back( elemIt->next()->GetID() );
301       if ( elements.empty() ) return histogram._retn();
302     }
303
304     myNumericalFunctorPtr->GetHistogram(nbIntervals,nbEvents,funValues, elements, 0, isLogarithmic);
305
306     nbIntervals = CORBA::Short( Min( int( nbEvents.size()),
307                                      int( funValues.size() - 1 )));
308     if ( nbIntervals > 0 )
309     {
310       histogram->length( nbIntervals );
311       for ( int i = 0; i < nbIntervals; ++i )
312       {
313         HistogramRectangle& rect = histogram[i];
314         rect.nbEvents = nbEvents[i];
315         rect.min = funValues[i];
316         rect.max = funValues[i+1];
317       }
318     }
319     return histogram._retn();
320   }
321
322   void NumericalFunctor_i::SetPrecision( CORBA::Long thePrecision )
323   {
324     myNumericalFunctorPtr->SetPrecision( thePrecision );
325     TPythonDump()<<this<<".SetPrecision("<<thePrecision<<")";
326   }
327
328   CORBA::Long NumericalFunctor_i::GetPrecision()
329   {
330    return myNumericalFunctorPtr->GetPrecision();
331   }
332
333   Controls::NumericalFunctorPtr NumericalFunctor_i::GetNumericalFunctor()
334   {
335     return myNumericalFunctorPtr;
336   }
337
338
339   /*
340     Class       : SMESH_MinimumAngle
341     Description : Functor for calculation of minimum angle
342   */
343   MinimumAngle_i::MinimumAngle_i()
344   {
345     myNumericalFunctorPtr.reset( new Controls::MinimumAngle() );
346     myFunctorPtr = myNumericalFunctorPtr;
347   }
348
349   FunctorType MinimumAngle_i::GetFunctorType()
350   {
351     return SMESH::FT_MinimumAngle;
352   }
353
354
355   /*
356     Class       : AspectRatio
357     Description : Functor for calculating aspect ratio
358   */
359   AspectRatio_i::AspectRatio_i()
360   {
361     myNumericalFunctorPtr.reset( new Controls::AspectRatio() );
362     myFunctorPtr = myNumericalFunctorPtr;
363   }
364
365   FunctorType AspectRatio_i::GetFunctorType()
366   {
367     return SMESH::FT_AspectRatio;
368   }
369
370
371   /*
372     Class       : AspectRatio3D
373     Description : Functor for calculating aspect ratio 3D
374   */
375   AspectRatio3D_i::AspectRatio3D_i()
376   {
377     myNumericalFunctorPtr.reset( new Controls::AspectRatio3D() );
378     myFunctorPtr = myNumericalFunctorPtr;
379   }
380
381   FunctorType AspectRatio3D_i::GetFunctorType()
382   {
383     return SMESH::FT_AspectRatio3D;
384   }
385
386
387   /*
388     Class       : Warping_i
389     Description : Functor for calculating warping
390   */
391   Warping_i::Warping_i()
392   {
393     myNumericalFunctorPtr.reset( new Controls::Warping() );
394     myFunctorPtr = myNumericalFunctorPtr;
395   }
396
397   FunctorType Warping_i::GetFunctorType()
398   {
399     return SMESH::FT_Warping;
400   }
401
402   /*
403     Class       : Warping3D_i
404     Description : Functor for calculating warping
405   */
406   Warping3D_i::Warping3D_i()
407   {
408     myNumericalFunctorPtr.reset(new Controls::Warping3D());
409     myFunctorPtr = myNumericalFunctorPtr;
410   }
411
412   FunctorType Warping3D_i::GetFunctorType()
413   {
414     return SMESH::FT_Warping3D;
415   }
416
417   /*
418     Class       : Taper_i
419     Description : Functor for calculating taper
420   */
421   Taper_i::Taper_i()
422   {
423     myNumericalFunctorPtr.reset( new Controls::Taper() );
424     myFunctorPtr = myNumericalFunctorPtr;
425   }
426
427   FunctorType Taper_i::GetFunctorType()
428   {
429     return SMESH::FT_Taper;
430   }
431
432   /*
433     Class       : Skew_i
434     Description : Functor for calculating skew in degrees
435   */
436   Skew_i::Skew_i()
437   {
438     myNumericalFunctorPtr.reset( new Controls::Skew() );
439     myFunctorPtr = myNumericalFunctorPtr;
440   }
441
442   FunctorType Skew_i::GetFunctorType()
443   {
444     return SMESH::FT_Skew;
445   }
446
447   /*
448     Class       : Area_i
449     Description : Functor for calculating area
450   */
451   Area_i::Area_i()
452   {
453     myNumericalFunctorPtr.reset( new Controls::Area() );
454     myFunctorPtr = myNumericalFunctorPtr;
455   }
456
457   FunctorType Area_i::GetFunctorType()
458   {
459     return SMESH::FT_Area;
460   }
461
462   /*
463     Class       : Volume3D_i
464     Description : Functor for calculating volume of 3D element
465   */
466   Volume3D_i::Volume3D_i()
467   {
468     myNumericalFunctorPtr.reset( new Controls::Volume() );
469     myFunctorPtr = myNumericalFunctorPtr;
470   }
471
472   FunctorType Volume3D_i::GetFunctorType()
473   {
474     return SMESH::FT_Volume3D;
475   }
476
477   /*
478     Class       : ScaledJacobian_i
479     Description : Functor for calculating volume of 3D element
480   */
481   ScaledJacobian_i::ScaledJacobian_i()
482   {
483     myNumericalFunctorPtr.reset( new Controls::ScaledJacobian() );
484     myFunctorPtr = myNumericalFunctorPtr;
485   }
486
487   FunctorType ScaledJacobian_i::GetFunctorType()
488   {
489     return SMESH::FT_ScaledJacobian;
490   }
491
492   /*
493     Class       : MaxElementLength2D_i
494     Description : Functor for calculating maximum length of 2D element
495   */
496   MaxElementLength2D_i::MaxElementLength2D_i()
497   {
498     myNumericalFunctorPtr.reset( new Controls::MaxElementLength2D() );
499     myFunctorPtr = myNumericalFunctorPtr;
500   }
501
502   FunctorType MaxElementLength2D_i::GetFunctorType()
503   {
504     return SMESH::FT_MaxElementLength2D;
505   }
506
507   /*
508     Class       : MaxElementLength3D_i
509     Description : Functor for calculating maximum length of 3D element
510   */
511   MaxElementLength3D_i::MaxElementLength3D_i()
512   {
513     myNumericalFunctorPtr.reset( new Controls::MaxElementLength3D() );
514     myFunctorPtr = myNumericalFunctorPtr;
515   }
516
517   FunctorType MaxElementLength3D_i::GetFunctorType()
518   {
519     return SMESH::FT_MaxElementLength3D;
520   }
521
522   /*
523     Class       : Length_i
524     Description : Functor for calculating length off edge
525   */
526   Length_i::Length_i()
527   {
528     myNumericalFunctorPtr.reset( new Controls::Length() );
529     myFunctorPtr = myNumericalFunctorPtr;
530   }
531
532   FunctorType Length_i::GetFunctorType()
533   {
534     return SMESH::FT_Length;
535   }
536
537   /*
538     Class       : Length2D_i
539     Description : Functor for calculating length of edge
540   */
541   Length2D_i::Length2D_i()
542   {
543     myNumericalFunctorPtr.reset( new Controls::Length2D() );
544     myFunctorPtr = myNumericalFunctorPtr;
545   }
546
547   FunctorType Length2D_i::GetFunctorType()
548   {
549     return SMESH::FT_Length2D;
550   }
551
552   SMESH::Length2D::Values* Length2D_i::GetValues()
553   {
554     SMESH::Controls::Length2D::TValues aValues;
555     (dynamic_cast<SMESH::Controls::Length2D*>(myFunctorPtr.get()))->GetValues( aValues );
556
557     long i = 0, iEnd = aValues.size();
558
559     SMESH::Length2D::Values_var aResult = new SMESH::Length2D::Values(iEnd);
560     aResult->length(iEnd);
561
562     SMESH::Controls::Length2D::TValues::const_iterator anIter;
563     for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ )
564     {
565       const SMESH::Controls::Length2D::Value&  aVal = *anIter;
566       SMESH::Length2D::Value &aValue = aResult[ i ];
567
568       aValue.myLength = aVal.myLength;
569       aValue.myPnt1 = aVal.myPntId[ 0 ];
570       aValue.myPnt2 = aVal.myPntId[ 1 ];
571     }
572
573     return aResult._retn();
574   }
575
576
577   /*
578     Class       : Length3D_i
579     Description : Functor for calculating length of edge
580   */
581   Length3D_i::Length3D_i()
582   {
583     myNumericalFunctorPtr.reset( new Controls::Length3D() );
584     myFunctorPtr = myNumericalFunctorPtr;
585   }
586
587   FunctorType Length3D_i::GetFunctorType()
588   {
589     return SMESH::FT_Length3D;
590   }
591
592   // SMESH::Length3D::Values* Length3D_i::GetValues()
593   // {
594   //   SMESH::Controls::Length3D::TValues aValues;
595   //   (dynamic_cast<SMESH::Controls::Length3D*>(myFunctorPtr.get()))->GetValues( aValues );
596
597   //   long i = 0, iEnd = aValues.size();
598
599   //   SMESH::Length3D::Values_var aResult = new SMESH::Length3D::Values(iEnd);
600   //   aResult->length(iEnd);
601
602   //   SMESH::Controls::Length3D::TValues::const_iterator anIter;
603   //   for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ )
604   //   {
605   //     const SMESH::Controls::Length3D::Value&  aVal = *anIter;
606   //     SMESH::Length3D::Value &aValue = aResult[ i ];
607
608   //     aValue.myLength = aVal.myLength;
609   //     aValue.myPnt1 = aVal.myPntId[ 0 ];
610   //     aValue.myPnt2 = aVal.myPntId[ 1 ];
611   //   }
612
613   //   return aResult._retn();
614   // }
615
616   /*
617     Class       : Deflection2D_i
618     Description : Functor for calculating distance between a face and geometry
619   */
620   Deflection2D_i::Deflection2D_i()
621   {
622     myNumericalFunctorPtr.reset( new Controls::Deflection2D() );
623     myFunctorPtr = myNumericalFunctorPtr;
624   }
625
626   FunctorType Deflection2D_i::GetFunctorType()
627   {
628     return SMESH::FT_Deflection2D;
629   }
630
631   /*
632     Class       : MultiConnection_i
633     Description : Functor for calculating number of faces conneted to the edge
634   */
635   MultiConnection_i::MultiConnection_i()
636   {
637     myNumericalFunctorPtr.reset( new Controls::MultiConnection() );
638     myFunctorPtr = myNumericalFunctorPtr;
639   }
640
641   FunctorType MultiConnection_i::GetFunctorType()
642   {
643     return SMESH::FT_MultiConnection;
644   }
645
646   /*
647     Class       : BallDiameter_i
648     Description : Functor returning diameter of a ball element
649   */
650   BallDiameter_i::BallDiameter_i()
651   {
652     myNumericalFunctorPtr.reset( new Controls::BallDiameter() );
653     myFunctorPtr = myNumericalFunctorPtr;
654   }
655
656   FunctorType BallDiameter_i::GetFunctorType()
657   {
658     return SMESH::FT_BallDiameter;
659   }
660
661   /*
662     Class       : NodeConnectivityNumber_i
663     Description : Functor returning diameter of a ball element
664   */
665   NodeConnectivityNumber_i::NodeConnectivityNumber_i()
666   {
667     myNumericalFunctorPtr.reset( new Controls::NodeConnectivityNumber() );
668     myFunctorPtr = myNumericalFunctorPtr;
669   }
670
671   FunctorType NodeConnectivityNumber_i::GetFunctorType()
672   {
673     return SMESH::FT_NodeConnectivityNumber;
674   }
675
676   /*
677     Class       : MultiConnection2D_i
678     Description : Functor for calculating number of faces conneted to the edge
679   */
680   MultiConnection2D_i::MultiConnection2D_i()
681   {
682     myNumericalFunctorPtr.reset( new Controls::MultiConnection2D() );
683     myFunctorPtr = myNumericalFunctorPtr;
684   }
685
686   FunctorType MultiConnection2D_i::GetFunctorType()
687   {
688     return SMESH::FT_MultiConnection2D;
689   }
690
691   SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues()
692   {
693     SMESH::Controls::MultiConnection2D::MValues aValues;
694     (dynamic_cast<SMESH::Controls::MultiConnection2D*>(myFunctorPtr.get()))->GetValues( aValues );
695   
696     long i = 0, iEnd = aValues.size();
697
698     SMESH::MultiConnection2D::Values_var aResult = new SMESH::MultiConnection2D::Values(iEnd);
699     aResult->length(iEnd);
700
701     SMESH::Controls::MultiConnection2D::MValues::const_iterator anIter;
702     for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ )
703     {
704       const SMESH::Controls::MultiConnection2D::Value&  aVal = (*anIter).first;
705       SMESH::MultiConnection2D::Value &aValue = aResult[ i ];
706
707       aValue.myPnt1 = aVal.myPntId[ 0 ];
708       aValue.myPnt2 = aVal.myPntId[ 1 ];
709       aValue.myNbConnects = (*anIter).second;
710     }
711
712     return aResult._retn();
713   }
714
715   /*
716                               PREDICATES
717   */
718
719
720   /*
721     Class       : Predicate_i
722     Description : Base class for all predicates
723   */
724   CORBA::Boolean Predicate_i::IsSatisfy( CORBA::Long theId )
725   {
726     return myPredicatePtr->IsSatisfy( theId );
727   }
728
729   CORBA::Long Predicate_i::NbSatisfying( SMESH::SMESH_IDSource_ptr obj )
730   {
731     SMESH::SMESH_Mesh_var meshVar = obj->GetMesh();
732     const SMDS_Mesh*       meshDS = MeshPtr2SMDSMesh( meshVar );
733     if ( !meshDS )
734       return 0;
735     myPredicatePtr->SetMesh( meshDS );
736
737     SMDSAbs_ElementType elemType = SMDSAbs_ElementType( GetElementType() );
738
739     int nb = 0;
740     SMDS_ElemIteratorPtr elemIt =
741       SMESH::DownCast<SMESH_Mesh_i*>( meshVar )->GetElements( obj, GetElementType() );
742     if ( elemIt )
743       while ( elemIt->more() )
744       {
745         const SMDS_MeshElement* e = elemIt->next();
746         if ( e && e->GetType() == elemType )
747           nb += myPredicatePtr->IsSatisfy( e->GetID() );
748       }
749     return nb;
750   }
751
752   Controls::PredicatePtr Predicate_i::GetPredicate()
753   {
754     return myPredicatePtr;
755   }
756
757   /*
758     Class       : BadOrientedVolume_i
759     Description : Verify whether a mesh volume is incorrectly oriented from
760                   the point of view of MED convention
761   */
762   BadOrientedVolume_i::BadOrientedVolume_i()
763   {
764     Controls::PredicatePtr control( new Controls::BadOrientedVolume() );
765     myFunctorPtr = myPredicatePtr = control;
766   }
767
768   FunctorType BadOrientedVolume_i::GetFunctorType()
769   {
770     return SMESH::FT_BadOrientedVolume;
771   }
772
773   /*
774     Class       : BareBorderVolume_i
775     Description : Verify whether a mesh volume has a free facet without a face on it
776   */
777   BareBorderVolume_i::BareBorderVolume_i()
778   {
779     Controls::PredicatePtr control( new Controls::BareBorderVolume() );
780     myFunctorPtr = myPredicatePtr = control;
781   }
782
783   FunctorType BareBorderVolume_i::GetFunctorType()
784   {
785     return SMESH::FT_BareBorderVolume;
786   }
787
788   /*
789     Class       : BareBorderFace_i
790     Description : Verify whether a mesh face has a free border without an edge on it
791   */
792   BareBorderFace_i::BareBorderFace_i()
793   {
794     Controls::PredicatePtr control( new Controls::BareBorderFace() );
795     myFunctorPtr = myPredicatePtr = control;
796   }
797
798   FunctorType BareBorderFace_i::GetFunctorType()
799   {
800     return SMESH::FT_BareBorderFace;
801   }
802
803   /*
804     Class       : OverConstrainedVolume_i
805     Description : Verify whether a mesh volume has only one facet shared with other volumes
806   */
807   OverConstrainedVolume_i::OverConstrainedVolume_i()
808   {
809     Controls::PredicatePtr control( new Controls::OverConstrainedVolume() );
810     myFunctorPtr = myPredicatePtr = control;
811   }
812
813   FunctorType OverConstrainedVolume_i::GetFunctorType()
814   {
815     return SMESH::FT_OverConstrainedVolume;
816   }
817
818   /*
819     Class       : OverConstrainedFace_i
820     Description : Verify whether a mesh face has only one border shared with other faces
821   */
822   OverConstrainedFace_i::OverConstrainedFace_i()
823   {
824     Controls::PredicatePtr control( new Controls::OverConstrainedFace() );
825     myFunctorPtr = myPredicatePtr = control;
826   }
827
828   FunctorType OverConstrainedFace_i::GetFunctorType()
829   {
830     return SMESH::FT_OverConstrainedFace;
831   }
832
833   /*
834     Class       : BelongToMeshGroup_i
835     Description : Verify whether a mesh element is included into a mesh group
836   */
837   BelongToMeshGroup_i::BelongToMeshGroup_i()
838   {
839     myBelongToMeshGroup = Controls::BelongToMeshGroupPtr( new Controls::BelongToMeshGroup() );
840     myFunctorPtr = myPredicatePtr = myBelongToMeshGroup;
841   }
842
843   BelongToMeshGroup_i::~BelongToMeshGroup_i()
844   {
845     SetGroup( SMESH::SMESH_GroupBase::_nil() );
846   }
847
848   void BelongToMeshGroup_i::SetGroup( SMESH::SMESH_GroupBase_ptr theGroup )
849   {
850     if ( myGroup->_is_equivalent( theGroup ))
851       return;
852
853     if ( ! myGroup->_is_nil() )
854       myGroup->UnRegister();
855
856     myGroup = SMESH_GroupBase::_duplicate( theGroup );
857
858     myBelongToMeshGroup->SetGroup( 0 );
859     if ( SMESH_GroupBase_i* gr_i = SMESH::DownCast< SMESH_GroupBase_i* >( myGroup ))
860     {
861       myBelongToMeshGroup->SetGroup( gr_i->GetGroupDS() );
862       myGroup->Register();
863     }
864   }
865
866   void BelongToMeshGroup_i::SetGroupID( const char* theID ) // IOR or StoreName
867   {
868     myID = theID;
869     if ( strncmp( "IOR:", myID.c_str(), 4 ) == 0 ) // transient mode, no GUI
870     {
871       CORBA::Object_var obj = SMESH_Gen_i::GetORB()->string_to_object( myID.c_str() );
872       SetGroup( SMESH::SMESH_GroupBase::_narrow( obj ));
873     }
874     else if ( strncmp( "0:", myID.c_str(), 2 ) == 0 ) // transient mode + GUI
875     {
876       SALOMEDS::SObject_wrap aSObj = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectID( myID.c_str() );
877       if ( !aSObj->_is_nil() ) {
878         CORBA::Object_var obj = aSObj->GetObject();
879         SetGroup( SMESH::SMESH_GroupBase::_narrow( obj ));
880       }
881     }
882     else if ( !myID.empty() ) // persistent mode
883     {
884       myBelongToMeshGroup->SetStoreName( myID );
885     }
886   }
887
888   std::string BelongToMeshGroup_i::GetGroupID()
889   {
890     if ( myGroup->_is_nil() )
891       SMESH::SMESH_GroupBase_var( GetGroup() );  // decref the returned pointer
892
893     if ( !myGroup->_is_nil() )
894       myID = SMESH_Gen_i::GetORB()->object_to_string( myGroup );
895
896     return myID;
897   }
898
899   SMESH::SMESH_GroupBase_ptr BelongToMeshGroup_i::GetGroup()
900   {
901     if ( myGroup->_is_nil() && myBelongToMeshGroup->GetGroup() )
902     {
903       // search for a group in a current study
904       SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
905       if ( StudyContext*  sc = aSMESHGen->GetStudyContext() )
906       {
907         int id = 1;
908         std::string ior;
909         while (true)
910         {
911           ior = sc->getIORbyId( id++ );
912           if ( ior.empty() ) break;
913           CORBA::Object_var obj = aSMESHGen->GetORB()->string_to_object( ior.c_str() );
914           if ( SMESH_GroupBase_i* g_i = SMESH::DownCast<SMESH_GroupBase_i*>( obj ))
915             if ( g_i->GetGroupDS() == myBelongToMeshGroup->GetGroup() )
916             {
917               SetGroup( g_i->_this() );
918               break;
919             }
920         }
921       }
922     }
923     return SMESH::SMESH_GroupBase::_duplicate( myGroup );
924   }
925
926   FunctorType BelongToMeshGroup_i::GetFunctorType()
927   {
928     return SMESH::FT_BelongToMeshGroup;
929   }
930
931   /*
932     Class       : BelongToGeom_i
933     Description : Predicate for selection on geometrical support
934   */
935   BelongToGeom_i::BelongToGeom_i()
936   {
937     myBelongToGeomPtr.reset( new Controls::BelongToGeom() );
938     myFunctorPtr = myPredicatePtr = myBelongToGeomPtr;
939     myShapeName = 0;
940     myShapeID   = 0;
941   }
942
943   BelongToGeom_i::~BelongToGeom_i()
944   {
945     CORBA::string_free( myShapeName );
946     CORBA::string_free( myShapeID );
947   }
948
949   void BelongToGeom_i::SetGeom( GEOM::GEOM_Object_ptr theGeom )
950   {
951     if ( theGeom->_is_nil() )
952       return;
953     TopoDS_Shape aLocShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theGeom );
954     myBelongToGeomPtr->SetGeom( aLocShape );
955     TPythonDump()<<this<<".SetGeom("<<theGeom<<")";
956   }
957
958   void BelongToGeom_i::SetGeom( const TopoDS_Shape& theShape )
959   {
960     myBelongToGeomPtr->SetGeom( theShape );
961   }
962
963   void BelongToGeom_i::SetElementType(ElementType theType)
964   {
965     myBelongToGeomPtr->SetType(SMDSAbs_ElementType(theType));
966     TPythonDump()<<this<<".SetElementType("<<theType<<")";
967   }
968
969   FunctorType BelongToGeom_i::GetFunctorType()
970   {
971     return SMESH::FT_BelongToGeom;
972   }
973
974   void BelongToGeom_i::SetShapeName( const char* theName )
975   {
976     CORBA::string_free( myShapeName );
977     myShapeName = CORBA::string_dup( theName );
978     myBelongToGeomPtr->SetGeom( getShapeByName( myShapeName ) );
979     TPythonDump()<<this<<".SetShapeName('"<<theName<<"')";
980   }
981
982   void BelongToGeom_i::SetShape( const char* theID, const char* theName )
983   {
984     CORBA::string_free( myShapeName );
985     CORBA::string_free( myShapeID );
986     myShapeName = CORBA::string_dup( theName );
987     myShapeID   = CORBA::string_dup( theID );
988     bool hasName = ( theName && theName[0] );
989     bool hasID   = ( theID   && theID[0] );
990
991     TopoDS_Shape S;
992     if ( hasName && hasID )
993     {
994       S = getShapeByID( myShapeID );
995       if ( S.IsNull() )
996         S = getShapeByName( myShapeName );
997     }
998     else
999     {
1000       S = hasID ? getShapeByID( myShapeID ) : getShapeByName( myShapeName );
1001     }
1002     myBelongToGeomPtr->SetGeom( S );
1003   }
1004
1005   char* BelongToGeom_i::GetShapeName()
1006   {
1007     return CORBA::string_dup( myShapeName );
1008   }
1009
1010   char* BelongToGeom_i::GetShapeID()
1011   {
1012     return CORBA::string_dup( myShapeID );
1013   }
1014
1015   void BelongToGeom_i::SetTolerance( CORBA::Double theToler )
1016   {
1017     myBelongToGeomPtr->SetTolerance( theToler );
1018     TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
1019   }
1020
1021   CORBA::Double BelongToGeom_i::GetTolerance()
1022   {
1023     return myBelongToGeomPtr->GetTolerance();
1024   }
1025
1026   /*
1027     Class       : BelongToSurface_i
1028     Description : Predicate for selection on geometrical support
1029   */
1030   BelongToSurface_i::BelongToSurface_i( const Handle(Standard_Type)& theSurfaceType )
1031   {
1032     myElementsOnSurfacePtr.reset( new Controls::ElementsOnSurface() );
1033     myFunctorPtr = myPredicatePtr = myElementsOnSurfacePtr;
1034     myShapeName = 0;
1035     myShapeID   = 0;
1036     mySurfaceType = theSurfaceType;
1037   }
1038
1039   BelongToSurface_i::~BelongToSurface_i()
1040   {
1041     CORBA::string_free( myShapeName );
1042     CORBA::string_free( myShapeID );
1043   }
1044
1045   void BelongToSurface_i::SetSurface( GEOM::GEOM_Object_ptr theGeom, ElementType theType )
1046   {
1047     if ( theGeom->_is_nil() )
1048       return;
1049     TopoDS_Shape aLocShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theGeom );
1050
1051     if ( aLocShape.ShapeType() == TopAbs_FACE )
1052     {
1053       Handle(Geom_Surface) aSurf = BRep_Tool::Surface( TopoDS::Face( aLocShape ) );
1054       if ( !aSurf.IsNull() && aSurf->DynamicType() == mySurfaceType )
1055       {
1056         myElementsOnSurfacePtr->SetSurface( aLocShape, (SMDSAbs_ElementType)theType );
1057         return;
1058       }
1059     }
1060
1061     myElementsOnSurfacePtr->SetSurface( TopoDS_Shape(), (SMDSAbs_ElementType)theType );
1062   }
1063
1064   void BelongToSurface_i::SetShapeName( const char* theName, ElementType theType )
1065   {
1066     CORBA::string_free( myShapeName );
1067     myShapeName = CORBA::string_dup( theName );
1068     myElementsOnSurfacePtr->SetSurface( getShapeByName( myShapeName ), (SMDSAbs_ElementType)theType );
1069     TPythonDump()<<this<<".SetShapeName('"<<theName<<"',"<<theType<<")";
1070   }
1071
1072   void BelongToSurface_i::SetShape( const char* theID,  const char* theName, ElementType theType )
1073   {
1074     CORBA::string_free( myShapeName );
1075     CORBA::string_free( myShapeID );
1076     myShapeName = CORBA::string_dup( theName );
1077     myShapeID   = CORBA::string_dup( theID );
1078     bool hasName = ( theName && theName[0] );
1079     bool hasID   = ( theID   && theID[0] );
1080
1081     TopoDS_Shape S;
1082     if ( hasName && hasID )
1083     {
1084       S = getShapeByID( myShapeID );
1085       if ( S.IsNull() )
1086         S = getShapeByName( myShapeName );
1087     }
1088     else
1089     {
1090       S = hasID ? getShapeByID( myShapeID ) : getShapeByName( myShapeName );
1091     }
1092     myElementsOnSurfacePtr->SetSurface( S, (SMDSAbs_ElementType)theType );
1093   }
1094
1095   char* BelongToSurface_i::GetShapeName()
1096   {
1097     return CORBA::string_dup( myShapeName );
1098   }
1099
1100   char* BelongToSurface_i::GetShapeID()
1101   {
1102     return CORBA::string_dup( myShapeID );
1103   }
1104
1105   void BelongToSurface_i::SetTolerance( CORBA::Double theToler )
1106   {
1107     myElementsOnSurfacePtr->SetTolerance( theToler );
1108     TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
1109   }
1110
1111   CORBA::Double BelongToSurface_i::GetTolerance()
1112   {
1113     return myElementsOnSurfacePtr->GetTolerance();
1114   }
1115
1116   void BelongToSurface_i::SetUseBoundaries( CORBA::Boolean theUseBndRestrictions )
1117   {
1118     myElementsOnSurfacePtr->SetUseBoundaries( theUseBndRestrictions );
1119     TPythonDump()<<this<<".SetUseBoundaries( " << theUseBndRestrictions << " )";
1120   }
1121
1122   CORBA::Boolean BelongToSurface_i::GetUseBoundaries()
1123   {
1124     return myElementsOnSurfacePtr->GetUseBoundaries();
1125   }
1126
1127
1128   /*
1129     Class       : BelongToPlane_i
1130     Description : Verify whether mesh element lie in pointed Geom planar object
1131   */
1132
1133   BelongToPlane_i::BelongToPlane_i()
1134   : BelongToSurface_i( STANDARD_TYPE( Geom_Plane ) )
1135   {
1136   }
1137
1138   void BelongToPlane_i::SetPlane( GEOM::GEOM_Object_ptr theGeom, ElementType theType )
1139   {
1140     BelongToSurface_i::SetSurface( theGeom, theType );
1141     TPythonDump()<<this<<".SetPlane("<<theGeom<<","<<theType<<")";
1142   }
1143
1144   FunctorType BelongToPlane_i::GetFunctorType()
1145   {
1146     return FT_BelongToPlane;
1147   }
1148
1149   /*
1150     Class       : BelongToCylinder_i
1151     Description : Verify whether mesh element lie in pointed Geom planar object
1152   */
1153
1154   BelongToCylinder_i::BelongToCylinder_i()
1155   : BelongToSurface_i( STANDARD_TYPE( Geom_CylindricalSurface ) )
1156   {
1157   }
1158
1159   void BelongToCylinder_i::SetCylinder( GEOM::GEOM_Object_ptr theGeom, ElementType theType )
1160   {
1161     BelongToSurface_i::SetSurface( theGeom, theType );
1162     TPythonDump()<<this<<".SetCylinder("<<theGeom<<","<<theType<<")";
1163   }
1164
1165   FunctorType BelongToCylinder_i::GetFunctorType()
1166   {
1167     return FT_BelongToCylinder;
1168   }
1169
1170   /*
1171     Class       : BelongToGenSurface_i
1172     Description : Verify whether mesh element lie in pointed Geom planar object
1173   */
1174
1175   BelongToGenSurface_i::BelongToGenSurface_i()
1176   : BelongToSurface_i( STANDARD_TYPE( Geom_CylindricalSurface ) )
1177   {
1178   }
1179
1180   void BelongToGenSurface_i::SetSurface( GEOM::GEOM_Object_ptr theGeom, ElementType theType )
1181   {
1182     if ( theGeom->_is_nil() )
1183       return;
1184     TopoDS_Shape aLocShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theGeom );
1185     if ( !aLocShape.IsNull() && aLocShape.ShapeType() != TopAbs_FACE )
1186       aLocShape.Nullify();
1187   
1188     BelongToSurface_i::myElementsOnSurfacePtr->SetSurface( aLocShape, (SMDSAbs_ElementType)theType );
1189     TPythonDump()<<this<<".SetGenSurface("<<theGeom<<","<<theType<<")";
1190   }
1191
1192   FunctorType BelongToGenSurface_i::GetFunctorType()
1193   {
1194     return FT_BelongToGenSurface;
1195   }
1196
1197   /*
1198     Class       : LyingOnGeom_i
1199     Description : Predicate for selection on geometrical support
1200   */
1201   LyingOnGeom_i::LyingOnGeom_i()
1202   {
1203     myLyingOnGeomPtr.reset( new Controls::LyingOnGeom() );
1204     myFunctorPtr = myPredicatePtr = myLyingOnGeomPtr;
1205     myShapeName = 0;
1206     myShapeID = 0;
1207   }
1208
1209   LyingOnGeom_i::~LyingOnGeom_i()
1210   {
1211     CORBA::string_free( myShapeName );
1212     CORBA::string_free( myShapeID );
1213   }
1214
1215   void LyingOnGeom_i::SetGeom( GEOM::GEOM_Object_ptr theGeom )
1216   {
1217     if ( theGeom->_is_nil() )
1218       return;
1219     TopoDS_Shape aLocShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theGeom );
1220     myLyingOnGeomPtr->SetGeom( aLocShape );
1221     TPythonDump()<<this<<".SetGeom("<<theGeom<<")";
1222   }
1223
1224   void LyingOnGeom_i::SetGeom( const TopoDS_Shape& theShape )
1225   {
1226     myLyingOnGeomPtr->SetGeom( theShape );
1227   }
1228
1229   void LyingOnGeom_i::SetElementType(ElementType theType){
1230     myLyingOnGeomPtr->SetType(SMDSAbs_ElementType(theType));
1231     TPythonDump()<<this<<".SetElementType("<<theType<<")";
1232   }
1233
1234   FunctorType LyingOnGeom_i::GetFunctorType()
1235   {
1236     return SMESH::FT_LyingOnGeom;
1237   }
1238
1239   void LyingOnGeom_i::SetShapeName( const char* theName )
1240   {
1241     CORBA::string_free( myShapeName );
1242     myShapeName = CORBA::string_dup( theName );
1243     myLyingOnGeomPtr->SetGeom( getShapeByName( myShapeName ) );
1244     TPythonDump()<<this<<".SetShapeName('"<<theName<<"')";
1245   }
1246
1247   void LyingOnGeom_i::SetShape( const char* theID, const char* theName )
1248   {
1249     CORBA::string_free( myShapeName );
1250     CORBA::string_free( myShapeID   );
1251     myShapeName = CORBA::string_dup( theName );
1252     myShapeID   = CORBA::string_dup( theID   );
1253     bool hasName = ( theName && theName[0] );
1254     bool hasID   = ( theID   && theID[0]   );
1255
1256     TopoDS_Shape S;
1257     if ( hasName && hasID )
1258     {
1259       S = getShapeByID( myShapeID );
1260       if ( S.IsNull() )
1261         S = getShapeByName( myShapeName );
1262     }
1263     else
1264     {
1265       S = hasID ? getShapeByID( myShapeID ) : getShapeByName( myShapeName );
1266     }
1267     myLyingOnGeomPtr->SetGeom( S );
1268   }
1269
1270   char* LyingOnGeom_i::GetShapeName()
1271   {
1272     return CORBA::string_dup( myShapeName );
1273   }
1274
1275   char* LyingOnGeom_i::GetShapeID()
1276   {
1277     return CORBA::string_dup( myShapeID );
1278   }
1279
1280   void LyingOnGeom_i::SetTolerance( CORBA::Double theToler )
1281   {
1282     myLyingOnGeomPtr->SetTolerance( theToler );
1283     TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
1284   }
1285
1286   CORBA::Double LyingOnGeom_i::GetTolerance()
1287   {
1288     return myLyingOnGeomPtr->GetTolerance();
1289   }
1290
1291   /*
1292     Class       : FreeBorders_i
1293     Description : Predicate for free borders
1294   */
1295   FreeBorders_i::FreeBorders_i()
1296   {
1297     myPredicatePtr.reset(new Controls::FreeBorders());
1298     myFunctorPtr = myPredicatePtr;
1299   }
1300
1301   FunctorType FreeBorders_i::GetFunctorType()
1302   {
1303     return SMESH::FT_FreeBorders;
1304   }
1305
1306   /*
1307     Class       : FreeEdges_i
1308     Description : Predicate for free borders
1309   */
1310   FreeEdges_i::FreeEdges_i()
1311   : myFreeEdgesPtr( new Controls::FreeEdges() )
1312   {
1313     myFunctorPtr = myPredicatePtr = myFreeEdgesPtr;
1314   }
1315
1316   SMESH::FreeEdges::Borders* FreeEdges_i::GetBorders()
1317   {
1318     SMESH::Controls::FreeEdges::TBorders aBorders;
1319     myFreeEdgesPtr->GetBoreders( aBorders );
1320
1321     long i = 0, iEnd = aBorders.size();
1322
1323     SMESH::FreeEdges::Borders_var aResult = new SMESH::FreeEdges::Borders;
1324     aResult->length(iEnd);
1325
1326     SMESH::Controls::FreeEdges::TBorders::const_iterator anIter;
1327     for ( anIter = aBorders.begin() ; anIter != aBorders.end(); anIter++, i++ )
1328     {
1329       const SMESH::Controls::FreeEdges::Border&  aBord = *anIter;
1330       SMESH::FreeEdges::Border &aBorder = aResult[ i ];
1331
1332       aBorder.myElemId = aBord.myElemId;
1333       aBorder.myPnt1 = aBord.myPntId[ 0 ];
1334       aBorder.myPnt2 = aBord.myPntId[ 1 ];
1335     }
1336     return aResult._retn();
1337   }
1338
1339   FunctorType FreeEdges_i::GetFunctorType()
1340   {
1341     return SMESH::FT_FreeEdges;
1342   }
1343
1344   /*
1345     Class       : FreeFaces_i
1346     Description : Predicate for free faces
1347   */
1348   FreeFaces_i::FreeFaces_i()
1349   {
1350     myPredicatePtr.reset(new Controls::FreeFaces());
1351     myFunctorPtr = myPredicatePtr;
1352   }
1353
1354   FunctorType FreeFaces_i::GetFunctorType()
1355   {
1356     return SMESH::FT_FreeFaces;
1357   }
1358
1359   /*
1360     Class       : FreeNodes_i
1361     Description : Predicate for free nodes
1362   */
1363   FreeNodes_i::FreeNodes_i()
1364   {
1365     myPredicatePtr.reset(new Controls::FreeNodes());
1366     myFunctorPtr = myPredicatePtr;
1367   }
1368
1369   FunctorType FreeNodes_i::GetFunctorType()
1370   {
1371     return SMESH::FT_FreeNodes;
1372   }
1373
1374   /*
1375     Class       : EqualNodes_i
1376     Description : Predicate for Equal nodes
1377   */
1378   EqualNodes_i::EqualNodes_i()
1379   {
1380     myCoincidentNodesPtr.reset(new Controls::CoincidentNodes());
1381     myFunctorPtr = myPredicatePtr = myCoincidentNodesPtr;
1382   }
1383
1384   FunctorType EqualNodes_i::GetFunctorType()
1385   {
1386     return SMESH::FT_EqualNodes;
1387   }
1388
1389   void EqualNodes_i::SetTolerance( double tol )
1390   {
1391     myCoincidentNodesPtr->SetTolerance( tol );
1392   }
1393
1394   double EqualNodes_i::GetTolerance()
1395   {
1396     return myCoincidentNodesPtr->GetTolerance();
1397   }
1398
1399   /*
1400     Class       : EqualEdges_i
1401     Description : Predicate for Equal Edges
1402   */
1403   EqualEdges_i::EqualEdges_i()
1404   {
1405     myPredicatePtr.reset(new Controls::CoincidentElements1D());
1406     myFunctorPtr = myPredicatePtr;
1407   }
1408
1409   FunctorType EqualEdges_i::GetFunctorType()
1410   {
1411     return SMESH::FT_EqualEdges;
1412   }
1413
1414   /*
1415     Class       : EqualFaces_i
1416     Description : Predicate for Equal Faces
1417   */
1418   EqualFaces_i::EqualFaces_i()
1419   {
1420     myPredicatePtr.reset(new Controls::CoincidentElements2D());
1421     myFunctorPtr = myPredicatePtr;
1422   }
1423
1424   FunctorType EqualFaces_i::GetFunctorType()
1425   {
1426     return SMESH::FT_EqualFaces;
1427   }
1428
1429   /*
1430     Class       : EqualVolumes_i
1431     Description : Predicate for Equal Volumes
1432   */
1433   EqualVolumes_i::EqualVolumes_i()
1434   {
1435     myPredicatePtr.reset(new Controls::CoincidentElements3D());
1436     myFunctorPtr = myPredicatePtr;
1437   }
1438
1439   FunctorType EqualVolumes_i::GetFunctorType()
1440   {
1441     return SMESH::FT_EqualVolumes;
1442   }
1443
1444
1445   /*
1446     Class       : RangeOfIds_i
1447     Description : Predicate for Range of Ids.
1448                   Range may be specified with two ways.
1449                   1. Using AddToRange method
1450                   2. With SetRangeStr method. Parameter of this method is a string
1451                      like as "1,2,3,50-60,63,67,70-"
1452   */
1453
1454   RangeOfIds_i::RangeOfIds_i()
1455   {
1456     myRangeOfIdsPtr.reset( new Controls::RangeOfIds() );
1457     myFunctorPtr = myPredicatePtr = myRangeOfIdsPtr;
1458   }
1459
1460   void RangeOfIds_i::SetRange( const SMESH::smIdType_array& theIds )
1461   {
1462     SMESH::smIdType iEnd = theIds.length();
1463     for ( SMESH::smIdType i = 0; i < iEnd; i++ )
1464       myRangeOfIdsPtr->AddToRange( theIds[ i ] );
1465     TPythonDump()<<this<<".SetRange("<<theIds<<")";
1466   }
1467
1468   CORBA::Boolean RangeOfIds_i::SetRangeStr( const char* theRange )
1469   {
1470     TPythonDump()<<this<<".SetRangeStr('"<<theRange<<"')";
1471     return myRangeOfIdsPtr->SetRangeStr(
1472       TCollection_AsciiString( (Standard_CString)theRange ) );
1473   }
1474
1475   char* RangeOfIds_i::GetRangeStr()
1476   {
1477     TCollection_AsciiString aStr;
1478     myRangeOfIdsPtr->GetRangeStr( aStr );
1479     return CORBA::string_dup( aStr.ToCString() );
1480   }
1481
1482   void RangeOfIds_i::SetElementType( ElementType theType )
1483   {
1484     myRangeOfIdsPtr->SetType( SMDSAbs_ElementType( theType ) );
1485     TPythonDump()<<this<<".SetElementType("<<theType<<")";
1486   }
1487
1488   FunctorType RangeOfIds_i::GetFunctorType()
1489   {
1490     return SMESH::FT_RangeOfIds;
1491   }
1492
1493   /*
1494     Class       : LinearOrQuadratic_i
1495     Description : Predicate to verify whether a mesh element is linear
1496   */
1497   LinearOrQuadratic_i::LinearOrQuadratic_i()
1498   {
1499     myLinearOrQuadraticPtr.reset(new Controls::LinearOrQuadratic());
1500     myFunctorPtr = myPredicatePtr = myLinearOrQuadraticPtr;
1501   }
1502
1503   void LinearOrQuadratic_i::SetElementType(ElementType theType)
1504   {
1505     myLinearOrQuadraticPtr->SetType(SMDSAbs_ElementType(theType));
1506     TPythonDump()<<this<<".SetElementType("<<theType<<")";
1507   }
1508
1509   FunctorType LinearOrQuadratic_i::GetFunctorType()
1510   {
1511     return SMESH::FT_LinearOrQuadratic;
1512   }
1513
1514   /*
1515     Class       : GroupColor_i
1516     Description : Functor for check color of group to which mesh element belongs to
1517   */
1518   GroupColor_i::GroupColor_i()
1519   {
1520     myGroupColorPtr.reset(new Controls::GroupColor());
1521     myFunctorPtr = myPredicatePtr = myGroupColorPtr;
1522   }
1523
1524   FunctorType GroupColor_i::GetFunctorType()
1525   {
1526     return SMESH::FT_GroupColor;
1527   }
1528
1529   void GroupColor_i::SetColorStr( const char* theColor )
1530   {
1531     myGroupColorPtr->SetColorStr(
1532       TCollection_AsciiString( (Standard_CString)theColor ) );
1533     TPythonDump()<<this<<".SetColorStr('"<<theColor<<"')";
1534   }
1535
1536   char* GroupColor_i::GetColorStr()
1537   {
1538     TCollection_AsciiString aStr;
1539     myGroupColorPtr->GetColorStr( aStr );
1540     return CORBA::string_dup( aStr.ToCString() );
1541   }
1542
1543   void GroupColor_i::SetElementType(ElementType theType)
1544   {
1545     myGroupColorPtr->SetType(SMDSAbs_ElementType(theType));
1546     TPythonDump()<<this<<".SetElementType("<<theType<<")";
1547   }
1548
1549   /*
1550     Class       : ElemGeomType_i
1551     Description : Predicate check is element has indicated geometry type
1552   */
1553   ElemGeomType_i::ElemGeomType_i()
1554   {
1555     myElemGeomTypePtr.reset(new Controls::ElemGeomType());
1556     myFunctorPtr = myPredicatePtr = myElemGeomTypePtr;
1557   }
1558
1559   void ElemGeomType_i::SetElementType(ElementType theType)
1560   {
1561     myElemGeomTypePtr->SetType(SMDSAbs_ElementType(theType));
1562     TPythonDump()<<this<<".SetElementType("<<theType<<")";
1563   }
1564
1565   void ElemGeomType_i::SetGeometryType(GeometryType theType)
1566   {
1567     myElemGeomTypePtr->SetGeomType(SMDSAbs_GeometryType(theType));
1568     TPythonDump()<<this<<".SetGeometryType("<<theType<<")";
1569   }
1570
1571   GeometryType ElemGeomType_i::GetGeometryType() const
1572   {
1573     return (GeometryType)myElemGeomTypePtr->GetGeomType();
1574   }
1575
1576   FunctorType ElemGeomType_i::GetFunctorType()
1577   {
1578     return SMESH::FT_ElemGeomType;
1579   }
1580
1581   /*
1582     Class       : ElemEntityType_i
1583     Description : Predicate check is element has indicated entity type
1584   */
1585   ElemEntityType_i::ElemEntityType_i()
1586   {
1587     myElemEntityTypePtr.reset(new Controls::ElemEntityType());
1588     myFunctorPtr = myPredicatePtr = myElemEntityTypePtr;
1589   }
1590
1591   void ElemEntityType_i::SetElementType(ElementType theType)
1592   {
1593     myElemEntityTypePtr->SetType(SMDSAbs_ElementType(theType));
1594     TPythonDump()<<this<<".SetElementType("<<theType<<")";
1595   }
1596
1597   void ElemEntityType_i::SetEntityType(EntityType theEntityType)
1598   {
1599     myElemEntityTypePtr->SetElemEntityType(SMDSAbs_EntityType (theEntityType));
1600     TPythonDump()<<this<<".SetEntityType("<<theEntityType<<")";
1601   }
1602   EntityType ElemEntityType_i::GetEntityType() const
1603   {
1604    return (EntityType) myElemEntityTypePtr->GetElemEntityType();
1605   }
1606
1607   FunctorType ElemEntityType_i::GetFunctorType()
1608   {
1609     return SMESH::FT_EntityType;
1610   }
1611
1612   /*
1613     Class       : CoplanarFaces_i
1614     Description : Returns true if a mesh face is a coplanar neighbour to a given one
1615   */
1616   CoplanarFaces_i::CoplanarFaces_i()
1617   {
1618     myCoplanarFacesPtr.reset(new Controls::CoplanarFaces());
1619     myFunctorPtr = myPredicatePtr = myCoplanarFacesPtr;
1620   }
1621
1622   void CoplanarFaces_i::SetFace ( CORBA::Long theFaceID )
1623   {
1624     myCoplanarFacesPtr->SetFace(theFaceID);
1625     TPythonDump()<<this<<".SetFace("<<theFaceID<<")";
1626   }
1627
1628   void CoplanarFaces_i::SetTolerance( CORBA::Double theToler )
1629   {
1630     myCoplanarFacesPtr->SetTolerance(theToler);
1631     TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
1632   }
1633
1634   CORBA::Long CoplanarFaces_i::GetFace () const
1635   {
1636     return myCoplanarFacesPtr->GetFace();
1637   }
1638
1639   char* CoplanarFaces_i::GetFaceAsString () const
1640   {
1641     TCollection_AsciiString str(Standard_Integer(myCoplanarFacesPtr->GetFace()));
1642     return CORBA::string_dup( str.ToCString() );
1643   }
1644
1645   CORBA::Double CoplanarFaces_i::GetTolerance() const
1646   {
1647     return myCoplanarFacesPtr->GetTolerance();
1648   }
1649
1650   FunctorType CoplanarFaces_i::GetFunctorType()
1651   {
1652     return SMESH::FT_CoplanarFaces;
1653   }
1654
1655   /*
1656    * Class       : ConnectedElements_i
1657    * Description : Returns true if an element is connected via other elements to the element
1658    *               located at a given point.
1659    */
1660   ConnectedElements_i::ConnectedElements_i()
1661   {
1662     myConnectedElementsPtr.reset(new Controls::ConnectedElements());
1663     myFunctorPtr = myPredicatePtr = myConnectedElementsPtr;
1664   }
1665
1666   FunctorType ConnectedElements_i::GetFunctorType()
1667   {
1668     return FT_ConnectedElements;
1669   }
1670
1671   void ConnectedElements_i::SetElementType( ElementType theType )
1672   {
1673     myConnectedElementsPtr->SetType( SMDSAbs_ElementType( theType ));
1674     TPythonDump() << this << ".SetElementType( " << theType << " )";
1675   }
1676
1677   void ConnectedElements_i::SetPoint( CORBA::Double x, CORBA::Double y, CORBA::Double z )
1678   {
1679     myConnectedElementsPtr->SetPoint( x,y,z );
1680     myVertexID.clear();
1681     TPythonDump() << this << ".SetPoint( " << x << ", " << y << ", " << z << " )";
1682   }
1683
1684   void ConnectedElements_i::SetVertex( GEOM::GEOM_Object_ptr vertex )
1685   {
1686     TopoDS_Shape shape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( vertex );
1687     if ( shape.IsNull() )
1688       THROW_SALOME_CORBA_EXCEPTION( "ConnectedElements_i::SetVertex(): NULL Vertex",
1689                                     SALOME::BAD_PARAM );
1690
1691     TopExp_Explorer v( shape, TopAbs_VERTEX );
1692     if ( !v.More() )
1693       THROW_SALOME_CORBA_EXCEPTION( "ConnectedElements_i::SetVertex(): empty vertex",
1694                                     SALOME::BAD_PARAM );
1695
1696     gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( v.Current() ));
1697     myConnectedElementsPtr->SetPoint( p.X(), p.Y(), p.Z() );
1698     //
1699     CORBA::String_var id = vertex->GetStudyEntry();
1700     myVertexID = id.in();
1701
1702     TPythonDump() << this << ".SetVertex( " << vertex << " )";
1703   }
1704
1705   void ConnectedElements_i::SetNode ( SMESH::smIdType nodeID )
1706   {
1707     if ( nodeID < 1 )
1708       THROW_SALOME_CORBA_EXCEPTION( "ConnectedElements_i::SetNode(): nodeID must be > 0",
1709                                     SALOME::BAD_PARAM );
1710
1711     myConnectedElementsPtr->SetNode( nodeID );
1712     myVertexID.clear();
1713     TPythonDump() << this << ".SetNode( " << nodeID << " )";
1714   }
1715
1716   /*!
1717    * \brief This is a comfort method for Filter dialog
1718    */
1719   void ConnectedElements_i::SetThreshold ( const char*                             threshold,
1720                                            SMESH::ConnectedElements::ThresholdType type )
1721   {
1722     if ( !threshold )
1723       THROW_SALOME_CORBA_EXCEPTION( "ConnectedElements_i::SetThreshold(): NULL threshold",
1724                                     SALOME::BAD_PARAM );
1725     switch ( type )
1726     {
1727     case SMESH::ConnectedElements::POINT: // read 3 node coordinates ///////////////////
1728       {
1729         std::vector< double > xyz;
1730         char* endptr;
1731         do
1732         {
1733           // skip a separator
1734           while ( *threshold &&
1735                   *threshold != '+' &&
1736                   *threshold != '-' &&
1737                   !isdigit( *threshold ))
1738             ++threshold;
1739           if ( !*threshold )
1740             break;
1741           // read a coordinate
1742           xyz.push_back( strtod( threshold, &endptr ));
1743           if ( threshold == endptr )
1744           {
1745             xyz.resize( xyz.size() - 1 );
1746             break;
1747           }
1748           threshold = endptr;
1749         }
1750         while ( xyz.size() < 3 );
1751
1752         if ( xyz.size() < 3 )
1753           THROW_SALOME_CORBA_EXCEPTION
1754             ( "ConnectedElements_i::SetThreshold(): invalid point coordinates", SALOME::BAD_PARAM );
1755
1756         SetPoint( xyz[0], xyz[1], xyz[2] );
1757         break;
1758       }
1759     case SMESH::ConnectedElements::VERTEX: // get a VERTEX by its entry /////////////////
1760       {
1761         SALOMEDS::SObject_wrap sobj = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectID( threshold );
1762         if ( sobj->_is_nil() )
1763           THROW_SALOME_CORBA_EXCEPTION
1764             ( "ConnectedElements_i::SetThreshold(): invalid vertex study entry", SALOME::BAD_PARAM );
1765         CORBA::Object_var        obj = sobj->GetObject();
1766         GEOM::GEOM_Object_var vertex = GEOM::GEOM_Object::_narrow( obj );
1767         if ( vertex->_is_nil() )
1768           THROW_SALOME_CORBA_EXCEPTION
1769             ( "ConnectedElements_i::SetThreshold(): no GEOM_Object in SObject", SALOME::BAD_PARAM );
1770         SetVertex( vertex );
1771         break;
1772       }
1773     case SMESH::ConnectedElements::NODE: // read a node ID ////////////////////////////
1774       {
1775         char* endptr;
1776         int id = strtol( threshold, &endptr, 10 );
1777         if ( threshold == endptr )
1778           THROW_SALOME_CORBA_EXCEPTION
1779             ( "ConnectedElements_i::SetThreshold(): invalid node ID", SALOME::BAD_PARAM );
1780         SetNode( id );
1781         break;
1782       }
1783     default:
1784       THROW_SALOME_CORBA_EXCEPTION
1785         ( "ConnectedElements_i::SetThreshold(): invalid ThresholdType", SALOME::BAD_PARAM );
1786     }
1787   }
1788
1789   char* ConnectedElements_i::GetThreshold ( SMESH::ConnectedElements::ThresholdType& type )
1790   {
1791     std::string threshold;
1792     if ( !myVertexID.empty() )
1793     {
1794       threshold = myVertexID;
1795       type      = SMESH::ConnectedElements::VERTEX;
1796     }
1797     else
1798     {
1799       std::vector<double> xyz = myConnectedElementsPtr->GetPoint();
1800       if ( xyz.size() == 3 )
1801       {
1802         threshold = SMESH_Comment( xyz[0] ) << "; " << xyz[1] << "; " << xyz[2];
1803         type      = SMESH::ConnectedElements::POINT;
1804       }
1805       else
1806       {
1807         threshold = SMESH_Comment( myConnectedElementsPtr->GetNode() );
1808         type      = SMESH::ConnectedElements::NODE;
1809       }
1810     }
1811     return CORBA::string_dup( threshold.c_str() );
1812   }
1813
1814   /*
1815     Class       : Comparator_i
1816     Description : Base class for comparators
1817   */
1818   Comparator_i::Comparator_i():
1819     myNumericalFunctor( NULL )
1820   {}
1821
1822   Comparator_i::~Comparator_i()
1823   {
1824     if ( myNumericalFunctor )
1825       myNumericalFunctor->UnRegister();
1826   }
1827
1828   void Comparator_i::SetMargin( CORBA::Double theValue )
1829   {
1830     myComparatorPtr->SetMargin( theValue );
1831     TPythonDump()<<this<<".SetMargin("<<theValue<<")";
1832   }
1833
1834   CORBA::Double Comparator_i::GetMargin()
1835   {
1836     return myComparatorPtr->GetMargin();
1837   }
1838
1839   void Comparator_i::SetNumFunctor( NumericalFunctor_ptr theFunct )
1840   {
1841     if ( myNumericalFunctor )
1842       myNumericalFunctor->UnRegister();
1843
1844     myNumericalFunctor = DownCast<NumericalFunctor_i*>(theFunct);
1845
1846     if ( myNumericalFunctor )
1847     {
1848       myComparatorPtr->SetNumFunctor( myNumericalFunctor->GetNumericalFunctor() );
1849       myNumericalFunctor->Register();
1850       TPythonDump()<<this<<".SetNumFunctor("<<myNumericalFunctor<<")";
1851     }
1852   }
1853
1854   Controls::ComparatorPtr Comparator_i::GetComparator()
1855   {
1856     return myComparatorPtr;
1857   }
1858
1859   NumericalFunctor_i* Comparator_i::GetNumFunctor_i()
1860   {
1861     return myNumericalFunctor;
1862   }
1863
1864
1865   /*
1866     Class       : LessThan_i
1867     Description : Comparator "<"
1868   */
1869   LessThan_i::LessThan_i()
1870   {
1871     myComparatorPtr.reset( new Controls::LessThan() );
1872     myFunctorPtr = myPredicatePtr = myComparatorPtr;
1873   }
1874
1875   FunctorType LessThan_i::GetFunctorType()
1876   {
1877     return SMESH::FT_LessThan;
1878   }
1879
1880
1881   /*
1882     Class       : MoreThan_i
1883     Description : Comparator ">"
1884   */
1885   MoreThan_i::MoreThan_i()
1886   {
1887     myComparatorPtr.reset( new Controls::MoreThan() );
1888     myFunctorPtr = myPredicatePtr = myComparatorPtr;
1889   }
1890
1891   FunctorType MoreThan_i::GetFunctorType()
1892   {
1893     return SMESH::FT_MoreThan;
1894   }
1895
1896
1897   /*
1898     Class       : EqualTo_i
1899     Description : Comparator "="
1900   */
1901   EqualTo_i::EqualTo_i()
1902   : myEqualToPtr( new Controls::EqualTo() )
1903   {
1904     myFunctorPtr = myPredicatePtr = myComparatorPtr = myEqualToPtr;
1905   }
1906
1907   void EqualTo_i::SetTolerance( CORBA::Double theToler )
1908   {
1909     myEqualToPtr->SetTolerance( theToler );
1910     TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
1911   }
1912
1913   CORBA::Double EqualTo_i::GetTolerance()
1914   {
1915     return myEqualToPtr->GetTolerance();
1916   }
1917
1918   FunctorType EqualTo_i::GetFunctorType()
1919   {
1920     return SMESH::FT_EqualTo;
1921   }
1922
1923   /*
1924     Class       : LogicalNOT_i
1925     Description : Logical NOT predicate
1926   */
1927   LogicalNOT_i::LogicalNOT_i():
1928     myLogicalNOTPtr( new Controls::LogicalNOT() ),
1929     myPredicate( NULL )
1930   {
1931     myFunctorPtr = myPredicatePtr = myLogicalNOTPtr;
1932   }
1933
1934   LogicalNOT_i::~LogicalNOT_i()
1935   {
1936     if ( myPredicate )
1937       myPredicate->UnRegister();
1938   }
1939
1940   void LogicalNOT_i::SetPredicate( Predicate_ptr thePredicate )
1941   {
1942     if ( myPredicate )
1943       myPredicate->UnRegister();
1944
1945     myPredicate = SMESH::GetPredicate(thePredicate);
1946
1947     if ( myPredicate ){
1948       myLogicalNOTPtr->SetPredicate(myPredicate->GetPredicate());
1949       myPredicate->Register();
1950       TPythonDump()<<this<<".SetPredicate("<<myPredicate<<")";
1951     }
1952   }
1953
1954   FunctorType LogicalNOT_i::GetFunctorType()
1955   {
1956     return SMESH::FT_LogicalNOT;
1957   }
1958
1959   Predicate_i* LogicalNOT_i::GetPredicate_i()
1960   {
1961     return myPredicate;
1962   }
1963
1964
1965
1966   /*
1967     Class       : LogicalBinary_i
1968     Description : Base class for binary logical predicate
1969   */
1970   LogicalBinary_i::LogicalBinary_i()
1971   : myPredicate1( NULL ),
1972     myPredicate2( NULL )
1973   {}
1974
1975   LogicalBinary_i::~LogicalBinary_i()
1976   {
1977     if ( myPredicate1 )
1978       myPredicate1->UnRegister();
1979
1980     if ( myPredicate2 )
1981       myPredicate2->UnRegister();
1982   }
1983
1984   void LogicalBinary_i::SetMesh( SMESH_Mesh_ptr theMesh )
1985   {
1986     if ( myPredicate1 )
1987       myPredicate1->SetMesh( theMesh );
1988
1989     if ( myPredicate2 )
1990       myPredicate2->SetMesh( theMesh );
1991   }
1992
1993   void LogicalBinary_i::SetPredicate1( Predicate_ptr thePredicate )
1994   {
1995     if ( myPredicate1 )
1996       myPredicate1->UnRegister();
1997
1998     myPredicate1 = SMESH::GetPredicate(thePredicate);
1999
2000     if ( myPredicate1 ){
2001       myLogicalBinaryPtr->SetPredicate1(myPredicate1->GetPredicate());
2002       myPredicate1->Register();
2003       TPythonDump()<<this<<".SetPredicate1("<<myPredicate1<<")";
2004     }
2005   }
2006
2007   void LogicalBinary_i::SetPredicate2( Predicate_ptr thePredicate )
2008   {
2009     if ( myPredicate2 )
2010       myPredicate2->UnRegister();
2011
2012     myPredicate2 = SMESH::GetPredicate(thePredicate);
2013
2014     if ( myPredicate2 ){
2015       myLogicalBinaryPtr->SetPredicate2(myPredicate2->GetPredicate());
2016       myPredicate2->Register();
2017       TPythonDump()<<this<<".SetPredicate2("<<myPredicate2<<")";
2018     }
2019   }
2020
2021   Controls::LogicalBinaryPtr LogicalBinary_i::GetLogicalBinary()
2022   {
2023     return myLogicalBinaryPtr;
2024   }
2025
2026   Predicate_i* LogicalBinary_i::GetPredicate1_i()
2027   {
2028     return myPredicate1;
2029   }
2030   Predicate_i* LogicalBinary_i::GetPredicate2_i()
2031   {
2032     return myPredicate2;
2033   }
2034
2035
2036   /*
2037     Class       : LogicalAND_i
2038     Description : Logical AND
2039   */
2040   LogicalAND_i::LogicalAND_i()
2041   {
2042     myLogicalBinaryPtr.reset( new Controls::LogicalAND() );
2043     myFunctorPtr = myPredicatePtr = myLogicalBinaryPtr;
2044   }
2045
2046   FunctorType LogicalAND_i::GetFunctorType()
2047   {
2048     return SMESH::FT_LogicalAND;
2049   }
2050
2051
2052   /*
2053     Class       : LogicalOR_i
2054     Description : Logical OR
2055   */
2056   LogicalOR_i::LogicalOR_i()
2057   {
2058     myLogicalBinaryPtr.reset( new Controls::LogicalOR() );
2059     myFunctorPtr = myPredicatePtr = myLogicalBinaryPtr;
2060   }
2061
2062   FunctorType LogicalOR_i::GetFunctorType()
2063   {
2064     return SMESH::FT_LogicalOR;
2065   }
2066
2067
2068   /*
2069                               FILTER MANAGER
2070   */
2071
2072   FilterManager_i::FilterManager_i()
2073   : SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
2074   {
2075     //Base class Salome_GenericObject do it inmplicitly by overriding PortableServer::POA_ptr _default_POA() method
2076     //PortableServer::ObjectId_var anObjectId =
2077     //  SMESH_Gen_i::GetPOA()->activate_object( this );
2078   }
2079
2080
2081   FilterManager_i::~FilterManager_i()
2082   {
2083     //TPythonDump()<<this<<".UnRegister()";
2084   }
2085
2086
2087   MinimumAngle_ptr FilterManager_i::CreateMinimumAngle()
2088   {
2089     SMESH::MinimumAngle_i* aServant = new SMESH::MinimumAngle_i();
2090     SMESH::MinimumAngle_var anObj = aServant->_this();
2091     TPythonDump()<<aServant<<" = "<<this<<".CreateMinimumAngle()";
2092     return anObj._retn();
2093   }
2094
2095
2096   AspectRatio_ptr FilterManager_i::CreateAspectRatio()
2097   {
2098     SMESH::AspectRatio_i* aServant = new SMESH::AspectRatio_i();
2099     SMESH::AspectRatio_var anObj = aServant->_this();
2100     TPythonDump()<<aServant<<" = "<<this<<".CreateAspectRatio()";
2101     return anObj._retn();
2102   }
2103
2104
2105   AspectRatio3D_ptr FilterManager_i::CreateAspectRatio3D()
2106   {
2107     SMESH::AspectRatio3D_i* aServant = new SMESH::AspectRatio3D_i();
2108     SMESH::AspectRatio3D_var anObj = aServant->_this();
2109     TPythonDump()<<aServant<<" = "<<this<<".CreateAspectRatio3D()";
2110     return anObj._retn();
2111   }
2112
2113
2114   Warping_ptr FilterManager_i::CreateWarping()
2115   {
2116     SMESH::Warping_i* aServant = new SMESH::Warping_i();
2117     SMESH::Warping_var anObj = aServant->_this();
2118     TPythonDump()<<aServant<<" = "<<this<<".CreateWarping()";
2119     return anObj._retn();
2120   }
2121
2122
2123   Warping3D_ptr FilterManager_i::CreateWarping3D()
2124   {
2125     SMESH::Warping3D_i* aServant = new SMESH::Warping3D_i();
2126     SMESH::Warping3D_var anObj = aServant->_this();
2127     TPythonDump() << aServant << " = " << this << ".CreateWarping3D()";
2128     return anObj._retn();
2129   }
2130
2131   Taper_ptr FilterManager_i::CreateTaper()
2132   {
2133     SMESH::Taper_i* aServant = new SMESH::Taper_i();
2134     SMESH::Taper_var anObj = aServant->_this();
2135     TPythonDump()<<aServant<<" = "<<this<<".CreateTaper()";
2136     return anObj._retn();
2137   }
2138
2139
2140   Skew_ptr FilterManager_i::CreateSkew()
2141   {
2142     SMESH::Skew_i* aServant = new SMESH::Skew_i();
2143     SMESH::Skew_var anObj = aServant->_this();
2144     TPythonDump()<<aServant<<" = "<<this<<".CreateSkew()";
2145     return anObj._retn();
2146   }
2147
2148
2149   Area_ptr FilterManager_i::CreateArea()
2150   {
2151     SMESH::Area_i* aServant = new SMESH::Area_i();
2152     SMESH::Area_var anObj = aServant->_this();
2153     TPythonDump()<<aServant<<" = "<<this<<".CreateArea()";
2154     return anObj._retn();
2155   }
2156
2157
2158   Volume3D_ptr FilterManager_i::CreateVolume3D()
2159   {
2160     SMESH::Volume3D_i* aServant = new SMESH::Volume3D_i();
2161     SMESH::Volume3D_var anObj = aServant->_this();
2162     TPythonDump()<<aServant<<" = "<<this<<".CreateVolume3D()";
2163     return anObj._retn();
2164   }
2165
2166   ScaledJacobian_ptr FilterManager_i::CreateScaledJacobian()
2167   {
2168     SMESH::ScaledJacobian_i* aServant = new SMESH::ScaledJacobian_i();
2169     SMESH::ScaledJacobian_var anObj   = aServant->_this();
2170     TPythonDump()<<aServant<<" = "<<this<<".CreateScaledJacobian()";
2171     return anObj._retn();
2172   }
2173
2174   MaxElementLength2D_ptr FilterManager_i::CreateMaxElementLength2D()
2175   {
2176     SMESH::MaxElementLength2D_i* aServant = new SMESH::MaxElementLength2D_i();
2177     SMESH::MaxElementLength2D_var anObj = aServant->_this();
2178     TPythonDump()<<aServant<<" = "<<this<<".CreateMaxElementLength2D()";
2179     return anObj._retn();
2180   }
2181
2182
2183   MaxElementLength3D_ptr FilterManager_i::CreateMaxElementLength3D()
2184   {
2185     SMESH::MaxElementLength3D_i* aServant = new SMESH::MaxElementLength3D_i();
2186     SMESH::MaxElementLength3D_var anObj = aServant->_this();
2187     TPythonDump()<<aServant<<" = "<<this<<".CreateMaxElementLength3D()";
2188     return anObj._retn();
2189   }
2190
2191
2192   Length_ptr FilterManager_i::CreateLength()
2193   {
2194     SMESH::Length_i* aServant = new SMESH::Length_i();
2195     SMESH::Length_var anObj = aServant->_this();
2196     TPythonDump()<<aServant<<" = "<<this<<".CreateLength()";
2197     return anObj._retn();
2198   }
2199
2200   Length2D_ptr FilterManager_i::CreateLength2D()
2201   {
2202     SMESH::Length2D_i* aServant = new SMESH::Length2D_i();
2203     SMESH::Length2D_var anObj = aServant->_this();
2204     TPythonDump()<<aServant<<" = "<<this<<".CreateLength2D()";
2205     return anObj._retn();
2206   }
2207
2208   Length3D_ptr FilterManager_i::CreateLength3D()
2209   {
2210     SMESH::Length3D_i* aServant = new SMESH::Length3D_i();
2211     SMESH::Length3D_var anObj = aServant->_this();
2212     TPythonDump()<<aServant<<" = "<<this<<".CreateLength3D()";
2213     return anObj._retn();
2214   }
2215
2216   Deflection2D_ptr FilterManager_i::CreateDeflection2D()
2217   {
2218     SMESH::Deflection2D_i* aServant = new SMESH::Deflection2D_i();
2219     SMESH::Deflection2D_var   anObj = aServant->_this();
2220     TPythonDump()<<aServant<<" = "<<this<<".CreateDeflection2D()";
2221     return anObj._retn();
2222   }
2223
2224   MultiConnection_ptr FilterManager_i::CreateMultiConnection()
2225   {
2226     SMESH::MultiConnection_i* aServant = new SMESH::MultiConnection_i();
2227     SMESH::MultiConnection_var anObj = aServant->_this();
2228     TPythonDump()<<aServant<<" = "<<this<<".CreateMultiConnection()";
2229     return anObj._retn();
2230   }
2231
2232   MultiConnection2D_ptr FilterManager_i::CreateMultiConnection2D()
2233   {
2234     SMESH::MultiConnection2D_i* aServant = new SMESH::MultiConnection2D_i();
2235     SMESH::MultiConnection2D_var anObj = aServant->_this();
2236     TPythonDump()<<aServant<<" = "<<this<<".CreateMultiConnection2D()";
2237     return anObj._retn();
2238   }
2239
2240   BallDiameter_ptr FilterManager_i::CreateBallDiameter()
2241   {
2242     SMESH::BallDiameter_i* aServant = new SMESH::BallDiameter_i();
2243     SMESH::BallDiameter_var anObj = aServant->_this();
2244     TPythonDump()<<aServant<<" = "<<this<<".CreateBallDiameter()";
2245     return anObj._retn();
2246   }
2247
2248   NodeConnectivityNumber_ptr FilterManager_i::CreateNodeConnectivityNumber()
2249   {
2250     SMESH::NodeConnectivityNumber_i* aServant = new SMESH::NodeConnectivityNumber_i();
2251     SMESH::NodeConnectivityNumber_var anObj = aServant->_this();
2252     TPythonDump()<<aServant<<" = "<<this<<".CreateNodeConnectivityNumber()";
2253     return anObj._retn();
2254   }
2255
2256   BelongToMeshGroup_ptr FilterManager_i::CreateBelongToMeshGroup()
2257   {
2258     SMESH::BelongToMeshGroup_i* aServant = new SMESH::BelongToMeshGroup_i();
2259     SMESH::BelongToMeshGroup_var anObj = aServant->_this();
2260     TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToMeshGroup()";
2261     return anObj._retn();
2262   }
2263
2264   BelongToGeom_ptr FilterManager_i::CreateBelongToGeom()
2265   {
2266     SMESH::BelongToGeom_i* aServant = new SMESH::BelongToGeom_i();
2267     SMESH::BelongToGeom_var anObj = aServant->_this();
2268     TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToGeom()";
2269     return anObj._retn();
2270   }
2271
2272   BelongToPlane_ptr FilterManager_i::CreateBelongToPlane()
2273   {
2274     SMESH::BelongToPlane_i* aServant = new SMESH::BelongToPlane_i();
2275     SMESH::BelongToPlane_var anObj = aServant->_this();
2276     TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToPlane()";
2277     return anObj._retn();
2278   }
2279
2280   BelongToCylinder_ptr FilterManager_i::CreateBelongToCylinder()
2281   {
2282     SMESH::BelongToCylinder_i* aServant = new SMESH::BelongToCylinder_i();
2283     SMESH::BelongToCylinder_var anObj = aServant->_this();
2284     TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToCylinder()";
2285     return anObj._retn();
2286   }
2287
2288   BelongToGenSurface_ptr FilterManager_i::CreateBelongToGenSurface()
2289   {
2290     SMESH::BelongToGenSurface_i* aServant = new SMESH::BelongToGenSurface_i();
2291     SMESH::BelongToGenSurface_var anObj = aServant->_this();
2292     TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToGenSurface()";
2293     return anObj._retn();
2294   }
2295
2296   LyingOnGeom_ptr FilterManager_i::CreateLyingOnGeom()
2297   {
2298     SMESH::LyingOnGeom_i* aServant = new SMESH::LyingOnGeom_i();
2299     SMESH::LyingOnGeom_var anObj = aServant->_this();
2300     TPythonDump()<<aServant<<" = "<<this<<".CreateLyingOnGeom()";
2301     return anObj._retn();
2302   }
2303
2304   CoplanarFaces_ptr FilterManager_i::CreateCoplanarFaces()
2305   {
2306     SMESH::CoplanarFaces_i* aServant = new SMESH::CoplanarFaces_i();
2307     SMESH::CoplanarFaces_var anObj = aServant->_this();
2308     TPythonDump()<<aServant<<" = "<<this<<".CreateCoplanarFaces()";
2309     return anObj._retn();
2310   }
2311
2312   ConnectedElements_ptr FilterManager_i::CreateConnectedElements()
2313   {
2314     SMESH::ConnectedElements_i* aServant = new SMESH::ConnectedElements_i();
2315     SMESH::ConnectedElements_var anObj = aServant->_this();
2316     TPythonDump()<<aServant<<" = "<<this<<".CreateConnectedElements()";
2317     return anObj._retn();
2318   }
2319
2320   FreeBorders_ptr FilterManager_i::CreateFreeBorders()
2321   {
2322     SMESH::FreeBorders_i* aServant = new SMESH::FreeBorders_i();
2323     SMESH::FreeBorders_var anObj = aServant->_this();
2324     TPythonDump()<<aServant<<" = "<<this<<".CreateFreeBorders()";
2325     return anObj._retn();
2326   }
2327
2328   FreeEdges_ptr FilterManager_i::CreateFreeEdges()
2329   {
2330     SMESH::FreeEdges_i* aServant = new SMESH::FreeEdges_i();
2331     SMESH::FreeEdges_var anObj = aServant->_this();
2332     TPythonDump()<<aServant<<" = "<<this<<".CreateFreeEdges()";
2333     return anObj._retn();
2334   }
2335
2336   FreeFaces_ptr FilterManager_i::CreateFreeFaces()
2337   {
2338     SMESH::FreeFaces_i* aServant = new SMESH::FreeFaces_i();
2339     SMESH::FreeFaces_var anObj = aServant->_this();
2340     TPythonDump()<<aServant<<" = "<<this<<".CreateFreeFaces()";
2341     return anObj._retn();
2342   }
2343
2344   FreeNodes_ptr FilterManager_i::CreateFreeNodes()
2345   {
2346     SMESH::FreeNodes_i* aServant = new SMESH::FreeNodes_i();
2347     SMESH::FreeNodes_var anObj = aServant->_this();
2348     TPythonDump()<<aServant<<" = "<<this<<".CreateFreeNodes()";
2349     return anObj._retn();
2350   }
2351
2352   EqualNodes_ptr FilterManager_i::CreateEqualNodes()
2353   {
2354     SMESH::EqualNodes_i* aServant = new SMESH::EqualNodes_i();
2355     SMESH::EqualNodes_var anObj = aServant->_this();
2356     TPythonDump()<<aServant<<" = "<<this<<".CreateEqualNodes()";
2357     return anObj._retn();
2358   }
2359
2360   EqualEdges_ptr FilterManager_i::CreateEqualEdges()
2361   {
2362     SMESH::EqualEdges_i* aServant = new SMESH::EqualEdges_i();
2363     SMESH::EqualEdges_var anObj = aServant->_this();
2364     TPythonDump()<<aServant<<" = "<<this<<".CreateEqualEdges()";
2365     return anObj._retn();
2366   }
2367   EqualFaces_ptr FilterManager_i::CreateEqualFaces()
2368   {
2369     SMESH::EqualFaces_i* aServant = new SMESH::EqualFaces_i();
2370     SMESH::EqualFaces_var anObj = aServant->_this();
2371     TPythonDump()<<aServant<<" = "<<this<<".CreateEqualFaces()";
2372     return anObj._retn();
2373   }
2374   EqualVolumes_ptr FilterManager_i::CreateEqualVolumes()
2375   {
2376     SMESH::EqualVolumes_i* aServant = new SMESH::EqualVolumes_i();
2377     SMESH::EqualVolumes_var anObj = aServant->_this();
2378     TPythonDump()<<aServant<<" = "<<this<<".CreateEqualVolumes()";
2379     return anObj._retn();
2380   }
2381
2382   RangeOfIds_ptr FilterManager_i::CreateRangeOfIds()
2383   {
2384     SMESH::RangeOfIds_i* aServant = new SMESH::RangeOfIds_i();
2385     SMESH::RangeOfIds_var anObj = aServant->_this();
2386     TPythonDump()<<aServant<<" = "<<this<<".CreateRangeOfIds()";
2387     return anObj._retn();
2388   }
2389
2390   BadOrientedVolume_ptr FilterManager_i::CreateBadOrientedVolume()
2391   {
2392     SMESH::BadOrientedVolume_i* aServant = new SMESH::BadOrientedVolume_i();
2393     SMESH::BadOrientedVolume_var anObj = aServant->_this();
2394     TPythonDump()<<aServant<<" = "<<this<<".CreateBadOrientedVolume()";
2395     return anObj._retn();
2396   }
2397
2398   BareBorderVolume_ptr FilterManager_i::CreateBareBorderVolume()
2399   {
2400     SMESH::BareBorderVolume_i* aServant = new SMESH::BareBorderVolume_i();
2401     SMESH::BareBorderVolume_var anObj = aServant->_this();
2402     TPythonDump()<<aServant<<" = "<<this<<".CreateBareBorderVolume()";
2403     return anObj._retn();
2404   }
2405
2406   BareBorderFace_ptr FilterManager_i::CreateBareBorderFace()
2407   {
2408     SMESH::BareBorderFace_i* aServant = new SMESH::BareBorderFace_i();
2409     SMESH::BareBorderFace_var anObj = aServant->_this();
2410     TPythonDump()<<aServant<<" = "<<this<<".CreateBareBorderFace()";
2411     return anObj._retn();
2412   }
2413
2414   OverConstrainedVolume_ptr FilterManager_i::CreateOverConstrainedVolume()
2415   {
2416     SMESH::OverConstrainedVolume_i* aServant = new SMESH::OverConstrainedVolume_i();
2417     SMESH::OverConstrainedVolume_var anObj = aServant->_this();
2418     TPythonDump()<<aServant<<" = "<<this<<".CreateOverConstrainedVolume()";
2419     return anObj._retn();
2420   }
2421
2422   OverConstrainedFace_ptr FilterManager_i::CreateOverConstrainedFace()
2423   {
2424     SMESH::OverConstrainedFace_i* aServant = new SMESH::OverConstrainedFace_i();
2425     SMESH::OverConstrainedFace_var anObj = aServant->_this();
2426     TPythonDump()<<aServant<<" = "<<this<<".CreateOverConstrainedFace()";
2427     return anObj._retn();
2428   }
2429
2430   LessThan_ptr FilterManager_i::CreateLessThan()
2431   {
2432     SMESH::LessThan_i* aServant = new SMESH::LessThan_i();
2433     SMESH::LessThan_var anObj = aServant->_this();
2434     TPythonDump()<<aServant<<" = "<<this<<".CreateLessThan()";
2435     return anObj._retn();
2436   }
2437
2438   MoreThan_ptr FilterManager_i::CreateMoreThan()
2439   {
2440     SMESH::MoreThan_i* aServant = new SMESH::MoreThan_i();
2441     SMESH::MoreThan_var anObj = aServant->_this();
2442     TPythonDump()<<aServant<<" = "<<this<<".CreateMoreThan()";
2443     return anObj._retn();
2444   }
2445
2446   EqualTo_ptr FilterManager_i::CreateEqualTo()
2447   {
2448     SMESH::EqualTo_i* aServant = new SMESH::EqualTo_i();
2449     SMESH::EqualTo_var anObj = aServant->_this();
2450     TPythonDump()<<aServant<<" = "<<this<<".CreateEqualTo()";
2451     return anObj._retn();
2452   }
2453
2454   LogicalNOT_ptr FilterManager_i::CreateLogicalNOT()
2455   {
2456     SMESH::LogicalNOT_i* aServant = new SMESH::LogicalNOT_i();
2457     SMESH::LogicalNOT_var anObj = aServant->_this();
2458     TPythonDump()<<aServant<<" = "<<this<<".CreateLogicalNOT()";
2459     return anObj._retn();
2460   }
2461
2462   LogicalAND_ptr FilterManager_i::CreateLogicalAND()
2463   {
2464     SMESH::LogicalAND_i* aServant = new SMESH::LogicalAND_i();
2465     SMESH::LogicalAND_var anObj = aServant->_this();
2466     TPythonDump()<<aServant<<" = "<<this<<".CreateLogicalAND()";
2467     return anObj._retn();
2468   }
2469
2470   LogicalOR_ptr FilterManager_i::CreateLogicalOR()
2471   {
2472     SMESH::LogicalOR_i* aServant = new SMESH::LogicalOR_i();
2473     SMESH::LogicalOR_var anObj = aServant->_this();
2474     TPythonDump()<<aServant<<" = "<<this<<".CreateLogicalOR()";
2475     return anObj._retn();
2476   }
2477
2478   LinearOrQuadratic_ptr FilterManager_i::CreateLinearOrQuadratic()
2479   {
2480     SMESH::LinearOrQuadratic_i* aServant = new SMESH::LinearOrQuadratic_i();
2481     SMESH::LinearOrQuadratic_var anObj = aServant->_this();
2482     TPythonDump()<<aServant<<" = "<<this<<".CreateLinearOrQuadratic()";
2483     return anObj._retn();
2484   }
2485
2486   GroupColor_ptr FilterManager_i::CreateGroupColor()
2487   {
2488     SMESH::GroupColor_i* aServant = new SMESH::GroupColor_i();
2489     SMESH::GroupColor_var anObj = aServant->_this();
2490     TPythonDump()<<aServant<<" = "<<this<<".CreateGroupColor()";
2491     return anObj._retn();
2492   }
2493
2494   ElemGeomType_ptr FilterManager_i::CreateElemGeomType()
2495   {
2496     SMESH::ElemGeomType_i* aServant = new SMESH::ElemGeomType_i();
2497     SMESH::ElemGeomType_var anObj = aServant->_this();
2498     TPythonDump()<<aServant<<" = "<<this<<".CreateElemGeomType()";
2499     return anObj._retn();
2500   }
2501
2502   ElemEntityType_ptr FilterManager_i::CreateElemEntityType()
2503   {
2504     SMESH::ElemEntityType_i* aServant = new SMESH::ElemEntityType_i();
2505     SMESH::ElemEntityType_var anObj = aServant->_this();
2506     TPythonDump()<<aServant<<" = "<<this<<".CreateElemEntityType()";
2507     return anObj._retn();
2508   }
2509
2510   Filter_ptr FilterManager_i::CreateFilter()
2511   {
2512     SMESH::Filter_i* aServant = new SMESH::Filter_i();
2513     SMESH::Filter_var anObj = aServant->_this();
2514     TPythonDump()<<aServant<<" = "<<this<<".CreateFilter()";
2515     return anObj._retn();
2516   }
2517
2518   FilterLibrary_ptr FilterManager_i::LoadLibrary( const char* aFileName )
2519   {
2520     SMESH::FilterLibrary_i* aServant = new SMESH::FilterLibrary_i( aFileName );
2521     SMESH::FilterLibrary_var anObj = aServant->_this();
2522     TPythonDump()<<aServant<<" = "<<this<<".LoadLibrary('"<<aFileName<<"')";
2523     return anObj._retn();
2524   }
2525
2526   FilterLibrary_ptr FilterManager_i::CreateLibrary()
2527   {
2528     SMESH::FilterLibrary_i* aServant = new SMESH::FilterLibrary_i();
2529     SMESH::FilterLibrary_var anObj = aServant->_this();
2530     TPythonDump()<<aServant<<" = "<<this<<".CreateLibrary()";
2531     return anObj._retn();
2532   }
2533
2534   CORBA::Boolean FilterManager_i::DeleteLibrary( const char* aFileName )
2535   {
2536     TPythonDump()<<this<<".DeleteLibrary("<<aFileName<<")";
2537     return remove( aFileName ) ? false : true;
2538   }
2539
2540   /*
2541                                 FILTER
2542   */
2543
2544   //=======================================================================
2545   // name    : Filter_i::Filter_i
2546   // Purpose : Constructor
2547   //=======================================================================
2548   Filter_i::Filter_i()
2549   : myPredicate( NULL )
2550   {}
2551
2552   //=======================================================================
2553   // name    : Filter_i::~Filter_i
2554   // Purpose : Destructor
2555   //=======================================================================
2556   Filter_i::~Filter_i()
2557   {
2558     if ( myPredicate )
2559       myPredicate->UnRegister();
2560
2561     if(!CORBA::is_nil(myMesh))
2562       myMesh->UnRegister();
2563
2564     myPredicate = 0;
2565     FindBaseObjects();
2566   }
2567
2568   //=======================================================================
2569   // name    : Filter_i::SetPredicate
2570   // Purpose : Set predicate
2571   //=======================================================================
2572   void Filter_i::SetPredicate( Predicate_ptr thePredicate )
2573   {
2574     if ( myPredicate )
2575       myPredicate->UnRegister();
2576
2577     myPredicate = SMESH::GetPredicate(thePredicate);
2578
2579     if ( myPredicate )
2580     {
2581       myFilter.SetPredicate( myPredicate->GetPredicate() );
2582       myPredicate->Register();
2583       if ( const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh))
2584         myPredicate->GetPredicate()->SetMesh( aMesh );
2585       TPythonDump()<<this<<".SetPredicate("<<myPredicate<<")";
2586     }
2587     NotifyerAndWaiter::Modified();
2588   }
2589
2590   //=======================================================================
2591   // name    : Filter_i::GetElementType
2592   // Purpose : Get entity type
2593   //=======================================================================
2594   SMESH::ElementType Filter_i::GetElementType()
2595   {
2596     return myPredicate != 0 ? myPredicate->GetElementType() : SMESH::ALL;
2597   }
2598
2599   //=======================================================================
2600   // name    : Filter_i::SetMesh
2601   // Purpose : Set mesh
2602   //=======================================================================
2603   void
2604   Filter_i::
2605   SetMesh( SMESH_Mesh_ptr theMesh )
2606   {
2607     if(!CORBA::is_nil(theMesh))
2608       theMesh->Register();
2609
2610     if(!CORBA::is_nil(myMesh))
2611       myMesh->UnRegister();
2612
2613     myMesh = SMESH_Mesh::_duplicate( theMesh );
2614     TPythonDump()<<this<<".SetMesh("<<theMesh<<")";
2615
2616     if ( myPredicate )
2617       if ( const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(theMesh))
2618         myPredicate->GetPredicate()->SetMesh( aMesh );
2619   }
2620
2621   SMESH::smIdType_array*
2622   Filter_i::
2623   GetIDs()
2624   {
2625     return GetElementsId(myMesh);
2626   }
2627
2628   //=======================================================================
2629   // name    : Filter_i::GetElementsId
2630   // Purpose : Get ids of entities
2631   //=======================================================================
2632   void
2633   Filter_i::
2634   GetElementsId( Predicate_i* thePredicate,
2635                  const SMDS_Mesh* theMesh,
2636                  Controls::Filter::TIdSequence& theSequence )
2637   {
2638     if (thePredicate)
2639       Controls::Filter::GetElementsId(theMesh,thePredicate->GetPredicate(),theSequence);
2640   }
2641
2642   void
2643   Filter_i::
2644   GetElementsId( Predicate_i* thePredicate,
2645                  SMESH_Mesh_ptr theMesh,
2646                  Controls::Filter::TIdSequence& theSequence )
2647   {
2648     if (thePredicate) 
2649       if(const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(theMesh))
2650         Controls::Filter::GetElementsId(aMesh,thePredicate->GetPredicate(),theSequence);
2651   }
2652
2653   SMESH::smIdType_array*
2654   Filter_i::
2655   GetElementsId( SMESH_Mesh_ptr theMesh )
2656   {
2657     SMESH::smIdType_array_var anArray = new SMESH::smIdType_array;
2658     if(!CORBA::is_nil(theMesh) && myPredicate){
2659       theMesh->Load();
2660       Controls::Filter::TIdSequence aSequence;
2661       GetElementsId(myPredicate,theMesh,aSequence);
2662       long i = 0, iEnd = aSequence.size();
2663       anArray->length( iEnd );
2664       for ( ; i < iEnd; i++ )
2665         anArray[ i ] = aSequence[i];
2666     }
2667     return anArray._retn();
2668   }
2669
2670   SMESH::smIdType_array*
2671   Filter_i::
2672   GetElementsIdFromParts( const ListOfIDSources& theParts )
2673   {
2674     SMESH::smIdType_array_var array = new SMESH::smIdType_array;
2675     if ( theParts.length() > 0 && myPredicate )
2676     {
2677       SMESH_Mesh_ptr mesh = theParts[0]->GetMesh();
2678       mesh->Load();
2679       const SMDS_Mesh* meshDS = MeshPtr2SMDSMesh( mesh );
2680       Controls::Filter::TIdSequence totalSequence;
2681       for ( CORBA::ULong i = 0; i < theParts.length(); ++i )
2682       {
2683         if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theParts[i] ))
2684           filter->SetMesh( mesh );
2685         SMDS_ElemIteratorPtr iter = SMESH_Mesh_i::GetElements( theParts[i], GetElementType() );
2686         if ( iter && meshDS )
2687         {
2688           Controls::Filter::TIdSequence sequence;
2689           Controls::Filter::GetElementsId( meshDS, myPredicate->GetPredicate(), sequence, iter );
2690           totalSequence.insert( totalSequence.end(), sequence.begin(), sequence.end() );
2691         }
2692       }
2693       array->length( totalSequence.size() );
2694       for ( size_t i = 0; i < totalSequence.size(); ++i )
2695         array[ i ] = totalSequence[ i ];
2696     }
2697     return array._retn();
2698   }
2699
2700   //=============================================================================
2701   /*!
2702    * \brief Returns number of mesh elements per each \a EntityType
2703    */
2704   //=============================================================================
2705
2706   SMESH::smIdType_array* Filter_i::GetMeshInfo()
2707   {
2708     SMESH::smIdType_array_var aRes = new SMESH::smIdType_array();
2709     aRes->length(SMESH::Entity_Last);
2710     for (int i = 0; i < SMESH::Entity_Last; i++)
2711       aRes[i] = 0;
2712
2713     if ( !CORBA::is_nil(myMesh) && myPredicate )
2714     {
2715       const SMDS_Mesh*  aMesh = MeshPtr2SMDSMesh(myMesh);
2716       SMDS_ElemIteratorPtr it = aMesh->elementsIterator( SMDSAbs_ElementType( GetElementType() ));
2717       while ( it->more() )
2718       {
2719         const SMDS_MeshElement* anElem = it->next();
2720         if ( myPredicate->IsSatisfy( anElem->GetID() ) )
2721           aRes[ anElem->GetEntityType() ]++;
2722       }
2723     }
2724
2725     return aRes._retn();  
2726   }
2727
2728   //=============================================================================
2729   /*!
2730    * \brief Returns number of mesh elements of each \a ElementType
2731    */
2732   //=============================================================================
2733
2734   SMESH::smIdType_array* Filter_i::GetNbElementsByType()
2735   {
2736     SMESH::smIdType_array_var aRes = new SMESH::smIdType_array();
2737     aRes->length(SMESH::NB_ELEMENT_TYPES);
2738     for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
2739       aRes[i] = 0;
2740
2741     if ( !CORBA::is_nil(myMesh) && myPredicate ) {
2742       const SMDS_Mesh*  aMesh = MeshPtr2SMDSMesh(myMesh);
2743       SMDS_ElemIteratorPtr it = aMesh->elementsIterator( SMDSAbs_ElementType( GetElementType() ));
2744       SMESH::smIdType& nbElems = aRes[ GetElementType() ];
2745       while ( it->more() )
2746       {
2747         const SMDS_MeshElement* anElem = it->next();
2748         if ( myPredicate->IsSatisfy( anElem->GetID() ) )
2749           nbElems++;
2750       }
2751     }
2752
2753     return aRes._retn();  
2754   }
2755
2756
2757   //================================================================================
2758   /*!
2759    * \brief Return GetElementType() within an array
2760    * Implement SMESH_IDSource interface
2761    */
2762   //================================================================================
2763
2764   SMESH::array_of_ElementType* Filter_i::GetTypes()
2765   {
2766     SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
2767
2768     // check if any element passes through the filter
2769     if ( !CORBA::is_nil(myMesh) && myPredicate )
2770     {
2771       const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh);
2772       SMDS_ElemIteratorPtr it = aMesh->elementsIterator( SMDSAbs_ElementType( GetElementType() ));
2773       bool satisfies = false;
2774       while ( !satisfies && it->more() )
2775         satisfies = myPredicate->IsSatisfy( it->next()->GetID() );
2776       if ( satisfies ) {
2777         types->length( 1 );
2778         types[0] = GetElementType();
2779       }
2780     }
2781     return types._retn();
2782   }
2783
2784   //=======================================================================
2785   //function : GetMesh
2786   //purpose  : Returns mesh
2787   //=======================================================================
2788
2789   SMESH::SMESH_Mesh_ptr Filter_i::GetMesh()
2790   {
2791     return SMESH_Mesh::_duplicate( myMesh );
2792   }
2793
2794   //=======================================================================
2795   //function : GetVtkUgStream
2796   //purpose  : Return data vtk unstructured grid (not implemented)
2797   //=======================================================================
2798
2799   SALOMEDS::TMPFile* Filter_i::GetVtkUgStream()
2800   {
2801     SALOMEDS::TMPFile_var SeqFile;
2802     return SeqFile._retn();
2803   }
2804   //=======================================================================
2805   // name    : getCriteria
2806   // Purpose : Retrieve criterions from predicate
2807   //=======================================================================
2808   static inline void getPrediacates( Predicate_i*                thePred,
2809                                      std::vector<Predicate_i*> & thePredVec )
2810   {
2811     const int aFType = thePred->GetFunctorType();
2812
2813     switch ( aFType )
2814     {
2815     case FT_LogicalNOT:
2816     {
2817       Predicate_i* aPred = ( dynamic_cast<LogicalNOT_i*>( thePred ) )->GetPredicate_i();
2818       getPrediacates( aPred, thePredVec );
2819       break;
2820     }
2821     case FT_LogicalAND:
2822     case FT_LogicalOR:
2823     {
2824       Predicate_i* aPred1 = ( dynamic_cast<LogicalBinary_i*>( thePred ) )->GetPredicate1_i();
2825       Predicate_i* aPred2 = ( dynamic_cast<LogicalBinary_i*>( thePred ) )->GetPredicate2_i();
2826       getPrediacates( aPred1, thePredVec );
2827       getPrediacates( aPred2, thePredVec );
2828       break;
2829      }
2830     default:;
2831     }
2832     thePredVec.push_back( thePred );
2833   }
2834
2835   //=======================================================================
2836   // name    : getCriteria
2837   // Purpose : Retrieve criterions from predicate
2838   //=======================================================================
2839   static inline bool getCriteria( Predicate_i*                thePred,
2840                                   SMESH::Filter::Criteria_out theCriteria )
2841   {
2842     const int aFType = thePred->GetFunctorType();
2843
2844     switch ( aFType )
2845     {
2846     case FT_LogicalNOT:
2847       {
2848         Predicate_i* aPred = ( dynamic_cast<LogicalNOT_i*>( thePred ) )->GetPredicate_i();
2849         getCriteria( aPred, theCriteria );
2850         theCriteria[ theCriteria->length() - 1 ].UnaryOp = FT_LogicalNOT;
2851       }
2852       return true;
2853
2854     case FT_LogicalAND:
2855     case FT_LogicalOR:
2856       {
2857         Predicate_i* aPred1 = ( dynamic_cast<LogicalBinary_i*>( thePred ) )->GetPredicate1_i();
2858         Predicate_i* aPred2 = ( dynamic_cast<LogicalBinary_i*>( thePred ) )->GetPredicate2_i();
2859         if ( !getCriteria( aPred1, theCriteria ) )
2860           return false;
2861         theCriteria[ theCriteria->length() - 1 ].BinaryOp = aFType;
2862         return getCriteria( aPred2, theCriteria );
2863       }
2864     case FT_Undefined:
2865       return false;
2866     }
2867
2868     // resize theCriteria
2869     CORBA::ULong i = theCriteria->length();
2870     theCriteria->length( i + 1 );
2871     theCriteria[ i ] = createCriterion();
2872
2873     // set members of the added Criterion
2874
2875     theCriteria[ i ].Type = aFType;
2876     theCriteria[ i ].TypeOfElement = thePred->GetElementType();
2877
2878     switch ( aFType )
2879     {
2880     case FT_FreeBorders:
2881     case FT_FreeEdges:
2882     case FT_FreeFaces:
2883     case FT_LinearOrQuadratic:
2884     case FT_FreeNodes:
2885     case FT_EqualEdges:
2886     case FT_EqualFaces:
2887     case FT_EqualVolumes:
2888     case FT_BadOrientedVolume:
2889     case FT_BareBorderVolume:
2890     case FT_BareBorderFace:
2891     case FT_OverConstrainedVolume:
2892     case FT_OverConstrainedFace:
2893       {
2894         return true;
2895       }
2896     case FT_BelongToMeshGroup:
2897       {
2898         BelongToMeshGroup_i* aPred = dynamic_cast<BelongToMeshGroup_i*>( thePred );
2899         SMESH::SMESH_GroupBase_var grp = aPred->GetGroup();
2900         if ( !grp->_is_nil() )
2901         {
2902           theCriteria[ i ].ThresholdStr = grp->GetName();
2903           theCriteria[ i ].ThresholdID  = aPred->GetGroupID().c_str();
2904         }
2905         return true;
2906       }
2907     case FT_BelongToGeom:
2908       {
2909         BelongToGeom_i* aPred = dynamic_cast<BelongToGeom_i*>( thePred );
2910         theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
2911         theCriteria[ i ].ThresholdID   = aPred->GetShapeID();
2912         theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2913         return true;
2914       }
2915     case FT_BelongToPlane:
2916     case FT_BelongToCylinder:
2917     case FT_BelongToGenSurface:
2918       {
2919         BelongToSurface_i* aPred = dynamic_cast<BelongToSurface_i*>( thePred );
2920         theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
2921         theCriteria[ i ].ThresholdID   = aPred->GetShapeID();
2922         theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2923         return true;
2924       }
2925     case FT_LyingOnGeom:
2926       {
2927         LyingOnGeom_i* aPred = dynamic_cast<LyingOnGeom_i*>( thePred );
2928         theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
2929         theCriteria[ i ].ThresholdID   = aPred->GetShapeID();
2930         theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2931         return true;
2932       }
2933     case FT_CoplanarFaces:
2934       {
2935         CoplanarFaces_i* aPred = dynamic_cast<CoplanarFaces_i*>( thePred );
2936         theCriteria[ i ].ThresholdID   = aPred->GetFaceAsString();
2937         theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2938         return true;
2939       }
2940     case FT_ConnectedElements:
2941       {
2942         ConnectedElements_i* aPred = dynamic_cast<ConnectedElements_i*>( thePred );
2943         SMESH::ConnectedElements::ThresholdType type;
2944         CORBA::String_var threshold = aPred->GetThreshold( type );
2945         switch ( type ) {
2946         case SMESH::ConnectedElements::POINT:
2947           theCriteria[ i ].ThresholdStr = threshold; break;
2948         case SMESH::ConnectedElements::VERTEX:
2949           theCriteria[ i ].ThresholdID = threshold; break;
2950         case SMESH::ConnectedElements::NODE:
2951           theCriteria[ i ].Threshold = atof( threshold.in() ); break;
2952         default:;
2953         }
2954         return true;
2955       }
2956     case FT_EqualNodes:
2957       {
2958         EqualNodes_i* aPred = dynamic_cast<EqualNodes_i*>( thePred );
2959         theCriteria[ i ].Tolerance  = aPred->GetTolerance();
2960         return true;
2961       }
2962     case FT_RangeOfIds:
2963       {
2964         RangeOfIds_i* aPred = dynamic_cast<RangeOfIds_i*>( thePred );
2965         theCriteria[ i ].ThresholdStr  = aPred->GetRangeStr();
2966         return true;
2967       }
2968     case FT_LessThan:
2969     case FT_MoreThan:
2970     case FT_EqualTo:
2971       {
2972         Comparator_i* aCompar = dynamic_cast<Comparator_i*>( thePred );
2973         theCriteria[ i ].Type      = aCompar->GetNumFunctor_i()->GetFunctorType();
2974         theCriteria[ i ].Compare   = aFType;
2975         theCriteria[ i ].Threshold = aCompar->GetMargin();
2976         if ( aFType == FT_EqualTo )
2977         {
2978           EqualTo_i* aCompar = dynamic_cast<EqualTo_i*>( thePred );
2979           theCriteria[ i ].Tolerance = aCompar->GetTolerance();
2980         }
2981         return true;
2982       }
2983     case FT_GroupColor:
2984       {
2985         GroupColor_i* aPred = dynamic_cast<GroupColor_i*>( thePred );
2986         theCriteria[ i ].ThresholdStr = aPred->GetColorStr();
2987         return true;
2988       }
2989     case FT_ElemGeomType:
2990       {
2991         ElemGeomType_i* aPred = dynamic_cast<ElemGeomType_i*>( thePred );
2992         theCriteria[ i ].Threshold = (double)aPred->GetGeometryType();
2993         return true;
2994       }
2995     case FT_EntityType:
2996       {
2997         ElemEntityType_i* aPred = dynamic_cast<ElemEntityType_i*>( thePred );
2998         theCriteria[ i ].Threshold = (double)aPred->GetEntityType();
2999         return true;
3000       }
3001     default:
3002       return false;
3003     }
3004   }
3005
3006   //=======================================================================
3007   // name    : Filter_i::GetCriteria
3008   // Purpose : Retrieve criterions from predicate
3009   //=======================================================================
3010   CORBA::Boolean Filter_i::GetCriteria( SMESH::Filter::Criteria_out theCriteria )
3011   {
3012     theCriteria = new SMESH::Filter::Criteria;
3013     return myPredicate != 0 ? getCriteria( myPredicate, theCriteria ) : true;
3014   }
3015
3016   //=======================================================================
3017   // name    : Filter_i::SetCriteria
3018   // Purpose : Create new predicate and set criterions in it
3019   //=======================================================================
3020   CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria )
3021   {
3022     SetPredicate( SMESH::Predicate::_nil() );
3023
3024     SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i();
3025     FilterManager_ptr aFilterMgr = aFilter->_this();
3026
3027     // CREATE two lists ( PREDICATES  and LOG OP )
3028
3029     // Criterion
3030     TPythonDump()<<"aCriteria = []";
3031     std::list<SMESH::Predicate_ptr> aPredicates;
3032     std::list<int>                  aBinaries;
3033     for ( int i = 0, n = theCriteria.length(); i < n; i++ )
3034     {
3035       int         aCriterion    = theCriteria[ i ].Type;
3036       int         aCompare      = theCriteria[ i ].Compare;
3037       double      aThreshold    = theCriteria[ i ].Threshold;
3038       const char* aThresholdStr = theCriteria[ i ].ThresholdStr;
3039       const char* aThresholdID  = theCriteria[ i ].ThresholdID;
3040       int         aUnary        = theCriteria[ i ].UnaryOp;
3041       int         aBinary       = theCriteria[ i ].BinaryOp;
3042       double      aTolerance    = theCriteria[ i ].Tolerance;
3043       ElementType aTypeOfElem   = theCriteria[ i ].TypeOfElement;
3044       long        aPrecision    = theCriteria[ i ].Precision;
3045
3046       {
3047         TPythonDump pd;
3048         pd << "aCriterion = SMESH.Filter.Criterion("
3049            << aCriterion    << ", "
3050            << aCompare      << ", "
3051            << aThreshold    << ", '"
3052            << aThresholdStr << "', '"
3053            << aThresholdID  << "', "
3054            << aUnary        << ", "
3055            << aBinary       << ", "
3056            << aTolerance    << ", "
3057            << aTypeOfElem   << ", "
3058            << aPrecision    << ")";
3059       }
3060       TPythonDump pd;
3061
3062       SMESH::Predicate_ptr aPredicate = SMESH::Predicate::_nil();
3063       SMESH::NumericalFunctor_ptr aFunctor = SMESH::NumericalFunctor::_nil();
3064
3065       switch ( aCriterion )
3066       {
3067         // Functors
3068
3069         case SMESH::FT_MultiConnection:
3070           aFunctor = aFilterMgr->CreateMultiConnection();
3071           break;
3072         case SMESH::FT_MultiConnection2D:
3073           aFunctor = aFilterMgr->CreateMultiConnection2D();
3074           break;
3075         case SMESH::FT_Length:
3076           aFunctor = aFilterMgr->CreateLength();
3077           break;
3078         case SMESH::FT_Length2D:
3079           aFunctor = aFilterMgr->CreateLength2D();
3080           break;
3081         case SMESH::FT_Length3D:
3082           aFunctor = aFilterMgr->CreateLength3D();
3083           break;
3084         case SMESH::FT_Deflection2D:
3085           aFunctor = aFilterMgr->CreateDeflection2D();
3086           break;
3087         case SMESH::FT_AspectRatio:
3088           aFunctor = aFilterMgr->CreateAspectRatio();
3089           break;
3090         case SMESH::FT_AspectRatio3D:
3091           aFunctor = aFilterMgr->CreateAspectRatio3D();
3092           break;
3093         case SMESH::FT_Warping:
3094           aFunctor = aFilterMgr->CreateWarping();
3095           break;
3096         case SMESH::FT_Warping3D:
3097           aFunctor = aFilterMgr->CreateWarping3D();
3098           break;
3099         case SMESH::FT_MinimumAngle:
3100           aFunctor = aFilterMgr->CreateMinimumAngle();
3101           break;
3102         case SMESH::FT_Taper:
3103           aFunctor = aFilterMgr->CreateTaper();
3104           break;
3105         case SMESH::FT_Skew:
3106           aFunctor = aFilterMgr->CreateSkew();
3107           break;
3108         case SMESH::FT_Area:
3109           aFunctor = aFilterMgr->CreateArea();
3110           break;
3111         case SMESH::FT_Volume3D:
3112           aFunctor = aFilterMgr->CreateVolume3D();
3113           break;
3114         case SMESH::FT_MaxElementLength2D:
3115           aFunctor = aFilterMgr->CreateMaxElementLength2D();
3116           break;
3117         case SMESH::FT_MaxElementLength3D:
3118           aFunctor = aFilterMgr->CreateMaxElementLength3D();
3119           break;
3120         case SMESH::FT_BallDiameter:
3121           aFunctor = aFilterMgr->CreateBallDiameter();
3122           break;
3123         case SMESH::FT_NodeConnectivityNumber:
3124           aFunctor = aFilterMgr->CreateNodeConnectivityNumber();
3125           break;
3126         case SMESH::FT_ScaledJacobian:
3127           aFunctor = aFilterMgr->CreateScaledJacobian();
3128           break;
3129
3130         // Predicates
3131
3132         case SMESH::FT_FreeBorders:
3133           aPredicate = aFilterMgr->CreateFreeBorders();
3134           break;
3135         case SMESH::FT_FreeEdges:
3136           aPredicate = aFilterMgr->CreateFreeEdges();
3137           break;
3138         case SMESH::FT_FreeFaces:
3139           aPredicate = aFilterMgr->CreateFreeFaces();
3140           break;
3141         case SMESH::FT_FreeNodes:
3142           aPredicate = aFilterMgr->CreateFreeNodes();
3143           break;
3144         case SMESH::FT_EqualNodes:
3145           {
3146             SMESH::EqualNodes_ptr pred = aFilterMgr->CreateEqualNodes();
3147             pred->SetTolerance( aTolerance );
3148             aPredicate = pred;
3149             break;
3150           }
3151         case SMESH::FT_EqualEdges:
3152           aPredicate = aFilterMgr->CreateEqualEdges();
3153           break;
3154         case SMESH::FT_EqualFaces:
3155           aPredicate = aFilterMgr->CreateEqualFaces();
3156           break;
3157         case SMESH::FT_EqualVolumes:
3158           aPredicate = aFilterMgr->CreateEqualVolumes();
3159           break;
3160         case SMESH::FT_BelongToMeshGroup:
3161           {
3162             SMESH::BelongToMeshGroup_ptr tmpPred = aFilterMgr->CreateBelongToMeshGroup();
3163             tmpPred->SetGroupID( aThresholdID );
3164             aPredicate = tmpPred;
3165           }
3166           break;
3167         case SMESH::FT_BelongToGeom:
3168           {
3169             SMESH::BelongToGeom_ptr tmpPred = aFilterMgr->CreateBelongToGeom();
3170             tmpPred->SetElementType( aTypeOfElem );
3171             tmpPred->SetShape( aThresholdID, aThresholdStr );
3172             tmpPred->SetTolerance( aTolerance );
3173             aPredicate = tmpPred;
3174           }
3175           break;
3176         case SMESH::FT_BelongToPlane:
3177         case SMESH::FT_BelongToCylinder:
3178         case SMESH::FT_BelongToGenSurface:
3179           {
3180             SMESH::BelongToSurface_ptr tmpPred;
3181             switch ( aCriterion ) {
3182             case SMESH::FT_BelongToPlane:
3183               tmpPred = aFilterMgr->CreateBelongToPlane(); break;
3184             case SMESH::FT_BelongToCylinder:
3185               tmpPred = aFilterMgr->CreateBelongToCylinder(); break;
3186             default:
3187               tmpPred = aFilterMgr->CreateBelongToGenSurface();
3188             }
3189             tmpPred->SetShape( aThresholdID, aThresholdStr, aTypeOfElem );
3190             tmpPred->SetTolerance( aTolerance );
3191             aPredicate = tmpPred;
3192           }
3193           break;
3194         case SMESH::FT_LyingOnGeom:
3195           {
3196             SMESH::LyingOnGeom_ptr tmpPred = aFilterMgr->CreateLyingOnGeom();
3197             tmpPred->SetElementType( aTypeOfElem );
3198             tmpPred->SetShape( aThresholdID, aThresholdStr );
3199             tmpPred->SetTolerance( aTolerance );
3200             aPredicate = tmpPred;
3201           }
3202           break;
3203         case SMESH::FT_RangeOfIds:
3204           {
3205             SMESH::RangeOfIds_ptr tmpPred = aFilterMgr->CreateRangeOfIds();
3206             tmpPred->SetRangeStr( aThresholdStr );
3207             tmpPred->SetElementType( aTypeOfElem );
3208             aPredicate = tmpPred;
3209           }
3210           break;
3211         case SMESH::FT_BadOrientedVolume:
3212           {
3213             aPredicate = aFilterMgr->CreateBadOrientedVolume();
3214           }
3215           break;
3216         case SMESH::FT_BareBorderVolume:
3217           {
3218             aPredicate = aFilterMgr->CreateBareBorderVolume();
3219           }
3220           break;
3221         case SMESH::FT_BareBorderFace:
3222           {
3223             aPredicate = aFilterMgr->CreateBareBorderFace();
3224           }
3225           break;
3226         case SMESH::FT_OverConstrainedVolume:
3227           {
3228             aPredicate = aFilterMgr->CreateOverConstrainedVolume();
3229           }
3230           break;
3231         case SMESH::FT_OverConstrainedFace:
3232           {
3233             aPredicate = aFilterMgr->CreateOverConstrainedFace();
3234           }
3235           break;
3236         case SMESH::FT_LinearOrQuadratic:
3237           {
3238             SMESH::LinearOrQuadratic_ptr tmpPred = aFilterMgr->CreateLinearOrQuadratic();
3239             tmpPred->SetElementType( aTypeOfElem );
3240             aPredicate = tmpPred;
3241             break;
3242           }
3243         case SMESH::FT_GroupColor:
3244           {
3245             SMESH::GroupColor_ptr tmpPred = aFilterMgr->CreateGroupColor();
3246             tmpPred->SetElementType( aTypeOfElem );
3247             tmpPred->SetColorStr( aThresholdStr );
3248             aPredicate = tmpPred;
3249             break;
3250           }
3251         case SMESH::FT_ElemGeomType:
3252           {
3253             SMESH::ElemGeomType_ptr tmpPred = aFilterMgr->CreateElemGeomType();
3254             tmpPred->SetElementType( aTypeOfElem );
3255             tmpPred->SetGeometryType( (GeometryType)(int)(aThreshold + 0.5) );
3256             aPredicate = tmpPred;
3257             break;
3258           }
3259         case SMESH::FT_EntityType:
3260           {
3261             SMESH::ElemEntityType_ptr tmpPred = aFilterMgr->CreateElemEntityType();
3262             tmpPred->SetElementType( aTypeOfElem );
3263             tmpPred->SetEntityType( EntityType( (int (aThreshold + 0.5))));
3264             aPredicate = tmpPred;
3265             break;
3266           }
3267         case SMESH::FT_CoplanarFaces:
3268           {
3269             SMESH::CoplanarFaces_ptr tmpPred = aFilterMgr->CreateCoplanarFaces();
3270             tmpPred->SetFace( atol (aThresholdID ));
3271             tmpPred->SetTolerance( aTolerance );
3272             aPredicate = tmpPred;
3273             break;
3274           }
3275         case SMESH::FT_ConnectedElements:
3276           {
3277             SMESH::ConnectedElements_ptr tmpPred = aFilterMgr->CreateConnectedElements();
3278             if ( strlen( aThresholdID ) > 0 ) // shape ID
3279               tmpPred->SetThreshold( aThresholdID, SMESH::ConnectedElements::VERTEX );
3280             else if ( strlen( aThresholdStr ) > 0 ) // point coords
3281               tmpPred->SetThreshold( aThresholdStr, SMESH::ConnectedElements::POINT );
3282             else if ( aThreshold >= 1 )
3283               tmpPred->SetNode( (CORBA::Long) aThreshold ); // node ID
3284             tmpPred->SetElementType( aTypeOfElem );
3285             aPredicate = tmpPred;
3286             break;
3287           }
3288
3289         default:
3290           continue;
3291       }
3292
3293       // Comparator
3294       if ( !aFunctor->_is_nil() && aPredicate->_is_nil() )
3295       {
3296         SMESH::Comparator_ptr aComparator = SMESH::Comparator::_nil();
3297
3298         if ( aCompare == SMESH::FT_LessThan )
3299           aComparator = aFilterMgr->CreateLessThan();
3300         else if ( aCompare == SMESH::FT_MoreThan )
3301           aComparator = aFilterMgr->CreateMoreThan();
3302         else if ( aCompare == SMESH::FT_EqualTo )
3303           aComparator = aFilterMgr->CreateEqualTo();
3304         else
3305           continue;
3306
3307         aComparator->SetNumFunctor( aFunctor );
3308         aComparator->SetMargin( aThreshold );
3309
3310         if ( aCompare == FT_EqualTo )
3311         {
3312           SMESH::EqualTo_var anEqualTo = SMESH::EqualTo::_narrow( aComparator );
3313           anEqualTo->SetTolerance( aTolerance );
3314         }
3315
3316         aPredicate = aComparator;
3317
3318         aFunctor->SetPrecision( aPrecision );
3319       }
3320
3321       // Logical not
3322       if ( aUnary == FT_LogicalNOT )
3323       {
3324         SMESH::LogicalNOT_ptr aNotPred = aFilterMgr->CreateLogicalNOT();
3325         aNotPred->SetPredicate( aPredicate );
3326         aPredicate = aNotPred;
3327       }
3328
3329       // logical op
3330       aPredicates.push_back( aPredicate );
3331       aBinaries.push_back( aBinary );
3332       pd <<"aCriteria.append(aCriterion)";
3333
3334     } // end of for
3335     TPythonDump pd; pd<<this<<".SetCriteria(aCriteria)";
3336
3337     // CREATE ONE PREDICATE FROM PREVIOUSLY CREATED MAP
3338
3339     // combine all "AND" operations
3340
3341     std::list<SMESH::Predicate_ptr> aResList;
3342
3343     std::list<SMESH::Predicate_ptr>::iterator aPredIter;
3344     std::list<int>::iterator                  aBinaryIter;
3345
3346     SMESH::Predicate_ptr aPrevPredicate = SMESH::Predicate::_nil();
3347     int aPrevBinary = SMESH::FT_Undefined;
3348     if ( !aBinaries.empty() )
3349       aBinaries.back() = SMESH::FT_Undefined;
3350
3351     for ( aPredIter = aPredicates.begin(), aBinaryIter = aBinaries.begin();
3352           aPredIter != aPredicates.end() && aBinaryIter != aBinaries.end();
3353           ++aPredIter, ++aBinaryIter )
3354     {
3355       int aCurrBinary = *aBinaryIter;
3356
3357       SMESH::Predicate_ptr aCurrPred = SMESH::Predicate::_nil();
3358
3359       if ( aPrevBinary == SMESH::FT_LogicalAND )
3360       {
3361
3362         SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalAND();
3363         aBinaryPred->SetPredicate1( aPrevPredicate );
3364         aBinaryPred->SetPredicate2( *aPredIter );
3365         aCurrPred = aBinaryPred;
3366       }
3367       else
3368         aCurrPred = *aPredIter;
3369
3370       if ( aCurrBinary != SMESH::FT_LogicalAND )
3371         aResList.push_back( aCurrPred );
3372
3373       aPrevPredicate = aCurrPred;
3374       aPrevBinary = aCurrBinary;
3375     }
3376
3377     // combine all "OR" operations
3378
3379     SMESH::Predicate_ptr aResPredicate = SMESH::Predicate::_nil();
3380
3381     if ( aResList.size() == 1 )
3382       aResPredicate = *aResList.begin();
3383     else if ( aResList.size() > 1 )
3384     {
3385       std::list<SMESH::Predicate_ptr>::iterator anIter = aResList.begin();
3386       aResPredicate = *anIter;
3387       anIter++;
3388       for ( ; anIter != aResList.end(); ++anIter )
3389       {
3390         SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalOR();
3391         aBinaryPred->SetPredicate1( aResPredicate );
3392         aBinaryPred->SetPredicate2( *anIter );
3393         aResPredicate = aBinaryPred;
3394       }
3395     }
3396
3397     SetPredicate( aResPredicate );
3398     if ( !aResPredicate->_is_nil() )
3399       aResPredicate->UnRegister();
3400
3401     return !aResPredicate->_is_nil();
3402   }
3403
3404   //=======================================================================
3405   // name    : Filter_i::GetPredicate_i
3406   // Purpose : Get implementation of predicate
3407   //=======================================================================
3408   Predicate_i* Filter_i::GetPredicate_i()
3409   {
3410     return myPredicate;
3411   }
3412
3413   //=======================================================================
3414   // name    : Filter_i::GetPredicate
3415   // Purpose : Get predicate
3416   //=======================================================================
3417   Predicate_ptr Filter_i::GetPredicate()
3418   {
3419     if ( myPredicate == 0 )
3420       return SMESH::Predicate::_nil();
3421     else
3422     {
3423       SMESH::Predicate_var anObj = myPredicate->_this();
3424       // if ( SMESH::Functor_i* fun = SMESH::DownCast<SMESH::Functor_i*>( anObj ))
3425       //   TPythonDump() << fun << " = " << this << ".GetPredicate()";
3426       return anObj._retn();
3427     }
3428   }
3429
3430   //================================================================================
3431   /*!
3432    * \brief Find groups it depends on
3433    */
3434   //================================================================================
3435
3436   void Filter_i::FindBaseObjects()
3437   {
3438     // release current groups
3439     for ( size_t i = 0; i < myBaseGroups.size(); ++i )
3440       if ( myBaseGroups[i] )
3441       {
3442         myBaseGroups[i]->RemoveModifWaiter( this );
3443         myBaseGroups[i]->UnRegister();
3444       }
3445
3446     // remember new groups
3447     myBaseGroups.clear();
3448     if ( myPredicate )
3449     {
3450       std::vector<Predicate_i*> predicates;
3451       getPrediacates( myPredicate, predicates );
3452       for ( size_t i = 0; i < predicates.size(); ++i )
3453         if ( BelongToMeshGroup_i* bmg = dynamic_cast< BelongToMeshGroup_i* >( predicates[i] ))
3454         {
3455           SMESH::SMESH_GroupBase_var g = bmg->GetGroup();
3456           SMESH_GroupBase_i* g_i = SMESH::DownCast< SMESH_GroupBase_i*>( g );
3457           if ( g_i )
3458           {
3459             g_i->AddModifWaiter( this );
3460             g_i->Register();
3461             myBaseGroups.push_back( g_i );
3462           }
3463         }
3464     }
3465   }
3466
3467   //================================================================================
3468   /*!
3469    * \brief When notified on removal of myBaseGroups[i], remove a reference to a
3470    *        group from a predicate
3471    */
3472   //================================================================================
3473
3474   void Filter_i::OnBaseObjModified(NotifyerAndWaiter* group, bool removed)
3475   {
3476     if ( !removed )
3477       return; // a GroupOnFilter holding this filter is notified automatically
3478
3479     if ( myPredicate )
3480     {
3481       std::vector<Predicate_i*> predicates;
3482       getPrediacates( myPredicate, predicates );
3483       for ( size_t i = 0; i < predicates.size(); ++i )
3484         if ( BelongToMeshGroup_i* bmg = dynamic_cast< BelongToMeshGroup_i* >( predicates[i] ))
3485         {
3486           SMESH::SMESH_GroupBase_var g = bmg->GetGroup();
3487           SMESH_GroupBase_i* g_i = SMESH::DownCast< SMESH_GroupBase_i*>( g );
3488           if ( g_i == group )
3489           {
3490             bmg->SetGroup( SMESH::SMESH_GroupBase::_nil() );
3491             bmg->SetGroupID( "" );
3492           }
3493         }
3494     }
3495
3496     FindBaseObjects(); // release and update myBaseGroups;
3497   }
3498
3499   /*
3500                               FILTER LIBRARY
3501   */
3502
3503   #define ATTR_TYPE          "type"
3504   #define ATTR_COMPARE       "compare"
3505   #define ATTR_THRESHOLD     "threshold"
3506   #define ATTR_UNARY         "unary"
3507   #define ATTR_BINARY        "binary"
3508   #define ATTR_THRESHOLD_STR "threshold_str"
3509   #define ATTR_TOLERANCE     "tolerance"
3510   #define ATTR_ELEMENT_TYPE  "ElementType"
3511
3512   //=======================================================================
3513   // name    : toString
3514   // Purpose : Convert bool to LDOMString
3515   //=======================================================================
3516   static inline LDOMString toString( CORBA::Boolean val )
3517   {
3518     return val ? "logical not" : "";
3519   }
3520
3521   //=======================================================================
3522   // name    : toBool
3523   // Purpose : Convert LDOMString to bool
3524   //=======================================================================
3525   static inline bool toBool( const LDOMString& theStr )
3526   {
3527     return theStr.equals( "logical not" );
3528   }
3529
3530   //=======================================================================
3531   // name    : toString
3532   // Purpose : Convert double to LDOMString
3533   //=======================================================================
3534   static inline LDOMString toString( CORBA::Double val )
3535   {
3536     char a[ 255 ];
3537     sprintf( a, "%e", val );
3538     return LDOMString( a );
3539   }
3540
3541   //=======================================================================
3542   // name    : toDouble
3543   // Purpose : Convert LDOMString to double
3544   //=======================================================================
3545   static inline double toDouble( const LDOMString& theStr )
3546   {
3547     return atof( theStr.GetString() );
3548   }
3549
3550   //=======================================================================
3551   // name    : toString
3552   // Purpose : Convert functor type to LDOMString
3553   //=======================================================================
3554   static inline LDOMString toString( CORBA::Long theType )
3555   {
3556     switch ( theType )
3557     {
3558       case FT_AspectRatio           : return "Aspect ratio";
3559       case FT_Warping               : return "Warping";
3560       case FT_Warping3D             : return "Warping 3D";
3561       case FT_MinimumAngle          : return "Minimum angle";
3562       case FT_Taper                 : return "Taper";
3563       case FT_Skew                  : return "Skew";
3564       case FT_Area                  : return "Area";
3565       case FT_Volume3D              : return "Volume3D";
3566       case FT_ScaledJacobian        : return "ScaledJacobian";
3567       case FT_MaxElementLength2D    : return "Max element length 2D";
3568       case FT_MaxElementLength3D    : return "Max element length 3D";
3569       case FT_BelongToMeshGroup     : return "Belong to Mesh Group";
3570       case FT_BelongToGeom          : return "Belong to Geom";
3571       case FT_BelongToPlane         : return "Belong to Plane";
3572       case FT_BelongToCylinder      : return "Belong to Cylinder";
3573       case FT_BelongToGenSurface    : return "Belong to Generic Surface";
3574       case FT_LyingOnGeom           : return "Lying on Geom";
3575       case FT_BadOrientedVolume     : return "Bad Oriented Volume";
3576       case FT_BareBorderVolume      : return "Volumes with bare border";
3577       case FT_BareBorderFace        : return "Faces with bare border";
3578       case FT_OverConstrainedVolume : return "Over-constrained Volumes";
3579       case FT_OverConstrainedFace   : return "Over-constrained Faces";
3580       case FT_RangeOfIds            : return "Range of IDs";
3581       case FT_FreeBorders           : return "Free borders";
3582       case FT_FreeEdges             : return "Free edges";
3583       case FT_FreeFaces             : return "Free faces";
3584       case FT_FreeNodes             : return "Free nodes";
3585       case FT_EqualNodes            : return "Equal nodes";
3586       case FT_EqualEdges            : return "Equal edges";
3587       case FT_EqualFaces            : return "Equal faces";
3588       case FT_EqualVolumes          : return "Equal volumes";
3589       case FT_MultiConnection       : return "Borders at multi-connections";
3590       case FT_MultiConnection2D     : return "Borders at multi-connections 2D";
3591       case FT_Length                : return "Length";
3592       case FT_Length2D              : return "Length 2D";
3593       case FT_Length3D              : return "Length 3D";
3594       case FT_Deflection2D          : return "Deflection 2D";
3595       case FT_LessThan              : return "Less than";
3596       case FT_MoreThan              : return "More than";
3597       case FT_EqualTo               : return "Equal to";
3598       case FT_LogicalNOT            : return "Not";
3599       case FT_LogicalAND            : return "And";
3600       case FT_LogicalOR             : return "Or";
3601       case FT_GroupColor            : return "Color of Group";
3602       case FT_LinearOrQuadratic     : return "Linear or Quadratic";
3603       case FT_ElemGeomType          : return "Element geometry type";
3604       case FT_EntityType            : return "Entity type";
3605       case FT_Undefined             : return "";
3606       default                       : return "";
3607     }
3608   }
3609
3610   //=======================================================================
3611   // name    : toFunctorType
3612   // Purpose : Convert LDOMString to functor type
3613   //=======================================================================
3614   static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
3615   {
3616     if      ( theStr.equals( "Aspect ratio"                 ) ) return FT_AspectRatio;
3617     else if ( theStr.equals( "Warping"                      ) ) return FT_Warping;
3618     else if ( theStr.equals( "Warping 3D"                   ) ) return FT_Warping3D;
3619     else if ( theStr.equals( "Minimum angle"                ) ) return FT_MinimumAngle;
3620     else if ( theStr.equals( "Taper"                        ) ) return FT_Taper;
3621     else if ( theStr.equals( "Skew"                         ) ) return FT_Skew;
3622     else if ( theStr.equals( "Area"                         ) ) return FT_Area;
3623     else if ( theStr.equals( "Volume3D"                     ) ) return FT_Volume3D;
3624     else if ( theStr.equals( "ScaledJacobian"               ) ) return FT_ScaledJacobian;
3625     else if ( theStr.equals( "Max element length 2D"        ) ) return FT_MaxElementLength2D;
3626     else if ( theStr.equals( "Max element length 3D"        ) ) return FT_MaxElementLength3D;
3627     else if ( theStr.equals( "Belong to Mesh Group"         ) ) return FT_BelongToMeshGroup;
3628     else if ( theStr.equals( "Belong to Geom"               ) ) return FT_BelongToGeom;
3629     else if ( theStr.equals( "Belong to Plane"              ) ) return FT_BelongToPlane;
3630     else if ( theStr.equals( "Belong to Cylinder"           ) ) return FT_BelongToCylinder;
3631     else if ( theStr.equals( "Belong to Generic Surface"    ) ) return FT_BelongToGenSurface;
3632     else if ( theStr.equals( "Lying on Geom"                ) ) return FT_LyingOnGeom;
3633     else if ( theStr.equals( "Free borders"                 ) ) return FT_FreeBorders;
3634     else if ( theStr.equals( "Free edges"                   ) ) return FT_FreeEdges;
3635     else if ( theStr.equals( "Free faces"                   ) ) return FT_FreeFaces;
3636     else if ( theStr.equals( "Free nodes"                   ) ) return FT_FreeNodes;
3637     else if ( theStr.equals( "Equal nodes"                  ) ) return FT_EqualNodes;
3638     else if ( theStr.equals( "Equal edges"                  ) ) return FT_EqualEdges;
3639     else if ( theStr.equals( "Equal faces"                  ) ) return FT_EqualFaces;
3640     else if ( theStr.equals( "Equal volumes"                ) ) return FT_EqualVolumes;
3641     else if ( theStr.equals( "Borders at multi-connections" ) ) return FT_MultiConnection;
3642     //  else if ( theStr.equals( "Borders at multi-connections 2D" ) ) return FT_MultiConnection2D;
3643     else if ( theStr.equals( "Length"                       ) ) return FT_Length;
3644     //  else if ( theStr.equals( "Length2D"                     ) ) return FT_Length2D;
3645     //  else if ( theStr.equals( "Length3D"                     ) ) return FT_Length3D;
3646     else if ( theStr.equals( "Deflection"                   ) ) return FT_Deflection2D;
3647     else if ( theStr.equals( "Range of IDs"                 ) ) return FT_RangeOfIds;
3648     else if ( theStr.equals( "Bad Oriented Volume"          ) ) return FT_BadOrientedVolume;
3649     else if ( theStr.equals( "Volumes with bare border"     ) ) return FT_BareBorderVolume;
3650     else if ( theStr.equals( "Faces with bare border"       ) ) return FT_BareBorderFace;
3651     else if ( theStr.equals( "Over-constrained Volumes"     ) ) return FT_OverConstrainedVolume;
3652     else if ( theStr.equals( "Over-constrained Faces"       ) ) return FT_OverConstrainedFace;
3653     else if ( theStr.equals( "Less than"                    ) ) return FT_LessThan;
3654     else if ( theStr.equals( "More than"                    ) ) return FT_MoreThan;
3655     else if ( theStr.equals( "Equal to"                     ) ) return FT_EqualTo;
3656     else if ( theStr.equals( "Not"                          ) ) return FT_LogicalNOT;
3657     else if ( theStr.equals( "And"                          ) ) return FT_LogicalAND;
3658     else if ( theStr.equals( "Or"                           ) ) return FT_LogicalOR;
3659     else if ( theStr.equals( "Color of Group"               ) ) return FT_GroupColor;
3660     else if ( theStr.equals( "Linear or Quadratic"          ) ) return FT_LinearOrQuadratic;
3661     else if ( theStr.equals( "Element geometry type"        ) ) return FT_ElemGeomType;
3662     else if ( theStr.equals( "Entity type"                  ) ) return FT_EntityType;
3663     else if ( theStr.equals( ""                             ) ) return FT_Undefined;
3664     else  return FT_Undefined;
3665   }
3666
3667   //=======================================================================
3668   // name    : toFunctorType
3669   // Purpose : Convert LDOMString to value of ElementType enumeration
3670   //=======================================================================
3671   static inline SMESH::ElementType toElementType( const LDOMString& theStr )
3672   {
3673     if      ( theStr.equals( "NODE"   ) ) return SMESH::NODE;
3674     else if ( theStr.equals( "EDGE"   ) ) return SMESH::EDGE;
3675     else if ( theStr.equals( "FACE"   ) ) return SMESH::FACE;
3676     else if ( theStr.equals( "VOLUME" ) ) return SMESH::VOLUME;
3677     else                                  return SMESH::ALL;
3678   }
3679
3680   //=======================================================================
3681   // name    : toString
3682   // Purpose : Convert ElementType to string
3683   //=======================================================================
3684   static inline LDOMString toString( const SMESH::ElementType theType )
3685   {
3686     switch ( theType )
3687     {
3688       case SMESH::NODE   : return "NODE";
3689       case SMESH::EDGE   : return "EDGE";
3690       case SMESH::FACE   : return "FACE";
3691       case SMESH::VOLUME : return "VOLUME";
3692       case SMESH::ALL    : return "ALL";
3693       default            : return "";
3694     }
3695   }
3696
3697   //=======================================================================
3698   // name    : findFilter
3699   // Purpose : Find filter in document
3700   //=======================================================================
3701   static LDOM_Element findFilter( const char* theFilterName,
3702                                   const LDOM_Document& theDoc,
3703                                   LDOM_Node* theParent = 0 )
3704   {
3705     LDOM_Element aRootElement = theDoc.getDocumentElement();
3706     if ( aRootElement.isNull() || !aRootElement.hasChildNodes() )
3707       return LDOM_Element();
3708
3709     for ( LDOM_Node aTypeNode = aRootElement.getFirstChild();
3710           !aTypeNode.isNull(); aTypeNode = aTypeNode.getNextSibling() )
3711     {
3712       for ( LDOM_Node aFilter = aTypeNode.getFirstChild();
3713             !aFilter.isNull(); aFilter = aFilter.getNextSibling() )
3714       {
3715         LDOM_Element* anElem = ( LDOM_Element* )&aFilter;
3716         if ( anElem->getTagName().equals( LDOMString( "filter" ) ) &&
3717              anElem->getAttribute( "name" ).equals( LDOMString( theFilterName ) ) )
3718         {
3719           if ( theParent != 0  )
3720             *theParent = aTypeNode;
3721           return (LDOM_Element&)aFilter;
3722         }
3723       }
3724     }
3725     return LDOM_Element();
3726   }
3727
3728   //=======================================================================
3729   // name    : getSectionName
3730   // Purpose : Get name of section of filters
3731   //=======================================================================
3732   static const char* getSectionName( const ElementType theType )
3733   {
3734     switch ( theType )
3735     {
3736       case SMESH::NODE   : return "Filters for nodes";
3737       case SMESH::EDGE   : return "Filters for edges";
3738       case SMESH::FACE   : return "Filters for faces";
3739       case SMESH::VOLUME : return "Filters for volumes";
3740       case SMESH::ALL    : return "Filters for elements";
3741       default            : return "";
3742     }
3743   }
3744
3745   //=======================================================================
3746   // name    : getSection
3747   // Purpose : Create section for filters corresponding to the entity type
3748   //=======================================================================
3749   static LDOM_Node getSection( const ElementType theType,
3750                                LDOM_Document&    theDoc,
3751                                const bool        toCreate = false )
3752   {
3753     LDOM_Element aRootElement = theDoc.getDocumentElement();
3754     if ( aRootElement.isNull() )
3755       return LDOM_Node();
3756
3757     // Find section
3758     bool anExist = false;
3759     const char* aSectionName = getSectionName( theType );
3760     if ( strcmp( aSectionName, "" ) == 0 )
3761       return LDOM_Node();
3762
3763     LDOM_NodeList aSections = theDoc.getElementsByTagName( "section" );
3764     LDOM_Node aNode;
3765     for ( int i = 0, n = aSections.getLength(); i < n; i++ )
3766     {
3767       aNode = aSections.item( i );
3768       LDOM_Element& anItem = ( LDOM_Element& )aNode;
3769       if ( anItem.getAttribute( "name" ).equals( LDOMString( aSectionName ) ) )
3770       {
3771         anExist = true;
3772         break;
3773       }
3774     }
3775
3776     // Create new section if necessary
3777     if ( !anExist )
3778     {
3779       if ( toCreate )
3780       {
3781         LDOM_Element aNewItem = theDoc.createElement( "section" );
3782         aNewItem.setAttribute( "name", aSectionName );
3783         aRootElement.appendChild( aNewItem );
3784         return aNewItem;
3785       }
3786       else
3787         return LDOM_Node();
3788     }
3789     return
3790       aNode;
3791   }
3792
3793   //=======================================================================
3794   // name    : createFilterItem
3795   // Purpose : Create filter item or LDOM document
3796   //=======================================================================
3797   static LDOM_Element createFilterItem( const char*       theName,
3798                                         SMESH::Filter_ptr theFilter,
3799                                         LDOM_Document&    theDoc )
3800   {
3801     // create new filter in document
3802     LDOM_Element aFilterItem = theDoc.createElement( "filter" );
3803     aFilterItem.setAttribute( "name", theName );
3804
3805     // save filter criterions
3806     SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria;
3807
3808     if ( !theFilter->GetCriteria( aCriteria ) )
3809       return LDOM_Element();
3810
3811     for ( CORBA::ULong i = 0, n = aCriteria->length(); i < n; i++ )
3812     {
3813       LDOM_Element aCriterionItem = theDoc.createElement( "criterion" );
3814     
3815       aCriterionItem.setAttribute( ATTR_TYPE         , toString(  aCriteria[ i ].Type) );
3816       aCriterionItem.setAttribute( ATTR_COMPARE      , toString(  aCriteria[ i ].Compare ) );
3817       aCriterionItem.setAttribute( ATTR_THRESHOLD    , toString(  aCriteria[ i ].Threshold ) );
3818       aCriterionItem.setAttribute( ATTR_UNARY        , toString(  aCriteria[ i ].UnaryOp ) );
3819       aCriterionItem.setAttribute( ATTR_BINARY       , toString(  aCriteria[ i ].BinaryOp ) );
3820
3821       aCriterionItem.setAttribute( ATTR_THRESHOLD_STR, (const char*)aCriteria[ i ].ThresholdStr );
3822       aCriterionItem.setAttribute( ATTR_TOLERANCE    , toString( aCriteria[ i ].Tolerance ) );
3823       aCriterionItem.setAttribute( ATTR_ELEMENT_TYPE ,
3824         toString( (SMESH::ElementType)aCriteria[ i ].TypeOfElement ) );
3825
3826       aFilterItem.appendChild( aCriterionItem );
3827     }
3828
3829     return aFilterItem;
3830   }
3831
3832   //=======================================================================
3833   // name    : FilterLibrary_i::FilterLibrary_i
3834   // Purpose : Constructor
3835   //=======================================================================
3836   FilterLibrary_i::FilterLibrary_i( const char* theFileName )
3837   {
3838     myFileName = CORBA::string_dup( theFileName );
3839     SMESH::FilterManager_i* aFilterMgr = new SMESH::FilterManager_i();
3840     myFilterMgr = aFilterMgr->_this();
3841
3842     LDOMParser aParser;
3843
3844     // Try to use existing library file
3845     bool anExists = false;
3846     if ( !aParser.parse( myFileName ) )
3847     {
3848       myDoc = aParser.getDocument();
3849       anExists = true;
3850     }
3851     // Create a new XML document if it doesn't exist
3852     else
3853       myDoc = LDOM_Document::createDocument( LDOMString() );
3854
3855     LDOM_Element aRootElement = myDoc.getDocumentElement();
3856     if ( aRootElement.isNull() )
3857     {
3858       // If the existing document is empty --> try to create a new one
3859       if ( anExists )
3860         myDoc = LDOM_Document::createDocument( LDOMString() );
3861     }
3862   }
3863
3864   //=======================================================================
3865   // name    : FilterLibrary_i::FilterLibrary_i
3866   // Purpose : Constructor
3867   //=======================================================================
3868   FilterLibrary_i::FilterLibrary_i()
3869   {
3870     myFileName = 0;
3871     SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i();
3872     myFilterMgr = aFilter->_this();
3873
3874     myDoc = LDOM_Document::createDocument( LDOMString() );
3875   }
3876
3877   FilterLibrary_i::~FilterLibrary_i()
3878   {
3879     CORBA::string_free( myFileName );
3880     //TPythonDump()<<this<<".UnRegister()";
3881   }
3882
3883   //=======================================================================
3884   // name    : FilterLibrary_i::Copy
3885   // Purpose : Create filter and initialize it with values from library
3886   //=======================================================================
3887   Filter_ptr FilterLibrary_i::Copy( const char* theFilterName )
3888   {
3889     Filter_ptr aRes = Filter::_nil();
3890     LDOM_Node aFilter = findFilter( theFilterName, myDoc );
3891
3892     if ( aFilter.isNull() )
3893       return aRes;
3894
3895     std::list<SMESH::Filter::Criterion> aCriteria;
3896
3897     for ( LDOM_Node aCritNode = aFilter.getFirstChild();
3898           !aCritNode.isNull() ; aCritNode = aCritNode.getNextSibling() )
3899     {
3900       LDOM_Element* aCrit = (LDOM_Element*)&aCritNode;
3901
3902       const char* aTypeStr      = aCrit->getAttribute( ATTR_TYPE          ).GetString();
3903       const char* aCompareStr   = aCrit->getAttribute( ATTR_COMPARE       ).GetString();
3904       const char* aUnaryStr     = aCrit->getAttribute( ATTR_UNARY         ).GetString();
3905       const char* aBinaryStr    = aCrit->getAttribute( ATTR_BINARY        ).GetString();
3906       const char* anElemTypeStr = aCrit->getAttribute( ATTR_ELEMENT_TYPE  ).GetString();
3907
3908       SMESH::Filter::Criterion aCriterion = createCriterion();
3909
3910       aCriterion.Type          = toFunctorType( aTypeStr );
3911       aCriterion.Compare       = toFunctorType( aCompareStr );
3912       aCriterion.UnaryOp       = toFunctorType( aUnaryStr );
3913       aCriterion.BinaryOp      = toFunctorType( aBinaryStr );
3914
3915       aCriterion.TypeOfElement = toElementType( anElemTypeStr );
3916
3917       LDOMString str = aCrit->getAttribute( ATTR_THRESHOLD );
3918       int val = 0;
3919       aCriterion.Threshold = str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val )
3920         ? val : atof( str.GetString() );
3921
3922       str = aCrit->getAttribute( ATTR_TOLERANCE );
3923       aCriterion.Tolerance = str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val )
3924         ? val : atof( str.GetString() );
3925
3926       str = aCrit->getAttribute( ATTR_THRESHOLD_STR );
3927       if ( str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val ) )
3928       {
3929         char a[ 255 ];
3930         sprintf( a, "%d", val );
3931         aCriterion.ThresholdStr = CORBA::string_dup( a );
3932       }
3933       else
3934         aCriterion.ThresholdStr = str.GetString();
3935
3936       aCriteria.push_back( aCriterion );
3937     }
3938
3939     SMESH::Filter::Criteria_var aCriteriaVar = new SMESH::Filter::Criteria;
3940     aCriteriaVar->length( aCriteria.size() );
3941
3942     CORBA::ULong i = 0;
3943     std::list<SMESH::Filter::Criterion>::iterator anIter = aCriteria.begin();
3944
3945     for( ; anIter != aCriteria.end(); ++anIter )
3946       aCriteriaVar[ i++ ] = *anIter;
3947
3948     aRes = myFilterMgr->CreateFilter();
3949     aRes->SetCriteria( aCriteriaVar.inout() );
3950
3951     TPythonDump()<<this<<".Copy('"<<theFilterName<<"')";
3952
3953     return aRes;
3954   }
3955
3956   //=======================================================================
3957   // name    : FilterLibrary_i::SetFileName
3958   // Purpose : Set file name for library
3959   //=======================================================================
3960   void FilterLibrary_i::SetFileName( const char* theFileName )
3961   {
3962     CORBA::string_free( myFileName );
3963     myFileName = CORBA::string_dup( theFileName );
3964     TPythonDump()<<this<<".SetFileName('"<<theFileName<<"')";
3965   }
3966
3967   //=======================================================================
3968   // name    : FilterLibrary_i::GetFileName
3969   // Purpose : Get file name of library
3970   //=======================================================================
3971   char* FilterLibrary_i::GetFileName()
3972   {
3973     return CORBA::string_dup( myFileName );
3974   }
3975
3976   //=======================================================================
3977   // name    : FilterLibrary_i::Add
3978   // Purpose : Add new filter to library
3979   //=======================================================================
3980   CORBA::Boolean FilterLibrary_i::Add( const char* theFilterName, Filter_ptr theFilter )
3981   {
3982     // if filter already in library or entry filter is null do nothing
3983     LDOM_Node aFilterNode = findFilter( theFilterName, myDoc );
3984     if ( !aFilterNode.isNull() || theFilter->_is_nil() )
3985       return false;
3986
3987     // get section corresponding to the filter type
3988     ElementType anEntType = theFilter->GetElementType();
3989
3990     LDOM_Node aSection = getSection( anEntType, myDoc, true );
3991     if ( aSection.isNull() )
3992       return false;
3993
3994     // create filter item
3995     LDOM_Element aFilterItem = createFilterItem( theFilterName, theFilter, myDoc );
3996     if ( aFilterItem.isNull() )
3997       return false;
3998     else
3999     {
4000       aSection.appendChild( aFilterItem );
4001       if(Filter_i* aFilter = DownCast<Filter_i*>(theFilter))
4002         TPythonDump()<<this<<".Add('"<<theFilterName<<"',"<<aFilter<<")";
4003       return true;
4004     }
4005   }
4006
4007   //=======================================================================
4008   // name    : FilterLibrary_i::Add
4009   // Purpose : Add new filter to library
4010   //=======================================================================
4011   CORBA::Boolean FilterLibrary_i::AddEmpty( const char* theFilterName, ElementType theType )
4012   {
4013     // if filter already in library or entry filter is null do nothing
4014     LDOM_Node aFilterNode = findFilter( theFilterName, myDoc );
4015     if ( !aFilterNode.isNull() )
4016       return false;
4017
4018     LDOM_Node aSection = getSection( theType, myDoc, true );
4019     if ( aSection.isNull() )
4020       return false;
4021
4022     // create filter item
4023     Filter_var aFilter = myFilterMgr->CreateFilter();
4024
4025     LDOM_Element aFilterItem = createFilterItem( theFilterName, aFilter, myDoc );
4026     if ( aFilterItem.isNull() )
4027       return false;
4028     else
4029     {
4030       aSection.appendChild( aFilterItem );
4031       TPythonDump()<<this<<".AddEmpty('"<<theFilterName<<"',"<<theType<<")";
4032       return true;
4033     }
4034   }
4035
4036   //=======================================================================
4037   // name    : FilterLibrary_i::Delete
4038   // Purpose : Delete filter from library
4039   //=======================================================================
4040   CORBA::Boolean FilterLibrary_i::Delete ( const char* theFilterName )
4041   {
4042     LDOM_Node aParentNode;
4043     LDOM_Node aFilterNode = findFilter( theFilterName, myDoc, &aParentNode );
4044     if ( aFilterNode.isNull() || aParentNode.isNull() )
4045       return false;
4046
4047     aParentNode.removeChild( aFilterNode );
4048     TPythonDump()<<this<<".Delete('"<<theFilterName<<"')";
4049     return true;
4050   }
4051
4052   //=======================================================================
4053   // name      : FilterLibrary_i::Replace
4054   // Purpose   : Replace existing filter with entry filter.
4055   // IMPORTANT : If filter does not exist it is not created
4056   //=======================================================================
4057   CORBA::Boolean FilterLibrary_i::Replace( const char* theFilterName,
4058                                            const char* theNewName,
4059                                            Filter_ptr  theFilter )
4060   {
4061     LDOM_Element aFilterItem = findFilter( theFilterName, myDoc );
4062     if ( aFilterItem.isNull() || theFilter->_is_nil() )
4063       return false;
4064
4065     LDOM_Element aNewItem = createFilterItem( theNewName, theFilter, myDoc );
4066     if ( aNewItem.isNull() )
4067       return false;
4068     else
4069     {
4070       aFilterItem.ReplaceElement( aNewItem );
4071       if(Filter_i* aFilter = DownCast<Filter_i*>(theFilter))
4072         TPythonDump()<<this<<".Replace('"<<theFilterName<<"','"<<theNewName<<"',"<<aFilter<<")";
4073       return true;
4074     }
4075   }
4076
4077   //=======================================================================
4078   // name    : FilterLibrary_i::Save
4079   // Purpose : Save library on disk
4080   //=======================================================================
4081   CORBA::Boolean FilterLibrary_i::Save()
4082   {
4083     if ( myFileName == 0 || strlen( myFileName ) == 0 )
4084       return false;
4085
4086     std::filebuf fb;
4087     fb.open( myFileName, std::ios::out );
4088
4089     Standard_OStream os( &fb );
4090
4091     LDOM_XmlWriter aWriter;
4092     aWriter.SetIndentation( 2 );
4093     aWriter.Write( os, myDoc );
4094     fb.close();
4095
4096     TPythonDump()<<this<<".Save()";
4097     return true;
4098   }
4099
4100   //=======================================================================
4101   // name    : FilterLibrary_i::SaveAs
4102   // Purpose : Save library on disk
4103   //=======================================================================
4104   CORBA::Boolean FilterLibrary_i::SaveAs( const char* aFileName )
4105   {
4106     myFileName = strdup ( aFileName );
4107     TPythonDump()<<this<<".SaveAs('"<<aFileName<<"')";
4108     return Save();
4109   }
4110
4111   //=======================================================================
4112   // name    : FilterLibrary_i::IsPresent
4113   // Purpose : Verify whether filter is in library
4114   //=======================================================================
4115   CORBA::Boolean FilterLibrary_i::IsPresent( const char* theFilterName )
4116   {
4117     return !findFilter( theFilterName, myDoc ).isNull();
4118   }
4119
4120   //=======================================================================
4121   // name    : FilterLibrary_i::NbFilters
4122   // Purpose : Return amount of filters in library
4123   //=======================================================================
4124   CORBA::Long FilterLibrary_i::NbFilters( ElementType theType )
4125   {
4126     string_array_var aNames = GetNames( theType );
4127     return aNames->length();
4128   }
4129
4130   //=======================================================================
4131   // name    : FilterLibrary_i::GetNames
4132   // Purpose : Get names of filters from library
4133   //=======================================================================
4134   string_array* FilterLibrary_i::GetNames( ElementType theType )
4135   {
4136     string_array_var anArray = new string_array;
4137     TColStd_SequenceOfHAsciiString aSeq;
4138
4139     LDOM_Node aSection = getSection( theType, myDoc, false );
4140
4141     if ( !aSection.isNull() )
4142     {
4143       for ( LDOM_Node aFilter = aSection.getFirstChild();
4144             !aFilter.isNull(); aFilter = aFilter.getNextSibling() )
4145       {
4146         LDOM_Element& anElem = ( LDOM_Element& )aFilter;
4147         aSeq.Append( new TCollection_HAsciiString(
4148            (Standard_CString)anElem.getAttribute( "name" ).GetString() ) );
4149       }
4150     }
4151
4152     anArray->length( aSeq.Length() );
4153     for ( int i = 1, n = aSeq.Length(); i <= n; i++ )
4154       anArray[ i - 1 ] = CORBA::string_dup( aSeq( i )->ToCString() );
4155
4156     return anArray._retn();
4157   }
4158
4159   //=======================================================================
4160   // name    : FilterLibrary_i::GetAllNames
4161   // Purpose : Get names of filters from library
4162   //=======================================================================
4163   string_array* FilterLibrary_i::GetAllNames()
4164   {
4165     string_array_var aResArray = new string_array;
4166     for ( int type = SMESH::ALL; type <= SMESH::VOLUME; type++ )
4167     {
4168       SMESH::string_array_var aNames = GetNames( (SMESH::ElementType)type );
4169
4170       int aPrevLength = aResArray->length();
4171       aResArray->length( aPrevLength + aNames->length() );
4172       for ( int i = 0, n = aNames->length(); i < n; i++ )
4173         aResArray[ aPrevLength + i ] = aNames[ i ];
4174     }
4175
4176     return aResArray._retn();
4177   }
4178
4179   //================================================================================
4180   /*!
4181    * \brief Return an array of strings corresponding to items of enum FunctorType
4182    */
4183   //================================================================================
4184
4185   static const char** getFunctNames()
4186   {
4187     static const char* functName[] = {
4188       // IT's necessary to update this array according to enum FunctorType (SMESH_Filter.idl)
4189       // The order is IMPORTANT !!!
4190       "FT_AspectRatio",
4191       "FT_AspectRatio3D",
4192       "FT_Warping",
4193       "FT_Warping3D",
4194       "FT_MinimumAngle",
4195       "FT_Taper",
4196       "FT_Skew",
4197       "FT_Area",
4198       "FT_Volume3D",
4199       "FT_ScaledJacobian",
4200       "FT_MaxElementLength2D",
4201       "FT_MaxElementLength3D",
4202       "FT_FreeBorders",
4203       "FT_FreeEdges",
4204       "FT_FreeNodes",
4205       "FT_FreeFaces",
4206       "FT_EqualNodes",
4207       "FT_EqualEdges",
4208       "FT_EqualFaces",
4209       "FT_EqualVolumes",
4210       "FT_MultiConnection",
4211       "FT_MultiConnection2D",
4212       "FT_Length",
4213       "FT_Length2D",
4214       "FT_Length3D",
4215       "FT_Deflection2D",
4216       "FT_NodeConnectivityNumber",
4217       "FT_BelongToMeshGroup",
4218       "FT_BelongToGeom",
4219       "FT_BelongToPlane",
4220       "FT_BelongToCylinder",
4221       "FT_BelongToGenSurface",
4222       "FT_LyingOnGeom",
4223       "FT_RangeOfIds",
4224       "FT_BadOrientedVolume",
4225       "FT_BareBorderVolume",
4226       "FT_BareBorderFace",
4227       "FT_OverConstrainedVolume",
4228       "FT_OverConstrainedFace",
4229       "FT_LinearOrQuadratic",
4230       "FT_GroupColor",
4231       "FT_ElemGeomType",
4232       "FT_EntityType",
4233       "FT_CoplanarFaces",
4234       "FT_BallDiameter",
4235       "FT_ConnectedElements",
4236       "FT_LessThan",
4237       "FT_MoreThan",
4238       "FT_EqualTo",
4239       "FT_LogicalNOT",
4240       "FT_LogicalAND",
4241       "FT_LogicalOR",
4242       "FT_Undefined"};
4243
4244     // check if functName is complete, compilation failure means that enum FunctorType changed
4245     static_assert( sizeof(functName) / sizeof(const char*) == SMESH::FT_Undefined + 1,
4246                    "Update names of FunctorType's!!!" );
4247
4248     return functName;
4249   }
4250
4251   //================================================================================
4252   /*!
4253    * \brief Return a string corresponding to an item of enum FunctorType
4254    */
4255   //================================================================================
4256
4257   const char* FunctorTypeToString(FunctorType ft)
4258   {
4259     if ( ft < 0 || ft > SMESH::FT_Undefined )
4260       return "FT_Undefined";
4261     return getFunctNames()[ ft ];
4262   }
4263
4264   //================================================================================
4265   /*!
4266    * \brief Converts a string to FunctorType. This is reverse of FunctorTypeToString()
4267    */
4268   //================================================================================
4269
4270   FunctorType StringToFunctorType(const char* str)
4271   {
4272     std::string name( str + 3 ); // skip "FT_"
4273     const char** functNames = getFunctNames();
4274     int ft = 0;
4275     for ( ; ft < SMESH::FT_Undefined; ++ft )
4276       if ( name == ( functNames[ft] + 3 ))
4277         break;
4278
4279     //ASSERT( strcmp( str, FunctorTypeToString( SMESH::FunctorType( ft ))) == 0 );
4280
4281     return SMESH::FunctorType( ft );
4282   }
4283
4284   //================================================================================
4285   /*!
4286    * \brief calls OnBaseObjModified(), if who != this, and myWaiters[i]->Modified(who)
4287    */
4288   //================================================================================
4289
4290   void NotifyerAndWaiter::Modified( bool removed, NotifyerAndWaiter* who )
4291   {
4292     if ( who != 0 && who != this )
4293       OnBaseObjModified( who, removed );
4294     else
4295       who = this;
4296
4297     std::list<NotifyerAndWaiter*> waiters = myWaiters; // myWaiters can be changed by Modified()
4298     std::list<NotifyerAndWaiter*>::iterator i = waiters.begin();
4299     for ( ; i != waiters.end(); ++i )
4300       (*i)->Modified( removed, who );
4301   }
4302
4303   //================================================================================
4304   /*!
4305    * \brief Stores an object to be notified on change of predicate
4306    */
4307   //================================================================================
4308
4309   void NotifyerAndWaiter::AddModifWaiter( NotifyerAndWaiter* waiter )
4310   {
4311     if ( waiter )
4312       myWaiters.push_back( waiter );
4313   }
4314
4315   //================================================================================
4316   /*!
4317    * \brief Removes an object to be notified on change of predicate
4318    */
4319   //================================================================================
4320
4321   void NotifyerAndWaiter::RemoveModifWaiter( NotifyerAndWaiter* waiter )
4322   {
4323     myWaiters.remove( waiter );
4324   }
4325
4326   //================================================================================
4327   /*!
4328    * \brief Checks if a waiter is among myWaiters, maybe nested
4329    */
4330   //================================================================================
4331
4332   bool NotifyerAndWaiter::ContainModifWaiter( NotifyerAndWaiter* waiter )
4333   {
4334     bool is = ( waiter == this );
4335
4336     std::list<NotifyerAndWaiter*>::iterator w = myWaiters.begin();
4337     for ( ; !is && w != myWaiters.end(); ++w )
4338       is = (*w)->ContainModifWaiter( waiter );
4339
4340     return is;
4341   }
4342 }