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