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