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