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