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