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