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