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