0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
[occt.git] / src / BRepCheck / BRepCheck_Analyzer.cxx
1 // Created on: 1995-12-08
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRepCheck_Analyzer.hxx>
19 #include <BRepCheck_Edge.hxx>
20 #include <BRepCheck_Face.hxx>
21 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
22 #include <BRepCheck_Result.hxx>
23 #include <BRepCheck_Shell.hxx>
24 #include <BRepCheck_Solid.hxx>
25 #include <BRepCheck_Vertex.hxx>
26 #include <BRepCheck_Wire.hxx>
27 #include <Standard_ErrorHandler.hxx>
28 #include <Standard_Failure.hxx>
29 #include <Standard_NoSuchObject.hxx>
30 #include <Standard_NullObject.hxx>
31 #include <TopExp_Explorer.hxx>
32 #include <TopoDS.hxx>
33 #include <TopoDS_Face.hxx>
34 #include <TopoDS_Iterator.hxx>
35 #include <TopoDS_Shape.hxx>
36 #include <TopTools_MapOfShape.hxx>
37
38 //=======================================================================
39 //function : Init
40 //purpose  : 
41 //=======================================================================
42 void BRepCheck_Analyzer::Init(const TopoDS_Shape& S,
43          const Standard_Boolean B)
44 {
45   if (S.IsNull()) {
46     throw Standard_NullObject();
47   }
48   myShape = S;
49   myMap.Clear();
50   Put(S,B);
51   Perform(S);
52 }
53 //=======================================================================
54 //function : Put
55 //purpose  : 
56 //=======================================================================
57 void BRepCheck_Analyzer::Put(const TopoDS_Shape& S,
58                              const Standard_Boolean B)
59 {
60   if (!myMap.IsBound(S)) {
61     Handle(BRepCheck_Result) HR;
62     switch (S.ShapeType()) {
63     case TopAbs_VERTEX:
64       HR = new BRepCheck_Vertex(TopoDS::Vertex(S));
65       break;
66     case TopAbs_EDGE:
67       HR = new BRepCheck_Edge(TopoDS::Edge(S));
68       Handle(BRepCheck_Edge)::DownCast(HR)->GeometricControls(B);
69       break;
70     case TopAbs_WIRE:
71       HR = new BRepCheck_Wire(TopoDS::Wire(S));
72       Handle(BRepCheck_Wire)::DownCast(HR)->GeometricControls(B);
73       break;
74     case TopAbs_FACE:
75       HR = new BRepCheck_Face(TopoDS::Face(S));
76       Handle(BRepCheck_Face)::DownCast(HR)->GeometricControls(B);
77       break;
78     case TopAbs_SHELL:
79       HR = new BRepCheck_Shell(TopoDS::Shell(S));
80       break;
81     case TopAbs_SOLID:
82       HR = new BRepCheck_Solid(TopoDS::Solid(S));
83       break;
84     case TopAbs_COMPSOLID:
85     case TopAbs_COMPOUND:
86       break;
87     default:
88       break;
89     }
90     myMap.Bind(S,HR);
91     for(TopoDS_Iterator theIterator(S);theIterator.More();theIterator.Next()) {
92       Put(theIterator.Value(),B); // performs minimum on each shape
93     }
94   }
95 }
96 //=======================================================================
97 //function : Perform
98 //purpose  : 
99 //=======================================================================
100 void BRepCheck_Analyzer::Perform(const TopoDS_Shape& S)
101 {
102   for(TopoDS_Iterator theIterator(S);theIterator.More();theIterator.Next()) 
103     Perform(theIterator.Value());
104   
105   //
106   TopAbs_ShapeEnum styp;
107   TopExp_Explorer exp;
108   //
109   styp = S.ShapeType();
110   
111   switch (styp) 
112   {
113   case TopAbs_VERTEX: 
114     // modified by NIZHNY-MKK  Wed May 19 16:56:16 2004.BEGIN
115     // There is no need to check anything.
116     //       if (myShape.IsSame(S)) {
117     //  myMap(S)->Blind();
118     //       }
119     // modified by NIZHNY-MKK  Wed May 19 16:56:23 2004.END
120   
121     break;
122   case TopAbs_EDGE:
123     {
124       Handle(BRepCheck_Result)& aRes = myMap(S);
125
126       try
127       {
128         BRepCheck_Status ste = Handle(BRepCheck_Edge)::
129           DownCast(aRes)->CheckPolygonOnTriangulation(TopoDS::Edge(S));
130
131         if(ste != BRepCheck_NoError)
132         {
133           Handle(BRepCheck_Edge)::DownCast(aRes)->SetStatus(ste);
134         }
135       }
136       catch(Standard_Failure const& anException) {
137 #ifdef OCCT_DEBUG
138         std::cout<<"BRepCheck_Analyzer : ";
139         anException.Print(std::cout);  
140         std::cout<<std::endl;
141 #endif
142         (void)anException;
143         if ( ! myMap(S).IsNull() )
144         {
145           myMap(S)->SetFailStatus(S);
146         }
147
148         if ( ! aRes.IsNull() )
149         {
150           aRes->SetFailStatus(S);
151         }
152       }
153
154       TopTools_MapOfShape MapS;
155       
156       for (exp.Init(S,TopAbs_VERTEX);exp.More(); exp.Next())
157       {
158         const TopoDS_Shape& aVertex = exp.Current();
159         try
160         {
161           OCC_CATCH_SIGNALS
162           if (MapS.Add(aVertex))
163             myMap(aVertex)->InContext(S);
164         }
165         catch(Standard_Failure const& anException) {
166 #ifdef OCCT_DEBUG
167           std::cout<<"BRepCheck_Analyzer : ";
168           anException.Print(std::cout);  
169           std::cout<<std::endl;
170 #endif
171           (void)anException;
172           if ( ! myMap(S).IsNull() )
173             myMap(S)->SetFailStatus(S);
174
175           Handle(BRepCheck_Result) aResOfVertex = myMap(aVertex);
176
177           if ( !aResOfVertex.IsNull() )
178           {
179             aResOfVertex->SetFailStatus(aVertex);
180             aResOfVertex->SetFailStatus(S);
181           }
182         }//catch(Standard_Failure)
183       }//for (exp.Init(S,TopAbs_VERTEX);exp.More(); exp.Next())
184     }
185     break;
186   case TopAbs_WIRE:
187     {
188     }
189     break;
190   case TopAbs_FACE:
191     {
192       TopTools_MapOfShape MapS;
193       for (exp.Init(S,TopAbs_VERTEX);exp.More(); exp.Next())
194       {
195         try
196         {
197           OCC_CATCH_SIGNALS
198           if (MapS.Add(exp.Current()))
199           {
200             myMap(exp.Current())->InContext(S);
201           }
202         }
203         catch(Standard_Failure const& anException) {
204 #ifdef OCCT_DEBUG
205           std::cout<<"BRepCheck_Analyzer : ";
206           anException.Print(std::cout);  
207           std::cout<<std::endl;
208 #endif
209           (void)anException;
210           if ( ! myMap(S).IsNull() )
211           {
212             myMap(S)->SetFailStatus(S);
213           }
214           
215           Handle(BRepCheck_Result) aRes = myMap(exp.Current());
216
217           if ( ! aRes.IsNull() )
218           {
219             aRes->SetFailStatus(exp.Current());
220             aRes->SetFailStatus(S);
221           }
222         }
223       }
224
225       Standard_Boolean performwire = Standard_True;
226       Standard_Boolean isInvalidTolerance = Standard_False;
227       MapS.Clear();
228       for (exp.Init(S,TopAbs_EDGE);exp.More(); exp.Next())
229       {
230         try
231         {
232           OCC_CATCH_SIGNALS
233           if (MapS.Add(exp.Current()))
234           {
235             Handle(BRepCheck_Result)& res = myMap(exp.Current());
236             res->InContext(S);
237             if (performwire)
238             {
239               for ( res->InitContextIterator();
240                     res->MoreShapeInContext();
241                     res->NextShapeInContext())
242               {
243                 if(res->ContextualShape().IsSame(S))
244                   break;
245               }
246
247               BRepCheck_ListIteratorOfListOfStatus itl(res->StatusOnShape());
248               for (; itl.More(); itl.Next())
249               {
250                 BRepCheck_Status ste = itl.Value();
251                 if (ste == BRepCheck_NoCurveOnSurface  ||
252                     ste == BRepCheck_InvalidCurveOnSurface ||
253                     ste == BRepCheck_InvalidRange ||
254                     ste == BRepCheck_InvalidCurveOnClosedSurface)
255                 {
256                   performwire = Standard_False;
257                   break;
258                 }
259               }
260             }
261           }
262         }
263         catch(Standard_Failure const& anException) {
264 #ifdef OCCT_DEBUG
265           std::cout<<"BRepCheck_Analyzer : ";
266           anException.Print(std::cout);  
267           std::cout<<std::endl;
268 #endif
269           (void)anException;
270           if ( ! myMap(S).IsNull() )
271           {
272             myMap(S)->SetFailStatus(S);
273           }
274
275           Handle(BRepCheck_Result) aRes = myMap(exp.Current());
276
277           if ( ! aRes.IsNull() )
278           {
279             aRes->SetFailStatus(exp.Current());
280             aRes->SetFailStatus(S);
281           }
282         }
283       }
284
285       Standard_Boolean orientofwires = performwire;
286       for (exp.Init(S,TopAbs_WIRE);exp.More(); exp.Next())
287       {
288         try
289         {
290           OCC_CATCH_SIGNALS
291           Handle(BRepCheck_Result)& res = myMap(exp.Current());
292           res->InContext(S);
293           if (orientofwires)
294           {
295             for ( res->InitContextIterator();
296                   res->MoreShapeInContext();
297                   res->NextShapeInContext())
298             {
299               if(res->ContextualShape().IsSame(S))
300               {
301                 break;
302               }
303             }
304             BRepCheck_ListIteratorOfListOfStatus itl(res->StatusOnShape());
305             for (; itl.More(); itl.Next())
306             {
307               BRepCheck_Status ste = itl.Value();
308               if (ste != BRepCheck_NoError)
309               {
310                 orientofwires = Standard_False;
311                 break;
312               }
313             }
314           }
315         }
316         catch(Standard_Failure const& anException) {
317 #ifdef OCCT_DEBUG
318           std::cout<<"BRepCheck_Analyzer : ";
319           anException.Print(std::cout);  
320           std::cout<<std::endl;
321 #endif
322           (void)anException;
323           if ( ! myMap(S).IsNull() )
324           {
325             myMap(S)->SetFailStatus(S);
326           }
327
328           Handle(BRepCheck_Result) aRes = myMap(exp.Current());
329
330           if ( ! aRes.IsNull() )
331           {
332             aRes->SetFailStatus(exp.Current());
333             aRes->SetFailStatus(S);
334           }
335         }
336       }
337
338       try
339       {
340         OCC_CATCH_SIGNALS
341         if(isInvalidTolerance)
342         {
343           Handle(BRepCheck_Face)::
344               DownCast(myMap(S))->SetStatus(BRepCheck_InvalidToleranceValue);
345         }
346         else if (performwire)
347         {
348           if (orientofwires)
349           {
350             Handle(BRepCheck_Face)::DownCast(myMap(S))->
351                         OrientationOfWires(Standard_True);// on enregistre
352           }
353           else
354           {
355             Handle(BRepCheck_Face)::DownCast(myMap(S))->SetUnorientable();
356           }
357         }
358         else
359         {
360           Handle(BRepCheck_Face)::DownCast(myMap(S))->SetUnorientable();
361         }
362       }
363       catch(Standard_Failure const& anException) {
364 #ifdef OCCT_DEBUG
365         std::cout<<"BRepCheck_Analyzer : ";
366         anException.Print(std::cout);  
367         std::cout<<std::endl;
368 #endif
369         (void)anException;
370         if ( ! myMap(S).IsNull() )
371         {
372           myMap(S)->SetFailStatus(S);
373         }
374
375         for (exp.Init(S,TopAbs_WIRE);exp.More(); exp.Next())
376         {
377           Handle(BRepCheck_Result) aRes = myMap(exp.Current());
378           
379           if ( ! aRes.IsNull() )
380           {
381             aRes->SetFailStatus(exp.Current());
382             aRes->SetFailStatus(S);
383             myMap(S)->SetFailStatus(exp.Current());
384           }
385         }
386       }
387     }
388     break;
389     
390   case TopAbs_SHELL:   
391     break;
392
393   case TopAbs_SOLID:
394     {
395       exp.Init(S,TopAbs_SHELL);
396       for (; exp.More(); exp.Next())
397         {
398           const TopoDS_Shape& aShell=exp.Current();
399           try 
400             {
401               OCC_CATCH_SIGNALS
402                 myMap(aShell)->InContext(S);
403             }
404           catch(Standard_Failure const& anException) {
405 #ifdef OCCT_DEBUG
406               std::cout<<"BRepCheck_Analyzer : ";
407               anException.Print(std::cout);  
408               std::cout<<std::endl;
409 #endif
410               (void)anException;
411               if ( ! myMap(S).IsNull() )
412                 {
413                   myMap(S)->SetFailStatus(S);
414                 }
415               
416               //
417               Handle(BRepCheck_Result) aRes = myMap(aShell);
418               if (!aRes.IsNull() )
419                 {
420                   aRes->SetFailStatus(exp.Current());
421                   aRes->SetFailStatus(S);
422                 }
423             }//catch(Standard_Failure)
424         }//for (; exp.More(); exp.Next())
425     }
426   break;//case TopAbs_SOLID
427   default:
428     break;
429   }//switch (styp) {
430 }
431
432
433 //=======================================================================
434 //function : IsValid
435 //purpose  : 
436 //=======================================================================
437
438 Standard_Boolean BRepCheck_Analyzer::IsValid(const TopoDS_Shape& S) const
439 {
440   if (!myMap(S).IsNull()) {
441     BRepCheck_ListIteratorOfListOfStatus itl;
442     itl.Initialize(myMap(S)->Status());
443     if (itl.Value() != BRepCheck_NoError) { // a voir
444       return Standard_False;
445     }
446   }
447
448   for(TopoDS_Iterator theIterator(S);theIterator.More();theIterator.Next()) {
449     if (!IsValid(theIterator.Value())) {
450       return Standard_False;
451     }
452   }
453
454   switch (S.ShapeType()) {
455   case TopAbs_EDGE:
456     {
457       return ValidSub(S,TopAbs_VERTEX);
458     }
459 //    break;
460   case TopAbs_FACE:
461     {
462       Standard_Boolean valid = ValidSub(S,TopAbs_WIRE);
463       valid = valid && ValidSub(S,TopAbs_EDGE);
464       valid = valid && ValidSub(S,TopAbs_VERTEX);
465       return valid;
466     }
467
468 //    break;
469   case TopAbs_SHELL:
470 //    return ValidSub(S,TopAbs_FACE);
471     break;
472   case TopAbs_SOLID:
473 //    return ValidSub(S,TopAbs_EDGE);
474 //    break;
475     return ValidSub(S,TopAbs_SHELL);
476     break;
477   default:
478     break;
479   }
480
481   return Standard_True;
482 }
483
484 //=======================================================================
485 //function : ValidSub
486 //purpose  : 
487 //=======================================================================
488
489 Standard_Boolean BRepCheck_Analyzer::ValidSub
490    (const TopoDS_Shape& S,
491     const TopAbs_ShapeEnum SubType) const
492 {
493   BRepCheck_ListIteratorOfListOfStatus itl;
494   TopExp_Explorer exp;
495   for (exp.Init(S,SubType);exp.More(); exp.Next()) {
496 //  for (TopExp_Explorer exp(S,SubType);exp.More(); exp.Next()) {
497     const Handle(BRepCheck_Result)& RV = myMap(exp.Current());
498     for (RV->InitContextIterator();
499          RV->MoreShapeInContext(); 
500          RV->NextShapeInContext()) {
501       if (RV->ContextualShape().IsSame(S)) {
502         break;
503       }
504     }
505
506     if(!RV->MoreShapeInContext()) break;
507
508     for (itl.Initialize(RV->StatusOnShape()); itl.More(); itl.Next()) {
509       if (itl.Value() != BRepCheck_NoError) {
510         return Standard_False;
511       }
512     }
513   }
514   return Standard_True ;
515 }