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