0022967: Boolean operations between two cylinders with orthogonal axis generate a...
[occt.git] / src / BOP / BOP_ShellSolid_1.cxx
1 // File:        BOP_ShellSolid_1.cxx
2 // Created:     Fri Nov  2 12:36:51 2001
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6
7 #include <BOP_ShellSolid.ixx>
8
9 #include <TColStd_ListOfInteger.hxx>
10 #include <TColStd_ListIteratorOfListOfInteger.hxx>
11 #include <TColStd_IndexedMapOfInteger.hxx>
12
13 #include <TopoDS_Face.hxx>
14 #include <TopoDS.hxx>
15 #include <TopoDS_Edge.hxx>
16 #include <TopoDS_Shape.hxx>
17
18 #include <TopAbs_Orientation.hxx>
19
20 #include <TopTools_IndexedMapOfShape.hxx>
21 #include <TopTools_ListOfShape.hxx>
22 #include <TopTools_ListIteratorOfListOfShape.hxx>
23 #include <TopTools_IndexedMapOfShape.hxx>
24 #include <TopTools_IndexedMapOfOrientedShape.hxx>
25
26 #include <TopExp_Explorer.hxx>
27
28 #include <BRep_Tool.hxx>
29
30 #include <BooleanOperations_ShapesDataStructure.hxx>
31 #include <BooleanOperations_IndexedDataMapOfShapeInteger.hxx>
32
33 #include <IntTools_Context.hxx>
34
35 #include <BOPTools_InterferencePool.hxx>
36 #include <BOPTools_CArray1OfSSInterference.hxx>
37 #include <BOPTools_SSInterference.hxx>
38
39 #include <BOPTools_SequenceOfCurves.hxx>
40 #include <BOPTools_Curve.hxx>
41 #include <BOPTools_ListOfPaveBlock.hxx>
42 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
43 #include <BOPTools_PaveBlock.hxx>
44 #include <BOPTools_PaveFiller.hxx>
45 #include <BOPTools_CommonBlockPool.hxx>
46
47 #include <BOPTools_ListOfCommonBlock.hxx>
48 #include <BOPTools_ListIteratorOfListOfCommonBlock.hxx>
49 #include <BOPTools_CommonBlock.hxx>
50 #include <BOPTools_Tools3D.hxx>
51 #include <BOPTools_InterferencePool.hxx>
52 #include <BOPTools_CArray1OfSSInterference.hxx>
53
54 #include <BOP_SDFWESFiller.hxx>
55
56 #include <GeomAPI_ProjectPointOnSurf.hxx>
57 #include <TopExp.hxx>
58
59 static 
60   Standard_Boolean CheckSplitToAvoid(const TopoDS_Edge&          theSplit,
61                                      const BOPTools_CommonBlock& theCB, 
62                                      const Standard_Integer      theEdgeIndex,
63                                      const Standard_Integer      theFaceIndex,
64                                      const BOPTools_PDSFiller&   theDSFiller, 
65                                      const BOP_Operation&        theOperation,
66                                      const Handle(IntTools_Context)& theContext);
67
68 //=======================================================================
69 // 
70 // the WES components for a shell
71 //
72 //=======================================================================
73 // function: AddSectionPartsSh
74 // purpose: 
75 //=======================================================================
76   void BOP_ShellSolid::AddSectionPartsSh (const Standard_Integer nF1, 
77                                           const Standard_Integer iFF,
78                                           BOP_WireEdgeSet& aWES)
79 {
80   const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
81   BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
82   BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
83   //
84   Standard_Integer i, aNbCurves, nF2,  nE, iRankF1;
85   //
86   iRankF1=aDS.Rank(nF1);
87   //
88   BOPTools_SSInterference& aFF=aFFs(iFF);
89   nF2=aFF.OppositeIndex(nF1);
90   //
91   BOPTools_SequenceOfCurves& aSC=aFF.Curves();
92   aNbCurves=aSC.Length();
93   for (i=1; i<=aNbCurves; i++) {
94     const BOPTools_Curve& aBC=aSC(i);
95     const BOPTools_ListOfPaveBlock& aLPB=aBC.NewPaveBlocks();
96     BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
97     for (; anIt.More(); anIt.Next()) {
98       const BOPTools_PaveBlock& aPB=anIt.Value();
99       nE=aPB.Edge();
100       const TopoDS_Edge& aE=TopoDS::Edge(aDS.Shape(nE));
101       
102       TopoDS_Edge aES=aE;
103       
104       if (myOperation==BOP_FUSE) {
105         aWES.AddStartElement (aES);
106         aES.Reverse();
107         aWES.AddStartElement (aES);
108       }
109         
110     }
111   }
112 }
113 //=======================================================================
114 // function: AddSplitPartsONSh
115 // purpose: 
116 //=======================================================================
117   void BOP_ShellSolid::AddSplitPartsONSh(const Standard_Integer nF1,
118                                          BOP_WireEdgeSet& aWES)
119 {
120   const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
121   const BOPTools_PaveFiller& aPaveFiller=myDSFiller->PaveFiller();
122   
123   BOPTools_PaveFiller* pPaveFiller=(BOPTools_PaveFiller*)&aPaveFiller;
124   BOPTools_CommonBlockPool& aCBPool=pPaveFiller->ChangeCommonBlockPool();
125   //
126   const Handle(IntTools_Context)& aContext=pPaveFiller->Context();
127   //
128   Standard_Integer nEF1, nF2, nSpF1, nSpF2, nEF2, nSpTaken, iRankF1;
129   Standard_Boolean bToReverse;
130   TopAbs_Orientation anOrEF1, anOrEF2;
131   TopExp_Explorer anExp;
132   TopTools_IndexedMapOfShape aM;
133   TopoDS_Edge aSSF1, aSSF2;
134   //
135   iRankF1=aDS.Rank(nF1);
136   //
137   anExp.Init(myFace, TopAbs_EDGE);
138   for (; anExp.More(); anExp.Next()) {
139     const TopoDS_Edge& anEF1=TopoDS::Edge(anExp.Current());
140     anOrEF1=anEF1.Orientation();
141     nEF1=aDS.ShapeIndex(anEF1, iRankF1);
142     
143     BOPTools_ListOfCommonBlock& aLCB=aCBPool(aDS.RefEdge(nEF1));
144     
145     BOPTools_ListIteratorOfListOfCommonBlock anItCB(aLCB);
146     for (; anItCB.More(); anItCB.Next()) {
147       BOPTools_CommonBlock& aCB=anItCB.Value();
148
149       BOPTools_PaveBlock& aPBEF1=aCB.PaveBlock1(nEF1);
150       BOPTools_PaveBlock& aPBEF2=aCB.PaveBlock2(nEF1);
151       nF2=aCB.Face();
152       if (nF2) { 
153         // Splits that are ON (IN 2D) for other Face (aF2)
154         nSpF1=aPBEF1.Edge();
155         const TopoDS_Shape& aSplit=aDS.Shape(nSpF1);
156         aSSF1=TopoDS::Edge(aSplit);
157         //
158         //iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
159         // Internal edges treatment
160         {
161           if (anOrEF1==TopAbs_INTERNAL) {
162             if (myOperation==BOP_FUSE) {
163               aSSF1.Orientation(TopAbs_FORWARD);
164               aWES.AddStartElement (aSSF1);
165               aSSF1.Reverse();
166               aWES.AddStartElement (aSSF1);
167             }
168             else if (myOperation==BOP_CUT) {
169               if (iRankF1==1) {
170                 aWES.AddStartElement (aSSF1);
171               }
172             }
173             else if (myOperation==BOP_CUT21) {
174               if (iRankF1==2) {
175                 aWES.AddStartElement (aSSF1);
176               }
177             }
178             continue;
179           }
180         }
181         //iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
182         //
183         aSSF1.Orientation(anOrEF1);
184         aWES.AddStartElement (aSSF1);
185       }
186
187       else {
188         // Splits that are ON other Edge from other Face
189         nSpF1=aPBEF1.Edge();
190         nSpF2=aPBEF2.Edge();
191         nEF2=aPBEF2.OriginalEdge();
192         
193         const TopoDS_Edge& anEF2=TopoDS::Edge(aDS.Shape(nEF2));
194         anOrEF2=anEF2.Orientation();
195
196         const TopoDS_Shape& aSpF1=aDS.Shape(nSpF1);
197         const TopoDS_Shape& aSpF2=aDS.Shape(nSpF2);
198         //
199         // Pave Block from which new edge will be taken
200         const BOPTools_PaveBlock& aPB=aCB.PaveBlock1();
201         nSpTaken=aPB.Edge();
202         //
203         //iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
204         // Internal edges treatment
205         {
206           Standard_Boolean bInternal1, bInternal2;
207           bInternal1=(anOrEF1==TopAbs_INTERNAL);
208           bInternal2=(anOrEF2==TopAbs_INTERNAL);
209           
210           if (bInternal1) {
211             aSSF1=TopoDS::Edge(aDS.Shape(nSpTaken));
212
213             if (myOperation==BOP_FUSE) {
214               aSSF1.Orientation(TopAbs_FORWARD);
215               aWES.AddStartElement (aSSF1);
216               aSSF1.Reverse();
217               aWES.AddStartElement (aSSF1);
218               continue;
219             }
220
221             if (myOperation==BOP_CUT && iRankF1==1) {
222               aSSF1.Orientation(TopAbs_INTERNAL);
223               aWES.AddStartElement (aSSF1);
224               continue;
225             }
226
227             if (myOperation==BOP_CUT21 && iRankF1==2) {
228               aSSF1.Orientation(TopAbs_INTERNAL);
229               aWES.AddStartElement (aSSF1);
230               continue;
231             }
232           }
233           
234           else if (!bInternal1 && bInternal2) {
235             if (nSpTaken!=nSpF1) {
236               
237               if ((myOperation==BOP_FUSE)||
238                   (myOperation==BOP_CUT && iRankF1==1) ||
239                   (myOperation==BOP_CUT21 && iRankF1==2)) { 
240               
241                 aSSF1=TopoDS::Edge(aSpF1);
242                 aSSF1.Orientation(anOrEF1);
243                 
244                 aSSF2=TopoDS::Edge(aSpF2);
245               
246                 aSSF2.Orientation(TopAbs_FORWARD);
247                 bToReverse=BOPTools_Tools3D::IsSplitToReverse1 (aSSF1, aSSF2, aContext);
248                 if (bToReverse) {
249                   aSSF2.Reverse();
250                 }
251               
252                 aWES.AddStartElement (aSSF2);
253                 continue;
254               }
255             }
256           }
257         }
258         //
259         aSSF1=TopoDS::Edge(aSpF1);
260         aSSF1.Orientation(anOrEF1);
261         
262         if (nSpTaken==nSpF1) {
263           // Common Edge is from nEF1
264           if(CheckSplitToAvoid(aSSF1, aCB, nEF1, nF1, myDSFiller, myOperation, aContext)){
265             continue;
266           }
267           aWES.AddStartElement (aSSF1);
268         }
269         
270         else {
271           // Common Edge is from nEF2 nSpTaken!=nSpF2
272           aSSF2=TopoDS::Edge(aSpF2);
273           
274           bToReverse=BOPTools_Tools3D::IsSplitToReverse1 (aSSF1, aSSF2, aContext);
275           if (bToReverse) {
276             aSSF2.Reverse();
277           }
278           //
279           if (BRep_Tool::IsClosed(aSSF1, myFace)) {
280             if (aM.Contains(aSSF2)){
281               continue;
282             }
283             aM.Add(aSSF2);
284             //
285             if (!BRep_Tool::IsClosed(aSSF2, myFace)) {
286               BOPTools_Tools3D::DoSplitSEAMOnFace (aSSF2, myFace);
287             }
288
289             aWES.AddStartElement (aSSF2);
290             aSSF2.Reverse();
291             aWES.AddStartElement (aSSF2);
292             continue;  
293           }
294           //
295           if(CheckSplitToAvoid(aSSF2, aCB, nEF1, nF1, myDSFiller, myOperation, aContext)) {
296             continue;
297           }
298           aWES.AddStartElement (aSSF2);
299         }
300       }
301     }
302   }
303 }
304 //=======================================================================
305 // function: AddPartsEFSh
306 // purpose: 
307 //=======================================================================
308   void BOP_ShellSolid::AddPartsEFSh (const Standard_Integer nF1, 
309                                      const Standard_Integer iFF,
310                                      TopTools_IndexedMapOfShape& anEMap,
311                                      BOP_WireEdgeSet& aWES)
312 {
313   const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
314   BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
315   BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
316   
317   const BOPTools_PaveFiller& aPF=myDSFiller->PaveFiller();
318   BOPTools_PaveFiller* pPaveFiller=(BOPTools_PaveFiller*)&aPF;
319   BOPTools_CommonBlockPool& aCBPool=pPaveFiller->ChangeCommonBlockPool();
320   //
321   Standard_Integer iRankF1, iRankF2, nF2, nSpEF2, nEF2,  nFace;
322   TopExp_Explorer anExp2;
323   TopAbs_Orientation anOrEF2;
324   //
325   BOPTools_SSInterference& aFF=aFFs(iFF);
326   nF2=aFF.OppositeIndex(nF1);
327   //
328   const TopoDS_Face& aF2=TopoDS::Face(aDS.Shape(nF2));
329   //
330   iRankF1=aDS.Rank(nF1);
331   iRankF2=aDS.Rank(nF2);
332   //
333   // EF2\F1 Processing
334   anExp2.Init (aF2, TopAbs_EDGE);
335   for (; anExp2.More(); anExp2.Next()) {
336     const TopoDS_Edge& aEF2= TopoDS::Edge(anExp2.Current());
337     anOrEF2=aEF2.Orientation();
338
339     nEF2=aDS.ShapeIndex (aEF2, iRankF2);
340
341     BOPTools_ListOfCommonBlock& aLCB=aCBPool(aDS.RefEdge(nEF2));
342     
343     BOPTools_ListIteratorOfListOfCommonBlock anItCB(aLCB);
344     for (; anItCB.More(); anItCB.Next()) {
345       BOPTools_CommonBlock& aCB=anItCB.Value();
346       nFace=aCB.Face();
347       if (nFace==nF1) {
348         BOPTools_PaveBlock& aPB=aCB.PaveBlock1(nEF2);
349
350         nSpEF2=aPB.Edge();
351         const TopoDS_Shape& aSpEF2=aDS.Shape(nSpEF2);
352         
353         if (anEMap.Contains(aSpEF2)) {
354           continue;// next CB
355         }
356         anEMap.Add(aSpEF2);
357         
358         TopoDS_Edge aSS=TopoDS::Edge(aSpEF2);
359         //
360         //
361         //iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
362         // Internal edges treatment
363         {
364           if (anOrEF2==TopAbs_INTERNAL) {
365             aSS.Orientation(TopAbs_FORWARD);
366           }
367         }
368         //iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
369         //
370         if (myOperation== BOP_FUSE) {
371           aWES.AddStartElement (aSS);
372           aSS.Reverse();
373           aWES.AddStartElement (aSS);
374         }
375       }
376     } // next CB on nEF2
377   }
378 }
379 //xf
380 //=======================================================================
381 // function: AddINON2DPartsSh
382 // purpose: 
383 //=======================================================================
384   void BOP_ShellSolid::AddINON2DPartsSh(const Standard_Integer nF1,
385                                         const Standard_Integer iFF,
386                                         BOP_WireEdgeSet& aWES)
387 {
388   TopTools_IndexedMapOfShape anEMap;
389   AddINON2DPartsSh(nF1, iFF, aWES, anEMap);
390 }
391 //xt
392 //=======================================================================
393 // function: AddINON2DPartsSh
394 // purpose: 
395 //=======================================================================
396   void BOP_ShellSolid::AddINON2DPartsSh(const Standard_Integer nF1,
397                                         const Standard_Integer iFF,
398                                         BOP_WireEdgeSet& aWES,
399                                         TopTools_IndexedMapOfShape& anEMap) //xft
400 {
401   const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
402   BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
403   BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
404   //
405   Standard_Integer iRankF1, nF2, iSenseFlag;
406
407   iRankF1=aDS.Rank(nF1);
408   
409   BOPTools_SSInterference& aFF=aFFs(iFF);
410   nF2=aFF.OppositeIndex(nF1);
411   //
412   iSenseFlag=aFF.SenseFlag();
413   //
414   BOP_SDFWESFiller aWESFiller;
415   
416   aWESFiller.SetDSFiller(*myDSFiller);
417   aWESFiller.SetFaces(nF1, nF2);
418   aWESFiller.SetStatesMap(aFF.StatesMap());
419   //
420   aWESFiller.SetSenseFlag(iSenseFlag);
421  
422   switch (myOperation) {
423   
424   case BOP_FUSE: 
425     if (myRank==2) {
426       //shell\solid case when the solid is the first arg.
427       iRankF1=1;
428     }
429     if (iRankF1==1) {
430       aWESFiller.SetOperation(BOP_CUT); 
431       aWESFiller.Do(aWES);
432       aWESFiller.SetOperation(BOP_COMMON);      
433       aWESFiller.Do(aWES);
434     }
435     else {
436       aWESFiller.SetOperation(BOP_CUT); 
437       aWESFiller.Do(aWES);
438     }
439     break;
440     
441   case BOP_COMMON:
442     if (myRank==2) {
443       //shell\solid case when the solid is the first arg.
444       iRankF1=1;
445     }
446     if (iRankF1==1) {
447       aWESFiller.SetOperation(BOP_COMMON);      
448       aWESFiller.Do(aWES);
449     }
450     break;
451     
452   case BOP_CUT: 
453     if (iRankF1==1) {
454       aWESFiller.SetOperation(BOP_CUT); 
455       aWESFiller.Do(aWES);
456     }
457     break;
458     
459   case BOP_CUT21: 
460     if (iRankF1==2) {
461       aWESFiller.SetOperation(BOP_CUT); 
462       aWESFiller.Do(aWES);
463     }
464     break;
465     
466   default:
467     break;
468   }
469   //
470   //xf
471   // Collect all split edges of nF1 that are CB with 
472   // splis of all SD faces to nFx,
473   // but not included in aWES (RejectedOnParts).
474   // This is necessary to prevent inclusion these splits in 
475   // AddPartsEENonSDSh(...) 
476   // see BOP_SDFWESFiller,  BOP_ShellSolid::DoNewFaces()
477   //  for more details;
478   TopTools_ListIteratorOfListOfShape aIt;
479   //
480   const TopTools_ListOfShape& aLRE=aWESFiller.RejectedOnParts();
481   aIt.Initialize(aLRE);
482   for(; aIt.More(); aIt.Next()) {
483     const TopoDS_Shape& aE=aIt.Value();
484     anEMap.Add(aE);
485   }
486   //xt
487 }
488 //=======================================================================
489 // function: AddPartsEFNonSDSh
490 // purpose: 
491 //=======================================================================
492   void BOP_ShellSolid::AddPartsEFNonSDSh (const Standard_Integer nF1, 
493                                           const Standard_Integer iFF,
494                                           TopTools_IndexedMapOfShape& anEMap,
495                                           BOP_WireEdgeSet& aWES)
496 {
497   const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
498   BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
499   BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
500   
501   const BOPTools_PaveFiller& aPF=myDSFiller->PaveFiller();
502   BOPTools_PaveFiller* pPaveFiller=(BOPTools_PaveFiller*)&aPF;
503   BOPTools_CommonBlockPool& aCBPool=pPaveFiller->ChangeCommonBlockPool();
504   //
505   Standard_Integer nF2, nSpEF2, nEF2,  nFace, iRankF2;
506   TopExp_Explorer anExp2;
507   TopAbs_Orientation anOrEF2 = TopAbs_FORWARD;
508   //
509   BOPTools_SSInterference& aFF=aFFs(iFF);
510   nF2=aFF.OppositeIndex(nF1);
511   //
512   const TopoDS_Face& aF2=TopoDS::Face(aDS.Shape(nF2));
513
514   iRankF2=aDS.Rank(nF2);
515   //
516   TopTools_IndexedMapOfOrientedShape aWESMap;
517   {
518     const TopTools_ListOfShape& aWESList=aWES.StartElements();
519     TopTools_ListIteratorOfListOfShape anIt(aWESList);
520     for (; anIt.More(); anIt.Next()) {
521       const TopoDS_Shape& aS=anIt.Value();
522       aWESMap.Add(aS);
523     }
524   }
525   //
526   // EF2\F1 Processing
527   anExp2.Init (aF2, TopAbs_EDGE);
528   for (; anExp2.More(); anExp2.Next()) {
529     const TopoDS_Edge& aEF2= TopoDS::Edge(anExp2.Current());
530
531     nEF2=aDS.ShapeIndex(aEF2, iRankF2);
532
533     BOPTools_ListOfCommonBlock& aLCB=aCBPool(aDS.RefEdge(nEF2));
534     
535     BOPTools_ListIteratorOfListOfCommonBlock anItCB(aLCB);
536     for (; anItCB.More(); anItCB.Next()) {
537       BOPTools_CommonBlock& aCB=anItCB.Value();
538       nFace=aCB.Face();
539       
540       if (nFace==nF1) {
541         BOPTools_PaveBlock& aPB=aCB.PaveBlock1(nEF2);
542
543         nSpEF2=aPB.Edge();
544         const TopoDS_Shape& aSpEF2=aDS.Shape(nSpEF2);
545         //
546         if (anEMap.Contains(aSpEF2)) {
547           continue;// next CB
548         }
549         anEMap.Add(aSpEF2);
550         //
551         if (aWESMap.Contains(aSpEF2)) {
552           continue;// next CB
553         }
554         aWESMap.Add(aSpEF2);
555         //
556         TopoDS_Edge aSS=TopoDS::Edge(aSpEF2);
557         //
558         //
559         //iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
560         // Internal edges treatment
561         {
562           if (anOrEF2==TopAbs_INTERNAL) {
563             aSS.Orientation(TopAbs_FORWARD);
564           }
565         }
566         //iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
567         //
568         if (myOperation==BOP_FUSE) {
569           aWES.AddStartElement(aSS);
570           aSS.Reverse();
571           aWES.AddStartElement(aSS);
572         }
573         //
574       } //if (nFace==nF1) {
575     } // next CB on nEF2
576   }
577 }
578 //=======================================================================
579 // function: AddPartsEENonSDSh
580 // purpose: 
581 //=======================================================================
582   void BOP_ShellSolid::AddPartsEENonSDSh (const Standard_Integer nF1, 
583                                           const Standard_Integer iFF,
584                                           TopTools_IndexedMapOfShape& anEMap,
585                                           BOP_WireEdgeSet& aWES)
586 {
587   const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
588   BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
589   BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
590   
591   const BOPTools_PaveFiller& aPF=myDSFiller->PaveFiller();
592   BOPTools_PaveFiller* pPaveFiller=(BOPTools_PaveFiller*)&aPF;
593   BOPTools_CommonBlockPool& aCBPool=pPaveFiller->ChangeCommonBlockPool();
594   //
595   const Handle(IntTools_Context)& aContext=pPaveFiller->Context();
596   //
597   Standard_Integer nEF1, nF2, nSpF1, nSpF2, nEF2, nSpTaken, nF2x, iRankF1;
598   Standard_Boolean bToReverse;
599   TopAbs_Orientation anOrEF1, anOrEF2;
600   TopExp_Explorer anExp;
601   TopTools_IndexedMapOfShape aM;
602   TColStd_ListOfInteger aSplitsOnF1;
603   TColStd_ListIteratorOfListOfInteger anItSp;
604   TColStd_IndexedMapOfInteger aMSplitsOnF1;
605   TopoDS_Edge aSSF1, aSSF2;
606   //
607   // nF1
608   iRankF1=aDS.Rank(nF1);
609   //
610   // nF2
611   BOPTools_SSInterference& aFF=aFFs(iFF);
612   nF2=aFF.OppositeIndex(nF1);
613   //
614   pPaveFiller->SplitsOnFace(0, nF1, nF2, aSplitsOnF1);
615   anItSp.Initialize(aSplitsOnF1);
616   for (; anItSp.More(); anItSp.Next()) {
617     nSpF1=anItSp.Value();
618     aMSplitsOnF1.Add(nSpF1);
619   }
620   //
621   TopTools_IndexedMapOfOrientedShape aWESMap;
622   {
623     const TopTools_ListOfShape& aWESList=aWES.StartElements();
624     TopTools_ListIteratorOfListOfShape anIt(aWESList);
625     for (; anIt.More(); anIt.Next()) {
626       const TopoDS_Shape& aS=anIt.Value();
627       aWESMap.Add(aS);
628     }
629   }
630   //
631   anExp.Init(myFace, TopAbs_EDGE);
632   for (; anExp.More(); anExp.Next()) {
633     const TopoDS_Edge& anEF1=TopoDS::Edge(anExp.Current());
634     anOrEF1=anEF1.Orientation();
635     nEF1=aDS.ShapeIndex(anEF1, iRankF1);
636     
637     BOPTools_ListOfCommonBlock& aLCB=aCBPool(aDS.RefEdge(nEF1));
638     
639     BOPTools_ListIteratorOfListOfCommonBlock anItCB(aLCB);
640     for (; anItCB.More(); anItCB.Next()) {
641       BOPTools_CommonBlock& aCB=anItCB.Value();
642     
643       BOPTools_PaveBlock& aPBEF1=aCB.PaveBlock1(nEF1);
644       BOPTools_PaveBlock& aPBEF2=aCB.PaveBlock2(nEF1);
645       
646       nF2x=aCB.Face();
647       if (nF2x) {
648         continue;
649       }
650       // Splits that are ON other Edge from other Face
651       nSpF1=aPBEF1.Edge();
652       //
653       if (!aMSplitsOnF1.Contains(nSpF1)) {
654         continue;// next CB
655       }
656       //
657       nSpF2=aPBEF2.Edge();
658       nEF2=aPBEF2.OriginalEdge();
659
660       const TopoDS_Edge& anEF2=TopoDS::Edge(aDS.Shape(nEF2));
661       anOrEF2=anEF2.Orientation();
662       
663       const TopoDS_Shape& aSpF1=aDS.Shape(nSpF1);
664       const TopoDS_Shape& aSpF2=aDS.Shape(nSpF2);
665       
666       //
667       if (anEMap.Contains(aSpF1)) {
668         continue;// next CB
669       }
670       anEMap.Add(aSpF1);
671       //
672       if (anEMap.Contains(aSpF2)) {
673         continue;// next CB
674       }
675       anEMap.Add(aSpF2);
676       //
677       
678       // Pave Block from which new edge will be taken
679       const BOPTools_PaveBlock& aPB=aCB.PaveBlock1();
680       nSpTaken=aPB.Edge();
681       //
682       //iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
683       // Internal edges treatment
684       {
685         Standard_Boolean bInternal1, bInternal2;
686         bInternal1=(anOrEF1==TopAbs_INTERNAL);
687         bInternal2=(anOrEF2==TopAbs_INTERNAL);
688         
689         if (bInternal1) {
690           aSSF1=TopoDS::Edge(aDS.Shape(nSpTaken));
691           
692           if (myOperation==BOP_FUSE) {
693             aSSF1.Orientation(TopAbs_FORWARD);
694             aWES.AddStartElement (aSSF1);
695             aSSF1.Reverse();
696             aWES.AddStartElement (aSSF1);
697             continue;
698           }
699           
700           if (myOperation==BOP_CUT && iRankF1==1) {
701             aSSF1.Orientation(TopAbs_INTERNAL);
702             aWES.AddStartElement (aSSF1);
703             continue;
704           }
705           
706           if (myOperation==BOP_CUT21 && iRankF1==2) {
707             aSSF1.Orientation(TopAbs_INTERNAL);
708             aWES.AddStartElement (aSSF1);
709             continue;
710           }
711         }
712           
713         else if (!bInternal1 && bInternal2) {
714           if (nSpTaken!=nSpF1) {
715             
716             if ((myOperation==BOP_FUSE)||
717                 (myOperation==BOP_CUT && iRankF1==1) ||
718                 (myOperation==BOP_CUT21 && iRankF1==2)) { 
719               
720               aSSF1=TopoDS::Edge(aSpF1);
721               aSSF1.Orientation(anOrEF1);
722               
723               aSSF2=TopoDS::Edge(aSpF2);
724               
725               aSSF2.Orientation(TopAbs_FORWARD);
726               bToReverse=BOPTools_Tools3D::IsSplitToReverse1 (aSSF1, aSSF2, aContext);
727               if (bToReverse) {
728                 aSSF2.Reverse();
729               }
730               
731               aWES.AddStartElement (aSSF2);
732               continue;
733             }
734           }
735         }
736       }
737       //iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
738       //
739       aSSF1=TopoDS::Edge(aSpF1);
740       aSSF1.Orientation(anOrEF1);
741       
742       if (nSpTaken==nSpF1) {
743         // Common Edge is from nEF1
744         aWES.AddStartElement (aSSF1);
745       }
746       else  {
747         // Common Edge is from nEF2 nSpTaken!=nSpF2
748         aSSF2=TopoDS::Edge(aSpF2);
749         
750         bToReverse=BOPTools_Tools3D::IsSplitToReverse1 (aSSF1, aSSF2, aContext);
751         if (bToReverse) {
752           aSSF2.Reverse();
753         }
754         //
755         if (BRep_Tool::IsClosed(aSSF1, myFace)) {
756           if (aM.Contains(aSSF2)){
757             continue;
758           }
759           aM.Add(aSSF2);
760           //
761           if (!BRep_Tool::IsClosed(aSSF2, myFace)) {
762             BOPTools_Tools3D::DoSplitSEAMOnFace (aSSF2, myFace);
763           }
764           aWES.AddStartElement (aSSF2);
765           aSSF2.Reverse();
766           aWES.AddStartElement (aSSF2);
767           continue;  
768         }
769         //
770         aWES.AddStartElement (aSSF2);
771       }// else /*if (nSpTaken==nSpF2)*/ {
772     }// for (; anItCB.More(); anItCB.Next())
773   }// for (; anExp.More(); anExp.Next())
774 }
775 //=======================================================================
776 //function : CheckSplitToAvoid
777 //purpose  : 
778 //=======================================================================
779 Standard_Boolean CheckSplitToAvoid(const TopoDS_Edge&          theSplit,
780                                    const BOPTools_CommonBlock& theCB, 
781                                    const Standard_Integer      theEdgeIndex,
782                                    const Standard_Integer      theFaceIndex,
783                                    const BOPTools_PDSFiller&   theDSFiller, 
784                                    const BOP_Operation&        theOperation,
785                                    const Handle(IntTools_Context)&  theContext) {
786
787   Standard_Integer anE = -1;
788
789   if(theCB.PaveBlock1().OriginalEdge() == theEdgeIndex) {
790     anE = theCB.PaveBlock2().OriginalEdge();
791   }
792   else if(theCB.PaveBlock2().OriginalEdge() == theEdgeIndex) {
793     anE = theCB.PaveBlock1().OriginalEdge();
794   }
795
796   if(anE >= 0) {
797     const TopoDS_Shape& anEdge = theDSFiller->DS().Shape(anE);
798     TopoDS_Face aFaceCur = TopoDS::Face(theDSFiller->DS().Shape(theFaceIndex));
799     aFaceCur.Orientation(TopAbs_FORWARD);
800
801     TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
802     Standard_Integer aRank = theDSFiller->DS().Rank(anE);
803     TopoDS_Shape aSource = (aRank == 1) ? theDSFiller->Shape1() : theDSFiller->Shape2();
804     TopExp::MapShapesAndAncestors(aSource, TopAbs_EDGE, TopAbs_FACE, aMapEF);
805
806     if(aMapEF.Contains(anEdge)) {
807       const TopTools_ListOfShape& aLF = aMapEF.FindFromKey(anEdge);
808
809       if(!aLF.IsEmpty()) {
810         TopTools_ListIteratorOfListOfShape anIt(aLF);
811         Standard_Boolean avoid = Standard_True;
812
813         for(; anIt.More(); anIt.Next()) {
814           const TopoDS_Face& aFace = TopoDS::Face(anIt.Value());
815           Standard_Real f = 0., l = 0.;
816           Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(theSplit, aFaceCur, f, l);
817
818           if(!aCurve.IsNull()) {
819             Standard_Real amidpar = (f + l) * 0.5;
820
821             if(theOperation == BOP_COMMON) {
822               gp_Pnt2d aPoint2d;
823               gp_Pnt aPoint3d;
824               Standard_Real aTolerance = BRep_Tool::Tolerance(theSplit); //???
825               BOPTools_Tools3D::PointNearEdge(theSplit, aFaceCur, amidpar, aTolerance, aPoint2d, aPoint3d);
826               GeomAPI_ProjectPointOnSurf& aProjector =  theContext->ProjPS(aFace);
827               aProjector.Perform(aPoint3d);
828
829               if(aProjector.IsDone()) {
830                 Standard_Real U = 0., V = 0.;
831                 Standard_Real adist = aProjector.LowerDistance();
832
833                 if(adist < BRep_Tool::Tolerance(aFace)) {
834                   aProjector.LowerDistanceParameters(U, V);
835
836                   if(theContext->IsPointInFace(aFace, gp_Pnt2d(U, V))) {
837                     avoid = Standard_False;
838                     break;
839                   }
840                   else {
841                   }
842                 }
843               }
844             }
845             else if(theOperation == BOP_CUT) {
846               if(theDSFiller->DS().Rank(theFaceIndex) != 2) {
847                 avoid = Standard_False;
848                 continue;
849               }
850               gp_Pnt2d aPoint2d;
851               gp_Pnt aPoint3d;
852               Standard_Real aTolerance = BRep_Tool::Tolerance(theSplit); //???
853               BOPTools_Tools3D::PointNearEdge(theSplit, aFaceCur, amidpar, aTolerance, aPoint2d, aPoint3d);
854               GeomAPI_ProjectPointOnSurf& aProjector =  theContext->ProjPS(aFace);
855               aProjector.Perform(aPoint3d);
856
857               if(aProjector.IsDone()) {
858                 Standard_Real U = 0., V = 0.;
859                 Standard_Real adist = aProjector.LowerDistance();
860
861                 if(adist < BRep_Tool::Tolerance(aFace)) {
862                   aProjector.LowerDistanceParameters(U, V);
863
864                   if(theContext->IsPointInFace(aFace, gp_Pnt2d(U, V))) {
865                     avoid = Standard_False;
866                     break;
867                   }
868                   else {
869                   }
870                 }
871               }
872             }
873             else if(theOperation == BOP_CUT21) {
874               if(theDSFiller->DS().Rank(theFaceIndex) != 1) {
875                 avoid = Standard_False;
876                 continue;
877               }
878               gp_Pnt2d aPoint2d;
879               gp_Pnt aPoint3d;
880               Standard_Real aTolerance = BRep_Tool::Tolerance(theSplit); //???
881               BOPTools_Tools3D::PointNearEdge(theSplit, aFaceCur, amidpar, aTolerance, aPoint2d, aPoint3d);
882               GeomAPI_ProjectPointOnSurf& aProjector =  theContext->ProjPS(aFace);
883               aProjector.Perform(aPoint3d);
884
885               if(aProjector.IsDone()) {
886                 Standard_Real U = 0., V = 0.;
887                 Standard_Real adist = aProjector.LowerDistance();
888
889                 if(adist < BRep_Tool::Tolerance(aFace)) {
890                   aProjector.LowerDistanceParameters(U, V);
891
892                   if(theContext->IsPointInFace(aFace, gp_Pnt2d(U, V))) {
893                     avoid = Standard_False;
894                     break;
895                   }
896                   else {
897                   }
898                 }
899               }
900             }
901             // end if(theOperation == BOP_CUT21...
902             else {
903               avoid = Standard_False;
904               break;
905             }
906           }
907         }
908
909         if(avoid) {
910           return Standard_True;
911         }
912       }
913       // end if(!aLF.IsEmpty...
914     }
915   }
916
917   return Standard_False;
918 }