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