Salome HOME
Copyright update: 2016
[modules/smesh.git] / src / SMESH / SMESH_HypoFilter.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 : implementaion of SMESH idl descriptions
24 //  File   : SMESH_HypoFilter.cxx
25 //  Module : SMESH
26 //
27 #include "SMESH_HypoFilter.hxx"
28
29 #include "SMESH_Gen.hxx"
30 #include "SMESH_Hypothesis.hxx"
31 #include "SMESH_MesherHelper.hxx"
32 #include "SMESH_subMesh.hxx"
33
34 #include <TopExp_Explorer.hxx>
35
36 using namespace std;
37
38
39 //=======================================================================
40 //function : NamePredicate::Value
41 //purpose  : 
42 //=======================================================================
43
44 bool SMESH_HypoFilter::NamePredicate::IsOk (const SMESH_Hypothesis* aHyp,
45                                             const TopoDS_Shape&     /*aShape*/ ) const
46 {
47   return ( _name == aHyp->GetName() );
48 }
49
50 //=======================================================================
51 //function : TypePredicate::Value
52 //purpose  : 
53 //=======================================================================
54
55 int SMESH_HypoFilter::TypePredicate::Value( const SMESH_Hypothesis* aHyp ) const
56 {
57   return aHyp->GetType();
58 };
59
60 //=======================================================================
61 //function : DimPredicate::Value
62 //purpose  : 
63 //=======================================================================
64
65 int SMESH_HypoFilter::DimPredicate::Value( const SMESH_Hypothesis* aHyp ) const
66 {
67   return aHyp->GetDim();
68 }
69
70 //=======================================================================
71 //function : ApplicablePredicate::IsOk
72 //purpose  : 
73 //=======================================================================
74
75 bool SMESH_HypoFilter::ApplicablePredicate::IsOk(const SMESH_Hypothesis* aHyp,
76                                                  const TopoDS_Shape&     /*aShape*/) const
77 {
78   return SMESH_subMesh::IsApplicableHypotesis( aHyp, (TopAbs_ShapeEnum)_shapeType );
79 };
80
81 //=======================================================================
82 //function : IsAuxiliaryPredicate::IsOk
83 //purpose  : 
84 //=======================================================================
85
86 bool SMESH_HypoFilter::IsAuxiliaryPredicate::IsOk(const SMESH_Hypothesis* aHyp,
87                                                   const TopoDS_Shape&     /*aShape*/) const
88 {
89   return aHyp->IsAuxiliary();
90 };
91
92 //=======================================================================
93 //function : ApplicablePredicate::ApplicablePredicate
94 //purpose  : 
95 //=======================================================================
96
97 SMESH_HypoFilter::ApplicablePredicate::ApplicablePredicate( const TopoDS_Shape& theShape )
98 {
99   _shapeType = ( theShape.IsNull() ? TopAbs_SHAPE : theShape.ShapeType());
100 }
101
102 //=======================================================================
103 //function : InstancePredicate::IsOk
104 //purpose  : 
105 //=======================================================================
106
107 bool SMESH_HypoFilter::InstancePredicate::IsOk(const SMESH_Hypothesis* aHyp,
108                                                const TopoDS_Shape&     /*aShape*/) const
109 {
110   return _hypo == aHyp;
111 }
112
113 //=======================================================================
114 //function : IsAssignedToPredicate::IsOk
115 //purpose  : 
116 //=======================================================================
117
118 bool SMESH_HypoFilter::IsAssignedToPredicate::IsOk(const SMESH_Hypothesis* aHyp,
119                                                    const TopoDS_Shape&     aShape) const
120 {
121   return ( !_mainShape.IsNull() && !aShape.IsNull() && _mainShape.IsSame( aShape ));
122 }
123
124 //================================================================================
125 /*!
126  * \brief Finds shapes preferable over _shape due to sub-mesh order
127  */
128 //================================================================================
129
130 void SMESH_HypoFilter::IsMoreLocalThanPredicate::findPreferable()
131 {
132   const int shapeID = _mesh.GetMeshDS()->ShapeToIndex( _shape );
133   const TListOfListOfInt& listOfShapeIDList = _mesh.GetMeshOrder();
134   TListOfListOfInt::const_iterator  listsIt = listOfShapeIDList.begin();
135   for ( ; listsIt != listOfShapeIDList.end(); ++listsIt )
136   {
137     const TListOfInt& idList = *listsIt;
138     TListOfInt::const_iterator idIt =
139       std::find( idList.begin(), idList.end(), shapeID );
140     if ( idIt != idList.end() && *idIt != idList.front() )
141     {
142       for ( --idIt; true; --idIt )
143       {
144         const TopoDS_Shape& shape = _mesh.GetMeshDS()->IndexToShape( *idIt );
145         if ( !shape.IsNull())
146           _preferableShapes.Add( shape );
147
148         if ( idIt == idList.begin() )
149           break;
150       }
151     }
152   }
153 }
154
155 //=======================================================================
156 //function : IsMoreLocalThanPredicate::IsOk
157 //purpose  : 
158 //=======================================================================
159
160 bool SMESH_HypoFilter::IsMoreLocalThanPredicate::IsOk(const SMESH_Hypothesis* aHyp,
161                                                       const TopoDS_Shape&     aShape) const
162 {
163   if ( aShape.IsSame( _mesh.GetShapeToMesh() ) ||  // aHyp is global
164        aShape.IsSame( _shape ))
165     return false;
166
167   if ( SMESH_MesherHelper::IsSubShape( aShape, /*mainShape=*/_shape ))
168     return true;
169
170   if ( aShape.ShapeType() == TopAbs_COMPOUND && 
171        !SMESH_MesherHelper::IsSubShape( _shape, /*mainShape=*/aShape)) // issue 0020963
172   {
173     for ( int type = TopAbs_SOLID; type < TopAbs_SHAPE; ++type )
174       if ( aHyp->GetDim() == SMESH_Gen::GetShapeDim( TopAbs_ShapeEnum( type )))
175         for ( TopExp_Explorer exp( aShape, TopAbs_ShapeEnum( type )); exp.More(); exp.Next())
176           if ( SMESH_MesherHelper::IsSubShape( exp.Current(), /*mainShape=*/_shape ))
177             return true;
178   }
179
180   if ( _preferableShapes.Contains( aShape ))
181     return true; // issue 21559, Mesh_6
182
183   return false;
184 }
185
186 //=======================================================================
187 //function : SMESH_HypoFilter
188 //purpose  : 
189 //=======================================================================
190
191 SMESH_HypoFilter::SMESH_HypoFilter()
192   : myNbPredicates(0)
193 {
194 }
195
196 //=======================================================================
197 //function : SMESH_HypoFilter
198 //purpose  : 
199 //=======================================================================
200
201 SMESH_HypoFilter::SMESH_HypoFilter( SMESH_HypoPredicate* aPredicate, bool notNegate )
202   : myNbPredicates(0)
203 {
204   add( notNegate ? AND : AND_NOT, aPredicate );
205 }
206
207 //=======================================================================
208 //function : And
209 //purpose  : 
210 //=======================================================================
211
212 SMESH_HypoFilter & SMESH_HypoFilter::And( SMESH_HypoPredicate* aPredicate )
213 {
214   add( AND, aPredicate );
215   return *this;
216 }
217
218 //=======================================================================
219 //function : AndNot
220 //purpose  : 
221 //=======================================================================
222
223 SMESH_HypoFilter & SMESH_HypoFilter::AndNot( SMESH_HypoPredicate* aPredicate )
224 {
225   add( AND_NOT, aPredicate );
226   return *this;
227 }
228
229 //=======================================================================
230 //function : Or
231 //purpose  : 
232 //=======================================================================
233
234 SMESH_HypoFilter & SMESH_HypoFilter::Or( SMESH_HypoPredicate* aPredicate )
235 {
236   add( OR, aPredicate );
237   return *this;
238 }
239
240 //=======================================================================
241 //function : OrNot
242 //purpose  : Return predicates
243 //=======================================================================
244
245 SMESH_HypoFilter & SMESH_HypoFilter::OrNot( SMESH_HypoPredicate* aPredicate )
246 {
247   add( OR_NOT, aPredicate );
248   return *this;
249 }
250
251 //=======================================================================
252 //function : Is
253 //purpose  : 
254 //=======================================================================
255
256 SMESH_HypoPredicate* SMESH_HypoFilter::Is(const SMESH_Hypothesis* theHypo)
257 {
258   return new InstancePredicate( theHypo );
259 }
260
261 //=======================================================================
262 //function : IsAlgo
263 //purpose  : 
264 //=======================================================================
265
266 SMESH_HypoPredicate* SMESH_HypoFilter::IsAlgo()
267 {
268   return new TypePredicate( MORE, SMESHDS_Hypothesis::PARAM_ALGO );
269 }
270
271 //=======================================================================
272 //function : IsAuxiliary
273 //purpose  : 
274 //=======================================================================
275
276 SMESH_HypoPredicate* SMESH_HypoFilter::IsAuxiliary()
277 {
278   return new IsAuxiliaryPredicate();
279 }
280
281
282 //=======================================================================
283 //function : IsGlobal
284 //purpose  : 
285 //=======================================================================
286
287  SMESH_HypoPredicate* SMESH_HypoFilter::IsGlobal(const TopoDS_Shape& theMainShape)
288 {
289   return new IsAssignedToPredicate( theMainShape );
290 }
291
292 //=======================================================================
293 //function : IsAssignedTo
294 //purpose  : 
295 //=======================================================================
296
297  SMESH_HypoPredicate* SMESH_HypoFilter::IsAssignedTo(const TopoDS_Shape& theShape)
298 {
299   return new IsAssignedToPredicate( theShape );
300 }
301
302 //=======================================================================
303 //function : HasName
304 //purpose  : 
305 //=======================================================================
306
307 SMESH_HypoPredicate* SMESH_HypoFilter::HasName(const string & theName)
308 {
309   return new NamePredicate( theName );
310 }
311
312 //=======================================================================
313 //function : HasDim
314 //purpose  : 
315 //=======================================================================
316
317 SMESH_HypoPredicate* SMESH_HypoFilter::HasDim(const int theDim)
318 {
319   return new DimPredicate( EQUAL, theDim );
320 }
321
322 //=======================================================================
323 //function : IsApplicableTo
324 //purpose  : 
325 //=======================================================================
326
327 SMESH_HypoPredicate* SMESH_HypoFilter::IsApplicableTo(const TopoDS_Shape& theShape)
328 {
329   return new ApplicablePredicate( theShape );
330 }
331
332 //=======================================================================
333 //function : IsMoreLocalThan
334 //purpose  : 
335 //=======================================================================
336
337 SMESH_HypoPredicate* SMESH_HypoFilter::IsMoreLocalThan(const TopoDS_Shape& theShape,
338                                                        const SMESH_Mesh&   theMesh)
339 {
340   return new IsMoreLocalThanPredicate( theShape, theMesh );
341 }
342
343 //=======================================================================
344 //function : HasType
345 //purpose  : 
346 //=======================================================================
347
348 SMESH_HypoPredicate* SMESH_HypoFilter::HasType(const int theHypType)
349 {
350   return new TypePredicate( EQUAL, theHypType );
351 }
352
353 //=======================================================================
354 //function : IsOk
355 //purpose  : 
356 //=======================================================================
357
358 bool SMESH_HypoFilter::IsOk (const SMESH_Hypothesis* aHyp,
359                              const TopoDS_Shape&     aShape) const
360 {
361   if ( IsEmpty() )
362     return true;
363
364   bool ok = ( myPredicates[0]->_logical_op <= AND_NOT );
365   for ( int i = 0; i < myNbPredicates; ++i )
366   {
367     bool ok2 = myPredicates[i]->IsOk( aHyp, aShape );
368     switch ( myPredicates[i]->_logical_op ) {
369     case AND:     ok = ok && ok2; break;
370     case AND_NOT: ok = ok && !ok2; break;
371     case OR:      ok = ok || ok2; break;
372     case OR_NOT:  ok = ok || !ok2; break;
373     default:;
374     }
375   }
376   return ok;
377 }
378
379 //=======================================================================
380 //function : Init
381 //purpose  : 
382 //=======================================================================
383
384 SMESH_HypoFilter & SMESH_HypoFilter::Init  ( SMESH_HypoPredicate* aPredicate, bool notNegate )
385 {
386   SMESH_HypoPredicate** pred = &myPredicates[0];
387   SMESH_HypoPredicate** end  = &myPredicates[myNbPredicates];
388   for ( ; pred != end; ++pred )
389     delete *pred;
390   myNbPredicates = 0;
391
392   add( notNegate ? AND : AND_NOT, aPredicate );
393   return *this;
394 }
395
396
397 //=======================================================================
398 //function : IsOk
399 //purpose  : 
400 //=======================================================================
401
402 SMESH_HypoFilter::~SMESH_HypoFilter()
403 {
404   SMESH_HypoPredicate** pred = &myPredicates[0];
405   SMESH_HypoPredicate** end  = &myPredicates[myNbPredicates];
406   for ( ; pred != end; ++pred )
407     delete *pred;
408   myNbPredicates = 0;
409 }
410
411
412