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