Salome HOME
'Extrusion Along Path' dialog box : rearrange widgets
[modules/smesh.git] / src / SMESH_I / SMESH_Filter_i.cxx
1 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
2 //
3 //  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
21 //
22 //
23 //
24 //  File   : SMESH_Filter_i.cxx
25 //  Author : Alexey Petrov, OCC
26 //  Module : SMESH
27
28
29 #include "SMESH_Filter_i.hxx"
30
31 #include "SMESH_Gen_i.hxx"
32
33 #include "SMDS_Mesh.hxx"
34 #include "SMDS_MeshNode.hxx"
35 #include "SMDS_MeshElement.hxx"
36
37 #include "SMESHDS_Mesh.hxx"
38
39 #include <LDOM_Document.hxx>
40 #include <LDOM_Element.hxx>
41 #include <LDOM_Node.hxx>
42 #include <LDOMString.hxx>
43 #include <LDOMParser.hxx>
44 #include <LDOM_XmlWriter.hxx>
45 #include <TCollection_HAsciiString.hxx>
46 #include <TColStd_ListIteratorOfListOfInteger.hxx>
47 #include <TColStd_ListOfInteger.hxx>
48 #include <TColStd_ListOfReal.hxx>
49 #include <TColStd_MapOfInteger.hxx>
50 #include <TColStd_SequenceOfHAsciiString.hxx>
51 #include <TColStd_ListIteratorOfListOfReal.hxx>
52 #include <Precision.hxx>
53 #include <BRep_Tool.hxx>
54 #include <TopoDS_Shape.hxx>
55 #include <TopoDS.hxx>
56 #include <TopoDS_Face.hxx>
57 #include <Geom_Plane.hxx>
58 #include <Geom_CylindricalSurface.hxx>
59 #include <TopExp_Explorer.hxx>
60 #include <OSD_Path.hxx>
61 #include <OSD_File.hxx>
62
63 using namespace SMESH;
64 using namespace SMESH::Controls;
65
66 /*
67   Class       : BelongToGeom
68   Description : Predicate for verifying whether entiy belong to
69                 specified geometrical support
70 */
71
72 Controls::BelongToGeom::BelongToGeom()
73 : myMeshDS(NULL),
74   myType(SMDSAbs_All)
75 {}
76
77 void Controls::BelongToGeom::SetMesh( SMDS_Mesh* theMesh )
78 {
79   myMeshDS = dynamic_cast<SMESHDS_Mesh*>(theMesh);
80 }
81
82 void Controls::BelongToGeom::SetGeom( const TopoDS_Shape& theShape )
83 {
84   myShape = theShape;
85 }
86
87 static bool IsContains( SMESHDS_Mesh*           theMeshDS,
88                         const TopoDS_Shape&     theShape,
89                         const SMDS_MeshElement* theElem,
90                         TopAbs_ShapeEnum        theFindShapeEnum,
91                         TopAbs_ShapeEnum        theAvoidShapeEnum = TopAbs_SHAPE )
92 {
93   TopExp_Explorer anExp( theShape,theFindShapeEnum,theAvoidShapeEnum );
94   
95   while( anExp.More() )
96   {
97     const TopoDS_Shape& aShape = anExp.Current();
98     if( SMESHDS_SubMesh* aSubMesh = theMeshDS->MeshElements( aShape ) ){
99       if( aSubMesh->Contains( theElem ) )
100         return true;
101     }
102     anExp.Next();
103   }
104   return false;
105 }
106
107 bool Controls::BelongToGeom::IsSatisfy( long theId )
108 {
109   if ( myMeshDS == 0 || myShape.IsNull() )
110     return false;
111
112   if( myType == SMDSAbs_Node )
113   {
114     if( const SMDS_MeshNode* aNode = myMeshDS->FindNode( theId ) )
115     {
116       const SMDS_PositionPtr& aPosition = aNode->GetPosition();
117       SMDS_TypeOfPosition aTypeOfPosition = aPosition->GetTypeOfPosition();
118       switch( aTypeOfPosition )
119       {
120       case SMDS_TOP_VERTEX : return IsContains( myMeshDS,myShape,aNode,TopAbs_VERTEX );
121       case SMDS_TOP_EDGE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_EDGE );
122       case SMDS_TOP_FACE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_FACE );
123       case SMDS_TOP_3DSPACE: return IsContains( myMeshDS,myShape,aNode,TopAbs_SHELL );
124       }
125     }
126   }
127   else
128   {
129     if( const SMDS_MeshElement* anElem = myMeshDS->FindElement( theId ) )
130     {
131       if( myType == SMDSAbs_All )
132       {
133         return IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE ) ||
134                IsContains( myMeshDS,myShape,anElem,TopAbs_FACE ) ||
135                IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
136                IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID );
137       }
138       else if( myType == anElem->GetType() )
139       {
140         switch( myType )
141         {
142         case SMDSAbs_Edge  : return IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE );
143         case SMDSAbs_Face  : return IsContains( myMeshDS,myShape,anElem,TopAbs_FACE );
144         case SMDSAbs_Volume: return IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
145                                     IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID );
146         }
147       }
148     }
149   }
150     
151   return false;
152 }
153
154 void Controls::BelongToGeom::SetType( SMDSAbs_ElementType theType )
155 {
156   myType = theType;
157 }
158
159 SMDSAbs_ElementType Controls::BelongToGeom::GetType() const
160 {
161   return myType;
162 }
163
164 TopoDS_Shape Controls::BelongToGeom::GetShape()
165 {
166   return myShape;
167 }
168
169 SMESHDS_Mesh* Controls::BelongToGeom::GetMeshDS()
170 {
171   return myMeshDS;
172 }
173
174 /*
175   Class       : LyingOnGeom
176   Description : Predicate for verifying whether entiy lying or partially lying on
177                 specified geometrical support
178 */
179
180 Controls::LyingOnGeom::LyingOnGeom()
181 : myMeshDS(NULL),
182   myType(SMDSAbs_All)
183 {}
184
185 void Controls::LyingOnGeom::SetMesh( SMDS_Mesh* theMesh )
186 {
187  myMeshDS = dynamic_cast<SMESHDS_Mesh*>(theMesh);
188 }
189
190 void Controls::LyingOnGeom::SetGeom( const TopoDS_Shape& theShape )
191 {
192   myShape = theShape;
193 }
194
195 bool Controls::LyingOnGeom::IsSatisfy( long theId )
196 {
197   if ( myMeshDS == 0 || myShape.IsNull() )
198     return false;
199
200   if( myType == SMDSAbs_Node )
201   {
202     if( const SMDS_MeshNode* aNode = myMeshDS->FindNode( theId ) )
203     {
204       const SMDS_PositionPtr& aPosition = aNode->GetPosition();
205       SMDS_TypeOfPosition aTypeOfPosition = aPosition->GetTypeOfPosition();
206       switch( aTypeOfPosition )
207       {
208       case SMDS_TOP_VERTEX : return IsContains( myMeshDS,myShape,aNode,TopAbs_VERTEX );
209       case SMDS_TOP_EDGE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_EDGE );
210       case SMDS_TOP_FACE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_FACE );
211       case SMDS_TOP_3DSPACE: return IsContains( myMeshDS,myShape,aNode,TopAbs_SHELL );
212       }
213     }
214   }
215   else
216   {
217     if( const SMDS_MeshElement* anElem = myMeshDS->FindElement( theId ) )
218     {
219       if( myType == SMDSAbs_All )
220       {
221         return Contains( myMeshDS,myShape,anElem,TopAbs_EDGE ) ||
222                Contains( myMeshDS,myShape,anElem,TopAbs_FACE ) ||
223                Contains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
224                Contains( myMeshDS,myShape,anElem,TopAbs_SOLID );
225       }
226       else if( myType == anElem->GetType() )
227       {
228         switch( myType )
229         {
230         case SMDSAbs_Edge  : return Contains( myMeshDS,myShape,anElem,TopAbs_EDGE );
231         case SMDSAbs_Face  : return Contains( myMeshDS,myShape,anElem,TopAbs_FACE );
232         case SMDSAbs_Volume: return Contains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
233                                     Contains( myMeshDS,myShape,anElem,TopAbs_SOLID );
234         }
235       }
236     }
237   }
238     
239   return false;
240 }
241
242 void Controls::LyingOnGeom::SetType( SMDSAbs_ElementType theType )
243 {
244   myType = theType;
245 }
246
247 SMDSAbs_ElementType Controls::LyingOnGeom::GetType() const
248 {
249   return myType;
250 }
251
252 TopoDS_Shape Controls::LyingOnGeom::GetShape()
253 {
254   return myShape;
255 }
256
257 SMESHDS_Mesh* Controls::LyingOnGeom::GetMeshDS()
258 {
259   return myMeshDS;
260 }
261
262 bool Controls::LyingOnGeom::Contains( SMESHDS_Mesh*           theMeshDS,
263                                       const TopoDS_Shape&     theShape,
264                                       const SMDS_MeshElement* theElem,
265                                       TopAbs_ShapeEnum        theFindShapeEnum,
266                                       TopAbs_ShapeEnum        theAvoidShapeEnum )
267 {
268   if (IsContains(theMeshDS, theShape, theElem, theFindShapeEnum, theAvoidShapeEnum))
269     return true;
270   
271   TopTools_IndexedMapOfShape aSubShapes;
272   TopExp::MapShapes( theShape, aSubShapes );
273   
274   for (int i = 1; i <= aSubShapes.Extent(); i++)
275     {
276       const TopoDS_Shape& aShape = aSubShapes.FindKey(i);
277       
278       if( SMESHDS_SubMesh* aSubMesh = theMeshDS->MeshElements( aShape ) ){
279         if( aSubMesh->Contains( theElem ) )
280           return true;
281         
282         SMDS_NodeIteratorPtr aNodeIt = aSubMesh->GetNodes();
283         while ( aNodeIt->more() )
284           {
285             const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(aNodeIt->next());
286             SMDS_ElemIteratorPtr anElemIt = aNode->GetInverseElementIterator();
287             while ( anElemIt->more() )
288               {
289                 const SMDS_MeshElement* anElement = static_cast<const SMDS_MeshElement*>(anElemIt->next());
290                 if (anElement == theElem)
291                   return true;
292               }
293           }
294       }
295     }
296   return false;
297 }
298
299
300 /*
301                             AUXILIARY METHODS
302 */
303
304 static inline SMDS_Mesh* MeshPtr2SMDSMesh( SMESH_Mesh_ptr theMesh )
305 {
306   SMESH_Mesh_i* anImplPtr = 
307     dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( theMesh ).in() );
308   return anImplPtr ? anImplPtr->GetImpl().GetMeshDS() : 0;
309 }
310
311 static inline SMESH::long_array* toArray( const TColStd_ListOfInteger& aList )
312 {
313   SMESH::long_array_var anArray = new SMESH::long_array;
314   anArray->length( aList.Extent() );
315   TColStd_ListIteratorOfListOfInteger anIter( aList );
316   int i = 0;
317   for( ; anIter.More(); anIter.Next() )
318     anArray[ i++ ] = anIter.Value();
319
320   return anArray._retn();
321 }
322
323 static inline SMESH::double_array* toArray( const TColStd_ListOfReal& aList )
324 {
325   SMESH::double_array_var anArray = new SMESH::double_array;
326   anArray->length( aList.Extent() );
327   TColStd_ListIteratorOfListOfReal anIter( aList );
328   int i = 0;
329   for( ; anIter.More(); anIter.Next() )
330     anArray[ i++ ] = anIter.Value();
331
332   return anArray._retn();
333 }
334
335 static SMESH::Filter::Criterion createCriterion()
336 {
337   SMESH::Filter::Criterion aCriterion;
338
339   aCriterion.Type          = FT_Undefined;
340   aCriterion.Compare       = FT_Undefined;
341   aCriterion.Threshold     = 0;
342   aCriterion.UnaryOp       = FT_Undefined;
343   aCriterion.BinaryOp      = FT_Undefined;
344   aCriterion.ThresholdStr  = "";
345   aCriterion.Tolerance     = Precision::Confusion();
346   aCriterion.TypeOfElement = SMESH::ALL;
347   aCriterion.Precision     = -1;
348
349   return aCriterion;
350 }
351
352 static TopoDS_Shape getShapeByName( const char* theName )
353 {
354   if ( theName != 0 )
355   {
356     SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
357     SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
358     if ( aStudy != 0 )
359     {
360       SALOMEDS::Study::ListOfSObject_var aList =
361         aStudy->FindObjectByName( theName, "GEOM" );
362       if ( aList->length() > 0 )
363       {
364         GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( aList[ 0 ]->GetObject() );
365         if ( !aGeomObj->_is_nil() )
366         {
367           GEOM::GEOM_Gen_var aGEOMGen = SMESH_Gen_i::GetGeomEngine();
368           TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, aGeomObj );
369           return aLocShape;
370         }
371       }
372     }
373   }
374   return TopoDS_Shape();
375 }
376
377
378
379 /*
380                                 FUNCTORS
381 */
382
383 /*
384   Class       : Functor_i
385   Description : An abstact class for all functors 
386 */
387 Functor_i::Functor_i(): 
388   SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
389 {
390   SMESH_Gen_i::GetPOA()->activate_object( this );
391 }
392
393 void Functor_i::SetMesh( SMESH_Mesh_ptr theMesh )
394 {
395   myFunctorPtr->SetMesh( MeshPtr2SMDSMesh( theMesh ) );
396   INFOS("Functor_i::SetMesh~");
397 }
398
399 ElementType Functor_i::GetElementType()
400 {
401   return ( ElementType )myFunctorPtr->GetType();
402 }
403
404
405 /*
406   Class       : NumericalFunctor_i
407   Description : Base class for numerical functors
408 */
409 CORBA::Double NumericalFunctor_i::GetValue( CORBA::Long theId )
410 {
411   return myNumericalFunctorPtr->GetValue( theId );
412 }
413
414 void NumericalFunctor_i::SetPrecision( CORBA::Long thePrecision )
415 {
416   myNumericalFunctorPtr->SetPrecision( thePrecision );
417 }
418
419 CORBA::Long NumericalFunctor_i::GetPrecision()
420 {
421  return myNumericalFunctorPtr->GetPrecision();
422 }
423
424 Controls::NumericalFunctorPtr NumericalFunctor_i::GetNumericalFunctor()
425 {
426   return myNumericalFunctorPtr;
427 }
428
429
430 /*
431   Class       : SMESH_MinimumAngle
432   Description : Functor for calculation of minimum angle
433 */
434 MinimumAngle_i::MinimumAngle_i()
435 {
436   myNumericalFunctorPtr.reset( new Controls::MinimumAngle() );
437   myFunctorPtr = myNumericalFunctorPtr;
438 }
439
440 FunctorType MinimumAngle_i::GetFunctorType()
441 {
442   return SMESH::FT_MinimumAngle;
443 }
444
445
446 /*
447   Class       : AspectRatio
448   Description : Functor for calculating aspect ratio
449 */
450 AspectRatio_i::AspectRatio_i()
451 {
452   myNumericalFunctorPtr.reset( new Controls::AspectRatio() );
453   myFunctorPtr = myNumericalFunctorPtr;
454 }
455
456 FunctorType AspectRatio_i::GetFunctorType()
457 {
458   return SMESH::FT_AspectRatio;
459 }
460
461
462 /*
463   Class       : AspectRatio3D
464   Description : Functor for calculating aspect ratio 3D
465 */
466 AspectRatio3D_i::AspectRatio3D_i()
467 {
468   myNumericalFunctorPtr.reset( new Controls::AspectRatio3D() );
469   myFunctorPtr = myNumericalFunctorPtr;
470 }
471
472 FunctorType AspectRatio3D_i::GetFunctorType()
473 {
474   return SMESH::FT_AspectRatio3D;
475 }
476
477
478 /*
479   Class       : Warping_i
480   Description : Functor for calculating warping
481 */
482 Warping_i::Warping_i()
483 {
484   myNumericalFunctorPtr.reset( new Controls::Warping() );
485   myFunctorPtr = myNumericalFunctorPtr;
486 }
487
488 FunctorType Warping_i::GetFunctorType()
489 {
490   return SMESH::FT_Warping;
491 }
492
493
494 /*
495   Class       : Taper_i
496   Description : Functor for calculating taper
497 */
498 Taper_i::Taper_i()
499 {
500   myNumericalFunctorPtr.reset( new Controls::Taper() );
501   myFunctorPtr = myNumericalFunctorPtr;
502 }
503
504 FunctorType Taper_i::GetFunctorType()
505 {
506   return SMESH::FT_Taper;
507 }
508
509
510 /*
511   Class       : Skew_i
512   Description : Functor for calculating skew in degrees
513 */
514 Skew_i::Skew_i()
515 {
516   myNumericalFunctorPtr.reset( new Controls::Skew() );
517   myFunctorPtr = myNumericalFunctorPtr;
518 }
519
520 FunctorType Skew_i::GetFunctorType()
521 {
522   return SMESH::FT_Skew;
523 }
524
525 /*
526   Class       : Area_i
527   Description : Functor for calculating area
528 */
529 Area_i::Area_i()
530 {
531   myNumericalFunctorPtr.reset( new Controls::Area() );
532   myFunctorPtr = myNumericalFunctorPtr;
533 }
534
535 FunctorType Area_i::GetFunctorType()
536 {
537   return SMESH::FT_Area;
538 }
539
540 /*
541   Class       : Length_i
542   Description : Functor for calculating length off edge
543 */
544 Length_i::Length_i()
545 {
546   myNumericalFunctorPtr.reset( new Controls::Length() );
547   myFunctorPtr = myNumericalFunctorPtr;
548 }
549
550 FunctorType Length_i::GetFunctorType()
551 {
552   return SMESH::FT_Length;
553 }
554
555 /*
556   Class       : Length2D_i
557   Description : Functor for calculating length of edge
558 */
559 Length2D_i::Length2D_i()
560 {
561   myNumericalFunctorPtr.reset( new Controls::Length2D() );
562   myFunctorPtr = myNumericalFunctorPtr;
563 }
564
565 FunctorType Length2D_i::GetFunctorType()
566 {
567   return SMESH::FT_Length2D;
568 }
569
570 SMESH::Length2D::Values* Length2D_i::GetValues()
571 {
572   INFOS("Length2D_i::GetValues");
573   SMESH::Controls::Length2D::TValues aValues;
574   myLength2DPtr->GetValues( aValues );
575   
576   long i = 0, iEnd = aValues.size();
577
578   SMESH::Length2D::Values_var aResult = new SMESH::Length2D::Values(iEnd);
579
580   SMESH::Controls::Length2D::TValues::const_iterator anIter;
581   for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ )
582   {
583     const SMESH::Controls::Length2D::Value&  aVal = *anIter;
584     SMESH::Length2D::Value &aValue = aResult[ i ];
585     
586     aValue.myLength = aVal.myLength;
587     aValue.myPnt1 = aVal.myPntId[ 0 ];
588     aValue.myPnt2 = aVal.myPntId[ 1 ];
589    
590   }
591
592   INFOS("Length2D_i::GetValuess~");
593   return aResult._retn();
594 }
595
596 /*
597   Class       : MultiConnection_i
598   Description : Functor for calculating number of faces conneted to the edge
599 */
600 MultiConnection_i::MultiConnection_i()
601 {
602   myNumericalFunctorPtr.reset( new Controls::MultiConnection() );
603   myFunctorPtr = myNumericalFunctorPtr;
604 }
605
606 FunctorType MultiConnection_i::GetFunctorType()
607 {
608   return SMESH::FT_MultiConnection;
609 }
610
611 /*
612   Class       : MultiConnection2D_i
613   Description : Functor for calculating number of faces conneted to the edge
614 */
615 MultiConnection2D_i::MultiConnection2D_i()
616 {
617   myNumericalFunctorPtr.reset( new Controls::MultiConnection2D() );
618   myFunctorPtr = myNumericalFunctorPtr;
619 }
620
621 FunctorType MultiConnection2D_i::GetFunctorType()
622 {
623   return SMESH::FT_MultiConnection2D;
624 }
625
626 SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues()
627 {
628   INFOS("MultiConnection2D_i::GetValues");
629   SMESH::Controls::MultiConnection2D::MValues aValues;
630   myMulticonnection2DPtr->GetValues( aValues );
631   
632   long i = 0, iEnd = aValues.size();
633
634   SMESH::MultiConnection2D::Values_var aResult = new SMESH::MultiConnection2D::Values(iEnd);
635
636   SMESH::Controls::MultiConnection2D::MValues::const_iterator anIter;
637   for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ )
638   {
639     const SMESH::Controls::MultiConnection2D::Value&  aVal = (*anIter).first;
640     SMESH::MultiConnection2D::Value &aValue = aResult[ i ];
641     
642     aValue.myPnt1 = aVal.myPntId[ 0 ];
643     aValue.myPnt2 = aVal.myPntId[ 1 ];
644     aValue.myNbConnects = (*anIter).second;
645    
646   }
647
648   INFOS("Multiconnection2D_i::GetValuess~");
649   return aResult._retn();
650 }
651
652 /*
653                             PREDICATES
654 */
655
656
657 /*
658   Class       : Predicate_i
659   Description : Base class for all predicates
660 */
661 CORBA::Boolean Predicate_i::IsSatisfy( CORBA::Long theId )
662 {
663   return myPredicatePtr->IsSatisfy( theId );
664 }
665
666 Controls::PredicatePtr Predicate_i::GetPredicate()
667 {
668   return myPredicatePtr;
669 }
670
671
672 /*
673   Class       : BelongToGeom_i
674   Description : Predicate for selection on geometrical support
675 */
676 BelongToGeom_i::BelongToGeom_i()
677 {
678   myBelongToGeomPtr.reset( new Controls::BelongToGeom() );
679   myFunctorPtr = myPredicatePtr = myBelongToGeomPtr;
680   myShapeName = 0;
681 }
682
683 BelongToGeom_i::~BelongToGeom_i()
684 {
685   delete myShapeName;
686 }
687
688 void BelongToGeom_i::SetGeom( GEOM::GEOM_Object_ptr theGeom )
689 {
690   if ( theGeom->_is_nil() )
691     return;
692   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
693   GEOM::GEOM_Gen_var aGEOMGen = SMESH_Gen_i::GetGeomEngine();
694   TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, theGeom );
695   myBelongToGeomPtr->SetGeom( aLocShape );
696 }
697
698 void BelongToGeom_i::SetGeom( const TopoDS_Shape& theShape )
699 {
700   myBelongToGeomPtr->SetGeom( theShape );
701 }
702
703 void BelongToGeom_i::SetElementType(ElementType theType){
704   myBelongToGeomPtr->SetType(SMDSAbs_ElementType(theType));
705 }
706
707 FunctorType BelongToGeom_i::GetFunctorType()
708 {
709   return SMESH::FT_BelongToGeom;
710 }
711
712 void BelongToGeom_i::SetShapeName( const char* theName )
713 {
714   delete myShapeName;
715   myShapeName = strdup( theName );
716   myBelongToGeomPtr->SetGeom( getShapeByName( myShapeName ) );
717 }
718
719 char* BelongToGeom_i::GetShapeName()
720 {
721   return CORBA::string_dup( myShapeName );
722 }
723
724 /*
725   Class       : BelongToSurface_i
726   Description : Predicate for selection on geometrical support
727 */
728 BelongToSurface_i::BelongToSurface_i( const Handle(Standard_Type)& theSurfaceType )
729 {
730   myElementsOnSurfacePtr.reset( new Controls::ElementsOnSurface() );
731   myFunctorPtr = myPredicatePtr = myElementsOnSurfacePtr;
732   myShapeName = 0;
733   mySurfaceType = theSurfaceType;
734 }
735
736 BelongToSurface_i::~BelongToSurface_i()
737 {
738   delete myShapeName;
739 }
740
741 void BelongToSurface_i::SetSurface( GEOM::GEOM_Object_ptr theGeom, ElementType theType )
742 {
743   if ( theGeom->_is_nil() )
744     return;
745   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
746   GEOM::GEOM_Gen_var aGEOMGen = SMESH_Gen_i::GetGeomEngine();
747   TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, theGeom );
748
749   if ( aLocShape.ShapeType() == TopAbs_FACE )
750   {
751     Handle(Geom_Surface) aSurf = BRep_Tool::Surface( TopoDS::Face( aLocShape ) );
752     if ( !aSurf.IsNull() && aSurf->DynamicType() == mySurfaceType )
753     {
754       myElementsOnSurfacePtr->SetSurface( aLocShape, (SMDSAbs_ElementType)theType );
755       return;
756     }
757   }
758
759   myElementsOnSurfacePtr->SetSurface( TopoDS_Shape(), (SMDSAbs_ElementType)theType );
760 }
761
762 void BelongToSurface_i::SetShapeName( const char* theName, ElementType theType )
763 {
764   delete myShapeName;
765   myShapeName = strdup( theName );
766   myElementsOnSurfacePtr->SetSurface( getShapeByName( myShapeName ), (SMDSAbs_ElementType)theType );
767 }
768
769 char* BelongToSurface_i::GetShapeName()
770 {
771   return CORBA::string_dup( myShapeName );
772 }
773
774 void BelongToSurface_i::SetTolerance( CORBA::Double theToler )
775 {
776   myElementsOnSurfacePtr->SetTolerance( theToler );
777 }
778
779 CORBA::Double BelongToSurface_i::GetTolerance()
780 {
781   return myElementsOnSurfacePtr->GetTolerance();
782 }
783
784 /*
785   Class       : BelongToPlane_i
786   Description : Verify whether mesh element lie in pointed Geom planar object
787 */
788
789 BelongToPlane_i::BelongToPlane_i()
790 : BelongToSurface_i( STANDARD_TYPE( Geom_Plane ) )
791 {
792 }
793
794 void BelongToPlane_i::SetPlane( GEOM::GEOM_Object_ptr theGeom, ElementType theType )
795 {
796   BelongToSurface_i::SetSurface( theGeom, theType );
797 }
798
799 FunctorType BelongToPlane_i::GetFunctorType()
800 {
801   return FT_BelongToPlane;
802 }
803
804 /*
805   Class       : BelongToCylinder_i
806   Description : Verify whether mesh element lie in pointed Geom planar object
807 */
808
809 BelongToCylinder_i::BelongToCylinder_i()
810 : BelongToSurface_i( STANDARD_TYPE( Geom_CylindricalSurface ) )
811 {
812 }
813
814 void BelongToCylinder_i::SetCylinder( GEOM::GEOM_Object_ptr theGeom, ElementType theType )
815 {
816   BelongToSurface_i::SetSurface( theGeom, theType );
817 }
818
819 FunctorType BelongToCylinder_i::GetFunctorType()
820 {
821   return FT_BelongToCylinder;
822 }
823
824 /*
825   Class       : LyingOnGeom_i
826   Description : Predicate for selection on geometrical support
827 */
828 LyingOnGeom_i::LyingOnGeom_i()
829 {
830   myLyingOnGeomPtr.reset( new Controls::LyingOnGeom() );
831   myFunctorPtr = myPredicatePtr = myLyingOnGeomPtr;
832   myShapeName = 0;
833 }
834
835 LyingOnGeom_i::~LyingOnGeom_i()
836 {
837   delete myShapeName;
838 }
839
840 void LyingOnGeom_i::SetGeom( GEOM::GEOM_Object_ptr theGeom )
841 {
842   if ( theGeom->_is_nil() )
843     return;
844   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
845   GEOM::GEOM_Gen_var aGEOMGen = SMESH_Gen_i::GetGeomEngine();
846   TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, theGeom );
847   myLyingOnGeomPtr->SetGeom( aLocShape );
848 }
849
850 void LyingOnGeom_i::SetGeom( const TopoDS_Shape& theShape )
851 {
852   myLyingOnGeomPtr->SetGeom( theShape );
853 }
854
855 void LyingOnGeom_i::SetElementType(ElementType theType){
856   myLyingOnGeomPtr->SetType(SMDSAbs_ElementType(theType));
857 }
858
859 FunctorType LyingOnGeom_i::GetFunctorType()
860 {
861   return SMESH::FT_LyingOnGeom;
862 }
863
864 void LyingOnGeom_i::SetShapeName( const char* theName )
865 {
866   delete myShapeName;
867   myShapeName = strdup( theName );
868   myLyingOnGeomPtr->SetGeom( getShapeByName( myShapeName ) );
869 }
870
871 char* LyingOnGeom_i::GetShapeName()
872 {
873   return CORBA::string_dup( myShapeName );
874 }
875
876 /*
877   Class       : FreeBorders_i
878   Description : Predicate for free borders
879 */
880 FreeBorders_i::FreeBorders_i()
881 {
882   myPredicatePtr.reset(new Controls::FreeBorders());
883   myFunctorPtr = myPredicatePtr;
884 }
885
886 FunctorType FreeBorders_i::GetFunctorType()
887 {
888   return SMESH::FT_FreeBorders;
889 }
890
891 /*
892   Class       : FreeEdges_i
893   Description : Predicate for free borders
894 */
895 FreeEdges_i::FreeEdges_i()
896 : myFreeEdgesPtr( new Controls::FreeEdges() )
897 {
898   myFunctorPtr = myPredicatePtr = myFreeEdgesPtr;
899 }
900
901 SMESH::FreeEdges::Borders* FreeEdges_i::GetBorders()
902 {
903   INFOS("FreeEdges_i::GetBorders");
904   SMESH::Controls::FreeEdges::TBorders aBorders;
905   myFreeEdgesPtr->GetBoreders( aBorders );
906   
907   long i = 0, iEnd = aBorders.size();
908
909   SMESH::FreeEdges::Borders_var aResult = new SMESH::FreeEdges::Borders(iEnd);
910
911   SMESH::Controls::FreeEdges::TBorders::const_iterator anIter;
912   for ( anIter = aBorders.begin() ; anIter != aBorders.end(); anIter++, i++ )
913   {
914     const SMESH::Controls::FreeEdges::Border&  aBord = *anIter;
915     SMESH::FreeEdges::Border &aBorder = aResult[ i ];
916     
917     aBorder.myElemId = aBord.myElemId;
918     aBorder.myPnt1 = aBord.myPntId[ 0 ];
919     aBorder.myPnt2 = aBord.myPntId[ 1 ];
920   }
921
922   INFOS("FreeEdges_i::GetBorders~");
923   return aResult._retn();
924 }
925
926 FunctorType FreeEdges_i::GetFunctorType()
927 {
928   return SMESH::FT_FreeEdges;
929 }
930
931 /*
932   Class       : RangeOfIds_i
933   Description : Predicate for Range of Ids.
934                 Range may be specified with two ways.
935                 1. Using AddToRange method
936                 2. With SetRangeStr method. Parameter of this method is a string
937                    like as "1,2,3,50-60,63,67,70-"
938 */
939
940 RangeOfIds_i::RangeOfIds_i()
941 {
942   myRangeOfIdsPtr.reset( new Controls::RangeOfIds() );
943   myFunctorPtr = myPredicatePtr = myRangeOfIdsPtr;
944 }
945
946 void RangeOfIds_i::SetRange( const SMESH::long_array& theIds )
947 {
948   CORBA::Long iEnd = theIds.length();
949   for ( CORBA::Long i = 0; i < iEnd; i++ )
950     myRangeOfIdsPtr->AddToRange( theIds[ i ] );
951 }
952
953 CORBA::Boolean RangeOfIds_i::SetRangeStr( const char* theRange )
954 {
955   return myRangeOfIdsPtr->SetRangeStr(
956     TCollection_AsciiString( (Standard_CString)theRange ) );
957 }
958
959 char* RangeOfIds_i::GetRangeStr()
960 {
961   TCollection_AsciiString aStr;
962   myRangeOfIdsPtr->GetRangeStr( aStr );
963   return CORBA::string_dup( aStr.ToCString() );
964 }
965
966 void RangeOfIds_i::SetElementType( ElementType theType )
967 {
968   myRangeOfIdsPtr->SetType( SMDSAbs_ElementType( theType ) );
969 }
970
971 FunctorType RangeOfIds_i::GetFunctorType()
972 {
973   return SMESH::FT_RangeOfIds;
974 }
975
976 /*
977   Class       : Comparator_i
978   Description : Base class for comparators
979 */
980 Comparator_i::Comparator_i():
981   myNumericalFunctor( NULL )
982 {}
983
984 Comparator_i::~Comparator_i()
985 {
986   if ( myNumericalFunctor )
987     myNumericalFunctor->Destroy();
988 }
989
990 void Comparator_i::SetMargin( CORBA::Double theValue )
991 {
992   myComparatorPtr->SetMargin( theValue );
993 }
994
995 CORBA::Double Comparator_i::GetMargin()
996 {
997   return myComparatorPtr->GetMargin();
998 }
999
1000 void Comparator_i::SetNumFunctor( NumericalFunctor_ptr theFunct )
1001 {
1002   if ( myNumericalFunctor )
1003     myNumericalFunctor->Destroy();
1004
1005   myNumericalFunctor = dynamic_cast<NumericalFunctor_i*>( SMESH_Gen_i::GetServant( theFunct ).in() );
1006
1007   if ( myNumericalFunctor )
1008   {
1009     myComparatorPtr->SetNumFunctor( myNumericalFunctor->GetNumericalFunctor() );
1010     myNumericalFunctor->Register();
1011   }
1012 }
1013
1014 Controls::ComparatorPtr Comparator_i::GetComparator()
1015 {
1016   return myComparatorPtr;
1017 }
1018
1019 NumericalFunctor_i* Comparator_i::GetNumFunctor_i()
1020 {
1021   return myNumericalFunctor;
1022 }
1023
1024
1025 /*
1026   Class       : LessThan_i
1027   Description : Comparator "<"
1028 */
1029 LessThan_i::LessThan_i()
1030 {
1031   myComparatorPtr.reset( new Controls::LessThan() );
1032   myFunctorPtr = myPredicatePtr = myComparatorPtr;
1033 }
1034
1035 FunctorType LessThan_i::GetFunctorType()
1036 {
1037   return SMESH::FT_LessThan;
1038 }
1039
1040
1041 /*
1042   Class       : MoreThan_i
1043   Description : Comparator ">"
1044 */
1045 MoreThan_i::MoreThan_i()
1046 {
1047   myComparatorPtr.reset( new Controls::MoreThan() );
1048   myFunctorPtr = myPredicatePtr = myComparatorPtr;
1049 }
1050
1051 FunctorType MoreThan_i::GetFunctorType()
1052 {
1053   return SMESH::FT_MoreThan;
1054 }
1055
1056
1057 /*
1058   Class       : EqualTo_i
1059   Description : Comparator "="
1060 */
1061 EqualTo_i::EqualTo_i()
1062 : myEqualToPtr( new Controls::EqualTo() )
1063 {
1064   myFunctorPtr = myPredicatePtr = myComparatorPtr = myEqualToPtr;
1065 }
1066
1067 void EqualTo_i::SetTolerance( CORBA::Double theToler )
1068 {
1069   myEqualToPtr->SetTolerance( theToler );
1070 }
1071
1072 CORBA::Double EqualTo_i::GetTolerance()
1073 {
1074   return myEqualToPtr->GetTolerance();
1075 }
1076
1077 FunctorType EqualTo_i::GetFunctorType()
1078 {
1079   return SMESH::FT_EqualTo;
1080 }
1081
1082 /*
1083   Class       : LogicalNOT_i
1084   Description : Logical NOT predicate
1085 */
1086 LogicalNOT_i::LogicalNOT_i()
1087 : myPredicate( NULL ),
1088   myLogicalNOTPtr( new Controls::LogicalNOT() )
1089 {
1090   myFunctorPtr = myPredicatePtr = myLogicalNOTPtr;
1091 }
1092
1093 LogicalNOT_i::~LogicalNOT_i()
1094 {
1095   if ( myPredicate )
1096     myPredicate->Destroy();
1097 }
1098
1099 void LogicalNOT_i::SetPredicate( Predicate_ptr thePred )
1100 {
1101   if ( myPredicate )
1102     myPredicate->Destroy();
1103
1104   myPredicate = dynamic_cast<Predicate_i*>( SMESH_Gen_i::GetServant( thePred ).in() );
1105
1106   if ( myPredicate ){
1107     myLogicalNOTPtr->SetPredicate(myPredicate->GetPredicate());
1108     myPredicate->Register();
1109   }
1110 }
1111
1112 FunctorType LogicalNOT_i::GetFunctorType()
1113 {
1114   return SMESH::FT_LogicalNOT;
1115 }
1116
1117 Predicate_i* LogicalNOT_i::GetPredicate_i()
1118 {
1119   return myPredicate;
1120 }
1121
1122
1123 /*
1124   Class       : LogicalBinary_i
1125   Description : Base class for binary logical predicate
1126 */
1127 LogicalBinary_i::LogicalBinary_i()
1128 : myPredicate1( NULL ),
1129   myPredicate2( NULL )
1130 {}
1131
1132 LogicalBinary_i::~LogicalBinary_i()
1133 {
1134   if ( myPredicate1 )
1135     myPredicate1->Destroy();
1136
1137   if ( myPredicate2 )
1138     myPredicate2->Destroy();
1139 }
1140
1141 void LogicalBinary_i::SetMesh( SMESH_Mesh_ptr theMesh )
1142 {
1143   if ( myPredicate1 )
1144     myPredicate1->SetMesh( theMesh );
1145
1146   if ( myPredicate2 )
1147     myPredicate2->SetMesh( theMesh );
1148 }
1149
1150 void LogicalBinary_i::SetPredicate1( Predicate_ptr thePredicate )
1151 {
1152   if ( myPredicate1 )
1153     myPredicate1->Destroy();
1154
1155   myPredicate1 = dynamic_cast<Predicate_i*>( SMESH_Gen_i::GetServant( thePredicate ).in() );
1156
1157   if ( myPredicate1 ){
1158     myLogicalBinaryPtr->SetPredicate1(myPredicate1->GetPredicate());
1159     myPredicate1->Register();
1160   }
1161 }
1162
1163 void LogicalBinary_i::SetPredicate2( Predicate_ptr thePredicate )
1164 {
1165   if ( myPredicate2 )
1166     myPredicate2->Destroy();
1167
1168   myPredicate2 = dynamic_cast<Predicate_i*>( SMESH_Gen_i::GetServant( thePredicate ).in() );
1169
1170   if ( myPredicate2 ){
1171     myLogicalBinaryPtr->SetPredicate2(myPredicate2->GetPredicate());
1172     myPredicate2->Register();
1173   }
1174 }
1175
1176 Controls::LogicalBinaryPtr LogicalBinary_i::GetLogicalBinary()
1177 {
1178   return myLogicalBinaryPtr;
1179 }
1180
1181 Predicate_i* LogicalBinary_i::GetPredicate1_i()
1182 {
1183   return myPredicate1;
1184 }
1185 Predicate_i* LogicalBinary_i::GetPredicate2_i()
1186 {
1187   return myPredicate2;
1188 }
1189
1190
1191 /*
1192   Class       : LogicalAND_i
1193   Description : Logical AND
1194 */
1195 LogicalAND_i::LogicalAND_i()
1196 {
1197   myLogicalBinaryPtr.reset( new Controls::LogicalAND() );
1198   myFunctorPtr = myPredicatePtr = myLogicalBinaryPtr;
1199 }
1200
1201 FunctorType LogicalAND_i::GetFunctorType()
1202 {
1203   return SMESH::FT_LogicalAND;
1204 }
1205
1206
1207 /*
1208   Class       : LogicalOR_i
1209   Description : Logical OR
1210 */
1211 LogicalOR_i::LogicalOR_i()
1212 {
1213   myLogicalBinaryPtr.reset( new Controls::LogicalOR() );
1214   myFunctorPtr = myPredicatePtr = myLogicalBinaryPtr;
1215 }
1216
1217 FunctorType LogicalOR_i::GetFunctorType()
1218 {
1219   return SMESH::FT_LogicalOR;
1220 }
1221
1222
1223 /*
1224                             FILTER MANAGER
1225 */
1226
1227 FilterManager_i::FilterManager_i()
1228 : SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
1229 {
1230   SMESH_Gen_i::GetPOA()->activate_object( this );
1231 }
1232
1233 MinimumAngle_ptr FilterManager_i::CreateMinimumAngle()
1234 {
1235   SMESH::MinimumAngle_i* aServant = new SMESH::MinimumAngle_i();
1236   SMESH::MinimumAngle_var anObj = aServant->_this();
1237   return anObj._retn();
1238 }
1239
1240
1241 AspectRatio_ptr FilterManager_i::CreateAspectRatio()
1242 {
1243   SMESH::AspectRatio_i* aServant = new SMESH::AspectRatio_i();
1244   SMESH::AspectRatio_var anObj = aServant->_this();
1245   return anObj._retn();
1246 }
1247
1248
1249 AspectRatio3D_ptr FilterManager_i::CreateAspectRatio3D()
1250 {
1251   SMESH::AspectRatio3D_i* aServant = new SMESH::AspectRatio3D_i();
1252   SMESH::AspectRatio3D_var anObj = aServant->_this();
1253   return anObj._retn();
1254 }
1255
1256
1257 Warping_ptr FilterManager_i::CreateWarping()
1258 {
1259   SMESH::Warping_i* aServant = new SMESH::Warping_i();
1260   SMESH::Warping_var anObj = aServant->_this();
1261   return anObj._retn();
1262 }
1263
1264
1265 Taper_ptr FilterManager_i::CreateTaper()
1266 {
1267   SMESH::Taper_i* aServant = new SMESH::Taper_i();
1268   SMESH::Taper_var anObj = aServant->_this();
1269   return anObj._retn();
1270 }
1271
1272
1273 Skew_ptr FilterManager_i::CreateSkew()
1274 {
1275   SMESH::Skew_i* aServant = new SMESH::Skew_i();
1276   SMESH::Skew_var anObj = aServant->_this();
1277   return anObj._retn();
1278 }
1279
1280
1281 Area_ptr FilterManager_i::CreateArea()
1282 {
1283   SMESH::Area_i* aServant = new SMESH::Area_i();
1284   SMESH::Area_var anObj = aServant->_this();
1285   return anObj._retn();
1286 }
1287
1288
1289 Length_ptr FilterManager_i::CreateLength()
1290 {
1291   SMESH::Length_i* aServant = new SMESH::Length_i();
1292   SMESH::Length_var anObj = aServant->_this();
1293   return anObj._retn();
1294 }
1295
1296 Length2D_ptr FilterManager_i::CreateLength2D()
1297 {
1298   SMESH::Length2D_i* aServant = new SMESH::Length2D_i();
1299   SMESH::Length2D_var anObj = aServant->_this();
1300   return anObj._retn();
1301 }
1302
1303 MultiConnection_ptr FilterManager_i::CreateMultiConnection()
1304 {
1305   SMESH::MultiConnection_i* aServant = new SMESH::MultiConnection_i();
1306   SMESH::MultiConnection_var anObj = aServant->_this();
1307   return anObj._retn();
1308 }
1309
1310 MultiConnection2D_ptr FilterManager_i::CreateMultiConnection2D()
1311 {
1312   SMESH::MultiConnection2D_i* aServant = new SMESH::MultiConnection2D_i();
1313   SMESH::MultiConnection2D_var anObj = aServant->_this();
1314   return anObj._retn();
1315 }
1316
1317 BelongToGeom_ptr FilterManager_i::CreateBelongToGeom()
1318 {
1319   SMESH::BelongToGeom_i* aServant = new SMESH::BelongToGeom_i();
1320   SMESH::BelongToGeom_var anObj = aServant->_this();
1321   return anObj._retn();
1322 }
1323
1324 BelongToPlane_ptr FilterManager_i::CreateBelongToPlane()
1325 {
1326   SMESH::BelongToPlane_i* aServant = new SMESH::BelongToPlane_i();
1327   SMESH::BelongToPlane_var anObj = aServant->_this();
1328   return anObj._retn();
1329 }
1330
1331 BelongToCylinder_ptr FilterManager_i::CreateBelongToCylinder()
1332 {
1333   SMESH::BelongToCylinder_i* aServant = new SMESH::BelongToCylinder_i();
1334   SMESH::BelongToCylinder_var anObj = aServant->_this();
1335   return anObj._retn();
1336 }
1337
1338 LyingOnGeom_ptr FilterManager_i::CreateLyingOnGeom()
1339 {
1340   SMESH::LyingOnGeom_i* aServant = new SMESH::LyingOnGeom_i();
1341   SMESH::LyingOnGeom_var anObj = aServant->_this();
1342   return anObj._retn();
1343 }
1344
1345 FreeBorders_ptr FilterManager_i::CreateFreeBorders()
1346 {
1347   SMESH::FreeBorders_i* aServant = new SMESH::FreeBorders_i();
1348   SMESH::FreeBorders_var anObj = aServant->_this();
1349   return anObj._retn();
1350 }
1351
1352 FreeEdges_ptr FilterManager_i::CreateFreeEdges()
1353 {
1354   SMESH::FreeEdges_i* aServant = new SMESH::FreeEdges_i();
1355   SMESH::FreeEdges_var anObj = aServant->_this();
1356   return anObj._retn();
1357 }
1358
1359 RangeOfIds_ptr FilterManager_i::CreateRangeOfIds()
1360 {
1361   SMESH::RangeOfIds_i* aServant = new SMESH::RangeOfIds_i();
1362   SMESH::RangeOfIds_var anObj = aServant->_this();
1363   return anObj._retn();
1364 }
1365
1366 LessThan_ptr FilterManager_i::CreateLessThan()
1367 {
1368   SMESH::LessThan_i* aServant = new SMESH::LessThan_i();
1369   SMESH::LessThan_var anObj = aServant->_this();
1370   return anObj._retn();
1371 }
1372
1373
1374 MoreThan_ptr FilterManager_i::CreateMoreThan()
1375 {
1376   SMESH::MoreThan_i* aServant = new SMESH::MoreThan_i();
1377   SMESH::MoreThan_var anObj = aServant->_this();
1378   return anObj._retn();
1379 }
1380
1381 EqualTo_ptr FilterManager_i::CreateEqualTo()
1382 {
1383   SMESH::EqualTo_i* aServant = new SMESH::EqualTo_i();
1384   SMESH::EqualTo_var anObj = aServant->_this();
1385   return anObj._retn();
1386 }
1387
1388
1389 LogicalNOT_ptr FilterManager_i::CreateLogicalNOT()
1390 {
1391   SMESH::LogicalNOT_i* aServant = new SMESH::LogicalNOT_i();
1392   SMESH::LogicalNOT_var anObj = aServant->_this();
1393   return anObj._retn();
1394 }
1395
1396
1397 LogicalAND_ptr FilterManager_i::CreateLogicalAND()
1398 {
1399   SMESH::LogicalAND_i* aServant = new SMESH::LogicalAND_i();
1400   SMESH::LogicalAND_var anObj = aServant->_this();
1401   return anObj._retn();
1402 }
1403
1404
1405 LogicalOR_ptr FilterManager_i::CreateLogicalOR()
1406 {
1407   SMESH::LogicalOR_i* aServant = new SMESH::LogicalOR_i();
1408   SMESH::LogicalOR_var anObj = aServant->_this();
1409   return anObj._retn();
1410 }
1411
1412 Filter_ptr FilterManager_i::CreateFilter()
1413 {
1414   SMESH::Filter_i* aServant = new SMESH::Filter_i();
1415   SMESH::Filter_var anObj = aServant->_this();
1416   return anObj._retn();
1417 }
1418
1419 FilterLibrary_ptr FilterManager_i::LoadLibrary( const char* aFileName )
1420 {
1421   SMESH::FilterLibrary_i* aServant = new SMESH::FilterLibrary_i( aFileName );
1422   SMESH::FilterLibrary_var anObj = aServant->_this();
1423   return anObj._retn();
1424 }
1425
1426 FilterLibrary_ptr FilterManager_i::CreateLibrary()
1427 {
1428   SMESH::FilterLibrary_i* aServant = new SMESH::FilterLibrary_i();
1429   SMESH::FilterLibrary_var anObj = aServant->_this();
1430   return anObj._retn();
1431 }
1432
1433 CORBA::Boolean FilterManager_i::DeleteLibrary( const char* aFileName )
1434 {
1435   return remove( aFileName ) ? false : true;
1436 }
1437
1438 //=============================================================================
1439 /*!
1440  *  SMESH_Gen_i::CreateFilterManager
1441  *
1442  *  Create filter manager
1443  */
1444 //=============================================================================
1445
1446 SMESH::FilterManager_ptr SMESH_Gen_i::CreateFilterManager()
1447 {
1448   SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i();
1449   SMESH::FilterManager_var anObj = aFilter->_this();
1450   return anObj._retn();
1451 }
1452
1453
1454 /*
1455                               FILTER
1456 */
1457
1458 //=======================================================================
1459 // name    : Filter_i::Filter_i
1460 // Purpose : Constructor
1461 //=======================================================================
1462 Filter_i::Filter_i()
1463 : myPredicate( NULL )
1464 {}
1465
1466 //=======================================================================
1467 // name    : Filter_i::~Filter_i
1468 // Purpose : Destructor
1469 //=======================================================================
1470 Filter_i::~Filter_i()
1471 {
1472   if ( myPredicate )
1473     myPredicate->Destroy();
1474 }
1475
1476 //=======================================================================
1477 // name    : Filter_i::SetPredicate
1478 // Purpose : Set predicate
1479 //=======================================================================
1480 void Filter_i::SetPredicate( Predicate_ptr thePredicate )
1481 {
1482   if ( myPredicate )
1483     myPredicate->Destroy();
1484
1485   myPredicate = dynamic_cast<Predicate_i*>( SMESH_Gen_i::GetServant( thePredicate ).in() );
1486
1487   if ( myPredicate )
1488   {
1489     myFilter.SetPredicate( myPredicate->GetPredicate() );
1490     myPredicate->Register();
1491   }
1492 }
1493
1494 //=======================================================================
1495 // name    : Filter_i::GetElementType
1496 // Purpose : Get entity type
1497 //=======================================================================
1498 SMESH::ElementType Filter_i::GetElementType()
1499 {
1500   return myPredicate != 0 ? myPredicate->GetElementType() : SMESH::ALL;
1501 }
1502
1503 //=======================================================================
1504 // name    : Filter_i::SetMesh
1505 // Purpose : Set mesh
1506 //=======================================================================
1507 void Filter_i::SetMesh( SMESH_Mesh_ptr theMesh )
1508 {
1509   if ( myPredicate )
1510     myPredicate->SetMesh( theMesh );
1511 }
1512
1513 //=======================================================================
1514 // name    : Filter_i::GetElementsId
1515 // Purpose : Get ids of entities
1516 //=======================================================================
1517 SMESH::long_array* Filter_i::GetElementsId( SMESH_Mesh_ptr theMesh )
1518 {
1519   SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(theMesh);
1520   Controls::Filter::TIdSequence aSequence = myFilter.GetElementsId(aMesh);
1521
1522   SMESH::long_array_var anArray = new SMESH::long_array;
1523   long i = 0, iEnd = aSequence.size();
1524
1525   anArray->length( iEnd );
1526   for ( ; i < iEnd; i++ )
1527     anArray[ i ] = aSequence[i];
1528
1529   return anArray._retn();
1530 }
1531
1532 //=======================================================================
1533 // name    : getCriteria
1534 // Purpose : Retrieve criterions from predicate
1535 //=======================================================================
1536 static inline bool getCriteria( Predicate_i*                thePred,
1537                                 SMESH::Filter::Criteria_out theCriteria )
1538 {
1539   int aFType = thePred->GetFunctorType();
1540
1541   switch ( aFType )
1542   {
1543   case FT_FreeBorders:
1544   case FT_FreeEdges:
1545     {
1546       CORBA::ULong i = theCriteria->length();
1547       theCriteria->length( i + 1 );
1548
1549       theCriteria[ i ] = createCriterion();
1550
1551       theCriteria[ i ].Type = aFType;
1552       theCriteria[ i ].TypeOfElement = thePred->GetElementType();
1553       return true;
1554     }
1555   case FT_BelongToGeom:
1556     {
1557       BelongToGeom_i* aPred = dynamic_cast<BelongToGeom_i*>( thePred );
1558
1559       CORBA::ULong i = theCriteria->length();
1560       theCriteria->length( i + 1 );
1561
1562       theCriteria[ i ] = createCriterion();
1563
1564       theCriteria[ i ].Type          = FT_BelongToGeom;
1565       theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
1566       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
1567
1568       return true;
1569     }
1570   case FT_BelongToPlane:
1571   case FT_BelongToCylinder:
1572     {
1573       BelongToSurface_i* aPred = dynamic_cast<BelongToSurface_i*>( thePred );
1574
1575       CORBA::ULong i = theCriteria->length();
1576       theCriteria->length( i + 1 );
1577
1578       theCriteria[ i ] = createCriterion();
1579
1580       theCriteria[ i ].Type          = aFType;
1581       theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
1582       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
1583       theCriteria[ i ].Tolerance     = aPred->GetTolerance();
1584
1585       return true;
1586     }
1587    case FT_LyingOnGeom:
1588     {
1589       LyingOnGeom_i* aPred = dynamic_cast<LyingOnGeom_i*>( thePred );
1590
1591       CORBA::ULong i = theCriteria->length();
1592       theCriteria->length( i + 1 );
1593
1594       theCriteria[ i ] = createCriterion();
1595
1596       theCriteria[ i ].Type          = FT_LyingOnGeom;
1597       theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
1598       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
1599
1600       return true;
1601     }
1602   case FT_RangeOfIds:
1603     {
1604       RangeOfIds_i* aPred = dynamic_cast<RangeOfIds_i*>( thePred );
1605
1606       CORBA::ULong i = theCriteria->length();
1607       theCriteria->length( i + 1 );
1608
1609       theCriteria[ i ] = createCriterion();
1610
1611       theCriteria[ i ].Type          = FT_RangeOfIds;
1612       theCriteria[ i ].ThresholdStr  = aPred->GetRangeStr();
1613       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
1614
1615       return true;
1616     }
1617   case FT_LessThan:
1618   case FT_MoreThan:
1619   case FT_EqualTo:
1620     {
1621       Comparator_i* aCompar = dynamic_cast<Comparator_i*>( thePred );
1622
1623       CORBA::ULong i = theCriteria->length();
1624       theCriteria->length( i + 1 );
1625
1626       theCriteria[ i ] = createCriterion();
1627
1628       theCriteria[ i ].Type      = aCompar->GetNumFunctor_i()->GetFunctorType();
1629       theCriteria[ i ].Compare   = aFType;
1630       theCriteria[ i ].Threshold = aCompar->GetMargin();
1631       theCriteria[ i ].TypeOfElement = aCompar->GetElementType();
1632
1633       if ( aFType == FT_EqualTo )
1634       {
1635         EqualTo_i* aCompar = dynamic_cast<EqualTo_i*>( thePred );
1636         theCriteria[ i ].Tolerance = aCompar->GetTolerance();
1637       }
1638     }
1639     return true;
1640
1641   case FT_LogicalNOT:
1642     {
1643       Predicate_i* aPred = ( dynamic_cast<LogicalNOT_i*>( thePred ) )->GetPredicate_i();
1644       getCriteria( aPred, theCriteria );
1645       theCriteria[ theCriteria->length() - 1 ].UnaryOp = FT_LogicalNOT;
1646     }
1647     return true;
1648
1649   case FT_LogicalAND:
1650   case FT_LogicalOR:
1651     {
1652       Predicate_i* aPred1 = ( dynamic_cast<LogicalBinary_i*>( thePred ) )->GetPredicate1_i();
1653       Predicate_i* aPred2 = ( dynamic_cast<LogicalBinary_i*>( thePred ) )->GetPredicate2_i();
1654       if ( !getCriteria( aPred1, theCriteria ) )
1655         return false;
1656       theCriteria[ theCriteria->length() - 1 ].BinaryOp = aFType;
1657       return getCriteria( aPred2, theCriteria );
1658     }
1659
1660   case FT_Undefined:
1661     return false;
1662   default:
1663     return false;
1664   }
1665 }
1666
1667 //=======================================================================
1668 // name    : Filter_i::GetCriteria
1669 // Purpose : Retrieve criterions from predicate
1670 //=======================================================================
1671 CORBA::Boolean Filter_i::GetCriteria( SMESH::Filter::Criteria_out theCriteria )
1672 {
1673   theCriteria = new SMESH::Filter::Criteria;
1674   return myPredicate != 0 ? getCriteria( myPredicate, theCriteria ) : true;
1675 }
1676
1677 //=======================================================================
1678 // name    : Filter_i::SetCriteria
1679 // Purpose : Create new predicate and set criterions in it
1680 //=======================================================================
1681 CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria )
1682 {
1683   if ( myPredicate != 0 )
1684     myPredicate->Destroy();
1685
1686     SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i();
1687     FilterManager_ptr aFilterMgr = aFilter->_this();
1688
1689   // CREATE two lists ( PREDICATES  and LOG OP )
1690
1691   // Criterion
1692   std::list<SMESH::Predicate_ptr> aPredicates;
1693   std::list<int>                  aBinaries;
1694   for ( int i = 0, n = theCriteria.length(); i < n; i++ )
1695   {
1696     int         aCriterion    = theCriteria[ i ].Type;
1697     int         aCompare      = theCriteria[ i ].Compare;
1698     double      aThreshold    = theCriteria[ i ].Threshold;
1699     int         aUnary        = theCriteria[ i ].UnaryOp;
1700     int         aBinary       = theCriteria[ i ].BinaryOp;
1701     double      aTolerance    = theCriteria[ i ].Tolerance;
1702     const char* aThresholdStr = theCriteria[ i ].ThresholdStr;
1703     ElementType aTypeOfElem   = theCriteria[ i ].TypeOfElement;
1704     long        aPrecision    = theCriteria[ i ].Precision;
1705     
1706     SMESH::Predicate_ptr aPredicate = SMESH::Predicate::_nil();
1707     SMESH::NumericalFunctor_ptr aFunctor = SMESH::NumericalFunctor::_nil();
1708
1709     switch ( aCriterion )
1710     {
1711       // Functors
1712       
1713       case SMESH::FT_MultiConnection:
1714         aFunctor = aFilterMgr->CreateMultiConnection();
1715         break;
1716       case SMESH::FT_MultiConnection2D:
1717         aFunctor = aFilterMgr->CreateMultiConnection2D();
1718         break;
1719       case SMESH::FT_Length:
1720         aFunctor = aFilterMgr->CreateLength();
1721         break;
1722       case SMESH::FT_Length2D:
1723         aFunctor = aFilterMgr->CreateLength2D();
1724         break;
1725       case SMESH::FT_AspectRatio:
1726         aFunctor = aFilterMgr->CreateAspectRatio();
1727         break;
1728       case SMESH::FT_AspectRatio3D:
1729         aFunctor = aFilterMgr->CreateAspectRatio3D();
1730         break;
1731       case SMESH::FT_Warping:
1732         aFunctor = aFilterMgr->CreateWarping();
1733         break;
1734       case SMESH::FT_MinimumAngle:
1735         aFunctor = aFilterMgr->CreateMinimumAngle();
1736         break;
1737       case SMESH::FT_Taper:
1738         aFunctor = aFilterMgr->CreateTaper();
1739         break;
1740       case SMESH::FT_Skew:
1741         aFunctor = aFilterMgr->CreateSkew();
1742         break;
1743       case SMESH::FT_Area:
1744         aFunctor = aFilterMgr->CreateArea();
1745         break;
1746
1747       // Predicates
1748
1749       case SMESH::FT_FreeBorders:
1750         aPredicate = aFilterMgr->CreateFreeBorders();
1751         break;
1752       case SMESH::FT_FreeEdges:
1753         aPredicate = aFilterMgr->CreateFreeEdges();
1754         break;
1755       case SMESH::FT_BelongToGeom:
1756         {
1757           SMESH::BelongToGeom_ptr tmpPred = aFilterMgr->CreateBelongToGeom();
1758           tmpPred->SetElementType( aTypeOfElem );
1759           tmpPred->SetShapeName( aThresholdStr );
1760           aPredicate = tmpPred;
1761         }
1762         break;
1763       case SMESH::FT_BelongToPlane:
1764       case SMESH::FT_BelongToCylinder:
1765         {
1766           SMESH::BelongToSurface_ptr tmpPred;
1767           if ( aCriterion == SMESH::FT_BelongToPlane )
1768             tmpPred = aFilterMgr->CreateBelongToPlane();
1769           else
1770             tmpPred = aFilterMgr->CreateBelongToCylinder();
1771           tmpPred->SetShapeName( aThresholdStr, aTypeOfElem );
1772           tmpPred->SetTolerance( aTolerance );
1773           aPredicate = tmpPred;
1774         }
1775         break;
1776       case SMESH::FT_LyingOnGeom:
1777         {
1778           SMESH::LyingOnGeom_ptr tmpPred = aFilterMgr->CreateLyingOnGeom();
1779           tmpPred->SetElementType( aTypeOfElem );
1780           tmpPred->SetShapeName( aThresholdStr );
1781           aPredicate = tmpPred;
1782         }
1783         break; 
1784       case SMESH::FT_RangeOfIds:
1785         {
1786           SMESH::RangeOfIds_ptr tmpPred = aFilterMgr->CreateRangeOfIds();
1787           tmpPred->SetRangeStr( aThresholdStr );
1788           tmpPred->SetElementType( aTypeOfElem );
1789           aPredicate = tmpPred;
1790         }
1791         break;
1792               
1793       default:
1794         continue;
1795     }
1796
1797     // Comparator
1798     if ( !aFunctor->_is_nil() && aPredicate->_is_nil() )
1799     {
1800       SMESH::Comparator_ptr aComparator = SMESH::Comparator::_nil();
1801
1802       if ( aCompare == SMESH::FT_LessThan )
1803         aComparator = aFilterMgr->CreateLessThan();
1804       else if ( aCompare == SMESH::FT_MoreThan )
1805         aComparator = aFilterMgr->CreateMoreThan();
1806       else if ( aCompare == SMESH::FT_EqualTo )
1807         aComparator = aFilterMgr->CreateEqualTo();
1808       else
1809         continue;
1810
1811       aComparator->SetNumFunctor( aFunctor );
1812       aComparator->SetMargin( aThreshold );
1813
1814       if ( aCompare == FT_EqualTo )
1815       {
1816         SMESH::EqualTo_var anEqualTo = SMESH::EqualTo::_narrow( aComparator );
1817         anEqualTo->SetTolerance( aTolerance );
1818       }
1819
1820       aPredicate = aComparator;
1821
1822       aFunctor->SetPrecision( aPrecision );
1823     }
1824
1825     // Logical not
1826     if ( aUnary == FT_LogicalNOT )
1827     {
1828       SMESH::LogicalNOT_ptr aNotPred = aFilterMgr->CreateLogicalNOT();
1829       aNotPred->SetPredicate( aPredicate );
1830       aPredicate = aNotPred;
1831     }
1832
1833     // logical op
1834     aPredicates.push_back( aPredicate );
1835     aBinaries.push_back( aBinary );
1836
1837   } // end of for
1838
1839   // CREATE ONE PREDICATE FROM PREVIOUSLY CREATED MAP
1840
1841   // combine all "AND" operations
1842
1843   std::list<SMESH::Predicate_ptr> aResList;
1844
1845   std::list<SMESH::Predicate_ptr>::iterator aPredIter;
1846   std::list<int>::iterator                  aBinaryIter;
1847
1848   SMESH::Predicate_ptr aPrevPredicate = SMESH::Predicate::_nil();
1849   int aPrevBinary = SMESH::FT_Undefined;
1850
1851   for ( aPredIter = aPredicates.begin(), aBinaryIter = aBinaries.begin();
1852         aPredIter != aPredicates.end() && aBinaryIter != aBinaries.end();
1853         ++aPredIter, ++aBinaryIter )
1854   {
1855     int aCurrBinary = *aBinaryIter;
1856
1857     SMESH::Predicate_ptr aCurrPred = SMESH::Predicate::_nil();
1858
1859     if ( aPrevBinary == SMESH::FT_LogicalAND )
1860     {
1861
1862       SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalAND();
1863       aBinaryPred->SetPredicate1( aPrevPredicate );
1864       aBinaryPred->SetPredicate2( *aPredIter );
1865       aCurrPred = aBinaryPred;
1866     }
1867     else
1868       aCurrPred = *aPredIter;
1869
1870     if ( aCurrBinary != SMESH::FT_LogicalAND )
1871       aResList.push_back( aCurrPred );
1872
1873     aPrevPredicate = aCurrPred;
1874     aPrevBinary = aCurrBinary;
1875   }
1876
1877   // combine all "OR" operations
1878
1879   SMESH::Predicate_ptr aResPredicate = SMESH::Predicate::_nil();
1880
1881   if ( aResList.size() == 1 )
1882     aResPredicate = *aResList.begin();
1883   else if ( aResList.size() > 1 )
1884   {
1885     std::list<SMESH::Predicate_ptr>::iterator anIter = aResList.begin();
1886     aResPredicate = *anIter;
1887     anIter++;
1888     for ( ; anIter != aResList.end(); ++anIter )
1889     {
1890       SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalOR();
1891       aBinaryPred->SetPredicate1( aResPredicate );
1892       aBinaryPred->SetPredicate2( *anIter );
1893       aResPredicate = aBinaryPred;
1894     }
1895   }
1896
1897   SetPredicate( aResPredicate );
1898
1899   return !aResPredicate->_is_nil();
1900 }
1901
1902 //=======================================================================
1903 // name    : Filter_i::GetPredicate_i
1904 // Purpose : Get implementation of predicate
1905 //=======================================================================
1906 Predicate_i* Filter_i::GetPredicate_i()
1907 {
1908   return myPredicate;
1909 }
1910
1911 //=======================================================================
1912 // name    : Filter_i::GetPredicate
1913 // Purpose : Get predicate
1914 //=======================================================================
1915 Predicate_ptr Filter_i::GetPredicate()
1916 {
1917   if ( myPredicate == 0 )
1918     return SMESH::Predicate::_nil();
1919   else
1920   {
1921     SMESH::Predicate_var anObj = myPredicate->_this();
1922     return anObj._retn();
1923   }
1924 }
1925
1926 /*
1927                             FILTER LIBRARY
1928 */
1929
1930 #define ATTR_TYPE          "type"
1931 #define ATTR_COMPARE       "compare"
1932 #define ATTR_THRESHOLD     "threshold"
1933 #define ATTR_UNARY         "unary"
1934 #define ATTR_BINARY        "binary"
1935 #define ATTR_THRESHOLD_STR "threshold_str"
1936 #define ATTR_TOLERANCE     "tolerance"
1937 #define ATTR_ELEMENT_TYPE  "ElementType"
1938
1939 //=======================================================================
1940 // name    : toString
1941 // Purpose : Convert bool to LDOMString
1942 //=======================================================================
1943 static inline LDOMString toString( const bool val )
1944 {
1945   return val ? "logical not" : "";
1946 }
1947
1948 //=======================================================================
1949 // name    : toBool
1950 // Purpose : Convert LDOMString to bool
1951 //=======================================================================
1952 static inline bool toBool( const LDOMString& theStr )
1953 {
1954   return theStr.equals( "logical not" );
1955 }
1956
1957 //=======================================================================
1958 // name    : toString
1959 // Purpose : Convert double to LDOMString
1960 //=======================================================================
1961 static inline LDOMString toString( const double val )
1962 {
1963   char a[ 255 ];
1964   sprintf( a, "%e", val );
1965   return LDOMString( a );
1966 }
1967
1968 //=======================================================================
1969 // name    : toDouble
1970 // Purpose : Convert LDOMString to double
1971 //=======================================================================
1972 static inline double toDouble( const LDOMString& theStr )
1973 {
1974   return atof( theStr.GetString() );
1975 }
1976
1977 //=======================================================================
1978 // name    : toString
1979 // Purpose : Convert functor type to LDOMString
1980 //=======================================================================
1981 static inline LDOMString toString( const long theType )
1982 {
1983   switch ( theType )
1984   {
1985     case FT_AspectRatio     : return "Aspect ratio";
1986     case FT_Warping         : return "Warping";
1987     case FT_MinimumAngle    : return "Minimum angle";
1988     case FT_Taper           : return "Taper";
1989     case FT_Skew            : return "Skew";
1990     case FT_Area            : return "Area";
1991     case FT_BelongToGeom    : return "Belong to Geom";
1992     case FT_BelongToPlane   : return "Belong to Plane";
1993     case FT_BelongToCylinder: return "Belong to Cylinder";
1994     case FT_LyingOnGeom     : return "Lying on Geom";
1995     case FT_RangeOfIds      : return "Range of IDs";
1996     case FT_FreeBorders     : return "Free borders";
1997     case FT_FreeEdges       : return "Free edges";
1998     case FT_MultiConnection : return "Borders at multi-connections";
1999     case FT_MultiConnection2D: return "Borders at multi-connections 2D";
2000     case FT_Length          : return "Length";
2001     case FT_Length2D        : return "Length2D";
2002     case FT_LessThan        : return "Less than";
2003     case FT_MoreThan        : return "More than";
2004     case FT_EqualTo         : return "Equal to";
2005     case FT_LogicalNOT      : return "Not";
2006     case FT_LogicalAND      : return "And";
2007     case FT_LogicalOR       : return "Or";
2008     case FT_Undefined       : return "";
2009     default                 : return "";
2010   }
2011 }
2012
2013 //=======================================================================
2014 // name    : toFunctorType
2015 // Purpose : Convert LDOMString to functor type
2016 //=======================================================================
2017 static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
2018 {
2019   if      ( theStr.equals( "Aspect ratio"                 ) ) return FT_AspectRatio;
2020   else if ( theStr.equals( "Warping"                      ) ) return FT_Warping;
2021   else if ( theStr.equals( "Minimum angle"                ) ) return FT_MinimumAngle;
2022   else if ( theStr.equals( "Taper"                        ) ) return FT_Taper;
2023   else if ( theStr.equals( "Skew"                         ) ) return FT_Skew;
2024   else if ( theStr.equals( "Area"                         ) ) return FT_Area;
2025   else if ( theStr.equals( "Belong to Geom"               ) ) return FT_BelongToGeom;
2026   else if ( theStr.equals( "Belong to Plane"              ) ) return FT_BelongToPlane;
2027   else if ( theStr.equals( "Belong to Cylinder"           ) ) return FT_BelongToCylinder;
2028   else if ( theStr.equals( "Lying on Geom"                ) ) return FT_LyingOnGeom;
2029   else if ( theStr.equals( "Free borders"                 ) ) return FT_FreeBorders;
2030   else if ( theStr.equals( "Free edges"                   ) ) return FT_FreeEdges;
2031   else if ( theStr.equals( "Borders at multi-connections" ) ) return FT_MultiConnection;
2032   //  else if ( theStr.equals( "Borders at multi-connections 2D" ) ) return FT_MultiConnection2D;
2033   else if ( theStr.equals( "Length"                       ) ) return FT_Length;
2034   //  else if ( theStr.equals( "Length2D"                     ) ) return FT_Length2D;
2035   else if ( theStr.equals( "Range of IDs"                 ) ) return FT_RangeOfIds;
2036   else if ( theStr.equals( "Less than"                    ) ) return FT_LessThan;
2037   else if ( theStr.equals( "More than"                    ) ) return FT_MoreThan;
2038   else if ( theStr.equals( "Equal to"                     ) ) return FT_EqualTo;
2039   else if ( theStr.equals( "Not"                          ) ) return FT_LogicalNOT;
2040   else if ( theStr.equals( "And"                          ) ) return FT_LogicalAND;
2041   else if ( theStr.equals( "Or"                           ) ) return FT_LogicalOR;
2042   else if ( theStr.equals( ""                             ) ) return FT_Undefined;
2043   else  return FT_Undefined;
2044 }
2045
2046 //=======================================================================
2047 // name    : toFunctorType
2048 // Purpose : Convert LDOMString to value of ElementType enumeration
2049 //=======================================================================
2050 static inline SMESH::ElementType toElementType( const LDOMString& theStr )
2051 {
2052   if      ( theStr.equals( "NODE"   ) ) return SMESH::NODE;
2053   else if ( theStr.equals( "EDGE"   ) ) return SMESH::EDGE;
2054   else if ( theStr.equals( "FACE"   ) ) return SMESH::FACE;
2055   else if ( theStr.equals( "VOLUME" ) ) return SMESH::VOLUME;
2056   else                                  return SMESH::ALL;
2057 }
2058
2059 //=======================================================================
2060 // name    : toString
2061 // Purpose : Convert ElementType to string
2062 //=======================================================================
2063 static inline LDOMString toString( const SMESH::ElementType theType )
2064 {
2065   switch ( theType )
2066   {
2067     case SMESH::NODE   : return "NODE";
2068     case SMESH::EDGE   : return "EDGE";
2069     case SMESH::FACE   : return "FACE";
2070     case SMESH::VOLUME : return "VOLUME";
2071     case SMESH::ALL    : return "ALL";
2072     default            : return "";
2073   }
2074 }
2075
2076 //=======================================================================
2077 // name    : findFilter
2078 // Purpose : Find filter in document
2079 //=======================================================================
2080 static LDOM_Element findFilter( const char* theFilterName,
2081                                 const LDOM_Document& theDoc,
2082                                 LDOM_Node* theParent = 0 )
2083 {
2084   LDOM_Element aRootElement = theDoc.getDocumentElement();
2085   if ( aRootElement.isNull() || !aRootElement.hasChildNodes() )
2086     return LDOM_Element();
2087
2088   for ( LDOM_Node aTypeNode = aRootElement.getFirstChild();
2089         !aTypeNode.isNull(); aTypeNode = aTypeNode.getNextSibling() )
2090   {
2091     for ( LDOM_Node aFilter = aTypeNode.getFirstChild();
2092           !aFilter.isNull(); aFilter = aFilter.getNextSibling() )
2093     {
2094       LDOM_Element* anElem = ( LDOM_Element* )&aFilter;
2095       if ( anElem->getTagName().equals( LDOMString( "filter" ) ) &&
2096            anElem->getAttribute( "name" ).equals( LDOMString( theFilterName ) ) )
2097       {
2098         if ( theParent != 0  )
2099           *theParent = aTypeNode;
2100         return (LDOM_Element&)aFilter;
2101       }
2102     }
2103   }
2104   return LDOM_Element();
2105 }
2106
2107 //=======================================================================
2108 // name    : getSectionName
2109 // Purpose : Get name of section of filters
2110 //=======================================================================
2111 static const char* getSectionName( const ElementType theType )
2112 {
2113   switch ( theType )
2114   {
2115     case SMESH::NODE   : return "Filters for nodes";
2116     case SMESH::EDGE   : return "Filters for edges";
2117     case SMESH::FACE   : return "Filters for faces";
2118     case SMESH::VOLUME : return "Filters for volumes";
2119     case SMESH::ALL    : return "Filters for elements";
2120     default            : return "";
2121   }
2122 }
2123
2124 //=======================================================================
2125 // name    : getSection
2126 // Purpose : Create section for filters corresponding to the entity type
2127 //=======================================================================
2128 static LDOM_Node getSection( const ElementType theType,
2129                              LDOM_Document&    theDoc,
2130                              const bool        toCreate = false )
2131 {
2132   LDOM_Element aRootElement = theDoc.getDocumentElement();
2133   if ( aRootElement.isNull() )
2134     return LDOM_Node();
2135
2136   // Find section
2137   bool anExist = false;
2138   const char* aSectionName = getSectionName( theType );
2139   if ( strcmp( aSectionName, "" ) == 0 )
2140     return LDOM_Node();
2141   
2142   LDOM_NodeList aSections = theDoc.getElementsByTagName( "section" );
2143   LDOM_Node aNode;
2144   for ( int i = 0, n = aSections.getLength(); i < n; i++ )
2145   {
2146     aNode = aSections.item( i );
2147     LDOM_Element& anItem = ( LDOM_Element& )aNode;
2148     if ( anItem.getAttribute( "name" ).equals( LDOMString( aSectionName ) ) )
2149     {
2150       anExist = true;
2151       break;
2152     }
2153   }
2154
2155   // Create new section if necessary
2156   if ( !anExist )
2157   {
2158     if ( toCreate )
2159     {
2160       LDOM_Element aNewItem = theDoc.createElement( "section" );
2161       aNewItem.setAttribute( "name", aSectionName );
2162       aRootElement.appendChild( aNewItem );
2163       return aNewItem;
2164     }
2165     else
2166       return LDOM_Node();
2167   }
2168   return
2169     aNode;
2170 }
2171
2172 //=======================================================================
2173 // name    : createFilterItem
2174 // Purpose : Create filter item or LDOM document
2175 //=======================================================================
2176 static LDOM_Element createFilterItem( const char*       theName,
2177                                       SMESH::Filter_ptr theFilter,
2178                                       LDOM_Document&    theDoc )
2179 {
2180   // create new filter in document
2181   LDOM_Element aFilterItem = theDoc.createElement( "filter" );
2182   aFilterItem.setAttribute( "name", theName );
2183
2184   // save filter criterions
2185   SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria;
2186
2187   if ( !theFilter->GetCriteria( aCriteria ) )
2188     return LDOM_Element();
2189
2190   for ( CORBA::ULong i = 0, n = aCriteria->length(); i < n; i++ )
2191   {
2192     LDOM_Element aCriterionItem = theDoc.createElement( "criterion" );
2193
2194     aCriterionItem.setAttribute( ATTR_TYPE         , toString( aCriteria[ i ].Type      ) );
2195     aCriterionItem.setAttribute( ATTR_COMPARE      , toString( aCriteria[ i ].Compare   ) );
2196     aCriterionItem.setAttribute( ATTR_THRESHOLD    , toString( aCriteria[ i ].Threshold ) );
2197     aCriterionItem.setAttribute( ATTR_UNARY        , toString( aCriteria[ i ].UnaryOp   ) );
2198     aCriterionItem.setAttribute( ATTR_BINARY       , toString( aCriteria[ i ].BinaryOp  ) );
2199     
2200     aCriterionItem.setAttribute( ATTR_THRESHOLD_STR, (const char*)aCriteria[ i ].ThresholdStr );
2201     aCriterionItem.setAttribute( ATTR_TOLERANCE    , toString( aCriteria[ i ].Tolerance ) );
2202     aCriterionItem.setAttribute( ATTR_ELEMENT_TYPE ,
2203       toString( (SMESH::ElementType)aCriteria[ i ].TypeOfElement ) );
2204
2205     aFilterItem.appendChild( aCriterionItem );
2206   }
2207
2208   return aFilterItem;
2209 }
2210
2211 //=======================================================================
2212 // name    : FilterLibrary_i::FilterLibrary_i
2213 // Purpose : Constructor
2214 //=======================================================================
2215 FilterLibrary_i::FilterLibrary_i( const char* theFileName )
2216 {
2217   myFileName = strdup( theFileName );
2218   SMESH::FilterManager_i* aFilterMgr = new SMESH::FilterManager_i();
2219   myFilterMgr = aFilterMgr->_this();
2220
2221   LDOMParser aParser;
2222
2223   // Try to use existing library file
2224   bool anExists = false;
2225   if ( !aParser.parse( myFileName ) )
2226   {
2227     myDoc = aParser.getDocument();
2228     anExists = true;
2229   }
2230   // Create a new XML document if it doesn't exist
2231   else
2232     myDoc = LDOM_Document::createDocument( LDOMString() );
2233
2234   LDOM_Element aRootElement = myDoc.getDocumentElement();
2235   if ( aRootElement.isNull() )
2236   {
2237     // If the existing document is empty --> try to create a new one
2238     if ( anExists )
2239       myDoc = LDOM_Document::createDocument( LDOMString() );
2240   }
2241 }
2242
2243 //=======================================================================
2244 // name    : FilterLibrary_i::FilterLibrary_i
2245 // Purpose : Constructor
2246 //=======================================================================
2247 FilterLibrary_i::FilterLibrary_i()
2248 {
2249   myFileName = 0;
2250   SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i();
2251   myFilterMgr = aFilter->_this();
2252
2253   myDoc = LDOM_Document::createDocument( LDOMString() );
2254 }
2255
2256 FilterLibrary_i::~FilterLibrary_i()
2257 {
2258   delete myFileName;
2259 }
2260
2261 //=======================================================================
2262 // name    : FilterLibrary_i::Copy
2263 // Purpose : Create filter and initialize it with values from library
2264 //=======================================================================
2265 Filter_ptr FilterLibrary_i::Copy( const char* theFilterName )
2266 {
2267   Filter_ptr aRes;
2268   LDOM_Node aFilter = findFilter( theFilterName, myDoc );
2269
2270   if ( aFilter.isNull() )
2271     return aRes;
2272
2273   std::list<SMESH::Filter::Criterion> aCriteria;
2274     
2275   for ( LDOM_Node aCritNode = aFilter.getFirstChild();
2276         !aCritNode.isNull() ; aCritNode = aCritNode.getNextSibling() )
2277   {
2278     LDOM_Element* aCrit = (LDOM_Element*)&aCritNode;
2279
2280     const char* aTypeStr      = aCrit->getAttribute( ATTR_TYPE          ).GetString();
2281     const char* aCompareStr   = aCrit->getAttribute( ATTR_COMPARE       ).GetString();
2282     const char* aUnaryStr     = aCrit->getAttribute( ATTR_UNARY         ).GetString();
2283     const char* aBinaryStr    = aCrit->getAttribute( ATTR_BINARY        ).GetString();
2284     const char* anElemTypeStr = aCrit->getAttribute( ATTR_ELEMENT_TYPE  ).GetString();
2285     
2286     SMESH::Filter::Criterion aCriterion = createCriterion();
2287
2288     aCriterion.Type          = toFunctorType( aTypeStr );
2289     aCriterion.Compare       = toFunctorType( aCompareStr );
2290     aCriterion.UnaryOp       = toFunctorType( aUnaryStr );
2291     aCriterion.BinaryOp      = toFunctorType( aBinaryStr );
2292     
2293     aCriterion.TypeOfElement = toElementType( anElemTypeStr );
2294
2295     LDOMString str = aCrit->getAttribute( ATTR_THRESHOLD );
2296     int val = 0;
2297     aCriterion.Threshold = str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val )
2298       ? val : atof( str.GetString() );
2299
2300     str = aCrit->getAttribute( ATTR_TOLERANCE );
2301     aCriterion.Tolerance = str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val )
2302       ? val : atof( str.GetString() );
2303
2304     str = aCrit->getAttribute( ATTR_THRESHOLD_STR );
2305     if ( str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val ) )
2306     {
2307       char a[ 255 ];
2308       sprintf( a, "%d", val );
2309       aCriterion.ThresholdStr = strdup( a );
2310     }
2311     else
2312       aCriterion.ThresholdStr = str.GetString();
2313
2314     aCriteria.push_back( aCriterion );
2315   }
2316
2317   SMESH::Filter::Criteria_var aCriteriaVar = new SMESH::Filter::Criteria;
2318   aCriteriaVar->length( aCriteria.size() );
2319   
2320   CORBA::ULong i = 0;
2321   std::list<SMESH::Filter::Criterion>::iterator anIter = aCriteria.begin();
2322   
2323   for( ; anIter != aCriteria.end(); ++anIter )
2324     aCriteriaVar[ i++ ] = *anIter;
2325
2326   aRes = myFilterMgr->CreateFilter();
2327   aRes->SetCriteria( aCriteriaVar.inout() );
2328
2329   return aRes;
2330 }
2331
2332 //=======================================================================
2333 // name    : FilterLibrary_i::SetFileName
2334 // Purpose : Set file name for library
2335 //=======================================================================
2336 void FilterLibrary_i::SetFileName( const char* theFileName )
2337 {
2338   delete myFileName;
2339   myFileName = strdup( theFileName );
2340 }
2341
2342 //=======================================================================
2343 // name    : FilterLibrary_i::GetFileName
2344 // Purpose : Get file name of library
2345 //=======================================================================
2346 char* FilterLibrary_i::GetFileName()
2347 {
2348   return CORBA::string_dup( myFileName );
2349 }
2350
2351 //=======================================================================
2352 // name    : FilterLibrary_i::Add
2353 // Purpose : Add new filter to library
2354 //=======================================================================
2355 CORBA::Boolean FilterLibrary_i::Add( const char* theFilterName, Filter_ptr theFilter )
2356 {
2357   // if filter already in library or entry filter is null do nothing
2358   LDOM_Node aFilterNode = findFilter( theFilterName, myDoc );
2359   if ( !aFilterNode.isNull() || theFilter->_is_nil() )
2360     return false;
2361
2362   // get section corresponding to the filter type
2363   ElementType anEntType = theFilter->GetElementType();
2364
2365   LDOM_Node aSection = getSection( anEntType, myDoc, true );
2366   if ( aSection.isNull() )
2367     return false;
2368
2369   // create filter item
2370   LDOM_Element aFilterItem = createFilterItem( theFilterName, theFilter, myDoc );
2371   if ( aFilterItem.isNull() )
2372     return false;
2373   else
2374   {
2375     aSection.appendChild( aFilterItem );
2376     return true;
2377   }
2378 }
2379
2380 //=======================================================================
2381 // name    : FilterLibrary_i::Add
2382 // Purpose : Add new filter to library
2383 //=======================================================================
2384 CORBA::Boolean FilterLibrary_i::AddEmpty( const char* theFilterName, ElementType theType )
2385 {
2386   // if filter already in library or entry filter is null do nothing
2387   LDOM_Node aFilterNode = findFilter( theFilterName, myDoc );
2388   if ( !aFilterNode.isNull() )
2389     return false;
2390
2391   LDOM_Node aSection = getSection( theType, myDoc, true );
2392   if ( aSection.isNull() )
2393     return false;
2394
2395   // create filter item
2396   Filter_var aFilter = myFilterMgr->CreateFilter();
2397   
2398   LDOM_Element aFilterItem = createFilterItem( theFilterName, aFilter, myDoc );
2399   if ( aFilterItem.isNull() )
2400     return false;
2401   else
2402   {
2403     aSection.appendChild( aFilterItem );
2404     return true;
2405   }
2406 }
2407
2408 //=======================================================================
2409 // name    : FilterLibrary_i::Delete
2410 // Purpose : Delete filter from library
2411 //=======================================================================
2412 CORBA::Boolean FilterLibrary_i::Delete ( const char* theFilterName )
2413 {
2414   LDOM_Node aParentNode;
2415   LDOM_Node aFilterNode = findFilter( theFilterName, myDoc, &aParentNode );
2416   if ( aFilterNode.isNull() || aParentNode.isNull() )
2417     return false;
2418
2419   aParentNode.removeChild( aFilterNode );
2420   return true;
2421 }
2422
2423 //=======================================================================
2424 // name      : FilterLibrary_i::Replace 
2425 // Purpose   : Replace existing filter with entry filter.
2426 // IMPORTANT : If filter does not exist it is not created
2427 //=======================================================================
2428 CORBA::Boolean FilterLibrary_i::Replace( const char* theFilterName,
2429                                          const char* theNewName,                 
2430                                          Filter_ptr  theFilter )
2431 {
2432   LDOM_Element aFilterItem = findFilter( theFilterName, myDoc );
2433   if ( aFilterItem.isNull() || theFilter->_is_nil() )
2434     return false;
2435
2436   LDOM_Element aNewItem = createFilterItem( theNewName, theFilter, myDoc );
2437   if ( aNewItem.isNull() )
2438     return false;
2439   else                                                                                          
2440   {
2441     aFilterItem.ReplaceElement( aNewItem );
2442     return true;
2443   }
2444 }
2445
2446 //=======================================================================
2447 // name    : FilterLibrary_i::Save
2448 // Purpose : Save library on disk
2449 //=======================================================================
2450 CORBA::Boolean FilterLibrary_i::Save()
2451 {
2452   if ( myFileName == 0 || strlen( myFileName ) == 0 )
2453     return false;
2454           
2455   FILE* aOutFile = fopen( myFileName, "wt" );
2456   if ( !aOutFile )
2457     return false;
2458
2459   LDOM_XmlWriter aWriter( aOutFile );
2460   aWriter.SetIndentation( 2 );
2461   aWriter << myDoc;
2462   fclose( aOutFile );
2463
2464   return true;
2465 }
2466
2467 //=======================================================================
2468 // name    : FilterLibrary_i::SaveAs
2469 // Purpose : Save library on disk
2470 //=======================================================================
2471 CORBA::Boolean FilterLibrary_i::SaveAs( const char* aFileName )
2472 {
2473   myFileName = strdup ( aFileName );
2474   return Save();
2475 }
2476
2477 //=======================================================================
2478 // name    : FilterLibrary_i::IsPresent
2479 // Purpose : Verify whether filter is in library
2480 //=======================================================================
2481 CORBA::Boolean FilterLibrary_i::IsPresent( const char* theFilterName )
2482 {
2483   return !findFilter( theFilterName, myDoc ).isNull();
2484 }
2485
2486 //=======================================================================
2487 // name    : FilterLibrary_i::NbFilters
2488 // Purpose : Return amount of filters in library
2489 //=======================================================================
2490 CORBA::Long FilterLibrary_i::NbFilters( ElementType theType )
2491 {
2492   string_array_var aNames = GetNames( theType );
2493   return aNames->length();
2494 }
2495
2496 //=======================================================================
2497 // name    : FilterLibrary_i::GetNames
2498 // Purpose : Get names of filters from library
2499 //=======================================================================
2500 string_array* FilterLibrary_i::GetNames( ElementType theType )
2501 {
2502   string_array_var anArray = new string_array;
2503   TColStd_SequenceOfHAsciiString aSeq;
2504
2505   LDOM_Node aSection = getSection( theType, myDoc, false );
2506
2507   if ( !aSection.isNull() )
2508   {
2509     for ( LDOM_Node aFilter = aSection.getFirstChild();
2510           !aFilter.isNull(); aFilter = aFilter.getNextSibling() )
2511     {
2512       LDOM_Element& anElem = ( LDOM_Element& )aFilter;
2513       aSeq.Append( new TCollection_HAsciiString(
2514          (Standard_CString)anElem.getAttribute( "name" ).GetString() ) );
2515     }
2516   }
2517
2518   anArray->length( aSeq.Length() );
2519   for ( int i = 1, n = aSeq.Length(); i <= n; i++ )
2520     anArray[ i - 1 ] = CORBA::string_dup( aSeq( i )->ToCString() );
2521
2522   return anArray._retn();
2523 }
2524
2525 //=======================================================================
2526 // name    : FilterLibrary_i::GetAllNames
2527 // Purpose : Get names of filters from library
2528 //=======================================================================
2529 string_array* FilterLibrary_i::GetAllNames()
2530 {
2531   string_array_var aResArray = new string_array;
2532   for ( int type = SMESH::ALL; type <= SMESH::VOLUME; type++ )
2533   {
2534     SMESH::string_array_var aNames = GetNames( (SMESH::ElementType)type );
2535
2536     int aPrevLength = aResArray->length();
2537     aResArray->length( aPrevLength + aNames->length() );
2538     for ( int i = 0, n = aNames->length(); i < n; i++ )
2539       aResArray[ aPrevLength + i ] = aNames[ i ];
2540   }
2541
2542   return aResArray._retn();
2543 }