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