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