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