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