0031682: Visualization - Prs3d_ShadingAspect::SetTransparency() has no effect with...
[occt.git] / src / DNaming / DNaming_BooleanOperationDriver.cxx
1 // Created on: 2009-05-05
2 // Created by: Sergey ZARITCHNY
3 // Copyright (c) 2009-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <Adaptor3d_HCurve.hxx>
18 #include <BRepAdaptor_Surface.hxx>
19 #include <BRepAlgoAPI_BooleanOperation.hxx>
20 #include <BRepAlgoAPI_Common.hxx>
21 #include <BRepAlgoAPI_Cut.hxx>
22 #include <BRepAlgoAPI_Fuse.hxx>
23 #include <BRepAlgoAPI_Section.hxx>
24 #include <BRepCheck_Analyzer.hxx>
25 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
26 #include <BRepCheck_ListOfStatus.hxx>
27 #include <BRepCheck_Result.hxx>
28 #include <BRepLib.hxx>
29 #include <DNaming.hxx>
30 #include <DNaming_BooleanOperationDriver.hxx>
31 #include <GeomAbs_SurfaceType.hxx>
32 #include <ModelDefinitions.hxx>
33 #include <Precision.hxx>
34 #include <Standard_GUID.hxx>
35 #include <Standard_Real.hxx>
36 #include <Standard_Type.hxx>
37 #include <TDataStd_Integer.hxx>
38 #include <TDataStd_Real.hxx>
39 #include <TDF_Label.hxx>
40 #include <TFunction_Function.hxx>
41 #include <TFunction_Logbook.hxx>
42 #include <TNaming.hxx>
43 #include <TNaming_Builder.hxx>
44 #include <TNaming_NamedShape.hxx>
45 #include <TopExp.hxx>
46 #include <TopExp_Explorer.hxx>
47 #include <TopLoc_Location.hxx>
48 #include <TopoDS.hxx>
49 #include <TopoDS_Iterator.hxx>
50 #include <TopoDS_Solid.hxx>
51 #include <TopoDS_Vertex.hxx>
52 #include <TopTools_IndexedMapOfShape.hxx>
53 #include <TopTools_ListIteratorOfListOfShape.hxx>
54 #include <TopTools_MapOfShape.hxx>
55
56 IMPLEMENT_STANDARD_RTTIEXT(DNaming_BooleanOperationDriver,TFunction_Driver)
57
58 static Standard_Boolean FixSameParameter(const TopoDS_Shape&    theShape,
59                                              BRepCheck_Analyzer&    theAnalyzer,
60                                              const Standard_Boolean bIgnoreNotSPErrors = Standard_False );
61 static void FindSPErrorEdges(const TopoDS_Shape&         theShape,
62                              const BRepCheck_Analyzer&   theAnalyzer,
63                              TopTools_IndexedMapOfShape& theMap);
64
65 static Standard_Boolean FindOtherErrors(const TopoDS_Shape&               theShape,
66                                         const BRepCheck_Analyzer&         theAnalyzer,
67                                         const TopTools_IndexedMapOfShape& theMap);
68
69 //=======================================================================
70 //function : DNaming_BooleanOperationDriver
71 //purpose  : Constructor
72 //=======================================================================
73 DNaming_BooleanOperationDriver::DNaming_BooleanOperationDriver()
74 {}
75
76 //=======================================================================
77 //function : Validate
78 //purpose  : Validates labels of a function in <log>.
79 //=======================================================================
80 void DNaming_BooleanOperationDriver::Validate(Handle(TFunction_Logbook)&) const
81 {}
82
83 //=======================================================================
84 //function : MustExecute
85 //purpose  : Analyse in <log> if the loaded function must be executed
86 //=======================================================================
87 Standard_Boolean DNaming_BooleanOperationDriver::MustExecute(const Handle(TFunction_Logbook)&) const
88 {
89   return Standard_True;
90 }
91
92 //=======================================================================
93 //function : Execute
94 //purpose  : Execute the function and push in <log> the impacted labels
95 //=======================================================================
96 Standard_Integer DNaming_BooleanOperationDriver::Execute(Handle(TFunction_Logbook)& theLog) const
97 {
98   Handle(TFunction_Function) aFunction;
99   Label().FindAttribute(TFunction_Function::GetID(),aFunction);
100   if(aFunction.IsNull()) return -1;
101
102 //  Handle(TDataStd_UAttribute) anObject = DNaming::GetObjectFromFunction(aFunction);
103 //  if(anObject.IsNull()) return -1;
104 //  Handle(TNaming_NamedShape) anObjectNS = DNaming::GetObjectValue(anObject);
105   Handle(TFunction_Function) aPrevFun = DNaming::GetPrevFunction(aFunction);
106   if(aPrevFun.IsNull()) return -1;
107   const TDF_Label& aLab = RESPOSITION(aPrevFun);
108   Handle(TNaming_NamedShape) anObjectNS;
109   aLab.FindAttribute(TNaming_NamedShape::GetID(), anObjectNS);
110   if (anObjectNS.IsNull() || anObjectNS->IsEmpty()) {
111 #ifdef OCCT_DEBUG
112     std::cout<<"BooleanOperationDriver:: Object is empty"<<std::endl;
113 #endif
114     aFunction->SetFailure(WRONG_ARGUMENT);
115     return -1;
116   }
117
118   Handle(TDataStd_UAttribute) aToolObj = DNaming::GetObjectArg(aFunction,BOOL_TOOL);
119   Handle(TNaming_NamedShape) aToolNS = DNaming::GetObjectValue(aToolObj);
120
121   if (aToolNS.IsNull() || aToolNS->IsEmpty()) {
122 #ifdef OCCT_DEBUG
123     std::cout<<"BooleanOperationDriver:: Tool is empty"<<std::endl;
124 #endif
125     aFunction->SetFailure(WRONG_ARGUMENT);
126     return -1;
127   }
128
129   TopoDS_Shape aTOOL = aToolNS->Get();
130   TopoDS_Shape anOBJECT = anObjectNS->Get();
131   if (aTOOL.IsNull() || anOBJECT.IsNull()) {
132 #ifdef OCCT_DEBUG
133     std::cout<<"BooleanOperationDriver:: Tool is null"<<std::endl;
134 #endif
135     aFunction->SetFailure(WRONG_ARGUMENT);
136     return -1;
137   }
138
139   Standard_Boolean anIsDone = Standard_False;
140
141   //case FUSE 
142   if(aFunction->GetDriverGUID() == FUSE_GUID){
143     BRepAlgoAPI_Fuse aMkFuse (anOBJECT, aTOOL);
144     anIsDone = CheckAndLoad(aMkFuse, aFunction);
145   }
146   //case CUT
147   else if(aFunction->GetDriverGUID() == CUT_GUID){
148     BRepAlgoAPI_Cut aMkCut (anOBJECT, aTOOL);    
149     anIsDone = CheckAndLoad(aMkCut, aFunction);
150   } 
151   // case COMMON
152   else if(aFunction->GetDriverGUID() == COMMON_GUID){
153     BRepAlgoAPI_Common aMkCom (anOBJECT, aTOOL);    
154     anIsDone = CheckAndLoad(aMkCom, aFunction);
155   }
156     // case SECTION
157   else if(aFunction->GetDriverGUID() == SECTION_GUID){
158     BRepAlgoAPI_Section aMkSect (anOBJECT, aTOOL);    
159     anIsDone = CheckAndLoad(aMkSect, aFunction);
160   }
161   else {
162     aFunction->SetFailure(UNSUPPORTED_FUNCTION);
163     return -1;
164   }
165   if(!anIsDone) return -1;
166   else {
167     theLog->SetValid(RESPOSITION(aFunction),Standard_True);  
168     aFunction->SetFailure(DONE);
169     return 0;
170   }
171
172 }
173 //===================================================================
174 //=======================================================================
175 //function : ShapeType
176 //purpose  :
177 //=======================================================================
178
179 static TopAbs_ShapeEnum ShapeType(const TopoDS_Shape& theShape) {
180   TopAbs_ShapeEnum TypeSh = theShape.ShapeType();
181   if (TypeSh == TopAbs_COMPOUND || TypeSh == TopAbs_COMPSOLID) {
182     TopoDS_Iterator itr(theShape);
183     if (!itr.More()) return TypeSh;
184     TypeSh = ShapeType(itr.Value());
185     if(TypeSh == TopAbs_COMPOUND) return TypeSh;
186     itr.Next();
187     for(; itr.More(); itr.Next())
188       if(ShapeType(itr.Value()) != TypeSh) return TopAbs_COMPOUND;
189   }
190   return TypeSh;
191 }
192 //=====================================================================
193 static Standard_Boolean IsValidSurfType(const TopoDS_Face& theFace) {
194   BRepAdaptor_Surface anAdapt(theFace);
195   Handle( Adaptor3d_HCurve ) aBasisCurve;
196   const GeomAbs_SurfaceType& aType = anAdapt.GetType();
197   if(aType == GeomAbs_Sphere)
198     return Standard_True;
199 /*  if(aType == GeomAbs_Cylinder || aType == GeomAbs_Cone || Type == GeomAbs_Sphere)
200     return Standard_True;
201   else if(aType == GeomAbs_SurfaceOfRevolution){
202     aBasisCurve = anAdapt.BasisCurve();
203     if (aBasisCurve->GetType() == GeomAbs_Line)
204       return Standard_True;
205   }
206   else if(aType == GeomAbs_SurfaceOfExtrusion) {
207     aBasisCurve = anAdapt.BasisCurve();
208     if (aBasisCurve->GetType() == GeomAbs_Circle || aBasisCurve->GetType() == GeomAbs_Ellipse)
209       return Standard_True;
210   }
211 */
212 #ifdef OCCT_DEBUG
213   //ModDbgTools_Write(theFace, "Surf");
214 #endif
215   return Standard_False;
216 }
217 //=======================================================================
218 //function : IsWRCase
219 //purpose  :
220 //=======================================================================
221
222 static Standard_Boolean IsWRCase(const BRepAlgoAPI_BooleanOperation& MS) {
223
224   const TopoDS_Shape& ObjSh = MS.Shape1();
225   const TopoDS_Shape& ToolSh = MS.Shape2();
226   const TopAbs_ShapeEnum& Type1 = ShapeType(ObjSh);
227   if(Type1  == TopAbs_COMPOUND || Type1 > TopAbs_FACE) return Standard_False;
228   const TopAbs_ShapeEnum& Type2 = ShapeType(ToolSh);
229   if(Type2  == TopAbs_COMPOUND || Type2 > TopAbs_FACE) return Standard_False;
230   TopTools_ListOfShape aList;
231
232   if(Type1 != TopAbs_FACE) {
233     TopExp_Explorer anExp(ObjSh, TopAbs_FACE);
234     for(;anExp.More();anExp.Next()) {
235       if(IsValidSurfType(TopoDS::Face(anExp.Current())))
236         aList.Append(anExp.Current());
237     }
238   } else
239        if(IsValidSurfType(TopoDS::Face(ObjSh)))
240         aList.Append(ObjSh);
241
242   if(aList.Extent() == 0) {
243     if(Type2 != TopAbs_FACE) {
244       TopExp_Explorer anExp(ToolSh, TopAbs_FACE);
245       for(;anExp.More();anExp.Next()) {
246         if(IsValidSurfType(TopoDS::Face(anExp.Current())))
247           aList.Append(anExp.Current());
248       }
249     } else
250       if(IsValidSurfType(TopoDS::Face(ToolSh)))
251         aList.Append(ToolSh);
252   }
253   if(aList.Extent() > 0) return Standard_True;
254   return Standard_False;
255 }
256
257 //=======================================================================
258 //function : LoadNamingDS
259 //purpose  : 
260 //=======================================================================
261 void DNaming_BooleanOperationDriver::LoadNamingDS (const TDF_Label& theResultLabel, 
262                                            BRepAlgoAPI_BooleanOperation& MS) const
263 {
264
265   const TopoDS_Shape& ResSh = MS.Shape();
266   const TopoDS_Shape& ObjSh = MS.Shape1();
267   const TopoDS_Shape& ToolSh = MS.Shape2();
268  if (ResSh.IsNull()) {
269 #ifdef OCCT_DEBUG
270    std::cout<<"LoadFuseNamingDS: The result of the boolean operation is null"<<std::endl;
271 #endif
272     return;
273   }
274
275   // LoadResult
276   DNaming::LoadResult(theResultLabel, MS);
277
278   TopTools_DataMapOfShapeShape SubShapes;
279   TopExp_Explorer Exp(ResSh, TopAbs_FACE);
280   for (; Exp.More(); Exp.Next()) {
281     SubShapes.Bind(Exp.Current(),Exp.Current());
282   }
283
284  // Naming of modified faces: 
285   TNaming_Builder modFB (theResultLabel.NewChild()); //FindChild(1,Standard_True)); 
286   DNaming::LoadAndOrientModifiedShapes (MS, ObjSh,  TopAbs_FACE, modFB,SubShapes);  
287   DNaming::LoadAndOrientModifiedShapes (MS, ToolSh, TopAbs_FACE, modFB, SubShapes);
288
289   // Naming of deleted faces:
290   if(MS.HasDeleted()){
291     TNaming_Builder delB (theResultLabel.NewChild());  // FindChild(2,Standard_True)); 
292     DNaming::LoadDeletedShapes  (MS, ObjSh,  TopAbs_FACE, delB);
293     DNaming::LoadDeletedShapes  (MS, ToolSh, TopAbs_FACE, delB);
294   }
295
296   if(IsWRCase(MS)) {
297   // Edges 
298     Exp.Init(ResSh, TopAbs_EDGE);
299     for (; Exp.More(); Exp.Next()) {
300       SubShapes.Bind(Exp.Current(),Exp.Current());
301     }
302   
303     const TopTools_ListOfShape& aList = MS.SectionEdges();
304     Standard_Boolean theCase(Standard_False);
305     TopTools_MapOfShape aView;
306     if(aList.Extent() > 0 && aList.Extent() < 3) 
307       theCase = Standard_True;
308     
309     TopTools_ListIteratorOfListOfShape it(aList);
310     for(;it.More();it.Next()) {
311       TopoDS_Shape newShape = it.Value();
312       if (SubShapes.IsBound(newShape)) 
313         newShape.Orientation((SubShapes(newShape)).Orientation());
314       TNaming_Builder secED (theResultLabel.NewChild());
315       secED.Generated(newShape);
316       if(theCase) {
317         TopoDS_Vertex Vfirst, Vlast;
318         TopExp::Vertices(TopoDS::Edge(newShape), Vfirst, Vlast, Standard_True);
319         if(aView.Add(Vfirst)) {
320           TNaming_Builder secV (theResultLabel.NewChild());
321           secV.Generated(Vfirst);
322         }
323         if(aView.Add(Vlast)) {
324           TNaming_Builder secV (theResultLabel.NewChild());
325           secV.Generated(Vlast);
326         }
327       }
328     }
329   }
330 }
331
332 //=======================================================================
333 //function : LoadNamingDS
334 //purpose  : 
335 //=======================================================================
336 void DNaming_BooleanOperationDriver::LoadSectionNDS (const TDF_Label& theResultLabel, 
337                                            BRepAlgoAPI_BooleanOperation& MS) const
338 {
339
340   const TopoDS_Shape& ResSh = MS.Shape();
341   const TopoDS_Shape& ObjSh = MS.Shape1();
342   const TopoDS_Shape& ToolSh = MS.Shape2();
343  if (ResSh.IsNull()) {
344 #ifdef OCCT_DEBUG
345    std::cout<<"LoadSectionNamingDS: The result of the boolean operation is null"<<std::endl;
346 #endif
347     return;
348   }
349
350   // LoadResult
351   DNaming::LoadResult(theResultLabel, MS);
352
353   TopTools_DataMapOfShapeShape SubShapes;
354   TopExp_Explorer Exp(ResSh, TopAbs_EDGE);
355   for (; Exp.More(); Exp.Next()) {
356     SubShapes.Bind(Exp.Current(),Exp.Current());
357   }
358
359  // Naming of modified faces: 
360   TNaming_Builder genEdB (theResultLabel.NewChild()); //FindChild(1,Standard_True)); 
361   DNaming::LoadAndOrientGeneratedShapes (MS, ObjSh,  TopAbs_FACE, genEdB,SubShapes);  
362   DNaming::LoadAndOrientGeneratedShapes (MS, ToolSh, TopAbs_FACE, genEdB, SubShapes);
363
364 }
365 //=======================================================================
366 //function : CheckAndLoad
367 //purpose  : checks result of operation and performs Topological Naming
368 //=======================================================================
369 Standard_Boolean DNaming_BooleanOperationDriver::CheckAndLoad
370   (BRepAlgoAPI_BooleanOperation& theMkOpe, 
371    const Handle(TFunction_Function)& theFunction) const
372 {
373
374   if (theMkOpe.IsDone() && !theMkOpe.Shape().IsNull()) {
375     if (theMkOpe.Shape().ShapeType() == TopAbs_COMPOUND) {
376       if (theMkOpe.Shape().NbChildren() == 0) {
377         theFunction->SetFailure(NULL_RESULT);
378         return Standard_False;
379       }      
380     }
381     BRepCheck_Analyzer aCheck (theMkOpe.Shape());
382     Standard_Boolean aResIsValid = Standard_True;
383     if(!aCheck.IsValid(theMkOpe.Shape())) 
384       aResIsValid = FixSameParameter(theMkOpe.Shape(), aCheck);
385     if (aResIsValid) {
386       if(theFunction->GetDriverGUID() == FUSE_GUID) {
387         LoadNamingDS(RESPOSITION(theFunction), theMkOpe);
388       }
389       else if(theFunction->GetDriverGUID() == CUT_GUID) {
390         LoadNamingDS(RESPOSITION(theFunction), theMkOpe); // the same naming only for case of solids
391       } else if(theFunction->GetDriverGUID() == COMMON_GUID) {
392             LoadNamingDS(RESPOSITION(theFunction), theMkOpe); 
393       } else if(theFunction->GetDriverGUID() == SECTION_GUID) {
394             LoadSectionNDS(RESPOSITION(theFunction), theMkOpe); 
395           }
396       
397       theFunction->SetFailure(DONE);
398       return Standard_True;
399     } else {
400       theFunction->SetFailure(RESULT_NOT_VALID);
401       return Standard_False;
402     }
403   }
404   theFunction->SetFailure(ALGO_FAILED);
405   return Standard_False;
406 }
407
408 // ------------------------------------------------------------------------
409 // static function: FixSameParameter
410 // purpose:
411 // ------------------------------------------------------------------------
412 Standard_Boolean FixSameParameter(const TopoDS_Shape&    theShape,
413                                       BRepCheck_Analyzer&    theAnalyzer,
414                                       const Standard_Boolean bIgnoreNotSPErrors) {
415
416   Standard_Integer bDoFix = Standard_True;
417   TopTools_IndexedMapOfShape aMapE;
418
419   FindSPErrorEdges(theShape, theAnalyzer, aMapE);
420
421   if(!bIgnoreNotSPErrors) {
422     if(FindOtherErrors(theShape, theAnalyzer, aMapE)) {
423       bDoFix = Standard_False;
424     }
425   }
426
427   if(bDoFix) {
428     Standard_Integer i = 0;
429
430     for(i = 1; i <= aMapE.Extent(); i++) {
431       const TopoDS_Shape& aE = aMapE(i);
432       BRepLib::SameParameter(aE, Precision::Confusion(), Standard_True);
433     }
434
435     if(!aMapE.IsEmpty()) {
436       theAnalyzer.Init(theShape);
437       return theAnalyzer.IsValid();
438     }
439   }
440   return Standard_False;
441 }
442
443 // ------------------------------------------------------------------------
444 // static function: FindSPErrorEdges
445 // purpose:
446 // ------------------------------------------------------------------------
447 void FindSPErrorEdges(const TopoDS_Shape&         theShape,
448                       const BRepCheck_Analyzer&   theAnalyzer,
449                       TopTools_IndexedMapOfShape& theMap) {
450   BRepCheck_ListIteratorOfListOfStatus itl;
451
452   TopoDS_Iterator anIt(theShape);
453
454   for (; anIt.More(); anIt.Next()) {
455     FindSPErrorEdges(anIt.Value(), theAnalyzer, theMap);
456   }
457
458   if(theShape.ShapeType() == TopAbs_FACE) {
459     TopExp_Explorer anExpE(theShape, TopAbs_EDGE);
460     
461     for(; anExpE.More(); anExpE.Next()) {
462       Handle(BRepCheck_Result) aResult = theAnalyzer.Result(anExpE.Current());
463
464       if(aResult.IsNull() || theMap.Contains(anExpE.Current()))
465         continue;
466
467       for (aResult->InitContextIterator();
468            aResult->MoreShapeInContext(); 
469            aResult->NextShapeInContext()) {
470         if (aResult->ContextualShape().IsSame(theShape)) {
471           itl.Initialize(aResult->StatusOnShape());
472
473           for(; itl.More(); itl.Next()) {
474             if((itl.Value() == BRepCheck_InvalidSameParameterFlag) ||
475                (itl.Value() == BRepCheck_InvalidCurveOnSurface)) {
476               theMap.Add(anExpE.Current());
477               break;
478             }
479           }
480         }
481       }
482     }
483   }
484   else if(theShape.ShapeType() == TopAbs_EDGE) {
485     Handle(BRepCheck_Result) aResult = theAnalyzer.Result(theShape);
486     itl.Initialize(aResult->Status());
487     
488     for(; itl.More(); itl.Next()) {
489       if((itl.Value() == BRepCheck_InvalidSameParameterFlag) ||
490          (itl.Value() == BRepCheck_InvalidCurveOnSurface)) {
491         theMap.Add(theShape);
492         break;
493       }
494     }
495   }
496 }
497
498 // ------------------------------------------------------------------------
499 // static function: FindOtherErrors
500 // purpose:
501 // ------------------------------------------------------------------------
502 Standard_Boolean FindOtherErrors(const TopoDS_Shape&               theShape,
503                                  const BRepCheck_Analyzer&         theAnalyzer,
504                                  const TopTools_IndexedMapOfShape& theMap) {
505
506   Standard_Boolean bOtherFound = Standard_False;
507   BRepCheck_ListIteratorOfListOfStatus itl;
508   TopoDS_Iterator anIt(theShape);
509   
510   for (; anIt.More(); anIt.Next()) {
511     if(FindOtherErrors(anIt.Value(), theAnalyzer, theMap))
512       return Standard_True;
513   }
514   Handle(BRepCheck_Result) aResult = theAnalyzer.Result(theShape);
515   
516   if (!aResult.IsNull()) {
517
518     if(!theMap.Contains(theShape) && !aResult->Status().IsEmpty()) {
519       if(aResult->Status().First() != BRepCheck_NoError) {
520         bOtherFound = Standard_True;
521
522         //
523         TopExp_Explorer anExpF(theShape, TopAbs_FACE);
524
525         for(; anExpF.More(); anExpF.Next()) {
526           TopExp_Explorer anExpE(anExpF.Current(), TopAbs_EDGE);
527
528           for(; anExpE.More(); anExpE.Next()) {
529             Handle(BRepCheck_Result) aResultE = theAnalyzer.Result(anExpE.Current());
530
531             if(aResultE.IsNull())
532               continue;
533             bOtherFound = Standard_False;
534
535             for (aResultE->InitContextIterator();
536                  aResultE->MoreShapeInContext(); 
537                  aResultE->NextShapeInContext()) {
538
539               if (aResultE->ContextualShape().IsSame(anExpF.Current()) ||
540                   aResultE->ContextualShape().IsSame(theShape)) {
541                 itl.Initialize(aResultE->StatusOnShape());
542
543                 if(!itl.More())
544                   continue;
545
546                 if(itl.Value() != BRepCheck_NoError) {
547                   if(theMap.Contains(anExpE.Current())) {
548                     for(; itl.More(); itl.Next()) {
549
550                       if((itl.Value() != BRepCheck_InvalidSameParameterFlag) &&
551                          (itl.Value() != BRepCheck_InvalidCurveOnSurface) &&
552                          (itl.Value() != BRepCheck_NoError)) {
553                         return Standard_True;
554                       }
555                     }
556                   }
557                   else {
558                     return Standard_True;
559                   }
560                 }
561               }
562             }
563           }
564         }
565         // 
566
567         if(!bOtherFound) {
568           for (aResult->InitContextIterator(); 
569                !bOtherFound && aResult->MoreShapeInContext(); 
570                aResult->NextShapeInContext()) {
571             if(!aResult->StatusOnShape().IsEmpty()) {
572               bOtherFound = (aResult->StatusOnShape().First() != BRepCheck_NoError);
573             }
574           }
575         }
576       }
577       else {
578         TopAbs_ShapeEnum aType = theShape.ShapeType();
579
580         if((aType == TopAbs_VERTEX) ||
581            (aType == TopAbs_EDGE) ||
582            (aType == TopAbs_WIRE) ||
583            (aType == TopAbs_FACE) ||
584            (aType == TopAbs_SHELL)) {
585           for (aResult->InitContextIterator();
586                aResult->MoreShapeInContext(); 
587                aResult->NextShapeInContext()) {
588             if(!aResult->StatusOnShape().IsEmpty()) {
589               if(aResult->StatusOnShape().First() != BRepCheck_NoError) {
590                 return Standard_True;
591               }
592             }
593           }
594         }
595       }
596     }
597     else {
598       itl.Initialize(aResult->Status());
599       
600       for(; itl.More(); itl.Next()) {
601         if((itl.Value() != BRepCheck_InvalidSameParameterFlag) &&
602            (itl.Value() != BRepCheck_InvalidCurveOnSurface) &&
603            (itl.Value() != BRepCheck_NoError)) {
604           return Standard_True;
605         }
606       }
607     }
608   }
609   
610   return bOtherFound;
611 }