Salome HOME
SALOME PAL V1_4_1
[modules/smesh.git] / src / SMESH_I / SMESH_Filter_i.cxx
1 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details.
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
21 //
22 //
23 //
24 //  File   : SMESH_Filter_i.cxx
25 //  Author : Alexey Petrov, OCC
26 //  Module : SMESH
27
28
29 #include "SMESH_Filter_i.hxx"
30
31 #include "SMDS_Iterator.hxx"
32 #include "SMDS_MeshElement.hxx"
33 #include "SMDS_MeshNode.hxx"
34 #include "SMDSAbs_ElementType.hxx"
35 #include "SMESH_Gen_i.hxx"
36 #include "SMESHDS_Mesh.hxx"
37
38 #include <gp_Pnt.hxx>
39 #include <gp_Vec.hxx>
40 #include <gp_XYZ.hxx>
41 #include <Precision.hxx>
42 #include <TColgp_SequenceOfXYZ.hxx>
43 #include <TColStd_ListOfInteger.hxx>
44 #include <TColStd_MapOfInteger.hxx>
45 #include <TColStd_ListIteratorOfListOfInteger.hxx>
46
47 /*
48                             AUXILIARY METHODS 
49 */
50
51 static inline double getAngle( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 )
52 {
53   return gp_Vec( P1 - P2 ).Angle( gp_Vec( P3 - P2 ) );
54 }
55
56 static inline double getArea( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 )
57 {
58   gp_Vec aVec1( P2 - P1 );
59   gp_Vec aVec2( P3 - P1 );
60   return ( aVec1 ^ aVec2 ).Magnitude() * 0.5;
61 }
62
63 static inline double getArea( const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3 )
64 {
65   return getArea( P1.XYZ(), P2.XYZ(), P3.XYZ() );
66 }
67
68 static inline double getDistance( const gp_XYZ& P1, const gp_XYZ& P2 )
69 {
70   double aDist = gp_Pnt( P1 ).Distance( gp_Pnt( P2 ) );
71   return aDist;
72 }
73
74 static int getNbMultiConnection( SMESHDS_Mesh* theMesh, const int theId )
75 {
76   if ( theMesh == 0 )
77     return 0;
78
79   const SMDS_MeshElement* anEdge = theMesh->FindElement( theId );
80   if ( anEdge == 0 || anEdge->GetType() != SMDSAbs_Edge || anEdge->NbNodes() != 2 )
81     return 0;
82
83   TColStd_MapOfInteger aMap;
84
85   int aResult = 0;
86   SMDS_ElemIteratorPtr anIter = anEdge->nodesIterator();
87   if ( anIter != 0 )
88   {
89     while( anIter->more() )
90     {
91       const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next();
92       if ( aNode == 0 )
93         return 0;
94       SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator();
95       while( anElemIter->more() )
96       {
97         const SMDS_MeshElement* anElem = anElemIter->next();
98         if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge )
99         {
100           int anId = anElem->GetID();
101
102           if ( anIter->more() )              // i.e. first node
103             aMap.Add( anId );
104           else if ( aMap.Contains( anId ) )
105             aResult++;
106         }
107       }
108 //      delete anElemIter;
109     }
110 //    delete anIter;
111   }
112
113   return aResult;
114 }
115
116 using namespace std;
117 using namespace SMESH;
118
119 /*
120                                 FUNCTORS
121 */
122
123 /*
124   Class       : NumericalFunctor_i
125   Description : Base class for numerical functors
126 */
127
128 NumericalFunctor_i::NumericalFunctor_i()
129 : SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
130 {
131   myMesh = 0;
132   SMESH_Gen_i::GetPOA()->activate_object( this );
133 }
134
135 void NumericalFunctor_i::SetMesh( SMESH_Mesh_ptr theMesh )
136 {
137   SMESH_Mesh_i* anImplPtr = 
138     dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( theMesh ).in() );
139   myMesh = anImplPtr ? anImplPtr->GetImpl().GetMeshDS() : 0;
140 }
141
142 bool NumericalFunctor_i::getPoints( const int             theId,
143                                     TColgp_SequenceOfXYZ& theRes ) const
144 {
145   theRes.Clear();
146
147   if ( myMesh == 0 )
148     return false;
149
150   // Get nodes of the face
151   const SMDS_MeshElement* anElem = myMesh->FindElement( theId );
152   if ( anElem == 0 || anElem->GetType() != GetType() )
153     return false;
154
155   int nbNodes = anElem->NbNodes();
156
157   SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
158   if ( anIter != 0 )
159   {
160     while( anIter->more() )
161     {
162       const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next();
163       if ( aNode != 0 )
164         theRes.Append( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) );
165     }
166
167 //    delete anIter;
168   }
169
170   return true;
171 }
172
173
174 /*
175   Class       : SMESH_MinimumAngleFunct
176   Description : Functor for calculation of minimum angle
177 */
178
179 CORBA::Double MinimumAngle_i::GetValue( CORBA::Long theId )
180 {
181   TColgp_SequenceOfXYZ P;
182   if ( !getPoints( theId, P )  || P.Length() != 3 && P.Length() != 4 )
183     return 0;
184
185   double aMin;
186
187   if ( P.Length() == 3 )
188   {
189     double A0 = getAngle( P( 3 ), P( 1 ), P( 2 ) );
190     double A1 = getAngle( P( 1 ), P( 2 ), P( 3 ) );
191     double A2 = getAngle( P( 2 ), P( 3 ), P( 1 ) );
192
193     aMin = Min( A0, Min( A1, A2 ) );
194   }
195   else
196   {
197     double A0 = getAngle( P( 4 ), P( 1 ), P( 2 ) );
198     double A1 = getAngle( P( 1 ), P( 2 ), P( 3 ) );
199     double A2 = getAngle( P( 2 ), P( 3 ), P( 4 ) );
200     double A3 = getAngle( P( 3 ), P( 4 ), P( 1 ) );
201     
202     aMin = Min( Min( A0, A1 ), Min( A2, A3 ) );
203   }
204   
205   return aMin * 180 / PI;
206 }
207
208 int MinimumAngle_i::GetType() const
209 {
210   return SMDSAbs_Face;
211 }
212
213 /*
214   Class       : AspectRatio_i
215   Description : Functor for calculating aspect ratio
216 */
217
218 CORBA::Double AspectRatio_i::GetValue( CORBA::Long theId )
219 {
220   TColgp_SequenceOfXYZ P;
221   if ( !getPoints( theId, P )  || P.Length() != 3 && P.Length() != 4 )
222     return 0;
223
224   int nbNodes = P.Length();
225
226   // Compute lengths of the sides
227
228   double aLen[ nbNodes ];
229   for ( int i = 0; i < nbNodes - 1; i++ )
230     aLen[ i ] = getDistance( P( i + 1 ), P( i + 2 ) );
231   aLen[ nbNodes - 1 ] = getDistance( P( 1 ), P( nbNodes ) );
232
233   // Compute aspect ratio
234
235   if ( nbNodes == 3 ) 
236   {
237     double aMaxLen = Max( aLen[ 0 ], Max( aLen[ 1 ], aLen[ 2 ] ) );
238     double anArea = getArea( P( 1 ), P( 2 ), P( 3 ) );
239     static double aCoef = sqrt( 3. ) / 4;
240
241     return anArea != 0 ? aCoef * aMaxLen * aMaxLen / anArea : 0;
242   }
243   else
244   {
245     double aMaxLen = Max( Max( aLen[ 0 ], aLen[ 1 ] ), Max( aLen[ 2 ], aLen[ 3 ] ) );
246     double aMinLen = Min( Min( aLen[ 0 ], aLen[ 1 ] ), Min( aLen[ 2 ], aLen[ 3 ] ) );
247     
248     return aMinLen != 0 ? aMaxLen / aMinLen : 0;
249   }
250 }
251
252 int AspectRatio_i::GetType() const
253 {
254   return SMDSAbs_Face;
255 }
256
257 /*
258   Class       : Warping_i
259   Description : Functor for calculating warping
260 */
261
262 CORBA::Double Warping_i::GetValue( CORBA::Long theId )
263 {
264   TColgp_SequenceOfXYZ P;
265   if ( !getPoints( theId, P ) || P.Length() != 4 )
266     return 0;
267
268   gp_XYZ G = ( P( 1 ) + P( 2 ) + P( 3 ) + P( 4 ) ) / 4;
269
270   double A1 = ComputeA( P( 1 ), P( 2 ), P( 3 ), G );
271   double A2 = ComputeA( P( 2 ), P( 3 ), P( 4 ), G );
272   double A3 = ComputeA( P( 3 ), P( 4 ), P( 1 ), G );
273   double A4 = ComputeA( P( 4 ), P( 1 ), P( 2 ), G );
274
275   return Max( Max( A1, A2 ), Max( A3, A4 ) );
276 }
277
278 double Warping_i::ComputeA( const gp_XYZ& thePnt1,
279                             const gp_XYZ& thePnt2,
280                             const gp_XYZ& thePnt3,
281                             const gp_XYZ& theG ) const
282 {
283   double aLen1 = gp_Pnt( thePnt1 ).Distance( gp_Pnt( thePnt2 ) );
284   double aLen2 = gp_Pnt( thePnt2 ).Distance( gp_Pnt( thePnt3 ) );
285   double L = Min( aLen1, aLen2 ) * 0.5;
286
287   gp_XYZ GI = ( thePnt2 - thePnt1 ) / 2. - theG;
288   gp_XYZ GJ = ( thePnt3 - thePnt2 ) / 2. - theG;
289   gp_XYZ N  = GI.Crossed( GJ );
290   N.Normalize();
291
292   double H = gp_Vec( thePnt2 - theG ).Dot( gp_Vec( N ) );
293   return asin( fabs( H / L ) ) * 180 / PI;
294 }
295
296 int Warping_i::GetType() const
297 {
298   return SMDSAbs_Face;
299 }
300
301 /*
302   Class       : Taper_i
303   Description : Functor for calculating taper
304 */
305
306 CORBA::Double Taper_i::GetValue( CORBA::Long theId )
307 {
308   TColgp_SequenceOfXYZ P;
309   if ( !getPoints( theId, P ) || P.Length() != 4 )
310     return 0;
311
312   // Compute taper
313   double J1 = getArea( P( 4 ), P( 1 ), P( 2 ) ) / 2;
314   double J2 = getArea( P( 3 ), P( 1 ), P( 2 ) ) / 2;
315   double J3 = getArea( P( 2 ), P( 3 ), P( 4 ) ) / 2;
316   double J4 = getArea( P( 3 ), P( 4 ), P( 1 ) ) / 2;
317
318   double JA = 0.25 * ( J1 + J2 + J3 + J4 );
319
320   double T1 = fabs( ( J1 - JA ) / JA );
321   double T2 = fabs( ( J2 - JA ) / JA );
322   double T3 = fabs( ( J3 - JA ) / JA );
323   double T4 = fabs( ( J4 - JA ) / JA );
324
325   return Max( Max( T1, T2 ), Max( T3, T4 ) );
326 }
327
328 int Taper_i::GetType() const
329 {
330   return SMDSAbs_Face;
331 }
332
333 /*
334   Class       : Skew_i
335   Description : Functor for calculating skew in degrees
336 */
337
338 static inline double skewAngle( const gp_XYZ& p1, const gp_XYZ& p2, const gp_XYZ& p3 )
339 {
340   gp_XYZ p12 = ( p2 + p1 ) / 2;
341   gp_XYZ p23 = ( p3 + p2 ) / 2;
342   gp_XYZ p31 = ( p3 + p1 ) / 2;
343
344   return gp_Vec( p31 - p2 ).Angle( p12 - p23 );
345 }
346
347 CORBA::Double Skew_i::GetValue( CORBA::Long theId )
348 {
349   TColgp_SequenceOfXYZ P;
350   if ( !getPoints( theId, P )  || P.Length() != 3 && P.Length() != 4 )
351     return 0;
352
353   // Compute skew
354   static double PI2 = PI / 2;
355   if ( P.Length() == 3 )
356   {
357     double A0 = fabs( PI2 - skewAngle( P( 3 ), P( 1 ), P( 2 ) ) );
358     double A1 = fabs( PI2 - skewAngle( P( 1 ), P( 2 ), P( 3 ) ) );
359     double A2 = fabs( PI2 - skewAngle( P( 2 ), P( 3 ), P( 1 ) ) );
360
361     return Max( A0, Max( A1, A2 ) ) * 180 / PI;
362   }
363   else 
364   {
365     gp_XYZ p12 = ( P( 1 ) + P( 2 ) ) / 2;
366     gp_XYZ p23 = ( P( 2 ) + P( 3 ) ) / 2;
367     gp_XYZ p34 = ( P( 3 ) + P( 4 ) ) / 2;
368     gp_XYZ p41 = ( P( 4 ) + P( 1 ) ) / 2;
369     
370     double A = fabs( PI2 - gp_Vec( p34 - p12 ).Angle( p23 - p41 ) );
371
372     return A * 180 / PI;
373   }
374 }
375
376 int Skew_i::GetType() const
377 {
378   return SMDSAbs_Face;
379 }
380
381 /*
382   Class       : Area_i
383   Description : Functor for calculating area
384 */
385
386 CORBA::Double Area_i::GetValue( CORBA::Long theId )
387 {
388   TColgp_SequenceOfXYZ P;
389   if ( !getPoints( theId, P )  || P.Length() != 3 && P.Length() != 4 )
390     return 0;
391
392   if ( P.Length() == 3 )
393     return getArea( P( 1 ), P( 2 ), P( 3 ) );
394   else
395     return getArea( P( 1 ), P( 2 ), P( 3 ) ) + getArea( P( 1 ), P( 3 ), P( 4 ) );
396 }
397
398 int Area_i::GetType() const
399 {
400   return SMDSAbs_Face;
401 }
402
403 /*
404   Class       : Length_i
405   Description : Functor for calculating length off edge
406 */
407
408 CORBA::Double Length_i::GetValue( CORBA::Long theId )
409 {
410   TColgp_SequenceOfXYZ P;
411   return getPoints( theId, P ) && P.Length() == 2 ? getDistance( P( 1 ), P( 2 ) ) : 0;
412 }
413
414 int Length_i::GetType() const
415 {
416   return SMDSAbs_Edge;
417 }
418
419 /*
420   Class       : MultiConnection_i
421   Description : Functor for calculating number of faces conneted to the edge
422 */
423
424 CORBA::Double MultiConnection_i::GetValue( CORBA::Long theId )
425 {
426   return getNbMultiConnection( myMesh, theId );
427 }
428
429 int MultiConnection_i::GetType() const
430 {
431   return SMDSAbs_Edge;
432 }
433
434 /*
435                             PREDICATES
436 */
437
438 /*
439   Class       : Predicate_i
440   Description : Base class for all predicates
441 */
442 Predicate_i::Predicate_i()
443 : SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
444 {
445   SMESH_Gen_i::GetPOA()->activate_object( this );
446 }
447
448
449 /*
450   Class       : FreeBorders_i
451   Description : Predicate for free borders
452 */
453
454 FreeBorders_i::FreeBorders_i()
455 {
456   myMesh = 0;
457 }
458
459 void FreeBorders_i::SetMesh( SMESH_Mesh_ptr theMesh )
460 {
461   SMESH_Mesh_i* anImplPtr =
462     dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( theMesh ).in() );
463   myMesh = anImplPtr ? anImplPtr->GetImpl().GetMeshDS() : 0;
464 }
465
466 CORBA::Boolean FreeBorders_i::IsSatisfy( CORBA::Long theId )
467 {
468   return getNbMultiConnection( myMesh, theId ) == 1;
469 }
470
471 int FreeBorders_i::GetType() const
472 {
473   return SMDSAbs_Edge;
474 }
475
476 /*
477   Class       : Comparator_i
478   Description : Base class for comparators
479 */
480
481 Comparator_i::Comparator_i()
482 {
483   myMargin  = 0;
484   myFunctor = 0;
485 }
486
487 Comparator_i::~Comparator_i()
488 {
489   if ( myFunctor != 0 )
490     myFunctor->Destroy();
491 }
492
493 void Comparator_i::SetMesh( SMESH_Mesh_ptr theMesh )
494 {
495   if ( myFunctor != 0 )
496     myFunctor->SetMesh( theMesh );
497 }
498
499 void Comparator_i::SetMargin( CORBA::Double theValue )
500 {
501   myMargin = theValue;
502 }
503
504 void Comparator_i::SetNumFunctor( NumericalFunctor_ptr theFunct )
505 {
506   if ( myFunctor != 0 )
507     myFunctor->Destroy();
508
509   myFunctor = dynamic_cast<NumericalFunctor_i*>( SMESH_Gen_i::GetServant( theFunct ).in() );
510
511   if ( myFunctor != 0 )
512     myFunctor->Register();
513 }
514
515 int Comparator_i::GetType() const
516 {
517   return myFunctor != 0 ? myFunctor->GetType() : SMDSAbs_All;
518 }
519
520 /*
521   Class       : LessThan_i
522   Description : Comparator "<"
523 */
524
525 CORBA::Boolean LessThan_i::IsSatisfy( CORBA::Long theId )
526 {
527   return myFunctor != 0 && myFunctor->GetValue( theId ) < myMargin;
528 }
529
530 /*
531   Class       : MoreThan_i
532   Description : Comparator ">"
533 */
534
535 CORBA::Boolean MoreThan_i::IsSatisfy( CORBA::Long theId )
536 {
537   return myFunctor != 0 && myFunctor->GetValue( theId ) > myMargin;
538 }
539
540 /*
541   Class       : EqualTo_i
542   Description : Comparator "="
543 */
544 EqualTo_i::EqualTo_i()
545 {
546   myToler = Precision::Confusion();
547 }
548
549 CORBA::Boolean EqualTo_i::IsSatisfy( CORBA::Long theId )
550 {
551   return myFunctor != 0 && fabs( myFunctor->GetValue( theId ) - myMargin ) < myToler;
552 }
553
554 void EqualTo_i::SetTolerance( CORBA::Double theToler )
555 {
556   myToler = theToler;
557 }
558
559
560 /*
561   Class       : LogicalNOT_i
562   Description : Logical NOT predicate
563 */
564
565 LogicalNOT_i::LogicalNOT_i()
566 {
567   myPredicate = 0;
568 }
569
570 LogicalNOT_i::~LogicalNOT_i()
571 {
572   if ( myPredicate )
573     myPredicate->Destroy();
574 }
575
576 CORBA::Boolean LogicalNOT_i::IsSatisfy( CORBA::Long theId )
577 {
578   return myPredicate !=0 && !myPredicate->IsSatisfy( theId );
579 }
580
581 void LogicalNOT_i::SetMesh( SMESH_Mesh_ptr theMesh )
582 {
583   if ( myPredicate != 0 )
584     myPredicate->SetMesh( theMesh );
585 }
586
587 void LogicalNOT_i::SetPredicate( Predicate_ptr thePred )
588 {
589   if ( myPredicate != 0 )
590     myPredicate->Destroy();
591
592   myPredicate = dynamic_cast<Predicate_i*>( SMESH_Gen_i::GetServant( thePred ).in() );
593
594   if ( myPredicate != 0 )
595     myPredicate->Register();
596 }
597
598 int LogicalNOT_i::GetType() const
599 {
600   return myPredicate != 0 ? myPredicate->GetType() : SMDSAbs_All;
601 }
602
603
604 /*
605   Class       : LogicalBinary_i
606   Description : Base class for binary logical predicate
607 */
608
609 LogicalBinary_i::LogicalBinary_i()
610 {
611   myPredicate1 = 0;
612   myPredicate2 = 0;
613 }
614 LogicalBinary_i::~LogicalBinary_i()
615 {
616   if ( myPredicate1 != 0 )
617     myPredicate1->Destroy();
618
619   if ( myPredicate2 != 0 )
620     myPredicate2->Destroy();
621 }
622
623 void LogicalBinary_i::SetMesh( SMESH_Mesh_ptr theMesh )
624 {
625   if ( myPredicate1 != 0 )
626     myPredicate1->SetMesh( theMesh );
627
628   if ( myPredicate2 != 0 )
629     myPredicate2->SetMesh( theMesh );
630 }
631
632 void LogicalBinary_i::SetPredicate1( Predicate_ptr thePredicate )
633 {
634   if ( myPredicate1 != 0 )
635     myPredicate1->Destroy();
636
637   myPredicate1 = dynamic_cast<Predicate_i*>( SMESH_Gen_i::GetServant( thePredicate ).in() );
638
639   if ( myPredicate1 != 0 )
640     myPredicate1->Register();
641 }
642
643 void LogicalBinary_i::SetPredicate2( Predicate_ptr thePredicate )
644 {
645   if ( myPredicate2 != 0 )
646     myPredicate2->Destroy();
647
648   myPredicate2 = dynamic_cast<Predicate_i*>( SMESH_Gen_i::GetServant( thePredicate ).in() );
649
650   if ( myPredicate2 != 0 )
651     myPredicate2->Register();
652 }
653
654 int LogicalBinary_i::GetType() const
655 {
656   if ( myPredicate1 == 0 || myPredicate2 == 0 )
657     return SMDSAbs_All;
658
659   int aType1 = myPredicate1->GetType();
660   int aType2 = myPredicate2->GetType();
661
662   return aType1 == aType2 ? aType1 : SMDSAbs_All;
663 }
664
665 /*
666   Class       : LogicalAND_i
667   Description : Logical AND
668 */
669
670 CORBA::Boolean LogicalAND_i::IsSatisfy( CORBA::Long theId )
671 {
672   return myPredicate1 != 0 && 
673          myPredicate2 != 0 && 
674          myPredicate1->IsSatisfy( theId ) && myPredicate2->IsSatisfy( theId );;
675 }
676
677 /*
678   Class       : LogicalOR_i
679   Description : Logical OR
680 */
681
682 CORBA::Boolean LogicalOR_i::IsSatisfy( CORBA::Long theId )
683 {
684   return myPredicate1 != 0 && 
685          myPredicate2 != 0 && 
686          myPredicate1->IsSatisfy( theId ) || myPredicate2->IsSatisfy( theId );
687 }
688
689
690 /*
691                               FILTER
692 */
693
694 Filter_i::Filter_i()
695 {
696   myPredicate = 0;
697 }
698
699 Filter_i::~Filter_i()
700 {
701   if ( myPredicate != 0 )
702     myPredicate->Destroy();
703 }
704
705 void Filter_i::SetPredicate( Predicate_ptr thePredicate )
706 {
707   if ( myPredicate != 0 )
708     myPredicate->Destroy();
709
710   myPredicate = dynamic_cast<Predicate_i*>( SMESH_Gen_i::GetServant( thePredicate ).in() );
711
712   if ( myPredicate != 0 )
713     myPredicate->Register();
714 }
715
716 void Filter_i::SetMesh( SMESH_Mesh_ptr theMesh )
717 {
718   if ( myPredicate != 0 )
719     myPredicate->SetMesh( theMesh );
720 }
721
722 SMESH::long_array* Filter_i::GetElementsId( SMESH_Mesh_ptr theMesh )
723 {
724
725   SetMesh( theMesh );
726
727   SMESH_Mesh_i* anImplPtr = 
728     dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( theMesh ).in() );
729
730   TColStd_ListOfInteger aList;
731
732   if ( anImplPtr != 0 )
733   {
734     SMESHDS_Mesh* aMesh = anImplPtr->GetImpl().GetMeshDS();
735
736     if ( myPredicate != 0 )
737     {
738       int aType = myPredicate->GetType();
739       
740       if ( aType == SMDSAbs_Edge )
741       {
742         SMDS_EdgeIteratorPtr anIter = aMesh->edgesIterator();
743         if ( anIter != 0 )
744         {
745           while( anIter->more() )
746           {
747             const SMDS_MeshElement* anElem = anIter->next();
748             if ( myPredicate->IsSatisfy( anElem->GetID() ) )
749               aList.Append( anElem->GetID() );
750           }
751         }
752 //        delete anIter;
753       }
754       else if ( aType == SMDSAbs_Face )
755       {
756         SMDS_FaceIteratorPtr anIter = aMesh->facesIterator();
757         if ( anIter != 0 )
758         {
759           while( anIter->more() )
760           {
761             const SMDS_MeshElement* anElem = anIter->next();
762             if ( myPredicate->IsSatisfy( anElem->GetID() ) )
763               aList.Append( anElem->GetID() );
764           }
765         }
766 //        delete anIter;
767       }
768     }
769   }
770   
771   SMESH::long_array_var anArray = new SMESH::long_array;
772   
773   anArray->length( aList.Extent() );
774   TColStd_ListIteratorOfListOfInteger anIter( aList );
775   int i = 0;
776   for( ; anIter.More(); anIter.Next() )
777     anArray[ i++ ] = anIter.Value();
778
779   return anArray._retn();
780 }
781
782 /*
783                             FILTER MANAGER
784 */
785
786 FilterManager_i::FilterManager_i()
787 : SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
788 {
789   SMESH_Gen_i::GetPOA()->activate_object( this );
790 }
791
792 MinimumAngle_ptr FilterManager_i::CreateMinimumAngle()
793 {
794   SMESH::MinimumAngle_i* aServant = new SMESH::MinimumAngle_i();
795   SMESH::MinimumAngle_var anObj = aServant->_this();
796   return anObj._retn();
797 }
798
799
800 AspectRatio_ptr FilterManager_i::CreateAspectRatio()
801 {
802   SMESH::AspectRatio_i* aServant = new SMESH::AspectRatio_i();
803   SMESH::AspectRatio_var anObj = aServant->_this();
804   return anObj._retn();
805 }
806
807
808 Warping_ptr FilterManager_i::CreateWarping()
809 {
810   SMESH::Warping_i* aServant = new SMESH::Warping_i();
811   SMESH::Warping_var anObj = aServant->_this();
812   return anObj._retn();
813 }
814
815
816 Taper_ptr FilterManager_i::CreateTaper()
817 {
818   SMESH::Taper_i* aServant = new SMESH::Taper_i();
819   SMESH::Taper_var anObj = aServant->_this();
820   return anObj._retn();
821 }
822
823
824 Skew_ptr FilterManager_i::CreateSkew()
825 {
826   SMESH::Skew_i* aServant = new SMESH::Skew_i();
827   SMESH::Skew_var anObj = aServant->_this();
828   return anObj._retn();
829 }
830
831
832 Area_ptr FilterManager_i::CreateArea()
833 {
834   SMESH::Area_i* aServant = new SMESH::Area_i();
835   SMESH::Area_var anObj = aServant->_this();
836   return anObj._retn();
837 }
838
839
840 Length_ptr FilterManager_i::CreateLength()
841 {
842   SMESH::Length_i* aServant = new SMESH::Length_i();
843   SMESH::Length_var anObj = aServant->_this();
844   return anObj._retn();
845 }
846
847
848 MultiConnection_ptr FilterManager_i::CreateMultiConnection()
849 {
850   SMESH::MultiConnection_i* aServant = new SMESH::MultiConnection_i();
851   SMESH::MultiConnection_var anObj = aServant->_this();
852   return anObj._retn();
853 }
854
855
856 FreeBorders_ptr FilterManager_i::CreateFreeBorders()
857 {
858   SMESH::FreeBorders_i* aServant = new SMESH::FreeBorders_i();
859   SMESH::FreeBorders_var anObj = aServant->_this();
860   return anObj._retn();
861 }
862
863 LessThan_ptr FilterManager_i::CreateLessThan()
864 {
865   SMESH::LessThan_i* aServant = new SMESH::LessThan_i();
866   SMESH::LessThan_var anObj = aServant->_this();
867   return anObj._retn();
868 }
869
870
871 MoreThan_ptr FilterManager_i::CreateMoreThan()
872 {
873   SMESH::MoreThan_i* aServant = new SMESH::MoreThan_i();
874   SMESH::MoreThan_var anObj = aServant->_this();
875   return anObj._retn();
876 }
877
878 EqualTo_ptr FilterManager_i::CreateEqualTo()
879 {
880   SMESH::EqualTo_i* aServant = new SMESH::EqualTo_i();
881   SMESH::EqualTo_var anObj = aServant->_this();
882   return anObj._retn();
883 }
884
885
886 LogicalNOT_ptr FilterManager_i::CreateLogicalNOT()
887 {
888   SMESH::LogicalNOT_i* aServant = new SMESH::LogicalNOT_i();
889   SMESH::LogicalNOT_var anObj = aServant->_this();
890   return anObj._retn();
891 }
892
893
894 LogicalAND_ptr FilterManager_i::CreateLogicalAND()
895 {
896   SMESH::LogicalAND_i* aServant = new SMESH::LogicalAND_i();
897   SMESH::LogicalAND_var anObj = aServant->_this();
898   return anObj._retn();
899 }
900
901
902 LogicalOR_ptr FilterManager_i::CreateLogicalOR()
903 {
904   SMESH::LogicalOR_i* aServant = new SMESH::LogicalOR_i();
905   SMESH::LogicalOR_var anObj = aServant->_this();
906   return anObj._retn();
907 }
908
909 Filter_ptr FilterManager_i::CreateFilter()
910 {
911   SMESH::Filter_i* aServant = new SMESH::Filter_i();
912   SMESH::Filter_var anObj = aServant->_this();
913   return anObj._retn();
914 }