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