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