Salome HOME
Update copyright
[modules/smesh.git] / src / SMESH_I / SMESH_Filter_i.cxx
1 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  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 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
24 //  File   : SMESH_Filter_i.cxx
25 //  Author : Alexey Petrov, OCC
26 //  Module : SMESH
27 //
28 #include "SMESH_Filter_i.hxx"
29
30 #include "SMESH_Gen_i.hxx"
31 #include "SMESH_PythonDump.hxx"
32
33 #include "SMDS_Mesh.hxx"
34 #include "SMDS_MeshNode.hxx"
35 #include "SMDS_MeshElement.hxx"
36 #include "SMDS_ElemIterator.hxx"
37 #include "SMDS_VolumeTool.hxx"
38
39 #include "SMESHDS_Mesh.hxx"
40
41 #include <BRep_Tool.hxx>
42 #include <Geom_CylindricalSurface.hxx>
43 #include <Geom_Plane.hxx>
44 #include <LDOMParser.hxx>
45 #include <LDOMString.hxx>
46 #include <LDOM_Document.hxx>
47 #include <LDOM_Element.hxx>
48 #include <LDOM_Node.hxx>
49 #include <LDOM_XmlWriter.hxx>
50 #include <Precision.hxx>
51 #include <TColStd_ListIteratorOfListOfInteger.hxx>
52 #include <TColStd_ListIteratorOfListOfReal.hxx>
53 #include <TColStd_ListOfInteger.hxx>
54 #include <TColStd_ListOfReal.hxx>
55 #include <TColStd_SequenceOfHAsciiString.hxx>
56 #include <TCollection_HAsciiString.hxx>
57 #include <TopExp.hxx>
58 #include <TopExp_Explorer.hxx>
59 #include <TopoDS.hxx>
60 #include <TopoDS_Face.hxx>
61 #include <TopoDS_Shape.hxx>
62 #include <TopTools_IndexedMapOfShape.hxx>
63
64 using namespace SMESH;
65 using namespace SMESH::Controls;
66
67
68 namespace SMESH
69 {
70   Predicate_i*
71   GetPredicate( Predicate_ptr thePredicate )
72   {
73     return DownCast<Predicate_i*>(thePredicate);
74   }
75 }
76
77
78 /*
79   Class       : BelongToGeom
80   Description : Predicate for verifying whether entity belongs to
81                 specified geometrical support
82 */
83
84 Controls::BelongToGeom::BelongToGeom()
85   : myMeshDS(NULL),
86     myType(SMDSAbs_All),
87     myIsSubshape(false),
88     myTolerance(Precision::Confusion())
89 {}
90
91 void Controls::BelongToGeom::SetMesh( const SMDS_Mesh* theMesh )
92 {
93   myMeshDS = dynamic_cast<const SMESHDS_Mesh*>(theMesh);
94   init();
95 }
96
97 void Controls::BelongToGeom::SetGeom( const TopoDS_Shape& theShape )
98 {
99   myShape = theShape;
100   init();
101 }
102
103 static bool IsSubShape (const TopTools_IndexedMapOfShape& theMap,
104                         const TopoDS_Shape& theShape)
105 {
106   if (theMap.Contains(theShape)) return true;
107
108   if (theShape.ShapeType() == TopAbs_COMPOUND ||
109       theShape.ShapeType() == TopAbs_COMPSOLID)
110   {
111     TopoDS_Iterator anIt (theShape, Standard_True, Standard_True);
112     for (; anIt.More(); anIt.Next())
113     {
114       if (!IsSubShape(theMap, anIt.Value())) {
115         return false;
116       }
117     }
118     return true;
119   }
120
121   return false;
122 }
123
124 void Controls::BelongToGeom::init()
125 {
126   if (!myMeshDS || myShape.IsNull()) return;
127
128   // is subshape of main shape?
129   TopoDS_Shape aMainShape = myMeshDS->ShapeToMesh();
130   if (aMainShape.IsNull()) {
131     myIsSubshape = false;
132   }
133   else {
134     TopTools_IndexedMapOfShape aMap;
135     TopExp::MapShapes(aMainShape, aMap);
136     myIsSubshape = IsSubShape(aMap, myShape);
137   }
138
139   if (!myIsSubshape)
140   {
141     myElementsOnShapePtr.reset(new Controls::ElementsOnShape());
142     myElementsOnShapePtr->SetTolerance(myTolerance);
143     myElementsOnShapePtr->SetAllNodes(true); // belong, while false means "lays on"
144     myElementsOnShapePtr->SetMesh(myMeshDS);
145     myElementsOnShapePtr->SetShape(myShape, myType);
146   }
147 }
148
149 static bool IsContains( const SMESHDS_Mesh*     theMeshDS,
150                         const TopoDS_Shape&     theShape,
151                         const SMDS_MeshElement* theElem,
152                         TopAbs_ShapeEnum        theFindShapeEnum,
153                         TopAbs_ShapeEnum        theAvoidShapeEnum = TopAbs_SHAPE )
154 {
155   TopExp_Explorer anExp( theShape,theFindShapeEnum,theAvoidShapeEnum );
156
157   while( anExp.More() )
158   {
159     const TopoDS_Shape& aShape = anExp.Current();
160     if( SMESHDS_SubMesh* aSubMesh = theMeshDS->MeshElements( aShape ) ){
161       if( aSubMesh->Contains( theElem ) )
162         return true;
163     }
164     anExp.Next();
165   }
166   return false;
167 }
168
169 bool Controls::BelongToGeom::IsSatisfy (long theId)
170 {
171   if (myMeshDS == 0 || myShape.IsNull())
172     return false;
173
174   if (!myIsSubshape)
175   {
176     return myElementsOnShapePtr->IsSatisfy(theId);
177   }
178
179   // Case of submesh
180   if (myType == SMDSAbs_Node)
181   {
182     if( const SMDS_MeshNode* aNode = myMeshDS->FindNode( theId ) )
183     {
184       const SMDS_PositionPtr& aPosition = aNode->GetPosition();
185       SMDS_TypeOfPosition aTypeOfPosition = aPosition->GetTypeOfPosition();
186       switch( aTypeOfPosition )
187       {
188       case SMDS_TOP_VERTEX : return IsContains( myMeshDS,myShape,aNode,TopAbs_VERTEX );
189       case SMDS_TOP_EDGE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_EDGE );
190       case SMDS_TOP_FACE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_FACE );
191       case SMDS_TOP_3DSPACE: return IsContains( myMeshDS,myShape,aNode,TopAbs_SHELL );
192       }
193     }
194   }
195   else
196   {
197     if( const SMDS_MeshElement* anElem = myMeshDS->FindElement( theId ) )
198     {
199       if( myType == SMDSAbs_All )
200       {
201         return IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE ) ||
202                IsContains( myMeshDS,myShape,anElem,TopAbs_FACE ) ||
203                IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
204                IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID );
205       }
206       else if( myType == anElem->GetType() )
207       {
208         switch( myType )
209         {
210         case SMDSAbs_Edge  : return IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE );
211         case SMDSAbs_Face  : return IsContains( myMeshDS,myShape,anElem,TopAbs_FACE );
212         case SMDSAbs_Volume: return IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
213                                     IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID );
214         }
215       }
216     }
217   }
218
219   return false;
220 }
221
222 void Controls::BelongToGeom::SetType (SMDSAbs_ElementType theType)
223 {
224   myType = theType;
225   init();
226 }
227
228 SMDSAbs_ElementType Controls::BelongToGeom::GetType() const
229 {
230   return myType;
231 }
232
233 TopoDS_Shape Controls::BelongToGeom::GetShape()
234 {
235   return myShape;
236 }
237
238 const SMESHDS_Mesh* Controls::BelongToGeom::GetMeshDS() const
239 {
240   return myMeshDS;
241 }
242
243 void Controls::BelongToGeom::SetTolerance (double theTolerance)
244 {
245   myTolerance = theTolerance;
246   if (!myIsSubshape)
247     init();
248 }
249
250 double Controls::BelongToGeom::GetTolerance()
251 {
252   return myTolerance;
253 }
254
255 /*
256   Class       : LyingOnGeom
257   Description : Predicate for verifying whether entiy lying or partially lying on
258                 specified geometrical support
259 */
260
261 Controls::LyingOnGeom::LyingOnGeom()
262   : myMeshDS(NULL),
263     myType(SMDSAbs_All),
264     myIsSubshape(false),
265     myTolerance(Precision::Confusion())
266 {}
267
268 void Controls::LyingOnGeom::SetMesh( const SMDS_Mesh* theMesh )
269 {
270   myMeshDS = dynamic_cast<const SMESHDS_Mesh*>(theMesh);
271   init();
272 }
273
274 void Controls::LyingOnGeom::SetGeom( const TopoDS_Shape& theShape )
275 {
276   myShape = theShape;
277   init();
278 }
279
280 void Controls::LyingOnGeom::init()
281 {
282   if (!myMeshDS || myShape.IsNull()) return;
283
284   // is subshape of main shape?
285   TopoDS_Shape aMainShape = myMeshDS->ShapeToMesh();
286   if (aMainShape.IsNull()) {
287     myIsSubshape = false;
288   }
289   else {
290     TopTools_IndexedMapOfShape aMap;
291     TopExp::MapShapes(aMainShape, aMap);
292     myIsSubshape = IsSubShape(aMap, myShape);
293   }
294
295   if (!myIsSubshape)
296   {
297     myElementsOnShapePtr.reset(new Controls::ElementsOnShape());
298     myElementsOnShapePtr->SetTolerance(myTolerance);
299     myElementsOnShapePtr->SetAllNodes(false); // lays on, while true means "belong"
300     myElementsOnShapePtr->SetMesh(myMeshDS);
301     myElementsOnShapePtr->SetShape(myShape, myType);
302   }
303 }
304
305 bool Controls::LyingOnGeom::IsSatisfy( long theId )
306 {
307   if ( myMeshDS == 0 || myShape.IsNull() )
308     return false;
309
310   if (!myIsSubshape)
311   {
312     return myElementsOnShapePtr->IsSatisfy(theId);
313   }
314
315   // Case of submesh
316   if( myType == SMDSAbs_Node )
317   {
318     if( const SMDS_MeshNode* aNode = myMeshDS->FindNode( theId ) )
319     {
320       const SMDS_PositionPtr& aPosition = aNode->GetPosition();
321       SMDS_TypeOfPosition aTypeOfPosition = aPosition->GetTypeOfPosition();
322       switch( aTypeOfPosition )
323       {
324       case SMDS_TOP_VERTEX : return IsContains( myMeshDS,myShape,aNode,TopAbs_VERTEX );
325       case SMDS_TOP_EDGE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_EDGE );
326       case SMDS_TOP_FACE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_FACE );
327       case SMDS_TOP_3DSPACE: return IsContains( myMeshDS,myShape,aNode,TopAbs_SHELL );
328       }
329     }
330   }
331   else
332   {
333     if( const SMDS_MeshElement* anElem = myMeshDS->FindElement( theId ) )
334     {
335       if( myType == SMDSAbs_All )
336       {
337         return Contains( myMeshDS,myShape,anElem,TopAbs_EDGE ) ||
338                Contains( myMeshDS,myShape,anElem,TopAbs_FACE ) ||
339                Contains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
340                Contains( myMeshDS,myShape,anElem,TopAbs_SOLID );
341       }
342       else if( myType == anElem->GetType() )
343       {
344         switch( myType )
345         {
346         case SMDSAbs_Edge  : return Contains( myMeshDS,myShape,anElem,TopAbs_EDGE );
347         case SMDSAbs_Face  : return Contains( myMeshDS,myShape,anElem,TopAbs_FACE );
348         case SMDSAbs_Volume: return Contains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
349                                     Contains( myMeshDS,myShape,anElem,TopAbs_SOLID );
350         }
351       }
352     }
353   }
354
355   return false;
356 }
357
358 void Controls::LyingOnGeom::SetType( SMDSAbs_ElementType theType )
359 {
360   myType = theType;
361   init();
362 }
363
364 SMDSAbs_ElementType Controls::LyingOnGeom::GetType() const
365 {
366   return myType;
367 }
368
369 TopoDS_Shape Controls::LyingOnGeom::GetShape()
370 {
371   return myShape;
372 }
373
374 const SMESHDS_Mesh* Controls::LyingOnGeom::GetMeshDS() const
375 {
376   return myMeshDS;
377 }
378
379 void Controls::LyingOnGeom::SetTolerance (double theTolerance)
380 {
381   myTolerance = theTolerance;
382   if (!myIsSubshape)
383     init();
384 }
385
386 double Controls::LyingOnGeom::GetTolerance()
387 {
388   return myTolerance;
389 }
390
391 bool Controls::LyingOnGeom::Contains( const SMESHDS_Mesh*     theMeshDS,
392                                       const TopoDS_Shape&     theShape,
393                                       const SMDS_MeshElement* theElem,
394                                       TopAbs_ShapeEnum        theFindShapeEnum,
395                                       TopAbs_ShapeEnum        theAvoidShapeEnum )
396 {
397   if (IsContains(theMeshDS, theShape, theElem, theFindShapeEnum, theAvoidShapeEnum))
398     return true;
399
400   TopTools_IndexedMapOfShape aSubShapes;
401   TopExp::MapShapes( theShape, aSubShapes );
402
403   for (int i = 1; i <= aSubShapes.Extent(); i++)
404   {
405     const TopoDS_Shape& aShape = aSubShapes.FindKey(i);
406
407     if( SMESHDS_SubMesh* aSubMesh = theMeshDS->MeshElements( aShape ) ){
408       if( aSubMesh->Contains( theElem ) )
409         return true;
410
411       SMDS_NodeIteratorPtr aNodeIt = aSubMesh->GetNodes();
412       while ( aNodeIt->more() )
413       {
414         const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(aNodeIt->next());
415         SMDS_ElemIteratorPtr anElemIt = aNode->GetInverseElementIterator();
416         while ( anElemIt->more() )
417         {
418           const SMDS_MeshElement* anElement = static_cast<const SMDS_MeshElement*>(anElemIt->next());
419           if (anElement == theElem)
420             return true;
421         }
422       }
423     }
424   }
425   return false;
426 }
427
428
429 /*
430                             AUXILIARY METHODS
431 */
432
433 inline
434 const SMDS_Mesh*
435 MeshPtr2SMDSMesh( SMESH_Mesh_ptr theMesh )
436 {
437   SMESH_Mesh_i* anImplPtr = DownCast<SMESH_Mesh_i*>(theMesh);
438   return anImplPtr ? anImplPtr->GetImpl().GetMeshDS() : 0;
439 }
440
441 inline
442 SMESH::long_array*
443 toArray( const TColStd_ListOfInteger& aList )
444 {
445   SMESH::long_array_var anArray = new SMESH::long_array;
446   anArray->length( aList.Extent() );
447   TColStd_ListIteratorOfListOfInteger anIter( aList );
448   int i = 0;
449   for( ; anIter.More(); anIter.Next() )
450     anArray[ i++ ] = anIter.Value();
451
452   return anArray._retn();
453 }
454
455 inline
456 SMESH::double_array*
457 toArray( const TColStd_ListOfReal& aList )
458 {
459   SMESH::double_array_var anArray = new SMESH::double_array;
460   anArray->length( aList.Extent() );
461   TColStd_ListIteratorOfListOfReal anIter( aList );
462   int i = 0;
463   for( ; anIter.More(); anIter.Next() )
464     anArray[ i++ ] = anIter.Value();
465
466   return anArray._retn();
467 }
468
469 static SMESH::Filter::Criterion createCriterion()
470 {
471   SMESH::Filter::Criterion aCriterion;
472
473   aCriterion.Type          = FT_Undefined;
474   aCriterion.Compare       = FT_Undefined;
475   aCriterion.Threshold     = 0;
476   aCriterion.UnaryOp       = FT_Undefined;
477   aCriterion.BinaryOp      = FT_Undefined;
478   aCriterion.ThresholdStr  = "";
479   aCriterion.ThresholdID   = "";
480   aCriterion.Tolerance     = Precision::Confusion();
481   aCriterion.TypeOfElement = SMESH::ALL;
482   aCriterion.Precision     = -1;
483
484   return aCriterion;
485 }
486
487 static TopoDS_Shape getShapeByName( const char* theName )
488 {
489   if ( theName != 0 )
490   {
491     SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
492     SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
493     if (!CORBA::is_nil(aStudy))
494     {
495       SALOMEDS::Study::ListOfSObject_var aList =
496         aStudy->FindObjectByName( theName, "GEOM" );
497       if ( aList->length() > 0 )
498       {
499         GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( aList[ 0 ]->GetObject() );
500         if ( !aGeomObj->_is_nil() )
501         {
502           GEOM::GEOM_Gen_ptr aGEOMGen = SMESH_Gen_i::GetGeomEngine();
503           TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, aGeomObj );
504           return aLocShape;
505         }
506       }
507     }
508   }
509   return TopoDS_Shape();
510 }
511
512 static TopoDS_Shape getShapeByID (const char* theID)
513 {
514   if (theID != 0 && theID != "") {
515     SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
516     SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
517     if (aStudy != 0) {
518       SALOMEDS::SObject_var aSObj = aStudy->FindObjectID(theID);
519       SALOMEDS::GenericAttribute_var anAttr;
520       if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) {
521         SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
522         CORBA::String_var aVal = anIOR->Value();
523         CORBA::Object_var obj = aStudy->ConvertIORToObject(aVal);
524         GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(obj);
525       
526         if (!aGeomObj->_is_nil()) {
527           GEOM::GEOM_Gen_ptr aGEOMGen = SMESH_Gen_i::GetGeomEngine();
528           TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, aGeomObj );
529           return aLocShape;
530         }
531       }
532     }
533   }
534   return TopoDS_Shape();
535 }
536
537 static char* getShapeNameByID (const char* theID)
538 {
539   char* aName = (char*)"";
540
541   if (theID != 0 && theID != "") {
542     SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
543     SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
544     if (aStudy != 0) {
545       //SALOMEDS::SObject_var aSObj = aStudy->FindObjectIOR( theID );
546       SALOMEDS::SObject_var aSObj = aStudy->FindObjectID(theID);
547       SALOMEDS::GenericAttribute_var anAttr;
548       if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeName")) {
549         SALOMEDS::AttributeName_var aNameAttr = SALOMEDS::AttributeName::_narrow(anAttr);
550         aName = aNameAttr->Value();
551       }
552     }
553   }
554
555   return aName;
556 }
557
558 /*
559                                 FUNCTORS
560 */
561
562 /*
563   Class       : Functor_i
564   Description : An abstact class for all functors
565 */
566 Functor_i::Functor_i():
567   SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
568 {
569   //Base class Salome_GenericObject do it inmplicitly by overriding PortableServer::POA_ptr _default_POA() method  
570   //PortableServer::ObjectId_var anObjectId =
571   //  SMESH_Gen_i::GetPOA()->activate_object( this );
572 }
573
574 Functor_i::~Functor_i()
575 {
576   //TPythonDump()<<this<<".UnRegister()";
577 }
578
579 void Functor_i::SetMesh( SMESH_Mesh_ptr theMesh )
580 {
581   myFunctorPtr->SetMesh( MeshPtr2SMDSMesh( theMesh ) );
582   TPythonDump()<<this<<".SetMesh("<<theMesh<<")";
583 }
584
585 ElementType Functor_i::GetElementType()
586 {
587   return ( ElementType )myFunctorPtr->GetType();
588 }
589
590
591 /*
592   Class       : NumericalFunctor_i
593   Description : Base class for numerical functors
594 */
595 CORBA::Double NumericalFunctor_i::GetValue( CORBA::Long theId )
596 {
597   return myNumericalFunctorPtr->GetValue( theId );
598 }
599
600 SMESH::Histogram* NumericalFunctor_i::GetHistogram(CORBA::Short nbIntervals)
601 {
602   std::vector<int> nbEvents;
603   std::vector<double> funValues;
604   std::vector<int> elements;
605   myNumericalFunctorPtr->GetHistogram(nbIntervals,nbEvents,funValues,elements);
606
607   nbIntervals = CORBA::Short( std::min( nbEvents.size(), funValues.size() - 1));
608   SMESH::Histogram_var histogram = new SMESH::Histogram;
609   if ( nbIntervals > 0 )
610   {
611     histogram->length( nbIntervals );
612     for ( int i = 0; i < nbIntervals; ++i )
613     {
614       HistogramRectangle& rect = histogram[i];
615       rect.nbEvents = nbEvents[i];
616       rect.min = funValues[i];
617       rect.max = funValues[i+1];
618     }
619   }
620   return histogram._retn();
621 }
622
623 void NumericalFunctor_i::SetPrecision( CORBA::Long thePrecision )
624 {
625   myNumericalFunctorPtr->SetPrecision( thePrecision );
626   TPythonDump()<<this<<".SetPrecision("<<thePrecision<<")";
627 }
628
629 CORBA::Long NumericalFunctor_i::GetPrecision()
630 {
631  return myNumericalFunctorPtr->GetPrecision();
632 }
633
634 Controls::NumericalFunctorPtr NumericalFunctor_i::GetNumericalFunctor()
635 {
636   return myNumericalFunctorPtr;
637 }
638
639
640 /*
641   Class       : SMESH_MinimumAngle
642   Description : Functor for calculation of minimum angle
643 */
644 MinimumAngle_i::MinimumAngle_i()
645 {
646   myNumericalFunctorPtr.reset( new Controls::MinimumAngle() );
647   myFunctorPtr = myNumericalFunctorPtr;
648 }
649
650 FunctorType MinimumAngle_i::GetFunctorType()
651 {
652   return SMESH::FT_MinimumAngle;
653 }
654
655
656 /*
657   Class       : AspectRatio
658   Description : Functor for calculating aspect ratio
659 */
660 AspectRatio_i::AspectRatio_i()
661 {
662   myNumericalFunctorPtr.reset( new Controls::AspectRatio() );
663   myFunctorPtr = myNumericalFunctorPtr;
664 }
665
666 FunctorType AspectRatio_i::GetFunctorType()
667 {
668   return SMESH::FT_AspectRatio;
669 }
670
671
672 /*
673   Class       : AspectRatio3D
674   Description : Functor for calculating aspect ratio 3D
675 */
676 AspectRatio3D_i::AspectRatio3D_i()
677 {
678   myNumericalFunctorPtr.reset( new Controls::AspectRatio3D() );
679   myFunctorPtr = myNumericalFunctorPtr;
680 }
681
682 FunctorType AspectRatio3D_i::GetFunctorType()
683 {
684   return SMESH::FT_AspectRatio3D;
685 }
686
687
688 /*
689   Class       : Warping_i
690   Description : Functor for calculating warping
691 */
692 Warping_i::Warping_i()
693 {
694   myNumericalFunctorPtr.reset( new Controls::Warping() );
695   myFunctorPtr = myNumericalFunctorPtr;
696 }
697
698 FunctorType Warping_i::GetFunctorType()
699 {
700   return SMESH::FT_Warping;
701 }
702
703
704 /*
705   Class       : Taper_i
706   Description : Functor for calculating taper
707 */
708 Taper_i::Taper_i()
709 {
710   myNumericalFunctorPtr.reset( new Controls::Taper() );
711   myFunctorPtr = myNumericalFunctorPtr;
712 }
713
714 FunctorType Taper_i::GetFunctorType()
715 {
716   return SMESH::FT_Taper;
717 }
718
719
720 /*
721   Class       : Skew_i
722   Description : Functor for calculating skew in degrees
723 */
724 Skew_i::Skew_i()
725 {
726   myNumericalFunctorPtr.reset( new Controls::Skew() );
727   myFunctorPtr = myNumericalFunctorPtr;
728 }
729
730 FunctorType Skew_i::GetFunctorType()
731 {
732   return SMESH::FT_Skew;
733 }
734
735 /*
736   Class       : Area_i
737   Description : Functor for calculating area
738 */
739 Area_i::Area_i()
740 {
741   myNumericalFunctorPtr.reset( new Controls::Area() );
742   myFunctorPtr = myNumericalFunctorPtr;
743 }
744
745 FunctorType Area_i::GetFunctorType()
746 {
747   return SMESH::FT_Area;
748 }
749
750 /*
751   Class       : Volume3D_i
752   Description : Functor for calculating volume of 3D element
753 */
754 Volume3D_i::Volume3D_i()
755 {
756   myNumericalFunctorPtr.reset( new Controls::Volume() );
757   myFunctorPtr = myNumericalFunctorPtr;
758 }
759
760 FunctorType Volume3D_i::GetFunctorType()
761 {
762   return SMESH::FT_Volume3D;
763 }
764
765 /*
766   Class       : MaxElementLength2D_i
767   Description : Functor for calculating maximum length of 2D element
768 */
769 MaxElementLength2D_i::MaxElementLength2D_i()
770 {
771   myNumericalFunctorPtr.reset( new Controls::MaxElementLength2D() );
772   myFunctorPtr = myNumericalFunctorPtr;
773 }
774
775 FunctorType MaxElementLength2D_i::GetFunctorType()
776 {
777   return SMESH::FT_MaxElementLength2D;
778 }
779
780 /*
781   Class       : MaxElementLength3D_i
782   Description : Functor for calculating maximum length of 3D element
783 */
784 MaxElementLength3D_i::MaxElementLength3D_i()
785 {
786   myNumericalFunctorPtr.reset( new Controls::MaxElementLength3D() );
787   myFunctorPtr = myNumericalFunctorPtr;
788 }
789
790 FunctorType MaxElementLength3D_i::GetFunctorType()
791 {
792   return SMESH::FT_MaxElementLength3D;
793 }
794
795 /*
796   Class       : Length_i
797   Description : Functor for calculating length off edge
798 */
799 Length_i::Length_i()
800 {
801   myNumericalFunctorPtr.reset( new Controls::Length() );
802   myFunctorPtr = myNumericalFunctorPtr;
803 }
804
805 FunctorType Length_i::GetFunctorType()
806 {
807   return SMESH::FT_Length;
808 }
809
810 /*
811   Class       : Length2D_i
812   Description : Functor for calculating length of edge
813 */
814 Length2D_i::Length2D_i()
815 {
816   myNumericalFunctorPtr.reset( new Controls::Length2D() );
817   myFunctorPtr = myNumericalFunctorPtr;
818 }
819
820 FunctorType Length2D_i::GetFunctorType()
821 {
822   return SMESH::FT_Length2D;
823 }
824
825 SMESH::Length2D::Values* Length2D_i::GetValues()
826 {
827   INFOS("Length2D_i::GetValues");
828   SMESH::Controls::Length2D::TValues aValues;
829   (dynamic_cast<SMESH::Controls::Length2D*>(myFunctorPtr.get()))->GetValues( aValues );
830
831   long i = 0, iEnd = aValues.size();
832
833   SMESH::Length2D::Values_var aResult = new SMESH::Length2D::Values(iEnd);
834   aResult->length(iEnd);
835
836   SMESH::Controls::Length2D::TValues::const_iterator anIter;
837   for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ )
838   {
839     const SMESH::Controls::Length2D::Value&  aVal = *anIter;
840     SMESH::Length2D::Value &aValue = aResult[ i ];
841
842     aValue.myLength = aVal.myLength;
843     aValue.myPnt1 = aVal.myPntId[ 0 ];
844     aValue.myPnt2 = aVal.myPntId[ 1 ];
845   }
846
847   INFOS("Length2D_i::GetValuess~");
848   return aResult._retn();
849 }
850
851 /*
852   Class       : MultiConnection_i
853   Description : Functor for calculating number of faces conneted to the edge
854 */
855 MultiConnection_i::MultiConnection_i()
856 {
857   myNumericalFunctorPtr.reset( new Controls::MultiConnection() );
858   myFunctorPtr = myNumericalFunctorPtr;
859 }
860
861 FunctorType MultiConnection_i::GetFunctorType()
862 {
863   return SMESH::FT_MultiConnection;
864 }
865
866 /*
867   Class       : MultiConnection2D_i
868   Description : Functor for calculating number of faces conneted to the edge
869 */
870 MultiConnection2D_i::MultiConnection2D_i()
871 {
872   myNumericalFunctorPtr.reset( new Controls::MultiConnection2D() );
873   myFunctorPtr = myNumericalFunctorPtr;
874 }
875
876 FunctorType MultiConnection2D_i::GetFunctorType()
877 {
878   return SMESH::FT_MultiConnection2D;
879 }
880
881 SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues()
882 {
883   INFOS("MultiConnection2D_i::GetValues");
884   SMESH::Controls::MultiConnection2D::MValues aValues;
885   (dynamic_cast<SMESH::Controls::MultiConnection2D*>(myFunctorPtr.get()))->GetValues( aValues );
886   
887   long i = 0, iEnd = aValues.size();
888
889   SMESH::MultiConnection2D::Values_var aResult = new SMESH::MultiConnection2D::Values(iEnd);
890   aResult->length(iEnd);
891
892   SMESH::Controls::MultiConnection2D::MValues::const_iterator anIter;
893   for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ )
894   {
895     const SMESH::Controls::MultiConnection2D::Value&  aVal = (*anIter).first;
896     SMESH::MultiConnection2D::Value &aValue = aResult[ i ];
897
898     aValue.myPnt1 = aVal.myPntId[ 0 ];
899     aValue.myPnt2 = aVal.myPntId[ 1 ];
900     aValue.myNbConnects = (*anIter).second;
901   }
902
903   INFOS("Multiconnection2D_i::GetValuess~");
904   return aResult._retn();
905 }
906
907 /*
908                             PREDICATES
909 */
910
911
912 /*
913   Class       : Predicate_i
914   Description : Base class for all predicates
915 */
916 CORBA::Boolean Predicate_i::IsSatisfy( CORBA::Long theId )
917 {
918   return myPredicatePtr->IsSatisfy( theId );
919 }
920
921 Controls::PredicatePtr Predicate_i::GetPredicate()
922 {
923   return myPredicatePtr;
924 }
925
926 /*
927   Class       : BadOrientedVolume_i
928   Description : Verify whether a mesh volume is incorrectly oriented from
929                 the point of view of MED convention
930 */
931 BadOrientedVolume_i::BadOrientedVolume_i()
932 {
933   Controls::PredicatePtr control( new Controls::BadOrientedVolume() );
934   myFunctorPtr = myPredicatePtr = control;
935 };
936
937 FunctorType BadOrientedVolume_i::GetFunctorType()
938 {
939   return SMESH::FT_BadOrientedVolume;
940 }
941
942 /*
943   Class       : BareBorderVolume_i
944   Description : Verify whether a mesh volume has a free facet without a face on it
945 */
946 BareBorderVolume_i::BareBorderVolume_i()
947 {
948   Controls::PredicatePtr control( new Controls::BareBorderVolume() );
949   myFunctorPtr = myPredicatePtr = control;
950 };
951
952 FunctorType BareBorderVolume_i::GetFunctorType()
953 {
954   return SMESH::FT_BareBorderVolume;
955 }
956
957 /*
958   Class       : BareBorderFace_i
959   Description : Verify whether a mesh face has a free border without an edge on it
960 */
961 BareBorderFace_i::BareBorderFace_i()
962 {
963   Controls::PredicatePtr control( new Controls::BareBorderFace() );
964   myFunctorPtr = myPredicatePtr = control;
965 };
966
967 FunctorType BareBorderFace_i::GetFunctorType()
968 {
969   return SMESH::FT_BareBorderFace;
970 }
971
972 /*
973   Class       : OverConstrainedVolume_i
974   Description : Verify whether a mesh volume has only one facet shared with other volumes
975 */
976 OverConstrainedVolume_i::OverConstrainedVolume_i()
977 {
978   Controls::PredicatePtr control( new Controls::OverConstrainedVolume() );
979   myFunctorPtr = myPredicatePtr = control;
980 };
981
982 FunctorType OverConstrainedVolume_i::GetFunctorType()
983 {
984   return SMESH::FT_OverConstrainedVolume;
985 }
986
987 /*
988   Class       : OverConstrainedFace_i
989   Description : Verify whether a mesh face has only one border shared with other faces
990 */
991 OverConstrainedFace_i::OverConstrainedFace_i()
992 {
993   Controls::PredicatePtr control( new Controls::OverConstrainedFace() );
994   myFunctorPtr = myPredicatePtr = control;
995 };
996
997 FunctorType OverConstrainedFace_i::GetFunctorType()
998 {
999   return SMESH::FT_OverConstrainedFace;
1000 }
1001
1002 /*
1003   Class       : BelongToGeom_i
1004   Description : Predicate for selection on geometrical support
1005 */
1006 BelongToGeom_i::BelongToGeom_i()
1007 {
1008   myBelongToGeomPtr.reset( new Controls::BelongToGeom() );
1009   myFunctorPtr = myPredicatePtr = myBelongToGeomPtr;
1010   myShapeName = 0;
1011   myShapeID   = 0;
1012 }
1013
1014 BelongToGeom_i::~BelongToGeom_i()
1015 {
1016   delete myShapeName;
1017   delete myShapeID;
1018 }
1019
1020 void BelongToGeom_i::SetGeom( GEOM::GEOM_Object_ptr theGeom )
1021 {
1022   if ( theGeom->_is_nil() )
1023     return;
1024   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1025   GEOM::GEOM_Gen_ptr aGEOMGen = SMESH_Gen_i::GetGeomEngine();
1026   TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, theGeom );
1027   myBelongToGeomPtr->SetGeom( aLocShape );
1028   TPythonDump()<<this<<".SetGeom("<<theGeom<<")";
1029 }
1030
1031 void BelongToGeom_i::SetGeom( const TopoDS_Shape& theShape )
1032 {
1033   myBelongToGeomPtr->SetGeom( theShape );
1034 }
1035
1036 void BelongToGeom_i::SetElementType(ElementType theType){
1037   myBelongToGeomPtr->SetType(SMDSAbs_ElementType(theType));
1038   TPythonDump()<<this<<".SetElementType("<<theType<<")";
1039 }
1040
1041 FunctorType BelongToGeom_i::GetFunctorType()
1042 {
1043   return SMESH::FT_BelongToGeom;
1044 }
1045
1046 void BelongToGeom_i::SetShapeName( const char* theName )
1047 {
1048   delete myShapeName;
1049   myShapeName = strdup( theName );
1050   myBelongToGeomPtr->SetGeom( getShapeByName( myShapeName ) );
1051   TPythonDump()<<this<<".SetShapeName('"<<theName<<"')";
1052 }
1053
1054 void BelongToGeom_i::SetShape( const char* theID, const char* theName )
1055 {
1056   delete myShapeName;
1057   myShapeName = strdup( theName );
1058   delete myShapeID;
1059   if ( theID )
1060     myShapeID = strdup( theID );
1061   else
1062     myShapeID = 0;
1063
1064   if ( myShapeID && strcmp(myShapeName, getShapeNameByID(myShapeID)) == 0 )
1065     myBelongToGeomPtr->SetGeom( getShapeByID(myShapeID) );
1066   else
1067     myBelongToGeomPtr->SetGeom( getShapeByName( myShapeName ) );
1068 }
1069
1070 char* BelongToGeom_i::GetShapeName()
1071 {
1072   return CORBA::string_dup( myShapeName );
1073 }
1074
1075 char* BelongToGeom_i::GetShapeID()
1076 {
1077   return CORBA::string_dup( myShapeID );
1078 }
1079
1080 void BelongToGeom_i::SetTolerance( CORBA::Double theToler )
1081 {
1082   myBelongToGeomPtr->SetTolerance( theToler );
1083   TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
1084 }
1085
1086 CORBA::Double BelongToGeom_i::GetTolerance()
1087 {
1088   return myBelongToGeomPtr->GetTolerance();
1089 }
1090
1091 /*
1092   Class       : BelongToSurface_i
1093   Description : Predicate for selection on geometrical support
1094 */
1095 BelongToSurface_i::BelongToSurface_i( const Handle(Standard_Type)& theSurfaceType )
1096 {
1097   myElementsOnSurfacePtr.reset( new Controls::ElementsOnSurface() );
1098   myFunctorPtr = myPredicatePtr = myElementsOnSurfacePtr;
1099   myShapeName = 0;
1100   myShapeID   = 0;
1101   mySurfaceType = theSurfaceType;
1102 }
1103
1104 BelongToSurface_i::~BelongToSurface_i()
1105 {
1106   delete myShapeName;
1107   delete myShapeID;
1108 }
1109
1110 void BelongToSurface_i::SetSurface( GEOM::GEOM_Object_ptr theGeom, ElementType theType )
1111 {
1112   if ( theGeom->_is_nil() )
1113     return;
1114   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1115   GEOM::GEOM_Gen_ptr aGEOMGen = SMESH_Gen_i::GetGeomEngine();
1116   TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, theGeom );
1117
1118   if ( aLocShape.ShapeType() == TopAbs_FACE )
1119   {
1120     Handle(Geom_Surface) aSurf = BRep_Tool::Surface( TopoDS::Face( aLocShape ) );
1121     if ( !aSurf.IsNull() && aSurf->DynamicType() == mySurfaceType )
1122     {
1123       myElementsOnSurfacePtr->SetSurface( aLocShape, (SMDSAbs_ElementType)theType );
1124       return;
1125     }
1126   }
1127
1128   myElementsOnSurfacePtr->SetSurface( TopoDS_Shape(), (SMDSAbs_ElementType)theType );
1129 }
1130
1131 void BelongToSurface_i::SetShapeName( const char* theName, ElementType theType )
1132 {
1133   delete myShapeName;
1134   myShapeName = strdup( theName );
1135   myElementsOnSurfacePtr->SetSurface( getShapeByName( myShapeName ), (SMDSAbs_ElementType)theType );
1136   TPythonDump()<<this<<".SetShapeName('"<<theName<<"',"<<theType<<")";
1137 }
1138
1139 void BelongToSurface_i::SetShape( const char* theID,  const char* theName, ElementType theType )
1140 {
1141   delete myShapeName;
1142   myShapeName = strdup( theName );
1143   delete myShapeID;
1144   if ( theID )
1145     myShapeID = strdup( theID );
1146   else
1147     myShapeID = 0;
1148   
1149   if ( myShapeID && strcmp(myShapeName, getShapeNameByID(myShapeID)) == 0 )
1150     myElementsOnSurfacePtr->SetSurface( getShapeByID(myShapeID), (SMDSAbs_ElementType)theType );
1151   else
1152     myElementsOnSurfacePtr->SetSurface( getShapeByName( myShapeName ), (SMDSAbs_ElementType)theType );
1153 }
1154
1155 char* BelongToSurface_i::GetShapeName()
1156 {
1157   return CORBA::string_dup( myShapeName );
1158 }
1159
1160 char* BelongToSurface_i::GetShapeID()
1161 {
1162   return CORBA::string_dup( myShapeID );
1163 }
1164
1165 void BelongToSurface_i::SetTolerance( CORBA::Double theToler )
1166 {
1167   myElementsOnSurfacePtr->SetTolerance( theToler );
1168   TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
1169 }
1170
1171 CORBA::Double BelongToSurface_i::GetTolerance()
1172 {
1173   return myElementsOnSurfacePtr->GetTolerance();
1174 }
1175
1176 void BelongToSurface_i::SetUseBoundaries( CORBA::Boolean theUseBndRestrictions )
1177 {
1178   myElementsOnSurfacePtr->SetUseBoundaries( theUseBndRestrictions );
1179   TPythonDump()<<this<<".SetUseBoundaries( " << theUseBndRestrictions << " )";
1180 }
1181
1182 CORBA::Boolean BelongToSurface_i::GetUseBoundaries()
1183 {
1184   return myElementsOnSurfacePtr->GetUseBoundaries();
1185 }
1186
1187
1188 /*
1189   Class       : BelongToPlane_i
1190   Description : Verify whether mesh element lie in pointed Geom planar object
1191 */
1192
1193 BelongToPlane_i::BelongToPlane_i()
1194 : BelongToSurface_i( STANDARD_TYPE( Geom_Plane ) )
1195 {
1196 }
1197
1198 void BelongToPlane_i::SetPlane( GEOM::GEOM_Object_ptr theGeom, ElementType theType )
1199 {
1200   BelongToSurface_i::SetSurface( theGeom, theType );
1201   TPythonDump()<<this<<".SetPlane("<<theGeom<<","<<theType<<")";
1202 }
1203
1204 FunctorType BelongToPlane_i::GetFunctorType()
1205 {
1206   return FT_BelongToPlane;
1207 }
1208
1209 /*
1210   Class       : BelongToCylinder_i
1211   Description : Verify whether mesh element lie in pointed Geom planar object
1212 */
1213
1214 BelongToCylinder_i::BelongToCylinder_i()
1215 : BelongToSurface_i( STANDARD_TYPE( Geom_CylindricalSurface ) )
1216 {
1217 }
1218
1219 void BelongToCylinder_i::SetCylinder( GEOM::GEOM_Object_ptr theGeom, ElementType theType )
1220 {
1221   BelongToSurface_i::SetSurface( theGeom, theType );
1222   TPythonDump()<<this<<".SetCylinder("<<theGeom<<","<<theType<<")";
1223 }
1224
1225 FunctorType BelongToCylinder_i::GetFunctorType()
1226 {
1227   return FT_BelongToCylinder;
1228 }
1229
1230 /*
1231   Class       : BelongToGenSurface_i
1232   Description : Verify whether mesh element lie in pointed Geom planar object
1233 */
1234
1235 BelongToGenSurface_i::BelongToGenSurface_i()
1236 : BelongToSurface_i( STANDARD_TYPE( Geom_CylindricalSurface ) )
1237 {
1238 }
1239
1240 void BelongToGenSurface_i::SetSurface( GEOM::GEOM_Object_ptr theGeom, ElementType theType )
1241 {
1242   if ( theGeom->_is_nil() )
1243     return;
1244   TopoDS_Shape aLocShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theGeom );
1245   if ( !aLocShape.IsNull() && aLocShape.ShapeType() != TopAbs_FACE )
1246     aLocShape.Nullify();
1247   
1248   BelongToSurface_i::myElementsOnSurfacePtr->SetSurface( aLocShape, (SMDSAbs_ElementType)theType );
1249   TPythonDump()<<this<<".SetGenSurface("<<theGeom<<","<<theType<<")";
1250 }
1251
1252 FunctorType BelongToGenSurface_i::GetFunctorType()
1253 {
1254   return FT_BelongToGenSurface;
1255 }
1256
1257 /*
1258   Class       : LyingOnGeom_i
1259   Description : Predicate for selection on geometrical support
1260 */
1261 LyingOnGeom_i::LyingOnGeom_i()
1262 {
1263   myLyingOnGeomPtr.reset( new Controls::LyingOnGeom() );
1264   myFunctorPtr = myPredicatePtr = myLyingOnGeomPtr;
1265   myShapeName = 0;
1266   myShapeID = 0;
1267 }
1268
1269 LyingOnGeom_i::~LyingOnGeom_i()
1270 {
1271   delete myShapeName;
1272   delete myShapeID;
1273 }
1274
1275 void LyingOnGeom_i::SetGeom( GEOM::GEOM_Object_ptr theGeom )
1276 {
1277   if ( theGeom->_is_nil() )
1278     return;
1279   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
1280   GEOM::GEOM_Gen_ptr aGEOMGen = SMESH_Gen_i::GetGeomEngine();
1281   TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, theGeom );
1282   myLyingOnGeomPtr->SetGeom( aLocShape );
1283   TPythonDump()<<this<<".SetGeom("<<theGeom<<")";
1284 }
1285
1286 void LyingOnGeom_i::SetGeom( const TopoDS_Shape& theShape )
1287 {
1288   myLyingOnGeomPtr->SetGeom( theShape );
1289 }
1290
1291 void LyingOnGeom_i::SetElementType(ElementType theType){
1292   myLyingOnGeomPtr->SetType(SMDSAbs_ElementType(theType));
1293   TPythonDump()<<this<<".SetElementType("<<theType<<")";
1294 }
1295
1296 FunctorType LyingOnGeom_i::GetFunctorType()
1297 {
1298   return SMESH::FT_LyingOnGeom;
1299 }
1300
1301 void LyingOnGeom_i::SetShapeName( const char* theName )
1302 {
1303   delete myShapeName;
1304   myShapeName = strdup( theName );
1305   myLyingOnGeomPtr->SetGeom( getShapeByName( myShapeName ) );
1306   TPythonDump()<<this<<".SetShapeName('"<<theName<<"')";
1307 }
1308
1309 void LyingOnGeom_i::SetShape( const char* theID, const char* theName )
1310 {
1311   delete myShapeName;
1312   myShapeName = strdup( theName );
1313   delete myShapeID;
1314   if ( theID )
1315     myShapeID = strdup( theID );
1316   else
1317     myShapeID = 0;
1318   
1319   if ( myShapeID && strcmp(myShapeName, getShapeNameByID(myShapeID)) == 0 )
1320     myLyingOnGeomPtr->SetGeom( getShapeByID(myShapeID) );
1321   else
1322     myLyingOnGeomPtr->SetGeom( getShapeByName( myShapeName ) );
1323 }
1324
1325 char* LyingOnGeom_i::GetShapeName()
1326 {
1327   return CORBA::string_dup( myShapeName );
1328 }
1329
1330 char* LyingOnGeom_i::GetShapeID()
1331 {
1332   return CORBA::string_dup( myShapeID );
1333 }
1334
1335 void LyingOnGeom_i::SetTolerance( CORBA::Double theToler )
1336 {
1337   myLyingOnGeomPtr->SetTolerance( theToler );
1338   TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
1339 }
1340
1341 CORBA::Double LyingOnGeom_i::GetTolerance()
1342 {
1343   return myLyingOnGeomPtr->GetTolerance();
1344 }
1345
1346 /*
1347   Class       : FreeBorders_i
1348   Description : Predicate for free borders
1349 */
1350 FreeBorders_i::FreeBorders_i()
1351 {
1352   myPredicatePtr.reset(new Controls::FreeBorders());
1353   myFunctorPtr = myPredicatePtr;
1354 }
1355
1356 FunctorType FreeBorders_i::GetFunctorType()
1357 {
1358   return SMESH::FT_FreeBorders;
1359 }
1360
1361 /*
1362   Class       : FreeEdges_i
1363   Description : Predicate for free borders
1364 */
1365 FreeEdges_i::FreeEdges_i()
1366 : myFreeEdgesPtr( new Controls::FreeEdges() )
1367 {
1368   myFunctorPtr = myPredicatePtr = myFreeEdgesPtr;
1369 }
1370
1371 SMESH::FreeEdges::Borders* FreeEdges_i::GetBorders()
1372 {
1373   INFOS("FreeEdges_i::GetBorders");
1374   SMESH::Controls::FreeEdges::TBorders aBorders;
1375   myFreeEdgesPtr->GetBoreders( aBorders );
1376
1377   long i = 0, iEnd = aBorders.size();
1378
1379   SMESH::FreeEdges::Borders_var aResult = new SMESH::FreeEdges::Borders;
1380   aResult->length(iEnd);
1381
1382   SMESH::Controls::FreeEdges::TBorders::const_iterator anIter;
1383   for ( anIter = aBorders.begin() ; anIter != aBorders.end(); anIter++, i++ )
1384   {
1385     const SMESH::Controls::FreeEdges::Border&  aBord = *anIter;
1386     SMESH::FreeEdges::Border &aBorder = aResult[ i ];
1387
1388     aBorder.myElemId = aBord.myElemId;
1389     aBorder.myPnt1 = aBord.myPntId[ 0 ];
1390     aBorder.myPnt2 = aBord.myPntId[ 1 ];
1391   }
1392
1393   INFOS("FreeEdges_i::GetBorders~");
1394   return aResult._retn();
1395 }
1396
1397 FunctorType FreeEdges_i::GetFunctorType()
1398 {
1399   return SMESH::FT_FreeEdges;
1400 }
1401
1402 /*
1403   Class       : FreeFaces_i
1404   Description : Predicate for free faces
1405 */
1406 FreeFaces_i::FreeFaces_i()
1407 {
1408   myPredicatePtr.reset(new Controls::FreeFaces());
1409   myFunctorPtr = myPredicatePtr;
1410 }
1411
1412 FunctorType FreeFaces_i::GetFunctorType()
1413 {
1414   return SMESH::FT_FreeFaces;
1415 }
1416
1417 /*
1418   Class       : FreeNodes_i
1419   Description : Predicate for free nodes
1420 */
1421 FreeNodes_i::FreeNodes_i()
1422 {
1423   myPredicatePtr.reset(new Controls::FreeNodes());
1424   myFunctorPtr = myPredicatePtr;
1425 }
1426
1427 FunctorType FreeNodes_i::GetFunctorType()
1428 {
1429   return SMESH::FT_FreeNodes;
1430 }
1431
1432 /*
1433   Class       : RangeOfIds_i
1434   Description : Predicate for Range of Ids.
1435                 Range may be specified with two ways.
1436                 1. Using AddToRange method
1437                 2. With SetRangeStr method. Parameter of this method is a string
1438                    like as "1,2,3,50-60,63,67,70-"
1439 */
1440
1441 RangeOfIds_i::RangeOfIds_i()
1442 {
1443   myRangeOfIdsPtr.reset( new Controls::RangeOfIds() );
1444   myFunctorPtr = myPredicatePtr = myRangeOfIdsPtr;
1445 }
1446
1447 void RangeOfIds_i::SetRange( const SMESH::long_array& theIds )
1448 {
1449   CORBA::Long iEnd = theIds.length();
1450   for ( CORBA::Long i = 0; i < iEnd; i++ )
1451     myRangeOfIdsPtr->AddToRange( theIds[ i ] );
1452   TPythonDump()<<this<<".SetRange("<<theIds<<")";
1453 }
1454
1455 CORBA::Boolean RangeOfIds_i::SetRangeStr( const char* theRange )
1456 {
1457   TPythonDump()<<this<<".SetRangeStr('"<<theRange<<"')";
1458   return myRangeOfIdsPtr->SetRangeStr(
1459     TCollection_AsciiString( (Standard_CString)theRange ) );
1460 }
1461
1462 char* RangeOfIds_i::GetRangeStr()
1463 {
1464   TCollection_AsciiString aStr;
1465   myRangeOfIdsPtr->GetRangeStr( aStr );
1466   return CORBA::string_dup( aStr.ToCString() );
1467 }
1468
1469 void RangeOfIds_i::SetElementType( ElementType theType )
1470 {
1471   myRangeOfIdsPtr->SetType( SMDSAbs_ElementType( theType ) );
1472   TPythonDump()<<this<<".SetElementType("<<theType<<")";
1473 }
1474
1475 FunctorType RangeOfIds_i::GetFunctorType()
1476 {
1477   return SMESH::FT_RangeOfIds;
1478 }
1479
1480 /*
1481   Class       : LinearOrQuadratic_i
1482   Description : Predicate to verify whether a mesh element is linear
1483 */
1484 LinearOrQuadratic_i::LinearOrQuadratic_i()
1485 {
1486   myLinearOrQuadraticPtr.reset(new Controls::LinearOrQuadratic());
1487   myFunctorPtr = myPredicatePtr = myLinearOrQuadraticPtr;
1488 }
1489
1490 void LinearOrQuadratic_i::SetElementType(ElementType theType)
1491 {
1492   myLinearOrQuadraticPtr->SetType(SMDSAbs_ElementType(theType));
1493   TPythonDump()<<this<<".SetElementType("<<theType<<")";
1494 }
1495
1496 FunctorType LinearOrQuadratic_i::GetFunctorType()
1497 {
1498   return SMESH::FT_LinearOrQuadratic;
1499 }
1500
1501 /*
1502   Class       : GroupColor_i
1503   Description : Functor for check color of group to whic mesh element belongs to
1504 */
1505 GroupColor_i::GroupColor_i()
1506 {
1507   myGroupColorPtr.reset(new Controls::GroupColor());
1508   myFunctorPtr = myPredicatePtr = myGroupColorPtr;
1509 }
1510
1511 FunctorType GroupColor_i::GetFunctorType()
1512 {
1513   return SMESH::FT_GroupColor;
1514 }
1515
1516 void GroupColor_i::SetColorStr( const char* theColor )
1517 {
1518   myGroupColorPtr->SetColorStr(
1519     TCollection_AsciiString( (Standard_CString)theColor ) );
1520   TPythonDump()<<this<<".SetColorStr('"<<theColor<<"')";
1521 }
1522
1523 char* GroupColor_i::GetColorStr()
1524 {
1525   TCollection_AsciiString aStr;
1526   myGroupColorPtr->GetColorStr( aStr );
1527   return CORBA::string_dup( aStr.ToCString() );
1528 }
1529
1530 void GroupColor_i::SetElementType(ElementType theType)
1531 {
1532   myGroupColorPtr->SetType(SMDSAbs_ElementType(theType));
1533   TPythonDump()<<this<<".SetElementType("<<theType<<")";
1534 }
1535
1536 /*
1537   Class       : ElemGeomType_i
1538   Description : Predicate check is element has indicated geometry type
1539 */
1540 ElemGeomType_i::ElemGeomType_i()
1541 {
1542   myElemGeomTypePtr.reset(new Controls::ElemGeomType());
1543   myFunctorPtr = myPredicatePtr = myElemGeomTypePtr;
1544 }
1545
1546 void ElemGeomType_i::SetElementType(ElementType theType)
1547 {
1548   myElemGeomTypePtr->SetType(SMDSAbs_ElementType(theType));
1549   TPythonDump()<<this<<".SetElementType("<<theType<<")";
1550 }
1551
1552 void ElemGeomType_i::SetGeometryType(GeometryType theType)
1553 {
1554   myElemGeomTypePtr->SetGeomType(SMDSAbs_GeometryType(theType));
1555   TPythonDump()<<this<<".SetGeometryType("<<theType<<")";
1556 }
1557
1558 GeometryType ElemGeomType_i::GetGeometryType() const
1559 {
1560   return (GeometryType)myElemGeomTypePtr->GetGeomType();
1561 }
1562
1563 FunctorType ElemGeomType_i::GetFunctorType()
1564 {
1565   return SMESH::FT_ElemGeomType;
1566 }
1567
1568 /*
1569   Class       : CoplanarFaces_i
1570   Description : Returns true if a mesh face is a coplanar neighbour to a given one
1571 */
1572 CoplanarFaces_i::CoplanarFaces_i()
1573 {
1574   myCoplanarFacesPtr.reset(new Controls::CoplanarFaces());
1575   myFunctorPtr = myPredicatePtr = myCoplanarFacesPtr;
1576 }
1577
1578 void CoplanarFaces_i::SetFace ( CORBA::Long theFaceID )
1579 {
1580   myCoplanarFacesPtr->SetFace(theFaceID);
1581   TPythonDump()<<this<<".SetFace("<<theFaceID<<")";
1582 }
1583
1584 void CoplanarFaces_i::SetTolerance( CORBA::Double theToler )
1585 {
1586   myCoplanarFacesPtr->SetTolerance(theToler);
1587   TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
1588 }
1589
1590 CORBA::Long CoplanarFaces_i::GetFace () const
1591 {
1592   return myCoplanarFacesPtr->GetFace();
1593 }
1594
1595 char* CoplanarFaces_i::GetFaceAsString () const
1596 {
1597   TCollection_AsciiString str(Standard_Integer(myCoplanarFacesPtr->GetFace()));
1598   return CORBA::string_dup( str.ToCString() );
1599 }
1600
1601 CORBA::Double CoplanarFaces_i::GetTolerance() const
1602 {
1603   return myCoplanarFacesPtr->GetTolerance();
1604 }
1605
1606 FunctorType CoplanarFaces_i::GetFunctorType()
1607 {
1608   return SMESH::FT_CoplanarFaces;
1609 }
1610
1611 /*
1612   Class       : Comparator_i
1613   Description : Base class for comparators
1614 */
1615 Comparator_i::Comparator_i():
1616   myNumericalFunctor( NULL )
1617 {}
1618
1619 Comparator_i::~Comparator_i()
1620 {
1621   if ( myNumericalFunctor )
1622     myNumericalFunctor->UnRegister();
1623 }
1624
1625 void Comparator_i::SetMargin( CORBA::Double theValue )
1626 {
1627   myComparatorPtr->SetMargin( theValue );
1628   TPythonDump()<<this<<".SetMargin("<<theValue<<")";
1629 }
1630
1631 CORBA::Double Comparator_i::GetMargin()
1632 {
1633   return myComparatorPtr->GetMargin();
1634 }
1635
1636 void Comparator_i::SetNumFunctor( NumericalFunctor_ptr theFunct )
1637 {
1638   if ( myNumericalFunctor )
1639     myNumericalFunctor->UnRegister();
1640
1641   myNumericalFunctor = DownCast<NumericalFunctor_i*>(theFunct);
1642
1643   if ( myNumericalFunctor )
1644   {
1645     myComparatorPtr->SetNumFunctor( myNumericalFunctor->GetNumericalFunctor() );
1646     myNumericalFunctor->Register();
1647     TPythonDump()<<this<<".SetNumFunctor("<<myNumericalFunctor<<")";
1648   }
1649 }
1650
1651 Controls::ComparatorPtr Comparator_i::GetComparator()
1652 {
1653   return myComparatorPtr;
1654 }
1655
1656 NumericalFunctor_i* Comparator_i::GetNumFunctor_i()
1657 {
1658   return myNumericalFunctor;
1659 }
1660
1661
1662 /*
1663   Class       : LessThan_i
1664   Description : Comparator "<"
1665 */
1666 LessThan_i::LessThan_i()
1667 {
1668   myComparatorPtr.reset( new Controls::LessThan() );
1669   myFunctorPtr = myPredicatePtr = myComparatorPtr;
1670 }
1671
1672 FunctorType LessThan_i::GetFunctorType()
1673 {
1674   return SMESH::FT_LessThan;
1675 }
1676
1677
1678 /*
1679   Class       : MoreThan_i
1680   Description : Comparator ">"
1681 */
1682 MoreThan_i::MoreThan_i()
1683 {
1684   myComparatorPtr.reset( new Controls::MoreThan() );
1685   myFunctorPtr = myPredicatePtr = myComparatorPtr;
1686 }
1687
1688 FunctorType MoreThan_i::GetFunctorType()
1689 {
1690   return SMESH::FT_MoreThan;
1691 }
1692
1693
1694 /*
1695   Class       : EqualTo_i
1696   Description : Comparator "="
1697 */
1698 EqualTo_i::EqualTo_i()
1699 : myEqualToPtr( new Controls::EqualTo() )
1700 {
1701   myFunctorPtr = myPredicatePtr = myComparatorPtr = myEqualToPtr;
1702 }
1703
1704 void EqualTo_i::SetTolerance( CORBA::Double theToler )
1705 {
1706   myEqualToPtr->SetTolerance( theToler );
1707   TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
1708 }
1709
1710 CORBA::Double EqualTo_i::GetTolerance()
1711 {
1712   return myEqualToPtr->GetTolerance();
1713 }
1714
1715 FunctorType EqualTo_i::GetFunctorType()
1716 {
1717   return SMESH::FT_EqualTo;
1718 }
1719
1720 /*
1721   Class       : LogicalNOT_i
1722   Description : Logical NOT predicate
1723 */
1724 LogicalNOT_i::LogicalNOT_i()
1725 : myPredicate( NULL ),
1726   myLogicalNOTPtr( new Controls::LogicalNOT() )
1727 {
1728   myFunctorPtr = myPredicatePtr = myLogicalNOTPtr;
1729 }
1730
1731 LogicalNOT_i::~LogicalNOT_i()
1732 {
1733   if ( myPredicate )
1734     myPredicate->UnRegister();
1735 }
1736
1737 void LogicalNOT_i::SetPredicate( Predicate_ptr thePredicate )
1738 {
1739   if ( myPredicate )
1740     myPredicate->UnRegister();
1741
1742   myPredicate = SMESH::GetPredicate(thePredicate);
1743
1744   if ( myPredicate ){
1745     myLogicalNOTPtr->SetPredicate(myPredicate->GetPredicate());
1746     myPredicate->Register();
1747     TPythonDump()<<this<<".SetPredicate("<<myPredicate<<")";
1748   }
1749 }
1750
1751 FunctorType LogicalNOT_i::GetFunctorType()
1752 {
1753   return SMESH::FT_LogicalNOT;
1754 }
1755
1756 Predicate_i* LogicalNOT_i::GetPredicate_i()
1757 {
1758   return myPredicate;
1759 }
1760
1761
1762 /*
1763   Class       : LogicalBinary_i
1764   Description : Base class for binary logical predicate
1765 */
1766 LogicalBinary_i::LogicalBinary_i()
1767 : myPredicate1( NULL ),
1768   myPredicate2( NULL )
1769 {}
1770
1771 LogicalBinary_i::~LogicalBinary_i()
1772 {
1773   if ( myPredicate1 )
1774     myPredicate1->UnRegister();
1775
1776   if ( myPredicate2 )
1777     myPredicate2->UnRegister();
1778 }
1779
1780 void LogicalBinary_i::SetMesh( SMESH_Mesh_ptr theMesh )
1781 {
1782   if ( myPredicate1 )
1783     myPredicate1->SetMesh( theMesh );
1784
1785   if ( myPredicate2 )
1786     myPredicate2->SetMesh( theMesh );
1787 }
1788
1789 void LogicalBinary_i::SetPredicate1( Predicate_ptr thePredicate )
1790 {
1791   if ( myPredicate1 )
1792     myPredicate1->UnRegister();
1793
1794   myPredicate1 = SMESH::GetPredicate(thePredicate);
1795
1796   if ( myPredicate1 ){
1797     myLogicalBinaryPtr->SetPredicate1(myPredicate1->GetPredicate());
1798     myPredicate1->Register();
1799     TPythonDump()<<this<<".SetPredicate1("<<myPredicate1<<")";
1800   }
1801 }
1802
1803 void LogicalBinary_i::SetPredicate2( Predicate_ptr thePredicate )
1804 {
1805   if ( myPredicate2 )
1806     myPredicate2->UnRegister();
1807
1808   myPredicate2 = SMESH::GetPredicate(thePredicate);
1809
1810   if ( myPredicate2 ){
1811     myLogicalBinaryPtr->SetPredicate2(myPredicate2->GetPredicate());
1812     myPredicate2->Register();
1813     TPythonDump()<<this<<".SetPredicate2("<<myPredicate2<<")";
1814   }
1815 }
1816
1817 Controls::LogicalBinaryPtr LogicalBinary_i::GetLogicalBinary()
1818 {
1819   return myLogicalBinaryPtr;
1820 }
1821
1822 Predicate_i* LogicalBinary_i::GetPredicate1_i()
1823 {
1824   return myPredicate1;
1825 }
1826 Predicate_i* LogicalBinary_i::GetPredicate2_i()
1827 {
1828   return myPredicate2;
1829 }
1830
1831
1832 /*
1833   Class       : LogicalAND_i
1834   Description : Logical AND
1835 */
1836 LogicalAND_i::LogicalAND_i()
1837 {
1838   myLogicalBinaryPtr.reset( new Controls::LogicalAND() );
1839   myFunctorPtr = myPredicatePtr = myLogicalBinaryPtr;
1840 }
1841
1842 FunctorType LogicalAND_i::GetFunctorType()
1843 {
1844   return SMESH::FT_LogicalAND;
1845 }
1846
1847
1848 /*
1849   Class       : LogicalOR_i
1850   Description : Logical OR
1851 */
1852 LogicalOR_i::LogicalOR_i()
1853 {
1854   myLogicalBinaryPtr.reset( new Controls::LogicalOR() );
1855   myFunctorPtr = myPredicatePtr = myLogicalBinaryPtr;
1856 }
1857
1858 FunctorType LogicalOR_i::GetFunctorType()
1859 {
1860   return SMESH::FT_LogicalOR;
1861 }
1862
1863
1864 /*
1865                             FILTER MANAGER
1866 */
1867
1868 FilterManager_i::FilterManager_i()
1869 : SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
1870 {
1871   //Base class Salome_GenericObject do it inmplicitly by overriding PortableServer::POA_ptr _default_POA() method
1872   //PortableServer::ObjectId_var anObjectId =
1873   //  SMESH_Gen_i::GetPOA()->activate_object( this );
1874 }
1875
1876
1877 FilterManager_i::~FilterManager_i()
1878 {
1879   //TPythonDump()<<this<<".UnRegister()";
1880 }
1881
1882
1883 MinimumAngle_ptr FilterManager_i::CreateMinimumAngle()
1884 {
1885   SMESH::MinimumAngle_i* aServant = new SMESH::MinimumAngle_i();
1886   SMESH::MinimumAngle_var anObj = aServant->_this();
1887   TPythonDump()<<aServant<<" = "<<this<<".CreateMinimumAngle()";
1888   return anObj._retn();
1889 }
1890
1891
1892 AspectRatio_ptr FilterManager_i::CreateAspectRatio()
1893 {
1894   SMESH::AspectRatio_i* aServant = new SMESH::AspectRatio_i();
1895   SMESH::AspectRatio_var anObj = aServant->_this();
1896   TPythonDump()<<aServant<<" = "<<this<<".CreateAspectRatio()";
1897   return anObj._retn();
1898 }
1899
1900
1901 AspectRatio3D_ptr FilterManager_i::CreateAspectRatio3D()
1902 {
1903   SMESH::AspectRatio3D_i* aServant = new SMESH::AspectRatio3D_i();
1904   SMESH::AspectRatio3D_var anObj = aServant->_this();
1905   TPythonDump()<<aServant<<" = "<<this<<".CreateAspectRatio3D()";
1906   return anObj._retn();
1907 }
1908
1909
1910 Warping_ptr FilterManager_i::CreateWarping()
1911 {
1912   SMESH::Warping_i* aServant = new SMESH::Warping_i();
1913   SMESH::Warping_var anObj = aServant->_this();
1914   TPythonDump()<<aServant<<" = "<<this<<".CreateWarping()";
1915   return anObj._retn();
1916 }
1917
1918
1919 Taper_ptr FilterManager_i::CreateTaper()
1920 {
1921   SMESH::Taper_i* aServant = new SMESH::Taper_i();
1922   SMESH::Taper_var anObj = aServant->_this();
1923   TPythonDump()<<aServant<<" = "<<this<<".CreateTaper()";
1924   return anObj._retn();
1925 }
1926
1927
1928 Skew_ptr FilterManager_i::CreateSkew()
1929 {
1930   SMESH::Skew_i* aServant = new SMESH::Skew_i();
1931   SMESH::Skew_var anObj = aServant->_this();
1932   TPythonDump()<<aServant<<" = "<<this<<".CreateSkew()";
1933   return anObj._retn();
1934 }
1935
1936
1937 Area_ptr FilterManager_i::CreateArea()
1938 {
1939   SMESH::Area_i* aServant = new SMESH::Area_i();
1940   SMESH::Area_var anObj = aServant->_this();
1941   TPythonDump()<<aServant<<" = "<<this<<".CreateArea()";
1942   return anObj._retn();
1943 }
1944
1945
1946 Volume3D_ptr FilterManager_i::CreateVolume3D()
1947 {
1948   SMESH::Volume3D_i* aServant = new SMESH::Volume3D_i();
1949   SMESH::Volume3D_var anObj = aServant->_this();
1950   TPythonDump()<<aServant<<" = "<<this<<".CreateVolume3D()";
1951   return anObj._retn();
1952 }
1953
1954
1955 MaxElementLength2D_ptr FilterManager_i::CreateMaxElementLength2D()
1956 {
1957   SMESH::MaxElementLength2D_i* aServant = new SMESH::MaxElementLength2D_i();
1958   SMESH::MaxElementLength2D_var anObj = aServant->_this();
1959   TPythonDump()<<aServant<<" = "<<this<<".CreateMaxElementLength2D()";
1960   return anObj._retn();
1961 }
1962
1963
1964 MaxElementLength3D_ptr FilterManager_i::CreateMaxElementLength3D()
1965 {
1966   SMESH::MaxElementLength3D_i* aServant = new SMESH::MaxElementLength3D_i();
1967   SMESH::MaxElementLength3D_var anObj = aServant->_this();
1968   TPythonDump()<<aServant<<" = "<<this<<".CreateMaxElementLength3D()";
1969   return anObj._retn();
1970 }
1971
1972
1973 Length_ptr FilterManager_i::CreateLength()
1974 {
1975   SMESH::Length_i* aServant = new SMESH::Length_i();
1976   SMESH::Length_var anObj = aServant->_this();
1977   TPythonDump()<<aServant<<" = "<<this<<".CreateLength()";
1978   return anObj._retn();
1979 }
1980
1981 Length2D_ptr FilterManager_i::CreateLength2D()
1982 {
1983   SMESH::Length2D_i* aServant = new SMESH::Length2D_i();
1984   SMESH::Length2D_var anObj = aServant->_this();
1985   TPythonDump()<<aServant<<" = "<<this<<".CreateLength2D()";
1986   return anObj._retn();
1987 }
1988
1989 MultiConnection_ptr FilterManager_i::CreateMultiConnection()
1990 {
1991   SMESH::MultiConnection_i* aServant = new SMESH::MultiConnection_i();
1992   SMESH::MultiConnection_var anObj = aServant->_this();
1993   TPythonDump()<<aServant<<" = "<<this<<".CreateMultiConnection()";
1994   return anObj._retn();
1995 }
1996
1997 MultiConnection2D_ptr FilterManager_i::CreateMultiConnection2D()
1998 {
1999   SMESH::MultiConnection2D_i* aServant = new SMESH::MultiConnection2D_i();
2000   SMESH::MultiConnection2D_var anObj = aServant->_this();
2001   TPythonDump()<<aServant<<" = "<<this<<".CreateMultiConnection2D()";
2002   return anObj._retn();
2003 }
2004
2005 BelongToGeom_ptr FilterManager_i::CreateBelongToGeom()
2006 {
2007   SMESH::BelongToGeom_i* aServant = new SMESH::BelongToGeom_i();
2008   SMESH::BelongToGeom_var anObj = aServant->_this();
2009   TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToGeom()";
2010   return anObj._retn();
2011 }
2012
2013 BelongToPlane_ptr FilterManager_i::CreateBelongToPlane()
2014 {
2015   SMESH::BelongToPlane_i* aServant = new SMESH::BelongToPlane_i();
2016   SMESH::BelongToPlane_var anObj = aServant->_this();
2017   TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToPlane()";
2018   return anObj._retn();
2019 }
2020
2021 BelongToCylinder_ptr FilterManager_i::CreateBelongToCylinder()
2022 {
2023   SMESH::BelongToCylinder_i* aServant = new SMESH::BelongToCylinder_i();
2024   SMESH::BelongToCylinder_var anObj = aServant->_this();
2025   TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToCylinder()";
2026   return anObj._retn();
2027 }
2028
2029 BelongToGenSurface_ptr FilterManager_i::CreateBelongToGenSurface()
2030 {
2031   SMESH::BelongToGenSurface_i* aServant = new SMESH::BelongToGenSurface_i();
2032   SMESH::BelongToGenSurface_var anObj = aServant->_this();
2033   TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToGenSurface()";
2034   return anObj._retn();
2035 }
2036
2037 LyingOnGeom_ptr FilterManager_i::CreateLyingOnGeom()
2038 {
2039   SMESH::LyingOnGeom_i* aServant = new SMESH::LyingOnGeom_i();
2040   SMESH::LyingOnGeom_var anObj = aServant->_this();
2041   TPythonDump()<<aServant<<" = "<<this<<".CreateLyingOnGeom()";
2042   return anObj._retn();
2043 }
2044
2045 CoplanarFaces_ptr FilterManager_i::CreateCoplanarFaces()
2046 {
2047   SMESH::CoplanarFaces_i* aServant = new SMESH::CoplanarFaces_i();
2048   SMESH::CoplanarFaces_var anObj = aServant->_this();
2049   TPythonDump()<<aServant<<" = "<<this<<".CreateCoplanarFaces()";
2050   return anObj._retn();
2051 }
2052
2053 FreeBorders_ptr FilterManager_i::CreateFreeBorders()
2054 {
2055   SMESH::FreeBorders_i* aServant = new SMESH::FreeBorders_i();
2056   SMESH::FreeBorders_var anObj = aServant->_this();
2057   TPythonDump()<<aServant<<" = "<<this<<".CreateFreeBorders()";
2058   return anObj._retn();
2059 }
2060
2061 FreeEdges_ptr FilterManager_i::CreateFreeEdges()
2062 {
2063   SMESH::FreeEdges_i* aServant = new SMESH::FreeEdges_i();
2064   SMESH::FreeEdges_var anObj = aServant->_this();
2065   TPythonDump()<<aServant<<" = "<<this<<".CreateFreeEdges()";
2066   return anObj._retn();
2067 }
2068
2069 FreeFaces_ptr FilterManager_i::CreateFreeFaces()
2070 {
2071   SMESH::FreeFaces_i* aServant = new SMESH::FreeFaces_i();
2072   SMESH::FreeFaces_var anObj = aServant->_this();
2073   TPythonDump()<<aServant<<" = "<<this<<".CreateFreeFaces()";
2074   return anObj._retn();
2075 }
2076
2077 FreeNodes_ptr FilterManager_i::CreateFreeNodes()
2078 {
2079   SMESH::FreeNodes_i* aServant = new SMESH::FreeNodes_i();
2080   SMESH::FreeNodes_var anObj = aServant->_this();
2081   TPythonDump()<<aServant<<" = "<<this<<".CreateFreeNodes()";
2082   return anObj._retn();
2083 }
2084
2085 RangeOfIds_ptr FilterManager_i::CreateRangeOfIds()
2086 {
2087   SMESH::RangeOfIds_i* aServant = new SMESH::RangeOfIds_i();
2088   SMESH::RangeOfIds_var anObj = aServant->_this();
2089   TPythonDump()<<aServant<<" = "<<this<<".CreateRangeOfIds()";
2090   return anObj._retn();
2091 }
2092
2093 BadOrientedVolume_ptr FilterManager_i::CreateBadOrientedVolume()
2094 {
2095   SMESH::BadOrientedVolume_i* aServant = new SMESH::BadOrientedVolume_i();
2096   SMESH::BadOrientedVolume_var anObj = aServant->_this();
2097   TPythonDump()<<aServant<<" = "<<this<<".CreateBadOrientedVolume()";
2098   return anObj._retn();
2099 }
2100
2101 BareBorderVolume_ptr FilterManager_i::CreateBareBorderVolume()
2102 {
2103   SMESH::BareBorderVolume_i* aServant = new SMESH::BareBorderVolume_i();
2104   SMESH::BareBorderVolume_var anObj = aServant->_this();
2105   TPythonDump()<<aServant<<" = "<<this<<".CreateBareBorderVolume()";
2106   return anObj._retn();
2107 }
2108
2109 BareBorderFace_ptr FilterManager_i::CreateBareBorderFace()
2110 {
2111   SMESH::BareBorderFace_i* aServant = new SMESH::BareBorderFace_i();
2112   SMESH::BareBorderFace_var anObj = aServant->_this();
2113   TPythonDump()<<aServant<<" = "<<this<<".CreateBareBorderFace()";
2114   return anObj._retn();
2115 }
2116
2117 OverConstrainedVolume_ptr FilterManager_i::CreateOverConstrainedVolume()
2118 {
2119   SMESH::OverConstrainedVolume_i* aServant = new SMESH::OverConstrainedVolume_i();
2120   SMESH::OverConstrainedVolume_var anObj = aServant->_this();
2121   TPythonDump()<<aServant<<" = "<<this<<".CreateOverConstrainedVolume()";
2122   return anObj._retn();
2123 }
2124
2125 OverConstrainedFace_ptr FilterManager_i::CreateOverConstrainedFace()
2126 {
2127   SMESH::OverConstrainedFace_i* aServant = new SMESH::OverConstrainedFace_i();
2128   SMESH::OverConstrainedFace_var anObj = aServant->_this();
2129   TPythonDump()<<aServant<<" = "<<this<<".CreateOverConstrainedFace()";
2130   return anObj._retn();
2131 }
2132
2133 LessThan_ptr FilterManager_i::CreateLessThan()
2134 {
2135   SMESH::LessThan_i* aServant = new SMESH::LessThan_i();
2136   SMESH::LessThan_var anObj = aServant->_this();
2137   TPythonDump()<<aServant<<" = "<<this<<".CreateLessThan()";
2138   return anObj._retn();
2139 }
2140
2141 MoreThan_ptr FilterManager_i::CreateMoreThan()
2142 {
2143   SMESH::MoreThan_i* aServant = new SMESH::MoreThan_i();
2144   SMESH::MoreThan_var anObj = aServant->_this();
2145   TPythonDump()<<aServant<<" = "<<this<<".CreateMoreThan()";
2146   return anObj._retn();
2147 }
2148
2149 EqualTo_ptr FilterManager_i::CreateEqualTo()
2150 {
2151   SMESH::EqualTo_i* aServant = new SMESH::EqualTo_i();
2152   SMESH::EqualTo_var anObj = aServant->_this();
2153   TPythonDump()<<aServant<<" = "<<this<<".CreateEqualTo()";
2154   return anObj._retn();
2155 }
2156
2157 LogicalNOT_ptr FilterManager_i::CreateLogicalNOT()
2158 {
2159   SMESH::LogicalNOT_i* aServant = new SMESH::LogicalNOT_i();
2160   SMESH::LogicalNOT_var anObj = aServant->_this();
2161   TPythonDump()<<aServant<<" = "<<this<<".CreateLogicalNOT()";
2162   return anObj._retn();
2163 }
2164
2165 LogicalAND_ptr FilterManager_i::CreateLogicalAND()
2166 {
2167   SMESH::LogicalAND_i* aServant = new SMESH::LogicalAND_i();
2168   SMESH::LogicalAND_var anObj = aServant->_this();
2169   TPythonDump()<<aServant<<" = "<<this<<".CreateLogicalAND()";
2170   return anObj._retn();
2171 }
2172
2173 LogicalOR_ptr FilterManager_i::CreateLogicalOR()
2174 {
2175   SMESH::LogicalOR_i* aServant = new SMESH::LogicalOR_i();
2176   SMESH::LogicalOR_var anObj = aServant->_this();
2177   TPythonDump()<<aServant<<" = "<<this<<".CreateLogicalOR()";
2178   return anObj._retn();
2179 }
2180
2181 LinearOrQuadratic_ptr FilterManager_i::CreateLinearOrQuadratic()
2182 {
2183   SMESH::LinearOrQuadratic_i* aServant = new SMESH::LinearOrQuadratic_i();
2184   SMESH::LinearOrQuadratic_var anObj = aServant->_this();
2185   TPythonDump()<<aServant<<" = "<<this<<".CreateLinearOrQuadratic()";
2186   return anObj._retn();
2187 }
2188
2189 GroupColor_ptr FilterManager_i::CreateGroupColor()
2190 {
2191   SMESH::GroupColor_i* aServant = new SMESH::GroupColor_i();
2192   SMESH::GroupColor_var anObj = aServant->_this();
2193   TPythonDump()<<aServant<<" = "<<this<<".CreateGroupColor()";
2194   return anObj._retn();
2195 }
2196
2197 ElemGeomType_ptr FilterManager_i::CreateElemGeomType()
2198 {
2199   SMESH::ElemGeomType_i* aServant = new SMESH::ElemGeomType_i();
2200   SMESH::ElemGeomType_var anObj = aServant->_this();
2201   TPythonDump()<<aServant<<" = "<<this<<".CreateElemGeomType()";
2202   return anObj._retn();
2203 }
2204
2205 Filter_ptr FilterManager_i::CreateFilter()
2206 {
2207   SMESH::Filter_i* aServant = new SMESH::Filter_i();
2208   SMESH::Filter_var anObj = aServant->_this();
2209   TPythonDump()<<aServant<<" = "<<this<<".CreateFilter()";
2210   return anObj._retn();
2211 }
2212
2213 FilterLibrary_ptr FilterManager_i::LoadLibrary( const char* aFileName )
2214 {
2215   SMESH::FilterLibrary_i* aServant = new SMESH::FilterLibrary_i( aFileName );
2216   SMESH::FilterLibrary_var anObj = aServant->_this();
2217   TPythonDump()<<aServant<<" = "<<this<<".LoadLibrary('"<<aFileName<<"')";
2218   return anObj._retn();
2219 }
2220
2221 FilterLibrary_ptr FilterManager_i::CreateLibrary()
2222 {
2223   SMESH::FilterLibrary_i* aServant = new SMESH::FilterLibrary_i();
2224   SMESH::FilterLibrary_var anObj = aServant->_this();
2225   TPythonDump()<<aServant<<" = "<<this<<".CreateLibrary()";
2226   return anObj._retn();
2227 }
2228
2229 CORBA::Boolean FilterManager_i::DeleteLibrary( const char* aFileName )
2230 {
2231   TPythonDump()<<this<<".DeleteLibrary("<<aFileName<<")";
2232   return remove( aFileName ) ? false : true;
2233 }
2234
2235 //=============================================================================
2236 /*!
2237  *  SMESH_Gen_i::CreateFilterManager
2238  *
2239  *  Create filter manager
2240  */
2241 //=============================================================================
2242
2243 SMESH::FilterManager_ptr SMESH_Gen_i::CreateFilterManager()
2244 {
2245   SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i();
2246   SMESH::FilterManager_var anObj = aFilter->_this();
2247   return anObj._retn();
2248 }
2249
2250
2251 /*
2252                               FILTER
2253 */
2254
2255 //=======================================================================
2256 // name    : Filter_i::Filter_i
2257 // Purpose : Constructor
2258 //=======================================================================
2259 Filter_i::Filter_i()
2260 : myPredicate( NULL )
2261 {}
2262
2263 //=======================================================================
2264 // name    : Filter_i::~Filter_i
2265 // Purpose : Destructor
2266 //=======================================================================
2267 Filter_i::~Filter_i()
2268 {
2269   if ( myPredicate )
2270     myPredicate->UnRegister();
2271
2272   if(!CORBA::is_nil(myMesh))
2273     myMesh->UnRegister();
2274
2275   //TPythonDump()<<this<<".UnRegister()";
2276 }
2277
2278 //=======================================================================
2279 // name    : Filter_i::SetPredicate
2280 // Purpose : Set predicate
2281 //=======================================================================
2282 void Filter_i::SetPredicate( Predicate_ptr thePredicate )
2283 {
2284   if ( myPredicate )
2285     myPredicate->UnRegister();
2286
2287   myPredicate = SMESH::GetPredicate(thePredicate);
2288
2289   if ( myPredicate )
2290   {
2291     myFilter.SetPredicate( myPredicate->GetPredicate() );
2292     myPredicate->Register();
2293     TPythonDump()<<this<<".SetPredicate("<<myPredicate<<")";
2294   }
2295 }
2296
2297 //=======================================================================
2298 // name    : Filter_i::GetElementType
2299 // Purpose : Get entity type
2300 //=======================================================================
2301 SMESH::ElementType Filter_i::GetElementType()
2302 {
2303   return myPredicate != 0 ? myPredicate->GetElementType() : SMESH::ALL;
2304 }
2305
2306 //=======================================================================
2307 // name    : Filter_i::SetMesh
2308 // Purpose : Set mesh
2309 //=======================================================================
2310 void
2311 Filter_i::
2312 SetMesh( SMESH_Mesh_ptr theMesh )
2313 {
2314   if(!CORBA::is_nil(theMesh))
2315     theMesh->Register();
2316
2317   if(!CORBA::is_nil(myMesh))
2318     myMesh->UnRegister();
2319
2320   myMesh = SMESH_Mesh::_duplicate( theMesh );
2321   TPythonDump()<<this<<".SetMesh("<<theMesh<<")";
2322 }
2323
2324 SMESH::long_array*
2325 Filter_i::
2326 GetIDs()
2327 {
2328   return GetElementsId(myMesh);
2329 }
2330
2331 //=======================================================================
2332 // name    : Filter_i::GetElementsId
2333 // Purpose : Get ids of entities
2334 //=======================================================================
2335 void
2336 Filter_i::
2337 GetElementsId( Predicate_i* thePredicate,
2338                const SMDS_Mesh* theMesh,
2339                Controls::Filter::TIdSequence& theSequence )
2340 {
2341   if (thePredicate)
2342     Controls::Filter::GetElementsId(theMesh,thePredicate->GetPredicate(),theSequence);
2343 }
2344
2345 void
2346 Filter_i::
2347 GetElementsId( Predicate_i* thePredicate,
2348                SMESH_Mesh_ptr theMesh,
2349                Controls::Filter::TIdSequence& theSequence )
2350 {
2351   if (thePredicate) 
2352     if(const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(theMesh))
2353       Controls::Filter::GetElementsId(aMesh,thePredicate->GetPredicate(),theSequence);
2354 }
2355
2356 SMESH::long_array*
2357 Filter_i::
2358 GetElementsId( SMESH_Mesh_ptr theMesh )
2359 {
2360   SMESH::long_array_var anArray = new SMESH::long_array;
2361   if(!CORBA::is_nil(theMesh) && myPredicate){
2362     Controls::Filter::TIdSequence aSequence;
2363     GetElementsId(myPredicate,theMesh,aSequence);
2364     long i = 0, iEnd = aSequence.size();
2365     anArray->length( iEnd );
2366     for ( ; i < iEnd; i++ )
2367       anArray[ i ] = aSequence[i];
2368   }
2369   return anArray._retn();
2370 }
2371
2372 template<class TElement, class TIterator, class TPredicate>
2373 static void collectMeshInfo(const TIterator& theItr,
2374                             TPredicate& thePred,
2375                             SMESH::long_array& theRes)
2376 {         
2377   if (!theItr)
2378     return;
2379   while (theItr->more()) {
2380     const SMDS_MeshElement* anElem = theItr->next();
2381     if ( thePred->IsSatisfy( anElem->GetID() ) )
2382       theRes[ anElem->GetEntityType() ]++;
2383   }
2384 }
2385
2386 //=============================================================================
2387 /*!
2388  * \brief Returns statistic of mesh elements
2389  */
2390 //=============================================================================
2391 SMESH::long_array* ::Filter_i::GetMeshInfo()
2392 {
2393   SMESH::long_array_var aRes = new SMESH::long_array();
2394   aRes->length(SMESH::Entity_Last);
2395   for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
2396     aRes[i] = 0;
2397
2398   if(!CORBA::is_nil(myMesh) && myPredicate) {
2399     const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh);
2400     SMDS_ElemIteratorPtr it;
2401     switch( GetElementType() )
2402     {
2403   case SMDSAbs_Node:
2404     collectMeshInfo<const SMDS_MeshNode*>(aMesh->nodesIterator(),myPredicate,aRes);
2405     break;
2406   case SMDSAbs_Edge:
2407     collectMeshInfo<const SMDS_MeshElement*>(aMesh->edgesIterator(),myPredicate,aRes);
2408     break;
2409   case SMDSAbs_Face:
2410     collectMeshInfo<const SMDS_MeshElement*>(aMesh->facesIterator(),myPredicate,aRes);
2411     break;
2412   case SMDSAbs_Volume:
2413     collectMeshInfo<const SMDS_MeshElement*>(aMesh->volumesIterator(),myPredicate,aRes);
2414     break;
2415   case SMDSAbs_All:
2416   default:
2417     collectMeshInfo<const SMDS_MeshElement*>(aMesh->elementsIterator(),myPredicate,aRes);
2418     break;
2419     }
2420   }
2421
2422
2423   return aRes._retn();  
2424 }
2425
2426 //================================================================================
2427 /*!
2428  * \brief Return GetElementType() within an array
2429  * Implement SMESH_IDSource interface
2430  */
2431 //================================================================================
2432
2433 SMESH::array_of_ElementType* Filter_i::GetTypes()
2434 {
2435   SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
2436   types->length( 1 );
2437   types[0] = GetElementType();
2438   return types._retn();
2439 }
2440
2441 //=======================================================================
2442 //function : GetMesh
2443 //purpose  : Returns mesh
2444 //=======================================================================
2445
2446 SMESH::SMESH_Mesh_ptr Filter_i::GetMesh()
2447 {
2448   return SMESH_Mesh::_duplicate( myMesh );
2449 }
2450
2451 //=======================================================================
2452 // name    : getCriteria
2453 // Purpose : Retrieve criterions from predicate
2454 //=======================================================================
2455 static inline bool getCriteria( Predicate_i*                thePred,
2456                                 SMESH::Filter::Criteria_out theCriteria )
2457 {
2458   int aFType = thePred->GetFunctorType();
2459
2460   switch ( aFType )
2461   {
2462   case FT_FreeBorders:
2463   case FT_FreeEdges:
2464   case FT_FreeFaces:
2465   case FT_LinearOrQuadratic:
2466   case FT_FreeNodes:
2467     {
2468       CORBA::ULong i = theCriteria->length();
2469       theCriteria->length( i + 1 );
2470
2471       theCriteria[ i ] = createCriterion();
2472
2473       theCriteria[ i ].Type = aFType;
2474       theCriteria[ i ].TypeOfElement = thePred->GetElementType();
2475       return true;
2476     }
2477   case FT_BelongToGeom:
2478     {
2479       BelongToGeom_i* aPred = dynamic_cast<BelongToGeom_i*>( thePred );
2480
2481       CORBA::ULong i = theCriteria->length();
2482       theCriteria->length( i + 1 );
2483
2484       theCriteria[ i ] = createCriterion();
2485
2486       theCriteria[ i ].Type          = FT_BelongToGeom;
2487       theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
2488       theCriteria[ i ].ThresholdID   = aPred->GetShapeID();
2489       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2490       theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2491
2492       return true;
2493     }
2494   case FT_BelongToPlane:
2495   case FT_BelongToCylinder:
2496   case FT_BelongToGenSurface:
2497     {
2498       BelongToSurface_i* aPred = dynamic_cast<BelongToSurface_i*>( thePred );
2499
2500       CORBA::ULong i = theCriteria->length();
2501       theCriteria->length( i + 1 );
2502
2503       theCriteria[ i ] = createCriterion();
2504
2505       theCriteria[ i ].Type          = aFType;
2506       theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
2507       theCriteria[ i ].ThresholdID   = aPred->GetShapeID();
2508       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2509       theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2510
2511       return true;
2512     }
2513    case FT_LyingOnGeom:
2514     {
2515       LyingOnGeom_i* aPred = dynamic_cast<LyingOnGeom_i*>( thePred );
2516
2517       CORBA::ULong i = theCriteria->length();
2518       theCriteria->length( i + 1 );
2519
2520       theCriteria[ i ] = createCriterion();
2521
2522       theCriteria[ i ].Type          = FT_LyingOnGeom;
2523       theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
2524       theCriteria[ i ].ThresholdID   = aPred->GetShapeID();
2525       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2526       theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2527
2528       return true;
2529     }
2530    case FT_CoplanarFaces:
2531     {
2532       CoplanarFaces_i* aPred = dynamic_cast<CoplanarFaces_i*>( thePred );
2533
2534       CORBA::ULong i = theCriteria->length();
2535       theCriteria->length( i + 1 );
2536
2537       theCriteria[ i ] = createCriterion();
2538       CORBA::String_var faceId = aPred->GetFaceAsString();
2539
2540       theCriteria[ i ].Type          = FT_CoplanarFaces;
2541       theCriteria[ i ].ThresholdID   = faceId;
2542       theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2543
2544       return true;
2545     }
2546   case FT_RangeOfIds:
2547     {
2548       RangeOfIds_i* aPred = dynamic_cast<RangeOfIds_i*>( thePred );
2549
2550       CORBA::ULong i = theCriteria->length();
2551       theCriteria->length( i + 1 );
2552
2553       theCriteria[ i ] = createCriterion();
2554
2555       theCriteria[ i ].Type          = FT_RangeOfIds;
2556       theCriteria[ i ].ThresholdStr  = aPred->GetRangeStr();
2557       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2558
2559       return true;
2560     }
2561   case FT_BadOrientedVolume:
2562     {
2563       BadOrientedVolume_i* aPred = dynamic_cast<BadOrientedVolume_i*>( thePred );
2564
2565       CORBA::ULong i = theCriteria->length();
2566       theCriteria->length( i + 1 );
2567
2568       theCriteria[ i ] = createCriterion();
2569
2570       theCriteria[ i ].Type          = FT_BadOrientedVolume;
2571       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2572
2573       return true;
2574     }
2575   case FT_BareBorderVolume:
2576     {
2577       BareBorderVolume_i* aPred = dynamic_cast<BareBorderVolume_i*>( thePred );
2578
2579       CORBA::ULong i = theCriteria->length();
2580       theCriteria->length( i + 1 );
2581
2582       theCriteria[ i ] = createCriterion();
2583
2584       theCriteria[ i ].Type          = FT_BareBorderVolume;
2585       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2586
2587       return true;
2588     }
2589   case FT_BareBorderFace:
2590     {
2591       BareBorderFace_i* aPred = dynamic_cast<BareBorderFace_i*>( thePred );
2592
2593       CORBA::ULong i = theCriteria->length();
2594       theCriteria->length( i + 1 );
2595
2596       theCriteria[ i ] = createCriterion();
2597
2598       theCriteria[ i ].Type          = FT_BareBorderFace;
2599       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2600
2601       return true;
2602     }
2603   case FT_OverConstrainedVolume:
2604     {
2605       OverConstrainedVolume_i* aPred = dynamic_cast<OverConstrainedVolume_i*>( thePred );
2606
2607       CORBA::ULong i = theCriteria->length();
2608       theCriteria->length( i + 1 );
2609
2610       theCriteria[ i ] = createCriterion();
2611
2612       theCriteria[ i ].Type          = FT_OverConstrainedVolume;
2613       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2614
2615       return true;
2616     }
2617   case FT_OverConstrainedFace:
2618     {
2619       OverConstrainedFace_i* aPred = dynamic_cast<OverConstrainedFace_i*>( thePred );
2620
2621       CORBA::ULong i = theCriteria->length();
2622       theCriteria->length( i + 1 );
2623
2624       theCriteria[ i ] = createCriterion();
2625
2626       theCriteria[ i ].Type          = FT_OverConstrainedFace;
2627       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2628
2629       return true;
2630     }
2631   case FT_LessThan:
2632   case FT_MoreThan:
2633   case FT_EqualTo:
2634     {
2635       Comparator_i* aCompar = dynamic_cast<Comparator_i*>( thePred );
2636
2637       CORBA::ULong i = theCriteria->length();
2638       theCriteria->length( i + 1 );
2639
2640       theCriteria[ i ] = createCriterion();
2641
2642       theCriteria[ i ].Type      = aCompar->GetNumFunctor_i()->GetFunctorType();
2643       theCriteria[ i ].Compare   = aFType;
2644       theCriteria[ i ].Threshold = aCompar->GetMargin();
2645       theCriteria[ i ].TypeOfElement = aCompar->GetElementType();
2646
2647       if ( aFType == FT_EqualTo )
2648       {
2649         EqualTo_i* aCompar = dynamic_cast<EqualTo_i*>( thePred );
2650         theCriteria[ i ].Tolerance = aCompar->GetTolerance();
2651       }
2652     }
2653     return true;
2654
2655   case FT_LogicalNOT:
2656     {
2657       Predicate_i* aPred = ( dynamic_cast<LogicalNOT_i*>( thePred ) )->GetPredicate_i();
2658       getCriteria( aPred, theCriteria );
2659       theCriteria[ theCriteria->length() - 1 ].UnaryOp = FT_LogicalNOT;
2660     }
2661     return true;
2662
2663   case FT_LogicalAND:
2664   case FT_LogicalOR:
2665     {
2666       Predicate_i* aPred1 = ( dynamic_cast<LogicalBinary_i*>( thePred ) )->GetPredicate1_i();
2667       Predicate_i* aPred2 = ( dynamic_cast<LogicalBinary_i*>( thePred ) )->GetPredicate2_i();
2668       if ( !getCriteria( aPred1, theCriteria ) )
2669         return false;
2670       theCriteria[ theCriteria->length() - 1 ].BinaryOp = aFType;
2671       return getCriteria( aPred2, theCriteria );
2672     }
2673   case FT_GroupColor:
2674     {
2675       CORBA::ULong i = theCriteria->length();
2676       theCriteria->length( i + 1 );
2677
2678       theCriteria[ i ] = createCriterion();
2679
2680       GroupColor_i* aPred = dynamic_cast<GroupColor_i*>( thePred );
2681       theCriteria[ i ].Type          = aFType;
2682       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2683       theCriteria[ i ].ThresholdStr  = aPred->GetColorStr();
2684
2685       return true;
2686     }
2687   case FT_ElemGeomType:
2688     {
2689       CORBA::ULong i = theCriteria->length();
2690       theCriteria->length( i + 1 );
2691
2692       theCriteria[ i ] = createCriterion();
2693
2694       ElemGeomType_i* aPred = dynamic_cast<ElemGeomType_i*>( thePred );
2695       theCriteria[ i ].Type          = aFType;
2696       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2697       theCriteria[ i ].Threshold     = (double)aPred->GetGeometryType();
2698       return true;
2699     }
2700
2701   case FT_Undefined:
2702     return false;
2703   default:
2704     return false;
2705   }
2706 }
2707
2708 //=======================================================================
2709 // name    : Filter_i::GetCriteria
2710 // Purpose : Retrieve criterions from predicate
2711 //=======================================================================
2712 CORBA::Boolean Filter_i::GetCriteria( SMESH::Filter::Criteria_out theCriteria )
2713 {
2714   theCriteria = new SMESH::Filter::Criteria;
2715   return myPredicate != 0 ? getCriteria( myPredicate, theCriteria ) : true;
2716 }
2717
2718 //=======================================================================
2719 // name    : Filter_i::SetCriteria
2720 // Purpose : Create new predicate and set criterions in it
2721 //=======================================================================
2722 CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria )
2723 {
2724   if ( myPredicate != 0 )
2725     myPredicate->UnRegister();
2726
2727   SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i();
2728   FilterManager_ptr aFilterMgr = aFilter->_this();
2729
2730   // CREATE two lists ( PREDICATES  and LOG OP )
2731
2732   // Criterion
2733   TPythonDump()<<"aCriteria = []";
2734   std::list<SMESH::Predicate_ptr> aPredicates;
2735   std::list<int>                  aBinaries;
2736   for ( int i = 0, n = theCriteria.length(); i < n; i++ )
2737   {
2738     int         aCriterion    = theCriteria[ i ].Type;
2739     int         aCompare      = theCriteria[ i ].Compare;
2740     double      aThreshold    = theCriteria[ i ].Threshold;
2741     const char* aThresholdStr = theCriteria[ i ].ThresholdStr;
2742     const char* aThresholdID  = theCriteria[ i ].ThresholdID;
2743     int         aUnary        = theCriteria[ i ].UnaryOp;
2744     int         aBinary       = theCriteria[ i ].BinaryOp;
2745     double      aTolerance    = theCriteria[ i ].Tolerance;
2746     ElementType aTypeOfElem   = theCriteria[ i ].TypeOfElement;
2747     long        aPrecision    = theCriteria[ i ].Precision;
2748
2749     {
2750       TPythonDump pd;
2751       pd << "aCriterion = SMESH.Filter.Criterion(" << aCriterion << "," << aCompare
2752          << "," << aThreshold << ",'" << aThresholdStr;
2753       if (aThresholdID && strlen(aThresholdID))
2754         //pd << "',salome.ObjectToID(" << aThresholdID
2755         pd << "','" << aThresholdID
2756            << "'," << aUnary << "," << aBinary << "," << aTolerance
2757            << "," << aTypeOfElem << "," << aPrecision << ")";
2758       else
2759         pd << "',''," << aUnary << "," << aBinary << "," << aTolerance
2760            << "," << aTypeOfElem << "," << aPrecision << ")";
2761     }
2762
2763     SMESH::Predicate_ptr aPredicate = SMESH::Predicate::_nil();
2764     SMESH::NumericalFunctor_ptr aFunctor = SMESH::NumericalFunctor::_nil();
2765
2766     switch ( aCriterion )
2767     {
2768       // Functors
2769
2770       case SMESH::FT_MultiConnection:
2771         aFunctor = aFilterMgr->CreateMultiConnection();
2772         break;
2773       case SMESH::FT_MultiConnection2D:
2774         aFunctor = aFilterMgr->CreateMultiConnection2D();
2775         break;
2776       case SMESH::FT_Length:
2777         aFunctor = aFilterMgr->CreateLength();
2778         break;
2779       case SMESH::FT_Length2D:
2780         aFunctor = aFilterMgr->CreateLength2D();
2781         break;
2782       case SMESH::FT_AspectRatio:
2783         aFunctor = aFilterMgr->CreateAspectRatio();
2784         break;
2785       case SMESH::FT_AspectRatio3D:
2786         aFunctor = aFilterMgr->CreateAspectRatio3D();
2787         break;
2788       case SMESH::FT_Warping:
2789         aFunctor = aFilterMgr->CreateWarping();
2790         break;
2791       case SMESH::FT_MinimumAngle:
2792         aFunctor = aFilterMgr->CreateMinimumAngle();
2793         break;
2794       case SMESH::FT_Taper:
2795         aFunctor = aFilterMgr->CreateTaper();
2796         break;
2797       case SMESH::FT_Skew:
2798         aFunctor = aFilterMgr->CreateSkew();
2799         break;
2800       case SMESH::FT_Area:
2801         aFunctor = aFilterMgr->CreateArea();
2802         break;
2803       case SMESH::FT_Volume3D:
2804         aFunctor = aFilterMgr->CreateVolume3D();
2805         break;
2806       case SMESH::FT_MaxElementLength2D:
2807         aFunctor = aFilterMgr->CreateMaxElementLength2D();
2808         break;
2809       case SMESH::FT_MaxElementLength3D:
2810         aFunctor = aFilterMgr->CreateMaxElementLength3D();
2811         break;
2812
2813       // Predicates
2814
2815       case SMESH::FT_FreeBorders:
2816         aPredicate = aFilterMgr->CreateFreeBorders();
2817         break;
2818       case SMESH::FT_FreeEdges:
2819         aPredicate = aFilterMgr->CreateFreeEdges();
2820         break;
2821       case SMESH::FT_FreeFaces:
2822         aPredicate = aFilterMgr->CreateFreeFaces();
2823         break;
2824       case SMESH::FT_FreeNodes:
2825         aPredicate = aFilterMgr->CreateFreeNodes();
2826         break;
2827       case SMESH::FT_BelongToGeom:
2828         {
2829           SMESH::BelongToGeom_ptr tmpPred = aFilterMgr->CreateBelongToGeom();
2830           tmpPred->SetElementType( aTypeOfElem );
2831           tmpPred->SetShape( aThresholdID, aThresholdStr );
2832           tmpPred->SetTolerance( aTolerance );
2833           aPredicate = tmpPred;
2834         }
2835         break;
2836       case SMESH::FT_BelongToPlane:
2837       case SMESH::FT_BelongToCylinder:
2838       case SMESH::FT_BelongToGenSurface:
2839         {
2840           SMESH::BelongToSurface_ptr tmpPred;
2841           switch ( aCriterion ) {
2842           case SMESH::FT_BelongToPlane:
2843             tmpPred = aFilterMgr->CreateBelongToPlane(); break;
2844           case SMESH::FT_BelongToCylinder:
2845             tmpPred = aFilterMgr->CreateBelongToCylinder(); break;
2846           default:
2847             tmpPred = aFilterMgr->CreateBelongToGenSurface();
2848           }
2849           tmpPred->SetShape( aThresholdID, aThresholdStr, aTypeOfElem );
2850           tmpPred->SetTolerance( aTolerance );
2851           aPredicate = tmpPred;
2852         }
2853         break;
2854       case SMESH::FT_LyingOnGeom:
2855         {
2856           SMESH::LyingOnGeom_ptr tmpPred = aFilterMgr->CreateLyingOnGeom();
2857           tmpPred->SetElementType( aTypeOfElem );
2858           tmpPred->SetShape( aThresholdID, aThresholdStr );
2859           tmpPred->SetTolerance( aTolerance );
2860           aPredicate = tmpPred;
2861         }
2862         break;
2863       case SMESH::FT_RangeOfIds:
2864         {
2865           SMESH::RangeOfIds_ptr tmpPred = aFilterMgr->CreateRangeOfIds();
2866           tmpPred->SetRangeStr( aThresholdStr );
2867           tmpPred->SetElementType( aTypeOfElem );
2868           aPredicate = tmpPred;
2869         }
2870         break;
2871       case SMESH::FT_BadOrientedVolume:
2872         {
2873           aPredicate = aFilterMgr->CreateBadOrientedVolume();
2874         }
2875         break;
2876       case SMESH::FT_BareBorderVolume:
2877         {
2878           aPredicate = aFilterMgr->CreateBareBorderVolume();
2879         }
2880         break;
2881       case SMESH::FT_BareBorderFace:
2882         {
2883           aPredicate = aFilterMgr->CreateBareBorderFace();
2884         }
2885         break;
2886       case SMESH::FT_OverConstrainedVolume:
2887         {
2888           aPredicate = aFilterMgr->CreateOverConstrainedVolume();
2889         }
2890         break;
2891       case SMESH::FT_OverConstrainedFace:
2892         {
2893           aPredicate = aFilterMgr->CreateOverConstrainedFace();
2894         }
2895         break;
2896       case SMESH::FT_LinearOrQuadratic:
2897         {
2898           SMESH::LinearOrQuadratic_ptr tmpPred = aFilterMgr->CreateLinearOrQuadratic();
2899           tmpPred->SetElementType( aTypeOfElem );
2900           aPredicate = tmpPred;
2901           break;
2902         }
2903       case SMESH::FT_GroupColor:
2904         {
2905           SMESH::GroupColor_ptr tmpPred = aFilterMgr->CreateGroupColor();
2906           tmpPred->SetElementType( aTypeOfElem );
2907           tmpPred->SetColorStr( aThresholdStr );
2908           aPredicate = tmpPred;
2909           break;
2910         }
2911       case SMESH::FT_ElemGeomType:
2912         {
2913           SMESH::ElemGeomType_ptr tmpPred = aFilterMgr->CreateElemGeomType();
2914           tmpPred->SetElementType( aTypeOfElem );
2915           tmpPred->SetGeometryType( (GeometryType)(int)(aThreshold + 0.5) );
2916           aPredicate = tmpPred;
2917           break;
2918         }
2919       case SMESH::FT_CoplanarFaces:
2920         {
2921           SMESH::CoplanarFaces_ptr tmpPred = aFilterMgr->CreateCoplanarFaces();
2922           tmpPred->SetFace( atol (aThresholdID ));
2923           tmpPred->SetTolerance( aTolerance );
2924           aPredicate = tmpPred;
2925           break;
2926         }
2927
2928       default:
2929         continue;
2930     }
2931
2932     // Comparator
2933     if ( !aFunctor->_is_nil() && aPredicate->_is_nil() )
2934     {
2935       SMESH::Comparator_ptr aComparator = SMESH::Comparator::_nil();
2936
2937       if ( aCompare == SMESH::FT_LessThan )
2938         aComparator = aFilterMgr->CreateLessThan();
2939       else if ( aCompare == SMESH::FT_MoreThan )
2940         aComparator = aFilterMgr->CreateMoreThan();
2941       else if ( aCompare == SMESH::FT_EqualTo )
2942         aComparator = aFilterMgr->CreateEqualTo();
2943       else
2944         continue;
2945
2946       aComparator->SetNumFunctor( aFunctor );
2947       aComparator->SetMargin( aThreshold );
2948
2949       if ( aCompare == FT_EqualTo )
2950       {
2951         SMESH::EqualTo_var anEqualTo = SMESH::EqualTo::_narrow( aComparator );
2952         anEqualTo->SetTolerance( aTolerance );
2953       }
2954
2955       aPredicate = aComparator;
2956
2957       aFunctor->SetPrecision( aPrecision );
2958     }
2959
2960     // Logical not
2961     if ( aUnary == FT_LogicalNOT )
2962     {
2963       SMESH::LogicalNOT_ptr aNotPred = aFilterMgr->CreateLogicalNOT();
2964       aNotPred->SetPredicate( aPredicate );
2965       aPredicate = aNotPred;
2966     }
2967
2968     // logical op
2969     aPredicates.push_back( aPredicate );
2970     aBinaries.push_back( aBinary );
2971     TPythonDump()<<"aCriteria.append(aCriterion)";
2972
2973   } // end of for
2974   TPythonDump()<<this<<".SetCriteria(aCriteria)";
2975
2976   // CREATE ONE PREDICATE FROM PREVIOUSLY CREATED MAP
2977
2978   // combine all "AND" operations
2979
2980   std::list<SMESH::Predicate_ptr> aResList;
2981
2982   std::list<SMESH::Predicate_ptr>::iterator aPredIter;
2983   std::list<int>::iterator                  aBinaryIter;
2984
2985   SMESH::Predicate_ptr aPrevPredicate = SMESH::Predicate::_nil();
2986   int aPrevBinary = SMESH::FT_Undefined;
2987
2988   for ( aPredIter = aPredicates.begin(), aBinaryIter = aBinaries.begin();
2989         aPredIter != aPredicates.end() && aBinaryIter != aBinaries.end();
2990         ++aPredIter, ++aBinaryIter )
2991   {
2992     int aCurrBinary = *aBinaryIter;
2993
2994     SMESH::Predicate_ptr aCurrPred = SMESH::Predicate::_nil();
2995
2996     if ( aPrevBinary == SMESH::FT_LogicalAND )
2997     {
2998
2999       SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalAND();
3000       aBinaryPred->SetPredicate1( aPrevPredicate );
3001       aBinaryPred->SetPredicate2( *aPredIter );
3002       aCurrPred = aBinaryPred;
3003     }
3004     else
3005       aCurrPred = *aPredIter;
3006
3007     if ( aCurrBinary != SMESH::FT_LogicalAND )
3008       aResList.push_back( aCurrPred );
3009
3010     aPrevPredicate = aCurrPred;
3011     aPrevBinary = aCurrBinary;
3012   }
3013
3014   // combine all "OR" operations
3015
3016   SMESH::Predicate_ptr aResPredicate = SMESH::Predicate::_nil();
3017
3018   if ( aResList.size() == 1 )
3019     aResPredicate = *aResList.begin();
3020   else if ( aResList.size() > 1 )
3021   {
3022     std::list<SMESH::Predicate_ptr>::iterator anIter = aResList.begin();
3023     aResPredicate = *anIter;
3024     anIter++;
3025     for ( ; anIter != aResList.end(); ++anIter )
3026     {
3027       SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalOR();
3028       aBinaryPred->SetPredicate1( aResPredicate );
3029       aBinaryPred->SetPredicate2( *anIter );
3030       aResPredicate = aBinaryPred;
3031     }
3032   }
3033
3034   SetPredicate( aResPredicate );
3035
3036   return !aResPredicate->_is_nil();
3037 }
3038
3039 //=======================================================================
3040 // name    : Filter_i::GetPredicate_i
3041 // Purpose : Get implementation of predicate
3042 //=======================================================================
3043 Predicate_i* Filter_i::GetPredicate_i()
3044 {
3045   return myPredicate;
3046 }
3047
3048 //=======================================================================
3049 // name    : Filter_i::GetPredicate
3050 // Purpose : Get predicate
3051 //=======================================================================
3052 Predicate_ptr Filter_i::GetPredicate()
3053 {
3054   if ( myPredicate == 0 )
3055     return SMESH::Predicate::_nil();
3056   else
3057   {
3058     SMESH::Predicate_var anObj = myPredicate->_this();
3059     return anObj._retn();
3060   }
3061 }
3062
3063 /*
3064                             FILTER LIBRARY
3065 */
3066
3067 #define ATTR_TYPE          "type"
3068 #define ATTR_COMPARE       "compare"
3069 #define ATTR_THRESHOLD     "threshold"
3070 #define ATTR_UNARY         "unary"
3071 #define ATTR_BINARY        "binary"
3072 #define ATTR_THRESHOLD_STR "threshold_str"
3073 #define ATTR_TOLERANCE     "tolerance"
3074 #define ATTR_ELEMENT_TYPE  "ElementType"
3075
3076 //=======================================================================
3077 // name    : toString
3078 // Purpose : Convert bool to LDOMString
3079 //=======================================================================
3080 static inline LDOMString toString( CORBA::Boolean val )
3081 {
3082   return val ? "logical not" : "";
3083 }
3084
3085 //=======================================================================
3086 // name    : toBool
3087 // Purpose : Convert LDOMString to bool
3088 //=======================================================================
3089 static inline bool toBool( const LDOMString& theStr )
3090 {
3091   return theStr.equals( "logical not" );
3092 }
3093
3094 //=======================================================================
3095 // name    : toString
3096 // Purpose : Convert double to LDOMString
3097 //=======================================================================
3098 static inline LDOMString toString( CORBA::Double val )
3099 {
3100   char a[ 255 ];
3101   sprintf( a, "%e", val );
3102   return LDOMString( a );
3103 }
3104
3105 //=======================================================================
3106 // name    : toDouble
3107 // Purpose : Convert LDOMString to double
3108 //=======================================================================
3109 static inline double toDouble( const LDOMString& theStr )
3110 {
3111   return atof( theStr.GetString() );
3112 }
3113
3114 //=======================================================================
3115 // name    : toString
3116 // Purpose : Convert functor type to LDOMString
3117 //=======================================================================
3118 static inline LDOMString toString( CORBA::Long theType )
3119 {
3120   switch ( theType )
3121   {
3122     case FT_AspectRatio     : return "Aspect ratio";
3123     case FT_Warping         : return "Warping";
3124     case FT_MinimumAngle    : return "Minimum angle";
3125     case FT_Taper           : return "Taper";
3126     case FT_Skew            : return "Skew";
3127     case FT_Area            : return "Area";
3128     case FT_Volume3D        : return "Volume3D";
3129     case FT_MaxElementLength2D: return "Max element length 2D";
3130     case FT_MaxElementLength3D: return "Max element length 3D";
3131     case FT_BelongToGeom    : return "Belong to Geom";
3132     case FT_BelongToPlane   : return "Belong to Plane";
3133     case FT_BelongToCylinder: return "Belong to Cylinder";
3134     case FT_BelongToGenSurface: return "Belong to Generic Surface";
3135     case FT_LyingOnGeom     : return "Lying on Geom";
3136     case FT_BadOrientedVolume:return "Bad Oriented Volume";
3137     case FT_BareBorderVolume: return "Volumes with bare border";
3138     case FT_BareBorderFace  : return "Faces with bare border";
3139     case FT_OverConstrainedVolume: return "Over-constrained Volumes";
3140     case FT_OverConstrainedFace  : return "Over-constrained Faces";
3141     case FT_RangeOfIds      : return "Range of IDs";
3142     case FT_FreeBorders     : return "Free borders";
3143     case FT_FreeEdges       : return "Free edges";
3144     case FT_FreeFaces       : return "Free faces";
3145     case FT_FreeNodes       : return "Free nodes";
3146     case FT_MultiConnection : return "Borders at multi-connections";
3147     case FT_MultiConnection2D: return "Borders at multi-connections 2D";
3148     case FT_Length          : return "Length";
3149     case FT_Length2D        : return "Length 2D";
3150     case FT_LessThan        : return "Less than";
3151     case FT_MoreThan        : return "More than";
3152     case FT_EqualTo         : return "Equal to";
3153     case FT_LogicalNOT      : return "Not";
3154     case FT_LogicalAND      : return "And";
3155     case FT_LogicalOR       : return "Or";
3156     case FT_GroupColor      : return "Color of Group";
3157     case FT_LinearOrQuadratic : return "Linear or Quadratic";
3158     case FT_ElemGeomType    : return "Element geomtry type";
3159     case FT_Undefined       : return "";
3160     default                 : return "";
3161   }
3162 }
3163
3164 //=======================================================================
3165 // name    : toFunctorType
3166 // Purpose : Convert LDOMString to functor type
3167 //=======================================================================
3168 static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
3169 {
3170   if      ( theStr.equals( "Aspect ratio"                 ) ) return FT_AspectRatio;
3171   else if ( theStr.equals( "Warping"                      ) ) return FT_Warping;
3172   else if ( theStr.equals( "Minimum angle"                ) ) return FT_MinimumAngle;
3173   else if ( theStr.equals( "Taper"                        ) ) return FT_Taper;
3174   else if ( theStr.equals( "Skew"                         ) ) return FT_Skew;
3175   else if ( theStr.equals( "Area"                         ) ) return FT_Area;
3176   else if ( theStr.equals( "Volume3D"                     ) ) return FT_Volume3D;
3177   else if ( theStr.equals( "Max element length 2D"        ) ) return FT_MaxElementLength2D;
3178   else if ( theStr.equals( "Max element length 3D"        ) ) return FT_MaxElementLength3D;
3179   else if ( theStr.equals( "Belong to Geom"               ) ) return FT_BelongToGeom;
3180   else if ( theStr.equals( "Belong to Plane"              ) ) return FT_BelongToPlane;
3181   else if ( theStr.equals( "Belong to Cylinder"           ) ) return FT_BelongToCylinder;
3182   else if ( theStr.equals( "Belong to Generic Surface"    ) ) return FT_BelongToGenSurface;
3183   else if ( theStr.equals( "Lying on Geom"                ) ) return FT_LyingOnGeom;
3184   else if ( theStr.equals( "Free borders"                 ) ) return FT_FreeBorders;
3185   else if ( theStr.equals( "Free edges"                   ) ) return FT_FreeEdges;
3186   else if ( theStr.equals( "Free faces"                   ) ) return FT_FreeFaces;
3187   else if ( theStr.equals( "Free nodes"                   ) ) return FT_FreeNodes;
3188   else if ( theStr.equals( "Borders at multi-connections" ) ) return FT_MultiConnection;
3189   //  else if ( theStr.equals( "Borders at multi-connections 2D" ) ) return FT_MultiConnection2D;
3190   else if ( theStr.equals( "Length"                       ) ) return FT_Length;
3191   //  else if ( theStr.equals( "Length2D"                     ) ) return FT_Length2D;
3192   else if ( theStr.equals( "Range of IDs"                 ) ) return FT_RangeOfIds;
3193   else if ( theStr.equals( "Bad Oriented Volume"          ) ) return FT_BadOrientedVolume;
3194   else if ( theStr.equals( "Volumes with bare border"     ) ) return FT_BareBorderVolume;
3195   else if ( theStr.equals( "Faces with bare border"       ) ) return FT_BareBorderFace;
3196   else if ( theStr.equals( "Over-constrained Volumes"     ) ) return FT_OverConstrainedVolume;
3197   else if ( theStr.equals( "Over-constrained Faces"       ) ) return FT_OverConstrainedFace;
3198   else if ( theStr.equals( "Less than"                    ) ) return FT_LessThan;
3199   else if ( theStr.equals( "More than"                    ) ) return FT_MoreThan;
3200   else if ( theStr.equals( "Equal to"                     ) ) return FT_EqualTo;
3201   else if ( theStr.equals( "Not"                          ) ) return FT_LogicalNOT;
3202   else if ( theStr.equals( "And"                          ) ) return FT_LogicalAND;
3203   else if ( theStr.equals( "Or"                           ) ) return FT_LogicalOR;
3204   else if ( theStr.equals( "Color of Group"               ) ) return FT_GroupColor;
3205   else if ( theStr.equals( "Linear or Quadratic"          ) ) return FT_LinearOrQuadratic;
3206   else if ( theStr.equals( "Element geomtry type"         ) ) return FT_ElemGeomType;
3207   else if ( theStr.equals( ""                             ) ) return FT_Undefined;
3208   else  return FT_Undefined;
3209 }
3210
3211 //=======================================================================
3212 // name    : toFunctorType
3213 // Purpose : Convert LDOMString to value of ElementType enumeration
3214 //=======================================================================
3215 static inline SMESH::ElementType toElementType( const LDOMString& theStr )
3216 {
3217   if      ( theStr.equals( "NODE"   ) ) return SMESH::NODE;
3218   else if ( theStr.equals( "EDGE"   ) ) return SMESH::EDGE;
3219   else if ( theStr.equals( "FACE"   ) ) return SMESH::FACE;
3220   else if ( theStr.equals( "VOLUME" ) ) return SMESH::VOLUME;
3221   else                                  return SMESH::ALL;
3222 }
3223
3224 //=======================================================================
3225 // name    : toString
3226 // Purpose : Convert ElementType to string
3227 //=======================================================================
3228 static inline LDOMString toString( const SMESH::ElementType theType )
3229 {
3230   switch ( theType )
3231   {
3232     case SMESH::NODE   : return "NODE";
3233     case SMESH::EDGE   : return "EDGE";
3234     case SMESH::FACE   : return "FACE";
3235     case SMESH::VOLUME : return "VOLUME";
3236     case SMESH::ALL    : return "ALL";
3237     default            : return "";
3238   }
3239 }
3240
3241 //=======================================================================
3242 // name    : findFilter
3243 // Purpose : Find filter in document
3244 //=======================================================================
3245 static LDOM_Element findFilter( const char* theFilterName,
3246                                 const LDOM_Document& theDoc,
3247                                 LDOM_Node* theParent = 0 )
3248 {
3249   LDOM_Element aRootElement = theDoc.getDocumentElement();
3250   if ( aRootElement.isNull() || !aRootElement.hasChildNodes() )
3251     return LDOM_Element();
3252
3253   for ( LDOM_Node aTypeNode = aRootElement.getFirstChild();
3254         !aTypeNode.isNull(); aTypeNode = aTypeNode.getNextSibling() )
3255   {
3256     for ( LDOM_Node aFilter = aTypeNode.getFirstChild();
3257           !aFilter.isNull(); aFilter = aFilter.getNextSibling() )
3258     {
3259       LDOM_Element* anElem = ( LDOM_Element* )&aFilter;
3260       if ( anElem->getTagName().equals( LDOMString( "filter" ) ) &&
3261            anElem->getAttribute( "name" ).equals( LDOMString( theFilterName ) ) )
3262       {
3263         if ( theParent != 0  )
3264           *theParent = aTypeNode;
3265         return (LDOM_Element&)aFilter;
3266       }
3267     }
3268   }
3269   return LDOM_Element();
3270 }
3271
3272 //=======================================================================
3273 // name    : getSectionName
3274 // Purpose : Get name of section of filters
3275 //=======================================================================
3276 static const char* getSectionName( const ElementType theType )
3277 {
3278   switch ( theType )
3279   {
3280     case SMESH::NODE   : return "Filters for nodes";
3281     case SMESH::EDGE   : return "Filters for edges";
3282     case SMESH::FACE   : return "Filters for faces";
3283     case SMESH::VOLUME : return "Filters for volumes";
3284     case SMESH::ALL    : return "Filters for elements";
3285     default            : return "";
3286   }
3287 }
3288
3289 //=======================================================================
3290 // name    : getSection
3291 // Purpose : Create section for filters corresponding to the entity type
3292 //=======================================================================
3293 static LDOM_Node getSection( const ElementType theType,
3294                              LDOM_Document&    theDoc,
3295                              const bool        toCreate = false )
3296 {
3297   LDOM_Element aRootElement = theDoc.getDocumentElement();
3298   if ( aRootElement.isNull() )
3299     return LDOM_Node();
3300
3301   // Find section
3302   bool anExist = false;
3303   const char* aSectionName = getSectionName( theType );
3304   if ( strcmp( aSectionName, "" ) == 0 )
3305     return LDOM_Node();
3306
3307   LDOM_NodeList aSections = theDoc.getElementsByTagName( "section" );
3308   LDOM_Node aNode;
3309   for ( int i = 0, n = aSections.getLength(); i < n; i++ )
3310   {
3311     aNode = aSections.item( i );
3312     LDOM_Element& anItem = ( LDOM_Element& )aNode;
3313     if ( anItem.getAttribute( "name" ).equals( LDOMString( aSectionName ) ) )
3314     {
3315       anExist = true;
3316       break;
3317     }
3318   }
3319
3320   // Create new section if necessary
3321   if ( !anExist )
3322   {
3323     if ( toCreate )
3324     {
3325       LDOM_Element aNewItem = theDoc.createElement( "section" );
3326       aNewItem.setAttribute( "name", aSectionName );
3327       aRootElement.appendChild( aNewItem );
3328       return aNewItem;
3329     }
3330     else
3331       return LDOM_Node();
3332   }
3333   return
3334     aNode;
3335 }
3336
3337 //=======================================================================
3338 // name    : createFilterItem
3339 // Purpose : Create filter item or LDOM document
3340 //=======================================================================
3341 static LDOM_Element createFilterItem( const char*       theName,
3342                                       SMESH::Filter_ptr theFilter,
3343                                       LDOM_Document&    theDoc )
3344 {
3345   // create new filter in document
3346   LDOM_Element aFilterItem = theDoc.createElement( "filter" );
3347   aFilterItem.setAttribute( "name", theName );
3348
3349   // save filter criterions
3350   SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria;
3351
3352   if ( !theFilter->GetCriteria( aCriteria ) )
3353     return LDOM_Element();
3354
3355   for ( CORBA::ULong i = 0, n = aCriteria->length(); i < n; i++ )
3356   {
3357     LDOM_Element aCriterionItem = theDoc.createElement( "criterion" );
3358     
3359     aCriterionItem.setAttribute( ATTR_TYPE         , toString(  aCriteria[ i ].Type) );
3360     aCriterionItem.setAttribute( ATTR_COMPARE      , toString(  aCriteria[ i ].Compare ) );
3361     aCriterionItem.setAttribute( ATTR_THRESHOLD    , toString(  aCriteria[ i ].Threshold ) );
3362     aCriterionItem.setAttribute( ATTR_UNARY        , toString(  aCriteria[ i ].UnaryOp ) );
3363     aCriterionItem.setAttribute( ATTR_BINARY       , toString(  aCriteria[ i ].BinaryOp ) );
3364
3365     aCriterionItem.setAttribute( ATTR_THRESHOLD_STR, (const char*)aCriteria[ i ].ThresholdStr );
3366     aCriterionItem.setAttribute( ATTR_TOLERANCE    , toString( aCriteria[ i ].Tolerance ) );
3367     aCriterionItem.setAttribute( ATTR_ELEMENT_TYPE ,
3368       toString( (SMESH::ElementType)aCriteria[ i ].TypeOfElement ) );
3369
3370     aFilterItem.appendChild( aCriterionItem );
3371   }
3372
3373   return aFilterItem;
3374 }
3375
3376 //=======================================================================
3377 // name    : FilterLibrary_i::FilterLibrary_i
3378 // Purpose : Constructor
3379 //=======================================================================
3380 FilterLibrary_i::FilterLibrary_i( const char* theFileName )
3381 {
3382   myFileName = strdup( theFileName );
3383   SMESH::FilterManager_i* aFilterMgr = new SMESH::FilterManager_i();
3384   myFilterMgr = aFilterMgr->_this();
3385
3386   LDOMParser aParser;
3387
3388   // Try to use existing library file
3389   bool anExists = false;
3390   if ( !aParser.parse( myFileName ) )
3391   {
3392     myDoc = aParser.getDocument();
3393     anExists = true;
3394   }
3395   // Create a new XML document if it doesn't exist
3396   else
3397     myDoc = LDOM_Document::createDocument( LDOMString() );
3398
3399   LDOM_Element aRootElement = myDoc.getDocumentElement();
3400   if ( aRootElement.isNull() )
3401   {
3402     // If the existing document is empty --> try to create a new one
3403     if ( anExists )
3404       myDoc = LDOM_Document::createDocument( LDOMString() );
3405   }
3406 }
3407
3408 //=======================================================================
3409 // name    : FilterLibrary_i::FilterLibrary_i
3410 // Purpose : Constructor
3411 //=======================================================================
3412 FilterLibrary_i::FilterLibrary_i()
3413 {
3414   myFileName = 0;
3415   SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i();
3416   myFilterMgr = aFilter->_this();
3417
3418   myDoc = LDOM_Document::createDocument( LDOMString() );
3419 }
3420
3421 FilterLibrary_i::~FilterLibrary_i()
3422 {
3423   delete myFileName;
3424   //TPythonDump()<<this<<".UnRegister()";
3425 }
3426
3427 //=======================================================================
3428 // name    : FilterLibrary_i::Copy
3429 // Purpose : Create filter and initialize it with values from library
3430 //=======================================================================
3431 Filter_ptr FilterLibrary_i::Copy( const char* theFilterName )
3432 {
3433   Filter_ptr aRes = Filter::_nil();
3434   LDOM_Node aFilter = findFilter( theFilterName, myDoc );
3435
3436   if ( aFilter.isNull() )
3437     return aRes;
3438
3439   std::list<SMESH::Filter::Criterion> aCriteria;
3440
3441   for ( LDOM_Node aCritNode = aFilter.getFirstChild();
3442         !aCritNode.isNull() ; aCritNode = aCritNode.getNextSibling() )
3443   {
3444     LDOM_Element* aCrit = (LDOM_Element*)&aCritNode;
3445
3446     const char* aTypeStr      = aCrit->getAttribute( ATTR_TYPE          ).GetString();
3447     const char* aCompareStr   = aCrit->getAttribute( ATTR_COMPARE       ).GetString();
3448     const char* aUnaryStr     = aCrit->getAttribute( ATTR_UNARY         ).GetString();
3449     const char* aBinaryStr    = aCrit->getAttribute( ATTR_BINARY        ).GetString();
3450     const char* anElemTypeStr = aCrit->getAttribute( ATTR_ELEMENT_TYPE  ).GetString();
3451
3452     SMESH::Filter::Criterion aCriterion = createCriterion();
3453
3454     aCriterion.Type          = toFunctorType( aTypeStr );
3455     aCriterion.Compare       = toFunctorType( aCompareStr );
3456     aCriterion.UnaryOp       = toFunctorType( aUnaryStr );
3457     aCriterion.BinaryOp      = toFunctorType( aBinaryStr );
3458
3459     aCriterion.TypeOfElement = toElementType( anElemTypeStr );
3460
3461     LDOMString str = aCrit->getAttribute( ATTR_THRESHOLD );
3462     int val = 0;
3463     aCriterion.Threshold = str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val )
3464       ? val : atof( str.GetString() );
3465
3466     str = aCrit->getAttribute( ATTR_TOLERANCE );
3467     aCriterion.Tolerance = str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val )
3468       ? val : atof( str.GetString() );
3469
3470     str = aCrit->getAttribute( ATTR_THRESHOLD_STR );
3471     if ( str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val ) )
3472     {
3473       char a[ 255 ];
3474       sprintf( a, "%d", val );
3475       aCriterion.ThresholdStr = strdup( a );
3476     }
3477     else
3478       aCriterion.ThresholdStr = str.GetString();
3479
3480     aCriteria.push_back( aCriterion );
3481   }
3482
3483   SMESH::Filter::Criteria_var aCriteriaVar = new SMESH::Filter::Criteria;
3484   aCriteriaVar->length( aCriteria.size() );
3485
3486   CORBA::ULong i = 0;
3487   std::list<SMESH::Filter::Criterion>::iterator anIter = aCriteria.begin();
3488
3489   for( ; anIter != aCriteria.end(); ++anIter )
3490     aCriteriaVar[ i++ ] = *anIter;
3491
3492   aRes = myFilterMgr->CreateFilter();
3493   aRes->SetCriteria( aCriteriaVar.inout() );
3494
3495   TPythonDump()<<this<<".Copy('"<<theFilterName<<"')";
3496
3497   return aRes;
3498 }
3499
3500 //=======================================================================
3501 // name    : FilterLibrary_i::SetFileName
3502 // Purpose : Set file name for library
3503 //=======================================================================
3504 void FilterLibrary_i::SetFileName( const char* theFileName )
3505 {
3506   delete myFileName;
3507   myFileName = strdup( theFileName );
3508   TPythonDump()<<this<<".SetFileName('"<<theFileName<<"')";
3509 }
3510
3511 //=======================================================================
3512 // name    : FilterLibrary_i::GetFileName
3513 // Purpose : Get file name of library
3514 //=======================================================================
3515 char* FilterLibrary_i::GetFileName()
3516 {
3517   return CORBA::string_dup( myFileName );
3518 }
3519
3520 //=======================================================================
3521 // name    : FilterLibrary_i::Add
3522 // Purpose : Add new filter to library
3523 //=======================================================================
3524 CORBA::Boolean FilterLibrary_i::Add( const char* theFilterName, Filter_ptr theFilter )
3525 {
3526   // if filter already in library or entry filter is null do nothing
3527   LDOM_Node aFilterNode = findFilter( theFilterName, myDoc );
3528   if ( !aFilterNode.isNull() || theFilter->_is_nil() )
3529     return false;
3530
3531   // get section corresponding to the filter type
3532   ElementType anEntType = theFilter->GetElementType();
3533
3534   LDOM_Node aSection = getSection( anEntType, myDoc, true );
3535   if ( aSection.isNull() )
3536     return false;
3537
3538   // create filter item
3539   LDOM_Element aFilterItem = createFilterItem( theFilterName, theFilter, myDoc );
3540   if ( aFilterItem.isNull() )
3541     return false;
3542   else
3543   {
3544     aSection.appendChild( aFilterItem );
3545     if(Filter_i* aFilter = DownCast<Filter_i*>(theFilter))
3546       TPythonDump()<<this<<".Add('"<<theFilterName<<"',"<<aFilter<<")";
3547     return true;
3548   }
3549 }
3550
3551 //=======================================================================
3552 // name    : FilterLibrary_i::Add
3553 // Purpose : Add new filter to library
3554 //=======================================================================
3555 CORBA::Boolean FilterLibrary_i::AddEmpty( const char* theFilterName, ElementType theType )
3556 {
3557   // if filter already in library or entry filter is null do nothing
3558   LDOM_Node aFilterNode = findFilter( theFilterName, myDoc );
3559   if ( !aFilterNode.isNull() )
3560     return false;
3561
3562   LDOM_Node aSection = getSection( theType, myDoc, true );
3563   if ( aSection.isNull() )
3564     return false;
3565
3566   // create filter item
3567   Filter_var aFilter = myFilterMgr->CreateFilter();
3568
3569   LDOM_Element aFilterItem = createFilterItem( theFilterName, aFilter, myDoc );
3570   if ( aFilterItem.isNull() )
3571     return false;
3572   else
3573   {
3574     aSection.appendChild( aFilterItem );
3575     TPythonDump()<<this<<".AddEmpty('"<<theFilterName<<"',"<<theType<<")";
3576     return true;
3577   }
3578 }
3579
3580 //=======================================================================
3581 // name    : FilterLibrary_i::Delete
3582 // Purpose : Delete filter from library
3583 //=======================================================================
3584 CORBA::Boolean FilterLibrary_i::Delete ( const char* theFilterName )
3585 {
3586   LDOM_Node aParentNode;
3587   LDOM_Node aFilterNode = findFilter( theFilterName, myDoc, &aParentNode );
3588   if ( aFilterNode.isNull() || aParentNode.isNull() )
3589     return false;
3590
3591   aParentNode.removeChild( aFilterNode );
3592   TPythonDump()<<this<<".Delete('"<<theFilterName<<"')";
3593   return true;
3594 }
3595
3596 //=======================================================================
3597 // name      : FilterLibrary_i::Replace
3598 // Purpose   : Replace existing filter with entry filter.
3599 // IMPORTANT : If filter does not exist it is not created
3600 //=======================================================================
3601 CORBA::Boolean FilterLibrary_i::Replace( const char* theFilterName,
3602                                          const char* theNewName,
3603                                          Filter_ptr  theFilter )
3604 {
3605   LDOM_Element aFilterItem = findFilter( theFilterName, myDoc );
3606   if ( aFilterItem.isNull() || theFilter->_is_nil() )
3607     return false;
3608
3609   LDOM_Element aNewItem = createFilterItem( theNewName, theFilter, myDoc );
3610   if ( aNewItem.isNull() )
3611     return false;
3612   else
3613   {
3614     aFilterItem.ReplaceElement( aNewItem );
3615     if(Filter_i* aFilter = DownCast<Filter_i*>(theFilter))
3616       TPythonDump()<<this<<".Replace('"<<theFilterName<<"',"<<theNewName<<"',"<<aFilter<<")";
3617     return true;
3618   }
3619 }
3620
3621 //=======================================================================
3622 // name    : FilterLibrary_i::Save
3623 // Purpose : Save library on disk
3624 //=======================================================================
3625 CORBA::Boolean FilterLibrary_i::Save()
3626 {
3627   if ( myFileName == 0 || strlen( myFileName ) == 0 )
3628     return false;
3629
3630   FILE* aOutFile = fopen( myFileName, "wt" );
3631   if ( !aOutFile )
3632     return false;
3633
3634   LDOM_XmlWriter aWriter( aOutFile );
3635   aWriter.SetIndentation( 2 );
3636   aWriter << myDoc;
3637   fclose( aOutFile );
3638
3639   TPythonDump()<<this<<".Save()";
3640   return true;
3641 }
3642
3643 //=======================================================================
3644 // name    : FilterLibrary_i::SaveAs
3645 // Purpose : Save library on disk
3646 //=======================================================================
3647 CORBA::Boolean FilterLibrary_i::SaveAs( const char* aFileName )
3648 {
3649   myFileName = strdup ( aFileName );
3650   TPythonDump()<<this<<".SaveAs('"<<aFileName<<"')";
3651   return Save();
3652 }
3653
3654 //=======================================================================
3655 // name    : FilterLibrary_i::IsPresent
3656 // Purpose : Verify whether filter is in library
3657 //=======================================================================
3658 CORBA::Boolean FilterLibrary_i::IsPresent( const char* theFilterName )
3659 {
3660   return !findFilter( theFilterName, myDoc ).isNull();
3661 }
3662
3663 //=======================================================================
3664 // name    : FilterLibrary_i::NbFilters
3665 // Purpose : Return amount of filters in library
3666 //=======================================================================
3667 CORBA::Long FilterLibrary_i::NbFilters( ElementType theType )
3668 {
3669   string_array_var aNames = GetNames( theType );
3670   return aNames->length();
3671 }
3672
3673 //=======================================================================
3674 // name    : FilterLibrary_i::GetNames
3675 // Purpose : Get names of filters from library
3676 //=======================================================================
3677 string_array* FilterLibrary_i::GetNames( ElementType theType )
3678 {
3679   string_array_var anArray = new string_array;
3680   TColStd_SequenceOfHAsciiString aSeq;
3681
3682   LDOM_Node aSection = getSection( theType, myDoc, false );
3683
3684   if ( !aSection.isNull() )
3685   {
3686     for ( LDOM_Node aFilter = aSection.getFirstChild();
3687           !aFilter.isNull(); aFilter = aFilter.getNextSibling() )
3688     {
3689       LDOM_Element& anElem = ( LDOM_Element& )aFilter;
3690       aSeq.Append( new TCollection_HAsciiString(
3691          (Standard_CString)anElem.getAttribute( "name" ).GetString() ) );
3692     }
3693   }
3694
3695   anArray->length( aSeq.Length() );
3696   for ( int i = 1, n = aSeq.Length(); i <= n; i++ )
3697     anArray[ i - 1 ] = CORBA::string_dup( aSeq( i )->ToCString() );
3698
3699   return anArray._retn();
3700 }
3701
3702 //=======================================================================
3703 // name    : FilterLibrary_i::GetAllNames
3704 // Purpose : Get names of filters from library
3705 //=======================================================================
3706 string_array* FilterLibrary_i::GetAllNames()
3707 {
3708   string_array_var aResArray = new string_array;
3709   for ( int type = SMESH::ALL; type <= SMESH::VOLUME; type++ )
3710   {
3711     SMESH::string_array_var aNames = GetNames( (SMESH::ElementType)type );
3712
3713     int aPrevLength = aResArray->length();
3714     aResArray->length( aPrevLength + aNames->length() );
3715     for ( int i = 0, n = aNames->length(); i < n; i++ )
3716       aResArray[ aPrevLength + i ] = aNames[ i ];
3717   }
3718
3719   return aResArray._retn();
3720 }