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