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 | |
7fd59977 |
17 | |
42cf5bc1 |
18 | #include <BRepCheck_Analyzer.hxx> |
7fd59977 |
19 | #include <BRepCheck_Edge.hxx> |
7fd59977 |
20 | #include <BRepCheck_Face.hxx> |
42cf5bc1 |
21 | #include <BRepCheck_ListIteratorOfListOfStatus.hxx> |
22 | #include <BRepCheck_Result.hxx> |
7fd59977 |
23 | #include <BRepCheck_Shell.hxx> |
949df2b6 |
24 | #include <BRepCheck_Solid.hxx> |
42cf5bc1 |
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> |
7fd59977 |
31 | #include <TopExp_Explorer.hxx> |
7fd59977 |
32 | #include <TopoDS.hxx> |
33 | #include <TopoDS_Face.hxx> |
42cf5bc1 |
34 | #include <TopoDS_Iterator.hxx> |
35 | #include <TopoDS_Shape.hxx> |
36 | #include <TopTools_MapOfShape.hxx> |
949df2b6 |
37 | |
7fd59977 |
38 | //======================================================================= |
39 | //function : Init |
40 | //purpose : |
41 | //======================================================================= |
7fd59977 |
42 | void BRepCheck_Analyzer::Init(const TopoDS_Shape& S, |
949df2b6 |
43 | const Standard_Boolean B) |
7fd59977 |
44 | { |
45 | if (S.IsNull()) { |
9775fa61 |
46 | throw Standard_NullObject(); |
7fd59977 |
47 | } |
48 | myShape = S; |
49 | myMap.Clear(); |
50 | Put(S,B); |
51 | Perform(S); |
52 | } |
7fd59977 |
53 | //======================================================================= |
54 | //function : Put |
55 | //purpose : |
56 | //======================================================================= |
7fd59977 |
57 | void BRepCheck_Analyzer::Put(const TopoDS_Shape& S, |
949df2b6 |
58 | const Standard_Boolean B) |
7fd59977 |
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: |
949df2b6 |
82 | HR = new BRepCheck_Solid(TopoDS::Solid(S)); |
83 | break; |
7fd59977 |
84 | case TopAbs_COMPSOLID: |
85 | case TopAbs_COMPOUND: |
86 | break; |
7fd59977 |
87 | default: |
88 | break; |
7fd59977 |
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 | } |
7fd59977 |
96 | //======================================================================= |
97 | //function : Perform |
98 | //purpose : |
99 | //======================================================================= |
7fd59977 |
100 | void BRepCheck_Analyzer::Perform(const TopoDS_Shape& S) |
101 | { |
52d45841 |
102 | for(TopoDS_Iterator theIterator(S);theIterator.More();theIterator.Next()) |
7fd59977 |
103 | Perform(theIterator.Value()); |
52d45841 |
104 | |
7fd59977 |
105 | // |
106 | TopAbs_ShapeEnum styp; |
107 | TopExp_Explorer exp; |
108 | // |
109 | styp = S.ShapeType(); |
52d45841 |
110 | |
111 | switch (styp) |
112 | { |
7fd59977 |
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)) { |
949df2b6 |
117 | // myMap(S)->Blind(); |
7fd59977 |
118 | // } |
119 | // modified by NIZHNY-MKK Wed May 19 16:56:23 2004.END |
120 | |
121 | break; |
52d45841 |
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 | } |
7fd59977 |
135 | } |
9775fa61 |
136 | catch(Standard_Failure const& anException) { |
0797d9d3 |
137 | #ifdef OCCT_DEBUG |
04232180 |
138 | std::cout<<"BRepCheck_Analyzer : "; |
139 | anException.Print(std::cout); |
140 | std::cout<<std::endl; |
7fd59977 |
141 | #endif |
9775fa61 |
142 | (void)anException; |
52d45841 |
143 | if ( ! myMap(S).IsNull() ) |
144 | { |
145 | myMap(S)->SetFailStatus(S); |
146 | } |
147 | |
148 | if ( ! aRes.IsNull() ) |
149 | { |
52d45841 |
150 | aRes->SetFailStatus(S); |
151 | } |
7fd59977 |
152 | } |
52d45841 |
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 | } |
9775fa61 |
165 | catch(Standard_Failure const& anException) { |
0797d9d3 |
166 | #ifdef OCCT_DEBUG |
04232180 |
167 | std::cout<<"BRepCheck_Analyzer : "; |
168 | anException.Print(std::cout); |
169 | std::cout<<std::endl; |
52d45841 |
170 | #endif |
9775fa61 |
171 | (void)anException; |
52d45841 |
172 | if ( ! myMap(S).IsNull() ) |
173 | myMap(S)->SetFailStatus(S); |
174 | |
51740958 |
175 | Handle(BRepCheck_Result) aResOfVertex = myMap(aVertex); |
52d45841 |
176 | |
51740958 |
177 | if ( !aResOfVertex.IsNull() ) |
52d45841 |
178 | { |
51740958 |
179 | aResOfVertex->SetFailStatus(aVertex); |
180 | aResOfVertex->SetFailStatus(S); |
52d45841 |
181 | } |
182 | }//catch(Standard_Failure) |
183 | }//for (exp.Init(S,TopAbs_VERTEX);exp.More(); exp.Next()) |
7fd59977 |
184 | } |
185 | break; |
186 | case TopAbs_WIRE: |
52d45841 |
187 | { |
188 | } |
7fd59977 |
189 | break; |
190 | case TopAbs_FACE: |
191 | { |
192 | TopTools_MapOfShape MapS; |
52d45841 |
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 | } |
9775fa61 |
203 | catch(Standard_Failure const& anException) { |
0797d9d3 |
204 | #ifdef OCCT_DEBUG |
04232180 |
205 | std::cout<<"BRepCheck_Analyzer : "; |
206 | anException.Print(std::cout); |
207 | std::cout<<std::endl; |
7fd59977 |
208 | #endif |
9775fa61 |
209 | (void)anException; |
52d45841 |
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 | } |
7fd59977 |
223 | } |
52d45841 |
224 | |
7fd59977 |
225 | Standard_Boolean performwire = Standard_True; |
52d45841 |
226 | Standard_Boolean isInvalidTolerance = Standard_False; |
7fd59977 |
227 | MapS.Clear(); |
52d45841 |
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 | } |
9775fa61 |
263 | catch(Standard_Failure const& anException) { |
0797d9d3 |
264 | #ifdef OCCT_DEBUG |
04232180 |
265 | std::cout<<"BRepCheck_Analyzer : "; |
266 | anException.Print(std::cout); |
267 | std::cout<<std::endl; |
7fd59977 |
268 | #endif |
9775fa61 |
269 | (void)anException; |
52d45841 |
270 | if ( ! myMap(S).IsNull() ) |
271 | { |
272 | myMap(S)->SetFailStatus(S); |
273 | } |
7fd59977 |
274 | |
52d45841 |
275 | Handle(BRepCheck_Result) aRes = myMap(exp.Current()); |
7fd59977 |
276 | |
52d45841 |
277 | if ( ! aRes.IsNull() ) |
278 | { |
279 | aRes->SetFailStatus(exp.Current()); |
280 | aRes->SetFailStatus(S); |
281 | } |
282 | } |
7fd59977 |
283 | } |
52d45841 |
284 | |
7fd59977 |
285 | Standard_Boolean orientofwires = performwire; |
52d45841 |
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 | } |
9775fa61 |
316 | catch(Standard_Failure const& anException) { |
0797d9d3 |
317 | #ifdef OCCT_DEBUG |
04232180 |
318 | std::cout<<"BRepCheck_Analyzer : "; |
319 | anException.Print(std::cout); |
320 | std::cout<<std::endl; |
7fd59977 |
321 | #endif |
9775fa61 |
322 | (void)anException; |
52d45841 |
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 | } |
7fd59977 |
336 | } |
52d45841 |
337 | |
338 | try |
339 | { |
7fd59977 |
340 | OCC_CATCH_SIGNALS |
52d45841 |
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 | } |
7fd59977 |
362 | } |
9775fa61 |
363 | catch(Standard_Failure const& anException) { |
0797d9d3 |
364 | #ifdef OCCT_DEBUG |
04232180 |
365 | std::cout<<"BRepCheck_Analyzer : "; |
366 | anException.Print(std::cout); |
367 | std::cout<<std::endl; |
7fd59977 |
368 | #endif |
9775fa61 |
369 | (void)anException; |
52d45841 |
370 | if ( ! myMap(S).IsNull() ) |
371 | { |
372 | myMap(S)->SetFailStatus(S); |
373 | } |
7fd59977 |
374 | |
52d45841 |
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 | } |
7fd59977 |
386 | } |
387 | } |
388 | break; |
389 | |
390 | case TopAbs_SHELL: |
7fd59977 |
391 | break; |
52d45841 |
392 | |
393 | case TopAbs_SOLID: |
394 | { |
949df2b6 |
395 | exp.Init(S,TopAbs_SHELL); |
52d45841 |
396 | for (; exp.More(); exp.Next()) |
52d45841 |
397 | { |
949df2b6 |
398 | const TopoDS_Shape& aShell=exp.Current(); |
399 | try |
400 | { |
401 | OCC_CATCH_SIGNALS |
402 | myMap(aShell)->InContext(S); |
403 | } |
9775fa61 |
404 | catch(Standard_Failure const& anException) { |
0797d9d3 |
405 | #ifdef OCCT_DEBUG |
04232180 |
406 | std::cout<<"BRepCheck_Analyzer : "; |
407 | anException.Print(std::cout); |
408 | std::cout<<std::endl; |
7fd59977 |
409 | #endif |
9775fa61 |
410 | (void)anException; |
949df2b6 |
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 | } |
7fd59977 |
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(); |
949df2b6 |
499 | RV->MoreShapeInContext(); |
500 | RV->NextShapeInContext()) { |
7fd59977 |
501 | if (RV->ContextualShape().IsSame(S)) { |
949df2b6 |
502 | break; |
7fd59977 |
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) { |
949df2b6 |
510 | return Standard_False; |
7fd59977 |
511 | } |
512 | } |
513 | } |
514 | return Standard_True ; |
515 | } |