0024220: bopargcheck returns valid for C0 shape but results of boolean operations...
[occt.git] / src / BOPAlgo / BOPAlgo_ArgumentAnalyzer.cxx
... / ...
CommitLineData
1// Created on: 2004-09-02
2// Copyright (c) 2004-2012 OPEN CASCADE SAS
3//
4// The content of this file is subject to the Open CASCADE Technology Public
5// License Version 6.5 (the "License"). You may not use the content of this file
6// except in compliance with the License. Please obtain a copy of the License
7// at http://www.opencascade.org and read it completely before using this file.
8//
9// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11//
12// The Original Code and all software distributed under the License is
13// distributed on an "AS IS" basis, without warranty of any kind, and the
14// Initial Developer hereby disclaims all such warranties, including without
15// limitation, any warranties of merchantability, fitness for a particular
16// purpose or non-infringement. Please see the License for the specific terms
17// and conditions governing the rights and limitations under the License.
18
19#include <BOPAlgo_ArgumentAnalyzer.ixx>
20
21#include <Standard_ErrorHandler.hxx>
22#include <Standard_Failure.hxx>
23#include <TopExp.hxx>
24#include <TopExp_Explorer.hxx>
25#include <BRep_Builder.hxx>
26#include <BRep_Tool.hxx>
27#include <BRepExtrema_DistShapeShape.hxx>
28#include <gp_Pnt.hxx>
29#include <TopoDS_Iterator.hxx>
30#include <TopoDS.hxx>
31#include <TopoDS_Vertex.hxx>
32#include <TopoDS_Edge.hxx>
33#include <TopoDS_Wire.hxx>
34#include <TopoDS_Shell.hxx>
35#include <TopoDS_Solid.hxx>
36#include <BOPCol_ListOfShape.hxx>
37#include <BOPCol_SequenceOfShape.hxx>
38#include <BOPCol_MapOfShape.hxx>
39
40#include <TColStd_Array2OfBoolean.hxx>
41
42#include <IntTools_Range.hxx>
43#include <IntTools_EdgeEdge.hxx>
44#include <IntTools_CommonPrt.hxx>
45
46#include <BOPAlgo_Operation.hxx>
47#include <BOPAlgo_CheckerSI.hxx>
48#include <BOPAlgo_BuilderFace.hxx>
49
50#include <BOPDS_DS.hxx>
51#include <BOPDS_VectorOfInterfVV.hxx>
52#include <BOPDS_VectorOfInterfVE.hxx>
53#include <BOPDS_VectorOfInterfEE.hxx>
54#include <BOPDS_VectorOfInterfVF.hxx>
55#include <BOPDS_VectorOfInterfEF.hxx>
56#include <BOPDS_VectorOfInterfFF.hxx>
57
58#include <BOPInt_Context.hxx>
59
60#include <BOPTools_AlgoTools3D.hxx>
61#include <BOPTools_AlgoTools.hxx>
62#include <BOPCol_ListOfShape.hxx>
63#include <Geom_Surface.hxx>
64
65// ================================================================================
66// function: Constructor
67// purpose:
68// ================================================================================
69BOPAlgo_ArgumentAnalyzer::BOPAlgo_ArgumentAnalyzer() :
70myStopOnFirst(Standard_False),
71myOperation(BOPAlgo_UNKNOWN),
72myArgumentTypeMode(Standard_False),
73mySelfInterMode(Standard_False),
74mySmallEdgeMode(Standard_False),
75myRebuildFaceMode(Standard_False),
76myTangentMode(Standard_False),
77myMergeVertexMode(Standard_False),
78myMergeEdgeMode(Standard_False),
79myContinuityMode(Standard_False),
80myEmpty1(Standard_False),
81myEmpty2(Standard_False)
82// myMergeFaceMode(Standard_False)
83{
84}
85
86// ================================================================================
87// function: SetShape1
88// purpose:
89// ================================================================================
90void BOPAlgo_ArgumentAnalyzer::SetShape1(const TopoDS_Shape & TheShape)
91{
92 myShape1 = TheShape;
93}
94
95// ================================================================================
96// function: SetShape2
97// purpose:
98// ================================================================================
99void BOPAlgo_ArgumentAnalyzer::SetShape2(const TopoDS_Shape & TheShape)
100{
101 myShape2 = TheShape;
102}
103
104// ================================================================================
105// function: GetShape1
106// purpose:
107// ================================================================================
108const TopoDS_Shape & BOPAlgo_ArgumentAnalyzer::GetShape1() const
109{
110 return myShape1;
111}
112
113// ================================================================================
114// function: GetShape2
115// purpose:
116// ================================================================================
117const TopoDS_Shape & BOPAlgo_ArgumentAnalyzer::GetShape2() const
118{
119 return myShape2;
120}
121
122// ================================================================================
123// function: OperationType
124// purpose:
125// ================================================================================
126BOPAlgo_Operation& BOPAlgo_ArgumentAnalyzer::OperationType()
127{
128 return myOperation;
129}
130
131// ================================================================================
132// function: StopOnFirstFaulty
133// purpose:
134// ================================================================================
135Standard_Boolean & BOPAlgo_ArgumentAnalyzer::StopOnFirstFaulty()
136{
137 return myStopOnFirst;
138}
139
140// ================================================================================
141// function: Prepare
142// purpose:
143// ================================================================================
144void BOPAlgo_ArgumentAnalyzer::Prepare()
145{
146 Standard_Boolean isS1 = myShape1.IsNull(), isS2 = myShape2.IsNull();
147 if (!isS1) {
148 myEmpty1 = BOPTools_AlgoTools3D::IsEmptyShape(myShape1);
149 }
150 if (!isS2) {
151 myEmpty2 = BOPTools_AlgoTools3D::IsEmptyShape(myShape2);
152 }
153}
154// ================================================================================
155// function: Perform
156// purpose:
157// ================================================================================
158void BOPAlgo_ArgumentAnalyzer::Perform()
159{
160 try {
161 OCC_CATCH_SIGNALS
162 myResult.Clear();
163
164 Prepare();
165
166 if(myArgumentTypeMode) {
167 TestTypes();
168 }
169
170 if(mySelfInterMode) {
171 TestSelfInterferences();
172 }
173
174 if(mySmallEdgeMode) {
175 if(!(!myResult.IsEmpty() && myStopOnFirst))
176 TestSmallEdge();
177 }
178
179 if(myRebuildFaceMode) {
180 if(!(!myResult.IsEmpty() && myStopOnFirst))
181 TestRebuildFace();
182 }
183
184 if(myTangentMode) {
185 if(!(!myResult.IsEmpty() && myStopOnFirst))
186 TestTangent();
187 }
188
189 if(myMergeVertexMode) {
190 if(!(!myResult.IsEmpty() && myStopOnFirst))
191 TestMergeVertex();
192 }
193
194 if(myMergeEdgeMode) {
195 if(!(!myResult.IsEmpty() && myStopOnFirst))
196 TestMergeEdge();
197 }
198
199 if(myContinuityMode) {
200 if(!(!myResult.IsEmpty() && myStopOnFirst))
201 TestContinuity();
202 }
203 }
204 catch(Standard_Failure) {
205 BOPAlgo_CheckResult aResult;
206 aResult.SetCheckStatus(BOPAlgo_CheckUnknown);
207 myResult.Append(aResult);
208 }
209}
210
211// ================================================================================
212// function: HasFaulty
213// purpose:
214// ================================================================================
215Standard_Boolean BOPAlgo_ArgumentAnalyzer::HasFaulty() const
216{
217 return ( !myResult.IsEmpty());
218}
219
220// ================================================================================
221// function: GetCheckResult
222// purpose:
223// ================================================================================
224const BOPAlgo_ListOfCheckResult& BOPAlgo_ArgumentAnalyzer::GetCheckResult() const
225{
226 return myResult;
227}
228
229// ================================================================================
230// function: TestTypes
231// purpose:
232// ================================================================================
233void BOPAlgo_ArgumentAnalyzer::TestTypes()
234{
235 Standard_Boolean isS1 = myShape1.IsNull(), isS2 = myShape2.IsNull();
236
237 if(isS1 && isS2) {
238 BOPAlgo_CheckResult aResult;
239 aResult.SetCheckStatus(BOPAlgo_BadType);
240 myResult.Append(aResult);
241 return;
242 }
243
244 //single shape check
245 if((isS1 && !isS2) || (!isS1 && isS2)) {
246 Standard_Boolean bIsEmpty = (isS1) ? myEmpty2 : myEmpty1;
247
248 if(bIsEmpty || myOperation!=BOPAlgo_UNKNOWN) {
249 const TopoDS_Shape & aS = (isS1) ? myShape2 : myShape1;
250 BOPAlgo_CheckResult aResult;
251 aResult.SetShape1(aS);
252 aResult.SetCheckStatus(BOPAlgo_BadType);
253 myResult.Append(aResult);
254 return;
255 }
256 }
257 // two shapes check (begin)
258 else {
259 if(myEmpty1 || myEmpty2) {
260 BOPAlgo_CheckResult aResult;
261 if(myEmpty1 && myEmpty2) {
262 aResult.SetShape1(myShape1);
263 aResult.SetShape2(myShape2);
264 }
265 else {
266 const TopoDS_Shape & aS = myEmpty1 ? myShape1 : myShape2;
267 if(myEmpty1)
268 aResult.SetShape1(aS);
269 else
270 aResult.SetShape2(aS);
271 }
272 aResult.SetCheckStatus(BOPAlgo_BadType);
273 myResult.Append(aResult);
274 return;
275 }
276 //
277 Standard_Integer aDim1, aDim2;
278 Standard_Boolean bBadTypes = Standard_False;
279 //
280 aDim1 = BOPTools_AlgoTools::Dimension(myShape1);
281 aDim2 = BOPTools_AlgoTools::Dimension(myShape2);
282 if (aDim1 < aDim2) {
283 if (myOperation == BOPAlgo_FUSE ||
284 myOperation == BOPAlgo_CUT21) {
285 bBadTypes = Standard_True;
286 }
287 }
288 else if (aDim1 > aDim2) {
289 if (myOperation == BOPAlgo_FUSE ||
290 myOperation == BOPAlgo_CUT) {
291 bBadTypes = Standard_True;
292 }
293 }
294 if (bBadTypes) {
295 BOPAlgo_CheckResult aResult;
296 aResult.SetShape1(myShape1);
297 aResult.SetShape2(myShape2);
298 aResult.SetCheckStatus(BOPAlgo_BadType);
299 myResult.Append(aResult);
300 }
301 }
302}
303
304// ================================================================================
305// function: TestSelfInterferences
306// purpose:
307// ================================================================================
308void BOPAlgo_ArgumentAnalyzer::TestSelfInterferences()
309{
310 Standard_Integer ii = 0, j;
311 Standard_Boolean bSelfInt;
312
313 for(ii = 0; ii < 2; ii++) {
314 const TopoDS_Shape& aS = (ii == 0) ? myShape1 : myShape2;
315
316 if(aS.IsNull())
317 continue;
318
319 Standard_Boolean bIsEmpty = (ii == 0) ? myEmpty1 : myEmpty2;
320 if (bIsEmpty) {
321 continue;
322 }
323
324 BOPAlgo_CheckerSI aChecker;
325 BOPCol_ListOfShape anArgs;
326 anArgs.Append(aS);
327 aChecker.SetArguments(anArgs);
328 //
329 aChecker.Perform();
330 Standard_Integer iErr = aChecker.ErrorStatus();
331 //
332 const BOPDS_PDS& theDS = aChecker.PDS();
333 BOPDS_VectorOfInterfVV& aVVs=theDS->InterfVV();
334 BOPDS_VectorOfInterfVE& aVEs=theDS->InterfVE();
335 BOPDS_VectorOfInterfEE& aEEs=theDS->InterfEE();
336 BOPDS_VectorOfInterfVF& aVFs=theDS->InterfVF();
337 BOPDS_VectorOfInterfEF& aEFs=theDS->InterfEF();
338 BOPDS_VectorOfInterfFF& aFFs=theDS->InterfFF();
339 //
340 Standard_Integer aNb[6] = {aVVs.Extent(), aVEs.Extent(), aEEs.Extent(),
341 aVFs.Extent(), aEFs.Extent(), aFFs.Extent()};
342 //
343 for (Standard_Integer aTypeInt = 0; aTypeInt < 6; ++aTypeInt) {
344 for (Standard_Integer i = 0; i < aNb[aTypeInt]; ++i) {
345 BOPDS_Interf* aInt = (aTypeInt==0) ? (BOPDS_Interf*)(&aVVs(i)) :
346 ((aTypeInt==1) ? (BOPDS_Interf*)(&aVEs(i)) :
347 ((aTypeInt==2) ? (BOPDS_Interf*)(&aEEs(i)) :
348 ((aTypeInt==3) ? (BOPDS_Interf*)(&aVFs(i)) :
349 ((aTypeInt==4) ? (BOPDS_Interf*)(&aEFs(i)) : (BOPDS_Interf*)(&aFFs(i))))));
350 //
351 Standard_Integer nI1 = aInt->Index1();
352 Standard_Integer nI2 = aInt->Index2();
353 if (nI1 == nI2) {
354 continue;
355 }
356 //
357 if (aTypeInt == 4) {
358 BOPDS_InterfEF& aEF=aEFs(i);
359 if (aEF.CommonPart().Type()==TopAbs_SHAPE) {
360 continue;
361 }
362 }
363 //
364 const TopoDS_Shape& aS1 = theDS->Shape(nI1);
365 const TopoDS_Shape& aS2 = theDS->Shape(nI2);
366 //
367 if (aTypeInt == 5) {
368 bSelfInt = Standard_False;
369 BOPDS_InterfFF& aFF = aFFs(i);
370 BOPDS_VectorOfPoint& aVP=aFF.ChangePoints();
371 Standard_Integer aNbP=aVP.Extent();
372 BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
373 Standard_Integer aNbC=aVC.Extent();
374 if (!aNbP && !aNbC) {
375 continue;
376 }
377 for (j=0; j<aNbC; ++j) {
378 BOPDS_Curve& aNC=aVC(j);
379 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
380 if (aLPBC.Extent()) {
381 bSelfInt = Standard_True;
382 break;
383 }
384 }
385 if (!bSelfInt) {
386 continue;
387 }
388 }
389 //
390 BOPAlgo_CheckResult aResult;
391 if(ii == 0) {
392 aResult.SetShape1(myShape1);
393 aResult.AddFaultyShape1(aS1);
394 aResult.AddFaultyShape1(aS2);
395 }
396 else {
397 aResult.SetShape2(myShape2);
398 aResult.AddFaultyShape2(aS1);
399 aResult.AddFaultyShape2(aS2);
400 }
401 aResult.SetCheckStatus(BOPAlgo_SelfIntersect);
402 myResult.Append(aResult);
403 }
404 }
405 if (iErr) {
406 BOPAlgo_CheckResult aResult;
407 if(ii == 0) {
408 aResult.SetShape1(myShape1);
409 aResult.AddFaultyShape1(myShape1);
410 }
411 else {
412 aResult.SetShape2(myShape2);
413 aResult.AddFaultyShape2(myShape2);
414 }
415 aResult.SetCheckStatus(BOPAlgo_OperationAborted);
416 myResult.Append(aResult);
417 }
418 }
419
420}
421
422// ================================================================================
423// function: TestSmallEdge
424// purpose:
425// ================================================================================
426void BOPAlgo_ArgumentAnalyzer::TestSmallEdge()
427{
428 Standard_Integer i = 0;
429 BRepExtrema_DistShapeShape aDist;
430 Handle(BOPInt_Context) aCtx;
431 //
432 aCtx = new BOPInt_Context;
433
434 for(i = 0; i < 2; i++) {
435 const TopoDS_Shape& aS = (i == 0) ? myShape1 : myShape2;
436
437 if(aS.IsNull())
438 continue;
439
440 TopExp_Explorer anExp(aS, TopAbs_EDGE);
441
442 for(; anExp.More(); anExp.Next()) {
443 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&anExp.Current();
444 if (BRep_Tool::Degenerated(anEdge)) {
445 continue;
446 }
447
448 if(BOPTools_AlgoTools::IsMicroEdge(anEdge, aCtx)) {
449 Standard_Boolean bKeepResult = Standard_True;
450
451 if(myOperation == BOPAlgo_SECTION) {
452 const TopoDS_Shape& anOtherS = (i == 0) ? myShape2 : myShape1;
453
454 if(!anOtherS.IsNull()) {
455 aDist.LoadS2(anOtherS);
456
457 Standard_Boolean bVertexIsOnShape = Standard_False;
458 Standard_Integer ii = 0;
459 TopExp_Explorer anExpV(anEdge, TopAbs_VERTEX);
460
461 for(; anExpV.More(); anExpV.Next()) {
462 const TopoDS_Shape& aV = anExpV.Current();
463
464 aDist.LoadS1(aV);
465 aDist.Perform();
466
467 if(aDist.IsDone()) {
468
469 for(ii = 1; ii <= aDist.NbSolution(); ii++) {
470 Standard_Real aTolerance = BRep_Tool::Tolerance(*(TopoDS_Vertex*)&aV);
471 const TopoDS_Shape& aSupportShape = aDist.SupportOnShape2(ii);
472
473 switch(aSupportShape.ShapeType()) {
474 case TopAbs_VERTEX: {
475 aTolerance += BRep_Tool::Tolerance(*(TopoDS_Vertex*)&(aSupportShape));
476 break;
477 }
478 case TopAbs_EDGE: {
479 aTolerance += BRep_Tool::Tolerance(*(TopoDS_Edge*)&(aSupportShape));
480 break;
481 }
482 case TopAbs_FACE: {
483 aTolerance += BRep_Tool::Tolerance(*(TopoDS_Face*)&(aSupportShape));
484 break;
485 }
486 default:
487 break;
488 }
489
490 if(aDist.Value() < aTolerance) {
491 bVertexIsOnShape = Standard_True;
492 break;
493 }
494 }
495 }
496 }
497
498 if(!bVertexIsOnShape) {
499 bKeepResult = Standard_False;
500 }
501 }
502 }
503
504 if(bKeepResult) {
505 BOPAlgo_CheckResult aResult;
506
507 if(i == 0) {
508 aResult.SetShape1(myShape1);
509 aResult.AddFaultyShape1(anEdge);
510 }
511 else {
512 aResult.SetShape2(myShape2);
513 aResult.AddFaultyShape2(anEdge);
514 }
515
516 aResult.SetCheckStatus(BOPAlgo_TooSmallEdge);
517 myResult.Append(aResult);
518
519 if(myStopOnFirst) {
520 return;
521 }
522 }
523 }
524 }
525 }
526}
527
528// ================================================================================
529// function: TestRebuildFace
530// purpose:
531// ================================================================================
532void BOPAlgo_ArgumentAnalyzer::TestRebuildFace()
533{
534 if((myOperation == BOPAlgo_SECTION) ||
535 (myOperation == BOPAlgo_UNKNOWN))
536 return;
537 Standard_Integer i = 0;
538
539 for(i = 0; i < 2; i++) {
540 const TopoDS_Shape& aS = (i == 0) ? myShape1 : myShape2;
541
542 if(aS.IsNull())
543 continue;
544
545 TopExp_Explorer anExp(aS, TopAbs_FACE);
546 BOPCol_ListOfShape aLS;
547
548 for(; anExp.More(); anExp.Next()) {
549 const TopoDS_Face& aFace = *(TopoDS_Face*)&(anExp.Current());
550
551 TopoDS_Face aFF = aFace;
552 aFF.Orientation(TopAbs_FORWARD);
553 TopExp_Explorer anExpE(aFF, TopAbs_EDGE);
554 Standard_Integer nbstartedges = 0;
555 aLS.Clear();
556 //
557 for(; anExpE.More(); anExpE.Next()) {
558 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&anExpE.Current()));
559 TopAbs_Orientation anOriE=aE.Orientation();
560 //
561 if (anOriE==TopAbs_INTERNAL) {
562 TopoDS_Edge aEE=aE;
563 aEE.Orientation(TopAbs_FORWARD);
564 aLS.Append(aEE);
565 aEE.Orientation(TopAbs_REVERSED);
566 aLS.Append(aEE);
567 }
568 else {
569 aLS.Append(aE);
570 }
571 nbstartedges++;
572 }
573 BOPAlgo_BuilderFace aBF;
574 aBF.SetFace(aFace);
575 aBF.SetShapes(aLS);
576 aBF.Perform();
577 const BOPCol_ListOfShape& aLF = aBF.Areas();
578 Standard_Boolean bBadFace = Standard_False;
579
580 if(aLF.Extent() != 1) {
581 bBadFace = Standard_True;
582 }
583 else {
584 Standard_Integer nbedgeused = 0;
585 anExpE.Init(aLF.First(), TopAbs_EDGE);
586
587 for(; anExpE.More(); anExpE.Next(), nbedgeused++);
588
589 if(nbstartedges != nbedgeused) {
590 bBadFace = Standard_True;
591 }
592 }
593
594 if(bBadFace) {
595 BOPAlgo_CheckResult aResult;
596
597 if(i == 0) {
598 aResult.SetShape1(myShape1);
599 aResult.AddFaultyShape1(aFace);
600 }
601 else {
602 aResult.SetShape2(myShape2);
603 aResult.AddFaultyShape2(aFace);
604 }
605
606 aResult.SetCheckStatus(BOPAlgo_NonRecoverableFace);
607 myResult.Append(aResult);
608
609 if(myStopOnFirst) {
610 return;
611 }
612 }
613 }
614 }
615}
616
617// ================================================================================
618// function: TestTangent
619// purpose:
620// ================================================================================
621void BOPAlgo_ArgumentAnalyzer::TestTangent()
622{
623 // not implemented
624}
625
626// ================================================================================
627// function: TestMergeSubShapes
628// purpose:
629// ================================================================================
630 void BOPAlgo_ArgumentAnalyzer::TestMergeSubShapes(const TopAbs_ShapeEnum theType)
631{
632 if(myShape1.IsNull() || myShape2.IsNull())
633 return;
634
635 if (myEmpty1 || myEmpty2)
636 return;
637
638 BOPAlgo_CheckStatus aStatus = BOPAlgo_CheckUnknown;
639
640 switch(theType) {
641 case TopAbs_VERTEX: {
642 aStatus = BOPAlgo_IncompatibilityOfVertex;
643 break;
644 }
645 case TopAbs_EDGE: {
646 aStatus = BOPAlgo_IncompatibilityOfEdge;
647 break;
648 }
649 case TopAbs_FACE: {
650 aStatus = BOPAlgo_IncompatibilityOfFace;
651 break;
652 }
653 default:
654 return;
655 }
656 TopExp_Explorer anExp1(myShape1, theType);
657 TopExp_Explorer anExp2(myShape2, theType);
658 BOPCol_SequenceOfShape aSeq1, aSeq2;
659 BOPCol_MapOfShape aMap1, aMap2;
660
661 for(; anExp1.More(); anExp1.Next()) {
662 const TopoDS_Shape& aS1 = anExp1.Current();
663
664 if(aMap1.Contains(aS1))
665 continue;
666 aSeq1.Append(aS1);
667 aMap1.Add(aS1);
668 }
669
670 for(; anExp2.More(); anExp2.Next()) {
671 const TopoDS_Shape& aS2 = anExp2.Current();
672 if(aMap2.Contains(aS2))
673 continue;
674 aSeq2.Append(aS2);
675 aMap2.Add(aS2);
676 }
677
678 TColStd_Array2OfBoolean anArrayOfFlag(1, aSeq1.Length(), 1, aSeq2.Length());
679 Standard_Integer i = 0, j = 0;
680 for(i = 1; i <= aSeq1.Length(); i++)
681 for(j = 1; j <= aSeq2.Length(); j++)
682 anArrayOfFlag.SetValue(i, j, Standard_False);
683
684 for(i = 1; i <= aSeq1.Length(); i++) {
685 const TopoDS_Shape& aS1 = aSeq1.Value(i);
686 BOPCol_ListOfShape aListOfS2;
687 Standard_Integer nbs = 0;
688
689 for(j = 1; j <= aSeq2.Length(); j++) {
690 const TopoDS_Shape& aS2 = aSeq2.Value(j);
691 Standard_Boolean bIsEqual = Standard_False;
692
693 if(theType == TopAbs_VERTEX) {
694
695 const TopoDS_Vertex& aV1 = *(TopoDS_Vertex*)&(aS1);
696 const TopoDS_Vertex& aV2 = *(TopoDS_Vertex*)&(aS2);
697 gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
698 gp_Pnt aP2 = BRep_Tool::Pnt(aV2);
699 Standard_Real aDist = aP1.Distance(aP2);
700
701 if(aDist <= (BRep_Tool::Tolerance(aV1) + BRep_Tool::Tolerance(aV2))) {
702 bIsEqual = Standard_True;
703 }
704 }
705 else if(theType == TopAbs_EDGE) {
706 Standard_Integer aDiscretize = 30;
707 Standard_Real aDeflection = 0.01;
708 const TopoDS_Edge& aE1 = *(TopoDS_Edge*)&(aS1);
709 const TopoDS_Edge& aE2 = *(TopoDS_Edge*)&(aS2);
710
711 IntTools_EdgeEdge aEE;
712 aEE.SetEdge1 (aE1);
713 aEE.SetEdge2 (aE2);
714 aEE.SetTolerance1 (BRep_Tool::Tolerance(aE1));
715 aEE.SetTolerance2 (BRep_Tool::Tolerance(aE2));
716 aEE.SetDiscretize (aDiscretize);
717 aEE.SetDeflection (aDeflection);
718
719 Standard_Real f = 0., l = 0.;
720 BRep_Tool::Range(aE1, f, l);
721 aEE.SetRange1(f, l);
722
723 BRep_Tool::Range(aE2, f, l);
724 aEE.SetRange2(f, l);
725
726 aEE.Perform();
727
728 if (aEE.IsDone()) {
729 const IntTools_SequenceOfCommonPrts& aCPrts = aEE.CommonParts();
730 Standard_Integer ii = 0;
731
732 for (ii = 1; ii <= aCPrts.Length(); ii++) {
733 const IntTools_CommonPrt& aCPart = aCPrts(ii);
734
735 if (aCPart.Type() == TopAbs_EDGE) {
736 bIsEqual = Standard_True;
737 }
738 }
739 }
740 }
741 else if(theType == TopAbs_FACE) {
742 // not yet implemented!
743 }
744
745 if(bIsEqual) {
746 anArrayOfFlag.SetValue(i, j, Standard_True );
747 aListOfS2.Append(aS2);
748 nbs++;
749 }
750 }
751
752 if(nbs > 1) {
753 BOPAlgo_CheckResult aResult;
754
755 aResult.SetShape1(myShape1);
756 aResult.SetShape2(myShape2);
757 aResult.AddFaultyShape1(aS1);
758 BOPCol_ListIteratorOfListOfShape anIt(aListOfS2);
759
760 for(; anIt.More(); anIt.Next()) {
761 aResult.AddFaultyShape2(anIt.Value());
762 }
763
764 aResult.SetCheckStatus(aStatus);
765 myResult.Append(aResult);
766
767 if(myStopOnFirst) {
768 return;
769 }
770 }
771 }
772
773 for(i = 1; i <= aSeq2.Length(); i++) {
774 const TopoDS_Shape& aS2 = aSeq2.Value(i);
775 BOPCol_ListOfShape aListOfS1;
776 Standard_Integer nbs = 0;
777
778 for(j = 1; j <= aSeq1.Length(); j++) {
779 const TopoDS_Shape& aS1 = aSeq1.Value(j);
780
781 if(anArrayOfFlag.Value(j, i)) {
782 aListOfS1.Append(aS1);
783 nbs++;
784 }
785 }
786
787 if(nbs > 1) {
788 BOPAlgo_CheckResult aResult;
789
790 aResult.SetShape1(myShape1);
791 aResult.SetShape2(myShape2);
792 BOPCol_ListIteratorOfListOfShape anIt(aListOfS1);
793
794 for(; anIt.More(); anIt.Next()) {
795 aResult.AddFaultyShape1(anIt.Value());
796 }
797 aResult.AddFaultyShape2(aS2);
798
799 aResult.SetCheckStatus(aStatus);
800 myResult.Append(aResult);
801
802 if(myStopOnFirst) {
803 return;
804 }
805 }
806 }
807}
808
809// ================================================================================
810// function: TestMergeVertex
811// purpose:
812// ================================================================================
813void BOPAlgo_ArgumentAnalyzer::TestMergeVertex()
814{
815 TestMergeSubShapes(TopAbs_VERTEX);
816}
817
818// ================================================================================
819// function: TestMergeEdge
820// purpose:
821// ================================================================================
822void BOPAlgo_ArgumentAnalyzer::TestMergeEdge()
823{
824 TestMergeSubShapes(TopAbs_EDGE);
825}
826
827// ================================================================================
828// function: TestContinuity
829// purpose:
830// ================================================================================
831void BOPAlgo_ArgumentAnalyzer::TestContinuity()
832{
833 Standard_Integer i;
834 Standard_Real f, l;
835 TopExp_Explorer aExp;
836 BOPCol_MapIteratorOfMapOfShape aIt;
837 //
838 for (i = 0; i < 2; ++i) {
839 const TopoDS_Shape& aS = !i ? myShape1 : myShape2;
840 if(aS.IsNull()) {
841 continue;
842 }
843 //
844 BOPCol_MapOfShape aMS;
845 //Edges
846 aExp.Init(aS, TopAbs_EDGE);
847 for (; aExp.More(); aExp.Next()) {
848 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
849 if (BRep_Tool::Degenerated(aE)) {
850 continue;
851 }
852 const Handle(Geom_Curve)& aC = BRep_Tool::Curve(aE, f, l);
853 if (aC->Continuity() == GeomAbs_C0) {
854 aMS.Add(aE);
855 }
856 }
857 //Faces
858 aExp.Init(aS, TopAbs_FACE);
859 for (; aExp.More(); aExp.Next()) {
860 const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
861 const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aF);
862 if (aS->Continuity() == GeomAbs_C0) {
863 aMS.Add(aF);
864 }
865 }
866 //
867 //add shapes with continuity C0 to result
868 aIt.Initialize(aMS);
869 for (; aIt.More(); aIt.Next()) {
870 const TopoDS_Shape& aFS = aIt.Value();
871 BOPAlgo_CheckResult aResult;
872 if(i == 0) {
873 aResult.SetShape1(myShape1);
874 aResult.AddFaultyShape1(aFS);
875 } else {
876 aResult.SetShape2(myShape2);
877 aResult.AddFaultyShape2(aFS);
878 }
879 aResult.SetCheckStatus(BOPAlgo_GeomAbs_C0);
880 myResult.Append(aResult);
881 }
882 }
883}
884
885// ================================================================================
886// function: TestMergeFace
887// purpose:
888// ================================================================================
889// void BOPAlgo_ArgumentAnalyzer::TestMergeFace()
890// {
891 // not implemented
892// }