0028903: BRepOffset_MakeOffset produces invalid shape (thickshell) in Intersection...
[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 <BRep_Builder.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAdaptor_Curve.hxx>
22 #include <BRepAlgo_AsDes.hxx>
23 #include <BRepAlgo_Image.hxx>
24 #include <BRepLib_MakeVertex.hxx>
25 #include <BRepOffset_Analyse.hxx>
26 #include <BRepOffset_DataMapOfShapeOffset.hxx>
27 #include <BRepOffset_Inter3d.hxx>
28 #include <BRepOffset_Interval.hxx>
29 #include <BRepOffset_ListOfInterval.hxx>
30 #include <BRepOffset_Offset.hxx>
31 #include <BRepOffset_Tool.hxx>
32 #include <Extrema_ExtPC.hxx>
33 #include <GeomAPI_ProjectPointOnCurve.hxx>
34 #include <Precision.hxx>
35 #include <TopExp.hxx>
36 #include <TopExp_Explorer.hxx>
37 #include <TopoDS.hxx>
38 #include <TopoDS_Compound.hxx>
39 #include <TopoDS_Edge.hxx>
40 #include <TopoDS_Face.hxx>
41 #include <TopoDS_Shape.hxx>
42 #include <TopoDS_Vertex.hxx>
43 #include <TopTools_IndexedMapOfShape.hxx>
44 #include <TopTools_ListIteratorOfListOfShape.hxx>
45 #include <TopTools_MapIteratorOfMapOfShape.hxx>
46 #include <TopTools_MapOfShape.hxx>
47 //
48 #include <BRepBndLib.hxx>
49 #include <BOPTools_BoxBndTree.hxx>
50 #include <NCollection_UBTreeFiller.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_BoxBndTree aBBTree;
118   NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
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     aTreeFiller.Add(i, aBoxF);
133   }
134   //
135   // shake tree filler
136   aTreeFiller.Fill();
137   //
138   // get faces with interfering bounding boxes
139   aItL.Initialize(SetOfFaces);
140   for (; aItL.More(); aItL.Next()) {
141     const TopoDS_Face& aF1 = TopoDS::Face(aItL.Value());
142     const Bnd_Box& aBoxF1 = aMFaces.FindFromKey(aF1);
143     //
144     BOPTools_BoxBndTreeSelector aSelector;
145     aSelector.SetBox(aBoxF1);
146     aBBTree.Select(aSelector);
147     //
148     const TColStd_ListOfInteger& aLI = aSelector.Indices();
149     TColStd_ListIteratorOfListOfInteger aItLI(aLI);
150     for (; aItLI.More(); aItLI.Next()) {
151       Standard_Integer i = aItLI.Value();
152       const TopoDS_Face& aF2 = TopoDS::Face(aMFaces.FindKey(i));
153       //
154       // intersect faces
155       FaceInter(aF1, aF2, InitOffsetFace);
156     }
157   }
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   BRepOffset_Type    OT   = BRepOffset_Concave;
257   if (mySide == TopAbs_OUT) OT   = BRepOffset_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() == BRepOffset_Tangent) {
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           TopoDS_Iterator aItV(aE);
451           for (; aItV.More(); aItV.Next()) {
452             if (aS.IsSame(aItV.Value())) {
453               aME.Add(aE);
454               break;
455             }
456           }
457         }
458         //
459         // get to the next face in the list
460         it1 = it;
461         for (it1.Next(); it1.More(); it1.Next()) {
462           const TopoDS_Shape& aFV2 = it1.Value();
463           //
464           aExp.Init(aFV2, TopAbs_EDGE);
465           for (; aExp.More(); aExp.Next()) {
466             const TopoDS_Shape& aEV2 = aExp.Current();
467             if (aME.Contains(aEV2)) {
468               break;
469             }
470           }
471           //
472           if (!aExp.More()) {
473             // faces share only vertex - make pair for intersection
474             aLF1.Append(aFV1);
475             aLF2.Append(aFV2);
476           }
477         }
478       }
479       //
480       if (aLF1.Extent()) {
481         aDMVLF1.Bind(aS, aLF1);
482         aDMVLF2.Bind(aS, aLF2);
483       }
484     }
485   }
486   //
487   aNb = VEmap.Extent();
488   for (i = 1; i <= aNb; ++i) {
489     const TopoDS_Shape& aS = VEmap(i);
490     //
491     TopoDS_Edge E;
492     TopTools_ListOfShape aLF1, aLF2;
493     //
494     bEdge = (aS.ShapeType() == TopAbs_EDGE);
495     if (bEdge) {
496       // faces connected by the edge
497       E = *(TopoDS_Edge*)&aS;
498       //
499       const BRepOffset_ListOfInterval& L = Analyse.Type(E);
500       if (L.IsEmpty()) {
501         continue;
502       }
503       //
504       BRepOffset_Type    OT   = L.First().Type();
505       if (OT != BRepOffset_Convex && OT != BRepOffset_Concave) {
506         continue;
507       }
508       //
509       if (OT == BRepOffset_Concave) CurSide = TopAbs_IN;
510       else                          CurSide = TopAbs_OUT;
511       //-----------------------------------------------------------
512       // edge is of the proper type, return adjacent faces.
513       //-----------------------------------------------------------
514       const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
515       if (Anc.Extent() != 2) {
516         continue;
517       }
518       //
519       F1  = TopoDS::Face(Anc.First());
520       F2  = TopoDS::Face(Anc.Last ());
521       //
522       aLF1.Append(F1);
523       aLF2.Append(F2);
524     }
525     else {
526       if (!aDMVLF1.IsBound(aS)) {
527         continue;
528       }
529       //
530       aLF1 = aDMVLF1.Find(aS);
531       aLF2 = aDMVLF2.Find(aS);
532       //
533       CurSide = mySide;
534     }
535     //
536     itF1.Initialize(aLF1);
537     itF2.Initialize(aLF2);
538     for (; itF1.More() && itF2.More(); itF1.Next(), itF2.Next()) {
539       F1 = TopoDS::Face(itF1.Value());
540       F2 = TopoDS::Face(itF2.Value());
541       //
542       OF1 = TopoDS::Face(MapSF(F1).Face());
543       OF2 = TopoDS::Face(MapSF(F2).Face());
544       if (!MES.IsBound(OF1)) {
545         Standard_Boolean enlargeU = Standard_True;
546         Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
547         BRepOffset_Tool::CheckBounds( F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
548         BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
549         MES.Bind(OF1,NF1);
550       }
551       else {
552         NF1 = TopoDS::Face(MES(OF1));
553       }
554       //
555       if (!MES.IsBound(OF2)) {
556         Standard_Boolean enlargeU = Standard_True;
557         Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
558         BRepOffset_Tool::CheckBounds( F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
559         BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
560         MES.Bind(OF2,NF2); 
561       }
562       else {
563         NF2 = TopoDS::Face(MES(OF2));
564       }
565       //
566       if (!IsDone(NF1,NF2)) {
567         TopTools_ListOfShape LInt1,LInt2;
568         BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,bEdge);
569         SetDone(NF1,NF2);
570         if (!LInt1.IsEmpty()) {
571           Store (NF1,NF2,LInt1,LInt2);
572           //
573           TopoDS_Compound C;
574           B.MakeCompound(C);
575           //
576           if (Build.IsBound(aS)) {
577             const TopoDS_Shape& aSE = Build(aS);
578             TopExp_Explorer aExp(aSE, TopAbs_EDGE);
579             for (; aExp.More(); aExp.Next()) {
580               const TopoDS_Shape& aNE = aExp.Current();
581               B.Add(C, aNE);
582             }
583           }
584           //
585           it.Initialize(LInt1);
586           for (; it.More(); it.Next()) {
587             const TopoDS_Shape& aNE = it.Value();
588             B.Add(C, aNE);
589             //
590             // keep connection from new edge to shape from which it was created
591             TopTools_ListOfShape *pLS = &aDMIntE(aDMIntE.Add(aNE, TopTools_ListOfShape()));
592             pLS->Append(aS);
593             // keep connection to faces created the edge as well
594             TopTools_ListOfShape* pLFF = aDMIntFF.Bound(aNE, TopTools_ListOfShape());
595             pLFF->Append(F1);
596             pLFF->Append(F2);
597           }
598           //
599           Build.Bind(aS,C);
600         }
601         else {
602           Failed.Append(aS);
603         }
604       } else { // IsDone(NF1,NF2)
605         //  Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin
606         const TopTools_ListOfShape &aLInt1 = myAsDes->Descendant(NF1);
607         const TopTools_ListOfShape &aLInt2 = myAsDes->Descendant(NF2);
608         
609         if (!aLInt1.IsEmpty()) {
610           TopoDS_Compound C;
611           B.MakeCompound(C);
612           //
613           if (Build.IsBound(aS)) {
614             const TopoDS_Shape& aSE = Build(aS);
615             TopExp_Explorer aExp(aSE, TopAbs_EDGE);
616             for (; aExp.More(); aExp.Next()) {
617               const TopoDS_Shape& aNE = aExp.Current();
618               B.Add(C, aNE);
619             }
620           }
621           //
622           for (it.Initialize(aLInt1) ; it.More(); it.Next()) {
623             const TopoDS_Shape &anE1 = it.Value();
624             //
625             for (it1.Initialize(aLInt2) ; it1.More(); it1.Next()) {
626               const TopoDS_Shape &anE2 = it1.Value();
627               if (anE1.IsSame(anE2)) {
628                 B.Add(C, anE1);
629                 //
630                 TopTools_ListOfShape *pLS = aDMIntE.ChangeSeek(anE1);
631                 if (pLS) {
632                   pLS->Append(aS);
633                 }
634               }
635             }
636           }
637           Build.Bind(aS,C);
638         }
639         else {
640           Failed.Append(aS);
641         }
642       }
643     }
644     //  Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End
645   }
646   //
647   // create unique intersection for each localized shared part
648   aNb = aDMIntE.Extent();
649   for (i = 1; i <= aNb; ++i) {
650     const TopTools_ListOfShape& aLS = aDMIntE(i);
651     if (aLS.Extent() < 2) {
652       continue;
653     }
654     //
655     // intersection edge
656     const TopoDS_Edge& aE = TopoDS::Edge(aDMIntE.FindKey(i));
657     // faces created the edge
658     const TopTools_ListOfShape& aLFF = aDMIntFF.Find(aE);
659     const TopoDS_Shape& aF1 = aLFF.First();
660     const TopoDS_Shape& aF2 = aLFF.Last();
661
662     // Build really localized blocks from the original shapes in <aLS>:
663     // 1. Find edges from original faces connected to two or more shapes in <aLS>;
664     // 2. Make connexity blocks from edges in <aLS> and found connection edges;
665     // 3. Check if the vertices from <aLS> are not connected by these connection edges:
666     //    a. If so - add these vertices to Connexity Block containing the corresponding
667     //       connexity edge;
668     //    b. If not - add this vertex to list of connexity blocks
669     // 4. Create unique intersection edge for each connexity block
670
671     // list of vertices
672     TopTools_ListOfShape aLV;
673     // compound of edges to build connexity blocks
674     TopoDS_Compound aCE;
675     B.MakeCompound(aCE);
676     TopTools_MapOfShape aMS;
677     TopTools_ListIteratorOfListOfShape aItLS(aLS);
678     for (; aItLS.More(); aItLS.Next()) {
679       const TopoDS_Shape& aS = aItLS.Value();
680       aMS.Add(aS);
681       if (aS.ShapeType() == TopAbs_EDGE) {
682         B.Add(aCE, aS);
683       }
684       else {
685         aLV.Append(aS);
686       }
687     }
688     //
689     // look for additional edges to connect the shared parts
690     TopTools_MapOfShape aMEConnection;
691     for (Standard_Integer j = 0; j < 2; ++j) {
692       const TopoDS_Shape& aF = !j ? aF1 : aF2;
693       //
694       TopExp_Explorer aExp(aF, TopAbs_EDGE);
695       for (; aExp.More(); aExp.Next()) {
696         const TopoDS_Shape& aEF = aExp.Current();
697         if (aMS.Contains(aEF) || aMEConnection.Contains(aEF)) {
698           continue;
699         }
700         //
701         TopoDS_Vertex aV1, aV2;
702         TopExp::Vertices(TopoDS::Edge(aEF), aV1, aV2);
703         //
704         // find parts to which the edge is connected
705         Standard_Integer iCounter = 0;
706         aItLS.Initialize(aLS);
707         for (; aItLS.More(); aItLS.Next()) {
708           const TopoDS_Shape& aS = aItLS.Value();
709           // iterator is not suitable here, because aS may be a vertex
710           TopExp_Explorer aExpV(aS, TopAbs_VERTEX);
711           for (; aExpV.More(); aExpV.Next()) {
712             const TopoDS_Shape& aV = aExpV.Current();
713             if (aV.IsSame(aV1) || aV.IsSame(aV2)) {
714               ++iCounter;
715               break;
716             }
717           }
718         }
719         //
720         if (iCounter >= 2) {
721           B.Add(aCE, aEF);
722           aMEConnection.Add(aEF);
723         }
724       }
725     }
726     //
727     TopTools_ListOfShape aLCBE;
728     BOPTools_AlgoTools::MakeConnexityBlocks(aCE, TopAbs_VERTEX, TopAbs_EDGE, aLCBE);
729     //
730     // create connexity blocks for alone vertices
731     TopTools_ListOfShape aLCBV;
732     TopTools_ListIteratorOfListOfShape aItLV(aLV);
733     for (; aItLV.More(); aItLV.Next()) {
734       const TopoDS_Shape& aV = aItLV.Value();
735       // check if this vertex is contained in some connexity block of edges
736       TopTools_ListIteratorOfListOfShape aItLCB(aLCBE);
737       for (; aItLCB.More(); aItLCB.Next()) {
738         TopoDS_Shape& aCB = aItLCB.ChangeValue();
739         TopExp_Explorer aExpV(aCB, TopAbs_VERTEX);
740         for (; aExpV.More(); aExpV.Next()) {
741           if (aV.IsSame(aExpV.Current())) {
742             B.Add(aCB, aV);
743             break;
744           }
745         }
746         if (aExpV.More()) {
747           break;
748         }
749       }
750       //
751       if (!aItLCB.More()) {
752         TopoDS_Compound aCV;
753         B.MakeCompound(aCV);
754         B.Add(aCV, aV);
755         aLCBV.Append(aCV);
756       }
757     }
758     //
759     aLCBE.Append(aLCBV);
760     //
761     if (aLCBE.Extent() == 1) {
762       continue;
763     }
764     //
765     const TopoDS_Shape& aNF1 = MES(MapSF(aF1).Face());
766     const TopoDS_Shape& aNF2 = MES(MapSF(aF2).Face());
767     //
768     TopTools_ListIteratorOfListOfShape aItLCB(aLCBE);
769     for (aItLCB.Next(); aItLCB.More(); aItLCB.Next()) {
770       // make new edge with different tedge instance
771       TopoDS_Edge aNewEdge;
772       TopoDS_Vertex aV1, aV2;
773       Standard_Real aT1, aT2;
774       //
775       TopExp::Vertices(aE, aV1, aV2);
776       BRep_Tool::Range(aE, aT1, aT2);
777       //
778       BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aNewEdge);
779       //
780       myAsDes->Add(aNF1, aNewEdge);
781       myAsDes->Add(aNF2, aNewEdge);
782       //
783       const TopoDS_Shape& aCB = aItLCB.Value();
784       TopoDS_Iterator aItCB(aCB);
785       for (; aItCB.More(); aItCB.Next()) {
786         const TopoDS_Shape& aS = aItCB.Value();
787         if (aMEConnection.Contains(aS)) {
788           continue;
789         }
790         TopoDS_Shape& aCI = Build.ChangeFind(aS);
791         //
792         TopoDS_Compound aNewCI;
793         B.MakeCompound(aNewCI);
794         TopExp_Explorer aExp(aCI, TopAbs_EDGE);
795         for (; aExp.More(); aExp.Next()) {
796           const TopoDS_Shape& aSx = aExp.Current();
797           if (!aSx.IsSame(aE)) {
798             B.Add(aNewCI, aSx);
799           }
800         }
801         B.Add(aNewCI, aNewEdge);
802         aCI = aNewCI;
803       }
804     }
805   }
806 }
807
808 //=======================================================================
809 //function : ContextIntByInt
810 //purpose  : 
811 //=======================================================================
812
813 void BRepOffset_Inter3d::ContextIntByInt
814 (const TopTools_IndexedMapOfShape&      ContextFaces, 
815  const Standard_Boolean                 ExtentContext,
816  const BRepOffset_DataMapOfShapeOffset& MapSF,
817  const BRepOffset_Analyse&              Analyse,
818  TopTools_DataMapOfShapeShape&          MES,
819  TopTools_DataMapOfShapeShape&          Build,
820  TopTools_ListOfShape&                  Failed,
821  const Standard_Boolean                 bIsPlanar)
822 {
823   TopTools_MapOfShape              MV;
824   TopExp_Explorer                  exp;
825   TopoDS_Face                      OF,NF,WCF;
826   TopoDS_Edge                      OE;
827   TopoDS_Compound                  C;
828   BRep_Builder                     B;
829   TopTools_ListIteratorOfListOfShape it, itF;
830   Standard_Integer i, j, aNb, aNbVE;
831   Standard_Boolean bEdge;
832
833   aNb = ContextFaces.Extent();
834   for (i = 1; i <= aNb; i++) {
835     const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i));
836     myTouched.Add(CF);
837     if (ExtentContext) {
838       BRepOffset_Tool::EnLargeFace(CF,NF,0,0);
839       MES.Bind(CF,NF);
840     }
841   }
842   TopAbs_State Side = TopAbs_OUT;
843  
844   for (i = 1; i <= aNb; i++) {
845     const TopoDS_Face& CF  = TopoDS::Face(ContextFaces(i));
846     if (ExtentContext) WCF = TopoDS::Face(MES(CF));
847     else               WCF = CF;
848
849     TopTools_IndexedMapOfShape VEmap;
850     TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_EDGE  , VEmap);
851     //
852     if (bIsPlanar) {
853       TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap);
854     }
855     //
856     aNbVE = VEmap.Extent();
857     for (j = 1; j <= aNbVE; ++j) {
858       const TopoDS_Shape& aS = VEmap(j);
859       //
860       bEdge = (aS.ShapeType() == TopAbs_EDGE);
861       //
862       TopoDS_Edge E;
863       TopTools_ListOfShape Anc;
864       //
865       if (bEdge) {
866         // faces connected by the edge
867         //
868         E = *(TopoDS_Edge*)&aS;
869         if (!Analyse.HasAncestor(E)) {
870           //----------------------------------------------------------------
871           // the edges of faces of context that are not in the initial shape
872           // can appear in the result.
873           //----------------------------------------------------------------
874           if (!ExtentContext) {
875             myAsDes->Add(CF,E);
876             myNewEdges.Add(E);
877           }
878           else {
879             if (!MES.IsBound(E)) {
880               TopoDS_Edge NE;
881               Standard_Real f,l,Tol;
882               BRep_Tool::Range(E,f,l);
883               Tol = BRep_Tool::Tolerance(E);
884               ExtentEdge(CF,E,NE);
885               TopoDS_Vertex V1,V2;
886               TopExp::Vertices(E,V1,V2);
887               NE.Orientation(TopAbs_FORWARD);
888               myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
889               myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
890               TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
891               B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
892               aLocalShape = V2.Oriented(TopAbs_INTERNAL);
893               B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
894 //            B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
895 //            B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
896               NE.Orientation(E.Orientation());
897               myAsDes->Add(CF,NE);
898               myNewEdges.Add(NE);
899               MES.Bind(E,NE);
900             }
901             else {
902               TopoDS_Shape NE = MES(E);
903               TopoDS_Shape aLocalShape = NE.Oriented(E.Orientation());
904               myAsDes->Add(CF,aLocalShape);
905 //            myAsDes->Add(CF,NE.Oriented(E.Orientation()));
906             }
907           }
908           continue;
909         } 
910         Anc = Analyse.Ancestors(E);
911       }
912       else {
913         // faces connected by the vertex
914         //
915         if (!Analyse.HasAncestor(aS)) {
916           continue;
917         }
918         //
919         const TopTools_ListOfShape& aLE = Analyse.Ancestors(aS);
920         it.Initialize(aLE);
921         for (; it.More(); it.Next()) {
922           const TopoDS_Edge& aE = *(TopoDS_Edge*)&it.Value();
923           //
924           if (BRep_Tool::Degenerated(aE)) {
925             continue;
926           }
927           //
928           if (VEmap.Contains(aE)) {
929             continue;
930           }
931           //
932           const TopTools_ListOfShape& aLF = Analyse.Ancestors(aE);
933           itF.Initialize(aLF);
934           for (; itF.More(); itF.Next()) {
935             const TopoDS_Shape& aF = itF.Value();
936             Standard_Boolean bAdd = Standard_True;
937             exp.Init(aF, TopAbs_EDGE);
938             for (; exp.More() && bAdd; exp.Next()) {
939               const TopoDS_Shape& aEF = exp.Current();
940               bAdd = !VEmap.Contains(aEF);
941             }
942             if (bAdd) {
943               Anc.Append(aF);
944             }
945           }
946         }
947       }
948       //
949       itF.Initialize(Anc);
950       for (; itF.More(); itF.Next()) {
951         const TopoDS_Face& F = TopoDS::Face(itF.Value());
952         OF = TopoDS::Face(MapSF(F).Face());
953         TopoDS_Shape aLocalShape = MapSF(F).Generated(E);
954         OE = TopoDS::Edge(aLocalShape);
955 //      OE = TopoDS::Edge(MapSF(F).Generated(E));
956         if (!MES.IsBound(OF)) {
957           BRepOffset_Tool::EnLargeFace(OF,NF,1,1);
958           MES.Bind(OF,NF);
959         }
960         else {
961           NF = TopoDS::Face(MES(OF));
962         }
963         if (!IsDone(NF,CF)) {
964           TopTools_ListOfShape LInt1,LInt2;
965           TopTools_ListOfShape LOE;
966           LOE.Append(OE);
967           BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,bEdge);
968           SetDone(NF,CF);
969           if (!LInt1.IsEmpty()) {
970             Store (CF,NF,LInt1,LInt2);
971             if ((LInt1.Extent() == 1) && !Build.IsBound(aS)) {
972               Build.Bind(aS,LInt1.First());
973             }
974             else {
975               B.MakeCompound(C);
976               if (Build.IsBound(aS)) {
977                 const TopoDS_Shape& aSE = Build(aS);
978                 exp.Init(aSE, TopAbs_EDGE);
979                 for (; exp.More(); exp.Next()) {
980                   const TopoDS_Shape& aNE = exp.Current();
981                   B.Add(C, aNE);
982                 }
983               }
984               //
985               for (it.Initialize(LInt1) ; it.More(); it.Next()) {
986                 B.Add(C,it.Value());
987               }
988               Build.Bind(aS,C);
989             }
990           }
991           else {
992             Failed.Append(aS);
993           }
994         }
995       }
996     }
997   }
998 }
999
1000 //=======================================================================
1001 //function : ContextIntByArc
1002 //purpose  : 
1003 //=======================================================================
1004
1005 void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& ContextFaces, 
1006                                          const Standard_Boolean            InSide,
1007                                          const BRepOffset_Analyse&         Analyse, 
1008                                          const BRepAlgo_Image&             InitOffsetFace, 
1009                                                BRepAlgo_Image&             InitOffsetEdge)
1010
1011
1012   TopTools_ListOfShape                      LInt1,LInt2;
1013   TopTools_MapOfShape                       MV;
1014   TopExp_Explorer                           exp;
1015   TopoDS_Face                               OF1,OF2;
1016   TopoDS_Edge                               OE;
1017   BRep_Builder                              B;  
1018   TopoDS_Edge                               NullEdge;
1019   Standard_Integer j;
1020
1021   for (j = 1; j <= ContextFaces.Extent(); j++) {
1022     const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j));
1023     myTouched.Add(CF);
1024   }
1025
1026   for (j = 1; j <= ContextFaces.Extent(); j++) {
1027     const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j));
1028     for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
1029          exp.More(); exp.Next()) {
1030       const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1031       if (!Analyse.HasAncestor(E)) {
1032         if (InSide)
1033           myAsDes->Add(CF,E);
1034         else {
1035           TopoDS_Edge NE;
1036           if (!InitOffsetEdge.HasImage(E)) {
1037             Standard_Real f,l,Tol;
1038             BRep_Tool::Range(E,f,l);
1039             Tol = BRep_Tool::Tolerance(E);
1040             ExtentEdge(CF,E,NE);
1041             TopoDS_Vertex V1,V2;
1042             TopExp::Vertices(E,V1,V2);
1043             NE.Orientation(TopAbs_FORWARD);
1044             myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
1045             myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
1046             TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
1047             B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
1048             aLocalShape = V2.Oriented(TopAbs_INTERNAL);
1049             B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
1050 //            B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
1051 //            B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
1052             NE.Orientation(E.Orientation());
1053             myAsDes->Add(CF,NE);
1054             InitOffsetEdge.Bind(E,NE);
1055           }
1056           else {
1057             NE = TopoDS::Edge(InitOffsetEdge.Image(E).First());
1058             myAsDes->Add(CF,NE.Oriented(E.Orientation()));
1059           }
1060         }
1061         continue;
1062       }
1063       OE.Nullify();
1064       //---------------------------------------------------
1065       // OF1 parallel facee generated by the ancestor of E.
1066       //---------------------------------------------------
1067       const TopoDS_Shape SI = Analyse.Ancestors(E).First();
1068       OF1 = TopoDS::Face(InitOffsetFace.Image(SI).First());
1069       OE  = TopoDS::Edge(InitOffsetEdge.Image(E).First());     
1070
1071       {
1072         //Check if OE has pcurve in CF
1073
1074         Standard_Real   f,l;
1075
1076         Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(OE,CF,f,l);
1077         Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(OE,OF1,f,l); 
1078
1079         if(C1.IsNull() || C2.IsNull())
1080         {
1081           continue;
1082         }
1083       }
1084
1085       //--------------------------------------------------
1086       // MAJ of OE on cap CF.
1087       //--------------------------------------------------
1088 //      TopTools_ListOfShape LOE; LOE.Append(OE);              
1089 //      BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
1090 //      LInt2.Clear();
1091 //      StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
1092 //                   LInt1,LInt2);
1093       LInt1.Clear(); LInt1.Append(OE);
1094       LInt2.Clear();    
1095       TopAbs_Orientation anOri1, anOri2;
1096       BRepOffset_Tool::OrientSection(OE,CF,OF1, anOri1,anOri2);
1097 //    if (mySide == TopAbs_OUT);
1098       anOri1 = TopAbs::Reverse(anOri1);
1099       LInt1.First().Orientation(anOri1);
1100       Store(CF,OF1,LInt1,LInt2);
1101       
1102       //------------------------------------------------------
1103       // Processing of offsets on the ancestors of vertices.
1104       //------------------------------------------------------
1105       TopoDS_Vertex V[2];
1106       TopExp::Vertices (E,V[0],V[1]);
1107       for (Standard_Integer i = 0; i < 2; i++) {
1108         if (!MV.Add(V[i])) continue;
1109         OF1.Nullify(); 
1110         const TopTools_ListOfShape& LE =  Analyse.Ancestors(V[i]);
1111         TopTools_ListIteratorOfListOfShape itLE(LE);
1112         for ( ; itLE.More(); itLE.Next()) {
1113           const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
1114           if (InitOffsetFace.HasImage(EV)) {
1115             //-------------------------------------------------
1116             // OF1 parallel face generated by an ancester edge of V[i].
1117             //-------------------------------------------------
1118             OF1 = TopoDS::Face(InitOffsetFace.Image(EV).First());
1119             OE  = TopoDS::Edge(InitOffsetEdge.Image(V[i]).First());
1120
1121       {
1122         //Check if OE has pcurve in CF and OF1
1123
1124         Standard_Real   f,l;
1125
1126         Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(OE,CF,f,l);
1127         Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(OE,OF1,f,l); 
1128
1129         if(C1.IsNull() || C2.IsNull())
1130         {
1131           continue;
1132         }
1133       }
1134
1135             //--------------------------------------------------
1136             // MAj of OE on cap CF.
1137             //--------------------------------------------------
1138             //              LOE.Clear(); LOE.Append(OE);
1139             //              BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
1140             //              LInt2.Clear();
1141             //              StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
1142             //                           LInt1,LInt2);
1143             LInt1.Clear(); LInt1.Append(OE);
1144             LInt2.Clear();    
1145             TopAbs_Orientation O1,O2;
1146             BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2);      
1147 //            if (mySide == TopAbs_OUT);
1148             O1 = TopAbs::Reverse(O1);
1149             LInt1.First().Orientation(O1);
1150             Store(CF,OF1,LInt1,LInt2);
1151           }
1152         }
1153       }
1154     }
1155     
1156     for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); 
1157          exp.More(); exp.Next()) {
1158       const TopoDS_Vertex&        V  = TopoDS::Vertex(exp.Current());
1159       if (!Analyse.HasAncestor(V)) {
1160         continue;
1161       }
1162       const TopTools_ListOfShape& LE =  Analyse.Ancestors(V);
1163       TopTools_ListIteratorOfListOfShape itLE(LE);
1164       for (; itLE.More(); itLE.Next()) {
1165         const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
1166         const TopTools_ListOfShape& LF = Analyse.Ancestors(EV);
1167         TopTools_ListIteratorOfListOfShape itLF(LF);
1168         for ( ; itLF.More(); itLF.Next()) {
1169           const TopoDS_Face& FEV = TopoDS::Face(itLF.Value());
1170           //-------------------------------------------------
1171           // OF1 parallel face generated by uneFace ancestor of V[i].
1172           //-------------------------------------------------
1173           OF1 = TopoDS::Face(InitOffsetFace.Image(FEV).First());
1174           if (!IsDone(OF1,CF)) {
1175             //-------------------------------------------------------
1176             // Find if one of edges of OF1 has no trace in CF.
1177             //-------------------------------------------------------
1178             TopTools_ListOfShape LOE;
1179             TopExp_Explorer exp2(OF1.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1180             for ( ;exp2.More(); exp2.Next()) {
1181               LOE.Append(exp2.Current());
1182             }
1183             BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide,myTol);
1184             //-------------------------------------------------------
1185             // If no trace try intersection.
1186             //-------------------------------------------------------
1187             if (LInt1.IsEmpty()) {
1188               BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,NullEdge);
1189             }
1190             Store (CF,OF1,LInt1,LInt2);
1191           }
1192         }
1193       }
1194     } 
1195   }
1196 }
1197
1198 //=======================================================================
1199 //function : AddCommonEdges
1200 //purpose  : 
1201 //=======================================================================
1202
1203 void BRepOffset_Inter3d::AddCommonEdges(const TopTools_ListOfShape&)
1204 {
1205 }
1206
1207
1208 //=======================================================================
1209 //function : SetDone
1210 //purpose  : 
1211 //=======================================================================
1212
1213 void BRepOffset_Inter3d::SetDone(const TopoDS_Face& F1, 
1214                                  const TopoDS_Face& F2)
1215 {
1216   if (!myDone.IsBound(F1)) {
1217     TopTools_ListOfShape empty;
1218     myDone.Bind(F1,empty);
1219   }
1220   myDone(F1).Append(F2);
1221   if (!myDone.IsBound(F2)) {
1222     TopTools_ListOfShape empty;
1223     myDone.Bind(F2,empty);
1224   }
1225   myDone(F2).Append(F1);
1226 }
1227
1228
1229 //=======================================================================
1230 //function : IsDone
1231 //purpose  : 
1232 //=======================================================================
1233
1234 Standard_Boolean BRepOffset_Inter3d::IsDone(const TopoDS_Face& F1, 
1235                                             const TopoDS_Face& F2) 
1236 const 
1237 {
1238   if (myDone.IsBound(F1)) {
1239     TopTools_ListIteratorOfListOfShape it (myDone(F1));
1240     for (; it.More(); it.Next()) {
1241       if (it.Value().IsSame(F2)) return Standard_True;
1242     }
1243   }
1244   return Standard_False;
1245 }
1246
1247
1248 //=======================================================================
1249 //function : TouchedFaces
1250 //purpose  : 
1251 //=======================================================================
1252
1253 TopTools_IndexedMapOfShape& BRepOffset_Inter3d::TouchedFaces()
1254 {
1255   return myTouched;
1256 }
1257
1258
1259 //=======================================================================
1260 //function : AsDes
1261 //purpose  : 
1262 //=======================================================================
1263
1264 Handle(BRepAlgo_AsDes) BRepOffset_Inter3d::AsDes() const 
1265 {
1266   return myAsDes;
1267 }
1268
1269
1270 //=======================================================================
1271 //function : NewEdges
1272 //purpose  : 
1273 //=======================================================================
1274
1275 TopTools_IndexedMapOfShape& BRepOffset_Inter3d::NewEdges() 
1276 {
1277   return myNewEdges;
1278 }
1279
1280
1281
1282 //=======================================================================
1283 //function : Store
1284 //purpose  : 
1285 //=======================================================================
1286
1287 void BRepOffset_Inter3d::Store(const TopoDS_Face& F1, 
1288                                const TopoDS_Face& F2, 
1289                                const TopTools_ListOfShape& LInt1, 
1290                                const TopTools_ListOfShape& LInt2)
1291 {
1292   if (!LInt1.IsEmpty()) {
1293     myTouched.Add(F1);
1294     myTouched.Add(F2);
1295     myAsDes->Add( F1,LInt1);
1296     myAsDes->Add( F2,LInt2);
1297     TopTools_ListIteratorOfListOfShape it(LInt1);
1298     for (; it.More(); it.Next()) {
1299       myNewEdges.Add(it.Value());
1300     }
1301   }
1302   SetDone(F1,F2);
1303 }