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