0023294: Identical sub-expression in 'if-clause'
[occt.git] / src / BOP / BOP_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
20#include <BOP_ArgumentAnalyzer.ixx>
21#include <BOP_CheckResult.hxx>
22#include <BOP_ShellSolid.hxx>
23#include <BOP_WireSolid.hxx>
24#include <BOP_WireShell.hxx>
25#include <BOP_WireEdgeSet.hxx>
26#include <BOP_FaceBuilder.hxx>
27
28#include <TopExp.hxx>
29#include <TopExp_Explorer.hxx>
30#include <BRep_Builder.hxx>
31#include <BRep_Tool.hxx>
32#include <BRepExtrema_DistShapeShape.hxx>
33#include <gp_Pnt.hxx>
34#include <TopoDS_Iterator.hxx>
35#include <TopoDS.hxx>
36#include <TopoDS_Vertex.hxx>
37#include <TopoDS_Edge.hxx>
38#include <TopoDS_Wire.hxx>
39#include <TopoDS_Shell.hxx>
40#include <TopoDS_Solid.hxx>
41#include <TopTools_ListOfShape.hxx>
42#include <TopTools_ListIteratorOfListOfShape.hxx>
43#include <TopTools_SequenceOfShape.hxx>
44#include <TopTools_MapOfShape.hxx>
45
46#include <TColStd_Array2OfBoolean.hxx>
47
48#include <IntTools_Context.hxx>
49#include <IntTools_Range.hxx>
50#include <IntTools_ShrunkRange.hxx>
51#include <IntTools_EdgeEdge.hxx>
52#include <IntTools_CommonPrt.hxx>
53
54#include <BOPTools_DSFiller.hxx>
55#include <BOPTools_Tools3D.hxx>
56#include <BOPTools_Checker.hxx>
57#include <BOPTools_CheckResult.hxx>
58#include <BOPTools_ListOfCheckResults.hxx>
59#include <BOPTools_ListIteratorOfListOfCheckResults.hxx>
60
61#include <Standard_ErrorHandler.hxx>
62#include <Standard_Failure.hxx>
63
64static Standard_Boolean TestShapeType(const TopoDS_Shape & TheShape);
65
66static Standard_Boolean CheckEdge(const TopoDS_Edge& theEdge);
67
68static Standard_Boolean TestSubShapeType(const TopAbs_ShapeEnum theT1,
69 const TopAbs_ShapeEnum theT2,
70 const BOP_Operation theOP);
71
72// ================================================================================
73// function: Constructor
74// purpose:
75// ================================================================================
76BOP_ArgumentAnalyzer::BOP_ArgumentAnalyzer() :
77myStopOnFirst(Standard_False),
78myOperation(BOP_UNKNOWN),
79myArgumentTypeMode(Standard_False),
80mySelfInterMode(Standard_False),
81mySmallEdgeMode(Standard_False),
82myRebuildFaceMode(Standard_False),
83myTangentMode(Standard_False),
84myMergeVertexMode(Standard_False),
85myMergeEdgeMode(Standard_False)
86// myMergeFaceMode(Standard_False)
87{
88}
89
90// ================================================================================
91// function: SetShape1
92// purpose:
93// ================================================================================
94void BOP_ArgumentAnalyzer::SetShape1(const TopoDS_Shape & TheShape)
95{
96 myShape1 = TheShape;
97}
98
99// ================================================================================
100// function: SetShape2
101// purpose:
102// ================================================================================
103void BOP_ArgumentAnalyzer::SetShape2(const TopoDS_Shape & TheShape)
104{
105 myShape2 = TheShape;
106}
107
108// ================================================================================
109// function: GetShape1
110// purpose:
111// ================================================================================
112const TopoDS_Shape & BOP_ArgumentAnalyzer::GetShape1() const
113{
114 return myShape1;
115}
116
117// ================================================================================
118// function: GetShape2
119// purpose:
120// ================================================================================
121const TopoDS_Shape & BOP_ArgumentAnalyzer::GetShape2() const
122{
123 return myShape2;
124}
125
126// ================================================================================
127// function: OperationType
128// purpose:
129// ================================================================================
130BOP_Operation& BOP_ArgumentAnalyzer::OperationType()
131{
132 return myOperation;
133}
134
135// ================================================================================
136// function: StopOnFirstFaulty
137// purpose:
138// ================================================================================
139Standard_Boolean & BOP_ArgumentAnalyzer::StopOnFirstFaulty()
140{
141 return myStopOnFirst;
142}
143
144// ================================================================================
145// function: Perform
146// purpose:
147// ================================================================================
148void BOP_ArgumentAnalyzer::Perform()
149{
150 try {
151 OCC_CATCH_SIGNALS
152 myResult.Clear();
153
154 if(myArgumentTypeMode) {
155 TestTypes();
156 }
157
158 if(mySelfInterMode) {
159 TestSelfInterferences();
160 }
161
162 if(mySmallEdgeMode) {
163 if(!(!myResult.IsEmpty() && myStopOnFirst))
164 TestSmallEdge();
165 }
166
167 if(myRebuildFaceMode) {
168 if(!(!myResult.IsEmpty() && myStopOnFirst))
169 TestRebuildFace();
170 }
171
172 if(myTangentMode) {
173 if(!(!myResult.IsEmpty() && myStopOnFirst))
174 TestTangent();
175 }
176
177 if(myMergeVertexMode) {
178 if(!(!myResult.IsEmpty() && myStopOnFirst))
179 TestMergeVertex();
180 }
181
182 if(myMergeEdgeMode) {
183 if(!(!myResult.IsEmpty() && myStopOnFirst))
184 TestMergeEdge();
185 }
186
187// if(myMergeFaceMode) {
188// TestMergeFace();
189// }
190 }
191 catch(Standard_Failure) {
192 BOP_CheckResult aResult;
193 aResult.SetCheckStatus(BOP_CheckUnknown);
194 myResult.Append(aResult);
195 }
196}
197
198// ================================================================================
199// function: HasFaulty
200// purpose:
201// ================================================================================
202Standard_Boolean BOP_ArgumentAnalyzer::HasFaulty() const
203{
204 return ( !myResult.IsEmpty());
205}
206
207// ================================================================================
208// function: GetCheckResult
209// purpose:
210// ================================================================================
211const BOP_ListOfCheckResult& BOP_ArgumentAnalyzer::GetCheckResult() const
212{
213 return myResult;
214}
215
216// ================================================================================
217// function: TestTypes
218// purpose:
219// ================================================================================
220void BOP_ArgumentAnalyzer::TestTypes()
221{
222 Standard_Boolean isS1 = myShape1.IsNull(), isS2 = myShape2.IsNull();
223
224 if(isS1 && isS2) {
225 BOP_CheckResult aResult;
226 aResult.SetCheckStatus(BOP_BadType);
227 myResult.Append(aResult);
228 return;
229 }
230
231 Standard_Boolean testS1 = TestShapeType(myShape1);
232 Standard_Boolean testS2 = TestShapeType(myShape2);
233
234 // single shape check (begin)
235 if((isS1 && !isS2) || (!isS1 && isS2)) {
236// Standard_Boolean testS = (isS1) ? testS1 : testS2;
237 Standard_Boolean testS = (isS1) ? testS2 : testS1;
238
239 if(!testS) {
240 const TopoDS_Shape & aS = (isS1) ? myShape1 : myShape2;
241 BOP_CheckResult aResult;
242 aResult.SetShape1(aS);
243 aResult.SetCheckStatus(BOP_BadType);
244 myResult.Append(aResult);
245 return;
246 }
247
248 } // single shape is set (end)
249 // two shapes check (begin)
250 else {
251 // test compounds and compsolids
252 if(!testS1 || !testS2) {
253 BOP_CheckResult aResult;
254 if(!testS1 && !testS2) {
255 aResult.SetShape1(myShape1);
256 aResult.SetShape2(myShape2);
257 }
258 else {
259 const TopoDS_Shape & aS = (!testS1) ? myShape1 : myShape2;
260 if(!testS1)
261 aResult.SetShape1(aS);
262 else
263 aResult.SetShape2(aS);
264 }
265 aResult.SetCheckStatus(BOP_BadType);
266 myResult.Append(aResult);
267 return;
268 }
269 // test faces, wires, edges
270 TopAbs_ShapeEnum aT1 = myShape1.ShapeType(), aT2 = myShape2.ShapeType();
271
272 if(aT1 != TopAbs_COMPOUND && aT2 != TopAbs_COMPOUND) {
273 Standard_Boolean aTestRes = TestSubShapeType(aT1,aT2,myOperation);
274 if(!aTestRes) {
275 BOP_CheckResult aResult;
276 aResult.SetShape1(myShape1);
277 aResult.SetShape2(myShape2);
278 aResult.SetCheckStatus(BOP_BadType);
279 myResult.Append(aResult);
280 return;
281 }
282 }
283 else {
284 Standard_Boolean aTestRes = Standard_True;
285 if(aT1 == TopAbs_COMPOUND && aT2 != TopAbs_COMPOUND) {
286 TopoDS_Iterator itS1(myShape1);
287 while(itS1.More()) {
288 aT1 = itS1.Value().ShapeType();
289 aTestRes = TestSubShapeType(aT1,aT2,myOperation);
290 if(!aTestRes)
291 break;
292 itS1.Next();
293 }
294 }
295 else if(aT1 != TopAbs_COMPOUND && aT2 == TopAbs_COMPOUND) {
296 TopoDS_Iterator itS2(myShape2);
297 while(itS2.More()) {
298 aT2 = itS2.Value().ShapeType();
299 aTestRes = TestSubShapeType(aT1,aT2,myOperation);
300 if(!aTestRes)
301 break;
302 itS2.Next();
303 }
304 }
305 else {
306 TopoDS_Iterator itS1(myShape1);
307 while(itS1.More()) {
308 aT1 = itS1.Value().ShapeType();
309 TopoDS_Iterator itS2(myShape2);
310 while(itS2.More()) {
311 aT2 = itS2.Value().ShapeType();
312 aTestRes = TestSubShapeType(aT1,aT2,myOperation);
313 if(!aTestRes)
314 break;
315 itS2.Next();
316 }
317 if(!aTestRes)
318 break;
319 itS1.Next();
320 }
321 }
322
323 if(!aTestRes) {
324 BOP_CheckResult aResult;
325 aResult.SetShape1(myShape1);
326 aResult.SetShape2(myShape2);
327 aResult.SetCheckStatus(BOP_BadType);
328 myResult.Append(aResult);
329 return;
330 }
331 }
332 } // both shapes are set (end)
333}
334
335// ================================================================================
336// function: TestSelfInterferences
337// purpose:
338// ================================================================================
339void BOP_ArgumentAnalyzer::TestSelfInterferences()
340{
341 Standard_Integer i = 0;
342
343 for(i = 0; i < 2; i++) {
344 TopoDS_Shape aS = (i == 0) ? myShape1 : myShape2;
345
346 if(aS.IsNull())
347 continue;
348 BOPTools_Checker aChecker(aS);
349 aChecker.Perform();
350
351 if (aChecker.HasFaulty()) {
352 const BOPTools_ListOfCheckResults& aResultList = aChecker.GetCheckResult();
353 BOPTools_ListIteratorOfListOfCheckResults anIt(aResultList);
354
355 for(; anIt.More(); anIt.Next()) {
356 const BOPTools_CheckResult& aCheckResult = anIt.Value();
357
358 if((aCheckResult.GetCheckStatus() == BOPTools_CHKUNKNOWN) ||
359 (aCheckResult.GetCheckStatus() == BOPTools_BADSHRANKRANGE) ||
360 (aCheckResult.GetCheckStatus() == BOPTools_NULLSRANKRANGE)) {
361 continue;
362 }
363 BOP_CheckResult aResult;
364 if(i == 0)
365 aResult.SetShape1(myShape1);
366 else
367 aResult.SetShape2(myShape2);
368 TopTools_ListIteratorOfListOfShape anIt2(aCheckResult.GetShapes());
369
370 for(; anIt2.More(); anIt2.Next()) {
371 if(i == 0)
372 aResult.AddFaultyShape1(anIt2.Value());
373 else
374 aResult.AddFaultyShape2(anIt2.Value());
375 }
376 aResult.SetCheckStatus(BOP_SelfIntersect);
377 myResult.Append(aResult);
378
379 if(myStopOnFirst) {
380 return;
381 }
382 }
383 }
384 }
385}
386
387// ================================================================================
388// function: TestSmallEdge
389// purpose:
390// ================================================================================
391void BOP_ArgumentAnalyzer::TestSmallEdge()
392{
393 Standard_Integer i = 0;
394 BRepExtrema_DistShapeShape aDist;
395
396 for(i = 0; i < 2; i++) {
397 TopoDS_Shape aS = (i == 0) ? myShape1 : myShape2;
398
399 if(aS.IsNull())
400 continue;
401
402 TopExp_Explorer anExp(aS, TopAbs_EDGE);
403
404 for(; anExp.More(); anExp.Next()) {
405 TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
406
407 if(!CheckEdge(anEdge)) {
408 Standard_Boolean bKeepResult = Standard_True;
409
410 if(myOperation == BOP_SECTION) {
411 TopoDS_Shape anOtherS = (i == 0) ? myShape2 : myShape1;
412
413 if(!anOtherS.IsNull()) {
414// BRepExtrema_DistShapeShape aDist;
415 aDist.LoadS2(anOtherS);
416
417 Standard_Boolean bVertexIsOnShape = Standard_False;
418 Standard_Integer ii = 0;
419 TopExp_Explorer anExpV(anEdge, TopAbs_VERTEX);
420
421 for(; anExpV.More(); anExpV.Next()) {
422 TopoDS_Shape aV = anExpV.Current();
423
424 aDist.LoadS1(aV);
425 aDist.Perform();
426
427 if(aDist.IsDone()) {
428
429 for(ii = 1; ii <= aDist.NbSolution(); ii++) {
430 Standard_Real aTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(aV));
431 TopoDS_Shape aSupportShape = aDist.SupportOnShape2(ii);
432
433 switch(aSupportShape.ShapeType()) {
434 case TopAbs_VERTEX: {
435 aTolerance += BRep_Tool::Tolerance(TopoDS::Vertex(aSupportShape));
436 break;
437 }
438 case TopAbs_EDGE: {
439 aTolerance += BRep_Tool::Tolerance(TopoDS::Edge(aSupportShape));
440 break;
441 }
442 case TopAbs_FACE: {
443 aTolerance += BRep_Tool::Tolerance(TopoDS::Face(aSupportShape));
444 break;
445 }
446 default:
447 break;
448 }
449
450 if(aDist.Value() < aTolerance) {
451 bVertexIsOnShape = Standard_True;
452 break;
453 }
454 }
455 }
456 }
457
458 if(!bVertexIsOnShape) {
459 bKeepResult = Standard_False;
460 }
461 }
462 }
463
464 if(bKeepResult) {
465 BOP_CheckResult aResult;
466
467 if(i == 0) {
468 aResult.SetShape1(myShape1);
469 aResult.AddFaultyShape1(anEdge);
470 }
471 else {
472 aResult.SetShape2(myShape2);
473 aResult.AddFaultyShape2(anEdge);
474 }
475
476 aResult.SetCheckStatus(BOP_TooSmallEdge);
477 myResult.Append(aResult);
478
479 if(myStopOnFirst) {
480 return;
481 }
482 }
483 }
484 }
485 }
486}
487
488// ================================================================================
489// function: TestRebuildFace
490// purpose:
491// ================================================================================
492void BOP_ArgumentAnalyzer::TestRebuildFace()
493{
494 if((myOperation == BOP_SECTION) ||
495 (myOperation == BOP_UNKNOWN))
496 return;
497 Standard_Integer i = 0;
498
499 for(i = 0; i < 2; i++) {
500 TopoDS_Shape aS = (i == 0) ? myShape1 : myShape2;
501
502 if(aS.IsNull())
503 continue;
504
505 TopExp_Explorer anExp(aS, TopAbs_FACE);
506
507 for(; anExp.More(); anExp.Next()) {
508 TopoDS_Face aFace = TopoDS::Face(anExp.Current());
509
510 BOP_WireEdgeSet aWES (aFace);
511 TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
512 Standard_Integer nbstartedges = 0;
513
514 for(; anExpE.More(); anExpE.Next()) {
515 aWES.AddStartElement(anExpE.Current());
516 nbstartedges++;
517 }
518 BOP_FaceBuilder aFB;
519 aFB.Do(aWES);
520 const TopTools_ListOfShape& aLF = aFB.NewFaces();
521 Standard_Boolean bBadFace = Standard_False;
522
523 if(aLF.Extent() != 1) {
524 bBadFace = Standard_True;
525 }
526 else {
527 Standard_Integer nbedgeused = 0;
528 anExpE.Init(aLF.First(), TopAbs_EDGE);
529
530 for(; anExpE.More(); anExpE.Next(), nbedgeused++);
531
532 if(nbstartedges != nbedgeused) {
533 bBadFace = Standard_True;
534 }
535 }
536
537 if(bBadFace) {
538 BOP_CheckResult aResult;
539
540 if(i == 0) {
541 aResult.SetShape1(myShape1);
542 aResult.AddFaultyShape1(aFace);
543 }
544 else {
545 aResult.SetShape2(myShape2);
546 aResult.AddFaultyShape2(aFace);
547 }
548
549 aResult.SetCheckStatus(BOP_NonRecoverableFace);
550 myResult.Append(aResult);
551
552 if(myStopOnFirst) {
553 return;
554 }
555 }
556 }
557 }
558}
559
560// ================================================================================
561// function: TestTangent
562// purpose:
563// ================================================================================
564void BOP_ArgumentAnalyzer::TestTangent()
565{
566 // not implemented
567}
568
569// ================================================================================
570// function: TestMergeSubShapes
571// purpose:
572// ================================================================================
573 void BOP_ArgumentAnalyzer::TestMergeSubShapes(const TopAbs_ShapeEnum theType)
574{
575 if(myShape1.IsNull() || myShape2.IsNull())
576 return;
577
578 BOP_CheckStatus aStatus = BOP_CheckUnknown;
579
580 switch(theType) {
581 case TopAbs_VERTEX: {
582 aStatus = BOP_IncompatibilityOfVertex;
583 break;
584 }
585 case TopAbs_EDGE: {
586 aStatus = BOP_IncompatibilityOfEdge;
587 break;
588 }
589 case TopAbs_FACE: {
590 aStatus = BOP_IncompatibilityOfFace;
591 break;
592 }
593 default:
594 return;
595 }
596 TopExp_Explorer anExp1(myShape1, theType);
597 TopExp_Explorer anExp2(myShape2, theType);
598 TopTools_SequenceOfShape aSeq1, aSeq2;
599 TopTools_MapOfShape aMap1, aMap2;
600
601 for(; anExp1.More(); anExp1.Next()) {
602 TopoDS_Shape aS1 = anExp1.Current();
603
604 if(aMap1.Contains(aS1))
605 continue;
606 aSeq1.Append(aS1);
607 aMap1.Add(aS1);
608 }
609
610 for(; anExp2.More(); anExp2.Next()) {
611 TopoDS_Shape aS2 = anExp2.Current();
612 if(aMap2.Contains(aS2))
613 continue;
614 aSeq2.Append(aS2);
615 aMap2.Add(aS2);
616 }
617
618 TColStd_Array2OfBoolean anArrayOfFlag(1, aSeq1.Length(), 1, aSeq2.Length());
619 Standard_Integer i = 0, j = 0;
620 for(i = 1; i <= aSeq1.Length(); i++)
621 for(j = 1; j <= aSeq2.Length(); j++)
622 anArrayOfFlag.SetValue(i, j, Standard_False);
623
624 for(i = 1; i <= aSeq1.Length(); i++) {
625 TopoDS_Shape aS1 = aSeq1.Value(i);
626 TopTools_ListOfShape aListOfS2;
627 Standard_Integer nbs = 0;
628
629 for(j = 1; j <= aSeq2.Length(); j++) {
630 TopoDS_Shape aS2 = aSeq2.Value(j);
631 Standard_Boolean bIsEqual = Standard_False;
632
633 if(theType == TopAbs_VERTEX) {
634
635 TopoDS_Vertex aV1 = TopoDS::Vertex(aS1);
636 TopoDS_Vertex aV2 = TopoDS::Vertex(aS2);
637 gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
638 gp_Pnt aP2 = BRep_Tool::Pnt(aV2);
639 Standard_Real aDist = aP1.Distance(aP2);
640
641 if(aDist <= (BRep_Tool::Tolerance(aV1) + BRep_Tool::Tolerance(aV2))) {
642 bIsEqual = Standard_True;
643 }
644 }
645 else if(theType == TopAbs_EDGE) {
646 Standard_Integer aDiscretize = 30;
647 Standard_Real aDeflection = 0.01;
648 TopoDS_Edge aE1 = TopoDS::Edge(aS1);
649 TopoDS_Edge aE2 = TopoDS::Edge(aS2);
650
651 IntTools_EdgeEdge aEE;
652 aEE.SetEdge1 (aE1);
653 aEE.SetEdge2 (aE2);
654 aEE.SetTolerance1 (BRep_Tool::Tolerance(aE1));
655 aEE.SetTolerance2 (BRep_Tool::Tolerance(aE2));
656 aEE.SetDiscretize (aDiscretize);
657 aEE.SetDeflection (aDeflection);
658
659 Standard_Real f = 0., l = 0.;
660 BRep_Tool::Range(aE1, f, l);
661 aEE.SetRange1(f, l);
662
663 BRep_Tool::Range(aE2, f, l);
664 aEE.SetRange2(f, l);
665
666 aEE.Perform();
667
668 if (aEE.IsDone()) {
669 const IntTools_SequenceOfCommonPrts& aCPrts = aEE.CommonParts();
670 Standard_Integer ii = 0;
671
672 for (ii = 1; ii <= aCPrts.Length(); ii++) {
673 const IntTools_CommonPrt& aCPart = aCPrts(ii);
674
675 if (aCPart.Type() == TopAbs_EDGE) {
676 bIsEqual = Standard_True;
677 }
678 }
679 }
680 }
681 else if(theType == TopAbs_FACE) {
682 // not yet implemented!
683 }
684
685 if(bIsEqual) {
686 anArrayOfFlag.SetValue(i, j, Standard_True );
687 aListOfS2.Append(aS2);
688 nbs++;
689 }
690 }
691
692 if(nbs > 1) {
693 BOP_CheckResult aResult;
694
695 aResult.SetShape1(myShape1);
696 aResult.SetShape2(myShape2);
697 aResult.AddFaultyShape1(aS1);
698 TopTools_ListIteratorOfListOfShape anIt(aListOfS2);
699
700 for(; anIt.More(); anIt.Next()) {
701 aResult.AddFaultyShape2(anIt.Value());
702 }
703
704 aResult.SetCheckStatus(aStatus);
705 myResult.Append(aResult);
706
707 if(myStopOnFirst) {
708 return;
709 }
710 }
711 }
712
713 for(i = 1; i <= aSeq2.Length(); i++) {
714 TopoDS_Shape aS2 = aSeq2.Value(i);
715 TopTools_ListOfShape aListOfS1;
716 Standard_Integer nbs = 0;
717
718 for(j = 1; j <= aSeq1.Length(); j++) {
719 TopoDS_Shape aS1 = aSeq1.Value(j);
720
721 if(anArrayOfFlag.Value(j, i)) {
722 aListOfS1.Append(aS1);
723 nbs++;
724 }
725 }
726
727 if(nbs > 1) {
728 BOP_CheckResult aResult;
729
730 aResult.SetShape1(myShape1);
731 aResult.SetShape2(myShape2);
732 TopTools_ListIteratorOfListOfShape anIt(aListOfS1);
733
734 for(; anIt.More(); anIt.Next()) {
735 aResult.AddFaultyShape1(anIt.Value());
736 }
737 aResult.AddFaultyShape2(aS2);
738
739 aResult.SetCheckStatus(aStatus);
740 myResult.Append(aResult);
741
742 if(myStopOnFirst) {
743 return;
744 }
745 }
746 }
747}
748
749// ================================================================================
750// function: TestMergeVertex
751// purpose:
752// ================================================================================
753void BOP_ArgumentAnalyzer::TestMergeVertex()
754{
755 TestMergeSubShapes(TopAbs_VERTEX);
756}
757
758// ================================================================================
759// function: TestMergeEdge
760// purpose:
761// ================================================================================
762void BOP_ArgumentAnalyzer::TestMergeEdge()
763{
764 TestMergeSubShapes(TopAbs_EDGE);
765}
766
767// ================================================================================
768// function: TestMergeFace
769// purpose:
770// ================================================================================
771// void BOP_ArgumentAnalyzer::TestMergeFace()
772// {
773 // not implemented
774// }
775
776// ----------------------------------------------------------------------
777// static function: TestShapeType
778// purpose:
779// ----------------------------------------------------------------------
780Standard_Boolean TestShapeType(const TopoDS_Shape & TheShape)
781{
782 if(TheShape.IsNull())
783 return Standard_False;
784
785 TopAbs_ShapeEnum aT = TheShape.ShapeType();
786
787 if(aT == TopAbs_COMPOUND && BOPTools_Tools3D::IsEmptyShape(TheShape))
788 return Standard_False;
789
790 TopoDS_Iterator anIt;
791 TopoDS_Shape aSTmp, aShape;
792 Standard_Integer aNbShapes, TreatRes = 0;
793
794 if(aT==TopAbs_COMPOUND || aT==TopAbs_COMPSOLID) {
795 aNbShapes=0;
796 anIt.Initialize(TheShape);
797 for (; anIt.More(); anIt.Next()) {
798 if(!aNbShapes) {
799 aSTmp=anIt.Value();
800 }
801 aNbShapes++;
802 if(aNbShapes>1) {
803 break;
804 }
805 }
806 if(aT == TopAbs_COMPOUND) {
807 if (aNbShapes==1) {
808 TreatRes = BOPTools_DSFiller::TreatCompound(TheShape, aSTmp);
809 if(TreatRes != 0)
810 return Standard_False;
811 aShape=aSTmp;
812 aT = aShape.ShapeType();
813 }
814 else if (aNbShapes>1) {
815 TreatRes = BOPTools_DSFiller::TreatCompound(TheShape, aSTmp);
816 if(TreatRes != 0)
817 return Standard_False;
818 aShape=aSTmp;
819 aT=aShape.ShapeType();
820 }
821 }
822 }
823
824 if(aT==TopAbs_COMPOUND || aT==TopAbs_COMPSOLID) {
825 return Standard_False;
826 }
827
828 return Standard_True;
829}
830
831// ----------------------------------------------------------------------
832// static function: CheckEdge
833// purpose:
834// ----------------------------------------------------------------------
835Standard_Boolean CheckEdge(const TopoDS_Edge& theEdge)
836{
837 Handle(IntTools_Context) aContext;
838 TopoDS_Vertex aV1, aV2;
839 //
840 //modified by NIZNHY-PKV Tue Jan 31 15:07:13 2012f
841 aContext=new IntTools_Context;
842 ////modified by NIZNHY-PKV Tue Jan 31 15:07:16 2012t
843 TopExp::Vertices(theEdge, aV1, aV2);
844
845
846 if(aV1.IsNull() || aV2.IsNull() || BRep_Tool::Degenerated(theEdge))
847 return Standard_True;
848 Standard_Real aFirst = 0., aLast = 0.;
849 BRep_Tool::Range(theEdge, aFirst, aLast);
850 IntTools_Range aRange(aFirst, aLast);
851 IntTools_ShrunkRange aSR(theEdge, aV1, aV2, aRange, aContext);
852
853 if (!aSR.IsDone() || aSR.ErrorStatus() == 6) {
854 return Standard_False;
855 }
856 return Standard_True;
857}
858
859// ----------------------------------------------------------------------
860// static function: TestSubShapeType
861// purpose:
862// ----------------------------------------------------------------------
863Standard_Boolean TestSubShapeType(const TopAbs_ShapeEnum theT1,
864 const TopAbs_ShapeEnum theT2,
865 const BOP_Operation theOP)
866{
867 TopAbs_ShapeEnum aT1 = theT1, aT2 = theT2;
868
869 if(aT1==TopAbs_FACE) {
870 if(aT2==TopAbs_SOLID || aT2==TopAbs_SHELL || aT2==TopAbs_FACE ||
871 aT2==TopAbs_WIRE || aT2==TopAbs_EDGE) {
872 aT1=TopAbs_SHELL;
873 }
874 }
875 if(aT2==TopAbs_FACE) {
876 if(aT1==TopAbs_SOLID || aT1==TopAbs_SHELL ||
877 aT1==TopAbs_WIRE || aT1==TopAbs_EDGE) {
878 aT2=TopAbs_SHELL;
879 }
880 }
881 if(aT1==TopAbs_EDGE) {
882 if(aT2==TopAbs_SOLID || aT2==TopAbs_SHELL ||
883 aT2==TopAbs_WIRE || aT2==TopAbs_EDGE) {
884 aT1=TopAbs_WIRE;
885 }
886 }
887 if(aT2==TopAbs_EDGE) {
888 if(aT1==TopAbs_SOLID || aT1==TopAbs_SHELL || aT1==TopAbs_WIRE) {
889 aT2=TopAbs_WIRE;
890 }
891 }
892
893 // test operations
894 if(theOP!=BOP_UNKNOWN) {
895 Standard_Boolean opOk;
896 if(aT1==TopAbs_SHELL && aT2==TopAbs_SHELL)
897 opOk = Standard_True;
898 else if(aT1==TopAbs_SOLID && aT2==TopAbs_SOLID)
899 opOk = Standard_True;
900 else if((aT1==TopAbs_SOLID && aT2==TopAbs_SHELL) ||
901 (aT2==TopAbs_SOLID && aT1==TopAbs_SHELL))
902 opOk = Standard_True;
903 else if(aT1==TopAbs_WIRE && aT2==TopAbs_WIRE)
904 opOk = Standard_True;
905 else if((aT1==TopAbs_WIRE && aT2==TopAbs_SHELL) ||
906 (aT2==TopAbs_WIRE && aT1==TopAbs_SHELL))
907 opOk = Standard_True;
908 else if((aT1==TopAbs_WIRE && aT2==TopAbs_SOLID) ||
909 (aT2==TopAbs_WIRE && aT1==TopAbs_SOLID))
910 opOk = Standard_True;
911 else
912 opOk = Standard_False;
913
914 if(!opOk) {
915 return Standard_False;
916 }
917
918 if((aT1==TopAbs_SHELL && aT2==TopAbs_SOLID) ||
919 (aT2==TopAbs_SHELL && aT1==TopAbs_SOLID)) {
920 if(!BOP_ShellSolid::CheckArgTypes(aT1,aT2,theOP)) {
921 return Standard_False;
922 }
923 }
924 if((aT1==TopAbs_WIRE && aT2==TopAbs_SOLID) ||
925 (aT2==TopAbs_WIRE && aT1==TopAbs_SOLID)) {
926 if(!BOP_WireSolid::CheckArgTypes(aT1,aT2,theOP)) {
927 return Standard_False;
928 }
929 }
930 if((aT1==TopAbs_WIRE && aT2==TopAbs_SHELL) ||
931 (aT2==TopAbs_WIRE && aT1==TopAbs_SHELL)) {
932 if(!BOP_WireShell::CheckArgTypes(aT1,aT2,theOP)) {
933 return Standard_False;
934 }
935 }
936 }
937
938 return Standard_True;
939}