1 // Created on: 1996-09-03
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16 
17 //  Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455
18 
19 #include <Bnd_Tools.hxx>
20 #include <BRep_Builder.hxx>
21 #include <BRep_Tool.hxx>
22 #include <BRepAdaptor_Curve.hxx>
23 #include <BRepAlgo_AsDes.hxx>
24 #include <BRepAlgo_Image.hxx>
25 #include <BRepLib_MakeVertex.hxx>
26 #include <BRepOffset_Analyse.hxx>
27 #include <BRepOffset_DataMapOfShapeOffset.hxx>
28 #include <BRepOffset_Inter3d.hxx>
29 #include <BRepOffset_Interval.hxx>
30 #include <BRepOffset_ListOfInterval.hxx>
31 #include <BRepOffset_Offset.hxx>
32 #include <BRepOffset_Tool.hxx>
33 #include <Extrema_ExtPC.hxx>
34 #include <GeomAPI_ProjectPointOnCurve.hxx>
35 #include <Precision.hxx>
36 #include <TopExp.hxx>
37 #include <TopExp_Explorer.hxx>
38 #include <TopoDS.hxx>
39 #include <TopoDS_Compound.hxx>
40 #include <TopoDS_Edge.hxx>
41 #include <TopoDS_Face.hxx>
42 #include <TopoDS_Shape.hxx>
43 #include <TopoDS_Vertex.hxx>
44 #include <TopTools_IndexedMapOfShape.hxx>
45 #include <TopTools_ListIteratorOfListOfShape.hxx>
46 #include <TopTools_MapIteratorOfMapOfShape.hxx>
47 #include <TopTools_MapOfShape.hxx>
48 //
49 #include <BRepBndLib.hxx>
50 #include <BOPTools_BoxTree.hxx>
51 //
52 #include <BOPTools_AlgoTools.hxx>
53 
54 //=======================================================================
55 //function : BRepOffset_Inter3d
56 //purpose  :
57 //=======================================================================
BRepOffset_Inter3d(const Handle (BRepAlgo_AsDes)& AsDes,const TopAbs_State Side,const Standard_Real Tol)58 BRepOffset_Inter3d::BRepOffset_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes,
59                                        const TopAbs_State            Side ,
60                                        const Standard_Real           Tol)
61 :myAsDes(AsDes),
62 mySide(Side),
63 myTol(Tol)
64 {
65 }
66 
67 
68 //=======================================================================
69 //function : ExtentEdge
70 //purpose  :
71 //=======================================================================
72 
ExtentEdge(const TopoDS_Face &,const TopoDS_Edge & E,TopoDS_Edge & NE)73 static void ExtentEdge(const TopoDS_Face& /*F*/,
74                        const TopoDS_Edge& E,
75                        TopoDS_Edge& NE)
76 {
77   TopoDS_Shape aLocalShape = E.EmptyCopied();
78   NE = TopoDS::Edge(aLocalShape);
79 //  NE = TopoDS::Edge(E.EmptyCopied());
80 
81 
82   // Enough for analytic edges, in general case reconstruct the
83   // geometry of the edge recalculating the intersection of surfaces.
84 
85   NE.Orientation(TopAbs_FORWARD);
86   Standard_Real f,l;
87   BRep_Tool::Range(E,f,l);
88   Standard_Real length = l-f;
89   f -=  100*length;
90   l +=  100*length;
91 
92   BRep_Builder B;
93   B.Range(NE,f,l);
94   BRepAdaptor_Curve CE(E);
95   TopoDS_Vertex V1 = BRepLib_MakeVertex(CE.Value(f));
96   TopoDS_Vertex V2 = BRepLib_MakeVertex(CE.Value(l));
97   B.Add(NE,V1.Oriented(TopAbs_FORWARD));
98   B.Add(NE,V2.Oriented(TopAbs_REVERSED));
99   NE.Orientation(E.Orientation());
100 
101 }
102 
103 //=======================================================================
104 //function : CompletInt
105 //purpose  :
106 //=======================================================================
107 
CompletInt(const TopTools_ListOfShape & SetOfFaces,const BRepAlgo_Image & InitOffsetFace,const Message_ProgressRange & theRange)108 void BRepOffset_Inter3d::CompletInt (const TopTools_ListOfShape& SetOfFaces,
109                                      const BRepAlgo_Image&     InitOffsetFace,
110                                      const Message_ProgressRange& theRange)
111 {
112   //---------------------------------------------------------------
113   // Calculate the intersections of offset faces
114   // Distinction of intersection between faces // tangents.
115   //---------------------------------------------------------------
116 
117   // Prepare tools for sorting the bounding boxes
118   BOPTools_BoxTree aBBTree;
119   aBBTree.SetSize (SetOfFaces.Extent());
120   //
121   NCollection_IndexedDataMap<TopoDS_Shape, Bnd_Box, TopTools_ShapeMapHasher> aMFaces;
122   // Construct bounding boxes for faces and add them to the tree
123   TopTools_ListIteratorOfListOfShape aItL(SetOfFaces);
124   for (; aItL.More(); aItL.Next()) {
125     const TopoDS_Face& aF = TopoDS::Face(aItL.Value());
126     //
127     // compute bounding box
128     Bnd_Box aBoxF;
129     BRepBndLib::Add(aF, aBoxF);
130     //
131     Standard_Integer i = aMFaces.Add (aF, aBoxF);
132     //
133     aBBTree.Add(i, Bnd_Tools::Bnd2BVH(aBoxF));
134   }
135 
136   // Build BVH
137   aBBTree.Build();
138 
139   // Perform selection of the pairs
140   BOPTools_BoxPairSelector aSelector;
141   aSelector.SetBVHSets (&aBBTree, &aBBTree);
142   aSelector.SetSame (Standard_True);
143   aSelector.Select();
144   aSelector.Sort();
145 
146   // Treat the selected pairs
147   const std::vector<BOPTools_BoxPairSelector::PairIDs>& aPairs = aSelector.Pairs();
148   const Standard_Integer aNbPairs = static_cast<Standard_Integer> (aPairs.size());
149   Message_ProgressScope aPS(theRange, "Complete intersection", aNbPairs);
150   for (Standard_Integer iPair = 0; iPair < aNbPairs; ++iPair, aPS.Next())
151   {
152     if (!aPS.More())
153     {
154       return;
155     }
156     const BOPTools_BoxPairSelector::PairIDs& aPair = aPairs[iPair];
157 
158     const TopoDS_Face& aF1 = TopoDS::Face (aMFaces.FindKey (Min (aPair.ID1, aPair.ID2)));
159     const TopoDS_Face& aF2 = TopoDS::Face (aMFaces.FindKey (Max (aPair.ID1, aPair.ID2)));
160 
161     // intersect faces
162     FaceInter(aF1, aF2, InitOffsetFace);
163   }
164 }
165 
166 //=======================================================================
167 //function : FaceInter
168 //purpose  : Performs intersection of the given faces
169 //=======================================================================
170 
FaceInter(const TopoDS_Face & F1,const TopoDS_Face & F2,const BRepAlgo_Image & InitOffsetFace)171 void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1,
172                                    const TopoDS_Face& F2,
173                                    const BRepAlgo_Image&     InitOffsetFace)
174 {
175   TopTools_ListOfShape LInt1, LInt2;
176   TopoDS_Edge NullEdge;
177   TopoDS_Face NullFace;
178 
179   if (F1.IsSame(F2)) return;
180   if (IsDone(F1,F2)) return;
181 
182   const TopoDS_Shape& InitF1 = InitOffsetFace.ImageFrom(F1);
183   const TopoDS_Shape& InitF2 = InitOffsetFace.ImageFrom(F2);
184   if (InitF1.IsSame(InitF2)) return;
185 
186   Standard_Boolean InterPipes = (InitF2.ShapeType() == TopAbs_EDGE &&
187                                  InitF1.ShapeType() == TopAbs_EDGE );
188   Standard_Boolean InterFaces = (InitF1.ShapeType() == TopAbs_FACE &&
189                                  InitF2.ShapeType() == TopAbs_FACE);
190   TopTools_ListOfShape LE,LV;
191   LInt1.Clear(); LInt2.Clear();
192   if (BRepOffset_Tool::FindCommonShapes(F1,F2,LE,LV) ||
193       myAsDes->HasCommonDescendant(F1,F2,LE)) {
194     //-------------------------------------------------
195     // F1 and F2 share shapes.
196     //-------------------------------------------------
197     if ( LE.IsEmpty() && !LV.IsEmpty()) {
198       if (InterPipes) {
199         //----------------------
200         // tubes share a vertex.
201         //----------------------
202         const TopoDS_Edge& EE1 = TopoDS::Edge(InitF1);
203         const TopoDS_Edge& EE2 = TopoDS::Edge(InitF2);
204         TopoDS_Vertex VE1[2],VE2[2];
205         TopExp::Vertices(EE1,VE1[0],VE1[1]);
206         TopExp::Vertices(EE2,VE2[0],VE2[1]);
207         TopoDS_Vertex V;
208         for (Standard_Integer i = 0 ; i < 2; i++) {
209           for (Standard_Integer j = 0 ; j < 2; j++) {
210             if (VE1[i].IsSame(VE2[j])) {
211               V = VE1[i];
212             }
213           }
214         }
215         if (!InitOffsetFace.HasImage(V)) { //no sphere
216           BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide);
217         }
218       }
219       else {
220         //--------------------------------------------------------
221         // Intersection having only common vertices
222         // and supports having common edges.
223         // UNSUFFICIENT, but a larger criterion shakes too
224         // many sections.
225         //--------------------------------------------------------
226         if (InterFaces) {
227           if (BRepOffset_Tool::FindCommonShapes(TopoDS::Face(InitF1),
228                                                 TopoDS::Face(InitF2),LE,LV)) {
229             if (!LE.IsEmpty()) {
230               BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
231             }
232           }
233           else {
234             BRepOffset_Tool::Inter3D(F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
235           }
236         }
237       }
238     }
239   }
240   else {
241     if (InterPipes) {
242       BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide);
243     }
244     else {
245       BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
246     }
247   }
248   Store (F1,F2,LInt1,LInt2);
249 }
250 
251 
252 //=======================================================================
253 //function : ConnexIntByArc
254 //purpose  :
255 //=======================================================================
256 
ConnexIntByArc(const TopTools_ListOfShape &,const TopoDS_Shape & ShapeInit,const BRepOffset_Analyse & Analyse,const BRepAlgo_Image & InitOffsetFace,const Message_ProgressRange & theRange)257 void BRepOffset_Inter3d::ConnexIntByArc(const TopTools_ListOfShape& /*SetOfFaces*/,
258                                         const TopoDS_Shape&          ShapeInit,
259                                         const BRepOffset_Analyse&    Analyse,
260                                         const BRepAlgo_Image&        InitOffsetFace,
261                                         const Message_ProgressRange& theRange)
262 {
263   ChFiDS_TypeOfConcavity    OT   = ChFiDS_Concave;
264   if (mySide == TopAbs_OUT) OT   = ChFiDS_Convex;
265   TopExp_Explorer                Exp(ShapeInit,TopAbs_EDGE);
266   TopTools_ListOfShape           LInt1,LInt2;
267   TopoDS_Face                    F1,F2;
268   TopoDS_Edge                    NullEdge;
269   TopoDS_Face                    NullFace;
270   Message_ProgressScope aPSOuter(theRange, NULL, 2);
271   Message_ProgressScope aPSIntF(aPSOuter.Next(), "Intersecting offset faces", 1, Standard_True);
272   //---------------------------------------------------------------------
273   // etape 1 : Intersection of faces // corresponding to the initial faces
274   //           separated by a concave edge if offset > 0, otherwise convex.
275   //---------------------------------------------------------------------
276   for (; Exp.More(); Exp.Next(), aPSIntF.Next()) {
277     if (!aPSIntF.More())
278     {
279       return;
280     }
281     const TopoDS_Edge&               E = TopoDS::Edge(Exp.Current());
282     const BRepOffset_ListOfInterval& L = Analyse.Type(E);
283     if (!L.IsEmpty() && L.First().Type() == OT) {
284       //-----------------------------------------------------------
285       // edge is of the proper type , return adjacent faces.
286       //-----------------------------------------------------------
287       const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
288       if (Anc.Extent() == 2) {
289 
290         const TopoDS_Face& InitF1 = TopoDS::Face(Anc.First());
291         const TopoDS_Face& InitF2 = TopoDS::Face(Anc.Last());
292         F1 = TopoDS::Face(InitOffsetFace.Image(InitF1).First());
293         F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
294         if (!IsDone(F1,F2)) {
295           BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,E,InitF1,InitF2);
296           Store (F1,F2,LInt1,LInt2);
297         }
298       }
299     }
300   }
301   //---------------------------------------------------------------------
302   // etape 2 : Intersections of tubes sharing a vertex without sphere with:
303   //           - tubes on each other edge sharing the vertex
304   //           - faces containing an edge connected to vertex that has no tubes.
305   //---------------------------------------------------------------------
306   TopoDS_Vertex                      V[2];
307   TopTools_ListIteratorOfListOfShape it;
308   Message_ProgressScope aPSIntT(aPSOuter.Next(), "Intersecting tubes", 1, Standard_True);
309   for (Exp.Init(ShapeInit,TopAbs_EDGE); Exp.More(); Exp.Next(), aPSIntT.Next()) {
310     if (!aPSIntT.More())
311     {
312       return;
313     }
314     const TopoDS_Edge& E1 = TopoDS::Edge(Exp.Current());
315     if (InitOffsetFace.HasImage(E1)) {
316       //---------------------------
317       // E1 generated a tube.
318       //---------------------------
319       F1 = TopoDS::Face(InitOffsetFace.Image(E1).First());
320       TopExp::Vertices(E1,V[0],V[1]);
321       const TopTools_ListOfShape& AncE1 = Analyse.Ancestors(E1);
322 
323       for (Standard_Integer i = 0; i < 2; i++) {
324         if (!InitOffsetFace.HasImage(V[i])) {
325           //-----------------------------
326           // the vertex has no sphere.
327           //-----------------------------
328           const TopTools_ListOfShape& Anc     = Analyse.Ancestors(V[i]);
329           TopTools_ListOfShape TangOnV;
330           Analyse.TangentEdges(E1,V[i],TangOnV);
331           TopTools_MapOfShape MTEV;
332           for (it.Initialize(TangOnV); it.More(); it.Next()) {
333             MTEV.Add(it.Value());
334           }
335           for (it.Initialize(Anc); it.More(); it.Next()) {
336             const TopoDS_Edge& E2 = TopoDS::Edge(it.Value());
337 //  Modified by skv - Fri Jan 16 16:27:54 2004 OCC4455 Begin
338 //            if (E1.IsSame(E2) || MTEV.Contains(E2)) continue;
339             Standard_Boolean isToSkip = Standard_False;
340 
341             if (!E1.IsSame(E2)) {
342               const BRepOffset_ListOfInterval& aL = Analyse.Type(E2);
343 
344               isToSkip = (MTEV.Contains(E2) &&
345                           (aL.IsEmpty() ||
346                           (!aL.IsEmpty() && aL.First().Type() != OT)));
347             }
348 
349             if (E1.IsSame(E2) || isToSkip)
350               continue;
351 //  Modified by skv - Fri Jan 16 16:27:54 2004 OCC4455 End
352             if (InitOffsetFace.HasImage(E2)) {
353               //-----------------------------
354               // E2 generated a tube.
355               //-----------------------------
356               F2 = TopoDS::Face(InitOffsetFace.Image(E2).First());
357               if (!IsDone(F1,F2)) {
358                 //---------------------------------------------------------------------
359                 // Intersection tube/tube if the edges are not tangent (AFINIR).
360                 //----------------------------------------------------------------------
361                 BRepOffset_Tool::PipeInter (F1,F2,LInt1,LInt2,mySide);
362                 Store (F1,F2,LInt1,LInt2);
363               }
364             }
365             else {
366               //-------------------------------------------------------
367               // Intersection of the tube of E1 with faces //
368               // to face containing E2 if they are not tangent
369               // to the tube or if E2 is not a tangent edge.
370               //-------------------------------------------------------
371               const BRepOffset_ListOfInterval& L = Analyse.Type(E2);
372                if (!L.IsEmpty() && L.First().Type() == ChFiDS_Tangential) {
373                 continue;
374               }
375               const TopTools_ListOfShape& AncE2        = Analyse.Ancestors(E2);
376               Standard_Boolean            TangentFaces = Standard_False;
377               if (AncE2.Extent() == 2) {
378                 TopoDS_Face InitF2 = TopoDS::Face(AncE2.First ());
379                 TangentFaces = (InitF2.IsSame(AncE1.First()) ||
380                                 InitF2.IsSame(AncE1.Last()));
381                 if (!TangentFaces) {
382                   F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
383                   if (!IsDone(F1,F2)) {
384                     BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
385                     Store (F1,F2,LInt1,LInt2);
386                   }
387                 }
388                 InitF2 = TopoDS::Face(AncE2.Last ());
389                 TangentFaces = (InitF2.IsSame(AncE1.First()) ||
390                                 InitF2.IsSame(AncE1.Last()));
391                 if (!TangentFaces) {
392                   F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
393                   if (!IsDone(F1,F2)) {
394                     BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
395                     Store (F1,F2,LInt1,LInt2);
396                   }
397                 }
398               }
399             }
400           }
401         }
402       }
403     }
404   }
405 }
406 
407 
408 //=======================================================================
409 //function : ConnexIntByInt
410 //purpose  :
411 //=======================================================================
412 
ConnexIntByInt(const TopoDS_Shape & SI,const BRepOffset_DataMapOfShapeOffset & MapSF,const BRepOffset_Analyse & Analyse,TopTools_DataMapOfShapeShape & MES,TopTools_DataMapOfShapeShape & Build,TopTools_ListOfShape & Failed,const Message_ProgressRange & theRange,const Standard_Boolean bIsPlanar)413 void BRepOffset_Inter3d::ConnexIntByInt
414 (const TopoDS_Shape&                    SI,
415  const BRepOffset_DataMapOfShapeOffset& MapSF,
416  const BRepOffset_Analyse&              Analyse,
417  TopTools_DataMapOfShapeShape&          MES,
418  TopTools_DataMapOfShapeShape&          Build,
419  TopTools_ListOfShape&                  Failed,
420  const Message_ProgressRange&           theRange,
421  const Standard_Boolean                 bIsPlanar)
422 {
423   TopTools_IndexedMapOfShape VEmap;
424   TopoDS_Face     F1,F2,OF1,OF2,NF1,NF2;
425   TopAbs_State    CurSide = mySide;
426   BRep_Builder    B;
427   Standard_Boolean bEdge;
428   Standard_Integer i, aNb = 0;
429   TopTools_ListIteratorOfListOfShape it, it1, itF1, itF2;
430   //
431   TopExp::MapShapes (SI, TopAbs_EDGE, VEmap);
432   // Take the vertices for treatment
433   Message_ProgressScope aPSOuter(theRange, NULL, 10);
434   if (bIsPlanar)
435   {
436     aNb = VEmap.Extent();
437     for (i = 1; i <= aNb; ++i)
438     {
439       const TopoDS_Edge& aE = TopoDS::Edge (VEmap (i));
440       TopoDS_Shape aFGen = Analyse.Generated (aE);
441       if (!aFGen.IsNull())
442         TopExp::MapShapes (aFGen, TopAbs_EDGE, VEmap);
443     }
444 
445     // Add vertices for treatment
446     TopExp::MapShapes(SI, TopAbs_VERTEX, VEmap);
447 
448     for (TopTools_ListOfShape::Iterator itNF (Analyse.NewFaces()); itNF.More(); itNF.Next())
449       TopExp::MapShapes (itNF.Value(), TopAbs_VERTEX, VEmap);
450   }
451   //
452   TopTools_DataMapOfShapeListOfShape aDMVLF1, aDMVLF2, aDMIntFF;
453   TopTools_IndexedDataMapOfShapeListOfShape aDMIntE;
454   //
455   if (bIsPlanar)
456   {
457     // Find internal edges in the faces to skip them while preparing faces
458     // for intersection through vertices
459     NCollection_DataMap<TopoDS_Shape, TopTools_MapOfShape, TopTools_ShapeMapHasher> aDMFEI;
460     {
461       for (TopExp_Explorer expF (SI, TopAbs_FACE); expF.More(); expF.Next())
462       {
463         const TopoDS_Shape& aFx = expF.Current();
464 
465         TopTools_MapOfShape aMEI;
466         for (TopExp_Explorer expE (aFx, TopAbs_EDGE); expE.More(); expE.Next())
467         {
468           const TopoDS_Shape& aEx = expE.Current();
469           if (aEx.Orientation() != TopAbs_FORWARD &&
470               aEx.Orientation() != TopAbs_REVERSED)
471             aMEI.Add (aEx);
472         }
473         if (!aMEI.IsEmpty())
474           aDMFEI.Bind (aFx, aMEI);
475       }
476     }
477 
478     // Analyze faces connected through vertices
479     for (i = aNb + 1, aNb = VEmap.Extent(); i <= aNb; ++i)
480     {
481       if (!aPSOuter.More())
482       {
483         return;
484       }
485       const TopoDS_Shape& aS = VEmap(i);
486       if (aS.ShapeType() != TopAbs_VERTEX)
487         continue;
488 
489       // Find faces connected to the vertex
490       TopTools_ListOfShape aLF;
491       {
492         const TopTools_ListOfShape& aLE = Analyse.Ancestors (aS);
493         for (TopTools_ListOfShape::Iterator itLE (aLE); itLE.More(); itLE.Next())
494         {
495           const TopTools_ListOfShape& aLEA = Analyse.Ancestors (itLE.Value());
496           for (TopTools_ListOfShape::Iterator itLEA (aLEA); itLEA.More(); itLEA.Next())
497           {
498             if (!aLF.Contains (itLEA.Value()))
499               aLF.Append (itLEA.Value());
500           }
501         }
502       }
503 
504       if (aLF.Extent() < 2)
505         continue;
506 
507       // build lists of faces connected to the same vertex by looking for
508       // the pairs in which the vertex is alone (not connected to shared edges)
509       TopTools_ListOfShape aLF1, aLF2;
510 
511       it.Initialize(aLF);
512       for (; it.More(); it.Next())
513       {
514         const TopoDS_Shape& aFV1 = it.Value();
515 
516         // get edges of first face connected to current vertex
517         TopTools_MapOfShape aME;
518         const TopTools_MapOfShape *pF1Internal = aDMFEI.Seek (aFV1);
519         const TopTools_ListOfShape* pLE1 = Analyse.Descendants (aFV1);
520         if (!pLE1)
521           continue;
522         TopTools_ListOfShape::Iterator itLE1 (*pLE1);
523         for (; itLE1.More(); itLE1.Next())
524         {
525           const TopoDS_Shape& aE = itLE1.Value();
526           if (pF1Internal && pF1Internal->Contains (aE))
527             break;
528 
529           for (TopoDS_Iterator aItV(aE); aItV.More(); aItV.Next())
530           {
531             if (aS.IsSame (aItV.Value()))
532             {
533               aME.Add(aE);
534               break;
535             }
536           }
537         }
538         if (itLE1.More())
539           continue;
540 
541         // get to the next face in the list
542         it1 = it;
543         for (it1.Next(); it1.More(); it1.Next()) {
544           const TopoDS_Face& aFV2 = TopoDS::Face (it1.Value());
545 
546           const TopTools_MapOfShape *pF2Internal = aDMFEI.Seek (aFV2);
547 
548           const TopTools_ListOfShape* pLE2 = Analyse.Descendants (aFV2);
549           if (!pLE2)
550             continue;
551           TopTools_ListOfShape::Iterator itLE2 (*pLE2);
552           for (; itLE2.More(); itLE2.Next())
553           {
554             const TopoDS_Shape& aEV2 = itLE2.Value();
555             if (!aME.Contains (aEV2))
556               continue;
557 
558             if (pF2Internal && pF2Internal->Contains (aEV2))
559               // Avoid intersection of faces connected by internal edge
560               break;
561 
562             if (Analyse.HasAncestor (aEV2) &&
563                 Analyse.Ancestors (aEV2).Extent() == 2)
564               // Faces will be intersected through the edge
565               break;
566           }
567 
568           if (!itLE2.More())
569           {
570             aLF1.Append(aFV1);
571             aLF2.Append(aFV2);
572           }
573         }
574       }
575       //
576       if (aLF1.Extent()) {
577         aDMVLF1.Bind(aS, aLF1);
578         aDMVLF2.Bind(aS, aLF2);
579       }
580     }
581   }
582   //
583   aNb = VEmap.Extent();
584   Message_ProgressScope aPSInter(aPSOuter.Next(8), "Intersecting offset faces", aNb);
585   for (i = 1; i <= aNb; ++i, aPSInter.Next()) {
586     if (!aPSInter.More())
587     {
588       return;
589     }
590     const TopoDS_Shape& aS = VEmap(i);
591     //
592     TopoDS_Edge E;
593     TopTools_ListOfShape aLF1, aLF2;
594     //
595     bEdge = (aS.ShapeType() == TopAbs_EDGE);
596     if (bEdge) {
597       // faces connected by the edge
598       E = *(TopoDS_Edge*)&aS;
599       //
600       const BRepOffset_ListOfInterval& L = Analyse.Type(E);
601       if (L.IsEmpty()) {
602         continue;
603       }
604       //
605       ChFiDS_TypeOfConcavity OT   = L.First().Type();
606       if (OT != ChFiDS_Convex && OT != ChFiDS_Concave) {
607         continue;
608       }
609       //
610       if (OT == ChFiDS_Concave) CurSide = TopAbs_IN;
611       else                      CurSide = TopAbs_OUT;
612       //-----------------------------------------------------------
613       // edge is of the proper type, return adjacent faces.
614       //-----------------------------------------------------------
615       const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
616       if (Anc.Extent() != 2) {
617         continue;
618       }
619       //
620       F1  = TopoDS::Face(Anc.First());
621       F2  = TopoDS::Face(Anc.Last ());
622       //
623       aLF1.Append(F1);
624       aLF2.Append(F2);
625     }
626     else {
627       if (!aDMVLF1.IsBound(aS)) {
628         continue;
629       }
630       //
631       aLF1 = aDMVLF1.Find(aS);
632       aLF2 = aDMVLF2.Find(aS);
633       //
634       CurSide = mySide;
635     }
636     //
637     itF1.Initialize(aLF1);
638     itF2.Initialize(aLF2);
639     for (; itF1.More() && itF2.More(); itF1.Next(), itF2.Next()) {
640       F1 = TopoDS::Face(itF1.Value());
641       F2 = TopoDS::Face(itF2.Value());
642       //
643       OF1 = TopoDS::Face(MapSF(F1).Face());
644       OF2 = TopoDS::Face(MapSF(F2).Face());
645       if (!MES.IsBound(OF1)) {
646         Standard_Boolean enlargeU = Standard_True;
647         Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
648         BRepOffset_Tool::CheckBounds( F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
649         BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
650         MES.Bind(OF1,NF1);
651       }
652       else {
653         NF1 = TopoDS::Face(MES(OF1));
654       }
655       //
656       if (!MES.IsBound(OF2)) {
657         Standard_Boolean enlargeU = Standard_True;
658         Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
659         BRepOffset_Tool::CheckBounds( F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
660         BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
661         MES.Bind(OF2,NF2);
662       }
663       else {
664         NF2 = TopoDS::Face(MES(OF2));
665       }
666       //
667       if (!IsDone(NF1,NF2)) {
668         TopTools_ListOfShape LInt1,LInt2;
669         BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,F1,F2);
670         SetDone(NF1,NF2);
671         if (!LInt1.IsEmpty()) {
672           Store (NF1,NF2,LInt1,LInt2);
673           //
674           TopoDS_Compound C;
675           B.MakeCompound(C);
676           //
677           if (Build.IsBound(aS)) {
678             const TopoDS_Shape& aSE = Build(aS);
679             TopExp_Explorer aExp(aSE, TopAbs_EDGE);
680             for (; aExp.More(); aExp.Next()) {
681               const TopoDS_Shape& aNE = aExp.Current();
682               B.Add(C, aNE);
683             }
684           }
685           //
686           it.Initialize(LInt1);
687           for (; it.More(); it.Next()) {
688             const TopoDS_Shape& aNE = it.Value();
689             B.Add(C, aNE);
690             //
691             // keep connection from new edge to shape from which it was created
692             TopTools_ListOfShape *pLS = &aDMIntE(aDMIntE.Add(aNE, TopTools_ListOfShape()));
693             pLS->Append(aS);
694             // keep connection to faces created the edge as well
695             TopTools_ListOfShape* pLFF = aDMIntFF.Bound(aNE, TopTools_ListOfShape());
696             pLFF->Append(F1);
697             pLFF->Append(F2);
698           }
699           //
700           Build.Bind(aS,C);
701         }
702         else {
703           Failed.Append(aS);
704         }
705       } else { // IsDone(NF1,NF2)
706         //  Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin
707         const TopTools_ListOfShape &aLInt1 = myAsDes->Descendant(NF1);
708         const TopTools_ListOfShape &aLInt2 = myAsDes->Descendant(NF2);
709 
710         if (!aLInt1.IsEmpty()) {
711           TopoDS_Compound C;
712           B.MakeCompound(C);
713           //
714           if (Build.IsBound(aS)) {
715             const TopoDS_Shape& aSE = Build(aS);
716             TopExp_Explorer aExp(aSE, TopAbs_EDGE);
717             for (; aExp.More(); aExp.Next()) {
718               const TopoDS_Shape& aNE = aExp.Current();
719               B.Add(C, aNE);
720             }
721           }
722           //
723           for (it.Initialize(aLInt1) ; it.More(); it.Next()) {
724             const TopoDS_Shape &anE1 = it.Value();
725             //
726             for (it1.Initialize(aLInt2) ; it1.More(); it1.Next()) {
727               const TopoDS_Shape &anE2 = it1.Value();
728               if (anE1.IsSame(anE2)) {
729                 B.Add(C, anE1);
730                 //
731                 TopTools_ListOfShape *pLS = aDMIntE.ChangeSeek(anE1);
732                 if (pLS) {
733                   pLS->Append(aS);
734                 }
735               }
736             }
737           }
738           Build.Bind(aS,C);
739         }
740         else {
741           Failed.Append(aS);
742         }
743       }
744     }
745     //  Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End
746   }
747   //
748   // create unique intersection for each localized shared part
749   aNb = aDMIntE.Extent();
750   Message_ProgressScope aPSPostTreat(aPSOuter.Next(2), "Creating unique intersection", aNb);
751   for (i = 1; i <= aNb; ++i, aPSPostTreat.Next()) {
752     if (!aPSPostTreat.More())
753     {
754       return;
755     }
756     const TopTools_ListOfShape& aLS = aDMIntE(i);
757     if (aLS.Extent() < 2) {
758       continue;
759     }
760     //
761     // intersection edge
762     const TopoDS_Edge& aE = TopoDS::Edge(aDMIntE.FindKey(i));
763     // faces created the edge
764     const TopTools_ListOfShape& aLFF = aDMIntFF.Find(aE);
765     const TopoDS_Shape& aF1 = aLFF.First();
766     const TopoDS_Shape& aF2 = aLFF.Last();
767 
768     // Build really localized blocks from the original shapes in <aLS>:
769     // 1. Find edges from original faces connected to two or more shapes in <aLS>;
770     // 2. Make connexity blocks from edges in <aLS> and found connection edges;
771     // 3. Check if the vertices from <aLS> are not connected by these connection edges:
772     //    a. If so - add these vertices to Connexity Block containing the corresponding
773     //       connexity edge;
774     //    b. If not - add this vertex to list of connexity blocks
775     // 4. Create unique intersection edge for each connexity block
776 
777     // list of vertices
778     TopTools_ListOfShape aLV;
779     // compound of edges to build connexity blocks
780     TopoDS_Compound aCE;
781     B.MakeCompound(aCE);
782     TopTools_MapOfShape aMS;
783     TopTools_ListIteratorOfListOfShape aItLS(aLS);
784     for (; aItLS.More(); aItLS.Next()) {
785       const TopoDS_Shape& aS = aItLS.Value();
786       aMS.Add(aS);
787       if (aS.ShapeType() == TopAbs_EDGE) {
788         B.Add(aCE, aS);
789       }
790       else {
791         aLV.Append(aS);
792       }
793     }
794     //
795     // look for additional edges to connect the shared parts
796     TopTools_MapOfShape aMEConnection;
797     for (Standard_Integer j = 0; j < 2; ++j) {
798       const TopoDS_Shape& aF = !j ? aF1 : aF2;
799       //
800       TopExp_Explorer aExp(aF, TopAbs_EDGE);
801       for (; aExp.More(); aExp.Next()) {
802         const TopoDS_Shape& aEF = aExp.Current();
803         if (aMS.Contains(aEF) || aMEConnection.Contains(aEF)) {
804           continue;
805         }
806         //
807         TopoDS_Vertex aV1, aV2;
808         TopExp::Vertices(TopoDS::Edge(aEF), aV1, aV2);
809         //
810         // find parts to which the edge is connected
811         Standard_Integer iCounter = 0;
812         aItLS.Initialize(aLS);
813         for (; aItLS.More(); aItLS.Next()) {
814           const TopoDS_Shape& aS = aItLS.Value();
815           // iterator is not suitable here, because aS may be a vertex
816           TopExp_Explorer aExpV(aS, TopAbs_VERTEX);
817           for (; aExpV.More(); aExpV.Next()) {
818             const TopoDS_Shape& aV = aExpV.Current();
819             if (aV.IsSame(aV1) || aV.IsSame(aV2)) {
820               ++iCounter;
821               break;
822             }
823           }
824         }
825         //
826         if (iCounter >= 2) {
827           B.Add(aCE, aEF);
828           aMEConnection.Add(aEF);
829         }
830       }
831     }
832     //
833     TopTools_ListOfShape aLCBE;
834     BOPTools_AlgoTools::MakeConnexityBlocks(aCE, TopAbs_VERTEX, TopAbs_EDGE, aLCBE);
835     //
836     // create connexity blocks for alone vertices
837     TopTools_ListOfShape aLCBV;
838     TopTools_ListIteratorOfListOfShape aItLV(aLV);
839     for (; aItLV.More(); aItLV.Next()) {
840       const TopoDS_Shape& aV = aItLV.Value();
841       // check if this vertex is contained in some connexity block of edges
842       TopTools_ListIteratorOfListOfShape aItLCB(aLCBE);
843       for (; aItLCB.More(); aItLCB.Next()) {
844         TopoDS_Shape& aCB = aItLCB.ChangeValue();
845         TopExp_Explorer aExpV(aCB, TopAbs_VERTEX);
846         for (; aExpV.More(); aExpV.Next()) {
847           if (aV.IsSame(aExpV.Current())) {
848             B.Add(aCB, aV);
849             break;
850           }
851         }
852         if (aExpV.More()) {
853           break;
854         }
855       }
856       //
857       if (!aItLCB.More()) {
858         TopoDS_Compound aCV;
859         B.MakeCompound(aCV);
860         B.Add(aCV, aV);
861         aLCBV.Append(aCV);
862       }
863     }
864     //
865     aLCBE.Append(aLCBV);
866     //
867     if (aLCBE.Extent() == 1) {
868       continue;
869     }
870     //
871     const TopoDS_Shape& aNF1 = MES(MapSF(aF1).Face());
872     const TopoDS_Shape& aNF2 = MES(MapSF(aF2).Face());
873     //
874     TopTools_ListIteratorOfListOfShape aItLCB(aLCBE);
875     for (aItLCB.Next(); aItLCB.More(); aItLCB.Next()) {
876       // make new edge with different tedge instance
877       TopoDS_Edge aNewEdge;
878       TopoDS_Vertex aV1, aV2;
879       Standard_Real aT1, aT2;
880       //
881       TopExp::Vertices(aE, aV1, aV2);
882       BRep_Tool::Range(aE, aT1, aT2);
883       //
884       BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aNewEdge);
885       //
886       myAsDes->Add(aNF1, aNewEdge);
887       myAsDes->Add(aNF2, aNewEdge);
888       //
889       const TopoDS_Shape& aCB = aItLCB.Value();
890       TopoDS_Iterator aItCB(aCB);
891       for (; aItCB.More(); aItCB.Next()) {
892         const TopoDS_Shape& aS = aItCB.Value();
893         if (aMEConnection.Contains(aS)) {
894           continue;
895         }
896         TopoDS_Shape& aCI = Build.ChangeFind(aS);
897         //
898         TopoDS_Compound aNewCI;
899         B.MakeCompound(aNewCI);
900         TopExp_Explorer aExp(aCI, TopAbs_EDGE);
901         for (; aExp.More(); aExp.Next()) {
902           const TopoDS_Shape& aSx = aExp.Current();
903           if (!aSx.IsSame(aE)) {
904             B.Add(aNewCI, aSx);
905           }
906         }
907         B.Add(aNewCI, aNewEdge);
908         aCI = aNewCI;
909       }
910     }
911   }
912 }
913 
914 //=======================================================================
915 //function : ContextIntByInt
916 //purpose  :
917 //=======================================================================
918 
ContextIntByInt(const TopTools_IndexedMapOfShape & ContextFaces,const Standard_Boolean ExtentContext,const BRepOffset_DataMapOfShapeOffset & MapSF,const BRepOffset_Analyse & Analyse,TopTools_DataMapOfShapeShape & MES,TopTools_DataMapOfShapeShape & Build,TopTools_ListOfShape & Failed,const Message_ProgressRange & theRange,const Standard_Boolean bIsPlanar)919 void BRepOffset_Inter3d::ContextIntByInt
920 (const TopTools_IndexedMapOfShape&      ContextFaces,
921  const Standard_Boolean                 ExtentContext,
922  const BRepOffset_DataMapOfShapeOffset& MapSF,
923  const BRepOffset_Analyse&              Analyse,
924  TopTools_DataMapOfShapeShape&          MES,
925  TopTools_DataMapOfShapeShape&          Build,
926  TopTools_ListOfShape&                  Failed,
927  const Message_ProgressRange&           theRange,
928  const Standard_Boolean                 bIsPlanar)
929 {
930   TopTools_MapOfShape              MV;
931   TopExp_Explorer                  exp;
932   TopoDS_Face                      OF,NF,WCF;
933   TopoDS_Edge                      OE;
934   TopoDS_Compound                  C;
935   BRep_Builder                     B;
936   TopTools_ListIteratorOfListOfShape it, itF;
937   Standard_Integer i, j, aNb, aNbVE;
938   Standard_Boolean bEdge;
939 
940   aNb = ContextFaces.Extent();
941   for (i = 1; i <= aNb; i++) {
942     const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i));
943     myTouched.Add(CF);
944     if (ExtentContext) {
945       BRepOffset_Tool::EnLargeFace(CF,NF,0,0);
946       MES.Bind(CF,NF);
947     }
948   }
949   TopAbs_State Side = TopAbs_OUT;
950 
951   Message_ProgressScope aPS(theRange, "Intersecting with deepening faces", aNb);
952   for (i = 1; i <= aNb; i++, aPS.Next()) {
953     if (!aPS.More())
954     {
955       return;
956     }
957     const TopoDS_Face& CF  = TopoDS::Face(ContextFaces(i));
958     if (ExtentContext) WCF = TopoDS::Face(MES(CF));
959     else               WCF = CF;
960 
961     TopTools_IndexedMapOfShape VEmap;
962     TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_EDGE  , VEmap);
963     //
964     if (bIsPlanar) {
965       TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap);
966     }
967     //
968     aNbVE = VEmap.Extent();
969     for (j = 1; j <= aNbVE; ++j) {
970       const TopoDS_Shape& aS = VEmap(j);
971       //
972       bEdge = (aS.ShapeType() == TopAbs_EDGE);
973       //
974       TopoDS_Edge E;
975       TopTools_ListOfShape Anc;
976       //
977       if (bEdge) {
978         // faces connected by the edge
979         //
980         E = *(TopoDS_Edge*)&aS;
981         if (!Analyse.HasAncestor(E)) {
982           //----------------------------------------------------------------
983           // the edges of faces of context that are not in the initial shape
984           // can appear in the result.
985           //----------------------------------------------------------------
986           if (!ExtentContext) {
987             myAsDes->Add(CF,E);
988             myNewEdges.Add(E);
989           }
990           else {
991             if (!MES.IsBound(E)) {
992               TopoDS_Edge NE;
993               Standard_Real f,l,Tol;
994               BRep_Tool::Range(E,f,l);
995               Tol = BRep_Tool::Tolerance(E);
996               ExtentEdge(CF,E,NE);
997               TopoDS_Vertex V1,V2;
998               TopExp::Vertices(E,V1,V2);
999               NE.Orientation(TopAbs_FORWARD);
1000               myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
1001               myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
1002               TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
1003               B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
1004               aLocalShape = V2.Oriented(TopAbs_INTERNAL);
1005               B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
1006 //            B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
1007 //            B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
1008               NE.Orientation(E.Orientation());
1009               myAsDes->Add(CF,NE);
1010               myNewEdges.Add(NE);
1011               MES.Bind(E,NE);
1012             }
1013             else {
1014               TopoDS_Shape NE = MES(E);
1015               TopoDS_Shape aLocalShape = NE.Oriented(E.Orientation());
1016               myAsDes->Add(CF,aLocalShape);
1017 //            myAsDes->Add(CF,NE.Oriented(E.Orientation()));
1018             }
1019           }
1020           continue;
1021         }
1022         Anc = Analyse.Ancestors(E);
1023       }
1024       else {
1025         // faces connected by the vertex
1026         //
1027         if (!Analyse.HasAncestor(aS)) {
1028           continue;
1029         }
1030         //
1031         const TopTools_ListOfShape& aLE = Analyse.Ancestors(aS);
1032         it.Initialize(aLE);
1033         for (; it.More(); it.Next()) {
1034           const TopoDS_Edge& aE = *(TopoDS_Edge*)&it.Value();
1035           //
1036           if (BRep_Tool::Degenerated(aE)) {
1037             continue;
1038           }
1039           //
1040           if (VEmap.Contains(aE)) {
1041             continue;
1042           }
1043           //
1044           const TopTools_ListOfShape& aLF = Analyse.Ancestors(aE);
1045           itF.Initialize(aLF);
1046           for (; itF.More(); itF.Next()) {
1047             const TopoDS_Shape& aF = itF.Value();
1048             Standard_Boolean bAdd = Standard_True;
1049             exp.Init(aF, TopAbs_EDGE);
1050             for (; exp.More() && bAdd; exp.Next()) {
1051               const TopoDS_Shape& aEF = exp.Current();
1052               bAdd = !VEmap.Contains(aEF);
1053             }
1054             if (bAdd) {
1055               Anc.Append(aF);
1056             }
1057           }
1058         }
1059       }
1060       //
1061       itF.Initialize(Anc);
1062       for (; itF.More(); itF.Next()) {
1063         const TopoDS_Face& F = TopoDS::Face(itF.Value());
1064         OF = TopoDS::Face(MapSF(F).Face());
1065         TopoDS_Shape aLocalShape = MapSF(F).Generated(E);
1066         OE = TopoDS::Edge(aLocalShape);
1067 //      OE = TopoDS::Edge(MapSF(F).Generated(E));
1068         if (!MES.IsBound(OF)) {
1069           BRepOffset_Tool::EnLargeFace(OF,NF,1,1);
1070           MES.Bind(OF,NF);
1071         }
1072         else {
1073           NF = TopoDS::Face(MES(OF));
1074         }
1075         if (!IsDone(NF,CF)) {
1076           TopTools_ListOfShape LInt1,LInt2;
1077           TopTools_ListOfShape LOE;
1078           LOE.Append(OE);
1079           BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,CF,F);
1080           SetDone(NF,CF);
1081           if (!LInt1.IsEmpty()) {
1082             Store (CF,NF,LInt1,LInt2);
1083             if ((LInt1.Extent() == 1) && !Build.IsBound(aS)) {
1084               Build.Bind(aS,LInt1.First());
1085             }
1086             else {
1087               B.MakeCompound(C);
1088               if (Build.IsBound(aS)) {
1089                 const TopoDS_Shape& aSE = Build(aS);
1090                 exp.Init(aSE, TopAbs_EDGE);
1091                 for (; exp.More(); exp.Next()) {
1092                   const TopoDS_Shape& aNE = exp.Current();
1093                   B.Add(C, aNE);
1094                 }
1095               }
1096               //
1097               for (it.Initialize(LInt1) ; it.More(); it.Next()) {
1098                 B.Add(C,it.Value());
1099               }
1100               Build.Bind(aS,C);
1101             }
1102           }
1103           else {
1104             Failed.Append(aS);
1105           }
1106         }
1107       }
1108     }
1109   }
1110 }
1111 
1112 //=======================================================================
1113 //function : ContextIntByArc
1114 //purpose  :
1115 //=======================================================================
ContextIntByArc(const TopTools_IndexedMapOfShape & ContextFaces,const Standard_Boolean InSide,const BRepOffset_Analyse & Analyse,const BRepAlgo_Image & InitOffsetFace,BRepAlgo_Image & InitOffsetEdge,const Message_ProgressRange & theRange)1116 void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& ContextFaces,
1117                                          const Standard_Boolean            InSide,
1118                                          const BRepOffset_Analyse&         Analyse,
1119                                          const BRepAlgo_Image&             InitOffsetFace,
1120                                                BRepAlgo_Image&             InitOffsetEdge,
1121                                          const Message_ProgressRange&      theRange)
1122 {
1123   TopTools_ListOfShape                      LInt1,LInt2;
1124   TopTools_MapOfShape                       MV;
1125   TopExp_Explorer                           exp;
1126   TopoDS_Face                               OF1,OF2;
1127   TopoDS_Edge                               OE;
1128   BRep_Builder                              B;
1129   TopoDS_Edge                               NullEdge;
1130   TopoDS_Face                               NullFace;
1131   Standard_Integer j;
1132 
1133   for (j = 1; j <= ContextFaces.Extent(); j++) {
1134     const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j));
1135     myTouched.Add(CF);
1136   }
1137 
1138   Message_ProgressScope aPS(theRange, "Intersecting with deepening faces", ContextFaces.Extent());
1139   for (j = 1; j <= ContextFaces.Extent(); j++, aPS.Next()) {
1140     if (!aPS.More())
1141     {
1142       return;
1143     }
1144     const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j));
1145     for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1146          exp.More(); exp.Next()) {
1147       const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1148       if (!Analyse.HasAncestor(E)) {
1149         if (InSide)
1150           myAsDes->Add(CF,E);
1151         else {
1152           TopoDS_Edge NE;
1153           if (!InitOffsetEdge.HasImage(E)) {
1154             Standard_Real f,l,Tol;
1155             BRep_Tool::Range(E,f,l);
1156             Tol = BRep_Tool::Tolerance(E);
1157             ExtentEdge(CF,E,NE);
1158             TopoDS_Vertex V1,V2;
1159             TopExp::Vertices(E,V1,V2);
1160             NE.Orientation(TopAbs_FORWARD);
1161             myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
1162             myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
1163             TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
1164             B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
1165             aLocalShape = V2.Oriented(TopAbs_INTERNAL);
1166             B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
1167 //            B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
1168 //            B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
1169             NE.Orientation(E.Orientation());
1170             myAsDes->Add(CF,NE);
1171             InitOffsetEdge.Bind(E,NE);
1172           }
1173           else {
1174             NE = TopoDS::Edge(InitOffsetEdge.Image(E).First());
1175             myAsDes->Add(CF,NE.Oriented(E.Orientation()));
1176           }
1177         }
1178         continue;
1179       }
1180       OE.Nullify();
1181       //---------------------------------------------------
1182       // OF1 parallel facee generated by the ancestor of E.
1183       //---------------------------------------------------
1184       const TopoDS_Shape SI = Analyse.Ancestors(E).First();
1185       OF1 = TopoDS::Face(InitOffsetFace.Image(SI).First());
1186       OE  = TopoDS::Edge(InitOffsetEdge.Image(E).First());
1187 
1188       {
1189         //Check if OE has pcurve in CF
1190 
1191         Standard_Real   f,l;
1192 
1193         Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(OE,CF,f,l);
1194         Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(OE,OF1,f,l);
1195 
1196         if(C1.IsNull() || C2.IsNull())
1197         {
1198           continue;
1199         }
1200       }
1201 
1202       //--------------------------------------------------
1203       // MAJ of OE on cap CF.
1204       //--------------------------------------------------
1205 //      TopTools_ListOfShape LOE; LOE.Append(OE);
1206 //      BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
1207 //      LInt2.Clear();
1208 //      StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
1209 //                   LInt1,LInt2);
1210       LInt1.Clear(); LInt1.Append(OE);
1211       LInt2.Clear();
1212       TopAbs_Orientation anOri1, anOri2;
1213       BRepOffset_Tool::OrientSection(OE,CF,OF1, anOri1,anOri2);
1214 //    if (mySide == TopAbs_OUT);
1215       anOri1 = TopAbs::Reverse(anOri1);
1216       LInt1.First().Orientation(anOri1);
1217       Store(CF,OF1,LInt1,LInt2);
1218 
1219       //------------------------------------------------------
1220       // Processing of offsets on the ancestors of vertices.
1221       //------------------------------------------------------
1222       TopoDS_Vertex V[2];
1223       TopExp::Vertices (E,V[0],V[1]);
1224       for (Standard_Integer i = 0; i < 2; i++) {
1225         if (!MV.Add(V[i])) continue;
1226         OF1.Nullify();
1227         const TopTools_ListOfShape& LE =  Analyse.Ancestors(V[i]);
1228         TopTools_ListIteratorOfListOfShape itLE(LE);
1229         for ( ; itLE.More(); itLE.Next()) {
1230           const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
1231           if (InitOffsetFace.HasImage(EV)) {
1232             //-------------------------------------------------
1233             // OF1 parallel face generated by an ancester edge of V[i].
1234             //-------------------------------------------------
1235             OF1 = TopoDS::Face(InitOffsetFace.Image(EV).First());
1236             OE  = TopoDS::Edge(InitOffsetEdge.Image(V[i]).First());
1237 
1238       {
1239         //Check if OE has pcurve in CF and OF1
1240 
1241         Standard_Real   f,l;
1242 
1243         Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(OE,CF,f,l);
1244         Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(OE,OF1,f,l);
1245 
1246         if(C1.IsNull() || C2.IsNull())
1247         {
1248           continue;
1249         }
1250       }
1251 
1252             //--------------------------------------------------
1253             // MAj of OE on cap CF.
1254             //--------------------------------------------------
1255             //              LOE.Clear(); LOE.Append(OE);
1256             //              BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
1257             //              LInt2.Clear();
1258             //              StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
1259             //                           LInt1,LInt2);
1260             LInt1.Clear(); LInt1.Append(OE);
1261             LInt2.Clear();
1262             TopAbs_Orientation O1,O2;
1263             BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2);
1264 //            if (mySide == TopAbs_OUT);
1265             O1 = TopAbs::Reverse(O1);
1266             LInt1.First().Orientation(O1);
1267             Store(CF,OF1,LInt1,LInt2);
1268           }
1269         }
1270       }
1271     }
1272 
1273     for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
1274          exp.More(); exp.Next()) {
1275       const TopoDS_Vertex&        V  = TopoDS::Vertex(exp.Current());
1276       if (!Analyse.HasAncestor(V)) {
1277         continue;
1278       }
1279       const TopTools_ListOfShape& LE =  Analyse.Ancestors(V);
1280       TopTools_ListIteratorOfListOfShape itLE(LE);
1281       for (; itLE.More(); itLE.Next()) {
1282         const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
1283         const TopTools_ListOfShape& LF = Analyse.Ancestors(EV);
1284         TopTools_ListIteratorOfListOfShape itLF(LF);
1285         for ( ; itLF.More(); itLF.Next()) {
1286           const TopoDS_Face& FEV = TopoDS::Face(itLF.Value());
1287           //-------------------------------------------------
1288           // OF1 parallel face generated by uneFace ancestor of V[i].
1289           //-------------------------------------------------
1290           OF1 = TopoDS::Face(InitOffsetFace.Image(FEV).First());
1291           if (!IsDone(OF1,CF)) {
1292             //-------------------------------------------------------
1293             // Find if one of edges of OF1 has no trace in CF.
1294             //-------------------------------------------------------
1295             TopTools_ListOfShape LOE;
1296             TopExp_Explorer exp2(OF1.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1297             for ( ;exp2.More(); exp2.Next()) {
1298               LOE.Append(exp2.Current());
1299             }
1300             BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide,myTol);
1301             //-------------------------------------------------------
1302             // If no trace try intersection.
1303             //-------------------------------------------------------
1304             if (LInt1.IsEmpty()) {
1305               BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
1306             }
1307             Store (CF,OF1,LInt1,LInt2);
1308           }
1309         }
1310       }
1311     }
1312   }
1313 }
1314 
1315 //=======================================================================
1316 //function : SetDone
1317 //purpose  :
1318 //=======================================================================
SetDone(const TopoDS_Face & F1,const TopoDS_Face & F2)1319 void BRepOffset_Inter3d::SetDone(const TopoDS_Face& F1,
1320                                  const TopoDS_Face& F2)
1321 {
1322   if (!myDone.IsBound(F1)) {
1323     TopTools_ListOfShape empty;
1324     myDone.Bind(F1,empty);
1325   }
1326   myDone(F1).Append(F2);
1327   if (!myDone.IsBound(F2)) {
1328     TopTools_ListOfShape empty;
1329     myDone.Bind(F2,empty);
1330   }
1331   myDone(F2).Append(F1);
1332 }
1333 
1334 //=======================================================================
1335 //function : IsDone
1336 //purpose  :
1337 //=======================================================================
IsDone(const TopoDS_Face & F1,const TopoDS_Face & F2) const1338 Standard_Boolean BRepOffset_Inter3d::IsDone(const TopoDS_Face& F1,
1339                                             const TopoDS_Face& F2) const
1340 {
1341   if (myDone.IsBound(F1)) {
1342     TopTools_ListIteratorOfListOfShape it (myDone(F1));
1343     for (; it.More(); it.Next()) {
1344       if (it.Value().IsSame(F2)) return Standard_True;
1345     }
1346   }
1347   return Standard_False;
1348 }
1349 
1350 //=======================================================================
1351 //function : Store
1352 //purpose  :
1353 //=======================================================================
Store(const TopoDS_Face & F1,const TopoDS_Face & F2,const TopTools_ListOfShape & LInt1,const TopTools_ListOfShape & LInt2)1354 void BRepOffset_Inter3d::Store(const TopoDS_Face& F1,
1355                                const TopoDS_Face& F2,
1356                                const TopTools_ListOfShape& LInt1,
1357                                const TopTools_ListOfShape& LInt2)
1358 {
1359   if (!LInt1.IsEmpty()) {
1360     myTouched.Add(F1);
1361     myTouched.Add(F2);
1362     myAsDes->Add( F1,LInt1);
1363     myAsDes->Add( F2,LInt2);
1364     TopTools_ListIteratorOfListOfShape it(LInt1);
1365     for (; it.More(); it.Next()) {
1366       myNewEdges.Add(it.Value());
1367     }
1368   }
1369   SetDone(F1,F2);
1370 }
1371