Salome HOME
0021014: EDF 1583 SMESH: Improvement of the Python Dumpfor the creation of groups
[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   std::list<TPredicateChangeWaiter*>::iterator i = myWaiters.begin();
2296   for ( ; i != myWaiters.end(); ++i )
2297     (*i)->PredicateChanged();
2298 }
2299
2300 //=======================================================================
2301 // name    : Filter_i::GetElementType
2302 // Purpose : Get entity type
2303 //=======================================================================
2304 SMESH::ElementType Filter_i::GetElementType()
2305 {
2306   return myPredicate != 0 ? myPredicate->GetElementType() : SMESH::ALL;
2307 }
2308
2309 //=======================================================================
2310 // name    : Filter_i::SetMesh
2311 // Purpose : Set mesh
2312 //=======================================================================
2313 void
2314 Filter_i::
2315 SetMesh( SMESH_Mesh_ptr theMesh )
2316 {
2317   if(!CORBA::is_nil(theMesh))
2318     theMesh->Register();
2319
2320   if(!CORBA::is_nil(myMesh))
2321     myMesh->UnRegister();
2322
2323   myMesh = SMESH_Mesh::_duplicate( theMesh );
2324   TPythonDump()<<this<<".SetMesh("<<theMesh<<")";
2325 }
2326
2327 SMESH::long_array*
2328 Filter_i::
2329 GetIDs()
2330 {
2331   return GetElementsId(myMesh);
2332 }
2333
2334 //=======================================================================
2335 // name    : Filter_i::GetElementsId
2336 // Purpose : Get ids of entities
2337 //=======================================================================
2338 void
2339 Filter_i::
2340 GetElementsId( Predicate_i* thePredicate,
2341                const SMDS_Mesh* theMesh,
2342                Controls::Filter::TIdSequence& theSequence )
2343 {
2344   if (thePredicate)
2345     Controls::Filter::GetElementsId(theMesh,thePredicate->GetPredicate(),theSequence);
2346 }
2347
2348 void
2349 Filter_i::
2350 GetElementsId( Predicate_i* thePredicate,
2351                SMESH_Mesh_ptr theMesh,
2352                Controls::Filter::TIdSequence& theSequence )
2353 {
2354   if (thePredicate) 
2355     if(const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(theMesh))
2356       Controls::Filter::GetElementsId(aMesh,thePredicate->GetPredicate(),theSequence);
2357 }
2358
2359 SMESH::long_array*
2360 Filter_i::
2361 GetElementsId( SMESH_Mesh_ptr theMesh )
2362 {
2363   SMESH::long_array_var anArray = new SMESH::long_array;
2364   if(!CORBA::is_nil(theMesh) && myPredicate){
2365     Controls::Filter::TIdSequence aSequence;
2366     GetElementsId(myPredicate,theMesh,aSequence);
2367     long i = 0, iEnd = aSequence.size();
2368     anArray->length( iEnd );
2369     for ( ; i < iEnd; i++ )
2370       anArray[ i ] = aSequence[i];
2371   }
2372   return anArray._retn();
2373 }
2374
2375 template<class TElement, class TIterator, class TPredicate>
2376 static void collectMeshInfo(const TIterator& theItr,
2377                             TPredicate& thePred,
2378                             SMESH::long_array& theRes)
2379 {         
2380   if (!theItr)
2381     return;
2382   while (theItr->more()) {
2383     const SMDS_MeshElement* anElem = theItr->next();
2384     if ( thePred->IsSatisfy( anElem->GetID() ) )
2385       theRes[ anElem->GetEntityType() ]++;
2386   }
2387 }
2388
2389 //=============================================================================
2390 /*!
2391  * \brief Returns statistic of mesh elements
2392  */
2393 //=============================================================================
2394 SMESH::long_array* ::Filter_i::GetMeshInfo()
2395 {
2396   SMESH::long_array_var aRes = new SMESH::long_array();
2397   aRes->length(SMESH::Entity_Last);
2398   for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
2399     aRes[i] = 0;
2400
2401   if(!CORBA::is_nil(myMesh) && myPredicate) {
2402     const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh);
2403     SMDS_ElemIteratorPtr it;
2404     switch( GetElementType() )
2405     {
2406     case SMDSAbs_Node:
2407       collectMeshInfo<const SMDS_MeshNode*>(aMesh->nodesIterator(),myPredicate,aRes);
2408       break;
2409     case SMDSAbs_Edge:
2410       collectMeshInfo<const SMDS_MeshElement*>(aMesh->edgesIterator(),myPredicate,aRes);
2411       break;
2412     case SMDSAbs_Face:
2413       collectMeshInfo<const SMDS_MeshElement*>(aMesh->facesIterator(),myPredicate,aRes);
2414       break;
2415     case SMDSAbs_Volume:
2416       collectMeshInfo<const SMDS_MeshElement*>(aMesh->volumesIterator(),myPredicate,aRes);
2417       break;
2418     case SMDSAbs_All:
2419     default:
2420       collectMeshInfo<const SMDS_MeshElement*>(aMesh->elementsIterator(),myPredicate,aRes);
2421       break;
2422     }
2423   }
2424
2425   return aRes._retn();  
2426 }
2427
2428 //================================================================================
2429 /*!
2430  * \brief Return GetElementType() within an array
2431  * Implement SMESH_IDSource interface
2432  */
2433 //================================================================================
2434
2435 SMESH::array_of_ElementType* Filter_i::GetTypes()
2436 {
2437   SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
2438
2439   // check if any element passes through the filter
2440   if ( !CORBA::is_nil(myMesh) && myPredicate )
2441   {
2442     const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh);
2443     SMDS_ElemIteratorPtr it = aMesh->elementsIterator( SMDSAbs_ElementType( GetElementType() ));
2444     bool satisfies = false;
2445     while ( !satisfies && it->more() )
2446       satisfies = myPredicate->IsSatisfy( it->next()->GetID() );
2447     if ( satisfies ) {
2448       types->length( 1 );
2449       types[0] = GetElementType();
2450     }
2451   }
2452   return types._retn();
2453 }
2454
2455 //=======================================================================
2456 //function : GetMesh
2457 //purpose  : Returns mesh
2458 //=======================================================================
2459
2460 SMESH::SMESH_Mesh_ptr Filter_i::GetMesh()
2461 {
2462   return SMESH_Mesh::_duplicate( myMesh );
2463 }
2464
2465 //================================================================================
2466 /*!
2467  * \brief Stores an object to be notified on change of predicate
2468  */
2469 //================================================================================
2470
2471 void Filter_i::AddWaiter( TPredicateChangeWaiter* waiter )
2472 {
2473   if ( waiter )
2474     myWaiters.push_back( waiter );
2475 }
2476
2477 //================================================================================
2478 /*!
2479  * \brief Removes an object to be notified on change of predicate
2480  */
2481 //================================================================================
2482
2483 void Filter_i::RemoveWaiter( TPredicateChangeWaiter* waiter )
2484 {
2485   myWaiters.remove( waiter );
2486 }
2487
2488 //=======================================================================
2489 // name    : getCriteria
2490 // Purpose : Retrieve criterions from predicate
2491 //=======================================================================
2492 static inline bool getCriteria( Predicate_i*                thePred,
2493                                 SMESH::Filter::Criteria_out theCriteria )
2494 {
2495   int aFType = thePred->GetFunctorType();
2496
2497   switch ( aFType )
2498   {
2499   case FT_FreeBorders:
2500   case FT_FreeEdges:
2501   case FT_FreeFaces:
2502   case FT_LinearOrQuadratic:
2503   case FT_FreeNodes:
2504     {
2505       CORBA::ULong i = theCriteria->length();
2506       theCriteria->length( i + 1 );
2507
2508       theCriteria[ i ] = createCriterion();
2509
2510       theCriteria[ i ].Type = aFType;
2511       theCriteria[ i ].TypeOfElement = thePred->GetElementType();
2512       return true;
2513     }
2514   case FT_BelongToGeom:
2515     {
2516       BelongToGeom_i* aPred = dynamic_cast<BelongToGeom_i*>( thePred );
2517
2518       CORBA::ULong i = theCriteria->length();
2519       theCriteria->length( i + 1 );
2520
2521       theCriteria[ i ] = createCriterion();
2522
2523       theCriteria[ i ].Type          = FT_BelongToGeom;
2524       theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
2525       theCriteria[ i ].ThresholdID   = aPred->GetShapeID();
2526       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2527       theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2528
2529       return true;
2530     }
2531   case FT_BelongToPlane:
2532   case FT_BelongToCylinder:
2533   case FT_BelongToGenSurface:
2534     {
2535       BelongToSurface_i* aPred = dynamic_cast<BelongToSurface_i*>( thePred );
2536
2537       CORBA::ULong i = theCriteria->length();
2538       theCriteria->length( i + 1 );
2539
2540       theCriteria[ i ] = createCriterion();
2541
2542       theCriteria[ i ].Type          = aFType;
2543       theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
2544       theCriteria[ i ].ThresholdID   = aPred->GetShapeID();
2545       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2546       theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2547
2548       return true;
2549     }
2550    case FT_LyingOnGeom:
2551     {
2552       LyingOnGeom_i* aPred = dynamic_cast<LyingOnGeom_i*>( thePred );
2553
2554       CORBA::ULong i = theCriteria->length();
2555       theCriteria->length( i + 1 );
2556
2557       theCriteria[ i ] = createCriterion();
2558
2559       theCriteria[ i ].Type          = FT_LyingOnGeom;
2560       theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
2561       theCriteria[ i ].ThresholdID   = aPred->GetShapeID();
2562       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2563       theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2564
2565       return true;
2566     }
2567    case FT_CoplanarFaces:
2568     {
2569       CoplanarFaces_i* aPred = dynamic_cast<CoplanarFaces_i*>( thePred );
2570
2571       CORBA::ULong i = theCriteria->length();
2572       theCriteria->length( i + 1 );
2573
2574       theCriteria[ i ] = createCriterion();
2575       CORBA::String_var faceId = aPred->GetFaceAsString();
2576
2577       theCriteria[ i ].Type          = FT_CoplanarFaces;
2578       theCriteria[ i ].ThresholdID   = faceId;
2579       theCriteria[ i ].Tolerance     = aPred->GetTolerance();
2580
2581       return true;
2582     }
2583   case FT_RangeOfIds:
2584     {
2585       RangeOfIds_i* aPred = dynamic_cast<RangeOfIds_i*>( thePred );
2586
2587       CORBA::ULong i = theCriteria->length();
2588       theCriteria->length( i + 1 );
2589
2590       theCriteria[ i ] = createCriterion();
2591
2592       theCriteria[ i ].Type          = FT_RangeOfIds;
2593       theCriteria[ i ].ThresholdStr  = aPred->GetRangeStr();
2594       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2595
2596       return true;
2597     }
2598   case FT_BadOrientedVolume:
2599     {
2600       BadOrientedVolume_i* aPred = dynamic_cast<BadOrientedVolume_i*>( thePred );
2601
2602       CORBA::ULong i = theCriteria->length();
2603       theCriteria->length( i + 1 );
2604
2605       theCriteria[ i ] = createCriterion();
2606
2607       theCriteria[ i ].Type          = FT_BadOrientedVolume;
2608       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2609
2610       return true;
2611     }
2612   case FT_BareBorderVolume:
2613     {
2614       BareBorderVolume_i* aPred = dynamic_cast<BareBorderVolume_i*>( thePred );
2615
2616       CORBA::ULong i = theCriteria->length();
2617       theCriteria->length( i + 1 );
2618
2619       theCriteria[ i ] = createCriterion();
2620
2621       theCriteria[ i ].Type          = FT_BareBorderVolume;
2622       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2623
2624       return true;
2625     }
2626   case FT_BareBorderFace:
2627     {
2628       BareBorderFace_i* aPred = dynamic_cast<BareBorderFace_i*>( thePred );
2629
2630       CORBA::ULong i = theCriteria->length();
2631       theCriteria->length( i + 1 );
2632
2633       theCriteria[ i ] = createCriterion();
2634
2635       theCriteria[ i ].Type          = FT_BareBorderFace;
2636       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2637
2638       return true;
2639     }
2640   case FT_OverConstrainedVolume:
2641     {
2642       OverConstrainedVolume_i* aPred = dynamic_cast<OverConstrainedVolume_i*>( thePred );
2643
2644       CORBA::ULong i = theCriteria->length();
2645       theCriteria->length( i + 1 );
2646
2647       theCriteria[ i ] = createCriterion();
2648
2649       theCriteria[ i ].Type          = FT_OverConstrainedVolume;
2650       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2651
2652       return true;
2653     }
2654   case FT_OverConstrainedFace:
2655     {
2656       OverConstrainedFace_i* aPred = dynamic_cast<OverConstrainedFace_i*>( thePred );
2657
2658       CORBA::ULong i = theCriteria->length();
2659       theCriteria->length( i + 1 );
2660
2661       theCriteria[ i ] = createCriterion();
2662
2663       theCriteria[ i ].Type          = FT_OverConstrainedFace;
2664       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2665
2666       return true;
2667     }
2668   case FT_LessThan:
2669   case FT_MoreThan:
2670   case FT_EqualTo:
2671     {
2672       Comparator_i* aCompar = dynamic_cast<Comparator_i*>( thePred );
2673
2674       CORBA::ULong i = theCriteria->length();
2675       theCriteria->length( i + 1 );
2676
2677       theCriteria[ i ] = createCriterion();
2678
2679       theCriteria[ i ].Type      = aCompar->GetNumFunctor_i()->GetFunctorType();
2680       theCriteria[ i ].Compare   = aFType;
2681       theCriteria[ i ].Threshold = aCompar->GetMargin();
2682       theCriteria[ i ].TypeOfElement = aCompar->GetElementType();
2683
2684       if ( aFType == FT_EqualTo )
2685       {
2686         EqualTo_i* aCompar = dynamic_cast<EqualTo_i*>( thePred );
2687         theCriteria[ i ].Tolerance = aCompar->GetTolerance();
2688       }
2689     }
2690     return true;
2691
2692   case FT_LogicalNOT:
2693     {
2694       Predicate_i* aPred = ( dynamic_cast<LogicalNOT_i*>( thePred ) )->GetPredicate_i();
2695       getCriteria( aPred, theCriteria );
2696       theCriteria[ theCriteria->length() - 1 ].UnaryOp = FT_LogicalNOT;
2697     }
2698     return true;
2699
2700   case FT_LogicalAND:
2701   case FT_LogicalOR:
2702     {
2703       Predicate_i* aPred1 = ( dynamic_cast<LogicalBinary_i*>( thePred ) )->GetPredicate1_i();
2704       Predicate_i* aPred2 = ( dynamic_cast<LogicalBinary_i*>( thePred ) )->GetPredicate2_i();
2705       if ( !getCriteria( aPred1, theCriteria ) )
2706         return false;
2707       theCriteria[ theCriteria->length() - 1 ].BinaryOp = aFType;
2708       return getCriteria( aPred2, theCriteria );
2709     }
2710   case FT_GroupColor:
2711     {
2712       CORBA::ULong i = theCriteria->length();
2713       theCriteria->length( i + 1 );
2714
2715       theCriteria[ i ] = createCriterion();
2716
2717       GroupColor_i* aPred = dynamic_cast<GroupColor_i*>( thePred );
2718       theCriteria[ i ].Type          = aFType;
2719       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2720       theCriteria[ i ].ThresholdStr  = aPred->GetColorStr();
2721
2722       return true;
2723     }
2724   case FT_ElemGeomType:
2725     {
2726       CORBA::ULong i = theCriteria->length();
2727       theCriteria->length( i + 1 );
2728
2729       theCriteria[ i ] = createCriterion();
2730
2731       ElemGeomType_i* aPred = dynamic_cast<ElemGeomType_i*>( thePred );
2732       theCriteria[ i ].Type          = aFType;
2733       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
2734       theCriteria[ i ].Threshold     = (double)aPred->GetGeometryType();
2735       return true;
2736     }
2737
2738   case FT_Undefined:
2739     return false;
2740   default:
2741     return false;
2742   }
2743 }
2744
2745 //=======================================================================
2746 // name    : Filter_i::GetCriteria
2747 // Purpose : Retrieve criterions from predicate
2748 //=======================================================================
2749 CORBA::Boolean Filter_i::GetCriteria( SMESH::Filter::Criteria_out theCriteria )
2750 {
2751   theCriteria = new SMESH::Filter::Criteria;
2752   return myPredicate != 0 ? getCriteria( myPredicate, theCriteria ) : true;
2753 }
2754
2755 //=======================================================================
2756 // name    : Filter_i::SetCriteria
2757 // Purpose : Create new predicate and set criterions in it
2758 //=======================================================================
2759 CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria )
2760 {
2761   if ( myPredicate != 0 )
2762     myPredicate->UnRegister();
2763
2764   SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i();
2765   FilterManager_ptr aFilterMgr = aFilter->_this();
2766
2767   // CREATE two lists ( PREDICATES  and LOG OP )
2768
2769   // Criterion
2770   TPythonDump()<<"aCriteria = []";
2771   std::list<SMESH::Predicate_ptr> aPredicates;
2772   std::list<int>                  aBinaries;
2773   for ( int i = 0, n = theCriteria.length(); i < n; i++ )
2774   {
2775     int         aCriterion    = theCriteria[ i ].Type;
2776     int         aCompare      = theCriteria[ i ].Compare;
2777     double      aThreshold    = theCriteria[ i ].Threshold;
2778     const char* aThresholdStr = theCriteria[ i ].ThresholdStr;
2779     const char* aThresholdID  = theCriteria[ i ].ThresholdID;
2780     int         aUnary        = theCriteria[ i ].UnaryOp;
2781     int         aBinary       = theCriteria[ i ].BinaryOp;
2782     double      aTolerance    = theCriteria[ i ].Tolerance;
2783     ElementType aTypeOfElem   = theCriteria[ i ].TypeOfElement;
2784     long        aPrecision    = theCriteria[ i ].Precision;
2785
2786     {
2787       TPythonDump pd;
2788       pd << "aCriterion = SMESH.Filter.Criterion("
2789          << aCriterion    << ", "
2790          << aCompare      << ", "
2791          << aThreshold    << ", '"
2792          << aThresholdStr << "', '";
2793       if (aThresholdID) pd << aThresholdID;
2794       pd                  << "', "
2795          << aUnary        << ", "
2796          << aBinary       << ", "
2797          << aTolerance    << ", "
2798          << aTypeOfElem   << ", "
2799          << aPrecision    << ")";
2800     }
2801     TPythonDump pd;
2802
2803     SMESH::Predicate_ptr aPredicate = SMESH::Predicate::_nil();
2804     SMESH::NumericalFunctor_ptr aFunctor = SMESH::NumericalFunctor::_nil();
2805
2806     switch ( aCriterion )
2807     {
2808       // Functors
2809
2810       case SMESH::FT_MultiConnection:
2811         aFunctor = aFilterMgr->CreateMultiConnection();
2812         break;
2813       case SMESH::FT_MultiConnection2D:
2814         aFunctor = aFilterMgr->CreateMultiConnection2D();
2815         break;
2816       case SMESH::FT_Length:
2817         aFunctor = aFilterMgr->CreateLength();
2818         break;
2819       case SMESH::FT_Length2D:
2820         aFunctor = aFilterMgr->CreateLength2D();
2821         break;
2822       case SMESH::FT_AspectRatio:
2823         aFunctor = aFilterMgr->CreateAspectRatio();
2824         break;
2825       case SMESH::FT_AspectRatio3D:
2826         aFunctor = aFilterMgr->CreateAspectRatio3D();
2827         break;
2828       case SMESH::FT_Warping:
2829         aFunctor = aFilterMgr->CreateWarping();
2830         break;
2831       case SMESH::FT_MinimumAngle:
2832         aFunctor = aFilterMgr->CreateMinimumAngle();
2833         break;
2834       case SMESH::FT_Taper:
2835         aFunctor = aFilterMgr->CreateTaper();
2836         break;
2837       case SMESH::FT_Skew:
2838         aFunctor = aFilterMgr->CreateSkew();
2839         break;
2840       case SMESH::FT_Area:
2841         aFunctor = aFilterMgr->CreateArea();
2842         break;
2843       case SMESH::FT_Volume3D:
2844         aFunctor = aFilterMgr->CreateVolume3D();
2845         break;
2846       case SMESH::FT_MaxElementLength2D:
2847         aFunctor = aFilterMgr->CreateMaxElementLength2D();
2848         break;
2849       case SMESH::FT_MaxElementLength3D:
2850         aFunctor = aFilterMgr->CreateMaxElementLength3D();
2851         break;
2852
2853       // Predicates
2854
2855       case SMESH::FT_FreeBorders:
2856         aPredicate = aFilterMgr->CreateFreeBorders();
2857         break;
2858       case SMESH::FT_FreeEdges:
2859         aPredicate = aFilterMgr->CreateFreeEdges();
2860         break;
2861       case SMESH::FT_FreeFaces:
2862         aPredicate = aFilterMgr->CreateFreeFaces();
2863         break;
2864       case SMESH::FT_FreeNodes:
2865         aPredicate = aFilterMgr->CreateFreeNodes();
2866         break;
2867       case SMESH::FT_BelongToGeom:
2868         {
2869           SMESH::BelongToGeom_ptr tmpPred = aFilterMgr->CreateBelongToGeom();
2870           tmpPred->SetElementType( aTypeOfElem );
2871           tmpPred->SetShape( aThresholdID, aThresholdStr );
2872           tmpPred->SetTolerance( aTolerance );
2873           aPredicate = tmpPred;
2874         }
2875         break;
2876       case SMESH::FT_BelongToPlane:
2877       case SMESH::FT_BelongToCylinder:
2878       case SMESH::FT_BelongToGenSurface:
2879         {
2880           SMESH::BelongToSurface_ptr tmpPred;
2881           switch ( aCriterion ) {
2882           case SMESH::FT_BelongToPlane:
2883             tmpPred = aFilterMgr->CreateBelongToPlane(); break;
2884           case SMESH::FT_BelongToCylinder:
2885             tmpPred = aFilterMgr->CreateBelongToCylinder(); break;
2886           default:
2887             tmpPred = aFilterMgr->CreateBelongToGenSurface();
2888           }
2889           tmpPred->SetShape( aThresholdID, aThresholdStr, aTypeOfElem );
2890           tmpPred->SetTolerance( aTolerance );
2891           aPredicate = tmpPred;
2892         }
2893         break;
2894       case SMESH::FT_LyingOnGeom:
2895         {
2896           SMESH::LyingOnGeom_ptr tmpPred = aFilterMgr->CreateLyingOnGeom();
2897           tmpPred->SetElementType( aTypeOfElem );
2898           tmpPred->SetShape( aThresholdID, aThresholdStr );
2899           tmpPred->SetTolerance( aTolerance );
2900           aPredicate = tmpPred;
2901         }
2902         break;
2903       case SMESH::FT_RangeOfIds:
2904         {
2905           SMESH::RangeOfIds_ptr tmpPred = aFilterMgr->CreateRangeOfIds();
2906           tmpPred->SetRangeStr( aThresholdStr );
2907           tmpPred->SetElementType( aTypeOfElem );
2908           aPredicate = tmpPred;
2909         }
2910         break;
2911       case SMESH::FT_BadOrientedVolume:
2912         {
2913           aPredicate = aFilterMgr->CreateBadOrientedVolume();
2914         }
2915         break;
2916       case SMESH::FT_BareBorderVolume:
2917         {
2918           aPredicate = aFilterMgr->CreateBareBorderVolume();
2919         }
2920         break;
2921       case SMESH::FT_BareBorderFace:
2922         {
2923           aPredicate = aFilterMgr->CreateBareBorderFace();
2924         }
2925         break;
2926       case SMESH::FT_OverConstrainedVolume:
2927         {
2928           aPredicate = aFilterMgr->CreateOverConstrainedVolume();
2929         }
2930         break;
2931       case SMESH::FT_OverConstrainedFace:
2932         {
2933           aPredicate = aFilterMgr->CreateOverConstrainedFace();
2934         }
2935         break;
2936       case SMESH::FT_LinearOrQuadratic:
2937         {
2938           SMESH::LinearOrQuadratic_ptr tmpPred = aFilterMgr->CreateLinearOrQuadratic();
2939           tmpPred->SetElementType( aTypeOfElem );
2940           aPredicate = tmpPred;
2941           break;
2942         }
2943       case SMESH::FT_GroupColor:
2944         {
2945           SMESH::GroupColor_ptr tmpPred = aFilterMgr->CreateGroupColor();
2946           tmpPred->SetElementType( aTypeOfElem );
2947           tmpPred->SetColorStr( aThresholdStr );
2948           aPredicate = tmpPred;
2949           break;
2950         }
2951       case SMESH::FT_ElemGeomType:
2952         {
2953           SMESH::ElemGeomType_ptr tmpPred = aFilterMgr->CreateElemGeomType();
2954           tmpPred->SetElementType( aTypeOfElem );
2955           tmpPred->SetGeometryType( (GeometryType)(int)(aThreshold + 0.5) );
2956           aPredicate = tmpPred;
2957           break;
2958         }
2959       case SMESH::FT_CoplanarFaces:
2960         {
2961           SMESH::CoplanarFaces_ptr tmpPred = aFilterMgr->CreateCoplanarFaces();
2962           tmpPred->SetFace( atol (aThresholdID ));
2963           tmpPred->SetTolerance( aTolerance );
2964           aPredicate = tmpPred;
2965           break;
2966         }
2967
2968       default:
2969         continue;
2970     }
2971
2972     // Comparator
2973     if ( !aFunctor->_is_nil() && aPredicate->_is_nil() )
2974     {
2975       SMESH::Comparator_ptr aComparator = SMESH::Comparator::_nil();
2976
2977       if ( aCompare == SMESH::FT_LessThan )
2978         aComparator = aFilterMgr->CreateLessThan();
2979       else if ( aCompare == SMESH::FT_MoreThan )
2980         aComparator = aFilterMgr->CreateMoreThan();
2981       else if ( aCompare == SMESH::FT_EqualTo )
2982         aComparator = aFilterMgr->CreateEqualTo();
2983       else
2984         continue;
2985
2986       aComparator->SetNumFunctor( aFunctor );
2987       aComparator->SetMargin( aThreshold );
2988
2989       if ( aCompare == FT_EqualTo )
2990       {
2991         SMESH::EqualTo_var anEqualTo = SMESH::EqualTo::_narrow( aComparator );
2992         anEqualTo->SetTolerance( aTolerance );
2993       }
2994
2995       aPredicate = aComparator;
2996
2997       aFunctor->SetPrecision( aPrecision );
2998     }
2999
3000     // Logical not
3001     if ( aUnary == FT_LogicalNOT )
3002     {
3003       SMESH::LogicalNOT_ptr aNotPred = aFilterMgr->CreateLogicalNOT();
3004       aNotPred->SetPredicate( aPredicate );
3005       aPredicate = aNotPred;
3006     }
3007
3008     // logical op
3009     aPredicates.push_back( aPredicate );
3010     aBinaries.push_back( aBinary );
3011     pd <<"aCriteria.append(aCriterion)";
3012
3013   } // end of for
3014   TPythonDump pd; pd<<this<<".SetCriteria(aCriteria)";
3015
3016   // CREATE ONE PREDICATE FROM PREVIOUSLY CREATED MAP
3017
3018   // combine all "AND" operations
3019
3020   std::list<SMESH::Predicate_ptr> aResList;
3021
3022   std::list<SMESH::Predicate_ptr>::iterator aPredIter;
3023   std::list<int>::iterator                  aBinaryIter;
3024
3025   SMESH::Predicate_ptr aPrevPredicate = SMESH::Predicate::_nil();
3026   int aPrevBinary = SMESH::FT_Undefined;
3027
3028   for ( aPredIter = aPredicates.begin(), aBinaryIter = aBinaries.begin();
3029         aPredIter != aPredicates.end() && aBinaryIter != aBinaries.end();
3030         ++aPredIter, ++aBinaryIter )
3031   {
3032     int aCurrBinary = *aBinaryIter;
3033
3034     SMESH::Predicate_ptr aCurrPred = SMESH::Predicate::_nil();
3035
3036     if ( aPrevBinary == SMESH::FT_LogicalAND )
3037     {
3038
3039       SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalAND();
3040       aBinaryPred->SetPredicate1( aPrevPredicate );
3041       aBinaryPred->SetPredicate2( *aPredIter );
3042       aCurrPred = aBinaryPred;
3043     }
3044     else
3045       aCurrPred = *aPredIter;
3046
3047     if ( aCurrBinary != SMESH::FT_LogicalAND )
3048       aResList.push_back( aCurrPred );
3049
3050     aPrevPredicate = aCurrPred;
3051     aPrevBinary = aCurrBinary;
3052   }
3053
3054   // combine all "OR" operations
3055
3056   SMESH::Predicate_ptr aResPredicate = SMESH::Predicate::_nil();
3057
3058   if ( aResList.size() == 1 )
3059     aResPredicate = *aResList.begin();
3060   else if ( aResList.size() > 1 )
3061   {
3062     std::list<SMESH::Predicate_ptr>::iterator anIter = aResList.begin();
3063     aResPredicate = *anIter;
3064     anIter++;
3065     for ( ; anIter != aResList.end(); ++anIter )
3066     {
3067       SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalOR();
3068       aBinaryPred->SetPredicate1( aResPredicate );
3069       aBinaryPred->SetPredicate2( *anIter );
3070       aResPredicate = aBinaryPred;
3071     }
3072   }
3073
3074   SetPredicate( aResPredicate );
3075
3076   return !aResPredicate->_is_nil();
3077 }
3078
3079 //=======================================================================
3080 // name    : Filter_i::GetPredicate_i
3081 // Purpose : Get implementation of predicate
3082 //=======================================================================
3083 Predicate_i* Filter_i::GetPredicate_i()
3084 {
3085   return myPredicate;
3086 }
3087
3088 //=======================================================================
3089 // name    : Filter_i::GetPredicate
3090 // Purpose : Get predicate
3091 //=======================================================================
3092 Predicate_ptr Filter_i::GetPredicate()
3093 {
3094   if ( myPredicate == 0 )
3095     return SMESH::Predicate::_nil();
3096   else
3097   {
3098     SMESH::Predicate_var anObj = myPredicate->_this();
3099     return anObj._retn();
3100   }
3101 }
3102
3103 /*
3104                             FILTER LIBRARY
3105 */
3106
3107 #define ATTR_TYPE          "type"
3108 #define ATTR_COMPARE       "compare"
3109 #define ATTR_THRESHOLD     "threshold"
3110 #define ATTR_UNARY         "unary"
3111 #define ATTR_BINARY        "binary"
3112 #define ATTR_THRESHOLD_STR "threshold_str"
3113 #define ATTR_TOLERANCE     "tolerance"
3114 #define ATTR_ELEMENT_TYPE  "ElementType"
3115
3116 //=======================================================================
3117 // name    : toString
3118 // Purpose : Convert bool to LDOMString
3119 //=======================================================================
3120 static inline LDOMString toString( CORBA::Boolean val )
3121 {
3122   return val ? "logical not" : "";
3123 }
3124
3125 //=======================================================================
3126 // name    : toBool
3127 // Purpose : Convert LDOMString to bool
3128 //=======================================================================
3129 static inline bool toBool( const LDOMString& theStr )
3130 {
3131   return theStr.equals( "logical not" );
3132 }
3133
3134 //=======================================================================
3135 // name    : toString
3136 // Purpose : Convert double to LDOMString
3137 //=======================================================================
3138 static inline LDOMString toString( CORBA::Double val )
3139 {
3140   char a[ 255 ];
3141   sprintf( a, "%e", val );
3142   return LDOMString( a );
3143 }
3144
3145 //=======================================================================
3146 // name    : toDouble
3147 // Purpose : Convert LDOMString to double
3148 //=======================================================================
3149 static inline double toDouble( const LDOMString& theStr )
3150 {
3151   return atof( theStr.GetString() );
3152 }
3153
3154 //=======================================================================
3155 // name    : toString
3156 // Purpose : Convert functor type to LDOMString
3157 //=======================================================================
3158 static inline LDOMString toString( CORBA::Long theType )
3159 {
3160   switch ( theType )
3161   {
3162     case FT_AspectRatio     : return "Aspect ratio";
3163     case FT_Warping         : return "Warping";
3164     case FT_MinimumAngle    : return "Minimum angle";
3165     case FT_Taper           : return "Taper";
3166     case FT_Skew            : return "Skew";
3167     case FT_Area            : return "Area";
3168     case FT_Volume3D        : return "Volume3D";
3169     case FT_MaxElementLength2D: return "Max element length 2D";
3170     case FT_MaxElementLength3D: return "Max element length 3D";
3171     case FT_BelongToGeom    : return "Belong to Geom";
3172     case FT_BelongToPlane   : return "Belong to Plane";
3173     case FT_BelongToCylinder: return "Belong to Cylinder";
3174     case FT_BelongToGenSurface: return "Belong to Generic Surface";
3175     case FT_LyingOnGeom     : return "Lying on Geom";
3176     case FT_BadOrientedVolume:return "Bad Oriented Volume";
3177     case FT_BareBorderVolume: return "Volumes with bare border";
3178     case FT_BareBorderFace  : return "Faces with bare border";
3179     case FT_OverConstrainedVolume: return "Over-constrained Volumes";
3180     case FT_OverConstrainedFace  : return "Over-constrained Faces";
3181     case FT_RangeOfIds      : return "Range of IDs";
3182     case FT_FreeBorders     : return "Free borders";
3183     case FT_FreeEdges       : return "Free edges";
3184     case FT_FreeFaces       : return "Free faces";
3185     case FT_FreeNodes       : return "Free nodes";
3186     case FT_MultiConnection : return "Borders at multi-connections";
3187     case FT_MultiConnection2D: return "Borders at multi-connections 2D";
3188     case FT_Length          : return "Length";
3189     case FT_Length2D        : return "Length 2D";
3190     case FT_LessThan        : return "Less than";
3191     case FT_MoreThan        : return "More than";
3192     case FT_EqualTo         : return "Equal to";
3193     case FT_LogicalNOT      : return "Not";
3194     case FT_LogicalAND      : return "And";
3195     case FT_LogicalOR       : return "Or";
3196     case FT_GroupColor      : return "Color of Group";
3197     case FT_LinearOrQuadratic : return "Linear or Quadratic";
3198     case FT_ElemGeomType    : return "Element geomtry type";
3199     case FT_Undefined       : return "";
3200     default                 : return "";
3201   }
3202 }
3203
3204 //=======================================================================
3205 // name    : toFunctorType
3206 // Purpose : Convert LDOMString to functor type
3207 //=======================================================================
3208 static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
3209 {
3210   if      ( theStr.equals( "Aspect ratio"                 ) ) return FT_AspectRatio;
3211   else if ( theStr.equals( "Warping"                      ) ) return FT_Warping;
3212   else if ( theStr.equals( "Minimum angle"                ) ) return FT_MinimumAngle;
3213   else if ( theStr.equals( "Taper"                        ) ) return FT_Taper;
3214   else if ( theStr.equals( "Skew"                         ) ) return FT_Skew;
3215   else if ( theStr.equals( "Area"                         ) ) return FT_Area;
3216   else if ( theStr.equals( "Volume3D"                     ) ) return FT_Volume3D;
3217   else if ( theStr.equals( "Max element length 2D"        ) ) return FT_MaxElementLength2D;
3218   else if ( theStr.equals( "Max element length 3D"        ) ) return FT_MaxElementLength3D;
3219   else if ( theStr.equals( "Belong to Geom"               ) ) return FT_BelongToGeom;
3220   else if ( theStr.equals( "Belong to Plane"              ) ) return FT_BelongToPlane;
3221   else if ( theStr.equals( "Belong to Cylinder"           ) ) return FT_BelongToCylinder;
3222   else if ( theStr.equals( "Belong to Generic Surface"    ) ) return FT_BelongToGenSurface;
3223   else if ( theStr.equals( "Lying on Geom"                ) ) return FT_LyingOnGeom;
3224   else if ( theStr.equals( "Free borders"                 ) ) return FT_FreeBorders;
3225   else if ( theStr.equals( "Free edges"                   ) ) return FT_FreeEdges;
3226   else if ( theStr.equals( "Free faces"                   ) ) return FT_FreeFaces;
3227   else if ( theStr.equals( "Free nodes"                   ) ) return FT_FreeNodes;
3228   else if ( theStr.equals( "Borders at multi-connections" ) ) return FT_MultiConnection;
3229   //  else if ( theStr.equals( "Borders at multi-connections 2D" ) ) return FT_MultiConnection2D;
3230   else if ( theStr.equals( "Length"                       ) ) return FT_Length;
3231   //  else if ( theStr.equals( "Length2D"                     ) ) return FT_Length2D;
3232   else if ( theStr.equals( "Range of IDs"                 ) ) return FT_RangeOfIds;
3233   else if ( theStr.equals( "Bad Oriented Volume"          ) ) return FT_BadOrientedVolume;
3234   else if ( theStr.equals( "Volumes with bare border"     ) ) return FT_BareBorderVolume;
3235   else if ( theStr.equals( "Faces with bare border"       ) ) return FT_BareBorderFace;
3236   else if ( theStr.equals( "Over-constrained Volumes"     ) ) return FT_OverConstrainedVolume;
3237   else if ( theStr.equals( "Over-constrained Faces"       ) ) return FT_OverConstrainedFace;
3238   else if ( theStr.equals( "Less than"                    ) ) return FT_LessThan;
3239   else if ( theStr.equals( "More than"                    ) ) return FT_MoreThan;
3240   else if ( theStr.equals( "Equal to"                     ) ) return FT_EqualTo;
3241   else if ( theStr.equals( "Not"                          ) ) return FT_LogicalNOT;
3242   else if ( theStr.equals( "And"                          ) ) return FT_LogicalAND;
3243   else if ( theStr.equals( "Or"                           ) ) return FT_LogicalOR;
3244   else if ( theStr.equals( "Color of Group"               ) ) return FT_GroupColor;
3245   else if ( theStr.equals( "Linear or Quadratic"          ) ) return FT_LinearOrQuadratic;
3246   else if ( theStr.equals( "Element geomtry type"         ) ) return FT_ElemGeomType;
3247   else if ( theStr.equals( ""                             ) ) return FT_Undefined;
3248   else  return FT_Undefined;
3249 }
3250
3251 //=======================================================================
3252 // name    : toFunctorType
3253 // Purpose : Convert LDOMString to value of ElementType enumeration
3254 //=======================================================================
3255 static inline SMESH::ElementType toElementType( const LDOMString& theStr )
3256 {
3257   if      ( theStr.equals( "NODE"   ) ) return SMESH::NODE;
3258   else if ( theStr.equals( "EDGE"   ) ) return SMESH::EDGE;
3259   else if ( theStr.equals( "FACE"   ) ) return SMESH::FACE;
3260   else if ( theStr.equals( "VOLUME" ) ) return SMESH::VOLUME;
3261   else                                  return SMESH::ALL;
3262 }
3263
3264 //=======================================================================
3265 // name    : toString
3266 // Purpose : Convert ElementType to string
3267 //=======================================================================
3268 static inline LDOMString toString( const SMESH::ElementType theType )
3269 {
3270   switch ( theType )
3271   {
3272     case SMESH::NODE   : return "NODE";
3273     case SMESH::EDGE   : return "EDGE";
3274     case SMESH::FACE   : return "FACE";
3275     case SMESH::VOLUME : return "VOLUME";
3276     case SMESH::ALL    : return "ALL";
3277     default            : return "";
3278   }
3279 }
3280
3281 //=======================================================================
3282 // name    : findFilter
3283 // Purpose : Find filter in document
3284 //=======================================================================
3285 static LDOM_Element findFilter( const char* theFilterName,
3286                                 const LDOM_Document& theDoc,
3287                                 LDOM_Node* theParent = 0 )
3288 {
3289   LDOM_Element aRootElement = theDoc.getDocumentElement();
3290   if ( aRootElement.isNull() || !aRootElement.hasChildNodes() )
3291     return LDOM_Element();
3292
3293   for ( LDOM_Node aTypeNode = aRootElement.getFirstChild();
3294         !aTypeNode.isNull(); aTypeNode = aTypeNode.getNextSibling() )
3295   {
3296     for ( LDOM_Node aFilter = aTypeNode.getFirstChild();
3297           !aFilter.isNull(); aFilter = aFilter.getNextSibling() )
3298     {
3299       LDOM_Element* anElem = ( LDOM_Element* )&aFilter;
3300       if ( anElem->getTagName().equals( LDOMString( "filter" ) ) &&
3301            anElem->getAttribute( "name" ).equals( LDOMString( theFilterName ) ) )
3302       {
3303         if ( theParent != 0  )
3304           *theParent = aTypeNode;
3305         return (LDOM_Element&)aFilter;
3306       }
3307     }
3308   }
3309   return LDOM_Element();
3310 }
3311
3312 //=======================================================================
3313 // name    : getSectionName
3314 // Purpose : Get name of section of filters
3315 //=======================================================================
3316 static const char* getSectionName( const ElementType theType )
3317 {
3318   switch ( theType )
3319   {
3320     case SMESH::NODE   : return "Filters for nodes";
3321     case SMESH::EDGE   : return "Filters for edges";
3322     case SMESH::FACE   : return "Filters for faces";
3323     case SMESH::VOLUME : return "Filters for volumes";
3324     case SMESH::ALL    : return "Filters for elements";
3325     default            : return "";
3326   }
3327 }
3328
3329 //=======================================================================
3330 // name    : getSection
3331 // Purpose : Create section for filters corresponding to the entity type
3332 //=======================================================================
3333 static LDOM_Node getSection( const ElementType theType,
3334                              LDOM_Document&    theDoc,
3335                              const bool        toCreate = false )
3336 {
3337   LDOM_Element aRootElement = theDoc.getDocumentElement();
3338   if ( aRootElement.isNull() )
3339     return LDOM_Node();
3340
3341   // Find section
3342   bool anExist = false;
3343   const char* aSectionName = getSectionName( theType );
3344   if ( strcmp( aSectionName, "" ) == 0 )
3345     return LDOM_Node();
3346
3347   LDOM_NodeList aSections = theDoc.getElementsByTagName( "section" );
3348   LDOM_Node aNode;
3349   for ( int i = 0, n = aSections.getLength(); i < n; i++ )
3350   {
3351     aNode = aSections.item( i );
3352     LDOM_Element& anItem = ( LDOM_Element& )aNode;
3353     if ( anItem.getAttribute( "name" ).equals( LDOMString( aSectionName ) ) )
3354     {
3355       anExist = true;
3356       break;
3357     }
3358   }
3359
3360   // Create new section if necessary
3361   if ( !anExist )
3362   {
3363     if ( toCreate )
3364     {
3365       LDOM_Element aNewItem = theDoc.createElement( "section" );
3366       aNewItem.setAttribute( "name", aSectionName );
3367       aRootElement.appendChild( aNewItem );
3368       return aNewItem;
3369     }
3370     else
3371       return LDOM_Node();
3372   }
3373   return
3374     aNode;
3375 }
3376
3377 //=======================================================================
3378 // name    : createFilterItem
3379 // Purpose : Create filter item or LDOM document
3380 //=======================================================================
3381 static LDOM_Element createFilterItem( const char*       theName,
3382                                       SMESH::Filter_ptr theFilter,
3383                                       LDOM_Document&    theDoc )
3384 {
3385   // create new filter in document
3386   LDOM_Element aFilterItem = theDoc.createElement( "filter" );
3387   aFilterItem.setAttribute( "name", theName );
3388
3389   // save filter criterions
3390   SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria;
3391
3392   if ( !theFilter->GetCriteria( aCriteria ) )
3393     return LDOM_Element();
3394
3395   for ( CORBA::ULong i = 0, n = aCriteria->length(); i < n; i++ )
3396   {
3397     LDOM_Element aCriterionItem = theDoc.createElement( "criterion" );
3398     
3399     aCriterionItem.setAttribute( ATTR_TYPE         , toString(  aCriteria[ i ].Type) );
3400     aCriterionItem.setAttribute( ATTR_COMPARE      , toString(  aCriteria[ i ].Compare ) );
3401     aCriterionItem.setAttribute( ATTR_THRESHOLD    , toString(  aCriteria[ i ].Threshold ) );
3402     aCriterionItem.setAttribute( ATTR_UNARY        , toString(  aCriteria[ i ].UnaryOp ) );
3403     aCriterionItem.setAttribute( ATTR_BINARY       , toString(  aCriteria[ i ].BinaryOp ) );
3404
3405     aCriterionItem.setAttribute( ATTR_THRESHOLD_STR, (const char*)aCriteria[ i ].ThresholdStr );
3406     aCriterionItem.setAttribute( ATTR_TOLERANCE    , toString( aCriteria[ i ].Tolerance ) );
3407     aCriterionItem.setAttribute( ATTR_ELEMENT_TYPE ,
3408       toString( (SMESH::ElementType)aCriteria[ i ].TypeOfElement ) );
3409
3410     aFilterItem.appendChild( aCriterionItem );
3411   }
3412
3413   return aFilterItem;
3414 }
3415
3416 //=======================================================================
3417 // name    : FilterLibrary_i::FilterLibrary_i
3418 // Purpose : Constructor
3419 //=======================================================================
3420 FilterLibrary_i::FilterLibrary_i( const char* theFileName )
3421 {
3422   myFileName = strdup( theFileName );
3423   SMESH::FilterManager_i* aFilterMgr = new SMESH::FilterManager_i();
3424   myFilterMgr = aFilterMgr->_this();
3425
3426   LDOMParser aParser;
3427
3428   // Try to use existing library file
3429   bool anExists = false;
3430   if ( !aParser.parse( myFileName ) )
3431   {
3432     myDoc = aParser.getDocument();
3433     anExists = true;
3434   }
3435   // Create a new XML document if it doesn't exist
3436   else
3437     myDoc = LDOM_Document::createDocument( LDOMString() );
3438
3439   LDOM_Element aRootElement = myDoc.getDocumentElement();
3440   if ( aRootElement.isNull() )
3441   {
3442     // If the existing document is empty --> try to create a new one
3443     if ( anExists )
3444       myDoc = LDOM_Document::createDocument( LDOMString() );
3445   }
3446 }
3447
3448 //=======================================================================
3449 // name    : FilterLibrary_i::FilterLibrary_i
3450 // Purpose : Constructor
3451 //=======================================================================
3452 FilterLibrary_i::FilterLibrary_i()
3453 {
3454   myFileName = 0;
3455   SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i();
3456   myFilterMgr = aFilter->_this();
3457
3458   myDoc = LDOM_Document::createDocument( LDOMString() );
3459 }
3460
3461 FilterLibrary_i::~FilterLibrary_i()
3462 {
3463   delete myFileName;
3464   //TPythonDump()<<this<<".UnRegister()";
3465 }
3466
3467 //=======================================================================
3468 // name    : FilterLibrary_i::Copy
3469 // Purpose : Create filter and initialize it with values from library
3470 //=======================================================================
3471 Filter_ptr FilterLibrary_i::Copy( const char* theFilterName )
3472 {
3473   Filter_ptr aRes = Filter::_nil();
3474   LDOM_Node aFilter = findFilter( theFilterName, myDoc );
3475
3476   if ( aFilter.isNull() )
3477     return aRes;
3478
3479   std::list<SMESH::Filter::Criterion> aCriteria;
3480
3481   for ( LDOM_Node aCritNode = aFilter.getFirstChild();
3482         !aCritNode.isNull() ; aCritNode = aCritNode.getNextSibling() )
3483   {
3484     LDOM_Element* aCrit = (LDOM_Element*)&aCritNode;
3485
3486     const char* aTypeStr      = aCrit->getAttribute( ATTR_TYPE          ).GetString();
3487     const char* aCompareStr   = aCrit->getAttribute( ATTR_COMPARE       ).GetString();
3488     const char* aUnaryStr     = aCrit->getAttribute( ATTR_UNARY         ).GetString();
3489     const char* aBinaryStr    = aCrit->getAttribute( ATTR_BINARY        ).GetString();
3490     const char* anElemTypeStr = aCrit->getAttribute( ATTR_ELEMENT_TYPE  ).GetString();
3491
3492     SMESH::Filter::Criterion aCriterion = createCriterion();
3493
3494     aCriterion.Type          = toFunctorType( aTypeStr );
3495     aCriterion.Compare       = toFunctorType( aCompareStr );
3496     aCriterion.UnaryOp       = toFunctorType( aUnaryStr );
3497     aCriterion.BinaryOp      = toFunctorType( aBinaryStr );
3498
3499     aCriterion.TypeOfElement = toElementType( anElemTypeStr );
3500
3501     LDOMString str = aCrit->getAttribute( ATTR_THRESHOLD );
3502     int val = 0;
3503     aCriterion.Threshold = str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val )
3504       ? val : atof( str.GetString() );
3505
3506     str = aCrit->getAttribute( ATTR_TOLERANCE );
3507     aCriterion.Tolerance = str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val )
3508       ? val : atof( str.GetString() );
3509
3510     str = aCrit->getAttribute( ATTR_THRESHOLD_STR );
3511     if ( str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val ) )
3512     {
3513       char a[ 255 ];
3514       sprintf( a, "%d", val );
3515       aCriterion.ThresholdStr = strdup( a );
3516     }
3517     else
3518       aCriterion.ThresholdStr = str.GetString();
3519
3520     aCriteria.push_back( aCriterion );
3521   }
3522
3523   SMESH::Filter::Criteria_var aCriteriaVar = new SMESH::Filter::Criteria;
3524   aCriteriaVar->length( aCriteria.size() );
3525
3526   CORBA::ULong i = 0;
3527   std::list<SMESH::Filter::Criterion>::iterator anIter = aCriteria.begin();
3528
3529   for( ; anIter != aCriteria.end(); ++anIter )
3530     aCriteriaVar[ i++ ] = *anIter;
3531
3532   aRes = myFilterMgr->CreateFilter();
3533   aRes->SetCriteria( aCriteriaVar.inout() );
3534
3535   TPythonDump()<<this<<".Copy('"<<theFilterName<<"')";
3536
3537   return aRes;
3538 }
3539
3540 //=======================================================================
3541 // name    : FilterLibrary_i::SetFileName
3542 // Purpose : Set file name for library
3543 //=======================================================================
3544 void FilterLibrary_i::SetFileName( const char* theFileName )
3545 {
3546   delete myFileName;
3547   myFileName = strdup( theFileName );
3548   TPythonDump()<<this<<".SetFileName('"<<theFileName<<"')";
3549 }
3550
3551 //=======================================================================
3552 // name    : FilterLibrary_i::GetFileName
3553 // Purpose : Get file name of library
3554 //=======================================================================
3555 char* FilterLibrary_i::GetFileName()
3556 {
3557   return CORBA::string_dup( myFileName );
3558 }
3559
3560 //=======================================================================
3561 // name    : FilterLibrary_i::Add
3562 // Purpose : Add new filter to library
3563 //=======================================================================
3564 CORBA::Boolean FilterLibrary_i::Add( const char* theFilterName, Filter_ptr theFilter )
3565 {
3566   // if filter already in library or entry filter is null do nothing
3567   LDOM_Node aFilterNode = findFilter( theFilterName, myDoc );
3568   if ( !aFilterNode.isNull() || theFilter->_is_nil() )
3569     return false;
3570
3571   // get section corresponding to the filter type
3572   ElementType anEntType = theFilter->GetElementType();
3573
3574   LDOM_Node aSection = getSection( anEntType, myDoc, true );
3575   if ( aSection.isNull() )
3576     return false;
3577
3578   // create filter item
3579   LDOM_Element aFilterItem = createFilterItem( theFilterName, theFilter, myDoc );
3580   if ( aFilterItem.isNull() )
3581     return false;
3582   else
3583   {
3584     aSection.appendChild( aFilterItem );
3585     if(Filter_i* aFilter = DownCast<Filter_i*>(theFilter))
3586       TPythonDump()<<this<<".Add('"<<theFilterName<<"',"<<aFilter<<")";
3587     return true;
3588   }
3589 }
3590
3591 //=======================================================================
3592 // name    : FilterLibrary_i::Add
3593 // Purpose : Add new filter to library
3594 //=======================================================================
3595 CORBA::Boolean FilterLibrary_i::AddEmpty( const char* theFilterName, ElementType theType )
3596 {
3597   // if filter already in library or entry filter is null do nothing
3598   LDOM_Node aFilterNode = findFilter( theFilterName, myDoc );
3599   if ( !aFilterNode.isNull() )
3600     return false;
3601
3602   LDOM_Node aSection = getSection( theType, myDoc, true );
3603   if ( aSection.isNull() )
3604     return false;
3605
3606   // create filter item
3607   Filter_var aFilter = myFilterMgr->CreateFilter();
3608
3609   LDOM_Element aFilterItem = createFilterItem( theFilterName, aFilter, myDoc );
3610   if ( aFilterItem.isNull() )
3611     return false;
3612   else
3613   {
3614     aSection.appendChild( aFilterItem );
3615     TPythonDump()<<this<<".AddEmpty('"<<theFilterName<<"',"<<theType<<")";
3616     return true;
3617   }
3618 }
3619
3620 //=======================================================================
3621 // name    : FilterLibrary_i::Delete
3622 // Purpose : Delete filter from library
3623 //=======================================================================
3624 CORBA::Boolean FilterLibrary_i::Delete ( const char* theFilterName )
3625 {
3626   LDOM_Node aParentNode;
3627   LDOM_Node aFilterNode = findFilter( theFilterName, myDoc, &aParentNode );
3628   if ( aFilterNode.isNull() || aParentNode.isNull() )
3629     return false;
3630
3631   aParentNode.removeChild( aFilterNode );
3632   TPythonDump()<<this<<".Delete('"<<theFilterName<<"')";
3633   return true;
3634 }
3635
3636 //=======================================================================
3637 // name      : FilterLibrary_i::Replace
3638 // Purpose   : Replace existing filter with entry filter.
3639 // IMPORTANT : If filter does not exist it is not created
3640 //=======================================================================
3641 CORBA::Boolean FilterLibrary_i::Replace( const char* theFilterName,
3642                                          const char* theNewName,
3643                                          Filter_ptr  theFilter )
3644 {
3645   LDOM_Element aFilterItem = findFilter( theFilterName, myDoc );
3646   if ( aFilterItem.isNull() || theFilter->_is_nil() )
3647     return false;
3648
3649   LDOM_Element aNewItem = createFilterItem( theNewName, theFilter, myDoc );
3650   if ( aNewItem.isNull() )
3651     return false;
3652   else
3653   {
3654     aFilterItem.ReplaceElement( aNewItem );
3655     if(Filter_i* aFilter = DownCast<Filter_i*>(theFilter))
3656       TPythonDump()<<this<<".Replace('"<<theFilterName<<"','"<<theNewName<<"',"<<aFilter<<")";
3657     return true;
3658   }
3659 }
3660
3661 //=======================================================================
3662 // name    : FilterLibrary_i::Save
3663 // Purpose : Save library on disk
3664 //=======================================================================
3665 CORBA::Boolean FilterLibrary_i::Save()
3666 {
3667   if ( myFileName == 0 || strlen( myFileName ) == 0 )
3668     return false;
3669
3670   FILE* aOutFile = fopen( myFileName, "wt" );
3671   if ( !aOutFile )
3672     return false;
3673
3674   LDOM_XmlWriter aWriter( aOutFile );
3675   aWriter.SetIndentation( 2 );
3676   aWriter << myDoc;
3677   fclose( aOutFile );
3678
3679   TPythonDump()<<this<<".Save()";
3680   return true;
3681 }
3682
3683 //=======================================================================
3684 // name    : FilterLibrary_i::SaveAs
3685 // Purpose : Save library on disk
3686 //=======================================================================
3687 CORBA::Boolean FilterLibrary_i::SaveAs( const char* aFileName )
3688 {
3689   myFileName = strdup ( aFileName );
3690   TPythonDump()<<this<<".SaveAs('"<<aFileName<<"')";
3691   return Save();
3692 }
3693
3694 //=======================================================================
3695 // name    : FilterLibrary_i::IsPresent
3696 // Purpose : Verify whether filter is in library
3697 //=======================================================================
3698 CORBA::Boolean FilterLibrary_i::IsPresent( const char* theFilterName )
3699 {
3700   return !findFilter( theFilterName, myDoc ).isNull();
3701 }
3702
3703 //=======================================================================
3704 // name    : FilterLibrary_i::NbFilters
3705 // Purpose : Return amount of filters in library
3706 //=======================================================================
3707 CORBA::Long FilterLibrary_i::NbFilters( ElementType theType )
3708 {
3709   string_array_var aNames = GetNames( theType );
3710   return aNames->length();
3711 }
3712
3713 //=======================================================================
3714 // name    : FilterLibrary_i::GetNames
3715 // Purpose : Get names of filters from library
3716 //=======================================================================
3717 string_array* FilterLibrary_i::GetNames( ElementType theType )
3718 {
3719   string_array_var anArray = new string_array;
3720   TColStd_SequenceOfHAsciiString aSeq;
3721
3722   LDOM_Node aSection = getSection( theType, myDoc, false );
3723
3724   if ( !aSection.isNull() )
3725   {
3726     for ( LDOM_Node aFilter = aSection.getFirstChild();
3727           !aFilter.isNull(); aFilter = aFilter.getNextSibling() )
3728     {
3729       LDOM_Element& anElem = ( LDOM_Element& )aFilter;
3730       aSeq.Append( new TCollection_HAsciiString(
3731          (Standard_CString)anElem.getAttribute( "name" ).GetString() ) );
3732     }
3733   }
3734
3735   anArray->length( aSeq.Length() );
3736   for ( int i = 1, n = aSeq.Length(); i <= n; i++ )
3737     anArray[ i - 1 ] = CORBA::string_dup( aSeq( i )->ToCString() );
3738
3739   return anArray._retn();
3740 }
3741
3742 //=======================================================================
3743 // name    : FilterLibrary_i::GetAllNames
3744 // Purpose : Get names of filters from library
3745 //=======================================================================
3746 string_array* FilterLibrary_i::GetAllNames()
3747 {
3748   string_array_var aResArray = new string_array;
3749   for ( int type = SMESH::ALL; type <= SMESH::VOLUME; type++ )
3750   {
3751     SMESH::string_array_var aNames = GetNames( (SMESH::ElementType)type );
3752
3753     int aPrevLength = aResArray->length();
3754     aResArray->length( aPrevLength + aNames->length() );
3755     for ( int i = 0, n = aNames->length(); i < n; i++ )
3756       aResArray[ aPrevLength + i ] = aNames[ i ];
3757   }
3758
3759   return aResArray._retn();
3760 }
3761
3762 //================================================================================
3763 /*!
3764  * \brief Return an array of strings corresponding to items of enum FunctorType
3765  */
3766 //================================================================================
3767
3768 static const char** getFunctNames()
3769 {
3770   static const char* functName[ SMESH::FT_Undefined + 1 ] = {
3771     // If this line doesn't compile, this means that enum FunctorType has changed and
3772     // it's necessary to update this array accordingly (refer to SMESH_Filter.idl)
3773     // The order is IMPORTANT !!!
3774     "FT_AspectRatio", "FT_AspectRatio3D", "FT_Warping", "FT_MinimumAngle",
3775     "FT_Taper", "FT_Skew", "FT_Area", "FT_Volume3D", "FT_MaxElementLength2D",
3776     "FT_MaxElementLength3D", "FT_FreeBorders", "FT_FreeEdges", "FT_FreeNodes",
3777     "FT_FreeFaces", "FT_MultiConnection", "FT_MultiConnection2D", "FT_Length",
3778     "FT_Length2D", "FT_BelongToGeom", "FT_BelongToPlane", "FT_BelongToCylinder",
3779     "FT_BelongToGenSurface", "FT_LyingOnGeom", "FT_RangeOfIds", "FT_BadOrientedVolume",
3780     "FT_BareBorderVolume", "FT_BareBorderFace", "FT_OverConstrainedVolume",
3781     "FT_OverConstrainedFace", "FT_LinearOrQuadratic", "FT_GroupColor", "FT_ElemGeomType",
3782     "FT_CoplanarFaces", "FT_LessThan", "FT_MoreThan", "FT_EqualTo", "FT_LogicalNOT",
3783     "FT_LogicalAND", "FT_LogicalOR", "FT_Undefined" };
3784   return functName;
3785 }
3786
3787 //================================================================================
3788 /*!
3789  * \brief Return a string corresponding to an item of enum FunctorType
3790  */
3791 //================================================================================
3792
3793 const char* SMESH::FunctorTypeToString(SMESH::FunctorType ft)
3794 {
3795   if ( ft < 0 || ft > SMESH::FT_Undefined )
3796     return "FT_Undefined";
3797   return getFunctNames()[ ft ];
3798 }
3799
3800 //================================================================================
3801 /*!
3802  * \brief Converts a string to FunctorType. This is reverse of FunctorTypeToString()
3803  */
3804 //================================================================================
3805
3806 SMESH::FunctorType SMESH::StringToFunctorType(const char* str)
3807 {
3808   std::string name( str + 3 ); // skip "FT_"
3809   const char** functNames = getFunctNames();
3810   int ft = SMESH::FT_Undefined;
3811   for ( ; ft >= 0; --ft )
3812     if ( name == ( functNames[ft] + 3 ))
3813       break;
3814
3815   //ASSERT( strcmp( str, FunctorTypeToString( SMESH::FunctorType( ft ))) == 0 );
3816
3817   return SMESH::FunctorType( ft );
3818 }