0024495: Crash during performeng boolean operation on attached shape for Windows...
[occt.git] / src / BOPAlgo / BOPAlgo_BOP.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and / or modify it
7 // under the terms of the GNU Lesser General Public version 2.1 as published
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.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <BOPAlgo_BOP.ixx>
16
17 #include <TopAbs_ShapeEnum.hxx>
18
19 #include <TopoDS_Compound.hxx>
20 #include <TopoDS_Iterator.hxx>
21 #include <BRep_Builder.hxx>
22 #include <TopExp_Explorer.hxx>
23
24 #include <BOPTools.hxx>
25 #include <BOPTools_AlgoTools.hxx>
26 #include <BOPTools_AlgoTools3D.hxx>
27
28 #include <BOPCol_ListOfShape.hxx>
29 #include <BOPAlgo_BuilderSolid.hxx>
30 #include <TopoDS_Edge.hxx>
31
32 static
33   TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim);
34
35 //=======================================================================
36 //function : 
37 //purpose  : 
38 //=======================================================================
39   BOPAlgo_BOP::BOPAlgo_BOP()
40 :
41   BOPAlgo_Builder(),
42   myTools(myAllocator),
43   myMapTools(100, myAllocator)
44 {
45   myNbArgs=2;
46   Clear();
47 }
48 //=======================================================================
49 //function : 
50 //purpose  : 
51 //=======================================================================
52   BOPAlgo_BOP::BOPAlgo_BOP(const Handle(NCollection_BaseAllocator)& theAllocator)
53 :
54   BOPAlgo_Builder(theAllocator),
55   myTools(myAllocator),
56   myMapTools(100, myAllocator)
57 {
58   myNbArgs=2;
59   Clear();
60 }
61 //=======================================================================
62 //function : ~
63 //purpose  : 
64 //=======================================================================
65   BOPAlgo_BOP::~BOPAlgo_BOP()
66 {
67 }
68 //=======================================================================
69 //function : Clear
70 //purpose  : 
71 //=======================================================================
72   void BOPAlgo_BOP::Clear()
73 {
74   myOperation=BOPAlgo_UNKNOWN;
75   myTools.Clear();
76   myMapTools.Clear();
77   myDims[0]=-1;
78   myDims[1]=-1;
79   //
80   BOPAlgo_Builder::Clear();
81 }
82 //=======================================================================
83 //function : AddArgument
84 //purpose  : 
85 //=======================================================================
86   void BOPAlgo_BOP::AddArgument(const TopoDS_Shape& theShape)
87 {
88   if (myMapFence.Add(theShape)) {
89     myArguments.Append(theShape);
90     myArgs[0]=theShape;
91   }
92 }
93 //=======================================================================
94 //function : AddTool
95 //purpose  : 
96 //=======================================================================
97   void BOPAlgo_BOP::AddTool(const TopoDS_Shape& theShape)
98 {
99   if (myMapTools.Add(theShape)) {
100     myTools.Append(theShape);
101     myArgs[1]=theShape;
102     //
103     if (myMapFence.Add(theShape)) {
104       myArguments.Append(theShape);
105     }
106   }
107 }
108 //=======================================================================
109 //function : Object
110 //purpose  : 
111 //=======================================================================
112   const TopoDS_Shape& BOPAlgo_BOP::Object()const
113 {
114   return myArgs[0];
115 }
116 //=======================================================================
117 //function : Tool
118 //purpose  : 
119 //=======================================================================
120   const TopoDS_Shape& BOPAlgo_BOP::Tool()const
121 {
122   return myArgs[1];
123 }
124 //=======================================================================
125 //function : SetOperation
126 //purpose  : 
127 //=======================================================================
128   void BOPAlgo_BOP::SetOperation(const BOPAlgo_Operation theOperation)
129 {
130   myOperation=theOperation;
131 }
132 //=======================================================================
133 //function : Operation
134 //purpose  : 
135 //=======================================================================
136   BOPAlgo_Operation BOPAlgo_BOP::Operation()const
137 {
138   return myOperation;
139 }
140 //=======================================================================
141 //function : CheckData
142 //purpose  : 
143 //=======================================================================
144   void BOPAlgo_BOP::CheckData()
145 {
146   Standard_Integer i, aNb;
147   Standard_Boolean bFlag;
148   //
149   myErrorStatus=0;
150   //
151   aNb=myArguments.Extent();
152   if (aNb!=myNbArgs) {
153     if (aNb!=1 || !(myArgs[0].IsSame(myArgs[1]))) {
154       myErrorStatus=10; // invalid number of arguments
155       return;
156     }
157   }
158   //
159   if (!myPaveFiller) {
160     myErrorStatus=101; 
161     return;
162   }
163   //
164   myErrorStatus=myPaveFiller->ErrorStatus();
165   if (myErrorStatus) {
166     return;
167   }
168   //
169   for (i=0; i<myNbArgs; ++i) {
170     if (myArgs[i].IsNull()) {
171       myErrorStatus=11; // argument is null shape
172       return;
173     }
174   }
175   //
176   for (i=0; i<myNbArgs; ++i) {
177     bFlag = BOPTools_AlgoTools3D::IsEmptyShape(myArgs[i]);
178     if(bFlag) {
179       myWarningStatus = 2;
180     }
181   }
182   //
183   for (i=0; i<myNbArgs; ++i) {
184     myDims[i]=BOPTools_AlgoTools::Dimension(myArgs[i]);
185     if (myDims[i]<0) {
186       myErrorStatus=13; // non-homogenious argument
187       return;
188     }
189   }
190   //
191   if (myOperation==BOPAlgo_UNKNOWN) {
192     myErrorStatus=14; // non-licit operation
193     return;
194   }
195   else if (myDims[0]<myDims[1]) {
196     if (myOperation==BOPAlgo_FUSE ||
197         myOperation==BOPAlgo_CUT21) {
198       myErrorStatus=14; // non-licit operation for the arguments
199       return;
200     }
201   }
202   else if (myDims[0]>myDims[1]) {
203     if (myOperation==BOPAlgo_FUSE ||
204         myOperation==BOPAlgo_CUT) {
205       myErrorStatus=14; // non-licit operation for the arguments
206       return;
207     }
208   }
209 }
210 //=======================================================================
211 //function : Prepare
212 //purpose  : 
213 //=======================================================================
214   void BOPAlgo_BOP::Prepare()
215 {
216   Standard_Integer i;
217   BRep_Builder aBB;
218   //
219   BOPAlgo_Builder::Prepare();
220   //
221   if(myWarningStatus == 2) {
222     switch(myOperation) {
223       case BOPAlgo_FUSE:
224         for ( i = 0; i < myNbArgs; i++ ) {
225           aBB.Add(myShape, myArgs[i]);
226         }
227         break;
228       case BOPAlgo_COMMON:
229       case BOPAlgo_SECTION:
230         break;
231       case BOPAlgo_CUT:
232         if(BOPTools_AlgoTools3D::IsEmptyShape(myArgs[0])) {
233           break;
234         } else {
235           aBB.Add(myShape, myArgs[0]);
236         }
237         break;
238       case BOPAlgo_CUT21:
239         if(BOPTools_AlgoTools3D::IsEmptyShape(myArgs[1])) {
240           break;
241         } else {
242           aBB.Add(myShape, myArgs[1]);
243         }
244         break;
245       default:
246         break;
247     }
248   }
249 }
250 //=======================================================================
251 //function : PerformInternal
252 //purpose  : 
253 //=======================================================================
254   void BOPAlgo_BOP::PerformInternal(const BOPAlgo_PaveFiller& theFiller)
255 {
256   myErrorStatus=0;
257   myWarningStatus=0;
258   //
259   myPaveFiller=(BOPAlgo_PaveFiller*)&theFiller;
260   myDS=myPaveFiller->PDS();
261   myContext=myPaveFiller->Context();
262   //
263   // 1. CheckData
264   CheckData();
265   if (myErrorStatus && !myWarningStatus) {
266     return;
267   }
268   //
269   // 2. Prepare
270   Prepare();
271   if (myErrorStatus) {
272     return;
273   }
274   if(myWarningStatus == 2) {
275     return;
276   }
277   //
278   // 3. Fill Images
279   // 3.1 Vertices
280   FillImagesVertices();
281   if (myErrorStatus) {
282     return;
283   }
284   //
285   BuildResult(TopAbs_VERTEX);
286   if (myErrorStatus) {
287     return;
288   }
289   // 3.2 Edges
290   FillImagesEdges();
291   if (myErrorStatus) {
292     return;
293   }
294   
295   BuildResult(TopAbs_EDGE);
296   if (myErrorStatus) {
297     return;
298   }
299   //-------------------------------- SECTION f
300   if (myOperation==BOPAlgo_SECTION) {
301     BuildSection();
302     PrepareHistory();
303     PostTreat();
304     return;
305   }
306   //-------------------------------- SECTION t
307   //
308   // 3.3 Wires
309   FillImagesContainers(TopAbs_WIRE);
310   if (myErrorStatus) {
311     return;
312   }
313   
314   BuildResult(TopAbs_WIRE);
315   if (myErrorStatus) {
316     return;
317   }
318   
319   // 3.4 Faces
320   FillImagesFaces();
321   if (myErrorStatus) {
322     return;
323   }
324   
325   BuildResult(TopAbs_FACE);
326   if (myErrorStatus) {
327     return;
328   }
329   // 3.5 Shells
330   
331   FillImagesContainers(TopAbs_SHELL);
332   if (myErrorStatus) {
333     return;
334   }
335   
336   BuildResult(TopAbs_SHELL);
337   if (myErrorStatus) {
338     return;
339   }
340   // 3.6 Solids
341   FillImagesSolids();
342   if (myErrorStatus) {
343     return;
344   }
345   
346   BuildResult(TopAbs_SOLID);
347   if (myErrorStatus) {
348     return;
349   }
350   // 3.7 CompSolids
351   FillImagesContainers(TopAbs_COMPSOLID);
352   if (myErrorStatus) {
353     return;
354   }
355   
356   BuildResult(TopAbs_COMPSOLID);
357   if (myErrorStatus) {
358     return;
359   }
360   // 3.8 Compounds
361   FillImagesCompounds();
362   if (myErrorStatus) {
363     return;
364   }
365   
366   BuildResult(TopAbs_COMPOUND);
367   if (myErrorStatus) {
368     return;
369   }
370   //
371   // 6.BuildShape;
372   BuildShape();
373   // 
374   // 4.History
375   PrepareHistory();
376
377   //
378   // 5 Post-treatment 
379   PostTreat();
380 }
381 //=======================================================================
382 //function : BuildShape
383 //purpose  : 
384 //=======================================================================
385   void BOPAlgo_BOP::BuildShape()
386 {
387   Standard_Integer aDmin, aNbLCB;
388   TopAbs_ShapeEnum aT1, aT2, aTR;
389   TopoDS_Shape aR, aRC;
390   TopoDS_Iterator aIt;
391   BRep_Builder aBB;
392   BOPCol_ListOfShape aLCB;
393   BOPCol_ListIteratorOfListOfShape aItLCB;
394   //
395   myErrorStatus=0;
396   //
397   BuildRC();
398   //myShape=myRC;
399   //
400   aDmin=myDims[1];
401   if (myDims[0]<myDims[1]) {
402     aDmin=myDims[0];
403   }
404   //
405   if (!aDmin) {
406     myShape=myRC;
407     return;
408   }
409   //
410   else if (aDmin==1 || aDmin==2) { //edges, faces 
411     aT1=TopAbs_VERTEX;
412     aT2=TopAbs_EDGE;
413     aTR=TopAbs_WIRE;
414     if (aDmin==2) {
415       aT1=TopAbs_EDGE;
416       aT2=TopAbs_FACE;
417       aTR=TopAbs_SHELL;
418     }
419     //
420     BOPTools_AlgoTools::MakeConnexityBlocks(myRC, aT1, aT2, aLCB);
421     aNbLCB=aLCB.Extent();
422     if (!aNbLCB) {
423       myShape=myRC;
424       return;
425     }
426     //
427     BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC);  
428     //
429     aItLCB.Initialize(aLCB);
430     for (; aItLCB.More(); aItLCB.Next()) {
431       BOPTools_AlgoTools::MakeContainer(aTR, aR);  
432       //
433       const TopoDS_Shape& aCB=aItLCB.Value();
434       aIt.Initialize(aCB);
435       for (; aIt.More(); aIt.Next()) {
436         const TopoDS_Shape& aS=aIt.Value();
437         aBB.Add(aR, aS);
438       }
439       //
440       if (aTR==TopAbs_SHELL) {
441         BOPTools_AlgoTools::OrientFacesOnShell(aR);
442       }
443       //
444       aBB.Add(aRC, aR);
445     }
446     myShape=aRC;
447   }// elase if (aDmin==1 || aDmin==2) {
448   
449   else { //aDmin=3
450     if (myOperation==BOPAlgo_FUSE) {
451       BuildSolid();
452     }
453     else {
454       myShape=myRC;
455     }
456   }
457 }
458 //=======================================================================
459 //function : BuildRC
460 //purpose  : 
461 //=======================================================================
462   void BOPAlgo_BOP::BuildRC()
463 {
464   Standard_Boolean bFlag;
465   Standard_Integer i, aDmin, aNb[2], iX = 0, iY = 0;
466   TopAbs_ShapeEnum aTmin;
467   TopoDS_Compound aC, aCS[2];
468   BRep_Builder aBB;
469   TopExp_Explorer aExp;
470   BOPCol_ListIteratorOfListOfShape aItIm;
471   BOPCol_IndexedMapOfShape aMS[2];
472   BOPCol_IndexedMapOfShape aMSV[2];
473   //
474   myErrorStatus=0;
475   //
476   // A. Fuse
477   if (myOperation==BOPAlgo_FUSE) {
478     aBB.MakeCompound(aC);
479     aTmin=TypeToExplore(myDims[0]);
480     aExp.Init(myShape, aTmin);
481     for (; aExp.More(); aExp.Next()) {
482       const TopoDS_Shape& aS=aExp.Current();
483       aBB.Add(aC, aS);
484     }
485     myRC=aC;
486     return;
487   }
488   //
489   // B. Non-Fuse
490   //
491   // 1. Compounds CS that consist of an Arg or Images of the Arg
492   for (i=0; i<myNbArgs; ++i) {
493     aBB.MakeCompound(aCS[i]);
494     const TopoDS_Shape& aS=myArgs[i];
495     if (myImages.IsBound(aS)){
496       const BOPCol_ListOfShape& aLSIm=myImages.Find(aS);
497       aItIm.Initialize(aLSIm);
498       for (; aItIm.More(); aItIm.Next()) {
499         const TopoDS_Shape& aSIm=aItIm.Value();
500         aBB.Add(aCS[i], aSIm);
501       }
502     }
503     else {
504       aBB.Add(aCS[i], aS);
505     }
506   }
507   //
508   aDmin=myDims[1];
509   if (myDims[0]<myDims[1]) {
510     aDmin=myDims[0];
511   }
512   aTmin=TypeToExplore(aDmin);
513   for (i=0; i<myNbArgs; ++i) {
514     aExp.Init(aCS[i], aTmin);
515     for (; aExp.More(); aExp.Next()) {
516       const TopoDS_Shape aS=aExp.Current();
517       if (aTmin == TopAbs_EDGE) {
518         const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aS));
519         if (BRep_Tool::Degenerated(aE)) {
520           TopExp_Explorer aExpE(aE, TopAbs_VERTEX);
521           TopoDS_Shape aS1 = aExpE.Current();
522           if (myImages.IsBound(aS1)){
523             const BOPCol_ListOfShape& aLSIm=myImages.Find(aS1);
524             const TopoDS_Shape& aSIm=aLSIm.First();
525             aMSV[i].Add(aSIm);
526           } else {
527             aMSV[i].Add(aS1);
528           }
529         }
530       }
531       //
532       if (myImages.IsBound(aS)){
533         const BOPCol_ListOfShape& aLSIm=myImages.Find(aS);
534         aItIm.Initialize(aLSIm);
535         for (; aItIm.More(); aItIm.Next()) {
536           const TopoDS_Shape& aSIm=aItIm.Value();
537           aMS[i].Add(aSIm);
538         }
539       }
540       else {
541         aMS[i].Add(aS);
542       }
543     }
544     aNb[i]=aMS[i].Extent();
545   }
546   //
547   aBB.MakeCompound(aC);
548   //
549   // 3. Find common parts
550   if (myOperation==BOPAlgo_COMMON) {
551     if (myDims[0]==myDims[1]) {
552       iX=(aNb[0]>aNb[1])? 1 : 0;
553     } else {
554       iX=(myDims[0]<myDims[1]) ? 0 : 1;
555     }
556     iY=(iX+1)%2;
557   }
558   else if (myOperation==BOPAlgo_CUT) {
559     iX=0;
560     iY=1;
561   }
562   else if (myOperation==BOPAlgo_CUT21) {
563     iX=1;
564     iY=0;
565   }
566   for (i=1; i<=aNb[iX]; ++i) {
567     const TopoDS_Shape& aSx=aMS[iX].FindKey(i);
568     bFlag=aMS[iY].Contains(aSx);
569     if (aTmin == TopAbs_EDGE) {
570       const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aSx));
571       if (BRep_Tool::Degenerated(aE)) {
572         TopExp_Explorer aExpE(aE, TopAbs_VERTEX);
573         TopoDS_Shape aSx1 = aExpE.Current();
574         TopoDS_Shape aSIm;
575         if (myImages.IsBound(aSx1)) {
576           const BOPCol_ListOfShape& aLSIm=myImages.Find(aSx1);
577           aSIm=aLSIm.First();
578         } else {
579           aSIm = aSx1;
580         }
581         bFlag=aMSV[iY].Contains(aSIm);
582       }
583     }
584     //
585     if (myOperation!=BOPAlgo_COMMON) {
586       bFlag=!bFlag;
587     }
588     //
589     if (bFlag) {
590       aBB.Add(aC, aSx);
591     }
592   }
593   //
594   myRC=aC;
595 }
596 //
597 //=======================================================================
598 //function : TypeToExplore
599 //purpose  : 
600 //=======================================================================
601 TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim)
602 {
603   TopAbs_ShapeEnum aRet;
604   //
605   switch(theDim) {
606   case 0:
607     aRet=TopAbs_VERTEX;
608     break;
609   case 1:
610     aRet=TopAbs_EDGE;
611     break;
612   case 2:
613     aRet=TopAbs_FACE;
614     break;
615   case 3:
616     aRet=TopAbs_SOLID;
617     break;
618   default:
619     aRet=TopAbs_SHAPE;
620     break;
621   }
622   return aRet;
623 }
624 //=======================================================================
625 //function : BuildSolid
626 //purpose  : 
627 //=======================================================================
628   void BOPAlgo_BOP::BuildSolid()
629 {
630   Standard_Integer i, aNbF, aNbSx, iX, iErr;
631   TopAbs_Orientation aOr, aOr1;
632   TopoDS_Iterator aIt;
633   TopoDS_Shape aRC;
634   BRep_Builder aBB;
635   TopExp_Explorer aExp;
636   BOPCol_IndexedMapOfShape aMFI;
637   BOPCol_IndexedDataMapOfShapeListOfShape aMFS, aMEF;
638   BOPCol_ListIteratorOfListOfShape aItLS;
639   BOPCol_ListOfShape aSFS;
640   BOPAlgo_BuilderSolid aSB;
641   //
642   myErrorStatus=0;
643   //
644   aIt.Initialize(myRC);
645   for (; aIt.More(); aIt.Next()) {
646     const TopoDS_Shape& aSx=aIt.Value(); 
647     aExp.Init(aSx, TopAbs_FACE);
648     for (; aExp.More(); aExp.Next()) {
649       const TopoDS_Shape& aFx=aExp.Current();
650       //
651       aOr=aFx.Orientation();
652       if (aOr==TopAbs_INTERNAL) {
653         aMFI.Add(aFx);
654         continue;
655       }
656       //
657       if (!aMFS.Contains(aFx)) {
658         BOPCol_ListOfShape aLSx;
659         //
660         aLSx.Append(aSx);
661         aMFS.Add(aFx, aLSx);
662       }
663       else {
664         iX=aMFS.FindIndex(aFx);
665         const TopoDS_Shape& aFx1=aMFS.FindKey(iX);
666         aOr1=aFx1.Orientation();
667         if (aOr1!=aOr) {
668           BOPCol_ListOfShape& aLSx=aMFS.ChangeFromKey(aFx);
669           aLSx.Append(aSx);
670           aMFS.Add(aFx, aLSx);
671         }
672       }
673     }
674   }
675   //
676   BOPCol_ListOfShape aLF, aLFx; //faces that will be added in the end;
677   // SFS
678   aNbF=aMFS.Extent();
679   for (i=1; i<=aNbF; ++i) {
680     const TopoDS_Shape& aFx=aMFS.FindKey(i);
681     const BOPCol_ListOfShape& aLSx=aMFS(i);
682     aNbSx=aLSx.Extent();
683     if (aNbSx==1) {
684       BOPTools::MapShapesAndAncestors(aFx, TopAbs_EDGE, TopAbs_FACE, aMEF);
685       if (IsBoundSplits(aFx, aMEF)){
686         aLFx.Append(aFx);
687         continue;
688       }
689       aLF.Append(aFx);
690     }
691   }
692
693   aItLS.Initialize(aLF);
694   for(; aItLS.More(); aItLS.Next()) {
695     const TopoDS_Shape& aFx=aItLS.Value();
696     aSFS.Append(aFx);
697   }
698   // add faces from aLFx to aSFS;
699   aItLS.Initialize(aLFx);
700   for (; aItLS.More(); aItLS.Next()) {
701     const TopoDS_Shape& aFx=aItLS.Value();
702     aSFS.Append(aFx);
703   }
704   //
705   aNbF=aMFI.Extent();
706   for (i=1; i<=aNbF; ++i) {
707     TopoDS_Shape aFx;
708     //
709     aFx=aMFI.FindKey(i);
710     aFx.Orientation(TopAbs_FORWARD);
711     aSFS.Append(aFx);
712     aFx.Orientation(TopAbs_REVERSED);
713     aSFS.Append(aFx);
714   }
715   //
716   // BuilderSolid
717   BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC);  
718   //
719   aSB.SetContext(myContext);
720   aSB.SetShapes(aSFS);
721   aSB.Perform();
722   iErr=aSB.ErrorStatus();
723   if (iErr) {
724     myErrorStatus=30; // SolidBuilder failed
725     return;
726   }
727   //
728   const BOPCol_ListOfShape& aLSR=aSB.Areas();
729   //
730   aItLS.Initialize(aLSR);
731   for (; aItLS.More(); aItLS.Next()) {
732     const TopoDS_Shape& aSR=aItLS.Value();
733     aBB.Add(aRC, aSR);
734   }
735   myShape=aRC;
736 }
737
738 //=======================================================================
739 //function : IsBoundImages
740 //purpose  : 
741 //=======================================================================
742   Standard_Boolean BOPAlgo_BOP::IsBoundSplits(const TopoDS_Shape& aS,
743                                               BOPCol_IndexedDataMapOfShapeListOfShape& aMEF)
744 {
745   Standard_Boolean bRet = Standard_False;
746   if (mySplits.IsBound(aS) || myOrigins.IsBound(aS)) {
747     return !bRet;
748   }
749
750   BOPCol_ListIteratorOfListOfShape aIt;
751   Standard_Integer aNbLS;
752   TopAbs_Orientation anOr;
753   //
754   //check face aF may be connected to face from mySplits
755   TopExp_Explorer aExp(aS, TopAbs_EDGE);
756   for (; aExp.More(); aExp.Next()) {
757     const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current()));
758     //
759     anOr = aE.Orientation();
760     if (anOr==TopAbs_INTERNAL) {
761       continue;
762     }
763     //
764     if (BRep_Tool::Degenerated(aE)) {
765       continue;
766     }
767     //
768     const BOPCol_ListOfShape& aLS=aMEF.FindFromKey(aE);
769     aNbLS = aLS.Extent();
770     if (!aNbLS) {
771       continue;
772     }
773     //
774     aIt.Initialize(aLS);
775     for (; aIt.More(); aIt.Next()) {
776       const TopoDS_Shape& aSx = aIt.Value();
777       if (mySplits.IsBound(aSx)  || myOrigins.IsBound(aS)) {
778         return !bRet;
779       }
780     }
781   }
782
783   return bRet;
784 }