7fd59977 |
1 | // File: BOPTools_Checker.cxx |
2 | // Created: Mon Aug 5 16:06:12 2002 |
3 | // Author: Peter KURNEV |
4 | // <pkv@irinox> |
5 | |
6 | |
7 | #include <BOPTools_Checker.ixx> |
8 | |
9 | #include <stdio.h> |
10 | #include <stdlib.h> |
11 | |
12 | #include <Precision.hxx> |
13 | |
14 | #include <gp_Pnt.hxx> |
15 | |
16 | #include <Geom_CartesianPoint.hxx> |
17 | #include <Geom_TrimmedCurve.hxx> |
18 | #include <Geom_Curve.hxx> |
19 | |
20 | #include <TopoDS.hxx> |
21 | #include <TopoDS_Vertex.hxx> |
22 | #include <TopoDS_Shape.hxx> |
23 | #include <TopoDS_Edge.hxx> |
24 | #include <TopoDS_Face.hxx> |
25 | |
26 | #include <TopTools_IndexedMapOfShape.hxx> |
27 | |
28 | #include <TopExp.hxx> |
29 | |
30 | #include <Bnd_Box.hxx> |
31 | |
32 | #include <BRep_Builder.hxx> |
33 | #include <BRep_Tool.hxx> |
34 | |
35 | #include <BOPTools_Pave.hxx> |
36 | #include <BOPTools_PaveSet.hxx> |
37 | #include <BOPTools_ListOfPaveBlock.hxx> |
38 | #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx> |
39 | #include <BOPTools_PaveBlock.hxx> |
40 | #include <BOPTools_Tools.hxx> |
41 | #include <BOPTools_PaveBlockIterator.hxx> |
42 | // modified by NIZHNY-MKK Fri Sep 3 16:00:15 2004.BEGIN |
43 | #include <BOPTools_CheckResult.hxx> |
44 | // modified by NIZHNY-MKK Fri Sep 3 16:00:18 2004.END |
45 | |
46 | #include <IntTools_ShrunkRange.hxx> |
47 | #include <IntTools_Range.hxx> |
48 | #include <IntTools_EdgeEdge.hxx> |
49 | #include <IntTools_SequenceOfCommonPrts.hxx> |
50 | #include <IntTools_CommonPrt.hxx> |
51 | #include <IntTools_SequenceOfRanges.hxx> |
52 | #include <IntTools_EdgeFace.hxx> |
53 | #include <IntTools_FaceFace.hxx> |
54 | #include <IntTools_Curve.hxx> |
55 | #include <IntTools_PntOn2Faces.hxx> |
56 | #include <IntTools_PntOnFace.hxx> |
57 | #include <IntTools_Tools.hxx> |
58 | |
59 | #include <BooleanOperations_ShapesDataStructure.hxx> |
60 | #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx> |
61 | |
62 | #include <BOPTColStd_Failure.hxx> |
63 | |
64 | //======================================================================= |
65 | // function: BOPTools_Checker::BOPTools_Checker |
66 | // purpose: |
67 | //======================================================================= |
68 | BOPTools_Checker::BOPTools_Checker() : BOPTools_PaveFiller() |
69 | { |
70 | myEntryType=1; |
71 | myStopOnFirst = Standard_False; |
72 | } |
73 | //======================================================================= |
74 | // function: BOPTools_Checker::BOPTools_Checker |
75 | // purpose: |
76 | //======================================================================= |
77 | BOPTools_Checker::BOPTools_Checker(const TopoDS_Shape& aS) : BOPTools_PaveFiller() |
78 | { |
79 | myEntryType=1; |
80 | myStopOnFirst = Standard_False; |
81 | SetShape(aS); |
82 | } |
83 | //======================================================================= |
84 | // function: BOPTools_Checker::BOPTools_Checker |
85 | // purpose: |
86 | //======================================================================= |
87 | BOPTools_Checker::BOPTools_Checker(const BOPTools_InterferencePool& aPool) : BOPTools_PaveFiller(aPool) |
88 | { |
89 | myStopOnFirst = Standard_False; |
90 | myEntryType=0; |
91 | myIsDone=Standard_False; |
92 | void* p=(void*) &aPool; |
93 | myIntrPool=(BOPTools_InterferencePool*) p; |
94 | myDS=myIntrPool->DS(); |
95 | myNbSources=myDS->NumberOfShapesOfTheObject()+myDS->NumberOfShapesOfTheTool(); |
96 | myNbEdges=myDS->NbEdges(); |
97 | } |
98 | |
99 | //======================================================================= |
100 | // function: SetShape |
101 | // purpose: |
102 | //======================================================================= |
103 | void BOPTools_Checker::SetShape(const TopoDS_Shape& aS) |
104 | { |
105 | myShape=aS; |
106 | |
107 | Destroy(); |
108 | myDS = new BooleanOperations_ShapesDataStructure (aS, aS); |
109 | |
110 | myIntrPool = new BOPTools_InterferencePool (*myDS); |
111 | |
112 | myNbSources=myDS->NumberOfShapesOfTheObject()+myDS->NumberOfShapesOfTheTool(); |
113 | myNbEdges=myDS->NbEdges(); |
114 | } |
115 | |
116 | //======================================================================= |
117 | // function: Destroy |
118 | // purpose: |
119 | //======================================================================= |
120 | void BOPTools_Checker::Destroy() |
121 | { |
122 | if (myEntryType) { |
123 | // |
124 | if (myIntrPool!=NULL) { |
125 | delete myIntrPool; myIntrPool = NULL; |
126 | } |
127 | if (myDS!=NULL) { |
128 | delete myDS; myDS = NULL; |
129 | } |
130 | } |
131 | myCheckResults.Clear(); |
132 | } |
133 | |
134 | //======================================================================= |
135 | // function: SetPerformType |
136 | // purpose: |
137 | //======================================================================= |
138 | |
139 | void BOPTools_Checker::SetPerformType(const Standard_Boolean StopOnFirstFaulty) |
140 | { |
141 | myStopOnFirst = StopOnFirstFaulty; |
142 | } |
143 | |
144 | //======================================================================= |
145 | // function: Perform |
146 | // purpose: |
147 | //======================================================================= |
148 | void BOPTools_Checker::Perform() |
149 | { |
150 | myCheckResults.Clear(); |
151 | try { |
152 | // |
153 | // 0. Prepare the IteratorOfCoupleOfShape |
154 | myDSIt.SetDataStructure(myDS); |
155 | // |
156 | // 1.VV |
157 | PerformVV(); |
158 | // |
159 | // 2.VE |
160 | myPavePool.Resize (myNbEdges); |
161 | PrepareEdges(); |
162 | PerformVE(); |
163 | // |
164 | // 3.VF |
165 | PerformVF(); |
166 | // |
167 | // 4.EE |
168 | myCommonBlockPool.Resize (myNbEdges); |
169 | mySplitShapesPool.Resize (myNbEdges); |
170 | myPavePoolNew .Resize (myNbEdges); |
171 | |
172 | PreparePaveBlocks(TopAbs_VERTEX, TopAbs_EDGE); |
173 | PreparePaveBlocks(TopAbs_EDGE, TopAbs_EDGE); |
174 | |
175 | PerformEE(); |
176 | // |
177 | // 5.EF |
178 | PreparePaveBlocks(TopAbs_EDGE, TopAbs_FACE); |
179 | |
180 | PerformEF(); |
181 | // |
182 | // 6. FF |
183 | PerformFF (); |
184 | }// end of try block |
185 | // |
186 | catch (BOPTColStd_Failure& x) { |
187 | cout << x.Message() << endl << flush; |
188 | } |
189 | } |
190 | //======================================================================= |
191 | // function: PerformVV |
192 | // purpose: |
193 | //======================================================================= |
194 | void BOPTools_Checker::PerformVV() |
195 | { |
196 | myIsDone=Standard_False; |
197 | Standard_Boolean bJustAddInterference; |
198 | Standard_Integer n1, n2, aFlag; |
199 | // |
200 | // V/V BooleanOperations_VertexVertex |
201 | myDSIt.Initialize(TopAbs_VERTEX, TopAbs_VERTEX); |
202 | // |
203 | for (; myDSIt.More(); myDSIt.Next()) { |
204 | bJustAddInterference = Standard_False; |
205 | myDSIt.Current(n1, n2, bJustAddInterference); |
206 | // |
207 | const TopoDS_Shape& aS1=myDS->Shape(n1); |
208 | const TopoDS_Shape& aS2=myDS->Shape(n2); |
209 | // |
210 | if (aS1.IsSame(aS2)){ |
211 | continue; |
212 | } |
213 | // |
214 | if(bJustAddInterference) { |
215 | continue; |
216 | } |
217 | // |
218 | const TopoDS_Vertex& aV1=TopoDS::Vertex(aS1); |
219 | const TopoDS_Vertex& aV2=TopoDS::Vertex(aS2); |
220 | |
221 | aFlag=IntTools_Tools::ComputeVV (aV1, aV2); |
222 | |
223 | if (!aFlag) { |
224 | char buf[512]; |
225 | sprintf (buf, "VV: (%d, %d)", n1, n2); |
226 | |
227 | BOPTools_CheckResult aChRes; |
228 | aChRes.AddShape(aV1); |
229 | aChRes.AddShape(aV2); |
230 | aChRes.SetCheckStatus(BOPTools_VERTEXVERTEX); |
231 | myCheckResults.Append(aChRes); |
232 | |
233 | if(myStopOnFirst) |
234 | throw BOPTColStd_Failure(buf) ; |
235 | } |
236 | } |
237 | myIsDone=Standard_True; |
238 | } |
239 | |
240 | //======================================================================= |
241 | // function: PerformVE |
242 | // purpose: |
243 | //======================================================================= |
244 | void BOPTools_Checker::PerformVE() |
245 | { |
246 | myIsDone=Standard_False; |
247 | Standard_Boolean bSameFlag, bJustAddInterference; |
248 | Standard_Integer n1, n2, aFlag, aWhat, aWith; |
249 | Standard_Real aT; |
250 | // |
251 | // V/E Interferences [BooleanOperations_VertexEdge] |
252 | myDSIt.Initialize (TopAbs_VERTEX, TopAbs_EDGE); |
253 | // |
254 | for (; myDSIt.More(); myDSIt.Next()) { |
255 | bJustAddInterference = Standard_False; |
256 | myDSIt.Current(n1, n2, bJustAddInterference); |
257 | // |
258 | aWhat=n1; // Vertex |
259 | aWith=n2; // Edge |
260 | |
261 | SortTypes(aWhat, aWith); |
262 | |
263 | const TopoDS_Shape& aS1=myDS->Shape(aWhat); |
264 | const TopoDS_Shape& aS2=myDS->Shape(aWith); |
265 | |
266 | const TopoDS_Vertex& aV1=TopoDS::Vertex(aS1); |
267 | const TopoDS_Edge& aE2=TopoDS::Edge (aS2); |
268 | |
269 | if (BRep_Tool::Degenerated(aE2)){ |
270 | continue; |
271 | } |
272 | // |
273 | TopTools_IndexedMapOfShape aM2; |
274 | // |
275 | bSameFlag=Standard_False; |
276 | // |
277 | BOPTools_Tools::MapShapes(aE2, aM2); |
278 | // |
279 | if (aM2.Contains(aV1)) { |
280 | bSameFlag=Standard_True; |
281 | } |
282 | // |
283 | if (bSameFlag){ |
284 | continue; |
285 | } |
286 | // |
287 | aFlag=myContext.ComputeVE (aV1, aE2, aT); |
288 | // |
289 | if (!aFlag) { |
290 | char buf[512]; |
291 | sprintf (buf, "VE: (%d, %d)", aWhat, aWith); |
292 | |
293 | BOPTools_CheckResult aChRes; |
294 | aChRes.AddShape(aV1); |
295 | aChRes.AddShape(aE2); |
296 | aChRes.SetCheckStatus(BOPTools_VERTEXEDGE); |
297 | myCheckResults.Append(aChRes); |
298 | // |
299 | if(myStopOnFirst) |
300 | throw BOPTColStd_Failure(buf) ; |
301 | } |
302 | } |
303 | myIsDone=Standard_True; |
304 | } |
305 | |
306 | //======================================================================= |
307 | // function: PerformVF |
308 | // purpose: |
309 | //======================================================================= |
310 | void BOPTools_Checker::PerformVF() |
311 | { |
312 | myIsDone=Standard_False; |
313 | Standard_Boolean justaddinterference, bSameFlag; |
314 | Standard_Integer n1, n2, aFlag, aWhat, aWith; |
315 | Standard_Real aU, aV; |
316 | // |
317 | // V/V BooleanOperations_VertexFace |
318 | myDSIt.Initialize(TopAbs_VERTEX, TopAbs_FACE); |
319 | // |
320 | for (; myDSIt.More(); myDSIt.Next()) { |
321 | justaddinterference = Standard_False; |
322 | myDSIt.Current(n1, n2, justaddinterference); |
323 | // |
324 | aWhat=n1; // Vertex |
325 | aWith=n2; // Face |
326 | SortTypes(aWhat, aWith); |
327 | |
328 | const TopoDS_Shape& aS1=myDS->Shape(aWhat); |
329 | const TopoDS_Shape& aS2=myDS->Shape(aWith); |
330 | |
331 | const TopoDS_Vertex& aV1=TopoDS::Vertex(aS1); |
332 | const TopoDS_Face& aF2=TopoDS::Face (aS2); |
333 | // |
334 | TopTools_IndexedMapOfShape aM2; |
335 | // |
336 | bSameFlag=Standard_False; |
337 | // |
338 | BOPTools_Tools::MapShapes(aF2, aM2); |
339 | // |
340 | if (aM2.Contains(aV1)) { |
341 | bSameFlag=Standard_True; |
342 | } |
343 | // |
344 | if (bSameFlag){ |
345 | continue; |
346 | } |
347 | // |
348 | aFlag=myContext.ComputeVS (aV1, aF2, aU, aV); |
349 | // |
350 | if (!aFlag) { |
351 | char buf[512]; |
352 | sprintf (buf, "VF: (%d, %d)", aWhat, aWith); |
353 | |
354 | BOPTools_CheckResult aChRes; |
355 | aChRes.AddShape(aV1); |
356 | aChRes.AddShape(aF2); |
357 | aChRes.SetCheckStatus(BOPTools_VERTEXFACE); |
358 | myCheckResults.Append(aChRes); |
359 | |
360 | if(myStopOnFirst) |
361 | throw BOPTColStd_Failure(buf) ; |
362 | } |
363 | } |
364 | myIsDone=Standard_True; |
365 | } |
366 | |
367 | //======================================================================= |
368 | // function: PerformEE |
369 | // purpose: |
370 | //======================================================================= |
371 | void BOPTools_Checker::PerformEE() |
372 | { |
373 | myIsDone=Standard_False; |
374 | |
375 | Standard_Boolean justaddinterference; |
376 | Standard_Integer n1, n2, anIndexIn=0, nE1, nE2; |
377 | Standard_Integer aTmp, aWhat, aWith; |
378 | Standard_Integer i, aNbCPrts; |
379 | // |
380 | // E/E Interferences [BooleanOperations_EdgeEdge] |
381 | myDSIt.Initialize(TopAbs_EDGE, TopAbs_EDGE); |
382 | // |
383 | for (; myDSIt.More(); myDSIt.Next()) { |
384 | justaddinterference = Standard_False; |
385 | myDSIt.Current(n1, n2, justaddinterference); |
386 | // |
387 | nE1=n1; |
388 | nE2=n2; |
389 | SortTypes(nE1, nE2); |
390 | // |
391 | Standard_Real aTolE1, aTolE2, aDeflection=0.01; |
392 | Standard_Integer aDiscretize=30; |
393 | |
394 | const TopoDS_Edge& aE1=TopoDS::Edge(myDS->GetShape(nE1)); |
395 | const TopoDS_Edge& aE2=TopoDS::Edge(myDS->GetShape(nE2)); |
396 | // |
397 | if (BRep_Tool::Degenerated(aE1)){ |
398 | continue; |
399 | } |
400 | if (BRep_Tool::Degenerated(aE2)){ |
401 | continue; |
402 | } |
403 | // |
404 | // |
405 | Standard_Boolean bSameFlag; |
406 | TopTools_IndexedMapOfShape aM1, aM2; |
407 | // |
408 | bSameFlag=aE1.IsSame(aE2); |
409 | // |
410 | if (bSameFlag){ |
411 | continue; |
412 | } |
413 | // |
414 | aTolE1=BRep_Tool::Tolerance(aE1); |
415 | aTolE2=BRep_Tool::Tolerance(aE2); |
416 | // |
417 | BOPTools_ListOfPaveBlock& aLPB1=mySplitShapesPool(myDS->RefEdge(nE1)); |
418 | BOPTools_ListIteratorOfListOfPaveBlock anIt1(aLPB1); |
419 | |
420 | for (; anIt1.More(); anIt1.Next()) { |
421 | BOPTools_PaveBlock& aPB1=anIt1.Value(); |
422 | const IntTools_ShrunkRange& aShrunkRange1=aPB1.ShrunkRange(); |
423 | |
424 | const IntTools_Range& aSR1=aShrunkRange1.ShrunkRange(); |
425 | const Bnd_Box& aBB1=aShrunkRange1.BndBox(); |
426 | |
427 | BOPTools_ListOfPaveBlock& aLPB2=mySplitShapesPool(myDS->RefEdge(nE2)); |
428 | BOPTools_ListIteratorOfListOfPaveBlock anIt2(aLPB2); |
429 | |
430 | for (; anIt2.More(); anIt2.Next()) { |
431 | BOPTools_PaveBlock& aPB2=anIt2.Value(); |
432 | const IntTools_ShrunkRange& aShrunkRange2=aPB2.ShrunkRange(); |
433 | |
434 | const IntTools_Range& aSR2=aShrunkRange2.ShrunkRange(); |
435 | const Bnd_Box& aBB2=aShrunkRange2.BndBox(); |
436 | |
437 | ////////////////////////////////////////////// |
438 | if (aBB1.IsOut (aBB2)) { |
439 | continue; |
440 | } |
441 | // |
442 | // EE |
443 | IntTools_EdgeEdge aEE; |
444 | aEE.SetEdge1 (aE1); |
445 | aEE.SetEdge2 (aE2); |
446 | aEE.SetTolerance1 (aTolE1); |
447 | aEE.SetTolerance2 (aTolE2); |
448 | aEE.SetDiscretize (aDiscretize); |
449 | aEE.SetDeflection (aDeflection); |
450 | // |
451 | IntTools_Range anewSR1 = aSR1; |
452 | IntTools_Range anewSR2 = aSR2; |
453 | // |
454 | BOPTools_Tools::CorrectRange (aE1, aE2, aSR1, anewSR1); |
455 | BOPTools_Tools::CorrectRange (aE2, aE1, aSR2, anewSR2); |
456 | // |
457 | aEE.SetRange1(anewSR1); |
458 | aEE.SetRange2(anewSR2); |
459 | |
460 | aEE.Perform(); |
461 | // |
462 | anIndexIn=0; |
463 | // |
464 | if (aEE.IsDone()) { |
465 | // |
466 | // reverse order if it is necessary |
467 | TopoDS_Edge aEWhat, aEWith; |
468 | aEWhat=aE1; |
469 | aEWith=aE2; |
470 | aWhat=nE1; |
471 | aWith=nE2; |
472 | if (aEE.Order()) { |
473 | aTmp=aWhat; |
474 | aWhat=aWith; |
475 | aWith=aTmp; |
476 | aEWhat=aE2; |
477 | aEWith=aE1; |
478 | } |
479 | // |
480 | const IntTools_SequenceOfCommonPrts& aCPrts=aEE.CommonParts(); |
481 | |
482 | aNbCPrts=aCPrts.Length(); |
483 | for (i=1; i<=aNbCPrts; i++) { |
484 | const IntTools_CommonPrt& aCPart=aCPrts(i); |
485 | // |
486 | anIndexIn=0; |
487 | // |
488 | TopAbs_ShapeEnum aType=aCPart.Type(); |
489 | switch (aType) { |
490 | |
491 | case TopAbs_VERTEX: { |
492 | |
493 | Standard_Real aT1, aT2; |
494 | |
495 | const IntTools_Range& aR1=aCPart.Range1(); |
496 | aT1=0.5*(aR1.First()+aR1.Last()); |
497 | |
498 | if((aCPart.VertexParameter1() >= aR1.First()) && |
499 | (aCPart.VertexParameter1() <= aR1.Last())) { |
500 | aT1 = aCPart.VertexParameter1(); |
501 | } |
502 | |
503 | const IntTools_SequenceOfRanges& aRanges2=aCPart.Ranges2(); |
504 | const IntTools_Range& aR2=aRanges2(1); |
505 | aT2=0.5*(aR2.First()+aR2.Last()); |
506 | |
507 | if((aCPart.VertexParameter2() >= aR2.First()) && |
508 | (aCPart.VertexParameter2() <= aR2.Last())) { |
509 | aT2 = aCPart.VertexParameter2(); |
510 | } |
511 | // |
512 | char buf[512]; |
513 | sprintf (buf, "EE: (%d, %d), vertex at t1=%f, t2=%f", aWhat, aWith, aT1, aT2); |
514 | // |
515 | gp_Pnt aPnt; |
516 | BOPTools_Tools::PointOnEdge(aEWhat, aT1, aPnt); |
517 | Handle (Geom_CartesianPoint) aCPnt= new Geom_CartesianPoint(aPnt); |
518 | // myInerference=aCPnt; |
519 | |
520 | BOPTools_CheckResult aChRes; |
521 | aChRes.AddShape(aE1); |
522 | aChRes.AddShape(aE2); |
523 | aChRes.SetCheckStatus(BOPTools_EDGEEDGE); |
524 | // modified by NIZHNY-MKK Fri Sep 3 16:01:52 2004 |
525 | // aChRes.SetInterferenceGeometry(myInerference); |
526 | aChRes.SetInterferenceGeometry(aCPnt); |
527 | myCheckResults.Append(aChRes); |
528 | |
529 | if(myStopOnFirst) |
530 | throw BOPTColStd_Failure(buf) ; |
531 | // |
532 | } |
533 | break; |
534 | |
535 | case TopAbs_EDGE: { |
536 | |
537 | const IntTools_SequenceOfRanges& aRanges2=aCPart.Ranges2(); |
538 | Standard_Integer aNbComPrt2=aRanges2.Length(); |
539 | |
540 | if (aNbComPrt2>1) { |
541 | break; |
542 | } |
543 | |
544 | Standard_Boolean aCoinsideFlag; |
545 | |
546 | aCoinsideFlag=IsBlocksCoinside(aPB1, aPB2); |
547 | // |
548 | if (!aCoinsideFlag) { |
549 | break; |
550 | } |
551 | // |
552 | char buf[512]; |
553 | sprintf (buf, "EE: (%d, %d), common block ", aWhat, aWith); |
554 | |
555 | BOPTools_CheckResult aChRes; |
556 | aChRes.AddShape(aE1); |
557 | aChRes.AddShape(aE2); |
558 | aChRes.SetCheckStatus(BOPTools_EDGEEDGECOMBLK); |
559 | myCheckResults.Append(aChRes); |
560 | |
561 | if(myStopOnFirst) |
562 | throw BOPTColStd_Failure(buf) ; |
563 | // |
564 | } |
565 | break; |
566 | |
567 | default: |
568 | break; |
569 | } // switch (aType) |
570 | } // for (i=1; i<=aNbCPrts; i++) |
571 | }// if (aEE.IsDone()) |
572 | |
573 | ////////////////////////////////////////////// |
574 | } // for (; anIt2.More(); anIt2.Next()) |
575 | } // for (; anIt1.More(); anIt1.Next()) |
576 | }// for (; myDSIt.More(); myDSIt.Next()) |
577 | myIsDone=Standard_True; |
578 | } |
579 | |
580 | //======================================================================= |
581 | // function: PerformEF |
582 | // purpose: |
583 | //======================================================================= |
584 | void BOPTools_Checker::PerformEF() |
585 | { |
586 | myIsDone=Standard_False; |
587 | // |
588 | Standard_Boolean justaddinterference, bSameFlag; |
589 | Standard_Integer n1, n2, nE, nF, i, aNbCPrts; |
590 | // |
591 | // E/F Interferences [BooleanOperations_EdgeFace] |
592 | myDSIt.Initialize(TopAbs_EDGE, TopAbs_FACE); |
593 | // |
594 | for (; myDSIt.More(); myDSIt.Next()) { |
595 | justaddinterference = Standard_True; |
596 | myDSIt.Current(n1, n2, justaddinterference); |
597 | // |
598 | nE=n1; |
599 | nF=n2; |
600 | SortTypes(nE, nF); |
601 | // |
602 | Standard_Real aTolE, aTolF, aDeflection=0.01; |
603 | Standard_Integer aDiscretize=35; |
604 | |
605 | const TopoDS_Edge& aE=TopoDS::Edge(myDS->GetShape(nE)); |
606 | const TopoDS_Face& aF=TopoDS::Face(myDS->GetShape(nF)); |
607 | // |
608 | if (BRep_Tool::Degenerated(aE)){ |
609 | continue; |
610 | } |
611 | // |
612 | TopTools_IndexedMapOfShape aMF; |
613 | // |
614 | bSameFlag=Standard_False; |
615 | // |
616 | TopExp::MapShapes(aF, TopAbs_EDGE, aMF); |
617 | if (aMF.Contains(aE)) { |
618 | bSameFlag=Standard_True; |
619 | } |
620 | // |
621 | if (bSameFlag){ |
622 | continue; |
623 | } |
624 | // |
625 | aTolE=BRep_Tool::Tolerance(aE); |
626 | aTolF=BRep_Tool::Tolerance(aF); |
627 | // |
628 | const Bnd_Box& aBBF=myDS->GetBoundingBox(nF); |
629 | // |
630 | BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE)); |
631 | BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB); |
632 | |
633 | for (; anIt.More(); anIt.Next()) { |
634 | BOPTools_PaveBlock& aPB=anIt.Value(); |
635 | const IntTools_ShrunkRange& aShrunkRange=aPB.ShrunkRange(); |
636 | const IntTools_Range& aSR =aShrunkRange.ShrunkRange(); |
637 | const Bnd_Box& aBBE=aShrunkRange.BndBox(); |
638 | // |
639 | if (aBBF.IsOut (aBBE)) { |
640 | continue; |
641 | } |
642 | // |
643 | // EF |
644 | IntTools_EdgeFace aEF; |
645 | aEF.SetEdge (aE); |
646 | aEF.SetFace (aF); |
647 | aEF.SetTolE (aTolE); |
648 | aEF.SetTolF (aTolF); |
649 | aEF.SetDiscretize (aDiscretize); |
650 | aEF.SetDeflection (aDeflection); |
651 | |
652 | IntTools_Range anewSR = aSR; |
653 | // |
654 | BOPTools_Tools::CorrectRange(aE, aF, aSR, anewSR); |
655 | // |
656 | aEF.SetRange (anewSR); |
657 | // |
658 | aEF.Perform(); |
659 | // |
660 | if (aEF.IsDone()) { |
661 | // |
662 | const IntTools_SequenceOfCommonPrts& aCPrts=aEF.CommonParts(); |
663 | aNbCPrts=aCPrts.Length(); |
664 | for (i=1; i<=aNbCPrts; i++) { |
665 | const IntTools_CommonPrt& aCPart=aCPrts(i); |
666 | // |
667 | TopAbs_ShapeEnum aType=aCPart.Type(); |
668 | switch (aType) { |
669 | |
670 | case TopAbs_VERTEX: { |
671 | |
672 | Standard_Real aT; |
673 | |
674 | const IntTools_Range& aR=aCPart.Range1(); |
675 | |
676 | Standard_Real aRFirst, aRLast; |
677 | |
678 | aR.Range(aRFirst, aRLast); |
679 | aT=0.5*(aRFirst+aRLast); |
680 | |
681 | if((aCPart.VertexParameter1() >= aRFirst) && |
682 | (aCPart.VertexParameter1() <= aRLast)) { |
683 | aT = aCPart.VertexParameter1(); |
684 | } |
685 | // |
686 | char buf[512]; |
687 | sprintf (buf, "EF: (%d, %d), vertex at t=%f", nE, nF, aT); |
688 | // |
689 | gp_Pnt aPnt; |
690 | BOPTools_Tools::PointOnEdge(aE, aT, aPnt); |
691 | Handle (Geom_CartesianPoint) aCPnt= new Geom_CartesianPoint(aPnt); |
692 | // myInerference=aCPnt; |
693 | |
694 | BOPTools_CheckResult aChRes; |
695 | aChRes.AddShape(aE); |
696 | aChRes.AddShape(aF); |
697 | aChRes.SetCheckStatus(BOPTools_EDGEFACE); |
698 | // modified by NIZHNY-MKK Fri Sep 3 16:02:10 2004 |
699 | // aChRes.SetInterferenceGeometry(myInerference); |
700 | aChRes.SetInterferenceGeometry(aCPnt); |
701 | myCheckResults.Append(aChRes); |
702 | |
703 | if(myStopOnFirst) |
704 | throw BOPTColStd_Failure(buf) ; |
705 | }// case TopAbs_VERTEX: |
706 | break; |
707 | |
708 | case TopAbs_EDGE: { |
709 | |
710 | Standard_Boolean aCoinsideFlag; |
711 | aCoinsideFlag=BOPTools_Tools::IsBlockInOnFace(aPB, aF, myContext); |
712 | if (!aCoinsideFlag) { |
713 | break; |
714 | } |
715 | // |
716 | char buf[512]; |
717 | sprintf (buf, "EF: (%d, %d), common block ", nE, nF); |
718 | |
719 | BOPTools_CheckResult aChRes; |
720 | aChRes.AddShape(aE); |
721 | aChRes.AddShape(aF); |
722 | aChRes.SetCheckStatus(BOPTools_EDGEFACECOMBLK); |
723 | myCheckResults.Append(aChRes); |
724 | |
725 | if(myStopOnFirst) |
726 | throw BOPTColStd_Failure(buf) ; |
727 | }// case TopAbs_EDGE: |
728 | break; |
729 | |
730 | default: |
731 | break; |
732 | } // switch (aType) |
733 | } // for (i=1; i<=aNbCPrts; i++) |
734 | } //if (aEF.IsDone()) |
735 | } // for (; anIt.More(); anIt.Next()) |
736 | }// for (; myDSIt.More(); myDSIt.Next()) |
737 | myIsDone=Standard_True; |
738 | } |
739 | |
740 | //======================================================================= |
741 | // function: PerformFF |
742 | // purpose: |
743 | //======================================================================= |
744 | void BOPTools_Checker::PerformFF() |
745 | { |
746 | myIsDone=Standard_False; |
747 | // |
748 | Standard_Boolean justaddinterference, bSameFlag; |
749 | Standard_Integer n1, n2, nF1, nF2, i, aNbS1; |
750 | // |
751 | // F/F Interferences [BooleanOperations_SurfaceSurface] |
752 | myDSIt.Initialize(TopAbs_FACE, TopAbs_FACE); |
753 | // |
754 | for (; myDSIt.More(); myDSIt.Next()) { |
755 | justaddinterference = Standard_True; |
756 | myDSIt.Current(n1, n2, justaddinterference); |
757 | // |
758 | nF1=n1; |
759 | nF2=n2; |
760 | if (nF1 > nF2) { |
761 | Standard_Integer iTmp; |
762 | iTmp=nF1; |
763 | nF1=nF2; |
764 | nF2=iTmp; |
765 | } |
766 | // |
767 | const TopoDS_Face& aF1=TopoDS::Face(myDS->Shape(nF1)); |
768 | const TopoDS_Face& aF2=TopoDS::Face(myDS->Shape(nF2)); |
769 | // |
770 | TopTools_IndexedMapOfShape aM1, aM2; |
771 | // |
772 | bSameFlag=Standard_False; |
773 | // |
774 | TopExp::MapShapes(aF1, TopAbs_EDGE, aM1); |
775 | TopExp::MapShapes(aF2, TopAbs_EDGE, aM2); |
776 | // |
777 | aNbS1=aM1.Extent(); |
778 | |
779 | for (i=1; i<=aNbS1; ++i) { |
780 | const TopoDS_Shape& aS1=aM1(i); |
781 | if (aM2.Contains(aS1)) { |
782 | bSameFlag=Standard_True; |
783 | break; |
784 | } |
785 | } |
786 | // |
787 | if (bSameFlag){ |
788 | continue; |
789 | } |
790 | // |
791 | // FF |
792 | Standard_Boolean bToApproxC3d, bToApproxC2dOnS1, bToApproxC2dOnS2; |
793 | Standard_Real anApproxTol, aTolR3D, aTolR2D; |
794 | // |
795 | bToApproxC3d = mySectionAttribute.Approximation(); |
796 | bToApproxC2dOnS1 = mySectionAttribute.PCurveOnS1(); |
797 | bToApproxC2dOnS2 = mySectionAttribute.PCurveOnS2(); |
798 | // |
799 | anApproxTol=1.e-7; |
800 | |
801 | IntTools_FaceFace aFF; |
802 | aFF.SetParameters (bToApproxC3d, |
803 | bToApproxC2dOnS1, |
804 | bToApproxC2dOnS2, |
805 | anApproxTol); |
806 | |
807 | aFF.Perform(aF1, aF2); |
808 | |
809 | if (aFF.IsDone()) { |
810 | // Add Interference to the Pool |
811 | aTolR3D=aFF.TolReached3d(); |
812 | aTolR2D=aFF.TolReached2d(); |
813 | if (aTolR3D < 1.e-7){ |
814 | aTolR3D=1.e-7; |
815 | } |
816 | aFF.PrepareLines3D(); |
817 | // |
818 | // |
819 | Standard_Integer j, aNbCurves, aNbPoints; |
820 | // |
821 | const IntTools_SequenceOfCurves& aCvs=aFF.Lines(); |
822 | aNbCurves=aCvs.Length(); |
823 | // |
824 | const IntTools_SequenceOfPntOn2Faces& aPnts=aFF.Points(); |
825 | aNbPoints=aPnts.Length(); |
826 | |
827 | if (aNbPoints) { |
828 | char buf[512]; |
829 | sprintf (buf, "FF: (%d, %d) ", nF1, nF2); |
830 | // |
831 | const IntTools_PntOn2Faces& aPntOn2Faces=aPnts(1); |
832 | const IntTools_PntOnFace& aPntOnFace=aPntOn2Faces.P1(); |
833 | const gp_Pnt& aPnt=aPntOnFace.Pnt(); |
834 | Handle (Geom_CartesianPoint) aCPnt= new Geom_CartesianPoint(aPnt); |
835 | // myInerference=aCPnt; |
836 | |
837 | BOPTools_CheckResult aChRes; |
838 | aChRes.AddShape(aF1); |
839 | aChRes.AddShape(aF2); |
840 | aChRes.SetCheckStatus(BOPTools_FACEFACE); |
841 | // modified by NIZHNY-MKK Fri Sep 3 16:02:25 2004 |
842 | // aChRes.SetInterferenceGeometry(myInerference); |
843 | aChRes.SetInterferenceGeometry(aCPnt); |
844 | myCheckResults.Append(aChRes); |
845 | |
846 | if(myStopOnFirst) |
847 | throw BOPTColStd_Failure(buf) ; |
848 | } |
849 | |
850 | if (aNbCurves) { |
851 | for (j=1; j<=aNbCurves; j++) { |
852 | const IntTools_Curve& aC=aCvs(j); |
853 | if (aC.HasBounds()) { |
854 | Standard_Real aT1, aT2; |
855 | Standard_Boolean bValid; |
856 | gp_Pnt aP1, aP2; |
857 | |
858 | aC.Bounds(aT1, aT2, aP1, aP2); |
859 | // |
860 | bValid=myContext.IsValidBlockForFaces(aT1, aT2, aC, aF1, aF2, 1.e-3); |
861 | // |
862 | if (bValid) { |
863 | char buf[512]; |
864 | sprintf (buf, "FF: (%d, %d) ", nF1, nF2); |
865 | // |
866 | Handle (Geom_Curve) aC3D=aC.Curve(); |
867 | Handle (Geom_TrimmedCurve) aTC3D=Handle (Geom_TrimmedCurve)::DownCast(aC3D); |
868 | // myInerference=aTC3D; |
869 | |
870 | BOPTools_CheckResult aChRes; |
871 | aChRes.AddShape(aF1); |
872 | aChRes.AddShape(aF2); |
873 | aChRes.SetCheckStatus(BOPTools_FACEFACE); |
874 | // modified by NIZHNY-MKK Fri Sep 3 16:02:40 2004 |
875 | // aChRes.SetInterferenceGeometry(myInerference); |
876 | aChRes.SetInterferenceGeometry(aTC3D); |
877 | myCheckResults.Append(aChRes); |
878 | |
879 | if(myStopOnFirst) |
880 | throw BOPTColStd_Failure(buf) ; |
881 | } |
882 | } |
883 | } |
884 | }// if (aNbCurves) |
885 | |
886 | }// if (aFF.IsDone()) |
887 | }// for (; myDSIt.More(); myDSIt.Next()) |
888 | myIsDone=Standard_True; |
889 | } |
890 | //======================================================================= |
891 | // function: PrepareEdges |
892 | // purpose: |
893 | //======================================================================= |
894 | void BOPTools_Checker::PrepareEdges() |
895 | { |
896 | Standard_Integer i, nV, ii, aNBSuc; |
897 | Standard_Real aT; |
898 | TopAbs_Orientation anOr; |
899 | TopoDS_Edge aE; |
900 | TopoDS_Vertex aV; |
901 | |
902 | for (i=1; i<=myNbSources; i++) { |
903 | if (myDS->GetShapeType(i)==TopAbs_EDGE) { |
904 | aE=TopoDS::Edge(myDS->GetShape(i)); |
905 | // |
906 | if (BRep_Tool::Degenerated(aE)){ |
907 | continue; |
908 | } |
909 | // |
910 | BOPTools_PaveSet& aPaveSet= myPavePool(myDS->RefEdge(i)); |
911 | // |
912 | // cto900/M2 |
913 | // Some of Edges can be [Semi] Infinite. Such Edges have no |
914 | // vertices on correspondant INF ends. So we must provide |
915 | // these vertices formally (to obtain Shrunk Ranges for e.g). |
916 | // In reality this vertex(-es) does not belong to the INF Edge. |
917 | // It just has reference in the DS. |
918 | // PKV Tue Apr 23 10:21:45 2002 |
919 | { |
920 | Standard_Real aT1, aT2, aTolE; |
921 | Standard_Boolean bInf1, bInf2; |
922 | gp_Pnt aPx; |
923 | TopoDS_Vertex aVx; |
924 | BRep_Builder aBB; |
925 | BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq; |
926 | // |
927 | aTolE=BRep_Tool::Tolerance(aE); |
928 | Handle(Geom_Curve) aC3D=BRep_Tool::Curve (aE, aT1, aT2); |
929 | bInf1=Precision::IsNegativeInfinite(aT1); |
930 | bInf2=Precision::IsPositiveInfinite(aT2); |
931 | |
932 | if (bInf1) { |
933 | aC3D->D0(aT1, aPx); |
934 | aBB.MakeVertex(aVx, aPx, aTolE); |
935 | myDS->InsertShapeAndAncestorsSuccessors(aVx, anASSeq); |
936 | nV=myDS->NumberOfInsertedShapes(); |
937 | BOPTools_Pave aPave(nV, aT1); |
938 | aPaveSet.Append (aPave); |
939 | } |
940 | |
941 | if (bInf2) { |
942 | aC3D->D0(aT2, aPx); |
943 | aBB.MakeVertex(aVx, aPx, aTolE); |
944 | myDS->InsertShapeAndAncestorsSuccessors(aVx, anASSeq); |
945 | nV=myDS->NumberOfInsertedShapes(); |
946 | BOPTools_Pave aPave(nV, aT2); |
947 | aPaveSet.Append (aPave); |
948 | } |
949 | } |
950 | // |
951 | aNBSuc=myDS->NumberOfSuccessors(i); |
952 | for (ii=1; ii <= aNBSuc; ii++) { |
953 | nV=myDS->GetSuccessor(i, ii); |
954 | anOr=myDS->GetOrientation(i, ii); |
955 | |
956 | aV=TopoDS::Vertex(myDS->GetShape(nV)); |
957 | aV.Orientation(anOr); |
958 | aT=BRep_Tool::Parameter(aV, aE); |
959 | // |
960 | BOPTools_Pave aPave(nV, aT); |
961 | aPaveSet.Append (aPave); |
962 | } |
963 | } |
964 | } |
965 | } |
966 | //======================================================================= |
967 | // function: PreparePaveBlocks |
968 | // purpose: |
969 | //======================================================================= |
970 | void BOPTools_Checker::PreparePaveBlocks(const TopAbs_ShapeEnum aType1, |
971 | const TopAbs_ShapeEnum aType2) |
972 | { |
973 | BOPTools_PaveFiller::PreparePaveBlocks(aType1, aType2); |
974 | } |
975 | //======================================================================= |
976 | // function: PreparePaveBlocks |
977 | // purpose: |
978 | //======================================================================= |
979 | void BOPTools_Checker::PreparePaveBlocks(const Standard_Integer nE) |
980 | { |
981 | myIsDone=Standard_False; |
982 | |
983 | Standard_Integer nV1, nV2; |
984 | |
985 | TopoDS_Edge aE; |
986 | TopoDS_Vertex aV1, aV2; |
987 | |
988 | // SplitShapesPool |
989 | BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE)); |
990 | // Edge |
991 | aE=TopoDS::Edge(myDS->GetShape(nE)); |
992 | // |
993 | if (!BRep_Tool::Degenerated(aE)){ |
994 | // |
995 | BOPTools_PaveSet& aPS=myPavePool(myDS->RefEdge(nE)); |
996 | |
997 | BOPTools_PaveBlockIterator aPBIt(nE, aPS); |
998 | for (; aPBIt.More(); aPBIt.Next()) { |
999 | BOPTools_PaveBlock& aPB=aPBIt.Value(); |
1000 | |
1001 | const IntTools_Range& aRange=aPB.Range(); |
1002 | |
1003 | const BOPTools_Pave& aPave1=aPB.Pave1(); |
1004 | nV1=aPave1.Index(); |
1005 | aV1=TopoDS::Vertex(myDS->GetShape(nV1)); |
1006 | |
1007 | const BOPTools_Pave& aPave2=aPB.Pave2(); |
1008 | nV2=aPave2.Index(); |
1009 | aV2=TopoDS::Vertex(myDS->GetShape(nV2)); |
1010 | // |
1011 | // ShrunkRange |
1012 | IntTools_ShrunkRange aSR (aE, aV1, aV2, aRange, myContext); |
1013 | // |
1014 | Standard_Integer anErrorStatus; |
1015 | anErrorStatus=aSR.ErrorStatus(); |
1016 | |
1017 | char buf[512]; |
1018 | if (!aSR.IsDone()) { |
1019 | sprintf (buf, "Can not obtain ShrunkRange for Edge %d", nE); |
1020 | |
1021 | BOPTools_CheckResult aChRes; |
1022 | aChRes.AddShape(aE); |
1023 | aChRes.SetCheckStatus(BOPTools_BADSHRANKRANGE); |
1024 | myCheckResults.Append(aChRes); |
1025 | |
1026 | if(myStopOnFirst) |
1027 | throw BOPTColStd_Failure(buf) ; |
1028 | } |
1029 | // |
1030 | if (anErrorStatus==6) { |
1031 | sprintf(buf, |
1032 | "Warning: [PreparePaveBlocks()] Max.Dummy Shrunk Range for Edge %d\n", nE); |
1033 | |
1034 | BOPTools_CheckResult aChRes; |
1035 | aChRes.AddShape(aE); |
1036 | aChRes.SetCheckStatus(BOPTools_NULLSRANKRANGE); |
1037 | myCheckResults.Append(aChRes); |
1038 | |
1039 | if(myStopOnFirst) |
1040 | throw BOPTColStd_Failure(buf); |
1041 | } |
1042 | else { |
1043 | // Check left paves and correct ShrunkRange if it is necessary |
1044 | CorrectShrunkRanges (0, aPave1, aSR); |
1045 | CorrectShrunkRanges (1, aPave2, aSR); |
1046 | } |
1047 | // |
1048 | aPB.SetShrunkRange(aSR); |
1049 | aLPB.Append(aPB); |
1050 | } //for (; aPBIt1.More(); aPBIt1.Next()) |
1051 | } |
1052 | myIsDone=Standard_True; |
1053 | } |
1054 | |
1055 | //======================================================================= |
1056 | // function: GetCheckResult |
1057 | // purpose: |
1058 | //======================================================================= |
1059 | const BOPTools_ListOfCheckResults& BOPTools_Checker::GetCheckResult() const |
1060 | { |
1061 | return myCheckResults; |
1062 | } |
1063 | |
1064 | //======================================================================= |
1065 | // function: HasFaulty |
1066 | // purpose: |
1067 | //======================================================================= |
1068 | Standard_Boolean BOPTools_Checker::HasFaulty()const |
1069 | { |
1070 | return (!myIsDone || !myCheckResults.IsEmpty()); |
1071 | } |
1072 | |
1073 | //======================================================================= |
1074 | // function: Shape |
1075 | // purpose: |
1076 | //======================================================================= |
1077 | const TopoDS_Shape& BOPTools_Checker::Shape()const |
1078 | { |
1079 | return myShape; |
1080 | } |
1081 | |
1082 | |
1083 | |