b311480e |
1 | // Created on: 1995-12-08 |
2 | // Created by: Jacques GOUSSARD |
3 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
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; |
7fd59977 |
88 | default: |
89 | break; |
7fd59977 |
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 | { |
52d45841 |
106 | for(TopoDS_Iterator theIterator(S);theIterator.More();theIterator.Next()) |
7fd59977 |
107 | Perform(theIterator.Value()); |
52d45841 |
108 | |
7fd59977 |
109 | // |
110 | TopAbs_ShapeEnum styp; |
111 | TopExp_Explorer exp; |
112 | // |
113 | styp = S.ShapeType(); |
52d45841 |
114 | |
115 | switch (styp) |
116 | { |
7fd59977 |
117 | case TopAbs_VERTEX: |
118 | // modified by NIZHNY-MKK Wed May 19 16:56:16 2004.BEGIN |
119 | // There is no need to check anything. |
120 | // if (myShape.IsSame(S)) { |
121 | // myMap(S)->Blind(); |
122 | // } |
123 | // modified by NIZHNY-MKK Wed May 19 16:56:23 2004.END |
124 | |
125 | break; |
52d45841 |
126 | case TopAbs_EDGE: |
127 | { |
128 | Handle(BRepCheck_Result)& aRes = myMap(S); |
129 | |
130 | try |
131 | { |
132 | BRepCheck_Status ste = Handle(BRepCheck_Edge):: |
133 | DownCast(aRes)->CheckPolygonOnTriangulation(TopoDS::Edge(S)); |
134 | |
135 | if(ste != BRepCheck_NoError) |
136 | { |
137 | Handle(BRepCheck_Edge)::DownCast(aRes)->SetStatus(ste); |
138 | } |
7fd59977 |
139 | } |
52d45841 |
140 | catch(Standard_Failure) |
141 | { |
0797d9d3 |
142 | #ifdef OCCT_DEBUG |
52d45841 |
143 | cout<<"BRepCheck_Analyzer : "; |
144 | Standard_Failure::Caught()->Print(cout); |
145 | cout<<endl; |
7fd59977 |
146 | #endif |
52d45841 |
147 | if ( ! myMap(S).IsNull() ) |
148 | { |
149 | myMap(S)->SetFailStatus(S); |
150 | } |
151 | |
152 | if ( ! aRes.IsNull() ) |
153 | { |
154 | aRes->SetFailStatus(exp.Current()); |
155 | aRes->SetFailStatus(S); |
156 | } |
7fd59977 |
157 | } |
52d45841 |
158 | |
159 | TopTools_MapOfShape MapS; |
160 | |
161 | for (exp.Init(S,TopAbs_VERTEX);exp.More(); exp.Next()) |
162 | { |
163 | const TopoDS_Shape& aVertex = exp.Current(); |
164 | try |
165 | { |
166 | OCC_CATCH_SIGNALS |
167 | if (MapS.Add(aVertex)) |
168 | myMap(aVertex)->InContext(S); |
169 | } |
170 | catch(Standard_Failure) |
171 | { |
0797d9d3 |
172 | #ifdef OCCT_DEBUG |
52d45841 |
173 | cout<<"BRepCheck_Analyzer : "; |
174 | Standard_Failure::Caught()->Print(cout); |
175 | cout<<endl; |
176 | #endif |
177 | if ( ! myMap(S).IsNull() ) |
178 | myMap(S)->SetFailStatus(S); |
179 | |
180 | Handle(BRepCheck_Result) aRes = myMap(aVertex); |
181 | |
182 | if ( ! aRes.IsNull() ) |
183 | { |
184 | aRes->SetFailStatus(aVertex); |
185 | aRes->SetFailStatus(S); |
186 | } |
187 | }//catch(Standard_Failure) |
188 | }//for (exp.Init(S,TopAbs_VERTEX);exp.More(); exp.Next()) |
7fd59977 |
189 | } |
190 | break; |
191 | case TopAbs_WIRE: |
52d45841 |
192 | { |
193 | } |
7fd59977 |
194 | break; |
195 | case TopAbs_FACE: |
196 | { |
197 | TopTools_MapOfShape MapS; |
52d45841 |
198 | for (exp.Init(S,TopAbs_VERTEX);exp.More(); exp.Next()) |
199 | { |
200 | try |
201 | { |
202 | OCC_CATCH_SIGNALS |
203 | if (MapS.Add(exp.Current())) |
204 | { |
205 | myMap(exp.Current())->InContext(S); |
206 | } |
207 | } |
208 | catch(Standard_Failure) |
209 | { |
0797d9d3 |
210 | #ifdef OCCT_DEBUG |
52d45841 |
211 | cout<<"BRepCheck_Analyzer : "; |
212 | Standard_Failure::Caught()->Print(cout); |
213 | cout<<endl; |
7fd59977 |
214 | #endif |
52d45841 |
215 | if ( ! myMap(S).IsNull() ) |
216 | { |
217 | myMap(S)->SetFailStatus(S); |
218 | } |
219 | |
220 | Handle(BRepCheck_Result) aRes = myMap(exp.Current()); |
221 | |
222 | if ( ! aRes.IsNull() ) |
223 | { |
224 | aRes->SetFailStatus(exp.Current()); |
225 | aRes->SetFailStatus(S); |
226 | } |
227 | } |
7fd59977 |
228 | } |
52d45841 |
229 | |
7fd59977 |
230 | Standard_Boolean performwire = Standard_True; |
52d45841 |
231 | Standard_Boolean isInvalidTolerance = Standard_False; |
7fd59977 |
232 | MapS.Clear(); |
52d45841 |
233 | for (exp.Init(S,TopAbs_EDGE);exp.More(); exp.Next()) |
234 | { |
235 | try |
236 | { |
237 | OCC_CATCH_SIGNALS |
238 | if (MapS.Add(exp.Current())) |
239 | { |
240 | Handle(BRepCheck_Result)& res = myMap(exp.Current()); |
241 | res->InContext(S); |
242 | if (performwire) |
243 | { |
244 | for ( res->InitContextIterator(); |
245 | res->MoreShapeInContext(); |
246 | res->NextShapeInContext()) |
247 | { |
248 | if(res->ContextualShape().IsSame(S)) |
249 | break; |
250 | } |
251 | |
252 | BRepCheck_ListIteratorOfListOfStatus itl(res->StatusOnShape()); |
253 | for (; itl.More(); itl.Next()) |
254 | { |
255 | BRepCheck_Status ste = itl.Value(); |
256 | if (ste == BRepCheck_NoCurveOnSurface || |
257 | ste == BRepCheck_InvalidCurveOnSurface || |
258 | ste == BRepCheck_InvalidRange || |
259 | ste == BRepCheck_InvalidCurveOnClosedSurface) |
260 | { |
261 | performwire = Standard_False; |
262 | break; |
263 | } |
264 | } |
265 | } |
266 | } |
267 | } |
268 | catch(Standard_Failure) |
269 | { |
0797d9d3 |
270 | #ifdef OCCT_DEBUG |
52d45841 |
271 | cout<<"BRepCheck_Analyzer : "; |
272 | Standard_Failure::Caught()->Print(cout); |
273 | cout<<endl; |
7fd59977 |
274 | #endif |
52d45841 |
275 | if ( ! myMap(S).IsNull() ) |
276 | { |
277 | myMap(S)->SetFailStatus(S); |
278 | } |
7fd59977 |
279 | |
52d45841 |
280 | Handle(BRepCheck_Result) aRes = myMap(exp.Current()); |
7fd59977 |
281 | |
52d45841 |
282 | if ( ! aRes.IsNull() ) |
283 | { |
284 | aRes->SetFailStatus(exp.Current()); |
285 | aRes->SetFailStatus(S); |
286 | } |
287 | } |
7fd59977 |
288 | } |
52d45841 |
289 | |
7fd59977 |
290 | Standard_Boolean orientofwires = performwire; |
52d45841 |
291 | for (exp.Init(S,TopAbs_WIRE);exp.More(); exp.Next()) |
292 | { |
293 | try |
294 | { |
295 | OCC_CATCH_SIGNALS |
296 | Handle(BRepCheck_Result)& res = myMap(exp.Current()); |
297 | res->InContext(S); |
298 | if (orientofwires) |
299 | { |
300 | for ( res->InitContextIterator(); |
301 | res->MoreShapeInContext(); |
302 | res->NextShapeInContext()) |
303 | { |
304 | if(res->ContextualShape().IsSame(S)) |
305 | { |
306 | break; |
307 | } |
308 | } |
309 | BRepCheck_ListIteratorOfListOfStatus itl(res->StatusOnShape()); |
310 | for (; itl.More(); itl.Next()) |
311 | { |
312 | BRepCheck_Status ste = itl.Value(); |
313 | if (ste != BRepCheck_NoError) |
314 | { |
315 | orientofwires = Standard_False; |
316 | break; |
317 | } |
318 | } |
319 | } |
320 | } |
321 | catch(Standard_Failure) |
322 | { |
0797d9d3 |
323 | #ifdef OCCT_DEBUG |
52d45841 |
324 | cout<<"BRepCheck_Analyzer : "; |
325 | Standard_Failure::Caught()->Print(cout); |
326 | cout<<endl; |
7fd59977 |
327 | #endif |
52d45841 |
328 | if ( ! myMap(S).IsNull() ) |
329 | { |
330 | myMap(S)->SetFailStatus(S); |
331 | } |
332 | |
333 | Handle(BRepCheck_Result) aRes = myMap(exp.Current()); |
334 | |
335 | if ( ! aRes.IsNull() ) |
336 | { |
337 | aRes->SetFailStatus(exp.Current()); |
338 | aRes->SetFailStatus(S); |
339 | } |
340 | } |
7fd59977 |
341 | } |
52d45841 |
342 | |
343 | try |
344 | { |
7fd59977 |
345 | OCC_CATCH_SIGNALS |
52d45841 |
346 | if(isInvalidTolerance) |
347 | { |
348 | Handle(BRepCheck_Face):: |
349 | DownCast(myMap(S))->SetStatus(BRepCheck_InvalidToleranceValue); |
350 | } |
351 | else if (performwire) |
352 | { |
353 | if (orientofwires) |
354 | { |
355 | Handle(BRepCheck_Face)::DownCast(myMap(S))-> |
356 | OrientationOfWires(Standard_True);// on enregistre |
357 | } |
358 | else |
359 | { |
360 | Handle(BRepCheck_Face)::DownCast(myMap(S))->SetUnorientable(); |
361 | } |
362 | } |
363 | else |
364 | { |
365 | Handle(BRepCheck_Face)::DownCast(myMap(S))->SetUnorientable(); |
366 | } |
7fd59977 |
367 | } |
52d45841 |
368 | catch(Standard_Failure) |
369 | { |
0797d9d3 |
370 | #ifdef OCCT_DEBUG |
52d45841 |
371 | cout<<"BRepCheck_Analyzer : "; |
372 | Standard_Failure::Caught()->Print(cout); |
373 | cout<<endl; |
7fd59977 |
374 | #endif |
52d45841 |
375 | if ( ! myMap(S).IsNull() ) |
376 | { |
377 | myMap(S)->SetFailStatus(S); |
378 | } |
7fd59977 |
379 | |
52d45841 |
380 | for (exp.Init(S,TopAbs_WIRE);exp.More(); exp.Next()) |
381 | { |
382 | Handle(BRepCheck_Result) aRes = myMap(exp.Current()); |
383 | |
384 | if ( ! aRes.IsNull() ) |
385 | { |
386 | aRes->SetFailStatus(exp.Current()); |
387 | aRes->SetFailStatus(S); |
388 | myMap(S)->SetFailStatus(exp.Current()); |
389 | } |
390 | } |
7fd59977 |
391 | } |
392 | } |
393 | break; |
394 | |
395 | case TopAbs_SHELL: |
396 | //modified by NIZNHY-PKV Mon Oct 13 14:23:53 2008f |
7fd59977 |
397 | //modified by NIZNHY-PKV Mon Oct 13 14:24:04 2008t |
398 | break; |
52d45841 |
399 | |
400 | case TopAbs_SOLID: |
401 | { |
7fd59977 |
402 | exp.Init(S,TopAbs_SHELL); |
52d45841 |
403 | for (; exp.More(); exp.Next()) |
404 | { |
7fd59977 |
405 | const TopoDS_Shape& aShell=exp.Current(); |
52d45841 |
406 | try |
407 | { |
7fd59977 |
408 | OCC_CATCH_SIGNALS |
409 | myMap(aShell)->InContext(S); |
410 | } |
52d45841 |
411 | catch(Standard_Failure) |
412 | { |
0797d9d3 |
413 | #ifdef OCCT_DEBUG |
7fd59977 |
414 | cout<<"BRepCheck_Analyzer : "; |
415 | Standard_Failure::Caught()->Print(cout); |
416 | cout<<endl; |
417 | #endif |
52d45841 |
418 | if ( ! myMap(S).IsNull() ) |
419 | { |
7fd59977 |
420 | myMap(S)->SetFailStatus(S); |
421 | } |
52d45841 |
422 | |
7fd59977 |
423 | // |
424 | Handle(BRepCheck_Result) aRes = myMap(aShell); |
52d45841 |
425 | if (!aRes.IsNull() ) |
426 | { |
7fd59977 |
427 | aRes->SetFailStatus(exp.Current()); |
428 | aRes->SetFailStatus(S); |
429 | } |
52d45841 |
430 | }//catch(Standard_Failure) |
431 | }//for (; exp.More(); exp.Next()) |
7fd59977 |
432 | } |
7fd59977 |
433 | break;//case TopAbs_SOLID |
434 | default: |
435 | break; |
436 | }//switch (styp) { |
437 | } |
438 | |
439 | |
440 | //======================================================================= |
441 | //function : IsValid |
442 | //purpose : |
443 | //======================================================================= |
444 | |
445 | Standard_Boolean BRepCheck_Analyzer::IsValid(const TopoDS_Shape& S) const |
446 | { |
447 | if (!myMap(S).IsNull()) { |
448 | BRepCheck_ListIteratorOfListOfStatus itl; |
449 | itl.Initialize(myMap(S)->Status()); |
450 | if (itl.Value() != BRepCheck_NoError) { // a voir |
451 | return Standard_False; |
452 | } |
453 | } |
454 | |
455 | for(TopoDS_Iterator theIterator(S);theIterator.More();theIterator.Next()) { |
456 | if (!IsValid(theIterator.Value())) { |
457 | return Standard_False; |
458 | } |
459 | } |
460 | |
461 | switch (S.ShapeType()) { |
462 | case TopAbs_EDGE: |
463 | { |
464 | return ValidSub(S,TopAbs_VERTEX); |
465 | } |
466 | // break; |
467 | case TopAbs_FACE: |
468 | { |
469 | Standard_Boolean valid = ValidSub(S,TopAbs_WIRE); |
470 | valid = valid && ValidSub(S,TopAbs_EDGE); |
471 | valid = valid && ValidSub(S,TopAbs_VERTEX); |
472 | return valid; |
473 | } |
474 | |
475 | // break; |
476 | case TopAbs_SHELL: |
477 | // return ValidSub(S,TopAbs_FACE); |
478 | break; |
479 | case TopAbs_SOLID: |
480 | // return ValidSub(S,TopAbs_EDGE); |
481 | // break; |
482 | return ValidSub(S,TopAbs_SHELL); |
483 | break; |
484 | default: |
485 | break; |
486 | } |
487 | |
488 | return Standard_True; |
489 | } |
490 | |
491 | //======================================================================= |
492 | //function : ValidSub |
493 | //purpose : |
494 | //======================================================================= |
495 | |
496 | Standard_Boolean BRepCheck_Analyzer::ValidSub |
497 | (const TopoDS_Shape& S, |
498 | const TopAbs_ShapeEnum SubType) const |
499 | { |
500 | BRepCheck_ListIteratorOfListOfStatus itl; |
501 | TopExp_Explorer exp; |
502 | for (exp.Init(S,SubType);exp.More(); exp.Next()) { |
503 | // for (TopExp_Explorer exp(S,SubType);exp.More(); exp.Next()) { |
504 | const Handle(BRepCheck_Result)& RV = myMap(exp.Current()); |
505 | for (RV->InitContextIterator(); |
506 | RV->MoreShapeInContext(); |
507 | RV->NextShapeInContext()) { |
508 | if (RV->ContextualShape().IsSame(S)) { |
509 | break; |
510 | } |
511 | } |
512 | |
513 | if(!RV->MoreShapeInContext()) break; |
514 | |
515 | for (itl.Initialize(RV->StatusOnShape()); itl.More(); itl.Next()) { |
516 | if (itl.Value() != BRepCheck_NoError) { |
517 | return Standard_False; |
518 | } |
519 | } |
520 | } |
521 | return Standard_True ; |
522 | } |