Salome HOME
Merge from V6_main 11/02/2013
[modules/smesh.git] / src / SMESH_I / SMESH_Filter_i.cxx
1 // Copyright (C) 2007-2012  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 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
23 //  File   : SMESH_Filter_i.cxx
24 //  Author : Alexey Petrov, OCC
25 //  Module : SMESH
26
27 #include "SMESH_Filter_i.hxx"
28
29 #include "SMDS_ElemIterator.hxx"
30 #include "SMDS_Mesh.hxx"
31 #include "SMDS_MeshElement.hxx"
32 #include "SMDS_MeshNode.hxx"
33 #include "SMESHDS_Mesh.hxx"
34 #include "SMESH_Gen_i.hxx"
35 #include "SMESH_PythonDump.hxx"
36
37 #include <SALOMEDS_wrap.hxx>
38
39 #include <BRep_Tool.hxx>
40 #include <Geom_CylindricalSurface.hxx>
41 #include <Geom_Plane.hxx>
42 #include <LDOMParser.hxx>
43 #include <LDOMString.hxx>
44 #include <LDOM_Document.hxx>
45 #include <LDOM_Element.hxx>
46 #include <LDOM_Node.hxx>
47 #include <LDOM_XmlWriter.hxx>
48 #include <Precision.hxx>
49 #include <TColStd_ListIteratorOfListOfInteger.hxx>
50 #include <TColStd_ListIteratorOfListOfReal.hxx>
51 #include <TColStd_ListOfInteger.hxx>
52 #include <TColStd_ListOfReal.hxx>
53 #include <TColStd_SequenceOfHAsciiString.hxx>
54 #include <TCollection_HAsciiString.hxx>
55 #include <TopExp.hxx>
56 #include <TopExp_Explorer.hxx>
57 #include <TopoDS.hxx>
58 #include <TopoDS_Face.hxx>
59 #include <TopoDS_Shape.hxx>
60 #include <TopTools_IndexedMapOfShape.hxx>
61
62 using namespace SMESH;
63 using namespace SMESH::Controls;
64
65
66 namespace SMESH
67 {
68   Predicate_i*
69   GetPredicate( Predicate_ptr thePredicate )
70   {
71     return DownCast<Predicate_i*>(thePredicate);
72   }
73 }
74
75
76 /*
77   Class       : BelongToGeom
78   Description : Predicate for verifying whether entity belongs to
79                 specified geometrical support
80 */
81
82 Controls::BelongToGeom::BelongToGeom()
83   : myMeshDS(NULL),
84     myType(SMDSAbs_All),
85     myIsSubshape(false),
86     myTolerance(Precision::Confusion())
87 {}
88
89 void Controls::BelongToGeom::SetMesh( const SMDS_Mesh* theMesh )
90 {
91   myMeshDS = dynamic_cast<const SMESHDS_Mesh*>(theMesh);
92   init();
93 }
94
95 void Controls::BelongToGeom::SetGeom( const TopoDS_Shape& theShape )
96 {
97   myShape = theShape;
98   init();
99 }
100
101 static bool IsSubShape (const TopTools_IndexedMapOfShape& theMap,
102                         const TopoDS_Shape& theShape)
103 {
104   if (theMap.Contains(theShape)) return true;
105
106   if (theShape.ShapeType() == TopAbs_COMPOUND ||
107       theShape.ShapeType() == TopAbs_COMPSOLID)
108   {
109     TopoDS_Iterator anIt (theShape, Standard_True, Standard_True);
110     for (; anIt.More(); anIt.Next())
111     {
112       if (!IsSubShape(theMap, anIt.Value())) {
113         return false;
114       }
115     }
116     return true;
117   }
118
119   return false;
120 }
121
122 void Controls::BelongToGeom::init()
123 {
124   if (!myMeshDS || myShape.IsNull()) return;
125
126   // is sub-shape of main shape?
127   TopoDS_Shape aMainShape = myMeshDS->ShapeToMesh();
128   if (aMainShape.IsNull()) {
129     myIsSubshape = false;
130   }
131   else {
132     TopTools_IndexedMapOfShape aMap;
133     TopExp::MapShapes(aMainShape, aMap);
134     myIsSubshape = IsSubShape(aMap, myShape);
135   }
136
137   if (!myIsSubshape)
138   {
139     myElementsOnShapePtr.reset(new Controls::ElementsOnShape());
140     myElementsOnShapePtr->SetTolerance(myTolerance);
141     myElementsOnShapePtr->SetAllNodes(true); // belong, while false means "lays on"
142     myElementsOnShapePtr->SetMesh(myMeshDS);
143     myElementsOnShapePtr->SetShape(myShape, myType);
144   }
145 }
146
147 static bool IsContains( const SMESHDS_Mesh*     theMeshDS,
148                         const TopoDS_Shape&     theShape,
149                         const SMDS_MeshElement* theElem,
150                         TopAbs_ShapeEnum        theFindShapeEnum,
151                         TopAbs_ShapeEnum        theAvoidShapeEnum = TopAbs_SHAPE )
152 {
153   TopExp_Explorer anExp( theShape,theFindShapeEnum,theAvoidShapeEnum );
154
155   while( anExp.More() )
156   {
157     const TopoDS_Shape& aShape = anExp.Current();
158     if( SMESHDS_SubMesh* aSubMesh = theMeshDS->MeshElements( aShape ) ){
159       if( aSubMesh->Contains( theElem ) )
160         return true;
161     }
162     anExp.Next();
163   }
164   return false;
165 }
166
167 bool Controls::BelongToGeom::IsSatisfy (long theId)
168 {
169   if (myMeshDS == 0 || myShape.IsNull())
170     return false;
171
172   if (!myIsSubshape)
173   {
174     return myElementsOnShapePtr->IsSatisfy(theId);
175   }
176
177   // Case of submesh
178   if (myType == SMDSAbs_Node)
179   {
180     if( const SMDS_MeshNode* aNode = myMeshDS->FindNode( theId ) )
181     {
182       const SMDS_PositionPtr& aPosition = aNode->GetPosition();
183       SMDS_TypeOfPosition aTypeOfPosition = aPosition->GetTypeOfPosition();
184       switch( aTypeOfPosition )
185       {
186       case SMDS_TOP_VERTEX : return IsContains( myMeshDS,myShape,aNode,TopAbs_VERTEX );
187       case SMDS_TOP_EDGE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_EDGE );
188       case SMDS_TOP_FACE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_FACE );
189       case SMDS_TOP_3DSPACE: return IsContains( myMeshDS,myShape,aNode,TopAbs_SHELL );
190       }
191     }
192   }
193   else
194   {
195     if( const SMDS_MeshElement* anElem = myMeshDS->FindElement( theId ) )
196     {
197       if( myType == SMDSAbs_All )
198       {
199         return IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE ) ||
200                IsContains( myMeshDS,myShape,anElem,TopAbs_FACE ) ||
201                IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
202                IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID );
203       }
204       else if( myType == anElem->GetType() )
205       {
206         switch( myType )
207         {
208         case SMDSAbs_Edge  : return IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE );
209         case SMDSAbs_Face  : return IsContains( myMeshDS,myShape,anElem,TopAbs_FACE );
210         case SMDSAbs_Volume: return IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
211                                     IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID );
212         }
213       }
214     }
215   }
216
217   return false;
218 }
219
220 void Controls::BelongToGeom::SetType (SMDSAbs_ElementType theType)
221 {
222   myType = theType;
223   init();
224 }
225
226 SMDSAbs_ElementType Controls::BelongToGeom::GetType() const
227 {
228   return myType;
229 }
230
231 TopoDS_Shape Controls::BelongToGeom::GetShape()
232 {
233   return myShape;
234 }
235
236 const SMESHDS_Mesh* Controls::BelongToGeom::GetMeshDS() const
237 {
238   return myMeshDS;
239 }
240
241 void Controls::BelongToGeom::SetTolerance (double theTolerance)
242 {
243   myTolerance = theTolerance;
244   if (!myIsSubshape)
245     init();
246 }
247
248 double Controls::BelongToGeom::GetTolerance()
249 {
250   return myTolerance;
251 }
252
253 /*
254   Class       : LyingOnGeom
255   Description : Predicate for verifying whether entiy lying or partially lying on
256                 specified geometrical support
257 */
258
259 Controls::LyingOnGeom::LyingOnGeom()
260   : myMeshDS(NULL),
261     myType(SMDSAbs_All),
262     myIsSubshape(false),
263     myTolerance(Precision::Confusion())
264 {}
265
266 void Controls::LyingOnGeom::SetMesh( const SMDS_Mesh* theMesh )
267 {
268   myMeshDS = dynamic_cast<const SMESHDS_Mesh*>(theMesh);
269   init();
270 }
271
272 void Controls::LyingOnGeom::SetGeom( const TopoDS_Shape& theShape )
273 {
274   myShape = theShape;
275   init();
276 }
277
278 void Controls::LyingOnGeom::init()
279 {
280   if (!myMeshDS || myShape.IsNull()) return;
281
282   // is sub-shape of main shape?
283   TopoDS_Shape aMainShape = myMeshDS->ShapeToMesh();
284   if (aMainShape.IsNull()) {
285     myIsSubshape = false;
286   }
287   else {
288     TopTools_IndexedMapOfShape aMap;
289     TopExp::MapShapes(aMainShape, aMap);
290     myIsSubshape = IsSubShape(aMap, myShape);
291   }
292
293   if (!myIsSubshape)
294   {
295     myElementsOnShapePtr.reset(new Controls::ElementsOnShape());
296     myElementsOnShapePtr->SetTolerance(myTolerance);
297     myElementsOnShapePtr->SetAllNodes(false); // lays on, while true means "belong"
298     myElementsOnShapePtr->SetMesh(myMeshDS);
299     myElementsOnShapePtr->SetShape(myShape, myType);
300   }
301 }
302
303 bool Controls::LyingOnGeom::IsSatisfy( long theId )
304 {
305   if ( myMeshDS == 0 || myShape.IsNull() )
306     return false;
307
308   if (!myIsSubshape)
309   {
310     return myElementsOnShapePtr->IsSatisfy(theId);
311   }
312
313   // Case of submesh
314   if( myType == SMDSAbs_Node )
315   {
316     if( const SMDS_MeshNode* aNode = myMeshDS->FindNode( theId ) )
317     {
318       const SMDS_PositionPtr& aPosition = aNode->GetPosition();
319       SMDS_TypeOfPosition aTypeOfPosition = aPosition->GetTypeOfPosition();
320       switch( aTypeOfPosition )
321       {
322       case SMDS_TOP_VERTEX : return IsContains( myMeshDS,myShape,aNode,TopAbs_VERTEX );
323       case SMDS_TOP_EDGE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_EDGE );
324       case SMDS_TOP_FACE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_FACE );
325       case SMDS_TOP_3DSPACE: return IsContains( myMeshDS,myShape,aNode,TopAbs_SHELL );
326       }
327     }
328   }
329   else
330   {
331     if( const SMDS_MeshElement* anElem = myMeshDS->FindElement( theId ) )
332     {
333       if( myType == SMDSAbs_All )
334       {
335         return Contains( myMeshDS,myShape,anElem,TopAbs_EDGE ) ||
336                Contains( myMeshDS,myShape,anElem,TopAbs_FACE ) ||
337                Contains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
338                Contains( myMeshDS,myShape,anElem,TopAbs_SOLID );
339       }
340       else if( myType == anElem->GetType() )
341       {
342         switch( myType )
343         {
344         case SMDSAbs_Edge  : return Contains( myMeshDS,myShape,anElem,TopAbs_EDGE );
345         case SMDSAbs_Face  : return Contains( myMeshDS,myShape,anElem,TopAbs_FACE );
346         case SMDSAbs_Volume: return Contains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
347                                     Contains( myMeshDS,myShape,anElem,TopAbs_SOLID );
348         }
349       }
350     }
351   }
352
353   return false;
354 }
355
356 void Controls::LyingOnGeom::SetType( SMDSAbs_ElementType theType )
357 {
358   myType = theType;
359   init();
360 }
361
362 SMDSAbs_ElementType Controls::LyingOnGeom::GetType() const
363 {
364   return myType;
365 }
366
367 TopoDS_Shape Controls::LyingOnGeom::GetShape()
368 {
369   return myShape;
370 }
371
372 const SMESHDS_Mesh* Controls::LyingOnGeom::GetMeshDS() const
373 {
374   return myMeshDS;
375 }
376
377 void Controls::LyingOnGeom::SetTolerance (double theTolerance)
378 {
379   myTolerance = theTolerance;
380   if (!myIsSubshape)
381     init();
382 }
383
384 double Controls::LyingOnGeom::GetTolerance()
385 {
386   return myTolerance;
387 }
388
389 bool Controls::LyingOnGeom::Contains( const SMESHDS_Mesh*     theMeshDS,
390                                       const TopoDS_Shape&     theShape,
391                                       const SMDS_MeshElement* theElem,
392                                       TopAbs_ShapeEnum        theFindShapeEnum,
393                                       TopAbs_ShapeEnum        theAvoidShapeEnum )
394 {
395   if (IsContains(theMeshDS, theShape, theElem, theFindShapeEnum, theAvoidShapeEnum))
396     return true;
397
398   TopTools_IndexedMapOfShape aSubShapes;
399   TopExp::MapShapes( theShape, aSubShapes );
400
401   for (int i = 1; i <= aSubShapes.Extent(); i++)
402   {
403     const TopoDS_Shape& aShape = aSubShapes.FindKey(i);
404
405     if( SMESHDS_SubMesh* aSubMesh = theMeshDS->MeshElements( aShape ) ){
406       if( aSubMesh->Contains( theElem ) )
407         return true;
408
409       SMDS_NodeIteratorPtr aNodeIt = aSubMesh->GetNodes();
410       while ( aNodeIt->more() )
411       {
412         const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(aNodeIt->next());
413         SMDS_ElemIteratorPtr anElemIt = aNode->GetInverseElementIterator();
414         while ( anElemIt->more() )
415         {
416           const SMDS_MeshElement* anElement = static_cast<const SMDS_MeshElement*>(anElemIt->next());
417           if (anElement == theElem)
418             return true;
419         }
420       }
421     }
422   }
423   return false;
424 }
425
426
427 /*
428                             AUXILIARY METHODS
429 */
430
431 inline
432 const SMDS_Mesh*
433 MeshPtr2SMDSMesh( SMESH_Mesh_ptr theMesh )
434 {
435   SMESH_Mesh_i* anImplPtr = DownCast<SMESH_Mesh_i*>(theMesh);
436   return anImplPtr ? anImplPtr->GetImpl().GetMeshDS() : 0;
437 }
438
439 inline
440 SMESH::long_array*
441 toArray( const TColStd_ListOfInteger& aList )
442 {
443   SMESH::long_array_var anArray = new SMESH::long_array;
444   anArray->length( aList.Extent() );
445   TColStd_ListIteratorOfListOfInteger anIter( aList );
446   int i = 0;
447   for( ; anIter.More(); anIter.Next() )
448     anArray[ i++ ] = anIter.Value();
449
450   return anArray._retn();
451 }
452
453 inline
454 SMESH::double_array*
455 toArray( const TColStd_ListOfReal& aList )
456 {
457   SMESH::double_array_var anArray = new SMESH::double_array;
458   anArray->length( aList.Extent() );
459   TColStd_ListIteratorOfListOfReal anIter( aList );
460   int i = 0;
461   for( ; anIter.More(); anIter.Next() )
462     anArray[ i++ ] = anIter.Value();
463
464   return anArray._retn();
465 }
466
467 static SMESH::Filter::Criterion createCriterion()
468 {
469   SMESH::Filter::Criterion aCriterion;
470
471   aCriterion.Type          = FT_Undefined;
472   aCriterion.Compare       = FT_Undefined;
473   aCriterion.Threshold     = 0;
474   aCriterion.UnaryOp       = FT_Undefined;
475   aCriterion.BinaryOp      = FT_Undefined;
476   aCriterion.ThresholdStr  = "";
477   aCriterion.ThresholdID   = "";
478   aCriterion.Tolerance     = Precision::Confusion();
479   aCriterion.TypeOfElement = SMESH::ALL;
480   aCriterion.Precision     = -1;
481
482   return aCriterion;
483 }
484
485 static TopoDS_Shape getShapeByName( const char* theName )
486 {
487   if ( theName != 0 )
488   {
489     SMESH_Gen_i* aSMESHGen     = SMESH_Gen_i::GetSMESHGen();
490     SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy();
491     if ( !aStudy->_is_nil() )
492     {
493       SALOMEDS::Study::ListOfSObject_var aList = aStudy->FindObjectByName( theName, "GEOM" );
494       if ( aList->length() > 0 )
495       {
496         CORBA::Object_var        anObj = aList[ 0 ]->GetObject();
497         GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( anObj );
498         TopoDS_Shape             shape = aSMESHGen->GeomObjectToShape( aGeomObj );
499         SALOME::UnRegister( aList ); // UnRegister() objects in aList
500         return shape;
501       }
502     }
503   }
504   return TopoDS_Shape();
505 }
506
507 static TopoDS_Shape getShapeByID (const char* theID)
508 {
509   if ( theID && strlen( theID ) > 0 ) {
510     SMESH_Gen_i*     aSMESHGen = SMESH_Gen_i::GetSMESHGen();
511     SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy();
512     if ( !aStudy->_is_nil() ) {
513       SALOMEDS::SObject_wrap aSObj = aStudy->FindObjectID(theID);
514       if ( !aSObj->_is_nil() ) {
515         CORBA::Object_var          obj = aSObj->GetObject();
516         GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(obj);
517         return aSMESHGen->GeomObjectToShape( aGeomObj );
518       }
519     }
520   }
521   return TopoDS_Shape();
522 }
523
524 static std::string getShapeNameByID (const char* theID)
525 {
526   if ( theID && strlen( theID ) > 0 ) {
527     SMESH_Gen_i*     aSMESHGen = SMESH_Gen_i::GetSMESHGen();
528     SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy();
529     if ( !aStudy->_is_nil() ) {
530       SALOMEDS::SObject_wrap aSObj = aStudy->FindObjectID(theID);
531       if ( !aSObj->_is_nil() ) {
532         CORBA::String_var name = aSObj->GetName();
533         return name.in();
534       }
535     }
536   }
537   return "";
538 }
539
540 /*
541                                 FUNCTORS
542 */
543
544 /*
545   Class       : Functor_i
546   Description : An abstact class for all functors
547 */
548 Functor_i::Functor_i():
549   SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
550 {
551   //Base class Salome_GenericObject do it inmplicitly by overriding PortableServer::POA_ptr _default_POA() method  
552   //PortableServer::ObjectId_var anObjectId =
553   //  SMESH_Gen_i::GetPOA()->activate_object( this );
554 }
555
556 Functor_i::~Functor_i()
557 {
558   //TPythonDump()<<this<<".UnRegister()";
559 }
560
561 void Functor_i::SetMesh( SMESH_Mesh_ptr theMesh )
562 {
563   myFunctorPtr->SetMesh( MeshPtr2SMDSMesh( theMesh ) );
564   TPythonDump()<<this<<".SetMesh("<<theMesh<<")";
565 }
566
567 ElementType Functor_i::GetElementType()
568 {
569   return ( ElementType )myFunctorPtr->GetType();
570 }
571
572
573 /*
574   Class       : NumericalFunctor_i
575   Description : Base class for numerical functors
576 */
577 CORBA::Double NumericalFunctor_i::GetValue( CORBA::Long theId )
578 {
579   return myNumericalFunctorPtr->GetValue( theId );
580 }
581
582 SMESH::Histogram* NumericalFunctor_i::GetHistogram(CORBA::Short nbIntervals, CORBA::Boolean isLogarithmic)
583 {
584   std::vector<int> nbEvents;
585   std::vector<double> funValues;
586   std::vector<int> elements;
587   myNumericalFunctorPtr->GetHistogram(nbIntervals,nbEvents,funValues,elements,0,isLogarithmic);
588
589 #ifdef WIN32
590   nbIntervals = CORBA::Short( min( nbEvents.size(), funValues.size() - 1));
591 #else
592   nbIntervals = CORBA::Short( std::min( nbEvents.size(), funValues.size() - 1));
593 #endif
594   SMESH::Histogram_var histogram = new SMESH::Histogram;
595   if ( nbIntervals > 0 )
596   {
597     histogram->length( nbIntervals );
598     for ( int i = 0; i < nbIntervals; ++i )
599     {
600       HistogramRectangle& rect = histogram[i];
601       rect.nbEvents = nbEvents[i];
602       rect.min = funValues[i];
603       rect.max = funValues[i+1];
604     }
605   }
606   return histogram._retn();
607 }
608
609 void NumericalFunctor_i::SetPrecision( CORBA::Long thePrecision )
610 {
611   myNumericalFunctorPtr->SetPrecision( thePrecision );
612   TPythonDump()<<this<<".SetPrecision("<<thePrecision<<")";
613 }
614
615 CORBA::Long NumericalFunctor_i::GetPrecision()
616 {
617  return myNumericalFunctorPtr->GetPrecision();
618 }
619
620 Controls::NumericalFunctorPtr NumericalFunctor_i::GetNumericalFunctor()
621 {
622   return myNumericalFunctorPtr;
623 }
624
625
626 /*
627   Class       : SMESH_MinimumAngle
628   Description : Functor for calculation of minimum angle
629 */
630 MinimumAngle_i::MinimumAngle_i()
631 {
632   myNumericalFunctorPtr.reset( new Controls::MinimumAngle() );
633   myFunctorPtr = myNumericalFunctorPtr;
634 }
635
636 FunctorType MinimumAngle_i::GetFunctorType()
637 {
638   return SMESH::FT_MinimumAngle;
639 }
640
641
642 /*
643   Class       : AspectRatio
644   Description : Functor for calculating aspect ratio
645 */
646 AspectRatio_i::AspectRatio_i()
647 {
648   myNumericalFunctorPtr.reset( new Controls::AspectRatio() );
649   myFunctorPtr = myNumericalFunctorPtr;
650 }
651
652 FunctorType AspectRatio_i::GetFunctorType()
653 {
654   return SMESH::FT_AspectRatio;
655 }
656
657
658 /*
659   Class       : AspectRatio3D
660   Description : Functor for calculating aspect ratio 3D
661 */
662 AspectRatio3D_i::AspectRatio3D_i()
663 {
664   myNumericalFunctorPtr.reset( new Controls::AspectRatio3D() );
665   myFunctorPtr = myNumericalFunctorPtr;
666 }
667
668 FunctorType AspectRatio3D_i::GetFunctorType()
669 {
670   return SMESH::FT_AspectRatio3D;
671 }
672
673
674 /*
675   Class       : Warping_i
676   Description : Functor for calculating warping
677 */
678 Warping_i::Warping_i()
679 {
680   myNumericalFunctorPtr.reset( new Controls::Warping() );
681   myFunctorPtr = myNumericalFunctorPtr;
682 }
683
684 FunctorType Warping_i::GetFunctorType()
685 {
686   return SMESH::FT_Warping;
687 }
688
689
690 /*
691   Class       : Taper_i
692   Description : Functor for calculating taper
693 */
694 Taper_i::Taper_i()
695 {
696   myNumericalFunctorPtr.reset( new Controls::Taper() );
697   myFunctorPtr = myNumericalFunctorPtr;
698 }
699
700 FunctorType Taper_i::GetFunctorType()
701 {
702   return SMESH::FT_Taper;
703 }
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       : CoplanarFaces_i
1642   Description : Returns true if a mesh face is a coplanar neighbour to a given one
1643 */
1644 CoplanarFaces_i::CoplanarFaces_i()
1645 {
1646   myCoplanarFacesPtr.reset(new Controls::CoplanarFaces());
1647   myFunctorPtr = myPredicatePtr = myCoplanarFacesPtr;
1648 }
1649
1650 void CoplanarFaces_i::SetFace ( CORBA::Long theFaceID )
1651 {
1652   myCoplanarFacesPtr->SetFace(theFaceID);
1653   TPythonDump()<<this<<".SetFace("<<theFaceID<<")";
1654 }
1655
1656 void CoplanarFaces_i::SetTolerance( CORBA::Double theToler )
1657 {
1658   myCoplanarFacesPtr->SetTolerance(theToler);
1659   TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
1660 }
1661
1662 CORBA::Long CoplanarFaces_i::GetFace () const
1663 {
1664   return myCoplanarFacesPtr->GetFace();
1665 }
1666
1667 char* CoplanarFaces_i::GetFaceAsString () const
1668 {
1669   TCollection_AsciiString str(Standard_Integer(myCoplanarFacesPtr->GetFace()));
1670   return CORBA::string_dup( str.ToCString() );
1671 }
1672
1673 CORBA::Double CoplanarFaces_i::GetTolerance() const
1674 {
1675   return myCoplanarFacesPtr->GetTolerance();
1676 }
1677
1678 FunctorType CoplanarFaces_i::GetFunctorType()
1679 {
1680   return SMESH::FT_CoplanarFaces;
1681 }
1682
1683 /*
1684   Class       : Comparator_i
1685   Description : Base class for comparators
1686 */
1687 Comparator_i::Comparator_i():
1688   myNumericalFunctor( NULL )
1689 {}
1690
1691 Comparator_i::~Comparator_i()
1692 {
1693   if ( myNumericalFunctor )
1694     myNumericalFunctor->UnRegister();
1695 }
1696
1697 void Comparator_i::SetMargin( CORBA::Double theValue )
1698 {
1699   myComparatorPtr->SetMargin( theValue );
1700   TPythonDump()<<this<<".SetMargin("<<theValue<<")";
1701 }
1702
1703 CORBA::Double Comparator_i::GetMargin()
1704 {
1705   return myComparatorPtr->GetMargin();
1706 }
1707
1708 void Comparator_i::SetNumFunctor( NumericalFunctor_ptr theFunct )
1709 {
1710   if ( myNumericalFunctor )
1711     myNumericalFunctor->UnRegister();
1712
1713   myNumericalFunctor = DownCast<NumericalFunctor_i*>(theFunct);
1714
1715   if ( myNumericalFunctor )
1716   {
1717     myComparatorPtr->SetNumFunctor( myNumericalFunctor->GetNumericalFunctor() );
1718     myNumericalFunctor->Register();
1719     TPythonDump()<<this<<".SetNumFunctor("<<myNumericalFunctor<<")";
1720   }
1721 }
1722
1723 Controls::ComparatorPtr Comparator_i::GetComparator()
1724 {
1725   return myComparatorPtr;
1726 }
1727
1728 NumericalFunctor_i* Comparator_i::GetNumFunctor_i()
1729 {
1730   return myNumericalFunctor;
1731 }
1732
1733
1734 /*
1735   Class       : LessThan_i
1736   Description : Comparator "<"
1737 */
1738 LessThan_i::LessThan_i()
1739 {
1740   myComparatorPtr.reset( new Controls::LessThan() );
1741   myFunctorPtr = myPredicatePtr = myComparatorPtr;
1742 }
1743
1744 FunctorType LessThan_i::GetFunctorType()
1745 {
1746   return SMESH::FT_LessThan;
1747 }
1748
1749
1750 /*
1751   Class       : MoreThan_i
1752   Description : Comparator ">"
1753 */
1754 MoreThan_i::MoreThan_i()
1755 {
1756   myComparatorPtr.reset( new Controls::MoreThan() );
1757   myFunctorPtr = myPredicatePtr = myComparatorPtr;
1758 }
1759
1760 FunctorType MoreThan_i::GetFunctorType()
1761 {
1762   return SMESH::FT_MoreThan;
1763 }
1764
1765
1766 /*
1767   Class       : EqualTo_i
1768   Description : Comparator "="
1769 */
1770 EqualTo_i::EqualTo_i()
1771 : myEqualToPtr( new Controls::EqualTo() )
1772 {
1773   myFunctorPtr = myPredicatePtr = myComparatorPtr = myEqualToPtr;
1774 }
1775
1776 void EqualTo_i::SetTolerance( CORBA::Double theToler )
1777 {
1778   myEqualToPtr->SetTolerance( theToler );
1779   TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
1780 }
1781
1782 CORBA::Double EqualTo_i::GetTolerance()
1783 {
1784   return myEqualToPtr->GetTolerance();
1785 }
1786
1787 FunctorType EqualTo_i::GetFunctorType()
1788 {
1789   return SMESH::FT_EqualTo;
1790 }
1791
1792 /*
1793   Class       : LogicalNOT_i
1794   Description : Logical NOT predicate
1795 */
1796 LogicalNOT_i::LogicalNOT_i()
1797 : myPredicate( NULL ),
1798   myLogicalNOTPtr( new Controls::LogicalNOT() )
1799 {
1800   myFunctorPtr = myPredicatePtr = myLogicalNOTPtr;
1801 }
1802
1803 LogicalNOT_i::~LogicalNOT_i()
1804 {
1805   if ( myPredicate )
1806     myPredicate->UnRegister();
1807 }
1808
1809 void LogicalNOT_i::SetPredicate( Predicate_ptr thePredicate )
1810 {
1811   if ( myPredicate )
1812     myPredicate->UnRegister();
1813
1814   myPredicate = SMESH::GetPredicate(thePredicate);
1815
1816   if ( myPredicate ){
1817     myLogicalNOTPtr->SetPredicate(myPredicate->GetPredicate());
1818     myPredicate->Register();
1819     TPythonDump()<<this<<".SetPredicate("<<myPredicate<<")";
1820   }
1821 }
1822
1823 FunctorType LogicalNOT_i::GetFunctorType()
1824 {
1825   return SMESH::FT_LogicalNOT;
1826 }
1827
1828 Predicate_i* LogicalNOT_i::GetPredicate_i()
1829 {
1830   return myPredicate;
1831 }
1832
1833
1834 /*
1835   Class       : LogicalBinary_i
1836   Description : Base class for binary logical predicate
1837 */
1838 LogicalBinary_i::LogicalBinary_i()
1839 : myPredicate1( NULL ),
1840   myPredicate2( NULL )
1841 {}
1842
1843 LogicalBinary_i::~LogicalBinary_i()
1844 {
1845   if ( myPredicate1 )
1846     myPredicate1->UnRegister();
1847
1848   if ( myPredicate2 )
1849     myPredicate2->UnRegister();
1850 }
1851
1852 void LogicalBinary_i::SetMesh( SMESH_Mesh_ptr theMesh )
1853 {
1854   if ( myPredicate1 )
1855     myPredicate1->SetMesh( theMesh );
1856
1857   if ( myPredicate2 )
1858     myPredicate2->SetMesh( theMesh );
1859 }
1860
1861 void LogicalBinary_i::SetPredicate1( Predicate_ptr thePredicate )
1862 {
1863   if ( myPredicate1 )
1864     myPredicate1->UnRegister();
1865
1866   myPredicate1 = SMESH::GetPredicate(thePredicate);
1867
1868   if ( myPredicate1 ){
1869     myLogicalBinaryPtr->SetPredicate1(myPredicate1->GetPredicate());
1870     myPredicate1->Register();
1871     TPythonDump()<<this<<".SetPredicate1("<<myPredicate1<<")";
1872   }
1873 }
1874
1875 void LogicalBinary_i::SetPredicate2( Predicate_ptr thePredicate )
1876 {
1877   if ( myPredicate2 )
1878     myPredicate2->UnRegister();
1879
1880   myPredicate2 = SMESH::GetPredicate(thePredicate);
1881
1882   if ( myPredicate2 ){
1883     myLogicalBinaryPtr->SetPredicate2(myPredicate2->GetPredicate());
1884     myPredicate2->Register();
1885     TPythonDump()<<this<<".SetPredicate2("<<myPredicate2<<")";
1886   }
1887 }
1888
1889 Controls::LogicalBinaryPtr LogicalBinary_i::GetLogicalBinary()
1890 {
1891   return myLogicalBinaryPtr;
1892 }
1893
1894 Predicate_i* LogicalBinary_i::GetPredicate1_i()
1895 {
1896   return myPredicate1;
1897 }
1898 Predicate_i* LogicalBinary_i::GetPredicate2_i()
1899 {
1900   return myPredicate2;
1901 }
1902
1903
1904 /*
1905   Class       : LogicalAND_i
1906   Description : Logical AND
1907 */
1908 LogicalAND_i::LogicalAND_i()
1909 {
1910   myLogicalBinaryPtr.reset( new Controls::LogicalAND() );
1911   myFunctorPtr = myPredicatePtr = myLogicalBinaryPtr;
1912 }
1913
1914 FunctorType LogicalAND_i::GetFunctorType()
1915 {
1916   return SMESH::FT_LogicalAND;
1917 }
1918
1919
1920 /*
1921   Class       : LogicalOR_i
1922   Description : Logical OR
1923 */
1924 LogicalOR_i::LogicalOR_i()
1925 {
1926   myLogicalBinaryPtr.reset( new Controls::LogicalOR() );
1927   myFunctorPtr = myPredicatePtr = myLogicalBinaryPtr;
1928 }
1929
1930 FunctorType LogicalOR_i::GetFunctorType()
1931 {
1932   return SMESH::FT_LogicalOR;
1933 }
1934
1935
1936 /*
1937                             FILTER MANAGER
1938 */
1939
1940 FilterManager_i::FilterManager_i()
1941 : SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
1942 {
1943   //Base class Salome_GenericObject do it inmplicitly by overriding PortableServer::POA_ptr _default_POA() method
1944   //PortableServer::ObjectId_var anObjectId =
1945   //  SMESH_Gen_i::GetPOA()->activate_object( this );
1946 }
1947
1948
1949 FilterManager_i::~FilterManager_i()
1950 {
1951   //TPythonDump()<<this<<".UnRegister()";
1952 }
1953
1954
1955 MinimumAngle_ptr FilterManager_i::CreateMinimumAngle()
1956 {
1957   SMESH::MinimumAngle_i* aServant = new SMESH::MinimumAngle_i();
1958   SMESH::MinimumAngle_var anObj = aServant->_this();
1959   TPythonDump()<<aServant<<" = "<<this<<".CreateMinimumAngle()";
1960   return anObj._retn();
1961 }
1962
1963
1964 AspectRatio_ptr FilterManager_i::CreateAspectRatio()
1965 {
1966   SMESH::AspectRatio_i* aServant = new SMESH::AspectRatio_i();
1967   SMESH::AspectRatio_var anObj = aServant->_this();
1968   TPythonDump()<<aServant<<" = "<<this<<".CreateAspectRatio()";
1969   return anObj._retn();
1970 }
1971
1972
1973 AspectRatio3D_ptr FilterManager_i::CreateAspectRatio3D()
1974 {
1975   SMESH::AspectRatio3D_i* aServant = new SMESH::AspectRatio3D_i();
1976   SMESH::AspectRatio3D_var anObj = aServant->_this();
1977   TPythonDump()<<aServant<<" = "<<this<<".CreateAspectRatio3D()";
1978   return anObj._retn();
1979 }
1980
1981
1982 Warping_ptr FilterManager_i::CreateWarping()
1983 {
1984   SMESH::Warping_i* aServant = new SMESH::Warping_i();
1985   SMESH::Warping_var anObj = aServant->_this();
1986   TPythonDump()<<aServant<<" = "<<this<<".CreateWarping()";
1987   return anObj._retn();
1988 }
1989
1990
1991 Taper_ptr FilterManager_i::CreateTaper()
1992 {
1993   SMESH::Taper_i* aServant = new SMESH::Taper_i();
1994   SMESH::Taper_var anObj = aServant->_this();
1995   TPythonDump()<<aServant<<" = "<<this<<".CreateTaper()";
1996   return anObj._retn();
1997 }
1998
1999
2000 Skew_ptr FilterManager_i::CreateSkew()
2001 {
2002   SMESH::Skew_i* aServant = new SMESH::Skew_i();
2003   SMESH::Skew_var anObj = aServant->_this();
2004   TPythonDump()<<aServant<<" = "<<this<<".CreateSkew()";
2005   return anObj._retn();
2006 }
2007
2008
2009 Area_ptr FilterManager_i::CreateArea()
2010 {
2011   SMESH::Area_i* aServant = new SMESH::Area_i();
2012   SMESH::Area_var anObj = aServant->_this();
2013   TPythonDump()<<aServant<<" = "<<this<<".CreateArea()";
2014   return anObj._retn();
2015 }
2016
2017
2018 Volume3D_ptr FilterManager_i::CreateVolume3D()
2019 {
2020   SMESH::Volume3D_i* aServant = new SMESH::Volume3D_i();
2021   SMESH::Volume3D_var anObj = aServant->_this();
2022   TPythonDump()<<aServant<<" = "<<this<<".CreateVolume3D()";
2023   return anObj._retn();
2024 }
2025
2026
2027 MaxElementLength2D_ptr FilterManager_i::CreateMaxElementLength2D()
2028 {
2029   SMESH::MaxElementLength2D_i* aServant = new SMESH::MaxElementLength2D_i();
2030   SMESH::MaxElementLength2D_var anObj = aServant->_this();
2031   TPythonDump()<<aServant<<" = "<<this<<".CreateMaxElementLength2D()";
2032   return anObj._retn();
2033 }
2034
2035
2036 MaxElementLength3D_ptr FilterManager_i::CreateMaxElementLength3D()
2037 {
2038   SMESH::MaxElementLength3D_i* aServant = new SMESH::MaxElementLength3D_i();
2039   SMESH::MaxElementLength3D_var anObj = aServant->_this();
2040   TPythonDump()<<aServant<<" = "<<this<<".CreateMaxElementLength3D()";
2041   return anObj._retn();
2042 }
2043
2044
2045 Length_ptr FilterManager_i::CreateLength()
2046 {
2047   SMESH::Length_i* aServant = new SMESH::Length_i();
2048   SMESH::Length_var anObj = aServant->_this();
2049   TPythonDump()<<aServant<<" = "<<this<<".CreateLength()";
2050   return anObj._retn();
2051 }
2052
2053 Length2D_ptr FilterManager_i::CreateLength2D()
2054 {
2055   SMESH::Length2D_i* aServant = new SMESH::Length2D_i();
2056   SMESH::Length2D_var anObj = aServant->_this();
2057   TPythonDump()<<aServant<<" = "<<this<<".CreateLength2D()";
2058   return anObj._retn();
2059 }
2060
2061 MultiConnection_ptr FilterManager_i::CreateMultiConnection()
2062 {
2063   SMESH::MultiConnection_i* aServant = new SMESH::MultiConnection_i();
2064   SMESH::MultiConnection_var anObj = aServant->_this();
2065   TPythonDump()<<aServant<<" = "<<this<<".CreateMultiConnection()";
2066   return anObj._retn();
2067 }
2068
2069 MultiConnection2D_ptr FilterManager_i::CreateMultiConnection2D()
2070 {
2071   SMESH::MultiConnection2D_i* aServant = new SMESH::MultiConnection2D_i();
2072   SMESH::MultiConnection2D_var anObj = aServant->_this();
2073   TPythonDump()<<aServant<<" = "<<this<<".CreateMultiConnection2D()";
2074   return anObj._retn();
2075 }
2076
2077 BallDiameter_ptr FilterManager_i::CreateBallDiameter()
2078 {
2079   SMESH::BallDiameter_i* aServant = new SMESH::BallDiameter_i();
2080   SMESH::BallDiameter_var anObj = aServant->_this();
2081   TPythonDump()<<aServant<<" = "<<this<<".CreateBallDiameter()";
2082   return anObj._retn();
2083 }
2084
2085 BelongToGeom_ptr FilterManager_i::CreateBelongToGeom()
2086 {
2087   SMESH::BelongToGeom_i* aServant = new SMESH::BelongToGeom_i();
2088   SMESH::BelongToGeom_var anObj = aServant->_this();
2089   TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToGeom()";
2090   return anObj._retn();
2091 }
2092
2093 BelongToPlane_ptr FilterManager_i::CreateBelongToPlane()
2094 {
2095   SMESH::BelongToPlane_i* aServant = new SMESH::BelongToPlane_i();
2096   SMESH::BelongToPlane_var anObj = aServant->_this();
2097   TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToPlane()";
2098   return anObj._retn();
2099 }
2100
2101 BelongToCylinder_ptr FilterManager_i::CreateBelongToCylinder()
2102 {
2103   SMESH::BelongToCylinder_i* aServant = new SMESH::BelongToCylinder_i();
2104   SMESH::BelongToCylinder_var anObj = aServant->_this();
2105   TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToCylinder()";
2106   return anObj._retn();
2107 }
2108
2109 BelongToGenSurface_ptr FilterManager_i::CreateBelongToGenSurface()
2110 {
2111   SMESH::BelongToGenSurface_i* aServant = new SMESH::BelongToGenSurface_i();
2112   SMESH::BelongToGenSurface_var anObj = aServant->_this();
2113   TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToGenSurface()";
2114   return anObj._retn();
2115 }
2116
2117 LyingOnGeom_ptr FilterManager_i::CreateLyingOnGeom()
2118 {
2119   SMESH::LyingOnGeom_i* aServant = new SMESH::LyingOnGeom_i();
2120   SMESH::LyingOnGeom_var anObj = aServant->_this();
2121   TPythonDump()<<aServant<<" = "<<this<<".CreateLyingOnGeom()";
2122   return anObj._retn();
2123 }
2124
2125 CoplanarFaces_ptr FilterManager_i::CreateCoplanarFaces()
2126 {
2127   SMESH::CoplanarFaces_i* aServant = new SMESH::CoplanarFaces_i();
2128   SMESH::CoplanarFaces_var anObj = aServant->_this();
2129   TPythonDump()<<aServant<<" = "<<this<<".CreateCoplanarFaces()";
2130   return anObj._retn();
2131 }
2132
2133 FreeBorders_ptr FilterManager_i::CreateFreeBorders()
2134 {
2135   SMESH::FreeBorders_i* aServant = new SMESH::FreeBorders_i();
2136   SMESH::FreeBorders_var anObj = aServant->_this();
2137   TPythonDump()<<aServant<<" = "<<this<<".CreateFreeBorders()";
2138   return anObj._retn();
2139 }
2140
2141 FreeEdges_ptr FilterManager_i::CreateFreeEdges()
2142 {
2143   SMESH::FreeEdges_i* aServant = new SMESH::FreeEdges_i();
2144   SMESH::FreeEdges_var anObj = aServant->_this();
2145   TPythonDump()<<aServant<<" = "<<this<<".CreateFreeEdges()";
2146   return anObj._retn();
2147 }
2148
2149 FreeFaces_ptr FilterManager_i::CreateFreeFaces()
2150 {
2151   SMESH::FreeFaces_i* aServant = new SMESH::FreeFaces_i();
2152   SMESH::FreeFaces_var anObj = aServant->_this();
2153   TPythonDump()<<aServant<<" = "<<this<<".CreateFreeFaces()";
2154   return anObj._retn();
2155 }
2156
2157 FreeNodes_ptr FilterManager_i::CreateFreeNodes()
2158 {
2159   SMESH::FreeNodes_i* aServant = new SMESH::FreeNodes_i();
2160   SMESH::FreeNodes_var anObj = aServant->_this();
2161   TPythonDump()<<aServant<<" = "<<this<<".CreateFreeNodes()";
2162   return anObj._retn();
2163 }
2164
2165 EqualNodes_ptr FilterManager_i::CreateEqualNodes()
2166 {
2167   SMESH::EqualNodes_i* aServant = new SMESH::EqualNodes_i();
2168   SMESH::EqualNodes_var anObj = aServant->_this();
2169   TPythonDump()<<aServant<<" = "<<this<<".CreateEqualNodes()";
2170   return anObj._retn();
2171 }
2172
2173 EqualEdges_ptr FilterManager_i::CreateEqualEdges()
2174 {
2175   SMESH::EqualEdges_i* aServant = new SMESH::EqualEdges_i();
2176   SMESH::EqualEdges_var anObj = aServant->_this();
2177   TPythonDump()<<aServant<<" = "<<this<<".CreateEqualEdges()";
2178   return anObj._retn();
2179 }
2180 EqualFaces_ptr FilterManager_i::CreateEqualFaces()
2181 {
2182   SMESH::EqualFaces_i* aServant = new SMESH::EqualFaces_i();
2183   SMESH::EqualFaces_var anObj = aServant->_this();
2184   TPythonDump()<<aServant<<" = "<<this<<".CreateEqualFaces()";
2185   return anObj._retn();
2186 }
2187 EqualVolumes_ptr FilterManager_i::CreateEqualVolumes()
2188 {
2189   SMESH::EqualVolumes_i* aServant = new SMESH::EqualVolumes_i();
2190   SMESH::EqualVolumes_var anObj = aServant->_this();
2191   TPythonDump()<<aServant<<" = "<<this<<".CreateEqualVolumes()";
2192   return anObj._retn();
2193 }
2194
2195 RangeOfIds_ptr FilterManager_i::CreateRangeOfIds()
2196 {
2197   SMESH::RangeOfIds_i* aServant = new SMESH::RangeOfIds_i();
2198   SMESH::RangeOfIds_var anObj = aServant->_this();
2199   TPythonDump()<<aServant<<" = "<<this<<".CreateRangeOfIds()";
2200   return anObj._retn();
2201 }
2202
2203 BadOrientedVolume_ptr FilterManager_i::CreateBadOrientedVolume()
2204 {
2205   SMESH::BadOrientedVolume_i* aServant = new SMESH::BadOrientedVolume_i();
2206   SMESH::BadOrientedVolume_var anObj = aServant->_this();
2207   TPythonDump()<<aServant<<" = "<<this<<".CreateBadOrientedVolume()";
2208   return anObj._retn();
2209 }
2210
2211 BareBorderVolume_ptr FilterManager_i::CreateBareBorderVolume()
2212 {
2213   SMESH::BareBorderVolume_i* aServant = new SMESH::BareBorderVolume_i();
2214   SMESH::BareBorderVolume_var anObj = aServant->_this();
2215   TPythonDump()<<aServant<<" = "<<this<<".CreateBareBorderVolume()";
2216   return anObj._retn();
2217 }
2218
2219 BareBorderFace_ptr FilterManager_i::CreateBareBorderFace()
2220 {
2221   SMESH::BareBorderFace_i* aServant = new SMESH::BareBorderFace_i();
2222   SMESH::BareBorderFace_var anObj = aServant->_this();
2223   TPythonDump()<<aServant<<" = "<<this<<".CreateBareBorderFace()";
2224   return anObj._retn();
2225 }
2226
2227 OverConstrainedVolume_ptr FilterManager_i::CreateOverConstrainedVolume()
2228 {
2229   SMESH::OverConstrainedVolume_i* aServant = new SMESH::OverConstrainedVolume_i();
2230   SMESH::OverConstrainedVolume_var anObj = aServant->_this();
2231   TPythonDump()<<aServant<<" = "<<this<<".CreateOverConstrainedVolume()";
2232   return anObj._retn();
2233 }
2234
2235 OverConstrainedFace_ptr FilterManager_i::CreateOverConstrainedFace()
2236 {
2237   SMESH::OverConstrainedFace_i* aServant = new SMESH::OverConstrainedFace_i();
2238   SMESH::OverConstrainedFace_var anObj = aServant->_this();
2239   TPythonDump()<<aServant<<" = "<<this<<".CreateOverConstrainedFace()";
2240   return anObj._retn();
2241 }
2242
2243 LessThan_ptr FilterManager_i::CreateLessThan()
2244 {
2245   SMESH::LessThan_i* aServant = new SMESH::LessThan_i();
2246   SMESH::LessThan_var anObj = aServant->_this();
2247   TPythonDump()<<aServant<<" = "<<this<<".CreateLessThan()";
2248   return anObj._retn();
2249 }
2250
2251 MoreThan_ptr FilterManager_i::CreateMoreThan()
2252 {
2253   SMESH::MoreThan_i* aServant = new SMESH::MoreThan_i();
2254   SMESH::MoreThan_var anObj = aServant->_this();
2255   TPythonDump()<<aServant<<" = "<<this<<".CreateMoreThan()";
2256   return anObj._retn();
2257 }
2258
2259 EqualTo_ptr FilterManager_i::CreateEqualTo()
2260 {
2261   SMESH::EqualTo_i* aServant = new SMESH::EqualTo_i();
2262   SMESH::EqualTo_var anObj = aServant->_this();
2263   TPythonDump()<<aServant<<" = "<<this<<".CreateEqualTo()";
2264   return anObj._retn();
2265 }
2266
2267 LogicalNOT_ptr FilterManager_i::CreateLogicalNOT()
2268 {
2269   SMESH::LogicalNOT_i* aServant = new SMESH::LogicalNOT_i();
2270   SMESH::LogicalNOT_var anObj = aServant->_this();
2271   TPythonDump()<<aServant<<" = "<<this<<".CreateLogicalNOT()";
2272   return anObj._retn();
2273 }
2274
2275 LogicalAND_ptr FilterManager_i::CreateLogicalAND()
2276 {
2277   SMESH::LogicalAND_i* aServant = new SMESH::LogicalAND_i();
2278   SMESH::LogicalAND_var anObj = aServant->_this();
2279   TPythonDump()<<aServant<<" = "<<this<<".CreateLogicalAND()";
2280   return anObj._retn();
2281 }
2282
2283 LogicalOR_ptr FilterManager_i::CreateLogicalOR()
2284 {
2285   SMESH::LogicalOR_i* aServant = new SMESH::LogicalOR_i();
2286   SMESH::LogicalOR_var anObj = aServant->_this();
2287   TPythonDump()<<aServant<<" = "<<this<<".CreateLogicalOR()";
2288   return anObj._retn();
2289 }
2290
2291 LinearOrQuadratic_ptr FilterManager_i::CreateLinearOrQuadratic()
2292 {
2293   SMESH::LinearOrQuadratic_i* aServant = new SMESH::LinearOrQuadratic_i();
2294   SMESH::LinearOrQuadratic_var anObj = aServant->_this();
2295   TPythonDump()<<aServant<<" = "<<this<<".CreateLinearOrQuadratic()";
2296   return anObj._retn();
2297 }
2298
2299 GroupColor_ptr FilterManager_i::CreateGroupColor()
2300 {
2301   SMESH::GroupColor_i* aServant = new SMESH::GroupColor_i();
2302   SMESH::GroupColor_var anObj = aServant->_this();
2303   TPythonDump()<<aServant<<" = "<<this<<".CreateGroupColor()";
2304   return anObj._retn();
2305 }
2306
2307 ElemGeomType_ptr FilterManager_i::CreateElemGeomType()
2308 {
2309   SMESH::ElemGeomType_i* aServant = new SMESH::ElemGeomType_i();
2310   SMESH::ElemGeomType_var anObj = aServant->_this();
2311   TPythonDump()<<aServant<<" = "<<this<<".CreateElemGeomType()";
2312   return anObj._retn();
2313 }
2314
2315 Filter_ptr FilterManager_i::CreateFilter()
2316 {
2317   SMESH::Filter_i* aServant = new SMESH::Filter_i();
2318   SMESH::Filter_var anObj = aServant->_this();
2319   TPythonDump()<<aServant<<" = "<<this<<".CreateFilter()";
2320   return anObj._retn();
2321 }
2322
2323 FilterLibrary_ptr FilterManager_i::LoadLibrary( const char* aFileName )
2324 {
2325   SMESH::FilterLibrary_i* aServant = new SMESH::FilterLibrary_i( aFileName );
2326   SMESH::FilterLibrary_var anObj = aServant->_this();
2327   TPythonDump()<<aServant<<" = "<<this<<".LoadLibrary('"<<aFileName<<"')";
2328   return anObj._retn();
2329 }
2330
2331 FilterLibrary_ptr FilterManager_i::CreateLibrary()
2332 {
2333   SMESH::FilterLibrary_i* aServant = new SMESH::FilterLibrary_i();
2334   SMESH::FilterLibrary_var anObj = aServant->_this();
2335   TPythonDump()<<aServant<<" = "<<this<<".CreateLibrary()";
2336   return anObj._retn();
2337 }
2338
2339 CORBA::Boolean FilterManager_i::DeleteLibrary( const char* aFileName )
2340 {
2341   TPythonDump()<<this<<".DeleteLibrary("<<aFileName<<")";
2342   return remove( aFileName ) ? false : true;
2343 }
2344
2345 //=============================================================================
2346 /*!
2347  *  SMESH_Gen_i::CreateFilterManager
2348  *
2349  *  Create filter manager
2350  */
2351 //=============================================================================
2352
2353 SMESH::FilterManager_ptr SMESH_Gen_i::CreateFilterManager()
2354 {
2355   SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i();
2356   SMESH::FilterManager_var anObj = aFilter->_this();
2357   return anObj._retn();
2358 }
2359
2360
2361 /*
2362                               FILTER
2363 */
2364
2365 //=======================================================================
2366 // name    : Filter_i::Filter_i
2367 // Purpose : Constructor
2368 //=======================================================================
2369 Filter_i::Filter_i()
2370 : myPredicate( NULL )
2371 {}
2372
2373 //=======================================================================
2374 // name    : Filter_i::~Filter_i
2375 // Purpose : Destructor
2376 //=======================================================================
2377 Filter_i::~Filter_i()
2378 {
2379   if ( myPredicate )
2380     myPredicate->UnRegister();
2381
2382   if(!CORBA::is_nil(myMesh))
2383     myMesh->UnRegister();
2384
2385   //TPythonDump()<<this<<".UnRegister()";
2386 }
2387
2388 //=======================================================================
2389 // name    : Filter_i::SetPredicate
2390 // Purpose : Set predicate
2391 //=======================================================================
2392 void Filter_i::SetPredicate( Predicate_ptr thePredicate )
2393 {
2394   if ( myPredicate )
2395     myPredicate->UnRegister();
2396
2397   myPredicate = SMESH::GetPredicate(thePredicate);
2398
2399   if ( myPredicate )
2400   {
2401     myFilter.SetPredicate( myPredicate->GetPredicate() );
2402     myPredicate->Register();
2403     if ( const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh))
2404       myPredicate->GetPredicate()->SetMesh( aMesh );
2405     TPythonDump()<<this<<".SetPredicate("<<myPredicate<<")";
2406   }
2407   std::list<TPredicateChangeWaiter*>::iterator i = myWaiters.begin();
2408   for ( ; i != myWaiters.end(); ++i )
2409     (*i)->PredicateChanged();
2410 }
2411
2412 //=======================================================================
2413 // name    : Filter_i::GetElementType
2414 // Purpose : Get entity type
2415 //=======================================================================
2416 SMESH::ElementType Filter_i::GetElementType()
2417 {
2418   return myPredicate != 0 ? myPredicate->GetElementType() : SMESH::ALL;
2419 }
2420
2421 //=======================================================================
2422 // name    : Filter_i::SetMesh
2423 // Purpose : Set mesh
2424 //=======================================================================
2425 void
2426 Filter_i::
2427 SetMesh( SMESH_Mesh_ptr theMesh )
2428 {
2429   if(!CORBA::is_nil(theMesh))
2430     theMesh->Register();
2431
2432   if(!CORBA::is_nil(myMesh))
2433     myMesh->UnRegister();
2434
2435   myMesh = SMESH_Mesh::_duplicate( theMesh );
2436   TPythonDump()<<this<<".SetMesh("<<theMesh<<")";
2437
2438   if ( myPredicate )
2439     if ( const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(theMesh))
2440       myPredicate->GetPredicate()->SetMesh( aMesh );
2441 }
2442
2443 SMESH::long_array*
2444 Filter_i::
2445 GetIDs()
2446 {
2447   return GetElementsId(myMesh);
2448 }
2449
2450 //=======================================================================
2451 // name    : Filter_i::GetElementsId
2452 // Purpose : Get ids of entities
2453 //=======================================================================
2454 void
2455 Filter_i::
2456 GetElementsId( Predicate_i* thePredicate,
2457                const SMDS_Mesh* theMesh,
2458                Controls::Filter::TIdSequence& theSequence )
2459 {
2460   if (thePredicate)
2461     Controls::Filter::GetElementsId(theMesh,thePredicate->GetPredicate(),theSequence);
2462 }
2463
2464 void
2465 Filter_i::
2466 GetElementsId( Predicate_i* thePredicate,
2467                SMESH_Mesh_ptr theMesh,
2468                Controls::Filter::TIdSequence& theSequence )
2469 {
2470   if (thePredicate) 
2471     if(const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(theMesh))
2472       Controls::Filter::GetElementsId(aMesh,thePredicate->GetPredicate(),theSequence);
2473 }
2474
2475 SMESH::long_array*
2476 Filter_i::
2477 GetElementsId( SMESH_Mesh_ptr theMesh )
2478 {
2479   SMESH::long_array_var anArray = new SMESH::long_array;
2480   if(!CORBA::is_nil(theMesh) && myPredicate){
2481     Controls::Filter::TIdSequence aSequence;
2482     GetElementsId(myPredicate,theMesh,aSequence);
2483     long i = 0, iEnd = aSequence.size();
2484     anArray->length( iEnd );
2485     for ( ; i < iEnd; i++ )
2486       anArray[ i ] = aSequence[i];
2487   }
2488   return anArray._retn();
2489 }
2490
2491 template<class TElement, class TIterator, class TPredicate>
2492 static void collectMeshInfo(const TIterator& theItr,
2493                             TPredicate& thePred,
2494                             SMESH::long_array& theRes)
2495 {         
2496   if (!theItr)
2497     return;
2498   while (theItr->more()) {
2499     const SMDS_MeshElement* anElem = theItr->next();
2500     if ( thePred->IsSatisfy( anElem->GetID() ) )
2501       theRes[ anElem->GetEntityType() ]++;
2502   }
2503 }
2504
2505 //=============================================================================
2506 /*!
2507  * \brief Returns statistic of mesh elements
2508  */
2509 //=============================================================================
2510 SMESH::long_array* ::Filter_i::GetMeshInfo()
2511 {
2512   SMESH::long_array_var aRes = new SMESH::long_array();
2513   aRes->length(SMESH::Entity_Last);
2514   for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
2515     aRes[i] = 0;
2516
2517   if(!CORBA::is_nil(myMesh) && myPredicate) {
2518     const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh);
2519     SMDS_ElemIteratorPtr it;
2520     switch( GetElementType() )
2521     {
2522     case SMDSAbs_Node:
2523       collectMeshInfo<const SMDS_MeshNode*>(aMesh->nodesIterator(),myPredicate,aRes);
2524       break;
2525     case SMDSAbs_Edge:
2526       collectMeshInfo<const SMDS_MeshElement*>(aMesh->edgesIterator(),myPredicate,aRes);
2527       break;
2528     case SMDSAbs_Face:
2529       collectMeshInfo<const SMDS_MeshElement*>(aMesh->facesIterator(),myPredicate,aRes);
2530       break;
2531     case SMDSAbs_Volume:
2532       collectMeshInfo<const SMDS_MeshElement*>(aMesh->volumesIterator(),myPredicate,aRes);
2533       break;
2534     case SMDSAbs_All:
2535     default:
2536       collectMeshInfo<const SMDS_MeshElement*>(aMesh->elementsIterator(),myPredicate,aRes);
2537       break;
2538     }
2539   }
2540
2541   return aRes._retn();  
2542 }
2543
2544 //================================================================================
2545 /*!
2546  * \brief Return GetElementType() within an array
2547  * Implement SMESH_IDSource interface
2548  */
2549 //================================================================================
2550
2551 SMESH::array_of_ElementType* Filter_i::GetTypes()
2552 {
2553   SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
2554
2555   // check if any element passes through the filter
2556   if ( !CORBA::is_nil(myMesh) && myPredicate )
2557   {
2558     const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh);
2559     SMDS_ElemIteratorPtr it = aMesh->elementsIterator( SMDSAbs_ElementType( GetElementType() ));
2560     bool satisfies = false;
2561     while ( !satisfies && it->more() )
2562       satisfies = myPredicate->IsSatisfy( it->next()->GetID() );
2563     if ( satisfies ) {
2564       types->length( 1 );
2565       types[0] = GetElementType();
2566     }
2567   }
2568   return types._retn();
2569 }
2570
2571 //=======================================================================
2572 //function : GetMesh
2573 //purpose  : Returns mesh
2574 //=======================================================================
2575
2576 SMESH::SMESH_Mesh_ptr Filter_i::GetMesh()
2577 {
2578   return SMESH_Mesh::_duplicate( myMesh );
2579 }
2580
2581 //================================================================================
2582 /*!
2583  * \brief Stores an object to be notified on change of predicate
2584  */
2585 //================================================================================
2586
2587 void Filter_i::AddWaiter( TPredicateChangeWaiter* waiter )
2588 {
2589   if ( waiter )
2590     myWaiters.push_back( waiter );
2591 }
2592
2593 //================================================================================
2594 /*!
2595  * \brief Removes an object to be notified on change of predicate
2596  */
2597 //================================================================================
2598
2599 void Filter_i::RemoveWaiter( TPredicateChangeWaiter* waiter )
2600 {
2601   myWaiters.remove( waiter );
2602 }
2603
2604 //=======================================================================
2605 // name    : getCriteria
2606 // Purpose : Retrieve criterions from predicate
2607 //=======================================================================
2608 static inline bool getCriteria( Predicate_i*                thePred,
2609                                 SMESH::Filter::Criteria_out theCriteria )
2610 {
2611   int aFType = thePred->GetFunctorType();
2612
2613   switch ( aFType )
2614   {
2615   case FT_FreeBorders:
2616   case FT_FreeEdges:
2617   case FT_FreeFaces:
2618   case FT_LinearOrQuadratic:
2619   case FT_FreeNodes:
2620   case FT_EqualEdges:
2621   case FT_EqualFaces:
2622   case FT_EqualVolumes:
2623   case FT_BadOrientedVolume:
2624   case FT_BareBorderVolume:
2625   case FT_BareBorderFace:
2626   case FT_OverConstrainedVolume:
2627   case FT_OverConstrainedFace:
2628     {
2629       CORBA::ULong i = theCriteria->length();
2630       theCriteria->length( i + 1 );
2631
2632       theCriteria[ i ] = createCriterion();
2633
2634       theCriteria[ i ].Type = aFType;
2635       theCriteria[ i ].TypeOfElement = thePred->GetElementType();
2636       return true;
2637     }
2638   case FT_BelongToGeom:
2639     {
2640       BelongToGeom_i* aPred = dynamic_cast<BelongToGeom_i*>( thePred );
2641
2642       CORBA::ULong i = theCriteria->length();
2643       theCriteria->length( i + 1 );
2644
2645       theCriteria[ i ] = createCriterion();
2646
2647       theCriteria[ i ].Type          = FT_BelongToGeom;
2648       theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
2649       theCriteria[ i ].ThresholdID   = aPred->GetShapeID();
2650       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2651       theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2652
2653       return true;
2654     }
2655   case FT_BelongToPlane:
2656   case FT_BelongToCylinder:
2657   case FT_BelongToGenSurface:
2658     {
2659       BelongToSurface_i* aPred = dynamic_cast<BelongToSurface_i*>( thePred );
2660
2661       CORBA::ULong i = theCriteria->length();
2662       theCriteria->length( i + 1 );
2663
2664       theCriteria[ i ] = createCriterion();
2665
2666       theCriteria[ i ].Type          = aFType;
2667       theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
2668       theCriteria[ i ].ThresholdID   = aPred->GetShapeID();
2669       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2670       theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2671
2672       return true;
2673     }
2674    case FT_LyingOnGeom:
2675     {
2676       LyingOnGeom_i* aPred = dynamic_cast<LyingOnGeom_i*>( thePred );
2677
2678       CORBA::ULong i = theCriteria->length();
2679       theCriteria->length( i + 1 );
2680
2681       theCriteria[ i ] = createCriterion();
2682
2683       theCriteria[ i ].Type          = FT_LyingOnGeom;
2684       theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
2685       theCriteria[ i ].ThresholdID   = aPred->GetShapeID();
2686       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2687       theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2688
2689       return true;
2690     }
2691    case FT_CoplanarFaces:
2692     {
2693       CoplanarFaces_i* aPred = dynamic_cast<CoplanarFaces_i*>( thePred );
2694
2695       CORBA::ULong i = theCriteria->length();
2696       theCriteria->length( i + 1 );
2697
2698       theCriteria[ i ] = createCriterion();
2699       CORBA::String_var faceId = aPred->GetFaceAsString();
2700
2701       theCriteria[ i ].Type          = FT_CoplanarFaces;
2702       theCriteria[ i ].ThresholdID   = faceId;
2703       theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2704
2705       return true;
2706     }
2707   case FT_EqualNodes:
2708     {
2709       EqualNodes_i* aPred = dynamic_cast<EqualNodes_i*>( thePred );
2710
2711       CORBA::ULong i = theCriteria->length();
2712       theCriteria->length( i + 1 );
2713
2714       theCriteria[ i ] = createCriterion();
2715
2716       theCriteria[ i ].Type          = FT_EqualNodes;
2717       theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2718
2719       return true;
2720     }
2721   case FT_RangeOfIds:
2722     {
2723       RangeOfIds_i* aPred = dynamic_cast<RangeOfIds_i*>( thePred );
2724
2725       CORBA::ULong i = theCriteria->length();
2726       theCriteria->length( i + 1 );
2727
2728       theCriteria[ i ] = createCriterion();
2729
2730       theCriteria[ i ].Type          = FT_RangeOfIds;
2731       theCriteria[ i ].ThresholdStr  = aPred->GetRangeStr();
2732       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2733
2734       return true;
2735     }
2736   case FT_LessThan:
2737   case FT_MoreThan:
2738   case FT_EqualTo:
2739     {
2740       Comparator_i* aCompar = dynamic_cast<Comparator_i*>( thePred );
2741
2742       CORBA::ULong i = theCriteria->length();
2743       theCriteria->length( i + 1 );
2744
2745       theCriteria[ i ] = createCriterion();
2746
2747       theCriteria[ i ].Type      = aCompar->GetNumFunctor_i()->GetFunctorType();
2748       theCriteria[ i ].Compare   = aFType;
2749       theCriteria[ i ].Threshold = aCompar->GetMargin();
2750       theCriteria[ i ].TypeOfElement = aCompar->GetElementType();
2751
2752       if ( aFType == FT_EqualTo )
2753       {
2754         EqualTo_i* aCompar = dynamic_cast<EqualTo_i*>( thePred );
2755         theCriteria[ i ].Tolerance = aCompar->GetTolerance();
2756       }
2757     }
2758     return true;
2759
2760   case FT_LogicalNOT:
2761     {
2762       Predicate_i* aPred = ( dynamic_cast<LogicalNOT_i*>( thePred ) )->GetPredicate_i();
2763       getCriteria( aPred, theCriteria );
2764       theCriteria[ theCriteria->length() - 1 ].UnaryOp = FT_LogicalNOT;
2765     }
2766     return true;
2767
2768   case FT_LogicalAND:
2769   case FT_LogicalOR:
2770     {
2771       Predicate_i* aPred1 = ( dynamic_cast<LogicalBinary_i*>( thePred ) )->GetPredicate1_i();
2772       Predicate_i* aPred2 = ( dynamic_cast<LogicalBinary_i*>( thePred ) )->GetPredicate2_i();
2773       if ( !getCriteria( aPred1, theCriteria ) )
2774         return false;
2775       theCriteria[ theCriteria->length() - 1 ].BinaryOp = aFType;
2776       return getCriteria( aPred2, theCriteria );
2777     }
2778   case FT_GroupColor:
2779     {
2780       CORBA::ULong i = theCriteria->length();
2781       theCriteria->length( i + 1 );
2782
2783       theCriteria[ i ] = createCriterion();
2784
2785       GroupColor_i* aPred = dynamic_cast<GroupColor_i*>( thePred );
2786       theCriteria[ i ].Type          = aFType;
2787       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2788       theCriteria[ i ].ThresholdStr  = aPred->GetColorStr();
2789
2790       return true;
2791     }
2792   case FT_ElemGeomType:
2793     {
2794       CORBA::ULong i = theCriteria->length();
2795       theCriteria->length( i + 1 );
2796
2797       theCriteria[ i ] = createCriterion();
2798
2799       ElemGeomType_i* aPred = dynamic_cast<ElemGeomType_i*>( thePred );
2800       theCriteria[ i ].Type          = aFType;
2801       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2802       theCriteria[ i ].Threshold     = (double)aPred->GetGeometryType();
2803       return true;
2804     }
2805
2806   case FT_Undefined:
2807     return false;
2808   default:
2809     return false;
2810   }
2811 }
2812
2813 //=======================================================================
2814 // name    : Filter_i::GetCriteria
2815 // Purpose : Retrieve criterions from predicate
2816 //=======================================================================
2817 CORBA::Boolean Filter_i::GetCriteria( SMESH::Filter::Criteria_out theCriteria )
2818 {
2819   theCriteria = new SMESH::Filter::Criteria;
2820   return myPredicate != 0 ? getCriteria( myPredicate, theCriteria ) : true;
2821 }
2822
2823 //=======================================================================
2824 // name    : Filter_i::SetCriteria
2825 // Purpose : Create new predicate and set criterions in it
2826 //=======================================================================
2827 CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria )
2828 {
2829   if ( myPredicate != 0 )
2830     myPredicate->UnRegister();
2831
2832   SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i();
2833   FilterManager_ptr aFilterMgr = aFilter->_this();
2834
2835   // CREATE two lists ( PREDICATES  and LOG OP )
2836
2837   // Criterion
2838   TPythonDump()<<"aCriteria = []";
2839   std::list<SMESH::Predicate_ptr> aPredicates;
2840   std::list<int>                  aBinaries;
2841   for ( int i = 0, n = theCriteria.length(); i < n; i++ )
2842   {
2843     int         aCriterion    = theCriteria[ i ].Type;
2844     int         aCompare      = theCriteria[ i ].Compare;
2845     double      aThreshold    = theCriteria[ i ].Threshold;
2846     const char* aThresholdStr = theCriteria[ i ].ThresholdStr;
2847     const char* aThresholdID  = theCriteria[ i ].ThresholdID;
2848     int         aUnary        = theCriteria[ i ].UnaryOp;
2849     int         aBinary       = theCriteria[ i ].BinaryOp;
2850     double      aTolerance    = theCriteria[ i ].Tolerance;
2851     ElementType aTypeOfElem   = theCriteria[ i ].TypeOfElement;
2852     long        aPrecision    = theCriteria[ i ].Precision;
2853
2854     {
2855       TPythonDump pd;
2856       pd << "aCriterion = SMESH.Filter.Criterion("
2857          << aCriterion    << ", "
2858          << aCompare      << ", "
2859          << aThreshold    << ", '"
2860          << aThresholdStr << "', '";
2861       if (aThresholdID) pd << aThresholdID;
2862       pd                  << "', "
2863          << aUnary        << ", "
2864          << aBinary       << ", "
2865          << aTolerance    << ", "
2866          << aTypeOfElem   << ", "
2867          << aPrecision    << ")";
2868     }
2869     TPythonDump pd;
2870
2871     SMESH::Predicate_ptr aPredicate = SMESH::Predicate::_nil();
2872     SMESH::NumericalFunctor_ptr aFunctor = SMESH::NumericalFunctor::_nil();
2873
2874     switch ( aCriterion )
2875     {
2876       // Functors
2877
2878       case SMESH::FT_MultiConnection:
2879         aFunctor = aFilterMgr->CreateMultiConnection();
2880         break;
2881       case SMESH::FT_MultiConnection2D:
2882         aFunctor = aFilterMgr->CreateMultiConnection2D();
2883         break;
2884       case SMESH::FT_Length:
2885         aFunctor = aFilterMgr->CreateLength();
2886         break;
2887       case SMESH::FT_Length2D:
2888         aFunctor = aFilterMgr->CreateLength2D();
2889         break;
2890       case SMESH::FT_AspectRatio:
2891         aFunctor = aFilterMgr->CreateAspectRatio();
2892         break;
2893       case SMESH::FT_AspectRatio3D:
2894         aFunctor = aFilterMgr->CreateAspectRatio3D();
2895         break;
2896       case SMESH::FT_Warping:
2897         aFunctor = aFilterMgr->CreateWarping();
2898         break;
2899       case SMESH::FT_MinimumAngle:
2900         aFunctor = aFilterMgr->CreateMinimumAngle();
2901         break;
2902       case SMESH::FT_Taper:
2903         aFunctor = aFilterMgr->CreateTaper();
2904         break;
2905       case SMESH::FT_Skew:
2906         aFunctor = aFilterMgr->CreateSkew();
2907         break;
2908       case SMESH::FT_Area:
2909         aFunctor = aFilterMgr->CreateArea();
2910         break;
2911       case SMESH::FT_Volume3D:
2912         aFunctor = aFilterMgr->CreateVolume3D();
2913         break;
2914       case SMESH::FT_MaxElementLength2D:
2915         aFunctor = aFilterMgr->CreateMaxElementLength2D();
2916         break;
2917       case SMESH::FT_MaxElementLength3D:
2918         aFunctor = aFilterMgr->CreateMaxElementLength3D();
2919         break;
2920       case SMESH::FT_BallDiameter:
2921         aFunctor = aFilterMgr->CreateBallDiameter();
2922         break;
2923
2924       // Predicates
2925
2926       case SMESH::FT_FreeBorders:
2927         aPredicate = aFilterMgr->CreateFreeBorders();
2928         break;
2929       case SMESH::FT_FreeEdges:
2930         aPredicate = aFilterMgr->CreateFreeEdges();
2931         break;
2932       case SMESH::FT_FreeFaces:
2933         aPredicate = aFilterMgr->CreateFreeFaces();
2934         break;
2935       case SMESH::FT_FreeNodes:
2936         aPredicate = aFilterMgr->CreateFreeNodes();
2937         break;
2938       case SMESH::FT_EqualNodes:
2939         {
2940           SMESH::EqualNodes_ptr pred = aFilterMgr->CreateEqualNodes();
2941           pred->SetTolerance( aTolerance );
2942           aPredicate = pred;
2943           break;
2944         }
2945       case SMESH::FT_EqualEdges:
2946         aPredicate = aFilterMgr->CreateEqualEdges();
2947         break;
2948       case SMESH::FT_EqualFaces:
2949         aPredicate = aFilterMgr->CreateEqualFaces();
2950         break;
2951       case SMESH::FT_EqualVolumes:
2952         aPredicate = aFilterMgr->CreateEqualVolumes();
2953         break;
2954       case SMESH::FT_BelongToGeom:
2955         {
2956           SMESH::BelongToGeom_ptr tmpPred = aFilterMgr->CreateBelongToGeom();
2957           tmpPred->SetElementType( aTypeOfElem );
2958           tmpPred->SetShape( aThresholdID, aThresholdStr );
2959           tmpPred->SetTolerance( aTolerance );
2960           aPredicate = tmpPred;
2961         }
2962         break;
2963       case SMESH::FT_BelongToPlane:
2964       case SMESH::FT_BelongToCylinder:
2965       case SMESH::FT_BelongToGenSurface:
2966         {
2967           SMESH::BelongToSurface_ptr tmpPred;
2968           switch ( aCriterion ) {
2969           case SMESH::FT_BelongToPlane:
2970             tmpPred = aFilterMgr->CreateBelongToPlane(); break;
2971           case SMESH::FT_BelongToCylinder:
2972             tmpPred = aFilterMgr->CreateBelongToCylinder(); break;
2973           default:
2974             tmpPred = aFilterMgr->CreateBelongToGenSurface();
2975           }
2976           tmpPred->SetShape( aThresholdID, aThresholdStr, aTypeOfElem );
2977           tmpPred->SetTolerance( aTolerance );
2978           aPredicate = tmpPred;
2979         }
2980         break;
2981       case SMESH::FT_LyingOnGeom:
2982         {
2983           SMESH::LyingOnGeom_ptr tmpPred = aFilterMgr->CreateLyingOnGeom();
2984           tmpPred->SetElementType( aTypeOfElem );
2985           tmpPred->SetShape( aThresholdID, aThresholdStr );
2986           tmpPred->SetTolerance( aTolerance );
2987           aPredicate = tmpPred;
2988         }
2989         break;
2990       case SMESH::FT_RangeOfIds:
2991         {
2992           SMESH::RangeOfIds_ptr tmpPred = aFilterMgr->CreateRangeOfIds();
2993           tmpPred->SetRangeStr( aThresholdStr );
2994           tmpPred->SetElementType( aTypeOfElem );
2995           aPredicate = tmpPred;
2996         }
2997         break;
2998       case SMESH::FT_BadOrientedVolume:
2999         {
3000           aPredicate = aFilterMgr->CreateBadOrientedVolume();
3001         }
3002         break;
3003       case SMESH::FT_BareBorderVolume:
3004         {
3005           aPredicate = aFilterMgr->CreateBareBorderVolume();
3006         }
3007         break;
3008       case SMESH::FT_BareBorderFace:
3009         {
3010           aPredicate = aFilterMgr->CreateBareBorderFace();
3011         }
3012         break;
3013       case SMESH::FT_OverConstrainedVolume:
3014         {
3015           aPredicate = aFilterMgr->CreateOverConstrainedVolume();
3016         }
3017         break;
3018       case SMESH::FT_OverConstrainedFace:
3019         {
3020           aPredicate = aFilterMgr->CreateOverConstrainedFace();
3021         }
3022         break;
3023       case SMESH::FT_LinearOrQuadratic:
3024         {
3025           SMESH::LinearOrQuadratic_ptr tmpPred = aFilterMgr->CreateLinearOrQuadratic();
3026           tmpPred->SetElementType( aTypeOfElem );
3027           aPredicate = tmpPred;
3028           break;
3029         }
3030       case SMESH::FT_GroupColor:
3031         {
3032           SMESH::GroupColor_ptr tmpPred = aFilterMgr->CreateGroupColor();
3033           tmpPred->SetElementType( aTypeOfElem );
3034           tmpPred->SetColorStr( aThresholdStr );
3035           aPredicate = tmpPred;
3036           break;
3037         }
3038       case SMESH::FT_ElemGeomType:
3039         {
3040           SMESH::ElemGeomType_ptr tmpPred = aFilterMgr->CreateElemGeomType();
3041           tmpPred->SetElementType( aTypeOfElem );
3042           tmpPred->SetGeometryType( (GeometryType)(int)(aThreshold + 0.5) );
3043           aPredicate = tmpPred;
3044           break;
3045         }
3046       case SMESH::FT_CoplanarFaces:
3047         {
3048           SMESH::CoplanarFaces_ptr tmpPred = aFilterMgr->CreateCoplanarFaces();
3049           tmpPred->SetFace( atol (aThresholdID ));
3050           tmpPred->SetTolerance( aTolerance );
3051           aPredicate = tmpPred;
3052           break;
3053         }
3054
3055       default:
3056         continue;
3057     }
3058
3059     // Comparator
3060     if ( !aFunctor->_is_nil() && aPredicate->_is_nil() )
3061     {
3062       SMESH::Comparator_ptr aComparator = SMESH::Comparator::_nil();
3063
3064       if ( aCompare == SMESH::FT_LessThan )
3065         aComparator = aFilterMgr->CreateLessThan();
3066       else if ( aCompare == SMESH::FT_MoreThan )
3067         aComparator = aFilterMgr->CreateMoreThan();
3068       else if ( aCompare == SMESH::FT_EqualTo )
3069         aComparator = aFilterMgr->CreateEqualTo();
3070       else
3071         continue;
3072
3073       aComparator->SetNumFunctor( aFunctor );
3074       aComparator->SetMargin( aThreshold );
3075
3076       if ( aCompare == FT_EqualTo )
3077       {
3078         SMESH::EqualTo_var anEqualTo = SMESH::EqualTo::_narrow( aComparator );
3079         anEqualTo->SetTolerance( aTolerance );
3080       }
3081
3082       aPredicate = aComparator;
3083
3084       aFunctor->SetPrecision( aPrecision );
3085     }
3086
3087     // Logical not
3088     if ( aUnary == FT_LogicalNOT )
3089     {
3090       SMESH::LogicalNOT_ptr aNotPred = aFilterMgr->CreateLogicalNOT();
3091       aNotPred->SetPredicate( aPredicate );
3092       aPredicate = aNotPred;
3093     }
3094
3095     // logical op
3096     aPredicates.push_back( aPredicate );
3097     aBinaries.push_back( aBinary );
3098     pd <<"aCriteria.append(aCriterion)";
3099
3100   } // end of for
3101   TPythonDump pd; pd<<this<<".SetCriteria(aCriteria)";
3102
3103   // CREATE ONE PREDICATE FROM PREVIOUSLY CREATED MAP
3104
3105   // combine all "AND" operations
3106
3107   std::list<SMESH::Predicate_ptr> aResList;
3108
3109   std::list<SMESH::Predicate_ptr>::iterator aPredIter;
3110   std::list<int>::iterator                  aBinaryIter;
3111
3112   SMESH::Predicate_ptr aPrevPredicate = SMESH::Predicate::_nil();
3113   int aPrevBinary = SMESH::FT_Undefined;
3114
3115   for ( aPredIter = aPredicates.begin(), aBinaryIter = aBinaries.begin();
3116         aPredIter != aPredicates.end() && aBinaryIter != aBinaries.end();
3117         ++aPredIter, ++aBinaryIter )
3118   {
3119     int aCurrBinary = *aBinaryIter;
3120
3121     SMESH::Predicate_ptr aCurrPred = SMESH::Predicate::_nil();
3122
3123     if ( aPrevBinary == SMESH::FT_LogicalAND )
3124     {
3125
3126       SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalAND();
3127       aBinaryPred->SetPredicate1( aPrevPredicate );
3128       aBinaryPred->SetPredicate2( *aPredIter );
3129       aCurrPred = aBinaryPred;
3130     }
3131     else
3132       aCurrPred = *aPredIter;
3133
3134     if ( aCurrBinary != SMESH::FT_LogicalAND )
3135       aResList.push_back( aCurrPred );
3136
3137     aPrevPredicate = aCurrPred;
3138     aPrevBinary = aCurrBinary;
3139   }
3140
3141   // combine all "OR" operations
3142
3143   SMESH::Predicate_ptr aResPredicate = SMESH::Predicate::_nil();
3144
3145   if ( aResList.size() == 1 )
3146     aResPredicate = *aResList.begin();
3147   else if ( aResList.size() > 1 )
3148   {
3149     std::list<SMESH::Predicate_ptr>::iterator anIter = aResList.begin();
3150     aResPredicate = *anIter;
3151     anIter++;
3152     for ( ; anIter != aResList.end(); ++anIter )
3153     {
3154       SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalOR();
3155       aBinaryPred->SetPredicate1( aResPredicate );
3156       aBinaryPred->SetPredicate2( *anIter );
3157       aResPredicate = aBinaryPred;
3158     }
3159   }
3160
3161   SetPredicate( aResPredicate );
3162
3163   return !aResPredicate->_is_nil();
3164 }
3165
3166 //=======================================================================
3167 // name    : Filter_i::GetPredicate_i
3168 // Purpose : Get implementation of predicate
3169 //=======================================================================
3170 Predicate_i* Filter_i::GetPredicate_i()
3171 {
3172   return myPredicate;
3173 }
3174
3175 //=======================================================================
3176 // name    : Filter_i::GetPredicate
3177 // Purpose : Get predicate
3178 //=======================================================================
3179 Predicate_ptr Filter_i::GetPredicate()
3180 {
3181   if ( myPredicate == 0 )
3182     return SMESH::Predicate::_nil();
3183   else
3184   {
3185     SMESH::Predicate_var anObj = myPredicate->_this();
3186     // if ( SMESH::Functor_i* fun = SMESH::DownCast<SMESH::Functor_i*>( anObj ))
3187     //   TPythonDump() << fun << " = " << this << ".GetPredicate()";
3188     return anObj._retn();
3189   }
3190 }
3191
3192 /*
3193                             FILTER LIBRARY
3194 */
3195
3196 #define ATTR_TYPE          "type"
3197 #define ATTR_COMPARE       "compare"
3198 #define ATTR_THRESHOLD     "threshold"
3199 #define ATTR_UNARY         "unary"
3200 #define ATTR_BINARY        "binary"
3201 #define ATTR_THRESHOLD_STR "threshold_str"
3202 #define ATTR_TOLERANCE     "tolerance"
3203 #define ATTR_ELEMENT_TYPE  "ElementType"
3204
3205 //=======================================================================
3206 // name    : toString
3207 // Purpose : Convert bool to LDOMString
3208 //=======================================================================
3209 static inline LDOMString toString( CORBA::Boolean val )
3210 {
3211   return val ? "logical not" : "";
3212 }
3213
3214 //=======================================================================
3215 // name    : toBool
3216 // Purpose : Convert LDOMString to bool
3217 //=======================================================================
3218 static inline bool toBool( const LDOMString& theStr )
3219 {
3220   return theStr.equals( "logical not" );
3221 }
3222
3223 //=======================================================================
3224 // name    : toString
3225 // Purpose : Convert double to LDOMString
3226 //=======================================================================
3227 static inline LDOMString toString( CORBA::Double val )
3228 {
3229   char a[ 255 ];
3230   sprintf( a, "%e", val );
3231   return LDOMString( a );
3232 }
3233
3234 //=======================================================================
3235 // name    : toDouble
3236 // Purpose : Convert LDOMString to double
3237 //=======================================================================
3238 static inline double toDouble( const LDOMString& theStr )
3239 {
3240   return atof( theStr.GetString() );
3241 }
3242
3243 //=======================================================================
3244 // name    : toString
3245 // Purpose : Convert functor type to LDOMString
3246 //=======================================================================
3247 static inline LDOMString toString( CORBA::Long theType )
3248 {
3249   switch ( theType )
3250   {
3251     case FT_AspectRatio     : return "Aspect ratio";
3252     case FT_Warping         : return "Warping";
3253     case FT_MinimumAngle    : return "Minimum angle";
3254     case FT_Taper           : return "Taper";
3255     case FT_Skew            : return "Skew";
3256     case FT_Area            : return "Area";
3257     case FT_Volume3D        : return "Volume3D";
3258     case FT_MaxElementLength2D: return "Max element length 2D";
3259     case FT_MaxElementLength3D: return "Max element length 3D";
3260     case FT_BelongToGeom    : return "Belong to Geom";
3261     case FT_BelongToPlane   : return "Belong to Plane";
3262     case FT_BelongToCylinder: return "Belong to Cylinder";
3263     case FT_BelongToGenSurface: return "Belong to Generic Surface";
3264     case FT_LyingOnGeom     : return "Lying on Geom";
3265     case FT_BadOrientedVolume:return "Bad Oriented Volume";
3266     case FT_BareBorderVolume: return "Volumes with bare border";
3267     case FT_BareBorderFace  : return "Faces with bare border";
3268     case FT_OverConstrainedVolume: return "Over-constrained Volumes";
3269     case FT_OverConstrainedFace  : return "Over-constrained Faces";
3270     case FT_RangeOfIds      : return "Range of IDs";
3271     case FT_FreeBorders     : return "Free borders";
3272     case FT_FreeEdges       : return "Free edges";
3273     case FT_FreeFaces       : return "Free faces";
3274     case FT_FreeNodes       : return "Free nodes";
3275     case FT_EqualNodes      : return "Equal nodes";
3276     case FT_EqualEdges      : return "Equal edges";
3277     case FT_EqualFaces      : return "Equal faces";
3278     case FT_EqualVolumes    : return "Equal volumes";
3279     case FT_MultiConnection : return "Borders at multi-connections";
3280     case FT_MultiConnection2D:return "Borders at multi-connections 2D";
3281     case FT_Length          : return "Length";
3282     case FT_Length2D        : return "Length 2D";
3283     case FT_LessThan        : return "Less than";
3284     case FT_MoreThan        : return "More than";
3285     case FT_EqualTo         : return "Equal to";
3286     case FT_LogicalNOT      : return "Not";
3287     case FT_LogicalAND      : return "And";
3288     case FT_LogicalOR       : return "Or";
3289     case FT_GroupColor      : return "Color of Group";
3290     case FT_LinearOrQuadratic : return "Linear or Quadratic";
3291     case FT_ElemGeomType    : return "Element geomtry type";
3292     case FT_Undefined       : return "";
3293     default                 : return "";
3294   }
3295 }
3296
3297 //=======================================================================
3298 // name    : toFunctorType
3299 // Purpose : Convert LDOMString to functor type
3300 //=======================================================================
3301 static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
3302 {
3303   if      ( theStr.equals( "Aspect ratio"                 ) ) return FT_AspectRatio;
3304   else if ( theStr.equals( "Warping"                      ) ) return FT_Warping;
3305   else if ( theStr.equals( "Minimum angle"                ) ) return FT_MinimumAngle;
3306   else if ( theStr.equals( "Taper"                        ) ) return FT_Taper;
3307   else if ( theStr.equals( "Skew"                         ) ) return FT_Skew;
3308   else if ( theStr.equals( "Area"                         ) ) return FT_Area;
3309   else if ( theStr.equals( "Volume3D"                     ) ) return FT_Volume3D;
3310   else if ( theStr.equals( "Max element length 2D"        ) ) return FT_MaxElementLength2D;
3311   else if ( theStr.equals( "Max element length 3D"        ) ) return FT_MaxElementLength3D;
3312   else if ( theStr.equals( "Belong to Geom"               ) ) return FT_BelongToGeom;
3313   else if ( theStr.equals( "Belong to Plane"              ) ) return FT_BelongToPlane;
3314   else if ( theStr.equals( "Belong to Cylinder"           ) ) return FT_BelongToCylinder;
3315   else if ( theStr.equals( "Belong to Generic Surface"    ) ) return FT_BelongToGenSurface;
3316   else if ( theStr.equals( "Lying on Geom"                ) ) return FT_LyingOnGeom;
3317   else if ( theStr.equals( "Free borders"                 ) ) return FT_FreeBorders;
3318   else if ( theStr.equals( "Free edges"                   ) ) return FT_FreeEdges;
3319   else if ( theStr.equals( "Free faces"                   ) ) return FT_FreeFaces;
3320   else if ( theStr.equals( "Free nodes"                   ) ) return FT_FreeNodes;
3321   else if ( theStr.equals( "Equal nodes"                  ) ) return FT_EqualNodes;
3322   else if ( theStr.equals( "Equal edges"                  ) ) return FT_EqualEdges;
3323   else if ( theStr.equals( "Equal faces"                  ) ) return FT_EqualFaces;
3324   else if ( theStr.equals( "Equal volumes"                ) ) return FT_EqualVolumes;
3325   else if ( theStr.equals( "Borders at multi-connections" ) ) return FT_MultiConnection;
3326   //  else if ( theStr.equals( "Borders at multi-connections 2D" ) ) return FT_MultiConnection2D;
3327   else if ( theStr.equals( "Length"                       ) ) return FT_Length;
3328   //  else if ( theStr.equals( "Length2D"                     ) ) return FT_Length2D;
3329   else if ( theStr.equals( "Range of IDs"                 ) ) return FT_RangeOfIds;
3330   else if ( theStr.equals( "Bad Oriented Volume"          ) ) return FT_BadOrientedVolume;
3331   else if ( theStr.equals( "Volumes with bare border"     ) ) return FT_BareBorderVolume;
3332   else if ( theStr.equals( "Faces with bare border"       ) ) return FT_BareBorderFace;
3333   else if ( theStr.equals( "Over-constrained Volumes"     ) ) return FT_OverConstrainedVolume;
3334   else if ( theStr.equals( "Over-constrained Faces"       ) ) return FT_OverConstrainedFace;
3335   else if ( theStr.equals( "Less than"                    ) ) return FT_LessThan;
3336   else if ( theStr.equals( "More than"                    ) ) return FT_MoreThan;
3337   else if ( theStr.equals( "Equal to"                     ) ) return FT_EqualTo;
3338   else if ( theStr.equals( "Not"                          ) ) return FT_LogicalNOT;
3339   else if ( theStr.equals( "And"                          ) ) return FT_LogicalAND;
3340   else if ( theStr.equals( "Or"                           ) ) return FT_LogicalOR;
3341   else if ( theStr.equals( "Color of Group"               ) ) return FT_GroupColor;
3342   else if ( theStr.equals( "Linear or Quadratic"          ) ) return FT_LinearOrQuadratic;
3343   else if ( theStr.equals( "Element geomtry type"         ) ) return FT_ElemGeomType;
3344   else if ( theStr.equals( ""                             ) ) return FT_Undefined;
3345   else  return FT_Undefined;
3346 }
3347
3348 //=======================================================================
3349 // name    : toFunctorType
3350 // Purpose : Convert LDOMString to value of ElementType enumeration
3351 //=======================================================================
3352 static inline SMESH::ElementType toElementType( const LDOMString& theStr )
3353 {
3354   if      ( theStr.equals( "NODE"   ) ) return SMESH::NODE;
3355   else if ( theStr.equals( "EDGE"   ) ) return SMESH::EDGE;
3356   else if ( theStr.equals( "FACE"   ) ) return SMESH::FACE;
3357   else if ( theStr.equals( "VOLUME" ) ) return SMESH::VOLUME;
3358   else                                  return SMESH::ALL;
3359 }
3360
3361 //=======================================================================
3362 // name    : toString
3363 // Purpose : Convert ElementType to string
3364 //=======================================================================
3365 static inline LDOMString toString( const SMESH::ElementType theType )
3366 {
3367   switch ( theType )
3368   {
3369     case SMESH::NODE   : return "NODE";
3370     case SMESH::EDGE   : return "EDGE";
3371     case SMESH::FACE   : return "FACE";
3372     case SMESH::VOLUME : return "VOLUME";
3373     case SMESH::ALL    : return "ALL";
3374     default            : return "";
3375   }
3376 }
3377
3378 //=======================================================================
3379 // name    : findFilter
3380 // Purpose : Find filter in document
3381 //=======================================================================
3382 static LDOM_Element findFilter( const char* theFilterName,
3383                                 const LDOM_Document& theDoc,
3384                                 LDOM_Node* theParent = 0 )
3385 {
3386   LDOM_Element aRootElement = theDoc.getDocumentElement();
3387   if ( aRootElement.isNull() || !aRootElement.hasChildNodes() )
3388     return LDOM_Element();
3389
3390   for ( LDOM_Node aTypeNode = aRootElement.getFirstChild();
3391         !aTypeNode.isNull(); aTypeNode = aTypeNode.getNextSibling() )
3392   {
3393     for ( LDOM_Node aFilter = aTypeNode.getFirstChild();
3394           !aFilter.isNull(); aFilter = aFilter.getNextSibling() )
3395     {
3396       LDOM_Element* anElem = ( LDOM_Element* )&aFilter;
3397       if ( anElem->getTagName().equals( LDOMString( "filter" ) ) &&
3398            anElem->getAttribute( "name" ).equals( LDOMString( theFilterName ) ) )
3399       {
3400         if ( theParent != 0  )
3401           *theParent = aTypeNode;
3402         return (LDOM_Element&)aFilter;
3403       }
3404     }
3405   }
3406   return LDOM_Element();
3407 }
3408
3409 //=======================================================================
3410 // name    : getSectionName
3411 // Purpose : Get name of section of filters
3412 //=======================================================================
3413 static const char* getSectionName( const ElementType theType )
3414 {
3415   switch ( theType )
3416   {
3417     case SMESH::NODE   : return "Filters for nodes";
3418     case SMESH::EDGE   : return "Filters for edges";
3419     case SMESH::FACE   : return "Filters for faces";
3420     case SMESH::VOLUME : return "Filters for volumes";
3421     case SMESH::ALL    : return "Filters for elements";
3422     default            : return "";
3423   }
3424 }
3425
3426 //=======================================================================
3427 // name    : getSection
3428 // Purpose : Create section for filters corresponding to the entity type
3429 //=======================================================================
3430 static LDOM_Node getSection( const ElementType theType,
3431                              LDOM_Document&    theDoc,
3432                              const bool        toCreate = false )
3433 {
3434   LDOM_Element aRootElement = theDoc.getDocumentElement();
3435   if ( aRootElement.isNull() )
3436     return LDOM_Node();
3437
3438   // Find section
3439   bool anExist = false;
3440   const char* aSectionName = getSectionName( theType );
3441   if ( strcmp( aSectionName, "" ) == 0 )
3442     return LDOM_Node();
3443
3444   LDOM_NodeList aSections = theDoc.getElementsByTagName( "section" );
3445   LDOM_Node aNode;
3446   for ( int i = 0, n = aSections.getLength(); i < n; i++ )
3447   {
3448     aNode = aSections.item( i );
3449     LDOM_Element& anItem = ( LDOM_Element& )aNode;
3450     if ( anItem.getAttribute( "name" ).equals( LDOMString( aSectionName ) ) )
3451     {
3452       anExist = true;
3453       break;
3454     }
3455   }
3456
3457   // Create new section if necessary
3458   if ( !anExist )
3459   {
3460     if ( toCreate )
3461     {
3462       LDOM_Element aNewItem = theDoc.createElement( "section" );
3463       aNewItem.setAttribute( "name", aSectionName );
3464       aRootElement.appendChild( aNewItem );
3465       return aNewItem;
3466     }
3467     else
3468       return LDOM_Node();
3469   }
3470   return
3471     aNode;
3472 }
3473
3474 //=======================================================================
3475 // name    : createFilterItem
3476 // Purpose : Create filter item or LDOM document
3477 //=======================================================================
3478 static LDOM_Element createFilterItem( const char*       theName,
3479                                       SMESH::Filter_ptr theFilter,
3480                                       LDOM_Document&    theDoc )
3481 {
3482   // create new filter in document
3483   LDOM_Element aFilterItem = theDoc.createElement( "filter" );
3484   aFilterItem.setAttribute( "name", theName );
3485
3486   // save filter criterions
3487   SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria;
3488
3489   if ( !theFilter->GetCriteria( aCriteria ) )
3490     return LDOM_Element();
3491
3492   for ( CORBA::ULong i = 0, n = aCriteria->length(); i < n; i++ )
3493   {
3494     LDOM_Element aCriterionItem = theDoc.createElement( "criterion" );
3495     
3496     aCriterionItem.setAttribute( ATTR_TYPE         , toString(  aCriteria[ i ].Type) );
3497     aCriterionItem.setAttribute( ATTR_COMPARE      , toString(  aCriteria[ i ].Compare ) );
3498     aCriterionItem.setAttribute( ATTR_THRESHOLD    , toString(  aCriteria[ i ].Threshold ) );
3499     aCriterionItem.setAttribute( ATTR_UNARY        , toString(  aCriteria[ i ].UnaryOp ) );
3500     aCriterionItem.setAttribute( ATTR_BINARY       , toString(  aCriteria[ i ].BinaryOp ) );
3501
3502     aCriterionItem.setAttribute( ATTR_THRESHOLD_STR, (const char*)aCriteria[ i ].ThresholdStr );
3503     aCriterionItem.setAttribute( ATTR_TOLERANCE    , toString( aCriteria[ i ].Tolerance ) );
3504     aCriterionItem.setAttribute( ATTR_ELEMENT_TYPE ,
3505       toString( (SMESH::ElementType)aCriteria[ i ].TypeOfElement ) );
3506
3507     aFilterItem.appendChild( aCriterionItem );
3508   }
3509
3510   return aFilterItem;
3511 }
3512
3513 //=======================================================================
3514 // name    : FilterLibrary_i::FilterLibrary_i
3515 // Purpose : Constructor
3516 //=======================================================================
3517 FilterLibrary_i::FilterLibrary_i( const char* theFileName )
3518 {
3519   myFileName = strdup( theFileName );
3520   SMESH::FilterManager_i* aFilterMgr = new SMESH::FilterManager_i();
3521   myFilterMgr = aFilterMgr->_this();
3522
3523   LDOMParser aParser;
3524
3525   // Try to use existing library file
3526   bool anExists = false;
3527   if ( !aParser.parse( myFileName ) )
3528   {
3529     myDoc = aParser.getDocument();
3530     anExists = true;
3531   }
3532   // Create a new XML document if it doesn't exist
3533   else
3534     myDoc = LDOM_Document::createDocument( LDOMString() );
3535
3536   LDOM_Element aRootElement = myDoc.getDocumentElement();
3537   if ( aRootElement.isNull() )
3538   {
3539     // If the existing document is empty --> try to create a new one
3540     if ( anExists )
3541       myDoc = LDOM_Document::createDocument( LDOMString() );
3542   }
3543 }
3544
3545 //=======================================================================
3546 // name    : FilterLibrary_i::FilterLibrary_i
3547 // Purpose : Constructor
3548 //=======================================================================
3549 FilterLibrary_i::FilterLibrary_i()
3550 {
3551   myFileName = 0;
3552   SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i();
3553   myFilterMgr = aFilter->_this();
3554
3555   myDoc = LDOM_Document::createDocument( LDOMString() );
3556 }
3557
3558 FilterLibrary_i::~FilterLibrary_i()
3559 {
3560   delete myFileName;
3561   //TPythonDump()<<this<<".UnRegister()";
3562 }
3563
3564 //=======================================================================
3565 // name    : FilterLibrary_i::Copy
3566 // Purpose : Create filter and initialize it with values from library
3567 //=======================================================================
3568 Filter_ptr FilterLibrary_i::Copy( const char* theFilterName )
3569 {
3570   Filter_ptr aRes = Filter::_nil();
3571   LDOM_Node aFilter = findFilter( theFilterName, myDoc );
3572
3573   if ( aFilter.isNull() )
3574     return aRes;
3575
3576   std::list<SMESH::Filter::Criterion> aCriteria;
3577
3578   for ( LDOM_Node aCritNode = aFilter.getFirstChild();
3579         !aCritNode.isNull() ; aCritNode = aCritNode.getNextSibling() )
3580   {
3581     LDOM_Element* aCrit = (LDOM_Element*)&aCritNode;
3582
3583     const char* aTypeStr      = aCrit->getAttribute( ATTR_TYPE          ).GetString();
3584     const char* aCompareStr   = aCrit->getAttribute( ATTR_COMPARE       ).GetString();
3585     const char* aUnaryStr     = aCrit->getAttribute( ATTR_UNARY         ).GetString();
3586     const char* aBinaryStr    = aCrit->getAttribute( ATTR_BINARY        ).GetString();
3587     const char* anElemTypeStr = aCrit->getAttribute( ATTR_ELEMENT_TYPE  ).GetString();
3588
3589     SMESH::Filter::Criterion aCriterion = createCriterion();
3590
3591     aCriterion.Type          = toFunctorType( aTypeStr );
3592     aCriterion.Compare       = toFunctorType( aCompareStr );
3593     aCriterion.UnaryOp       = toFunctorType( aUnaryStr );
3594     aCriterion.BinaryOp      = toFunctorType( aBinaryStr );
3595
3596     aCriterion.TypeOfElement = toElementType( anElemTypeStr );
3597
3598     LDOMString str = aCrit->getAttribute( ATTR_THRESHOLD );
3599     int val = 0;
3600     aCriterion.Threshold = str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val )
3601       ? val : atof( str.GetString() );
3602
3603     str = aCrit->getAttribute( ATTR_TOLERANCE );
3604     aCriterion.Tolerance = str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val )
3605       ? val : atof( str.GetString() );
3606
3607     str = aCrit->getAttribute( ATTR_THRESHOLD_STR );
3608     if ( str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val ) )
3609     {
3610       char a[ 255 ];
3611       sprintf( a, "%d", val );
3612       aCriterion.ThresholdStr = strdup( a );
3613     }
3614     else
3615       aCriterion.ThresholdStr = str.GetString();
3616
3617     aCriteria.push_back( aCriterion );
3618   }
3619
3620   SMESH::Filter::Criteria_var aCriteriaVar = new SMESH::Filter::Criteria;
3621   aCriteriaVar->length( aCriteria.size() );
3622
3623   CORBA::ULong i = 0;
3624   std::list<SMESH::Filter::Criterion>::iterator anIter = aCriteria.begin();
3625
3626   for( ; anIter != aCriteria.end(); ++anIter )
3627     aCriteriaVar[ i++ ] = *anIter;
3628
3629   aRes = myFilterMgr->CreateFilter();
3630   aRes->SetCriteria( aCriteriaVar.inout() );
3631
3632   TPythonDump()<<this<<".Copy('"<<theFilterName<<"')";
3633
3634   return aRes;
3635 }
3636
3637 //=======================================================================
3638 // name    : FilterLibrary_i::SetFileName
3639 // Purpose : Set file name for library
3640 //=======================================================================
3641 void FilterLibrary_i::SetFileName( const char* theFileName )
3642 {
3643   delete myFileName;
3644   myFileName = strdup( theFileName );
3645   TPythonDump()<<this<<".SetFileName('"<<theFileName<<"')";
3646 }
3647
3648 //=======================================================================
3649 // name    : FilterLibrary_i::GetFileName
3650 // Purpose : Get file name of library
3651 //=======================================================================
3652 char* FilterLibrary_i::GetFileName()
3653 {
3654   return CORBA::string_dup( myFileName );
3655 }
3656
3657 //=======================================================================
3658 // name    : FilterLibrary_i::Add
3659 // Purpose : Add new filter to library
3660 //=======================================================================
3661 CORBA::Boolean FilterLibrary_i::Add( const char* theFilterName, Filter_ptr theFilter )
3662 {
3663   // if filter already in library or entry filter is null do nothing
3664   LDOM_Node aFilterNode = findFilter( theFilterName, myDoc );
3665   if ( !aFilterNode.isNull() || theFilter->_is_nil() )
3666     return false;
3667
3668   // get section corresponding to the filter type
3669   ElementType anEntType = theFilter->GetElementType();
3670
3671   LDOM_Node aSection = getSection( anEntType, myDoc, true );
3672   if ( aSection.isNull() )
3673     return false;
3674
3675   // create filter item
3676   LDOM_Element aFilterItem = createFilterItem( theFilterName, theFilter, myDoc );
3677   if ( aFilterItem.isNull() )
3678     return false;
3679   else
3680   {
3681     aSection.appendChild( aFilterItem );
3682     if(Filter_i* aFilter = DownCast<Filter_i*>(theFilter))
3683       TPythonDump()<<this<<".Add('"<<theFilterName<<"',"<<aFilter<<")";
3684     return true;
3685   }
3686 }
3687
3688 //=======================================================================
3689 // name    : FilterLibrary_i::Add
3690 // Purpose : Add new filter to library
3691 //=======================================================================
3692 CORBA::Boolean FilterLibrary_i::AddEmpty( const char* theFilterName, ElementType theType )
3693 {
3694   // if filter already in library or entry filter is null do nothing
3695   LDOM_Node aFilterNode = findFilter( theFilterName, myDoc );
3696   if ( !aFilterNode.isNull() )
3697     return false;
3698
3699   LDOM_Node aSection = getSection( theType, myDoc, true );
3700   if ( aSection.isNull() )
3701     return false;
3702
3703   // create filter item
3704   Filter_var aFilter = myFilterMgr->CreateFilter();
3705
3706   LDOM_Element aFilterItem = createFilterItem( theFilterName, aFilter, myDoc );
3707   if ( aFilterItem.isNull() )
3708     return false;
3709   else
3710   {
3711     aSection.appendChild( aFilterItem );
3712     TPythonDump()<<this<<".AddEmpty('"<<theFilterName<<"',"<<theType<<")";
3713     return true;
3714   }
3715 }
3716
3717 //=======================================================================
3718 // name    : FilterLibrary_i::Delete
3719 // Purpose : Delete filter from library
3720 //=======================================================================
3721 CORBA::Boolean FilterLibrary_i::Delete ( const char* theFilterName )
3722 {
3723   LDOM_Node aParentNode;
3724   LDOM_Node aFilterNode = findFilter( theFilterName, myDoc, &aParentNode );
3725   if ( aFilterNode.isNull() || aParentNode.isNull() )
3726     return false;
3727
3728   aParentNode.removeChild( aFilterNode );
3729   TPythonDump()<<this<<".Delete('"<<theFilterName<<"')";
3730   return true;
3731 }
3732
3733 //=======================================================================
3734 // name      : FilterLibrary_i::Replace
3735 // Purpose   : Replace existing filter with entry filter.
3736 // IMPORTANT : If filter does not exist it is not created
3737 //=======================================================================
3738 CORBA::Boolean FilterLibrary_i::Replace( const char* theFilterName,
3739                                          const char* theNewName,
3740                                          Filter_ptr  theFilter )
3741 {
3742   LDOM_Element aFilterItem = findFilter( theFilterName, myDoc );
3743   if ( aFilterItem.isNull() || theFilter->_is_nil() )
3744     return false;
3745
3746   LDOM_Element aNewItem = createFilterItem( theNewName, theFilter, myDoc );
3747   if ( aNewItem.isNull() )
3748     return false;
3749   else
3750   {
3751     aFilterItem.ReplaceElement( aNewItem );
3752     if(Filter_i* aFilter = DownCast<Filter_i*>(theFilter))
3753       TPythonDump()<<this<<".Replace('"<<theFilterName<<"','"<<theNewName<<"',"<<aFilter<<")";
3754     return true;
3755   }
3756 }
3757
3758 //=======================================================================
3759 // name    : FilterLibrary_i::Save
3760 // Purpose : Save library on disk
3761 //=======================================================================
3762 CORBA::Boolean FilterLibrary_i::Save()
3763 {
3764   if ( myFileName == 0 || strlen( myFileName ) == 0 )
3765     return false;
3766
3767   FILE* aOutFile = fopen( myFileName, "wt" );
3768   if ( !aOutFile )
3769     return false;
3770
3771   LDOM_XmlWriter aWriter( aOutFile );
3772   aWriter.SetIndentation( 2 );
3773   aWriter << myDoc;
3774   fclose( aOutFile );
3775
3776   TPythonDump()<<this<<".Save()";
3777   return true;
3778 }
3779
3780 //=======================================================================
3781 // name    : FilterLibrary_i::SaveAs
3782 // Purpose : Save library on disk
3783 //=======================================================================
3784 CORBA::Boolean FilterLibrary_i::SaveAs( const char* aFileName )
3785 {
3786   myFileName = strdup ( aFileName );
3787   TPythonDump()<<this<<".SaveAs('"<<aFileName<<"')";
3788   return Save();
3789 }
3790
3791 //=======================================================================
3792 // name    : FilterLibrary_i::IsPresent
3793 // Purpose : Verify whether filter is in library
3794 //=======================================================================
3795 CORBA::Boolean FilterLibrary_i::IsPresent( const char* theFilterName )
3796 {
3797   return !findFilter( theFilterName, myDoc ).isNull();
3798 }
3799
3800 //=======================================================================
3801 // name    : FilterLibrary_i::NbFilters
3802 // Purpose : Return amount of filters in library
3803 //=======================================================================
3804 CORBA::Long FilterLibrary_i::NbFilters( ElementType theType )
3805 {
3806   string_array_var aNames = GetNames( theType );
3807   return aNames->length();
3808 }
3809
3810 //=======================================================================
3811 // name    : FilterLibrary_i::GetNames
3812 // Purpose : Get names of filters from library
3813 //=======================================================================
3814 string_array* FilterLibrary_i::GetNames( ElementType theType )
3815 {
3816   string_array_var anArray = new string_array;
3817   TColStd_SequenceOfHAsciiString aSeq;
3818
3819   LDOM_Node aSection = getSection( theType, myDoc, false );
3820
3821   if ( !aSection.isNull() )
3822   {
3823     for ( LDOM_Node aFilter = aSection.getFirstChild();
3824           !aFilter.isNull(); aFilter = aFilter.getNextSibling() )
3825     {
3826       LDOM_Element& anElem = ( LDOM_Element& )aFilter;
3827       aSeq.Append( new TCollection_HAsciiString(
3828          (Standard_CString)anElem.getAttribute( "name" ).GetString() ) );
3829     }
3830   }
3831
3832   anArray->length( aSeq.Length() );
3833   for ( int i = 1, n = aSeq.Length(); i <= n; i++ )
3834     anArray[ i - 1 ] = CORBA::string_dup( aSeq( i )->ToCString() );
3835
3836   return anArray._retn();
3837 }
3838
3839 //=======================================================================
3840 // name    : FilterLibrary_i::GetAllNames
3841 // Purpose : Get names of filters from library
3842 //=======================================================================
3843 string_array* FilterLibrary_i::GetAllNames()
3844 {
3845   string_array_var aResArray = new string_array;
3846   for ( int type = SMESH::ALL; type <= SMESH::VOLUME; type++ )
3847   {
3848     SMESH::string_array_var aNames = GetNames( (SMESH::ElementType)type );
3849
3850     int aPrevLength = aResArray->length();
3851     aResArray->length( aPrevLength + aNames->length() );
3852     for ( int i = 0, n = aNames->length(); i < n; i++ )
3853       aResArray[ aPrevLength + i ] = aNames[ i ];
3854   }
3855
3856   return aResArray._retn();
3857 }
3858
3859 //================================================================================
3860 /*!
3861  * \brief Return an array of strings corresponding to items of enum FunctorType
3862  */
3863 //================================================================================
3864
3865 static const char** getFunctNames()
3866 {
3867   static const char* functName[ SMESH::FT_Undefined + 1 ] = {
3868     // IT's necessary to update this array according to enum FunctorType (SMESH_Filter.idl)
3869     // The order is IMPORTANT !!!
3870     "FT_AspectRatio",
3871     "FT_AspectRatio3D",
3872     "FT_Warping",
3873     "FT_MinimumAngle",
3874     "FT_Taper",
3875     "FT_Skew",
3876     "FT_Area",
3877     "FT_Volume3D",
3878     "FT_MaxElementLength2D",
3879     "FT_MaxElementLength3D",
3880     "FT_FreeBorders",
3881     "FT_FreeEdges",
3882     "FT_FreeNodes",
3883     "FT_FreeFaces",
3884     "FT_EqualNodes",
3885     "FT_EqualEdges",
3886     "FT_EqualFaces",
3887     "FT_EqualVolumes",
3888     "FT_MultiConnection",
3889     "FT_MultiConnection2D",
3890     "FT_Length",
3891     "FT_Length2D",
3892     "FT_BelongToGeom",
3893     "FT_BelongToPlane",
3894     "FT_BelongToCylinder",
3895     "FT_BelongToGenSurface",
3896     "FT_LyingOnGeom",
3897     "FT_RangeOfIds",
3898     "FT_BadOrientedVolume",
3899     "FT_BareBorderVolume",
3900     "FT_BareBorderFace",
3901     "FT_OverConstrainedVolume",
3902     "FT_OverConstrainedFace",
3903     "FT_LinearOrQuadratic",
3904     "FT_GroupColor",
3905     "FT_ElemGeomType",
3906     "FT_CoplanarFaces",
3907     "FT_BallDiameter",
3908     "FT_LessThan",
3909     "FT_MoreThan",
3910     "FT_EqualTo",
3911     "FT_LogicalNOT",
3912     "FT_LogicalAND",
3913     "FT_LogicalOR",
3914     "FT_Undefined" };
3915   return functName;
3916 }
3917
3918 //================================================================================
3919 /*!
3920  * \brief Return a string corresponding to an item of enum FunctorType
3921  */
3922 //================================================================================
3923
3924 const char* SMESH::FunctorTypeToString(SMESH::FunctorType ft)
3925 {
3926   if ( ft < 0 || ft > SMESH::FT_Undefined )
3927     return "FT_Undefined";
3928   return getFunctNames()[ ft ];
3929 }
3930
3931 //================================================================================
3932 /*!
3933  * \brief Converts a string to FunctorType. This is reverse of FunctorTypeToString()
3934  */
3935 //================================================================================
3936
3937 SMESH::FunctorType SMESH::StringToFunctorType(const char* str)
3938 {
3939   std::string name( str + 3 ); // skip "FT_"
3940   const char** functNames = getFunctNames();
3941   int ft = 0;
3942   for ( ; ft < SMESH::FT_Undefined; ++ft )
3943     if ( name == ( functNames[ft] + 3 ))
3944       break;
3945
3946   //ASSERT( strcmp( str, FunctorTypeToString( SMESH::FunctorType( ft ))) == 0 );
3947
3948   return SMESH::FunctorType( ft );
3949 }